I search for solutions in this order: Past Code, Unreal Source, Wiki, BUF, groups.yahoo, google, screaming at monitor. – RegularX

Difference between revisions of "UE3:UT MDB GameExp (UT3)"

From Unreal Wiki, The Unreal Engine Documentation Site
Jump to: navigation, search
m (removed some jaggies from my wheel)
(Added new GameInfo object, moved all LogObj and associated functionality that was in this class there, Added new EventNotifier object and plugged it in here)
 
Line 16: Line 16:
 
<uscript>
 
<uscript>
 
//===================================================
 
//===================================================
// Class: UT_MDB_GameExp //%GAMEEXPANSIONCLASS%  (ClassName)
+
// Class: UT_MDB_GameExp
// Creation date: 06/12/2007 08:10 //%CREATIONDATE% (Date)
+
// Creation Date: 06/12/2007 08:10
// Last updated: 11/04/2010 13:19 //%UPDATEDDATE%  (Date)
+
// Last Updated: 18/04/2010 21:06
// Contributors: 00zX //%CONTRIBUTORS% (String)
+
// Contributors: 00zX
 
//---------------------------------------------------
 
//---------------------------------------------------
 
//TODO: Expanded Tag Support -
 
//TODO: Expanded Tag Support -
Line 29: Line 29:
 
//Moved FactoryData and ItemReplacer functionality out to GameRules object subclasses
 
//Moved FactoryData and ItemReplacer functionality out to GameRules object subclasses
 
//Started readying things for UTM_ prefix class depreciation
 
//Started readying things for UTM_ prefix class depreciation
 +
//Added new GameInfo object, moved all LogObj and associated functionality that was in this class there
 +
//Added new EventNotifier object and plugged it in here
 +
// -This allows removal of linked list call stack where needed (at the cost of 1 larger for loop and a smaller foreach loop {more list hybridization})
 +
// -GameRules objects with only certain notifies will have their functions called (no redundant calls to virtual voids)
  
 
//---------------------------------------------------
 
//---------------------------------------------------
Line 41: Line 45:
  
 
/** Version number for this Game Expasion Mutator. */
 
/** Version number for this Game Expasion Mutator. */
Const MutVer = 2.68;
+
Const MutVer = 2.72;
  
//Gametype
+
/* Gametype Data Object */
var() class<Gameinfo> GClass;
+
var UT_MDB_GameInfo GameData;
var() class<PlayerController> PCClass; /// Controller for this Mutator.
+
var() class<UTPawn> PClass; /// Pawn for this Mutator.
+
var() class<HUD> HUDClass; /// HUD for this Mutator.
+
var() class<UTCheatManager> CMClass;
+
  
 
/** GameRules Objects - Hybrid Array/List */
 
/** GameRules Objects - Hybrid Array/List */
 
var protected array<UT_MDB_GameRules> GameRulesList;
 
var protected array<UT_MDB_GameRules> GameRulesList;
 
var UT_MDB_GameInfo GameData;
 
 
/** Logging */
 
//var UT_MDB_LogObj LogObj;
 
 
//Gravity
 
var float VehicleGravityScale; //Could be %
 
var float InfantryGravityScale;
 
 
//From GameInfo
 
var bool bNewPlayersVsBots;
 
var bool bNewCustomBots;
 
var bool bNewWeaponStay;
 
var bool bAllowTranslocator;
 
//UTGame(WorldInfo.Game).bAllowHoverboard = false;
 
  
 
////
 
////
 
//Utility Functions for GameRulesList
 
//Utility Functions for GameRulesList
//TODO: Pull Hybrid list functions into this class
+
//TODO: Could make this a function of GameData;
 
final function UT_GR_Info GetMasterGameRules()
 
final function UT_GR_Info GetMasterGameRules()
 
{
 
{
Line 86: Line 70:
 
}
 
}
 
//TODO: Search for class if other non-GameDex mutators are used.
 
//TODO: Search for class if other non-GameDex mutators are used.
+
 
 
return UT_GR_Info(MasterGameRules);
 
return UT_GR_Info(MasterGameRules);
 
}
 
}
  
 
//Returns none if next is none, returns object if found.
 
//Returns none if next is none, returns object if found.
 +
//FIXME: It is a possibility that 'this' will not be in the list at all
 +
//which would mean, Find will fail returning index_none and breakin the return
 
final function UT_MDB_GameRules GetNextGameRules(UT_MDB_GameRules this)
 
final function UT_MDB_GameRules GetNextGameRules(UT_MDB_GameRules this)
 
{
 
{
Line 145: Line 131:
 
function GetServerDetails(out GameInfo.ServerResponseLine ServerState)
 
function GetServerDetails(out GameInfo.ServerResponseLine ServerState)
 
{
 
{
 +
local UT_MDB_GameRules GR;
 
local int i;
 
local int i;
  
Line 154: Line 141:
 
ServerState.ServerInfo[i].Key = "GameDex";
 
ServerState.ServerInfo[i].Key = "GameDex";
 
ServerState.ServerInfo[i++].Value = "v"$MutVer;
 
ServerState.ServerInfo[i++].Value = "v"$MutVer;
 +
 +
for(GR = GetBaseGameRules(); GR != None; GR = GetNextGameRules(GR))
 +
{
 +
//All GameRules get this method called regardless of Notifys
 +
GR.GetServerDetails(ServerState);
 +
}
 
}
 
}
  
Line 171: Line 164:
 
{
 
{
 
`LogdFuncN()
 
`LogdFuncN()
 
/* if(LogObj != none)
 
{
 
LogObj.lMuts.Additem(class.name);
 
}*/
 
 
}
 
}
  
Line 181: Line 169:
 
{
 
{
 
local UT_MDB_GameRules GR;
 
local UT_MDB_GameRules GR;
 +
local UT_MDB_EventNotifier.NotifyMode HandleNotify;
  
 
`LogdFuncN()
 
`LogdFuncN()
Line 187: Line 176:
  
 
for(GR = GetBaseGameRules(); GR != None; GR = GetNextGameRules(GR))
 
for(GR = GetBaseGameRules(); GR != None; GR = GetNextGameRules(GR))
{
+
foreach GR.EventNotifier.Notifies(HandleNotify)
GR.PostBeginPlay();
+
if(HandleNotify.EventName == ET_OnStart && HandleNotify.NotifyName == NT_Match)
}
+
GR.PostBeginPlay();
 
}
 
}
  
Line 198: Line 187:
 
Super.InitMutator(Options, ErrorMessage);
 
Super.InitMutator(Options, ErrorMessage);
  
 +
//Ran only once for all mutators regardless of Mutator.Next!
 
if(NextMutator == None)
 
if(NextMutator == None)
 +
{
 
PostInitMutator();
 
PostInitMutator();
 +
GameData.Init();
 +
}
 
}
 
}
  
Line 207: Line 200:
 
local UT_GR_Info MasterGameRules;
 
local UT_GR_Info MasterGameRules;
 
local UT_MDB_GameRules GR;
 
local UT_MDB_GameRules GR;
+
 
 
`LogdFuncN()
 
`LogdFuncN()
  
 
if(WorldInfo.Game != none)
 
if(WorldInfo.Game != none)
 
{
 
{
UTGame(WorldInfo.Game).bAllowTranslocator = default.bAllowTranslocator;
+
GameData.CurWorldInfo = WorldInfo;
 
+
GameData.CurGameType = UTGame(WorldInfo.Game);
 
GameData.CurMap = WorldInfo.GetMapName(true);
 
GameData.CurMap = WorldInfo.GetMapName(true);
GameData.CurGameType = UTGame(WorldInfo.Game);
+
 
+
if(PClass != None) WorldInfo.Game.DefaultPawnClass = PClass;
+
if(PCClass != None) WorldInfo.Game.PlayerControllerClass = PCClass;
+
if(HUDClass != None) WorldInfo.Game.HUDType = HUDClass;
+
 
+
`logd("Pawn.Class: "$WorldInfo.Game.DefaultPawnClass,,'GameExp');
+
`logd("Controller.Class: "$WorldInfo.Game.PlayerControllerClass,,'GameExp');
+
`logd("HUD.Class: "$WorldInfo.Game.HUDType,,'GameExp');
+
 
+
 
//TODO: Check LinkedList for UT_GR_Info, not just First in List!
 
//TODO: Check LinkedList for UT_GR_Info, not just First in List!
 
MasterGameRules = GetMasterGameRules();
 
MasterGameRules = GetMasterGameRules();
Line 233: Line 217:
 
for(GR = GetBaseGameRules(); GR != None; GR = GetNextGameRules(GR))
 
for(GR = GetBaseGameRules(); GR != None; GR = GetNextGameRules(GR))
 
{
 
{
 +
//All GameRules get the Init() method called regardless of Notifys
 
GR.Init();
 
GR.Init();
 
}
 
}
Line 242: Line 227:
 
function bool CheckReplacement(Actor Other)
 
function bool CheckReplacement(Actor Other)
 
{
 
{
local UTPlayerController UTPlayer;
+
local Controller C;
local UT_MDB_GameRules GR;
+
local UT_MDB_GameRules BaseGameRules, GR;
+
local UT_MDB_EventNotifier.NotifyMode HandleNotify;
UTPlayer = UTPlayerController(Controller(other));
+
if(UTPlayer != None && CMClass != None)
+
UTPlayer.CheatClass = default.CMClass;
+
  
for(GR = GetBaseGameRules(); GR != None; GR = GetNextGameRules(GR))
+
BaseGameRules = GetBaseGameRules();
 +
 
 +
for(GR = BaseGameRules; GR != None; GR = GetNextGameRules(GR))
 
{
 
{
 
return GR.CheckReplacement(Other);
 
return GR.CheckReplacement(Other);
 
}
 
}
+
 
 +
C = Controller(Other);
 +
if(C != None)
 +
{
 +
if(GameData != None && C.name != GameData.CurPawn)
 +
{
 +
`logd("Controller: "$PathName(C),,'GameExp');
 +
GameData.CurController = C.name;
 +
}
 +
 
 +
for(GR = GetBaseGameRules(); GR != None; GR = GetNextGameRules(GR))
 +
foreach GR.EventNotifier.Notifies(HandleNotify)
 +
if(HandleNotify.EventName == ET_OnSpawn && HandleNotify.NotifyName == NT_Weapon)
 +
GR.NotifyController(C);
 +
}
 +
 
 +
//ET_OnSpawn?
 +
if(Other.IsA('Weapon'))
 +
{
 +
for(GR = GetBaseGameRules(); GR != None; GR = GetNextGameRules(GR))
 +
foreach GR.EventNotifier.Notifies(HandleNotify)
 +
if(HandleNotify.EventName == ET_OnStart && HandleNotify.NotifyName == NT_Weapon)
 +
GR.ModifyWeapon(Weapon(Other));
 +
}
 +
 
 
return true;
 
return true;
 
}
 
}
Line 263: Line 271:
 
local UTPawn P;
 
local UTPawn P;
 
local UTVehicle V;
 
local UTVehicle V;
local UT_MDB_GameRules BaseGameRules;
 
  
//if(Other.IsA(class'')){}
+
local UT_GR_Info.PawnInfo PInfo;
 +
local UT_MDB_GameRules BaseGameRules, GR;
 +
local UT_MDB_EventNotifier.NotifyMode HandleNotify;
  
 
BaseGameRules = GetBaseGameRules();
 
BaseGameRules = GetBaseGameRules();
 +
 +
//new PawnInfo
 +
PInfo.Type = class'UT_GR_Info'.static.GetPawnType(Other);
 +
PInfo.Pawn = Other;
 +
 +
if(BaseGameRules != None)
 +
BaseGameRules.ModifyPawnInfo(PInfo);
 +
 
P = UTPawn(Other);
 
P = UTPawn(Other);
 
if(P != None && BaseGameRules != None)
 
if(P != None && BaseGameRules != None)
Line 278: Line 295:
 
GameData.CurRook = UTHeroPawn(P).name;
 
GameData.CurRook = UTHeroPawn(P).name;
 
}
 
}
BaseGameRules.ModifyRook(UTHeroPawn(P));
+
 
 +
for(GR = GetBaseGameRules(); GR != None; GR = GetNextGameRules(GR))
 +
foreach GR.EventNotifier.Notifies(HandleNotify)
 +
if(HandleNotify.EventName == ET_OnSpawn && HandleNotify.NotifyName == NT_Player)
 +
GR.ModifyRook(UTHeroPawn(P));
 +
 
 +
//BaseGameRules.ModifyRook(UTHeroPawn(P));
 
}
 
}
+
 
 
if(GameData != None && P.name != GameData.CurPawn)
 
if(GameData != None && P.name != GameData.CurPawn)
 
{
 
{
Line 286: Line 309:
 
GameData.CurPawn = P.name;
 
GameData.CurPawn = P.name;
 
}
 
}
BaseGameRules.ModifyPawn(P);
+
 
 +
for(GR = GetBaseGameRules(); GR != None; GR = GetNextGameRules(GR))
 +
foreach GR.EventNotifier.Notifies(HandleNotify)
 +
if(HandleNotify.EventName == ET_OnSpawn && HandleNotify.NotifyName == NT_Player)
 +
GR.ModifyPawn(P);
 +
 
 +
//BaseGameRules.ModifyPawn(P);
 
}
 
}
 
 
Line 299: Line 328:
 
GameData.CurVehicle = V.name;
 
GameData.CurVehicle = V.name;
 
}
 
}
BaseGameRules.ModifyVehicle(V);
+
 
 +
for(GR = GetBaseGameRules(); GR != None; GR = GetNextGameRules(GR))
 +
foreach GR.EventNotifier.Notifies(HandleNotify)
 +
if(HandleNotify.EventName == ET_OnSpawn && HandleNotify.NotifyName == NT_Vehicle)
 +
GR.ModifyVehicle(V);
 +
 
 +
//BaseGameRules.ModifyVehicle(V);
 
}
 
}
  
 
Super.ModifyPlayer(Other);
 
Super.ModifyPlayer(Other);
 +
}
 +
 +
// TODO: Only modifys the vehicle once a player enters it or on spawn?
 +
function DriverEnteredVehicle(Vehicle V, Pawn P)
 +
{
 +
local UT_MDB_GameRules GR;
 +
local UT_MDB_EventNotifier.NotifyMode HandleNotify;
 +
 +
for(GR = GetBaseGameRules(); GR != None; GR = GetNextGameRules(GR))
 +
foreach GR.EventNotifier.Notifies(HandleNotify)
 +
if(HandleNotify.EventName == ET_OnEnter && HandleNotify.NotifyName == NT_Vehicle)
 +
{
 +
GR.ModifyVehicleOnEnter(V);
 +
GR.NotifyEnteredVehicle(P);
 +
// GR.DriverEnteredVehicle(V, P);
 +
}
 +
}
 +
 +
function DriverLeftVehicle(Vehicle V, Pawn P)
 +
{
 +
local UT_MDB_GameRules GR;
 +
local UT_MDB_EventNotifier.NotifyMode HandleNotify;
 +
// local int idx;
 +
 +
for(GR = GetBaseGameRules(); GR != None; GR = GetNextGameRules(GR))
 +
foreach GR.EventNotifier.Notifies(HandleNotify)
 +
if(HandleNotify.EventName == ET_OnExit && HandleNotify.NotifyName == NT_Vehicle)
 +
{
 +
GR.ModifyVehicleOnEnter(V);
 +
GR.NotifyEnteredVehicle(P);
 +
// GR.DriverLeftVehicle(V, P);
 +
}
 +
 +
//HandleNotify = (EventName = ET_OnExit, NotifyName = NT_Vehicle);
 +
/* HandleNotify.EventName = ET_OnExit;
 +
HandleNotify.NotifyName = NT_Vehicle;
 +
for(GR = GetBaseGameRules(); GR != None; GR = GetNextGameRules(GR))
 +
{
 +
idx = GR.EventNotifier.Notifies.find(HandleNotify);
 +
if(idx != Index_None)
 +
{
 +
GR.ModifyVehicleOnEnter(V);
 +
GR.NotifyEnteredVehicle(P);
 +
// GR.DriverLeftVehicle(V, P);
 +
}
 +
}*/
 
}
 
}
  
Line 310: Line 391:
 
End Object
 
End Object
 
GameData=UT_MDB_GameInfo0
 
GameData=UT_MDB_GameInfo0
 
PClass=None
 
PCClass=None
 
HUDClass=None
 
CMClass=None
 
 
}
 
}
 
</uscript>
 
</uscript>

Latest revision as of 23:54, 18 April 2010

Introduction[edit]

Code[edit]

UT3 Info >> UTMutator >> UT_MDB_GameExp (custom)
Package: 
UT_GameDex
Known custom subclass:
UTM_BloodLust (UT3)

Functions[edit]

Script[edit]

//===================================================
//	Class: UT_MDB_GameExp
//	Creation Date: 06/12/2007 08:10
//	Last Updated: 18/04/2010 21:06
//	Contributors: 00zX
//---------------------------------------------------
//TODO: Expanded Tag Support -
//	Can be used to auto assign groups based on what adjustments are made.
 
//Removed Redundant function calls
//Moved Info Attachments to Gamerules objects
//Killed the ObjectList and put the list functionality in this class
//Moved FactoryData and ItemReplacer functionality out to GameRules object subclasses
//Started readying things for UTM_ prefix class depreciation
//Added new GameInfo object, moved all LogObj and associated functionality that was in this class there
//Added new EventNotifier object and plugged it in here
//	-This allows removal of linked list call stack where needed (at the cost of 1 larger for loop and a smaller foreach loop {more list hybridization})
//	-GameRules objects with only certain notifies will have their functions called (no redundant calls to virtual voids)
 
//---------------------------------------------------
//	Attribution-Noncommercial-Share Alike 3.0 Unported
//	http://creativecommons.org/licenses/by-nc-sa/3.0/
//	http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode
//===================================================
class UT_MDB_GameExp extends UTMutator
	abstract;
 
`include(MOD.uci)
 
/** Version number for this Game Expasion Mutator. */
Const MutVer = 2.72;
 
/* Gametype Data Object */
var UT_MDB_GameInfo						GameData;
 
/** GameRules Objects - Hybrid Array/List */
var protected array<UT_MDB_GameRules>	GameRulesList;
 
////
//Utility Functions for GameRulesList
//TODO: Could make this a function of GameData;
final function UT_GR_Info GetMasterGameRules()
{
	local GameRules MasterGameRules;
 
	MasterGameRules = WorldInfo.Game.GameRulesModifiers;
 
	//Spawn the Master GameRules for GameDex
	if(MasterGameRules == none)
	{
		WorldInfo.Game.AddGameRules(class'UT_GameDex.UT_GR_Info');
		MasterGameRules = WorldInfo.Game.GameRulesModifiers;
		UT_GR_Info(MasterGameRules).GameExp = self;
	}
	//TODO: Search for class if other non-GameDex mutators are used.
 
	return UT_GR_Info(MasterGameRules);
}
 
//Returns none if next is none, returns object if found.
//FIXME: It is a possibility that 'this' will not be in the list at all
//which would mean, Find will fail returning index_none and breakin the return
final function UT_MDB_GameRules GetNextGameRules(UT_MDB_GameRules this)
{
	local int idx;
 
	idx = self.GameRulesList.Find(this);
	return self.GameRulesList[idx+1];
}
 
final function UT_MDB_GameRules GetBaseGameRules()
{
	return self.GameRulesList[0];
}
 
//Returns first instance of GameRules matching class
//Or creates a new instance of GameRules and returns that
final function UT_MDB_GameRules UpdateGameRules(class<UT_MDB_GameRules> GRC)
{
	local UT_MDB_GameRules GR;
 
	for(GR = GetBaseGameRules(); GR != None; GR = GetNextGameRules(GR))
	{
		if(GR.Class == GRC)
			return GR;
	}
 
	GR = new(self)GRC;
	self.GameRulesList.Additem(GR);
	GR.Init();
	return GR;
}
 
////
//Utility Functions for GroupNames
final function AddGroupName(string G)
{
	local int idx;
 
	idx = GroupNames.find(G);
	if(idx != INDEX_NONE)
		GroupNames.Additem(G);
}
 
final function RemoveGroupName(string G)
{
	local int idx;
 
	idx = GroupNames.find(G);
	if(idx != INDEX_NONE)
		GroupNames.Removeitem(G);
}
 
////
function GetServerDetails(out GameInfo.ServerResponseLine ServerState)
{
	local UT_MDB_GameRules GR;
	local int i;
 
	Super.GetServerDetails(ServerState);
 
	i = ServerState.ServerInfo.Length;
 
	ServerState.ServerInfo.Length = i+1;
	ServerState.ServerInfo[i].Key = "GameDex";
	ServerState.ServerInfo[i++].Value = "v"$MutVer;
 
	for(GR = GetBaseGameRules(); GR != None; GR = GetNextGameRules(GR))
	{
		//All GameRules get this method called regardless of Notifys
		GR.GetServerDetails(ServerState);
	}
}
 
////
//TODO: Tidy everything up in this case.
event Destroyed();
 
function ModifyLogin(out string Portal, out string Options)
{
	Super.ModifyLogin(Portal, Options);
	if(NextMutator == None)
		`logd("Logged in!",,'GameExp');
}
 
////
event PreBeginPlay()
{
	`LogdFuncN()
}
 
event PostBeginPlay()
{
	local UT_MDB_GameRules GR;
	local UT_MDB_EventNotifier.NotifyMode HandleNotify;
 
	`LogdFuncN()
 
	Super.PostBeginPlay();
 
	for(GR = GetBaseGameRules(); GR != None; GR = GetNextGameRules(GR))
		foreach GR.EventNotifier.Notifies(HandleNotify)
			if(HandleNotify.EventName == ET_OnStart && HandleNotify.NotifyName == NT_Match)
				GR.PostBeginPlay();
}
 
function InitMutator(string Options, out string ErrorMessage)
{
	`LogdFuncN()
 
	Super.InitMutator(Options, ErrorMessage);
 
	//Ran only once for all mutators regardless of Mutator.Next!
	if(NextMutator == None)
	{
		PostInitMutator();
		GameData.Init();
	}
}
 
//Ran only once for all mutators regardless of Mutator.Next!
singular function PostInitMutator()
{
	local UT_GR_Info MasterGameRules;
	local UT_MDB_GameRules GR;
 
	`LogdFuncN()
 
	if(WorldInfo.Game != none)
	{
		GameData.CurWorldInfo = WorldInfo;
		GameData.CurGameType = UTGame(WorldInfo.Game);
		GameData.CurMap = WorldInfo.GetMapName(true);
 
		//TODO: Check LinkedList for UT_GR_Info, not just First in List!
		MasterGameRules = GetMasterGameRules();
		MasterGameRules.SetBaseGameRules();
		`logd("MasterGameRules: "$PathName(MasterGameRules)$" Initialized!",,'GameExp',);
 
		//Call Init for all GameRules Objects
		for(GR = GetBaseGameRules(); GR != None; GR = GetNextGameRules(GR))
		{
			//All GameRules get the Init() method called regardless of Notifys
			GR.Init();
		}
	}
}
 
////
//Replacement
function bool CheckReplacement(Actor Other)
{
	local Controller C;
	local UT_MDB_GameRules BaseGameRules, GR;
	local UT_MDB_EventNotifier.NotifyMode HandleNotify;
 
	BaseGameRules = GetBaseGameRules();
 
	for(GR = BaseGameRules; GR != None; GR = GetNextGameRules(GR))
	{
		return GR.CheckReplacement(Other);
	}
 
	C = Controller(Other);
	if(C != None)
	{
		if(GameData != None && C.name != GameData.CurPawn)
		{
			`logd("Controller: "$PathName(C),,'GameExp');
			GameData.CurController = C.name;
		}
 
		for(GR = GetBaseGameRules(); GR != None; GR = GetNextGameRules(GR))
			foreach GR.EventNotifier.Notifies(HandleNotify)
				if(HandleNotify.EventName == ET_OnSpawn && HandleNotify.NotifyName == NT_Weapon)
					GR.NotifyController(C);
	}
 
	//ET_OnSpawn?
	if(Other.IsA('Weapon'))
	{
		for(GR = GetBaseGameRules(); GR != None; GR = GetNextGameRules(GR))
			foreach GR.EventNotifier.Notifies(HandleNotify)
				if(HandleNotify.EventName == ET_OnStart && HandleNotify.NotifyName == NT_Weapon)
					GR.ModifyWeapon(Weapon(Other));
	}
 
	return true;
}
 
////
//Modify
function ModifyPlayer(Pawn Other)
{
	local UTPawn P;
	local UTVehicle V;
 
	local UT_GR_Info.PawnInfo PInfo;
	local UT_MDB_GameRules BaseGameRules, GR;
	local UT_MDB_EventNotifier.NotifyMode HandleNotify;
 
	BaseGameRules = GetBaseGameRules();
 
	//new PawnInfo
	PInfo.Type = class'UT_GR_Info'.static.GetPawnType(Other);
	PInfo.Pawn = Other;
 
	if(BaseGameRules != None)
		BaseGameRules.ModifyPawnInfo(PInfo);
 
	P = UTPawn(Other);
	if(P != None && BaseGameRules != None)
	{
		if(UTHeroPawn(P) != None)
		{
			if(GameData != None && UTHeroPawn(P).name != GameData.CurRook)
			{
				`logd("Rook: "$PathName(UTHeroPawn(P)),,'GameExp');
				GameData.CurRook = UTHeroPawn(P).name;
			}
 
			for(GR = GetBaseGameRules(); GR != None; GR = GetNextGameRules(GR))
				foreach GR.EventNotifier.Notifies(HandleNotify)
					if(HandleNotify.EventName == ET_OnSpawn && HandleNotify.NotifyName == NT_Player)
						GR.ModifyRook(UTHeroPawn(P));
 
			//BaseGameRules.ModifyRook(UTHeroPawn(P));
		}
 
		if(GameData != None && P.name != GameData.CurPawn)
		{
			`logd("Pawn: "$PathName(P),,'GameExp');
			GameData.CurPawn = P.name;
		}
 
		for(GR = GetBaseGameRules(); GR != None; GR = GetNextGameRules(GR))
			foreach GR.EventNotifier.Notifies(HandleNotify)
				if(HandleNotify.EventName == ET_OnSpawn && HandleNotify.NotifyName == NT_Player)
					GR.ModifyPawn(P);
 
		//BaseGameRules.ModifyPawn(P);
	}
 
	// TODO: Only modifys the vehicle once a player enters it or on spawn?
	V = UTVehicle(Other);
	if(V != None && BaseGameRules != None)
	{
//		ModifyKnight(V);
		if(GameData != None && V.name != GameData.CurVehicle)
		{
			`logd("Vehicle: "$PathName(V),,'GameExp');
			GameData.CurVehicle = V.name;
		}
 
		for(GR = GetBaseGameRules(); GR != None; GR = GetNextGameRules(GR))
			foreach GR.EventNotifier.Notifies(HandleNotify)
				if(HandleNotify.EventName == ET_OnSpawn && HandleNotify.NotifyName == NT_Vehicle)
					GR.ModifyVehicle(V);
 
		//BaseGameRules.ModifyVehicle(V);
	}
 
	Super.ModifyPlayer(Other);
}
 
// TODO: Only modifys the vehicle once a player enters it or on spawn?
function DriverEnteredVehicle(Vehicle V, Pawn P)
{
	local UT_MDB_GameRules GR;
	local UT_MDB_EventNotifier.NotifyMode HandleNotify;
 
	for(GR = GetBaseGameRules(); GR != None; GR = GetNextGameRules(GR))
		foreach GR.EventNotifier.Notifies(HandleNotify)
			if(HandleNotify.EventName == ET_OnEnter && HandleNotify.NotifyName == NT_Vehicle)
			{
				GR.ModifyVehicleOnEnter(V);
				GR.NotifyEnteredVehicle(P);
//				GR.DriverEnteredVehicle(V, P);
			}
}
 
function DriverLeftVehicle(Vehicle V, Pawn P)
{
	local UT_MDB_GameRules GR;
	local UT_MDB_EventNotifier.NotifyMode HandleNotify;
//	local int idx;
 
	for(GR = GetBaseGameRules(); GR != None; GR = GetNextGameRules(GR))
		foreach GR.EventNotifier.Notifies(HandleNotify)
			if(HandleNotify.EventName == ET_OnExit && HandleNotify.NotifyName == NT_Vehicle)
			{
				GR.ModifyVehicleOnEnter(V);
				GR.NotifyEnteredVehicle(P);
//				GR.DriverLeftVehicle(V, P);
			}
 
	//HandleNotify = (EventName = ET_OnExit, NotifyName = NT_Vehicle);
/*	HandleNotify.EventName = ET_OnExit;
	HandleNotify.NotifyName = NT_Vehicle;
	for(GR = GetBaseGameRules(); GR != None; GR = GetNextGameRules(GR))
	{
		idx = GR.EventNotifier.Notifies.find(HandleNotify);
		if(idx != Index_None)
		{
			GR.ModifyVehicleOnEnter(V);
			GR.NotifyEnteredVehicle(P);
//			GR.DriverLeftVehicle(V, P);
		}
	}*/
}
 
defaultproperties
{
	Begin Object Class=UT_MDB_GameInfo Name=UT_MDB_GameInfo0
	End Object
	GameData=UT_MDB_GameInfo0
}