diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 5333a8226..5d61dc8ce 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -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 diff --git a/include/decl.h b/include/decl.h index 1e8e75120..62d21c33f 100644 --- a/include/decl.h +++ b/include/decl.h @@ -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; diff --git a/include/extern.h b/include/extern.h index 1e533c96f..dc2a42737 100644 --- a/include/extern.h +++ b/include/extern.h @@ -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); diff --git a/src/cmd.c b/src/cmd.c index a81e80e57..f3480e63d 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -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[] */ diff --git a/src/decl.c b/src/decl.c index 88e7f97ad..c3e36aa78 100644 --- a/src/decl.c +++ b/src/decl.c @@ -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 */ diff --git a/src/dogmove.c b/src/dogmove.c index 3a575830c..dedb26743 100644 --- a/src/dogmove.c +++ b/src/dogmove.c @@ -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 diff --git a/src/dokick.c b/src/dokick.c index 980f6b29c..202e714d5 100644 --- a/src/dokick.c +++ b/src/dokick.c @@ -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) diff --git a/src/hack.c b/src/hack.c index 2286e7b87..85117b63c 100644 --- a/src/hack.c +++ b/src/hack.c @@ -2511,6 +2511,8 @@ domove(void) maybe_adjust_hero_bubble(); } gd.domove_attempting = 0L; + + gk.kickedloc.x = 0, gk.kickedloc.y = 0; } staticfn void diff --git a/src/monmove.c b/src/monmove.c index 9eae66ffe..bd0241aaa 100644 --- a/src/monmove.c +++ b/src/monmove.c @@ -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;