Consistent rounding rules create oddities between (damage done) and (current HP) reports.
FewerFlaws opened this issue ยท 8 comments
Another mod I use had a weapon doing half points of damage. This caused an oddity in Toro.
For example, if a 10hp mob takes 1.5 damage its current hp will be 8.5hp. Toro will round both numbers up to show 2 damage done and 9 current hp on the mob. Seeing this left me wondering why a 2 damage attack reduced the mob's health by 1.
Changing the rounding rules or how the damage report works could improve general compatibility with mods.
Here's the other mod I'm referencing: Globox1997/MedievalWeapons#3
Alternatively, adding a config option to change number formatting such that decimal values are shown might be appropriate.
I will give this some thought next when working on the next release. I am assuming you would prefer to the numbers rounded to the nearest 10th?
I would be happy with tenths, yes.
That being said, I'm a fan of maintaining the vanilla feel whenever possible. Minecraft doesn't show decimals. However, I can't come up with a rounding system that produces good results. I think the best possible system would be to report the drop in displayed HP as damage rather than rounding the actual damage done:
- Get the mob's actual health
- Get the mob's rounded health
- Get the actual damage done.
- Subtract the actual damage done from the actual health.
- Get the mob's final rounded health.
- Subtract the mob's final rounded health from former rounded health.
- Report that number as damage done.
This would make the 1.5 damage daggers in my situation alternate between 1 and 2 damage. I'd be happy with that. Others might prefer the tenths. If the algorithm I proposed is used there will be consistency between health displayed and damage done with any number format =]
If I understand correctly, that is pretty close to what it is doing now and should already be working the way you want:
https://github.com/ToroCraft/ToroHealth/blob/master/src/main/java/net/torocraft/torohealth/bars/BarState.java#L36
Since this is a client side mod, we weren't getting the damage event, so we scan the health of nearby entities and detect when it changes. So the damage numbers should add up correctly over time while being incorrect independently. So for example, if you did .5 damage, the first hit would be zero and on the second hit you would see a 1. Well, at least that is what I thought, will have to test it out.
I did some data gathering. Whacking a 220HP skeleton with a dagger doing 4.5 damage per hit I got these results:
- 220
- (-5) 216
- (-5) 211
- (-5) 207
- (-3) 204
- (-5) 199
- (-3) 196
- (-3) 193
- (-5) 189
- (-3) 186
- (-5) 181
- (-5) 177
- (-3) 174
- (-5) 169
- (-3) 166
- (-3) 163
- (-5) 159
- (-5) 154
- (-3) 151
- (-3) 148
- (-5) 144
- (-3) 141
- (-3) 138
- (-3) 135
- (-3) 132
- (-5) 127
- (-5) 123
- (-3) 120
- (-3) 117
- (-5) 112
- (-3) 109
- (-5) 105
- (-3) 102
- (-5) 97
- (-5) 93
- (-3) 90
- (-5) 85
- (-5) 81
- (-3) 78
- (-3) 75
- (-3) 72
- (-3) 69
- (-5) 64
- (-5) 60
- (-3) 57
- (-5) 52
- (-3) 49
- (-3) 46
- (-5) 42
- (-5) 37
- (-5) 33
- (-3) 30
- (-5) 25
- (-5) 21
- (-5) 16
- (-3) 13
- (-5) 9
- (-5) 4
- (-4) Dead
Based on this I think it's pretty clear that my 4.5 damage per hit premise is false (that would've killed the skeleton in 49 hits, but it took 58). That being said, the damage reports sum to 235, which exceeds the skeleton's health by 15. There were exactly 30 reports of 5 damage. It looks to me like every successful sneak attack was rounded up in the damage report, save for the killing blow.
Looking at the code you linked, the easiest way to solve the problem is to change line 36 to this:
lastDmg = ceil(lastHealth) - ceil(entity.getHealth());
According to the code linked below the current HP shown on the health bar is always rounded up. I adjusted the damage report so that it's based on the fall observed in the HP bar.
To be clear, my goal is not to have precision in the damage reports. I don't need to see 4.5 show up every time. My goal is to have no discrepency between the damage reports and the observed drop in hit points.
Just as a further suggestion, if I were in charge of this code I would also do a single call of entity.getHealth() within the whole tick function. That value should be stored then used repeatedly. But it's not my code ^_^
Good stuff, I will try that out. As for the code, it is in need of some clean up, something I might do as well.