Skip to content

Commit

Permalink
Fix xv to hit % when wielding sniper, and always bypass shield
Browse files Browse the repository at this point in the history
Recent to hit changes introduced a bug when hit
chance is AUTOMATIC_HIT causing the % to hit to
display as 1%.

While fixing this I noticed there is a very tiny (but still
non-zero) chance for AUTOMATIC_HIT attacks to
be blocked by a shield. Since this is either unexpected
or should be rather more significant, it seems
easiest to just bypass shield checks as well for
something like Sniper.
  • Loading branch information
chucksellick committed Sep 28, 2024
1 parent ec18552 commit 7cc9653
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 11 deletions.
2 changes: 1 addition & 1 deletion crawl-ref/source/attack.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1098,7 +1098,7 @@ int attack::apply_defender_ac(int damage, int damage_max, ac_type ac_rule) const
*/
bool attack::attack_shield_blocked(bool verbose)
{
if (defender == attacker)
if (defender == attacker || to_hit >= AUTOMATIC_HIT)
return false; // You can't block your own attacks!

// Divine Shield blocks are guaranteed, no matter what.
Expand Down
18 changes: 8 additions & 10 deletions crawl-ref/source/fight.cc
Original file line number Diff line number Diff line change
Expand Up @@ -89,18 +89,12 @@ int aux_to_hit()

}

static double _to_hit_to_land(attack &atk)
{
int to_land = atk.calc_pre_roll_to_hit(false);
if (to_land >= AUTOMATIC_HIT)
return 1;

return to_land;
}

static double _to_hit_hit_chance(const monster_info& mi, attack &atk, bool melee,
int to_land, bool is_aux = false)
{
if (to_land >= AUTOMATIC_HIT)
return 1.0;

const double AUTO_MISS_CHANCE = is_aux ? 0 : 2.5;
const double AUTO_HIT_CHANCE = is_aux ? 3.3333 : 2.5;

Expand Down Expand Up @@ -156,6 +150,10 @@ static double _to_hit_shield_chance(const monster_info& mi,
// Duplicates more logic that is defined in attack::attack_shield_blocked, and
// attack_melee and attack_ranged classes, for real attacks.

// Guaranteed hits should ignore the shield as well
if (to_land >= AUTOMATIC_HIT)
return 0;

// Attack first checks for incapacitation, this is handled with a shield bonus
// of -100 (or if they have no shield) so we can resolve this here.
if (mi.shield_bonus == -100)
Expand Down Expand Up @@ -187,7 +185,7 @@ static double _to_hit_shield_chance(const monster_info& mi,
int to_hit_pct(const monster_info& mi, attack &atk, bool melee,
bool penetrating, int distance)
{
const int to_land = _to_hit_to_land(atk);
const int to_land = atk.calc_pre_roll_to_hit(false);
const double hit_chance = _to_hit_hit_chance(mi, atk, melee, to_land);
const double shield_chance = _to_hit_shield_chance(mi, melee, to_land, penetrating);
const int blind_miss_chance = player_blind_miss_chance(distance);
Expand Down

0 comments on commit 7cc9653

Please sign in to comment.