Solving the HTH Combat Problem

Solving the HTH Combat Problem

Requests for features in the spring code.

Moderator: Moderators

User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Solving the HTH Combat Problem

Post 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 ;)
User avatar
MadRat
Posts: 532
Joined: 24 Oct 2006, 13:45

Post 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.
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Post 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 :wink:







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...
Last edited by Argh on 21 Nov 2006, 03:36, edited 1 time in total.
User avatar
Maelstrom
Posts: 1950
Joined: 23 Jul 2005, 14:52

Post 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.
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Post 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.
User avatar
MadRat
Posts: 532
Joined: 24 Oct 2006, 13:45

Post 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.
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post 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);
Tobi
Spring Developer
Posts: 4598
Joined: 01 Jun 2005, 11:36

Post 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.
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Post 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.
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post 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
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post 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);
Tobi
Spring Developer
Posts: 4598
Joined: 01 Jun 2005, 11:36

Post 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.
User avatar
rattle
Damned Developer
Posts: 8278
Joined: 01 Jun 2006, 13:15

Post 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?
Warlord Zsinj
Imperial Winter Developer
Posts: 3742
Joined: 24 Aug 2004, 08:59

Post 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?
User avatar
Peet
Malcontent
Posts: 4384
Joined: 27 Feb 2006, 22:04

Post by Peet »

So...make it a tag instead of automatic. targetsurface=1 or something.
User avatar
MadRat
Posts: 532
Joined: 24 Oct 2006, 13:45

Post 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.
User avatar
zwzsg
Kernel Panic Co-Developer
Posts: 7052
Joined: 16 Nov 2004, 13:08

Post 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.
Tobi
Spring Developer
Posts: 4598
Joined: 01 Jun 2005, 11:36

Post 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.
User avatar
rattle
Damned Developer
Posts: 8278
Joined: 01 Jun 2006, 13:15

Post 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... :?
User avatar
KDR_11k
Game Developer
Posts: 8293
Joined: 25 Jun 2006, 08:44

Post 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).
Post Reply

Return to “Feature Requests”