assumes isok() at one space away, but not necessarily at two */
| 2674 | |
| 2675 | /* assumes isok() at one space away, but not necessarily at two */ |
| 2676 | staticfn boolean |
| 2677 | blocked_boulder(int dx, int dy) |
| 2678 | { |
| 2679 | struct obj *otmp; |
| 2680 | int nx, ny; |
| 2681 | long count = 0L; |
| 2682 | |
| 2683 | for (otmp = svl.level.objects[u.ux + dx][u.uy + dy]; otmp; |
| 2684 | otmp = otmp->nexthere) { |
| 2685 | if (otmp->otyp == BOULDER) |
| 2686 | count += otmp->quan; |
| 2687 | } |
| 2688 | |
| 2689 | nx = u.ux + 2 * dx, ny = u.uy + 2 * dy; /* next spot beyond boulder(s) */ |
| 2690 | switch (count) { |
| 2691 | case 0: |
| 2692 | /* no boulders--not blocked */ |
| 2693 | return FALSE; |
| 2694 | case 1: |
| 2695 | /* possibly blocked depending on if it's pushable */ |
| 2696 | break; |
| 2697 | case 2: |
| 2698 | /* this is only approximate since multiple boulders might sink */ |
| 2699 | if (is_pool_or_lava(nx, ny)) /* does its own isok() check */ |
| 2700 | break; /* still need Sokoban check below */ |
| 2701 | FALLTHROUGH; |
| 2702 | /*FALLTHRU*/ |
| 2703 | default: |
| 2704 | /* more than one boulder--blocked after they push the top one; |
| 2705 | don't force them to push it first to find out */ |
| 2706 | return TRUE; |
| 2707 | } |
| 2708 | |
| 2709 | if (dx && dy && Sokoban) /* can't push boulder diagonally in Sokoban */ |
| 2710 | return TRUE; |
| 2711 | if (!isok(nx, ny)) |
| 2712 | return TRUE; |
| 2713 | if (IS_OBSTRUCTED(levl[nx][ny].typ)) |
| 2714 | return TRUE; |
| 2715 | if (sobj_at(BOULDER, nx, ny)) |
| 2716 | return TRUE; |
| 2717 | |
| 2718 | return FALSE; |
| 2719 | } |
| 2720 | |
| 2721 | /*pray.c*/ |
no test coverage detected