comparison rogue4/command.c @ 12:9535a08ddc39

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