Page 1 of 2
Solving the HTH Combat Problem
Posted: 21 Nov 2006, 00:55
by Argh
Folks... everybody who has worked with Spring knows that Hand-to-Hand combat isn't really practical in Spring right now.
I have a solution, that would also solve a few other problems.
Basically we need the aiming code to aim at the closest edge of the hitspheres, rather than the centers.
Right now, the code basically does this:
1. Aims at the center of the target.
2. Calls COB script for aiming conditions.
3. Fires weapon.
What I want the code to do is:
1. Aim at center of target. Subtract out the Radius from the line-length from the target to the firing unit.
2. Call COB script for aiming conditions.
3. Fire weapon.
Ok... assuming that we're getting the target's location, and storing as a Float3, and storing the shooter's location as a Float3, and the Radius is a value that the hit-detection code already has, and it's stored from the moment Unit.cpp runs... what math do we need to do, to shorten that line? My math skills suck, basically. Are there fast-and-dirty ways to do this, that are less accurate, but faster math? Because if we change this, the code needs to be fast, fast, fast- Spring's units are calling aiming code every frame, or every other frame, IIRC.
Please help a not-very-math-smart guy figure this out, and we can have HTH combat

Posted: 21 Nov 2006, 02:27
by MadRat
I can remember hack-n-slash games long before graphics were a worthwhile investment in game design. Ever play a game called Wizardry? Maybe even Temple of Aphsai? (Better example as its code base was easy to read BASIC.) Some things might be better done without hit spheres and such. And the code from these old 8-bit games was usually under 200 lines for the entire game. Maybe there are some abandonware examples out there if you look hard enough.
Posted: 21 Nov 2006, 02:48
by Argh
Please see "
relevance". It's in the dictionary. This is not the Atari 800 or some 2-bit vector-graphics game recorded onto an 8-track tape, and my question is simple if you actually know how to do math, which is my problem- I get stuck past long division
Most of the high-school kids taking trig or geometry here can probably solve this without breaking a sweat- I suck at math, and I'm not sure even where to look this up on Wikipedia, or I would've done so already.
I have two
points in 3D space, XYZ. I have a
line between them, which we can assume is being translated into a
vector. I want to shorten that line, so that instead of aiming at the target's center, I am aiming at the point on the line where the target's radius intersects that line. This is, I am sure... pretty easy trig or analytical geometry.
[EDIT]
There may even be an easier way to do this. Maybe I could get the Radius value of the target... and subtract Radius from whatever checks for "in range"... and if < the "in range" distance, then = "in range". That's probably the most elegant way to do this...
Posted: 21 Nov 2006, 03:36
by Maelstrom
Code: Select all
targetPos = XYZ; //XYZ position of the target
attackerPos = XYZ; //XYZ position of the attacker
lineLength = number; //Distance from target to attacker
radius = number; //Radius of the attackers hitsphere
ratio = (linelength - radius) / linelength; // Will return a number like 0.9
//This will return the XYZ pos of the edge of the attacker hitsphere
targetPos = ( ( targetPos - attackerPos ) * ratio ) + attackerPos;
Very rough pseudo code there, but I think its what your looking for. I dont know how this would work using Springs float3() and stuff, but thats basically what you need to do. Theres probably an easier way of doing though, i havnt done any really hard vector maths or anything.
Posted: 21 Nov 2006, 03:39
by Argh
Aha... so if LineLength - LineDerived < the weapon's range, then the condition allowing firing would be TRUE. Cool.
Translating that into C++ shouldn't be hard. I thought it was a ratio, but I wasn't sure.
Posted: 21 Nov 2006, 03:52
by MadRat
You really only need to know the radius of the attacker, the radius of the defender, the distance between the centers, and subtract the sum of the first two from the last. If its equal or less than zero you are within range. Direction is only important when you want to determine the animation. Otherwise you're connecting two round spheres together, which means everything is a straight line between the two.
Posted: 21 Nov 2006, 15:03
by AF
I have a function in NTai(at uni so I'll post when I get home) that takes 2 float3 co-ordinates and a distance x and gives the position on the line that is distance x from the second point.
so it'd be
Code: Select all
float3 unit=xyz;
float3 target=xyz;
target = distfrom(unit,target,radius);
Posted: 21 Nov 2006, 15:26
by Tobi
You guys are all searching for way too complex solutions to the problem, solving the targetting is a matter of subtracting u->radius from the distance used in the range check. No vector math needed at all...
But that won't make HTH/melee combat possible because damage calculation (and possibly more) only works on the center of units, ie. melee weapons would need an AoE bigger then the biggest unit they should be able to damage.
Posted: 21 Nov 2006, 15:44
by Argh
For AOE, yeah, but I thought direct hits applied damage directly, and were based off collision with the hitsphere. Could be wrong- heck, probably am wrong... dunno.
Posted: 21 Nov 2006, 16:36
by AF
So if I have a unit thats about half the map in size and I make an explosion inside the unit say about a quarter of the map away from the centre of the unit but inside its model, the unit wont be damaged? Despite the explosion occuring within its hitsphere? Thats horrendous.
It also explains a few ingame situatiuons that seem slightly odd
Posted: 21 Nov 2006, 16:39
by AF
This is the code I use in NTai, although I'm sure there's a better way of doing it.
Code: Select all
float p = distance/Start.distance2D(Target);
if(p < 0) p *= -1;
float dx = Start.x-Target.x;
if(dx < 0) dx *= -1;
float dz = Start.z-Target.z;
if(dz < 0) dz *= -1;
dz *= p;
dx *= p;
float x = Target.x;
if(Start.x > Target.x){
x += dx;
} else{
x -= dx;
}
float z = Target.z;
if(Start.z > Target.z){
z += dz;
}else{
z -= dz;
}
return float3(x,0,z);
Posted: 21 Nov 2006, 16:57
by Tobi
Seems an overly complex version of:
Code: Select all
float3 direction = (target - start);
return start + direction * position;
where position is a scalar for position on line from start (position = 0) to target (position = 1). Extrapolation is also possible.
Posted: 21 Nov 2006, 18:40
by rattle
Might be stupid but isn't the radius saved in the s3o already? So wouldn it be easier to set both formulas (the line and hit circle) against each other and get the (two) points where they meet?
Also, what happens when a zero AOE weapon hits the outer hitsphere?
Posted: 21 Nov 2006, 23:50
by Warlord Zsinj
Wouldn't this potentially make the issues with inaccurate hit spheres for odd shaped units, and large units, all the more problematic?
Posted: 21 Nov 2006, 23:57
by Peet
So...make it a tag instead of automatic. targetsurface=1 or something.
Posted: 22 Nov 2006, 01:35
by MadRat
Its easier to just judge if the hitspheres are within length of the weapon and then use a psuedo-melee for the outcome if you want variance. Its just not worth it to get overly complex computations for melee in Spring, but its perhaps doable in OSRTS if they use hitspheres for each unit piece. I've got the impression that OSRTS is to Spring what TA:K was to OTA.
Posted: 22 Nov 2006, 12:21
by zwzsg
Tobi wrote:damage calculation (and possibly more) only works on the center of units, ie. melee weapons would need an AoE bigger then the biggest unit they should be able to damage.
Last time I tried, a shot would score a hit if:
- It was inside the footprint on the xz plane
and:
- It was within the model radius on the y axis
Oh wait it's Tobi I'm quotting, he probably knows better since he reads the source. Maybe I just mixed up "shot explode" and "shot deal damage".
But if big units can only be damaged in their center, like AF said, that's horrendous.
Posted: 22 Nov 2006, 13:17
by Tobi
This time it was just my conclusion from some experiments after I fixed the targetting: I noticed the weapon didn't deal any damage, unless I made it's AoE bigger.
Posted: 22 Nov 2006, 14:57
by rattle
Can't you make the weapon apply damage to the unit regardless of where or what it hits? Okay I have no idea how the damage system works now if it's all AOE dependent...

Posted: 22 Nov 2006, 16:27
by KDR_11k
I think at least for buildings thew weapon only collides when it's over the footprint (more specifically solid parts of the footprint, it'll go right through open spaces).