Annotation of early-roguelike/rogue5/move.c, Revision 1.1.1.1
1.1 rubenllo 1: /*
2: * hero movement commands
3: *
4: * @(#)move.c 4.49 (Berkeley) 02/05/99
5: *
6: * Rogue: Exploring the Dungeons of Doom
7: * Copyright (C) 1980-1983, 1985, 1999 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:
22: /*
23: * do_run:
24: * Start the hero running
25: */
26:
27: void
28: do_run(int 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:
41: void
42: do_move(int dy, int dx)
43: {
44: int ch, fl;
45: coord nh;
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 (on(player, ISHUH) && rnd(5) != 0)
58: {
59: nh = rndmove(&player);
60: if (ce(nh, hero))
61: {
62: after = FALSE;
63: running = FALSE;
64: to_death = FALSE;
65: return;
66: }
67: }
68: else
69: {
70: over:
71: nh.y = hero.y + dy;
72: nh.x = hero.x + dx;
73: }
74:
75: /*
76: * Check if he tried to move off the screen or make an illegal
77: * diagonal move, and stop him if he did.
78: */
79: if (nh.x < 0 || nh.x >= NUMCOLS || nh.y <= 0 || nh.y >= NUMLINES - 1)
80: goto hit_bound;
81: if (!diag_ok(&hero, &nh))
82: {
83: after = FALSE;
84: running = FALSE;
85: return;
86: }
87: if (running && ce(hero, nh))
88: after = running = FALSE;
89: fl = flat(nh.y, nh.x);
90: ch = winat(nh.y, nh.x);
91: if (!(fl & F_REAL) && ch == FLOOR)
92: {
93: if (!on(player, ISLEVIT))
94: {
95: chat(nh.y, nh.x) = ch = TRAP;
96: flat(nh.y, nh.x) |= F_REAL;
97: }
98: }
99: else if (on(player, ISHELD) && ch != 'F')
100: {
101: msg("you are being held");
102: return;
103: }
104: switch (ch)
105: {
106: case ' ':
107: case '|':
108: case '-':
109: hit_bound:
110: if (passgo && running && (proom->r_flags & ISGONE)
111: && !on(player, ISBLIND))
112: {
113: int b1, b2;
114:
115: switch (runch)
116: {
117: case 'h':
118: case 'l':
119: b1 = (hero.y != 1 && turn_ok(hero.y - 1, hero.x));
120: b2 = (hero.y != NUMLINES - 2 && turn_ok(hero.y + 1, hero.x));
121: if (!(b1 ^ b2))
122: break;
123: if (b1)
124: {
125: runch = 'k';
126: dy = -1;
127: }
128: else
129: {
130: runch = 'j';
131: dy = 1;
132: }
133: dx = 0;
134: turnref();
135: goto over;
136: case 'j':
137: case 'k':
138: b1 = (hero.x != 0 && turn_ok(hero.y, hero.x - 1));
139: b2 = (hero.x != NUMCOLS - 1 && turn_ok(hero.y, hero.x + 1));
140: if (!(b1 ^ b2))
141: break;
142: if (b1)
143: {
144: runch = 'h';
145: dx = -1;
146: }
147: else
148: {
149: runch = 'l';
150: dx = 1;
151: }
152: dy = 0;
153: turnref();
154: goto over;
155: }
156: }
157: running = FALSE;
158: after = FALSE;
159: break;
160: case DOOR:
161: running = FALSE;
162: if (flat(hero.y, hero.x) & F_PASS)
163: enter_room(&nh);
164: goto move_stuff;
165: case TRAP:
166: ch = be_trapped(&nh);
167: if (ch == T_DOOR || ch == T_TELEP)
168: return;
169: goto move_stuff;
170: case PASSAGE:
171: /*
172: * when you're in a corridor, you don't know if you're in
173: * a maze room or not, and there ain't no way to find out
174: * if you're leaving a maze room, so it is necessary to
175: * always recalculate proom.
176: */
177: proom = roomin(&hero);
178: goto move_stuff;
179: case FLOOR:
180: if (!(fl & F_REAL))
181: be_trapped(&hero);
182: goto move_stuff;
183: case STAIRS:
184: seenstairs = TRUE;
185: /* FALLTHROUGH */
186: default:
187: running = FALSE;
188: if (isupper(ch) || moat(nh.y, nh.x))
189: fight(&nh, cur_weapon, FALSE);
190: else
191: {
192: if (ch != STAIRS)
193: take = ch;
194: move_stuff:
195: mvaddch(hero.y, hero.x, floor_at());
196: if ((fl & F_PASS) && chat(oldpos.y, oldpos.x) == DOOR)
197: leave_room(&nh);
198: hero = nh;
199: }
200: }
201: }
202:
203: /*
204: * turn_ok:
205: * Decide whether it is legal to turn onto the given space
206: */
207: int
208: turn_ok(int y, int x)
209: {
210: PLACE *pp;
211:
212: pp = INDEX(y, x);
213: return (pp->p_ch == DOOR
214: || (pp->p_flags & (F_REAL|F_PASS)) == (F_REAL|F_PASS));
215: }
216:
217: /*
218: * turnref:
219: * Decide whether to refresh at a passage turning or not
220: */
221:
222: void
223: turnref(void)
224: {
225: PLACE *pp;
226:
227: pp = INDEX(hero.y, hero.x);
228: if (!(pp->p_flags & F_SEEN))
229: {
230: if (jump)
231: {
232: leaveok(stdscr, TRUE);
233: refresh();
234: leaveok(stdscr, FALSE);
235: }
236: pp->p_flags |= F_SEEN;
237: }
238: }
239:
240: /*
241: * door_open:
242: * Called to illuminate a room. If it is dark, remove anything
243: * that might move.
244: */
245:
246: void
247: door_open(const struct room *rp)
248: {
249: int y, x;
250:
251: if (!(rp->r_flags & ISGONE))
252: for (y = rp->r_pos.y; y < rp->r_pos.y + rp->r_max.y; y++)
253: for (x = rp->r_pos.x; x < rp->r_pos.x + rp->r_max.x; x++)
254: if (isupper(winat(y, x)))
255: wake_monster(y, x);
256: }
257:
258: /*
259: * be_trapped:
260: * The guy stepped on a trap.... Make him pay.
261: */
262: int
263: be_trapped(const coord *tc)
264: {
265: PLACE *pp;
266: THING *arrow;
267: int tr;
268:
269: if (on(player, ISLEVIT))
270: return T_RUST; /* anything that's not a door or teleport */
271: running = FALSE;
272: count = FALSE;
273: pp = INDEX(tc->y, tc->x);
274: pp->p_ch = TRAP;
275: tr = pp->p_flags & F_TMASK;
276: pp->p_flags |= F_SEEN;
277: switch (tr)
278: {
279: case T_DOOR:
280: level++;
281: new_level();
282: msg("you fell into a trap!");
283: when T_BEAR:
284: no_move += BEARTIME;
285: msg("you are caught in a bear trap");
286: when T_MYST:
287: switch(rnd(11))
288: {
289: case 0: msg("you are suddenly in a parallel dimension");
290: when 1: msg("the light in here suddenly seems %s", rainbow[rnd(cNCOLORS)]);
291: when 2: msg("you feel a sting in the side of your neck");
292: when 3: msg("multi-colored lines swirl around you, then fade");
293: when 4: msg("a %s light flashes in your eyes", rainbow[rnd(cNCOLORS)]);
294: when 5: msg("a spike shoots past your ear!");
295: when 6: msg("%s sparks dance across your armor", rainbow[rnd(cNCOLORS)]);
296: when 7: msg("you suddenly feel very thirsty");
297: when 8: msg("you feel time speed up suddenly");
298: when 9: msg("time now seems to be going slower");
299: when 10: msg("you pack turns %s!", rainbow[rnd(cNCOLORS)]);
300: }
301: when T_SLEEP:
302: no_command += SLEEPTIME;
303: player.t_flags &= ~ISRUN;
304: msg("a strange white mist envelops you and you fall asleep");
305: when T_ARROW:
306: if (swing(pstats.s_lvl - 1, pstats.s_arm, 1))
307: {
308: pstats.s_hpt -= roll(1, 6);
309: if (pstats.s_hpt <= 0)
310: {
311: msg("an arrow killed you");
312: death('a');
313: }
314: else
315: msg("oh no! An arrow shot you");
316: }
317: else
318: {
319: arrow = new_item();
320: init_weapon(arrow, ARROW);
321: arrow->o_count = 1;
322: arrow->o_pos = hero;
323: fall(arrow, FALSE);
324: msg("an arrow shoots past you");
325: }
326: when T_TELEP:
327: /*
328: * since the hero's leaving, look() won't put a TRAP
329: * down for us, so we have to do it ourself
330: */
331: teleport();
332: mvaddch(tc->y, tc->x, TRAP);
333: when T_DART:
334: if (!swing(pstats.s_lvl+1, pstats.s_arm, 1))
335: msg("a small dart whizzes by your ear and vanishes");
336: else
337: {
338: pstats.s_hpt -= roll(1, 4);
339: if (pstats.s_hpt <= 0)
340: {
341: msg("a poisoned dart killed you");
342: death('d');
343: }
344: if (!ISWEARING(R_SUSTSTR) && !save(VS_POISON))
345: chg_str(-1);
346: msg("a small dart just hit you in the shoulder");
347: }
348: when T_RUST:
349: msg("a gush of water hits you on the head");
350: rust_armor(cur_armor);
351: }
352: flush_type();
353: return tr;
354: }
355:
356: /*
357: * rndmove:
358: * Move in a random direction if the monster/person is confused
359: */
360: coord
361: rndmove(const THING *who)
362: {
363: THING *obj;
364: int x, y;
365: int ch;
366: coord ret; /* what we will be returning */
367:
368: y = ret.y = who->t_pos.y + rnd(3) - 1;
369: x = ret.x = who->t_pos.x + rnd(3) - 1;
370: /*
371: * Now check to see if that's a legal move. If not, don't move.
372: * (I.e., bump into the wall or whatever)
373: */
374: if (y == who->t_pos.y && x == who->t_pos.x)
375: return ret;
376: if (!diag_ok(&who->t_pos, &ret))
377: goto bad;
378: else
379: {
380: ch = winat(y, x);
381: if (!step_ok(ch))
382: goto bad;
383: if (ch == SCROLL)
384: {
385: for (obj = lvl_obj; obj != NULL; obj = next(obj))
386: if (y == obj->o_pos.y && x == obj->o_pos.x)
387: break;
388: if (obj != NULL && obj->o_which == S_SCARE)
389: goto bad;
390: }
391: }
392: return ret;
393:
394: bad:
395: ret = who->t_pos;
396: return ret;
397: }
398:
399: /*
400: * rust_armor:
401: * Rust the given armor, if it is a legal kind to rust, and we
402: * aren't wearing a magic ring.
403: */
404:
405: void
406: rust_armor(THING *arm)
407: {
408: if (arm == NULL || arm->o_type != ARMOR || arm->o_which == LEATHER ||
409: arm->o_arm >= 9)
410: return;
411:
412: if ((arm->o_flags & ISPROT) || ISWEARING(R_SUSTARM))
413: {
414: if (!to_death)
415: msg("the rust vanishes instantly");
416: }
417: else
418: {
419: arm->o_arm++;
420: if (!terse)
421: msg("your armor appears to be weaker now. Oh my!");
422: else
423: msg("your armor weakens");
424: }
425: }
CVSweb