* Pick coordinates for a starting position for the mail daemon. Called * from newmail() and newphone(). */
| 146 | * from newmail() and newphone(). |
| 147 | */ |
| 148 | staticfn boolean |
| 149 | md_start(coord *startp) |
| 150 | { |
| 151 | coord testcc; /* scratch coordinates */ |
| 152 | int row; /* current row we are checking */ |
| 153 | int lax; /* if TRUE, pick a position in sight. */ |
| 154 | int dd; /* distance to current point */ |
| 155 | int max_distance; /* max distance found so far */ |
| 156 | stairway *stway = gs.stairs; |
| 157 | |
| 158 | /* |
| 159 | * If blind and not telepathic, then it doesn't matter what we pick --- |
| 160 | * the hero is not going to see it anyway. So pick a nearby position. |
| 161 | */ |
| 162 | if (Blind && !Blind_telepat) { |
| 163 | if (!enexto(startp, u.ux, u.uy, (struct permonst *) 0)) |
| 164 | return FALSE; /* no good positions */ |
| 165 | return TRUE; |
| 166 | } |
| 167 | |
| 168 | /* |
| 169 | * Arrive at an up or down stairwell if it is in line of sight from the |
| 170 | * hero. |
| 171 | */ |
| 172 | while (stway) { |
| 173 | if (stway->tolev.dnum == u.uz.dnum |
| 174 | && couldsee(stway->sx, stway->sy)) { |
| 175 | startp->x = stway->sx; |
| 176 | startp->y = stway->sy; |
| 177 | return TRUE; |
| 178 | } |
| 179 | stway = stway->next; |
| 180 | } |
| 181 | |
| 182 | /* |
| 183 | * Try to pick a location out of sight next to the farthest position away |
| 184 | * from the hero. If this fails, try again, just picking the farthest |
| 185 | * position that could be seen. What we really ought to be doing is |
| 186 | * finding a path from a stairwell... |
| 187 | * |
| 188 | * The arrays gv.viz_rmin[] and gv.viz_rmax[] are set even when blind. |
| 189 | * These are the LOS limits for each row. |
| 190 | */ |
| 191 | lax = 0; /* be picky */ |
| 192 | max_distance = -1; |
| 193 | retry: |
| 194 | for (row = 0; row < ROWNO; row++) { |
| 195 | if (gv.viz_rmin[row] < gv.viz_rmax[row]) { |
| 196 | /* There are valid positions on this row. */ |
| 197 | dd = distu(gv.viz_rmin[row], row); |
| 198 | if (dd > max_distance) { |
| 199 | if (lax) { |
| 200 | max_distance = dd; |
| 201 | startp->y = row; |
| 202 | startp->x = gv.viz_rmin[row]; |
| 203 | |
| 204 | } else if (enexto(&testcc, gv.viz_rmin[row], row, |
| 205 | (struct permonst *) 0) |