class CyBotGuns expands CyBot
abstract;

#exec AUDIO IMPORT NAME="Z_Amb" FILE=SOUNDS\Z_Amb.wav GROUP="Cybot"
#exec AUDIO IMPORT NAME="Cybot_ZYFire" FILE=SOUNDS\Cybot_ZYFire.wav GROUP="Cybot"
#exec AUDIO IMPORT NAME="Cybot_SZYFire" FILE=SOUNDS\Cybot_SZYFire.wav GROUP="Cybot"

var byte Team, RndMoveCount;
var() float FireRate, SensorRadius;
var() class<ZY_Proj> CybotProj;
var() bool ZPositive;
var() texture ProjFX01[4], ProjFX02[4];
var() sound FireSound;
var bool bReady;
var Pawn PEnemy;
var float RateCount;

replication
{
	reliable if(Role == ROLE_Authority)
		PEnemy;
}

simulated function PostBeginPlay()
{
	PlayAnim('Openning', 0.4, 0.0);
	Team = Instigator.PlayerReplicationInfo.Team;
	DesiredRotation = Rotation;

	SetTimer(1/FMax(FireRate, 0.1), True);
}


function Timer()
{
local Pawn P, PTarget;
local bool bEnemy, bHavePawnSet;

	if (bReady)
	{

	ForEach VisibleCollidingActors(Class'Pawn', P, FMax(SensorRadius, 10))
	{

		bEnemy = CheckEnemy(P);
		
		if (bEnemy && !bHavePawnSet)
			bHavePawnSet = True;

		if (bEnemy && PTarget == None)
			PTarget = P;
		else if (bEnemy && PTarget != None)
		{
			//Attack the closest enemy pawn
			if (Vsize(Location - P.Location) < VSize(Location - PTarget.Location))
				PTarget = P;
		}
	}

	PEnemy = PTarget;

	}
}


simulated function Tick(float DeltaTime)
{
local float Amplitude;

	RateCount += DeltaTime;

	if (RateCount >= 1/FMax(FireRate, 0.1) && bReady)
	{

	RateCount = 0;

	if (PEnemy != None)
	{
		if ((PEnemy.Location.Z < Location.Z && ZPositive) || (PEnemy.Location.Z > Location.Z && !ZPositive))
				DesiredRotation = rotator(PEnemy.Location - Location).Yaw * rot(0,1,0);
			else
				DesiredRotation = rotator(PEnemy.Location - Location);

			CalcRate();

			Amplitude = VSize((vector(Rotation) * 20) - (vector(DesiredRotation) * 20));

			if (Amplitude < 8)
			{
				FireProjectile();
				PlayProjectileFiring();
			}
	}

	RndMoveCount++;

	if (RndMoveCount >= 4)
		RndMoveCount = 0;

	if (RndMoveCount == 0 && PEnemy == None)
	{
		if (ZPositive)
			DesiredRotation = (Rand(32768)*2 - 32768) * rot(0,1,0) + (Rand(8192)) * rot(1,0,0);
		else
			DesiredRotation = (Rand(32768)*2 - 32768) * rot(0,1,0) + (-Rand(8192)) * rot(1,0,0);
		
		CalcRate();
	}

	}

}


function bool CheckEnemy( pawn PotentialP)
{
	if ((PotentialP.Location.Z + PotentialP.CollisionHeight < Location.Z && ZPositive) || (PotentialP.Location.Z - PotentialP.CollisionHeight > Location.Z && !ZPositive)
		|| PotentialP.Tag == 'NoCybotEnemy' || PotentialP.Tag == 'IsFriend')
			return False;
		else if (PotentialP.IsA('StationaryPawn'))
			return False;
		else if (Level.Game.IsA('MonsterHunt') && !PotentialP.IsA('ScriptedPawn'))
			return False;
		else if (Level.Game.IsA('MonsterHunt') && PotentialP.IsA('ScriptedPawn'))
			return True;
		else if (PotentialP == Instigator)
			return False;
		else if (TeamGamePlus(Level.Game) != None)
		{
			if (PotentialP.PlayerReplicationInfo.Team == Instigator.PlayerReplicationInfo.Team)
				return False;
		}
		else if (!Level.Game.IsA('DeathMatchPlus'))
		{
			if (PotentialP.IsA('ScriptedPawn') && Instigator.IsA('ScriptedPawn'))
			{
				if (ScriptedPawn(PotentialP).TeamTag == ScriptedPawn(Instigator).TeamTag && ScriptedPawn(PotentialP).TeamTag != '')
					return False;
			}
			else if (Instigator.IsA('PlayerPawn') && (PotentialP.AttitudeToPlayer == ATTITUDE_Friendly || PotentialP.AttitudeToPlayer == ATTITUDE_Follow))
				return False;
		}

	return True;
}

simulated function CalcRate()
{
		SetRotation(Normalize(Rotation));

		if (DesiredRotation.Pitch > Rotation.Pitch)
			RotationRate.Pitch = Default.RotationRate.Pitch;
		else
			RotationRate.Pitch = -Default.RotationRate.Pitch;

	//More complex rotation calculations, since it must obbey to the quadrants proximity
	if (DesiredRotation.Yaw > 16384 && Normalize(Rotation).Yaw < -16384)
		RotationRate.Yaw = -Default.RotationRate.Yaw;
	else if (DesiredRotation.Yaw < -16384 && Normalize(Rotation).Yaw > 16384)
		RotationRate.Yaw = Default.RotationRate.Yaw;
	else
	{
		if (DesiredRotation.Yaw > Normalize(Rotation).Yaw)
			RotationRate.Yaw = Default.RotationRate.Yaw;
		else
			RotationRate.Yaw = -Default.RotationRate.Yaw;
	}

	/*log("__________________________________________________________________________________________________");
	log("Current Rotation = (Pitch = " $ Rotation.Pitch $ "; Yaw = " $ Rotation.Yaw $ " )");
	log("Desired Rotation = (Pitch = " $ DesiredRotation.Pitch $ "; Yaw = " $ DesiredRotation.Yaw $ " )");
	log("Rotation Rate = (Pitch = " $ RotationRate.Pitch $ "; Yaw = " $ RotationRate.Yaw $ " )");
	log("__________________________________________________________________________________________________");*/
}

function FireProjectile()
{
local ZY_Proj zyp;

	zyp = Spawn(CybotProj);
	
	if (Class'NWMutator'.default.bCybotID_InTeamGames && Level.Game.IsA('TeamGamePlus') && !Level.Game.IsA('MonsterHunt'))
	{
		zyp.MultiSkins[0] = ProjFX01[Team];
		zyp.MultiSkins[1] = ProjFX02[Team];
	}
}

simulated function PlayProjectileFiring()
{
	PlaySound(FireSound,,32.0);
	PlayAnim('Fire', 2.0, 0.0);
}


function SpawnWreckedPiece( vector SpawnDir)
{
local WreckedPiece wp;

	wp = Spawn(Class'WreckedPiece',,, Location, rotator(vect(0,0,20) + SpawnDir.X * vect(1,0,0) + SpawnDir.Y * vect(0,1,0)));
	GiveProperties(wp);
}

simulated function GiveProperties(actor A)
{
	A.AnimSequence = AnimSequence;
	A.AnimFrame = AnimFrame;
	A.DrawScale = DrawScale;
	A.Mesh = Mesh;

	Destroy();
}


defaultproperties
{
	RemoteRole=ROLE_SimulatedProxy
	LifeSpan=0.000000
	bNetTemporary=False
	SoundVolume=40
	SoundRadius=60
	RotationRate=(Pitch=40000,Yaw=40000)
	ProjFX01(0)=Texture'UnrealShare.Effect1.FireEffect1p'
	ProjFX01(1)=Texture'UnrealShare.Effect1.FireEffect1u'
	ProjFX01(2)=Texture'UnrealShare.Effect1.FireEffect1a'
	ProjFX01(3)=Texture'UnrealShare.Effect1.FireEffect1e'
	ProjFX02(0)=Texture'UnrealShare.Effect1.FireEffect1ob'
	ProjFX02(1)=Texture'UnrealShare.Effect1.FireEffect1t'
	ProjFX02(2)=Texture'UnrealShare.Effect1.FireEffect1'
	ProjFX02(3)=Texture'UnrealShare.Effect1.FireEffect1d'
	Physics=PHYS_Projectile
}
