comparison rogue4/move.c @ 12:9535a08ddc39

Import Rogue 5.2 from the Roguelike Restoration Project (r1490)
author edwarj4
date Sat, 24 Oct 2009 16:52:52 +0000
parents
children 1b73a8641b37
comparison
equal deleted inserted replaced
11:949d558c2162 12:9535a08ddc39
1 /*
2 * Hero movement commands
3 *
4 * @(#)move.c 4.24 (Berkeley) 5/12/82
5 *
6 * Rogue: Exploring the Dungeons of Doom
7 * Copyright (C) 1980, 1981, 1982 Michael Toy, Ken Arnold and Glenn Wichman
8 * All rights reserved.
9 *
10 * See the file LICENSE.TXT for full copyright and licensing information.
11 */
12
13 #include <curses.h>
14 #include <ctype.h>
15 #include "rogue.h"
16
17 /*
18 * Used to hold the new hero position
19 */
20
21 coord nh;
22
23 /*
24 * do_run:
25 * Start the hero running
26 */
27 do_run(ch)
28 char ch;
29 {
30 running = TRUE;
31 after = FALSE;
32 runch = ch;
33 }
34
35 /*
36 * do_move:
37 * Check to see that a move is legal. If it is handle the
38 * consequences (fighting, picking up, etc.)
39 */
40 do_move(dy, dx)
41 int dy, dx;
42 {
43 register char ch, fl;
44
45 firstmove = FALSE;
46 if (no_move)
47 {
48 no_move--;
49 msg("you are still stuck in the bear trap");
50 return;
51 }
52 /*
53 * Do a confused move (maybe)
54 */
55 if (on(player, ISHUH) && rnd(5) != 0)
56 {
57 nh = *rndmove(&player);
58 if (ce(nh, hero))
59 {
60 after = FALSE;
61 running = FALSE;
62 return;
63 }
64 }
65 else
66 {
67 over:
68 nh.y = hero.y + dy;
69 nh.x = hero.x + dx;
70 }
71
72 /*
73 * Check if he tried to move off the screen or make an illegal
74 * diagonal move, and stop him if he did.
75 */
76 if (nh.x < 0 || nh.x > COLS-1 || nh.y < 1 || nh.y > LINES - 2)
77 goto hit_bound;
78 if (!diag_ok(&hero, &nh))
79 {
80 after = FALSE;
81 running = FALSE;
82 return;
83 }
84 if (running && ce(hero, nh))
85 after = running = FALSE;
86 fl = flat(nh.y, nh.x);
87 ch = winat(nh.y, nh.x);
88 if (!(fl & F_REAL) && ch == FLOOR)
89 {
90 chat(nh.y, nh.x) = ch = TRAP;
91 flat(nh.y, nh.x) |= F_REAL;
92 }
93 else
94 if (on(player, ISHELD) && ch != 'F')
95 {
96 msg("you are being held");
97 return;
98 }
99 switch (ch)
100 {
101 case ' ':
102 case '|':
103 case '-':
104 hit_bound:
105 if (passgo && running && (proom->r_flags & ISGONE)
106 && !on(player, ISBLIND))
107 {
108 register bool b1, b2;
109
110 switch (runch)
111 {
112 case 'h':
113 case 'l':
114 b1 = (((flat(hero.y - 1, hero.x) & F_PASS) || chat(hero.y - 1, hero.x) == DOOR) && hero.y != 1);
115 b2 = (((flat(hero.y + 1, hero.x) & F_PASS) || chat(hero.y + 1, hero.x) == DOOR) && hero.y != LINES - 2);
116 if (!(b1 ^ b2))
117 break;
118 if (b1)
119 {
120 runch = 'k';
121 dy = -1;
122 }
123 else
124 {
125 runch = 'j';
126 dy = 1;
127 }
128 dx = 0;
129 turnref();
130 goto over;
131 case 'j':
132 case 'k':
133 b1 = (((flat(hero.y, hero.x - 1) & F_PASS) || chat(hero.y, hero.x - 1) == DOOR) && hero.x != 0);
134 b2 = (((flat(hero.y, hero.x + 1) & F_PASS) || chat(hero.y, hero.x + 1) == DOOR) && hero.x != COLS - 1);
135 if (!(b1 ^ b2))
136 break;
137 if (b1)
138 {
139 runch = 'h';
140 dx = -1;
141 }
142 else
143 {
144 runch = 'l';
145 dx = 1;
146 }
147 dy = 0;
148 turnref();
149 goto over;
150 }
151 }
152 after = running = FALSE;
153 break;
154 case DOOR:
155 running = FALSE;
156 if (flat(hero.y, hero.x) & F_PASS)
157 enter_room(&nh);
158 goto move_stuff;
159 case TRAP:
160 ch = be_trapped(&nh);
161 if (ch == T_DOOR || ch == T_TELEP)
162 return;
163 goto move_stuff;
164 case PASSAGE:
165 goto move_stuff;
166 case FLOOR:
167 if (!(fl & F_REAL))
168 be_trapped(&hero);
169 goto move_stuff;
170 default:
171 running = FALSE;
172 if (isupper(ch) || moat(nh.y, nh.x))
173 fight(&nh, ch, cur_weapon, FALSE);
174 else
175 {
176 running = FALSE;
177 if (ch != STAIRS)
178 take = ch;
179 move_stuff:
180 mvaddch(hero.y, hero.x, chat(hero.y, hero.x));
181 if ((fl & F_PASS) && chat(oldpos.y, oldpos.x) == DOOR)
182 leave_room(&nh);
183 hero = nh;
184 }
185 }
186 }
187
188 /*
189 * turnref:
190 * Decide whether to refresh at a passage turning or not
191 */
192 turnref()
193 {
194 register int index;
195
196 index = INDEX(hero.y, hero.x);
197 if (!(_flags[index] & F_SEEN))
198 {
199 if (jump)
200 {
201 leaveok(stdscr, TRUE);
202 refresh();
203 leaveok(stdscr, FALSE);
204 }
205 _flags[index] |= F_SEEN;
206 }
207 }
208
209 /*
210 * door_open:
211 * Called to illuminate a room. If it is dark, remove anything
212 * that might move.
213 */
214 door_open(rp)
215 struct room *rp;
216 {
217 register int j, k;
218 register char ch;
219 register THING *item;
220
221 if (!(rp->r_flags & ISGONE) && !on(player, ISBLIND))
222 for (j = rp->r_pos.y; j < rp->r_pos.y + rp->r_max.y; j++)
223 for (k = rp->r_pos.x; k < rp->r_pos.x + rp->r_max.x; k++)
224 {
225 ch = winat(j, k);
226 move(j, k);
227 if (isupper(ch))
228 {
229 item = wake_monster(j, k);
230 if (item->t_oldch == ' ' && !(rp->r_flags & ISDARK)
231 && !on(player, ISBLIND))
232 item->t_oldch = chat(j, k);
233 }
234 }
235 }
236
237 /*
238 * be_trapped:
239 * The guy stepped on a trap.... Make him pay.
240 */
241 be_trapped(tc)
242 register coord *tc;
243 {
244 register char tr;
245 register int index;
246
247 count = running = FALSE;
248 index = INDEX(tc->y, tc->x);
249 _level[index] = TRAP;
250 tr = _flags[index] & F_TMASK;
251 switch (tr)
252 {
253 case T_DOOR:
254 level++;
255 new_level();
256 msg("you fell into a trap!");
257 when T_BEAR:
258 no_move += BEARTIME;
259 msg("you are caught in a bear trap");
260 when T_SLEEP:
261 no_command += SLEEPTIME;
262 player.t_flags &= ~ISRUN;
263 msg("a strange white mist envelops you and you fall asleep");
264 when T_ARROW:
265 if (swing(pstats.s_lvl-1, pstats.s_arm, 1))
266 {
267 pstats.s_hpt -= roll(1, 6);
268 if (pstats.s_hpt <= 0)
269 {
270 msg("an arrow killed you");
271 death('a');
272 }
273 else
274 msg("oh no! An arrow shot you");
275 }
276 else
277 {
278 register THING *arrow;
279
280 arrow = new_item();
281 arrow->o_type = WEAPON;
282 arrow->o_which = ARROW;
283 init_weapon(arrow, ARROW);
284 arrow->o_count = 1;
285 arrow->o_pos = hero;
286 arrow->o_hplus = arrow->o_dplus = 0;
287 fall(arrow, FALSE);
288 msg("an arrow shoots past you");
289 }
290 when T_TELEP:
291 teleport();
292 mvaddch(tc->y, tc->x, TRAP); /* since the hero's leaving, look()
293 won't put it on for us */
294 when T_DART:
295 if (swing(pstats.s_lvl+1, pstats.s_arm, 1))
296 {
297 pstats.s_hpt -= roll(1, 4);
298 if (pstats.s_hpt <= 0)
299 {
300 msg("a poisoned dart killed you");
301 death('d');
302 }
303 if (!ISWEARING(R_SUSTSTR) && !save(VS_POISON))
304 chg_str(-1);
305 msg("a small dart just hit you in the shoulder");
306 }
307 else
308 msg("a small dart whizzes by your ear and vanishes");
309 }
310 flush_type();
311 return tr;
312 }
313
314 /*
315 * rndmove:
316 * Move in a random direction if the monster/person is confused
317 */
318 coord *
319 rndmove(who)
320 THING *who;
321 {
322 register int x, y;
323 register char ch;
324 register THING *obj;
325 static coord ret; /* what we will be returning */
326
327 y = ret.y = who->t_pos.y + rnd(3) - 1;
328 x = ret.x = who->t_pos.x + rnd(3) - 1;
329 /*
330 * Now check to see if that's a legal move. If not, don't move.
331 * (I.e., bump into the wall or whatever)
332 */
333 if (y == who->t_pos.y && x == who->t_pos.x)
334 return &ret;
335 if ((y < 0 || y >= LINES - 1) || (x < 0 || x >= COLS))
336 goto bad;
337 else if (!diag_ok(&who->t_pos, &ret))
338 goto bad;
339 else
340 {
341 ch = winat(y, x);
342 if (!step_ok(ch))
343 goto bad;
344 if (ch == SCROLL)
345 {
346 for (obj = lvl_obj; obj != NULL; obj = next(obj))
347 if (y == obj->o_pos.y && x == obj->o_pos.x)
348 break;
349 if (obj != NULL && obj->o_which == S_SCARE)
350 goto bad;
351 }
352 }
353 return &ret;
354
355 bad:
356 ret = who->t_pos;
357 return &ret;
358 }