]> granicus.if.org Git - nethack/commitdiff
Hit and wake sleeping monster makes it growl
authorPasi Kallinen <paxed@alt.org>
Sat, 21 Jan 2023 14:52:17 +0000 (16:52 +0200)
committerPasi Kallinen <paxed@alt.org>
Sat, 21 Jan 2023 14:52:23 +0000 (16:52 +0200)
Unless you kill the monster with one hit, it'll wake up
cranky and make noise - waking up other sleeping monsters.

This was a bit tricky with all the message sequencing; I tested
all the hit/throw/fire/zap combos I could think of, and it took
a while to get things looking right.

doc/fixes3-7-0.txt
include/extern.h
src/dokick.c
src/dothrow.c
src/explode.c
src/mon.c
src/uhitm.c
src/zap.c

index 6e8864a0fa9a1cada7cd53e7ee87130f763dc763..73479ac16962069b6a22b8ef9cf26a1daa979e0b 100644 (file)
@@ -1089,6 +1089,7 @@ allow setting per-level "temperature": hot, cold, or temperate, currently
        only affects some messages
 digging is noisy
 polymorphing into fire elemental allows you eat flammable items
+hitting sleeping monsters will cause them to wake up noisily
 
 
 Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
index c6370f6a845e5e9a22b2b7fb3c1a5d5e05d07b11..baae091517d8267f1a879c54403eea625e8aaff0 100644 (file)
@@ -2914,7 +2914,7 @@ extern void dynamic_multi_reason(struct monst *, const char *, boolean);
 extern void erode_armor(struct monst *, int);
 extern boolean attack_checks(struct monst *, struct obj *);
 extern void check_caitiff(struct monst *);
-extern void mon_maybe_wakeup_on_hit(struct monst *);
+extern void mon_maybe_unparalyze(struct monst *);
 extern int find_roll_to_hit(struct monst *, uchar, struct obj *, int *, int *);
 extern boolean force_attack(struct monst *, boolean);
 extern boolean do_attack(struct monst *);
@@ -3477,7 +3477,7 @@ extern void dobuzz(int, int, coordxy, coordxy, int, int, boolean);
 extern void melt_ice(coordxy, coordxy, const char *);
 extern void start_melt_ice_timeout(coordxy, coordxy, long);
 extern void melt_ice_away(union any *, long);
-extern int zap_over_floor(coordxy, coordxy, int, boolean *, short);
+extern int zap_over_floor(coordxy, coordxy, int, boolean *, boolean, short);
 extern void fracture_rock(struct obj *);
 extern boolean break_statue(struct obj *);
 extern boolean u_adtyp_resistance_obj(int);
index 2b08f7525df0061151868a66924113a3d41b988b..676764114038f9d67e097f85ce9980a57f929206 100644 (file)
@@ -183,7 +183,7 @@ kick_monster(struct monst *mon, coordxy x, coordxy y)
             attknum = 0,
             tmp = find_roll_to_hit(mon, AT_KICK, (struct obj *) 0, &attknum,
                                    &armorpenalty);
-        mon_maybe_wakeup_on_hit(mon);
+        mon_maybe_unparalyze(mon);
 
         for (i = 0; i < NATTK; i++) {
             /* first of two kicks might have provoked counterattack
index 217f65a24a96bcddf096db860b7c682427e850aa..84b16e09973255df7cc7d22d216ac26ff309b226 100644 (file)
@@ -1830,8 +1830,6 @@ omon_adj(struct monst *mon, struct obj *obj, boolean mon_notices)
     /* sleeping target is more likely to be hit */
     if (mon->msleeping) {
         tmp += 2;
-        if (mon_notices)
-            mon->msleeping = 0;
     }
     /* ditto for immobilized target */
     if (!mon->mcanmove || !mon->data->mmove) {
index 32a146542b4d428df318d8eb2a5a077be30dbee4..204899987f4f8bcd1348fe9aa749d1cf077af762 100644 (file)
@@ -411,7 +411,8 @@ explode(
                  * from inside their engulfer. */
                 if (!(u.uswallow && !gc.context.mon_moving))
                     (void) zap_over_floor(xx, yy, type,
-                                          &shopdamage, exploding_wand_typ);
+                                          &shopdamage, FALSE,
+                                          exploding_wand_typ);
 
                 mtmp = m_at(xx, yy);
                 if (!mtmp && u_at(xx, yy))
index 8736edbe32d1e6389818f4a79512e003d010be2f..279e3dbcbd885390e8cff072fbc96486d44544af 100644 (file)
--- a/src/mon.c
+++ b/src/mon.c
@@ -3789,6 +3789,8 @@ wake_msg(struct monst *mtmp, boolean interesting)
 void
 wakeup(struct monst* mtmp, boolean via_attack)
 {
+    boolean was_sleeping = mtmp->msleeping;
+
     wake_msg(mtmp, via_attack);
     mtmp->msleeping = 0;
     if (M_AP_TYPE(mtmp) != M_AP_NOTHING) {
@@ -3802,8 +3804,15 @@ wakeup(struct monst* mtmp, boolean via_attack)
         newsym(mtmp->mx, mtmp->my);
     }
     finish_meating(mtmp);
-    if (via_attack)
+    if (via_attack) {
+        if (was_sleeping)
+            growl(mtmp);
         setmangry(mtmp, TRUE);
+        if (mtmp->ispriest && *in_rooms(mtmp->mx, mtmp->my, TEMPLE))
+            ghod_hitsu(mtmp);
+        if (mtmp->isshk && !*u.ushops)
+            hot_pursuit(mtmp);
+    }
 }
 
 /* Wake up nearby monsters without angering them. */
index f90a56a7bdf4bb096abe634a10c7a234127652a7..06a20e0cae49a8ebe7a64776729e6b7039f84e6f 100644 (file)
@@ -293,13 +293,10 @@ check_caitiff(struct monst *mtmp)
     }
 }
 
-/* wake up monster, maybe unparalyze it */
+/* maybe unparalyze monster */
 void
-mon_maybe_wakeup_on_hit(struct monst *mtmp)
+mon_maybe_unparalyze(struct monst *mtmp)
 {
-    if (mtmp->msleeping)
-        mtmp->msleeping = 0;
-
     if (!mtmp->mcanmove) {
         if (!rn2(10)) {
             mtmp->mcanmove = 1;
@@ -647,7 +644,7 @@ hitum_cleave(
 
         tmp = find_roll_to_hit(mtmp, uattk->aatyp, uwep,
                                &attknum, &armorpenalty);
-        mon_maybe_wakeup_on_hit(mtmp);
+        mon_maybe_unparalyze(mtmp);
         dieroll = rnd(20);
         mhit = (tmp > dieroll);
         gb.bhitpos.x = tx, gb.bhitpos.y = ty; /* normally set up by
@@ -685,7 +682,7 @@ hitum(struct monst *mon, struct attack *uattk)
         dieroll = rnd(20),
         mhit = (tmp > dieroll || u.uswallow);
 
-    mon_maybe_wakeup_on_hit(mon);
+    mon_maybe_unparalyze(mon);
 
     /* Cleaver attacks three spots, 'mon' and one on either side of 'mon';
        it can't be part of dual-wielding but we guard against that anyway;
@@ -712,7 +709,7 @@ hitum(struct monst *mon, struct attack *uattk)
                        || !malive || m_at(x, y) != mon)) {
         tmp = find_roll_to_hit(mon, uattk->aatyp, uswapwep, &attknum,
                                &armorpenalty);
-        mon_maybe_wakeup_on_hit(mon);
+        mon_maybe_unparalyze(mon);
         dieroll = rnd(20);
         mhit = (tmp > dieroll || u.uswallow);
         malive = known_hitum(mon, uswapwep, &mhit, tmp, armorpenalty, uattk,
@@ -786,7 +783,6 @@ hmon_hitmon(
 
     saved_oname[0] = '\0';
 
-    wakeup(mon, TRUE);
     if (!obj) { /* attack with bare hands */
         long silverhit = 0L; /* armor mask */
 
@@ -816,6 +812,7 @@ hmon_hitmon(
         if ((thrown == HMON_THROWN || thrown == HMON_KICKED) /* not Applied */
             && stone_missile(obj) && passes_rocks(mdat)) {
             hit(mshot_xname(obj), mon, " but does no harm.");
+            wakeup(mon, TRUE);
             return TRUE;
         }
         /* remember obj's name since it might end up being destroyed and
@@ -1510,6 +1507,9 @@ hmon_hitmon(
         Your("%s %s no longer poisoned.", saved_oname,
              vtense(saved_oname, "are"));
 
+    if (!destroyed)
+        wakeup(mon, TRUE);
+
     return destroyed ? FALSE : TRUE;
 }
 
@@ -4854,7 +4854,7 @@ hmonas(struct monst *mon)
 
             tmp = find_roll_to_hit(mon, AT_WEAP, weapon, &attknum,
                                    &armorpenalty);
-            mon_maybe_wakeup_on_hit(mon);
+            mon_maybe_unparalyze(mon);
             dieroll = rnd(20);
             dhit = (tmp > dieroll || u.uswallow);
             /* caller must set gb.bhitpos */
@@ -4896,7 +4896,7 @@ hmonas(struct monst *mon)
         /*weaponless:*/
             tmp = find_roll_to_hit(mon, mattk->aatyp, (struct obj *) 0,
                                    &attknum, &armorpenalty);
-            mon_maybe_wakeup_on_hit(mon);
+            mon_maybe_unparalyze(mon);
             dieroll = rnd(20);
             dhit = (tmp > dieroll || u.uswallow);
             if (dhit) {
@@ -5089,7 +5089,7 @@ hmonas(struct monst *mon)
         case AT_ENGL:
             tmp = find_roll_to_hit(mon, mattk->aatyp, (struct obj *) 0,
                                    &attknum, &armorpenalty);
-            mon_maybe_wakeup_on_hit(mon);
+            mon_maybe_unparalyze(mon);
             if ((dhit = (tmp > rnd(20 + i)))) {
                 wakeup(mon, TRUE);
                 if (mon->data == &mons[PM_SHADE]) {
index 0104280c33cd8215192381b14485480b28d1aa8a..17353df2dee8849adcdb0f75fa6c8aaf196eacc9 100644 (file)
--- a/src/zap.c
+++ b/src/zap.c
@@ -4393,7 +4393,7 @@ dobuzz(
         gb.bhitpos.x = sx, gb.bhitpos.y = sy;
         /* Fireballs only damage when they explode */
         if (type != ZT_SPELL(ZT_FIRE)) {
-            range += zap_over_floor(sx, sy, type, &shopdamage, 0);
+            range += zap_over_floor(sx, sy, type, &shopdamage, 0, TRUE);
             /* zap with fire -> melt ice -> drown monster, so monster
                found and cached above might not be here any more */
             mon = m_at(sx, sy);
@@ -4480,6 +4480,8 @@ dobuzz(
                         }
                         if (mon_could_move && !mon->mcanmove) /* ZT_SLEEP */
                             slept_monst(mon);
+                        if (abstype != ZT_SLEEP)
+                            wakeup(mon, TRUE);
                     }
                 }
                 range -= 2;
@@ -4698,6 +4700,7 @@ zap_over_floor(
     coordxy x, coordxy y,         /* location */
     int type,                 /* damage type plus {wand|spell|breath} info */
     boolean *shopdamage,      /* extra output if shop door is destroyed */
+    boolean ignoremon,        /* ignore any monster here */
     short exploding_wand_typ) /* supplied when breaking a wand; or POT_OIL
                                * when a lit potion of oil explodes */
 {
@@ -5012,16 +5015,8 @@ zap_over_floor(
             newsym(x, y);
             You("%s of smoke.", !Blind ? "see a puff" : "smell a whiff");
         }
-    if ((mon = m_at(x, y)) != 0) {
-        wakeup(mon, FALSE);
-        if (type >= 0) {
-            setmangry(mon, TRUE);
-            if (mon->ispriest && *in_rooms(mon->mx, mon->my, TEMPLE))
-                ghod_hitsu(mon);
-            if (mon->isshk && !*u.ushops)
-                hot_pursuit(mon);
-        }
-    }
+    if (!ignoremon && (mon = m_at(x, y)) != 0)
+        wakeup(mon, (type >= 0) ? TRUE : FALSE);
     return rangemod;
 }