Adding the Z Axis back in
by Robert Stewart · in RTS Starter Kit · 02/26/2005 (6:37 pm) · 12 replies
Hey, I couldent find a real awnser from these forums, except from the thread "Remove Terrain". I was wondering what I would have to change to get the Z axis back in, so units dont snap to the ground. I read something about changing some stuff in RTSUnit.cc, can anyone help me a little more than that? maybe a employee can tell me where exactly they changed those settings. Also this unit will not be the only selectable unit, and already selected. Thanks for any help.
About the author
#2
02/26/2005 (7:02 pm)
I wouldent mind physics but I'am only trying to add the ability to "hover", the amount you are hovering would be dynamic though.
#3
Next, look at RTSUnit.cc, function processTick(), down near the bottom. Look for:
You will want to factor in your mHoverHeight here, such as:
NOTE: This is based on your statement that the units will already be selected. If they should be able to be selected again once hovering, you will probably need to confirm the selection/drag-select code will work properly. Click-selection should be fine as long as they click on the unit, but drag select may need some work.
02/26/2005 (7:19 pm)
First, you want to add a new field to RTSUnit, call it "mHoverHeight". You will need to add it in RTSUnit.h, add it appropriately in RTSUnit.cc, initPersistFields, packUpdate(), unpackUpdate(), as well as create access methods (both in C++ and as ConsoleMethods to allow the values to be modified via script).Next, look at RTSUnit.cc, function processTick(), down near the bottom. Look for:
if (mFabs(location.z - height) > 0.01)
{
location.z = height;
setMaskBits(MoveMask);
}You will want to factor in your mHoverHeight here, such as:
if (mFabs(location.z -mHoverHeight - height) > 0.01)
{
location.z = height + mHoverHeight;
setMaskBits(MoveMask);
}NOTE: This is based on your statement that the units will already be selected. If they should be able to be selected again once hovering, you will probably need to confirm the selection/drag-select code will work properly. Click-selection should be fine as long as they click on the unit, but drag select may need some work.
#4
Edit: Ok so im pretty sure it goes into RTSUnit, but i cant find a InitPersistField for RTSUnit.
02/26/2005 (8:43 pm)
Couple questions, should i add the new field to RTSUnit or RTSUnitdata? Also i dont see any console functions for mMoveSpeed, but yet i can change it like %player.movespeed = 1; at least i think.. hmmm. I have mHoverHeight in RTSUnitData right now, but in processtick it says that mHoverHeight is not declared. Ill recheck what i just put in see if i can get it to work. thanksEdit: Ok so im pretty sure it goes into RTSUnit, but i cant find a InitPersistField for RTSUnit.
#5
movespeed is actually a bad example to look at for a reference, as IIRC it got modified/removed. There actually isn't an easy example to draw from in RTSUnit, but you can use the same technique that is used for the values in RTSUnitData pack/unpack.
For an example or two of console methods to modify values, look at setTeam/getTeam, in RTSUnit.cc.
02/26/2005 (9:08 pm)
You said that you wanted it dynamic, so I assumed it was going to have a unique value for each unit--so it needs to be in RTSUnit, not RTSUnitData.movespeed is actually a bad example to look at for a reference, as IIRC it got modified/removed. There actually isn't an easy example to draw from in RTSUnit, but you can use the same technique that is used for the values in RTSUnitData pack/unpack.
For an example or two of console methods to modify values, look at setTeam/getTeam, in RTSUnit.cc.
#6
02/26/2005 (9:13 pm)
Ok so i have it in RTSUnitData for now, but processtick is RTSUnit:: so, stuff in RTSUnitData wont be read in there right? is that why im getting mHoverHeight undefined, and if that is my problem right now, then how would i do that? i tried something like RTSUnitData* mHoverHeight, but it dosent seem to work. Sorry im not an expert in C++. Also thanks for helping so much stephen.
#7
(search for // Unit Movement, about line 150-ish):
S32 mHoverHeight;
The rest of the stuff could be modifed from the mTeam, getTeam()/setTeam() stuff.
02/26/2005 (9:23 pm)
MHoverHeight needs to be probably an integer value, which would be the height above the terrain the unit can fly. It also needs to be in the RTSUnit section: (class RTSUnit : public Player) It would look like this in RTSUnit.h:(search for // Unit Movement, about line 150-ish):
S32 mHoverHeight;
The rest of the stuff could be modifed from the mTeam, getTeam()/setTeam() stuff.
#8
02/27/2005 (8:27 am)
Ok, this is my own lack of knowledge with C++ but.. I cant find and refrences of mTeam or any other variable from RTSUnit, from the RTSUnit::packUpdata(). i see stuff like this if(stream->writeFlag(mask & InitialUpdateMask))
{
AssertISV(getTeam() < 64, "Can only pack 64 unique teams!");
stream->writeInt(getTeam(), 5);
} . this looks close but, how does it acually have input with mTeam?
#9
S32 getTeam() const { return mTeam; }
(Side Note: A lot of developers will include very basic/small functions like this in the .h file, instead of implementing them in a .cc file. This is valid programming practice, but can be quite confusing to new programmers, since the syntax is just a bit different. You are just as perfectly fine putting the implementation of getTeam() in the RTSUnit.cc file.).
A better example is setTeam() in RTSUnit.cc:
A couple of general C++ concepts to note:
--since this is a class method (see how it has RTSUnit::setTeam ), there are some assumptions the compiler will make for you:
a) the very first place to look for methods and variables that are called are in the namespace class--in this case, the "RTSUnit" class.
b) the token "this" always refers to the object that called the method. NOTE: TGEScript mimics this assumption, but slightly differently. In TGEScript, you must actually list %this as the first parameter in your script function to be able to access it. You do not need to do this in C++.
Ok, on to the code:
First line, we see the mTeam variable. Since it is not given a class identifier, the compiler knows that you really mean RTSUnit->mTeam. Therefore, this line sets the mTeam variable for this specific unit to the value sent to the method in the team variable (which is passed by the caller).
Second Line: this is a class method to mark the unit as "dirty", or "has been modified". It's used for optimization processes in other loops, so that if the processing loop checks to see if a unit "isDirty()", and gets back "no", it won't do any further processing. Saves cpu cycles.
Third/fourth lines:
"If the object is a client object (meaning that the executable is a client executable), then activate the callback in the client's visMangler (visManager--sorry, inside joke!), and "handle" that event. Note that here we tell the compiler specifically that we want to call the "onSetTeam" method of the gClientVisManager global object. We also send the object "this" as a parameter to this method--see #2 assumption above.
If you follow the implementation in RTSUnit.cc to adjust for mHoverHeight, all you should need in your access methods are:
In RTSUnit.h:
S32 getHoverHeight() const { return mHoverHeight; }
and in RTSUnit.cc:
NOTE: IIRC, the setDirty() isn't needed, because it's used for the visManager updating. Since all you are doing is changing the height of the RTSUnit, not changing it's x,y coordinates, the "is visible" state won't change due to this action.
You will also probably want the following to make your new variable accessable to script:
02/27/2005 (9:56 am)
GetTeam() is an access method (the "most proper") way of encapsulating data. If you do a further search on "getTeam()", you'll find the following code in RTSUnit.h:S32 getTeam() const { return mTeam; }
(Side Note: A lot of developers will include very basic/small functions like this in the .h file, instead of implementing them in a .cc file. This is valid programming practice, but can be quite confusing to new programmers, since the syntax is just a bit different. You are just as perfectly fine putting the implementation of getTeam() in the RTSUnit.cc file.).
A better example is setTeam() in RTSUnit.cc:
void RTSUnit::setTeam(S32 team)
{
mTeam = team;
setDirty();
if (isClientObject())
gClientVisManager->onSetTeam(this);
}A couple of general C++ concepts to note:
--since this is a class method (see how it has RTSUnit::setTeam ), there are some assumptions the compiler will make for you:
a) the very first place to look for methods and variables that are called are in the namespace class--in this case, the "RTSUnit" class.
b) the token "this" always refers to the object that called the method. NOTE: TGEScript mimics this assumption, but slightly differently. In TGEScript, you must actually list %this as the first parameter in your script function to be able to access it. You do not need to do this in C++.
Ok, on to the code:
First line, we see the mTeam variable. Since it is not given a class identifier, the compiler knows that you really mean RTSUnit->mTeam. Therefore, this line sets the mTeam variable for this specific unit to the value sent to the method in the team variable (which is passed by the caller).
Second Line: this is a class method to mark the unit as "dirty", or "has been modified". It's used for optimization processes in other loops, so that if the processing loop checks to see if a unit "isDirty()", and gets back "no", it won't do any further processing. Saves cpu cycles.
Third/fourth lines:
"If the object is a client object (meaning that the executable is a client executable), then activate the callback in the client's visMangler (visManager--sorry, inside joke!), and "handle" that event. Note that here we tell the compiler specifically that we want to call the "onSetTeam" method of the gClientVisManager global object. We also send the object "this" as a parameter to this method--see #2 assumption above.
If you follow the implementation in RTSUnit.cc to adjust for mHoverHeight, all you should need in your access methods are:
In RTSUnit.h:
S32 getHoverHeight() const { return mHoverHeight; }
and in RTSUnit.cc:
void RTSUnit::setHoverHeight(S32 hoverHeight)
{
mHoverHeight = hoverHeight;
}NOTE: IIRC, the setDirty() isn't needed, because it's used for the visManager updating. Since all you are doing is changing the height of the RTSUnit, not changing it's x,y coordinates, the "is visible" state won't change due to this action.
You will also probably want the following to make your new variable accessable to script:
ConsoleMethod( RTSUnit, setHoverHeight, void, 3, 3, "( S32 hoverHeight )"
"Sets the units new hover altitude above ground level.")
{
object->setHoverHeight(dAtoi(argv[2]));
}
ConsoleMethod( RTSUnit, getHoverHeight, S32, 2, 2, "()"
"Returns the units altitude above terrain.")
{
return object->getHoverHeight();
}
#10
02/27/2005 (12:27 pm)
It works, thank you for taking the time to help me on this.
#11
02/27/2005 (12:39 pm)
Not a problem! I'm sure that others will come along that will be looking for similar functionality, and hopefully this will act as a good starting guide!
#12
*** Phase 3: Mission Lighting
Successfully loaded mission lighting file: 'starter.RTS/data/missions/frenzy_b588d5fc.ml'
Mission lighting done
Mapping string: MissionStartPhase3Ack to index: 3
Fatal: (c:\users\chriskuy\desktop\new folder\rtsstarterkit\engine\core\bitstream.h @ 170) Out of bounds value!
Now I have not yet made any changes to any torquescript and am using a fresh download (no lighting kit or extras added in), Are there changes that should be made in script? and if so, where?
Thanks,
Chris
11/20/2007 (12:28 pm)
Sorry to un-bury an old thread, but I'd really like to take this a little further, I've managed to get the c++ code shown here into my program and have it compile with no errors or warnings, now when I start up the starter.rts, the console gets to this point shown below, and then crashes out:*** Phase 3: Mission Lighting
Successfully loaded mission lighting file: 'starter.RTS/data/missions/frenzy_b588d5fc.ml'
Mission lighting done
Mapping string: MissionStartPhase3Ack to index: 3
Fatal: (c:\users\chriskuy\desktop\new folder\rtsstarterkit\engine\core\bitstream.h @ 170) Out of bounds value!
Now I have not yet made any changes to any torquescript and am using a fresh download (no lighting kit or extras added in), Are there changes that should be made in script? and if so, where?
Thanks,
Chris
Torque 3D Owner Stephen Zepp