comparison urogue/move.c @ 256:c495a4f288c6

Import UltraRogue from the Roguelike Restoration Project (r1490)
author John "Elwin" Edwards
date Tue, 31 Jan 2017 19:56:04 -0500
parents
children e52a8a7ad4c5
comparison
equal deleted inserted replaced
253:d9badb9c0179 256:c495a4f288c6
1 /*
2 move.c - Hero movement commands
3
4 UltraRogue: The Ultimate Adventure in the Dungeons of Doom
5 Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong
6 All rights reserved.
7
8 Based on "Advanced Rogue"
9 Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka
10 All rights reserved.
11
12 Based on "Rogue: Exploring the Dungeons of Doom"
13 Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
14 All rights reserved.
15
16 See the file LICENSE.TXT for full copyright and licensing information.
17 */
18
19 #include <stdlib.h>
20 #include <ctype.h>
21 #include "rogue.h"
22
23 /*
24 do_run()
25 Start the hero running
26 */
27
28 void
29 do_run(char ch)
30 {
31 running = TRUE;
32 after = FALSE;
33 runch = ch;
34
35 if (doorstop && !on(player, ISBLIND))
36 {
37 door_stop = TRUE;
38 firstmove = TRUE;
39 }
40 }
41
42 /*
43 step_ok()
44 returns true if it is ok for type to step on ch flgptr will be
45 NULL if we don't know what the monster is yet!
46 */
47
48 int
49 step_ok(int y, int x, int can_on_monst, struct thing *flgptr)
50 {
51 struct linked_list *item;
52 char ch;
53
54 /* What is here? Don't check monster window if MONSTOK is set */
55
56 if (can_on_monst == MONSTOK)
57 ch = CCHAR( mvinch(y, x) );
58 else
59 ch = winat(y, x);
60
61 switch (ch)
62 {
63 case ' ':
64 case '|':
65 case '-':
66 case SECRETDOOR:
67 if (flgptr && on(*flgptr, CANINWALL))
68 return(TRUE);
69
70 return(FALSE);
71
72 case SCROLL:
73 /*
74 * If it is a scroll, it might be a scare monster scroll so
75 * we need to look it up to see what type it is.
76 */
77
78 if (flgptr && flgptr->t_ctype == C_MONSTER)
79 {
80 item = find_obj(y, x);
81
82 if (item != NULL && (OBJPTR(item))->o_type == SCROLL
83 && (OBJPTR(item))->o_which == S_SCARE
84 && rnd(flgptr->t_stats.s_intel) < 12)
85 return(FALSE); /* All but smart ones are scared */
86 }
87 return(TRUE);
88
89 default:
90 return(!isalpha(ch));
91 }
92 }
93
94 /*
95 corr_move()
96 Check to see that a move is legal. If so, return correct
97 character. If not, if player came from a legal place, then try to turn
98 him.
99 */
100
101 void
102 corr_move(int dy, int dx)
103 {
104 char ch;
105 short legal = 0; /* Number of legal alternatives */
106 int y = 0, x = 0; /* Holds legal new position */
107 int *ny, *nx; /* Point to which direction to change */
108
109 /* New position */
110
111 player.t_nxtpos.y = hero.y + dy;
112 player.t_nxtpos.x = hero.x + dx;
113
114 /* A bad diagonal move is illegal */
115
116 if (!diag_ok(&hero, &player.t_nxtpos, &player))
117 return;
118
119 /* If it is a legal move, just return */
120
121 if (player.t_nxtpos.x >= 0 && player.t_nxtpos.x < COLS && player.t_nxtpos.y > 0 && player.t_nxtpos.y < LINES - 2)
122 {
123 ch = winat(player.t_nxtpos.y, player.t_nxtpos.x);
124
125 switch (ch)
126 {
127 case ' ':
128 case '|':
129 case '-':
130 break;
131 default:
132 return;
133 }
134 }
135
136 /* Check the legal alternatives */
137
138 if (dy == 0)
139 {
140 ny = &dy;
141 nx = &dx;
142 }
143 else
144 {
145 ny = &dx;
146 nx = &dy;
147 }
148
149 for (*nx = 0, *ny = -1; *ny < 2; *ny += 2)
150 {
151 /* New position */
152 player.t_nxtpos.y = hero.y + dy;
153 player.t_nxtpos.x = hero.x + dx;
154
155 if (player.t_nxtpos.x < 0 || player.t_nxtpos.x > COLS - 1 || player.t_nxtpos.y < 1 || player.t_nxtpos.y > LINES - 3)
156 continue;
157
158 ch = winat(player.t_nxtpos.y, player.t_nxtpos.x);
159
160 switch (ch)
161 {
162 case ' ':
163 case '|':
164 case '-':
165 break;
166 default:
167 legal++;
168 y = dy;
169 x = dx;
170 }
171 }
172
173 /* If we have 2 legal moves, make no change */
174
175 if (legal != 1)
176 return;
177
178 /* Make the change */
179
180 if (y == 0) /* Move horizontally */
181 {
182 if (x == 1)
183 runch = 'l';
184 else
185 runch = 'h';
186 }
187 else /* Move vertically */
188 {
189 if (y == 1)
190 runch = 'j';
191 else
192 runch = 'k';
193 }
194
195 return;
196 }
197
198
199 /*
200 do_move()
201 Check to see that a move is legal. If it is handle the
202 consequences (fighting, picking up, etc.)
203 */
204
205 void
206 do_move(int dy, int dx)
207 {
208 char ch;
209 coord old_hero;
210 char hch;
211
212 firstmove = FALSE;
213
214 if (player.t_no_move)
215 {
216 player.t_no_move--;
217 msg("You are still stuck in the bear trap.");
218 return;
219 }
220
221 /* Do a confused move (maybe) */
222
223 if ((rnd(100) < 80 && on(player, ISHUH)) ||
224 (is_wearing(R_DELUSION) && rnd(100) < 25) ||
225 on(player, STUMBLER) && rnd(40) == 0)
226 player.t_nxtpos = rndmove(&player);
227 else
228 {
229 player.t_nxtpos.y = hero.y + dy;
230 player.t_nxtpos.x = hero.x + dx;
231 }
232
233 /*
234 * Check if he tried to move off the screen or make an illegal
235 * diagonal move, and stop him if he did.
236 */
237
238 if (player.t_nxtpos.x < 0 || player.t_nxtpos.x > COLS - 1 || player.t_nxtpos.y < 1 || player.t_nxtpos.y >= LINES - 2
239 || !diag_ok(&hero, &player.t_nxtpos, &player))
240 {
241 after = fighting = running = FALSE;
242 return;
243 }
244
245 if (running && ce(hero, player.t_nxtpos))
246 after = running = FALSE;
247
248 ch = winat(player.t_nxtpos.y, player.t_nxtpos.x);
249
250 if (isalpha(ch))
251 debug("Moving onto monster %c",ch);
252
253 /* Take care of hero trying to move close to something frightening */
254
255 if (on(player, ISFLEE))
256 {
257 if (rnd(10) < 1)
258 {
259 turn_off(player, ISFLEE);
260 msg("You regain your composure.");
261 }
262 else if (DISTANCE(player.t_nxtpos, player.t_chasee->t_pos) <
263 DISTANCE(hero,player.t_chasee->t_pos))
264 return;
265 }
266
267 /* Take care of hero being held */
268
269 if (on(player, ISHELD) && !isalpha(ch))
270 {
271 if (rnd(pstats.s_str) > 14)
272 {
273 msg("You break free of the hold.");
274
275 if (--hold_count == 0)
276 turn_off(player, ISHELD);
277 }
278 else
279 {
280 msg("You are being held.");
281 return;
282 }
283 }
284
285 /* Might lose disguise */
286
287 if (on(player, ISDISGUISE) && rnd(11 * pstats.s_dext) == 0)
288 {
289 extinguish_fuse(FUSE_UNDISGUISE);
290 undisguise(NULL);
291 }
292
293 /* assume he's not in a wall */
294
295 if (!isalpha(ch))
296 turn_off(player, ISINWALL);
297
298 hch = CCHAR( mvinch(hero.y, hero.x) ); /* Where hero was */
299 old_hero = hero; /* Save hero's old position */
300
301 switch (ch)
302 {
303 case ' ':
304 case '|':
305 case '-':
306 case SECRETDOOR:
307 if (off(player, CANINWALL))
308 {
309 after = running = FALSE;
310 return;
311 }
312 else if (running)
313 {
314 after = running = FALSE;
315 return;
316 }
317 turn_on(player, ISINWALL);
318 break;
319
320 case TRAPDOOR:
321 case TELTRAP:
322 case BEARTRAP:
323 case SLEEPTRAP:
324 case ARROWTRAP:
325 case DARTTRAP:
326 case POOL:
327 case MAZETRAP:
328 case FIRETRAP:
329 case POISONTRAP:
330 case LAIR:
331 case RUSTTRAP:
332 ch = be_trapped(&player, player.t_nxtpos);
333
334 if (!is_wearing(R_LEVITATION) && off(player, CANFLY) &&
335 (old_hero.x != hero.x || old_hero.y != hero.y
336 || pool_teleport))
337 {
338 pool_teleport = FALSE;
339 return;
340 }
341
342 break;
343
344 case GOLD:
345 case POTION:
346 case SCROLL:
347 case FOOD:
348 case WEAPON:
349 case ARMOR:
350 case RING:
351 case ARTIFACT:
352 case STICK:
353 running = FALSE;
354 take = ch;
355 break;
356
357 default:
358 break;
359 }
360
361 if (ch == FIRETRAP)
362 light(&hero);
363
364 hero = player.t_nxtpos; /* Move the hero */
365
366 /* adjust lighting */
367
368 if (roomin(hero) == NULL && (hch == '-' || hch == '|' ||
369 hch == DOOR || hch == SECRETDOOR))
370 {
371 /* Leaving a room -- darken it */
372 struct room *rp = roomin(old_hero);
373 int is_lit = FALSE;
374
375 if (!(rp->r_flags & ISDARK))
376 is_lit = TRUE;
377
378 rp->r_flags |= ISDARK; /* Fake darkness */
379 light(&old_hero);
380
381 if (is_lit)