]> granicus.if.org Git - nethack/commitdiff
fix [part of] #H2554 - hunger when declining to attack peaceful monst
authornethack.rankin <nethack.rankin>
Tue, 1 May 2012 02:22:33 +0000 (02:22 +0000)
committernethack.rankin <nethack.rankin>
Tue, 1 May 2012 02:22:33 +0000 (02:22 +0000)
     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.

doc/fixes35.0
include/extern.h
src/apply.c
src/dokick.c
src/hack.c
src/uhitm.c

index 968fa79fd3af90f7ec3fb106986f7ec6e374b7d5..5007eca1c34a5ab3c147c3427c709a255808ebdf 100644 (file)
@@ -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
 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
 
 
 Platform- and/or Interface-Specific Fixes
index bb279fd7fa95c95e25190f674da169237509d615..0e7eb4420b0419fd56bd3a2c37e73e61650be8e2 100644 (file)
@@ -802,6 +802,7 @@ E int FDECL(cant_squeeze_thru, (struct monst *));
 E boolean FDECL(invocation_pos, (XCHAR_P,XCHAR_P));
 E boolean FDECL(test_move, (int, int, int, int, int));
 E void NDECL(domove);
+E boolean NDECL(overexertion);
 E void NDECL(invocation_message);
 E boolean FDECL(pooleffects, (BOOLEAN_P));
 E void FDECL(spoteffects, (BOOLEAN_P));
index 1b0c001a1d67a9b5935662bd8a48b9958f0453a2..77608b38efd15268cdf8b0b11d549775cb440746 100644 (file)
@@ -2649,6 +2649,7 @@ use_pole(obj)
        bhitpos = cc;
        if ((mtmp = m_at(bhitpos.x, bhitpos.y)) != (struct monst *)0) {
            if (attack_checks(mtmp, uwep)) return res;
+           if (overexertion()) return 1; /* burn nutrition; maybe pass out */
            check_caitiff(mtmp);
            notonhead = (bhitpos.x != mtmp->mx || bhitpos.y != mtmp->my);
            (void) thitmonst(mtmp, uwep);
index 0238c0c349ae5798f5b27acd90383828cca2df4c..15d685bd8761e44a799cfecc0f9c6d9f96669fb7 100644 (file)
@@ -125,6 +125,9 @@ register xchar x, y;
        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;
        /* anger target even if wild miss will occur */
        setmangry(mon);
 
@@ -805,6 +808,11 @@ 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)) {
index 2899a931227d69f624e19c2d99c086b05d8eaba6..055930d9f901aac45b5b2e79344748721304e54a 100644 (file)
@@ -1329,20 +1329,6 @@ domove()
            if(context.forcefight || !mtmp->mundetected || sensemon(mtmp) ||
                    ((hides_under(mtmp->data) || mtmp->data->mlet == S_EEL) &&
                        !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 */
                /* also, we don't attack tame when _safepet_ */
                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
 invocation_message()
 {
index 568be33f831b9d1a17283f69ae4331a928194696..cbd0cdbeca1f68d2c5783d66071f308c842a356c 100644 (file)
@@ -366,16 +366,16 @@ register struct monst *mtmp;
        bhitpos.y = u.uy + u.dy;
        if (attack_checks(mtmp, uwep)) return(TRUE);
 
-       if (Upolyd) {
-               /* certain "pacifist" monsters don't attack */
-               if(noattacks(youmonst.data)) {
-                       You("have no way to attack monsters physically.");
-                       mtmp->mstrategy &= ~STRAT_WAITMASK;
-                       goto atk_done;
-               }
+       if (Upolyd && noattacks(youmonst.data)) {
+           /* certain "pacifist" monsters don't attack */
+           You("have no way to attack monsters physically.");
+           mtmp->mstrategy &= ~STRAT_WAITMASK;
+           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;
 
        if (u.twoweap && !can_twoweapon())