MCPcopy Create free account
hub / github.com/NetHack/NetHack / goodpos

Function goodpos

src/teleport.c:85–185  ·  view source on GitHub ↗

* Is (x,y) a good position of mtmp? If mtmp is NULL, then is (x,y) good * for an object? * * This function will only look at mtmp->mdat, so makemon, mplayer, etc can * call it to generate new monster positions with fake monster structures. */

Source from the content-addressed store, hash-verified

83 * call it to generate new monster positions with fake monster structures.
84 */
85boolean
86goodpos(
87 coordxy x, coordxy y,
88 struct monst *mtmp,
89 mmflags_nht gpflags)
90{
91 struct permonst *mdat = (struct permonst *) 0;
92 boolean ignorewater = ((gpflags & MM_IGNOREWATER) != 0),
93 ignorelava = ((gpflags & MM_IGNORELAVA) != 0),
94 checkscary = ((gpflags & GP_CHECKSCARY) != 0),
95 allow_u = ((gpflags & GP_ALLOW_U) != 0),
96 avoid_monpos = ((gpflags & GP_AVOID_MONPOS) != 0);
97
98 if (!isok(x, y))
99 return FALSE;
100
101 /* in many cases, we're trying to create a new monster, which
102 * can't go on top of the player or any existing monster.
103 * however, occasionally we are relocating engravings or objects,
104 * which could be co-located and thus get restricted a bit too much.
105 * oh well.
106 */
107 if (!allow_u) {
108 if (u_at(x, y) && mtmp != &gy.youmonst
109 && (mtmp != u.ustuck || !u.uswallow)
110 && (!u.usteed || mtmp != u.usteed))
111 return FALSE;
112 }
113
114 if (MON_AT(x, y) && avoid_monpos)
115 return FALSE;
116
117 if (mtmp) {
118 struct monst *mtmp2 = m_at(x, y);
119
120 /* Be careful with long worms. A monster may be placed back in
121 * its own location. Normally, if m_at() returns the same monster
122 * that we're trying to place, the monster is being placed in its
123 * own location. However, that is not correct for worm segments,
124 * because all the segments of the worm return the same m_at().
125 * Actually we overdo the check a little bit--a worm can't be placed
126 * in its own location, period. If we just checked for mtmp->mx
127 * != x || mtmp->my != y, we'd miss the case where we're called
128 * to place the worm segment and the worm's head is at x,y.
129 */
130 if (mtmp2 && (mtmp2 != mtmp || mtmp->wormno))
131 return FALSE;
132
133 mdat = mtmp->data;
134 if (is_pool(x, y) && !ignorewater) {
135 /* [what about Breathless?] */
136 if (mtmp == &gy.youmonst)
137 return (Swimming || Amphibious
138 || (!Is_waterlevel(&u.uz)
139 && !is_waterwall(x, y)
140 /* water on the Plane of Water has no surface
141 so there's no way to be on or above that */
142 && (Levitation || Flying || Wwalking)));

Callers 15

create_mplayersFunction · 0.85
enexto_coreFunction · 0.85
teleokFunction · 0.85
rloc_pos_okFunction · 0.85
rlocFunction · 0.85
control_mon_teleFunction · 0.85
mvault_teleFunction · 0.85
rlocoFunction · 0.85
revive_nastyFunction · 0.85
domove_attackmon_atFunction · 0.85
domove_swap_with_petFunction · 0.85
crawl_destinationFunction · 0.85

Calls 13

isokFunction · 0.85
is_poolFunction · 0.85
is_waterwallFunction · 0.85
m_in_airFunction · 0.85
rn2Function · 0.85
is_lavaFunction · 0.85
may_passwallFunction · 0.85
closed_doorFunction · 0.85
onscaryFunction · 0.85
goodpos_onscaryFunction · 0.85
accessibleFunction · 0.85
sobj_atFunction · 0.85

Tested by

no test coverage detected