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