fix [rest of] #H2554 - noise when declining to kick peaceful monst

Reported last December by <email deleted>, 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.
This commit is contained in:
nethack.rankin
2012-05-02 23:01:40 +00:00
parent 0d6d24ed97
commit e2ff15fe09
2 changed files with 45 additions and 27 deletions
+4 -2
View File
@@ -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 or objects and known traps in preference to remembered objects
restrictions on diagonal movement were ignored when crawling out of water restrictions on diagonal movement were ignored when crawling out of water
when using magic whistle, prevent steed from being affected (trap interaction) when using magic whistle, prevent steed from being affected (trap interaction)
declining to attack a peaceful monster burned nutrition even though no action declining to attack a peaceful monster via movement used up nutrition even
took place 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 Platform- and/or Interface-Specific Fixes
+41 -25
View File
@@ -16,8 +16,9 @@ static NEARDATA const char *gate_str;
extern boolean notonhead; /* for long worms */ extern boolean notonhead; /* for long worms */
STATIC_DCL void FDECL(kickdmg, (struct monst *, BOOLEAN_P)); STATIC_DCL void FDECL(kickdmg, (struct monst *, BOOLEAN_P));
STATIC_DCL void FDECL(kick_monster, (XCHAR_P, XCHAR_P)); STATIC_DCL boolean FDECL(maybe_kick_monster, (struct monst *,XCHAR_P,XCHAR_P));
STATIC_DCL int FDECL(kick_object, (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 int FDECL(really_kick_object, (XCHAR_P,XCHAR_P));
STATIC_DCL char *FDECL(kickstr, (char *)); STATIC_DCL char *FDECL(kickstr, (char *));
STATIC_DCL void FDECL(otransit_msg, (struct obj *, BOOLEAN_P, long)); STATIC_DCL void FDECL(otransit_msg, (struct obj *, BOOLEAN_P, long));
@@ -114,20 +115,36 @@ register boolean clumsy;
use_skill(kick_skill, 1); use_skill(kick_skill, 1);
} }
STATIC_OVL void STATIC_OVL boolean
kick_monster(x, y) maybe_kick_monster(mon, x, y)
register xchar x, y; struct monst *mon;
xchar x, y;
{ {
register boolean clumsy = FALSE; if (mon) {
register struct monst *mon = m_at(x, y); boolean save_forcefight = context.forcefight;
register int i, j;
bhitpos.x = x; bhitpos.x = x;
bhitpos.y = y; bhitpos.y = y;
if (attack_checks(mon, (struct obj *)0)) return; if (!mon->mpeaceful || !canspotmon(mon))
/* burn extra nutrition, same as direct combat; context.forcefight = TRUE; /* attack even if invisible */
maybe pass out before making target angry */ /* kicking might be halted by discovery of hidden monster,
if (overexertion()) return; 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 */ /* anger target even if wild miss will occur */
setmangry(mon); 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(); wake_nearby();
u_wipe_engr(2); u_wipe_engr(2);
@@ -808,22 +833,13 @@ dokick()
* ceiling shouldn't be kickable (unless hero is flying?); * ceiling shouldn't be kickable (unless hero is flying?);
* kicking toward them should just target whatever is on * kicking toward them should just target whatever is on
* the floor at that spot.] * 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)) { if (mtmp) {
struct permonst *mdat; /* save mtmp->data (for recoil) in case mtmp gets killed */
struct permonst *mdat = mtmp->data;
mtmp = m_at(x, y); kick_monster(mtmp, x, y);
mdat = mtmp->data;
if (!mtmp->mpeaceful || !canspotmon(mtmp))
context.forcefight = TRUE; /* attack even if invisible */
kick_monster(x, y);
context.forcefight = FALSE;
/* see comment in attack_checks() */ /* see comment in attack_checks() */
if (!DEADMONSTER(mtmp) && if (!DEADMONSTER(mtmp) &&
!canspotmon(mtmp) && !canspotmon(mtmp) &&