allow a parent function to restrict use of placebc

placebc was triggering an impossible sometimes on the plane of
water

It turned out to be because movebubbles issued an
unplacebc(), but a downstream function called
placebc(), so when movebubbles() issued its own
placebc() there was a problem.

The downstream function that beat movebubbles to the placebc()
turned out to be unstuck(). There could be others.
This commit is contained in:
nhmall
2019-06-04 21:18:46 -04:00
parent 05a0d10097
commit a65682f58e
5 changed files with 185 additions and 42 deletions
+2 -1
View File
@@ -51,7 +51,8 @@ similar perm_invent issue when lock state known and/or contents known become
blessed scroll of remove curse read while confused might be shown to operate blessed scroll of remove curse read while confused might be shown to operate
on itself by perm_invent after player is told that it has disappeared on itself by perm_invent after player is told that it has disappeared
fix memory leak if corpse auto-revival attempt failed ("you feel less hassled") fix memory leak if corpse auto-revival attempt failed ("you feel less hassled")
allow a parent function to issue an an unplacebc() call that restricts
subsequent placebc() calls to that parent only
Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository
------------------------------------------------------------------ ------------------------------------------------------------------
+1
View File
@@ -431,6 +431,7 @@ struct plinemsg_type {
E struct plinemsg_type *plinemsg_types; E struct plinemsg_type *plinemsg_types;
enum bcargs {override_restriction = -1};
struct breadcrumbs { struct breadcrumbs {
const char *funcnm; const char *funcnm;
int linenum; int linenum;
+8
View File
@@ -130,11 +130,19 @@ E void NDECL(ballfall);
#ifndef BREADCRUMBS #ifndef BREADCRUMBS
E void NDECL(placebc); E void NDECL(placebc);
E void NDECL(unplacebc); E void NDECL(unplacebc);
E int NDECL(unplacebc_and_covet_placebc);
E void FDECL(lift_covet_and_placebc, (int));
#else #else
E void FDECL(Placebc, (const char *, int)); E void FDECL(Placebc, (const char *, int));
E void FDECL(Unplacebc, (const char *, int)); E void FDECL(Unplacebc, (const char *, int));
E int FDECL(Unplacebc_and_covet_placebc, (const char *, int));
E void FDECL(Lift_covet_and_placebc, (int, const char *, int));
#define placebc() Placebc(__FUNCTION__, __LINE__) #define placebc() Placebc(__FUNCTION__, __LINE__)
#define unplacebc() Unplacebc(__FUNCTION__, __LINE__) #define unplacebc() Unplacebc(__FUNCTION__, __LINE__)
#define unplacebc_and_covet_placebc() \
Unplacebc_and_covet_placebc(__FUNCTION__, __LINE__)
#define lift_covet_and_placebc(x) \
Lift_covet_and_placebc(x, __FUNCTION__, __LINE__)
#endif #endif
E void FDECL(set_bc, (int)); E void FDECL(set_bc, (int));
E void FDECL(move_bc, (int, int, XCHAR_P, XCHAR_P, XCHAR_P, XCHAR_P)); E void FDECL(move_bc, (int, int, XCHAR_P, XCHAR_P, XCHAR_P, XCHAR_P));
+171 -38
View File
@@ -12,10 +12,11 @@ STATIC_DCL int NDECL(bc_order);
STATIC_DCL void NDECL(litter); STATIC_DCL void NDECL(litter);
STATIC_OVL void NDECL(placebc_core); STATIC_OVL void NDECL(placebc_core);
STATIC_OVL void NDECL(unplacebc_core); STATIC_OVL void NDECL(unplacebc_core);
STATIC_DCL boolean FDECL(check_restriction, (int));
static int bcrestriction = 0;
#ifdef BREADCRUMBS #ifdef BREADCRUMBS
static struct breadcrumbs bcpbreadcrumbs = { (const char *) 0, 0, FALSE}, static struct breadcrumbs bcpbreadcrumbs = {0}, bcubreadcrumbs = {0};
bcubreadcrumbs = { (const char *) 0, 0, FALSE};
#endif #endif
void void
@@ -137,34 +138,9 @@ placebc_core()
u.bglyph = u.cglyph = levl[u.ux][u.uy].glyph; /* pick up glyph */ u.bglyph = u.cglyph = levl[u.ux][u.uy].glyph; /* pick up glyph */
newsym(u.ux, u.uy); newsym(u.ux, u.uy);
bcrestriction = 0;
} }
#ifdef BREADCRUMBS
void
Placebc(funcnm, linenum)
const char *funcnm;
int linenum;
{
if (uball && bcpbreadcrumbs.in_effect && uball->where == OBJ_FLOOR) {
impossible("placebc collision from %s:%d, already placed by %s:%d",
funcnm, linenum,
bcpbreadcrumbs.funcnm, bcpbreadcrumbs.linenum);
return;
}
bcpbreadcrumbs.in_effect = TRUE;
bcubreadcrumbs.in_effect = FALSE;
bcpbreadcrumbs.funcnm = funcnm;
bcpbreadcrumbs.linenum = linenum;
placebc_core();
}
#else
void
placebc()
{
placebc_core();
}
#endif
STATIC_OVL void STATIC_OVL void
unplacebc_core() unplacebc_core()
{ {
@@ -197,33 +173,190 @@ unplacebc_core()
u.bc_felt = 0; /* feel nothing */ u.bc_felt = 0; /* feel nothing */
} }
#ifdef BREADCRUMBS STATIC_OVL boolean
check_restriction(restriction)
int restriction;
{
boolean ret = FALSE;
if (!bcrestriction || (restriction == override_restriction))
ret = TRUE;
else
ret = (bcrestriction == restriction) ? TRUE : FALSE;
return ret;
}
#ifndef BREADCRUMBS
void
placebc()
{
if (!check_restriction(0)) {
#if (NH_DEVEL_STATUS != NH_STATUS_RELEASED)
char panicbuf[BUFSZ];
Sprintf(panicbuf,
"placebc denied, restriction in effect");
paniclog("placebc", panicbuf);
#endif
return;
}
if (uchain && uchain->where != OBJ_FREE) {
impossible("bc already placed?");
return;
}
placebc_core();
}
void
unplacebc()
{
if (bcrestriction) {
impossible("unplacebc denied, restriction in place");
return;
}
unplacebc_core();
}
int
unplacebc_and_covet_placebc()
{
int restriction = 0;
if (bcrestriction) {
impossible("unplacebc_and_covet_placebc denied, already restricted");
} else {
restriction = bcrestriction = rnd(400);
unplacebc_core();
}
return restriction;
}
void
lift_covet_and_placebc(pin)
int pin;
{
if (!check_restriction(pin)) {
#if (NH_DEVEL_STATUS != NH_STATUS_RELEASED)
char panicbuf[BUFSZ];
Sprintf(panicbuf,
"lift_covet_and_placebc denied, %s",
(pin != bcrestriction) ?
"pin mismatch" : "restriction in effect");
paniclog("placebc", panicbuf);
#endif
return;
}
if (uchain && uchain->where != OBJ_FREE) {
impossible("bc already placed?");
return;
}
placebc_core();
}
#else /* BREADCRUMBS */
void
Placebc(funcnm, linenum)
const char *funcnm;
int linenum;
{
if (!check_restriction(0)) {
#if (NH_DEVEL_STATUS != NH_STATUS_RELEASED)
char panicbuf[BUFSZ];
Sprintf(panicbuf,
"Placebc denied to %s:%d, restricted by %s:%d",
funcnm, linenum,
bcpbreadcrumbs.funcnm, bcpbreadcrumbs.linenum);
paniclog("Placebc", panicbuf);
#endif
return;
}
if ((uchain && uchain->where != OBJ_FREE)
&& bcpbreadcrumbs.in_effect) {
impossible("Placebc collision at %s:%d, already placed by %s:%d",
funcnm, linenum,
bcpbreadcrumbs.funcnm, bcpbreadcrumbs.linenum);
return;
}
bcpbreadcrumbs.in_effect = TRUE;
bcubreadcrumbs.in_effect = FALSE;
bcpbreadcrumbs.funcnm = funcnm;
bcpbreadcrumbs.linenum = linenum;
placebc_core();
}
void void
Unplacebc(funcnm, linenum) Unplacebc(funcnm, linenum)
const char *funcnm; const char *funcnm;
int linenum; int linenum;
{ {
#if 0
if (uball && bcubreadcrumbs.in_effect && uball->where == OBJ_FREE) { if (bcrestriction) {
impossible("unplacebc collision from %s:%d, already placed by %s:%d", char panicbuf[BUFSZ];
Sprintf(panicbuf,
"Unplacebc from %s:%d, when restricted to %s:%d",
funcnm, linenum, funcnm, linenum,
bcubreadcrumbs.funcnm, bcubreadcrumbs.linenum); bcubreadcrumbs.funcnm, bcubreadcrumbs.linenum);
return; paniclog("Unplacebc", panicbuf);
} }
#endif
bcpbreadcrumbs.in_effect = FALSE; bcpbreadcrumbs.in_effect = FALSE;
bcubreadcrumbs.in_effect = TRUE; bcubreadcrumbs.in_effect = TRUE;
bcubreadcrumbs.funcnm = funcnm; bcubreadcrumbs.funcnm = funcnm;
bcubreadcrumbs.linenum = linenum; bcubreadcrumbs.linenum = linenum;
unplacebc_core(); unplacebc_core();
} }
#else
void int
unplacebc() Unplacebc_and_covet_placebc(funcnm, linenum)
const char *funcnm;
int linenum;
{ {
unplacebc_core(); int restriction = 0;
if (bcrestriction) {
impossible(
"Unplacebc_and_covet_placebc denied to %s:%d, restricted by %s:%d",
funcnm, linenum,
bcubreadcrumbs.funcnm, bcubreadcrumbs.linenum);
} else {
restriction = bcrestriction = rnd(400);
bcpbreadcrumbs.in_effect = FALSE;
bcubreadcrumbs.in_effect = TRUE;
bcubreadcrumbs.funcnm = funcnm;
bcubreadcrumbs.linenum = linenum;
unplacebc_core();
}
return restriction;
} }
void
Lift_covet_and_placebc(pin, funcnm, linenum)
int pin;
char *funcnm;
int linenum;
{
if (!check_restriction(pin)) {
#if (NH_DEVEL_STATUS != NH_STATUS_RELEASED)
char panicbuf[BUFSZ];
Sprintf(panicbuf,
"Lift_covet_and_placebc denied to %s:%d, restricted by %s:%d",
funcnm, linenum,
bcpbreadcrumbs.funcnm, bcpbreadcrumbs.linenum);
paniclog("Lift_covet_and_placebc", panicbuf);
#endif #endif
return;
}
if (uchain && uchain->where != OBJ_FREE) {
impossible("bc already placed?");
return;
}
placebc_core();
}
#endif /* BREADCRUMBS */
/* /*
* Return the stacking of the hero's ball & chain. This assumes that the * Return the stacking of the hero's ball & chain. This assumes that the
+3 -3
View File
@@ -1400,7 +1400,7 @@ movebubbles()
struct bubble *b; struct bubble *b;
struct container *cons; struct container *cons;
struct trap *btrap; struct trap *btrap;
int x, y, i, j; int x, y, i, j, bcpin;
/* set up the portal the first time bubbles are moved */ /* set up the portal the first time bubbles are moved */
if (!wportal) if (!wportal)
@@ -1411,7 +1411,7 @@ movebubbles()
if (Is_waterlevel(&u.uz)) { if (Is_waterlevel(&u.uz)) {
/* keep attached ball&chain separate from bubble objects */ /* keep attached ball&chain separate from bubble objects */
if (Punished) if (Punished)
unplacebc(); bcpin = unplacebc_and_covet_placebc();
/* /*
* Pick up everything inside of a bubble then fill all bubble * Pick up everything inside of a bubble then fill all bubble
@@ -1528,7 +1528,7 @@ movebubbles()
/* put attached ball&chain back */ /* put attached ball&chain back */
if (Is_waterlevel(&u.uz) && Punished) if (Is_waterlevel(&u.uz) && Punished)
placebc(); lift_covet_and_placebc(bcpin);
vision_full_recalc = 1; vision_full_recalc = 1;
} }