From: cohrs Date: Fri, 29 Mar 2002 17:56:13 +0000 (+0000) Subject: Rolling boulder traps and pacifism X-Git-Tag: MOVE2GIT~2866 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a1d3c539a9057a4676787fdb70eb34146d8aa01a;p=nethack Rolling boulder traps and pacifism If you stepped on an unknown rolling boulder trap, and that rolling boulder hit a monster and killed it, you would be called a killer. This makes playing a pacifism conduct game rather difficult. - track boulders from unknown rolling boulder traps, and don't charge/credit hero if they kill monsters. This is done by temporarily setting otrapped on such boulders. - boulders from known traps are still charged/credited to the hero - fix a couple places in ohitmon where is_poisonable wasn't checked along with opoisoned. --- diff --git a/doc/fixes34.1 b/doc/fixes34.1 index 3af3739af..9e381ded1 100644 --- a/doc/fixes34.1 +++ b/doc/fixes34.1 @@ -29,6 +29,7 @@ let lev_comp and dgn_comp accept optional carriage return character prior to Wizard of Yendor will start harassing you after the invocation if you've managed to get that far without ever killing him characters polymorphed into centaurs can't wear boots +if an unknown rolling boulder trap kills a monster, you shouldn't be a murderer Platform- and/or Interface-Specific Fixes diff --git a/include/hack.h b/include/hack.h index 6529f4f60..3a3aadffb 100644 --- a/include/hack.h +++ b/include/hack.h @@ -195,8 +195,9 @@ NEARDATA extern coord bhitpos; /* place where throw or zap hits or stops */ #define MAY_FRACTURE 0x10 /* boulders & statues may fracture */ /* Macros for launching objects */ -#define ROLL 1 -#define FLING 2 +#define ROLL 0x01 /* the object is rolling */ +#define FLING 0x02 /* the object is flying thru the air */ +#define LAUNCH_KNOWN 0x80 /* the hero caused this by explicit action */ /* Macros for explosion types */ #define EXPL_DARK 0 diff --git a/include/obj.h b/include/obj.h index e118b1d2e..324a1409d 100644 --- a/include/obj.h +++ b/include/obj.h @@ -70,6 +70,7 @@ struct obj { Bitfield(olocked,1); /* object is locked */ Bitfield(obroken,1); /* lock has been broken */ Bitfield(otrapped,1); /* container is trapped */ + /* or accidental tripped rolling boulder trap */ #define opoisoned otrapped /* object (weapon) is coated with poison */ Bitfield(recharged,3); /* number of times it's been recharged */ diff --git a/src/dokick.c b/src/dokick.c index 9cf1acfae..aff4e2987 100644 --- a/src/dokick.c +++ b/src/dokick.c @@ -1313,6 +1313,8 @@ boolean shop_floor_obj; otmp->ox = cc.x; otmp->oy = cc.y; otmp->owornmask = (long)toloc; + /* boulder from rolling boulder trap, no longer part of the trap */ + if (otmp->otyp == BOULDER) otmp->otrapped = 0; if(impact) { /* the objs impacted may be in a shop other than diff --git a/src/mthrowu.c b/src/mthrowu.c index 1943b3d82..a397191cb 100644 --- a/src/mthrowu.c +++ b/src/mthrowu.c @@ -188,7 +188,7 @@ boolean verbose; /* give message(s) even when you can't see what happened */ if (vis) hit(distant_name(otmp,mshot_xname), mtmp, exclam(damage)); else if (verbose) pline("It is hit%s", exclam(damage)); - if (otmp->opoisoned) { + if (otmp->opoisoned && is_poisonable(otmp)) { if (resists_poison(mtmp)) { if (vis) pline_The("poison doesn't seem to affect %s.", mon_nam(mtmp)); @@ -223,7 +223,10 @@ boolean verbose; /* give message(s) even when you can't see what happened */ pline("%s is %s!", Monnam(mtmp), (nonliving(mtmp->data) || !vis) ? "destroyed" : "killed"); - if (!flags.mon_moving) xkilled(mtmp,0); + /* don't blame hero for unknown rolling boulder trap */ + if (!flags.mon_moving && + (otmp->otyp != BOULDER || range >= 0 || !otmp->otrapped)) + xkilled(mtmp,0); else mondied(mtmp); } @@ -377,7 +380,8 @@ m_throw(mon, x, y, dx, dy, range, obj) if (dam < 1) dam = 1; hitu = thitu(hitv, dam, singleobj, (char *)0); } - if (hitu && singleobj->opoisoned) { + if (hitu && singleobj->opoisoned && + is_poisonable(singleobj)) { char onmbuf[BUFSZ], knmbuf[BUFSZ]; struct obj otmp; unsigned save_ocknown; diff --git a/src/trap.c b/src/trap.c index 82d07456f..be96ae52e 100644 --- a/src/trap.c +++ b/src/trap.c @@ -1000,17 +1000,19 @@ glovecheck: (void) rust_dmg(uarmg, "gauntlets", 1, TRUE, &youmonst); fill_pit(u.ux, u.uy); break; - case ROLLING_BOULDER_TRAP: + case ROLLING_BOULDER_TRAP: { + int style = ROLL | (trap->tseen ? LAUNCH_KNOWN : 0); + seetrap(trap); pline("Click! You trigger a rolling boulder trap!"); if(!launch_obj(BOULDER, trap->launch.x, trap->launch.y, - trap->launch2.x,trap->launch2.y, ROLL)) { + trap->launch2.x, trap->launch2.y, style)) { deltrap(trap); newsym(u.ux,u.uy); /* get rid of trap symbol */ pline("Fortunately for you, no boulder was released."); } break; - + } case MAGIC_PORTAL: seetrap(trap); domagicportal(trap); @@ -1194,6 +1196,11 @@ int style; dx = sgn(x2 - x1); dy = sgn(y2 - y1); switch (style) { + case ROLL|LAUNCH_KNOWN: + /* use otrapped as a flag to ohitmon */ + singleobj->otrapped = 1; + style &= ~LAUNCH_KNOWN; + /* fall through */ case ROLL: delaycnt = 2; /* fall through */ @@ -1223,6 +1230,7 @@ int style; if (rn2(3)) { pline("%s snatches the boulder.", Monnam(mtmp)); + singleobj->otrapped = 0; (void) mpickobj(mtmp, singleobj); used_up = TRUE; break; @@ -1242,7 +1250,7 @@ int style; } if (style == ROLL) { if (down_gate(bhitpos.x, bhitpos.y) != -1) { - if (ship_object(singleobj, bhitpos.x, bhitpos.y, FALSE)){ + if(ship_object(singleobj, bhitpos.x, bhitpos.y, FALSE)){ used_up = TRUE; break; } @@ -1258,6 +1266,7 @@ int style; deltrap(t); del_engr_at(bhitpos.x,bhitpos.y); place_object(singleobj, bhitpos.x, bhitpos.y); + singleobj->otrapped = 0; fracture_rock(singleobj); scatter(bhitpos.x,bhitpos.y, 4, MAY_DESTROY|MAY_HIT|MAY_FRACTURE|VIS_EFFECTS, @@ -1273,6 +1282,7 @@ int style; pline("Suddenly the rolling boulder disappears!"); else You_hear("a rumbling stop abruptly."); + singleobj->otrapped = 0; if (t->ttyp == TELEP_TRAP) rloco(singleobj); else { @@ -1304,6 +1314,9 @@ int style; You_hear("a loud crash%s!", cansee(bhitpos.x, bhitpos.y) ? bmsg : ""); obj_extract_self(otmp2); + /* pass off the otrapped flag to the next boulder */ + otmp2->otrapped = singleobj->otrapped; + singleobj->otrapped = 0; place_object(singleobj, bhitpos.x, bhitpos.y); singleobj = otmp2; otmp2 = (struct obj *)0; @@ -1319,6 +1332,7 @@ int style; } tmp_at(DISP_END, 0); if (!used_up) { + singleobj->otrapped = 0; place_object(singleobj, x2,y2); newsym(x2,y2); return 1;