- unrealed.net
  Main Page
  Editing News
  Help Wanted
  Sharky's Tips
  Submitions
  Links
  Staff
   - Levels
  Main Page
  Tutorials
  Reference
   - UnrealScript
  Main Page
  Tutorials
  Reference
  Ask the Codemaster
   - Meshes
  Minor Nerve Damage
   - #unrealed
#unrealed on GamesLink (irc.gameslink.net) is the official channel for unrealed.net. Already a steady group of people are there helping out each other with Unreal editing. Stop by and share your knowledge.
   - hosted sites
  The 3D Model Emporium
  Weapons of Destruction
  Shambler's Prefabs
  Snarf's U.M.E.
  T.P.T.Avalon TC
  Rage TC


   Hosting
Interested in having your site hosted here? Goto the Hosted Sites page and find out what we offer in order to give your work a permanent home.
   - Your Unrealed.com
   Submitting
Want to have your latest tutorial, tip, or general info on Unrealed.com? Just send it on over. We will be glad to post it on the site. Also, feel free to request a tutorial, because we can't give you what you want, without you telling us what you want.
   - network sites
  Unreal Nation
  World of Dreams
   - noteworthy sites
  Unrealized
  SFX (Sound FX)
 

 
CTF Mod: Part 1Intermediate
I created this tutorial not to teach you how to make ctf (what would be the point, I could just make it for you), but instead, to introduce you to the process of creating a gameplay modifying mod. Capture the flag, in it's most basic form, is a very simple game. You have two teams, with a matching flag. The only new item in the world is the flag, with the players remaining exactly the same as regular deathmatch. So, this is where I started, I had to add the flags into Unreal. The first step in creating Capture the Flag for Unreal.

When creating a new object, you must consider what similarities it might have with existing Unreal objects, so you may inherit their properties and thus save code and time. A flag, it is placed by the level designer, and a player picks it up and returns it to their base. What objects in Unreal are similar to that? Well, ammo, inventory items, armor all do, where are they located. They are all subclasses of Pickup which itself is a subclass of Inventory. Perfect. That's where we want our flag to be stored, in the inventory. So, I made a subclass of Pickup, named CTFFlag (Right click on Pickup, select "Create new class below Pickup", enter CTFFlag for the "New actor classname" and unctf for the Package name).

Open CTFFlag for editing. Change the line that says:

class CTFFlag expands Pickup;
Change To
class CTFFlag expands Pickup
abstract;

Abstract means, that this is not an actual class to be placed in the game, much as you'll never find a Pickup or an Inventory in the game itself, just subclasses of. The reason we do this, is because we will make a subclass of CTFFlag for the Red and Blue flags. Why don't we just make the Red and Blue flags subclasses of Pickup? Because we will put in functionality common to both flags in CTFFlag, and it will be inherited by the Red and Blue flags, thus saving code and preventing some possible mistakes.

Next, we make our Red and Blue flag subclasses. Name the subclasses CTFFlagBlue and CTFFlagRed. Since the Red and Blue flags act differently from eachother when you contact them (whether you have a red or blue flag, or which team your on), we will override the Touch() function in CTFFlagBlue and CTFFlagRed. In the Pickup class, the touch() function, in the Pickup state is defined as follows:

auto state Pickup
{ function Touch( actor Other )
{ local Inventory Copy;
if ( ValidTouch(Other) )
{
Copy = SpawnCopy(Pawn(Other));
if (bActivatable && Pawn(Other).SelectedItem==None) Pawn(Other).SelectedItem=Copy; if (bActivatable && bAutoActivate && Pawn(Other).bAutoActivate) Copy.Activate();
Pawn(Other).ClientMessage(PickupMessage);
PlaySound (PickupSound,,2.0);
PickupFunction(Pawn(Other));
}
}

function BeginState()
{

Super.BeginState();
NumCopies = 0;
}
}

Place this in your Red and Blue flag classes, from which we will edit to make the flags work properly. The first functionality we will add is that you cannot pickup one flag, if you have the other flag in possession. To do this, we change:

if ( ValidTouch(Other) )
{ Copy = SpawnCopy(Pawn(Other));
if (bActivatable && Pawn(Other).SelectedItem==None) Pawn(Other).SelectedItem=Copy; if (bActivatable && bAutoActivate && Pawn(Other).bAutoActivate) Copy.Activate(); Pawn(Other).ClientMessage(PickupMessage); PlaySound (PickupSound,,2.0);
PickupFunction(Pawn(Other));
}

Change To

if ( ValidTouch(Other) )
{ if (Pawn(Other).FindInventoryType(class'CTFFlagRed') == None)
{
Copy = SpawnCopy(Pawn(Other));
Pawn(Other).ClientMessage(PickupMessage);
PlaySound (PickupSound,,2.0);
PickupFunction(Pawn(Other));
}
}

This is for the Blue flag, as we check to see if the player (the Other variable passed to the Touch() function) has an inventory item of class CTFFlagRed. If not, we allow them to pick up the Blue flag. For the Red flag, change CTFFlagRed to CTFFlagBlue. Not we removed the line Conditional statements that included bActivatable, because in our basic CTF mod, you cannot activate the Flag.

So, now we have flags, that you can pickup, what functionality should we add next? Well, once you pickup one flag, if you touch the other, you should score. In our Touch() function, we had it check and make sure that the player doesn't have the other flag, so, we could place an else condition in, which means that they DO have the other flag, change the class'CTFFlagRed' to class'CTFFlagBlue' for the Red flag class:

if ( ValidTouch(Other) )
{ if (Pawn(Other).FindInventoryType(class'CTFFlagRed') == None)
{ Copy = SpawnCopy(Pawn(Other));
Pawn(Other).ClientMessage(PickupMessage); // add to inventory and run pickupfunction
PlaySound (PickupSound,,2.0);
PickupFunction(Pawn(Other));
}
else
{ Pawn(Other).ClientMessage("Score!");
Copy = Pawn(Other).FindInventoryType(class'CTFFlagRed');
Copy.Destroy();
}
}

Now, we need to set the mesh and texture for our red and blue flags, so right click on them, and select Default Properties. Go to Display, and for Mesh, set it to: Mesh'UnrealI.Flag1M'
Under Skin, enter: Texture'UnrealI.Skins.JFlag11' for the Red flag, and: Texture'UnrealI.Skins.JFlag12' for the blue flag.
Then go to Inventory, and for PickupMesh, set it to: Mesh'UnrealI.Flag1M' for both flags.

Alright, now when you have one flag, and touch the other, it prints "Score!" (we'll add a true scoring system later), and destroys the flag your carrying as we want. But, it does not respawn the flag we were carrying back in it's original location. We can't just spawn a flag where the player is when he touchs the other flag, or it won't return back to it's original location and we have two flags on top of eachother. Hmm, if only we had a special point that we could remember where the flag originated from. Well, there just happens to be a class for that, NavigationPoint. So, we'll make a subclass named FlagSpawner that will originally spawn the flags, and also will remain located at the original position, so we can have it spawn a new flag again when one is captured. The first thing we add in FlagSpawner is a enumeration for the color of the flag it will spawn that is as follows:

var() enum EColor
{ COLOR_Red,
COLOR_Blue
} bFlagColor;

The var() means it can be set in UnrealEd properties menu, so the level designer can set two FlagSpawners, one set to a Red color, and to Blue. Next we add a variable of type CTFFlag so we can refer to the Flag we just spawned:

var CTFFlag Flag;
Now we write the SpawnFlag() function. It needs to spawn a flag of the color stored in bFlagColor variable:

function SpawnFlag()
switch (bFlagColor){
case COLOR_Blue:
Flag = Spawn( class'CTFFlagBlue',self );
break;
case COLOR_Red:
Flag = Spawn( class'CTFFlagRed',self );
break;
}
}

But, we need a way for the flag to remember the FlagSpawner that spawned it, so we add this expression to the end of the function:

function SpawnFlag()
{ switch (bFlagColor){
case COLOR_Blue:
Flag = Spawn( class'CTFFlagBlue',self );
break;
case COLOR_Red:
Flag = Spawn( class'CTFFlagRed',self );
break;
}
Flag.Spawner = self;
}

This sets the Spawner variable of a CTFFlag to the FlagSpawner that spawned it. But, at the moment, CTFFlag doesn't have a Spawner variable, so we have to add this line to CTFFlag:
var FlagSpawner Spawner;
Now that we created a reference to the Spawner, we need to have the flag tell it to spawn a new one when it is captured, so make the bold change in the CTFFlagRed and Blue classes, remember to change the class'CTFFlagRed' to class'CTFFlagBlue' for the Red flag class:

if ( ValidTouch(Other) )
{ if (Pawn(Other).FindInventoryType(class'CTFFlagRed') == None)
{ Copy = SpawnCopy(Pawn(Other));
Pawn(Other).ClientMessage(PickupMessage); // add to inventory and run pickupfunction
PlaySound (PickupSound,,2.0);
PickupFunction(Pawn(Other));
}
else
{ Pawn(Other).ClientMessage("Score!");
Copy = Pawn(Other).FindInventoryType(class'CTFFlagRed');
CTFFlag(Copy).Spawner.SpawnFlag();
Copy.Destroy();
}
}

Now, we want a FlagSpawner to spawn a flag at the start of the game too, so we override the BeginPlay() function to spawn a flag:

function BeginPlay()
{ SpawnFlag();
Super.BeginPlay();
}

Now when the FlagSpawner is created when the game is started, it will spawn the flag of appropriate color. Now we have created a teamless version of ctf with some problems remaining, but in it's current state, we can grab one flag, and capture it on the other flag. So, let's create a test map to do this. Because we're coders and not Level Designers, we don't care oh ugly or basic our level is, we're just testing out the code. So I created a cube, 512x512x512 and subtracted it from the world, using whatever texture was currently selected, added some lights and applied them. I added a FlagSpawner in two of the corners of the map, and set one of the FlagSpawners to Red and the other to Blue (in the FlagSpawner section of the properties), added a PlayerStart Navigation point and saved the map. I've included my own test map in the source zip file, named flagtest.unr, just double click on it to play with it.

Read Part 2
Tutorial : CTF Mod
Creating a Capture the Flag Mod for Unreal, Part 1

Download: unctf.zip
Size:4kb

Author: Stonage
Date:July 15th, 1998
Sample Map:Yes



Site design and graphics by Matt Washer
Unreal and UnrealED are copy Epic Megagames, 1998