-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
item: improve the calculation and display of DPS #39362
Conversation
7e6c874
to
917f9e1
Compare
If there are now two things to be kept in sync, can we have a unit test to verify that they are in sync? We already have unit tests which involve creating a monster and having it fight the avatar (which I would hope was the hard part) and can provide some inspiration. |
I'll look into that after I get the existing test cases to pass. |
917f9e1
to
8b5731a
Compare
base_hit *= std::max( 0.25f, 1.0f - guy.encumb( bp_torso ) / 100.0f ); | ||
float mon_defense = mon_dodge + mon.size_melee_penalty(); | ||
double num_hits = 0; | ||
constexpr double hit_trials = 1000.0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like hit_trials
ought to be an integer type, but it's not a big problem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Legacy of the original implementation, but I don't think it matters either.
src/item.cpp
Outdated
} | ||
info.push_back( iteminfo( "BASE", _( "Damage per second: " ), "", | ||
iteminfo::is_decimal, dps ) ); | ||
info.emplace_back( "BASE", _( "Typical damage per second: " ), "" ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you can find a succinct way to express it, I think it would help avoid confusion to clarify that these values are:
- Specific to current circumstances (e.g. encumbrance, temporary stat changes) and thus only meaningful if the avatar is currently in a "combat-ready state".
- Random, and thus likely to differ slightly on each observation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to express that in the help file. There's not enough space in the info planel to put in a long explanation and caveats.
d7a46c0
to
e0c5dc5
Compare
Calculate and display typical damage per second values based on the avatar's actual stats and encumbrance, factoring in misses, critical hits, and the effects of armor. Display typical DPS in the best case scenario (against an debug monster with no armor or dodge), against agile targets (a smoker zombie with no armor but Dodge 7), and against armored targets (a soldier zombie with bash resistance 20 and cut resistance 25). Fix a bug in tests/player_helpers.cpp where clear_avatar() is not guaranteed to result in all stats being 8. Update the help file to reflect these changes.
e0c5dc5
to
526fe21
Compare
Summary
SUMMARY: Interface "item: improve the calculation and display of DPS"
Purpose of change
The current DPS value displayed in item info is extremely misleading: it is technically a raw damage per second and doesn't account for misses, weapon speed, user encumbrance, user stats, user skill, critical hits, or the defenses of potential targets. This makes it difficult to compare weapons with widely different stats, such as a trench knife (acc +1, 83 moves/attack, 14 pierce damage) and a sledgehammer (acc +0, 180 moves/attack, 40 bash damage). The knife does 14 damage every 83 moves and the sledgehammer does 40 damage every 180 moves, and that works out to DPS 19 versus DP 22, but the knife hits more often and is stopped by thinner armor.
Display typical damage per second values instead, based on simulated attacks against some reference monsters and accounting for missed strikes, critical hits, and armor.
Also, the help file for items is very out of date, so bring parts of it up to reflect the post 0.E game.
This also lays the ground work for improved NPC evaluation of weapons.
Describe the solution
Calculate and display typical damage per second values based on the avatar's actual stats and encumbrance, factoring in misses, critical hits, and the effects of armor. Display typical DPS in the best case scenario (against an debug monster with no armor or dodge), against agile targets (a smoker zombie with no armor but Dodge 7), and against armored targets (a soldier zombie with bash resistance 20 and cut resistance 25).
Update the help file to reflect these changes.
Describe alternatives you've considered
This adds a stripped down version of the combat calculations, which means there are two things that need to be kept in sync now. I considered spawning a fake NPC and making it fake fight a sample monster through 1000 attacks and recording the results, but there are a lot of problems with that solution.
To hit rolls are a normal distribution, and there's no easy way to convert the input values of CDDA's normal rng function to a percentage success that I am aware of.
I used a quick monte carlo simulation to get the values, but number of hits varied by +/- 5% in my testing. I'd use a better solution if I knew of one.The need to get consistent values for unit test cases means the monte carlo simulation was abandoned in favor of a look-up table.I considered caching the results of the monte carlo simulation but didn't do it at this time; it'd be fairly straightforward to add if people think that is worthwhile.The initial implementation displayed the results against the survivor zombie and the average of the scores, but that was rejected because it made things too cluttered.
Other reference monsters could be used, but the soldier zombie and the smoker zombie are familiar to most players.
Testing
Loaded a game and looked at a variety of weapons, modifying my character to have different stats.
Additional context
This is the new melee information display.