Hit and wake sleeping monster makes it growl

Unless you kill the monster with one hit, it'll wake up
cranky and make noise - waking up other sleeping monsters.

This was a bit tricky with all the message sequencing; I tested
all the hit/throw/fire/zap combos I could think of, and it took
a while to get things looking right.
This commit is contained in:
Pasi Kallinen
2023-01-21 16:52:17 +02:00
parent 9dca76bb50
commit 677b32c2a7
8 changed files with 34 additions and 30 deletions

View File

@@ -1089,6 +1089,7 @@ allow setting per-level "temperature": hot, cold, or temperate, currently
only affects some messages
digging is noisy
polymorphing into fire elemental allows you eat flammable items
hitting sleeping monsters will cause them to wake up noisily
Fixes to 3.7.0-x Problems that Were Exposed Via git Repository

View File

@@ -2914,7 +2914,7 @@ extern void dynamic_multi_reason(struct monst *, const char *, boolean);
extern void erode_armor(struct monst *, int);
extern boolean attack_checks(struct monst *, struct obj *);
extern void check_caitiff(struct monst *);
extern void mon_maybe_wakeup_on_hit(struct monst *);
extern void mon_maybe_unparalyze(struct monst *);
extern int find_roll_to_hit(struct monst *, uchar, struct obj *, int *, int *);
extern boolean force_attack(struct monst *, boolean);
extern boolean do_attack(struct monst *);
@@ -3477,7 +3477,7 @@ extern void dobuzz(int, int, coordxy, coordxy, int, int, boolean);
extern void melt_ice(coordxy, coordxy, const char *);
extern void start_melt_ice_timeout(coordxy, coordxy, long);
extern void melt_ice_away(union any *, long);
extern int zap_over_floor(coordxy, coordxy, int, boolean *, short);
extern int zap_over_floor(coordxy, coordxy, int, boolean *, boolean, short);
extern void fracture_rock(struct obj *);
extern boolean break_statue(struct obj *);
extern boolean u_adtyp_resistance_obj(int);

View File

@@ -183,7 +183,7 @@ kick_monster(struct monst *mon, coordxy x, coordxy y)
attknum = 0,
tmp = find_roll_to_hit(mon, AT_KICK, (struct obj *) 0, &attknum,
&armorpenalty);
mon_maybe_wakeup_on_hit(mon);
mon_maybe_unparalyze(mon);
for (i = 0; i < NATTK; i++) {
/* first of two kicks might have provoked counterattack

View File

@@ -1830,8 +1830,6 @@ omon_adj(struct monst *mon, struct obj *obj, boolean mon_notices)
/* sleeping target is more likely to be hit */
if (mon->msleeping) {
tmp += 2;
if (mon_notices)
mon->msleeping = 0;
}
/* ditto for immobilized target */
if (!mon->mcanmove || !mon->data->mmove) {

View File

@@ -411,7 +411,8 @@ explode(
* from inside their engulfer. */
if (!(u.uswallow && !gc.context.mon_moving))
(void) zap_over_floor(xx, yy, type,
&shopdamage, exploding_wand_typ);
&shopdamage, FALSE,
exploding_wand_typ);
mtmp = m_at(xx, yy);
if (!mtmp && u_at(xx, yy))

View File

@@ -3789,6 +3789,8 @@ wake_msg(struct monst *mtmp, boolean interesting)
void
wakeup(struct monst* mtmp, boolean via_attack)
{
boolean was_sleeping = mtmp->msleeping;
wake_msg(mtmp, via_attack);
mtmp->msleeping = 0;
if (M_AP_TYPE(mtmp) != M_AP_NOTHING) {
@@ -3802,8 +3804,15 @@ wakeup(struct monst* mtmp, boolean via_attack)
newsym(mtmp->mx, mtmp->my);
}
finish_meating(mtmp);
if (via_attack)
if (via_attack) {
if (was_sleeping)
growl(mtmp);
setmangry(mtmp, TRUE);
if (mtmp->ispriest && *in_rooms(mtmp->mx, mtmp->my, TEMPLE))
ghod_hitsu(mtmp);
if (mtmp->isshk && !*u.ushops)
hot_pursuit(mtmp);
}
}
/* Wake up nearby monsters without angering them. */

View File

@@ -293,13 +293,10 @@ check_caitiff(struct monst *mtmp)
}
}
/* wake up monster, maybe unparalyze it */
/* maybe unparalyze monster */
void
mon_maybe_wakeup_on_hit(struct monst *mtmp)
mon_maybe_unparalyze(struct monst *mtmp)
{
if (mtmp->msleeping)
mtmp->msleeping = 0;
if (!mtmp->mcanmove) {
if (!rn2(10)) {
mtmp->mcanmove = 1;
@@ -647,7 +644,7 @@ hitum_cleave(
tmp = find_roll_to_hit(mtmp, uattk->aatyp, uwep,
&attknum, &armorpenalty);
mon_maybe_wakeup_on_hit(mtmp);
mon_maybe_unparalyze(mtmp);
dieroll = rnd(20);
mhit = (tmp > dieroll);
gb.bhitpos.x = tx, gb.bhitpos.y = ty; /* normally set up by
@@ -685,7 +682,7 @@ hitum(struct monst *mon, struct attack *uattk)
dieroll = rnd(20),
mhit = (tmp > dieroll || u.uswallow);
mon_maybe_wakeup_on_hit(mon);
mon_maybe_unparalyze(mon);
/* Cleaver attacks three spots, 'mon' and one on either side of 'mon';
it can't be part of dual-wielding but we guard against that anyway;
@@ -712,7 +709,7 @@ hitum(struct monst *mon, struct attack *uattk)
|| !malive || m_at(x, y) != mon)) {
tmp = find_roll_to_hit(mon, uattk->aatyp, uswapwep, &attknum,
&armorpenalty);
mon_maybe_wakeup_on_hit(mon);
mon_maybe_unparalyze(mon);
dieroll = rnd(20);
mhit = (tmp > dieroll || u.uswallow);
malive = known_hitum(mon, uswapwep, &mhit, tmp, armorpenalty, uattk,
@@ -786,7 +783,6 @@ hmon_hitmon(
saved_oname[0] = '\0';
wakeup(mon, TRUE);
if (!obj) { /* attack with bare hands */
long silverhit = 0L; /* armor mask */
@@ -816,6 +812,7 @@ hmon_hitmon(
if ((thrown == HMON_THROWN || thrown == HMON_KICKED) /* not Applied */
&& stone_missile(obj) && passes_rocks(mdat)) {
hit(mshot_xname(obj), mon, " but does no harm.");
wakeup(mon, TRUE);
return TRUE;
}
/* remember obj's name since it might end up being destroyed and
@@ -1510,6 +1507,9 @@ hmon_hitmon(
Your("%s %s no longer poisoned.", saved_oname,
vtense(saved_oname, "are"));
if (!destroyed)
wakeup(mon, TRUE);
return destroyed ? FALSE : TRUE;
}
@@ -4854,7 +4854,7 @@ hmonas(struct monst *mon)
tmp = find_roll_to_hit(mon, AT_WEAP, weapon, &attknum,
&armorpenalty);
mon_maybe_wakeup_on_hit(mon);
mon_maybe_unparalyze(mon);
dieroll = rnd(20);
dhit = (tmp > dieroll || u.uswallow);
/* caller must set gb.bhitpos */
@@ -4896,7 +4896,7 @@ hmonas(struct monst *mon)
/*weaponless:*/
tmp = find_roll_to_hit(mon, mattk->aatyp, (struct obj *) 0,
&attknum, &armorpenalty);
mon_maybe_wakeup_on_hit(mon);
mon_maybe_unparalyze(mon);
dieroll = rnd(20);
dhit = (tmp > dieroll || u.uswallow);
if (dhit) {
@@ -5089,7 +5089,7 @@ hmonas(struct monst *mon)
case AT_ENGL:
tmp = find_roll_to_hit(mon, mattk->aatyp, (struct obj *) 0,
&attknum, &armorpenalty);
mon_maybe_wakeup_on_hit(mon);
mon_maybe_unparalyze(mon);
if ((dhit = (tmp > rnd(20 + i)))) {
wakeup(mon, TRUE);
if (mon->data == &mons[PM_SHADE]) {

View File

@@ -4393,7 +4393,7 @@ dobuzz(
gb.bhitpos.x = sx, gb.bhitpos.y = sy;
/* Fireballs only damage when they explode */
if (type != ZT_SPELL(ZT_FIRE)) {
range += zap_over_floor(sx, sy, type, &shopdamage, 0);
range += zap_over_floor(sx, sy, type, &shopdamage, 0, TRUE);
/* zap with fire -> melt ice -> drown monster, so monster
found and cached above might not be here any more */
mon = m_at(sx, sy);
@@ -4480,6 +4480,8 @@ dobuzz(
}
if (mon_could_move && !mon->mcanmove) /* ZT_SLEEP */
slept_monst(mon);
if (abstype != ZT_SLEEP)
wakeup(mon, TRUE);
}
}
range -= 2;
@@ -4698,6 +4700,7 @@ zap_over_floor(
coordxy x, coordxy y, /* location */
int type, /* damage type plus {wand|spell|breath} info */
boolean *shopdamage, /* extra output if shop door is destroyed */
boolean ignoremon, /* ignore any monster here */
short exploding_wand_typ) /* supplied when breaking a wand; or POT_OIL
* when a lit potion of oil explodes */
{
@@ -5012,16 +5015,8 @@ zap_over_floor(
newsym(x, y);
You("%s of smoke.", !Blind ? "see a puff" : "smell a whiff");
}
if ((mon = m_at(x, y)) != 0) {
wakeup(mon, FALSE);
if (type >= 0) {
setmangry(mon, TRUE);
if (mon->ispriest && *in_rooms(mon->mx, mon->my, TEMPLE))
ghod_hitsu(mon);
if (mon->isshk && !*u.ushops)
hot_pursuit(mon);
}
}
if (!ignoremon && (mon = m_at(x, y)) != 0)
wakeup(mon, (type >= 0) ? TRUE : FALSE);
return rangemod;
}