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
|
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
|
monster throwing greased weapon has same chance for slip/misfire as player
|
||||||
killing a pet by displacing it into a trap now yields experience
|
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
|
Platform- and/or Interface-Specific Fixes
|
||||||
|
|||||||
@@ -2102,6 +2102,8 @@ E boolean NDECL(unconscious);
|
|||||||
E boolean NDECL(lava_effects);
|
E boolean NDECL(lava_effects);
|
||||||
E void FDECL(blow_up_landmine, (struct trap *));
|
E void FDECL(blow_up_landmine, (struct trap *));
|
||||||
E int FDECL(launch_obj,(SHORT_P,int,int,int,int,int));
|
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 *));
|
E boolean FDECL(uteetering_at_seen_pit, (struct trap *));
|
||||||
|
|
||||||
/* ### u_init.c ### */
|
/* ### 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. */
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
|
|
||||||
@@ -668,6 +668,8 @@ die:
|
|||||||
if (how == TURNED_SLIME)
|
if (how == TURNED_SLIME)
|
||||||
u.ugrave_arise = PM_GREEN_SLIME;
|
u.ugrave_arise = PM_GREEN_SLIME;
|
||||||
|
|
||||||
|
if (bones_ok && launch_in_progress()) force_launch_placement();
|
||||||
|
|
||||||
if (bones_ok && u.ugrave_arise < LOW_PM) {
|
if (bones_ok && u.ugrave_arise < LOW_PM) {
|
||||||
/* corpse gets burnt up too */
|
/* corpse gets burnt up too */
|
||||||
if (how == BURNING)
|
if (how == BURNING)
|
||||||
|
|||||||
+67
-3
@@ -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. */
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* 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(try_lift, (struct monst *, struct trap *, int, BOOLEAN_P));
|
||||||
STATIC_DCL int FDECL(help_monster_out, (struct monst *, struct trap *));
|
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 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,
|
STATIC_DCL int FDECL(mkroll_launch,
|
||||||
(struct trap *,XCHAR_P,XCHAR_P,SHORT_P,long));
|
(struct trap *,XCHAR_P,XCHAR_P,SHORT_P,long));
|
||||||
STATIC_DCL boolean FDECL(isclearpath,(coord *, int, SCHAR_P, SCHAR_P));
|
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 */
|
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)
|
* Move obj from (x1,y1) to (x2,y2)
|
||||||
*
|
*
|
||||||
@@ -1366,6 +1409,15 @@ int style;
|
|||||||
tmp_at(DISP_FLASH, obj_to_glyph(singleobj));
|
tmp_at(DISP_FLASH, obj_to_glyph(singleobj));
|
||||||
tmp_at(bhitpos.x, bhitpos.y);
|
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 */
|
/* Set the object in motion */
|
||||||
while(dist-- > 0 && !used_up) {
|
while(dist-- > 0 && !used_up) {
|
||||||
@@ -1389,12 +1441,14 @@ int style;
|
|||||||
singleobj->otrapped = 0;
|
singleobj->otrapped = 0;
|
||||||
(void) mpickobj(mtmp, singleobj);
|
(void) mpickobj(mtmp, singleobj);
|
||||||
used_up = TRUE;
|
used_up = TRUE;
|
||||||
|
launch_drop_spot((struct obj *)0, 0, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ohitmon(mtmp,singleobj,
|
if (ohitmon(mtmp,singleobj,
|
||||||
(style==ROLL) ? -1 : dist, FALSE)) {
|
(style==ROLL) ? -1 : dist, FALSE)) {
|
||||||
used_up = TRUE;
|
used_up = TRUE;
|
||||||
|
launch_drop_spot((struct obj *)0, 0, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (bhitpos.x == u.ux && bhitpos.y == u.uy) {
|
} 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 (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;
|
||||||
|
launch_drop_spot((struct obj *)0, 0, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1430,6 +1485,7 @@ int style;
|
|||||||
if (cansee(bhitpos.x,bhitpos.y))
|
if (cansee(bhitpos.x,bhitpos.y))
|
||||||
newsym(bhitpos.x,bhitpos.y);
|
newsym(bhitpos.x,bhitpos.y);
|
||||||
used_up = TRUE;
|
used_up = TRUE;
|
||||||
|
launch_drop_spot((struct obj *)0, 0, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LEVEL_TELEP:
|
case LEVEL_TELEP:
|
||||||
@@ -1455,6 +1511,7 @@ int style;
|
|||||||
}
|
}
|
||||||
seetrap(t);
|
seetrap(t);
|
||||||
used_up = TRUE;
|
used_up = TRUE;
|
||||||
|
launch_drop_spot((struct obj *)0, 0, 0);
|
||||||
break;
|
break;
|
||||||
case PIT:
|
case PIT:
|
||||||
case SPIKED_PIT:
|
case SPIKED_PIT:
|
||||||
@@ -1463,8 +1520,10 @@ int style;
|
|||||||
/* the boulder won't be used up if there is a
|
/* the boulder won't be used up if there is a
|
||||||
monster in the trap; stop rolling anyway */
|
monster in the trap; stop rolling anyway */
|
||||||
x2 = bhitpos.x, y2 = bhitpos.y; /* stops here */
|
x2 = bhitpos.x, y2 = bhitpos.y; /* stops here */
|
||||||
if (flooreffects(singleobj, x2, y2, "fall"))
|
if (flooreffects(singleobj, x2, y2, "fall")) {
|
||||||
used_up = TRUE;
|
used_up = TRUE;
|
||||||
|
launch_drop_spot((struct obj *)0, 0, 0);
|
||||||
|
}
|
||||||
dist = -1; /* stop rolling immediately */
|
dist = -1; /* stop rolling immediately */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1472,6 +1531,7 @@ int style;
|
|||||||
}
|
}
|
||||||
if (flooreffects(singleobj, bhitpos.x, bhitpos.y, "fall")) {
|
if (flooreffects(singleobj, bhitpos.x, bhitpos.y, "fall")) {
|
||||||
used_up = TRUE;
|
used_up = TRUE;
|
||||||
|
launch_drop_spot((struct obj *)0, 0, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (otyp == BOULDER &&
|
if (otyp == BOULDER &&
|
||||||
@@ -1507,12 +1567,16 @@ int style;
|
|||||||
levl[bhitpos.x + dx][bhitpos.y + dy].typ == IRONBARS) {
|
levl[bhitpos.x + dx][bhitpos.y + dy].typ == IRONBARS) {
|
||||||
x2 = bhitpos.x, y2 = bhitpos.y; /* object stops here */
|
x2 = bhitpos.x, y2 = bhitpos.y; /* object stops here */
|
||||||
if (hits_bars(&singleobj, x2, y2, !rn2(20), 0)) {
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tmp_at(DISP_END, 0);
|
tmp_at(DISP_END, 0);
|
||||||
|
launch_drop_spot((struct obj *)0, 0, 0);
|
||||||
if (!used_up) {
|
if (!used_up) {
|
||||||
singleobj->otrapped = 0;
|
singleobj->otrapped = 0;
|
||||||
place_object(singleobj, x2,y2);
|
place_object(singleobj, x2,y2);
|
||||||
|
|||||||
Reference in New Issue
Block a user