//--------------------------------------
// Missile launcher
//--------------------------------------


//--------------------------------------------------------------------------
// Debris
//--------------------------------------
datablock DebrisData( FlechetteDebris )
{
   shapeName = "weapon_missile_fleschette.dts";

   lifetime = 5.0;

   minSpinSpeed = -320.0;
   maxSpinSpeed = 320.0;

   elasticity = 0.2;
   friction = 0.3;

   numBounces = 3;

   gravModifier = 0.40;

   staticOnMaxBounce = true;
};             

//--------------------------------------------------------------------------
// Projectile
//--------------------------------------
datablock SeekerProjectileData(ShoulderMissile)
{
   casingShapeName     = "weapon_missile_casement.dts";
   projectileShapeName = "weapon_missile_projectile.dts";

   hasDamageRadius     = true;
   indirectDamage      = 1.3;
   damageRadius        = 4.5;
   radiusDamageType    = $DamageType::HighExplosion;
   kickBackStrength    = 2000;

   explosion           = "MissileExplosion";
   splash              = MissileSplash;
   velInheritFactor    = 1.0;    // to compensate for slow starting velocity, this value
                                 // is cranked up to full so the missile doesn't start
                                 // out behind the player when the player is moving
                                 // very quickly - bramage

   baseEmitter         = MissileSmokeEmitter;
   delayEmitter        = MissileFireEmitter;
   puffEmitter         = MissilePuffEmitter;
   bubbleEmitter       = GrenadeBubbleEmitter;
   bubbleEmitTime      = 1.0;

   exhaustEmitter      = MissileLauncherExhaustEmitter;
   exhaustTimeMs       = 300;
   exhaustNodeName     = "muzzlePoint1";

   lifetimeMS          = 8500;
   muzzleVelocity      = 10.0;
   maxVelocity         = 120.0;
   turningSpeed        = 90.0;
   acceleration        = 200.0;

   proximityRadius     = 3;

   terrainAvoidanceSpeed         = 180;
   terrainScanAhead              = 25;
   terrainHeightFail             = 12;
   terrainAvoidanceRadius        = 100;  
   
   flareDistance = 200;
   flareAngle    = 30;

   sound = MissileProjectileSound;

   rearDamageFactor    = 1.2;

   hasLight    = true;
   lightRadius = 5.0;
   lightColor  = "0.2 0.05 0";

   useFlechette = true;
   flechetteDelayMs = 550;
   casingDeb = FlechetteDebris;

   explodeOnWaterImpact = false;
};

//--------------------------------------------------------------------------
// Ammo
//--------------------------------------

datablock ItemData(MissileLauncherAmmo)
{
   className = Ammo;
   catagory = "Ammo";
   shapeFile = "ammo_missile.dts";

   mass = 1;
   trueMass = 0.01;

   elasticity = 0.2;
   friction = 0.6;
   pickupRadius = 2;
   pickUpName = "some missiles";

   computeCRC = true;

};

//--------------------------------------------------------------------------
// Weapon
//--------------------------------------
datablock ItemData(MissileLauncher)
{
   className = Weapon;
   catagory = "Spawn Items";
   shapeFile = "weapon_missile.dts";
   image = MissileLauncherImage;

   mass = 1;
   trueMass = 6;

   elasticity = 0.2;
   friction = 0.6;
   pickupRadius = 2;
   pickUpName = "a missile launcher";

   computeCRC = true;
   emap = true;
};

datablock ShapeBaseImageData(MissileLauncherImage)
{
   className = WeaponImage;
   shapeFile = "weapon_missile.dts";

   item = MissileLauncher;
   ammo = MissileLauncherAmmo;

   offset = "0 0 0";
   armThread = lookms;
   emap = true;

   ProjectileType = SeekerProjectile;
   Projectile = ShoulderMissile;

   FailSound = MissileDryFireSound;
   FireSound = MissileFireSound;

   isSeeker     = true;
   seekRadius   = 400;
   maxSeekAngle = 8;
   seekTime     = 0.7;
   minSeekHeat  = 0.5;  // the heat that must be present on a target to lock it.

   // only target objects outside this range
   minTargetingDistance             = 40;
   
   stateName[0]                     = "Activate";
   stateTransitionOnTimeout[0]      = "ActivateReady";
   stateTimeoutValue[0]             = 0.5;
   stateSequence[0]                 = "Activate";
   stateSound[0]                    = MissileSwitchSound;

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

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

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

   stateName[4]                     = "Reload";
   stateTransitionOnNoAmmo[4]       = "NoAmmo";
   stateTransitionOnTimeout[4]      = "Ready";
   stateTimeoutValue[4]             = 2.5;
   stateAllowImageChange[4]         = true;
   stateSequence[4]                 = "Reload";
   stateSound[4]                    = MissileReloadSound;

   stateName[5]                     = "NoAmmo";
   stateTransitionOnAmmo[5]         = "Reload";
   stateSequence[5]                 = "NoAmmo";
   stateTransitionOnTriggerDown[5]  = "DryFire";

   stateName[6]                     = "DryFire";
   stateTimeoutValue[6]             = 1.0;
   stateTransitionOnTimeout[6]      = "ActivateReady";
};

function MissileLauncherImage::onFire(%data, %Player, %slot)
{
   if (%Player.PlayerNoFire == true)
      return;

   // If the player is cheating using animations to bypass the state waits, blow them up
   if (%Player.NoMissileFire == true)
   {
      %Player.Explode();
      return;
   }
   %Player.NoMissileFire = true;
   %Player.schedule(2250, AllowMissileFire);

   %MuzzlePosition = %Player.getMuzzlePoint($WeaponSlot);
   %MuzzleVector = %Player.getMuzzleVector($WeaponSlot);

   if (%Player.isLocked() == false && %Player.InWater != true)
   {
      %EndPosition = VectorAdd(%MuzzlePosition, VectorScale(%MuzzleVector, %data.minTargetingDistance));
      %Result = ContainerRayCast(%MuzzlePosition, %EndPosition, $EverythingMask, %Player);

      if (%Result !$= "0")
      {
         %FailSound = %Data.FailSound;
         serverPlay3D(%FailSound, %Object.getMuzzlePoint(%slot));
         return;
      }
   }

   %FailSound = %Data.FireSound;
   serverPlay3D(%FireSound, %MuzzlePosition);

   %Projectile = Parent::onFire(%data, %Player, %slot);
   MissileSet.add(%Projectile);

   %Projectile.sourceObject = %Player;

   %TargetLock = %Player.getLockedTarget();
   if (%TargetLock)
      %Projectile.setObjectTarget(%TargetLock);
   else if (%Player.isLocked())
      %Projectile.setPositionTarget(%Player.getLockedPosition());
   else if (%Player.InWater == true)
      %Projectile.setTarget(0);
   else
      %Projectile.setNoTarget();

   if (%Player.AutoRocketOn == true && %Player.Special $= "WCS")
      %Player.AutoRocketLockCheck(true);
}

function Player::AllowMissileFire(%Player)
{
   %Player.NoMissileFire = "";
}