buried_ball()

Noticed when I was looking at float_up()/float_down() vs being trapped.
(I have a substantial patch for that but it involves infrastructure
changes so will have to go into master instead of the 3.6.0 branch.)
buried_ball() was using nested loops as a very convoluted way to test
  if (otmp->ox >= cc->x - 2 && otmp->ox <= cc->x + 2
   && otmp->oy >= cc->y - 2 && otmp->oy <= cc->y + 2)
I think this revised version is closer to what was intended.

There are issues.  buried_ball() finds the buried iron ball nearest to
the specified location--which is always the hero's current location--
rather than the one which was 'uball' before being buried.  A player
can spot that since iron balls aren't necessarily identical.  Also, it
searches within a radius of two steps but a tethered hero is only
allowed to move one step away from buried ball, so something is off.
This commit is contained in:
PatR
2018-03-03 15:26:49 -08:00
parent 6bd8efe510
commit 2111abdc29
+38 -24
View File
@@ -1714,36 +1714,47 @@ struct obj *
buried_ball(cc) buried_ball(cc)
coord *cc; coord *cc;
{ {
xchar check_x, check_y; int odist, bdist = COLNO;
struct obj *otmp, *otmp2; struct obj *otmp, *ball = 0;
if (u.utraptype == TT_BURIEDBALL) /* FIXME:
for (otmp = level.buriedobjlist; otmp; otmp = otmp2) { * This is just approximate; if multiple buried balls meet the
otmp2 = otmp->nobj; * criterium (within 2 steps of tethered hero's present location)
* it will find an arbitrary one rather than the one which used
* to be uball. Once 3.6.{0,1} save file compatibility is broken,
* we should add context.buriedball_oid and then we can find the
* actual former uball, which might be extra heavy or christened
* or not the one buried directly underneath the target spot.
*
* [Why does this search within a radius of two when trapmove()
* only lets hero get one step away from the buried ball?]
*/
if (u.utrap && u.utraptype == TT_BURIEDBALL)
for (otmp = level.buriedobjlist; otmp; otmp = otmp->nobj) {
if (otmp->otyp != HEAVY_IRON_BALL) if (otmp->otyp != HEAVY_IRON_BALL)
continue; continue;
/* try the exact location first */ /* if found at the target spot, we're done */
if (otmp->ox == cc->x && otmp->oy == cc->y) if (otmp->ox == cc->x && otmp->oy == cc->y)
return otmp; return otmp;
/* Now try the vicinity */ /* find nearest within allowable vicinity: +/-2
/* * 4 5 8
* (x-2,y-2) (x+2,y-2) * 1 2 5
* (x,y) * 0 1 4
* (x-2,y+2) (x+2,y+2)
*/ */
for (check_x = cc->x - 2; check_x <= cc->x + 2; ++check_x) odist = dist2(otmp->ox, otmp->oy, cc->x, cc->y);
for (check_y = cc->y - 2; check_y <= cc->y + 2; ++check_y) { if (odist <= 8 && (!ball || odist < bdist)) {
if (check_x == cc->x && check_y == cc->y) /* remember nearest buried ball but keep checking others */
continue; ball = otmp;
if (isok(check_x, check_y) bdist = odist;
&& (otmp->ox == check_x && otmp->oy == check_y)) { }
cc->x = check_x;
cc->y = check_y;
return otmp;
}
}
} }
return (struct obj *) 0; if (ball) {
/* found, but not at < cc->x, cc->y > */
cc->x = ball->ox;
cc->y = ball->oy;
}
return ball;
} }
void void
@@ -1751,6 +1762,7 @@ buried_ball_to_punishment()
{ {
coord cc; coord cc;
struct obj *ball; struct obj *ball;
cc.x = u.ux; cc.x = u.ux;
cc.y = u.uy; cc.y = u.uy;
ball = buried_ball(&cc); ball = buried_ball(&cc);
@@ -1774,6 +1786,7 @@ buried_ball_to_freedom()
{ {
coord cc; coord cc;
struct obj *ball; struct obj *ball;
cc.x = u.ux; cc.x = u.ux;
cc.y = u.uy; cc.y = u.uy;
ball = buried_ball(&cc); ball = buried_ball(&cc);
@@ -1913,7 +1926,8 @@ int x, y;
for (otmp = level.buriedobjlist; otmp; otmp = otmp2) { for (otmp = level.buriedobjlist; otmp; otmp = otmp2) {
otmp2 = otmp->nobj; otmp2 = otmp->nobj;
if (otmp->ox == x && otmp->oy == y) { if (otmp->ox == x && otmp->oy == y) {
if (bball && otmp == bball && u.utraptype == TT_BURIEDBALL) { if (bball && otmp == bball
&& u.utrap && u.utraptype == TT_BURIEDBALL) {
buried_ball_to_punishment(); buried_ball_to_punishment();
} else { } else {
obj_extract_self(otmp); obj_extract_self(otmp);