//=============================================================================
// CoopGame.
//=============================================================================
class CoopGame expands UnrealGameInfo
	config;

var() config bool	bNoFriendlyFire;

function bool IsRelevant(actor Other)
{
	// hide all playerpawns

	if ( Other.IsA('PlayerPawn') )
	{
		Other.SetCollision(false,false,false);
		Other.bHidden = true;
	}
	return CallParent.IsRelevant(Other);
}

event playerpawn Login
(
	string[32]     Portal,
	string[120]    Options,
	out string[80] Error,
	class          SpawnClass
)
{
	local NavigationPoint StartSpot;
	local PlayerPawn      NewPlayer;
	local string[64]      InName, InTeam, InPassword;
	local pawn			  aPawn;

	// Get options.
	InName     = ParseOption( Options, "Name"     );
	InPassword = ParseOption( Options, "Password" );

	aPawn = Level.PawnList;
	while ( aPawn != None )
	{
		if ( aPawn.IsA('PlayerPawn') && (PlayerPawn(aPawn).Player == None )
			&& (aPawn.PlayerName	~= InName) && (PlayerPawn(aPawn).Password ~= InPassword) )
				return PlayerPawn(aPawn);
		aPawn = aPawn.nextPawn;
	}
	return CallParent.Login(Portal, Options, Error, SpawnClass);
}
	
function NavigationPoint FindPlayerStart(optional byte team, optional string[32] incomingName)
{
	local PlayerStart Dest, Candidate[8], Best;
	local float Score[8], BestScore, NextDist;
	local pawn OtherPlayer;
	local int i, num;
	local Teleporter Tel;

	if( incomingName!="" )
		foreach AllActors( class 'Teleporter', Tel )
			if( string(Tel.Tag)~=incomingName )
				return Tel;

	num = 0;
	//choose candidates	
	foreach AllActors( class 'PlayerStart', Dest )
	{
		if (Dest.bSinglePlayerStart || Dest.bCoopStart)
		{
			if (num<8)
				Candidate[num] = Dest;
			else if (Rand(num) < 8)
				Candidate[Rand(8)] = Dest;
			num++;
		}
	}
	
	if (num>8) num = 8;
	else if (num == 0)
		return None;
		
	//assess candidates
	for (i=0;i<num;i++)
		Score[i] = 0; 
		
	foreach AllActors( class 'Pawn', OtherPlayer )
	{
		if (OtherPlayer.bIsPlayer)
		{
			for (i=0;i<num;i++)
			{
				NextDist = Size(OtherPlayer.Location - Candidate[i].Location);
				if (NextDist < CollisionRadius + CollisionHeight)
					Score[i] -= 1000000.0;
			}
		}
	}
	
	BestScore = Score[0];
	Best = Candidate[0];
	for (i=1;i<num;i++)
	{
		if (Score[i] > BestScore)
		{
			BestScore = Score[i];
			Best = Candidate[i];
		}
	}			
	
	//if (BestScore < -500000.0) //then would telefrag - but then how to handle re-try?
	//	return None;
				
	return Best;
}

function int ReduceDamage(int Damage, name DamageType, pawn injured, pawn instigatedBy)
{
	if (injured.Region.Zone.bNeutralZone)
		return 0;

	if ( instigatedBy == None )
		return Damage;
		
	if ( instigatedBy.bIsPlayer )
	{
		if (injured.bIsPlayer)
		{
			if (bNoFriendlyFire && (instigatedBy != injured) )
				return 0;
		}
		else
			Damage = float(Damage) * (1.0 - 0.1 * injured.skill);
	}
	else //skill level modification
		Damage = float(Damage) * (0.5 + 0.25 * instigatedBy.skill);
			
	return (Damage * instigatedBy.DamageScaling);
}

function bool PickupQuery(Pawn Other, Inventory item)
{
	if ( item.IsA('Weapon') && (Other.FindInventoryType(item.class) != None) )
		return false;
	else
		return CallParent.PickupQuery(Other, item);
}

function bool ShouldRespawn(Actor Other)
{
	if ( Other.IsA('Weapon') )
	{
		Inventory(Other).ReSpawnTime = 1.0;
		return true;
	}
	return false;
}

