Deus Ex: Human Renovation (fan patch/mod)

A refuge for those migrating from the fallen DXEditing.com and a place for general discussion relating to Deus Ex editing (coding, mapping, etc).
Post Reply
User avatar
Dragon
Silhouette
Posts: 609
Joined: Sun Oct 23, 2005 9:20 pm
Location: switzerland
Contact:

Re: Deus Ex: Human Renovation (fan patch/mod)

Post by Dragon »

Close, but not fully hit. Evenly distributed point in a circle:

radius = sqrt( random() * maxRadius )
angle = random() * PI * 2
x = radius * sin( angle )
y = radius * cos( angle )

You missed the sqrt for the even distribution otherwise it's what you need. Adjust maxRadius according to weapon skill and there you are.

EDIT: If you want to skew the distribution towards the center or towards the outside you can use the general version
radius = pow( random() * maxRadius, factor )

whereas factor = 0.5 gives even distribution, factor > 0.5 favors center and factor < 0.5 favors border.
Leader and Head Programmer: Epsylon, Drag[en]gine Game Engine (Alt-Page) and others
Steve921
Mole Person
Posts: 4
Joined: Tue Sep 13, 2011 11:24 am

Re: Deus Ex: Human Renovation (fan patch/mod)

Post by Steve921 »

I was thinking something like the above would be simpler to implement too

Simply,
Distance from centre = (random number between 0 and radius)
Angle = random number between 0 and 360, both inclusive

x coordinate = (Distance from centre) * cos(angle)
y coordinate = (Distance from centre) * sin(angle)
DDL
Traditional Evil Scientist
Traditional Evil Scientist
Posts: 3791
Joined: Mon Oct 17, 2005 10:03 am

Re: Deus Ex: Human Renovation (fan patch/mod)

Post by DDL »

..reasonably sure that taking the higher of two random numbers gives an almost identical result to taking the root of one random number, plus it's marginally faster. Marginally. :)
G-Flex
Silhouette
Posts: 621
Joined: Mon Jul 11, 2011 10:16 pm

Re: Deus Ex: Human Renovation (fan patch/mod)

Post by G-Flex »

Dragon wrote:Close, but not fully hit. Evenly distributed point in a circle:

radius = sqrt( random() * maxRadius )
angle = random() * PI * 2
x = radius * sin( angle )
y = radius * cos( angle )

You missed the sqrt for the even distribution otherwise it's what you need. Adjust maxRadius according to weapon skill and there you are.
This is wrong. Yes, it's for an evenly distributed point in a circle, but we're not working with those. We're working with angles. You don't have a radius and you don't have an x and y, you have an offset angle and a yaw and pitch.

I really have no idea why you're doing sqrt(rand() * maxRadius) though. That means that max radius is the square root of maxRadius, as opposed to maxRadius itself!


Seriously though, I don't know how better to explain this. When dealing with angle offsets, you cannot pretend you're finding points on a circle. It doesn't work.
Steve921 wrote:I was thinking something like the above would be simpler to implement too

Simply,
Distance from centre = (random number between 0 and radius)
Angle = random number between 0 and 360, both inclusive

x coordinate = (Distance from centre) * cos(angle)
y coordinate = (Distance from centre) * sin(angle)
See above. The implemention of DX:HuRen up right now uses this, and it fails. It's an approximate solution at low angles, but that's it.

Obviously, here we're pretending that "radius" is the angle offset and that "angle" is the orientation of it on the cone. Let's pretend you're firing at an 89 degree offset (very ridiculously poor aim, nearly perpendicular to the crosshair direction), at a 45 degree orientation. That gives you a yaw of 62.9 degrees and a pitch of 62.9 degrees as well, which is nowhere even close to an 89 degree offset; it's more like 70.1 degrees, which value is off by 21.2%. At more reasonable values for firing angle, the error is far less serious.


I hate to repeat myself, but you guys have to remember here that the "point on a circle" thing is only a flawed visual metaphor for what's actually going on. It pretends that a given unit out from the center of the "circle" is equivalent to a given unit of angle, but this is not the case. Imagine a firing cone aiming straight at a wall, then increase the angle of the firing cone by the same increment (say, 5 degrees) each time. Each increment increases the radius of the circle on the wall by a variable amount. Going from 5 to 10 degrees of angle doesn't increase the radius nearly as much as increasing it from 70 to 75 degrees. This is trivially provable by imagining what happens when the angle approaches 90 degrees, in which case the radius approaches infinity. The "point-in-a-circle" method does not account for this, because it pretends that distance on the circle is linearly proportional to angle of fire, which it is not. You aren't determining where a shot falls onto a surface within a circle based on the radius of that circle, you're determining at what angle the shot is being fired to begin with, and you cannot use the same math for either of those.
DDL
Traditional Evil Scientist
Traditional Evil Scientist
Posts: 3791
Joined: Mon Oct 17, 2005 10:03 am

Re: Deus Ex: Human Renovation (fan patch/mod)

Post by DDL »

you guys have to remember here that the "point on a circle" thing is only a flawed visual metaphor for what's actually going on
Technically, this is in fact EXACTLY what is going on. It's not realistic, but it is exactly how DX does it (albeit with a square rather than a circle).

See, the problem with your approach is it requires a long hard look at each and every weaponclass and autoturret and whatever that fires, because as soon as you start treating fire offsets as actual angles, you have to go back and check what the trace range of the original weapon/whatever was.

With the "point on circle, extend forward" method, a pistol is inherently less accurate than a rifle, purely because the rifle extends further forward. So a shot that goes totally wide to the left might give a 10 degree yaw to the pistol, but only ca. 5 degrees to the rifle coz the trace range is doubled.

Now, I dunno if this is intentional or not, admittedly, but it IS the way the weapons have always behaved, and all I'm trying to do is distribute shots over a conical area rather than a pyramidal one. If I were to adopt your angle method, I'd have to calibrate the accuracy modifiers for every weapon to account for the fact that the total "conespace" of the rifle is longer and thinner than the conespace of the pistol, so the rifle should inherently generate smaller offset angles, for the same given 'accuracy' value.

And then you'd have the problem that weaponmodrange no longer quite works the same way (changes the trace range, so is a passive -albeit small- accuracy boost), weaponmodaccuracy would possibly have to be applied differently to each weapon (or possibly not, it's been a while since I fucked with weaponmod code)...it gets tricky.

Don't get me wrong, the circle+extend method is..well, ugly as all hell, but it IS simple, and as you demonstrate with your example, it allows for fairly linear accuracy increases, rather than near-exponential ones. Halving your inaccuracy under this system simply halves the radius of the circlespace, thus reducing the area by 4. It will do this whether you have awful accuracy or great accuracy.

Compare this to your system, where halving the inaccuracy of an already inaccurate weapon can have stupendous effects on reducing the resultant 'area', whereas halving the inaccuracy of a highly accurate weapon does very little.


TL:DR version, you are correct in that your system is a vastly more faithful representation of actual gun inaccuracy. But the area+extend method IS what has always been going on in DX, and as a result is a lot easier to implement without massive systemic recoding, and thus circle+extend most faithfully replicates the original gun behaviour while preventing 'square' artefacts.


...at least, as far as I can tell. Feel free to prove me wrong: learning is always good. :)
G-Flex
Silhouette
Posts: 621
Joined: Mon Jul 11, 2011 10:16 pm

Re: Deus Ex: Human Renovation (fan patch/mod)

Post by G-Flex »

DDL wrote:Yes, but the problem with your approach is it requires a long hard look at each and every weaponclass and autoturret and whatever that fires, because as soon as you start treating fire offsets as actual angles, you have to go back and check what the trace range of the original weapon/whatever was.

With the "point on circle, extend forward" method, a pistol is inherently less accurate than a rifle, purely because the rifle extends further forward. So a shot that goes totally wide to the left might give a 10 degree yaw to the pistol, but only ca. 5 degrees to the rifle coz the trace range is doubled.
It might help to note that I started off using Shifter's aim offset method as a base, which works directly with angles to begin with. I never really looked into the original algorithm much, but for comparison:

Shifter's method:

Code: Select all

//== Use a new, consistent method for calculating aim offsets.  Works just like the laser sight
rot = AdjustedAim;
if(Accuracy != 0.0)
{
	rot.Yaw += Accuracy * (Rand(3072) - 1536);
	rot.Pitch += Accuracy * (Rand(3072) - 1536);
}
EndTrace = StartTrace + ( FMax(1024.0, MaxRange) * vector(rot) );
Original DX method:

Code: Select all

EndTrace = StartTrace + Accuracy * (FRand()-0.5)*Y*1000 + Accuracy * (FRand()-0.5)*Z*1000 ;
EndTrace += (FMax(1024.0, MaxRange) * vector(AdjustedAim));
Shifter's method randomizes both pitch and yaw separately and ends the trace at the point along that direction determined by MaxRange (or 1024.0, whichever is greater).

The original method is a little more confusing to me since I never bothered with it much. It's worth mentioning, of course, that it doesn't match the targeting reticule (which is itself angular), hence Shifter's original change. As far as I can tell, it draws a square, plots a point within the square, then adds that positional offset to the end of the trace (determined by MaxRange and where you're facing). If I'm reading this right, you're right to say that Deus Ex's original method does result in a different angular accuracy depending on the range of the weapon, as moving EndTrace up 1 unit of length means a greater change in angle the closer it is to you.

So it's possible people here are talking about two things, seeing as how these two methods are completely different! I apologize if anyone else was talking about adjusting the end of the trace (a point) when I thought they were talking about adjusting the pitch/yaw (angles).

However, the real questions then become: Which works better? Which is more consistent with other aspects of the game? Which is more fun? Which makes more conceptual sense? What did the developers originally intend, and why?

Some of these questions are ones we can't answer, and some are very much debatable, so it's largely up to taste and opinion. My personal assumptions and opinions:
  1. The firing cone should be circular. This is perfectly solved using either a modification of Deus Ex's EndTrace adjustment method (as you suggest) or with my method, and imperfectly solved with my current uploaded implementation and not solved at all in either original Deus Ex or Shifter.
  2. The targeting reticule should match the firing cone. Since the reticule effectively represents an angle that varies linearly with accuracy, this is only possible if accuracy affects firing angles the same way. This is accomplished in Shifter's mod and my implementations, but not in any method that affects EndTrace the way original Deus Ex does (e.g. your suggested method). It may be possible to also solve this by changing the targeting reticule placement to account for the weapon's maximum range, I guess.
  3. Accuracy listed in-game should reflect your actual current accuracy. If the game says that two weapons have 85% accuracy, then each should be as accurate as the other. Same goes for the targeting reticule. This is only true if other factors (e.g. MaxRange) don't muck with it, nor is it intuitive to the player that a weapon's maximum range has anything to do with how accurate it is, especially when accuracy is itself listed. Again, I suppose it's possible to change how the game display's accuracy information, but even then, I consider it highly unintuitive to the player that range would even be a factor.
  4. Probability distribution of shots should be reasonable. I won't get into this too much, but it should suffice to say that this is true of my proposed method and also yours, but not Shifter's or the original game's. The current Human Renovation version's method is a close approximation, as is true with all of this.
Of course, you're right to say that there are balance ramifications for doing this, as guns no longer get an accuracy penalty/bonus based on range. However, that was never clear to the player to begin with, really, I'm not 100% convinced the developers intended it, and even the simple act of making firing spread circular has balance ramifications by effectively making guns more accurate (both by changing the distribution inside the firing cone, and inscribing a circle inside the previous square). If I had to guess, the developers wrote TraceFire() the way they did because it was 1) simple and didn't use much math, and 2) good enough that nobody complained. After all, I didn't even know firing spread was square in the game until fairly recently, and I had already played it several times!

It's also worth noting this comment in Shifter's code:

Code: Select all

//== This is the old method.  It works in theory, but the spread is different than what the reticle shows.
//==  We need to use it for hand to hand weapons and NPC weapons (otherwise NPCs suck)
I couldn't tell you why Shifter uses the original DX method for NPCs, and I especially can't tell you why it uses it for hand-to-hand weapons. I would be very curious to know this! Since I don't know why Yuki did this, I kept it myself just in case it turned out to be for some important reason, but I might at least alter it to be circular instead of square (which will actually make NPCs more accurate, for what it's worth).

Also bear in mind that I don't have a strict rule about adhering to the mechanics of the original game; I alter them where it seems realistic, player-friendly, and fun. For example, shotgun spread in the original game never made any sense to me, how it treated all the pellets individually, such that having bad accuracy means that your pellet spread is inexplicably huge, and having good accuracy means it's inexplicably small. I can remember playing a game where I became a sort of Shotgun Ninja with the targeting aug, getting 100% accuracy with the sawed-off shotgun, meaning all pellets landed right in the crosshairs. In this case, I figured that a change would make things more reasonable while preserving the characteristic flavor of that sort of weaponry, and I think it works fairly well.

TL:DR version, you are correct in that your system is a vastly more faithful representation of actual gun inaccuracy. But the area+extend method IS what has always been going on in DX, and as a result is a lot easier to implement without massive systemic recoding, and thus circle+extend most faithfully replicates the original gun behaviour while preventing 'square' artefacts.
I didn't have to do "massive systemic recoding" at all in order to implement my changes, actually. Yeah, it very slightly changes what a given increase/decrease in accuracy means, and nixes the effect range has on it, but I'm okay with that if it means the system makes more conceptual sense to me, and like I said, none of that stuff was ever intuitive (or at all clear, or even presented) to the player anyway.



So basically: Strictly speaking, you're right that the extended-circular-endtrace-adjustment method works (with regard to making the cone circular) and is consistent with original DX, but original DX isn't even consistent with original DX especially in the ways in which it presents accuracy to the player, and I'm willing to deviate from the original game slightly more than you. I'm not saying your method is bad, just that it's not what I prefer.

If anything, I'd say that Shifter's method is the black sheep here, as while it fixes the problem of the targeting reticule not matching actual firing offsets, it neither preserves the original range-based mechanic nor the problem of a square firing cone.
DDL
Traditional Evil Scientist
Traditional Evil Scientist
Posts: 3791
Joined: Mon Oct 17, 2005 10:03 am

Re: Deus Ex: Human Renovation (fan patch/mod)

Post by DDL »

I'd guess the hand-to-hand issue is to do with the fact that tracerange for those weapon is like 64uunits, so if translated into cone-angles, it's into the region subject to those wild variations in area that you listed above, thus making NPCs use it means they end up flailing hopelessly?

Possibly. Mind you NPC accuracy was always on the border between "fucking terrible" and "utterly deadly".

The reticle issue is a definite point in your favour, though. I can't remember if I ever actually looked into that. Possibly I just went "fuck it, close enough." :P

Edit: hang on though..surely if the reticle extension it to be truly representative of your firecone, it depends not only on accuracy but also distance to target? I.e. the reticle would have to expand and contract as you focussed on nearer or further targets.
G-Flex
Silhouette
Posts: 621
Joined: Mon Jul 11, 2011 10:16 pm

Re: Deus Ex: Human Renovation (fan patch/mod)

Post by G-Flex »

Nah, reticule represents a cone. Let me illustrate it thusly: Cut a circle in a piece of paper, and hold it in front of you at a certain distance. The space you see through that cut-out hole is conical, determined by the angle between your eye and the edge of that circle. Basically, the same as the edges of the pupil of an eye or a camera lens.

The targeting reticule is the same way. By being in a certain position on the screen, it represents a certain angle of field, just as the borders of the screen do. Hence the fact that larger objects fit inside the reticule while farther away.

DDL wrote:I'd guess the hand-to-hand issue is to do with the fact that tracerange for those weapon is like 64uunits, so if translated into cone-angles, it's into the region subject to those wild variations in area that you listed above, thus making NPCs use it means they end up flailing hopelessly?
I don't know. Even using my method or Shifter's method, the angle of attack is the same as with long-ranged weapons, so they should be able to hit just fine. Also bear in mind that Shifter keeps the old method not for NPCs using hand-to-hand weapons, but both for NPCs in general and the player when he uses hand-to-hand weapons. Weirdly enough, this also probably affects things like throwing knives and LAMs, since they're technically hand-to-hand (same reason why throwing knives don't give you a targeting reticule). You would really have to ask Yuki about it.

The trace should definitely extend far enough, though, since it's guaranteed to extend at least 1024 units.

Regarding NPC accuracy, both Shifter and my mod grant NPCs the sort of standing-still bonus that is normally only given to the player... but I don't know if the AI is really set up to take advantage of that, so it probably isn't very effective.
DDL
Traditional Evil Scientist
Traditional Evil Scientist
Posts: 3791
Joined: Mon Oct 17, 2005 10:03 am

Re: Deus Ex: Human Renovation (fan patch/mod)

Post by DDL »

Yeah I was almost certain that was true, but it kinda falls apart for very near objects, I think: i.e. it has to be arbitrarily placed at certain non-zero distance from the player (i.e. eye) or it would be a point, not a circle (representing the tip of the cone rather than a section through it), and inside that distance things don't quite work. Fire a shotgun at a wall directly in front of you and you should get almost zero spread for an angle-based system, since barrel to wall distance is almost nothing, but the apparent reticule size won't necessarily reflect this.

Mind you, I think traces are often calculated from fairly arbitrary startpoints anyway, like **checks** the player's face, so possibly this isn't actually an issue.
G-Flex
Silhouette
Posts: 621
Joined: Mon Jul 11, 2011 10:16 pm

Re: Deus Ex: Human Renovation (fan patch/mod)

Post by G-Flex »

DDL wrote:Yeah I was almost certain that was true, but it kinda falls apart for very near objects, I think: i.e. it has to be arbitrarily placed at certain non-zero distance from the player (i.e. eye) or it would be a point, not a circle (representing the tip of the cone rather than a section through it), and inside that distance things don't quite work.
This is only true for a distance of exactly zero, though, which is obviously problematic.
Fire a shotgun at a wall directly in front of you and you should get almost zero spread for an angle-based system, since barrel to wall distance is almost nothing, but the apparent reticule size won't necessarily reflect this.
It should reflect it, though. Even if the reticule is "drawn" a certain distance out from the player, that shouldn't matter, as it should still be drawn in such a way that it represents a certain angle of field. No matter how far away from you it's assumed to be, it should still look exactly the same, since if it's assumed to be closer to you, then the radius is smaller but is still drawn larger by virtue of being closer. All that should matter is that it's drawn on the boundaries of the cone some positive distance away from the cone's focal point.
Mind you, I think traces are often calculated from fairly arbitrary startpoints anyway, like **checks** the player's face, so possibly this isn't actually an issue.
Yeah, I don't know that the trace extends exactly from the same point as the camera. Looking at the code, I want to say that it does adhere to the camera, but I can't be 100% sure without looking further.

Doing some really cursory testing in the current released version of Human Renovation, the reticule is (basically) accurate even when you're pressed up against a wall
User avatar
Dragon
Silhouette
Posts: 609
Joined: Sun Oct 23, 2005 9:20 pm
Location: switzerland
Contact:

Re: Deus Ex: Human Renovation (fan patch/mod)

Post by Dragon »

G-Flex wrote:This is wrong. Yes, it's for an evenly distributed point in a circle, but we're not working with those. We're working with angles. You don't have a radius and you don't have an x and y, you have an offset angle and a yaw and pitch.
Basic trigonometry. Both are interchangeable. If you know angles you can easily calculate the respective radius and angle (for a given distance) and vice versa. Besides what you need is the end point of the trace if I get this right so not angles but coordinates. If you want a spread of X degrees simply choose the distance of the trace (I assume this is known) and calculate how large the radius is. That's the job of the tangens: radius/distance = tan(spread) => radius = distance * tan(spread). So if you prefer spread as your variable just do it like this then:
radius = sqrt( random() * traceDistance * tan( spreadAngle ) )
I really have no idea why you're doing sqrt(rand() * maxRadius) though. That means that max radius is the square root of maxRadius, as opposed to maxRadius itself!
This has to do with probability distribution. If you use "radius = random()*maxRadius" you end up with an uneven distribution clustering points in the center of the circle. Using sqrt is the mathematical correct solution to obtain an even distribution of points in the circle. Using the "pow" version I mentioned you can check this. Using linear radius would equal to using pow with factor 1. As I mentioned "factor > 0.5 favors center" thus without the sqrt correction your points would end up with higher probability in the center and scarcely at the outside. This can be the solution if you want to simulate a good shooter that only rarely hits inaccurately. And it doesn't matter if the spreadAngle is small or not since the size of the circle does not alter the probability distribution function.
Seriously though, I don't know how better to explain this. When dealing with angle offsets, you cannot pretend you're finding points on a circle. It doesn't work.
Yep, you can. As mentioned above offsets and angles are interchangeable since they are mathematically linked by formulas. Besides this is how serious games do it. Find a random point on a circle (trigonometry) and project it to the distance you need it (proportionality). It's simple, clean, fast and customizable depending on what you want to simulate.
Leader and Head Programmer: Epsylon, Drag[en]gine Game Engine (Alt-Page) and others
G-Flex
Silhouette
Posts: 621
Joined: Mon Jul 11, 2011 10:16 pm

Re: Deus Ex: Human Renovation (fan patch/mod)

Post by G-Flex »

Like I said, it depends on what the point on the circle represents. In the post you quoted, I thought you were talking about using it to determine an angular offset directly. If, as in the case of Deus Ex, you're simply using it to find a point an an arbitrary circle and then drawing a trace to that point, then it works. However, the way Deus Ex does it, this has the effect that DDL pointed out, where the range of weapon adds a confounding factor to the weapon's accuracy.
User avatar
Dragon
Silhouette
Posts: 609
Joined: Sun Oct 23, 2005 9:20 pm
Location: switzerland
Contact:

Re: Deus Ex: Human Renovation (fan patch/mod)

Post by Dragon »

G-Flex wrote:Like I said, it depends on what the point on the circle represents. In the post you quoted, I thought you were talking about using it to determine an angular offset directly. If, as in the case of Deus Ex, you're simply using it to find a point an an arbitrary circle and then drawing a trace to that point, then it works. However, the way Deus Ex does it, this has the effect that DDL pointed out, where the range of weapon adds a confounding factor to the weapon's accuracy.
Why should it add a confounding factor? DX does it wrong, that's clear, but using this version after you have the point on a circle you proportionally project it to the distance where the trace ends. Such a projection does not alter the angle the bullet is fired from relative to the view direction in any way and thus the accuracy is maintained.
Leader and Head Programmer: Epsylon, Drag[en]gine Game Engine (Alt-Page) and others
G-Flex
Silhouette
Posts: 621
Joined: Mon Jul 11, 2011 10:16 pm

Re: Deus Ex: Human Renovation (fan patch/mod)

Post by G-Flex »

I didn't say that it should, just that in Deus Ex, it does, and the algorithm would need to be changed to account for it.

Like you were saying, what you would need to do is: Draw the circle at some constant distance from the player's view (instead of a distance relative to maximum range), and draw the trace to there, but extend the trace to such a length that the weapon's range is respected. Of course, this would require calculating the distance between the viewpoint and that point on the circle, so you'd know how far to extend/retract the trace.

The probability distribution would still be different from direct computation of the angle of fire, though; it would result in greater density towards the edges of the cone. Also, although this has been stated, accuracy means something very different in each case.
User avatar
Dragon
Silhouette
Posts: 609
Joined: Sun Oct 23, 2005 9:20 pm
Location: switzerland
Contact:

Re: Deus Ex: Human Renovation (fan patch/mod)

Post by Dragon »

G-Flex wrote:Like you were saying, what you would need to do is: Draw the circle at some constant distance from the player's view (instead of a distance relative to maximum range), and draw the trace to there, but extend the trace to such a length that the weapon's range is respected. Of course, this would require calculating the distance between the viewpoint and that point on the circle, so you'd know how far to extend/retract the trace.
No need for that. Nobody prevents you from choosing 1 as the distance where you calculate your circle. So it all boils down to multiply the result by the distance to the end of the trace (typically the firing range).
The probability distribution would still be different from direct computation of the angle of fire, though; it would result in greater density towards the edges of the cone. Also, although this has been stated, accuracy means something very different in each case, and the targeting reticule only works as-is if accuracy represents angle rather than distance from a central point on an arbitrary plane perpendicular to line-of-sight.
That's though not correct. You do not need an even distribution in the cone. What you need is an even distribution in the target circle as if the circle is painted on a wall and you shot at it. The formula I gave is mathematically correct and evenly distributed in the circle. Furthermore the maximum spread angle is an input variable as you requested. So you have everything you need:
1) upper spread angle limit as input variable (angle based spread)
2) even distribution in a circle (circular impact shape, mathematically correct as long as PRNG is good enough)
3) easy and fast to calculate (requires only one sin, cos and tan)

So what is missing so it is not a viable solution?
Leader and Head Programmer: Epsylon, Drag[en]gine Game Engine (Alt-Page) and others
Post Reply