Fallout 2 mod F2: damage calculation change, a FIX (v3 by my count)

The latest version of my FIX has been thoroughly tested by NovaRain (one of this forum's most enthusiastic mod testers). It still follows the original ideas I had for this FIX, but now optimized and as efficient as possible.

Notes below:

My understanding of the game engine; as it applies to this change, is built on other great modders work:
--- ravachol, first to expose the damage calculation in the exe
--- Kanhef, Haenlomal, and Timeslip, exposing even more of the inner workings of the exe
--- Cubik2k, leading the way in discussions and attempting to change the damage calculation
--- all other contributers to threads that have discussed the problem and ways it could be solved in this forum

What I understand of the damage calculation in the exe:
(assumptions are based on knowing if they were anything else then the calculation would fail badly)

- it adds the DR modifier from the attacking critter's ammo (loaded in its weapon) to the DR value in the target critters armor (starting at line 004249A1 when debugging the exe from the killap's RP - the tool I use is OllyDbg)
--- I don't know what the DR modifier value is if the attacking critter is not using a weapon or if the weapon does not use ammo, assumed to be 0 in this case

- it checks if the new sum is greater than or equal to 0, if not it sets this new value to 0

- if greater than or equal to 0, it then checks if the new sum is less than or equal to 100, if not it sets this new value to 100

- the new value is then stored for later use
--- armorDR+ammoDRM - at this point the value is between 0 and 100 inclusive

- it then multiplies the Critical Multiplier (CM) by the attacking critter's ammo damage multiplier (X)
--- CM is by default 2 or if the hit was determined to be a critical hit (happens somewhere before this) is set to a value from the critical hit table (I assume)
--- X is either 1, 2, or 3 based on known ammo types
--- I don't know what the X value is if the attacking critter is not using a weapon or if the weapon does not use ammo, assumed to be 1 in this case

- it then multiplies the attacking critter's ammo damage divisor (Y) by a value (I wish I knew what - ravachol mentioned the value was 1, but I have not confirmed this is always the case)
--- mystery value (MV)???
--- Y is either 1 or 2 based on known ammo types
--- I don't know what the Y value is if the attacking critter is not using a weapon or if the weapon does not use ammo, assumed to be 1 in this case

- it then gets the number of hits the target critter took
--- I assume if multiple targets were hit from a burst weapon that it is tracked elsewhere and once one target is handled, the next is sent through

- it then clears a counter thats tracks the number of hits processed

- it then stores the X*CM value for later

- it then checks if the number of hits is less than or equal to 0, if not it skips all else
--- I assume it then returns to see if there was another target hit or initiates the next critters/players turn

- if the number of hits is greater than 0, it then gets the range bonus (RB)
--- I assume RB to be default 0 unless the critter/player has the Bonus Ranged Damage perk

- it then adds RB to the raw random damage value (RD)
--- RD is dependant on the damage min.-max. of the attacking critter's weapon or whatever an unarmed critter is capable of

- it then multiplies this new value (ND) by X*CM

- it then checks if MV*Y is 0, if it is then it skips ahead
--- this leads me to believe that either MV or Y may be allowed to be 0 when called in
--- I suspect MV is what may be allowed to be 0 and if so then maybe it's associated to a weapon perk???

- it MV*Y is greater than 0, it then divides ND by MV*Y

- it then divides the new ND value by 2
--- this seems to be done because for whatever reason CM is by default 2 and always multiplied in thus to negate an increase in damage when there was no critical hit, divide by 2
--- when CM is not 2, this should also mean values in the critical hit table should always be even, as odd numbers would produce a decimal which would be dropped, I have not confirmed this

- it then multiples the new ND value by the combat difficulty setting value (CD)
--- CD appears to be either 72, 100, or 112
--- given the way the CD value is used, I assume if the player chose a setting of Easy then CD=112 and if Hard then CD=72, this is counter intuitive but it would not work correctly the other way around

- it then divides the new ND value by 100
--- this is meant to cause CD to be used as a percentage
--- unfortunately, again there is no rounding, any decimal value (remainder) is dropped after division

- it then subtracts the armor's damage threshold (armorDT) from the new ND value

- it checks if the new ND value is less than or equal to 0, if it is then it skips ahead to increment the counter
--- I assume it counts this as a hit with no damage, given the counter is increased but nothing is added to damage taken by the target

- if the ND value is greater than 0, it then holds on to this value, and separately multiplies this value by armorDR+ammoDRM
--- ND1 and ND2=ND1*armorDR+ammoDRM

- it then divides ND2 by 100
--- this is meant to cause armorDR+ammoDRM to be used as a percentage of damage resisted
--- unfortunately, again there is no rounding, any decimal value (remainder) is dropped after division

- it then subtracts ND2 from ND1
--- ND=ND1-ND2

- it then checks if ND the new ND value is less than or equal to 0, if it is then it skips ahead
--- I assume it counts this as a hit with no damage, given the counter is increased but nothing is added to damage taken by the target

- if the ND value is greater than 0, it then adds that value to the total damage the target will take

- it then increments the counter
--- this is where it skips ahead to if at the checks mentioned previously damage was 0 or less

- it then compares the counter value to the number of hits the target critter was going to take, if the counter value is less than the number of hits it loops back and starts again

- if the counter is equal to the number of hits then the damage calculation for that specific target critter is complete

Based on what I know of the original damage calculation I believe there are several major flaws:
1- Division is not using decimals or rounding numbers
2- The critical multiplier is applied too early in my opinion; how does one score a critical hit if it's unknown whether the hit got through the target's armor damage threshold or got past the target's armor damage resistance yet?
3- The ammo multiplier is applied incorrectly in my opinion; first, multiplying the damage value directly implies that the ammo itself somehow increases the min.-max. damage potential of the weapon (I disagree with this) and second, how is damage multiplied if it's unknown whether the hit got through the target's armor damage threshold or got past the target's armor damage resistance yet?
4- The ammo divisor is applied incorrectly in my opinion; dividing the damage by the ammo divisor only reduces the damage, why would anything about ammo be designed to reduce damage?
5- The difficulty setting is applied too early in my opinion; again, how do you apply something that is to either make the damage more or less if it's unknown whether you got by the target's armor yet?

Here's how I approached each of the flaws:
1- I have removed division; instead I applied division by using subtraction in a loop, tracking the number of times through the loop (the quotient) and the remainder, I use the remainder to determine if the quotient should be rounded up (quotient+1)
2- The critical multiplier (CM) is only applied after it is determined that the hit got through the target's armor
--- how else can a hit be considered critical unless it got past armor to hurt a supposedly sensitive spot on the target
3- The ammo multiplier (X) to me seemed out of place, so I compared all the ammo in the game
--- it seemed that JHP ammo was the one (for the most part) which had an X value greater than 1
--- so knowing JHP, was not designed to penetrate armor but rather when it did to fragment and cause more damage, I chose to use X to reduce the target's armor damage resistance
4- The ammo divisor (Y) to me seemed again out of place, so again I compared all the ammo in the game
--- it semed that AP ammo was the one (for the most part) which had a Y value greater than 1
--- so knowing AP, was designed to penetrate armor but not fragment, I chose to use Y to reduce the target's armor damage threshold
5- The combat difficulty setting (CD) felt wrong to apply like CM, if Easy or Hard were selected
--- so I looked at treating it as a decrease or increase to the target's armor damage resistence value, -20 for Easy and +20 for Hard
--- I tested a similiar decrease or increase to the target's armor damage threshold, and it had no meaningful affect

Some consequences and realizations to my approach:
1- Some ammo which has X greater than 1 and Y greater than 1, gets both advantages (currently only 2mm EC and 4.7mm caseless)
2- Some of the ammo does not follow the expected X and Y values for it's type (ex. HN AP needler cartridge has X=2 and Y=1, Rocket AP has X=1 and Y=1)
--- I consider this a bug in the ammo
3- After seeing the output of my rough calculation tool, I've come to the following conclusions:
--- the 9mm ammo is bugged, it was not intended to be AP ammo (X=1 and Y=2), it should have been JHP ammo (X=2 and Y=1)
--- the HN AP needler cartridge ammo is bugged, it was not intended to be JHP ammo (X=2 and Y=1), it should have been AP ammo (X=1 and Y=2)
--- the Cell ammo (both kinds) is bugged, it does nothing to modify the target's armor values, it should have been like JHP ammo in values (X=2 and Y=1)
--- other ammo that might be considered bugged following the same case as Cell ammo are: .45 Caliber, 9mm ball, 12 gauge shotgun shells, HN Needler cartridge
4- All weapons that use an ammo with X and Y values of 1 and an ammoDRM of 0 have no advantage whatsoever against the target's armor damage threshold and damage resistance (in the original calculation and mine)
--- this is why Laser weapons don't do much damage, its not the weapon, it's the ammo and the fact that most armor in the game have high laser damage resistance
5- I may be close to what the original devs had intended
--- ammo was always meant to affect how the target's armor reacted to a hit, not how it might increase the min.-max. of a weapon's damage potential
6- Ammo values are the biggest factor in whether a weapon is good or not, second is the weapon's min.-max.
7- Ammo, weapons, and armor values need tweaking; to my previous point, ammo more so than anything else

HTML/Javascript rough calculation tool --- http://di.proximitystore.com/newCalculator.html
The rough calculation tool should be straight forward; you pick the ammo type, combat difficulty setting, and/or to have what I think the ammo value could be turned on or off
The min.-max. is set to what is possible for the weapons that use that ammo
(ex. if you pick .223 FMJ, use the weapon reference link and you'll see the .223 pistol has a min.=20 and a max.=30, all values for 20-30 would apply to that weapon)
Choosing "None" for ammo type is the same as unarmed or a melee weapon that is not powered

My damage calculation:
(the following is based on what I've built in HTML/Javascript)

assertions:
1- armor cannot have a negative damage threshold
2- armor cannot have a negative damage resistance
3- ammo cannot add damage resistance
4- in the exe a setting of Easy has CD greater than 100, and Hard less than 100

if armDT is less than 0 then armDT is set to 0
if amY is less than or equal to 0 then amY is set to 1
armDT is divided by amY
ND=RD-armDT
if armDR is less than 0 then armDR is set to 0
if amDRM is greater than 0 then amDRM=0-armDRM
if CD is greater than 100 then CD is set to -20
if CD is less than 100 then CD is set to 20
armDR=armDR+amDRM+CD
if amX is less than or equal to 0 then amX is set to 1
armDR is divided by amX
if armDR is greater than 0 then temp=(ND*armDR)/100, ND=ND-temp
if armDR is less than or equal to 0 then temp=(ND*small bonus percent)/100, ND=ND+temp
if ND is less than 0 then ND=0

(assembly version) if multiple hits it loops back through for each, just as the original did

Here is a link to the script plus ini JimTheDinosaur initially provided and that NovaRain tweaked, which allows you to set your own ammoX, ammoY, ammoDRM, and acM to be used with any damage calculation (original, my mod, or anyone elses) --- http://di.proximitystore.com/Glovz_Fix2.zip (initial values are set to what I think works best with my fix turned on)

Much appreciated Jim and NovaRain!

EDIT:
The new version is still DamageFormula=1 in the ini file for sfall, but now DamageFormula=2 is the new version plus a small tweak.

I changed the way the critical multiplier is applied in the second version to Critical Damage = Net Damage + (Net Damage * 25% * Critical Multiplier)

I always thought the critical multiplier was a little heavy handed, so this change reduces it bit. Makes things more interesting.

-I'm pretty sure 9mm ball should have some advantage over 9mm (JHP) against armor, with you it's just always inferior (a funny inversion of the original though).

-I like the new 10mmAP/JHP in general, but maybe you could consider making JHP a bit more effective against unarmored and less against armored (right now with an average 10 damage shot against combat armor JHP is still the better choice).

-I'm pretty sure you've insanely overpowered .223 FMJ, a 35 damage shot now actually does more damage against APAII (38, instead of 7 in the original formula).

- I think you've made a mistake with the .44 FMJ/JHP; they do the same amount of damage against unarmored, and for all other scenarios FMJ is far superior. I think you're better off just more or less using the same relative values as AP/JHP.

-Do Gauss Weapons really need further overpowering (it's not that much, but still...)?

-I'm pretty sure 9mm ball should have some advantage over 9mm (JHP) against armor, with you it's just always inferior (a funny inversion of the original though).

-I like the new 10mmAP/JHP in general, but maybe you could consider making JHP a bit more effective against unarmored and less against armored (right now with an average 10 damage shot against combat armor JHP is still the better choice).

-I'm pretty sure you've insanely overpowered .223 FMJ, a 35 damage shot now actually does more damage against APAII (38, instead of 7 in the original formula).

- I think you've made a mistake with the .44 FMJ/JHP; they do the same amount of damage against unarmored, and for all other scenarios FMJ is far superior. I think you're better off just more or less using the same relative values as AP/JHP.

-Do Gauss Weapons really need further overpowering (it's not that much, but still...)?

Rest looks very nice! Good job dude

Click to expand...

Are you reviewing with modified ammo values on or off? I think you're reviewing with it on.

I will take your feedback and tweak the modified ammo values.

But please review how the damage calculation behaves with the original ammo values as well. I'm hoping my change improves the game without modifying the ammo and later with your help and/or others, through tweaking ammo, weapons, and armor, possibly improve balance.

Couple more comments (sorry I don't comment on the formula in general, but I think any potential problems with it are best found by just going through examples):

- You did something weird with rockets, explosive (non-ap) rockets now occasionally do more than three times the damage against maximum armored opponents than in the original. The formula for ap rockets seems good (only now it's always inferior to explosive rockets).

-You did the same weird inversion as with 9mm with the needler cartridges: instead of AP being overpowered, you overpowered the regular one (the regular one has the same armor piercing value as the AP one, namely -10, maybe you meant 10?)

-Did flamethrower fuel really need this much powering up? Never used it that much myself, but going on a damage of 60 from 13 against APAII to 43 seems pretty drastic. Also, this might expose a small problem with your formula, because Flamethrower fuel mark II, despite having -15 DM added, does the exact same damage, namely 43, in this scenario).

-Doubling up microfusion cell damage? Is that a good idea? A max turbo plasma rifle hit of 70 now does 77 against APAII instead of 21. What's your reason for that?

Still, I think in general it looks like a good formula and that the issues I have with it can be tweaked with different DM values. Again, good stuff!

Are you reviewing with modified ammo values on or off? I think you're reviewing with it on.

Click to expand...

On.

But please review how the damage calculation behaves with the original ammo values as well.

Click to expand...

What do you mean exactly? When I use the modification on setting it already compares it with the original formula. Or did you mean compare it with your own original formula?

Click to expand...

The chart on the left is the original damage calculation using the original ammo values (always) and the chart on the right is my change to the damage calculation using either the the original ammo values or the modified ammo values.

I know I haven't explained the exact workings of my change yet, but do compare the outputs. I want opinions on whether it feels under powered or overpowered, but taking into consideration the original calculations flaws it should be understood weapons using JHP ammo were originally overpowered and weapons using AP ammo and/or X=1, Y=1, ammoDRM=0 ammo was underpowered.

Even without modifying the ammo values I think I've taking the calculation in the right direction but there is always room for improvement.

EDIT:
Found a couple of small bugs in my javascript code - I updated the file - the output makes more sense now.

Couple more comments (sorry I don't comment on the formula in general, but I think any potential problems with it are best found by just going through examples):

- You did something weird with rockets, explosive (non-ap) rockets now occasionally do more than three times the damage against maximum armored opponents than in the original. The formula for ap rockets seems good (only now it's always inferior to explosive rockets).

-You did the same weird inversion as with 9mm with the needler cartridges: instead of AP being overpowered, you overpowered the regular one (the regular one has the same armor piercing value as the AP one, namely -10, maybe you meant 10?)

-Did flamethrower fuel really need this much powering up? Never used it that much myself, but going on a damage of 60 from 13 against APAII to 43 seems pretty drastic. Also, this might expose a small problem with your formula, because Flamethrower fuel mark II, despite having -15 DM added, does the exact same damage, namely 43, in this scenario).

-Doubling up microfusion cell damage? Is that a good idea? A max turbo plasma rifle hit of 70 now does 77 against APAII instead of 21. What's your reason for that?

Still, I think in general it looks like a good formula and that the issues I have with it can be tweaked with different DM values. Again, good stuff!

I will now be working on documenting and producing this calculator in assembly to be added to sfall.

I also did some digging where I went wrong with my previous version; besides not realizing the division was not using decimals, I messed up when the calculation should have started. This was the cause of the zero values.

The version I'm producing now takes into account misunderstandings of the assembly code I had before; so there should be no logic issues, and I've triple checked the math to be sure division by subtraction is done correctly.

When reviewing the output of the prototype, please remember that without the modded ammo values selected to be on, the output for damage will still be somewhat unbalanced.

EDIT:
I have now updated the first post with a description my new calculation

jle = jump if the value is less than or equal to what it is being compared to

at the point you are asking about its checking that the value of the 'number of hits' to zero, if the number of hits is zero (or less somehow) then there is no need to calculate anything

the other chunk of code you are looking at is to subtract the amount of damage the target's armor resisted from the overall possible damage amount to end up with the net damage amount, the amount of damage the target will actually take

also remember you are looking at some division by subtraction there and it will/does look funky - even to me

EDIT:
Sorry - forget to address the last part

the reason the code looks like it repeats itself a lot is because; first I don't know how to create functions that can be called with sfall, second assembly is a really simple language and doesn't allow for calling and jumping back to when you been when where you been is different from the previous time the call was made (a little confusing but I don't have a better way to describe it)

ok - I updated again - this is just a guess but maybe "begin" is a reserved word, so I changed that - but if it's choking on jle then it's possible the cmp command when comparing a value to 0 is no good for the compiler and that should not be the case

if it is then then I have to change all the lines that compare a value to 0 to the test command, which will do the same thing but again should not be needed