Pets avoid a location hero just kicked

If hero kicks a location, pets and peacefuls will avoid moving
into that location for that turn.
This commit is contained in:
Pasi Kallinen
2024-04-11 18:05:12 +03:00
parent 62b78ba037
commit f1c77aa2fd
9 changed files with 37 additions and 1 deletions

View File

@@ -1397,6 +1397,7 @@ gold thrown or kicked at a sleeping monster with the 'greedy' attribute gets
caught instead of being treated as an attack but the catch message
neglected to report that target monster was awakened in the process
hero movement affects the water bubble movement direction
pets and peacefuls avoid a location hero just kicked
Fixes to 3.7.0-x General Problems Exposed Via git Repository

View File

@@ -515,6 +515,8 @@ struct instance_globals_j {
struct instance_globals_k {
coord kickedloc; /* location hero just kicked */
/* decl.c */
struct obj *kickedobj; /* object in flight due to kicking */
struct kinfo killer;

View File

@@ -1840,6 +1840,7 @@ extern boolean m_can_break_boulder(struct monst *) NONNULLARG1;
extern void m_break_boulder(struct monst *, coordxy, coordxy) NONNULLARG1;
extern int dochug(struct monst *) NONNULLARG1;
extern boolean m_digweapon_check(struct monst *, coordxy, coordxy) NONNULLARG1;
extern boolean m_avoid_kicked_loc(struct monst *, coordxy, coordxy) NONNULLARG1;
extern int m_move(struct monst *, int) NONNULLARG1;
extern int m_move_aggress(struct monst *, coordxy, coordxy) NONNULLARG1;
extern void dissolve_bars(coordxy, coordxy);

View File

@@ -3446,8 +3446,14 @@ rhack(int key)
}
/* reset_cmd_vars() sets context.move to False so we might
need to change it [back] to True */
if ((res & ECMD_TIME) != 0)
if ((res & ECMD_TIME) != 0) {
gc.context.move = TRUE;
if (func != dokick) {
/* hero did something else than kicking a location;
reset the location, so pets don't avoid it */
gk.kickedloc.x = 0, gk.kickedloc.y = 0;
}
}
return;
}
/* if we reach here, cmd wasn't found in cmdlist[] */

View File

@@ -477,6 +477,7 @@ static const struct instance_globals_j g_init_j = {
};
static const struct instance_globals_k g_init_k = {
{ 0, 0 }, /* kickedloc */
/* decl.c */
UNDEFINED_PTR, /* kickedobj */
DUMMY, /* killer */

View File

@@ -1145,6 +1145,10 @@ dog_move(
return MMOVE_NOTHING;
}
/* avoid a location hero just kicked */
if (m_avoid_kicked_loc(mtmp, nx, ny))
continue;
{
/* Dog avoids harmful traps, but perhaps it has to pass one
* in order to follow player. (Non-harmful traps do not

View File

@@ -1314,6 +1314,7 @@ dokick(void)
x = u.ux + u.dx;
y = u.uy + u.dy;
gk.kickedloc.x = x, gk.kickedloc.y = y;
/* KMH -- Kicking boots always succeed */
if (uarmf && uarmf->otyp == KICKING_BOOTS)

View File

@@ -2511,6 +2511,8 @@ domove(void)
maybe_adjust_hero_bubble();
}
gd.domove_attempting = 0L;
gk.kickedloc.x = 0, gk.kickedloc.y = 0;
}
staticfn void

View File

@@ -1215,6 +1215,21 @@ maybe_spin_web(struct monst *mtmp)
}
}
/* monster avoids a location nx, ny, if hero kicked that location */
boolean
m_avoid_kicked_loc(struct monst *mtmp, coordxy nx, coordxy ny)
{
if ((mtmp->mpeaceful || mtmp->mtame)
&& mtmp->mcansee
&& !mtmp->mconf && !mtmp->mstun
&& !Conflict
&& isok(gk.kickedloc.x, gk.kickedloc.y)
&& nx == gk.kickedloc.x && ny == gk.kickedloc.y
&& next2u(nx, ny))
return TRUE;
return FALSE;
}
/* max distmin() distance for monster to look for items */
#define SQSRCHRADIUS 5
@@ -1831,6 +1846,9 @@ m_move(struct monst *mtmp, int after)
nx = poss[i].x;
ny = poss[i].y;
if (m_avoid_kicked_loc(mtmp, nx, ny))
continue;
if (MON_AT(nx, ny) && (info[i] & ALLOW_MDISP)
&& !(info[i] & ALLOW_M) && !better_with_displacing)
continue;