Annotation of early-roguelike/rogue3/move.c, Revision 1.1.1.1
1.1 rubenllo 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 = NULL;
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: }
CVSweb