From 1ef3167ca0bdcbccb969c085ae7fc84e57599a07 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sat, 4 Jan 2025 16:37:11 +0200 Subject: [PATCH] Steed #monster breath feedback Using #monster to make the steed use the breath weapon often failed because the steed did not want to breathe at weak or too strong monsters. Make #monster force the steed use the breath, and if there is no targets available, make the steed make some noise as feedback. --- include/extern.h | 3 ++- src/cmd.c | 2 +- src/dogmove.c | 17 +++++++++-------- src/sounds.c | 3 +-- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/include/extern.h b/include/extern.h index 5b0f69b8b..8a4c66ccb 100644 --- a/include/extern.h +++ b/include/extern.h @@ -762,7 +762,7 @@ extern struct obj *droppables(struct monst *) NONNULLARG1; extern int dog_nutrition(struct monst *, struct obj *) NONNULLPTRS; extern int dog_eat(struct monst *, struct obj *, coordxy, coordxy, boolean) NONNULLPTRS; -extern int pet_ranged_attk(struct monst *) NONNULLARG1; +extern int pet_ranged_attk(struct monst *, boolean) NONNULLARG1; extern int dog_move(struct monst *, int) NONNULLARG1; extern boolean could_reach_item(struct monst *, coordxy, coordxy) NONNULLARG1; extern void finish_meating(struct monst *) NONNULLARG1; @@ -2911,6 +2911,7 @@ extern void whimper(struct monst *) NONNULLARG1; extern void beg(struct monst *) NONNULLARG1; extern const char *maybe_gasp(struct monst *) NONNULLARG1; extern const char *cry_sound(struct monst *) NONNULLARG1; +extern int domonnoise(struct monst *) NONNULLARG1; extern int dotalk(void); extern int tiphat(void); #ifdef USER_SOUNDS diff --git a/src/cmd.c b/src/cmd.c index 557edffd2..6db62f9af 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -934,7 +934,7 @@ domonability(void) } else if (is_vampire(uptr) || is_vampshifter(&gy.youmonst)) { return dopoly(); } else if (u.usteed && can_breathe(u.usteed->data)) { - (void) pet_ranged_attk(u.usteed); + (void) pet_ranged_attk(u.usteed, TRUE); return ECMD_TIME; } else if (Upolyd) { pline("Any special ability you may have is purely reflexive."); diff --git a/src/dogmove.c b/src/dogmove.c index b0fe44864..6eba6c089 100644 --- a/src/dogmove.c +++ b/src/dogmove.c @@ -17,7 +17,7 @@ staticfn int dog_invent(struct monst *, struct edog *, int); staticfn int dog_goal(struct monst *, struct edog *, int, int, int); staticfn struct monst *find_targ(struct monst *, int, int, int); staticfn int find_friends(struct monst *, struct monst *, int); -staticfn struct monst *best_target(struct monst *); +staticfn struct monst *best_target(struct monst *, boolean); staticfn long score_targ(struct monst *, struct monst *); staticfn boolean can_reach_location(struct monst *, coordxy, coordxy, coordxy, coordxy) NONNULLARG1; @@ -819,7 +819,7 @@ score_targ(struct monst *mtmp, struct monst *mtarg) } staticfn struct monst * -best_target(struct monst *mtmp) /* Pet */ +best_target(struct monst *mtmp, boolean forced) /* Pet */ { int dx, dy; long bestscore = -40000L, currscore; @@ -862,7 +862,7 @@ best_target(struct monst *mtmp) /* Pet */ } /* Filter out targets the pet doesn't like */ - if (bestscore < 0L) + if (!forced && bestscore < 0L) best_targ = 0; return best_targ; @@ -870,7 +870,7 @@ best_target(struct monst *mtmp) /* Pet */ /* Pet considers and maybe executes a ranged attack */ int -pet_ranged_attk(struct monst *mtmp) +pet_ranged_attk(struct monst *mtmp, boolean forced) { struct monst *mtarg; int hungry = 0; @@ -885,7 +885,7 @@ pet_ranged_attk(struct monst *mtmp) /* Identify the best target in a straight line from the pet; * if there is such a target, we'll let the pet attempt an attack. */ - mtarg = best_target(mtmp); + mtarg = best_target(mtmp, forced); /* Hungry pets are unlikely to use breath/spit attacks */ if (mtarg && (!hungry || !rn2(5))) { @@ -945,7 +945,8 @@ pet_ranged_attk(struct monst *mtmp) */ if (mstatus != M_ATTK_MISS) return MMOVE_DONE; - } + } else if (forced) + (void) domonnoise(mtmp); return MMOVE_NOTHING; } @@ -1119,7 +1120,7 @@ dog_move( || (touch_petrifies(mtmp2->data) && !resists_ston(mtmp))) { /* only skip this foe if a ranged attack isn't viable */ if (dist2(mtmp->mx, mtmp->my, mtmp2->mx, mtmp2->my) <= 2 - || best_target(mtmp) != mtmp2) + || best_target(mtmp, FALSE) != mtmp2) continue; ranged_only = TRUE; } @@ -1254,7 +1255,7 @@ dog_move( * now's the time for ranged attacks. Note that the pet can move * after it performs its ranged attack. Should this be changed? */ - if ((i = pet_ranged_attk(mtmp)) != MMOVE_NOTHING) + if ((i = pet_ranged_attk(mtmp, FALSE)) != MMOVE_NOTHING) return i; newdogpos: diff --git a/src/sounds.c b/src/sounds.c index 9ca6b199d..5b7d2baae 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -10,7 +10,6 @@ staticfn boolean morgue_mon_sound(struct monst *); staticfn boolean zoo_mon_sound(struct monst *); staticfn boolean temple_priest_sound(struct monst *); staticfn boolean mon_is_gecko(struct monst *); -staticfn int domonnoise(struct monst *); staticfn int dochat(void); staticfn struct monst *responsive_mon_at(int, int); staticfn int mon_in_room(struct monst *, int); @@ -675,7 +674,7 @@ mon_is_gecko(struct monst *mon) DISABLE_WARNING_FORMAT_NONLITERAL -staticfn int /* check calls to this */ +int /* check calls to this */ domonnoise(struct monst *mtmp) { char verbuf[BUFSZ];