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:
nethack.allison
2004-08-23 16:57:59 +00:00
parent 10eea7710d
commit d84ad3ec3c
4 changed files with 73 additions and 4 deletions

View File

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

View File

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

View File

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

View File

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