CleverRaven / Cataclysm-DDA

Cataclysm - Dark Days Ahead. A turn-based survival game set in a post-apocalyptic world.
http://cataclysmdda.org
Other
10.23k stars 4.11k forks source link

Invalid melee resistance #12459

Closed seerdecker closed 9 years ago

seerdecker commented 9 years ago

Reading the code, I believe I stumbled on a bug related to melee + resistances. Consider this code path: roll_bash_damage(), add_damage(), get_effective_resist(). I've pasted the relevant code below, explanation follows.

void player::roll_bash_damage( bool crit, damage_instance &di )
{
    float percentage_arpen = 0.0f;
    // Finally, extra crit effects
    if( crit ) {
        bash_dam += int(stat / 2);
        bash_dam += skill;
        bash_mul *= 1.5;
        // 50% arpen
        percentage_arpen = 0.5f;
    }

    di.add_damage( DT_BASH, bash_dam, 0, percentage_arpen, bash_mul );
}

void damage_instance::add_damage( damage_type dt, float a, int rp, float rm, float mul )
{
    damage_unit du( dt, a, rp, rm, mul );
    damage_units.push_back( du );
}

damage_unit(damage_type dt, float a, int rp, float rm, float mul) :
    type(dt), amount(a), res_pen(rp), res_mult(rm), damage_multiplier(mul) {}

float resistances::get_effective_resist( const damage_unit &du ) const
{
    float effective_resist = 0.f;
    switch( du.type ) {
        case DT_BASH:
            effective_resist = std::max( type_resist( DT_BASH ) - du.res_pen, 0 ) * du.res_mult;
}

The resistance code expects res_mult to be 1.0 if there is no resistance penetration. The bash roll code assumes the reverse -- it sets res_mult to 0 unless there is a critical hit, in which case res_mult becomes 0.5. The same bug is present for all three roll functions (bash, cut, stab). I've traced with printf() and the rest of the code seems to be sane, as I'm getting 1.0 res_mult values presumably coming from monster attacks.

When attacking with melee (my printf): Roll Bash with amount 4 rm 0.000000. Adding damage type 3 amount 4.000000 rp 0 rm 0.000000. Applying resistance rp 0 rm 0.000000 result 0.000000.

Other damage getting processed (my printf): Adding damage type 3 amount 3.000000 rp 0 rm 1.000000. Applying resistance rp 0 rm 1.000000 result 14.000000.

Suggested patch: fix the roll functions by setting effective_resist 1.0f and subtracting instead of adding for the critical hits.

Thanks for the game.

BevapDin commented 9 years ago

If you put your code between ```, it will be formated nicely:

some code 

Becomes:

some code 
seerdecker commented 9 years ago

Thanks for the tip BevapDin. I've edited the post.