From: cohrs Date: Sun, 24 Sep 2006 22:31:22 +0000 (+0000) Subject: H216 - ball and chain movement X-Git-Tag: MOVE2GIT~878 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7272de6881a94865566c461aeb734c2d980e3852;p=nethack H216 - ball and chain movement reported the longstanding behavior that when dragging, the chain does not always remain directly between the player and the ball. This occurs when the player zigzags. Added a check to the simple drag code to try to keep the chain directly between the player and the ball. But, don't do this if the player is walking thru rock or if it would move the chain into rock. --- diff --git a/doc/fixes34.4 b/doc/fixes34.4 index 5a33792b9..58335f4fc 100644 --- a/doc/fixes34.4 +++ b/doc/fixes34.4 @@ -259,6 +259,7 @@ fix region timeout detection, caused strange display of stinking cloud while wearing the Eyes of the Overworld try to keep migrating monsters from escaping the wizard tower affected monsters should always respect "Elbereth" +try harder to keep dragged chain between ball and hero Platform- and/or Interface-Specific Fixes diff --git a/src/ball.c b/src/ball.c index c1b5dec2a..7bc7b743b 100644 --- a/src/ball.c +++ b/src/ball.c @@ -395,9 +395,9 @@ boolean allow_drag; return TRUE; } #define CHAIN_IN_MIDDLE(chx, chy) \ -(distmin(x, y, chx, chy) <= 1 && distmin(chx, chy, uball->ox, uball->oy) <= 1) + (distmin(x, y, chx, chy) <= 1 && distmin(chx, chy, uball->ox, uball->oy) <= 1) #define IS_CHAIN_ROCK(x,y) \ -(IS_ROCK(levl[x][y].typ) || (IS_DOOR(levl[x][y].typ) && \ + (IS_ROCK(levl[x][y].typ) || (IS_DOOR(levl[x][y].typ) && \ (levl[x][y].doormask & (D_CLOSED|D_LOCKED)))) /* Don't ever move the chain into solid rock. If we have to, then instead * undo the move_bc() and jump to the drag ball code. Note that this also @@ -548,7 +548,6 @@ boolean allow_drag; break; } #undef SKIP_TO_DRAG -#undef IS_CHAIN_ROCK #undef CHAIN_IN_MIDDLE return TRUE; } @@ -622,11 +621,32 @@ drag: *ballx = *chainx = x; *bally = *chainy = y; } else { + xchar newchainx = u.ux, newchainy = u.uy; + + /* + * Generally, chain moves to hero's previous location and ball + * moves to chain's previous location, except that we try to + * keep the chain directly between the hero and the ball. But, + * take the simple approach if the hero's previous location or + * the potential between location is inaccessible. + */ + if (dist2(x, y, uchain->ox, uchain->oy) == 4 && + !IS_CHAIN_ROCK(newchainx, newchainy)) { + newchainx = (x + uchain->ox)/2; + newchainy = (y + uchain->oy)/2; + if (IS_CHAIN_ROCK(newchainx, newchainy)) { + /* don't let chain move to inaccessible location */ + newchainx = u.ux; + newchainy = u.uy; + } + } + *ballx = uchain->ox; *bally = uchain->oy; - *chainx = u.ux; - *chainy = u.uy; + *chainx = newchainx; + *chainy = newchainy; } +#undef IS_CHAIN_ROCK *cause_delay = TRUE; return TRUE; }