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