Game Development Community

Spawning units in the RTS.

by SIInudeity · in RTS Starter Kit · 12/29/2004 (11:41 am) · 12 replies

Good evening yall.

First post here, new Torque user. Purchased the RTS pack and SDK. Been running through the Resources. Unfortunately, struggling to apply FPS resources to RTS game. Been studying the scripts. Need some help, with the following:

RTSunits are spawned from the following file:
\starter.RTS\server\scripts\core\gameConnection.cs

function RTSConnection::onClientEnterGame(%this)
{
...
%unitsPerDir = 4 ;
...
}

Units to spawn amount.
And then more importantly the actual spawning code:

function RTSConnection::createPlayer(%this, %spawnPoint, %index)
{
...
%player = new RTSUnit()
{
scale = "1 1 1";
dataBlock = %data;
shapeFile = "~/data/shapes/player/player.dts";
path = "";
};
...
}

dataBlock is determined by a case statement, which RTSunit to populate it with. Why does the shapeFile point to player.dts?

How can I set spawn-coordinates for each RTSUnit?

Kind regards
Sinudeity

About the author

Recent Threads


#1
12/29/2004 (3:21 pm)
I don't honestly know why the shapeFile is in the block there as you mention, it should be in your individual datablocks.


For the spawn coordinates, note the %spawnPoint variable passed in to the createPlayer function. This is a 3 "Word" variable provided by the calling function giving the coordinates X Y Z for the spawn location.

In the example given in the stock RTS SK, they use a bit of math to offset units based on which team they are on, and then which unit it is in the complete unit set that gets created.

Look at this portion of RTSConnection::onClientEnterGame():
// Create a player object.
  for(%i=%offset........
..
..
  %this.createPlayer((%j*5) SPC (%i*5) SPC "250", %j + %unitsPerDir*%i);
..
..

If you step through the createPlayer line carefully, you'll see that it's actually sending something like:

%this.createPlayer(9 9 250, 36);

for the case where you are the third client in a game, the first iteration of each loop. Long story short, the (%j*5) SPC (%i*5) SPC "250", portion of that call is where they define the spawn location for each specific unit.

The World Domination Through Collaboration RTS mod handles spawn location based on which building the unit was trained in, so if/when you apply that mod to your starter kit, you'll see an alternate way of handling the unit creation issue.
#2
12/29/2004 (3:49 pm)
Mmm, ok. Sweet. Thanks for the info. Seriously.
I can knock the shapeFile from the spawn routine.
Assumed it got overwritten.

So, it checks any incoming clients, and will spawn %unitsPerDir, and assign appropriate team. Cool for multiplayer. Can case statement createPlayer() based on teams.

I noticed on the worldcreator, using RTS demo mission, Mission info - scriptObject has dynamic fields created for Team0, Team1 etc. Are those the global variables that are accessed by getTeam() and setTeam() functions? Are these the same variables as hardcoded in the \starter.RTS\server\defaults.cs file?

What then, for some AI units on theit own team, I could assign 1 more team , as an AI Team, from the worldcreator (or defaults.cs file). Stop anymore humans joining the game after the current team count - 1, assign some createPlayer() bots, and script them some AI?

Is that how it's done?
#3
12/30/2004 (5:41 pm)
I've got a somewhat similar problem. I'm using the World Domination Through Collaboration RTS mod, but I haven't done much with it yet.

I'm trying to get a more RPG-style game, and am working on being able to make and display names.

In ShapeBase I added a name, and a testing string to see when it was getting tripped.

void ShapeBase::setShapeName(const char* name)
{
Con::errorf("ShapeBase::setShapeName - hi Mom! '%s'", name );

In GuiRTSTSCtrl.cc I had it print out the the name
dglDrawText(mProfile->mFont, offset, object->getShapeName() );

and added the console method to change it.
ConsoleMethod( RTSUnit, setShapeName, void, 3, 3, "( string tag )"
"Sets name.")
{
object->setShapeName( argv[2] );
}

to Gameconnection.cs I added to createplayer a case statement to name them.

%player.setShapeName("Villager");

The game was crashing before because bots were coming out with no name, so I added to the RTSUnit.cc constructor

setShapeName("Nameless");

And all the bots now come out as Nameless.

console.log
Mapping string: MissionStartPhase3Ack to index: 3
RTSConnection::createPlayer()--this (client?) is (1431) unit type is (3)
ShapeBase::setShapeName - hi Mom! 'Nameless'
RTSConnection::createPlayer--Created new %player 1640 for Connection 1431 dataBlock = villagerBlock
ShapeBase::setShapeName - hi Mom! 'Villager'
RTSConnection::createPlayer()--this (client?) is (1431) unit type is (3)
ShapeBase::setShapeName - hi Mom! 'Nameless'
RTSConnection::createPlayer--Created new %player 1643 for Connection 1431 dataBlock = villagerBlock
ShapeBase::setShapeName - hi Mom! 'Villager'
RTSConnection::createPlayer()--this (client?) is (1431) unit type is (3)
ShapeBase::setShapeName - hi Mom! 'Nameless'
RTSConnection::createPlayer--Created new %player 1646 for Connection 1431 dataBlock = villagerBlock
ShapeBase::setShapeName - hi Mom! 'Villager'
RTSConnection::createPlayer()--this (client?) is (1431) unit type is (3)
ShapeBase::setShapeName - hi Mom! 'Nameless'
RTSConnection::createPlayer--Created new %player 1649 for Connection 1431 dataBlock = villagerBlock
ShapeBase::setShapeName - hi Mom! 'Villager'
starter.RTS/server/scripts/core/gameConnection.cs (71): Unable to find function resourceStore::Ctor
Mapping string: MissionStart to index: 18
Mapping string: SyncClock to index: 19
Mapping string: AcceptSetupStores to index: 20
clientCmdAcceptSetupStores: Unknown command.
ShapeBase::setShapeName - hi Mom! 'Nameless'
ShapeBase::setShapeName - hi Mom! 'Nameless'
ShapeBase::setShapeName - hi Mom! 'Nameless'
ShapeBase::setShapeName - hi Mom! 'Nameless'

From what I can see, the bots are getting constructed twice, but not passing through RTSconnection the second time.
#4
12/30/2004 (6:05 pm)
I'm not sure what you mean by getting constructed twice--you are simply seeing two debug lines for the RTSConnection::createPlayer()--one at the beginning when it is entered:

RTSCOnnection::createPlayer()--this (client?) is (1431) unit type is (3).

and one when it's finished:

RTSConnection::createPlayer--Created new %player XXXX (object's ID) for Connection 1431 dataBlock = villagerBlock.

If you step through the object ID assignments, you'll see that only 4 objects are created.

As an aside, it appears that you didn't fully integrate the mod to your starter kit--you are missing the resource store part :
(gameConnection.cs(71): Unable to find function resourceStore::Ctor, and
clientCmdAcceptSetupStores: unknown command.

Those two functions are in resources-server.cs and resources-client.cs respectively (from memory).
#5
12/30/2004 (7:23 pm)
I mean theres the block after
clientCmdAcceptSetupStores: unknown command
where the debug lines come up again.

It seems like they were respawned, but this time skipping the createPlayer() information.
#6
01/01/2005 (10:35 am)
Allright, thanks for the info yall.
Good new year and all that.
#7
03/08/2005 (4:11 pm)
Hey SIInudeity where did you end up putting the variable for the "Name" ?

I was also interested in adding addittional attributes, like age and gender, to my people.
#8
03/09/2005 (12:33 am)
Hey Ed.

I can't remember. Will check my code this evening.
#9
03/09/2005 (9:55 pm)
*waits with baited breath* hehe
#10
03/11/2005 (3:51 pm)
*pokes with a stick* you alive bro?
#11
03/21/2005 (2:24 pm)
Hey I am interested in this as well. Would like to know how to add additional information to the people. Anyone else figure this out?
Also is it possible to pull said information from a database? (xml?) I am more of a 3d artist than a programmer. Is their a resource/tutorial that would point me in the right direction for getting that started?

Thanks,
Eric
#12
03/27/2007 (2:28 pm)
How can I? Which File?

Can i specify the starting locations of the units?