Unit Attack Accuracy
by Daniel Rank · in RTS Starter Kit · 11/21/2004 (11:09 am) · 3 replies
I wanted to add an accuracy field for the RTS units so that they wouldn't always hit the target. I'm not very familiar with Torque yet, so this probably isn't the best implementation, and I would appreciate any suggestions.
In RTSUnit.h I added an accuracy data field, a random number generator and seed.
The following code was added to RTSUnit.cc.
For the accuracy data field:
For the RNG:
Then I tested it out with rifleman.cs by adding to riflemanBlock::onAttack.
So for this implementation the accuracy field should be set to an int between 1 and 10. Again, I'm looking for suggestions and better implementations. I would also like to find out how to prevent the target unit from "glowing" when attacked, when the attacker misses. I would appreciate any help on this, or else I will post my own findings later.
In RTSUnit.h I added an accuracy data field, a random number generator and seed.
class RTSUnitData : public PlayerData
{
. . .
public:
S32 mAccuracy;
. . .
}
class RTSUnit : public Player
{
. . .
private:
. . .
S32 mTimeSeed;
MRandom mRandom;
. . .
public:
. . .
S32 getTimeSeed();
S32 getRandomInt(S32 i, S32 n);
. . .
}The following code was added to RTSUnit.cc.
For the accuracy data field:
RTSUnitData::RTSUnitData()
{
mAccuracy = 5;
. . .
}
void RTSUnitData::packData(BitStream* stream)
{
. . .
stream->write(mAccuracy);
. . .
}
void RTSUnitData::unpackData(BitStream* stream)
{
. . .
stream->read(&mAccuracy);
. . .
}
void RTSUnitData::initPersistFields()
{
. . .
addField("accuracy", TypeS32, Offset(mAccuracy, RTSUnitData));
. . .
}For the RNG:
RTSUnit::RTSUnit()
{
. . .
mTimeSeed = 0;
}
S32 RTSUnit::getTimeSeed() { return mTimeSeed; }
// kludge
S32 RTSUnit::getRandomInt(S32 i, S32 n)
{
mRandom.setSeed(mTimeSeed);
mTimeSeed += mRandom.randI(0, 10000);
mRandom.setSeed(mTimeSeed);
return mRandom.randI(i, n);
}
void RTSUnit::processTick(const Move *move)
{
// kludge
mTimeSeed += 3333;
. . .
}
// for debugging
ConsoleMethod( RTSUnit, getTimeSeed, S32, 2, 2, "()")
{
return object->getTimeSeed();
}
ConsoleMethod( RTSUnit, getRandomInt, S32, 4, 4, "(S32 i, S32 n)")
{
return object->getRandomInt(dAtoi(argv[2]), dAtoi(argv[3]));
}Then I tested it out with rifleman.cs by adding to riflemanBlock::onAttack.
function riflemanBlock::onAttack(%this, %attacker, %target)
{
echo(attacking);
%hitAccuracy = %attacker.getRandomInt(1, 10);
echo(%hitAccuracy);
echo(%attacker.getTimeSeed());
if(%hitAccuracy <= %attacker.getDataBlock().accuracy)
{
echo(hit);
%damage = %attacker.getDataBlock().baseDamage;
if(%attacker.getNetModifier().baseDamage)
%damage *= %attacker.getNetModifier().baseDamage;
%armor = %target.getDataBlock().armor;
if(%target.getNetModifier().armor)
%armor *= %target.getNetModifier().armor;
if(%damage > %armor)
%damage -= %armor;
else
%damage = 0;
%target.applyDamage(%damage);
}
else
{
echo(miss);
}
}So for this implementation the accuracy field should be set to an int between 1 and 10. Again, I'm looking for suggestions and better implementations. I would also like to find out how to prevent the target unit from "glowing" when attacked, when the attacker misses. I would appreciate any help on this, or else I will post my own findings later.
#2
EDIT: My idea above is complete rubbish. I ought to look at the code before shooting my mouth off. Opps.
11/22/2004 (12:25 pm)
I've not started to code it up yet - but here is my approach. At the moment I think the aim defaults to shooting at the target unit's feet. What I'm going to do is create a box around the target and pick a position randomly within that box. Some might be a hit others might be a miss. Of course the bigger the box, the less accuracy. For the game I am designing this works well, because if you miss and hit another unit - thats fine - its 'realistic'. And you can do this all in script.EDIT: My idea above is complete rubbish. I ought to look at the code before shooting my mouth off. Opps.
#3
01/17/2006 (9:18 pm)
Do you have any problem with the code? I have made the changes, but when I try to launch the mission, appears an error "out of range" from the bitStream class.
Torque 3D Owner Stephen Zepp
What this means is that your client is going to go ahead and do it's own "pretend" attacks regardless of what happens server side (hence the glowing of a hit), while the server is going to only update the damage on the unit when a real hit connects.
I don't have an implementation fix for you right off the bat, but this is yet another thing our project will have to address, so I'll start thinking about it.
Of course, my understanding of the documentation could be comepletely wrong as well!