Skip to content

Commit

Permalink
Allow some monsters to break boulders
Browse files Browse the repository at this point in the history
... 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.
  • Loading branch information
paxed committed Apr 19, 2023
1 parent 4d681ee commit 200cc21
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 2 deletions.
1 change: 1 addition & 0 deletions doc/fixes3-7-0.txt
Expand Up @@ -1147,6 +1147,7 @@ prevent hug attacks and touch or engulf attacks for wrap, stick-to, and
digestion damage from succeeding against unsolid targets (ghosts,
vortices, a few others)
wand of speed gives temporary speed, potion gives intrinsic
some monsters (riders, shopkeepers, priests, quest leader) can break boulders


Fixes to 3.7.0-x General Problems Exposed Via git Repository
Expand Down
2 changes: 2 additions & 0 deletions include/extern.h
Expand Up @@ -1711,6 +1711,8 @@ extern struct monst *find_pmmonst(int);
extern int bee_eat_jelly(struct monst *, struct obj *);
extern void monflee(struct monst *, int, boolean, boolean);
extern void mon_yells(struct monst *, const char *);
extern boolean m_can_break_boulder(struct monst *);
extern void m_break_boulder(struct monst *, coordxy, coordxy);
extern int dochug(struct monst *);
extern boolean m_digweapon_check(struct monst *, coordxy, coordxy);
extern int m_move(struct monst *, int);
Expand Down
2 changes: 1 addition & 1 deletion src/mon.c
Expand Up @@ -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;
Expand Down
35 changes: 35 additions & 0 deletions src/monmove.c
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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);
Expand Down
5 changes: 4 additions & 1 deletion src/priest.c
Expand Up @@ -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. */
Expand Down

0 comments on commit 200cc21

Please sign in to comment.