Game Development Community

dev|Pro Game Development Curriculum

Team King of the Hill

by Brian Jansen · 04/11/2006 (2:02 pm) · 9 comments

Ok here is my Team King oh the Hill Mode Enjoy
Step 1)
Make a new file called TeamKOTH.cs in fps/server/scripts and put this code in it.
//******************************************
//****************Other Stuff***************
//******************************************
//Team Variables
$Game::TeamScores[1] = 0;
$Game::TeamScores[2] = 0;
$Game::TeamScores[3] = 0;
$Game::Teamkings[1] = 0;
$Game::Teamkings[2] = 0;
$Game::Teamkings[3] = 0;
$Game::Teamplayerc[1] = 0;
$Game::Teamplayerc[2] = 0;
$Game::Teamplayerc[3] = 0;
$Game::Teamkills[1] = 0;
$Game::Teamkills[2] = 0;
$Game::Teamkills[3] = 0;
//Team Stuff
$Team1 = new ScriptObject()
{
   teamId = 1;
   name = Fury;
   score = 0;
   numPlayers = 0;
   kings = 0;
   color = red;
   nametag = "[FURY]";
};

$Team2 = new ScriptObject()
{
   teamId = 2;
   name = Rage;
   score = 0;
   numPlayers = 0;
   kings = 0;
   color = blue;
   nametag = "[RAGE]";
};
$Team3 = new ScriptObject()
{
   teamId = 3;
   name = nonplayer;
   score = 0;
   numPlayers = 0;
   kings = 0;
   color = grey;
   nametag = "[NPC]";
};
datablock AudioProfile(Hilloff)
{
   filename    = "~/data/sound/KOTHoff.wav";
   description = "AudioClose3d";
   preload = false;
};
datablock AudioProfile(Hillon) 
{
   filename    = "~/data/sound/KOTHon.wav";
   description = "AudioClose3d";
   preload = false;
};
//******************************************
//****************Triggers******************
//******************************************
datablock TriggerData(teamkingofthehillTrigger)
{
  tickPeriodMS = 1000; 
  //set to 1000 so it ticks every second
};
function teamkingofthehillTrigger::onEnterTrigger(%this,%trigger,%obj)
{
   %scorefury = $Game::Teamscores[1];
   %scorerage = $Game::Teamscores[2];
   $kingofthehill = %obj.client;
   %client = $kingofthehill;
   $Game::TeamScores[%client.team.teamID]++;
   %client.incScore(1);

   serverPlay3D(hillon,%obj.getTransform());
   $Game::Teamkings[%client.team.teamID]++;
   messageAll('MsgClienthill','\c4 %1 from Team %2 is King of the Hill(Fury: %3 | Rage: %4.',%obj.client.name, %obj.client.team.name,%scorefury,%scorerage); 
      $KingsoftheHill++;
   %client = $kingofthehill;
   if ($Game::Teamscores[%client.team.teamID] >= $Game::EndGameScore) 
   cycleGame(); 
   }
function teamkingofthehillTrigger::onLeaveTrigger(%this,%trigger,%obj)
{
  %scorefury = $Game::Teamscores[1];
  %scorerage = $Game::Teamscores[2];
  %client = $kingofthehill;
  serverPlay3D(hilloff,%obj.getTransform()); 
  messageAll('MsgClienthill','\c4 %1 from Team %2 has left the Hill(Fury: %3 | Rage: %4.',%obj.client.name, %obj.client.team.name,%scorefury,%scorerage);
  $KingsoftheHill--;
  $Game::Teamkings[%client.team.teamID]--;
}
function teamkingofthehillTrigger::onTickTrigger(%this,%trigger,%obj)
{
 %scorefury = $Game::Teamscores[1];
 %scorerage = $Game::Teamscores[2];
 %client = $kingofthehill; 
 $Game::TeamScores[%client.team.teamID]++;
 %client.incScore(1);
 if ($Game::Teamscores[%client.team.teamID] >= $Game::EndGameScore) 
 cycleGame(); 
}
datablock TriggerData(newgameTrigger)
{
  tickPeriodMS = 1000;
};
function newgameTrigger::onEnterTrigger(%this,%trigger,%obj)
{ 
  $kingofthehill = %obj.client;
  %obj.client.setScore(0);
  //resets the score to Start a new game of KOTH
}
function newgameTrigger::onLeaveTrigger(%this,%trigger,%obj)
{
  %client = $kingofthehill;
  %client.setScore(0);
}
function newgameTrigger::onTickTrigger(%this,%trigger,%obj)
{
}
//*********************************
//*******Functions*****************
//*********************************
function serverCmdJoinTeam(%client, %teamid)
{
  %client.joinTeam(%teamid);
}
function MsgAll(%msg)
{
	// useful function for admins to msg everyone
	messageAll('MsgGlobal', 'Admin: %1', %msg);
}

Step 2)
Open up game.cs and add the Teamkoth.cs file we just made to it by adding exec("./TeamKoth.cs"); under exec("./player.cs"); and then add this code to cyclegame().
$Game::TeamScores[1] = 0;
$Game::TeamScores[2] = 0;
$Game::TeamScores[3] = 0;
$Game::Teamkings[1] = 0;
$Game::Teamkings[2] = 0;
$Game::Teamkings[3] = 0;

Step 3)
Replace function GameConnection::onClientEnterGame(%this) with this.
function GameConnection::onClientEnterGame(%this)
{
   commandToClient(%this, 'SyncClock', $Sim::Time - $Game::StartTime);

   // Create a new camera object.
   %this.camera = new Camera() {
      dataBlock = Observer;
   };
   MissionCleanup.add( %this.camera );
   %this.camera.scopeToClient(%this);

   // Setup game parameters, the onConnect method currently starts
   // everyone with a 0 score.
   %this.score = 0;
   %this.team = 0;  //default team is 0 (observer)

   //Spawn a camera by default on a observer point
   %this.camera.setTransform(pickObserverPoint(%this));
   %this.camera.setVelocity("0 0 0");
   %this.setControlObject(%this.camera);
}

Step 4)
Then add this code to game.cs.
function GameConnection::joinTeam(%this, %teamid)
{
   //We only have 2 teams so if team is greater than 2 or less than 0 its invalid.
   if (%teamid > 3 || %teamid < 0) 
      return false;
   //If we already are on that team return. 
   if (%teamid == %this.team.teamId)
      return false;

   %this.leaveTeam();

   if (%teamid == 1)
      %this.team = $Team1; 
   if (%teamid == 2)
      %this.team = $Team2;
   if (%teamid == 3)
      %this.team = $Team3;	

   MessageAll('MsgClientJoinTeam', '\c4%1 joined Team %2',
      %this.name,
      %this.team.name,
      %this.team.teamId,
      %this,
      %this.sendGuid,
      %this.score,
      %this.isAiControlled(),
      %this.isAdmin,
      %this.isSuperAdmin);

   %this.spawnPlayer();
}
function GameConnection::leaveTeam(%client, %teamid)
{
   %this.score = 0;
   
   messageAll('MsgClientLeaveTeam', '\c2%1 left Team %2.',
      %client.name,
      %client.team.name,
      %client);
   
   if (%client.player)
      %client.player.delete();
}
function pickObserverPoint(%client)
{
   %groupName = "MissionGroup/observerDropPoints";
   %group = nameToID(%groupName);
   
   if (%group != -1) {
      %count = %group.getCount();
      if (%count != 0) {
         %index = getRandom(%count-1);
         %spawn = %group.getObject(%index);
         return %spawn.getTransform();
      }
      else
         error("No observer spawn points found in " @ %groupName);
   }
   else
      error("Missing observer spawn points group " @ %groupName);

   // Could be no spawn points, in which case we'll stick the
   // player at the center of the world.
   return "0 0 300 1 0 0 0";
}
Replace the pickSpawnPoint(%client) with this.
function pickSpawnPoint(%client)
{
   %groupName = "MissionGroup/" @ %client.team.name @ "TeamDropPoints";
   %group = nameToID(%groupName);

   if (%group != -1) {
      %count = %group.getCount();
      if (%count != 0) {
         %index = getRandom(%count-1);
         %spawn = %group.getObject(%index);
         return %spawn.getTransform();
      }
      else
         error("No " @ %client.team.name @ " team spawn points found in " @ %groupName);
   }
   else
      error("Missing " @ %client.team.name @ " team spawn points group " @ %groupName);

   // Could be no spawn points, in which case we'll stick the
   // player at the center of the world.
   return "0 0 300 1 0 0 0";
}

Step 5)
Make a new file in fps/client/scripts and call it teams.cs then add this code to it.
function jointeam(%teamid)
{
   commandtoserver('JoinTeam', %teamid);
   Canvas.popDialog(TeamSelectDlg); //Hide the dialog once selection was made
   ragescore.setText("");
   furyscore.setText("");
}

Step 6)
Now make a file called team.gui in fps/client/ui and have this as the contents.
//--- OBJECT WRITE BEGIN ---
new GameTSCtrl(TeamSelectDlg) {
   profile = "GuiDefaultProfile";
   horizSizing = "right";
   vertSizing = "bottom";
   position = "0 0";
   extent = "640 480";
   minExtent = "8 8";
   visible = "1";
   helpTag = "0";

   new GuiControl() {
      profile = "GuiWindowProfile";
      horizSizing = "center";
      vertSizing = "center";
      position = "159 155";
      extent = "321 170";
      minExtent = "8 8";
      visible = "1";
      helpTag = "0";
      maxLength = "255";
      resizeWidth = "1";
      resizeHeight = "1";
      closeCommand = "Canvas.popDialog(TeamSelectDlg);";

      new GuiTextCtrl() {
         profile = "GuiBigTextProfile";
         horizSizing = "center";
         vertSizing = "relative";
         position = "32 30";
         extent = "257 40";
         minExtent = "8 8";
         visible = "1";
         helpTag = "0";
         text = "Choose your team";
         maxLength = "255";
      };
      new GuiButtonCtrl(RedTeam) {
         profile = "GuiButtonProfile";
         horizSizing = "right";
         vertSizing = "bottom";
         position = "10 130";
         extent = "140 30";
         minExtent = "8 8";
         visible = "1";
         command = "jointeam(1);";
         helpTag = "0";
         text = "Team Fury";
         groupNum = "-1";
         buttonType = "PushButton";
      };
      new GuiButtonCtrl(BlueTeam) {
         profile = "GuiButtonProfile";
         horizSizing = "right";
         vertSizing = "bottom";
         position = "170 130";
         extent = "140 30";
         minExtent = "8 8";
         visible = "1";
         command = "jointeam(2);";
         helpTag = "0";
         text = "Team Rage";
         groupNum = "-1";
         buttonType = "PushButton";
      };
   };
};
//--- OBJECT WRITE END ---
When your done with that exec the files in init.cs.

Step 7)
Add this code to fps/client/config.cs.
moveMap.bindCmd(keyboard, "m", "Canvas.pushDialog(TeamSelectDlg);", "");

Step 8)
Start the game then when you go into the F11 mission editor and add a trigger choose either teamkingofthehilltrigger or newgame trigger and place/scale it accordingly.
Also follow Part 2 in this resource to configure the spawn points http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=2312 which is

Quote:
Part 2: Adding Team Spawn Points

Ok, what's a team support without being able to spawn team members at different locations? Well, that's what we are going to do now, and it's pretty simple. If you open your mission file you'll see that there's a SimGroup called PlayerDropPoints, and inside it you may have one or more spawnspheres which are chosen at random by the function pickSpawnPoint in the game.cs file (fps/server/scripts/game.cs). Well let's modify the mission file, rename the PlayerDropPoints SimGroup so that it's called something team related, for example I'm using for this example RedTeamDropPoints. Now copy the whole SimGroup "RedTeamDropPoints" and paste it after the existing one, now rename the second copy to BlueTeamDropPoints. You should end with something like this:


new SimGroup(RedTeamDropPoints) {
new SpawnSphere() {
position = "80.0366 -215.868 183.615";
rotation = "0 0 1 130.062";
scale = "0.940827 1.97505 1";
dataBlock = "SpawnSphereMarker";
radius = "10";
sphereWeight = "1";
indoorWeight = "1";
outdoorWeight = "1";
locked = "false";
lockCount = "0";
homingCount = "0";
};
};

new SimGroup(BlueTeamDropPoints) {
new SpawnSphere() {
position = "80.0366 -215.868 183.615";
rotation = "0 0 1 130.062";
scale = "0.940827 1.97505 1";
dataBlock = "SpawnSphereMarker";
radius = "10";
sphereWeight = "1";
indoorWeight = "1";
outdoorWeight = "1";
locked = "false";
lockCount = "0";
homingCount = "0";
};
};



In the example code I'm only using one spawnsphere per SimGroup, you can add as many as you want. You might also want to change the position of the spawnspheres, do this changing the coordinates in the code above or by entering the game using the in-game editor and moving the SpawnSpheres around.
Let's implement the code that will read through the SpawnPoints. Open up game.cs and in the GameConnection::spawnPlayer() function add %this between the parentheses of the first line, the whole function should then look like this:


function GameConnection::spawnPlayer(%this)
{
// Combination create player and drop him somewhere
%spawnPoint = pickSpawnPoint(%this); //This line changed
%this.createPlayer(%spawnPoint);
}



Well what's that for? I made that change cause you'll have to access the GameConnection in the pickSpawnPoint function to get the team the player is in, so I just passed the %this variable which points to GameConnection, to the pickSpawnPoint function. Another way of doing this could be to include the pickSpawnPoint function in the GameConnection class, but I prefered to pass it as argument.
Well now scroll down in game.cs and look for the pickSpawnPoint function, should be almost at the end of the file. Now change that function to look like this (just replace the old one with this one):


function pickSpawnPoint(%client)
{
%groupName = "MissionGroup/" @ %client.team.name @ "TeamDropPoints";
%group = nameToID(%groupName);

if (%group != -1) {
%count = %group.getCount();
if (%count != 0) {
%index = getRandom(%count-1);
%spawn = %group.getObject(%index);
return %spawn.getTransform();
}
else
error("No " @ %client.team.name @ " team spawn points found in " @ %groupName);
}
else
error("Missing " @ %client.team.name @ " team spawn points group " @ %groupName);

// Could be no spawn points, in which case we'll stick the
// player at the center of the world.
return "0 0 300 1 0 0 0";
}



The most important change in this function is the first line, instead of looking for PlayerDropPoints group it will now look for RedTeamDropPoints or BlueTeamDropPoints, depending on the client's team. I also changed the two error lines to report what team is missing spawn points instead of just saying there are no spawn points.
Well that's all, easy part huh? Enjoy your new team spawn points.

I'll be posting a ScoreBoard later, it should have been here as Part #3 but got delayed, and delayed, etc so i decided to release what i had! have fun!
Thanks to Phil for "Beta" testing the tutorial :)

Now open up your game and test.

If you have any way to improve this please post and if you are using this please give me for the Koth code and the dude who made the teams implementation resource credit. Enjoy.

#1
04/12/2006 (5:03 am)
I have a problem with this resource....Sorry but i'm a stupid....Uff i try and try for resolve the problem but i become crazy!!!
If select a team....My player is always red team...In chatbox see a enter in different team
But if press F11 .... select my player and F3 for see a carateristic....In team see RED always....HELP MY PLEASE!!! THANKS for ALL
#2
04/29/2006 (2:29 pm)
Speaking of using large triggers, has anyone else had an issue when firing projectiles while standing inside the trigger, while _also_ inside a DIF with zone portals?
#3
05/01/2006 (2:28 pm)
sorry?
#4
08/03/2006 (8:16 pm)
I did everything it said in the tutorial. I couldn't spawn, and my inventory said 'omgwtf'. I was playing Blockland (jason7811). Good thing I backed up the files.
#5
08/12/2006 (6:06 am)
Great resource!
Thank you tons.

Ari
#6
11/26/2006 (11:09 am)
starter.fps/client/scripts/teams.cs (5): Unable to find object: 'ragescore' attempting to call function 'setText'
starter.fps/client/scripts/teams.cs (6): Unable to find object: 'furyscore' attempting to call function 'setText'

What does this mean?
#7
11/26/2006 (11:12 am)
Thats means you need to create 2 gui text elements and name them ragescore and furyscore
#8
11/26/2006 (1:03 pm)
I'll try, I'm new to TGE so I'm not exactly sure what I'm doing.

Also, when I'm in the trigger zone, nothing happens.
#9
11/05/2009 (6:25 pm)
Ok, i tested all.. very good work..

only one erro with drop teams..
IN TeamKoth.cs you have Rage and Fury team deop points
and after you have write to add to the mission file RedPlayerDrop adn BluePlayerDrop..

This can create confusion..
Because the datablock name must be:
FuryTeamDropPoints
RageTeamDropPoints

... .................................................

This only for noobs:) like me:)