Split swapping places with pet code out of domove
This commit is contained in:
+122
-114
@@ -18,6 +18,7 @@ static boolean swim_move_danger(xchar, xchar);
|
|||||||
static boolean domove_bump_mon(struct monst *, int);
|
static boolean domove_bump_mon(struct monst *, int);
|
||||||
static boolean domove_attackmon_at(struct monst *, xchar, xchar, boolean *);
|
static boolean domove_attackmon_at(struct monst *, xchar, xchar, boolean *);
|
||||||
static boolean domove_fight_ironbars(xchar, xchar);
|
static boolean domove_fight_ironbars(xchar, xchar);
|
||||||
|
static boolean domove_swap_with_pet(struct monst *, xchar, xchar);
|
||||||
static void domove_core(void);
|
static void domove_core(void);
|
||||||
static void maybe_smudge_engr(int, int, int, int);
|
static void maybe_smudge_engr(int, int, int, int);
|
||||||
static struct monst *monstinroom(struct permonst *, int);
|
static struct monst *monstinroom(struct permonst *, int);
|
||||||
@@ -1683,6 +1684,125 @@ domove_fight_ironbars(xchar x, xchar y)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* maybe swap places with a pet? returns TRUE if swapped places */
|
||||||
|
static boolean
|
||||||
|
domove_swap_with_pet(struct monst *mtmp, xchar x, xchar y)
|
||||||
|
{
|
||||||
|
struct trap *trap;
|
||||||
|
/* if it turns out we can't actually move */
|
||||||
|
boolean didnt_move = FALSE;
|
||||||
|
boolean u_with_boulder = (sobj_at(BOULDER, u.ux, u.uy) != 0);
|
||||||
|
|
||||||
|
/* 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 */
|
||||||
|
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 */
|
||||||
|
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 */
|
||||||
|
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 */
|
||||||
|
You("stop. %s won't fit through.", upstart(y_monnam(mtmp)));
|
||||||
|
didnt_move = TRUE;
|
||||||
|
} else if (mtmp->mpeaceful && mtmp->mtrapped) {
|
||||||
|
/* all mtame are also mpeaceful, so this affects pets too */
|
||||||
|
You("stop. %s can't move out of that trap.",
|
||||||
|
upstart(y_monnam(mtmp)));
|
||||||
|
didnt_move = TRUE;
|
||||||
|
} else if (mtmp->mpeaceful
|
||||||
|
&& (!goodpos(u.ux0, u.uy0, mtmp, 0)
|
||||||
|
|| t_at(u.ux0, u.uy0) != NULL
|
||||||
|
|| mundisplaceable(mtmp))) {
|
||||||
|
/* displacing peaceful into unsafe or trapped space, or trying to
|
||||||
|
* displace quest leader, Oracle, shopkeeper, or priest */
|
||||||
|
You("stop. %s doesn't want to swap places.",
|
||||||
|
upstart(y_monnam(mtmp)));
|
||||||
|
didnt_move = TRUE;
|
||||||
|
} else {
|
||||||
|
mtmp->mtrapped = 0;
|
||||||
|
remove_monster(x, y);
|
||||||
|
place_monster(mtmp, u.ux0, u.uy0);
|
||||||
|
newsym(x, y);
|
||||||
|
newsym(u.ux0, u.uy0);
|
||||||
|
|
||||||
|
You("%s %s.", mtmp->mpeaceful ? "swap places with" : "frighten",
|
||||||
|
x_monnam(mtmp,
|
||||||
|
mtmp->mtame ? ARTICLE_YOUR
|
||||||
|
: (!has_mgivenname(mtmp)
|
||||||
|
&& !type_is_pname(mtmp->data)) ? ARTICLE_THE
|
||||||
|
: ARTICLE_NONE,
|
||||||
|
(mtmp->mpeaceful && !mtmp->mtame) ? "peaceful" : 0,
|
||||||
|
has_mgivenname(mtmp) ? SUPPRESS_SADDLE : 0, FALSE));
|
||||||
|
|
||||||
|
/* check for displacing it into pools and traps */
|
||||||
|
switch (minliquid(mtmp) ? Trap_Killed_Mon
|
||||||
|
: mintrap(mtmp, NO_TRAP_FLAGS)) {
|
||||||
|
case Trap_Effect_Finished:
|
||||||
|
break;
|
||||||
|
case Trap_Caught_Mon: /* trapped */
|
||||||
|
case Trap_Moved_Mon: /* changed levels */
|
||||||
|
/* there's already been a trap message, reinforce it */
|
||||||
|
abuse_dog(mtmp);
|
||||||
|
adjalign(-3);
|
||||||
|
break;
|
||||||
|
case Trap_Killed_Mon:
|
||||||
|
/* drowned or died...
|
||||||
|
* you killed your pet by direct action, so get experience
|
||||||
|
* and possibly penalties;
|
||||||
|
* we want the level gain message, if it happens, to occur
|
||||||
|
* before the guilt message below
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
/* minliquid() and mintrap() call mondead() rather than
|
||||||
|
killed() so we duplicate some of the latter here */
|
||||||
|
int tmp, mndx;
|
||||||
|
|
||||||
|
if (!u.uconduct.killer++)
|
||||||
|
livelog_printf(LL_CONDUCT, "killed for the first time");
|
||||||
|
mndx = monsndx(mtmp->data);
|
||||||
|
tmp = experience(mtmp, (int) g.mvitals[mndx].died);
|
||||||
|
more_experienced(tmp, 0);
|
||||||
|
newexplevel(); /* will decide if you go up */
|
||||||
|
}
|
||||||
|
/* That's no way to treat a pet! Your god gets angry.
|
||||||
|
*
|
||||||
|
* [This has always been pretty iffy. Why does your
|
||||||
|
* patron deity care at all, let alone enough to get mad?]
|
||||||
|
*/
|
||||||
|
if (rn2(4)) {
|
||||||
|
You_feel("guilty about losing your pet like this.");
|
||||||
|
u.ugangr++;
|
||||||
|
adjalign(-15);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
impossible("that's strange, unknown mintrap result!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return !didnt_move;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
domove(void)
|
domove(void)
|
||||||
{
|
{
|
||||||
@@ -1709,8 +1829,7 @@ domove_core(void)
|
|||||||
ballx = 0, bally = 0; /* ball&chain new positions */
|
ballx = 0, bally = 0; /* ball&chain new positions */
|
||||||
int bc_control = 0; /* control for ball&chain */
|
int bc_control = 0; /* control for ball&chain */
|
||||||
boolean cause_delay = FALSE, /* dragging ball will skip a move */
|
boolean cause_delay = FALSE, /* dragging ball will skip a move */
|
||||||
displaceu = FALSE, /* involuntary swap */
|
displaceu = FALSE; /* involuntary swap */
|
||||||
u_with_boulder = (sobj_at(BOULDER, u.ux, u.uy) != 0);
|
|
||||||
|
|
||||||
if (g.context.travel) {
|
if (g.context.travel) {
|
||||||
if (!findtravelpath(FALSE))
|
if (!findtravelpath(FALSE))
|
||||||
@@ -2107,118 +2226,7 @@ domove_core(void)
|
|||||||
*/
|
*/
|
||||||
} else if (is_safemon(mtmp)
|
} else if (is_safemon(mtmp)
|
||||||
&& !(is_hider(mtmp->data) && mtmp->mundetected)) {
|
&& !(is_hider(mtmp->data) && mtmp->mundetected)) {
|
||||||
/* if it turns out we can't actually move */
|
if (!domove_swap_with_pet(mtmp, x, y)) {
|
||||||
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 */
|
|
||||||
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 */
|
|
||||||
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 */
|
|
||||||
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 */
|
|
||||||
You("stop. %s won't fit through.", upstart(y_monnam(mtmp)));
|
|
||||||
didnt_move = TRUE;
|
|
||||||
} else if (mtmp->mpeaceful && mtmp->mtrapped) {
|
|
||||||
/* all mtame are also mpeaceful, so this affects pets too */
|
|
||||||
You("stop. %s can't move out of that trap.",
|
|
||||||
upstart(y_monnam(mtmp)));
|
|
||||||
didnt_move = TRUE;
|
|
||||||
} else if (mtmp->mpeaceful
|
|
||||||
&& (!goodpos(u.ux0, u.uy0, mtmp, 0)
|
|
||||||
|| t_at(u.ux0, u.uy0) != NULL
|
|
||||||
|| mundisplaceable(mtmp))) {
|
|
||||||
/* displacing peaceful into unsafe or trapped space, or trying to
|
|
||||||
* displace quest leader, Oracle, shopkeeper, or priest */
|
|
||||||
You("stop. %s doesn't want to swap places.",
|
|
||||||
upstart(y_monnam(mtmp)));
|
|
||||||
didnt_move = TRUE;
|
|
||||||
} else {
|
|
||||||
mtmp->mtrapped = 0;
|
|
||||||
remove_monster(x, y);
|
|
||||||
place_monster(mtmp, u.ux0, u.uy0);
|
|
||||||
newsym(x, y);
|
|
||||||
newsym(u.ux0, u.uy0);
|
|
||||||
|
|
||||||
You("%s %s.", mtmp->mpeaceful ? "swap places with" : "frighten",
|
|
||||||
x_monnam(mtmp,
|
|
||||||
mtmp->mtame ? ARTICLE_YOUR
|
|
||||||
: (!has_mgivenname(mtmp)
|
|
||||||
&& !type_is_pname(mtmp->data)) ? ARTICLE_THE
|
|
||||||
: ARTICLE_NONE,
|
|
||||||
(mtmp->mpeaceful && !mtmp->mtame) ? "peaceful" : 0,
|
|
||||||
has_mgivenname(mtmp) ? SUPPRESS_SADDLE : 0, FALSE));
|
|
||||||
|
|
||||||
/* check for displacing it into pools and traps */
|
|
||||||
switch (minliquid(mtmp) ? Trap_Killed_Mon
|
|
||||||
: mintrap(mtmp, NO_TRAP_FLAGS)) {
|
|
||||||
case Trap_Effect_Finished:
|
|
||||||
break;
|
|
||||||
case Trap_Caught_Mon: /* trapped */
|
|
||||||
case Trap_Moved_Mon: /* changed levels */
|
|
||||||
/* there's already been a trap message, reinforce it */
|
|
||||||
abuse_dog(mtmp);
|
|
||||||
adjalign(-3);
|
|
||||||
break;
|
|
||||||
case Trap_Killed_Mon:
|
|
||||||
/* drowned or died...
|
|
||||||
* you killed your pet by direct action, so get experience
|
|
||||||
* and possibly penalties;
|
|
||||||
* we want the level gain message, if it happens, to occur
|
|
||||||
* before the guilt message below
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
/* minliquid() and mintrap() call mondead() rather than
|
|
||||||
killed() so we duplicate some of the latter here */
|
|
||||||
int tmp, mndx;
|
|
||||||
|
|
||||||
if (!u.uconduct.killer++)
|
|
||||||
livelog_printf(LL_CONDUCT, "killed for the first time");
|
|
||||||
mndx = monsndx(mtmp->data);
|
|
||||||
tmp = experience(mtmp, (int) g.mvitals[mndx].died);
|
|
||||||
more_experienced(tmp, 0);
|
|
||||||
newexplevel(); /* will decide if you go up */
|
|
||||||
}
|
|
||||||
/* That's no way to treat a pet! Your god gets angry.
|
|
||||||
*
|
|
||||||
* [This has always been pretty iffy. Why does your
|
|
||||||
* patron deity care at all, let alone enough to get mad?]
|
|
||||||
*/
|
|
||||||
if (rn2(4)) {
|
|
||||||
You_feel("guilty about losing your pet like this.");
|
|
||||||
u.ugangr++;
|
|
||||||
adjalign(-15);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
impossible("that's strange, unknown mintrap result!");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (didnt_move) {
|
|
||||||
u.ux = u.ux0, u.uy = u.uy0; /* didn't move after all */
|
u.ux = u.ux0, u.uy = u.uy0; /* didn't move after all */
|
||||||
/* could skip this bit since we're about to call u_on_newpos() */
|
/* could skip this bit since we're about to call u_on_newpos() */
|
||||||
if (u.usteed)
|
if (u.usteed)
|
||||||
|
|||||||
Reference in New Issue
Block a user