From: copperwater Date: Mon, 12 Mar 2018 02:20:32 +0000 (-0400) Subject: Fix: rn2(0) when trying to displace peaceful out of trap X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5a1bbb4d161685cf85f940df74ec222ab30d6fdf;p=nethack Fix: rn2(0) when trying to displace peaceful out of trap A side effect of making is_safepet() count peacefuls. Now checks directly for a trapped, peaceful monster and says "they can't move out of the trap"; this is inconsistent with pet behavior, and pet behavior should probably be changed to be in line with it (ie they can't be displaced out of a trap at all.) Also refactor the code here a bit: a bunch of different if statements have the exact same resetting code and steed resetting code in them. Change this to a boolean flag and put the resetting code in one place checked by that flag. --- diff --git a/src/hack.c b/src/hack.c index 013fc43b0..d88bd9421 100644 --- a/src/hack.c +++ b/src/hack.c @@ -1802,40 +1802,48 @@ domove_core() * be caught by the normal falling-monster code. */ if (is_safepet(mtmp) && !(is_hider(mtmp->data) && mtmp->mundetected)) { + /* if it turns out we can't actually move */ + boolean didnt_move = FALSE; + + /* 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); + 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) && sobj_at(BOULDER, trap->tx, trap->ty)) { /* can't swap places with pet pinned in a pit by a boulder */ - u.ux = u.ux0, u.uy = u.uy0; /* didn't move after all */ - if (u.usteed) - u.usteed->mx = u.ux, u.usteed->my = u.uy; + didnt_move = TRUE; } else if (u.ux0 != x && u.uy0 != y && NODIAG(mtmp->data - mons)) { /* can't swap places when pet can't move to your spot */ - u.ux = u.ux0, u.uy = u.uy0; - if (u.usteed) - u.usteed->mx = u.ux, u.usteed->my = u.uy; You("stop. %s can't move diagonally.", upstart(y_monnam(mtmp))); + didnt_move = TRUE; } else if (u_with_boulder && !(verysmall(mtmp->data) && (!mtmp->minvent || (curr_mon_load(mtmp) <= 600)))) { /* can't swap places when pet won't fit there with the boulder */ - u.ux = u.ux0, u.uy = u.uy0; /* didn't move after all */ - if (u.usteed) - u.usteed->mx = u.ux, u.usteed->my = u.uy; You("stop. %s won't fit into the same spot that you're at.", upstart(y_monnam(mtmp))); + didnt_move = TRUE; } else if (u.ux0 != x && u.uy0 != y && bad_rock(mtmp->data, x, u.uy0) && bad_rock(mtmp->data, u.ux0, y) && (bigmonst(mtmp->data) || (curr_mon_load(mtmp) > 600))) { /* can't swap places when pet won't fit thru the opening */ - u.ux = u.ux0, u.uy = u.uy0; /* didn't move after all */ - if (u.usteed) - u.usteed->mx = u.ux, u.usteed->my = u.uy; You("stop. %s won't fit through.", upstart(y_monnam(mtmp))); + didnt_move = TRUE; + } else if (mtmp->mpeaceful && !mtmp->mtame && mtmp->mtrapped) { + /* TODO: pets can get angered when displaced out of a trap. + * Having peaceful monsters simply refuse is inconsistent. + * Probably, pets should not be able to be displaced out of a + * trap like a pit or bear trap at all. */ + You("stop. %s can't move out of that trap.", + upstart(y_monnam(mtmp))); + didnt_move = TRUE; } else if (mtmp->mpeaceful && !mtmp->mtame && (!goodpos(u.ux0, u.uy0, mtmp, 0) || t_at(u.ux0, u.uy0) != NULL @@ -1844,9 +1852,9 @@ domove_core() || mtmp->m_id == g.quest_status.leader_m_id)) { /* displacing peaceful into unsafe or trapped space, or trying to * displace quest leader, Oracle, or priest */ - 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))); + didnt_move = TRUE; } else { /* if trapped, there's a chance the pet goes wild */ if (mtmp->mtrapped) { @@ -1916,6 +1924,12 @@ domove_core() break; } } + + if (didnt_move) { + u.ux = u.ux0, u.uy = u.uy0; /* didn't move after all */ + if (u.usteed) + u.usteed->mx = u.ux, u.usteed->my = u.uy; + } } reset_occupations();