From: PatR Date: Wed, 26 Oct 2022 08:13:01 +0000 (-0700) Subject: more steadfast X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=13fb141ddd7b1b2f0090a92e13b97d958a26c5dd;p=nethack more steadfast Make changes similar to the suggested patch from entrez: support for 'youmonst' as the monster passed to m_carrying(). This doesn't change carrying(otyp) to call m_carrying(&g.youmonst,otyp) though. Also, treat being on the Plane of Air or in an air bubble on the Plane of Water similar to flying or levitating: wielded Giantslayer (or carried loadstone) doesn't prevent knockback there. --- diff --git a/src/invent.c b/src/invent.c index 01794c024..5b2b8638f 100644 --- a/src/invent.c +++ b/src/invent.c @@ -1285,15 +1285,17 @@ nxtobj(struct obj *obj, int type, boolean by_nexthere) return otmp; } +/* return inventory object of type 'type' if hero has one, otherwise Null */ struct obj * carrying(int type) { register struct obj *otmp; + /* this could be replaced by 'return m_carrying(&g.youmonst, type);' */ for (otmp = g.invent; otmp; otmp = otmp->nobj) if (otmp->otyp == type) - return otmp; - return (struct obj *) 0; + break; + return otmp; } /* Fictional and not-so-fictional currencies. diff --git a/src/mthrowu.c b/src/mthrowu.c index d595e37ed..780509528 100644 --- a/src/mthrowu.c +++ b/src/mthrowu.c @@ -1182,22 +1182,23 @@ lined_up(register struct monst* mtmp) return m_lined_up(&g.youmonst, mtmp) ? TRUE : FALSE; } -/* check if a monster is carrying a particular item */ +/* check if a monster is carrying an item of a particular type */ struct obj * -m_carrying(struct monst* mtmp, int type) +m_carrying(struct monst *mtmp, int type) { register struct obj *otmp; - for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj) + for (otmp = (mtmp == &g.youmonst) ? g.invent : mtmp->minvent; otmp; + otmp = otmp->nobj) if (otmp->otyp == type) - return otmp; - return (struct obj *) 0; + break; + return otmp; } void hit_bars( struct obj **objp, /* *objp will be set to NULL if object breaks */ - coordxy objx, coordxy objy, /* hero's spot (when wielded) or missile's spot */ + coordxy objx, coordxy objy, /* hero's (when wielded) or missile's spot */ coordxy barsx, coordxy barsy, /* adjacent spot where bars are located */ unsigned breakflags) /* breakage control */ { diff --git a/src/uhitm.c b/src/uhitm.c index b34797dbf..f5db387c2 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -4611,26 +4611,29 @@ missum( wakeup(mdef, TRUE); } +/* check whether equipment protects against knockback */ static boolean m_is_steadfast(struct monst *mtmp) { boolean is_u = (mtmp == &g.youmonst); struct obj *otmp = is_u ? uwep : MON_WEP(mtmp); - /* must be on the ground */ - if (is_u ? (Flying || Levitation) - : (is_flyer(mtmp->data) || is_floater(mtmp->data))) + /* must be on the ground (or in water) */ + if ((is_u ? (Flying || Levitation) + : (is_flyer(mtmp->data) || is_floater(mtmp->data))) + || Is_airlevel(&u.uz) /* air or cloud */ + || (Is_waterlevel(&u.uz) && !is_pool(u.ux, u.uy))) /* air bubble */ return FALSE; if (is_art(otmp, ART_GIANTSLAYER)) return TRUE; /* steadfast if carrying any loadstone (and not floating or flying); - when mounted and steed is target of knockback, check the rider - for a loadstone too */ - for (otmp = is_u ? g.invent : mtmp->minvent; otmp; otmp = otmp->nobj) - if (otmp->otyp == LOADSTONE) - return TRUE; + 'is_u' test not needed here; m_carrying() is 'youmonst' aware */ + if (m_carrying(mtmp, LOADSTONE)) + return TRUE; + /* when mounted and steed is target of knockback, check the rider for + a loadstone too (Giantslayer's protection doesn't extend to steed) */ if (u.usteed && mtmp == u.usteed && carrying(LOADSTONE)) return TRUE;