// sounds and effects
///////////////////////

datablock AudioProfile(DeployablesExplosionSound)
{
   filename = "fx/explosions/deployables_explosion.wav";
   description = AudioExplosion3d;
   preload = true;
};

//--------------------------------------------------------------------------
// Shockwave
//--------------------------------------------------------------------------
datablock ShockwaveData(TurretShockwave)
{
   width = 6.0;
   numSegments = 20;
   numVertSegments = 2;
   velocity = 8;
   acceleration = 20.0;
   lifetimeMS = 1500;
   height = 1.0;
   verticalCurve = 0.5;

   mapToTerrain = false;
   renderBottom = true;

   texture[0] = "special/shockwave4";
   texture[1] = "special/gradient";
   texWrap = 6.0;

   times[0] = 0.0;
   times[1] = 0.5;
   times[2] = 1.0;

   colors[0] = "0.8 0.8 0.8 1.00";
   colors[1] = "0.8 0.5 0.2 0.20";
   colors[2] = "1.0 0.5 0.5 0.0";
};

//--------------------------------------------------------------------------
// Explosion
//--------------------------------------------------------------------------
datablock ExplosionData(TurretExplosion)
{
   explosionShape = "effect_plasma_explosion.dts";
   soundProfile = ShapeExplosionSound;
   faceViewer = true;
   shockwave = TurretShockwave;
};

datablock ExplosionData(SmallTurretExplosion)
{
   soundProfile = DeployablesExplosionSound;
   faceViewer = true;

   explosionShape = "effect_plasma_explosion.dts";
   sizes[0] = "0.3 0.3 0.3";
   sizes[1] = "0.3 0.3 0.3";
   times[0] = 0;
   times[1] = 1;
};


//--------------------------------------------------------------------------
// Turret Debris
//--------------------------------------------------------------------------
datablock DebrisData( TurretDebris )
{
   explodeOnMaxBounce = false;

   elasticity = 0.20;
   friction = 0.5;

   lifetime = 17.0;
   lifetimeVariance = 0.0;

   minSpinSpeed = 60;
   maxSpinSpeed = 600;

   numBounces = 10;
   bounceVariance = 0;

   staticOnMaxBounce = true;

   useRadiusMass = true;
   baseRadius = 0.4;

   velocity = 9.0;
   velocityVariance = 4.5;
};

datablock DebrisData( TurretDebrisSmall )
{
   explodeOnMaxBounce = false;

   elasticity = 0.20;
   friction = 0.5;

   lifetime = 17.0;
   lifetimeVariance = 0.0;

   minSpinSpeed = 60;
   maxSpinSpeed = 600;

   numBounces = 10;
   bounceVariance = 0;

   staticOnMaxBounce = true;

   useRadiusMass = true;
   baseRadius = 0.2;

   velocity = 5.0;
   velocityVariance = 2.5;
};


//--------------------------------------------------------------------------
// Turret base class functionality.  Barrels are in scripts/weapons/*.cs
//
//
//--------------------------------------------------------------------------

function GameBaseData::hasLOS(%data, %this, %slot, %target) {
   //%vec = %this.getMuzzleVector(%slot);
   %vec = getVectorFromObjects(%this, %target);
   
   %pos = %this.getMuzzlePoint(%slot);
   %nVec = VectorNormalize(%vec);
   %scVec = VectorScale(%nVec, %this.getMountedImage(0).attackRadius);
   %end = VectorAdd(%pos, %scVec);
   %searchResult = containerRayCast(%pos, %end, $TypeMasks::TerrainObjectType | $TypeMasks::InteriorObjectType | $TypeMasks::PlayerObjectType | $TypeMasks::VehicleObjectType | $TypeMasks::StaticShapeObjectType | $TypeMasks::TurretObjectType | $TypeMasks::ItemObjectType, %this);

   %targetObject = getWord(%searchResult, 0);
   if(%targetObject == %target) {
      return 1;
   }
   else {
      return 0;
   }
}

function TurretData::create(%block)
{
   %obj = new Turret() {
      dataBlock = %block;
   };

   return %obj;
}

datablock SensorData(TurretBaseSensorObj)
{
   detects = true;
   detectsUsingLOS = true;
   detectsPassiveJammed = false;
   detectsActiveJammed = false;
   detectsCloaked = false;
   detectionPings = true;
   detectRadius = 80;
};


datablock TurretData(TurretBaseLarge) : TurretDamageProfile
{
   className      = TurretBase;
   catagory       = "Turrets";
   shapeFile      = "turret_base_large.dts";
   preload        = true;

   mass           = 1.0;  // Not really relevant

   maxDamage      = 2.25;
   destroyedLevel = 2.25;
   disabledLevel  = 1.35;
   explosion      = TurretExplosion;
	expDmgRadius = 15.0;
	expDamage = 0.66;
	expImpulse = 2000.0;
   repairRate     = 0.5;
   emap = true;

   thetaMin = 15;
   thetaMax = 140;

   isShielded           = true;
   energyPerDamagePoint = 50;
   maxEnergy = 150;
   rechargeRate = 0.31;
   humSound = SensorHumSound;
   pausePowerThread = true;

   canControl = true;
   cmdCategory = "Tactical";
   cmdIcon = CMDTurretIcon;
   cmdMiniIconName = "commander/MiniIcons/com_turretbase_grey";
   targetNameTag = 'Base';
   targetTypeTag = 'Turret';
   sensorData = TurretBaseSensorObj;
   sensorRadius = TurretBaseSensorObj.detectRadius;
   sensorColor = "0 212 45";
   heatSignature = 1.0;
   firstPersonOnly = true;

   debrisShapeName = "debris_generic.dts";
   debris = TurretDebris;
};

function TurretData::onGainPowerEnabled(%data, %obj) {
	if (shouldChangePowerState(%obj,true))
		setTargetSensorData(%obj.target, %data.sensorData);
	Parent::onGainPowerEnabled(%data, %obj);
}

function TurretData::onLosePowerDisabled(%data, %obj) {
	if (shouldChangePowerState(%obj,false)) {
		// Must kick players out of turret
		%obj.clearTarget();
		setTargetSensorData(%obj.target, 0);
	}
	Parent::onLosePowerDisabled(%data, %obj);
}

function TurretData::selectTarget(%this, %turret) {
 if($TWM2::TurretsDisabled)
    return;
 %turretTarg = %turret.getTarget();
	if(%turretTarg == -1)
		return;

	// if the turret isn't on a team, don't fire at anyone
	if(getTargetSensorGroup(%turretTarg) == 0) {
		%turret.clearTarget();
		return;
	}

	// stop firing if turret is disabled or if it needs power and isn't powered
	if((!%turret.isPowered()) && (!%turret.needsNoPower)) {
		%turret.clearTarget();
		return;
	}

	%TargetSearchMask = $TypeMasks::PlayerObjectType | $TypeMasks::VehicleObjectType | $TypeMasks::StationObjectType | $TypeMasks::GeneratorObjectType |
	$TypeMasks::SensorObjectType | $TypeMasks::TurretObjectType; //$TypeMasks::StaticObjectType;

	InitContainerRadiusSearch(%turret.getMuzzlePoint(0),
				%turret.getMountedImage(0).attackRadius,
				%TargetSearchMask);

	// TODO - clean up this mess + GameBaseData::hasLOS()

	while ((%potentialTarget = ContainerSearchNext()) != 0) {
		if (%potentialtarget) {
			%potTargTarg = %potentialTarget.getTarget();
			if (%turret.isValidTarget(%potentialTarget)
			&& (getTargetSensorGroup(%turretTarg) != getTargetSensorGroup(%potTargTarg))
			&& (getTargetSensorGroup(%potTargTarg) != 0)
			&& ((%potentialTarget.getType() & $TypeMasks::PlayerObjectType) || !$TurretOnlyTargetPlayers)
			&& %this.hasLOS(%turret, 0, %potentialTarget)) {
				if (%potentialTarget.homingCount > 0 && !%secondTarg) {
					if (!%firstTarg)
						%firstTarg = %potentialTarget;
					else
						%secondTarg = %potentialTarget;
				}
				else {
					%turret.setTargetObject(%potentialTarget);
					%turret.aquireTime = getSimTime();
					return;
				}
			}
		    else if(%potentialTarget.iszombie) {
		       %turret.setTargetObject(%potentialTarget);
		       return;
            }
            else if(%potentialTarget.isBoss) {
               %dbN = %turret.getDatablock().getName();
               if(%dbN !$= "PlatFormPlasma" && %dbN !$= "PlatFormMissile"
                  && %dbN !$= "PlatFormMortar") {
                     %turret.setTargetObject(%potentialTarget);
                     return;
                  }
            }
		}
	}
	if (%secondTarg) {
		%turret.setTargetObject(%firstTarg);
		%turret.aquireTime = getSimTime();
		return;
	}
	if (%firstTarg) {
		%turret.setTargetObject(%firstTarg);
		%turret.aquireTime = getSimTime();
		return;
	}
}

function TurretData::replaceCallback(%this, %turret, %engineer)
{
   // This is a valid replacement.  First, let's see if the engineer
   //  still has the correct pack in place...
   if (%engineer.getMountedImage($BackPackSlot) != 0)
   {
      %barrel = %engineer.getMountedImage($BackPackSlot).turretBarrel;
      if (%barrel !$= "")
      {
         // if there was a barrel there before, get rid of it
         %turret.unmountImage(0);
         // remove the turret barrel pack
         %engineer.setInventory(%engineer.getMountedImage($BackPackSlot).item, 0);
         // mount new barrel on base
         %turret.mountImage(%barrel, 0, false);
      }
      else
      {
         // Player doesn't have the correct pack on...
      }
   }
   else
   {
      // Player doesn't have any pack on...
   }
}

function TurretData::onDestroyed(%this, %turret, %prevState)
{
   if( isObject( %turret.lastProjectile ) )
      %turret.lastProjectile.delete();

   Parent::onDestroyed(%this, %turret, %prevState);
}

function checkTurretMount(%data, %obj, %slot)
{
   // search for a turret base in player's LOS
   %eyeVec = VectorNormalize(%obj.getEyeVector());
   %srchRange = VectorScale(%eyeVec, 5.0); // look 5m for a turret base
   %plTm = %obj.getEyeTransform();
   %plyrLoc = firstWord(%plTm) @ " " @ getWord(%plTm, 1) @ " " @ getWord(%plTm, 2);
   %srchEnd = VectorAdd(%plyrLoc, %srchRange);
   %potTurret = ContainerRayCast(%obj.getEyeTransform(), %srchEnd, $TypeMasks::TurretObjectType);
   if(%potTurret != 0)
   {
      %otherMountObj = "foo";

	if(%potTurret.getDatablock().getName() $= "TurretBaseLarge"
	|| %potTurret.getDatablock().getName() $= %otherMountObj
	|| %potTurret.getDatablock().getName() $= "TurretDeployedBase")
      {
         // found a turret base, what team is it on?
         if(%potTurret.team == %obj.client.team)
         {
				if(%potTurret.getDamageState() !$= "Enabled")
				{
					// the base is destroyed
					messageClient(%obj.client, 'MsgBaseDestroyed', "\c2Turret base is disabled, cannot mount barrel.");
					%obj.setImageTrigger($BackpackSlot, false);
				}
				else
				{
		         // it's a functional turret base on our team! stick the barrel on it
		         messageClient(%obj.client, 'MsgTurretMount', "\c2Mounting barrel pack on turret base.");
		         serverPlay3D(TurretPackActivateSound, %potTurret.getTransform());
		         %potTurret.initiateBarrelSwap(%obj);
				}
         }
         else
         {
            // whoops, wrong team
            messageClient(%obj.client, 'MsgTryEnemyTurretMount', "\c2Cannot mount a barrel on an enemy turret base!");
            %obj.setImageTrigger($BackpackSlot, false);
         }
      }
      else
      {
         // tried to mount barrel on some other turret type
         messageClient(%obj.client, 'MsgNotTurretBase', "\c2Can only mount a barrel on a turret base.");
         %obj.setImageTrigger($BackpackSlot, false);
      }
   }
   else
   {
      // I don't see any turret
      messageClient(%obj.client, 'MsgNoTurretBase', "\c2No turret within range.");
      %obj.setImageTrigger($BackpackSlot, false);
   }
}

//-------------------------------------- Load Barrel Images
//
exec("scripts/turrets/mortarBarrelLarge.cs");
exec("scripts/turrets/aaBarrelLarge.cs");
exec("scripts/turrets/missileBarrelLarge.cs");
exec("scripts/turrets/plasmaBarrelLarge.cs");
exec("scripts/turrets/ELFBarrelLarge.cs");
exec("scripts/turrets/outdoorDeployableBarrel.cs");
exec("scripts/turrets/indoorDeployableBarrel.cs");
exec("scripts/turrets/sentryTurret.cs");
