RTS Prototype updated to T3D 1.2
by Richard Ranft · in Torque 3D Beginner · 10/02/2012 (5:54 am) · 29 replies
The T3D RTS Prototype originally created by Mitch has finally been brought up to speed with T3D 1.2. You can find it in the Online Documentation under Scripting > Advanced. You'll also find an Adventure Prototype and a tutorial on using triggers to move between mission files there.
About the author
I was a soldier, then a computer technician, an electrician, a technical writer, game programmer, and now software test/tools developer. I've been a hobbyist programmer since the age of 13.
#2
10/02/2012 (12:07 pm)
Good job! I'm sure this is going to make a lot of people happy.
#3
10/02/2012 (12:28 pm)
Actually, browsing through the new docs I see that there are a few new additions such as postFX color correction - all cool and useful stuff.
#4
Added in math/mConsoleFunctions.cpp:
And use this to replace the unit offsets from the multi-select unit section in the scripts with geometric formations....
Of course, you'll have to set up some new decals....
10/02/2012 (1:21 pm)
Hope people find it useful - and I might even add a few little source tweaks to make it cooler.Added in math/mConsoleFunctions.cpp:
DefineConsoleFunction( mVectorRotateZAxis, Point3F, ( Point3F vector, F32 radians ),,
"Rotate a 3D vector around its origin on its z axis.\n"
"@param vector The vector to rotate."
"@param radians The angle to rotate to."
"@returns The lesser value of the two specified values."
"@ingroup Math" )
{
Point3F &v = vector;
MathUtils::vectorRotateZAxis( v, radians );
return v;
}And use this to replace the unit offsets from the multi-select unit section in the scripts with geometric formations....
// Set the destination for the AI player to
// make him move
if (isObject(Team1List))
{
%c = 0;
%rotCount = 0;
%ringRotCount = 0;
%vailanceCount = 6;
%offsetVector = "4 0 0";
%angle = 0;
%degrees = 60;
%end = Team1List.getCount();
%unit = Team1List.getObject(0);
while (isObject(%unit))
{
if (%unit.isSelected)
{
if (%ringRotCount > %vailanceCount - 1)
{
%vailanceCount = 6 * (%ringRotCount + 1);
%ringRotCount = 0;
%rotCount++;
%offsetVector = (%rotCount + 1) * 4 @ " 0 0";
%degrees /= 2;
}
%dest = VectorAdd(%pos, mVectorRotateZAxis(%offsetVector, %angle));
%unit.setMoveDestination( %dest );
decalManagerAddDecal(%dest, %norm, 0, 0.25, "UnitDest_Decal", false);
%ringRotCount++;
%angle = mDegToRad(%degrees * %ringRotCount);
}
%c++;
if (%c < %end)
%unit = Team1List.getObject(%c);
else
%unit = 0;
}
}Of course, you'll have to set up some new decals....
#5
10/02/2012 (1:22 pm)
That script was game/scripts/server/commands.cs in serverCmdmovePlayer(), but I didn't want to deal with the quote mark edit bug to add this to the previous post....
#6
10/02/2012 (5:34 pm)
This is a great tutorial update! Thanks for taking the time to make this avaiable to everyone. Hopefully I can get started on it in the next couple of days.
#7
side note, all the docs, everywhere, always say press '~' for console, yet its ' key - unless its a typical uk-us keyboard difference, but most modern things aren't affected by keyboard types
10/13/2012 (9:53 am)
side note, all the docs, everywhere, always say press '~' for console, yet its ' key - unless its a typical uk-us keyboard difference, but most modern things aren't affected by keyboard types
#8
10/14/2012 (8:25 am)
was an irrelevent post, cant delete so edited out
#9
in server/commands.cs
Note if (%target.class $= "barracks") and what it does, you must ensure that your barracks object has its class set to "barracks" when it is created. I should have caught that, but it looks like I missed it.
So, in server/commands.cs in serverCmdcreateBuilding() the code to create the building should look like this:
I'll have to update that - thanks for catching it!
10/15/2012 (9:31 am)
I was busy over the weekend and didn't catch this until this morning - but you were right about where the change was:in server/commands.cs
function serverCmdcheckTarget(%client, %pos, %start, %ray)
{
%ray = VectorScale(%ray, 1000);
%end = VectorAdd(%start, %ray);
// Add new typemasks to the search so we can find clicks on barracks too
%searchMasks = $TypeMasks::PlayerObjectType | $TypeMasks::StaticTSObjectType
| $TypeMasks::StaticObjectType;
// Search!
%scanTarg = ContainerRayCast( %start, %end, %searchMasks);
// If an enemy AI object was found in the scan
if( %scanTarg )
{
// Get the enemy ID
%target = firstWord(%scanTarg);
if (%target.class $= "barracks")
{
serverCmdspawnTeammate(%client, %target);
}
else if (%target.getClassName() $= "AIPlayer")Note if (%target.class $= "barracks") and what it does, you must ensure that your barracks object has its class set to "barracks" when it is created. I should have caught that, but it looks like I missed it.
So, in server/commands.cs in serverCmdcreateBuilding() the code to create the building should look like this:
// spawn a new object at the intersection point
%obj = new TSStatic()
{
position = %pos;
shapeName = "art/shapes/building/orcburrow.dts";
class = "barracks"; // added this
collisionType = "Visible Mesh";
scale = "0.5 0.5 0.5";
};I'll have to update that - thanks for catching it!
#10
11/03/2012 (8:58 am)
Richard first thanks for having this updated to 1.2 t3d. I am trying to remove the button off of the corner of the screen and instead have it work as a button attached inside a container. So one would select a worker and a gui would open with options of things to build. But in the example you never use a command line to attached the button to the function. Also cant seem to find a way to open gui when a avatar is selected. And for this to be a real example rts need some gather like say wood and make barracks cost so much to build.
#11
then set it to false again on the part that unselects units.
units costs are easy enough , in the sense that you simply need a global variable containing your money, and then the code that places the barracks, add a logic(if) statement to check said variable is as high as whatever cost you decide.
ressources are a bit trickier to explian, seeing as there are so many different ways different RTSs make their ressources work. i have gone down the simple route on mine, whereby its jsut 1 ressource type, thats collected in collection zones, triggers handle this fine, but if you want more advanced ressources and say diminishing trees as you colelct, it would be considerably trickier.
11/03/2012 (9:39 am)
i am working on a prject based on the RTS tutorial Tom, and for the first part, the gui, all you need to do is go to the part of the script that handles the selection on units(been a while since it touched that part so youll excuse me not having an exact code of the top of my head) then just add a logic check(if) to check if your selection is a worker, if so -> yourguicontainer.visible = true;then set it to false again on the part that unselects units.
units costs are easy enough , in the sense that you simply need a global variable containing your money, and then the code that places the barracks, add a logic(if) statement to check said variable is as high as whatever cost you decide.
ressources are a bit trickier to explian, seeing as there are so many different ways different RTSs make their ressources work. i have gone down the simple route on mine, whereby its jsut 1 ressource type, thats collected in collection zones, triggers handle this fine, but if you want more advanced ressources and say diminishing trees as you colelct, it would be considerably trickier.
#12
[IMG]http://i1099.photobucket.com/albums/g395/Captaincrud6/t3dpic.png[/IMG]
This is the code I am trying to connect the button
function inventoryGui::btn1()
{
// If we're in building placement mode ask the server to create a building for
// us at the point that we clicked.
if (%this.placingBuilding)
{
// Clear the building placement flag first.
%this.placingBuilding = false;
// Request a building at the clicked coordinates from the server.
commandToServer('createBuilding', %pos, %start, %ray);
}
else
{
// Ask the server to let us attack a target at the clicked position.
commandToServer('checkTarget', %pos, %start, %ray);
}
}
// This function is the callback that handles our new button. When you click it
// the button tells the PlayGui that we're now in building placement mode.
function orcBurrowButton::onClick(%this)
{
PlayGui.placingBuilding = true;
}
11/03/2012 (10:48 am)
The problem I am having is making the button work in the screen [IMG]http://i1099.photobucket.com/albums/g395/Captaincrud6/t3dpic.png[/IMG]
This is the code I am trying to connect the button
function inventoryGui::btn1()
{
// If we're in building placement mode ask the server to create a building for
// us at the point that we clicked.
if (%this.placingBuilding)
{
// Clear the building placement flag first.
%this.placingBuilding = false;
// Request a building at the clicked coordinates from the server.
commandToServer('createBuilding', %pos, %start, %ray);
}
else
{
// Ask the server to let us attack a target at the clicked position.
commandToServer('checkTarget', %pos, %start, %ray);
}
}
// This function is the callback that handles our new button. When you click it
// the button tells the PlayGui that we're now in building placement mode.
function orcBurrowButton::onClick(%this)
{
PlayGui.placingBuilding = true;
}
#13
11/03/2012 (11:42 am)
unless i'm missunderstanding you, you jsut need to call this in gui/playGui.cs under function btn1::onClick()
#14
11/03/2012 (11:45 am)
the only tourtiorals I can find tell me to link a button I mustt add it to a command line in the gui editiotr this works diffrent how do i link it togther?
#15
but if you got to the scripts/gui/playGui.cs file
add the function (i'm assuming you named your button btn1 in the gui editor, if not use whatver name you gave it inplace)
function btn1::onClick(%this)
{
//everthing to happen goes here, meaning you can move your code here, or jsut call the other function you made
}
this then automatically pick up when you click on btn1 and runs it.
similarly you can add things for onHover, or various other conditions.
hope this makes sense
11/03/2012 (12:38 pm)
never used the gui editor for commands, onyl for appearence and placementbut if you got to the scripts/gui/playGui.cs file
add the function (i'm assuming you named your button btn1 in the gui editor, if not use whatver name you gave it inplace)
function btn1::onClick(%this)
{
//everthing to happen goes here, meaning you can move your code here, or jsut call the other function you made
}
this then automatically pick up when you click on btn1 and runs it.
similarly you can add things for onHover, or various other conditions.
hope this makes sense
#16
Okay little Help in this area
function PlayGui::onMouseDown(%this, %pos, %start, %ray)
{
// If we're in building placement mode ask the server to create a building for
// us at the point that we clicked.
if (%this.placingBuilding)
{
// Clear the building placement flag first.
%this.placingBuilding = false;
// Request a building at the clicked coordinates from the server.
commandToServer('createtestbuilding', %pos, %start, %ray);
}
else
{
// Ask the server to let us attack a target at the clicked position.
commandToServer('checkTarget', %pos, %start, %ray);
}
}
I need to place diffrent buildings based on what button is clicked
so something like
commandToServer('createtestbuilding', %pos, %start, %ray);
commandToServer('createtorcbuilding', %pos, %start, %ray);
I know I need a and if in there just not sure how to tell it how to understand me
11/03/2012 (1:13 pm)
That helped a ton Louis thank youOkay little Help in this area
function PlayGui::onMouseDown(%this, %pos, %start, %ray)
{
// If we're in building placement mode ask the server to create a building for
// us at the point that we clicked.
if (%this.placingBuilding)
{
// Clear the building placement flag first.
%this.placingBuilding = false;
// Request a building at the clicked coordinates from the server.
commandToServer('createtestbuilding', %pos, %start, %ray);
}
else
{
// Ask the server to let us attack a target at the clicked position.
commandToServer('checkTarget', %pos, %start, %ray);
}
}
I need to place diffrent buildings based on what button is clicked
so something like
commandToServer('createtestbuilding', %pos, %start, %ray);
commandToServer('createtorcbuilding', %pos, %start, %ray);
I know I need a and if in there just not sure how to tell it how to understand me
#17
for example lets use $lastbutton
now in your btn1::onCick function
insert a line that sets this variable, like so
$lastbutton="orc";
now i assume you then have btn2 btn3....
so int heir respective ...::onClick functions do the same, only set it to a different value.
that way in your code above you can to a switch check on $lastbutton
case equals "orc2" do commandToServer('createtorcbuilding', %pos, %start, %ray);
case equals "test" do commandToServer('createtestbuilding', %pos, %start, %ray);
and so forth.
and glad i can help for once, instead of being the one that needs the help lol
11/03/2012 (1:58 pm)
well, the way i would do it, there are no doubt other ways, maybe even better ways, would be to declare a global variablefor example lets use $lastbutton
now in your btn1::onCick function
insert a line that sets this variable, like so
$lastbutton="orc";
now i assume you then have btn2 btn3....
so int heir respective ...::onClick functions do the same, only set it to a different value.
that way in your code above you can to a switch check on $lastbutton
case equals "orc2" do commandToServer('createtorcbuilding', %pos, %start, %ray);
case equals "test" do commandToServer('createtestbuilding', %pos, %start, %ray);
and so forth.
and glad i can help for once, instead of being the one that needs the help lol
#18
function PlayGui::onMouseDown(%this, %pos, %start, %ray)
{
// If we're in building placement mode ask the server to create a building for
// us at the point that we clicked.
if (%this.placingBuilding)
{
// Clear the building placement flag first.
%this.placingBuilding = false;
// Request a building at the clicked coordinates from the server.
commandToServer('createBuilding', %pos, %start, %ray);
}
else
{
// Ask the server to let us attack a target at the clicked position.
commandToServer('checkTarget', %pos, %start, %ray);
}
}
// This function is the callback that handles our new button. When you click it
// the button tells the PlayGui that we're now in building placement mode.
function orcBurrowButton::onClick(%this)
{
PlayGui.placingBuilding = true;
}
function testbuildingButton::onClick(%this)
{
PlayGui.placingBuilding = true;
}
11/03/2012 (2:02 pm)
Sorry Louis not quite following could you post a code example of it with chaning this code sorry not coder so some things pass me by when you explain them.function PlayGui::onMouseDown(%this, %pos, %start, %ray)
{
// If we're in building placement mode ask the server to create a building for
// us at the point that we clicked.
if (%this.placingBuilding)
{
// Clear the building placement flag first.
%this.placingBuilding = false;
// Request a building at the clicked coordinates from the server.
commandToServer('createBuilding', %pos, %start, %ray);
}
else
{
// Ask the server to let us attack a target at the clicked position.
commandToServer('checkTarget', %pos, %start, %ray);
}
}
// This function is the callback that handles our new button. When you click it
// the button tells the PlayGui that we're now in building placement mode.
function orcBurrowButton::onClick(%this)
{
PlayGui.placingBuilding = true;
}
function testbuildingButton::onClick(%this)
{
PlayGui.placingBuilding = true;
}
#19
$lastbutton = "none";
Not strictly required but always good practice to default global variables to avoid any chance of unexpected behaviour later on.
The next step should have been straight forward, in functiion btn1::onClick, anywhere inside the { } add
$lastbutton = "Orc";
And the same line in each button's onClick function , replacing Orc with whatever .
Now th bit You might have had more trouble with, you'll have to excuse me for not copying your entire code , I'm not at home and typing on my phone., but your line :
commandToServer("createbuilding",%pos,%start,%ray);
Replace it with :
switch$($lastbutton)
{
case "Orc" :
commandToServer("createorcbuilding",%pos,%start,%ray);
case "test" :
commandToServer("createtestbuilding",%pos,%start,%ray);
}
and add more cases for each extra button
Remember you'll need appropriate createorcbuilding and createtestbuilding , similar to the createbuilding one, in .../server/commands.cs
Hopefully my phone hasn't auotocorrected any mistakes in, and it's clear enough, if not I'll try and do better when next on my pc
11/03/2012 (3:42 pm)
Well the first step is to add at the start of .../GUI/plagui.cs :$lastbutton = "none";
Not strictly required but always good practice to default global variables to avoid any chance of unexpected behaviour later on.
The next step should have been straight forward, in functiion btn1::onClick, anywhere inside the { } add
$lastbutton = "Orc";
And the same line in each button's onClick function , replacing Orc with whatever .
Now th bit You might have had more trouble with, you'll have to excuse me for not copying your entire code , I'm not at home and typing on my phone., but your line :
commandToServer("createbuilding",%pos,%start,%ray);
Replace it with :
switch$($lastbutton)
{
case "Orc" :
commandToServer("createorcbuilding",%pos,%start,%ray);
case "test" :
commandToServer("createtestbuilding",%pos,%start,%ray);
}
and add more cases for each extra button
Remember you'll need appropriate createorcbuilding and createtestbuilding , similar to the createbuilding one, in .../server/commands.cs
Hopefully my phone hasn't auotocorrected any mistakes in, and it's clear enough, if not I'll try and do better when next on my pc
#20
11/03/2012 (4:46 pm)
Got it working perffect now thank you again next to figure out resource of some type then to add cost of building
Associate Steve Acaster
[YorkshireRifles.com]
Congrats on that Richard. Great work! :)