Branch data Line data Source code
1 : : /* omega copyright (c) 1987,1988,1989 by Laurence Raphael Brothers */
2 : : /* mmove.c */
3 : : /* monster move functions */
4 : :
5 : : #include "glob.h"
6 : :
7 : :
8 : : /* like m_normal_move, but can open doors */
9 : 136 : void m_smart_move(pmt m)
10 : : {
11 : 136 : m_simple_move(m);
12 : 136 : }
13 : :
14 : : /* not very smart, but not altogether stupid movement */
15 : 0 : void m_normal_move(pmt m)
16 : : {
17 : 0 : m_simple_move(m);
18 : 0 : }
19 : :
20 : :
21 : : /* used by both m_normal_move and m_smart_move */
22 : 136 : void m_simple_move(pmt m)
23 : : {
24 [ + + ]: 136 : int dx = sign(Player.x - m->x);
25 [ + + ]: 136 : int dy = sign(Player.y - m->y);
26 : :
27 : 136 : erase_monster(m);
28 [ - + ]: 136 : if (m->hp < Monsters[m->id].hp/4) {
29 : 0 : dx = - dx;
30 : 0 : dy = - dy;
31 : 0 : m->movef = M_MOVE_SCAREDY;
32 [ # # ]: 0 : if (m->uniqueness == COMMON) {
33 : 0 : strcpy(Str2,"The ");
34 : 0 : strcat(Str2,m->monstring);
35 : : }
36 : 0 : else strcpy(Str2,m->monstring);
37 [ # # ]: 0 : if (m->possessions != NULL) {
38 : 0 : strcat(Str2," drops its treasure and flees!");
39 : 0 : m_dropstuff(m);
40 : : }
41 : 0 : else strcat(Str2," flees!");
42 : 0 : mprint(Str2);
43 : 0 : m->speed = min(2,m->speed-1);
44 : : }
45 [ - + ][ # # ]: 136 : if ((! m_statusp(m,HOSTILE) && !m_statusp(m, NEEDY)) ||
[ - + ]
46 : 0 : (Player.status[INVISIBLE] > 0)) m_random_move(m);
47 : : else {
48 [ + + ]: 136 : if (m_unblocked(m,m->x+dx,m->y+dy))
49 : 18 : movemonster(m,m->x+dx,m->y+dy);
50 [ - + ]: 118 : else if (dx == 0) {
51 [ # # ]: 0 : if (m_unblocked(m,m->x+1,m->y+dy))
52 : 0 : movemonster(m,m->x+1,m->y+dy);
53 [ # # ]: 0 : else if (m_unblocked(m,m->x-1,m->y+dy))
54 : 0 : movemonster(m,m->x-1,m->y+dy);
55 : : }
56 : :
57 [ + + ]: 118 : else if (dy == 0) {
58 [ - + ]: 15 : if (m_unblocked(m,m->x+dx,m->y+1))
59 : 0 : movemonster(m,m->x+dx,m->y+1);
60 [ - + ]: 15 : else if (m_unblocked(m,m->x+dx,m->y-1))
61 : 15 : movemonster(m,m->x+dx,m->y-1);
62 : : }
63 : :
64 : : else {
65 [ + + ]: 103 : if (m_unblocked(m,m->x+dx,m->y))
66 : 42 : movemonster(m,m->x+dx,m->y);
67 [ + + ]: 61 : else if (m_unblocked(m,m->x,m->y+dy))
68 : 40 : movemonster(m,m->x,m->y+dy);
69 : : }
70 : : }
71 : 136 : }
72 : :
73 : :
74 : 0 : void m_move_animal(pmt m)
75 : : {
76 [ # # ]: 0 : if (m_statusp(m,HOSTILE))
77 : 0 : m_normal_move(m);
78 : 0 : else m_scaredy_move(m);
79 : 0 : }
80 : :
81 : :
82 : : /* same as simple move except run in opposite direction */
83 : 0 : void m_scaredy_move(pmt m)
84 : : {
85 [ # # ]: 0 : int dx = -sign(Player.x - m->x);
86 [ # # ]: 0 : int dy = -sign(Player.y - m->y);
87 : 0 : erase_monster(m);
88 [ # # ]: 0 : if (Player.status[INVISIBLE]) m_random_move(m);
89 : : else {
90 [ # # ]: 0 : if (m_unblocked(m,m->x+dx,m->y+dy))
91 : 0 : movemonster(m,m->x+dx,m->y+dy);
92 [ # # ]: 0 : else if (dx == 0) {
93 [ # # ]: 0 : if (m_unblocked(m,m->x+1,m->y+dy))
94 : 0 : movemonster(m,m->x+1,m->y+dy);
95 [ # # ]: 0 : else if (m_unblocked(m,m->x-1,m->y+dy))
96 : 0 : movemonster(m,m->x-1,m->y+dy);
97 : : }
98 : :
99 [ # # ]: 0 : else if (dy == 0) {
100 [ # # ]: 0 : if (m_unblocked(m,m->x+dx,m->y+1))
101 : 0 : movemonster(m,m->x+dx,m->y+1);
102 [ # # ]: 0 : else if (m_unblocked(m,m->x+dx,m->y-1))
103 : 0 : movemonster(m,m->x+dx,m->y-1);
104 : : }
105 : :
106 : : else {
107 [ # # ]: 0 : if (m_unblocked(m,m->x+dx,m->y))
108 : 0 : movemonster(m,m->x+dx,m->y);
109 [ # # ]: 0 : else if (m_unblocked(m,m->x,m->y+dy))
110 : 0 : movemonster(m,m->x,m->y+dy);
111 : : }
112 : : }
113 : 0 : }
114 : :
115 : :
116 : : /* for spirits (and earth creatures) who can ignore blockages because
117 : : either they are noncorporeal or they can move through stone */
118 : 0 : void m_spirit_move(pmt m)
119 : : {
120 [ # # ]: 0 : int dx = sign(Player.x - m->x);
121 [ # # ]: 0 : int dy = sign(Player.y - m->y);
122 : 0 : erase_monster(m);
123 [ # # ]: 0 : if (m->hp < Monsters[m->id].hp/6) {
124 : 0 : dx = -dx;
125 : 0 : dy = -dy;
126 : : }
127 : :
128 [ # # ][ # # ]: 0 : if (Player.status[INVISIBLE] > 0 || !m_unblocked(m, m->x+dx, m->y+dy))
129 : 0 : m_random_move(m);
130 : : else
131 : 0 : movemonster(m,m->x+dx,m->y+dy);
132 : 0 : }
133 : :
134 : :
135 : :
136 : : /* fluttery dumb movement */
137 : 0 : void m_flutter_move(pmt m)
138 : : {
139 : 0 : int trange,range = distance(m->x,m->y,Player.x,Player.y);
140 : 0 : int i,tx,ty,nx=m->x,ny=m->y;
141 : 0 : erase_monster(m);
142 [ # # ]: 0 : if (Player.status[INVISIBLE] > 0) m_random_move(m);
143 : : else {
144 [ # # ]: 0 : for (i=0;i<8;i++) {
145 : 0 : tx = m->x+Dirs[0][i];
146 : 0 : ty = m->y+Dirs[1][i];
147 : 0 : trange = distance(tx,ty,Player.x,Player.y);
148 [ # # ]: 0 : if (m->hp < Monsters[m->id].hp/6) {
149 [ # # ][ # # ]: 0 : if ((trange > range) && m_unblocked(m,tx,ty)) {
150 : 0 : range = trange;
151 : 0 : nx = tx;
152 : 0 : ny = ty;
153 : : }
154 : : }
155 [ # # ][ # # ]: 0 : else if ((trange <= range) && m_unblocked(m,tx,ty)) {
156 : 0 : range = trange;
157 : 0 : nx = tx;
158 : 0 : ny = ty;
159 : : }
160 : : }
161 : 0 : movemonster(m,nx,ny);
162 : : }
163 : 0 : }
164 : :
165 : :
166 : 0 : void m_follow_move(pmt m)
167 : : {
168 [ # # ]: 0 : if (! m_statusp(m,HOSTILE))
169 : 0 : m_normal_move(m);
170 : 0 : else m_scaredy_move(m);
171 : 0 : }
172 : :
173 : :
174 : :
175 : : /* allows monsters to fall into pools, revealed traps, etc */
176 : 0 : void m_confused_move(pmt m)
177 : : {
178 : 0 : int i,nx,ny,done=FALSE;
179 : 0 : erase_monster(m);
180 [ # # ][ # # ]: 0 : for (i=0;((i<8)&&(! done));i++) {
181 : 0 : nx = m->x+random_range(3)-1;
182 : 0 : ny = m->y+random_range(3)-1;
183 [ # # ][ # # ]: 0 : if (unblocked(nx,ny) &&
184 [ # # ]: 0 : ((nx != Player.x) ||
185 : 0 : (ny != Player.y))) {
186 : 0 : done = TRUE;
187 : 0 : movemonster(m,nx,ny);
188 : : }
189 : : }
190 : 0 : }
191 : :
192 : 0 : void m_random_move(pmt m)
193 : : {
194 : 0 : int i,nx,ny,done=FALSE;
195 : 0 : erase_monster(m);
196 [ # # ][ # # ]: 0 : for (i=0;((i<8)&&(! done));i++) {
197 : 0 : nx = m->x+random_range(3)-1;
198 : 0 : ny = m->y+random_range(3)-1;
199 [ # # ][ # # ]: 0 : if (m_unblocked(m,nx,ny) &&
200 [ # # ]: 0 : ((nx != Player.x) ||
201 : 0 : (ny != Player.y))) {
202 : 0 : done = TRUE;
203 : 0 : movemonster(m,nx,ny);
204 : : }
205 : : }
206 : 0 : }
207 : :
208 : :
209 : : /* monster removed from play */
210 : 0 : void m_vanish(pmt m)
211 : : {
212 [ # # ]: 0 : if (m->uniqueness == COMMON) {
213 : 0 : strcpy(Str2,"The ");
214 : 0 : strcat(Str2,m->monstring);
215 : : }
216 : 0 : else strcpy(Str2,m->monstring);
217 : 0 : strcat(Str2," vanishes in the twinkling of an eye!");
218 : 0 : mprint(Str2);
219 : 0 : m_remove( m );/* signals "death" -- no credit to player, though */
220 : 0 : }
221 : :
222 : : /* monster still in play */
223 : 1 : void m_teleport(pmt m)
224 : : {
225 : 1 : erase_monster(m);
226 [ + - ]: 1 : if (m_statusp(m,AWAKE)) {
227 : 1 : Level->site[m->x][m->y].creature = NULL;
228 : 1 : putspot(m->x,m->y,getspot(m->x,m->y,FALSE));
229 : 1 : findspace(&(m->x),&(m->y),-1);
230 : 1 : Level->site[m->x][m->y].creature = m;
231 : : }
232 : 1 : }
233 : :
234 : 0 : void m_move_leash(pmt m)
235 : : {
236 : 0 : m_simple_move(m);
237 [ # # ]: 0 : if (m->aux1 == 0) {
238 : 0 : m->aux1 = m->x;
239 : 0 : m->aux2 = m->y;
240 : : }
241 [ # # ]: 0 : else if (distance(m->x,m->y,m->aux1,m->aux2) > 5) {
242 [ # # ]: 0 : if (Level->site[m->aux1][m->aux2].creature != NULL) {
243 [ # # ]: 0 : if (los_p(Player.x,Player.y,m->aux1,m->aux2)) {
244 : : /* some other monster is where the chain starts */
245 [ # # ]: 0 : if (Level->site[m->aux1][m->aux2].creature->uniqueness == COMMON) {
246 : 0 : strcpy(Str1, "The ");
247 : 0 : strcat(Str1, Level->site[m->aux1][m->aux2].creature->monstring);
248 : : }
249 : : else
250 : 0 : strcpy(Str1, Level->site[m->aux1][m->aux2].creature->monstring);
251 : 0 : strcat(Str1, " releases the dog's chain!");
252 : 0 : mprint(Str1);
253 : : }
254 : 0 : m->movef = M_MOVE_NORMAL;
255 : : /* otherwise, we'd lose either the dog or the other monster. */
256 : : }
257 [ # # ]: 0 : else if (los_p(Player.x,Player.y,m->x,m->y)) {
258 : 0 : mprint("You see the dog jerked back by its chain!");
259 : 0 : plotspot(m->x, m->y, FALSE);
260 : : }
261 : 0 : else mprint("You hear a strangled sort of yelp!");
262 : 0 : Level->site[m->x][m->y].creature = NULL;
263 : 0 : m->x = m->aux1;
264 : 0 : m->y = m->aux2;
265 : 0 : Level->site[m->x][m->y].creature = m;
266 : : }
267 : 0 : }
|