Trystan/12 24 02
Custom Gametype
Not satisfied with mutators and want to make your own game type eh? Well, first off, a note. This page will be under an unusual amount of construction for me - and will be updated over the course of a long time as I don't believe I currently have a complete grasp on what constitutes a full game type. This will be my attempt at categorizing the fleeting thoughts in my head into one.
Map List Class
class MapListModName extends MapList config;
Mine's based off xInterface.MapListTeamDeathMatch. This class primarily figures into the int file. Speaking of that..
ModName.int
[Public] Object=(Class=Class,MetaClass=Engine.GameInfo,Name=MyPackage.MyGame,Description="XxX|My Game Name|xinterface.Tab_IADeathMatch|MyPackage.MapListModName|false") Preferences=(Caption="My Game Name",Parent="Game Types",Class=MyPackage.MyGame,Immediate=True) GameName="World at War"
xInterface.Tab_IADeathMatch
Yea, we'll need to replace that at some point as well.
MyPackage.MyGame
class MyGame extends TeamGame config; // Do stuff specific to your mod prior to play starting here. function PostBeginPlay() { Super.PostBeginPlay(); } // Called before players log out. Drop inventory, guns, etc. function Logout( Controller Exiting ) { Super.Logout( Exiting ); } // Check end of game situations here. function bool CheckEndGame( PlayerReplicationInfo Winner, string Reason ) { return Super.CheckEndGame( Winner, Reason ); } // This function decides if we can change teams from what I can tell. // It does -not- do the actual team change. That seems to be processed // in the player class. Removal of this function results in an // error on startup of the game type if the game type is team based -- // this function's existence in the parent class doesn't seem to matter? function bool ChangeTeam(Controller Other, int N, bool bNewTeam) { return true; } // TODO: Create our own AI routines and replace below. defaultproperties { bAllowTrans = true bSpawnInTeamArea = false bScoreTeamKills = false bWeaponStay = true GoalScore = 3 TeamAIType(0) = class'MyPackage.MyTeamAI' TeamAIType(1) = class'MyPackage.MyTeamAI' bScoreVictimsTarget = true ADR_Kill = 2.0 BeaconName = "XxX" MapPrefix = "XxX" GameName = "My Game Name" HUDType = "MyPackage.MyHud" PlayerControllerClassName = "MyPackage.MyPlayer" }
MyPackage.MyHud
Heads up display. This will determine what's drawn on the screen and is one of the most heavily modified classes out there. Mine's simple and sleek because it doesn't do squat. Yet.
class MyHud extends HudBTeamDeathMatch; #exec OBJ LOAD FILE=MyTextures.utx var texture FireMode; function DrawHud(Canvas c) { local color preColor; local byte preStyle; // Store the current color and style variables. preColor = c.DrawColor; preStyle = c.Style; // We want to (generally) draw in white. c.DrawColor = WhiteColor; c.Style = ERenderStyle.STY_Translucent; // Draw the texture. c.SetPos(0, 0 ); c.DrawIcon( FireMode, 1 ); // Restore prior color and style. // A lot like Windows GDI programming here.. c.DrawColor = preColor; c.Style = preStyle; Super.DrawHud( c ); } DefaultProperties { }
MyPackage.TeamAI
Determines how bots work together in a team. Again, mine's sparse - the point of this entry is not to do it for you, but to show you the parts that are necessary.
class MyTeamAI extends TeamAI; defaultproperties { SquadType = Class'MyPackage.MySquadAI' }
MyPackage.SquadAI
Each team gets broken into squads - "I've got your back!" in UT2K3 for instance. This file determines how the squads work together.
class MySquadAI extends SquadAI; defaultproperties { }
MyPackage.MyPlayerController
This determines your own custom controller class. The guy running around in the game is a pawn - the person controlling the pawn controls it through the controller class. This is a very important class.
// All new functions (exec) should go here. All interaction with // the player's controls occur here. Important class. class MyPlayer extends xPlayer; exec function MyTest() { Log("Function successfully called."); } defaultproperties { PawnClass = Class'MyPackage.MyPawn' InputClass = Class'MyPackage.MyPlayerInput' PlayerReplicationInfoClass = Class'MyPackage.MyPlayerReplicationInfo' }
Mychaeel: I don't see why it's important to subclass it though.
Wormbo: It might not sound like good OOP, but if you already have a HUD subclass and only use the PlayerController class to add new exec functions, then you could as well use the HUD class for those and leave the PlayerController alone.
Trystan: Where would you turn on your pawn and/or input class if you didn't subclass this? And I don't know, it would seem more logical to me to leave new functions in the controller class - that's what it's for. (Logical == OOP? Hm, not always. ) I think subclassing this has caused me some grief though as I have a few access nones I simply can't track down that really shouldn't be happening. Perhaps I'll find out how to create my pawn another way and try to remove this class from my hierarchy. We also do subclass PlayerInput to disable dodging.
MyPackage.MyPawn
The pawn class determines how the player actually works in game. It is controlled by the controller.
class MyPawn extends xPawn; DefaultProperties { GroundSpeed=350.000000 WaterSpeed=210.000000 AirSpeed=320.000000 JumpZ=210.000000 AccelRate=1024 WalkingPct=0.60000 CrouchedPct=0.45000 MaxFallSpeed=665 MultiJumpRemaining=0 MaxMultiJump=0 MultiJumpBoost=0 bCanDoubleJump=False }
MyPackage.MyPlayerInput
Honestly there's not a lot for my mod to do in this class. We've subclassed it for one basic reason: to turn off dodging in the defaultproperties. There's probably a hugely better way to do that but I haven't looked into it yet.
class MyPlayerInput extends PlayerInput; defaultproperties { bEnableDodging = False }
MyPackage.MyPlayerReplicationInfo
PlayerReplicationInfo holds information specific to the players of your game. This information is replicated to the network clients as needed.
class MyPlayerReplicationInfo extends PlayerReplicationInfo;
More to come. Specifically more information on bots and their proper configuration.