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