Game Development Community

Change Player's datablock through an Trigger

by Paul Rueder · in Torque 3D Professional · 03/08/2012 (10:46 am) · 5 replies

Hi Guys, i have a small Problem. I try to set the player's datablock through an ingame trigger. My used code is the following:

(both .cs files are "exec" in scripts/main.cs in the onStart() function)

clientcommands.cs:

function clientCmdChangeSoldier()
{
   commandToServer('ChangePlayerSoldier');
}
function clientCmdChangeGideon()
{
   commandToServer('ChangePlayerGideon');
}

servercommands.cs:

function serverCmdChangePlayerSoldier(%obj)
{
   %client = %obj.client; 
   %client.player.setDatablock(DefaultPlayerData);
   echo("You are now a Soldier!");
}
function serverCmdChangePlayerGideon(%obj)
{
   %client = %obj.client; 
   %client.player.setDatablock(GideonPlayerData);
   echo("You are now a Gideon!");
}

The two used triggers ingame (based of the defaulttriggerdata datablock), have a (World Editor -> Trigger Object -> General -> enterCommand) "ChangeGideon();" or "ChangeSoldier();" command set.

It works perfectly for the Player who hosts the Server, but all other Clients datablocks arent changed when they walk into the trigger.

So, what can i do to fix that? :/

#1
03/08/2012 (11:12 am)
You can just re-instantiate a datablock for an object, they can't be modified on the fly. You could delete and spawn a new player type in one go at the location and hand that over to the client for control.
#2
03/08/2012 (1:12 pm)
I'm pretty sure the Player class is made to handle switching datablocks - check out all the code in onNewDataBlock.

Trigger objects operate on the server, so you shouldn't need to deal with clientCmd or serverCmds at all. Also, the argument to a serverCmd is a client, not an object:
function serverCmdChangePlayerSoldier(%client)
{
   %client.player.setDatablock(DefaultPlayerData);
}
I'm not sure what might be causing the code to work just for the local host, but try removing the client/serverCmd paradigm (just make your functions regular functions in server scripts) and see how you go.
#3
03/08/2012 (9:22 pm)
[edit] looks like I haven't refreshed the page for a while.


I'm not sure how this works for the server, but I know why it wouldn't work for your clients.

The command to server functions have the client ID of who ran the function as their first parameter.
So in:
function serverCmdChangePlayerSoldier(%obj)
%obj is the client ID.

%client = %obj.client;
probably puts a value of 0 inside %client so
%client.player.setDatablock(DefaultPlayerData);
wont do anything.

try
function serverCmdChangePlayerSoldier(%obj)
{
   %obj.player.setDatablock(DefaultPlayerData);
   echo("You are now a Soldier!");
}

and hopefully that fixes your problem.
#4
03/09/2012 (1:42 pm)
Hi, now i tried hours over hours to fix that problem and i finally found the solution. the %obj and %client things dont work very well, i have to go with the "%client = %obj.getControllingClient();" command to change the one specific player who walks into the trigger. Here is my updated code:

main.cs -> onStart() function

exec("./server/servercommands.cs");

scripts/server/servercommands.cs

function ChangePlayertoGideonData::onEnterTrigger( %this, %trigger, %obj )
{
   %client = %obj.getControllingClient();
   %client.player.setDatablock(GideonPlayerData);
   echo("The Player is now a Gideon");
}
function ChangePlayertoSoldierData::onEnterTrigger( %this, %trigger, %obj )
{
   %client = %obj.getControllingClient();
   %client.player.setDatablock(DefaultPlayerData);
   echo("The Player is now a Soldier");
}

additionally as you can see, you have to create a ChangePlayertoXXXData Datablock and a Trigger who uses this datablock:

datablock TriggerData(ChangePlayertoSoldierData)
{
};
datablock TriggerData(ChangePlayertoGideonData)
{
};

I think its a good way to start implementing an ingame "interactive" character switcher / selector.

Regards,
#5
03/11/2012 (12:44 pm)
The Tribes inventory stations changed the player's armor by applying setDatablock(NewArmorDatablockName) to the player object in question.