class CCTVCamera extends SecurityCamera;

#exec obj load file=..\Textures\CoreTexMetal.utx package=CoreTexMetal
#exec obj load file=..\Textures\Effects.utx package=Effects

var DeusExPlayer Lagbot;
var() int Penalty;


function HackAction(Actor Hacker, bool bHacked)
{
}


auto state Active
{
function TakeDamage(int Damage, Pawn EventInstigator, vector HitLocation, vector Momentum, name DamageType)
{
}
}

function Actor AcquireMultiplayerTarget()
{
   local Pawn apawn;
	local DeusExPlayer aplayer;
	local Vector dist;

   //DEUS_EX AMSD See if our old target is still valid.
   if ((prevtarget != None) && (prevtarget != safetarget) && (Pawn(prevtarget) != None))
   {
      if (Pawn(prevtarget).AICanSee(self, 1.0, false, false, false, true) > 0)
      {
         if (DeusExPlayer(prevtarget) == None)         
         {
            curtarget = prevtarget;
            return curtarget;
         }
         else
         {
            if (DeusExPlayer(prevtarget).AugmentationSystem.GetAugLevelValue(class'AugRadarTrans') == -1.0)
            {
               curtarget = prevtarget;
               return curtarget;
            }
         }
      }
   }
	// MB Optimized to use pawn list, previous way used foreach VisibleActors
	apawn = Level.PawnList;
	while ( apawn != None )
	{
      if (apawn.bDetectable && !apawn.bIgnore && apawn.IsA('DeusExPlayer'))
      {
			aplayer = DeusExPlayer(apawn);

			dist = aplayer.Location - Location;

			if ( VSize(dist) < CameraRange )
			{
				// Only players we can see
				if ( aplayer.FastTrace( aplayer.Location, Location ))
				{
					//only track players who aren't the safetarget.
					//we already know prevtarget not valid.
					if ((aplayer != safeTarget) && (aplayer != prevTarget))
					{
							
							if (_MMRPGPlayer(aplayer).GetLightVal() > 0.15)
							{
								curTarget = apawn;
								break;
							}
					}
				}
			}
      }
		apawn = apawn.nextPawn;
	}
   return curtarget;
}


function CheckPlayerVisibility(DeusExPlayer player)
{
	local float yaw, pitch, dist;
	local Actor hit;
	local Vector HitLocation, HitNormal;
	local Rotator rot;

   if (player == None)
      return;
	dist = Abs(VSize(player.Location - Location));

	// if the player is in range
	if (player.bDetectable && !player.bIgnore && (dist <= cameraRange))
	{
		hit = Trace(HitLocation, HitNormal, player.Location, Location, True);
		if (hit == player)
		{
			// If the player's RadarTrans aug is on, the camera can't see him
         // DEUS_EX AMSD In multiplayer, we've already done this test with 
         // AcquireMultiplayerTarget
         if (Level.Netmode == NM_Standalone)
         {
            if (player.AugmentationSystem.GetAugLevelValue(class'AugRadarTrans') != -1.0)
               return;
         }

			// figure out if we can see the player
			rot = Rotator(player.Location - Location);
			rot.Roll = 0;
			yaw = (Abs(Rotation.Yaw - rot.Yaw)) % 65536;
			pitch = (Abs(Rotation.Pitch - rot.Pitch)) % 65536;

			// center the angles around zero
			if (yaw > 32767)
				yaw -= 65536;
			if (pitch > 32767)
				pitch -= 65536;

			// if we are in the camera's FOV
			if ((Abs(yaw) < cameraFOV) && (Abs(pitch) < cameraFOV))
			{
				lagbot = Player;
				// rotate to face the player
				//if (bTrackPlayer)
					//DesiredRotation = rot;

				lastSeenTimer = 0;
				bPlayerSeen = True;
				bTrackPlayer = True;
            bFoundCurPlayer = True;

				playerLocation = player.Location - vect(0,0,1)*(player.CollisionHeight-5);

				// trigger the event if we haven't yet for this sighting
				if (!bEventTriggered && (triggerTimer >= triggerDelay) && (Level.Netmode == NM_Standalone))
				{
					TriggerEvent(True);
				}

				return;
			}
		}
	}
}

function TriggerEvent(bool bTrigger)
{
	bEventTriggered = bTrigger;
	bTrackPlayer = bTrigger;
	triggerTimer = 0;

	// now, the camera sounds its own alarm
	if (bTrigger)
	{
		AmbientSound = Sound'Klaxon2';
		SoundVolume = 255;
		SoundRadius = 128;
		LightHue = 0;
		MultiSkins[1] = Texture'RedLightTex';
		AIStartEvent('Alarm', EAITYPE_Audio, SoundVolume/255.0, 25*(SoundRadius+1));
		//Arrestee.ClientMessage("You have been arrested for thieving!");

		// make sure we can't go into stasis while we're alarming
		bStasis = False;


	}
	else
	{
		AmbientSound = Sound'CameraHum';
		SoundRadius = 48;
		SoundVolume = 192;
		LightHue = 80;
		MultiSkins[1] = Texture'GreenLightTex';
		AIEndEvent('Alarm', EAITYPE_Audio);

		// reset our stasis info
		bStasis = Default.bStasis;
	}
}



function Tick(float deltaTime)
{
	local float ang;
	local Rotator rot;
   local DeusExPlayer curplayer;
	local _MMRPGPlayer MMP;

   Super(HackableDevices).Tick(deltaTime);

   curTarget = None;

   // if this camera is not active, get out
	if (!bActive)
	{
      // DEUS_EX AMSD For multiplayer
      ReplicatedRotation = DesiredRotation;

		MultiSkins[1] = Texture'BlackMaskTex';
		return;
	}

	// if we've been EMP'ed, act confused
	if (bConfused)
	{
		confusionTimer += deltaTime;

		// pick a random facing at random
		if (confusionTimer % 0.25 > 0.2)
		{
			//DesiredRotation.Pitch = origRot.Pitch + 0.5*swingAngle - Rand(swingAngle);
			//DesiredRotation.Yaw = origRot.Yaw + 0.5*swingAngle - Rand(swingAngle);
		}

		if (confusionTimer > confusionDuration)
		{
			bConfused = False;
			confusionTimer = 0;
			confusionDuration = Default.confusionDuration;
			LightHue = 80;
			MultiSkins[1] = Texture'GreenLightTex';
			SoundPitch = 64;
			//DesiredRotation = origRot;
		}

		return;
	}


	// check the player's visibility every 0.1 seconds
	if (!bNoAlarm)
	{
		playerCheckTimer += deltaTime;

		if (playerCheckTimer > 0.1)
		{
			playerCheckTimer = 0;
         if (Level.NetMode == NM_Standalone)
            CheckPlayerVisibility(DeusExPlayer(GetPlayerPawn()));
         else
         {
            curPlayer = DeusExPlayer(AcquireMultiplayerTarget());
            if (curPlayer != None)
               CheckPlayerVisibility(curPlayer);
         }
		}
	}

	// forget about the player after a set amount of time
	if (bPlayerSeen)
	{
		// if the player has been seen, but the camera hasn't triggered yet,
		// provide some feedback to the player (light and sound)
		if (!bEventTriggered)
		{
			triggerTimer += deltaTime;

			if(lagbot != None)
			{
				lagbot.ClientMessage("You have set off the alarm!");

				if(_MMRPGPlayer(lagbot) != None)
				{

					_MMRPGPlayer(lagbot).SendJail(Penalty);
				}

				lagbot = None;
			}

			if (triggerTimer % 0.5 > 0.4)
			{
				LightHue = 0;
				MultiSkins[1] = Texture'RedLightTex';
				PlaySound(Sound'Beep6',,,, 1280);
			}
			else
			{
				LightHue = 80;
				MultiSkins[1] = Texture'GreenLightTex';
			}
		}

		if (lastSeenTimer < memoryTime)
			lastSeenTimer += deltaTime;
		else
		{
			lastSeenTimer = 0;
			bPlayerSeen = False;

			// untrigger the event
			TriggerEvent(False);
		}

		return;
	}

	swingTimer += deltaTime;
	MultiSkins[1] = Texture'GreenLightTex';

	// swing back and forth if all is well
	if (bSwing && !bTrackPlayer)
	{
		ang = 2 * Pi * swingTimer / swingPeriod;
		rot = origRot;
		rot.Yaw += Sin(ang) * swingAngle;
		DesiredRotation = rot;
	}

   // DEUS_EX AMSD For multiplayer
   ReplicatedRotation = DesiredRotation;
}


defaultproperties
{
  Penalty=50
  confusionDuration=8.000000
  cameraFOV=4096
  bSwing=False
  Mesh=Mesh'ContenderStuff.cctv'
  CollisionRadius=25
  CollisionHeight=25
  MultiSkins(0)=Texture'CoreTexMetal.Metal.ShipGrayMetal_A'
  MultiSkins(1)=Texture'DeusExItems.Skins.RedLightTex'
  MultiSkins(2)=Texture'Effects.Corona.Corona_G'
}
