Allow some monsters to break boulders

... if the boulder is in a position they want to move to.
Shopkeepers, priests, and the quest leader can break one boulder
and then need to take several turns before being able to break
another.  Riders can break a boulder every turn.
This commit is contained in:
Pasi Kallinen
2023-04-19 14:37:51 +03:00
parent 4d681eed46
commit 200cc21fb3
5 changed files with 43 additions and 2 deletions

View File

@@ -1829,7 +1829,7 @@ mon_allowflags(struct monst* mtmp)
allowflags |= ALLOW_SSM | ALLOW_SANCT;
if (passes_walls(mtmp->data))
allowflags |= (ALLOW_ROCK | ALLOW_WALL);
if (throws_rocks(mtmp->data))
if (throws_rocks(mtmp->data) || m_can_break_boulder(mtmp))
allowflags |= ALLOW_ROCK;
if (can_tunnel)
allowflags |= ALLOW_DIG;

View File

@@ -104,6 +104,36 @@ mon_yells(struct monst* mon, const char* shout)
}
}
/* can monster mtmp break boulders? */
boolean
m_can_break_boulder(struct monst *mtmp)
{
return (is_rider(mtmp->data)
|| (!mtmp->mspec_used
&& (mtmp->isshk || mtmp->ispriest
|| (mtmp->data->msound == MS_LEADER))));
}
/* monster mtmp breaks boulder at x,y */
void
m_break_boulder(struct monst *mtmp, coordxy x, coordxy y)
{
struct obj *otmp;
if (m_can_break_boulder(mtmp) && ((otmp = sobj_at(BOULDER, x, y)) != 0)) {
if (!is_rider(mtmp->data)) {
if (!Deaf && (mdistu(mtmp) < 4*4))
pline("%s mutters %s.",
Monnam(mtmp),
mtmp->ispriest ? "a prayer" : "an incantation");
mtmp->mspec_used += rn1(20, 10);
}
if (cansee(x, y))
pline_The("boulder falls apart.");
fracture_rock(otmp);
}
}
static void
watch_on_duty(register struct monst* mtmp)
{
@@ -1536,6 +1566,11 @@ m_move(register struct monst* mtmp, register int after)
if (!m_in_out_region(mtmp, nix, niy))
return MMOVE_DONE;
if ((info[chi] & ALLOW_ROCK) && m_can_break_boulder(mtmp)) {
(void) m_break_boulder(mtmp, nix, niy);
return MMOVE_DONE;
}
/* move a normal monster; for a long worm, remove_monster() and
place_monster() only manipulate the head; they leave tail as-is */
remove_monster(omx, omy);

View File

@@ -101,7 +101,10 @@ move_special(struct monst *mtmp, boolean in_his_shop, schar appr,
if (nix != omx || niy != omy) {
if (ninfo & ALLOW_M) {
if (ninfo & ALLOW_ROCK) {
m_break_boulder(mtmp, nix, niy);
return 1;
} else if (ninfo & ALLOW_M) {
/* mtmp is deciding it would like to attack this turn.
* Returns from m_move_aggress don't correspond to the same things
* as this function should return, so we need to translate. */