From 2ee09b92102cbff5e4ea7b8557920a57af8dffe1 Mon Sep 17 00:00:00 2001 From: copperwater Date: Thu, 7 Dec 2017 23:26:17 -0500 Subject: [PATCH] Player can now displace peaceful monsters 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 | 2 +- src/hack.c | 41 +++++++++++++++++++++-------------------- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/include/display.h b/include/display.h index 4fd7b9915..aa6af465f 100644 --- a/include/display.h +++ b/include/display.h @@ -128,7 +128,7 @@ * 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) /* diff --git a/src/hack.c b/src/hack.c index 49a8fef7e..0230e79d5 100644 --- a/src/hack.c +++ b/src/hack.c @@ -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 */ -- 2.50.1