comparison rogue3/move.c @ 0:527e2150eaf0

Import Rogue 3.6 from the Roguelike Restoration Project (r1490)
author edwarj4
date Tue, 13 Oct 2009 13:33:34 +0000
parents
children d9e44e18eeec
comparison
equal deleted inserted replaced
-1:000000000000 0:527e2150eaf0
1 /*
2 * Hero movement commands
3 *
4 * @(#)move.c 3.26 (Berkeley) 6/15/81
5 *
6 * Rogue: Exploring the Dungeons of Doom
7 * Copyright (C) 1980, 1981 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
28 void
29 do_run(int ch)
30 {
31 running = TRUE;
32 after = FALSE;
33 runch = ch;
34 }
35
36 /*
37 * do_move:
38 * Check to see that a move is legal. If it is handle the
39 * consequences (fighting, picking up, etc.)
40 */
41
42 void
43 do_move(int dy, int dx)
44 {
45 int ch;
46
47 firstmove = FALSE;
48 if (no_move)
49 {
50 no_move--;
51 msg("You are still stuck in the bear trap");
52 return;
53 }
54 /*
55 * Do a confused move (maybe)
56 */
57 if (rnd(100) < 80 && on(player, ISHUH))
58 nh = *rndmove(&player);
59 else
60 {
61 nh.y = hero.y + dy;
62 nh.x = hero.x + dx;
63 }
64
65 /*
66 * Check if he tried to move off the screen or make an illegal
67 * diagonal move, and stop him if he did.
68 */
69 if (nh.x < 0 || nh.x > COLS-1 || nh.y < 0 || nh.y > LINES - 1
70 || !diag_ok(&hero, &nh))
71 {
72 after = FALSE;
73 running = FALSE;
74 return;
75 }
76 if (running && ce(hero, nh))
77 after = running = FALSE;
78 ch = winat(nh.y, nh.x);
79 if (on(player, ISHELD) && ch != 'F')
80 {
81 msg("You are being held");
82 return;
83 }
84 switch(ch)
85 {
86 case ' ':
87 case '|':
88 case '-':
89 case SECRETDOOR:
90 after = running = FALSE;
91 return;
92 case TRAP:
93 ch = be_trapped(&nh);
94 if (ch == TRAPDOOR || ch == TELTRAP)
95 return;
96 goto move_stuff;
97 case GOLD:
98 case POTION:
99 case SCROLL:
100 case FOOD:
101 case WEAPON:
102 case ARMOR:
103 case RING:
104 case AMULET:
105 case STICK:
106 running = FALSE;
107 take = ch;
108 default:
109 move_stuff:
110 if (ch == PASSAGE && winat(hero.y, hero.x) == DOOR)
111 light(&hero);
112 else if (ch == DOOR)
113 {
114 running = FALSE;
115 if (winat(hero.y, hero.x) == PASSAGE)
116 light(&nh);
117 }
118 else if (ch == STAIRS)
119 running = FALSE;
120 else if (isupper(ch))
121 {
122 running = FALSE;
123 fight(&nh, ch, cur_weapon, FALSE);
124 return;
125 }
126 ch = winat(hero.y, hero.x);
127 wmove(cw, unc(hero));
128 waddch(cw, ch);
129 hero = nh;
130 wmove(cw, unc(hero));
131 waddch(cw, PLAYER);
132 }
133 }
134
135 /*
136 * Called to illuminate a room.
137 * If it is dark, remove anything that might move.
138 */
139
140 void
141 light(coord *cp)
142 {
143 struct room *rp;
144 int j, k;
145 int ch;
146 int rch;
147 struct linked_list *item;
148
149 if ((rp = roomin(cp)) != NULL && !on(player, ISBLIND))
150 {
151 for (j = 0; j < rp->r_max.y; j++)
152 {
153 for (k = 0; k < rp->r_max.x; k++)
154 {
155 ch = show(rp->r_pos.y + j, rp->r_pos.x + k);
156 wmove(cw, rp->r_pos.y + j, rp->r_pos.x + k);
157 /*
158 * Figure out how to display a secret door
159 */
160 if (ch == SECRETDOOR)
161 {
162 if (j == 0 || j == rp->r_max.y - 1)
163 ch = '-';
164 else
165 ch = '|';
166 }
167 /*
168 * If the room is a dark room, we might want to remove
169 * monsters and the like from it (since they might
170 * move)
171 */
172 if (isupper(ch))
173 {
174 item = wake_monster(rp->r_pos.y+j, rp->r_pos.x+k);
175 if (((struct thing *) ldata(item))->t_oldch == ' ')
176 if (!(rp->r_flags & ISDARK))
177 ((struct thing *) ldata(item))->t_oldch =
178 mvwinch(stdscr, rp->r_pos.y+j, rp->r_pos.x+k);
179 }
180 if (rp->r_flags & ISDARK)
181 {
182 rch = mvwinch(cw, rp->r_pos.y+j, rp->r_pos.x+k);
183 switch (rch)
184 {
185 case DOOR:
186 case STAIRS:
187 case TRAP:
188 case '|':
189 case '-':
190 case ' ':
191 ch = rch;
192 when FLOOR:
193 ch = (on(player, ISBLIND) ? FLOOR : ' ');
194 otherwise:
195 ch = ' ';
196 }
197 }
198 mvwaddch(cw, rp->r_pos.y+j, rp->r_pos.x+k, ch);
199 }
200 }
201 }
202 }
203
204 /*
205 * show:
206 * returns what a certain thing will display as to the un-initiated
207 */
208
209 int
210 show(int y, int x)
211 {
212 int ch = winat(y, x);
213 struct linked_list *it;
214 struct thing *tp;
215
216 if (ch == TRAP)
217 return (trap_at(y, x)->tr_flags & ISFOUND) ? TRAP : FLOOR;
218 else if (ch == 'M' || ch == 'I')
219 {
220 if ((it = find_mons(y, x)) == NULL)
221 fatal("Can't find monster in show");
222 tp = (struct thing *) ldata(it);
223 if (ch == 'M')
224 ch = tp->t_disguise;
225 /*
226 * Hide invisible monsters
227 */
228 else if (off(player, CANSEE))
229 ch = mvwinch(stdscr, y, x);
230 }
231 return ch;
232 }
233
234 /*
235 * be_trapped:
236 * The guy stepped on a trap.... Make him pay.
237 */
238
239 int
240 be_trapped(coord *tc)
241 {
242 struct trap *tp;
243 int ch;
244
245 tp = trap_at(tc->y, tc->x);
246 count = running = FALSE;
247 mvwaddch(cw, tp->tr_pos.y, tp->tr_pos.x, TRAP);
248 tp->tr_flags |= ISFOUND;
249 switch (ch = tp->tr_type)
250 {
251 case TRAPDOOR:
252 level++;
253 new_level();
254 msg("You fell into a trap!");
255 when BEARTRAP:
256 no_move += BEARTIME;
257 msg("You are caught in a bear trap");
258 when SLEEPTRAP:
259 no_command += SLEEPTIME;
260 msg("A strange white mist envelops you and you fall asleep");
261 when ARROWTRAP:
262 if (swing(pstats.s_lvl-1, pstats.s_arm, 1))
263 {
264 msg("Oh no! An arrow shot you");
265 if ((pstats.s_hpt -= roll(1, 6)) <= 0)
266 {
267 msg("The arrow killed you.");
268 death('a');
269 }
270 }
271 else
272 {
273 struct linked_list *item;
274 struct object *arrow;
275
276 msg("An arrow shoots past you.");
277 item = new_item(sizeof *arrow);
278 arrow = (struct object *) ldata(item);
279 arrow->o_type = WEAPON;
280 arrow->o_which = ARROW;
281 init_weapon(arrow, ARROW);
282 arrow->o_count = 1;
283 arrow->o_pos = hero;
284 arrow->o_hplus = arrow->o_dplus = 0; /* "arrow bug" FIX */
285 fall(item, FALSE);
286 }
287 when TELTRAP:
288 teleport();
289 when DARTTRAP:
290 if (swing(pstats.s_lvl+1, pstats.s_arm, 1))
291 {
292 msg("A small dart just hit you in the shoulder");
293 if ((pstats.s_hpt -= roll(1, 4)) <= 0)
294 {
295 msg("The dart killed you.");
296 death('d');
297 }
298 if (!ISWEARING(R_SUSTSTR))
299 chg_str(-1);
300 }
301 else
302 msg("A small dart whizzes by your ear and vanishes.");
303 }
304 flush_type(); /* flush typeahead */
305 return(ch);
306 }
307
308 /*
309 * trap_at:
310 * find the trap at (y,x) on screen.
311 */
312
313 struct trap *
314 trap_at(int y, int x)
315 {
316 struct trap *tp, *ep;
317
318 ep = &traps[ntraps];
319 for (tp = traps; tp < ep; tp++)
320 if (tp->tr_pos.y == y && tp->tr_pos.x == x)
321 break;
322 if (tp == ep)
323 {
324 sprintf(prbuf, "Trap at %d,%d not in array", y, x);
325 fatal(prbuf);
326 }
327 return tp;
328 }
329
330 /*
331 * rndmove:
332 * move in a random direction if the monster/person is confused
333 */
334
335 coord *
336 rndmove(struct thing *who)
337 {
338 int x, y;
339 int ch;
340 int ex, ey, nopen = 0;
341 struct linked_list *item;
342 struct object *obj;
343 static coord ret; /* what we will be returning */
344 static coord dest;
345
346 ret = who->t_pos;
347 /*
348 * Now go through the spaces surrounding the player and
349 * set that place in the array to true if the space can be
350 * moved into
351 */
352 ey = ret.y + 1;
353 ex = ret.x + 1;
354 for (y = who->t_pos.y - 1; y <= ey; y++)
355 if (y >= 0 && y < LINES)
356 for (x = who->t_pos.x - 1; x <= ex; x++)
357 {
358 if (x < 0 || x >= COLS)
359 continue;
360 ch = winat(y, x);
361 if (step_ok(ch))
362 {
363 dest.y = y;
364 dest.x = x;
365 if (!diag_ok(&who->t_pos, &dest))
366 continue;
367 if (ch == SCROLL)
368 {
369 item = NULL;
370 for (item = lvl_obj; item != NULL; item = next(item))
371 {
372 obj = (struct object *) ldata(item);
373 if (y == obj->o_pos.y && x == obj->o_pos.x)
374 break;
375 }
376 if (item != NULL && obj->o_which == S_SCARE)
377 continue;
378 }
379 if (rnd(++nopen) == 0)
380 ret = dest;
381 }
382 }
383 return &ret;
384 }