//--------------------------------------------------------------------------
// Deconstruct Gun
// Originally from Hammer Mod. Changed and redone for LuCiD MoD.
// Also Changed again and redone for construction mod.
// All changes made by LuCiD from LuCiD MoD & Mostlikely from Construction Mod.

//Globals to set what can be deconstructed. I'd put this in
//deployables.cs just to make things easyer..
$ReverseDeployItem[DeployedStationInventory] = InventoryDeployable;
$ReverseDeployItem[DeployedMotionSensor] = MotionSensorDeployable;
$ReverseDeployItem[DeployedPulseSensor] = PulseSensorDeployable;
$ReverseDeployItem[TurretDeployedOutdoor] = TurretOutdoorDeployable;
$ReverseDeployItem[TurretDeployedFloorIndoor] = TurretIndoorDeployable;
$ReverseDeployItem[TurretDeployedWallIndoor] = TurretIndoorDeployable;
$ReverseDeployItem[TurretDeployedCeilingIndoor] = TurretIndoorDeployable;
$ReverseDeployItem[TurretDeployedBase] = TurretBasePack;
$ReverseDeployItem[TelePadDeployedBase] = TelePadPack;
$ReverseDeployItem[Deployedspine] = "poof spineDeployable";
$ReverseDeployItem[Deployedwwall] = "poof wwallDeployable";
//Base stuff
$ReverseDeployItem[StationInventory] = BaseInventoryPack;
$ReverseDeployItem[SentryTurret] = BaseSentryPack;
$ReverseDeployItem[GeneratorLarge] = BaseGeneratorPack;
$ReverseDeployItem[SenSorLargePulse] = BaseLargeSensorPack;
$ReverseDeployItem[TurretDeployedBase] = TurretBasePack;
$ReverseDeployItem[TurretBaseLarge] = BaseTurretPack;
$ReverseDeployItem[SenSorMediumPulse] = BaseMediumSensorPack;
$ReverseDeployItem[SolarPanel] = BaseSolarPack;
$ReverseDeployItem[FlipFlop] = BaseGPTPack;

$ReverseDeployItem[Scoutflyer] = BaseShrikePack;
$ReverseDeployItem[ScoutVehicle] = BasegravcyclePack;
$ReverseDeployItem[AssaultVehicle] = BasetankPack;
$ReverseDeployItem[BomberFlyer] = BasebomberPack;
$ReverseDeployItem[HAPCFlyer] = BasetransportPack;
$ReverseDeployItem[MobileBaseVehicle] = BasempbPack;

//[[futur reverence]]
//$ReverseDeployItem[Deployedfloor] = "poof floorDeployable";
//$ReverseDeployItem[Deployedwall] = "poof wallDeployable";
//$ReverseDeployItem[Deployedmspine] = "poof mspineDeployable";
//$ReverseDeployItem[Deployedtree] = treeDeployable;
//$ReverseDeployItem[DeployedVampire] = VampireDeployable;
//$ReverseDeployItem[Deployedmspinering] = "poof nothing";
//$ReverseDeployItem[StationInventory] = BunkerDeployable;



//--------------------------------------------------------------------------
// Sounds
// Construct: Added Effects datablocks

datablock EffectProfile(DeconstructorSwitchEffect)
{
   effectname = "packs/packs.repairPackOn";
   minDistance = 2.5;
   maxDistance = 2.5;
};

//datablock EffectProfile(DeconstructorActivateEffect)
//{
//   effectname = "packs/packs.repairPackOn";
//   minDistance = 2.5;
//   maxDistance = 2.5;
//};

datablock EffectProfile(DeconstructorFireEffect)
{
   effectname = "misc/downloading";
   minDistance = 2.5;
   maxDistance = 5.0;
};

datablock AudioProfile(DeconstructorSwitchSound)
{
   filename    = "fx/packs/packs.repairPackOn.wav";
   description = AudioClosest3d;
   preload = true;
   effect = DeconstructSwitchEffect;
};

//datablock AudioProfile(DeconstructorActivateSound)
//{
//   filename    = "fx/packs/packs.repairPackOn.wav";
//   description = AudioClosest3d;
//   preload = true;
//   effect = DeconstructActivateEffect;
//};

datablock AudioProfile(DeconstructorFireSound)
{
   filename    = "fx/misc/downloading.wav";
 //filename    = "fx/packs/repair_use.wav";
   description = CloseLooping3d;
   preload = true;
   effect = DeconstructFireEffect;
};

//--------------------------------------------------------------------------
// Projectile

datablock RepairProjectileData(DefaultDisBeam)
{
   sound = ElfFireWetSound;

   beamRange      = 20;
   beamWidth      = 0.15;
   numSegments    = 20;
   texRepeat      = 0.20;
   blurFreq       = 10.0;
   blurLifetime   = 1.0;
   cutoffAngle    = 25.0;

   textures[0]   = "special/ELFLightning";
   textures[1]   = "skins/flaregreen";

};

//-------------------------------------------------------------------------
// shapebase datablocks

datablock ItemData(Deconstructor)
{
   className = Weapon;
   catagory = "Spawn Items";
   shapeFile = "weapon_shocklance.dts";
   image = DeconstructorImage;
   mass = 1;
   elasticity = 0.2;
   friction = 0.6;
   pickupRadius = 2;
   rotate = true;
   pickUpName = "a Deconstructor";

   lightOnlyStatic = true;
   lightType = "PulsingLight";
   lightColor = "0 1 0 1";
   lightTime = 1200;
   lightRadius = 4;

   //computeCRC = true;
   emap = true;
};

//--------------------------------------------------------------------------
// Dis Gun

datablock ShapeBaseImageData(DeconstructorImage)
{
   shapeFile = "weapon_shocklance.dts";
   offset = "0 0 0";

	item = Deconstructor;
   usesEnergy = true;

   minEnergy = 3;

   cutOffEnergy = 3.1;
   emap = true;

   stateName[0] = "Activate";
   stateTransitionOnTimeout[0] = "ActivateReady";
   stateTimeoutValue[0] = 0.25;  //Construct: Was 0.25
   stateSound[0] = DeconstructorSwitchSound;

   stateName[1] = "ActivateReady";
   stateScript[1] = "onActivateReady";
   stateSpinThread[1] = Stop;
   stateTransitionOnAmmo[1] = "Ready";
   stateTransitionOnNoAmmo[1] = "ActivateReady";

   stateName[2] = "Ready";
   stateSpinThread[2] = Stop;
   stateTransitionOnNoAmmo[2] = "Deactivate";
   stateTransitionOnTriggerDown[2] = "Validate";

   stateName[3] = "Validate";
   stateTransitionOnTimeout[3] = "Validate";
   stateTimeoutValue[3] = 0.2;  //Construct: Was 0.2
   stateEnergyDrain[3] = 3;
   stateSpinThread[3] = SpinUp;
   stateScript[3] = "onValidate";
   stateIgnoreLoadedForReady[3] = true;
   stateTransitionOnLoaded[3] = "Disassemble";
   stateTransitionOnNoAmmo[3] = "Deactivate";
   stateTransitionOnTriggerUp[3] = "Deactivate";

   stateName[4] = "Disassemble";
   stateSound[4] = DeconstructorFireSound;
   stateScript[4] = "onDisassemble";
   stateSpinThread[4] = FullSpeed;
   stateAllowImageChange[4] = false;
   stateSequence[4] = "activate";
   stateFire[4] = true;
   stateEnergyDrain[4] = 16;
   stateTimeoutValue[4] = 0.2;  //Construct: Was 0.2
   stateTransitionOnTimeOut[4] = "Disassemble";
   stateTransitionOnNoAmmo[4] = "Deactivate";
   stateTransitionOnTriggerUp[4] = "Deactivate";
   stateTransitionOnNotLoaded[4] = "Validate";

   stateName[5] = "Deactivate";
   stateScript[5] = "onDeactivate";
   stateSpinThread[5] = SpinDown;
   stateSequence[5] = "activate";
   stateDirection[5] = false;
   stateTimeoutValue[5] = 0.2;  //Construct: Was 0.2
   stateTransitionOnTimeout[5] = "ActivateReady";
};

function DeconstructorImage::onDisassemble(%this,%obj,%slot)
{
	// this = Deconstructorimage datablock
	// obj = player wielding the Disassemble gun
	// slot = weapon slot

	if(%obj.getEnergyLevel() <= %this.cutOffEnergy)
	{
		if(%obj.Disassembling > 0)
			stopDisassembling(%obj);
		return;
	}

   // reset the flag that indicates an error message has been sent
   %obj.errMsgSent = false;

   %target = %obj.Disassembling;
   if(!%target)
   {
      // no target -- whoops! never mind
		stopDisassembling(%obj);
		return;
   }
   %hGun = %obj.getMountedImage(%slot);
   // muzVec is the vector coming from the Disassemble gun's "muzzle"
   %muzVec = %obj.getMuzzleVector(%slot);
   // muzNVec = normalized muzVec
   %muzNVec = VectorNormalize(%muzVec);
   %Disassemblerange = DefaultDisBeam.beamRange;
   // scale muzNVec to the range the repair beam can reach
   %muzScaled = VectorScale(%muzNVec, %Disassemblerange);
   // muzPoint = the actual point of the gun's "muzzle"
   %muzPoint = %obj.getMuzzlePoint(%slot);
   // rangeEnd = muzzle point + length of beam
   %rangeEnd = VectorAdd(%muzPoint, %muzScaled);
   // search for just about anything that can be damaged as well as interiors
	%searchMasks = $TypeMasks::InteriorObjectType | $TypeMasks::StaticShapeObjectType | $TypeMasks::VehicleObjectType;
   // search for objects within the beam's range that fit the masks above
   %scanTarg = ContainerRayCast(%muzPoint, %rangeEnd, %searchMasks, %obj);
	// screen out interiors
   if(%scanTarg && !(%scanTarg.getType() & $TypeMasks::InteriorObjectType))
	{
      // a target in range was found
      %hTgt = firstWord(%scanTarg);
      // can it be dissed? is it already being dissed?
      if($ReverseDeployItem[%hTgt.getDataBlock().getName()] !$= "" && !%hTht.BeingDisassembled)
	   {
			// yes, it's Disassembleable
			if(%hTgt != %obj.Disassembling) // its not what we were originally dising
			{
				if(isObject(%obj.Disassembling))
				{
					stopDisassembling(%obj);
					%obj.Disassembling = %hTgt;
					startDisassembling(%obj);
				}
			}
			else // continue dising
			{
				%obj.DisassembleTime = %obj.DisassembleTime - 120;
                // if its a shield beacon & not already being dissed.
  //[[Set Times]] This is where i adjust how long it takes to deconstruct different objects.
  if($ReverseDeployItem[%hTgt.getDataBlock().getName()] $= "LargeShieldBeaconPack" || $ReverseDeployItem[%hTgt.getDataBlock().getName()] $= "SmallShieldBeaconPack" || $ReverseDeployItem[%hTgt.getDataBlock().getName()] $= "MobileBaseVehicle" || $ReverseDeployItem[%hTgt.getDataBlock().getName()] $= "ShieldGeneratorPack" && !%hTht.BeingDisassembled)
  {
   %obj.DisassembleTime = %obj.DisassembleTime + 80;
  }
  if($ReverseDeployItem[%hTgt.getDataBlock().getName()] $= "InventoryDeployable" && !%hTht.BeingDisassembled)
  {
   %obj.DisassembleTime = %obj.DisassembleTime - 175;
  }
  //[[End Set Times]]
  
				%failure = (0.1 + (20 - %obj.getEnergyLevel()) / 100);
				if(getRandom() < %failure) // Dis failure
				{
					messageClient(%obj.client, 'MsgdeconstructorFailed', '\c2Disassemble Failed!~wfx/powered/nexus_deny.wav', %hTgt);
					stopDisassembling(%obj);
				}
				else if(%obj.DisassembleTime < 0) // we have a Dis!
				{
                    if(%hTgt.team != %obj.team)
                    {
                     echo(%hTgt.team);
                     echo(%obj.team);
                     return;
                    }
					if(%hTgt.getGameName() !$= "")
						%hName = %hTgt.getGameName();
					else
						%hName = %hTgt.getDatablock().getName();

					stopDisassembling(%obj);

                    //[[Set Message]] This is where i set messages for different objects.
                    if($ReverseDeployItem[%hTgt.getDataBlock().getName()] $= "MobileBaseVehicle")
                    {
                      messageClient(%obj.client, 'MsgdeconstructorGotDis', '\c4You dematerialized a %1!~wfx/weapons/plasma_rifle_activate.wav', %hName);
                    }
                    else
                    {                   //Construct: Commented out below.
					messageClient(%obj.client, 'MsgdeconstructorGotDis', '\c4You disassembled a %1!', %hName);
					//messageClient(%obj.client, 'MsgdeconstructorGotDis', %hTgt.team SPC %obj.client.team, %hName);

   		echo("Dis successfull target: " @ %hTgt @ " owner : " @ %hTgt.owner @ " time : " @ %obj.DisassembleTime);
                    }
                    //[[End Set Message]]

                    //[[Reverse it]] Make it available to the team again and turn it back into a pack
                                //%name = %hTgt.getDataBlock().getName();
                                //messageClient(%obj.client, 'MsgdeconstructorGotDis', '\c4You disassembled a %1!~wfx/weapons/plasma_rifle_activate.wav', %name);
                                
                                
					%revitem = %hTgt.getDataBlock().getName();
					%newpack = $ReverseDeployItem[%revitem];
                                        
                    //$TeamDeployedCount[%hTgt.team,GetWord(%newpack,1)]--;
                    //else
				    %hTgt.dissasembled = 1;
                    if (GetWord(%newpack,0) !$= "poof")
                      {
                        //$TeamDeployedCount[%hTgt.team,%newpack]--;
					    //%obj.setInventory(%newpack, 1);
					    //place it on ground instead..

                        %npack = new Item() {
      			        dataBlock = %newpack;
  				        };
				        MissionCleanup.add(%npack);
                        %npack.GTWID = %hTgt.GTWID;
                        %pos = %hTgt.getPosition();
                        if (VectorLen(%htgt.dSurfaceNrm))
                          %dir = %htgt.dSurfaceNrm;
                        else
                          %dir = "0 0 1";
                        %npack.team = %hTgt.team;
                        %npack.schedule(501,"applyImpulse",%npack.getTransform(), "0 0 5");
                        //messageClient(%obj.client, 'MsgdeconstructorGotDis', %hTgt.team, %name);
				        %npack.setTransform(VectorAdd(%pos,%dir) SPC "0 0 1" SPC (getRandom() * 360));
                        if (%newpack $= "BaseGPTPack")
                          {
                            echo("NPack: "@ %npack @" Team: "@ %npack.team);
                            $GPTisPack[%npack.team] = true;
                            GPTbeacon(%npack,%npack.team);
                          }
                      }
                   %hTgt.getDataBlock().disassemble(%obj, %hTgt); // Run Item Specific code.
      			   //%hTgt.delete();
				}
			}
		}
	}
   else
   {
		stopDisassembling(%obj);
      // there is no target in range
   }
}

function deconstructorImage::onActivate(%this,%obj,%slot)
{
}

function endDisassemble(%target)
{
	%target.team = %target.OldTeam;
   setTargetSensorGroup(%target.getTarget(), %target.team);
	%target.owner = %target.OldOwner;

	%target.Disassembled = false;
	echo("Disassemble has worn off of " @ %target);
}

function deconstructorImage::onDeactivate(%this,%obj,%slot)
{
}

function deconstructorImage::onDeactivate(%this,%obj,%slot)
{
   %obj.setImageTrigger(%slot, false);
	if(%obj.Disassembling > 0)
	{
		stopDisassembling(%obj);
		messageClient(%player.client, 'MsgdeconstructorStopped', '\c2Disassembling Stopped.', %hTgt);
	}
   %obj.errMsgSent = false;
}

function deconstructorImage::onValidate(%this,%obj,%slot)
{
   %hGun = %obj.getMountedImage(%slot);
   // muzVec is the vector coming from the Disassemble gun's "muzzle"
   %muzVec = %obj.getMuzzleVector(%slot);
   // muzNVec = normalized muzVec
   %muzNVec = VectorNormalize(%muzVec);
   %Disassemblerange = DefaultDisBeam.beamRange;
   // scale muzNVec to the range the repair beam can reach
   %muzScaled = VectorScale(%muzNVec, %Disassemblerange);
   // muzPoint = the actual point of the gun's "muzzle"
   %muzPoint = %obj.getMuzzlePoint(%slot);
   // rangeEnd = muzzle point + length of beam
   %rangeEnd = VectorAdd(%muzPoint, %muzScaled);
   // search for just about anything that can be damaged as well as interiors
	%searchMasks = $TypeMasks::InteriorObjectType | $TypeMasks::StaticShapeObjectType | $TypeMasks::VehicleObjectType;
   // search for objects within the beam's range that fit the masks above
   %scanTarg = ContainerRayCast(%muzPoint, %rangeEnd, %searchMasks, %obj);

	// screen out interiors
   if(%scanTarg && !(%scanTarg.getType() & $TypeMasks::InteriorObjectType))
   {
      %hTgt = firstWord(%scanTarg);

      // can it be dissed? is it already being dissed?
      if($ReverseDeployItem[%hTgt.getDataBlock().getName()] !$= "" && !%hTht.BeingDisassembled && %hTgt.team == %obj.client.team)
      {
			// yes, it's Disassembleable
			if(%hTgt != %obj.Disassembling)
			{
				if(isObject(%obj.Disassembling))
					stopDisassembling(%obj);

				%obj.Disassembling = %hTgt;
				startDisassembling(%obj);
			}
			// setting imageLoaded to true sends us to Disassemble state (function onDisassemble)
			%obj.setImageLoaded(%slot, true);
      }
      else
      {
         // there is a target in range, but it's not disable
         if(!%obj.errMsgSent)
         {
            messageClient(%obj.client, 'MsgdeconstructorBadTarget', '\c2You can\'t Disassemble that', %hTgt.getDataBlock().getName());
            %obj.errMsgSent = true;
         }
         // if player was Disassembling something, stop the Disassembling -- we're done
			if(%obj.Disassembling > 0)
				stopDisassembling(%obj);
      }
   }
   else
   {
      // there is no target in range
      if(!%obj.errMsgSent)
      {
         // send an error message only once
         messageClient(%obj.client, 'MsgdeconstructorNoTarget', '\c2No target to Disassemble.');
         %obj.errMsgSent = true;
      }
   }
}

function deconstructorImage::onMount(%this,%obj,%slot)
{
   // Mount message - ZOD
   $Host::MountMsg = true;
   if ($Host::MountMsg == true && !$Host::TournamentMode) {
   %curWeap = ( %obj.getMountedImage($WeaponSlot) == 0 ) ? "" : %obj.getMountedImage($WeaponSlot).getName().item.pickUpName;
   BottomPrint(%obj.client, "Now using " @ %curWeap, 2, 1 );
   }
   // Mount message end - ZOD

   %obj.errMsgSent = false;
   %obj.client.setWeaponsHudActive(%this.item);
}

function deconstructorImage::onActivateReady(%this,%obj,%slot)
{
   %obj.errMsgSent = false;
}

function stopDisassembling(%player)
{
   // %player = the player who was using the Disassemble gun
   if(%player.Disassembling > 0)
   {
      if(isObject(%player.DisassembleProjectile))
      	%player.DisassembleProjectile.delete();
   }
   %hTgt.BeingDisassembled = false;
   %player.DisassembleProjectile = 0;
	%player.Disassembling = 0;
	%player.DisassembleTime = 0;
 	%player.errMsgSent = true;
 	%player.setImageTrigger($WeaponSlot, false);
	%player.setImageLoaded($WeaponSlot, false);
    %client = %player.client;
   if(%client.CampingThread)
   cancel(%client.campingThread);
   return;

}

function startDisassembling(%player)
{
   // %player = the player who was using the Disassemble gun

   %initialDirection = %player.getMuzzleVector($WeaponSlot);
   %initialPosition  = %player.getMuzzlePoint($WeaponSlot);

   //else
      %DisassembleTime = 250; //250

   %player.DisassembleTime = %DisassembleTime;
   %player.DisassembleProjectile = new RepairProjectile() {
      dataBlock = DefaultDisBeam;
      initialDirection = %initialDirection;
      initialPosition  = %initialPosition;
      sourceObject     = %player;
      sourceSlot       = $WeaponSlot;
      targetObject     = %player.Disassembling;
   };
   MissionCleanup.add(%player.DisassembleProjectile);

   %hTgt = %player.Disassembling;
   %hTgt.BeingDisassembled = true;
	if(%hTgt.getGameName() !$= "")
      %hName = %hTgt.getGameName();
   else
      %hName = %hTgt.getDatablock().getName();
   //Construct: Commented out below.
   //messageClient(%player.client, 'MsgdeconstructorStarted', '\c2Disassembling %1.', %hName);
}

function deconstructor::onPickup(%this, %obj, %shape, %amount)
{
   // created to prevent console errors
}
