comparison rogue3/command.c @ 0:527e2150eaf0

Import Rogue 3.6 from the Roguelike Restoration Project (r1490)
author edwarj4
date Tue, 13 Oct 2009 13:33:34 +0000
parents
children e551d384f7c6
comparison
equal deleted inserted replaced
-1:000000000000 0:527e2150eaf0
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' : 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 exit(0);
193 }
194 when ' ' : ; /* Rest command */
195 when CTRL('P') :
196 after = FALSE;
197 if (wizard)
198 {
199 wizard = FALSE;
200 msg("Not wizard any more");
201 }
202 else
203 {
204 if (wizard = passwd())
205 {
206 msg("You are suddenly as smart as Ken Arnold in dungeon #%d", dnum);
207 wizard = TRUE;
208 waswizard = TRUE;
209 }
210 else
211 msg("Sorry");
212 }
213 when ESCAPE : /* Escape */
214 door_stop = FALSE;
215 count = 0;
216 after = FALSE;
217 otherwise :
218 after = FALSE;
219 if (wizard) switch (ch)
220 {
221 case '@' : msg("@ %d,%d", hero.y, hero.x);
222 when 'C' : create_obj();
223 when CTRL('I') : inventory(lvl_obj, 0);
224 when CTRL('W') : whatis();
225 when CTRL('D') : level++; new_level();
226 when CTRL('U') : level--; new_level();
227 when CTRL('F') : show_win(stdscr, "--More (level map)--");
228 when CTRL('X') : show_win(mw, "--More (monsters)--");
229 when CTRL('T') : teleport();
230 when CTRL('E') : msg("food left: %d", food_left);
231 when CTRL('A') : msg("%d things in your pack", inpack);
232 when CTRL('C') : add_pass();
233 when CTRL('N') :
234 {
235 struct linked_list *item;
236
237 if ((item = get_item("charge", STICK)) != NULL)
238 ((struct object *) ldata(item))->o_charges = 10000;
239 }
240 when CTRL('H') :
241 {
242 int i;
243 struct linked_list *item;
244 struct object *obj;
245
246 for (i = 0; i < 9; i++)
247 raise_level();
248 /*
249 * Give the rogue a sword (+1,+1)
250 */
251 item = new_item(sizeof *obj);
252 obj = (struct object *) ldata(item);
253 obj->o_type = WEAPON;
254 obj->o_which = TWOSWORD;
255 init_weapon(obj, SWORD);
256 obj->o_hplus = 1;
257 obj->o_dplus = 1;
258 add_pack(item, TRUE);
259 cur_weapon = obj;
260 /*
261 * And his suit of armor
262 */
263 item = new_item(sizeof *obj);
264 obj = (struct object *) ldata(item);
265 obj->o_type = ARMOR;
266 obj->o_which = PLATE_MAIL;
267 obj->o_ac = -5;
268 obj->o_flags |= ISKNOW;
269 cur_armor = obj;
270 add_pack(item, TRUE);
271 }
272 otherwise :
273 msg("Illegal command '%s'.", unctrl(ch));
274 count = 0;
275 }
276 else
277 {
278 msg("Illegal command '%s'.", unctrl(ch));
279 count = 0;
280 }
281 }
282 /*
283 * turn off flags if no longer needed
284 */
285 if (!running)
286 door_stop = FALSE;
287 }
288 /*
289 * If he ran into something to take, let him pick it up.
290 */
291 if (take != 0)
292 pick_up(take);
293 if (!running)
294 door_stop = FALSE;
295 if (!after)
296 ntimes++;
297 }
298 /*
299 * Kick off the rest if the daemons and fuses
300 */
301 if (after)
302 {
303 look(FALSE);
304 do_daemons(AFTER);
305 do_fuses(AFTER);
306 if (ISRING(LEFT, R_SEARCH))
307 search();
308 else if (ISRING(LEFT, R_TELEPORT) && rnd(100) < 2)
309 teleport();
310 if (ISRING(RIGHT, R_SEARCH))
311 search();
312 else if (ISRING(RIGHT, R_TELEPORT) && rnd(100) < 2)
313 teleport();
314 }
315 }
316
317 /*
318 * quit:
319 * Have player make certain, then exit.
320 */
321
322 void
323 quit(int p)
324 {
325 /*
326 * Reset the signal in case we got here via an interrupt
327 */
328 if (signal(SIGINT, quit) != &quit)
329 mpos = 0;
330 msg("Really quit?");
331 draw(cw);
332 if (readchar(cw) == 'y')
333 {
334 clear();
335 move(LINES-1, 0);
336 draw(stdscr);
337 endwin();
338 score(purse, 1, 0);
339 exit(0);
340 }
341 else
342 {
343 signal(SIGINT, quit);
344 wmove(cw, 0, 0);
345 wclrtoeol(cw);
346 status();
347 draw(cw);
348 mpos = 0;
349 count = 0;
350 }
351 }
352
353 /*
354 * search:
355 * Player gropes about him to find hidden things.
356 */
357
358 void
359 search()
360 {
361 int x, y;
362 int ch;
363
364 /*
365 * Look all around the hero, if there is something hidden there,
366 * give him a chance to find it. If its found, display it.
367 */
368 if (on(player, ISBLIND))
369 return;
370 for (x = hero.x - 1; x <= hero.x + 1; x++)
371 for (y = hero.y - 1; y <= hero.y + 1; y++)
372 {
373 ch = winat(y, x);
374 switch (ch)
375 {
376 case SECRETDOOR:
377 if (rnd(100) < 20) {
378 mvaddch(y, x, DOOR);
379 count = 0;
380 }
381 break;
382 case TRAP:
383 {
384 struct trap *tp;
385
386 if (mvwinch(cw, y, x) == TRAP)
387 break;
388 if (rnd(100) > 50)
389 break;
390 tp = trap_at(y, x);
391 tp->tr_flags |= ISFOUND;
392 mvwaddch(cw, y, x, TRAP);
393 count = 0;
394 running = FALSE;
395 msg(tr_name(tp->tr_type));
396 }
397 }
398 }
399 }
400
401 /*
402 * help:
403 * Give single character help, or the whole mess if he wants it
404 */
405
406 void
407 help()
408 {
409 struct h_list *strp = helpstr;
410 int helpch;
411 int cnt;
412
413 msg("Character you want help for (* for all): ");
414 helpch = readchar(cw);
415 mpos = 0;
416 /*
417 * If its not a *, print the right help string
418 * or an error if he typed a funny character.
419 */
420 if (helpch != '*')
421 {
422 wmove(cw, 0, 0);
423 while (strp->h_ch)
424 {
425 if (strp->h_ch == helpch)
426 {
427 msg("%s%s", unctrl(strp->h_ch), strp->h_desc);
428 break;
429 }
430 strp++;
431 }
432 if (strp->h_ch != helpch)
433 msg("Unknown character '%s'", unctrl(helpch));
434 return;
435 }
436 /*
437 * Here we print help for everything.
438 * Then wait before we return to command mode
439 */
440 wclear(hw);
441 cnt = 0;
442 while (strp->h_ch)
443 {
444 mvwaddstr(hw, cnt % 23, cnt > 22 ? 40 : 0, unctrl(strp->h_ch));
445 waddstr(hw, strp->h_desc);
446 cnt++;
447 strp++;
448 }
449 wmove(hw, LINES-1, 0);
450 wprintw(hw, "--Press space to continue--");
451 draw(hw);
452 wait_for(hw,' ');
453 wclear(hw);
454 draw(hw);
455 wmove(cw, 0, 0);
456 wclrtoeol(cw);
457 status();
458 touchwin(cw);
459 }
460
461 /*
462 * identify:
463 * Tell the player what a certain thing is.
464 */
465
466 void
467 identify()
468 {
469 int ch;
470 char *str;
471
472 msg("What do you want identified? ");
473 ch = readchar(cw);
474 mpos = 0;
475 if (ch == ESCAPE)
476 {
477 msg("");
478 return;
479 }
480 if (isalpha(ch) && isupper(ch))
481 str = monsters[ch-'A'].m_name;
482 else switch(ch)
483 {
484 case '|':
485 case '-':
486 str = "wall of a room";
487 when GOLD: str = "gold";
488 when STAIRS : str = "passage leading down";
489 when DOOR: str = "door";
490 when FLOOR: str = "room floor";
491 when PLAYER: str = "you";
492 when PASSAGE: str = "passage";
493 when TRAP: str = "trap";
494 when POTION: str = "potion";
495 when SCROLL: str = "scroll";
496 when FOOD: str = "food";
497 when WEAPON: str = "weapon";
498 when ' ' : str = "solid rock";
499 when ARMOR: str = "armor";
500 when AMULET: str = "The Amulet of Yendor";
501 when RING: str = "ring";
502 when STICK: str = "wand or staff";
503 otherwise: str = "unknown character";
504 }
505 msg("'%s' : %s", unctrl(ch), str);
506 }
507
508 /*
509 * d_level:
510 * He wants to go down a level
511 */
512
513 void
514 d_level()
515 {
516 if (winat(hero.y, hero.x) != STAIRS)
517 msg("I see no way down.");
518 else
519 {
520 level++;
521 new_level();
522 }
523 }
524
525 /*
526 * u_level:
527 * He wants to go up a level
528 */
529
530 void
531 u_level()
532 {
533 if (winat(hero.y, hero.x) == STAIRS)
534 {
535 if (amulet)
536 {
537 level--;
538 if (level == 0)
539 total_winner();
540 new_level();
541 msg("You feel a wrenching sensation in your gut.");
542 return;
543 }
544 }
545 msg("I see no way up.");
546 }
547
548 /*
549 * Let him escape for a while
550 */
551
552 void
553 shell()
554 {
555 /*
556 * Set the terminal back to original mode
557 */
558 wclear(hw);
559 wmove(hw, LINES-1, 0);
560 draw(hw);
561 endwin();
562 in_shell = TRUE;
563 fflush(stdout);
564
565 md_shellescape();
566
567 printf("\n[Press return to continue]");
568 fflush(stdout);
569 noecho();
570 crmode();
571 in_shell = FALSE;
572 wait_for(cw,'\n');
573 clearok(cw, TRUE);
574 touchwin(cw);
575 draw(cw);
576 }
577
578 /*
579 * allow a user to call a potion, scroll, or ring something
580 */
581 void
582 call()
583 {
584 struct object *obj;
585 struct linked_list *item;
586 char **guess, *elsewise;
587 int *know;
588
589 item = get_item("call", CALLABLE);
590 /*
591 * Make certain that it is somethings that we want to wear
592 */
593 if (item == NULL)
594 return;
595 obj = (struct object *) ldata(item);
596 switch (obj->o_type)
597 {
598 case RING:
599 guess = r_guess;
600 know = r_know;
601 elsewise = (r_guess[obj->o_which] != NULL ?
602 r_guess[obj->o_which] : r_stones[obj->o_which]);
603 when POTION:
604 guess = p_guess;
605 know = p_know;
606 elsewise = (p_guess[obj->o_which] != NULL ?
607 p_guess[obj->o_which] : p_colors[obj->o_which]);
608 when SCROLL:
609 guess = s_guess;
610 know = s_know;
611 elsewise = (s_guess[obj->o_which] != NULL ?
612 s_guess[obj->o_which] : s_names[obj->o_which]);
613 when STICK:
614 guess = ws_guess;
615 know = ws_know;
616 elsewise = (ws_guess[obj->o_which] != NULL ?
617 ws_guess[obj->o_which] : ws_made[obj->o_which]);
618 otherwise:
619 msg("You can't call that anything");
620 return;
621 }
622 if (know[obj->o_which])
623 {
624 msg("That has already been identified");
625 return;
626 }
627 if (terse)
628 addmsg("C");
629 else
630 addmsg("Was c");
631 msg("alled \"%s\"", elsewise);
632 if (terse)
633 msg("Call it: ");
634 else
635 msg("What do you want to call it? ");
636 strcpy(prbuf, elsewise);
637 if (get_str(prbuf, cw) == NORM)
638 {
639 if (guess[obj->o_which] != NULL)
640 free(guess[obj->o_which]);
641 guess[obj->o_which] = malloc((unsigned int) strlen(prbuf) + 1);
642 if (guess[obj->o_which] != NULL)
643 strcpy(guess[obj->o_which], prbuf);
644 }
645 }