Mercurial > hg > early-roguelike
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 } |