]> granicus.if.org Git - nethack/commitdiff
fix #H4333 - angry god vs pacifist conduct
authorPatR <rankin@nethack.org>
Mon, 9 May 2016 23:21:35 +0000 (16:21 -0700)
committerPatR <rankin@nethack.org>
Mon, 9 May 2016 23:21:35 +0000 (16:21 -0700)
When you're swallowed, an angry god trying to zap you will kill
the engulfer and hero gets credit (experience) and blame (possible
loss of luck and/or alignment if engulfer is peaceful or tame) for
the act.  But hero didn't actually kill the critter, so don't
increment the kill counter that monitors pacifism.

I think there are other circumstances where hero gets credit and/or
blame for something he or she didn't directly do, but offhand I
can't think of them.  They might warrant similar treatment.

Tidying of xkilled() triggered by malformed block comment which is
actually a hybrid of an end of line comment (the boulder one, not
the 'dest' parameter one)....

doc/fixes36.1
src/mon.c
src/pray.c

index a3aeb01a58cde2f8d7e70fbfba00695b049db3e4..eb2c76985e4c852887888e83ecf2a6a24da3f6a6 100644 (file)
@@ -231,6 +231,9 @@ Vlad's tower2 and tower3 didn't show up in wizard-mode ^O output or ^V? menu
 remove extra space from "All of your  <stack-of-potions> boil and explode."
        (also applies to potions freezing and to scrolls burning)
 effects of cursed potion of levitation were skipped if already levitating
+when engulfed, having swallower be killed by angry deity trying to zap hero
+       no longer violates pacifist conduct (other penalties--reduced luck or
+       alignment--still apply if target is something you shouldn't kill)
 
 
 Fixes to Post-3.6.0 Problems that Were Exposed Via git Respository
index b4a8f97f65c57d90392a3d75dde5744bd68750e7..adae1756331011dc92e5cd53d710d32f6e73ff0b 100644 (file)
--- a/src/mon.c
+++ b/src/mon.c
@@ -2158,47 +2158,36 @@ struct monst *mtmp;
 
 /* the player has killed the monster mtmp */
 void
-xkilled(mtmp, dest)
+xkilled(mtmp, dflags)
 struct monst *mtmp;
-int dest; /* dest==1, normal; dest==0, don't print message; dest==2, don't
-             drop corpse either; dest==3, message but no corpse */
+int dflags; /* disposition flags:  1 => give message, 2 => suppress corpse */
 {
     int tmp, mndx, x = mtmp->mx, y = mtmp->my;
     struct permonst *mdat;
     struct obj *otmp;
     struct trap *t;
-    boolean wasinside = u.uswallow && (u.ustuck == mtmp);
-    boolean burycorpse = FALSE;
+    boolean wasinside = u.uswallow && (u.ustuck == mtmp), burycorpse = FALSE,
+            givemsg = (dflags & 1) != 0, nocorpse = (dflags & 2) != 0;
 
     /* KMH, conduct */
     u.uconduct.killer++;
 
-    if (dest & 1) {
-        const char *verb = nonliving(mtmp->data) ? "destroy" : "kill";
-
-        if (!wasinside && !canspotmon(mtmp))
-            You("%s it!", verb);
-        else {
-            You("%s %s!", verb,
-                !mtmp->mtame
-                    ? mon_nam(mtmp)
-                    : x_monnam(mtmp,
-                               (has_mname(mtmp)) ? ARTICLE_NONE : ARTICLE_THE,
-                               "poor",
-                               (has_mname(mtmp)) ? SUPPRESS_SADDLE : 0,
-                               FALSE));
-        }
-    }
+    if (givemsg)
+        You("%s %s!",
+            nonliving(mtmp->data) ? "destroy" : "kill",
+            !(wasinside || canspotmon(mtmp)) ? "it"
+              : !mtmp->mtame ? mon_nam(mtmp)
+                : x_monnam(mtmp, has_mname(mtmp) ? ARTICLE_NONE : ARTICLE_THE,
+                           "poor", has_mname(mtmp) ? SUPPRESS_SADDLE : 0,
+                           FALSE));
 
     if (mtmp->mtrapped && (t = t_at(x, y)) != 0
         && (t->ttyp == PIT || t->ttyp == SPIKED_PIT)) {
         if (sobj_at(BOULDER, x, y))
-            dest |= 2; /*
-        * Prevent corpses/treasure being created "on top"
-        * of the boulder that is about to fall in. This is
-        * out of order, but cannot be helped unless this
-        * whole routine is rearranged.
-        */
+            nocorpse = TRUE; /* Prevent corpses/treasure being created
+                                "on top" of boulder that is about to fall in.
+                                This is out of order, but cannot be helped
+                                unless this whole routine is rearranged. */
         if (m_carrying(mtmp, BOULDER))
             burycorpse = TRUE;
     }
@@ -2228,8 +2217,7 @@ int dest; /* dest==1, normal; dest==0, don't print message; dest==2, don't
     if (mtmp->mhp > 0) { /* monster lifesaved */
         /* Cannot put the non-visible lifesaving message in
          * lifesaved_monster() since the message appears only when you
-         * kill it (as opposed to visible lifesaving which always
-         * appears).
+         * kill it (as opposed to visible lifesaving which always appears).
          */
         stoned = FALSE;
         if (!cansee(x, y) && !vamp_rise_msg)
@@ -2245,7 +2233,7 @@ int dest; /* dest==1, normal; dest==0, don't print message; dest==2, don't
         goto cleanup;
     }
 
-    if ((dest & 2) || LEVEL_SPECIFIC_NOCORPSE(mdat))
+    if (nocorpse || LEVEL_SPECIFIC_NOCORPSE(mdat))
         goto cleanup;
 
 #ifdef MAIL
@@ -2272,7 +2260,7 @@ int dest; /* dest==1, normal; dest==0, don't print message; dest==2, don't
                 /* oc_big is also oc_bimanual and oc_bulky */
                 && (otmp->owt > 30 || objects[otyp].oc_big)) {
                 delobj(otmp);
-            } else if (!flooreffects(otmp, x, y, (dest & 1) ? "fall" : "")) {
+            } else if (!flooreffects(otmp, x, y, givemsg ? "fall" : "")) {
                 place_object(otmp, x, y);
                 stackobj(otmp);
             }
@@ -2282,7 +2270,7 @@ int dest; /* dest==1, normal; dest==0, don't print message; dest==2, don't
             cadaver = make_corpse(mtmp, burycorpse ? CORPSTAT_BURIED
                                                    : CORPSTAT_NONE);
             if (burycorpse && cadaver && cansee(x, y) && !mtmp->minvis
-                && cadaver->where == OBJ_BURIED && (dest & 1)) {
+                && cadaver->where == OBJ_BURIED && givemsg) {
                 pline("%s corpse ends up buried.", s_suffix(Monnam(mtmp)));
             }
         }
@@ -2294,7 +2282,8 @@ int dest; /* dest==1, normal; dest==0, don't print message; dest==2, don't
 
 cleanup:
     /* punish bad behaviour */
-    if (is_human(mdat) && (!always_hostile(mdat) && mtmp->malign <= 0)
+    if (is_human(mdat)
+        && (!always_hostile(mdat) && mtmp->malign <= 0)
         && (mndx < PM_ARCHEOLOGIST || mndx > PM_WIZARD)
         && u.ualign.type != A_CHAOTIC) {
         HTelepat &= ~INTRINSIC;
index 604e0663f4ee48c397d8fb0cb3ee6dc38c9a83f3..6d29089906d6bf7600d8f51db89c5187459e7945 100644 (file)
@@ -520,9 +520,8 @@ int trouble;
     }
 }
 
-/* "I am sometimes shocked by...  the nuns who never take a bath without
- * wearing a bathrobe all the time.  When asked why, since no man can see
- * them,
+/* "I am sometimes shocked by... the nuns who never take a bath without
+ * wearing a bathrobe all the time.  When asked why, since no man can see them,
  * they reply 'Oh, but you forget the good God'.  Apparently they conceive of
  * the Deity as a Peeping Tom, whose omnipotence enables Him to see through
  * bathroom walls, but who is foiled by bathrobes." --Bertrand Russell, 1943
@@ -532,6 +531,8 @@ STATIC_OVL void
 god_zaps_you(resp_god)
 aligntyp resp_god;
 {
+    long oldkillcount = u.uconduct.killer;
+
     if (u.uswallow) {
         pline(
           "Suddenly a bolt of lightning comes down at you from the heavens!");
@@ -540,8 +541,11 @@ aligntyp resp_god;
             pline("%s fries to a crisp!", Monnam(u.ustuck));
             /* Yup, you get experience.  It takes guts to successfully
              * pull off this trick on your god, anyway.
+             * Other credit/blame applies (luck or alignment adjustments),
+             * but not direct kill count (pacifist conduct).
              */
             xkilled(u.ustuck, 0);
+            u.uconduct.killer = oldkillcount;
         } else
             pline("%s seems unaffected.", Monnam(u.ustuck));
     } else {
@@ -566,6 +570,7 @@ aligntyp resp_god;
         if (!resists_disint(u.ustuck)) {
             pline("%s disintegrates into a pile of dust!", Monnam(u.ustuck));
             xkilled(u.ustuck, 2); /* no corpse */
+            u.uconduct.killer = oldkillcount;
         } else
             pline("%s seems unaffected.", Monnam(u.ustuck));
     } else {
@@ -585,9 +590,9 @@ aligntyp resp_god;
             (void) destroy_arm(uarm);
         if (uarmu && !uarm && !uarmc)
             (void) destroy_arm(uarmu);
-        if (!Disint_resistance)
+        if (!Disint_resistance) {
             fry_by_god(resp_god, TRUE);
-        else {
+        else {
             You("bask in its %s glow for a minute...", NH_BLACK);
             godvoice(resp_god, "I believe it not!");
         }