Annotation of early-roguelike/rogue3/command.c, Revision 1.1.1.1
1.1 rubenllo 1: /*
2: * Read and execute the user commands
3: *
4: * @(#)command.c 3.45 (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 <stdlib.h>
14: #include <ctype.h>
15: #include <signal.h>
16: #include <string.h>
17: #include "curses.h"
18: #include "machdep.h"
19: #include "rogue.h"
20:
21: /*
22: * command:
23: * Process the user commands
24: */
25:
26: void
27: command()
28: {
29: int ch;
30: int ntimes = 1; /* Number of player moves */
31: static int countch, direction, newcount = FALSE;
32:
33:
34: if (on(player, ISHASTE)) ntimes++;
35: /*
36: * Let the daemons start up
37: */
38: do_daemons(BEFORE);
39: do_fuses(BEFORE);
40: while (ntimes--)
41: {
42: look(TRUE);
43: if (!running)
44: door_stop = FALSE;
45: status();
46: lastscore = purse;
47: wmove(cw, hero.y, hero.x);
48: if (!((running || count) && jump))
49: draw(cw); /* Draw screen */
50: take = 0;
51: after = TRUE;
52: /*
53: * Read command or continue run
54: */
55: if (wizard)
56: waswizard = TRUE;
57: if (!no_command)
58: {
59: if (running) ch = runch;
60: else if (count) ch = countch;
61: else
62: {
63: ch = readchar(cw);
64: if (mpos != 0 && !running) /* Erase message if its there */
65: msg("");
66: }
67: }
68: else ch = ' ';
69: if (no_command)
70: {
71: if (--no_command == 0)
72: msg("You can move again.");
73: }
74: else
75: {
76: /*
77: * check for prefixes
78: */
79: if (isdigit(ch))
80: {
81: count = 0;
82: newcount = TRUE;
83: while (isdigit(ch))
84: {
85: count = count * 10 + (ch - '0');
86: ch = readchar(cw);
87: }
88: countch = ch;
89: /*
90: * turn off count for commands which don't make sense
91: * to repeat
92: */
93: switch (ch) {
94: case 'h': case 'j': case 'k': case 'l':
95: case 'y': case 'u': case 'b': case 'n':
96: case 'H': case 'J': case 'K': case 'L':
97: case 'Y': case 'U': case 'B': case 'N':
98: case 'q': case 'r': case 's': case 'f':
99: case 't': case 'C': case 'I': case '.':
100: case 'z': case 'p':
101: break;
102: default:
103: count = 0;
104: }
105: }
106: switch (ch)
107: {
108: case 'f':
109: if (!on(player, ISBLIND))
110: {
111: door_stop = TRUE;
112: firstmove = TRUE;
113: }
114: if (count && !newcount)
115: ch = direction;
116: else
117: ch = readchar(cw);
118: switch (ch)
119: {
120: case 'h': case 'j': case 'k': case 'l':
121: case 'y': case 'u': case 'b': case 'n':
122: ch = toupper(ch);
123: }
124: direction = ch;
125: }
126: newcount = FALSE;
127: /*
128: * execute a command
129: */
130: if (count && !running)
131: count--;
132: switch (ch)
133: {
134: case '!' : shell();
135: when 'h' : do_move(0, -1);
136: when 'j' : do_move(1, 0);
137: when 'k' : do_move(-1, 0);
138: when 'l' : do_move(0, 1);
139: when 'y' : do_move(-1, -1);
140: when 'u' : do_move(-1, 1);
141: when 'b' : do_move(1, -1);
142: when 'n' : do_move(1, 1);
143: when 'H' : do_run('h');
144: when 'J' : do_run('j');
145: when 'K' : do_run('k');
146: when 'L' : do_run('l');
147: when 'Y' : do_run('y');
148: when 'U' : do_run('u');
149: when 'B' : do_run('b');
150: when 'N' : do_run('n');
151: when 't':
152: if (!get_dir())
153: after = FALSE;
154: else
155: missile(delta.y, delta.x);
156: when 'Q' : after = FALSE; quit(0);
157: when 'i' : after = FALSE; inventory(pack, 0);
158: when 'I' : after = FALSE; picky_inven();
159: when 'd' : drop();
160: when 'q' : quaff();
161: when 'r' : read_scroll();
162: when 'e' : eat();
163: when 'w' : wield();
164: when 'W' : wear();
165: when 'T' : take_off();
166: when 'P' : ring_on();
167: when 'R' : ring_off();
168: when 'o' : option();
169: when 'c' : call();
170: when '>' : after = FALSE; d_level();
171: when '<' : after = FALSE; u_level();
172: when '?' : after = FALSE; help();
173: when '/' : after = FALSE; identify();
174: when 's' : search();
175: when 'z' : do_zap(FALSE);
176: when 'p':
177: if (get_dir())
178: do_zap(TRUE);
179: else
180: after = FALSE;
181: when 'v' : after = FALSE; msg("Rogue version %s. (mctesq was here)", release);
182: when CTRL('L') : after = FALSE; clearok(curscr,TRUE);draw(curscr);
183: when CTRL('R') : after = FALSE; msg(huh);
184: when 'S' :
185: after = FALSE;
186: if (save_game())
187: {
188: wmove(cw, LINES-1, 0);
189: wclrtoeol(cw);
190: draw(cw);
191: endwin();
192: printf("See you soon, %s!\n", whoami);
193: exit(0);
194: }
195: when '.' : ; /* Rest command */
196: #ifdef WIZARD
197: when CTRL('P') :
198: after = FALSE;
199: if (wizard)
200: {
201: wizard = FALSE;
202: msg("Not wizard any more");
203: }
204: else
205: {
206: if (wizard = passwd())
207: {
208: msg("You are suddenly as smart as Ken Arnold in dungeon #%d", dnum);
209: wizard = TRUE;
210: waswizard = TRUE;
211: }
212: else
213: msg("Sorry");
214: }
215: #endif
216: when ESCAPE : /* Escape */
217: door_stop = FALSE;
218: count = 0;
219: after = FALSE;
220: otherwise :
221: after = FALSE;
222: if (wizard) switch (ch)
223: {
224: case '@' : msg("@ %d,%d", hero.y, hero.x);
225: when 'C' : create_obj();
226: when CTRL('I') : inventory(lvl_obj, 0);
227: when CTRL('W') : whatis();
228: when CTRL('D') : level++; new_level();
229: when CTRL('U') : level--; new_level();
230: when CTRL('F') : show_win(stdscr, "--More (level map)--");
231: when CTRL('X') : show_win(mw, "--More (monsters)--");
232: when CTRL('T') : teleport();
233: when CTRL('E') : msg("food left: %d", food_left);
234: when CTRL('A') : msg("%d things in your pack", inpack);
235: when CTRL('C') : add_pass();
236: when CTRL('N') :
237: {
238: struct linked_list *item;
239:
240: if ((item = get_item("charge", STICK)) != NULL)
241: ((struct object *) ldata(item))->o_charges = 10000;
242: }
243: when CTRL('H') :
244: {
245: int i;
246: struct linked_list *item;
247: struct object *obj;
248:
249: for (i = 0; i < 9; i++)
250: raise_level();
251: /*
252: * Give the rogue a sword (+1,+1)
253: */
254: item = new_item(sizeof *obj);
255: obj = (struct object *) ldata(item);
256: obj->o_type = WEAPON;
257: obj->o_which = TWOSWORD;
258: init_weapon(obj, SWORD);
259: obj->o_hplus = 1;
260: obj->o_dplus = 1;
261: add_pack(item, TRUE);
262: cur_weapon = obj;
263: /*
264: * And his suit of armor
265: */
266: item = new_item(sizeof *obj);
267: obj = (struct object *) ldata(item);
268: obj->o_type = ARMOR;
269: obj->o_which = PLATE_MAIL;
270: obj->o_ac = -5;
271: obj->o_flags |= ISKNOW;
272: cur_armor = obj;
273: add_pack(item, TRUE);
274: }
275: otherwise :
276: msg("Illegal command '%s'.", unctrl(ch));
277: count = 0;
278: }
279: else
280: {
281: msg("Illegal command '%s'.", unctrl(ch));
282: count = 0;
283: }
284: }
285: /*
286: * turn off flags if no longer needed
287: */
288: if (!running)
289: door_stop = FALSE;
290: }
291: /*
292: * If he ran into something to take, let him pick it up.
293: */
294: if (take != 0)
295: pick_up(take);
296: if (!running)
297: door_stop = FALSE;
298: if (!after)
299: ntimes++;
300: }
301: /*
302: * Kick off the rest if the daemons and fuses
303: */
304: if (after)
305: {
306: look(FALSE);
307: do_daemons(AFTER);
308: do_fuses(AFTER);
309: if (ISRING(LEFT, R_SEARCH))
310: search();
311: else if (ISRING(LEFT, R_TELEPORT) && rnd(100) < 2)
312: teleport();
313: if (ISRING(RIGHT, R_SEARCH))
314: search();
315: else if (ISRING(RIGHT, R_TELEPORT) && rnd(100) < 2)
316: teleport();
317: }
318: }
319:
320: /*
321: * quit:
322: * Have player make certain, then exit.
323: */
324:
325: void
326: quit(int p)
327: {
328: /*
329: * Reset the signal in case we got here via an interrupt
330: */
331: if (signal(SIGINT, quit) != &quit)
332: mpos = 0;
333: msg("Really quit?");
334: draw(cw);
335: if (readchar(cw) == 'y')
336: {
337: clear();
338: move(LINES-1, 0);
339: draw(stdscr);
340: endwin();
341: writelog(purse, 1, 0);
342: score(purse, 1, 0);
343: printf("[Press return to exit]\n");
344: fflush(NULL);
345: getchar();
346: exit(0);
347: }
348: else
349: {
350: signal(SIGINT, quit);
351: wmove(cw, 0, 0);
352: wclrtoeol(cw);
353: status();
354: draw(cw);
355: mpos = 0;
356: count = 0;
357: }
358: }
359:
360: /*
361: * search:
362: * Player gropes about him to find hidden things.
363: */
364:
365: void
366: search()
367: {
368: int x, y;
369: int ch;
370:
371: /*
372: * Look all around the hero, if there is something hidden there,
373: * give him a chance to find it. If its found, display it.
374: */
375: if (on(player, ISBLIND))
376: return;
377: for (x = hero.x - 1; x <= hero.x + 1; x++)
378: for (y = hero.y - 1; y <= hero.y + 1; y++)
379: {
380: ch = winat(y, x);
381: switch (ch)
382: {
383: case SECRETDOOR:
384: if (rnd(100) < 20) {
385: mvaddch(y, x, DOOR);
386: count = 0;
387: }
388: break;
389: case TRAP:
390: {
391: struct trap *tp;
392:
393: if (mvwinch(cw, y, x) == TRAP)
394: break;
395: if (rnd(100) > 50)
396: break;
397: tp = trap_at(y, x);
398: tp->tr_flags |= ISFOUND;
399: mvwaddch(cw, y, x, TRAP);
400: count = 0;
401: running = FALSE;
402: msg(tr_name(tp->tr_type));
403: }
404: }
405: }
406: }
407:
408: /*
409: * help:
410: * Give single character help, or the whole mess if he wants it
411: */
412:
413: void
414: help()
415: {
416: struct h_list *strp = helpstr;
417: int helpch;
418: int cnt;
419:
420: msg("Character you want help for (* for all): ");
421: helpch = readchar(cw);
422: mpos = 0;
423: /*
424: * If its not a *, print the right help string
425: * or an error if he typed a funny character.
426: */
427: if (helpch != '*')
428: {
429: wmove(cw, 0, 0);
430: while (strp->h_ch)
431: {
432: if (strp->h_ch == helpch)
433: {
434: msg("%s%s", unctrl(strp->h_ch), strp->h_desc);
435: break;
436: }
437: strp++;
438: }
439: if (strp->h_ch != helpch)
440: msg("Unknown character '%s'", unctrl(helpch));
441: return;
442: }
443: /*
444: * Here we print help for everything.
445: * Then wait before we return to command mode
446: */
447: wclear(hw);
448: cnt = 0;
449: while (strp->h_ch)
450: {
451: mvwaddstr(hw, cnt % 23, cnt > 22 ? 40 : 0, unctrl(strp->h_ch));
452: waddstr(hw, strp->h_desc);
453: cnt++;
454: strp++;
455: }
456: wmove(hw, LINES-1, 0);
457: wprintw(hw, "--Press space to continue--");
458: draw(hw);
459: wait_for(hw,' ');
460: wclear(hw);
461: draw(hw);
462: wmove(cw, 0, 0);
463: wclrtoeol(cw);
464: status();
465: touchwin(cw);
466: }
467:
468: /*
469: * identify:
470: * Tell the player what a certain thing is.
471: */
472:
473: void
474: identify()
475: {
476: int ch;
477: char *str;
478:
479: msg("What do you want identified? ");
480: ch = readchar(cw);
481: mpos = 0;
482: if (ch == ESCAPE)
483: {
484: msg("");
485: return;
486: }
487: if (isalpha(ch) && isupper(ch))
488: str = monsters[ch-'A'].m_name;
489: else switch(ch)
490: {
491: case '|':
492: case '-':
493: str = "wall of a room";
494: when GOLD: str = "gold";
495: when STAIRS : str = "passage leading down";
496: when DOOR: str = "door";
497: when FLOOR: str = "room floor";
498: when PLAYER: str = "you";
499: when PASSAGE: str = "passage";
500: when TRAP: str = "trap";
501: when POTION: str = "potion";
502: when SCROLL: str = "scroll";
503: when FOOD: str = "food";
504: when WEAPON: str = "weapon";
505: when ' ' : str = "solid rock";
506: when ARMOR: str = "armor";
507: when AMULET: str = "The Amulet of Yendor";
508: when RING: str = "ring";
509: when STICK: str = "wand or staff";
510: otherwise: str = "unknown character";
511: }
512: msg("'%s' : %s", unctrl(ch), str);
513: }
514:
515: /*
516: * d_level:
517: * He wants to go down a level
518: */
519:
520: void
521: d_level()
522: {
523: if (winat(hero.y, hero.x) != STAIRS)
524: msg("I see no way down.");
525: else
526: {
527: level++;
528: new_level();
529: }
530: }
531:
532: /*
533: * u_level:
534: * He wants to go up a level
535: */
536:
537: void
538: u_level()
539: {
540: if (winat(hero.y, hero.x) == STAIRS)
541: {
542: if (amulet)
543: {
544: level--;
545: if (level == 0)
546: total_winner();
547: new_level();
548: msg("You feel a wrenching sensation in your gut.");
549: return;
550: }
551: }
552: msg("I see no way up.");
553: }
554:
555: /*
556: * Let him escape for a while
557: */
558:
559: void
560: shell()
561: {
562: /*
563: * Set the terminal back to original mode
564: */
565: wclear(hw);
566: wmove(hw, LINES-1, 0);
567: draw(hw);
568: endwin();
569: in_shell = TRUE;
570: fflush(stdout);
571:
572: md_shellescape();
573:
574: printf("\n[Press return to continue]");
575: fflush(stdout);
576: noecho();
577: crmode();
578: in_shell = FALSE;
579: wait_for(cw,'\n');
580: clearok(cw, TRUE);
581: touchwin(cw);
582: draw(cw);
583: }
584:
585: /*
586: * allow a user to call a potion, scroll, or ring something
587: */
588: void
589: call()
590: {
591: struct object *obj;
592: struct linked_list *item;
593: char **guess, *elsewise;
594: int *know;
595:
596: item = get_item("call", CALLABLE);
597: /*
598: * Make certain that it is somethings that we want to wear
599: */
600: if (item == NULL)
601: return;
602: obj = (struct object *) ldata(item);
603: switch (obj->o_type)
604: {
605: case RING:
606: guess = r_guess;
607: know = r_know;
608: elsewise = (r_guess[obj->o_which] != NULL ?
609: r_guess[obj->o_which] : r_stones[obj->o_which]);
610: when POTION:
611: guess = p_guess;
612: know = p_know;
613: elsewise = (p_guess[obj->o_which] != NULL ?
614: p_guess[obj->o_which] : p_colors[obj->o_which]);
615: when SCROLL:
616: guess = s_guess;
617: know = s_know;
618: elsewise = (s_guess[obj->o_which] != NULL ?
619: s_guess[obj->o_which] : s_names[obj->o_which]);
620: when STICK:
621: guess = ws_guess;
622: know = ws_know;
623: elsewise = (ws_guess[obj->o_which] != NULL ?
624: ws_guess[obj->o_which] : ws_made[obj->o_which]);
625: otherwise:
626: msg("You can't call that anything");
627: return;
628: }
629: if (know[obj->o_which])
630: {
631: msg("That has already been identified");
632: return;
633: }
634: if (terse)
635: addmsg("C");
636: else
637: addmsg("Was c");
638: msg("alled \"%s\"", elsewise);
639: if (terse)
640: msg("Call it: ");
641: else
642: msg("What do you want to call it? ");
643: strcpy(prbuf, elsewise);
644: if (get_str(prbuf, cw) == NORM)
645: {
646: if (guess[obj->o_which] != NULL)
647: free(guess[obj->o_which]);
648: guess[obj->o_which] = malloc((unsigned int) strlen(prbuf) + 1);
649: if (guess[obj->o_which] != NULL)
650: strcpy(guess[obj->o_which], prbuf);
651: }
652: }
CVSweb