From: nethack.rankin Date: Wed, 2 May 2012 23:01:40 +0000 (+0000) Subject: fix [rest of] #H2554 - noise when declining to kick peaceful monst X-Git-Tag: MOVE2GIT~19 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e2ff15fe096c11d6f18a25a9f17bac0c7a338837;p=nethack fix [rest of] #H2554 - noise when declining to kick peaceful monst Reported last December by , attempting to kick a peaceful monster then declining to attack at the confirmation prompt uses no time, as expected, but does wake up nearby monsters and scuff an engraving at the hero's location. --- diff --git a/doc/fixes35.0 b/doc/fixes35.0 index 5007eca1c..c239c3815 100644 --- a/doc/fixes35.0 +++ b/doc/fixes35.0 @@ -834,8 +834,10 @@ magic mapping now displays furniture in preference to known or remembered traps or objects and known traps in preference to remembered objects restrictions on diagonal movement were ignored when crawling out of water when using magic whistle, prevent steed from being affected (trap interaction) -declining to attack a peaceful monster burned nutrition even though no action - took place +declining to attack a peaceful monster via movement used up nutrition even + though no action took place +declining to attack a peaceful monster via kicking woke nearby monsters and + scuffed engraving at hero's location even though no action took place Platform- and/or Interface-Specific Fixes diff --git a/src/dokick.c b/src/dokick.c index 15d685bd8..a8b82b8db 100644 --- a/src/dokick.c +++ b/src/dokick.c @@ -16,8 +16,9 @@ static NEARDATA const char *gate_str; extern boolean notonhead; /* for long worms */ STATIC_DCL void FDECL(kickdmg, (struct monst *, BOOLEAN_P)); -STATIC_DCL void FDECL(kick_monster, (XCHAR_P, XCHAR_P)); -STATIC_DCL int FDECL(kick_object, (XCHAR_P, XCHAR_P)); +STATIC_DCL boolean FDECL(maybe_kick_monster, (struct monst *,XCHAR_P,XCHAR_P)); +STATIC_DCL void FDECL(kick_monster, (struct monst *,XCHAR_P,XCHAR_P)); +STATIC_DCL int FDECL(kick_object, (XCHAR_P,XCHAR_P)); STATIC_DCL int FDECL(really_kick_object, (XCHAR_P,XCHAR_P)); STATIC_DCL char *FDECL(kickstr, (char *)); STATIC_DCL void FDECL(otransit_msg, (struct obj *, BOOLEAN_P, long)); @@ -114,20 +115,36 @@ register boolean clumsy; use_skill(kick_skill, 1); } -STATIC_OVL void -kick_monster(x, y) -register xchar x, y; +STATIC_OVL boolean +maybe_kick_monster(mon, x, y) +struct monst *mon; +xchar x, y; { - register boolean clumsy = FALSE; - register struct monst *mon = m_at(x, y); - register int i, j; + if (mon) { + boolean save_forcefight = context.forcefight; bhitpos.x = x; bhitpos.y = y; - if (attack_checks(mon, (struct obj *)0)) return; - /* burn extra nutrition, same as direct combat; - maybe pass out before making target angry */ - if (overexertion()) return; + if (!mon->mpeaceful || !canspotmon(mon)) + context.forcefight = TRUE; /* attack even if invisible */ + /* kicking might be halted by discovery of hidden monster, + by player declining to attack peaceful monster, + or by passing out due to encumbrance */ + if (attack_checks(mon, (struct obj *)0) || overexertion()) + mon = 0; /* don't kick after all */ + context.forcefight = save_forcefight; + } + return (boolean)(mon != 0); +} + +STATIC_OVL void +kick_monster(mon, x, y) +struct monst *mon; +xchar x, y; +{ + boolean clumsy = FALSE; + int i, j; + /* anger target even if wild miss will occur */ setmangry(mon); @@ -788,6 +805,14 @@ dokick() } } + mtmp = isok(x, y) ? m_at(x, y) : 0; + /* might not kick monster if it is hidden and becomes revealed, + if it is peaceful and player declines to attack, or if the + hero passes out due to enbumbrance with low hp; context.move + will be 1 unless player declines to kick peaceful monster */ + if (mtmp && !maybe_kick_monster(mtmp, x, y)) + return context.move; + wake_nearby(); u_wipe_engr(2); @@ -808,22 +833,13 @@ dokick() * ceiling shouldn't be kickable (unless hero is flying?); * kicking toward them should just target whatever is on * the floor at that spot.] - * [FIXME too: kick_monster() calls attack_checks() which gives - * the player a chance to decline to attack a peaceful monster, - * and also calls overexertion() so hero might pass out before - * performing the kick. We shouldn't call wake_nearby() (and - * u_wipe_engr(), both already done above) in such cases.] */ - if(MON_AT(x, y)) { - struct permonst *mdat; + if (mtmp) { + /* save mtmp->data (for recoil) in case mtmp gets killed */ + struct permonst *mdat = mtmp->data; - mtmp = m_at(x, y); - mdat = mtmp->data; - if (!mtmp->mpeaceful || !canspotmon(mtmp)) - context.forcefight = TRUE; /* attack even if invisible */ - kick_monster(x, y); - context.forcefight = FALSE; + kick_monster(mtmp, x, y); /* see comment in attack_checks() */ if (!DEADMONSTER(mtmp) && !canspotmon(mtmp) &&