//Explosive Pack.. Wall-mountable explosives.


datablock SensorData(DeployExplosiveObj)
{
   detects = true;
   detectsUsingLOS = false;
   detectsActiveJammed = false;
   detectsPassiveJammed = false;
   detectsCloaked = true;
   detectionPings = true;
   detectMinVelocity = 2;
   detectRadius = 20;
};

datablock StaticShapeData(DeployedExplosive) : StaticShapeDamageProfile
{
   className = Weapon;
   shapeFile = "grenade.dts";
//   shapeFile = "stackable4l.dts";
   maxDamage = 0.8;
   destroyedLevel = 0.8;
   disabledLevel = 0.8;
   dynamicType = $TypeMasks::SensorObjectType;

   deployedObject = true;

   cmdCategory = "DSupport";
   cmdIcon = CMDSensorIcon;
   cmdMiniIconName = "commander/MiniIcons/com_deploymotionsensor";
   targetNameTag = 'Deployable';
   targetTypeTag = 'Explosive';
   sensorData = DeployExplosiveObj;
   sensorRadius = DeployExplosiveObj.detectRadius;
   sensorColor = "128 128 128";
   deployAmbientThread = true;

   debrisShapeName = "debris_generic_small.dts";
   debris = DeployableDebris;
   heatSignature = 0;

   indirectDamage = 0.5;
   maxdamage      = 0.5;
   damageRadius   = 10.0;
   radiusDamageType = $DamageType::Mine;
   kickBackStrength = 1800;
	aiAvoidThis = true;
   proximity = 5; // how close causes a detonation (by player/vehicle)
   armTime = 5000; // 5 seconds to arm 

   explosion = HvyGrenExplosion;
   underwaterExplosion = UnderwaterHvyGrenExplosion;

};

datablock ShapeBaseImageData(ExplosiveDeployableImage)
{
//   shapeFile = "pack_deploy_sensor_motion.dts";
   shapeFile = "stackable1s.dts";
   item = ExplosiveDeployable;
   mountPoint = 1;
   offset = "0.3 -0.22 0";
   rotation = "0 1 0 90";
   deployed = DeployedExplosive;

   mass = 10.0;

   stateName[0] = "Idle";
   stateTransitionOnTriggerDown[0] = "Activate";

   stateName[1] = "Activate";
   stateScript[1] = "onActivate";
   stateTransitionOnTriggerUp[1] = "Idle";

   maxDepSlope = 92;
   deploySound = SatchelChargeActivateSound;
   emap = true;
   heatSignature = 1;

   minDeployDis                       =  0.5;
   maxDeployDis                       =  5.0;  //meters from body
};

datablock ItemData(ExplosiveDeployable)
{
   className = Pack;
   catagory = "Deployables";
//   shapeFile = "pack_deploy_sensor_motion.dts";
   shapeFile = "stackable1s.dts";
   mass = 2.0;
   elasticity = 0.2;
   friction = 0.6;
   pickupRadius = 1;
   rotate = false;
   image = "ExplosiveDeployableImage";
   pickUpName = "an explosives pack";

   computeCRC = true;
   emap = true;
   heatSignature = 0;

   maxSensors = 4;
};


datablock ShapeBaseImageData(ExplosiveDiscImage0)
{
   shapeFile = "ammo_disc.dts";
   mountPoint = 0;
   offset = "0.14 0 0.55";
   rotation = "0 1 0 90";
};
datablock ShapeBaseImageData(ExplosiveDiscImage1)
{
   shapeFile = "ammo_disc.dts";
   mountPoint = 0;
   offset = "0 -0.14 0.55";
   rotation = "1 0 0 90";
};



function DeployedExplosive::onAdd(%this, %obj)
{
	StaticShapeData::onAdd(%this, %obj);
	%obj.mountImage(ExplosiveDiscImage0, 0);
	%obj.mountImage(ExplosiveDiscImage1, 1);
	%obj.schedule(%obj.getDatablock().armTime, "playThread", $ActivateThread, "activate");
}


function ExplosiveDeployableImage::getInitialRotation(%item, %plyr)
{
   %rotAxis = vectorNormalize(vectorCross(%item.surfaceNrm, "0 0 1"));
   if (getWord(%item.surfaceNrm, 2) == 1 || getWord(%item.surfaceNrm, 2) == -1)
      %rotAxis = vectorNormalize(vectorCross(%item.surfaceNrm, "0 1 0"));     
   return %rotAxis SPC mACos(vectorDot(%item.surfaceNrm, "0 0 1"));
}

function ExplosiveDeployable::onPickup(%this, %pack, %player, %amount)
{
   // %this = Sensor pack datablock
   // %pack = Sensor pack object number
   // %player = player
   // %amount = amount picked up (1)

   if(%pack.sensors $= "")
   {
      // assume that this is a pack that has been placed in a mission
      // this case was handled in ::onInventory below (max sensors);
   }
   else
   {
      // find out how many sensor were in the pack
      %player.deploySensors = %pack.sensors;
      %player.client.updateSensorPackText(%player.deploySensors);
   }
}

function ExplosiveDeployable::onThrow(%this,%pack,%player)
{
   // %this = Sensor pack datablock
   // %pack = Sensor pack object number
   // %player = player

   %player.throwSensorPack = 1;
   %pack.sensors = %player.deploySensors;
   %player.deploySensors = 0;
   %player.client.updateSensorPackText(%player.deploySensors);
   // do the normal ItemData::onThrow stuff -- sound and schedule deletion
   serverPlay3D(ItemThrowSound, %player.getTransform());
   %pack.schedulePop();
}

function ExplosiveDeployable::onInventory(%this,%player,%value)
{
   // %this = Sensor pack datablock
   // %player = player
   // %value = 1 if gaining a pack, 0 if losing a pack

   if(%player.getClassName() $= "Player")
   {
      if(%value)
      {
         // player picked up or bought a motion sensor pack
         %player.deploySensors = %this.maxSensors;
         %player.client.updateSensorPackText(%player.deploySensors);
      }
      else
      {
         // player dropped or sold a motion sensor pack
         if(%player.throwSensorPack)
         {
            // player threw the pack
            %player.throwSensorPack = 0;
            // everything handled in ::onThrow above
         }
         else
         {
            //the pack was sold at an inventory station, or unmounted because the player
            // used all the sensors
            %player.deploySensors = 0;
            %player.client.updateSensorPackText(%player.deploySensors);
         }
      }
   }
   Pack::onInventory(%this,%player,%value);
}


function armDeployedExplosive(%obj)
{
   %obj.armed = true;
   messageClient(%obj.owner,'MsgClient',"Explosive armed!");
//   %obj.mountImage(ExplosiveDiscImage0, 0);
//   %obj.mountImage(ExplosiveDiscImage1, 1);
//   %obj.schedule(1, "playThread", $ActivateThread, "activate");
}


function DeployedExplosive::onCollision(%data, %obj, %col)
{
   // don't detonate if mine isn't armed yet
   if(!%obj.armed)
      return;

   // don't detonate if mine is already detonating
//   if(%obj.boom)
//      return;

   //check to see what it is that collided with the mine
   %struck = %col.getClassName();
   if(%struck $= "Player" || %struck $= "WheeledVehicle" || %struck $= "FlyingVehicle" || %struck $= "HoverVehicle")
   {
      //error("Mine detonated due to collision with #"@%col@" ("@%struck@"); armed = "@%obj.armed);
      explodeExplosive(%obj, false);
   }
}

function explodeExplosive(%mo, %noDamage)
{
   %mo.noDamage = %noDamage;
   %mo.setDamageState(Destroyed);
}

function DeployedExplosive::damageObject(%data, %targetObject, %sourceObject, %position, %amount, %damageType)
{
   if(%targetObject.boom)
      return;

   StaticShapeData::damageObject(%data, %targetObject, %sourceObject, %position, %amount, %damageType);

   if (%targetObject.getDamageLevel() >= %data.maxDamage)
	%targetObject.setDamageState(Destroyed);

//   %targetObject.damagelevel += %amount;
//
//   if(%targetObject.damagelevel >= %data.maxDamage)
//   {   
//      %targetObject.setDamageState(Destroyed);
//   }
}

function DeployedExplosive::onDestroyed(%data, %obj, %lastState)
{
   StaticShapeData::onDestroyed(%data, %obj, %lastState);
   %obj.boom = true;
   %mineTeam = %obj.team;
   $TeamDeployedCount[%mineTeam, ExplosiveDeployable]--;
   RadiusExplosion(%obj, %obj.getPosition(), %data.damageRadius, %data.indirectDamage, 
                   %data.kickBackStrength, %obj.sourceObject, %data.radiusDamageType);
   %obj.schedule(300, "delete");
}


function ExplosiveDeployableImage::onDeploy(%item, %plyr, %slot)
{
   %deplObj = Parent::onDeploy(%item, %plyr, %slot);


   %deplObj.armed = false;
   %deplObj.damagelevel = 0;
   %deplObj.detonated = false;
   %deplObj.boom = false;
   %deplObj.depCount = 0;
   %deplObj.sourceObject = %plyr;
   %deplObj.client = %deplObj.owner;
   %deplObj.theclient = %deplObj.owner;

   // Schedule it to be armed
   schedule(%deplObj.getDatablock().armTime, %deplObj, "armDeployedExplosive", %deplObj);
   explosiveCheckVicinity(%deplObj);

   messageClient(%deplobj.owner,'MsgClient',"Explosive placed, and arming...");

   return %deplObj;  
}

function explosiveCheckVicinity(%mine)
{

//   messageAll('MsgClient',"Explosive checking proximity!");

   // don't bother to check if mine isn't armed yet
   if(%mine.armed)
      // don't keep checking if mine is already detonating
      if(!%mine.boom)
      {
         // the actual check for objects in the area
         %mineLoc = %mine.getWorldBoxCenter();
         %masks = $TypeMasks::PlayerObjectType | $TypeMasks::VehicleObjectType;
         %detonateRange = %mine.getDatablock().proximity;

         InitContainerRadiusSearch(%mineLoc, %detonateRange, %masks);
         while((%tgt = containerSearchNext()) != 0) 
           {
             %mine.detonated = true;
             schedule(50, %mine, "explodeExplosive", %mine, false);
             break;
           }
      }
   // if nothing set off the mine, schedule another check
   if(!%mine.detonated)
      schedule(500, %mine, "explosiveCheckVicinity", %mine);
}
