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