XIIIMP
Class XIIIMPGameInfo

source: C:\XIII\XIIIMP\Classes\XIIIMPGameInfo.uc
Core.Object
   |
   +--Engine.Actor
      |
      +--Engine.Info
         |
         +--Engine.GameInfo
            |
            +--XIII.XIIIGameInfo
               |
               +--XIIIMP.XIIIMPGameInfo
Direct Known Subclasses:XIIIMPDuckGameInfo, XIIIMPTeamGameInfo

class XIIIMPGameInfo
extends XIII.XIIIGameInfo

//----------------------------------------------------------- // XIIIMJGameInfo || For DeathMatch GamePlay //-----------------------------------------------------------
Variables
 string AltGameName
           To limit up to 2 corpses max on ground in multiplayer
 string BotClassesName[8]
           dynamic load of bot classes
 class BotClasses[8]
           dynamic load of pawn classes
 int BotNumber
           To limit up to 2 corpses max on ground in multiplayer
 Cadavre1, Cadavre2
           To limit up to 2 corpses max on ground in multiplayer
 string EndGameMessage
           To display message when game ended
 float Endtime
           Time remaining before Game End
 NavigationPoint LastPlayerStartSpot
           last place player looking for start spot started from
 NavigationPoint LastStartSpot
           last place any player started from
 GameTypeIndex, MapIndex
           To limit up to 2 corpses max on ground in multiplayer
 ServerName, MapName
           To limit up to 2 corpses max on ground in multiplayer
 float MaxTime
           Maximum duration of a game
 int Mnu_BotLevel[8]
           To limit up to 2 corpses max on ground in multiplayer
 int Mnu_BotNumber
           To limit up to 2 corpses max on ground in multiplayer
 int Mnu_BotTeam[8]
           To limit up to 2 corpses max on ground in multiplayer
 string PawnClassesName[16]
           dynamic load of pawn classes
 class PawnClasses[16]
           E3 CHEAT
 string PreGameEndMessageTimeOut,PostGameEndMessageTimeOut
           Time remaining before Game End
 string PreGameEndMessageWinner,PostGameEndMessageWinner
           Time remaining before Game End
 int RemainingTime
           Time remaining before Game End
 int RestartTimeOut
           To limit up to 2 corpses max on ground in multiplayer
 int SpeudoUsed[28]
           To limit up to 2 corpses max on ground in multiplayer
 int WinningScore
           Maximum Score of a game
 bool bNeedToKeepGSPosted
           To limit up to 2 corpses max on ground in multiplayer
 float fFriendlyFireScale
 hTimeLimit,hLastFragLimit, hFragLimit
           To limit up to 2 corpses max on ground in multiplayer
 string strBotLevel[4]
           To limit up to 2 corpses max on ground in multiplayer
 string strSpeudo[28]
           To limit up to 2 corpses max on ground in multiplayer
 XboxLiveManager xboxlive
           To limit up to 2 corpses max on ground in multiplayer
 String xboxliveName
           To limit up to 2 corpses max on ground in multiplayer

States
MatchOver, MatchInProgress, PendingMatch

Function Summary
 void AddBot(int BotID)
     
//_____________________________________________________________________________
 void ChangeName(Controller Other, string S, bool bNameChange)
     
//_____________________________________________________________________________
 bool CheckEndGame(PlayerReplicationInfo Winner, string Reason)
     
//_____________________________________________________________________________
 void CheckScore(PlayerReplicationInfo Scorer)
     
//_____________________________________________________________________________
 void EndGame(PlayerReplicationInfo Winner, string Reason)
     
//_____________________________________________________________________________
// ELR GameEnded in solo mode = GameOver
 NavigationPoint FindPlayerStart(Controller Player, optional byte, optional string)
     
//_____________________________________________________________________________
// ELR Copy from UW DeathMatch RatePlayerStart
 PlayerReplicationInfo FindWinner()
     
//_____________________________________________________________________________
 void InitGameReplicationInfo()
     
//_____________________________________________________________________________
 void Logout(Controller Exiting)
     
//_____________________________________________________________________________
 void PlayTeleportEffect(Actor Incoming, bool bOut, bool bSound)
     
//_____________________________________________________________________________
// Play a teleporting special effect.
 float RatePlayerStart(NavigationPoint N, byte Team, Controller Player)
     
//_____________________________________________________________________________
// ELR Copy from UW DeathMatch RatePlayerStart
 void ReStartMatch()
     
//_____________________________________________________________________________
//
 void RestartPlayer(Controller aPlayer)
     
//_____________________________________________________________________________
// Restart a player.
 void ScoreKill(Controller Killer, Controller Other)
     
//_____________________________________________________________________________
 void SetGameEndMessage(XIIIGameReplicationInfo TGRI, string reason, PlayerReplicationInfo winner)
     
//_____________________________________________________________________________
 void SetLonePlayer()
     
//_____________________________________________________________________________
 void StartMatch()
     
//_____________________________________________________________________________


State MatchOver Function Summary


State MatchInProgress Function Summary


State PendingMatch Function Summary



Source Code


00001	//-----------------------------------------------------------
00002	// XIIIMJGameInfo || For DeathMatch GamePlay
00003	//-----------------------------------------------------------
00004	class XIIIMPGameInfo extends XIIIGameInfo;
00005	
00006	var float fFriendlyFireScale;
00007	var int WinningScore;          // Maximum Score of a game
00008	var float MaxTime;             // Maximum duration of a game
00009	var int RemainingTime;                // Time remaining before Game End
00010	var float Endtime;
00011	var localized string PreGameEndMessageWinner,PostGameEndMessageWinner;
00012	var localized string PreGameEndMessageTimeOut,PostGameEndMessageTimeOut;
00013	
00014	var NavigationPoint LastPlayerStartSpot;  // last place player looking for start spot started from
00015	var NavigationPoint LastStartSpot;        // last place any player started from
00016	
00017	var string EndGameMessage;            // To display message when game ended
00018	
00019	var class<XIIIPlayerPawn> PawnClasses[16]; // E3 CHEAT
00020	var string PawnClassesName[16];             // dynamic load of pawn classes
00021	var class<XIIIPlayerPawn> BotClasses[8];
00022	var string BotClassesName[8];             // dynamic load of bot classes
00023	
00024	var Pawn Cadavre1, Cadavre2;          // To limit up to 2 corpses max on ground in multiplayer
00025	var int BotNumber;
00026	var string strBotLevel[4];
00027	
00028	var int Mnu_BotLevel[8];
00029	var int Mnu_BotTeam[8];
00030	var int Mnu_BotNumber;
00031	
00032	var string strSpeudo[28];
00033	var int SpeudoUsed[28];
00034	var XboxLiveManager xboxlive;
00035	var String xboxliveName;
00036	var sound hLastMinute, hTimeLimit,hLastFragLimit, hFragLimit;
00037	
00038	var bool bNeedToKeepGSPosted;
00039	var string ServerName, MapName;
00040	VAR localized string AltGameName;
00041	VAR int GameTypeIndex, MapIndex;
00042	var int RestartTimeOut;
00043	
00044	event string GetBeaconText()
00045	{
00046		if ( Level.GetPlateforme()==0 )
00047		{ // PC
00048			return
00049				ServerName
00050				$"|"$ MapName
00051				$"|"$ GameTypeIndex
00052				$"|"$ BeaconName
00053				$"|"$ NumPlayers $"/"$ MaxPlayers;
00054		}
00055		else
00056		{ // X-Box and al.
00057			return
00058				ServerName
00059				$"|"$ MapIndex
00060				$"|"$ GameTypeIndex
00061				$"|"$ BeaconName
00062				$"|"$ NumPlayers $"/"$ MaxPlayers;
00063		}
00064	}
00065	
00066	//_____________________________________________________________________________
00067	function AddBot(int BotID)
00068	{
00069	    local BotController Bot;
00070	
00071	    Bot = spawn( class'BotController');
00072	
00073	    if ( BotClasses[ BotID ] == none )
00074	      BotClasses[ BotID ] = class<XIIIPlayerPawn>(DynamicLoadObject(BotClassesName[ BotID ], class'class'));
00075	
00076	
00077	    Bot.PawnClass = BotClasses[ BotID ];
00078	    Bot.PlayerReplicationInfo.PlayerID = CurrentID++;
00079	    Bot.bIsBot = true;
00080	    Bot.TeamID = Level.BotTeam[BotID];
00081	    Bot.Skill = level.BotLevel[BotID];
00082	    Bot.GRI = GameReplicationInfo;
00083	}
00084	
00085	//_____________________________________________________________________________
00086	// Called BEFORE PreBeginPlay.
00087	event InitGame( string Options, out string Error )
00088	{
00089	    Super.InitGame(Options, Error);
00090	
00091	    ServerName = ParseOption ( Options, "SN" );
00092	    if ( ServerName=="")
00093	      ServerName="InternetServer";
00094	    MaxPlayers = GetIntOption( Options, "NP", 2 );
00095	    fFriendlyFireScale = GetIntOption( Options, "FF", 0 );
00096	    MaxTime = GetIntOption( Options, "TI", 0 ) * 60;
00097	    WinningScore  = GetIntOption( Options, "FR", 0 );
00098	    GameTypeIndex = GetIntOption( Options, "GameIdx", 0 );
00099	    MapIndex = GetIntOption( Options, "MapIdx", 0 );
00100	    MapName = ParseOption( Options, "MapName" );
00101	
00102	    if ( ParseOption ( Options, "Mutator" )!="" )
00103	      GameName = AltGameName;
00104	
00105	    Log(" MaxPlayers:"$MaxPlayers);
00106	    Log(" fFriendlyFireScale:"$fFriendlyFireScale);
00107	    Log(" MaxTime:"$MaxTime);
00108	    Log(" WinningScore:"$WinningScore);
00109	
00110	    if ( !Level.bLonePlayer )
00111	    {
00112	      if ( GameRulesModifiers == None )
00113	        GameRulesModifiers = Spawn(class'XIIIMP.XIIIMPGameRules');
00114	      else
00115	        GameRulesModifiers.AddGameRules(Spawn(class'XIIIMP.XIIIMPGameRules'));
00116	    }
00117	}
00118	
00119	//_____________________________________________________________________________
00120	event PostBeginPlay()
00121	{
00122	    Super.PostBeginPlay();
00123	    SetTimer(1.0, true);
00124	}
00125	
00126	//_____________________________________________________________________________
00127	function SetLonePlayer()
00128	{
00129	    Level.bLonePlayer=false;
00130	}
00131	
00132	//_____________________________________________________________________________
00133	function InitGameReplicationInfo()
00134	{
00135	    Super.InitGameReplicationInfo();
00136	    Log("InitGameReplicationInfo:"$GameReplicationInfo);
00137	
00138	    GameReplicationInfo.GoalScore = WinningScore;
00139	    GameReplicationInfo.TimeLimit = MaxTime;
00140	    GameReplicationInfo.bStopCountDown = true;
00141	    XIIIGameReplicationInfo(GameReplicationInfo).iGameState = 1;
00142	}
00143	
00144	//_____________________________________________________________________________
00145	event PreLogin(string Options, string Address, out string Error, out string FailCode)
00146	{
00147	  local string IP, gamertag;
00148	
00149	  Super.Prelogin(Options, Address, Error, FailCode);
00150	
00151	  gamertag = ParseOption ( Options, "GAMERTAG" );
00152	
00153	  if ( Level.GetPlateForme() == 2 )
00154	  {
00155	    if (xboxlive == none)
00156	      xboxlive=New Class'XboxLiveManager';
00157	    gamertag = xboxlive.UnconvertString(gamertag);
00158	    if (xboxlive.IsLoggedIn(xboxlive.GetCurrentUser()))
00159	    { // Running on Xbox live
00160	      IP = Address;
00161	      if (IP != "")
00162	      { // Client
00163	        Log("Xbox Live IP: "$IP);
00164	        if (!xboxlive.VerifyIPLoggedIn(gamertag, IP))
00165	        {
00166	          Error = GameMessageClass.Default.MaxedOutMessage; // Temp error
00167	          return;
00168	        }
00169	        //xboxliveName = gamertag;//xboxlive.GetGamerTag(IP);
00170	      }
00171	      else
00172	      { // Server
00173	        Log("Xbox Live IP: <LOCALHOST>");
00174	        //xboxliveName = xboxlive.GetCurrentUser();
00175	      }
00176	    }
00177	  }
00178	}
00179	
00180	//_____________________________________________________________________________
00181	//
00182	// Log a player in.
00183	// Fails login if you set the Error string.
00184	// PreLogin is called before Login, but significant game time may pass before
00185	// Login is called, especially if content is downloaded.
00186	//
00187	event PlayerController Login ( string Portal, string Options, out string Error )
00188	{
00189	    local NavigationPoint StartSpot;
00190	    local PlayerController NewPlayer;
00191	    local class<Pawn> DesiredPawnClass;
00192	    local Pawn TestPawn;
00193	    local string InName, InPassword, InChecksum, InClass;
00194	    local byte InTeam;
00195	    local bool bSpectator;
00196	    local int i;
00197	    local Actor A;
00198	    local int BotBumber, Loop;
00199	    local int BotLevel[8];
00200	    local int BotTeam[8];
00201	    local int SkinID;
00202	    local int PlayerTeam[4];
00203	    local int PlayerSkin[4];
00204	    local string InSkinName;
00205	    local MatchMakingManager myMMManager;
00206	
00207	
00208	//    log("");
00209	//    log("_________________________________");
00210	//    log("Parameters");
00211	
00212	    bSpectator = ( ParseOption( Options, "SpectatorOnly" ) != "" );
00213	    InName = "";
00214	
00215	    // Make sure there is capacity. (This might have changed since the PreLogin call).
00216	    if ( AtCapacity(bSpectator) )
00217	    {
00218	      Error=GameMessageClass.Default.MaxedOutMessage;
00219	      return None;
00220	    }
00221	
00222	    BaseMutator.ModifyLogin(Portal, Options);
00223	
00224	    // Get URL options.
00225	    PlayerSkin[0]  = GetIntOption( Options, "PC0", 0 );
00226	    PlayerSkin[1]  = GetIntOption( Options, "PC1", 1 );
00227	    PlayerSkin[2]  = GetIntOption( Options, "PC2", 2 );
00228	    PlayerSkin[3]  = GetIntOption( Options, "PC3", 3 );
00229	
00230	    PlayerTeam[0]  = GetIntOption( Options, "PT0", 0 );
00231	    PlayerTeam[1]  = GetIntOption( Options, "PT1", 1 );
00232	    PlayerTeam[2]  = GetIntOption( Options, "PT2", 0 );
00233	    PlayerTeam[3]  = GetIntOption( Options, "PT3", 1 );
00234	
00235	    if (ParseOption ( Options, "GS" ) != "")
00236	    {
00237	        bNeedToKeepGSPosted = true;
00238	        myMMManager = new(none) class'MatchMakingManager';
00239	        myMMManager.IStartMatch();       // in fact, the server joins its own room...
00240	    }
00241	
00242	    if ( Level.NetMode == NM_StandAlone )
00243	      InTeam = PlayerTeam[NumPlayers];
00244	    else
00245	      InTeam = GetIntOption( Options, "Team", 255 ); // default to "no team"
00246	
00247	    InPassword = ParseOption ( Options, "Password" );
00248	    InChecksum = ParseOption ( Options, "Checksum" );
00249	
00250	    BotBumber  = GetIntOption( Options, "Nbots", Level.BotNumber );
00251	
00252	    BotLevel[0]  = GetIntOption( Options, "Nb0", Level.BotLevel[0] );
00253	    BotLevel[1]  = GetIntOption( Options, "Nb1", Level.BotLevel[1] );
00254	    BotLevel[2]  = GetIntOption( Options, "Nb2", Level.BotLevel[2] );
00255	    BotLevel[3]  = GetIntOption( Options, "Nb3", Level.BotLevel[3] );
00256	    BotLevel[4]  = GetIntOption( Options, "Nb4", Level.BotLevel[4] );
00257	    BotLevel[5]  = GetIntOption( Options, "Nb5", Level.BotLevel[5] );
00258	    BotLevel[6]  = GetIntOption( Options, "Nb6", Level.BotLevel[6] );
00259	
00260	    BotTeam[0]  = GetIntOption( Options, "Tb0", Level.BotTeam[0] );
00261	    BotTeam[1]  = GetIntOption( Options, "Tb1", Level.BotTeam[1] );
00262	    BotTeam[2]  = GetIntOption( Options, "Tb2", Level.BotTeam[2] );
00263	    BotTeam[3]  = GetIntOption( Options, "Tb3", Level.BotTeam[3] );
00264	    BotTeam[4]  = GetIntOption( Options, "Tb4", Level.BotTeam[4] );
00265	    BotTeam[5]  = GetIntOption( Options, "Tb5", Level.BotTeam[5] );
00266	    BotTeam[6]  = GetIntOption( Options, "Tb6", Level.BotTeam[6] );
00267	
00268	//    GameReplicationInfo.GoalScore = WinningScore;
00269	//    GameReplicationInfo.TimeLimit = MaxTime;
00270	
00271	    Level.BotNumber = BotBumber;
00272	
00273	    for( Loop = 0; Loop < 7 ; Loop++ )
00274	    {
00275	        Level.BotLevel[Loop] = BotLevel[Loop];
00276	        Level.BotTeam[Loop] = BotTeam[Loop];
00277	    }
00278	
00279	    log("_________________________________");
00280	    log( "Login LevelNetMode ="@Level.NetMode);
00281	
00282	    log( " Login:" @ InName );
00283	    if( InPassword != "" )
00284	      log( " Password"@InPassword );
00285	
00286	    // Pick a team (if need teams)
00287	    InTeam = PickTeam(InTeam);
00288	    log( " InTeam:" @ InTeam );
00289	
00290	    // Find a start spot.
00291	    StartSpot = FindPlayerStart( None, InTeam, Portal );
00292	
00293	    if( StartSpot == none )
00294	    {
00295	      Error = GameMessageClass.Default.FailedPlaceMessage;
00296	      return None;
00297	    }
00298	
00299	    // Init player's administrative privileges
00300	    if ( AccessControl.AdminLogin(NewPlayer, InPassword) )
00301	    {
00302	      NewPlayer = spawn(AccessControl.AdminClass,,,StartSpot.Location,StartSpot.Rotation);
00303	//      bSpectator = true; // Leave admin being player for console on-line
00304	    }
00305	    else
00306	    {
00307	      if ( PlayerControllerClass == None )
00308	        PlayerControllerClass = class<PlayerController>(DynamicLoadObject(PlayerControllerClassName, class'Class'));
00309	      NewPlayer = spawn(PlayerControllerClass,,,StartSpot.Location,StartSpot.Rotation);
00310	    }
00311	
00312	    // Handle spawn failure.
00313	    if( NewPlayer == None )
00314	    {
00315	      log("Couldn't spawn player controller of class "$PlayerControllerClass);
00316	      Error = GameMessageClass.Default.FailedSpawnMessage;
00317	      return None;
00318	    }
00319	
00320	    NewPlayer.StartSpot = StartSpot;
00321	
00322	    // Init player's replication info
00323	    NewPlayer.GameReplicationInfo = GameReplicationInfo;
00324	    NewPlayer.PlayerStat = Spawn(class'PlayerStats', NewPlayer);
00325	    NewPlayer.PlayerStat.EnterTimeSeconds = Level.TimeSeconds;
00326	
00327	    NewPlayer.GotoState('Spectating');
00328	
00329	    if ( bSpectator )
00330	    {
00331	      NewPlayer.bOnlySpectator = true;
00332	      NumSpectators++;
00333	      return NewPlayer;
00334	    }
00335	
00336	    // Change player's team.
00337	    if ( !ChangeTeam(newPlayer, InTeam) )
00338	    {
00339	      Error = GameMessageClass.Default.FailedTeamMessage;
00340	      return None;
00341	    }
00342	
00343	    // Set the player's ID.
00344	    NewPlayer.PlayerReplicationInfo.PlayerID = CurrentID++;
00345	
00346	    // Set Player Class
00347	    if ( Level.NetMode == NM_StandAlone )
00348	    { // Solo/Split game
00349	      if( IsA('XIIIMPBombGame') ) // OD:Prise en compte de l'URL pour le choix des classes en Sabotage OffLine
00350	      {
00351	          PlayerSkin[NumPlayers] = PlayerSkin[NumPlayers] % class'MPClassList'.default.ClassListInfo.Length;
00352	          InClass = class'MPClassList'.default.ClassListInfo[PlayerSkin[NumPlayers]].ClassName;
00353	          DefaultPlayerName = class'MPClassList'.default.ClassListInfo[PlayerSkin[0]].ReadableName;
00354	          DesiredPawnClass = class<Pawn>(DynamicLoadObject(InClass, class'Class'));
00355	      }
00356	      else
00357	      {
00358	          InClass = class'MPClassList'.default.ClassListInfo[NumPlayers].ClassName;
00359	          DefaultPlayerName = class'MPClassList'.default.ClassListInfo[NumPlayers].ReadableName;
00360	          DesiredPawnClass = class<Pawn>(DynamicLoadObject(InClass, class'Class'));
00361	      }
00362	    }
00363	    else
00364	    { // On-line game, get Class in
00365	      PlayerSkin[0] = PlayerSkin[0] % class'MPClassList'.default.ClassListInfo.Length;
00366	      InClass = class'MPClassList'.default.ClassListInfo[PlayerSkin[0]].ClassName;
00367	      DefaultPlayerName = class'MPClassList'.default.ClassListInfo[PlayerSkin[0]].ReadableName;
00368	      DesiredPawnClass = class<Pawn>(DynamicLoadObject(InClass, class'Class'));
00369	    }
00370	    if ( DesiredPawnClass != None )
00371	      NewPlayer.PawnClass = DesiredPawnClass;
00372	    log( " Class:" @ NewPlayer.PawnClass );
00373	
00374	    if ( Level.NetMode != NM_StandAlone )
00375	    {
00376	      InSkinName = caps(ParseOption ( Options, "SK" ));
00377	      if ( InSkinName != "" )
00378	      {
00379	        Log(" Skin:" @ InSkinName);
00380	        NewPlayer.PlayerReplicationInfo.SkinCodeName = InSkinName;
00381	      }
00382	    }
00383	
00384	/* // reminder of skin usage
00385	    NbSkins = class'SkinList'.default.SkinListInfo.Length;
00386	    Log("STATIC SkinList NbSkins="$NbSkins);
00387	    if ( NbSkins > 0 )
00388	    {
00389	      for (i=0; i<NbSkins; i++)
00390	        Log("  "$i$" - "$class'SkinList'.default.SkinListInfo[i].SkinReadableName@"("$class'SkinList'.default.SkinListInfo[i].SkinClassName$")");
00391	    }
00392	*/
00393	    // Init player's name
00394	    if( Level.NetMode == NM_Standalone )
00395	    { // solo /splitt game
00396	      InName = NewPlayer.PawnClass.Default.PawnName;
00397	    }
00398	    else
00399	    {
00400	      InName = ParseOption ( Options, "GAMERTAG" );
00401	      if (xboxlive == none)
00402	        xboxlive=New Class'XboxLiveManager';
00403	      InName = xboxlive.UnconvertString(InName);
00404	      if (InName=="")
00405	  	    InName = Left(ParseOption ( Options, "Name"), 20);
00406	      if (InName=="")
00407	  	    InName = NewPlayer.PawnClass.Default.PawnName;
00408	    }
00409	    if( InName == "" )
00410	      InName = DefaultPlayerName;
00411	
00412	//    if( (Level.NetMode = NM_Standalone) || (NewPlayer.PlayerReplicationInfo.PlayerName == DefaultPlayerName) )
00413	    if( !Level.bLonePlayer || (NewPlayer.PlayerReplicationInfo.PlayerName == DefaultPlayerName) )
00414	      ChangeName( NewPlayer, InName, false );
00415	//    ChangeName(NewPlayer, NewPlayer.PlayerReplicationInfo.PlayerName, false);
00416	    log( " Name:" @ NewPlayer.PlayerReplicationInfo.PlayerName );
00417	
00418	    // Log it.
00419	    if ( StatLog != None )
00420	      StatLog.LogPlayerConnect(NewPlayer);
00421	    NewPlayer.ReceivedSecretChecksum = !(InChecksum ~= "NoChecksum");
00422	
00423	    NumPlayers++;
00424	
00425	    // if delayed start, don't give a pawn to the player yet
00426	    // Normal for multiplayer games
00427	//    if ( bDelayedStart )
00428	    if ( bDelayedStart && !(XIIIGameReplicationInfo(GameReplicationInfo).iGameState == 2) )
00429	    {
00430	      NewPlayer.GotoState('PlayerWaiting');
00431	      return NewPlayer;
00432	    }
00433	
00434	    // Try to match up to existing unoccupied player in level,
00435	    // for savegames and coop level switching.
00436	    ForEach DynamicActors(class'Pawn', TestPawn )
00437	    {
00438	      if ( (TestPawn!=None) && (PlayerController(TestPawn.Controller)!=None) && (PlayerController(TestPawn.Controller).Player==None) && (TestPawn.Health > 0)
00439	        &&  (TestPawn.PawnName~=InName) )
00440	      {
00441	        TestPawn.Controller.Destroy();
00442	        NewPlayer.Possess(TestPawn);
00443	        return NewPlayer;
00444	      }
00445	    }
00446	
00447	    // start match, or let player enter, immediately
00448	    bRestartLevel = false;     // let player spawn once in levels that must be restarted after every death
00449	    if ( bWaitingToStartMatch )
00450	      StartMatch();
00451	    bRestartLevel = Default.bRestartLevel;
00452	
00453	    return newPlayer;
00454	}
00455	
00456	//_____________________________________________________________________________
00457	// Called after a successful login. This is the first place
00458	// it is safe to call replicated functions on the PlayerPawn.
00459	event PostLogin( PlayerController NewPlayer )
00460	{
00461	    local Controller P;
00462	    local class<Scoreboard> S;
00463	    local class<HUD> H;
00464	
00465	    // tell client what hud and scoreboard to use
00466	    H = class<HUD>(DynamicLoadObject(HUDType, class'Class'));
00467	    S = class<Scoreboard>(DynamicLoadObject(ScoreboardType, class'Class'));
00468	    NewPlayer.ClientSetHUD(H,S);
00469	
00470	    // Replicate skins - to avoid loading pauses in multiplayer games
00471	//    if ( Level.NetMode != NM_Standalone )
00472	/*
00473	    if ( !Level.bLonePlayer )
00474	    {
00475	      for ( P=Level.ControllerList; P!=None; P=P.NextController )
00476	        if ( P != NewPlayer )
00477	        {
00478	          // send other players' skins to new player
00479	          if ( P.Pawn != None )
00480	          {
00481	               NewPlayer.ClientReplicateSkins(P.Pawn.Skins[0], P.Pawn.Skins[1], P.Pawn.Skins[2], P.Pawn.Skins[3]);
00482	          }
00483	
00484	          // send new player's skins to any player which hasn't started play yet
00485	          if ( (NewPlayer.Pawn != None)
00486	               && (P.PlayerReplicationInfo != None)
00487	               && P.PlayerReplicationInfo.bWaitingPlayer
00488	               && (PlayerController(P) != None) )
00489	          {
00490	               PlayerController(P).ClientReplicateSkins(NewPlayer.Skins[0], NewPlayer.Skins[1], NewPlayer.Skins[2], NewPlayer.Skins[3]);
00491	          }
00492	        }
00493	    }
00494	*/
00495	
00496	    if ( NewPlayer.Pawn != None )
00497	      NewPlayer.Pawn.ClientSetRotation(NewPlayer.Pawn.Rotation);
00498	
00499	    if ( !bWaitingToStartMatch )
00500	      RestartPlayer(newPlayer);
00501	
00502	    // if we are a server, broadcast a welcome message.
00503	    // ELR message may be received before name is replicated ??
00504	    if( (Level.NetMode == NM_DedicatedServer) || (Level.NetMode == NM_ListenServer) )
00505	    {
00506	      Log("MP-] Sending Welcome message for"@NewPlayer@"("$NewPlayer.PlayerReplicationInfo.PlayerName$")");
00507	//      BroadcastLocalizedMessage(GameMessageClass, 1, NewPlayer.PlayerReplicationInfo);
00508	//      Broadcast(self, class'XIIIMultiMessage'.static.GetString(1,NewPlayer.PlayerReplicationInfo), 'PlayerEnter');
00509	      Broadcast(self, NewPlayer.PlayerReplicationInfo.PlayerName, 'PlayerEnter');
00510	    }
00511	}
00512	
00513	//_____________________________________________________________________________
00514	function Logout(Controller Exiting)
00515	{
00516	    local bool bMessage;
00517	
00518	    Log("LOGOUT"@exiting);
00519	
00520	    bMessage = true;
00521	    if ( PlayerController(Exiting) != None )
00522	    {
00523	      if ( PlayerController(Exiting).bOnlySpectator )
00524	      {
00525	        bMessage = false;
00526	        if ( Level.NetMode == NM_DedicatedServer )
00527	          NumSpectators--;
00528	      }
00529	      else
00530	        NumPlayers--;
00531	    }
00532	    if( !Exiting.bTearOff && bMessage && (Level.NetMode==NM_DedicatedServer || Level.NetMode==NM_ListenServer) )
00533	//      Broadcast(self, class'XIIIMultiMessage'.static.GetString(4,Exiting.PlayerReplicationInfo), 'PlayerEnter');
00534	      BroadcastLocalizedMessage(GameMessageClass, 4, Exiting.PlayerReplicationInfo);
00535	
00536	    if ( StatLog != None )
00537	      StatLog.LogPlayerDisconnect(Exiting);
00538	    if ( (PlayerController(Exiting) != none) && PlayerController(Exiting).PlayerStat != none )
00539	    {
00540	//      PlayerController(Exiting).PlayerStat.LeaveTimeSeconds = Level.TimeSeconds;
00541	//      PlayerController(Exiting).PlayerStat.LogStats();
00542	      PlayerController(Exiting).PlayerStat.Destroy();
00543	    }
00544	}
00545	
00546	//_____________________________________________________________________________
00547	function ChangeName( Controller Other, coerce string S, bool bNameChange )
00548	{
00549	    Local Controller C;
00550	
00551	    if ( (S == "") || (S == Other.PlayerReplicationInfo.PlayerName) )
00552	      return;
00553	
00554	    // Check for same names, add "+" if same name until name different.
00555			for( C=Level.ControllerList; C!=None; C=C.nextController )
00556			{
00557	      if ( (C != Other) && (C.PlayerReplicationInfo.PlayerName ~= S) )
00558	      {
00559	        S = S$"+";
00560	        C = Level.ControllerList;
00561	      }
00562	    }
00563	
00564	    if ( StatLog != None)
00565	      StatLog.LogNameChange(Other);
00566	
00567	    Other.PlayerReplicationInfo.SetPlayerName(S);
00568	    if ( bNameChange && (PlayerController(Other) != None) )
00569	      BroadcastLocalizedMessage( GameMessageClass, 2, Other.PlayerReplicationInfo );
00570	}
00571	
00572	//_____________________________________________________________________________
00573	// Restart a player.
00574	function RestartPlayer( Controller aPlayer )
00575	{
00576	    local NavigationPoint startSpot;
00577	    local bool foundStart;
00578	    local int TeamNum,i;
00579	    local class<Pawn> defaultPlayerClass;
00580	    local Pawn P;
00581	
00582	    Log("MP-] RestartPlayer call for "$aPlayer);
00583	
00584	    if( bRestartLevel && Level.NetMode!=NM_DedicatedServer && Level.NetMode!=NM_ListenServer )
00585	      return;
00586	
00587	    if ( (aPlayer.PlayerReplicationInfo == None) || (aPlayer.PlayerReplicationInfo.Team == None) )
00588	      TeamNum = 255;
00589	    else
00590	      TeamNum = aPlayer.PlayerReplicationInfo.Team.TeamIndex;
00591	
00592	    startSpot = FindPlayerStart(aPlayer, TeamNum);
00593	
00594	//    log(" > PlayerStart ="@startSpot);
00595	
00596	    if( startSpot == none )
00597	    {
00598	      log("MP-] Player start not found for "$aplayer@"!!!");
00599	      return;
00600	    }
00601	
00602	    if ( (aPlayer.PlayerReplicationInfo.Team != None)
00603	      && ((aPlayer.PawnClass == None) || !aPlayer.PlayerReplicationInfo.Team.BelongsOnTeam(aPlayer.PawnClass)) )
00604	           aPlayer.PawnClass = class<Pawn>(DynamicLoadObject(aPlayer.PlayerReplicationInfo.Team.DefaultPlayerClassName, class'Class'));
00605	
00606	    // ELR Destroy it before reinitializing after (to be sure we have a fresh just-intialized pawn)
00607	    if( aPlayer.Pawn!=None )
00608	    {
00609	      P = aPlayer.Pawn;
00610	      aPlayer.PawnDied();
00611	      P.Destroy();
00612	    }
00613	
00614	    if ( aPlayer.PawnClass != None )
00615	      aPlayer.Pawn = Spawn(aPlayer.PawnClass,,,StartSpot.Location,StartSpot.Rotation);
00616	
00617	    if( aPlayer.Pawn == None )
00618	    {
00619	      DefaultPlayerClass = class<Pawn>(DynamicLoadObject(GetDefaultPlayerClassName(aPlayer), class'Class'));
00620	      aPlayer.Pawn = Spawn(DefaultPlayerClass,,,StartSpot.Location,StartSpot.Rotation);
00621	    }
00622	
00623	    if ( aPlayer.Pawn == None )
00624	    {
00625	      log("Couldn't spawn player of type "$aPlayer.PawnClass$" at "$StartSpot);
00626	      aPlayer.GotoState('Dead');
00627	      return;
00628	    }
00629	
00630	    aPlayer.Possess(aPlayer.Pawn);
00631	    aPlayer.PawnClass = aPlayer.Pawn.Class;
00632	    XIIIMPPlayerPawn(aPlayer.Pawn).ClientChangeSkin( TeamNum );
00633	
00634	    PlayTeleportEffect(aPlayer, true, true);
00635	    aPlayer.ClientSetRotation(aPlayer.Pawn.Rotation);
00636	    AddDefaultInventory(aPlayer.Pawn);
00637	    TriggerEvent( StartSpot.Event, StartSpot, aPlayer.Pawn);
00638	}
00639	
00640	//_____________________________________________________________________________
00641	event AcceptInventory(pawn PlayerPawn)
00642	{
00643	    local inventory Inv, InvT;
00644	
00645	    // In multiplayer accept nothing
00646	    Inv = PlayerPawn.Inventory;
00647	    while ( Inv != none )
00648	    {
00649	      InvT = Inv;
00650	      Inv = Inv.Inventory;
00651	      InvT.Destroy();
00652	    }
00653	}
00654	
00655	//_____________________________________________________________________________
00656	// Play a teleporting special effect.
00657	function PlayTeleportEffect( actor Incoming, bool bOut, bool bSound)
00658	{
00659	    if ( PlayerController(Incoming) != none )
00660	      Spawn(class'SpawnEmitter',,, PlayerController(Incoming).Pawn.Location);
00661	}
00662	
00663	//_____________________________________________________________________________
00664	function bool CheckEndGame(PlayerReplicationInfo Winner, string Reason)
00665	{
00666	    local Controller P;
00667	    local PlayerController Player;
00668	    local XIIIGameReplicationInfo TGRI;
00669	
00670	    if ( (GameRulesModifiers != None) && !GameRulesModifiers.CheckEndGame(Winner, Reason) )
00671	      return false;
00672	
00673	    // check for tie
00674	    if ( Winner != none )
00675	      for ( P=Level.ControllerList; P!=None; P=P.nextController )
00676	        if ( P.bIsPlayer && (Winner != P.PlayerReplicationInfo) && (P.PlayerReplicationInfo.Score == Winner.Score) )
00677	        {
00678	          BroadcastLocalizedMessage( GameMessageClass, 0 );
00679	          return false;
00680	        }
00681	
00682	    EndTime = Level.TimeSeconds + 3.0;
00683	    TGRI = XIIIGameReplicationInfo(GameReplicationInfo);
00684	    SetGameEndMessage(TGRI, reason, winner);
00685	
00686	    log( "MP-] Game ended at "$EndTime);
00687	//    GameReplicationInfo.bStopCountDown = true;
00688	
00689	    XIIIGameReplicationInfo(GameReplicationInfo).iGameState = 3;
00690	    gotoState('MatchOver');
00691	
00692	    for ( P=Level.ControllerList; P!=None; P=P.nextController )
00693	    {
00694	      P.GotoState('GameEnded');
00695	      Player = PlayerController(P);
00696	      if ( Player != None )
00697	      {
00698	        //PlayWinMessage(Player, (Player.PlayerReplicationInfo == Winner));
00699	        Player.ClientSetBehindView(true);
00700	        if ( (Controller(Winner.Owner).Pawn != None) && !XIIIPawn(Controller(Winner.Owner).Pawn).IsDead() )
00701	          Player.SetViewTarget(Controller(Winner.Owner).Pawn);
00702	        Player.ClientGameEnded();
00703	      }
00704	    }
00705	    return true;
00706	}
00707	
00708	//_____________________________________________________________________________
00709	// ELR GameEnded in solo mode = GameOver
00710	function EndGame( PlayerReplicationInfo Winner, string Reason )
00711	{
00712	    // don't end game if not really ready
00713	    if ( !CheckEndGame(Winner, Reason) )
00714	    {
00715	      bOverTime = true;
00716	      return;
00717	    }
00718	
00719	    bGameEnded = true;
00720	    TriggerEvent('EndGame', self, None);
00721	/*    if ( Reason=="PlayerKilled" )
00722	      Level.Game.BroadCastLocalizedMessage(class'XIIIEndGameMessage', 1, winner);
00723	    else if ( Reason=="GoalComplete" )
00724	      Level.Game.BroadCastLocalizedMessage(class'XIIIEndGameMessage', 2, winner);
00725	    else if ( Reason=="GoalIncomplete" )
00726	      Level.Game.BroadCastLocalizedMessage(class'XIIIEndGameMessage', 3, winner); */
00727	    EndLogging(Reason);
00728	}
00729	
00730	//_____________________________________________________________________________
00731	function SetGameEndMessage(XIIIGameReplicationInfo TGRI, string reason, PlayerReplicationInfo winner)
00732	{
00733	    if ( caps(Reason)=="FRAGLIMIT" )
00734	      TGRI.EndGameMessage = PreGameEndMessageWinner@Winner.playername@PostGameEndMessageWinner;
00735	    else if ( caps(Reason)=="TIMELIMIT" )
00736	      TGRI.EndGameMessage = PreGameEndMessageTimeOut@PostGameEndMessageTimeOut;
00737	    else
00738	      TGRI.EndGameMessage = "BUG EndGameMessage::"@reason@":: EndGameMessage BUG";
00739	    log("#### GameEnded, TGRI.EndGameMessage == "$TGRI.EndGameMessage@"Level.Game="$Level.Game);
00740	}
00741	
00742	//_____________________________________________________________________________
00743	function CheckScore(PlayerReplicationInfo Scorer)
00744	{
00745	//    log("--- ChechScore --- Goal="$GameReplicationInfo.GoalScore@"current="$Scorer.Score);
00746	    if ( (GameRulesModifiers != None) && GameRulesModifiers.CheckScore(Scorer) )
00747	      return;
00748	
00749	    //log(" > Ok test"@int(Scorer.Score)@"/"@GameReplicationInfo.GoalScore);
00750	
00751	    if ( (Scorer != None)
00752	     && (bOverTime || (GameReplicationInfo.GoalScore > 0))
00753	     && (Scorer.Score >= GameReplicationInfo.GoalScore) )
00754	    {
00755	      PlayMenu(hFragLimit);
00756	      EndGame(Scorer,"FragLimit");
00757	    }
00758	
00759	    if ( (Scorer != None)
00760	      && (bOverTime || (GameReplicationInfo.GoalScore > 0))
00761	      && (Scorer.Score == GameReplicationInfo.GoalScore - 1) )
00762	    {
00763	//      Log("MP-] Near FragLimit");
00764	      PlayMenu(hLastFragLimit);
00765	      BroadCastLocalizedMessage(class'XIIIMultiMessage',5,Scorer);
00766	    }
00767	}
00768	
00769	//_____________________________________________________________________________
00770	//
00771	function ReStartMatch()
00772	{
00773	//    local actor A;
00774	    local controller C;
00775	
00776	//    ForEach AllActors(class'Actor', A)
00777	//      A.Reset();
00778	    Log("MP-] -- RESTART MATCH --, MaxTime="$MaxTime@"RemainingTime="$XIIIGameReplicationInfo(GameReplicationInfo).XIIIRemainingTime);
00779	    for (C=Level.ControllerList; C!=None; C=C.NextController )
00780	      RestartPlayer(C);
00781	
00782	    StartMatch();
00783	}
00784	
00785	//_____________________________________________________________________________
00786	function StartMatch()
00787	{
00788	    local Controller C;
00789	    local BotController Bot;
00790	    local int NumPlayer, Loop, Index1, Index2;
00791	    local string BotName, strTmpSpeudo;
00792	    local bool BotAlreadyExist;
00793	    local Actor a;
00794	
00795	    //DEBUGLOG( "Initialize Breakablemover " );
00796	    foreach DynamicActors(class'actor',a)
00797	    {
00798	      if (a.IsA('BreakableMover'))
00799	        a.Reset();
00800	    }
00801	
00802	    // ELR as we do not restart by reloading the map, need to initialize scores w/ each StartMatch.
00803	    for (C=Level.ControllerList; C!=None; C=C.NextController )
00804	    {
00805	      if ( (PlayerController(C) != none) && (C.PlayerReplicationInfo != None) )
00806	      {
00807	        C.PlayerReplicationInfo.Score = 0;
00808	        C.PlayerReplicationInfo.Deaths = 0;
00809	        C.PlayerReplicationInfo.HasFlag = none;
00810	        NumPlayer++;
00811	      }
00812	
00813	      if( BotController(C) != none )
00814	          BotAlreadyExist = true;
00815	    }
00816	
00817	    if( Mnu_BotNumber != -1 )
00818	    {
00819	        Level.BotNumber = Mnu_BotNumber;
00820	
00821	        for( Loop=0;Loop<8;Loop++)
00822	        {
00823	            Level.BotLevel[Loop] = Mnu_BotLevel[Loop];
00824	            Level.BotTeam[Loop] = Mnu_BotTeam[Loop];
00825	        }
00826	    }
00827	
00828	    BotNumber = Level.BotNumber;//  Max( 0,Level.IdealPlayerCount-NumPlayer);
00829	
00830	    if( BotNumber > Level.IdealPlayerCount - NumPlayer )
00831	    {
00832	        BotNumber = Level.IdealPlayerCount - NumPlayer;
00833	    }
00834	
00835	    if( BotAlreadyExist )
00836	        BotNumber = 0;
00837	
00838	    if( ( ! Level.bLonePlayer ) && ( Level.NetMode == NM_StandAlone ) )
00839	    {
00840	        if( BotNumber > 0 )
00841	        {
00842	            for( Loop=0;Loop<BotNumber;Loop++)
00843	                AddBot(Loop);
00844	        }
00845	    }
00846	
00847	    GotoState('MatchInProgress');
00848	    RemainingTime = MaxTime;
00849	    XIIIGameReplicationInfo(GameReplicationInfo).XIIIRemainingTime = RemainingTime;
00850	    XIIIGameReplicationInfo(GameReplicationInfo).iGameState = 2;
00851	    Super.StartMatch();
00852	    Log("MP-] -- START MATCH --, MaxTime="$MaxTime@"RemainingTime="$XIIIGameReplicationInfo(GameReplicationInfo).XIIIRemainingTime);
00853	//    if ( Cadavre1 != none )
00854	//      Cadavre1.destroy();
00855	//    if ( Cadavre2 != none )
00856	//      Cadavre2.destroy();
00857	
00858	
00859	    // Init Bot
00860	
00861	//    Loop=0;
00862	//    for (C=Level.ControllerList; C!=None; C=C.NextController )
00863	//    {
00864	//      if ( (BotController(C) != none) && (C.bIsBot) )
00865	//      {
00866	//          BotController(C).Skill = level.BotLevel[Loop];
00867	//          Loop++;
00868	//      }
00869	//    }
00870	
00871	    for( Loop=0; Loop<28 ; Loop++ )
00872	        SpeudoUsed[ Loop ] = 0;
00873	
00874	    Loop=0;
00875	    for (C=Level.ControllerList; C!=None; C=C.NextController )
00876	    {
00877	      if ( (BotController(C) != none) && (C.bIsBot) )
00878	      {
00879	           Index1 = Rand(7);
00880	
00881	           for( Index2=0 ; Index2<7 ; Index2++ )
00882	           {
00883	               if( Index1 + Index2 == 7 )
00884	                   Index1 -= 7;
00885	
00886	               if( SpeudoUsed[ Index1 + Index2 + BotController(C).Skill*7 ] == 0 )
00887	               {
00888	                   SpeudoUsed[ Index1 + Index2 + BotController(C).Skill*7 ] = 1;
00889	                   strTmpSpeudo = strSpeudo[ Index1 + Index2 + BotController(C).Skill*7 ];
00890	                   break;
00891	               }
00892	           }
00893	
00894	           BotName = strTmpSpeudo$" "$strBotLevel[BotController(C).Skill]$" ";
00895	
00896	           BotController(C).Initialize( Loop , BotController(C).Skill , BotName );
00897	
00898	           ChangeName( BotController(C), BotName, false );
00899	           Loop++;
00900	
00901	            C.PlayerReplicationInfo.Score = 0;
00902	            C.PlayerReplicationInfo.Deaths = 0;
00903	            C.PlayerReplicationInfo.HasFlag = none;
00904	      }
00905	      else if( XIIIMPDuckController(C)!= none )
00906	      {
00907	          if( XIIIMPDuckController(C).IsInState('GameEnded') )
00908	              XIIIMPDuckController(C).Gotostate('ReInitWithTeleport');
00909	      }
00910	    }
00911	
00912	}
00913	
00914	//_____________________________________________________________________________
00915	// ELR Copy from UW DeathMatch RatePlayerStart
00916	function NavigationPoint FindPlayerStart(Controller Player, optional byte InTeam, optional string incomingName)
00917	{
00918	     local NavigationPoint Best;
00919	
00920	     if ( (Player != none) && (Player.StartSpot != None) )
00921	          LastPlayerStartSpot = Player.StartSpot;
00922	
00923	     Best = Super.FindPlayerStart(Player, InTeam, incomingName );
00924	     if ( Best != None )
00925	          LastStartSpot = Best;
00926	     return Best;
00927	}
00928	
00929	//_____________________________________________________________________________
00930	// ELR Copy from UW DeathMatch RatePlayerStart
00931	function float RatePlayerStart(NavigationPoint N, byte Team, Controller Player)
00932	{
00933	    local PlayerStart P;
00934	    local float Score, NextDist;
00935	    local Controller OtherPlayer;
00936	
00937	    P = PlayerStart(N);
00938	
00939	    if ( (P == None) || !P.bEnabled || P.PhysicsVolume.bWaterVolume )
00940	      return 1;
00941	
00942	//    log("");
00943	//    log("    > "@N);
00944	//    log("    > LastStartSpot="@LastStartSpot);
00945	//    log("    > LastPlayerStartSpot="@LastPlayerStartSpot);
00946	
00947	    //assess candidate
00948	    Score = 10000000;
00949	
00950	//    if ( (N == LastStartSpot) || (N == LastPlayerStartSpot) )
00951	    if ( N == LastStartSpot )
00952	      Score -= 100000.0;
00953	    else
00954	      Score += 3000 * FRand(); //randomize
00955	
00956	    for ( OtherPlayer=Level.ControllerList; OtherPlayer!=None; OtherPlayer=OtherPlayer.NextController)
00957	    {
00958	      if ( OtherPlayer.bIsPlayer && (OtherPlayer.Pawn != None) )
00959	      {
00960	          //Score -= 1500;
00961	          NextDist = VSize(OtherPlayer.Pawn.Location - N.Location);
00962	          if ( NextDist < OtherPlayer.Pawn.CollisionRadius + OtherPlayer.Pawn.CollisionHeight )
00963	          {
00964	//            log("    > Warning TeleFrag"@N);
00965	            Score -= 1000000.0;
00966	          }
00967	//          else if ( (NextDist < 3000) && FastTrace(N.Location, OtherPlayer.Pawn.Location) )
00968	//          {
00969	//            log("    > Player in the zone"@N);
00970	//            Score -= (10000.0 - NextDist);
00971	//          }
00972	      }
00973	    }
00974	    return Score;
00975	}
00976	
00977	//_____________________________________________________________________________
00978	function PlayerReplicationInfo FindWinner()
00979	{
00980	    local PlayerReplicationInfo PRI, Winner;
00981	
00982	    ForEach AllActors(class'PlayerReplicationInfo', PRI)
00983	    {
00984	      if (PRI!=none)
00985	      {
00986	        if ( Winner == none )
00987	          PRI = Winner;
00988	        else if ( PRI.Score > Winner.Score )
00989	          PRI = Winner;
00990	      }
00991	    }
00992	    return Winner;
00993	}
00994	
00995	//_____________________________________________________________________________
00996	function BroadcastDeathMessage(Controller Killer, Controller Other, class<DamageType> damageType)
00997	{
00998	    if ( Killer == none )
00999	       return;
01000	
01001	    if ( (Killer == Other) || (Killer == None) )
01002	      BroadcastLocalizedMessage(DeathMessageClass, 1, None, Other.PlayerReplicationInfo, damageType);
01003	    else
01004	      BroadcastLocalizedMessage(DeathMessageClass, 0, Killer.PlayerReplicationInfo, Other.PlayerReplicationInfo, damageType);
01005	}
01006	
01007	//_____________________________________________________________________________
01008	function ScoreKill(Controller Killer, Controller Other)
01009	{
01010	    if (killer == Other)
01011	    {
01012	        if ( PlayerController(Other) != none )
01013	          PlayerController(Other).PlayerStat.StatSuicides ++;
01014	        Other.PlayerReplicationInfo.Score -= 1;
01015	    }
01016	    else if ( killer.PlayerReplicationInfo != None )
01017	    {
01018	        if ( PlayerController(Killer) != none)
01019	          PlayerController(killer).PlayerStat.StatKills ++;
01020	        if ( PlayerController(Other) != none)
01021	          PlayerController(Other).PlayerStat.StatDeaths ++;
01022	        killer.PlayerReplicationInfo.Score += 1;
01023	        XIIIPlayerReplicationInfo(killer.PlayerReplicationInfo).MyDeathScore += 1;
01024	    }
01025	
01026	    if ( GameRulesModifiers != None )
01027	        GameRulesModifiers.ScoreKill(Killer, Other);
01028	
01029	    CheckScore(Killer.PlayerReplicationInfo);
01030	}
01031	
01032	//_____________________________________________________________________________
01033	auto State PendingMatch
01034	{
01035	    event BeginState()
01036	    { // ELR, Timing out the 'press fire to start', after (default) seconds, start anyway
01037	      RestartTimeOut = default.RestartTimeOut;
01038	    }
01039	
01040	    event Timer()
01041	    {
01042	      local Controller P;
01043	      local bool bReady;
01044	
01045	      bReady = false;
01046	      for (P = Level.ControllerList; P != None; P = P.NextController )
01047	        if ( XIIIPlayerController(P) != none )
01048	          bReady = true;
01049	      if ( !bReady )
01050	      {
01051	//        log("MP-] "$self$" PendingMatch, No PlayerController logged");
01052	        return; // ELR launch no game if no playercontroller connected (on dedicated serveur, wait for 1rst player to connect
01053	      }
01054	
01055	//      log("MP-] "$self$" PendingMatch, bWaitingToStartMatch="$bWaitingToStartMatch@"TimeOut="$RestartTimeOut);
01056	
01057	      if ( Level.NetMode != NM_StandAlone )
01058	        RestartTimeOut --; // ELR Only in on-line multiplayer, not offline
01059	
01060	      if ( bWaitingToStartMatch )
01061	      {
01062	        bReady = true;
01063	        if ( RestartTimeOut > 0 )
01064	        {
01065	          for (P=Level.ControllerList; P!=None; P=P.NextController )
01066	          {
01067	            if ( PlayerController(P)!=none && (P.PlayerReplicationInfo != None) )
01068	            {
01069	  //            Log("MP-] "$P@"bWaitingPlayer="$P.PlayerReplicationInfo.bWaitingPlayer@"bReadyToPlay="$P.PlayerReplicationInfo.bReadyToPlay);
01070	              if (P.PlayerReplicationInfo.bWaitingPlayer && !P.PlayerReplicationInfo.bReadyToPlay )
01071	                bReady = false;
01072	            }
01073	          }
01074	        }
01075	
01076	//        log("MP-] "$self$" bWaitingToStartMatch, ready="$bReady);
01077	        if ( bReady )
01078	        {
01079	          log("_________________________________");
01080	          log("StartMatch");
01081	          StartMatch();
01082	        }
01083	/*        else
01084	        {
01085	          for (P=Level.ControllerList; P!=None; P=P.NextController )
01086	            if ( XIIIPlayerController(P) != none )
01087	              XIIIPlayerController(P).ReceiveLocalizedMessage(class'XIIIMultiMessage', 1, XIIIPlayerController(P).PlayerReplicationInfo);
01088	        }
01089	*/
01090	      }
01091	      else
01092	      { // ELR Unused in XIII, we always wait to start match
01093	//        StartMatch();
01094	      }
01095	    }
01096	
01097	}
01098	
01099	//_____________________________________________________________________________
01100	State MatchInProgress
01101	{
01102	    event BeginState()
01103	    {
01104	      bGameEnded = false;
01105	    }
01106	
01107	    event timer()
01108	    {
01109	      Super.Timer();
01110	//      log("MP-] "$"Match in Progress -- RemainingTime="@RemainingTime);
01111	      if ( !bOverTime && (MaxTime > 0) )
01112	      {
01113	        GameReplicationInfo.bStopCountDown = false;
01114	        RemainingTime --;
01115	        XIIIGameReplicationInfo(GameReplicationInfo).XIIIRemainingTime = RemainingTime;
01116	        if ( RemainingTime % 60 == 0 )
01117	          GameReplicationInfo.RemainingMinute = RemainingTime;
01118	        if ( RemainingTime <= 0 )
01119	        {
01120	          PlayMenu(hTimeLimit);
01121	          EndGame(FindWinner(),"TimeLimit");
01122	        }
01123	        if ( RemainingTime == 60 )
01124	        {
01125	          PlayMenu(hLastMinute);
01126	        }
01127	      }
01128	    }
01129	}
01130	
01131	//_____________________________________________________________________________
01132	State MatchOver
01133	{
01134	    event BeginState()
01135	    {
01136	      local controller C;
01137	
01138	      // Force stat update for each client
01139	      for (C=Level.ControllerList; C!=None; C=C.NextController )
01140	        if ( (PlayerController(C) != none) && (C.PlayerReplicationInfo != None) )
01141	        {
01142	          PlayerController(C).PlayerStat.Timer();
01143	          PlayerController(C).PlayerStat.StatMatchesPlayed ++;
01144	        }
01145	    }
01146	
01147	    event Timer()
01148	    {
01149	      local controller C;
01150	      local Pawn P;
01151	
01152	      Super.Timer();
01153	//      log("MP-] "$"Match Over -- RemainingTime before next match="@(Level.TimeSeconds -(EndTime+2.0)));
01154	      if ( Level.TimeSeconds > EndTime+4.0 )
01155	      {
01156	        bWaitingToStartMatch = true;
01157	        for (C=Level.ControllerList; C!=None; C=C.NextController )
01158	        {
01159	          if ( (PlayerController(C) != none) && (C.PlayerReplicationInfo != None) )
01160	          {
01161	            P = C.Pawn;
01162	//            PlayerController(C).UnPossess();
01163	//            C.PawnDied();
01164	            P.Controller = none; /* Thanx iKi else crash on-line */
01165	            P.Destroy();
01166	            C.GotoState('PlayerWaiting');
01167	//            Log("Sent"@C@"in PlayerWaiting state");
01168	            C.PlayerReplicationInfo.bReadyToPlay=false;
01169	          }
01170	        }
01171	        XIIIGameReplicationInfo(GameReplicationInfo).iGameState = 1;
01172	        GotoState('PendingMatch');
01173	      }
01174	    }
01175	}
01176	
01177	
01178	
01179	defaultproperties
01180	{
01181	     PreGameEndMessageWinner="Player "
01182	     PostGameEndMessageWinner=" Wins the match"
01183	     PreGameEndMessageTimeOut="Time Out"
01184	     BotClassesName(0)="XIIIMP.Bot_GI"
01185	     BotClassesName(1)="XIIIMP.Bot_Killer1"
01186	     BotClassesName(2)="XIIIMP.Bot_Killer2"
01187	     BotClassesName(3)="XIIIMP.Bot_XIII"
01188	     BotClassesName(4)="XIIIMP.Bot_GI"
01189	     BotClassesName(5)="XIIIMP.Bot_XIII"
01190	     BotClassesName(6)="XIIIMP.Bot_Killer1"
01191	     BotClassesName(7)="XIIIMP.Bot_Killer2"
01192	     strBotLevel(0)="*"
01193	     strBotLevel(1)="**"
01194	     strBotLevel(2)="***"
01195	     strBotLevel(3)="****"
01196	     Mnu_BotNumber=-1
01197	     strSpeudo(0)="Ender"
01198	     strSpeudo(1)="Blade"
01199	     strSpeudo(2)="Lunatic"
01200	     strSpeudo(3)="Whiz"
01201	     strSpeudo(4)="GroBeuh"
01202	     strSpeudo(5)="Furax"
01203	     strSpeudo(6)="Freddy"
01204	     strSpeudo(7)="Cho"
01205	     strSpeudo(8)="iKi"
01206	     strSpeudo(9)="Sly"
01207	     strSpeudo(10)="Rip"
01208	     strSpeudo(11)="Rhill"
01209	     strSpeudo(12)="Brutus"
01210	     strSpeudo(13)="Douceur"
01211	     strSpeudo(14)="Cray"
01212	     strSpeudo(15)="Atlas"
01213	     strSpeudo(16)="Oya-DM"
01214	     strSpeudo(17)="Dr Spy"
01215	     strSpeudo(18)="Baby"
01216	     strSpeudo(19)="Tek C."
01217	     strSpeudo(20)="Kyo"
01218	     strSpeudo(21)="Draax"
01219	     strSpeudo(22)="Solo"
01220	     strSpeudo(23)="Rigolax"
01221	     strSpeudo(24)="Matheo"
01222	     strSpeudo(25)="Litst"
01223	     strSpeudo(26)="Chandy"
01224	     strSpeudo(27)="Gyb"
01225	     hLastMinute=Sound'XIIIsound.Multi__SFXMulti.SFXMulti__hTime1Mn'
01226	     hTimeLimit=Sound'XIIIsound.Multi__SFXMulti.SFXMulti__hTimeLimit'
01227	     hLastFragLimit=Sound'XIIIsound.Multi__SFXMulti.SFXMulti__hFragLimit'
01228	     hFragLimit=Sound'XIIIsound.Multi__SFXMulti.SFXMulti__hTimeLimit'
01229	     AltGameName="Power Up"
01230	     RestartTimeOut=30
01231	     bDelayedStart=True
01232	     DefaultPlayerClassName="XIIIMP.XIIIMPPlayerPawn"
01233	     ScoreBoardType="XIIIMP.XIIIMPScoreBoard"
01234	     HUDType="XIIIMP.XIIIMPHUD"
01235	     MapPrefix="DM"
01236	     GameName="DeathCheese"
01237	     DeathMessageClass=Class'XIII.XIIIDeathMessage'
01238	     GameMessageClass=Class'XIII.XIIIMultiMessage'
01239	     MutatorClass="XIIIMP.XIIIMPMutator"
01240	     AccessControlClass="XIIIMP.XIIIAccessControl"
01241	     PlayerControllerClassName="XIIIMP.XIIIMPPlayerController"
01242	     GameReplicationInfoClass=Class'XIII.XIIIGameReplicationInfo'
01243	}

End Source Code