UnrealShare
Class TeamGame

source: e:\games\UnrealTournament\UnrealShare\Classes\TeamGame.uc
Core.Object
   |
   +--Engine.Actor
      |
      +--Engine.Info
         |
         +--Engine.GameInfo
            |
            +--UnrealShare.UnrealGameInfo
               |
               +--UnrealShare.DeathMatchGame
                  |
                  +--UnrealShare.TeamGame
Direct Known Subclasses:None

class TeamGame
extends UnrealShare.DeathMatchGame

//============================================================================= // TeamGame. //=============================================================================
Variables
 float FriendlyFireScale
           scale friendly fire damage by this value
 float GoalTeamScore
           like fraglimit
 int MaxTeamSize
           like fraglimit
 int MaxTeams
           Maximum number of teams allowed in (up to 16)
 string NewTeamMessage
           like fraglimit
 TEAM_Green, TEAM_Gold
           like fraglimit
 string TeamColor[4]
           like fraglimit
 bool bNoTeamChanges
 bool bSpawnInTeamArea


Function Summary
 bool AddBot()
 void AddToTeam(int num, Pawn Other)
 bool CanSpectate(Pawn Viewer, Actor ViewTarget)
 bool ChangeTeam(Pawn Other, int NewTeam)
 NavigationPoint FindPlayerStart(Pawn Player, optional byte, optional string)
 void Killed(Pawn killer, Pawn Other, name damageType)
 void Logout(Pawn Exiting)
 void PostBeginPlay()
 int ReduceDamage(int Damage, name DamageType, Pawn injured, Pawn instigatedBy)
     
//Use reduce damage for teamplay modifications, etc.



Source Code


00001	//=============================================================================
00002	// TeamGame.
00003	//=============================================================================
00004	class TeamGame extends DeathMatchGame;
00005	
00006	var() config bool   bSpawnInTeamArea;
00007	var() config bool	bNoTeamChanges;
00008	var() config float  FriendlyFireScale; //scale friendly fire damage by this value
00009	var() config int	MaxTeams; //Maximum number of teams allowed in (up to 16)
00010	var	TeamInfo Teams[16]; 
00011	var() config float  GoalTeamScore; //like fraglimit
00012	var() config int	MaxTeamSize;
00013	var  localized string NewTeamMessage;
00014	var		int			NextBotTeam;
00015	var byte TEAM_Red, TEAM_Blue, TEAM_Green, TEAM_Gold;
00016	var localized string TeamColor[4];
00017	
00018	function PostBeginPlay()
00019	{
00020		local int i;
00021		for (i=0;i<4;i++)
00022		{
00023			Teams[i] = Spawn(class'TeamInfo');
00024			Teams[i].Size = 0;
00025			Teams[i].Score = 0;
00026			Teams[i].TeamName = TeamColor[i];
00027			Teams[i].TeamIndex = i;
00028		}
00029		Super.PostBeginPlay();
00030	}
00031	
00032	event InitGame( string Options, out string Error )
00033	{
00034		Super.InitGame(Options, Error);
00035		GoalTeamScore = FragLimit;
00036	}
00037	
00038	//------------------------------------------------------------------------------
00039	// Player start functions
00040	
00041	
00042	//FindPlayerStart
00043	//- add teamnames as new teams enter
00044	//- choose team spawn point if bSpawnInTeamArea
00045	
00046	function playerpawn Login
00047	(
00048		string Portal,
00049		string Options,
00050		out string Error,
00051		class<playerpawn> SpawnClass
00052	)
00053	{
00054		local PlayerPawn newPlayer;
00055		local NavigationPoint StartSpot;
00056	
00057		newPlayer = Super.Login(Portal, Options, Error, SpawnClass);
00058		if ( newPlayer == None)
00059			return None;
00060	
00061		if ( bSpawnInTeamArea )
00062		{
00063			StartSpot = FindPlayerStart(newPlayer,255, Portal);
00064			if ( StartSpot != None )
00065			{
00066				NewPlayer.SetLocation(StartSpot.Location);
00067				NewPlayer.SetRotation(StartSpot.Rotation);
00068				NewPlayer.ViewRotation = StartSpot.Rotation;
00069				NewPlayer.ClientSetRotation(NewPlayer.Rotation);
00070				StartSpot.PlayTeleportEffect( NewPlayer, true );
00071			}
00072		}
00073					
00074		return newPlayer;
00075	}
00076	
00077	function Logout(pawn Exiting)
00078	{
00079		Super.Logout(Exiting);
00080		if ( Exiting.IsA('Spectator') )
00081			return;
00082		Teams[Exiting.PlayerReplicationInfo.Team].Size--;
00083	}
00084		
00085	function NavigationPoint FindPlayerStart( Pawn Player, optional byte InTeam, optional string incomingName )
00086	{
00087		local PlayerStart Dest, Candidate[4], Best;
00088		local float Score[4], BestScore, NextDist;
00089		local pawn OtherPlayer;
00090		local int i, num;
00091		local Teleporter Tel;
00092		local NavigationPoint N;
00093		local byte Team;
00094	
00095		if ( (Player != None) && (Player.PlayerReplicationInfo != None) )
00096			Team = Player.PlayerReplicationInfo.Team;
00097		else
00098			Team = InTeam;
00099	
00100		if( incomingName!="" )
00101			foreach AllActors( class 'Teleporter', Tel )
00102				if( string(Tel.Tag)~=incomingName )
00103					return Tel;
00104				
00105		num = 0;
00106		//choose candidates	
00107		for ( N=Level.NavigationPointList; N!=None; N=N.nextNavigationPoint )
00108			if ( N.IsA('PlayerStart') 
00109				&& (!bSpawnInTeamArea || (Team == PlayerStart(N).TeamNumber)) )
00110			{
00111				if (num<4)
00112					Candidate[num] = PlayerStart(N);
00113				else if (Rand(num) < 4)
00114					Candidate[Rand(4)] = PlayerStart(N);
00115				num++;
00116			}
00117	
00118		if (num == 0 )
00119		{
00120			foreach AllActors( class'PlayerStart', Dest )
00121			{
00122				if (num<4)
00123					Candidate[num] = Dest;
00124				else if (Rand(num) < 4)
00125					Candidate[Rand(4)] = Dest;
00126				num++;
00127			}
00128		}
00129	
00130		if (num>4) num = 4;
00131		else if (num == 0)
00132			return None;
00133			
00134		//assess candidates
00135		for (i=0;i<num;i++)
00136			Score[i] = 4000 * FRand(); //randomize
00137			
00138		for ( OtherPlayer=Level.PawnList; OtherPlayer!=None; OtherPlayer=OtherPlayer.NextPawn)	
00139			if ( OtherPlayer.bIsPlayer && (OtherPlayer.Health > 0) && !OtherPlayer.IsA('Spectator') )
00140				for (i=0;i<num;i++)
00141					if ( OtherPlayer.Region.Zone == Candidate[i].Region.Zone )
00142					{
00143						NextDist = VSize(OtherPlayer.Location - Candidate[i].Location);
00144						if (NextDist < CollisionRadius + CollisionHeight)
00145							Score[i] -= 1000000.0;
00146						else if ( (NextDist < 1400) && (Team != OtherPlayer.PlayerReplicationInfo.Team) && OtherPlayer.LineOfSightTo(Candidate[i]) )
00147							Score[i] -= 10000.0;
00148					}
00149		
00150		BestScore = Score[0];
00151		Best = Candidate[0];
00152		for (i=1;i<num;i++)
00153		{
00154			if (Score[i] > BestScore)
00155			{
00156				BestScore = Score[i];
00157				Best = Candidate[i];
00158			}
00159		}			
00160					
00161		return Best;
00162	}
00163	
00164	function bool AddBot()
00165	{
00166		local NavigationPoint StartSpot;
00167		local bots NewBot;
00168		local int BotN, DesiredTeam;
00169	
00170		BotN = BotConfig.ChooseBotInfo();
00171		
00172		// Find a start spot.
00173		StartSpot = FindPlayerStart(None, 255);
00174		if( StartSpot == None )
00175		{
00176			log("Could not find starting spot for Bot");
00177			return false;
00178		}
00179	
00180		// Try to spawn the player.
00181		NewBot = Spawn(BotConfig.GetBotClass(BotN),,,StartSpot.Location,StartSpot.Rotation);
00182	
00183		if ( NewBot == None )
00184			return false;
00185	
00186		if ( (bHumansOnly || Level.bHumansOnly) && !NewBot.bIsHuman )
00187		{
00188			NewBot.Destroy();
00189			log("Failed to spawn bot");
00190			return false;
00191		}
00192	
00193		StartSpot.PlayTeleportEffect(NewBot, true);
00194	
00195		// Init player's information.
00196		BotConfig.Individualize(NewBot, BotN, NumBots);
00197		NewBot.ViewRotation = StartSpot.Rotation;
00198	
00199		// broadcast a welcome message.
00200		BroadcastMessage( NewBot.PlayerReplicationInfo.PlayerName$EnteredMessage, true );
00201	
00202		AddDefaultInventory( NewBot );
00203		NumBots++;
00204	
00205		DesiredTeam = BotConfig.GetBotTeam(BotN);
00206		if ( (DesiredTeam == 255) || !ChangeTeam(NewBot, DesiredTeam) )
00207		{
00208			ChangeTeam(NewBot, NextBotTeam);
00209			NextBotTeam++;
00210			if ( NextBotTeam >= MaxTeams )
00211				NextBotTeam = 0;
00212		}
00213	
00214		if ( bSpawnInTeamArea )
00215		{
00216			StartSpot = FindPlayerStart(newBot, 255);
00217			if ( StartSpot != None )
00218			{
00219				NewBot.SetLocation(StartSpot.Location);
00220				NewBot.SetRotation(StartSpot.Rotation);
00221				NewBot.ViewRotation = StartSpot.Rotation;
00222				NewBot.ClientSetRotation(NewBot.Rotation);
00223				StartSpot.PlayTeleportEffect( NewBot, true );
00224			}
00225		}
00226	
00227		return true;
00228	}
00229	
00230	//-------------------------------------------------------------------------------------
00231	// Level gameplay modification
00232	
00233	//Use reduce damage for teamplay modifications, etc.
00234	function int ReduceDamage(int Damage, name DamageType, pawn injured, pawn instigatedBy)
00235	{
00236		local int reducedDamage;
00237	
00238		if (injured.Region.Zone.bNeutralZone)
00239			return 0;
00240		
00241		if ( instigatedBy == None )
00242			return Damage;
00243	
00244		Damage *= instigatedBy.DamageScaling;
00245	
00246		if ( (instigatedBy != injured) 
00247			&& (injured.PlayerReplicationInfo.Team ~= instigatedBy.PlayerReplicationInfo.Team) )
00248			return (Damage * FriendlyFireScale);
00249		else
00250			return Damage;
00251	}
00252	
00253	function Killed(pawn killer, pawn Other, name damageType)
00254	{
00255		Super.Killed(killer, Other, damageType);
00256	
00257		if( (killer == Other) || (killer == None) )
00258			Teams[Other.PlayerReplicationInfo.Team].Score -= 1.0;
00259		else
00260			Teams[killer.PlayerReplicationInfo.Team].Score += 1.0;
00261	
00262		if ( (GoalTeamScore > 0) && (Teams[killer.PlayerReplicationInfo.Team].Score >= GoalTeamScore) )
00263			EndGame("teamscorelimit");
00264	}
00265	
00266	function bool ChangeTeam(Pawn Other, int NewTeam)
00267	{
00268		local int i, s;
00269		local pawn APlayer;
00270		local teaminfo SmallestTeam;
00271		local string SkinName, FaceName;
00272	
00273		for( i=0; i<MaxTeams; i++ )
00274			if ( (Teams[i].Size < MaxTeamSize) 
00275					&& ((SmallestTeam == None) || (SmallestTeam.Size > Teams[i].Size)) )
00276			{
00277				s = i;
00278				SmallestTeam = Teams[i];
00279			}
00280	
00281		if ( NewTeam == 255 )
00282			NewTeam = s;
00283	
00284		if ( Other.IsA('Spectator') )
00285		{
00286			Other.PlayerReplicationInfo.Team = NewTeam;
00287			Other.PlayerReplicationInfo.TeamName = Teams[NewTeam].TeamName;
00288			return true;
00289		}
00290		if ( Other.PlayerReplicationInfo.Team != 255 )
00291		{
00292			if ( bNoTeamChanges )
00293				return false;
00294			Teams[Other.PlayerReplicationInfo.Team].Size--;	
00295		}
00296	
00297		for( i=0; i<MaxTeams; i++ )
00298		{
00299			if ( i == NewTeam )
00300			{
00301				if (Teams[i].Size < MaxTeamSize)
00302				{
00303					AddToTeam(i, Other);
00304					return true;
00305				}
00306				else 
00307					break;
00308			}
00309		}
00310	
00311		if ( (SmallestTeam != None) && (SmallestTeam.Size < MaxTeamSize) )
00312		{
00313			AddToTeam(s, Other);
00314			return true;
00315		}
00316	
00317		return false;
00318	}
00319	
00320	function AddToTeam( int num, Pawn Other )
00321	{
00322		local teaminfo aTeam;
00323		local Pawn P;
00324		local bool bSuccess;
00325		local string SkinName, FaceName;
00326	
00327		aTeam = Teams[num];
00328	
00329		aTeam.Size++;
00330		Other.PlayerReplicationInfo.Team = num;
00331		Other.PlayerReplicationInfo.TeamName = aTeam.TeamName;
00332		bSuccess = false;
00333		if ( Other.IsA('PlayerPawn') )
00334			Other.PlayerReplicationInfo.TeamID = 0;
00335		else
00336			Other.PlayerReplicationInfo.TeamID = 1;
00337	
00338		while ( !bSuccess )
00339		{
00340			bSuccess = true;
00341			for ( P=Level.PawnList; P!=None; P=P.nextPawn )
00342	                        if ( P.bIsPlayer && (P != Other) 
00343								&& (P.PlayerReplicationInfo.Team == Other.PlayerReplicationInfo.Team) 
00344								&& (P.PlayerReplicationInfo.TeamId == Other.PlayerReplicationInfo.TeamId) )
00345					bSuccess = false;
00346			if ( !bSuccess )
00347				Other.PlayerReplicationInfo.TeamID++;
00348		}
00349	
00350		BroadcastMessage(Other.PlayerReplicationInfo.PlayerName$NewTeamMessage$aTeam.TeamName, false);
00351	
00352		Other.static.GetMultiSkin(Other, SkinName, FaceName);
00353		Other.static.SetMultiSkin(Other, SkinName, FaceName, num);
00354	}
00355	
00356	function bool CanSpectate( pawn Viewer, actor ViewTarget )
00357	{
00358		return ( (Spectator(Viewer) != None) 
00359				|| ((Pawn(ViewTarget) != None) && (Pawn(ViewTarget).PlayerReplicationInfo.Team == Viewer.PlayerReplicationInfo.Team)) );
00360	}
00361	
00362	defaultproperties
00363	{
00364	     MaxTeams=2
00365	     MaxTeamSize=16
00366	     NewTeamMessage=" is now on "
00367	     TEAM_Blue=1
00368	     TEAM_Green=2
00369	     TEAM_Gold=3
00370	     TeamColor(0)="Red"
00371	     TeamColor(1)="Blue"
00372	     TeamColor(2)="Green"
00373	     TeamColor(3)="Gold"
00374	     bCanChangeSkin=False
00375	     bTeamGame=True
00376	     ScoreBoardType=Class'UnrealShare.UnrealTeamScoreBoard'
00377	     GameMenuType=Class'UnrealShare.UnrealTeamGameOptionsMenu'
00378	     RulesMenuType="UMenu.UMenuTeamGameRulesSClient"
00379	     HUDType=Class'UnrealShare.UnrealTeamHUD'
00380	     BeaconName="Team"
00381	     GameName="Team Game"
00382	}

End Source Code