try to find a random coordinate where launching a rolling boulder could work. return TRUE if found, with coordinate in cc. */
| 3596 | /* try to find a random coordinate where launching a rolling boulder |
| 3597 | could work. return TRUE if found, with coordinate in cc. */ |
| 3598 | staticfn boolean |
| 3599 | find_random_launch_coord(struct trap *ttmp, coord *cc) |
| 3600 | { |
| 3601 | int tmp; |
| 3602 | boolean success = FALSE; |
| 3603 | coord bcc = UNDEFINED_VALUES; |
| 3604 | int distance; |
| 3605 | int mindist = 4; |
| 3606 | int trycount = 0; |
| 3607 | coordxy dx, dy; |
| 3608 | coordxy x, y; |
| 3609 | |
| 3610 | if (!ttmp || !cc || Sokoban) |
| 3611 | return FALSE; |
| 3612 | |
| 3613 | x = ttmp->tx; |
| 3614 | y = ttmp->ty; |
| 3615 | |
| 3616 | bcc.x = ttmp->tx + gl.launchplace.x; |
| 3617 | bcc.y = ttmp->ty + gl.launchplace.y; |
| 3618 | if (isok(bcc.x, bcc.y) && linedup(ttmp->tx, ttmp->ty, bcc.x, bcc.y, 1)) { |
| 3619 | cc->x = bcc.x; |
| 3620 | cc->y = bcc.y; |
| 3621 | return TRUE; |
| 3622 | } |
| 3623 | |
| 3624 | if (ttmp->ttyp == ROLLING_BOULDER_TRAP) |
| 3625 | mindist = 2; |
| 3626 | distance = rn1(5, 4); /* 4..8 away */ |
| 3627 | tmp = rn2(N_DIRS); /* randomly pick a direction to try first */ |
| 3628 | while (distance >= mindist) { |
| 3629 | dx = xdir[tmp]; |
| 3630 | dy = ydir[tmp]; |
| 3631 | cc->x = x; |
| 3632 | cc->y = y; |
| 3633 | /* Prevent boulder from being placed on water */ |
| 3634 | if (ttmp->ttyp == ROLLING_BOULDER_TRAP |
| 3635 | && is_pool_or_lava(x + distance * dx, y + distance * dy)) |
| 3636 | success = FALSE; |
| 3637 | else |
| 3638 | success = isclearpath(cc, distance, dx, dy); |
| 3639 | if (ttmp->ttyp == ROLLING_BOULDER_TRAP) { |
| 3640 | boolean success_otherway; |
| 3641 | |
| 3642 | bcc.x = x; |
| 3643 | bcc.y = y; |
| 3644 | success_otherway = isclearpath(&bcc, distance, -(dx), -(dy)); |
| 3645 | if (!success_otherway) |
| 3646 | success = FALSE; |
| 3647 | } |
| 3648 | if (success) |
| 3649 | break; |
| 3650 | if (++tmp > 7) |
| 3651 | tmp = 0; |
| 3652 | if ((++trycount % 8) == 0) |
| 3653 | --distance; |
| 3654 | } |
| 3655 | return success; |
no test coverage detected