//=============================================================================
// CTFFlag.
//=============================================================================
class CTFFlag expands Decoration
	localized;

#exec MESH IMPORT MESH=pflag ANIVFILE=MODELS\pflag_a.3d DATAFILE=MODELS\pflag_d.3d X=0 Y=0 Z=0 ZEROTEX=1
#exec MESH ORIGIN MESH=pflag X=400 Y=0 Z=0

#exec MESH SEQUENCE MESH=pflag SEQ=All   STARTFRAME=0 NUMFRAMES=133
#exec MESH SEQUENCE MESH=pflag SEQ=pflag STARTFRAME=0 NUMFRAMES=133

#exec TEXTURE IMPORT NAME=JpflagB FILE=MODELS\N-Flag-B.PCX GROUP=Skins FLAGS=2 // twosided
#exec TEXTURE IMPORT NAME=JpflagR FILE=MODELS\N-Flag-R.PCX GROUP=Skins FLAGS=2 // twosided

#exec MESHMAP NEW   MESHMAP=pflag MESH=pflag
#exec MESHMAP SCALE MESHMAP=pflag X=0.1 Y=0.1 Z=0.2

#exec MESHMAP SETTEXTURE MESHMAP=pflag NUM=1 TEXTURE=JpflagB

var byte	 	 Team;      	
var bool bHome;
var bool bKnownLocation; //for bot AI
var bool bHeld;
var Pawn		Holder;
var FlagBase	HomeBase;
var localized string[64] HasThe;
var localized string[32] FlagStr;
var localized string[32] TheStr;
var localized string[64] ReturnedStr;
var localized string[64] DroppedThe;

replication
{
	reliable if ( Role == ROLE_Authority )
		Team, bHome, bHeld;
}

function PostBeginPlay()
{
	Super.PostBeginPlay();
	LoopAnim('pflag');
}

event FellOutOfWorld()
{
	if ( Holder != None )
	{
		FollowHolder(Holder);
		GotoState('Held');
	}
	else
		SendHome();
}
	
function SendHome()
{
	local Pawn aPawn;

	//log(self$" sent home");
	bHidden = true;
	HomeBase.bHidden = false;
	bCollideWorld = false;
	if ( Holder != None )
		Holder.PlayerReplicationInfo.HasFlag = None;
	Holder = None;
	bHeld = false;
	SetPhysics(PHYS_None);
	HomeBase.AmbientSound = None;
	bHome = true;
	SetLocation(HomeBase.Location);
	SetRotation(HomeBase.Rotation);
	SetCollision(true,false,false);
	SetBase(None);
	For (aPawn = Level.PawnList; aPawn!=None; aPawn=aPawn.nextPawn )
		if ( aPawn.MoveTarget == self )
			aPawn.MoveTimer = -1.0;
	GotoState('Dropped');
	SetTimer(1.0, true);
}

function SetHolder()
{
	//log(self$" set holder "$holder);
	bHidden = false;
	HomeBase.bHidden = true;
	HomeBase.PlayAlarm();
	bHome = false;
	SetPhysics(PHYS_None);
	SetCollision(false, false, false);
	FollowHolder(Holder);
	GotoState('Held');
}

simulated function FollowHolder(Actor Other)
{
	local vector X,Y,Z;

	GetAxes(Other.Rotation, X,Y,Z);
	SetRotation(rotator(-1 * X));
 	SetLocation(Other.Location - 2 * Other.CollisionRadius * X + Other.CollisionHeight * vect(0,0,0.5));
	SetBase(Other);
}
	
function Landed(vector HitNormall)
{
	local rotator NewRot;

	//log(self$" landed with coll "$bCollideActors);
	NewRot = Rot(16384,0,0);
	NewRot.Yaw = Rotation.Yaw;
	SetRotation(NewRot);
}


function BaseChange()
{
	if ( (Holder != None) && (Base != Holder) )
	{
		//log(self$" reset to holder "$holder);
		FollowHolder(Holder);
		GotoState('Held');
	}
}

function Drop(vector newVel)
{
	local Pawn OldHolder;

	BroadCastMessage(Holder.PlayerReplicationInfo.PlayerName$DroppedThe$CTFGame(Level.Game).Teams[Team].TeamName$FlagStr, true, 'CriticalEvent');
	RotationRate.Yaw = Rand(200000) - 100000;
	RotationRate.Pitch = Rand(200000 - Abs(RotationRate.Yaw)) - 0.5 * (200000 - Abs(RotationRate.Yaw));
	Velocity = (0.2 + FRand()) * (newVel + 400 * FRand() * VRand());
	If (Region.Zone.bWaterZone)
		Velocity *= 0.5;
	SetTimer(12.0, false);
	bCollideWorld = true;
	OldHolder = Holder;
	Holder.PlayerReplicationInfo.HasFlag = None;
	Holder = None;
	bHeld = false;
	if ( SetLocation(Location) || SetLocation(OldHolder.Location) )
		SetPhysics(PHYS_Falling);
	SetBase(None);
	SetCollision(true, false, false);
	GotoState('Dropped');
}

function Timer()
{
	if ( !bHome || (VSize(Location - HomeBase.Location) > 10) )
	{
		//log(self$" Timed home");
		SendHome();
		BroadCastMessage(TheStr$CTFGame(Level.Game).Teams[Team].TeamName$ReturnedStr, true, 'CriticalEvent');
	}
}
	
function TakeDamage( int Damage, Pawn instigatedBy, Vector hitlocation, 
						Vector momentum, name damageType)
{
	if ( (instigatedBy == None) && (Holder == None) )
		Timer();
}
	
auto state Dropped
{
	function Touch(Actor Other)
	{
		local CTFFlag aFlag;
		local Pawn aPawn;
		local NavigationPoint N;
		local int num, i;

		if ( Other.IsA('Pawn') && Pawn(Other).bIsPlayer
			&& (Pawn(Other).Health > 0) )
		{
			//log(self$" touched by "$Other);
			bCollideWorld = false;
			bKnownLocation = false;
			SetTimer(0.0, false);
			Holder = Pawn(Other);
			Holder.PlayerReplicationInfo.HasFlag = self;
			bHeld = true;
			if ( Holder.PlayerReplicationInfo.Team == Team )
			{
				if ( !bHome )
				{
					// returned flag
					CTFGame(Level.Game).ScoreFlag(Holder, self);
					SendHome();
				}
				else
				{
					// check if scored capture
					for ( i=0; i<2; i++ )
					{
						aFlag=CTFReplicationInfo(Level.Game.GameReplicationInfo).FlagList[i];
						if ( (aFlag != self) && (aFlag.Holder == Holder) )
						{
							//Score!
							CTFGame(Level.Game).ScoreFlag(Holder, aFlag);
							aFlag.SendHome();
						}
					}
					bHeld = false;
					Holder.PlayerReplicationInfo.HasFlag = None;
					Holder = None;
				}
				return;
			}
			else if ( Holder.IsA('Bot') )
			{
				if ( Bot(Holder).Orders == 'Attack' )
				{
					Bot(Holder).AlternatePath = None;
					if ( bHome && (FRand() < 0.5) )
						for ( N=Level.NavigationPointList; N!=None; N=N.nextNavigationPoint )
							if ( N.IsA('AlternatePath') && (AlternatePath(N).team == Holder.PlayerReplicationInfo.team) )
							{
								num++;
								if ( (num == 1) || (Rand(num) == 1) )
									Bot(Holder).AlternatePath = AlternatePath(N);
							}
				}	
				Bot(Holder).SendTeamMessage(None, 'OTHER', 2, 10);
			}
			BroadCastMessage(Holder.PlayerReplicationInfo.PlayerName$HasThe$CTFGame(Level.Game).Teams[Team].TeamName$FlagStr, true, 'CriticalEvent');
			SetHolder();
		}
	}
}

state Held
{
	function Tick(float DeltaTime)
	{
		FollowHolder(Holder);
	}
}		

defaultproperties
{
	 bHidden=true
	 bStasis=false
	 Skin=JpFlagB
     bHome=True
     HasThe=" has the "
     FlagStr=" flag "
     TheStr="The "
     ReturnedStr=" flag was returned."
     DroppedThe=" dropped the "
     bStatic=False
	 DrawScale=0.6
     DrawType=DT_Mesh
	 Style=STY_Masked
     Mesh=Mesh'BotPack.pflag'
     bUnlit=True
     bAlwaysRelevant=True
     CollisionRadius=24.000000
     CollisionHeight=30.000000
     bCollideActors=True
     LightType=LT_Steady
     LightEffect=LE_NonIncidence
     LightBrightness=255
     LightHue=170
     LightRadius=6
     bFixedRotationDir=True
     Mass=30.000000
     Buoyancy=27.000000
     RotationRate=(Pitch=30000,Roll=30000)
}
