Capture the Flag Triggers
by Anthony Rosenbaum · 06/06/2002 (8:05 pm) · 43 comments
A)ADDING the Flag mesh
LabRat was kind enough to post some free Flag mesh and the basic flag.cs for everyone.HERE is a link. Put the flag.cs file in /server/scripts folder and put the flag folder (full of the mesh and their textures) into data/shapes folder, Ok now we are ready to impliment all this stuff.
INTO THE CODE
B)Initializing flag.csGo to /server/scripts/game.cs and add
C)Adding Flags to Inventory
I ALWAYS forget this, I was going nuts because the flag wasn't mounting. So be sure to add whatever flag you want you player to carry to their datablock so in player.cs I added:
D)Making a Capture the Flag Trigger
This code is my own twist, based off of James Lupiani's and Phil Carlisle's code for Realm Wars Team Assault their file is called teamObjectives.cs and I liked that so we'll call out new file the same.
In our new file we'll put in this code:
1)Is this trigger for this player's team and
2)Does this player have a flag object in his inventory
If both are true the flag will be remove and will be respwned at a location we will declare later(with a Marker Object). There is some other code I left in there that increments a Capping variable and it also calls to the display.
E)Initializing teamObjectives.cs
Now that we made our trigger we got to make sure it loads. Go back to game.cs and add:
INTO THE GAME
F)Adding a Flag with the Mission Editor
Load up a mission. Goto where you want to put a flag. Hit f11 to bring up the mission editor. Then hit f4 (or select World Editor Creator from the "window" menu selection)Expand the Shapes selection. You'll notice you new Flag category. Expand that and there are 3 Flag objects Flag1, Flag2, and Flag3. Choose one and put it on the ground. Remember which one you chose! Also while your there switch to the World Editor Inspector(f3), and note that flag's position. (Note for the example I will presume you used Flag1 item)
G)Adding a Marker object
Before you move, go back to the World Editor Creator(f4) and make a Marker Object. It is found under Mission Objects - Missions - Marker put the marker down close to the flag.
H)Changing/Adding properties to Objects
With the marker still selected bring the World Editor Inspector up (f3) first off you want to make the marker exist exactly where the flag is at. You can do this manually, or just take the numbers from the flag's position variable and put them into the marker's position variable, then click Apply. Now we need to name the Marker. So type:
I)Adding a Trigger
Almost Done!!!
Goto where you want the flag to be capped at.
While in the World Editor Creator(f4) make a trigger object.Mission Objects-Mission-Trigger A Dialog box will pop up, in it you can name the new trigger object. To change the trigger from a "defaultTrigger" just click in that box, the new "CapFlagTrigger" should be available. Click Ok and a Box repesenting the trigger area is created. Resize the trigger accordingly (f1 for more info on positioning and scaling).
J)Adding Dynamic Properties
All right remember those 3 variables I told you about, here is where they are needed. To add a variable, first off be in World Editor Inspector (f4) and select the object we are adding vaiables to (the CapFlagTrigger of course). Click the Dynamic Button a window pops up. In the Window you can add a name for the variable and a value it repesents.
I added . . . .presuming the players' team is 1, and the flag object is Flag1, and the newly created marker object is labled Flag1Respawn . . . .:
SAVE and that is it. . . .take a player, grab the flag and go cap it! It will respawn. Rewrite the code so it fits your needs, enjoy!!!!
If you are wondering what these object look like in the .mis file here you go.
EDIT Note this works with the origial set up for inventory I am currently altering the code so it works for the new Inventory setup as posted my Tim Newell
EDIT
OK if you are using the Inventory Manager by Tim Newell you have to be sure to change a couple things
A)Changing player.cs
Remove the maxInv[] items from the player.cs instead place them in the game.cs
after you create a player. I have each team get assined a specific type of flag it looks like this
B)Altering Flag.cs
Change the onPickup Function to this:
C)Fixing the Trigger
I put the whole trigger function in, but really only 1 line was changed. . .can you find it?
LabRat was kind enough to post some free Flag mesh and the basic flag.cs for everyone.HERE is a link. Put the flag.cs file in /server/scripts folder and put the flag folder (full of the mesh and their textures) into data/shapes folder, Ok now we are ready to impliment all this stuff.
INTO THE CODE
B)Initializing flag.csGo to /server/scripts/game.cs and add
exec("./flag.cs"); to the rest of the executeablesC)Adding Flags to Inventory
I ALWAYS forget this, I was going nuts because the flag wasn't mounting. So be sure to add whatever flag you want you player to carry to their datablock so in player.cs I added:
maxInv[Flag1] = 1; maxInv[Flag2] = 1; maxInv[Flag3] = 1;to the bottom of the LightHumanArmor dataBlock. That takes care of all the flag types found in the flag.cs file.
D)Making a Capture the Flag Trigger
This code is my own twist, based off of James Lupiani's and Phil Carlisle's code for Realm Wars Team Assault their file is called teamObjectives.cs and I liked that so we'll call out new file the same.
In our new file we'll put in this code:
// Trigger count
$Game::TeamObjectives[1] = 0;
$Game::TeamObjectives[2] = 0;
$Game::TeamScores[1] = 0;
$Game::TeamScores[2] = 0;
$Game::TeamFlagCaptures[1] = 0;
$Game::TeamFlagCaptures[2] = 0;
$Game::PointsForCapture = 50;
//-----------------------------------------------------------
//NEW FLAG CAPTURE TRIGGER
//--------------------------------------------------------------
// Trigger datablock
//--------------------------------------------------------------
datablock TriggerData(CapFlagTrigger)
{
tickPeriodMS = 100;
team = -1;
teamEmitter = 0;
pointsforcapture = 50;
};
//--------------------------------------------------------------
// Events
//--------------------------------------------------------------
function CapFlagTrigger::onEnterTrigger( %this, %trigger, %obj )
{
// This method is called whenever an object enters the %trigger
// area, the object is passed as %obj. The default onEnterTrigger
// method (in the C++ code) invokes the ::onTrigger(%trigger,1) method on
// every object (whatever it's type) in the same group as the trigger.
Parent::onEnterTrigger( %this, %trigger, %obj );
//SO the trigger requires 3 dynamic variable when placing
//invcheckitem = Flag1 OR Flag2 OR whatever it is looking for in the players
//inv and
//team = 1 or 2 or whatever you labled the team property
// and
//respawnat = the name of a marker object
echo("ENTERING A CapFLAG TRIGGER");
// check to see if the lad who is in this trigger is on the our team
if( %obj.client.team.teamId $= %trigger.team )
{
echo("This is your team");
// ok, its one of our lads.. see if he has the enemy flag?
if (%obj.getInventory(%trigger.invcheckitem) > 0)
{
echo("You Scored");
// cool.. we got a capture!
$Game::TeamFlagCaptures[%obj.client.team.teamID]++;
// make a hoot about capping.
messageAll( 'MsgObjective', '\c2Team %1 captured a flag! %2 points!', %obj.client.team,$Game::PointsForCapture );
$Game::TeamScores[%obj.client.team.teamID] += $Game::PointsForCapture;
// take the flag out the guys inventory.
%obj.setInventory(%trigger.invcheckitem,0);
%obj.unmountImage($FlagSlot);
// now return the flag..
echo("ENTERING A CapFLAG TRIGGER");
newflag(%trigger.invcheckitem,%trigger.respawnat);
}
}
}now be warned this trigger REQUIRES you to set up you teams with a variable called teamID. Something like this in the games.cs (if you used exodus' tutorial, as I did, it will be familiar)//TEAM TYPES
$Team1 = new ScriptObject()
{
teamId = 1;
name = "BLUE";
score = 0;
numPlayers = 0;
};Just keep this in mind more on the Id later.The Trigger will use 3 variables(we will set later) to determine 2 things 1)Is this trigger for this player's team and
2)Does this player have a flag object in his inventory
If both are true the flag will be remove and will be respwned at a location we will declare later(with a Marker Object). There is some other code I left in there that increments a Capping variable and it also calls to the display.
E)Initializing teamObjectives.cs
Now that we made our trigger we got to make sure it loads. Go back to game.cs and add:
exec("./teamObjectives.cs");to the list.INTO THE GAME
F)Adding a Flag with the Mission Editor
Load up a mission. Goto where you want to put a flag. Hit f11 to bring up the mission editor. Then hit f4 (or select World Editor Creator from the "window" menu selection)Expand the Shapes selection. You'll notice you new Flag category. Expand that and there are 3 Flag objects Flag1, Flag2, and Flag3. Choose one and put it on the ground. Remember which one you chose! Also while your there switch to the World Editor Inspector(f3), and note that flag's position. (Note for the example I will presume you used Flag1 item)
G)Adding a Marker object
Before you move, go back to the World Editor Creator(f4) and make a Marker Object. It is found under Mission Objects - Missions - Marker put the marker down close to the flag.
H)Changing/Adding properties to Objects
With the marker still selected bring the World Editor Inspector up (f3) first off you want to make the marker exist exactly where the flag is at. You can do this manually, or just take the numbers from the flag's position variable and put them into the marker's position variable, then click Apply. Now we need to name the Marker. So type:
Flag1Respawnin the box next to the Apply button. Then click Apply. Your marker is set and is in the correct position.
I)Adding a Trigger
Almost Done!!!
Goto where you want the flag to be capped at.
While in the World Editor Creator(f4) make a trigger object.Mission Objects-Mission-Trigger A Dialog box will pop up, in it you can name the new trigger object. To change the trigger from a "defaultTrigger" just click in that box, the new "CapFlagTrigger" should be available. Click Ok and a Box repesenting the trigger area is created. Resize the trigger accordingly (f1 for more info on positioning and scaling).
J)Adding Dynamic Properties
All right remember those 3 variables I told you about, here is where they are needed. To add a variable, first off be in World Editor Inspector (f4) and select the object we are adding vaiables to (the CapFlagTrigger of course). Click the Dynamic Button a window pops up. In the Window you can add a name for the variable and a value it repesents.
I added . . . .presuming the players' team is 1, and the flag object is Flag1, and the newly created marker object is labled Flag1Respawn . . . .:
name = team value = 1 name = invcheckitem value = Flag1 name = respawnat value = Flag1Respawn
SAVE and that is it. . . .take a player, grab the flag and go cap it! It will respawn. Rewrite the code so it fits your needs, enjoy!!!!
If you are wondering what these object look like in the .mis file here you go.
new Item(FlagToCapture) {
position = "231.146 -202.12 182.761";
rotation = "1 0 0 0";
scale = "1 1 1";
dataBlock = "Flag1";
collideable = "0";
static = "1";
rotate = "1";
};
new Trigger(capArea) {
position = "13.3721 -167.616 161.581";
rotation = "1 0 0 0";
scale = "16.4867 5.21523 3.8244";
nameTag = "capArea";
dataBlock = "CapFlagTrigger";
polyhedron = "0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 0.0000000 -1.0000000 0.0000000 0.0000000 0.0000000 1.0000000";
respawnat = "FlagReSpawn";
invcheckitem = "Flag1";
team = "1";
};
new Marker(FlagReSpawn) {
position = "231.146 -202.12 182.761";
rotation = "1 0 0 0";
scale = "1 1 1";
seqNum = "0";
msToNext = "1000";
}; it you put this in Scorched earth. The Flag will be on top of a pyramid and the capping area is inside the building.EDIT Note this works with the origial set up for inventory I am currently altering the code so it works for the new Inventory setup as posted my Tim Newell
EDIT
OK if you are using the Inventory Manager by Tim Newell you have to be sure to change a couple things
A)Changing player.cs
Remove the maxInv[] items from the player.cs instead place them in the game.cs
after you create a player. I have each team get assined a specific type of flag it looks like this
if( %this.team.name $= "Red")
{
%player = new Player() {
dataBlock = RedHumanArmor;
client = %this;
};
%player.addInvItem("Flag2", "0","item","Now You have the flag.",1);
}
else{
%player = new Player() {
dataBlock = BlueHumanArmor;
client = %this;
};
%player.addInvItem("Flag1", "0","item","Now You have the flag.",1);
}this set so only ppl on the Red team can carry Flag2 and Blue team can only carry Flag1B)Altering Flag.cs
Change the onPickup Function to this:
function Flag::onPickup(%this, %flag, %player, %amount)
{
if (%player.getClassName() $= "Player" && %player.getMountedImage($FlagSlot) == 0) {
serverPlay3D(WeaponPickupSound,%flag.getTransform());
//%player.incInventory(%this,1);
if(%player.incInvItem(%flag.dataBlock,1) > 0)
echo("incrimented" @ %flag.dataBlock);
else
echo("nothing");
%player.mountImage(%this.image, $FlagSlot);
%flag.delete();
}
}C)Fixing the Trigger
I put the whole trigger function in, but really only 1 line was changed. . .can you find it?
function CapFlagTrigger::onEnterTrigger( %this, %trigger, %obj )
{
// This method is called whenever an object enters the %trigger
// area, the object is passed as %obj. The default onEnterTrigger
// method (in the C++ code) invokes the ::onTrigger(%trigger,1) method on
// every object (whatever it's type) in the same group as the trigger.
Parent::onEnterTrigger( %this, %trigger, %obj );
//SO the trigger requires 3 dynamic variable when placing
//invcheckitem = Flag1 OR Flag2 OR whatever it is looking for in the players
//inv and
//team = 1 or 2 or whatever you labled the team property
// and
//respawnat = the name of a marker object
echo("ENTERING A CapFLAG TRIGGER");
// check to see if the lad who is in this trigger is on the our team
if( %obj.client.team.teamId $= %trigger.team )
{
echo("This is your team");
echo("you have " @ %obj.getInvItem(%trigger.invcheckitem,"amount") @ " Flags");
// ok, its one of our lads.. see if he has the enemy flag?
if (%obj.getInvItem(%trigger.invcheckitem,"amount") > 0)
{
echo("You Scored");
// cool.. we got a capture!
$Game::TeamFlagCaptures[%obj.client.team.teamID]++;
// make a hoot about capping.
messageAll( 'MsgObjective', '\c2Team %1 captured a flag! %2 points!', %obj.client.team,$Game::PointsForCapture );
$Game::TeamScores[%obj.client.team.teamID] += $Game::PointsForCapture;
// take the flag out the guys inventory.
%obj.setInvItem(%trigger.invcheckitem,0);
%obj.unmountImage($FlagSlot);
// now return the flag..
echo("ENTERING A CapFLAG TRIGGER");
newflag(%trigger.invcheckitem,%trigger.respawnat);
}
}
}There you have it enjoy !!!
#2
06/07/2002 (6:26 pm)
Awesome! This just might help me implement triggers in my game, instead of using collision detection. Thanks!
#3
06/11/2002 (6:37 pm)
thanks man
#4
10/30/2003 (9:01 pm)
the CapFlagTrigger does not show up when creating a new trigger object. What could I have missed or forgotten? Also in the Mission - Mission Objects, there is no Marker, only a PathMarker
#5
05/11/2004 (4:11 am)
What i dont get is why have the flag be a trigger.. why not just have it be an object that gets mounted when you pick it up.. seems alot easier that way..
#6
05/27/2004 (9:35 pm)
The flag is just an item, but the trigger holds the name of flag to look for on the client.
#7
My problem is that I would like to use it in my vehicle game. So I wonder if someone knows if it is possible to use this code (with only some minor changes). As far as I can see there's only the player.cs file that I don't have in my game. It can't be that easy that I can add the flags to the inventory just by writing these lines in the create car datablock in the file car.cs, or can it?
Any tip is preciated though I haven't found anything in the forum yet.
06/17/2004 (7:12 pm)
This seems to be a nice tutorial.My problem is that I would like to use it in my vehicle game. So I wonder if someone knows if it is possible to use this code (with only some minor changes). As far as I can see there's only the player.cs file that I don't have in my game. It can't be that easy that I can add the flags to the inventory just by writing these lines in the create car datablock in the file car.cs, or can it?
Any tip is preciated though I haven't found anything in the forum yet.
#8
problem solved I accidently placed the team defining item in the incorrect place. oh yeah and this is a great tutorial keep up the good work!!
08/24/2004 (4:38 pm)
if the capflag trigger does not show you did something wrong with the team objectives file. try saving it in starter.fps\server\scripts thats what I did and it seemed to work except. I set the trigger and dynamics but I can't cap the sucker. He said you need to set up teams in the games.cs how do you do that, some help please?problem solved I accidently placed the team defining item in the incorrect place. oh yeah and this is a great tutorial keep up the good work!!
#9
//TEAM TYPES
$Team1 = new ScriptObject()
{
teamId = 1;
name = "BLUE";
score = 0;
numPlayers = 0;
};
I'm just sticking this at one of the game.cs files but I don't think it's doing anything.
10/25/2004 (5:44 pm)
I can't get this to work, there's a problem with the obj.client.team.teamId i think because it's value never gets set. What is obj.client? And how do I make sure it has a team and team.teamId. I'm guessing it has something to do with the code//TEAM TYPES
$Team1 = new ScriptObject()
{
teamId = 1;
name = "BLUE";
score = 0;
numPlayers = 0;
};
I'm just sticking this at one of the game.cs files but I don't think it's doing anything.
#10
player::onAdd(%this, %obj){
%this.team = $Team1;
}
this sets the team on the client
[quote]What is obj.client?[/quote
because the %obj is the object that activated the trigger we need to get client from the object with %player = %obj.client;
then we can get the team information from the client ie player
%player.team.teamId;
10/25/2004 (6:33 pm)
you have to add the teams to the player when they are created like in player::onAdd(%this, %obj){
%this.team = $Team1;
}
this sets the team on the client
[quote]What is obj.client?[/quote
because the %obj is the object that activated the trigger we need to get client from the object with %player = %obj.client;
then we can get the team information from the client ie player
%player.team.teamId;
#11
Since there was no Player::onAdd() I tried to just add it like this
function Player::onAdd(%this, %obj)
{
%this.team = $Team1;
}
in player.cs but that didn't work, but I put it in Armor::onAdd like this
function Armor::onAdd(%this, %obj)
{
%obj.client.team = $Team1;
}
and it seems to work now.
Why can't I add a player::onAdd function? I'm confused about how to know what functions 'Player' has and when they are going to get called.
10/25/2004 (7:43 pm)
Thanks Anthony,Since there was no Player::onAdd() I tried to just add it like this
function Player::onAdd(%this, %obj)
{
%this.team = $Team1;
}
in player.cs but that didn't work, but I put it in Armor::onAdd like this
function Armor::onAdd(%this, %obj)
{
%obj.client.team = $Team1;
}
and it seems to work now.
Why can't I add a player::onAdd function? I'm confused about how to know what functions 'Player' has and when they are going to get called.
#12
10/25/2004 (7:58 pm)
the Team resouce recommends to make a function GameConnection::joinTeam(%this, %teamid)but player on add should work fine also
#13
02/18/2005 (12:39 am)
Nevermind I fixed it, it was the teamobjectives.cs, I accidently added an extra ";".
#14
02/18/2005 (3:57 am)
was the captrigger file exececuted?
#15
06/02/2005 (3:27 am)
Hi I am able to get the flag to mount and I am able to setup the cap trigger but with the flag and I cross the trigger it does nothing. My only thought is the team ids. I am not sure if I did that right. My question is What file do I need to open and what to put in it so the the trigger knows what team I am on?
#16
06/08/2005 (5:10 pm)
I got it to work
#17
Thanks
07/22/2005 (9:35 pm)
Will this code work with the current release of the engine? Im asking because this tut is from 3 years agoThanks
#18
07/23/2005 (2:06 pm)
Yes, it is only scripts
#19
"Mission Objects - Missions - Marker put the marker down close to the flag."
Thank you in advanced for the help.
11/22/2005 (12:56 am)
How do I add a marker...the marker in this tut does not exist:"Mission Objects - Missions - Marker put the marker down close to the flag."
Thank you in advanced for the help.
#20
it is actually one too many steps =)
11/22/2005 (1:49 am)
I would Name the Trigger where the flag should spawn whatever I had named for the markerit is actually one too many steps =)
Torque Owner Ian Roach
Easy to follow and will be used alot i reckon.
Nice work.