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
|
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
@@ -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
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user