monster attacked wrong location due to monster blindness, hero invisibility, hero displacement, or hero being underwater */
| 173 | /* monster attacked wrong location due to monster blindness, hero |
| 174 | invisibility, hero displacement, or hero being underwater */ |
| 175 | staticfn void |
| 176 | wildmiss(struct monst *mtmp, struct attack *mattk) |
| 177 | { |
| 178 | int compat; |
| 179 | const char *Monst_name; /* Monnam(), deferred until after early returns */ |
| 180 | /* expected reasons for wildmiss() */ |
| 181 | boolean unotseen = (!mtmp->mcansee || (Invis && !perceives(mtmp->data))), |
| 182 | unotthere = (Displaced != 0), usubmerged = (Underwater != 0); |
| 183 | |
| 184 | /* the reasons for wildmiss end up getting checked twice so that the |
| 185 | impossible can be given, if warranted, before the early returns */ |
| 186 | if (!unotseen && !unotthere && !usubmerged) { |
| 187 | /* this used to be the 'else' case below */ |
| 188 | impossible("%s attacks you without knowing your location?", |
| 189 | Some_Monnam(mtmp)); |
| 190 | return; |
| 191 | } |
| 192 | |
| 193 | /* no map_invisible() -- no way to tell where _this_ is coming from */ |
| 194 | |
| 195 | if (!flags.verbose) |
| 196 | return; |
| 197 | /* no feedback if hero doesn't see the monster's spot */ |
| 198 | if (!cansee(mtmp->mx, mtmp->my)) |
| 199 | return; |
| 200 | /* maybe it's attacking an image around the corner? */ |
| 201 | |
| 202 | compat = ((mattk->adtyp == AD_SEDU || mattk->adtyp == AD_SSEX) |
| 203 | ? could_seduce(mtmp, &gy.youmonst, mattk) : 0); |
| 204 | Monst_name = Monnam(mtmp); |
| 205 | |
| 206 | set_msg_xy(mtmp->mx, mtmp->my); |
| 207 | if (unotseen) { /* !mtmp->cansee || (Invis && !perceives(mtmp->data)) */ |
| 208 | const char *swings = (mattk->aatyp == AT_BITE) ? "snaps" |
| 209 | : (mattk->aatyp == AT_KICK) ? "kicks" |
| 210 | : (mattk->aatyp == AT_STNG |
| 211 | || mattk->aatyp == AT_BUTT |
| 212 | || nolimbs(mtmp->data)) ? "lunges" |
| 213 | : "swings"; |
| 214 | |
| 215 | if (compat) { |
| 216 | pline("%s tries to touch you and misses!", Monst_name); |
| 217 | } else { |
| 218 | switch (rn2(3)) { |
| 219 | case 0: |
| 220 | pline("%s %s wildly and misses!", Monst_name, swings); |
| 221 | break; |
| 222 | case 1: |
| 223 | pline("%s attacks a spot beside you.", Monst_name); |
| 224 | break; |
| 225 | case 2: |
| 226 | pline("%s strikes at %s!", Monst_name, |
| 227 | is_waterwall(mtmp->mux,mtmp->muy) |
| 228 | ? "empty water" |
| 229 | : "thin air"); |
| 230 | break; |
| 231 | default: |
| 232 | pline("%s %s wildly!", Monst_name, swings); |
no test coverage detected