
// ---------------------------------------------------------------------------------------
// Held Explosive in Inventory
// ---------------------------------------------------------------------------------------

datablock ItemData(PlasticExplosive)
{
   className = HandInventory;
   catagory = "Handheld";
   shapeFile = "deploy_sensor_motion.dts";
   mass = 1;
   trueMass = 0.1;

   elasticity = 0.2;
   friction = 0.6;
   pickupRadius = 1;
   thrownItem = PlasticExplosiveThrown;
   pickUpName = "a shaped demolition charge";
};

// ------------------------------------------------------------------------
// Thrown Exposive
// ------------------------------------------------------------------------

datablock ItemData(PlasticExplosiveThrown)
{
   className = Weapon;
   shapeFile = "deploy_sensor_motion.dts";

   indirectDamage = 2.0;
   damageRadius = 5.0;
   radiusDamageType = $DamageType::HighExplosion;
   kickBackStrength = 1200;

   mass = 0.6;
   elasticity = 0.0;
   friction = 1.0;
   pickupRadius = 1;

   maxDamage = 0.65;

   explosion           = "GrenadeExplosion";
   underwaterExplosion = "UnderwaterGrenadeExplosion";

   sticky = true;

   rearDamageFactor    = 1.2;

   deployAmbientThread = false;

   lightType = "PulsingLight";
   lightColor = "1.0 0.8 0.2 1.0";
   lightTime = "1000";
   lightRadius = "1.75";
};

// Function that starts the time on the clock
function PlasticExplosiveThrown::onThrow(%this, %Grenade)
{
   PlasticCountDown(%Grenade, 15);
}

// Function to handle touching of a thrown explosive
function PlasticExplosiveThrown::onCollision(%data, %Charge, %Player)
{
   // If not an armor, return
   if (%Player.getDataBlock().className !$= "Armor")
      return;

   // If the thrower or his team touchs it, ignore the pickup
   if (%Charge.sourceObject.client == %Player.client || %Charge.team == %Player.team)
      return;

   %DisarmTime = (getRandom() * 6) + 6;

   // If the player already has 2 explosives, disallow any more
   if (%Player.PlasticCount >= 2)
   {
      messageClient(%Player.client, 'MsgCantSitHere', 'You can only hold 2 explosive charges at one time. ~wfx/misc/misc.error.wav');
      return;
   }

   %PlasticTime = %Charge.PlasticTime;
   %PlasticOwner = %Charge.sourceObject;
   %Player.PlasticType = %Charge.getDataBlock();
   %Charge.setDamageState(Destroyed);
   %Charge.delete();

   if (%Player.PlasticCount >= 1)
   {
      // If the new charge will detonate before the existing one, stop work on that one and start on the new one.
      if (%Player.Plastic1.DetonateTime > %PlasticTime)
      {
         messageClient(%Player.client, 'MsgItemPickup', 'You picked up another ticking charge, but since it is more urgent you begin work on it!');
         %Player.Plastic2DisarmTime = %Player.Plastic1DisarmTime;
         %Player.Plastic2DetonateTime = %Player.Plastic1DetonateTime;
         %Player.Plastic2Owner = %Player.Plastic1Owner;
         %Player.Plastic1DisarmTime = %DisarmTime;
         %Player.Plastic1DetonateTime = %PlasticTime;
         %Player.Plastic1Owner = %PlasticOwner;
      } else {     
         messageClient(%Player.client, 'MsgItemPickup', 'You picked up another ticking charge and will attempt to disarm it once you have finished with the first one!');
         %Player.Plastic2DisarmTime = %DisarmTime;
         %Player.Plastic2DetonateTime = %PlasticTime;
         %Player.Plastic2Owner = %PlasticOwner;
      }
      %Player.PlasticCount = 2;
   } else {
      messageClient(%Player.client, 'MsgItemPickup', 'You picked up a ticking charge and are attempting to disarm it.');
      %Player.Plastic1DisarmTime = %DisarmTime;
      %Player.Plastic1DetonateTime = %PlasticTime;
      %Player.Plastic1Owner = %PlasticOwner;
      %Player.PlasticCount = 1;
      PlasticTick(%Player);
   }
   Cancel(%Grenade.CountDown);
}

// This function loops through every second to determine which wins
function PlasticTick(%Player)
{
   // The plastic explosive ticks and the player works on it...  which will win?
   %Player.Plastic1DetonateTime--;
   %Player.Plastic1DisarmTime--;

   // An Engineer works 3 times faster than others
   %ArmorName = getSubStr(%Player.getDataBlock().getName(), 0, 8);
   if (%ArmorName $= "Engineer")
   {
      %Player.Plastic1DisarmTime -= 2;
   }

   // The plastic explosive ticks even if the player is not working on it
   if (%Player.PlasticCount > 1)
   {
      %Player.Plastic2DetonateTime--;
   }

   // If the disarm has happened, check that.
   if (%Player.Plastic1DisarmTime <= 0)
   {
      if (%Player.PlasticCount > 1)
      {
         // If there is another explosive, then we move it into our hands to work on it.
         messageClient(%Player.client, 'MsgCantSitHere', 'You disarm the first charge, now working on the second.');
         %Player.Plastic1DetonateTime = %Player.Plastic2DetonateTime;
         %Player.Plastic1DisarmTime = %Player.Plastic2DisarmTime;
         %Player.Plastic2DetonateTime = 0;
         %Player.Plastic2DisarmTime = 0;
         schedule(1000, 0, PlasticTick, %Player);
      } else {
         messageClient(%Player.client, 'MsgCantSitHere', 'You successfully disarm the explosive charge.');
         %Player.Plastic1DetonateTime = 1;
      }
      %Player.PlasticCount--;

      // Play the disarm sound
      %Player.playAudio(0, PlasticDisarm);
      return(0);
    }

   // The Player didn't make it...  oh well, nice paste though
   if (%Player.Plastic1DetonateTime <= 0)
   {
      %Player.playAudio(0, PlasticFinal);
      messageClient(%Player.client, 'MsgCantSitHere', 'OH SH!T !!!');
      schedule(1200, 0, PlasticBoom, %Player);
      return(0);
   }
   
   // Schedule another check in a second, if 2 seconds since beep them beep again
   schedule(1000, 0, PlasticTick, %Player);
   if (%Player.Plastic1DetonateTime % 2 < 1)
      %Player.playAudio(0, PlasticBeep);
}

// A player exploding from a carried explosive detonating.
function PlasticBoom(%Player)
{
   // Determine the Damage Level and Radius of the explosive
   %DataBlock = PlasticExplosiveThrown;
   %Damage = %DataBlock.indirectDamage;
   %Radius = %DataBlock.damageRadius;
   %Impulse = %DataBlock.kickBackStrength;
   %Type = %DataBlock.damageType;

   // If a second explosive is on the user, then increase the damage and radius some.
   if (%Player.PlasticCount > 1)
   {
      %Damage *= 1.65;
      %Radius *= 1.4;
      %Impulse *= 1.4;
   }

   // Determine the owner of that plastic explosive and where you were when it blows
   %Source = %Player.Plastic1Owner;
   %Transform = %Player.getTransform();
   %Position = posFromTransform(%Transform);

   %PositionXY = getWords(%Position, 0, 1);
   %PositionZ = getWord(%Position, 2);
   %Position = %PositionXY @ " " @ %PositionZ;

   // If in the water, the damage is spread out more   
   if (%Player.InWater == true)
   {
      %Radius *= 3;
      %Damage *= 0.7;
      %Impulse *= 3;
   }

   %Player.BoosterSmokeEffect();

   // The Player is nuked no matter how strong thier shields or where they are.
   RadiusExplosion(%Source, %Position, %Radius, %Damage, %Impulse, %Source, %Type);
}

// This function handles the countdown of the plastic explosive and makes the 
// beeping sound more and more frequent.  When it gets down under 1.5 second
// then it plays the final tone and schedules the explosion for 1.5 seconds.
 
// Usage ItemID.CountDown([Time til explosion]);

function PlasticCountDown(%Grenade, %Time)
{
   // Play the starting sound
   %Grenade.playAudio(0, PlasticInitial);

   // Start the countdown on time
   %NewIncrementalTime = %Time * 0.25;
   %Grenade.PlasticTime = %Time - %NewIncrementalTime;
   %Grenade.CountDown = schedule(%NewIncrementalTime * 1000, 0, PlasticCountDownCheck, %Grenade);
}
 
function PlasticCountDownCheck(%Grenade)
{
   // If the final loop, play last tone and explode on time   
   if (%Grenade.PlasticTime <= 1.5)
   {
      %Grenade.playAudio(0, PlasticFinal);
      %Grenade.CountDown = schedule(1200, 0, detonatePlasticExplosive, %Grenade);
      return(0);
   }

   // Make the checks between the counts more and more frequent.
   // Play the incremental beep
   %NewIncrementalTime = %Grenade.PlasticTime * 0.25;
   %Grenade.PlasticTime -= %NewIncrementalTime;

   %Grenade.playAudio(0, PlasticBeep);
   %Grenade.CountDown = schedule(%NewIncrementalTime * 1000, %Grenade, PlasticCountDownCheck, %Grenade);
}

function detonatePlasticExplosive(%Grenade)
{
   %Grenade.setDamageState(Destroyed);

   Cancel(%Grenade.CountDown);

   %Transform = %Grenade.getTransform();
   %Position = posFromTransform(%Transform);
   %Source = %Grenade.sourceObject;

   %DataBlock = %Grenade.getDataBlock();

   %Radius = %DataBlock.damageRadius;
   %Damage = %DataBlock.indirectDamage;
   %Impulse = %DataBlock.kickBackStrength;
   %Type = %DataBlock.radiusDamageType;

   // If in the water, the damage is spread out more   
   if (%Grenade.InWater == true)
   {
      %Radius *= 2;
      %Damage *= 0.5;
      %Impulse *= 2;
   }

   RadiusExplosion(%Grenade, %Position, %Radius, %Damage, %Impulse, %Source, %Type);

   %Grenade.schedule(100, "delete");
}