fix [part of] #H2554 - hunger when declining to attack peaceful monst
Reported last December by <email deleted>, attempting to move
into a peaceful monster's position and then declining to attack at the
confirmation prompt uses no time, as expected, but does burn nutrition
the same as if you carried out the attack. A player could abuse that to
make room to eat an intrinisic-conferring corpse before it rots away.
This fixes that, and also makes attacking a monster via applying a polearm
and via kicking burn the same extra nutrition as ordinary attack. I didn't
add it for attacking via throwing.
He/she also reported that kicking at a peaceful monster and declining
to attack at the prompt wakes up nearby monsters even though no actual kick
ultimately takes place. I can confirm that, but this does not fix it.
This commit is contained in:
@@ -834,6 +834,8 @@ 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
|
||||||
|
took place
|
||||||
|
|
||||||
|
|
||||||
Platform- and/or Interface-Specific Fixes
|
Platform- and/or Interface-Specific Fixes
|
||||||
|
|||||||
@@ -802,6 +802,7 @@ E int FDECL(cant_squeeze_thru, (struct monst *));
|
|||||||
E boolean FDECL(invocation_pos, (XCHAR_P,XCHAR_P));
|
E boolean FDECL(invocation_pos, (XCHAR_P,XCHAR_P));
|
||||||
E boolean FDECL(test_move, (int, int, int, int, int));
|
E boolean FDECL(test_move, (int, int, int, int, int));
|
||||||
E void NDECL(domove);
|
E void NDECL(domove);
|
||||||
|
E boolean NDECL(overexertion);
|
||||||
E void NDECL(invocation_message);
|
E void NDECL(invocation_message);
|
||||||
E boolean FDECL(pooleffects, (BOOLEAN_P));
|
E boolean FDECL(pooleffects, (BOOLEAN_P));
|
||||||
E void FDECL(spoteffects, (BOOLEAN_P));
|
E void FDECL(spoteffects, (BOOLEAN_P));
|
||||||
|
|||||||
@@ -2649,6 +2649,7 @@ use_pole(obj)
|
|||||||
bhitpos = cc;
|
bhitpos = cc;
|
||||||
if ((mtmp = m_at(bhitpos.x, bhitpos.y)) != (struct monst *)0) {
|
if ((mtmp = m_at(bhitpos.x, bhitpos.y)) != (struct monst *)0) {
|
||||||
if (attack_checks(mtmp, uwep)) return res;
|
if (attack_checks(mtmp, uwep)) return res;
|
||||||
|
if (overexertion()) return 1; /* burn nutrition; maybe pass out */
|
||||||
check_caitiff(mtmp);
|
check_caitiff(mtmp);
|
||||||
notonhead = (bhitpos.x != mtmp->mx || bhitpos.y != mtmp->my);
|
notonhead = (bhitpos.x != mtmp->mx || bhitpos.y != mtmp->my);
|
||||||
(void) thitmonst(mtmp, uwep);
|
(void) thitmonst(mtmp, uwep);
|
||||||
|
|||||||
@@ -125,6 +125,9 @@ register xchar x, y;
|
|||||||
bhitpos.x = x;
|
bhitpos.x = x;
|
||||||
bhitpos.y = y;
|
bhitpos.y = y;
|
||||||
if (attack_checks(mon, (struct obj *)0)) return;
|
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;
|
||||||
/* anger target even if wild miss will occur */
|
/* anger target even if wild miss will occur */
|
||||||
setmangry(mon);
|
setmangry(mon);
|
||||||
|
|
||||||
@@ -805,6 +808,11 @@ 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(MON_AT(x, y)) {
|
||||||
|
|||||||
36
src/hack.c
36
src/hack.c
@@ -1329,20 +1329,6 @@ domove()
|
|||||||
if(context.forcefight || !mtmp->mundetected || sensemon(mtmp) ||
|
if(context.forcefight || !mtmp->mundetected || sensemon(mtmp) ||
|
||||||
((hides_under(mtmp->data) || mtmp->data->mlet == S_EEL) &&
|
((hides_under(mtmp->data) || mtmp->data->mlet == S_EEL) &&
|
||||||
!is_safepet(mtmp))){
|
!is_safepet(mtmp))){
|
||||||
gethungry();
|
|
||||||
if(wtcap >= HVY_ENCUMBER && moves%3) {
|
|
||||||
if (Upolyd && u.mh > 1) {
|
|
||||||
u.mh--;
|
|
||||||
} else if (!Upolyd && u.uhp > 1) {
|
|
||||||
u.uhp--;
|
|
||||||
} else {
|
|
||||||
You("pass out from exertion!");
|
|
||||||
exercise(A_CON, FALSE);
|
|
||||||
fall_asleep(-10, FALSE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(multi < 0) return; /* we just fainted */
|
|
||||||
|
|
||||||
/* try to attack; note that it might evade */
|
/* try to attack; note that it might evade */
|
||||||
/* also, we don't attack tame when _safepet_ */
|
/* also, we don't attack tame when _safepet_ */
|
||||||
if(attack(mtmp)) return;
|
if(attack(mtmp)) return;
|
||||||
@@ -1621,6 +1607,28 @@ domove()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* combat increases metabolism */
|
||||||
|
boolean
|
||||||
|
overexertion()
|
||||||
|
{
|
||||||
|
/* this used to be part of domove() when moving to a monster's
|
||||||
|
position, but is now called by attack() so that it doesn't
|
||||||
|
execute if you decline to attack a peaceful monster */
|
||||||
|
gethungry();
|
||||||
|
if ((moves % 3L) != 0L && near_capacity() >= HVY_ENCUMBER) {
|
||||||
|
int *hp = (!Upolyd ? &u.uhp : &u.mh);
|
||||||
|
|
||||||
|
if (*hp > 1) {
|
||||||
|
*hp -= 1;
|
||||||
|
} else {
|
||||||
|
You("pass out from exertion!");
|
||||||
|
exercise(A_CON, FALSE);
|
||||||
|
fall_asleep(-10, FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (multi < 0); /* might have fainted (actually gone to sleep) */
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
invocation_message()
|
invocation_message()
|
||||||
{
|
{
|
||||||
|
|||||||
16
src/uhitm.c
16
src/uhitm.c
@@ -366,16 +366,16 @@ register struct monst *mtmp;
|
|||||||
bhitpos.y = u.uy + u.dy;
|
bhitpos.y = u.uy + u.dy;
|
||||||
if (attack_checks(mtmp, uwep)) return(TRUE);
|
if (attack_checks(mtmp, uwep)) return(TRUE);
|
||||||
|
|
||||||
if (Upolyd) {
|
if (Upolyd && noattacks(youmonst.data)) {
|
||||||
/* certain "pacifist" monsters don't attack */
|
/* certain "pacifist" monsters don't attack */
|
||||||
if(noattacks(youmonst.data)) {
|
You("have no way to attack monsters physically.");
|
||||||
You("have no way to attack monsters physically.");
|
mtmp->mstrategy &= ~STRAT_WAITMASK;
|
||||||
mtmp->mstrategy &= ~STRAT_WAITMASK;
|
goto atk_done;
|
||||||
goto atk_done;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(check_capacity("You cannot fight while so heavily loaded."))
|
if (check_capacity("You cannot fight while so heavily loaded.") ||
|
||||||
|
/* consume extra nutrition during combat; maybe pass out */
|
||||||
|
overexertion())
|
||||||
goto atk_done;
|
goto atk_done;
|
||||||
|
|
||||||
if (u.twoweap && !can_twoweapon())
|
if (u.twoweap && !can_twoweapon())
|
||||||
|
|||||||
Reference in New Issue
Block a user