]> granicus.if.org Git - nethack/commitdiff
Player can now displace peaceful monsters
authorcopperwater <aosdict@gmail.com>
Fri, 8 Dec 2017 04:26:17 +0000 (23:26 -0500)
committerPasi Kallinen <paxed@alt.org>
Wed, 15 Apr 2020 05:46:47 +0000 (08:46 +0300)
Changes domove() code to allow displacing peaceful monsters.
Specifically, is_safepet() now returns true if the monster is peaceful.
Peacefuls are slightly pickier than pets about whether they consent to
being displaced: they will not displace if a goodpos() check fails for
the displaced space, or if there is a trap on the displaced space, or if
they are your quest leader. is_safepet should probably be renamed to
something else.

In the process of doing this, some other changes were made: the code now
checks whether the player and monster should be swapping places at all
first (previously it ran some code for displacing pets out of traps
first, which was a little weird if the displacement didn't actually
happen.)

In the original commit for this, I needed to guard the spoteffects()
call made in domove with a clause testing whether the player actually
moved; it was previously possible to fail to displace a monster and then
re-trigger a trap on the space you were still standing on. However, the
devteam has apparently put in an if (u.umoved) clause in the same place
and serving the same purpose.

include/display.h
src/hack.c

index 4fd7b99157e76e59591610aa05cafa4b84594c04..aa6af465f8029cc8f5122bb1790831c51efb9300 100644 (file)
  * definition here is convenient.
  */
 #define is_safepet(mon)                                                   \
-    (mon && mon->mtame && canspotmon(mon) && flags.safe_dog && !Confusion \
+    (mon && (mon->mtame || mon->mpeaceful) && canspotmon(mon) && flags.safe_dog && !Confusion \
      && !Hallucination && !Stunned)
 
 /*
index 49a8fef7e45a1b0ced7223bd5e0e26190018b69b..0230e79d5f251152e501181a5a1bc982bfc09456 100644 (file)
@@ -1802,28 +1802,9 @@ domove_core()
      * be caught by the normal falling-monster code.
      */
     if (is_safepet(mtmp) && !(is_hider(mtmp->data) && mtmp->mundetected)) {
-        /* if trapped, there's a chance the pet goes wild */
-        if (mtmp->mtrapped) {
-            if (!rn2(mtmp->mtame)) {
-                mtmp->mtame = mtmp->mpeaceful = mtmp->msleeping = 0;
-                if (mtmp->mleashed)
-                    m_unleash(mtmp, TRUE);
-                growl(mtmp);
-            } else {
-                yelp(mtmp);
-            }
-        }
-
-        /* seemimic/newsym should be done before moving hero, otherwise
-           the display code will draw the hero here before we possibly
-           cancel the swap below (we can ignore steed mx,my here) */
-        u.ux = u.ux0, u.uy = u.uy0;
         mtmp->mundetected = 0;
         if (M_AP_TYPE(mtmp))
             seemimic(mtmp);
-        else if (!mtmp->mtame)
-            newsym(mtmp->mx, mtmp->my);
-        u.ux = mtmp->mx, u.uy = mtmp->my; /* resume swapping positions */
 
         if (mtmp->mtrapped && (trap = t_at(mtmp->mx, mtmp->my)) != 0
             && is_pit(trap->ttyp)
@@ -1855,7 +1836,27 @@ domove_core()
             if (u.usteed)
                 u.usteed->mx = u.ux, u.usteed->my = u.uy;
             You("stop.  %s won't fit through.", upstart(y_monnam(mtmp)));
+        } else if (mtmp->mpeaceful && !mtmp->mtame
+                   && (!goodpos(u.ux0, u.uy0, mtmp, 0)
+                       || t_at(u.ux0, u.uy0) != NULL
+                       || mtmp->m_id == g.quest_status.leader_m_id)) {
+            /* displacing peaceful into unsafe or trapped space, or trying to
+             * displace quest leader */
+            u.ux = u.ux0, u.uy = u.uy0; /* didn't move after all */
+            You("stop.  %s doesn't want to swap places.",
+                upstart(y_monnam(mtmp)));
         } else {
+            /* if trapped, there's a chance the pet goes wild */
+            if (mtmp->mtrapped) {
+                if (!rn2(mtmp->mtame)) {
+                    mtmp->mtame = mtmp->mpeaceful = mtmp->msleeping = 0;
+                    if (mtmp->mleashed)
+                        m_unleash(mtmp, TRUE);
+                    growl(mtmp);
+                } else {
+                    yelp(mtmp);
+                }
+            }
             char pnambuf[BUFSZ];
 
             /* save its current description in case of polymorph */
@@ -1866,7 +1867,7 @@ domove_core()
             newsym(x, y);
             newsym(u.ux0, u.uy0);
 
-            You("%s %s.", mtmp->mtame ? "swap places with" : "frighten",
+            You("%s %s.", mtmp->mpeaceful ? "swap places with" : "frighten",
                 pnambuf);
 
             /* check for displacing it into pools and traps */