This tutorial explains how to create a small gametype for Unreal Tournament 2003. You will need to know some basic UScript to understand this tutorial. This tutorial assumes that you do your scripting in something like notepad, however you can do it with other editing programs.
The Gametype
First of all, i'm going to explain the gametype that we are about to create. This gametype is called Reverse Tag. It is mainly just deathmatch with an added twist. Instead of everybody's kills increasing when they frag someone, they only increase when the tagged player kills someone. Killing the tagged player turns you into the person that is tagged. The objective of this gametype is to get the most kills while you are it. Oh... Did I mention that the tagged player has UDamage? 
Creating The Files
First of all, I should let you know that this package will not show in Unreal Editor, so all of you Unreal Editor users, close it and open notepad.
Now, we create a package. To do this just go into your UT2003 folder and make a new folder in it called RevTag, then put a folder in the UT2003/RevTag folder
and call it classes. In the classes folder, make a file named "RevTag.uc" (excluding the quotes).
Next, we need to add this package to our EditPackages. To do this, simply go to your UT2003/System folder and open up UT2003.ini. Go to this line:
After that line, add this:
That should be all you need to do to set up your packages. Now, let's get to some scripting!
The Gametype Code
Finally, we have our files set up for editing. Now we can get into some real code! First of all, open up your RevTag.uc file. This file is where most of the code will be placed. First, let's declare the class. The class name is RevTag, and it extends xDeathMatch. So, add this:
| |
class RevTag extends xDeathMatch;
|
Now we add a variable global to the class. Changing something in this variable or calling a function in it will do it on the player that is tagged. When this variable is equal to none, it means that nobody is tagged. Add this:
Now we need to add a few functions that will help us later on with changing who is it. So, add these lines:
| | function unsetTaggedPawn() { setTimer(0, false); TaggedPawn = none; }
function setTaggedPawn(Pawn P) { TaggedPawn = P; setTimer(0.5, true); }
|
First, we made a function that cleared the TaggedPawn variable (meaning there is nobody tagged). When there is nobody that is tagged, the next person to kill
somone becomes the tagged pawn. The second function "tags" a player.
For the readers who don't know what setTimer() is, I will explain it now. The setTimer() function is a function that all actor classes can use. The first parameter it takes specifies how much time there is until the timer is called as a float. The second one specifies if the timer should loop as a bool. If it loops, it will wait the specified amount of seconds, then call the function again repeatedly until you call the setTimer function again.
Now, we need to make the tagged player recieve UDamage whenever the timer is called, so put this in:
| | function Timer() { if (TaggedPawn != none) { TaggedPawn.EnableUDamage(1.0); } }
|
Now for the most important part of our gametype! The Killed function... This function is called whenever someone is killed in the game. Add this (i'll explain it later):
| | function Killed(Controller Killer, Controller Killed, Pawn KilledPawn, class<DamageType> damageType) { if (TaggedPawn == none) { setTaggedPawn(Killer.Pawn); super.Killed(Killer, Killed, KilledPawn, damageType); } else if (Killed.Pawn == TaggedPawn) { if (Killer == Killed) { unsetTaggedPawn(); super.Killed(Killer, Killed, KilledPawn, damageType); } else { setTaggedPawn(Killer.Pawn); super.Killed(Killer, Killed, KilledPawn, damageType); } } else if (Killer.Pawn == TaggedPawn) { if (Killer == Killed) { unsetTaggedPawn(); super.Killed(Killer, Killed, KilledPawn, damageType); } else { super.Killed(Killer, Killed, KilledPawn, damageType); } } }
|
So, what is this? This function controls the tagging of players. I'll go through each if block to show you what is happening.
The first block checks if there isnt a tagged player. If there isnt, it tags the killer, and gives him/her a point.
The second block checks if the person that was killed was the tagged player. If so, it checks if he/she committed suicide or if he/she was killed by someone else, and rewards the players depending on the situation.
The third block of code checks if the person that killed was the tagged player. If so,it checks if he/she committed suicide or if he/she killed someone else, and rewards the players depending on the situation.
Last, but certainly not least, we need to make it so that it shows the name of the gametype when you view the scores. Add this:
| | defaultproperties { GameName = "Reverse Tag" }
|
What this will do, is tell the game that this gametype is called Reverse Tag. Without this, it would say you were playing deathmatch.
Now, compile this gametype. If you did it correctly, you should get no errors or warnings. Once it compiles, move onto the next section!
Testing your gametype
Now, we finally get to test our gametype! Well... almost. Before we can though, we need to make one more very small file. This file is the INT file, and every gametype,
mutator, weapon, etc has a description in some int file in the System folder. This pretty much tells the engine what classes to use for the game type, and
the description of it to show in game. So, make a new file in UT2003/System and put this in it:
| | [Public] Object=(Class=Class,MetaClass=Engine.GameInfo,Name=RevTag.RevTag,Description="DM|Reverse Tag|xinterface.Tab_IADeathMatch|xinterface.MapListDeathMatch|false")
|
Most of the variables in there are self-descriptive, but I want to explain the description variable. contains a lot of values that the engine needs to show the gametype information correctly. Each value is separated with a '|'. Here's what each value means:
- DM is the prefix used to choose what maps show in the level select screen.
- Reverse Tag is the name of the gametype
- xinterface.Tab_IADeathMatch and xinterface.MapListDeathMatch are both classes used for the tabs that show in the instant action screen.
- false is a boolean value used to tell the game whether this is a team game or not. I'm not totally sure on this though, please email me if this is wrong.
Now, add all of this and test! If it showed in the gametype selection, you have made your first gametype! I hope that you learned something new while reading this.
Since this is my first tutorial, i'd appreciate you to send any comments or feedback you have about this tutorial to monokrome@gmail.com . The source code to this tutorial can be located here. |