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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
22
src/trap.c
22
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;
|
||||
|
||||
Reference in New Issue
Block a user