// ------------------------------------------------------------------
// Auto-Rocket Pack
// This pack is used only by heavy armors and makes them more effective
// against vehicles and jetting players.  This is a special pack that
// is used in conjunction with the Missile Launcher to fire a less
// powerful but more accurate and harder to avoid missile.  It stores
// 6 Mini-Missiles and is very effective.

datablock SeekerProjectileData(AutoRocketMissile)
{
   casingShapeName        = "weapon_missile_casement.dts";
   projectileShapeName    = "weapon_missile_projectile.dts";

   directDamage           = 0.18;
   directDamageType       = $DamageType::HighExplosion;
   hasDamageRadius        = true;
   indirectDamage         = 0.74;
   damageRadius           = 6.5;
   directDamageType       = $DamageType::HighExplosion;
   kickBackStrength       = 2250;

   flareDistance          = 120;
   flareAngle             = 12;
   minSeekHeat            = 0.5;

   explosion              = "MissileExplosion";
   velInheritFactor       = 0;

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

   lifetimeMS             = 9000;
   muzzleVelocity         = 20.0;
   turningSpeed           = 90.0;
   maxVelocity            = 375.0;
   acceleration           = 65.0;
   
   proximityRadius        = 3;

   terrainAvoidanceSpeed  = 280;
   terrainScanAhead       = 45;
   terrainHeightFail      = 16;
   terrainAvoidanceRadius = 160;

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

datablock ItemData(AutoRocketPack)
{
   className = Pack;
   catagory = "Packs";

   shapeFile = "weapon_Mortar.dts";

   image = AutoRocketPackImage;

   mass = 2.5;

   elasticity = 0.2;
   friction = 0.6;

   pickupRadius = 2;
   pickUpName = "an Auto-Rocket Pack";

   computeCRC = true;
   emap = true;
};

datablock ItemData(AutoRocketExtra)
{
   className = Pack;
   catagory = "Packs";

   shapeFile = "turret_belly_base.dts";

   image = AutoRocketPackImage;

   mass = 2.5;

   elasticity = 0.2;
   friction = 0.6;

   pickupRadius = 0;
   pickUpName = "an Auto-Rocket Pack";

   computeCRC = true;
   emap = true;
};

function AutoRocketPack::onAdd(%Data, %Pack)
{
   %Item = new Item()
   {
      datablock = AutoRocketExtra;
   };
   MissionCleanUp.Add(%Item);

   %Pack.Slave = %Item;

   FollowObject(%Item, %Pack);
}

function AutoRocketPack::onRemove(%Data, %Pack)
{
   %Pack.slave.delete();
}

function AutoRocketPack::onPickup(%this, %Pack, %Player, %Amount)
{
   if (%Pack.sensors !$= "")
   {
      // Get the ammo from the pack
      %Player.inv[AutoRocketAmmo] += %pack.sensors;
      if (%Player.inv[AutoRocketAmmo] > %Player.getDataBlock().max[AutoRocketAmmo])
         %Player.inv[AutoRocketAmmo] = %Player.getDataBlock().max[AutoRocketAmmo];

      %Player.client.updateSensorPackText(%PLayer.inv[AutoRocketAmmo]);
   }
}

function AutoRocketPack::onThrow(%this,%pack,%player)
{
   %Player.throwSensorPack = true;

   %Pack.sensors = %Player.inv[AutoRocketAmmo];
   %Player.inv[AutoRocketAmmo] = 0;
   %Player.client.updateSensorPackText(%Player.inv[AutoRocketAmmo]);

   // do the normal ItemData::onThrow stuff -- sound and schedule deletion
   serverPlay3D(ItemThrowSound, %Player.getTransform());
   %Pack.schedulePop();
}

datablock ShapeBaseImageData(AutoRocketExtra1Image)
{
   shapeFile = "weapon_Mortar.dts";
   mass = 0;

   mountPoint = 1;
   offset = "-0.42 0.1 0.3";
   rotation = "0.74 -1.402 -1.402 270";
};

datablock ShapeBaseImageData(AutoRocketExtra2Image)
{
   shapeFile = "weapon_Mortar.dts";
   mass = 0;

   mountPoint = 0;
   offset = "-0.95 -0.55 0.85";
   rotation = "0 -1 0 90";
};

datablock ShapeBaseImageData(AutoRocketExtra3Image)
{
   shapeFile = "weapon_Mortar.dts";
   mass = 0;

   mountPoint = 0;
   offset = "-0.9 -0.85 0.25";
   rotation = "0 -1 0 90";
};

datablock ShapeBaseImageData(AutoRocketPackImage)
{
   shapeFile = "turret_belly_base.dts";

   mass = 15;
   item = AutoRocketPack;

   mountPoint = 1;

   offset = "0 0.1 0.03";
   rotation = "1 0 0 90";

   stateName[0] = "Idle";
   stateTransitionOnTriggerDown[0] = "Activate";
   
   stateName[1] = "Activate";
   stateScript[1] = "onActivate";
   stateSequence[1] = "fire";
   stateTransitionOnTriggerUp[1] = "Deactivate";

   stateName[2] = "Deactivate";
   stateScript[2] = "onDeactivate";
   stateTransitionOnTimeout[2] = "Idle";
};

function AutoRocketPackImage::onMount(%data, %Player, %Slot)
{
   %Player.mountImage("AutoRocketExtra1Image", 6);
}

function AutoRocketPackImage::onUnmount(%data, %Player, %Slot)
{
   %Player.setImageTrigger(%Slot, false);

   %Player.unMountImage(6);
}

function AutoRocketPackImage::onActivate(%data, %Player, %Slot)
{
   if (%Player.inv[AutoRocketAmmo] <= 0)
   {
      %Message = "Auto-Rocket Pack is out of ammunition.";
      messageClient(%Player.client, '', %Message);

      return;
   }

   %Player.AutoRocketOn = true;

   %Message = "Auto-Rocket Pack activated, waiting for you to acquire a missile lock.";
   messageClient(%Player.client, '', %Message);

   // If the Missile Launcher is in the hand already, start the searching
   if (%Player.getMountedImage($WeaponSlot).getName() $= "MissileLauncherImage")
   {
      %Player.mountImage("AutoRocketExtra3Image", 6);

      if (%Player.AutoRocketLockCheck $= "")
         %Player.AutoRocketLockCheck();
   } else {
      %Player.mountImage("AutoRocketExtra2Image", 6);
   }

   %Player.playAudio(0, MissileSwitchSound);

   return;
}

function AutoRocketPackImage::onDeactivate(%data, %Player, %Slot)
{
   %Player.AutoRocketOn = "";

   %Message = "Auto-Rocket Pack De-activated.";
   messageClient(%Player.client, '', %Message);

   if (%Player.AutoRocketLockCheck !$= "")
   {
      cancel(%Player.AutoRocketLockCheck);
      %Player.AutoRocketLockCheck = "";
   }

   %Player.mountImage("AutoRocketExtra1Image", 6);
   %Player.setImageTrigger(%Slot, false);

   %Player.playAudio(0, MissileSwitchSound);

   return;
}

function Player::AutoRocketLockCheck(%Player, %Forced)
{
   if (%Player.AutoRocketOn $= "")
      return;

   // If the Pack has no ammo, then we turn it off.
   if (%Player.inv[AutoRocketAmmo] <= 0)
   {
      %Message = "Auto-Rocket Pack is out of ammunition, deactivating.";
      messageClient(%Player.client, '', %Message);

      AutoRocketPackImage::onDeactivate(%data, %Player, %Slot);

      return;
   }

   if (%Player.isLocked() == true || %Forced == true)
   {
      %Target = %Player.getLockedTarget();

      // Raise the position to the cannon's level
      %Position = %Player.getMuzzlePoint($WeaponSlot);

      // Move the position to the side
      %FacingVector = %this.getMuzzleVector($WeaponSlot);
      %FacingVector2D = VectorNormalize(getWords(%FacingVector, 0, 1) @ " 0");

      %DisplacementVector = VectorNormalize(VectorCross(%FacingVector2D, "0 0 1"));

      // Define that point as the basis of all the Firing
      %FiringPosition = VectorAdd(%Position, VectorScale(%DisplacementVector, 0.85));

      %Projectile = new SeekerProjectile()
      {
         dataBlock        = AutoRocketMissile;
         initialDirection = %Player.getMuzzleVector($WeaponSlot);
         initialPosition  = %FiringPosition;
         sourceObject     = %Player;
         sourceSlot       = $AuxiliarySlot;
      };
      MissileSet.add(%Projectile);

      %Player.lastProjectile = %Projectile;

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

         // Chance of it not seeking, but you need the WCS
         %Random = getRandom();
         if (%Random > 0.10 && %Player.Special $= "WCS")
            %Projectile.SeekHeat = %Projectile.getDataBlock().SeekHeat(%Projectile, %Player.team, %Data.minSeekHeat, %Player.getMuzzleVector($WeaponSlot), 40, 32);
      }

      %Player.AutoRocketLockCheck = %Player.schedule(2250, AutoRocketLockCheck);

      %Player.inv[AutoRocketAmmo]--;
   } else {
      %Player.AutoRocketLockCheck = %Player.schedule(750, AutoRocketLockCheck);
   }
}