Multiple Player Class Selection
by mb · 11/30/2006 (1:21 pm) · 44 comments
<a href="/static/pg/resource/11733.classes.rtf">Download Code File</a>
This version has been updated for T3D and you don't need to use the old Team Implementation resource as I merged the two. The new version is found here: www.garagegames.com/community/resources/view/18383
Description:
This adds player classes and a selection menu to the Teams Implementation resource. Also adds spawn delays after choosing your classes. There 5 classes for each team and each class can have its own models, weapons, ammo, etc... <NOTE: the .rtf file explains the code in more detail if you need it.>
Note: Add the Team Implementation resource first before adding this resource:
www.garagegames.com/community/resources/view/2312
fps/server/scripts/game.cs
at the end of the file add:
Next at the top of the same file: fps/server/scripts/game.cs
add these: As you can see it uses playerClassId to identify what clas a player is, and a name. You could define more in here
if you wanted like weapons/ammo/armor, various traits etc... but I decided to do this before the player spawns.
Next is the GUI selection screen, very basic, you can change it how you like.
Name it: ClassSelectDlg.gui and save it in client/ui
then in fps/server/scripts/commands.cs I put the server commands which in the team implementation was done on the client, I
just moved it all into the server. I dont know if thats right or not, but I did it. If it doesnt work for you then move the joinclass function into a script on the client, like they do in the team code. Im gonna list the whole code cause Im sure I changed some stuff in here.
Next in fps/client/init.cs add this exec: (note: if you did what I mentioned above and put a file clientside, you would need
to exec it here also. If you look at the team code you'll know what I mean.)
Next in game.cs again serverside... I added some code: This just resets some variables if needed (probably not needed but doesnt hurt to have them)
Then down a bit in game.cs the spawnplayer function: makes the player spawn after about ten seconds.
Next bit of code is where you set the classes & the player datablocks, weapons, ammo, etc... you could again do this at the
top of game.cs and then reference it here, but I just did it all in here... btw: change the player datablocks to your own. IE: PlayerBody1Class1, etc. and mount weapons/ammo.. how you like.
Still in game.cs comment out the spawnPlayer in function GameConnection::joinTeam because we dont do that here (we do it in GameConnection::joinPlayerClass).
Then in player.cs
I inherited the same player datablock and just changed the dts model. Do this for all your players. PlayerBody1Class1 - PlayerBody2Class5. You dont have to change the models if you dont want to of course, you could just use just one. Put this after: datablock PlayerData(PlayerBody)
<EDIT>
When your already in game and want to switch$ team/classes.
make a new gui: TeamSelectDlg2.gui
config.cs: you could just delete this file, the engine will make a new one for you
change defaultbind.cs:
and client/scripts/client/config.cs
When you press 'm' you get the TeamSelectDlg2 menu and it kills your player in "suicideJoinTeam".
And one last thing if it's not in there already add this line in bold to clientscriptsserverConnection.cs :
Sorry if I left anything out, I coded this a few months back when I first got TGE.
This version has been updated for T3D and you don't need to use the old Team Implementation resource as I merged the two. The new version is found here: www.garagegames.com/community/resources/view/18383
Description:
This adds player classes and a selection menu to the Teams Implementation resource. Also adds spawn delays after choosing your classes. There 5 classes for each team and each class can have its own models, weapons, ammo, etc... <NOTE: the .rtf file explains the code in more detail if you need it.>
Note: Add the Team Implementation resource first before adding this resource:
www.garagegames.com/community/resources/view/2312
fps/server/scripts/game.cs
at the end of the file add:
function GameConnection::joinPlayerClass(%this, %classid)
{
//We only have 5 player classes so if class is greater than 5 or less than 0 its invalid.
if (%classid > 5 || %classid < 0)
return false;
if (%this.respawn == 1) // If player is spawning then dont spawn again!
return false;
if (%classid == 1)
%this.playerClass = $PlayerClass1;
if (%classid == 2)
%this.playerClass = $PlayerClass2;
if (%classid == 3)
%this.playerClass = $PlayerClass3;
if (%classid == 4)
%this.playerClass = $PlayerClass4;
if (%classid == 5)
%this.playerClass = $PlayerClass5;
// MessageAll('MsgClientJoinTeam', 'c2%1 joined the %2 side', %this.name, %this.team.name, %this.team.teamId, %this,
%this.sendGuid, %this.score, %this.isAiControlled(), %this.isAdmin, %this.isSuperAdmin);
%this.spawnPlayer(%this);
}Next at the top of the same file: fps/server/scripts/game.cs
add these: As you can see it uses playerClassId to identify what clas a player is, and a name. You could define more in here
if you wanted like weapons/ammo/armor, various traits etc... but I decided to do this before the player spawns.
$PlayerClass1 = new ScriptObject()
{
playerClassId = 1;
name = Engineer;
};
$PlayerClass2 = new ScriptObject()
{
playerClassId = 2;
name = Assault;
};
$PlayerClass3 = new ScriptObject()
{
playerClassId = 3;
name = Medic;
};
$PlayerClass4 = new ScriptObject()
{
playerClassId = 4;
name = Demolition;
};
$PlayerClass5 = new ScriptObject()
{
playerClassId = 5;
name = Noob;
};Next is the GUI selection screen, very basic, you can change it how you like.
Name it: ClassSelectDlg.gui and save it in client/ui
//--- OBJECT WRITE BEGIN ---
new GameTSCtrl(ClassSelectDlg) {
Profile = "GuiDefaultProfile";
HorizSizing = "right";
VertSizing = "bottom";
position = "0 0";
Extent = "640 480";
MinExtent = "8 8";
Visible = "1";
applyFilterToChildren = "1";
cameraZRot = "0";
forceFOV = "0";
helpTag = "0";
new GuiWindowCtrl() {
Profile = "GuiWindowProfile";
HorizSizing = "center";
VertSizing = "center";
position = "159 155";
Extent = "321 170";
MinExtent = "8 8";
Visible = "1";
maxLength = "255";
resizeWidth = "1";
resizeHeight = "1";
canMove = "1";
canClose = "1";
canMinimize = "1";
canMaximize = "1";
MinSize = "50 50";
closeCommand = "Canvas.popDialog(ClassSelectDlg);";
helpTag = "0";
new GuiTextCtrl() {
Profile = "GuiBigTextProfile";
HorizSizing = "center";
VertSizing = "relative";
position = "31 22";
Extent = "259 40";
MinExtent = "8 8";
Visible = "1";
text = "Choose your class";
maxLength = "255";
helpTag = "0";
};
new GuiButtonCtrl(Class1) {
Profile = "GuiButtonProfile";
HorizSizing = "right";
VertSizing = "bottom";
position = "11 63";
Extent = "140 30";
MinExtent = "8 8";
Visible = "1";
Command = "joinclass(1);";
tooltipprofile = "GuiDefaultProfile";
text = "Class 1";
groupNum = "-1";
buttonType = "PushButton";
helpTag = "0";
};
new GuiButtonCtrl(Class2) {
Profile = "GuiButtonProfile";
HorizSizing = "right";
VertSizing = "bottom";
position = "11 97";
Extent = "140 30";
MinExtent = "8 8";
Visible = "1";
Command = "joinclass(2);";
text = "Class 2";
groupNum = "-1";
buttonType = "PushButton";
helpTag = "0";
};
new GuiButtonCtrl(Class3) {
Profile = "GuiButtonProfile";
HorizSizing = "right";
VertSizing = "bottom";
position = "11 132";
Extent = "140 30";
MinExtent = "8 8";
Visible = "1";
Command = "joinclass(3);";
text = "Class 3";
groupNum = "-1";
buttonType = "PushButton";
helpTag = "0";
};
new GuiButtonCtrl(Class4) {
Profile = "GuiButtonProfile";
HorizSizing = "right";
VertSizing = "bottom";
position = "157 64";
Extent = "140 30";
MinExtent = "8 8";
Visible = "1";
Command = "joinclass(4);";
text = "Class 4";
groupNum = "-1";
buttonType = "PushButton";
helpTag = "0";
};
new GuiButtonCtrl(Class5) {
Profile = "GuiButtonProfile";
HorizSizing = "right";
VertSizing = "bottom";
position = "157 97";
Extent = "140 30";
MinExtent = "8 8";
Visible = "1";
Command = "joinclass(5);";
text = "Class 5";
groupNum = "-1";
buttonType = "PushButton";
helpTag = "0";
};
};
};
//--- OBJECT WRITE END ---then in fps/server/scripts/commands.cs I put the server commands which in the team implementation was done on the client, I
just moved it all into the server. I dont know if thats right or not, but I did it. If it doesnt work for you then move the joinclass function into a script on the client, like they do in the team code. Im gonna list the whole code cause Im sure I changed some stuff in here.
// Teamplay
function serverCmdJoinTeam(%client, %teamid)
{
%client.joinTeam(%teamid);
}
// Teamplay - pick a class
function serverCmdJoinPlayerClass(%client, %classid)
{
%client.joinPlayerClass(%classid);
}
function joinclass(%classid)
{
commandtoserver('JoinPlayerClass', %classid);
Canvas.popDialog(ClassSelectDlg); //Hide the dialog once selection was made
}
function jointeam(%this, %teamid)
{
commandtoserver('JoinTeam', %this, %teamid);
Canvas.popDialog(TeamSelectDlg); //Hide team select menu
Canvas.pushDialog(ClassSelectDlg); // Show class select menu
}
function suicideJoinTeam(%this, %teamid)
{
commandtoserver('Suicide');
commandtoserver('JoinTeam', %this, %teamid);
Canvas.popDialog(TeamSelectDlg2); //Hide team select menu
Canvas.pushDialog(ClassSelectDlg); // Show class select menu
}Next in fps/client/init.cs add this exec: (note: if you did what I mentioned above and put a file clientside, you would need
to exec it here also. If you look at the team code you'll know what I mean.)
exec("./ui/ClassSelectDlg.gui");
exec("./ui/TeamSelectDlg2.gui");Next in game.cs again serverside... I added some code: This just resets some variables if needed (probably not needed but doesnt hurt to have them)
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.respawn = 0; // tracks whether a player is spawning or not
%this.team = 0; //default team is 0 (observer)
%this.playerClass = 0; // default class is 0
//Spawn a camera by default on a observer point
%this.camera.setTransform(pickObserverPoint(%this));
%this.camera.setVelocity("0 0 0");
%this.setControlObject(%this.camera);
}Then down a bit in game.cs the spawnplayer function: makes the player spawn after about ten seconds.
function GameConnection::spawnPlayer(%this)
{
if (%this.respawn == 1) // If player is spawning then dont spawn again!
return;
%this.respawn = 1;
// Combination create player and drop him somewhere
%spawnPoint = pickSpawnPoint(%this);
%this.schedule(10000,createPlayer,%spawnPoint); // delay spawn
}Next bit of code is where you set the classes & the player datablocks, weapons, ammo, etc... you could again do this at the
top of game.cs and then reference it here, but I just did it all in here... btw: change the player datablocks to your own. IE: PlayerBody1Class1, etc. and mount weapons/ammo.. how you like.
function GameConnection::createPlayer(%this, %spawnPoint)
{
if (%this.player > 0) {
// The client should not have a player currently
// assigned. Assigning a new one could result in
// a player ghost.
error( "Attempting to create an angus ghost!" );
}
// get the correct datablock for the player. This is the players class.
// TEAM 1 DATABLOCKS
if (%this.team.teamId == 1)
{
switch ( %this.playerClass.playerClassId )
{
// Class 1
case 1:
%classDatablock = PlayerBody1Class1; // change to another datablock when we make new models for each class
// Class 2
case 2:
%classDatablock = PlayerBody1Class2;
// Class 3
case 3:
%classDatablock = PlayerBody1Class3;
// Class 4
case 4:
%classDatablock = PlayerBody1Class4;
// Class 5
case 5:
%classDatablock = PlayerBody1Class5;
}
}
// TEAM 2 DATABLOCKS
if (%this.team.teamId == 2)
{
switch ( %this.playerClass.playerClassId )
{
// Class 1
case 1:
%classDatablock = PlayerBody2Class1; // change to another datablock when we make new models for each class
// Class 2
case 2:
%classDatablock = PlayerBody2Class2;
// Class 3
case 3:
%classDatablock = PlayerBody2Class3;
// Class 4
case 4:
%classDatablock = PlayerBody2Class4;
// Class 5
case 5:
%classDatablock = PlayerBody2Class5;
}
}
// Create the player object
%player = new Player() {
dataBlock = %classDatablock;
client = %this;
};
MissionCleanup.add(%player);
// Player setup...
%player.setTransform(%spawnPoint);
%player.setShapeName(%this.name);
// Starting equipment
// need to change this to a switch$ statement for each class...
// TEAM 1 WEAPONS
if (%this.team.teamId == 1)
{
switch ( %this.playerClass.playerClassId )
{
// Class 1
case 1:
%player.setInventory(Crossbow,1);
%player.setInventory(CrossbowAmmo,10);
%player.mountImage(CrossbowImage,0);
// Class 2
case 2:
%player.setInventory(Pistol,1);
%player.setInventory(PistolImage,1);
%player.setInventory(PistolAmmoClip,4);
%player.setInventory(Rifle,1);
%player.setInventory(RifleAmmoClip,3);
%player.mountImage(RifleImage,0);
// Class 3
case 3:
%player.setInventory(Pistol,1);
%player.setInventory(PistolAmmoClip,4);
%player.mountImage(PistolImage,0);
// Class 4
case 4:
%player.setInventory(Shotgun,1);
%player.setInventory(ShotgunAmmoClip,5);
%player.mountImage(ShotgunImage,0);
// Class 5
case 5:
%player.setInventory(Shotgun,1);
%player.setInventory(ShotgunAmmoClip,5);
%player.mountImage(ShotgunImage,0);
}
}
// TEAM 2 WEAPONS
if (%this.team.teamId == 2)
{
switch ( %this.playerClass.playerClassId )
{
// Class 1
case 1:
%player.setInventory(Pistol,1);
%player.setInventory(PistolAmmo,10);
%player.mountImage(PistolImage,0);
// Class 2
case 2:
%player.setInventory(Pistol,1);
%player.setInventory(PistolAmmo,10);
%player.mountImage(PistolImage,0);
// Class 3
case 3:
%player.setInventory(Pistol,1);
%player.setInventory(PistolAmmo,10);
%player.mountImage(PistolImage,0);
// Class 4
case 4:
%player.setInventory(Pistol,1);
%player.setInventory(PistolAmmo,10);
%player.mountImage(PistolImage,0);
// Class 5
case 5:
%player.setInventory(Pistol,1);
%player.setInventory(PistolAmmo,10);
%player.mountImage(PistolImage,0);
}
}
// Update the camera to start with the player
%this.camera.setTransform(%player.getEyeTransform());
// Give the client control of the player
%this.player = %player;
%this.setControlObject(%player);
%this.respawn = 0; // allow player to respawn after dying.
echo ("CLASS NAME: " @ %this.playerClass.name );
}Still in game.cs comment out the spawnPlayer in function GameConnection::joinTeam because we dont do that here (we do it in GameConnection::joinPlayerClass).
//%this.spawnPlayer(); // in GameConnection::joinTeam
Then in player.cs
I inherited the same player datablock and just changed the dts model. Do this for all your players. PlayerBody1Class1 - PlayerBody2Class5. You dont have to change the models if you dont want to of course, you could just use just one. Put this after: datablock PlayerData(PlayerBody)
datablock PlayerData(PlayerBody1Class1 : PlayerBody)
{
shapeFile = "~/data/shapes/player/player.dts";
};
datablock PlayerData(PlayerBody1Class2 : PlayerBody)
{
shapeFile = "~/data/shapes/player/player.dts";
};
datablock PlayerData(PlayerBody1Class3 : PlayerBody)
{
shapeFile = "~/data/shapes/player/player.dts";
};
datablock PlayerData(PlayerBody1Class4 : PlayerBody)
{
shapeFile = "~/data/shapes/player/player.dts";
};
datablock PlayerData(PlayerBody1Class5 : PlayerBody)
{
shapeFile = "~/data/shapes/player/player.dts";
};
datablock PlayerData(PlayerBody2Class1 : PlayerBody)
{
shapeFile = "~/data/shapes/player/player.dts";
};
datablock PlayerData(PlayerBody2Class2 : PlayerBody)
{
shapeFile = "~/data/shapes/player/player.dts";
};
datablock PlayerData(PlayerBody2Class3 : PlayerBody)
{
shapeFile = "~/data/shapes/player/player.dts";
};
datablock PlayerData(PlayerBody2Class4 : PlayerBody)
{
shapeFile = "~/data/shapes/player/player.dts";
};
datablock PlayerData(PlayerBody2Class4 : PlayerBody)
{
shapeFile = "~/data/shapes/player/player.dts";
};<EDIT>
When your already in game and want to switch$ team/classes.
make a new gui: TeamSelectDlg2.gui
//--- OBJECT WRITE BEGIN ---
new GameTSCtrl(TeamSelectDlg2) {
Profile = "GuiDefaultProfile";
HorizSizing = "right";
VertSizing = "bottom";
position = "0 0";
Extent = "640 480";
MinExtent = "8 8";
Visible = "1";
applyFilterToChildren = "1";
cameraZRot = "0";
forceFOV = "0";
helpTag = "0";
new GuiWindowCtrl() {
Profile = "GuiWindowProfile";
HorizSizing = "center";
VertSizing = "center";
position = "159 155";
Extent = "321 170";
MinExtent = "8 8";
Visible = "1";
maxLength = "255";
resizeWidth = "1";
resizeHeight = "1";
canMove = "1";
canClose = "1";
canMinimize = "1";
canMaximize = "1";
MinSize = "50 50";
closeCommand = "Canvas.popDialog(TeamSelectDlg2);";
helpTag = "0";
new GuiTextCtrl() {
Profile = "GuiBigTextProfile";
HorizSizing = "center";
VertSizing = "relative";
position = "32 30";
Extent = "257 40";
MinExtent = "8 8";
Visible = "1";
text = "Choose your team";
maxLength = "255";
helpTag = "0";
};
new GuiButtonCtrl(RedTeam) {
Profile = "GuiButtonProfile";
HorizSizing = "right";
VertSizing = "bottom";
position = "10 130";
Extent = "140 30";
MinExtent = "8 8";
Visible = "1";
Command = "suicideJoinTeam(1);";
tooltipprofile = "GuiDefaultProfile";
text = "Red Team";
groupNum = "-1";
buttonType = "PushButton";
helpTag = "0";
};
new GuiButtonCtrl(BlueTeam) {
Profile = "GuiButtonProfile";
HorizSizing = "right";
VertSizing = "bottom";
position = "170 130";
Extent = "140 30";
MinExtent = "8 8";
Visible = "1";
Command = "suicideJoinTeam(2);";
text = "Blue Team";
groupNum = "-1";
buttonType = "PushButton";
helpTag = "0";
};
};
};
//--- OBJECT WRITE END ---config.cs: you could just delete this file, the engine will make a new one for you
moveMap.bindCmd(keyboard, "m", "Canvas.pushDialog(TeamSelectDlg2);", "");
change defaultbind.cs:
moveMap.bindCmd(keyboard, "m", "Canvas.pushDialog(TeamSelectDlg2);", "");
and client/scripts/client/config.cs
moveMap.bindCmd(keyboard, "m", "Canvas.pushDialog(TeamSelectDlg2);", "");
When you press 'm' you get the TeamSelectDlg2 menu and it kills your player in "suicideJoinTeam".
And one last thing if it's not in there already add this line in bold to clientscriptsserverConnection.cs :
function GameConnection::initialControlSet(%this)
{
echo ("*** Initial Control Object");
// The first control object has been set by the server
// and we are now ready to go.
// first check if the editor is active
if (!Editor::checkActiveLoadDone())
{
if (Canvas.getContent() != PlayGui.getId())
Canvas.setContent(PlayGui);
[b]
// Teamplay - popup team select gui
Canvas.pushDialog(TeamSelectDlg);[/b]
}
}Sorry if I left anything out, I coded this a few months back when I first got TGE.
About the author
#42
09/27/2009 (8:03 pm)
New Teams & Classes resource for T3D here: www.garagegames.com/community/resources/view/18383
#43
...
anyone have think to add another code for teamplay for example:
player of team 1 cannot se nick in green color of players in team 2
and players in team2 cannot see green nick of players in team 1..
I have search and i find nothing that can work..
I have tested many.. but not work..
Please who use TGEA and is big programmer not noob:) like me..
create one TeamPlayer Thread for TGEA 1.8x for have many working script..
This for example is one big script but i don't know why don't work in tgea 1.8x..
.............................s.o.s..............................
11/09/2009 (5:49 pm)
what is the team drop points name? i think is this the problem about why this script don't work for me in tgea 1.81...
anyone have think to add another code for teamplay for example:
player of team 1 cannot se nick in green color of players in team 2
and players in team2 cannot see green nick of players in team 1..
I have search and i find nothing that can work..
I have tested many.. but not work..
Please who use TGEA and is big programmer not noob:) like me..
create one TeamPlayer Thread for TGEA 1.8x for have many working script..
This for example is one big script but i don't know why don't work in tgea 1.8x..
.............................s.o.s..............................
#44
It works in TGEA but I don't know which version of TGEA I used. The drop points are the same as in the original resource for teams and also the new T3D version might actually work for TGEA also.
Drop point names: RedTeamDropPoints, BlueTeamDropPoints, ObserverDropPoints.
Original version: www.garagegames.com/community/resources/view/2312
T3D Version:
www.garagegames.com/community/resources/view/18383
11/13/2009 (2:19 pm)
Did you first do the Teams Implementation resource? For this version to work you need to do that resource first. If you use the T3D version you don't have to because I merged the two resources into one resource. It works in TGEA but I don't know which version of TGEA I used. The drop points are the same as in the original resource for teams and also the new T3D version might actually work for TGEA also.
Drop point names: RedTeamDropPoints, BlueTeamDropPoints, ObserverDropPoints.
Original version: www.garagegames.com/community/resources/view/2312
T3D Version:
www.garagegames.com/community/resources/view/18383

Torque 3D Owner mb