rolling boulder not in bones files
<Someone> Cced from rgrn: <email deleted> (<Someone>) writes: [killed by a boulder trap, left bones] > Then I realized... there's no boulder. Did the boulder disappear > because I died from the attack, thus bypassing the code that moves the > boulder to its intended destination? Did the creation of the bones > file destroy the boulder? Do boulder traps sometimes get > "deactivated" when bones files are loaded? The first of these. If you look at launch_obj(), there's an obj_extract_self() early on, then all the tracking its trajectory, then a place_object() when it comes to rest; since the thitu() call kills you during the trajectory part, the boulder never gets re-placed onto the map. This is, I think, a bug (and one that will apply to any monster-thrown object that kills you, as well); reported to the DevTeam.
This commit is contained in:
@@ -49,6 +49,7 @@ fractured boulders or statues produced inconsistent object settings on the
|
||||
really fix rolling boulder bug C340-18, the previous "fix" reversed the test
|
||||
monster throwing greased weapon has same chance for slip/misfire as player
|
||||
killing a pet by displacing it into a trap now yields experience
|
||||
prevent a rolling boulder that is in motion from vanishing in bones files
|
||||
|
||||
|
||||
Platform- and/or Interface-Specific Fixes
|
||||
|
||||
@@ -2102,6 +2102,8 @@ E boolean NDECL(unconscious);
|
||||
E boolean NDECL(lava_effects);
|
||||
E void FDECL(blow_up_landmine, (struct trap *));
|
||||
E int FDECL(launch_obj,(SHORT_P,int,int,int,int,int));
|
||||
E boolean NDECL(launch_in_progress);
|
||||
E void NDECL(force_launch_placement);
|
||||
E boolean FDECL(uteetering_at_seen_pit, (struct trap *));
|
||||
|
||||
/* ### u_init.c ### */
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* SCCS Id: @(#)end.c 3.4 2003/03/10 */
|
||||
/* SCCS Id: @(#)end.c 3.4 2004/08/23 */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -668,6 +668,8 @@ die:
|
||||
if (how == TURNED_SLIME)
|
||||
u.ugrave_arise = PM_GREEN_SLIME;
|
||||
|
||||
if (bones_ok && launch_in_progress()) force_launch_placement();
|
||||
|
||||
if (bones_ok && u.ugrave_arise < LOW_PM) {
|
||||
/* corpse gets burnt up too */
|
||||
if (how == BURNING)
|
||||
|
||||
70
src/trap.c
70
src/trap.c
@@ -1,4 +1,4 @@
|
||||
/* SCCS Id: @(#)trap.c 3.4 2004/06/12 */
|
||||
/* SCCS Id: @(#)trap.c 3.4 2004/08/23 */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -21,6 +21,7 @@ STATIC_DCL int FDECL(disarm_shooting_trap, (struct trap *, int));
|
||||
STATIC_DCL int FDECL(try_lift, (struct monst *, struct trap *, int, BOOLEAN_P));
|
||||
STATIC_DCL int FDECL(help_monster_out, (struct monst *, struct trap *));
|
||||
STATIC_DCL boolean FDECL(thitm, (int,struct monst *,struct obj *,int,BOOLEAN_P));
|
||||
STATIC_DCL void FDECL(launch_drop_spot, (struct obj *, XCHAR_P, XCHAR_P));
|
||||
STATIC_DCL int FDECL(mkroll_launch,
|
||||
(struct trap *,XCHAR_P,XCHAR_P,SHORT_P,long));
|
||||
STATIC_DCL boolean FDECL(isclearpath,(coord *, int, SCHAR_P, SCHAR_P));
|
||||
@@ -1282,6 +1283,48 @@ struct trap *trap;
|
||||
seetrap(trap); /* and it isn't concealed */
|
||||
}
|
||||
|
||||
/*
|
||||
* The following are used to track launched objects to
|
||||
* prevent them from vanishing if you are killed. They
|
||||
* will reappear at the launchplace in bones files.
|
||||
*/
|
||||
static struct {
|
||||
struct obj *obj;
|
||||
xchar x,y;
|
||||
} launchplace;
|
||||
|
||||
static void
|
||||
launch_drop_spot(obj,x,y)
|
||||
struct obj *obj;
|
||||
xchar x,y;
|
||||
{
|
||||
if (!obj) {
|
||||
launchplace.obj = (struct obj *)0;
|
||||
launchplace.x = 0;
|
||||
launchplace.y = 0;
|
||||
} else {
|
||||
launchplace.obj = obj;
|
||||
launchplace.x = x;
|
||||
launchplace.y = y;
|
||||
}
|
||||
}
|
||||
|
||||
boolean
|
||||
launch_in_progress()
|
||||
{
|
||||
if (launchplace.obj) return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
force_launch_placement()
|
||||
{
|
||||
if (launchplace.obj) {
|
||||
launchplace.obj->otrapped = 0;
|
||||
place_object(launchplace.obj, launchplace.x, launchplace.y);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Move obj from (x1,y1) to (x2,y2)
|
||||
*
|
||||
@@ -1366,6 +1409,15 @@ int style;
|
||||
tmp_at(DISP_FLASH, obj_to_glyph(singleobj));
|
||||
tmp_at(bhitpos.x, bhitpos.y);
|
||||
}
|
||||
/* Mark a spot to place object in bones files to prevent
|
||||
* loss of object. Use the starting spot to ensure that
|
||||
* a rolling boulder will still launch, which it wouldn't
|
||||
* do if left midstream. Unfortunately we can't use the
|
||||
* target resting spot, because there are some things/situations
|
||||
* that would prevent it from ever getting there (bars), and we
|
||||
* can't tell that yet.
|
||||
*/
|
||||
launch_drop_spot(singleobj, bhitpos.x, bhitpos.y);
|
||||
|
||||
/* Set the object in motion */
|
||||
while(dist-- > 0 && !used_up) {
|
||||
@@ -1389,12 +1441,14 @@ int style;
|
||||
singleobj->otrapped = 0;
|
||||
(void) mpickobj(mtmp, singleobj);
|
||||
used_up = TRUE;
|
||||
launch_drop_spot((struct obj *)0, 0, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ohitmon(mtmp,singleobj,
|
||||
(style==ROLL) ? -1 : dist, FALSE)) {
|
||||
used_up = TRUE;
|
||||
launch_drop_spot((struct obj *)0, 0, 0);
|
||||
break;
|
||||
}
|
||||
} else if (bhitpos.x == u.ux && bhitpos.y == u.uy) {
|
||||
@@ -1408,6 +1462,7 @@ int style;
|
||||
if (down_gate(bhitpos.x, bhitpos.y) != -1) {
|
||||
if(ship_object(singleobj, bhitpos.x, bhitpos.y, FALSE)){
|
||||
used_up = TRUE;
|
||||
launch_drop_spot((struct obj *)0, 0, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1430,6 +1485,7 @@ int style;
|
||||
if (cansee(bhitpos.x,bhitpos.y))
|
||||
newsym(bhitpos.x,bhitpos.y);
|
||||
used_up = TRUE;
|
||||
launch_drop_spot((struct obj *)0, 0, 0);
|
||||
}
|
||||
break;
|
||||
case LEVEL_TELEP:
|
||||
@@ -1455,6 +1511,7 @@ int style;
|
||||
}
|
||||
seetrap(t);
|
||||
used_up = TRUE;
|
||||
launch_drop_spot((struct obj *)0, 0, 0);
|
||||
break;
|
||||
case PIT:
|
||||
case SPIKED_PIT:
|
||||
@@ -1463,8 +1520,10 @@ int style;
|
||||
/* the boulder won't be used up if there is a
|
||||
monster in the trap; stop rolling anyway */
|
||||
x2 = bhitpos.x, y2 = bhitpos.y; /* stops here */
|
||||
if (flooreffects(singleobj, x2, y2, "fall"))
|
||||
if (flooreffects(singleobj, x2, y2, "fall")) {
|
||||
used_up = TRUE;
|
||||
launch_drop_spot((struct obj *)0, 0, 0);
|
||||
}
|
||||
dist = -1; /* stop rolling immediately */
|
||||
break;
|
||||
}
|
||||
@@ -1472,6 +1531,7 @@ int style;
|
||||
}
|
||||
if (flooreffects(singleobj, bhitpos.x, bhitpos.y, "fall")) {
|
||||
used_up = TRUE;
|
||||
launch_drop_spot((struct obj *)0, 0, 0);
|
||||
break;
|
||||
}
|
||||
if (otyp == BOULDER &&
|
||||
@@ -1507,12 +1567,16 @@ int style;
|
||||
levl[bhitpos.x + dx][bhitpos.y + dy].typ == IRONBARS) {
|
||||
x2 = bhitpos.x, y2 = bhitpos.y; /* object stops here */
|
||||
if (hits_bars(&singleobj, x2, y2, !rn2(20), 0)) {
|
||||
if (!singleobj) used_up = TRUE;
|
||||
if (!singleobj) {
|
||||
used_up = TRUE;
|
||||
launch_drop_spot((struct obj *)0, 0, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
tmp_at(DISP_END, 0);
|
||||
launch_drop_spot((struct obj *)0, 0, 0);
|
||||
if (!used_up) {
|
||||
singleobj->otrapped = 0;
|
||||
place_object(singleobj, x2,y2);
|
||||
|
||||
Reference in New Issue
Block a user