
$File = "Sensor Tap";

datablock StaticShapeData(SensorTapLarge) : StaticShapeDamageProfile
{
   className = Sensor;  
   catagory = "Sensors";
   shapeFile = "turret_muzzlepoint.dts";
   maxDamage = 1000;
   destroyedLevel = 1000;
   disabledLevel = 1000;

   dynamicType = $TypeMasks::SensorObjectType;

   name = "large pulse sensor (tapped)";

   cmdCategory = "Support";
   cmdIcon = CMDSensorIcon;
   cmdMiniIconName = "commander/MiniIcons/com_sensor_grey";
   targetNameTag = 'Large';
   targetTypeTag = 'Sensor Tap';

   heatSignature = 0;

   sensorData = SensorLgPulseObj;
   sensorRadius = SensorLgPulseObj.detectRadius;
};

datablock StaticShapeData(SensorTapMedium) : StaticShapeDamageProfile
{
   className = Sensor;  
   catagory = "Sensors";
   shapeFile = "turret_muzzlepoint.dts";
   maxDamage = 1000;
   destroyedLevel = 1000;
   disabledLevel = 1000;

   dynamicType = $TypeMasks::SensorObjectType;

   name = "medium pulse sensor (tapped)";

   cmdCategory = "Support";
   cmdIcon = CMDSensorIcon;
   cmdMiniIconName = "commander/MiniIcons/com_sensor_grey";
   targetNameTag = 'Medium';
   targetTypeTag = 'Sensor Tap';

   heatSignature = 0;

   sensorData = SensorMedPulseObj;
   sensorRadius = SensorMedPulseObj.detectRadius;
};

datablock ShapeBaseImageData(SensorTapImage)
{
   mass = 4;
   emap = true;

   shapeFile = "pack_deploy_sensor_pulse.dts";

   item = SensorTapPack;
   deployed = SensorTap;

   mountPoint = 1;
   offset = "0 0 0";

   stateName[0] = "Idle";
   stateTransitionOnTriggerDown[0] = "Activate";

   stateName[1] = "Activate";
   stateScript[1] = "onActivate";
   stateTransitionOnTriggerUp[1] = "Idle";

   maxDepSlope = 360;
   deploySound = SensorDeploySound;
};

datablock ItemData(SensorTapPack)
{
   className = Pack;
   catagory = "Deployables";

   shapeFile = "deploy_sensor_pulse.dts";
   mass = 4;

   scale = "!.6 1.6 1.6";

   elasticity = 0.2;
   friction = 0.6;
   pickupRadius = 2;

   rotate = true;

   haslightradius = true;
   lightType = "PulsingLight";
   lightColor  = "1.0 0.4 0.4";
   lightTime = "1500";
   lightRadius = "1.25";

   deployed = SensorTap;
   image = SensorTapImage;
   pickUpName = "a sensor tap";

   computeCRC = true;
   emap = true;
};

datablock StaticShapeData(SensorTap) : StaticShapeDamageProfile
{
   className = Sensor;
   shapeFile = "deploy_sensor_pulse.dts";

   maxDamage = 0.4;
   destroyedLevel = 0.4;

   item = SensorTapPack;
   image = SensorTapImage;

   detectionRadius = 50;

   explosion = DeployablesExplosion;
   dynamicType = $TypeMasks::SensorObjectType;

   name = "Sensor Tap";

   deployedObject = true;
   deployAmbientThread = true;

   cmdCategory = "DSupport";
   cmdIcon = CMDSensorIcon;
   cmdMiniIconName = "commander/MiniIcons/com_deploymotionsensor";

   scale = "2.0 2.0 2.0";

   targetNameTag = 'Sensor Tap';
   targetTypeTag = '';

   isShielded = true;
   energyPerDamagePoint = 80;
   maxEnergy = 35;
   rechargeRate = 0.1;

   debrisShapeName = "debris_generic_small.dts";
   debris = DeployableDebris;

   heatSignature = 0;
};

function SensorTapImage::onActivate(%Data, %Player, %Slot)
{
   if (VectorLen(%Player.getVelocity()) > 0.1)
   {
      messageClient(%Player.client, 'MsgDeployFailed', '\c2You must be stationary to deploy the Sensor Tap properly.%1', '~wfx/misc/misc.error.wav');
      %Player.setImageTrigger(%Slot, false);
      return;
   }

   // If all of the item has been deployed.
   if ($TeamDeployedCount[%Player.team, SensorTapImage] >= $TeamDeployableMax[SensorTapImage])
   {
      messageClient(%Player.client, 'MsgDeployFailed', '\c2Your team\'s control network has reached its capacity for this item.%1', '~wfx/misc/misc.error.wav');
      %Player.setImageTrigger(%Slot, false);
      return;
   }

   // Check along a player's field of view   
   %Object = %Player.searchView(3.5, $EverythingMask);

   // If nothing was found, then we say so and stop
   if (%Object $= "0")
   {
      messageClient(%Player.client, 'MsgDeployFailed', '\c2Permanent Enemy Sensor Array must be within reach.%1', '~wfx/misc/misc.error.wav');
      %Player.setImageTrigger(%Slot, false);
      return;
   }

   // Make sure it is what we want
   %ObjectName = %Object.getDataBlock().getName();

   if (%ObjectName $= "SensorLargePulse" || %ObjectName $= "SensorMediumPulse")
   {
      // For simplicity we do it this way
   } else {
      messageClient(%Player.client, 'MsgDeployFailed', '\c2Can not be used to tap that.%1', '~wfx/misc/misc.error.wav');
      %Player.setImageTrigger(%Slot, false);
      return;
   }

   %ObjectRotation = getWords(%Object, 4, 7);
   %ObjectPosition = getWords(%Object, 1, 3);
   %Object = getWord(%Object, 0);
   %ObjectPositionXY = getWords(%ObjectPosition, 0, 1);

   if (%Object.team == %Player.team)
   {
      messageClient(%Player.client, 'MsgDeployFailed', '\c2There must be a Permanent ENEMY Sensor Array within reach.%1', '~wfx/misc/misc.error.wav');
      %Player.setImageTrigger(%Slot, false);
      return;
   }

   if (%Object.SensorTap !$= "")
   {
      messageClient(%Player.client, 'MsgDeployFailed', '\c2Enemy Sensor Array is already tapped, installing more than one risks detection.%1', '~wfx/misc/misc.error.wav');
      %Player.setImageTrigger(%Slot, false);
      return;
   }

   %Transform = %Object.getTransform();
   %ObjectRotation2 = rotFromTransform(%Transform);
   %ObjectPosition2 = posFromTransform(%Transform);
   %ObjectPosition2Z = getWord(%Position, 2);

   %SensorTapPosition = %ObjectPositionXY @ " " @ %ObjectPosition2Z;

   // Take the deployable off the player's back and out of inventory
   %Player.unmountImage(%Slot);
   %Player.decInventory(SensorTap, 1);  

   // Load where the play is
   %Transform = %Player.getTransform();
   %Position = posFromTransform(%Transform);
   %Rotation = rotFromTransform(%Transform);

   // Make the tap item
   %sensorTap = new StaticShape()
   {
      dataBlock = SensorTap;
      position = %Position;
      rotation = %Rotation;
      scale = SensorTap.scale;
      owner = %Player.client;
      team = %Player.team;
   };
   MissionCleanUp.Add(%sensorTap);

   // play the deploy sound
   serverPlay3D(%Item.deploySound, %Position);
   %SensorTap.deploy();

   // increment the team count for this deployed object
   $TeamDeployedCount[%Player.team, SensorTapImage]++;

   // Set up the box's target
   %SensorTap.target = createTarget(%SensorTap, "", "", "", %SensorTap.getDataBlock().targetNameTag, %Player.team, 0);
   setTargetSensorGroup(%SensorTap.getTarget(), %Player.team);

   // Link the parts
   %Object.SensorTap = %SensorTap;
   %SensorTap.EnemySensor = %Object;

   if (%ObjectName $= "SensorLargePulse")
   {
      %TapPosition = VectorAdd(%ObjectPosition2, "0 0 7");

      %Tap = new StaticShape()
      {
         dataBlock = SensorTapLarge;
         position = %TapPosition;
         owner = %Player.client;
         team = %Player.team;
      };
   } else {
      %TapPosition = VectorAdd(%ObjectPosition2, "0 0 5");

      %Tap = new StaticShape()
      {
         dataBlock = SensorTapMedium;
         position = %TapPosition;
         owner = %Player.client;
         team = %Player.team;
      };
   }
   MissionCleanUp.Add(%Tap);

   %Tap.setSelfPowered();

   // Set up the box's target
   %Tap.target = createTarget(%Tap, "", "", %Tap.getDataBlock().targetNameTag, %Tap.getDataBlock().targetTypeTag, %Player.team, 0);
   setTargetSensorGroup(%Tap.getTarget(), %Player.team);

   %sensorTap.Tap = %Tap;
   %Tap.SensorTap = %sensorTap;
   %Tap.Sensor = %Object;

   %ObjectName = %Object.getName();
   if (%ObjectName $= "")
      %ObjectName = %Object.getDataBlock().Name;

   %Message = "Sensor Tap installed to monitor and transmit data from " @ %ObjectName @ ".";
   messageClient(%Player.client, '', %Message);

   return(%SensorTap);
}

function SensorTap::damageObject(%Data, %SensorTap, %SourceObject, %Position, %Amount, %DamageType)
{
   if (%SourceObject !$= "" && %SourceObject != 0)
   {
      %SensorTap.lastDamagedBy = %sourceObject.client;
      %SensorTap.lastDamagedByTeam = %sourceObject.client.team;
      %SensorTap.damageTimeMS = GetSimTime();
   }

   %DamageScale = %Data.damageScale[%DamageType];
   if (%DamageScale !$= "")
      %Amount *= %DamageScale;

   %SensorTap.applyDamage(%Amount);

   %DamageLevel = %SensorTap.getDamageLevel();
   if (%DamageLevel >= %SensorTap.getDataBlock().destroyedLevel)
   {
      $TeamDeployedCount[%SensorTap.team, SensorTapImage]--;  

      // Clear the Sensor to Tap Link
      %SensorTap.EnemySensor.SensorTap = "";

      // Delete the Actual Tap
      %SensorTap.Tap.delete();

      %SensorTap.setDamageState(Destroyed);
      %SensorTap.schedule(550, delete);
   }
}

function SensorTap::ItemSwap(%Data, %Object)
{
   %Transform = %Object.getTransform();
   %Position = posFromTransform(%Transform);

   %ItemData = %Object.getDataBlock().item;

   %NewItem = new Item()
   {
      dataBlock = %ItemData;
      position = %Position;
   };
   MissionCleanup.add(%NewItem);

   $TeamDeployedCount[%Object.team, SensorTap]--;

   %NewItem.applyImpulse(%Position, "0 0 10");

   %Object.delete();

   %NewItem.schedulePop();
}

function MonitorSensorTapStatus(%Sensor, %LastState)
{
   if (%Sensor.SensorTap $= "" || isObject(%Sensor) == false)
      return;

   %State = %Sensor.getDamageState();

   // To help prevent extra function calls 
   if (%LastState !$= %State)
      %Sensor.SensorTap.setDataState(%State);

   // If not fixed yet, check again shortly.
   if (%State !$= "Enabled")
      schedule(1250, 0, MonitorSensorTapStatus, %Sensor, %State);
}
