From: PatR Date: Mon, 9 May 2016 23:21:35 +0000 (-0700) Subject: fix #H4333 - angry god vs pacifist conduct X-Git-Tag: NetHack-3.6.1_RC01~785 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2cffaccb3f964bd5746acada4bea22b80f30f97f;p=nethack fix #H4333 - angry god vs pacifist conduct 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).... --- diff --git a/doc/fixes36.1 b/doc/fixes36.1 index a3aeb01a5..eb2c76985 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -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 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 diff --git a/src/mon.c b/src/mon.c index b4a8f97f6..adae17563 100644 --- 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; diff --git a/src/pray.c b/src/pray.c index 604e0663f..6d2908990 100644 --- a/src/pray.c +++ b/src/pray.c @@ -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!"); }