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.
This commit is contained in:
copperwater
2017-12-07 23:26:17 -05:00
committed by Pasi Kallinen
parent 7efe7b05df
commit 2ee09b9210
2 changed files with 22 additions and 21 deletions

View File

@@ -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)
/*

View 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 */