Changes to buff system
by Jared Barger · in RTS Starter Kit · 11/21/2004 (9:21 pm) · 6 replies
I've been working on some additions to the buff system the last couple hours here and have found two things so far that I didn't like. Neither is a show stopper bug but they are both inconsistent with the rest of Torque.
First off, in engine/game/rts/rtsunit.cc, the console functions to add and remove a modifier get at the data like this
This works however only if you were to make the script call passing the modifier's id (ie. unit.addModifier(some_modifier.getId());). We can change findObject to use the overloaded version that takes a string param instead by changing the line to
Which will allow the script call to look like unit.addModifier(some_modifier);
Second, and quite a bit more problematic, is the constructor for the RTSUnitModifier in engine/game/rts/rtsunit.h. The constructor defaults all values to 1.0 which is great for creating a new unit. However, if I want to, for instance, add a movement modifier to a unit I declare the datablock...
datablock RTSUnitModifierData(RoadRunner){
moveSpeed = 2.0;
};
Due to the constructor this modifier actually augments all stats by +1 except for moveSpeed which is a +2. I didn't want to alter anything but moveSpeed though. You could either take the time to add every value to each datablock definition or....
Change the constructor to...
Then, in starter.rts/server/scripts/core/buffs.cs add the datablock
Lastly, in starter.rts/server/scripts/avatars/player.cs add the line
Maybe these were both done for a reason that I don't get because it all does work the way it is out of the box but I have to assume that these are boo-boos.
Oh, one last super minor thing in the buffs.cs file the buff Cripple has the modifier moveSpeed = 0.5; which obviously needs to be moveSpeed = -0.5;
First off, in engine/game/rts/rtsunit.cc, the console functions to add and remove a modifier get at the data like this
RTSUnitModifierData* data = dynamic_cast<RTSUnitModifierData*>(Sim::findObject(dAtoi(argv[2])));
This works however only if you were to make the script call passing the modifier's id (ie. unit.addModifier(some_modifier.getId());). We can change findObject to use the overloaded version that takes a string param instead by changing the line to
RTSUnitModifierData* data = dynamic_cast<RTSUnitModifierData*>(Sim::findObject(argv[2]));
Which will allow the script call to look like unit.addModifier(some_modifier);
Second, and quite a bit more problematic, is the constructor for the RTSUnitModifier in engine/game/rts/rtsunit.h. The constructor defaults all values to 1.0 which is great for creating a new unit. However, if I want to, for instance, add a movement modifier to a unit I declare the datablock...
datablock RTSUnitModifierData(RoadRunner){
moveSpeed = 2.0;
};
Due to the constructor this modifier actually augments all stats by +1 except for moveSpeed which is a +2. I didn't want to alter anything but moveSpeed though. You could either take the time to add every value to each datablock definition or....
Change the constructor to...
RTSUnitModifier()
{
mDamage = 0.0; //1.0;
mAttackDelay = 0.0; //1.0;
mArmor = 0.0; //1.0;
mMoveSpeed = 0.0; //1.0;
mRange = 0.0; //1.0;
mVision = 0.0; //1.0;
}Then, in starter.rts/server/scripts/core/buffs.cs add the datablock
datablock RTSUnitModifierData(BaseStats){
damage = 1.0;
Damage = 1.0;
AttackDelay = 1.0;
Armor = 1.0;
MoveSpeed = 1.0;
Range = 1.0;
mVision = 1.0;
};Lastly, in starter.rts/server/scripts/avatars/player.cs add the line
%obj.addModifier(BaseStats);to the end of the RTSUnit::onAdd function.
Maybe these were both done for a reason that I don't get because it all does work the way it is out of the box but I have to assume that these are boo-boos.
Oh, one last super minor thing in the buffs.cs file the buff Cripple has the modifier moveSpeed = 0.5; which obviously needs to be moveSpeed = -0.5;
#2
syntax is:
datablock ClassNameData(BlockName : BlockToCopyName)
And this dataBlock will copy everything from the BlockToCopyName db, then apply it's values on top of it. For really basic things I will even use a simDatablock to hold info to copy from.
11/22/2004 (1:04 pm)
Yes, you can copy the fields from another dataBlock quite easily. In fact the RTS SK does this with the units. The shocker, rifleman and bot all inherit from the UnitBaseBlock defined in base.cs.syntax is:
datablock ClassNameData(BlockName : BlockToCopyName)
And this dataBlock will copy everything from the BlockToCopyName db, then apply it's values on top of it. For really basic things I will even use a simDatablock to hold info to copy from.
#3
Actually, do this to understand what I mean. Take a look at buffs.cs to get an idea what the buffs are intended to do. Now run the app and check your default stats with
echo(unitid.getNetModifier().dump());
you'll see that all the unit stats are 1 by default
then add the sharpened weapons mod like this
unitid.addModifier(SharpenedWeaponsModifier.getId());
Now take a look at the modifiers again with echo(unit.getNetModifier().dump());
You will have added 1 to all mods that you didn't want to alter with it. So if you debuffed someone's vision, then debuffed their armor, then debuffed their movement they would be slow, unarmored, poorly sighted, and hit extra hard because they got a damage bonus piggy backed in with each of those debuffs =p
11/22/2004 (3:56 pm)
Yes I know you can do the datablock copies in the script. I'm referring to the C++ constructor for the class it attaches to. That class's default ctor defaults everything to 1.0 I'm just giving one way of getting around the way it works now.Actually, do this to understand what I mean. Take a look at buffs.cs to get an idea what the buffs are intended to do. Now run the app and check your default stats with
echo(unitid.getNetModifier().dump());
you'll see that all the unit stats are 1 by default
then add the sharpened weapons mod like this
unitid.addModifier(SharpenedWeaponsModifier.getId());
Now take a look at the modifiers again with echo(unit.getNetModifier().dump());
You will have added 1 to all mods that you didn't want to alter with it. So if you debuffed someone's vision, then debuffed their armor, then debuffed their movement they would be slow, unarmored, poorly sighted, and hit extra hard because they got a damage bonus piggy backed in with each of those debuffs =p
#4
11/22/2004 (4:49 pm)
@Jared: k, makes more sense now, and great catch :)
#5
So what about this code from server/scripts/core/commands.cs
%target.addModifier(%modifier.getID());
to
%target.addModifier(%modifier);
but what about
%target.schedule(%duration, "removeModifier", %modifier.getID());
it seems that removeModifier is actually expecting an ID, so I can't change that line, right?
Edit - Nevermind, I see that you were referring to both console functions, so I would have to change both console functions, and both lines.
But since I have your attention, have you seen a good post on how to add an attribute to an rts unit. I've been trying to figure that out for some time now. Do I wanna add to the datablock, or do I need to get into RTSUnit.cc and mimick the setTeam/getTeam stuff. I wanna add something like mana, for example. I expect the value to change as frequently as health changes.
06/15/2005 (2:27 pm)
Thanks, I was confused by that constructor, and the whole modifier concept.So what about this code from server/scripts/core/commands.cs
function serverCmdApplyModifier(%client, %modifier, %targetID, %duration)
{
%target = %client.resolveObjectFromGhostIndex(%targetID);
%target.addModifier(%modifier);
%target.schedule(%duration, "removeModifier", %modifier.getID());
}I already applied your suggestions, so therefore I had to change %target.addModifier(%modifier.getID());
to
%target.addModifier(%modifier);
but what about
%target.schedule(%duration, "removeModifier", %modifier.getID());
it seems that removeModifier is actually expecting an ID, so I can't change that line, right?
Edit - Nevermind, I see that you were referring to both console functions, so I would have to change both console functions, and both lines.
But since I have your attention, have you seen a good post on how to add an attribute to an rts unit. I've been trying to figure that out for some time now. Do I wanna add to the datablock, or do I need to get into RTSUnit.cc and mimick the setTeam/getTeam stuff. I wanna add something like mana, for example. I expect the value to change as frequently as health changes.
#6
06/15/2005 (5:32 pm)
Then you would want to mimic where it's at for RTSUnit's health. You can have a "default" value in the datablock, but you are going to want to implement something that can have a unique value for every instantiation of an object in the object itself--in this case, within RTSUnit.
Torque 3D Owner Stephen Zepp
I don't know if it would fix the issue or not to be honest, but what you indicate doesn't sound normal.