
//----------------------------------------------------------------------------
// This controls the EMPing of a player.  It sets one variable at the player
// level, the duration of it's effects.  Time should passed in intervals of 
// 2 seconds, that is how it cycles.  Damage is the percent of energy remaining
// after being EMPed initially and the recharge it slowed appropriately.  Usually
// damage is 0 so that it will take all energy and stop the recharge all together.

// Usage: PlayerID.EMP([Duration], [Percentage of Energy Remaining/Recharging]);

function Player::EMP(%this, %Duration, %Damage)
{
   // Make sure the user is not invincible (Initial Spawn) or shielded.
   if (%this.invincible == true || %this.CheckForShields() == true)
       return(0);

   // If the player is an engineer, don't EMP them
   if (%this.getArmorSize() $= "Engineer")
      return;

   // Take power from the user
   %Energy = %this.getEnergyLevel();
   %this.setEnergyLevel(%Energy * %Damage);

   // If the player has a backpack, see if they loose it.
   %Chance = getRandom();
   if (%Chance > %Damage)
      %this.LoosePack();

   if (%this.EMPTime > 0)
   {
      // If already EMPed, then increase the time a bit
      %this.EMPTime += (%Duration * 0.65);
      messageClient(%this.client, 'You have been hit with another EMP.');

   } else {
      %this.EMPTime = %Duration;
      %this.OldRechargeRate = %this.getRechargeRate();

      %this.setRechargeRate(%this.OldRechargeRate * %Damage);

      // Schedule an EMP check
      messageClient(%this.client, '', 'You have been hit with an EMP.');
      %this.EMPCheck();
   }
}

// This function loops through every 2 seconds and does the sound effect and visualization.
function Player::EMPCheck(%this)
{
   %this.EMPTime -= 2;

   // Make the visual and audible effects.
   if (%this.EMPTime > 0)
   {
      %this.EMPSpark();
      %this.schedule(1000, EMPSpark);
      ShockObject(%this);
      schedule(1000, 0, ShockObject, %this);

      // Schedule another loop
      %this.EMPCheck = %this.schedule(2000, EMPCheck);

   } else {
 
      %this.PlayerSmokeEffect();
      %this.schedule(1000, PlayerSmokeEffect);

      %this.EMPCheck = "";

      %this.setRechargeRate(%this.OldRechargeRate);
      messageClient(%this.client, '', 'The effects of the EMP wear off.');
   }
}

function StaticShapeData::EMP(%this, %Duration, %Damage)
{
   echo("EMPed Static Object");

   echo("Duration: " @ %Duration);
   echo("Strength: " @ %Damage);

   // Make sure the user is not invincible (Initial Spawn) or shielded.
   if (%this.invincible == true || %this.CheckForShields() == true)
       return(0);

   // Take power from the object
   %Energy = %this.getEnergyLevel();
   %this.setEnergyLevel(%Energy * %Damage);

   if (%this.EMPTime > 0)
   {
      // If already EMPed, then increase the time a bit
      %this.EMPTime += (%Duration * 0.65);

   } else {
      %this.EMPTime = %Duration;
      %this.OldRechargeRate = %this.getRechargeRate();

      %this.setRechargeRate(%this.OldRechargeRate * %Damage);

      // Schedule an EMP check
      %this.EMPCheck();
   }
}

// This function loops through every 2 seconds and does the sound effect and visualization.
function StaticShapeData::EMPCheck(%this)
{
   %this.EMPTime -= 2;

   // Make the visual and audible effects.
   if (%this.EMPTime > 0)
   {
      ShockObject(%this);
      schedule(1000, 0, ShockObject, %this);

      // Schedule another loop
      %this.EMPCheck = %this.schedule(2000, EMPCheck);

   } else {
 
      %this.EMPCheck = "";

      %this.setRechargeRate(%this.OldRechargeRate);
   }
}

function ShapeBaseData::EMP(%this, %Duration, %Damage)
{
   echo("EMPed ShapeBase Object");

   echo("Duration: " @ %Duration);
   echo("Strength: " @ %Damage);

   // Make sure the user is not invincible (Initial Spawn) or shielded.
   if (%this.invincible == true || %this.getDatablock().CheckForShields(%this) == true)
       return(0);

   // Take power from the object
   %Energy = %this.getEnergyLevel();
   %this.setEnergyLevel(%Energy * %Damage);

   if (%this.EMPTime > 0)
   {
      // If already EMPed, then increase the time a bit
      %this.EMPTime += (%Duration * 0.65);

   } else {
      %this.EMPTime = %Duration;
      %this.OldRechargeRate = %this.getRechargeRate();

      %this.setRechargeRate(%this.OldRechargeRate * %Damage);

      // Schedule an EMP check
      %this.EMPCheck();
   }
}

// This function loops through every 2 seconds and does the sound effect and visualization.
function ShapeBaseData::EMPCheck(%this)
{
   %this.EMPTime -= 2;

   // Make the visual and audible effects.
   if (%this.EMPTime > 0)
   {
      ShockObject(%this);
      schedule(1000, 0, ShockObject, %this);

      // Schedule another loop
      %this.EMPCheck = %this.schedule(2000, EMPCheck);

   } else {
 
      %this.EMPCheck = "";

      %this.setRechargeRate(%this.OldRechargeRate);
   }
}

function EMPingCheck(%Position, %Radius, %DamageDuration, %DamageStrength, %Owner)
{
   // check the damageRadius for objects we can damage/set on fire
   InitContainerRadiusSearch(%Position, %Radius, $TypeMasks::PlayerObjectType | $TypeMasks::StaticObjectType |
                                                 $TypeMasks::VehicleObjectType | $TypeMasks::StationObjectType);

   while ((%Object = containerSearchNext()) != 0)
   {
      %DistanceFromBlast = containerSearchCurrRadDamageDist();

      // If further from the blast than specified (extra error handling)
      if (%DistanceFromBlast > %Radius)
         continue;

      // Engineer armors are shieled from the effects of EMP
      if (%Object.className $= "Armor" && %Object.getArmorSize() $= "Engineer")
         continue;

      // If team damage is off, don't EMP team mate
      if ($teamDamage == false && %Object.team == %Owner.team && %Object != %Owner)
         continue;

      // Determine how much of the object is exposed to the effects
      %PercentExposed = calcExplosionCoverage(%Position, %Object,
                                         ($TypeMasks::InteriorObjectType |
                                          $TypeMasks::TerrainObjectType |
                                          $TypeMasks::ForceFieldObjectType));

      // If the player, item, deployable, whatever is covered then resume the loop.
      if (%PercentExposed == 0)
         continue;

      %Object.lastDamagedBy = %Owner;
      %Object.lastDamagedByTeam = %Owner.team;

      %DamagePercentage = (1.0 - ((%DistanceFromBlast * %DistanceFromBlast) / (%Radius * %Radius)));
      %DamagePercentage *= %PercentExposed;

      // If the player is shielded, then they can not be EMPed
      if (%Object.getDataBlock().CheckforShields(%Object) != true)
      {
         // Notify the one affected and the one who did it about the team damage
         if (%Object.team == %Owner.team && %Object != %Owner)
         {
            if (%Object.className $= "Armor")
            {
               %Name1 = getTaggedString(%Owner.name);
               %Name2 = getTaggedString(%Object.name);

               %Message1 = "Teammate " @ %Name1 @ " has EMP/'ed you.";
               %Message2 = "You have EMP/'ed Teammate " @ %Name2 @ ".";

               messageClient(%Object.client, "", %Message1);
               messageClient(%Owner.client, "", %Message2);
            } else {
               %ObjectName = %Object.getName();
               if (%ObjectName $= "")
                  %ObjectName = %Object.getDataBlock().name;

               %Message = "You have EMP/'ed your team/'s " @ %ObjectName @ ".";
//               messageClient(%Owner.client, "", %Message);
            }
         }

         // Put up a dummy sign if you got yourself
         if (%Object == %Owner)
            messageClient(%Owner.client, "", "You have EMP/'ed yourself.");

         %EMPStrength = %DamageStrength * %DamagePercentage;
         %EMPDuration = %DamageDuration * %DamagePercentage;

         %Object.EMP(%EMPDuration, %EMPStrength);

         ShockObject(%Object);
      }
   }
}