
// The havoc shrike now has a single missile launcher on it's belly.  If needed
// we can add one to either wing instead.  Because of the added complexity and
// the wing lowering animation, I would rather not.  But if insisted upon or it
// becomes needed that can be handled much like the chaingun is and the weapons
// mounted on a timer.

//--------------------------------------------------------------------------
$vehicleReticle[ScoutFlyer, 1, bitmap] = "gui/hud_ret_shrike.png";
$vehicleReticle[ScoutFlyer, 1, frame] = true;
$vehicleReticle[ScoutFlyer, 2, bitmap] = "gui/ret_missile.png";
$vehicleReticle[ScoutFlyer, 2, frame] = true;
$vehicleReticle[ScoutFlyer, 3, bitmap] = "gui/hud_ret_targlaser.png";
$vehicleReticle[ScoutFlyer, 3, frame] = false;

datablock AudioProfile(ShrikeBlasterProjectileSound)
{
   filename    = "fx/vehicles/shrike_blaster_projectile.wav";
   description = ProjectileLooping3d;
   preload = true;
};

datablock AudioProfile(ScoutFlyerThrustSound)
{
   filename    = "fx/vehicles/shrike_boost.wav";
   description = AudioDefaultLooping3d;
   preload = true;
};

datablock AudioProfile(ScoutFlyerEngineSound)
{
   filename    = "fx/vehicles/shrike_engine.wav";
   description = AudioDefaultLooping3d;
   preload = true;
};

datablock AudioProfile(ShrikeBlasterFire)
{
   filename    = "fx/vehicles/shrike_blaster.wav";
   description = AudioDefault3d;
   preload = true;
};

datablock AudioProfile(ShrikeBlasterProjectile)
{
   filename    = "fx/weapons/shrike_blaster_projectile.wav";
   description = ProjectileLooping3d;
   preload = true;
};

datablock AudioProfile(ShrikeBlasterDryFireSound)
{
   filename    = "fx/weapons/chaingun_dryfire.wav";
   description = AudioClose3d;
   preload = true;
};

//**************************************************************
// LIGHTS
//**************************************************************
datablock RunningLightData(ShrikeLight1)
{
   type        = 1;
   radius      = 2.0;
   length      = 3.0;
   color       = "1.0  1.0  1.0  1.0";
   direction   = "0.0  1.0 -1.0 ";
   offset      = "0.0  0.0 -0.5";
   texture     = "special/lightcone04";
};

datablock RunningLightData(ShrikeLight2)
{
   radius = 1.5;
   color = "1.0 1.0 1.0 0.3";
   direction = "0.0 0.0 -1.0";
   offset      = "0.0  0.8 -1.2";
   texture = "special/headlight4";
};

//--------------------------------------------------------------------------
// Missile Projectile
//--------------------------------------
datablock SeekerProjectileData(ShrikeMissile)
{
   projectileShapeName    = "weapon_missile_projectile.dts";

   hasDamageRadius        = true;
   indirectDamage         = 0.78;
   damageRadius           = 7.5;
   radiusDamageType       = $DamageType::HighExplosion;
   kickBackStrength       = 1500;

   flareDistance          = 10;
   flareAngle             = 0.1;
   minSeekHeat            = 0.5;

   explosion              = "MissileExplosion";
   velInheritFactor       = 1;

   splash                 = MissileSplash;
   baseEmitter            = MissileSmokeEmitter;
   delayEmitter           = MissileFireEmitter;
   puffEmitter            = MissilePuffEmitter;

   lifetimeMS             = 14000;
   muzzleVelocity         = 30.0;
   turningSpeed           = 90.0;
   maxVelocity            = 650.0;
   acceleration           = 65.0;
   
   proximityRadius        = 3;

   terrainAvoidanceSpeed  = 320;
   terrainScanAhead       = 65;
   terrainHeightFail      = 20;
   terrainAvoidanceRadius = 200;
};

datablock TurretImageData(ScoutMissileImage)
{
   shapeFile = "turret_mortar_large.dts";
   item = MissileBarrelLargePack;

   offset = "0 2.4 -0.25";
   mountPoint = 10;

   projectile = ShrikeMissile;
   projectileType = SeekerProjectile;

   usesEnergy = true;
   fireEnergy = 35.0;
   minEnergy = 45.0;

   minHeatSeek = 0.5;

   emap = true;

   // State transitions
   stateName[0]                  = "Activate";
   stateTransitionOnNotLoaded[0] = "Dead";
   stateTransitionOnLoaded[0]    = "ActivateReady";

   stateName[1]                  = "ActivateReady";
   stateSequence[1]              = "Activate";
   stateSound[1]                 = MBLSwitchSound;
   stateTimeoutValue[1]          = 0.7;
   stateTransitionOnTimeout[1]   = "Ready";
   stateTransitionOnNotLoaded[1] = "Deactivate";
   stateTransitionOnNoAmmo[1]    = "NoAmmo";

   stateName[2]                    = "Ready";
   stateTransitionOnNotLoaded[2]   = "Deactivate";
   stateTransitionOnTriggerDown[2] = "Fire";
   stateTransitionOnNoAmmo[2]      = "NoAmmo";

   stateName[3]                = "Fire";
   stateTransitionOnTimeout[3] = "Reload";
   stateTimeoutValue[3]        = 0.3;
   stateFire[3]                = true;
   stateAllowImageChange[3]    = false;
   stateSequence[3]            = "Fire";
   stateSound[3]               = MissileFireSound;
   stateScript[3]              = "onFire";

   stateName[4]                  = "Reload";
   stateTimeoutValue[4]          = 1.95;
   stateAllowImageChange[4]      = false;
   stateSequence[4]              = "Reload";
   stateTransitionOnTimeout[4]   = "Ready";
   stateTransitionOnNotLoaded[4] = "Deactivate";
   stateTransitionOnNoAmmo[4]    = "NoAmmo";

   stateName[5]                = "Deactivate";
   stateSequence[5]            = "Activate";
   stateDirection[5]           = false;
   stateTimeoutValue[5]        = 1;
   stateTransitionOnLoaded[5]  = "ActivateReady";
   stateTransitionOnTimeout[5] = "Dead";

   stateName[6]               = "Dead";
   stateTransitionOnLoaded[6] = "ActivateReady";

   stateName[7]             = "NoAmmo";
   stateTransitionOnAmmo[7] = "Reload";
   stateSequence[7]         = "NoAmmo";
};

function ScoutMissileImage::onFire(%Data, %Object, %Slot)
{
   %Projectile = Parent::onFire(%Data, %Object, %Slot);
   MissileSet.add(%Projectile);

   %Projectile.sourceObject = %Object.lastPilot;
  
   %Projectile.setNoTarget();

   // Chance of it not seeking
   %Random = getRandom();
   if (%Random > 0.06)
      %Projectile.SeekHeat = %Projectile.getDataBlock().SeekHeat(%Projectile, %Object.lastPilot.team, %Data.minSeekHeat, %Object.getForwardVector(), 50, 40);
}

datablock FlyingVehicleData(ScoutFlyer) : ShrikeDamageProfile
{
   spawnOffset = "0 0 2";

   catagory = "Vehicles";
   shapeFile = "vehicle_air_scout.dts";
   multipassenger = false;
   computeCRC = true;

   numWeapons = 3;

   debrisShapeName = "vehicle_air_scout_debris.dts";
//   debris = ShapeDebris;
   debrisBase = 6;
   debrisVariance = 6;
   debrisEjectionScale = 1.2;

   drag    = 0.15;
   density = 1.0;

   mountPose[0] = sitting;
   numMountPoints = 1;  
   isProtectedMountPoint[0] = true;
   cameraMaxDist = 15;
   cameraOffset = 2.5;
   cameraLag = 0.9;
   explosion = VehicleExplosion;
   explosionDamage = 1.5;
   explosionRadius = 25.0;
   explosionImpulse = 2500;

   maxDamage = 1.40;
   destroyedLevel = 1.40;

   isShielded = true;
   energyPerDamagePoint = 120;
   maxEnergy = 200;      // Afterburner and any energy weapon pool
   minDrag = 30;           // Linear Drag (eventually slows you down when not thrusting...constant drag)
   rotationalDrag = 900;        // Anguler Drag (dampens the drift after you stop moving the mouse...also tumble drag)
   rechargeRate = 0.55;

   maxAutoSpeed = 15;       // Autostabilizer kicks in when less than this speed. (meters/second)
   autoAngularForce = 400;       // Angular stabilizer force (this force levels you out when autostabilizer kicks in)
   autoLinearForce = 300;        // Linear stabilzer force (this slows you down when autostabilizer kicks in)
   autoInputDamping = 0.95;      // Dampen control input so you don't` whack out at very slow speeds
   
   // Maneuvering
   maxSteeringAngle = 5;    // Max radiens you can rotate the wheel. Smaller number is more maneuverable.
   horizontalSurfaceForce = 6;   // Horizontal center "wing" (provides "bite" into the wind for climbing/diving and turning)
   verticalSurfaceForce = 4;     // Vertical center "wing" (controls side slip. lower numbers make MORE slide.)
   maneuveringForce = 3200;      // Horizontal jets (W,S,D,A key thrust)
   steeringForce = 1200;         // Steering jets (force applied when you move the mouse)
   steeringRollForce = 400;      // Steering jets (how much you heel over when you turn)
   rollForce = 4;                // Auto-roll (self-correction to right you after you roll/invert)
   hoverHeight = 4.5;        // Height off the ground at rest
   createHoverHeight = 3;  // Height off the ground when created
   maxForwardSpeed = 1000;

   // Turbo Jet
   jetForce = 2500;      // Afterburner thrust (this is in addition to normal thrust)
   minJetEnergy = 20;     // Afterburner can't be used if below this threshhold.
   jetEnergyDrain = 2.4;       // Energy use of the afterburners (low number is less drain...can be fractional)                                                                                                                                                                                                                                                                                          // Auto stabilize speed
   vertThrustMultiple = 5.0;

   ELFDrain  = 2.0;

   // Rigid body
   mass = 120;        // Mass of the vehicle
   bodyFriction = 0;     // Don't mess with this.
   bodyRestitution = 0.5;   // When you hit the ground, how much you rebound. (between 0 and 1)
   minRollSpeed = 0;     // Don't mess with this.
   softImpactSpeed = 14;       // Sound hooks. This is the soft hit.
   hardImpactSpeed = 25;    // Sound hooks. This is the hard hit.

   // Ground Impact Damage (uses DamageType::Ground)
   minImpactSpeed = 30;      // If hit ground at speed above this then it's an impact. Meters/second
   speedDamageScale = 0.04;

   // Object Impact Damage (uses DamageType::Impact)
   collDamageThresholdVel = 25.0;
   collDamageMultiplier   = 0.02;

   //
   minTrailSpeed = 20;      // The speed your contrail shows up at.
   trailEmitter = ContrailEmitter;
   forwardJetEmitter = FlyerJetEmitter;
   downJetEmitter = FlyerJetEmitter;

   //
   jetSound = ScoutFlyerThrustSound;
   engineSound = ScoutFlyerEngineSound;
   softImpactSound = SoftImpactSound;
   hardImpactSound = HardImpactSound;
   //wheelImpactSound = WheelImpactSound;
   
   //
   softSplashSoundVelocity = 10.0; 
   mediumSplashSoundVelocity = 15.0;   
   hardSplashSoundVelocity = 20.0;   
   exitSplashSoundVelocity = 10.0;
   
   exitingWater      = VehicleExitWaterMediumSound;
   impactWaterEasy   = VehicleImpactWaterSoftSound;
   impactWaterMedium = VehicleImpactWaterMediumSound;
   impactWaterHard   = VehicleImpactWaterMediumSound;
   waterWakeSound    = VehicleWakeMediumSplashSound; 
    
   dustEmitter = VehicleLiftoffDustEmitter;
   triggerDustHeight = 4.0;
   dustHeight = 1.0;

   damageEmitter[0] = LightDamageSmoke;
   damageEmitter[1] = HeavyDamageSmoke;
   damageEmitter[2] = DamageBubbles;
   damageEmitterOffset[0] = "0.0 -3.0 0.0 ";
   damageLevelTolerance[0] = 0.3;
   damageLevelTolerance[1] = 0.7;
   numDmgEmitterAreas = 1;

   minMountDist = 4;

   splashEmitter[0] = VehicleFoamDropletsEmitter;
   splashEmitter[1] = VehicleFoamEmitter;

   shieldImpact = VehicleShieldImpact;

   cmdCategory = "Tactical";
   cmdIcon = CMDFlyingScoutIcon;
   cmdMiniIconName = "commander/MiniIcons/com_scout_grey";
   targetNameTag = 'Shrike';
   targetTypeTag = 'Flying Vehicle';
   sensorData = AWACPulseSensor;
   sensorRadius = AWACPulseSensor.detectRadius;
   sensorColor = "255 194 9";
   
   checkRadius = 5.5;
   observeParameters = "1 10 10";
};

datablock ShockwaveData(ScoutChaingunHit)
{
   width = 0.5;
   numSegments = 13;
   numVertSegments = 1;
   velocity = 0.5;
   acceleration = 2.0;
   lifetimeMS = 900;
   height = 0.1;
   verticalCurve = 0.5;

   mapToTerrain = false;
   renderBottom = false;
   orientToNormal = true;

   texture[0] = "special/shockwave5";
   texture[1] = "special/gradient";
   texWrap = 3.0;

   times[0] = 0.0;
   times[1] = 0.5;
   times[2] = 1.0;

   colors[0] = "0.6 0.6 1.0 1.0";
   colors[1] = "0.6 0.3 1.0 0.5";
   colors[2] = "0.0 0.0 1.0 0.0";
};

datablock ParticleData(ScoutChaingunExplosionParticle1)
{
   dragCoefficient      = 2;
   gravityCoefficient   = 0.0;
   inheritedVelFactor   = 0.2;
   constantAcceleration = -0.0;
   lifetimeMS           = 600;
   lifetimeVarianceMS   = 000;
   textureName          = "special/crescent4";
   colors[0] = "0.6 0.6 1.0 1.0";
   colors[1] = "0.6 0.3 1.0 1.0";
   colors[2] = "0.0 0.0 1.0 0.0";
   sizes[0]      = 0.25;
   sizes[1]      = 0.5;
   sizes[2]      = 1.0;
   times[0]      = 0.0;
   times[1]      = 0.5;
   times[2]      = 1.0;
};

datablock ParticleEmitterData(ScoutChaingunExplosionEmitter)
{
   ejectionPeriodMS = 10;
   periodVarianceMS = 0;
   ejectionVelocity = 2;
   velocityVariance = 1.5;
   ejectionOffset   = 0.0;
   thetaMin         = 80;
   thetaMax         = 90;
   phiReferenceVel  = 0;
   phiVariance      = 360;
   overrideAdvances = false;
   orientParticles  = true;
   lifetimeMS       = 200;
   particles = "ScoutChaingunExplosionParticle1";
};

datablock ExplosionData(ScoutChaingunExplosion)
{
   soundProfile   = blasterExpSound;
   shockwave = ScoutChaingunHit;
   emitter[0] = ScoutChaingunExplosionEmitter;
};

datablock TracerProjectileData(ScoutChaingunBullet)
{
   doDynamicClientHits = true;

   directDamage        = 0.14;
   explosion           = ScoutChaingunExplosion;
   splash              = ChaingunSplash;

   directDamageType    = $DamageType::Energy;
   kickBackStrength    = 350.0;

   sound = ShrikeBlasterProjectileSound;

   dryVelocity       = 325.0;
   wetVelocity       = 180.0;
   velInheritFactor  = 1.0;
   fizzleTimeMS      = 500;
   lifetimeMS        = 800;
   explodeOnDeath    = false;
   reflectOnWaterImpactAngle = 0.0;
   explodeOnWaterImpact      = false;
   deflectionOnWaterImpact   = 0.0;
   fizzleUnderwaterMS        = 1600;

   tracerLength    = 45.0;
   tracerAlpha     = false;
   tracerMinPixels = 6;
   tracerColor     = "1.0 1.0 1.0 1.0";
   tracerTex[0]  	 = "special/shrikeBolt";
   tracerTex[1]  	 = "special/shrikeBoltCross";
   tracerWidth     = 0.55;

   crossSize       = 0.99;
   crossViewAng    = 0.990;
   renderCross     = true;

};

datablock ShapeBaseImageData(ScoutChaingunPairImage)
{
   className = WeaponImage;
   shapeFile = "weapon_energy_vehicle.dts";
   item      = Chaingun;
   ammo   = ChaingunAmmo;
   projectile = ScoutChaingunBullet;
   projectileType = TracerProjectile;
   mountPoint = 10;
   offset = ".73 0 0";
   
   usesEnergy = true;
   useMountEnergy = true;
   // DAVEG -- balancing numbers below!
   minEnergy = 5;
   fireEnergy = 5;
   fireTimeout = 125;

   //--------------------------------------
   stateName[0]             = "Activate";
   stateSequence[0]         = "Activate";
   stateAllowImageChange[0] = false;
   stateTimeoutValue[0]        = 0.05;
   stateTransitionOnTimeout[0] = "Ready";
   stateTransitionOnNoAmmo[0]  = "NoAmmo";
   //--------------------------------------
   stateName[1]       = "Ready";
   stateSpinThread[1] = Stop;
   stateTransitionOnTriggerDown[1] = "Spinup";
   stateTransitionOnNoAmmo[1]      = "NoAmmo";
   //--------------------------------------
   stateName[2]               = "NoAmmo";
   stateTransitionOnAmmo[2]   = "Ready";
   stateSpinThread[2]         = Stop;
   stateTransitionOnTriggerDown[2] = "DryFire";
   //--------------------------------------
   stateName[3]         = "Spinup";
   stateSpinThread[3]   = SpinUp;
   stateTimeoutValue[3]          = 0.01;
   stateWaitForTimeout[3]        = false;
   stateTransitionOnTimeout[3]   = "Fire";
   stateTransitionOnTriggerUp[3] = "Spindown";
   //--------------------------------------
   stateName[4]             = "Fire";
   stateSpinThread[4]       = FullSpeed;
   stateRecoil[4]           = LightRecoil;
   stateAllowImageChange[4] = false;
   stateScript[4]           = "onFire";
   stateFire[4]             = true;
   stateSound[4]            = ShrikeBlasterFire;
   // IMPORTANT! The stateTimeoutValue below has been replaced by fireTimeOut
   // above.
   stateTimeoutValue[4]          = 0.35;
   stateTransitionOnTimeout[4]   = "checkState";
   //--------------------------------------
   stateName[5]       = "Spindown";
   stateSpinThread[5] = SpinDown;
   stateTimeoutValue[5]            = 0.01;
   stateWaitForTimeout[5]          = false;
   stateTransitionOnTimeout[5]     = "Ready";
   stateTransitionOnTriggerDown[5] = "Spinup";
   //--------------------------------------
   stateName[6]       = "EmptySpindown";
   stateSpinThread[6] = SpinDown;
   stateTransitionOnAmmo[6]   = "Ready";
   stateTimeoutValue[6]        = 0.01;
   stateTransitionOnTimeout[6] = "NoAmmo";
   //--------------------------------------
   stateName[7]       = "DryFire";
   stateSound[7]      = ShrikeBlasterDryFireSound;
   stateTransitionOnTriggerUp[7] = "NoAmmo";
   stateTimeoutValue[7]        = 0.25;
   stateTransitionOnTimeout[7] = "NoAmmo";

   stateName[8] = "checkState";
   stateTransitionOnTriggerUp[8] = "Spindown";
   stateTransitionOnNoAmmo[8]    = "EmptySpindown";
   stateTimeoutValue[8]          = 0.01;
   stateTransitionOnTimeout[8]   = "ready";
};

datablock ShapeBaseImageData(ScoutChaingunImage) : ScoutChaingunPairImage
{
   offset = "-.73 0 0";
   stateScript[3]           = "onTriggerDown";
   stateScript[5]           = "onTriggerUp";
   stateScript[6]           = "onTriggerUp";
};

datablock ShapeBaseImageData(ScoutChaingunParam)
{
   mountPoint = 2;
   shapeFile = "turret_muzzlepoint.dts";

   projectile = ScoutChaingunBullet;
   projectileType = TracerProjectile;
}; 

//-------------------------------------
// BOMBER TARGETING CHARACTERISTICS
//-------------------------------------
datablock ShapeBaseImageData(ShrikeTargetingImage)
{
   className = WeaponImage;

   shapeFile = "weapon_targeting.dts";
   offset = "0 2.4 0.75";
   mountPoint = 10;

   projectile = BomberTargeter;
   projectileType = TargetProjectile;
   deleteLastProjectile = true;

   usesEnergy = true;
   minEnergy = 3;

   stateName[0]                = "Activate";
   stateSequence[0]            = "Activate";
   stateSound[0]               = BomberTargetingSwitchSound;
   stateTimeoutValue[0]        = 0.5;
   stateTransitionOnTimeout[0] = "ActivateReady";

   stateName[1]               = "ActivateReady";
   stateTransitionOnAmmo[1]   = "Ready";
   stateTransitionOnNoAmmo[1] = "NoAmmo";

   stateName[2]                    = "Ready";
   stateTransitionOnNoAmmo[2]      = "NoAmmo";
   stateTransitionOnTriggerDown[2] = "Fire";

   stateName[3]                  = "Fire";
   stateEnergyDrain[3]           = 3;
   stateFire[3]                  = true;
   stateAllowImageChange[3]      = false;
   stateScript[3]                = "onFire";
   stateTransitionOnTriggerUp[3] = "Deconstruction";
   stateTransitionOnNoAmmo[3]    = "Deconstruction";
   stateSound[3] = BomberTargetingPaintSound;

   stateName[4]                = "NoAmmo";
   stateTransitionOnAmmo[4]    = "Ready";

   stateName[5]                = "Deconstruction";
   stateTransitionOnTimeout[5] = "ActivateReady";
   stateTimeoutValue[5]        = 0.05;
   stateScript[5]              = "deconstruct";
};

function ShrikeTargetingImage::onFire(%Data, %Vehicle, %Slot)
{
   if (%Vehicle.beacon !$= "")
   {
      %Vehicle.beacon.delete();
      %Vehicle.beacon = "";
   }

   %Projectile = Parent::onFire(%Data, %Vehicle, %Slot);
   %Projectile.setTarget(%Vehicle.team);
}

function ShrikeTargetingImage::deconstruct(%Data, %Vehicle, %Slot)
{
   %Position = %Vehicle.lastProjectile.getTargetPoint();

   if (%Vehicle.beacon !$= "")
      %Vehicle.beacon.delete();

   %Vehicle.beacon = new BeaconObject()
   {
      dataBlock = "BomberBeacon";
      beaconType = "vehicle";
      position = %Position;
   };

   %Vehicle.beacon.playThread($AmbientThread, "ambient");
   %Vehicle.beacon.team = %Vehicle.team;
   %Vehicle.beacon.sourceObject = %Vehicle;

   // give it a team target
   %Vehicle.beacon.setTarget(%Vehicle.team);                  
   BeaconGroup.add(%Vehicle.beacon);
   
   Parent::deconstruct(%Data, %Object, %Slot);
}

function ScoutFlyer::playerDismounted(%data, %Vehicle, %player)
{
   %Vehicle.fireWeapon = false;
   %Vehicle.setImageTrigger(2, false);
   %Vehicle.setImageTrigger(3, false);
   %Vehicle.setImageTrigger(4, false);
   if (%Vehicle.getImageTrigger(5) == true)
   {
      %Vehicle.setImageTrigger(5, false);
      ShapeBaseImageData::deconstruct(%Vehicle.getMountedImage(5), %Vehicle);
   }

   // If there is a marked location, delete it
   if (%Vehicle.beacon !$= "")
   {
      %Vehicle.beacon.delete();
      %Vehicle.beacon = "";
   }   

   setTargetSensorGroup(%Vehicle.getTarget(), %Vehicle.team);
}


// The shrike now has a single missile launcher under it's nose
function ScoutFlyer::onAdd(%this, %obj)
{
   Parent::onAdd(%this, %obj);

   %obj.mountImage(ScoutChaingunParam, 1);

   %obj.mountImage(ScoutChaingunImage, 2);
   %obj.mountImage(ScoutChaingunPairImage, 3);

   %obj.mountImage(ScoutMissileImage, 4);

   %obj.mountImage(ShrikeTargetingImage, 5);

   %obj.nextWeaponFire = 2;
   %obj.schedule(5500, "playThread", $ActivateThread, "activate");
   %obj.selectedWeapon = 1;
}
