Player help in RTS
by Shon Gale · in RTS Starter Kit · 09/23/2005 (11:34 am) · 20 replies
When I create the default characters in RTS Starter in gameConnection.cs
in RTSConnection::createPlayer I created 1 player and then I tracked the %player
variable created and %player = 1578
Here is my problem: When I continue to track the character in GuiRTSTSCtrl::onMouseDown
the %obj number is totally different from the %player variable
This is also the same in GuiRTSTSCtrl::onMouseDownUnit
The only place I am able to track the %player value is in serverCmdAddToSelection
in commands.cs. What I am asking is why when I create the %player it will equal 1575
and when I click on the %player 1575 it passes %obj 1582 to selectObject,
onMouseDown, onMouseDownUnit. Where did the number %obj 1582 come from and how am
I able to access this number and how does it relate to the %player variable.
in RTSConnection::createPlayer I created 1 player and then I tracked the %player
variable created and %player = 1578
Here is my problem: When I continue to track the character in GuiRTSTSCtrl::onMouseDown
the %obj number is totally different from the %player variable
This is also the same in GuiRTSTSCtrl::onMouseDownUnit
The only place I am able to track the %player value is in serverCmdAddToSelection
in commands.cs. What I am asking is why when I create the %player it will equal 1575
and when I click on the %player 1575 it passes %obj 1582 to selectObject,
onMouseDown, onMouseDownUnit. Where did the number %obj 1582 come from and how am
I able to access this number and how does it relate to the %player variable.
About the author
#2
Thanks
09/24/2005 (5:32 am)
Magic numbers cool!! No wonder I couldn't find them! Understood. I had gathered from my traces that that was what happened. My problem is that I want to read the character selected in the functions onMouseDown and onMouseDownUnit. The ghost ID is the one I want to trap. It happens the most. I still haven't wrapped my head around it. How do [bold]I[/bold] make the %player relate to %objID. I have a list of players that were created and I want total individual control over them by object ID. I am trying to setup a single key stroke to select all units of a type. Like Command and Conquer, you press the e key and select everything on the screen and press e again and select everything in the game. I need these ID numbers for that control and I want to expand this list furthur for the AI stuff.Thanks
#3
First, keep in mind I just woke up, so don't expect this to work perfectly the very first time!
In this case it's a client side action that you want to perform, so GhostID's are all you really need to worry about. Additionally, you already have an addToSelection capability (sheer chance that that is the one I quoted above!), so let's show that fully from client side to server side:
All of the selecting functionality is in the script file on the client side called selection.cs.
The most appropriate client side code that we want to work with from quickly glancing through is this method:
Now here is the psuedo-code for how to use this to accomplish what you want:
1) Find the typeID for the object currently selected (GuiRTSTSCtrl.getTypeID(%selectedUnit)
2) Iterate over all of the team's units, and for each unit that has the same typeID, call the above script method (addToSelection).
The rest is done for you already...the above code handles:
A) finding the GhostId that is appropriate for each of the replicated (client) sim's objects
B) telling the server to add each object to the slection.
C) on the server side, we confirm it's a valid selection add request, and do it (again, it's done for you already).
I actually do not know off the top of my head the best way to iterate over all of the player's units on the client side...if you want to do some research on that I will as well, and maybe someone will beat us to it!
PS: Note that my implementation is completely script side (RTS-SK is cool like that, much of what we do on the client, and even on the server doesn't even need C++ implementation, it's already done for you), while your examples in your question imply that you've been working on the code side. Of course, either works fine, but script is easier, especially to prototype. It's also quite fast for a task like this.
It's also possible to assume from your question that you only want it to select units that are currently on the screen--this would take some additional checks. One might be to actually do a radius check on the units that are to be added (doesn't actually limit to onscreen only, but makes the selected unit check a certain distance around it for units to add), or it's possible to actually do only what's on screen. This would most likely require c++ work, and probably need to access information from other objects as well (SceneGraph possibly? would have to think about it some more).
09/24/2005 (9:33 am)
That's an interesting one!First, keep in mind I just woke up, so don't expect this to work perfectly the very first time!
In this case it's a client side action that you want to perform, so GhostID's are all you really need to worry about. Additionally, you already have an addToSelection capability (sheer chance that that is the one I quoted above!), so let's show that fully from client side to server side:
All of the selecting functionality is in the script file on the client side called selection.cs.
The most appropriate client side code that we want to work with from quickly glancing through is this method:
function GuiRTSTSCtrl::selectObject(%this,%obj)
{
if(!%this.selectionLocked)
{
%this.addToSelection(%obj);
commandToServer('AddToSelection', %obj.getGhostID());
CommandMenu.visible = "1";
%this.refreshSelectionDisplay();
SelectionDisplay.visible = "1";
if(%obj.getTeam() == ServerConnection.getTeam())
%this.selectionIncludesTeam = true;
}
}Now here is the psuedo-code for how to use this to accomplish what you want:
1) Find the typeID for the object currently selected (GuiRTSTSCtrl.getTypeID(%selectedUnit)
2) Iterate over all of the team's units, and for each unit that has the same typeID, call the above script method (addToSelection).
The rest is done for you already...the above code handles:
A) finding the GhostId that is appropriate for each of the replicated (client) sim's objects
B) telling the server to add each object to the slection.
C) on the server side, we confirm it's a valid selection add request, and do it (again, it's done for you already).
I actually do not know off the top of my head the best way to iterate over all of the player's units on the client side...if you want to do some research on that I will as well, and maybe someone will beat us to it!
PS: Note that my implementation is completely script side (RTS-SK is cool like that, much of what we do on the client, and even on the server doesn't even need C++ implementation, it's already done for you), while your examples in your question imply that you've been working on the code side. Of course, either works fine, but script is easier, especially to prototype. It's also quite fast for a task like this.
It's also possible to assume from your question that you only want it to select units that are currently on the screen--this would take some additional checks. One might be to actually do a radius check on the units that are to be added (doesn't actually limit to onscreen only, but makes the selected unit check a certain distance around it for units to add), or it's possible to actually do only what's on screen. This would most likely require c++ work, and probably need to access information from other objects as well (SceneGraph possibly? would have to think about it some more).
#4
09/24/2005 (11:06 am)
Iterate over the GameConnection - it's a SimSet and it holds all ghosted objects.
#5
This would require you (I think) to manage that set manually, but it should improve performance if it becomes an issue.
09/24/2005 (11:40 am)
It might also make sense to duplicate on the client what the server does: have a script SimSet that holds all of your owned/controlled units, and that way you won't need to iterate over -all- the ghosted objects (in a large mission, that may be a lot).This would require you (I think) to manage that set manually, but it should improve performance if it becomes an issue.
#6
09/26/2005 (5:38 am)
Thanks for all the suggestions and help. I still am having a problem though. The method you showed me was %ghostID or the %obj passed in onMouseDown and then on to AddToSelection where it is resolved into the %player ID I captured in createPlayer. I got it. But I need to go the other way. I need to take the %player value I have in my list and convert it to the ghostID or %obj in onMouseDown. This ghost number gets passed to the most functions and is the easiest to track. Also I figure my entry point to select all of my items of type, will be selectObject and that function needs the ghost ID or %obj. I cannot trace where it creates this value. I even tried to track it in the C++ source. I believe I need to create a list of these %obj values to compare against. I hope I am clear on what I am trying to do and I may be trying the wrong way. I appreciate any input on this.
#7
Instead of worrying about code, can you describe your functionality goal in just a few sentences? That way we can get a common frame of reference to see exactly what you are trying to accomplish, and hopefully discover the best way for you to move forward.
My gut feeling is that you are trying to do something client side that needs to be done server side, or are thinking about using data that may only exist server side (right now), so I'd like to see exactly what the "gameplay" description is and go from there.
09/26/2005 (8:18 am)
Ok, you did lose me there!Instead of worrying about code, can you describe your functionality goal in just a few sentences? That way we can get a common frame of reference to see exactly what you are trying to accomplish, and hopefully discover the best way for you to move forward.
My gut feeling is that you are trying to do something client side that needs to be done server side, or are thinking about using data that may only exist server side (right now), so I'd like to see exactly what the "gameplay" description is and go from there.
#8
I appreciate all of the time spent on this.
09/26/2005 (9:09 am)
Thanks again. To get away from the trace stuff. I simply want to select a character. Like a Shocker. Then press a key. 'e' for example and select all of the Shockers. I appreciate all of the time spent on this.
#9
You will also probably want something like:
and bind this to the appropriate key (e) in your default.binds.cs. Make sure you delete your config.cs and config.cs.dso.
EDIT: Unrelated comment taken out--I changed the imp slightly after I wrote the psuedo code, but forgot to take the // out.
09/26/2005 (9:53 am)
Untested example code to try to get you started:function GuiRTSTSCtrl::selectAllObjectsByType(%this)
{
// get the typeID of the currently selected object.
// assumptions:
// 1) One and only one object selected.
// 2) Is an RTSUnit
if (PlayGui.getSelectionSize() <>1 )
{
echo("GuiRTSTSCtrl::selectAllObjectsByType--More than one object selected!");
return;
}
%curUnitTypeName = %this.getSelectedObject(0).getDataBlock().getName();
// first clear our selection, so that way we don't need to worry about our current object being there twice
%this.clearTheSelection();
// iterate over each of our objects in the GameConnection, make sure they qualify.
// if they do, add to selection
for(%i=0; %i < ClientGroup.getCount(); %i++)
{
%itrObject = ClientGroup.getObject(%i);
if ( ( %iterObject.getTeam() == ServerConnection.getTeam() ) &&
( ( %itrObject.getClassName() !$= "RTSUnit") ||
( %itrObject.getDataBlock().getName() !$= %curUnitTypeName) ) )
{
continue;
}
// object qualifies, add to selection
%this.addToSelection(%iterObject);
}
// at this point, we've:
// 1) added all units as appropriate to our selection
// 2) our selection was cleared, so -only- this unit type exists in it
// we need to refresh our display, and set some variables:
CommandMenu.visible = "1";
SelectionDisplay.visible = "1";
%this.selectionIncludesTeam = true;
%this.refreshSelectionDisplay();
}You will also probably want something like:
function selectAllUnitsOfCurrentType(%val)
{
if (%val)
{
PlayGui.selectAllObjectsByType();
}
}and bind this to the appropriate key (e) in your default.binds.cs. Make sure you delete your config.cs and config.cs.dso.
EDIT: Unrelated comment taken out--I changed the imp slightly after I wrote the psuedo code, but forgot to take the // out.
#10
I appreciate all of the time spent on this.
09/26/2005 (10:45 am)
Thanks again. To get away from the trace stuff. I simply want to select a character. Like a Shocker. Then press a key. 'e' for example and select all of the Shockers. I appreciate all of the time spent on this.
#11
I put the function GuiRTSTSCtrl::selectAllObjectsByType(%this) in client/scripts/selection.cs
I put the function selectAllUnitsOfCurrentType(%val) in client/scripts/default.bind.cs
I added moveMap.bind(keyboard, "e", selectAllUnitsOfCurrentType); after the above function.
I select a unit then press the e key and get the following in my console.log
control/client/scripts/default.bind.cs (0): Unknown command selectAllObjectsByType.
Object PlayGui(1369) PlayGui -> GuiRTSTSCtrl -> EditTSCtrl -> GuiTSCtrl -> GuiControl -> SimGroup -> SimSet -> SimObject
Sorry to be such a pest but I am still a newbie to this SDK (2 mos witth TGE, 1 month with RTS) so I really appreciate your time.
09/26/2005 (1:03 pm)
Wow you wrote the whole thing!!!!! Thanks.I put the function GuiRTSTSCtrl::selectAllObjectsByType(%this) in client/scripts/selection.cs
I put the function selectAllUnitsOfCurrentType(%val) in client/scripts/default.bind.cs
I added moveMap.bind(keyboard, "e", selectAllUnitsOfCurrentType); after the above function.
I select a unit then press the e key and get the following in my console.log
control/client/scripts/default.bind.cs (0): Unknown command selectAllObjectsByType.
Object PlayGui(1369) PlayGui -> GuiRTSTSCtrl -> EditTSCtrl -> GuiTSCtrl -> GuiControl -> SimGroup -> SimSet -> SimObject
Sorry to be such a pest but I am still a newbie to this SDK (2 mos witth TGE, 1 month with RTS) so I really appreciate your time.
#12
It's also possible that PlayGui isn't where you want this as a namespace. If that's the case then we'll need to rework it slightly, and that will take a bit more time on my part...
09/26/2005 (1:24 pm)
There is almost certainly a typo in the function(s) you wrote, which is making the .cs not compile. Check up higher in your console.log and see if there are any errors being reported.It's also possible that PlayGui isn't where you want this as a namespace. If that's the case then we'll need to rework it slightly, and that will take a bit more time on my part...
#13
First I added a single Global variable in the function RTSConnection::onClientEnterGame
in the file server/scripts/core/gameConnection.cs where the code is
// Create simset to track all units
%this.units = new SimGroup();
add the following
$unitGroup = %this.units;
Then in client/scripts/selection.cs add at the bottom of the file
function GuiRTSTSCtrl::selectAllObjectsByType(%this)
{
// get the typeID of the currently selected object.
// assumptions:
// 1) One and only one object selected.
// 2) Is an RTSUnit
if (PlayGui.getSelectionSize() != 1 )
{
echo("*** GuiRTSTSCtrl::selectAllObjectsByType--More than one object selected!");
return;
}
// one and only 1 object selected above, %index == 0
%curUnitTypeName = %this.getSelectedObject(0).getDataBlock().getName();
// first clear our selection, so that way we don't need to worry about
// our current object being there twice
%this.clearTheSelection();
// iterate over each of our objects in the GameConnection, make sure
// they qualify. if they do, add to selection
//%cg = ClientGroup.getCount();
%cg = $unitGroup.getCount(); // See RTSConnection::onClientEnterGame
for(%i=0; %i < %cg; %i++)
{
%iterObject = $unitGroup.getObject(%i);
%unitTypeName = $unitGroup.getObject(%i).getDataBlock().getName();
if ((%iterObject.getTeam() == ServerConnection.getTeam()) &&
((%iterObject.getClassName() $= "RTSUnit") &&
(%n $= %curUnitTypeName)))
{
// object qualifies, add to selection .getDataBlock()
%this.addToSelection(%iterObject);
echo("*** selectAllObjectsByType %iterObject:" @%iterObject@", unitTypeName:" @%unitTypeName);
}
}
// at this point, we've:
// 1) added all units as appropriate to our selection
// 2) our selection was cleared, so -only- this unit type exists in it
// we need to refresh our display, and set some variables:
CommandMenu.visible = "1";
SelectionDisplay.visible = "1";
%this.selectionIncludesTeam = true;
%this.refreshSelectionDisplay();
}
Then in client/scripts/default.bind.cs add at the end of the file
function selectAllUnitsOfCurrentType(%val)
{
echo("*** selectAllUnitsOfCurrentType");
if (%val)
{
PlayGui.selectAllObjectsByType();
}
}
moveMap.bind(keyboard, "e", selectAllUnitsOfCurrentType);
It works great so far but as I stated I cannot move or attack.
Almost got it!!!
09/27/2005 (10:00 am)
You were correct. I found several typos. Must have been tired. I live out in the boonie on the Northern California Coaqst and get up real early. Anyway I corrected them. I want to thank you profusely. You're awesome and I got a great education out of this exchange. I worked on this this morning and I got the units selected by type with the following code. The problem now is they will not move or attack.First I added a single Global variable in the function RTSConnection::onClientEnterGame
in the file server/scripts/core/gameConnection.cs where the code is
// Create simset to track all units
%this.units = new SimGroup();
add the following
$unitGroup = %this.units;
Then in client/scripts/selection.cs add at the bottom of the file
function GuiRTSTSCtrl::selectAllObjectsByType(%this)
{
// get the typeID of the currently selected object.
// assumptions:
// 1) One and only one object selected.
// 2) Is an RTSUnit
if (PlayGui.getSelectionSize() != 1 )
{
echo("*** GuiRTSTSCtrl::selectAllObjectsByType--More than one object selected!");
return;
}
// one and only 1 object selected above, %index == 0
%curUnitTypeName = %this.getSelectedObject(0).getDataBlock().getName();
// first clear our selection, so that way we don't need to worry about
// our current object being there twice
%this.clearTheSelection();
// iterate over each of our objects in the GameConnection, make sure
// they qualify. if they do, add to selection
//%cg = ClientGroup.getCount();
%cg = $unitGroup.getCount(); // See RTSConnection::onClientEnterGame
for(%i=0; %i < %cg; %i++)
{
%iterObject = $unitGroup.getObject(%i);
%unitTypeName = $unitGroup.getObject(%i).getDataBlock().getName();
if ((%iterObject.getTeam() == ServerConnection.getTeam()) &&
((%iterObject.getClassName() $= "RTSUnit") &&
(%n $= %curUnitTypeName)))
{
// object qualifies, add to selection .getDataBlock()
%this.addToSelection(%iterObject);
echo("*** selectAllObjectsByType %iterObject:" @%iterObject@", unitTypeName:" @%unitTypeName);
}
}
// at this point, we've:
// 1) added all units as appropriate to our selection
// 2) our selection was cleared, so -only- this unit type exists in it
// we need to refresh our display, and set some variables:
CommandMenu.visible = "1";
SelectionDisplay.visible = "1";
%this.selectionIncludesTeam = true;
%this.refreshSelectionDisplay();
}
Then in client/scripts/default.bind.cs add at the end of the file
function selectAllUnitsOfCurrentType(%val)
{
echo("*** selectAllUnitsOfCurrentType");
if (%val)
{
PlayGui.selectAllObjectsByType();
}
}
moveMap.bind(keyboard, "e", selectAllUnitsOfCurrentType);
It works great so far but as I stated I cannot move or attack.
Almost got it!!!
#14
Change your SimGroup to a SimSet. I had thought that bug got removed, but I guess you are working on an original install, or it wasn't fixed.
Also, keep in mind that by default, units won't attack their own team unless you specifically give them an "attack" command (clicking on the button and -then- right clicking on the target). Simply right clicking on another unit won't do it.
Also, in this code area:
I don't ever see where you are setting %n, so this check is failing (I think).
09/27/2005 (10:53 am)
Well, one major thing:Change your SimGroup to a SimSet. I had thought that bug got removed, but I guess you are working on an original install, or it wasn't fixed.
Also, keep in mind that by default, units won't attack their own team unless you specifically give them an "attack" command (clicking on the button and -then- right clicking on the target). Simply right clicking on another unit won't do it.
Also, in this code area:
%n $= %curUnitTypeName)))
I don't ever see where you are setting %n, so this check is failing (I think).
#15
09/27/2005 (10:56 am)
I also think that you may be somehow adding in units that aren't on your team (not sure how, but...)...that would keep you from moving or attacking as a group, since you can't give orders to enemy units.
#16
09/27/2005 (1:35 pm)
Whoops typo %n is %unitTypeName. I'll try changing the SimGroup to a Simset and keerp you posted. Once again Thanks
#17
in the file server/scripts/core/gameConnection.cs where the code is
// Create simset to track all units
%this.units = new SimGroup();
add the following
$unitGroup = %this.units;
Then in client/scripts/selection.cs add at the bottom of the file
function GuiRTSTSCtrl::selectAllObjectsByType(%this)
{
// get the typeID of the currently selected object.
// assumptions:
// 1) One and only one object selected.
// 2) Is an RTSUnit
if (PlayGui.getSelectionSize() != 1 )
{
echo("*** GuiRTSTSCtrl::selectAllObjectsByType--More than one object selected!");
return;
}
// one and only 1 object selected above, %index == 0
%curUnitTypeName = %this.getSelectedObject(0).getDataBlock().getName();
// first clear our selection, so that way we don't need to worry about
// our current object being there twice
%this.clearTheSelection();
// iterate over each of our objects in the GameConnection, make sure
// they qualify. if they do, add to selection
%cg = $unitGroup.getCount(); // See RTSConnection::onClientEnterGame
for(%i=0; %i < %cg; %i++)
{
%iterObject = $unitGroup.getObject(%i);
%unitTypeName = $unitGroup.getObject(%i).getDataBlock().getName();
if ((%iterObject.getTeam() == ServerConnection.getTeam()) &&
((%iterObject.getClassName() $= "RTSUnit") &&
(%unitTypeName $= %curUnitTypeName)))
{
// object qualifies, add to selection in all my tests the index into
// the units SimGroup starts at 2. As far as I can tell
// 0 is the %client, 1 is the Group ID and the units start at 2
%obj = %i+2;
echo("*** selectAllObjectsByType %iterObject:" @%iterObject@", Selecting:"@%obj);
%this.addToSelection(%iterObject);
commandToServer('AddToSelection', %obj); // make them move, attack
}
}
// at this point, we've:
// 1) added all units as appropriate to our selection
// 2) our selection was cleared, so -only- this unit type exists in it
// we need to refresh our display, and set some variables:
CommandMenu.visible = "1";
SelectionDisplay.visible = "1";
%this.selectionIncludesTeam = true;
%this.refreshSelectionDisplay();
}
Then in client/scripts/default.bind.cs add at the end of the file
function selectAllUnitsOfCurrentType(%val)
{
echo("*** selectAllUnitsOfCurrentType");
if (%val)
{
PlayGui.selectAllObjectsByType();
}
}
moveMap.bind(keyboard, "e", selectAllUnitsOfCurrentType);
This does it I can now select a unit, press the 'e' key and that selects all units
of that type. I still need to implement the select on the screen only. I will now work on the second part which is press 'e' again and select all units of a type in the game. I'll keep you guys posted on this. To me this was one of the greatest features of Command and Conquer Generals. It allows you to quickly select a group of unit of a particular strength and send them where you need them.
Thanks Stephen for pointing me in the right direction. I really appreciate it. Maybe we need a book on RTS like for the TGE????
09/28/2005 (5:34 am)
OK here it is. This works!! First I added a single Global variable in the function RTSConnection::onClientEnterGamein the file server/scripts/core/gameConnection.cs where the code is
// Create simset to track all units
%this.units = new SimGroup();
add the following
$unitGroup = %this.units;
Then in client/scripts/selection.cs add at the bottom of the file
function GuiRTSTSCtrl::selectAllObjectsByType(%this)
{
// get the typeID of the currently selected object.
// assumptions:
// 1) One and only one object selected.
// 2) Is an RTSUnit
if (PlayGui.getSelectionSize() != 1 )
{
echo("*** GuiRTSTSCtrl::selectAllObjectsByType--More than one object selected!");
return;
}
// one and only 1 object selected above, %index == 0
%curUnitTypeName = %this.getSelectedObject(0).getDataBlock().getName();
// first clear our selection, so that way we don't need to worry about
// our current object being there twice
%this.clearTheSelection();
// iterate over each of our objects in the GameConnection, make sure
// they qualify. if they do, add to selection
%cg = $unitGroup.getCount(); // See RTSConnection::onClientEnterGame
for(%i=0; %i < %cg; %i++)
{
%iterObject = $unitGroup.getObject(%i);
%unitTypeName = $unitGroup.getObject(%i).getDataBlock().getName();
if ((%iterObject.getTeam() == ServerConnection.getTeam()) &&
((%iterObject.getClassName() $= "RTSUnit") &&
(%unitTypeName $= %curUnitTypeName)))
{
// object qualifies, add to selection in all my tests the index into
// the units SimGroup starts at 2. As far as I can tell
// 0 is the %client, 1 is the Group ID and the units start at 2
%obj = %i+2;
echo("*** selectAllObjectsByType %iterObject:" @%iterObject@", Selecting:"@%obj);
%this.addToSelection(%iterObject);
commandToServer('AddToSelection', %obj); // make them move, attack
}
}
// at this point, we've:
// 1) added all units as appropriate to our selection
// 2) our selection was cleared, so -only- this unit type exists in it
// we need to refresh our display, and set some variables:
CommandMenu.visible = "1";
SelectionDisplay.visible = "1";
%this.selectionIncludesTeam = true;
%this.refreshSelectionDisplay();
}
Then in client/scripts/default.bind.cs add at the end of the file
function selectAllUnitsOfCurrentType(%val)
{
echo("*** selectAllUnitsOfCurrentType");
if (%val)
{
PlayGui.selectAllObjectsByType();
}
}
moveMap.bind(keyboard, "e", selectAllUnitsOfCurrentType);
This does it I can now select a unit, press the 'e' key and that selects all units
of that type. I still need to implement the select on the screen only. I will now work on the second part which is press 'e' again and select all units of a type in the game. I'll keep you guys posted on this. To me this was one of the greatest features of Command and Conquer Generals. It allows you to quickly select a group of unit of a particular strength and send them where you need them.
Thanks Stephen for pointing me in the right direction. I really appreciate it. Maybe we need a book on RTS like for the TGE????
#18
selectObject()? ie- the mouse
%this.addToSelection(%iterObject);
I'm trying to do something similar where I automatically add my hero units into the selection set. my guess is that the GuiRTSTSCtrl is selecting the client side unit while your function is grabbing the server side unit, which is created by createPlayer(). or maybe I have it backwards, all I know is, that the id's don't match.
I did the same thing and it does work; the units receive their commands and move, but I'm not exactly sure why. ultimately, I suppose it's because this statement has the proper ID:
commandToServer('AddToSelection', %obj); // make them move, attack
dan
01/10/2006 (1:59 pm)
Have you noticed that the iterObject's ID is different than if you select that same object throughselectObject()? ie- the mouse
%this.addToSelection(%iterObject);
I'm trying to do something similar where I automatically add my hero units into the selection set. my guess is that the GuiRTSTSCtrl is selecting the client side unit while your function is grabbing the server side unit, which is created by createPlayer(). or maybe I have it backwards, all I know is, that the id's don't match.
I did the same thing and it does work; the units receive their commands and move, but I'm not exactly sure why. ultimately, I suppose it's because this statement has the proper ID:
commandToServer('AddToSelection', %obj); // make them move, attack
dan
#19
I also describe the topic in the first couple of messages in this thread if you want to go back and review!
01/10/2006 (5:20 pm)
Clients and Servers use completely different ID's for networking purposes (primarily anti-cheat). You can read about it on the TDN Networking:Ghosting article.I also describe the topic in the first couple of messages in this thread if you want to go back and review!
#20
I'm actually having a similar problem to what you stated earlier, that you don't know the best way to iterate over the client's units. when looking through the units in RTSConnection->ClientGroup in gameConnection.cs, it does not contain the client side units.
01/10/2006 (5:31 pm)
I'm familiar with the networking model in torque and I've read over this thread a few times. my problem is how to access some of these things via script.I'm actually having a similar problem to what you stated earlier, that you don't know the best way to iterate over the client's units. when looking through the units in RTSConnection->ClientGroup in gameConnection.cs, it does not contain the client side units.
Torque 3D Owner Stephen Zepp
The reason that the GUI is reporting a different ID number is becuase the GUI is reporting the GhostID number. When the client is sending an ID number to the server, it uses it's own personal GhostID number, and the server keeps track of the proper SimID for that particular client.
If you'll note in the server side scripts, we use the functions that convert from a client's ghostID to the server's SimID, and then use the SimID for what we need to do. Here is some example script code that demonstrates:
function serverCmdAddToSelection(%client, %objID) { %obj = %client.resolveObjectFromGhostIndex(%objID); %client.selection.add(%obj); sendAllStatsToClient(%client, %obj); }As you can see, %objID, sent from the client, needs to be resolved to a true SimID (in our case, %obj)...so the server calls the member method resolveObjectFromGhostIndex() on the GhostID the client told us about, and then returns the true server side SimID.
Complex in theory, but it gives us all sorts of advantages and benefits!