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.
This commit is contained in:
cohrs
2002-03-29 17:56:13 +00:00
parent 72048905ad
commit a1d3c539a9
6 changed files with 32 additions and 9 deletions
+1
View File
@@ -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 Wizard of Yendor will start harassing you after the invocation if you've
managed to get that far without ever killing him managed to get that far without ever killing him
characters polymorphed into centaurs can't wear boots 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 Platform- and/or Interface-Specific Fixes
+3 -2
View File
@@ -195,8 +195,9 @@ NEARDATA extern coord bhitpos; /* place where throw or zap hits or stops */
#define MAY_FRACTURE 0x10 /* boulders & statues may fracture */ #define MAY_FRACTURE 0x10 /* boulders & statues may fracture */
/* Macros for launching objects */ /* Macros for launching objects */
#define ROLL 1 #define ROLL 0x01 /* the object is rolling */
#define FLING 2 #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 */ /* Macros for explosion types */
#define EXPL_DARK 0 #define EXPL_DARK 0
+1
View File
@@ -70,6 +70,7 @@ struct obj {
Bitfield(olocked,1); /* object is locked */ Bitfield(olocked,1); /* object is locked */
Bitfield(obroken,1); /* lock has been broken */ Bitfield(obroken,1); /* lock has been broken */
Bitfield(otrapped,1); /* container is trapped */ Bitfield(otrapped,1); /* container is trapped */
/* or accidental tripped rolling boulder trap */
#define opoisoned otrapped /* object (weapon) is coated with poison */ #define opoisoned otrapped /* object (weapon) is coated with poison */
Bitfield(recharged,3); /* number of times it's been recharged */ Bitfield(recharged,3); /* number of times it's been recharged */
+2
View File
@@ -1313,6 +1313,8 @@ boolean shop_floor_obj;
otmp->ox = cc.x; otmp->ox = cc.x;
otmp->oy = cc.y; otmp->oy = cc.y;
otmp->owornmask = (long)toloc; otmp->owornmask = (long)toloc;
/* boulder from rolling boulder trap, no longer part of the trap */
if (otmp->otyp == BOULDER) otmp->otrapped = 0;
if(impact) { if(impact) {
/* the objs impacted may be in a shop other than /* the objs impacted may be in a shop other than
+7 -3
View File
@@ -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)); if (vis) hit(distant_name(otmp,mshot_xname), mtmp, exclam(damage));
else if (verbose) pline("It is hit%s", 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 (resists_poison(mtmp)) {
if (vis) pline_The("poison doesn't seem to affect %s.", if (vis) pline_The("poison doesn't seem to affect %s.",
mon_nam(mtmp)); 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), pline("%s is %s!", Monnam(mtmp),
(nonliving(mtmp->data) || !vis) (nonliving(mtmp->data) || !vis)
? "destroyed" : "killed"); ? "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); else mondied(mtmp);
} }
@@ -377,7 +380,8 @@ m_throw(mon, x, y, dx, dy, range, obj)
if (dam < 1) dam = 1; if (dam < 1) dam = 1;
hitu = thitu(hitv, dam, singleobj, (char *)0); hitu = thitu(hitv, dam, singleobj, (char *)0);
} }
if (hitu && singleobj->opoisoned) { if (hitu && singleobj->opoisoned &&
is_poisonable(singleobj)) {
char onmbuf[BUFSZ], knmbuf[BUFSZ]; char onmbuf[BUFSZ], knmbuf[BUFSZ];
struct obj otmp; struct obj otmp;
unsigned save_ocknown; unsigned save_ocknown;
+18 -4
View File
@@ -1000,17 +1000,19 @@ glovecheck: (void) rust_dmg(uarmg, "gauntlets", 1, TRUE, &youmonst);
fill_pit(u.ux, u.uy); fill_pit(u.ux, u.uy);
break; break;
case ROLLING_BOULDER_TRAP: case ROLLING_BOULDER_TRAP: {
int style = ROLL | (trap->tseen ? LAUNCH_KNOWN : 0);
seetrap(trap); seetrap(trap);
pline("Click! You trigger a rolling boulder trap!"); pline("Click! You trigger a rolling boulder trap!");
if(!launch_obj(BOULDER, trap->launch.x, trap->launch.y, 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); deltrap(trap);
newsym(u.ux,u.uy); /* get rid of trap symbol */ newsym(u.ux,u.uy); /* get rid of trap symbol */
pline("Fortunately for you, no boulder was released."); pline("Fortunately for you, no boulder was released.");
} }
break; break;
}
case MAGIC_PORTAL: case MAGIC_PORTAL:
seetrap(trap); seetrap(trap);
domagicportal(trap); domagicportal(trap);
@@ -1194,6 +1196,11 @@ int style;
dx = sgn(x2 - x1); dx = sgn(x2 - x1);
dy = sgn(y2 - y1); dy = sgn(y2 - y1);
switch (style) { switch (style) {
case ROLL|LAUNCH_KNOWN:
/* use otrapped as a flag to ohitmon */
singleobj->otrapped = 1;
style &= ~LAUNCH_KNOWN;
/* fall through */
case ROLL: case ROLL:
delaycnt = 2; delaycnt = 2;
/* fall through */ /* fall through */
@@ -1223,6 +1230,7 @@ int style;
if (rn2(3)) { if (rn2(3)) {
pline("%s snatches the boulder.", pline("%s snatches the boulder.",
Monnam(mtmp)); Monnam(mtmp));
singleobj->otrapped = 0;
(void) mpickobj(mtmp, singleobj); (void) mpickobj(mtmp, singleobj);
used_up = TRUE; used_up = TRUE;
break; break;
@@ -1242,7 +1250,7 @@ int style;
} }
if (style == ROLL) { if (style == ROLL) {
if (down_gate(bhitpos.x, bhitpos.y) != -1) { 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; used_up = TRUE;
break; break;
} }
@@ -1258,6 +1266,7 @@ int style;
deltrap(t); deltrap(t);
del_engr_at(bhitpos.x,bhitpos.y); del_engr_at(bhitpos.x,bhitpos.y);
place_object(singleobj, bhitpos.x, bhitpos.y); place_object(singleobj, bhitpos.x, bhitpos.y);
singleobj->otrapped = 0;
fracture_rock(singleobj); fracture_rock(singleobj);
scatter(bhitpos.x,bhitpos.y, 4, scatter(bhitpos.x,bhitpos.y, 4,
MAY_DESTROY|MAY_HIT|MAY_FRACTURE|VIS_EFFECTS, MAY_DESTROY|MAY_HIT|MAY_FRACTURE|VIS_EFFECTS,
@@ -1273,6 +1282,7 @@ int style;
pline("Suddenly the rolling boulder disappears!"); pline("Suddenly the rolling boulder disappears!");
else else
You_hear("a rumbling stop abruptly."); You_hear("a rumbling stop abruptly.");
singleobj->otrapped = 0;
if (t->ttyp == TELEP_TRAP) if (t->ttyp == TELEP_TRAP)
rloco(singleobj); rloco(singleobj);
else { else {
@@ -1304,6 +1314,9 @@ int style;
You_hear("a loud crash%s!", You_hear("a loud crash%s!",
cansee(bhitpos.x, bhitpos.y) ? bmsg : ""); cansee(bhitpos.x, bhitpos.y) ? bmsg : "");
obj_extract_self(otmp2); 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); place_object(singleobj, bhitpos.x, bhitpos.y);
singleobj = otmp2; singleobj = otmp2;
otmp2 = (struct obj *)0; otmp2 = (struct obj *)0;
@@ -1319,6 +1332,7 @@ int style;
} }
tmp_at(DISP_END, 0); tmp_at(DISP_END, 0);
if (!used_up) { if (!used_up) {
singleobj->otrapped = 0;
place_object(singleobj, x2,y2); place_object(singleobj, x2,y2);
newsym(x2,y2); newsym(x2,y2);
return 1; return 1;