return TRUE if the caller needs to place the ball and chain down again */
| 557 | |
| 558 | /* return TRUE if the caller needs to place the ball and chain down again */ |
| 559 | boolean |
| 560 | drag_ball(coordxy x, coordxy y, int *bc_control, |
| 561 | coordxy *ballx, coordxy *bally, coordxy *chainx, coordxy *chainy, |
| 562 | boolean *cause_delay, boolean allow_drag) |
| 563 | { |
| 564 | struct trap *t = (struct trap *) 0; |
| 565 | boolean already_in_rock; |
| 566 | |
| 567 | /* |
| 568 | * Should not be called while swallowed. Should be called before |
| 569 | * movement, because we might want to move the ball or chain to the |
| 570 | * hero's old position. |
| 571 | * |
| 572 | * It is called if we are moving. It is also called if we are |
| 573 | * teleporting *if* the ball doesn't move and we thus must drag the |
| 574 | * chain. It is not called for ordinary teleportation. |
| 575 | * |
| 576 | * 'allow_drag' is only used in the ugly special case where teleporting |
| 577 | * must drag the chain, while an identical-looking movement must drag |
| 578 | * both the ball and chain. |
| 579 | */ |
| 580 | |
| 581 | *ballx = uball->ox; |
| 582 | *bally = uball->oy; |
| 583 | *chainx = uchain->ox; |
| 584 | *chainy = uchain->oy; |
| 585 | *bc_control = 0; |
| 586 | *cause_delay = FALSE; |
| 587 | |
| 588 | if (dist2(x, y, uchain->ox, uchain->oy) <= 2) { /* nothing moved */ |
| 589 | move_bc(1, *bc_control, *ballx, *bally, *chainx, *chainy); |
| 590 | return TRUE; |
| 591 | } |
| 592 | |
| 593 | /* only need to move the chain? */ |
| 594 | if (carried(uball) || distmin(x, y, uball->ox, uball->oy) <= 2) { |
| 595 | coordxy oldchainx = uchain->ox, oldchainy = uchain->oy; |
| 596 | |
| 597 | *bc_control = BC_CHAIN; |
| 598 | move_bc(1, *bc_control, *ballx, *bally, *chainx, *chainy); |
| 599 | if (carried(uball)) { |
| 600 | /* move chain only if necessary */ |
| 601 | if (distmin(x, y, uchain->ox, uchain->oy) > 1) { |
| 602 | *chainx = u.ux; |
| 603 | *chainy = u.uy; |
| 604 | } |
| 605 | return TRUE; |
| 606 | } |
| 607 | |
| 608 | #define CHAIN_IN_MIDDLE(chx, chy) \ |
| 609 | (distmin(x, y, chx, chy) <= 1 \ |
| 610 | && distmin(chx, chy, uball->ox, uball->oy) <= 1) |
| 611 | #define IS_CHAIN_ROCK(x, y) \ |
| 612 | (IS_OBSTRUCTED(levl[x][y].typ) \ |
| 613 | || (IS_DOOR(levl[x][y].typ) \ |
| 614 | && (levl[x][y].doormask & (D_CLOSED | D_LOCKED)))) |
| 615 | /* |
| 616 | * Don't ever move the chain into solid rock. If we have to, then |
no test coverage detected