Game Development Community

dev|Pro Game Development Curriculum

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:
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.
#21
07/13/2007 (10:46 am)
You would need to get the handle 'id #' of the player on the clientside in defaultbind.cs (not sure how right now without looking at the code, it might just pass it in like everything else using %this) and then check what class he is like %this.playerClass.playerClassId and run some code for that class. You could use a switch statement like I did above or if statements.

So assuming that the player calls that function and %this is the players handle... it would look something like:

function myJetpack( %this, %val )
{
if ( %val )
{
if (%this.playerClass.playerClassId == 1)
{
  // run the jetpack code
}
}
}
#22
08/27/2007 (1:09 pm)
mb Thanks also from me for this resource. I got everything working for your resource. But, I want to change it to No Teams, only PlayerBodies (classes) I have it figured out except for the server side init. My problem is knowing where to call the joinclass(%classid) function. I want to skip your Class dialog (I made my own for selecting a player and have it in the game options at the mainmenu) and just call the joinclass() function. My thinking is that I need to do the call in GameConnection::onClientEnterGame() in game.cs or maybe GameConnection::createPlayer().

Also wondering if you could change characters in mid-game using only script by forcing a suicide on 1 character and then respawn as a different character. The vision is to enter a portal and emerge somewhere else as someone else. That would be nice!
My thanks to all who contributed to this resource, it's been extremely helpful.
#23
08/28/2007 (10:37 am)
Thanks Shon.

One way (just an idea...keep in mind this is all theory, I'm making this up as I go) you could do that is create buttons for each class and have it call a command when you click on it. Like so:

new GuiButtonCtrl(Class1Button)
{
command = "ChooseClass(1);";
};

Then in server/scripts/commands.cs you could make a function that sets the class.

// This function is called from the gui.
function  chooseClass(%classID)
{
commandtoserver('ChooseClass', %classid);
}

// This function  is called from the function above (chooseClass)
function  serverCmdChooseClass(%client, %classID)
{
%client.joinPlayerClass(%classid);
}

Now the players class should be set. In my code the player spawns from the GameConnection::joinPlayerClass function which is what we called above so you would need to change that so they don't spawn until they connect. At the end of GameConnection::joinPlayerClass function is: %this.spawnPlayer(%this); . You would need to comment that out or delete it.

In GameConnection::onClientEnterGame it resets the player class to 0 with the command: %this.playerClass = 0; // default class is 0. Comment or delete that line. And then I guess it's safe to spawn from there? So at the end of GameConnection::onClientEnterGame function (same function)add: %this.spawnPlayer(%this);


You would need a default set already in-case they don't click on a class.. unless you want to force them to pick one everytime. .. or save it in a file or database. This is all in theory btw... good luck! And I hope this isn't too confusing.. cause I didn't test any of this. :)


The function suicideJoinTeam will force a suicide on a character and respawn them after a few seconds.
#24
09/05/2007 (8:23 am)
@mb I appreciate your input and will start playing with it this week. Sorry I took so long to get back but I actually had a short vacation and went so far into the woods that the cell phone didn't even work. So once again thanks and I will post back what I come up with.
#25
01/26/2009 (9:23 pm)
Thanks man, awesome resource. I'm new to scripting,coding, and what not. I can dig through and sort out some of the common sense stuff, like maxInventory and such, but I never would have gotten this without your help.

One question I have though:

The game wouldn't launch, it kept hanging on loading objects. I pressed
"~" to bring up the console. It informed me of a script error in game.cs on a specific line. I went and checked it out and found this. (sorry i don't know how to add code boxes in posts).

(this was all on one line commented out)
// MessageAll('MsgClientJoinTeam', '\c2%1 joined the %2 side', %this.name, %this.team.name, %this.team.teamId, %this,

(this was all on one line, as is)
%this.sendGuid, %this.score, %this.isAiControlled(), %this.isAdmin, %this.isSuperAdmin);

I copied it from the code blocks posted. When I commented out the line

%this.sendGuid, %this.score, %this.isAiControlled(), %this.isAdmin, %this.isSuperAdmin);

It worked. Is this line for anything important? It all seems to work fine.

#26
01/27/2009 (6:18 am)
@Charlie: Wow been a long time since I did this. You can comment out the line you stated. It is just a continuation of the line you already commented. Like you said it worked. The listing has a forced carriage return when I pasted it and I missed it and I apologize. This was initially a debug line simply to test values. Hope that helped.
#27
01/27/2009 (2:48 pm)
Ah, I had thought maybe it had wrapped around and maybe just carried over to the next line. Thank you for confirming that.

I noticed one last thing. I am using

http://www.garagegames.com/community/resources/view/13640 the Usebutton resource.

I have had it implemented for some time. I currently only use it for mounting vehicles. The resource is still stock, I did not alter anything.

It worked before I used the team implementation resource. It worked after I used that resource.

However, with the class selection resource implemented. It only works with the first class on the first team. It won't work with any other classes (2,3,4,5) or team 2 at all. If I press "e" Torque immediately crashes, UNLESS I am using Team 1, Class 1.

I am unable to open the console to check for errors due to the crash. I actually don't even need to be near the vehicle, it seems the raycast itself encounters something from the class resource. It crashes any time I press E (except with team 1, class 1), looking at water, terrain, the sky, etc.

I went as far as to install Torque again. Then implement the resources one at a time. I added, Usebutton, Team Implementation, and Class Selection. In team implementation, both teams could use vehicles, no prob.

Is there anything I should add/change? Or are the 2 resources compatible at all? Just wondering if anyone had ran into this.
#28
01/28/2009 (7:06 am)
@Charlie: Not seeing your code and where it is being called from, I really have no idea what the problem is. One thing I noticed reading the article about Use Button the code is written as a Server Command. I remember Server commands being very complex with this system. There is no real separation in the explanations about separating Server and Client Code. You can also look at the file console.log in your work directory and see the console. As I am not programming Torque ever again over a disagreement with management about pricing. I will say no more because I am a nice guy and when I get screwed I just leave the scene. Fighting back is worthless and can be the mind killer. We have moved on from Torque to a real Multi-User system that handles 2000 users per Linux server (tested) and is configurable to allow clustering and may contain separate servers for Animation Control, Voice Chat, Database Management, Quests, Large Terrain Region control, Video and Audio Streaming and the ability to use ANY collision system you like (do it by the model) as all collision types are available (obb, aabb). There is a lot more but I will shut up now because I am under gag order as are all of our partners to keep our mouths shut on the internet until beta in March. All I will add is that I have been working with servers for 28 years and this is some of the finest server programming work I have ever seen, so come see Interactive Worlds Online at GDC in San Francisco. We will unveil beta world in progress there.
#29
08/06/2009 (2:08 am)
i’ve tried to import this to my T3D game. The guis and the weapons are working, but my ammo is still on zero. I spawn with my chosen class and the weapon, but without ammo.

I’ve tried some options to my code.

case 1:
      %player.setInventory(crossbow,1);
   	%player.setInventory(crossbowAmmo, 10);
   	%player.mountImage(crossbowImage,0);
            

            // Class 2
            case 2:
	   %player.setInventory(m4,1);
      %player.mountImage(m4Image,0);
   	%player.Inv[m4Ammo]= 40;

case1 was from the original code. When I spawn I’ve got no ammo. For example the crossbow in the hands is empty without any bolt.

In case2 I tried something, now I got just 1 shot, but still not my value.

without this classes script, are my weapons working. so i 've got somewhere an error.

What is my fault?

should i use another script for inventorysetup?
#30
08/06/2009 (10:39 am)
@Charlie

I used the team implementation, the class resource and the use button. I don't know what is causing the crash. Check the console or the log for errors.

@Arnie

I haven't tried putting this code into T3D yet. I don't know if they changed any scripting code or not. I'll have to look at it later tonight.
#31
08/30/2009 (11:02 am)
did you find something out?
#32
09/23/2009 (4:41 pm)
hmm, i think i stop with it now. i'm to unskilled at the moment. i just started to study development. maybe i can fix it some day.

after 1 month searching for my bug and a help request in the private t3d with no reply i stop now.

my console ingame has no error at the script, i spawn with the correct player model, with the correct weapon, but without any ammo -_-
#33
09/23/2009 (4:48 pm)
Arne, it looks like you have a typo in the code above.
%player.Inv[m4Ammo]= 40;

should be
%player.setInventory(m4Ammo, 40);
I would also put it before you mount the image.
#34
09/23/2009 (4:54 pm)
Also make sure you have the items set up in your playerdata datablock for the inventory system. You should see a section like:
// Allowable Inventory Items
   maxInv[BulletAmmo] = 20;
   maxInv[HealthKit] = 1;
   maxInv[RifleAmmo] = 100;
   maxInv[CrossbowAmmo] = 50;
   maxInv[RocketLauncherAmmo] = 50;
   maxInv[Crossbow] = 1;
   maxInv[Rifle] = 1;
   maxInv[RocketLauncher] = 1;

If you do not have a definition for you ammo it cannot be added to your inventory.
#35
09/23/2009 (5:43 pm)
thx ryan for help! my playerdata block is fine. i insert those weapons and ammo max values.

at the code above, i tried some different versions. this code was just to show 2 types of it. i tried them the whole function. and even all are like this
%player.setInventory(crossbow,1);
   	%player.setInventory(crossbowAmmo, 10);
   	%player.mountImage(crossbowImage,0);
they are not working. :(

the default weapons like this crossbow are not working too. but when i insert those weapons without this class script, they are working. so the weapons scripts should be fine too. and i can't tell you where i have to search for it.
#36
09/23/2009 (6:13 pm)
Do you have Torsion? If you do then set a break point at the line:
if (%this.team.teamId == 1)
Step through that and see what path your code is taking. If you still can't get it you send me your files and I will take a look. Email should be in my profile.
#37
09/23/2009 (6:26 pm)
thx ryan! you're a great help. i check this, and if i can't get any progress i send it tommorow via email. i have to go to bed soon, in germany it's nearly midnight and i have to be in university tommorow :(
#38
09/24/2009 (5:31 am)
wow, my first thunderbird didn't send it, cause of an error, and at my webmail interface i've missed the topic, so the mail without topic, that's me ;)
#39
09/24/2009 (6:16 am)
ok, the webmail send me a mailerdeamon, can you check your email in the profile?
#40
09/24/2009 (11:12 am)
The email in my profile is correct, how big is the file? Earthlink may have a limit so try this one as well ryan.mick@sacdeveloper.com. If its too big I will set up an FTP site for you to upload it to.