|
|
1.1 root 1: /*
2: * move.c
3: *
4: * This source herein may be modified and/or distributed by anybody who
5: * so desires, with the following restrictions:
6: * 1.) No portion of this notice shall be removed.
7: * 2.) Credit shall not be taken for the creation of this source.
8: * 3.) This code is not to be traded, sold, or used for personal
9: * gain or profit.
10: *
11: */
12:
13: #ifndef lint
14: static char sccsid[] = "@(#)move.c 5.1 (Berkeley) 11/25/87";
15: #endif /* not lint */
16:
17: #include "rogue.h"
18:
19: short m_moves = 0;
20: boolean jump = 0;
21: char *you_can_move_again = "you can move again";
22:
23: extern short cur_room, halluc, blind, levitate;
24: extern short cur_level, max_level;
25: extern short bear_trap, haste_self, confused;
26: extern short e_rings, regeneration, auto_search;
27: extern char hunger_str[];
28: extern boolean being_held, interrupted, r_teleport, passgo;
29:
30: one_move_rogue(dirch, pickup)
31: short dirch, pickup;
32: {
33: short row, col;
34: object *obj;
35: char desc[DCOLS];
36: short n, status, d;
37:
38: row = rogue.row;
39: col = rogue.col;
40:
41: if (confused) {
42: dirch = gr_dir();
43: }
44: (void) is_direction(dirch, &d);
45: get_dir_rc(d, &row, &col, 1);
46:
47: if (!can_move(rogue.row, rogue.col, row, col)) {
48: return(MOVE_FAILED);
49: }
50: if (being_held || bear_trap) {
51: if (!(dungeon[row][col] & MONSTER)) {
52: if (being_held) {
53: message("you are being held", 1);
54: } else {
55: message("you are still stuck in the bear trap", 0);
56: (void) reg_move();
57: }
58: return(MOVE_FAILED);
59: }
60: }
61: if (r_teleport) {
62: if (rand_percent(R_TELE_PERCENT)) {
63: tele();
64: return(STOPPED_ON_SOMETHING);
65: }
66: }
67: if (dungeon[row][col] & MONSTER) {
68: rogue_hit(object_at(&level_monsters, row, col), 0);
69: (void) reg_move();
70: return(MOVE_FAILED);
71: }
72: if (dungeon[row][col] & DOOR) {
73: if (cur_room == PASSAGE) {
74: cur_room = get_room_number(row, col);
75: light_up_room(cur_room);
76: wake_room(cur_room, 1, row, col);
77: } else {
78: light_passage(row, col);
79: }
80: } else if ((dungeon[rogue.row][rogue.col] & DOOR) &&
81: (dungeon[row][col] & TUNNEL)) {
82: light_passage(row, col);
83: wake_room(cur_room, 0, rogue.row, rogue.col);
84: darken_room(cur_room);
85: cur_room = PASSAGE;
86: } else if (dungeon[row][col] & TUNNEL) {
87: light_passage(row, col);
88: }
89: mvaddch(rogue.row, rogue.col, get_dungeon_char(rogue.row, rogue.col));
90: mvaddch(row, col, rogue.fchar);
91:
92: if (!jump) {
93: refresh();
94: }
95: rogue.row = row;
96: rogue.col = col;
97: if (dungeon[row][col] & OBJECT) {
98: if (levitate && pickup) {
99: return(STOPPED_ON_SOMETHING);
100: }
101: if (pickup && !levitate) {
102: if (obj = pick_up(row, col, &status)) {
103: get_desc(obj, desc);
104: if (obj->what_is == GOLD) {
105: free_object(obj);
106: goto NOT_IN_PACK;
107: }
108: } else if (!status) {
109: goto MVED;
110: } else {
111: goto MOVE_ON;
112: }
113: } else {
114: MOVE_ON:
115: obj = object_at(&level_objects, row, col);
116: (void) strcpy(desc, "moved onto ");
117: get_desc(obj, desc+11);
118: goto NOT_IN_PACK;
119: }
120: n = strlen(desc);
121: desc[n] = '(';
122: desc[n+1] = obj->ichar;
123: desc[n+2] = ')';
124: desc[n+3] = 0;
125: NOT_IN_PACK:
126: message(desc, 1);
127: (void) reg_move();
128: return(STOPPED_ON_SOMETHING);
129: }
130: if (dungeon[row][col] & (DOOR | STAIRS | TRAP)) {
131: if ((!levitate) && (dungeon[row][col] & TRAP)) {
132: trap_player(row, col);
133: }
134: (void) reg_move();
135: return(STOPPED_ON_SOMETHING);
136: }
137: MVED: if (reg_move()) { /* fainted from hunger */
138: return(STOPPED_ON_SOMETHING);
139: }
140: return((confused ? STOPPED_ON_SOMETHING : MOVED));
141: }
142:
143: multiple_move_rogue(dirch)
144: short dirch;
145: {
146: short row, col;
147: short m;
148:
149: switch(dirch) {
150: case '\010':
151: case '\012':
152: case '\013':
153: case '\014':
154: case '\031':
155: case '\025':
156: case '\016':
157: case '\002':
158: do {
159: row = rogue.row;
160: col = rogue.col;
161: if (((m = one_move_rogue((dirch + 96), 1)) == MOVE_FAILED) ||
162: (m == STOPPED_ON_SOMETHING) ||
163: interrupted) {
164: break;
165: }
166: } while (!next_to_something(row, col));
167: if ( (!interrupted) && passgo && (m == MOVE_FAILED) &&
168: (dungeon[rogue.row][rogue.col] & TUNNEL)) {
169: turn_passage(dirch + 96, 0);
170: }
171: break;
172: case 'H':
173: case 'J':
174: case 'K':
175: case 'L':
176: case 'B':
177: case 'Y':
178: case 'U':
179: case 'N':
180: while ((!interrupted) && (one_move_rogue((dirch + 32), 1) == MOVED)) ;
181:
182: if ( (!interrupted) && passgo &&
183: (dungeon[rogue.row][rogue.col] & TUNNEL)) {
184: turn_passage(dirch + 32, 1);
185: }
186: break;
187: }
188: }
189:
190: is_passable(row, col)
191: register row, col;
192: {
193: if ((row < MIN_ROW) || (row > (DROWS - 2)) || (col < 0) ||
194: (col > (DCOLS-1))) {
195: return(0);
196: }
197: if (dungeon[row][col] & HIDDEN) {
198: return((dungeon[row][col] & TRAP) ? 1 : 0);
199: }
200: return(dungeon[row][col] & (FLOOR | TUNNEL | DOOR | STAIRS | TRAP));
201: }
202:
203: next_to_something(drow, dcol)
204: register drow, dcol;
205: {
206: short i, j, i_end, j_end, row, col;
207: short pass_count = 0;
208: unsigned short s;
209:
210: if (confused) {
211: return(1);
212: }
213: if (blind) {
214: return(0);
215: }
216: i_end = (rogue.row < (DROWS-2)) ? 1 : 0;
217: j_end = (rogue.col < (DCOLS-1)) ? 1 : 0;
218:
219: for (i = ((rogue.row > MIN_ROW) ? -1 : 0); i <= i_end; i++) {
220: for (j = ((rogue.col > 0) ? -1 : 0); j <= j_end; j++) {
221: if ((i == 0) && (j == 0)) {
222: continue;
223: }
224: if (((rogue.row+i) == drow) && ((rogue.col+j) == dcol)) {
225: continue;
226: }
227: row = rogue.row + i;
228: col = rogue.col + j;
229: s = dungeon[row][col];
230: if (s & HIDDEN) {
231: continue;
232: }
233: /* If the rogue used to be right, up, left, down, or right of
234: * row,col, and now isn't, then don't stop */
235: if (s & (MONSTER | OBJECT | STAIRS)) {
236: if (((row == drow) || (col == dcol)) &&
237: (!((row == rogue.row) || (col == rogue.col)))) {
238: continue;
239: }
240: return(1);
241: }
242: if (s & TRAP) {
243: if (!(s & HIDDEN)) {
244: if (((row == drow) || (col == dcol)) &&
245: (!((row == rogue.row) || (col == rogue.col)))) {
246: continue;
247: }
248: return(1);
249: }
250: }
251: if ((((i - j) == 1) || ((i - j) == -1)) && (s & TUNNEL)) {
252: if (++pass_count > 1) {
253: return(1);
254: }
255: }
256: if ((s & DOOR) && ((i == 0) || (j == 0))) {
257: return(1);
258: }
259: }
260: }
261: return(0);
262: }
263:
264: can_move(row1, col1, row2, col2)
265: {
266: if (!is_passable(row2, col2)) {
267: return(0);
268: }
269: if ((row1 != row2) && (col1 != col2)) {
270: if ((dungeon[row1][col1] & DOOR) || (dungeon[row2][col2] & DOOR)) {
271: return(0);
272: }
273: if ((!dungeon[row1][col2]) || (!dungeon[row2][col1])) {
274: return(0);
275: }
276: }
277: return(1);
278: }
279:
280: move_onto()
281: {
282: short ch, d;
283: boolean first_miss = 1;
284:
285: while (!is_direction(ch = rgetchar(), &d)) {
286: sound_bell();
287: if (first_miss) {
288: message("direction? ", 0);
289: first_miss = 0;
290: }
291: }
292: check_message();
293: if (ch != CANCEL) {
294: (void) one_move_rogue(ch, 0);
295: }
296: }
297:
298: boolean
299: is_direction(c, d)
300: short c;
301: short *d;
302: {
303: switch(c) {
304: case 'h':
305: *d = LEFT;
306: break;
307: case 'j':
308: *d = DOWN;
309: break;
310: case 'k':
311: *d = UPWARD;
312: break;
313: case 'l':
314: *d = RIGHT;
315: break;
316: case 'b':
317: *d = DOWNLEFT;
318: break;
319: case 'y':
320: *d = UPLEFT;
321: break;
322: case 'u':
323: *d = UPRIGHT;
324: break;
325: case 'n':
326: *d = DOWNRIGHT;
327: break;
328: case CANCEL:
329: break;
330: default:
331: return(0);
332: }
333: return(1);
334: }
335:
336: boolean
337: check_hunger(msg_only)
338: boolean msg_only;
339: {
340: register short i, n;
341: boolean fainted = 0;
342:
343: if (rogue.moves_left == HUNGRY) {
344: (void) strcpy(hunger_str, "hungry");
345: message(hunger_str, 0);
346: print_stats(STAT_HUNGER);
347: }
348: if (rogue.moves_left == WEAK) {
349: (void) strcpy(hunger_str, "weak");
350: message(hunger_str, 1);
351: print_stats(STAT_HUNGER);
352: }
353: if (rogue.moves_left <= FAINT) {
354: if (rogue.moves_left == FAINT) {
355: (void) strcpy(hunger_str, "faint");
356: message(hunger_str, 1);
357: print_stats(STAT_HUNGER);
358: }
359: n = get_rand(0, (FAINT - rogue.moves_left));
360: if (n > 0) {
361: fainted = 1;
362: if (rand_percent(40)) {
363: rogue.moves_left++;
364: }
365: message("you faint", 1);
366: for (i = 0; i < n; i++) {
367: if (coin_toss()) {
368: mv_mons();
369: }
370: }
371: message(you_can_move_again, 1);
372: }
373: }
374: if (msg_only) {
375: return(fainted);
376: }
377: if (rogue.moves_left <= STARVE) {
378: killed_by((object *) 0, STARVATION);
379: }
380:
381: switch(e_rings) {
382: /*case -2:
383: Subtract 0, i.e. do nothing.
384: break;*/
385: case -1:
386: rogue.moves_left -= (rogue.moves_left % 2);
387: break;
388: case 0:
389: rogue.moves_left--;
390: break;
391: case 1:
392: rogue.moves_left--;
393: (void) check_hunger(1);
394: rogue.moves_left -= (rogue.moves_left % 2);
395: break;
396: case 2:
397: rogue.moves_left--;
398: (void) check_hunger(1);
399: rogue.moves_left--;
400: break;
401: }
402: return(fainted);
403: }
404:
405: boolean
406: reg_move()
407: {
408: boolean fainted;
409:
410: if ((rogue.moves_left <= HUNGRY) || (cur_level >= max_level)) {
411: fainted = check_hunger(0);
412: } else {
413: fainted = 0;
414: }
415:
416: mv_mons();
417:
418: if (++m_moves >= 120) {
419: m_moves = 0;
420: wanderer();
421: }
422: if (halluc) {
423: if (!(--halluc)) {
424: unhallucinate();
425: } else {
426: hallucinate();
427: }
428: }
429: if (blind) {
430: if (!(--blind)) {
431: unblind();
432: }
433: }
434: if (confused) {
435: if (!(--confused)) {
436: unconfuse();
437: }
438: }
439: if (bear_trap) {
440: bear_trap--;
441: }
442: if (levitate) {
443: if (!(--levitate)) {
444: message("you float gently to the ground", 1);
445: if (dungeon[rogue.row][rogue.col] & TRAP) {
446: trap_player(rogue.row, rogue.col);
447: }
448: }
449: }
450: if (haste_self) {
451: if (!(--haste_self)) {
452: message("you feel yourself slowing down", 0);
453: }
454: }
455: heal();
456: if (auto_search > 0) {
457: search(auto_search, auto_search);
458: }
459: return(fainted);
460: }
461:
462: rest(count)
463: {
464: int i;
465:
466: interrupted = 0;
467:
468: for (i = 0; i < count; i++) {
469: if (interrupted) {
470: break;
471: }
472: (void) reg_move();
473: }
474: }
475:
476: gr_dir()
477: {
478: short d;
479:
480: d = get_rand(1, 8);
481:
482: switch(d) {
483: case 1:
484: d = 'j';
485: break;
486: case 2:
487: d = 'k';
488: break;
489: case 3:
490: d = 'l';
491: break;
492: case 4:
493: d = 'h';
494: break;
495: case 5:
496: d = 'y';
497: break;
498: case 6:
499: d = 'u';
500: break;
501: case 7:
502: d = 'b';
503: break;
504: case 8:
505: d = 'n';
506: break;
507: }
508: return(d);
509: }
510:
511: heal()
512: {
513: static short heal_exp = -1, n, c = 0;
514: static boolean alt;
515:
516: if (rogue.hp_current == rogue.hp_max) {
517: c = 0;
518: return;
519: }
520: if (rogue.exp != heal_exp) {
521: heal_exp = rogue.exp;
522:
523: switch(heal_exp) {
524: case 1:
525: n = 20;
526: break;
527: case 2:
528: n = 18;
529: break;
530: case 3:
531: n = 17;
532: break;
533: case 4:
534: n = 14;
535: break;
536: case 5:
537: n = 13;
538: break;
539: case 6:
540: n = 10;
541: break;
542: case 7:
543: n = 9;
544: break;
545: case 8:
546: n = 8;
547: break;
548: case 9:
549: n = 7;
550: break;
551: case 10:
552: n = 4;
553: break;
554: case 11:
555: n = 3;
556: break;
557: case 12:
558: default:
559: n = 2;
560: }
561: }
562: if (++c >= n) {
563: c = 0;
564: rogue.hp_current++;
565: if (alt = !alt) {
566: rogue.hp_current++;
567: }
568: if ((rogue.hp_current += regeneration) > rogue.hp_max) {
569: rogue.hp_current = rogue.hp_max;
570: }
571: print_stats(STAT_HP);
572: }
573: }
574:
575: static boolean
576: can_turn(nrow, ncol)
577: short nrow, ncol;
578: {
579: if ((dungeon[nrow][ncol] & TUNNEL) && is_passable(nrow, ncol)) {
580: return(1);
581: }
582: return(0);
583: }
584:
585: turn_passage(dir, fast)
586: short dir;
587: boolean fast;
588: {
589: short crow = rogue.row, ccol = rogue.col, turns = 0;
590: short ndir;
591:
592: if ((dir != 'h') && can_turn(crow, ccol + 1)) {
593: turns++;
594: ndir = 'l';
595: }
596: if ((dir != 'l') && can_turn(crow, ccol - 1)) {
597: turns++;
598: ndir = 'h';
599: }
600: if ((dir != 'k') && can_turn(crow + 1, ccol)) {
601: turns++;
602: ndir = 'j';
603: }
604: if ((dir != 'j') && can_turn(crow - 1, ccol)) {
605: turns++;
606: ndir = 'k';
607: }
608: if (turns == 1) {
609: multiple_move_rogue(ndir - (fast ? 32 : 96));
610: }
611: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.