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:
@@ -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
|
||||
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")
|
||||
|
||||
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
|
||||
------------------------------------------------------------------
|
||||
|
||||
@@ -431,6 +431,7 @@ struct plinemsg_type {
|
||||
|
||||
E struct plinemsg_type *plinemsg_types;
|
||||
|
||||
enum bcargs {override_restriction = -1};
|
||||
struct breadcrumbs {
|
||||
const char *funcnm;
|
||||
int linenum;
|
||||
|
||||
@@ -130,11 +130,19 @@ E void NDECL(ballfall);
|
||||
#ifndef BREADCRUMBS
|
||||
E void NDECL(placebc);
|
||||
E void NDECL(unplacebc);
|
||||
E int NDECL(unplacebc_and_covet_placebc);
|
||||
E void FDECL(lift_covet_and_placebc, (int));
|
||||
#else
|
||||
E void FDECL(Placebc, (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 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
|
||||
E void FDECL(set_bc, (int));
|
||||
E void FDECL(move_bc, (int, int, XCHAR_P, XCHAR_P, XCHAR_P, XCHAR_P));
|
||||
|
||||
209
src/ball.c
209
src/ball.c
@@ -12,10 +12,11 @@ STATIC_DCL int NDECL(bc_order);
|
||||
STATIC_DCL void NDECL(litter);
|
||||
STATIC_OVL void NDECL(placebc_core);
|
||||
STATIC_OVL void NDECL(unplacebc_core);
|
||||
STATIC_DCL boolean FDECL(check_restriction, (int));
|
||||
|
||||
static int bcrestriction = 0;
|
||||
#ifdef BREADCRUMBS
|
||||
static struct breadcrumbs bcpbreadcrumbs = { (const char *) 0, 0, FALSE},
|
||||
bcubreadcrumbs = { (const char *) 0, 0, FALSE};
|
||||
static struct breadcrumbs bcpbreadcrumbs = {0}, bcubreadcrumbs = {0};
|
||||
#endif
|
||||
|
||||
void
|
||||
@@ -137,34 +138,9 @@ placebc_core()
|
||||
u.bglyph = u.cglyph = levl[u.ux][u.uy].glyph; /* pick up glyph */
|
||||
|
||||
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
|
||||
unplacebc_core()
|
||||
{
|
||||
@@ -197,33 +173,190 @@ unplacebc_core()
|
||||
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
|
||||
Unplacebc(funcnm, linenum)
|
||||
const char *funcnm;
|
||||
int linenum;
|
||||
{
|
||||
#if 0
|
||||
if (uball && bcubreadcrumbs.in_effect && uball->where == OBJ_FREE) {
|
||||
impossible("unplacebc collision from %s:%d, already placed by %s:%d",
|
||||
|
||||
if (bcrestriction) {
|
||||
char panicbuf[BUFSZ];
|
||||
|
||||
Sprintf(panicbuf,
|
||||
"Unplacebc from %s:%d, when restricted to %s:%d",
|
||||
funcnm, linenum,
|
||||
bcubreadcrumbs.funcnm, bcubreadcrumbs.linenum);
|
||||
return;
|
||||
paniclog("Unplacebc", panicbuf);
|
||||
}
|
||||
#endif
|
||||
bcpbreadcrumbs.in_effect = FALSE;
|
||||
bcubreadcrumbs.in_effect = TRUE;
|
||||
bcubreadcrumbs.funcnm = funcnm;
|
||||
bcubreadcrumbs.linenum = linenum;
|
||||
unplacebc_core();
|
||||
}
|
||||
#else
|
||||
void
|
||||
unplacebc()
|
||||
|
||||
int
|
||||
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
|
||||
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
|
||||
|
||||
@@ -1400,7 +1400,7 @@ movebubbles()
|
||||
struct bubble *b;
|
||||
struct container *cons;
|
||||
struct trap *btrap;
|
||||
int x, y, i, j;
|
||||
int x, y, i, j, bcpin;
|
||||
|
||||
/* set up the portal the first time bubbles are moved */
|
||||
if (!wportal)
|
||||
@@ -1411,7 +1411,7 @@ movebubbles()
|
||||
if (Is_waterlevel(&u.uz)) {
|
||||
/* keep attached ball&chain separate from bubble objects */
|
||||
if (Punished)
|
||||
unplacebc();
|
||||
bcpin = unplacebc_and_covet_placebc();
|
||||
|
||||
/*
|
||||
* Pick up everything inside of a bubble then fill all bubble
|
||||
@@ -1528,7 +1528,7 @@ movebubbles()
|
||||
|
||||
/* put attached ball&chain back */
|
||||
if (Is_waterlevel(&u.uz) && Punished)
|
||||
placebc();
|
||||
lift_covet_and_placebc(bcpin);
|
||||
vision_full_recalc = 1;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user