Addressing bug with the use of static dieroll in uhitm.c.

This commit is contained in:
Bart House
2017-09-24 23:24:36 -07:00
committed by Pasi Kallinen
parent d51f74a507
commit 78756c9bd6
5 changed files with 43 additions and 27 deletions

View File

@@ -2459,7 +2459,7 @@ E void FDECL(check_caitiff, (struct monst *));
E int FDECL(find_roll_to_hit,
(struct monst *, UCHAR_P, struct obj *, int *, int *));
E boolean FDECL(attack, (struct monst *));
E boolean FDECL(hmon, (struct monst *, struct obj *, int));
E boolean FDECL(hmon, (struct monst *, struct obj *, int, int));
E int FDECL(damageum, (struct monst *, struct attack *));
E void FDECL(missum, (struct monst *, struct attack *, BOOLEAN_P));
E int FDECL(passive, (struct monst *, BOOLEAN_P, int, UCHAR_P, BOOLEAN_P));

View File

@@ -610,11 +610,13 @@ drag:
You("are jerked back by the iron ball!");
if ((victim = m_at(uchain->ox, uchain->oy)) != 0) {
int tmp;
int dieroll = rnd(20);
tmp = -2 + Luck + find_mac(victim);
tmp += omon_adj(victim, uball, TRUE);
if (tmp >= rnd(20))
(void) hmon(victim, uball, HMON_DRAGGED);
if (tmp >= dieroll)
(void) hmon(victim, uball, HMON_DRAGGED, dieroll);
else
miss(xname(uball), victim);

View File

@@ -158,7 +158,8 @@ const char *verb;
(mtmp) ? "" : " with you");
if (mtmp) {
if (!passes_walls(mtmp->data) && !throws_rocks(mtmp->data)) {
if (hmon(mtmp, obj, TRUE) && !is_whirly(mtmp->data))
int dieroll = rnd(20);
if (hmon(mtmp, obj, TRUE, dieroll) && !is_whirly(mtmp->data))
return FALSE; /* still alive */
}
mtmp->mtrapped = 0;

View File

@@ -1386,6 +1386,7 @@ register struct obj *obj; /* thrownobj or kickedobj or uwep */
register int disttmp; /* distance modifier */
int otyp = obj->otyp, hmode;
boolean guaranteed_hit = (u.uswallow && mon == u.ustuck);
int dieroll;
hmode = (obj == uwep) ? HMON_APPLIED
: (obj == kickedobj) ? HMON_KICKED
@@ -1493,6 +1494,8 @@ register struct obj *obj; /* thrownobj or kickedobj or uwep */
return 0;
}
dieroll = rnd(20);
if (obj->oclass == WEAPON_CLASS || is_weptool(obj)
|| obj->oclass == GEM_CLASS) {
if (hmode == HMON_KICKED) {
@@ -1533,13 +1536,13 @@ register struct obj *obj; /* thrownobj or kickedobj or uwep */
tmp += weapon_hit_bonus(obj);
}
if (tmp >= rnd(20)) {
if (tmp >= dieroll) {
boolean wasthrown = (thrownobj != 0);
/* attack hits mon */
if (hmode == HMON_APPLIED)
u.uconduct.weaphit++;
if (hmon(mon, obj, hmode)) { /* mon still alive */
if (hmon(mon, obj, hmode, dieroll)) { /* mon still alive */
cutworm(mon, bhitpos.x, bhitpos.y, obj);
}
exercise(A_DEX, TRUE);
@@ -1585,11 +1588,11 @@ register struct obj *obj; /* thrownobj or kickedobj or uwep */
} else if (otyp == HEAVY_IRON_BALL) {
exercise(A_STR, TRUE);
if (tmp >= rnd(20)) {
if (tmp >= dieroll) {
int was_swallowed = guaranteed_hit;
exercise(A_DEX, TRUE);
if (!hmon(mon, obj, hmode)) { /* mon killed */
if (!hmon(mon, obj, hmode, dieroll)) { /* mon killed */
if (was_swallowed && !u.uswallow && obj == uball)
return 1; /* already did placebc() */
}
@@ -1599,9 +1602,9 @@ register struct obj *obj; /* thrownobj or kickedobj or uwep */
} else if (otyp == BOULDER) {
exercise(A_STR, TRUE);
if (tmp >= rnd(20)) {
if (tmp >= dieroll) {
exercise(A_DEX, TRUE);
(void) hmon(mon, obj, hmode);
(void) hmon(mon, obj, hmode, dieroll);
} else {
tmiss(obj, mon, TRUE);
}
@@ -1609,7 +1612,7 @@ register struct obj *obj; /* thrownobj or kickedobj or uwep */
} else if ((otyp == EGG || otyp == CREAM_PIE || otyp == BLINDING_VENOM
|| otyp == ACID_VENOM)
&& (guaranteed_hit || ACURR(A_DEX) > rnd(25))) {
(void) hmon(mon, obj, hmode);
(void) hmon(mon, obj, hmode, dieroll);
return 1; /* hmon used it up */
} else if (obj->oclass == POTION_CLASS

View File

@@ -5,11 +5,12 @@
#include "hack.h"
STATIC_DCL boolean FDECL(known_hitum, (struct monst *, struct obj *, int *,
int, int, struct attack *));
int, int, struct attack *, int));
STATIC_DCL boolean FDECL(theft_petrifies, (struct obj *));
STATIC_DCL void FDECL(steal_it, (struct monst *, struct attack *));
STATIC_DCL boolean FDECL(hitum, (struct monst *, struct attack *));
STATIC_DCL boolean FDECL(hmon_hitmon, (struct monst *, struct obj *, int));
STATIC_DCL boolean FDECL(hmon_hitmon, (struct monst *, struct obj *, int,
int));
STATIC_DCL int FDECL(joust, (struct monst *, struct obj *));
STATIC_DCL void NDECL(demonpet);
STATIC_DCL boolean FDECL(m_slips_free, (struct monst * mtmp,
@@ -23,8 +24,7 @@ STATIC_DCL void FDECL(nohandglow, (struct monst *));
STATIC_DCL boolean FDECL(shade_aware, (struct obj *));
extern boolean notonhead; /* for long worms */
/* The below might become a parameter instead if we use it a lot */
static int dieroll;
/* Used to flag attacks caused by Stormbringer's maliciousness. */
static boolean override_confirmation = FALSE;
@@ -434,12 +434,13 @@ atk_done:
/* really hit target monster; returns TRUE if it still lives */
STATIC_OVL boolean
known_hitum(mon, weapon, mhit, rollneeded, armorpenalty, uattk)
known_hitum(mon, weapon, mhit, rollneeded, armorpenalty, uattk, dieroll)
register struct monst *mon;
struct obj *weapon;
int *mhit;
int rollneeded, armorpenalty; /* for monks */
struct attack *uattk;
int dieroll;
{
register boolean malive = TRUE;
@@ -463,7 +464,7 @@ struct attack *uattk;
/* we hit the monster; be careful: it might die or
be knocked into a different location */
notonhead = (mon->mx != x || mon->my != y);
malive = hmon(mon, weapon, HMON_MELEE);
malive = hmon(mon, weapon, HMON_MELEE, dieroll);
if (malive) {
/* monster still alive */
if (!rn2(25) && mon->mhp < mon->mhpmax / 2
@@ -499,19 +500,22 @@ struct attack *uattk;
int armorpenalty, attknum = 0, x = u.ux + u.dx, y = u.uy + u.dy,
tmp = find_roll_to_hit(mon, uattk->aatyp, uwep,
&attknum, &armorpenalty);
int mhit = (tmp > (dieroll = rnd(20)) || u.uswallow);
int dieroll = rnd(20);
int mhit = (tmp > dieroll || u.uswallow);
if (tmp > dieroll)
exercise(A_DEX, TRUE);
malive = known_hitum(mon, uwep, &mhit, tmp, armorpenalty, uattk);
malive = known_hitum(mon, uwep, &mhit, tmp, armorpenalty, uattk, dieroll);
/* second attack for two-weapon combat; won't occur if Stormbringer
overrode confirmation (assumes Stormbringer is primary weapon)
or if the monster was killed or knocked to different location */
if (u.twoweap && !override_confirmation && malive && m_at(x, y) == mon) {
tmp = find_roll_to_hit(mon, uattk->aatyp, uswapwep, &attknum,
&armorpenalty);
mhit = (tmp > (dieroll = rnd(20)) || u.uswallow);
malive = known_hitum(mon, uswapwep, &mhit, tmp, armorpenalty, uattk);
dieroll = rnd(20);
mhit = (tmp > dieroll || u.uswallow);
malive = known_hitum(mon, uswapwep, &mhit, tmp, armorpenalty, uattk,
dieroll);
}
if (wepbefore && !uwep)
wep_was_destroyed = TRUE;
@@ -521,16 +525,17 @@ struct attack *uattk;
/* general "damage monster" routine; return True if mon still alive */
boolean
hmon(mon, obj, thrown)
hmon(mon, obj, thrown, dieroll)
struct monst *mon;
struct obj *obj;
int thrown; /* HMON_xxx (0 => hand-to-hand, other => ranged) */
int dieroll;
{
boolean result, anger_guards;
anger_guards = (mon->mpeaceful
&& (mon->ispriest || mon->isshk || is_watch(mon->data)));
result = hmon_hitmon(mon, obj, thrown);
result = hmon_hitmon(mon, obj, thrown, dieroll);
if (mon->ispriest && !rn2(2))
ghod_hitsu(mon);
if (anger_guards)
@@ -540,10 +545,11 @@ int thrown; /* HMON_xxx (0 => hand-to-hand, other => ranged) */
/* guts of hmon() */
STATIC_OVL boolean
hmon_hitmon(mon, obj, thrown)
hmon_hitmon(mon, obj, thrown, dieroll)
struct monst *mon;
struct obj *obj;
int thrown; /* HMON_xxx (0 => hand-to-hand, other => ranged) */
int dieroll;
{
int tmp;
struct permonst *mdat = mon->data;
@@ -2115,6 +2121,7 @@ register struct monst *mon;
struct obj *weapon;
boolean altwep = FALSE, weapon_used = FALSE;
int i, tmp, armorpenalty, sum[NATTK], nsum = 0, dhit = 0, attknum = 0;
int dieroll;
for (i = 0; i < NATTK; i++) {
sum[i] = 0;
@@ -2138,9 +2145,11 @@ register struct monst *mon;
altwep = !altwep; /* toggle for next attack */
tmp = find_roll_to_hit(mon, AT_WEAP, weapon, &attknum,
&armorpenalty);
dhit = (tmp > (dieroll = rnd(20)) || u.uswallow);
dieroll = rnd(20);
dhit = (tmp > dieroll || u.uswallow);
/* Enemy dead, before any special abilities used */
if (!known_hitum(mon, weapon, &dhit, tmp, armorpenalty, mattk)) {
if (!known_hitum(mon, weapon, &dhit, tmp, armorpenalty, mattk,
dieroll)) {
sum[i] = 2;
break;
} else
@@ -2169,7 +2178,8 @@ register struct monst *mon;
case AT_TENT:
tmp = find_roll_to_hit(mon, mattk->aatyp, (struct obj *) 0,
&attknum, &armorpenalty);
dhit = (tmp > (dieroll = rnd(20)) || u.uswallow);
dieroll = rnd(20);
dhit = (tmp > dieroll || u.uswallow);
if (dhit) {
int compat;