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

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
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

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 */
/* 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

View File

@@ -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 */

View File

@@ -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

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));
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;

View File

@@ -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;