monster/hero tries to hide under something at the current location; if used by monster creation, should only happen during level creation, otherwise there will be message sequencing issues */
| 4723 | if used by monster creation, should only happen during level |
| 4724 | creation, otherwise there will be message sequencing issues */ |
| 4725 | boolean |
| 4726 | hideunder(struct monst *mtmp) |
| 4727 | { |
| 4728 | struct trap *t; |
| 4729 | struct obj *otmp; |
| 4730 | const char *seenmon = (char *) 0, *seenobj = (char *) 0, |
| 4731 | *locomo = (char *) 0; |
| 4732 | int seeit = gi.in_mklev ? 0 : canseemon(mtmp); |
| 4733 | boolean oldundetctd, undetected = FALSE, is_u = (mtmp == &gy.youmonst); |
| 4734 | coordxy x = is_u ? u.ux : mtmp->mx, y = is_u ? u.uy : mtmp->my; |
| 4735 | |
| 4736 | if (mtmp == u.ustuck) { |
| 4737 | ; /* undetected==FALSE; can't hide if holding you or held by you */ |
| 4738 | } else if ((is_u ? u.utrap : mtmp->mtrapped) |
| 4739 | || ((t = t_at(x, y)) != 0 && !is_pit(t->ttyp))) { |
| 4740 | ; /* undetected==FALSE; can't hide while trapped or on/in/under |
| 4741 | any non-pit trap when not trapped */ |
| 4742 | } else if (mtmp->data->mlet == S_EEL) { |
| 4743 | /* aquatic creatures only hide under water, not under objects; |
| 4744 | they don't do so on the Plane of Water or when hero is also |
| 4745 | under water unless some obstacle blocks line-of-sight */ |
| 4746 | undetected = (is_pool(x, y) && !Is_waterlevel(&u.uz) |
| 4747 | && (!Underwater || !couldsee(x, y))); |
| 4748 | if (seeit) { |
| 4749 | seenobj = "the water"; |
| 4750 | locomo = "dive"; |
| 4751 | } |
| 4752 | } else if (hides_under(mtmp->data) |
| 4753 | /* hider-underers only hide under objects */ |
| 4754 | && (otmp = svl.level.objects[x][y]) != 0 |
| 4755 | /* most things can be hidden under, but not all */ |
| 4756 | && can_hide_under_obj(otmp) |
| 4757 | /* pets won't hide under a cursed item or an item of any BUC |
| 4758 | state that shares a pile with one or more cursed items */ |
| 4759 | && (!mtmp->mtame || !cursed_object_at(x, y)) |
| 4760 | /* aquatic creatures don't reach here; other swimmers |
| 4761 | shouldn't hide beneath underwater objects */ |
| 4762 | && !is_pool_or_lava(x, y)) { |
| 4763 | if (seeit) /*&& (!is_pool(x, y) || (Underwater && distu(x, y) <= 2))*/ |
| 4764 | seenobj = ansimpleoname(otmp); |
| 4765 | /* most monsters won't hide under a cockatrice corpse but they |
| 4766 | can hide under a pile containing more than just such corpses */ |
| 4767 | if (is_u ? !Stone_resistance : !resists_ston(mtmp)) |
| 4768 | while (otmp && otmp->otyp == CORPSE |
| 4769 | && touch_petrifies(&mons[otmp->corpsenm])) |
| 4770 | otmp = otmp->nexthere; |
| 4771 | if (otmp) |
| 4772 | undetected = TRUE; |
| 4773 | } |
| 4774 | |
| 4775 | if (is_u) { |
| 4776 | oldundetctd = u.uundetected != 0; |
| 4777 | u.uundetected = undetected ? 1 : 0; |
| 4778 | #if 0 /* feedback handled via #monster */ |
| 4779 | if (undetected && !oldundeteced && seenobj) |
| 4780 | You("hide under %s.", seenobj); |
| 4781 | #endif |
| 4782 | } else { |
no test coverage detected