]> granicus.if.org Git - nethack/commitdiff
Wielding Giantslayer prevents knockback from monsters
authorPasi Kallinen <paxed@alt.org>
Wed, 20 Jul 2022 11:44:15 +0000 (14:44 +0300)
committerPasi Kallinen <paxed@alt.org>
Wed, 20 Jul 2022 11:44:15 +0000 (14:44 +0300)
doc/fixes3-7-0.txt
src/uhitm.c

index 3fcb7fd55b28bea36c02c5d5865ecd7630f0c9b1..68feecfc765972b38431d1f020745a4ab9e3dcbc 100644 (file)
@@ -974,6 +974,7 @@ bigroom variant 2 may have ice floor in unlit areas
 some large monsters can knock back smaller monsters with a hit
 change Demonbane to a mace, make it the first sac gift for priests,
        and give it an invoke ability to banish demons
+wielding Giantslayer prevents knockback from larger monsters
 
 
 Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
index a021206e6eadd9ac0f641d35621d0efaac12b8bb..9a6036bf6bb0271891a9ee9411f1e68c679a21cc 100644 (file)
@@ -22,6 +22,7 @@ static boolean m_slips_free(struct monst *, struct attack *);
 static void start_engulf(struct monst *);
 static void end_engulf(void);
 static int gulpum(struct monst *, struct attack *);
+static boolean m_is_steadfast(struct monst *);
 static boolean hmonas(struct monst *);
 static void nohandglow(struct monst *);
 static boolean mhurtle_to_doom(struct monst *, int, struct permonst **);
@@ -4551,6 +4552,22 @@ missum(struct monst *mdef, struct attack *mattk, boolean wouldhavehit)
         wakeup(mdef, TRUE);
 }
 
+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_u && (is_flyer(mtmp->data) || is_floater(mtmp->data))))
+        return FALSE;
+
+    if (otmp && otmp->oartifact == ART_GIANTSLAYER)
+        return TRUE;
+    return FALSE;
+}
+
 /* monster hits another monster hard enough to knock it back? */
 boolean
 mhitm_knockback(struct monst *magr,
@@ -4588,6 +4605,10 @@ mhitm_knockback(struct monst *magr,
     if ((u_agr || u_def) && !(*hitflags & MM_HIT))
         return FALSE;
 
+    /* steadfast defender cannot be pushed around */
+    if (m_is_steadfast(mdef))
+        return FALSE;
+
     /* give the message */
     if (u_def || canseemon(mdef)) {
         boolean dosteed = u_def && u.usteed;