comparison arogue7/command.c @ 125:adfa37e67084

Import Advanced Rogue 7.7 from the Roguelike Restoration Project (r1490)
author John "Elwin" Edwards
date Fri, 08 May 2015 15:24:40 -0400
parents
children b786053d2f37
comparison
equal deleted inserted replaced
124:d10fc4a065ac 125:adfa37e67084
1 /*
2 * command.c - Read and execute the user commands
3 *
4 * Advanced Rogue
5 * Copyright (C) 1984, 1985, 1986 Michael Morgan, Ken Dalka and AT&T
6 * All rights reserved.
7 *
8 * Based on "Rogue: Exploring the Dungeons of Doom"
9 * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
10 * All rights reserved.
11 *
12 * See the file LICENSE.TXT for full copyright and licensing information.
13 */
14
15 /*
16 * Read and execute the user commands
17 *
18 */
19
20 #include "curses.h"
21 #include <ctype.h>
22 #include <signal.h>
23 #include "mach_dep.h"
24 #include "rogue.h"
25 #ifdef PC7300
26 #include "sys/window.h"
27 extern struct uwdata wdata;
28 #endif
29
30 /*
31 * command:
32 * Process the user commands
33 */
34
35 command()
36 {
37 unsigned char ch;
38 struct linked_list *item;
39 unsigned char countch, direction, newcount = FALSE;
40 int segment = 1;
41 int monst_limit, monst_current;
42
43 monst_limit = monst_current = 1;
44 while (playing) {
45 /*
46 * Let the daemons start up, but only do them once a round
47 * (round = 10 segments).
48 */
49 if (segment >= 10) {
50 do_daemons(BEFORE);
51 do_fuses(BEFORE);
52 }
53
54 after = TRUE;
55 do {
56 /* One more tick of the clock. */
57 if (segment >= 10 && after && (++turns % DAYLENGTH) == 0) {
58 daytime ^= TRUE;
59 if (levtype == OUTSIDE) {
60 if (daytime) msg("The sun rises above the horizon");
61 else msg("The sun sinks below the horizon");
62 }
63 light(&hero);
64 }
65
66 /*
67 * Don't bother with these updates unless the player's going
68 * to do something.
69 */
70 if (player.t_action == A_NIL && player.t_no_move <= 1) {
71 look(after, FALSE);
72 lastscore = purse;
73 wmove(cw, hero.y, hero.x);
74 if (!((running || count) && jump)) {
75 status(FALSE);
76 }
77 }
78
79 /* Draw the screen */
80 if (!((running || count) && jump)) {
81 wmove(cw, hero.y, hero.x);
82 draw(cw);
83 }
84
85 after = TRUE;
86
87 /*
88 * Read command or continue run
89 */
90 if (--player.t_no_move <= 0) {
91 take = 0; /* Nothing here to start with */
92 player.t_no_move = 0; /* Be sure we don't go too negative */
93 if (!running) door_stop = FALSE;
94
95 /* Was the player being held? */
96 if (player.t_action == A_FREEZE) {
97 player.t_action = A_NIL;
98 msg("You can move again.");
99 }
100
101 if (player.t_action != A_NIL) ch = (char) player.t_action;
102 else if (running) {
103 char scratch;
104
105 /* If in a corridor or maze, if we are at a turn with
106 * only one way to go, turn that way.
107 */
108 scratch = CCHAR( winat(hero.y, hero.x) );
109 if ((scratch==PASSAGE||scratch==DOOR||levtype==MAZELEV) &&
110 off(player, ISHUH) &&
111 off(player, ISBLIND)) {
112 int y, x;
113 if (getdelta(runch, &y, &x) == TRUE) {
114 corr_move(y, x);
115 }
116 }
117 ch = runch;
118 }
119 else if (count) ch = countch;
120 else {
121 ch = readchar();
122 if (mpos != 0 && !running) /* Erase message if its there */
123 msg("");
124 }
125
126 /*
127 * check for prefixes
128 */
129 if (isdigit(ch))
130 {
131 count = 0;
132 newcount = TRUE;
133 while (isdigit(ch))
134 {
135 count = count * 10 + (ch - '0');
136 if (count > 255)
137 count = 255;
138 ch = readchar();
139 }
140 countch = ch;
141 /*
142 * turn off count for commands which don't make sense
143 * to repeat
144 */
145 switch (ch) {
146 case 'h': case 'j': case 'k': case 'l':
147 case 'y': case 'u': case 'b': case 'n':
148 case 'H': case 'J': case 'K': case 'L':
149 case 'Y': case 'U': case 'B': case 'N':
150 case C_SEARCH: case '.':
151 break;
152 default:
153 count = 0;
154 }
155 }
156
157 /* Save current direction */
158 if (!running) { /* If running, it is already saved */
159 switch (ch) {
160 case 'h': case 'j': case 'k': case 'l':
161 case 'y': case 'u': case 'b': case 'n':
162 case 'H': case 'J': case 'K': case 'L':
163 case 'Y': case 'U': case 'B': case 'N':
164 runch = tolower(ch);
165 }
166 }
167
168 /* Perform the action */
169 switch (ch) {
170 case 'f':
171 if (!on(player, ISBLIND))
172 {
173 door_stop = TRUE;
174 firstmove = TRUE;
175 }
176 if (count && !newcount)
177 ch = direction;
178 else
179 ch = readchar();
180 switch (ch)
181 {
182 case 'h': case 'j': case 'k': case 'l':
183 case 'y': case 'u': case 'b': case 'n':
184 ch = toupper(ch);
185 }
186 direction = ch;
187 }
188 newcount = FALSE;
189
190 /*
191 * execute a command
192 */
193 if (count && !running)
194 count--;
195 switch (ch) {
196 case '!' : shell();
197 when 'h' : do_move(0, -1);
198 when 'j' : do_move(1, 0);
199 when 'k' : do_move(-1, 0);
200 when 'l' : do_move(0, 1);
201 when 'y' : do_move(-1, -1);
202 when 'u' : do_move(-1, 1);
203 when 'b' : do_move(1, -1);
204 when 'n' : do_move(1, 1);
205 when 'H' : do_run('h');
206 when 'J' : do_run('j');
207 when 'K' : do_run('k');
208 when 'L' : do_run('l');
209 when 'Y' : do_run('y');
210 when 'U' : do_run('u');
211 when 'B' : do_run('b');
212 when 'N' : do_run('n');
213 when A_PICKUP:
214 player.t_action = A_NIL;
215 if (add_pack(NULL, FALSE, NULL)) {
216 char tch;
217
218 tch = CCHAR( mvwinch(stdscr, hero.y, hero.x) );
219 if (tch != FLOOR && tch != PASSAGE) {
220 player.t_action = A_PICKUP; /*get more */
221 player.t_no_move += 2 * movement(&player);
222 }
223 }
224 when A_ATTACK:
225 /* Is our attackee still there? */
226 if (isalpha(winat(player.t_newpos.y,
227 player.t_newpos.x))) {
228 /* Our friend is still here */
229 player.t_action = A_NIL;
230 fight(&player.t_newpos, cur_weapon, FALSE);
231 }
232 else { /* Our monster has moved */
233 player.t_action = A_NIL;
234 }
235 when A_THROW:
236 if (player.t_action == A_NIL) {
237 item = get_item(pack, "throw", ALL, FALSE, FALSE);
238 if (item != NULL && get_dir(&player.t_newpos)) {
239 player.t_action = A_THROW;
240 player.t_using = item;
241 player.t_no_move = 2 * movement(&player);
242 }
243 else
244 after = FALSE;
245 }
246 else {
247 missile(player.t_newpos.y, player.t_newpos.x,
248 player.t_using, &player);
249 player.t_action = A_NIL;
250 player.t_using = 0;
251 }
252 when 'Q' : after = FALSE; quit(0);
253 when 'i' : after = FALSE; inventory(pack, ALL);
254 when 'I' : after = FALSE; picky_inven();
255 when C_DROP : player.t_action = C_DROP; drop(NULL);
256 when 'P' :
257 if (levtype != POSTLEV) {
258 /* We charge 2 movement units per item */
259 player.t_no_move =
260 2 * grab(hero.y, hero.x) * movement(&player);
261 }
262 else {
263 /* Let's quote the wise guy a price */
264 buy_it();
265 after = FALSE;
266 }
267 when C_COUNT : count_gold();
268 when C_QUAFF : quaff(-1, NULL, NULL, TRUE);
269 when C_READ : read_scroll(-1, NULL, TRUE);
270 when C_EAT : eat();
271 when C_WIELD : wield();
272 when C_WEAR : wear();
273 when C_TAKEOFF : take_off();
274 when 'o' : option();
275 when CTRL('N') : nameit();
276 when '=' : after = FALSE; display();
277 when 'm' : nameitem(NULL, TRUE);
278 when '>' : after = FALSE; d_level();
279 when '<' : after = FALSE; u_level();
280 when '?' : after = FALSE; help();
281 when '/' : after = FALSE; identify(NULL);
282 when C_USE : use_mm(-1);
283 when CTRL('T') :
284 if (player.t_action == A_NIL) {
285 if (get_dir(&player.t_newpos)) {
286 player.t_action = CTRL('T');
287 player.t_no_move = 2 * movement(&player);
288 }
289 else
290 after = FALSE;
291 }
292 else {
293 steal();
294 player.t_action = A_NIL;
295 }
296 when C_DIP : dip_it();
297 when 'G' :
298 if (player.t_action == A_NIL) {
299 player.t_action = 'G';
300 player.t_no_move = movement(&player);
301 }
302 else {
303 gsense();
304 player.t_action = A_NIL;
305 }
306 when C_SETTRAP : set_trap(&player, hero.y, hero.x);
307 when C_SEARCH :
308 if (player.t_action == A_NIL) {
309 player.t_action = C_SEARCH;
310 player.t_no_move = 5 * movement(&player);
311 }
312 else {
313 search(FALSE, FALSE);
314 player.t_action = A_NIL;
315 }
316 when C_ZAP : if (!player_zap(NULL, FALSE))
317 after=FALSE;
318 when C_PRAY : pray();
319 when C_CHANT : chant();
320 when C_CAST : cast();
321 when 'a' :
322 if (player.t_action == A_NIL) {
323 if (get_dir(&player.t_newpos)) {
324 player.t_action = 'a';
325 player.t_no_move = 2 * movement(&player);
326 }
327 else
328 after = FALSE;
329 }
330 else {
331 affect();
332 player.t_action = A_NIL;
333 }
334 when 'v' : after = FALSE;
335 msg("Advanced Rogue Version %s.",
336 release);
337 when CTRL('L') : after = FALSE; clearok(curscr, TRUE);
338 touchwin(cw); /* MMMMMMMMMM */
339 when CTRL('R') : after = FALSE; msg(huh);
340 when 'S' :
341 after = FALSE;
342 if (save_game())
343 {
344 wclear(cw);
345 draw(cw);
346 endwin();
347 #ifdef PC7300
348 endhardwin();
349 #endif
350 exit(0);
351 }
352 when '.' :
353 player.t_no_move = movement(&player); /* Rest */
354 player.t_action = A_NIL;
355 when ' ' : after = FALSE; /* Do Nothing */
356 #ifdef WIZARD
357 when CTRL('P') :
358 after = FALSE;
359 if (wizard)
360 {
361 wizard = FALSE;
362 trader = 0;
363 msg("Not wizard any more");
364 }
365 else
366 {
367 if (waswizard || passwd())
368 {
369 msg("Welcome, oh mighty wizard.");
370 wizard = waswizard = TRUE;
371 }
372 else
373 msg("Sorry");
374 }
375 #endif
376 when ESCAPE : /* Escape */
377 door_stop = FALSE;
378 count = 0;
379 after = FALSE;
380 when '#':
381 if (levtype == POSTLEV) /* buy something */
382 buy_it();
383 after = FALSE;
384 when '$':
385 if (levtype == POSTLEV) /* price something */
386 price_it();
387 after = FALSE;
388 when '%':
389 if (levtype == POSTLEV) /* sell something */
390 sell_it();
391 after = FALSE;
392 otherwise :
393 after = FALSE;
394 #ifdef WIZARD
395 if (wizard) switch (ch)
396 {
397 case 'M' : create_obj(TRUE, 0, 0);
398 when CTRL('W') : wanderer();
399 when CTRL('I') : inventory(lvl_obj, ALL);
400 when CTRL('Z') : whatis(NULL);
401 when CTRL('D') : level++; new_level(NORMLEV);
402 when CTRL('F') : overlay(stdscr,cw);
403 when CTRL('X') : overlay(mw,cw);
404 when CTRL('J') : teleport();
405 when CTRL('E') : msg("food left: %d\tfood level: %d",
406 food_left, foodlev);
407 when CTRL('A') : activity();
408 when CTRL('C') :
409 {
410 int tlev;
411 prbuf[0] = 0;
412 msg("Which level? ");
413 if(get_str(prbuf,msgw) == NORM) {
414 tlev = atoi(prbuf);
415 if(tlev < 1) {
416 mpos = 0;
417 msg("Illegal level.");
418 }
419 else if (tlev > 199) {
420 levtype = MAZELEV;
421 level = tlev - 200 + 1;
422 }
423 else if (tlev > 99) {
424 levtype = POSTLEV;
425 level = tlev - 100 + 1;
426 }
427 else {
428 levtype = NORMLEV;
429 level = tlev;
430 }
431 new_level(levtype);
432 }
433 }
434 when CTRL('G') :
435 {
436 item=get_item(pack,"charge",STICK,FALSE,FALSE);
437 if (item != NULL) {
438 (OBJPTR(item))->o_charges=10000;
439 }
440 }
441 when CTRL('H') :
442 {
443 register int i;
444 register struct object *obj;
445
446 for (i = 0; i < 9; i++)
447 raise_level();
448 /*
449 * Give the rogue a sword
450 */
451 if (cur_weapon==NULL || cur_weapon->o_type !=
452 RELIC) {
453 item = spec_item(WEAPON, TWOSWORD, 5, 5);
454 add_pack(item, TRUE, NULL);
455 cur_weapon = OBJPTR(item);
456 (OBJPTR(item))->o_flags |= (ISKNOW|ISPROT);
457 }
458 /*
459 * And his suit of armor
460 */
461 if (player.t_ctype != C_MONK) {
462 item = spec_item(ARMOR, PLATE_ARMOR, 10, 0);
463 obj = OBJPTR(item);
464 if (player.t_ctype == C_THIEF)
465 obj->o_which = STUDDED_LEATHER;
466 obj->o_flags |= (ISKNOW | ISPROT);
467 obj->o_weight = armors[PLATE_ARMOR].a_wght;
468 cur_armor = obj;
469 add_pack(item, TRUE, NULL);
470 }
471 purse += 20000;
472 }
473 otherwise :
474 msg("Illegal command '%s'.", unctrl(ch));
475 count = 0;
476 }
477 else
478 #endif
479 {
480 msg("Illegal command '%s'.", unctrl(ch));
481 count = 0;
482 after = FALSE;
483 }
484 }
485
486 /*
487 * If he ran into something to take, let him pick it up.
488 * unless it's a trading post
489 */
490 if (auto_pickup && take != 0 && levtype != POSTLEV) {
491 /* get ready to pick it up */
492 player.t_action = A_PICKUP;
493 player.t_no_move += 2 * movement(&player);
494 }
495 }
496
497 /* If he was fighting, let's stop (for now) */
498 if (player.t_quiet < 0) player.t_quiet = 0;
499
500 if (!running)
501 door_stop = FALSE;
502
503 if (after && segment >= 10) {
504 /*
505 * Kick off the rest if the daemons and fuses
506 */
507
508 /*
509 * If player is infested, take off a hit point
510 */
511 if (on(player, HASINFEST)) {
512 if ((pstats.s_hpt -= infest_dam) <= 0) death(D_INFESTATION);
513 }
514
515 /*
516 * The eye of Vecna is a constant drain on the player
517 */
518 if (cur_relic[EYE_VECNA]) {
519 if ((--pstats.s_hpt) <= 0) death(D_RELIC);
520 }
521
522 /*
523 * if player has body rot then take off five hits
524 */
525 if (on(player, DOROT)) {
526 if ((pstats.s_hpt -= 5) <= 0) death(D_ROT);
527 }
528 do_daemons(AFTER);
529 do_fuses(AFTER);
530 }
531 } while (after == FALSE);
532
533 /* Make the monsters go */
534 if (--monst_current <= 0)
535 monst_current = monst_limit = runners(monst_limit);
536
537 #ifdef NEEDLOOK
538 /* Shall we take a look? */
539 if (player.t_no_move <= 1 &&
540 !((running || count) && jump))
541 look(FALSE, FALSE);
542 #endif
543
544 if (++segment > 10) segment = 1;
545 t_free_list(monst_dead);
546 }
547 }
548
549 /*
550 * display
551 * tell the player what is at a certain coordinates assuming
552 * it can be seen.
553 */
554 display()
555 {
556 coord c;
557 struct linked_list *item;
558 struct thing *tp;
559 int what;
560
561 msg("What do you want to display (* for help)?");
562 c = get_coordinates();
563 mpos = 0;
564 if (!cansee(c.y, c.x)) {
565 msg("You can't see what is there.");
566 return;
567 }
568 what = mvwinch(cw, c.y, c.x);
569 if (isalpha(what)) {
570 item = find_mons(c.y, c.x);
571 tp = THINGPTR(item);
572 msg("%s", monster_name(tp));
573 return;
574 }
575 if ((item = find_obj(c.y, c.x)) != NULL) {
576 msg("%s", inv_name(OBJPTR(item), FALSE));
577 return;
578 }
579 identify(what);
580 }
581
582 /*
583 * quit:
584 * Have player make certain, then exit.
585 */
586
587 void
588 quit(sig)
589 int sig;
590 {
591 /*
592 * Reset the signal in case we got here via an interrupt
593 */
594 if (signal(SIGINT, quit) != quit)
595 mpos = 0;
596 msg("Really quit? <yes or no> ");
597 draw(cw);
598 prbuf[0] = '\0';
599 if ((get_str(prbuf, msgw) == NORM) && strcmp(prbuf, "yes") == 0) {
600 clear();
601 move(lines-1, 0);
602 draw(stdscr);
603 score(pstats.s_exp + (long) purse, CHICKEN, 0);
604 #ifdef PC7300
605 endhardwin();
606 #endif
607 exit(0);
608 }
609 else
610 {
611 signal(SIGINT, quit);
612 wmove(cw, 0, 0);
613 wclrtoeol(cw);
614 status(FALSE);
615 draw(cw);
616 mpos = 0;
617 count = 0;
618 running = FALSE;
619 }
620 }
621
622 /*
623 * bugkill:
624 * killed by a program bug instead of voluntarily.
625 */
626
627 void
628 bugkill(sig)
629 int sig;
630 {
631 signal(sig, quit); /* If we get it again, give up */
632 death(D_SIGNAL); /* Killed by a bug */
633 }
634
635
636 /*
637 * search:
638 * Player gropes about him to find hidden things.
639 */
640
641 search(is_thief, door_chime)
642 register bool is_thief, door_chime;
643 {
644 register int x, y;
645 register char ch, /* The trap or door character */
646 sch, /* Trap or door character (as seen on screen) */
647 mch; /* Monster, if a monster is on the trap or door */
648 register struct linked_list *item;
649 register struct thing *mp; /* Status on surrounding monster */
650
651 /*
652 * Look all around the hero, if there is something hidden there,
653 * give him a chance to find it. If its found, display it.
654 */
655 if (on(player, ISBLIND))
656 return;
657 for (x = hero.x - 1; x <= hero.x + 1; x++)
658 for (y = hero.y - 1; y <= hero.y + 1; y++)
659 {
660 if (y==hero.y && x==hero.x)
661 continue;
662
663 /* Mch and ch will be the same unless there is a monster here */
664 mch = CCHAR( winat(y, x) );
665 ch = CCHAR( mvwinch(stdscr, y, x) );
666 sch = CCHAR( mvwinch(cw, y, x) ); /* What's on the screen */
667
668 if (door_chime == FALSE && isatrap(ch)) {
669 register struct trap *tp;
670
671 /* Is there a monster on the trap? */
672 if (mch != ch && (item = find_mons(y, x)) != NULL) {
673 mp = THINGPTR(item);
674 if (sch == mch) sch = mp->t_oldch;
675 }
676 else mp = NULL;
677
678 /*
679 * is this one found already?
680 */
681 if (isatrap(sch))
682 continue; /* give him chance for other traps */
683 tp = trap_at(y, x);
684 /*
685 * if the thief set it then don't display it.
686 * if its not a thief he has 50/50 shot
687 */
688 if((tp->tr_flags&ISTHIEFSET) || (!is_thief && rnd(100)>50))
689 continue; /* give him chance for other traps */
690 tp->tr_flags |= ISFOUND;
691
692 /* Let's update the screen */
693 if (mp != NULL && mvwinch(cw, y, x) == mch)
694 mp->t_oldch = ch; /* Will change when monst moves */
695 else mvwaddch(cw, y, x, ch);
696
697 count = 0;
698 running = FALSE;
699
700 /* Stop what we were doing */
701 player.t_no_move = movement(&player);
702 player.t_action = A_NIL;
703 player.t_using = NULL;
704
705 if (fight_flush) md_flushinp();
706 msg(tr_name(tp->tr_type));
707 }
708 else if (ch == SECRETDOOR) {
709 if (door_chime == TRUE || (!is_thief && rnd(100) < 20)) {
710 struct room *rp;
711 coord cp;
712
713 /* Is there a monster on the door? */
714 if (mch != ch && (item = find_mons(y, x)) != NULL) {
715 mp = THINGPTR(item);
716
717 /* Screen will change when monster moves */
718 if (sch == mch) mp->t_oldch = ch;
719 }
720 mvaddch(y, x, DOOR);
721 count = 0;
722 /*
723 * if its the entrance to a treasure room, wake it up
724 */
725 cp.y = y;
726 cp.x = x;
727 rp = roomin(&cp);
728 if (rp->r_flags & ISTREAS)
729 wake_room(rp);
730
731 /* Make sure we don't shoot into the room */
732 if (door_chime == FALSE) {
733 count = 0;
734 running = FALSE;
735
736 /* Stop what we were doing */
737 player.t_no_move = movement(&player);
738 player.t_action = A_NIL;
739 player.t_using = NULL;
740 }
741 }
742 }
743 }
744 }
745
746
747 /*
748 * help:
749 * Give single character help, or the whole mess if he wants it
750 */
751
752 help()
753 {
754 register struct h_list *strp = helpstr;
755 #ifdef WIZARD
756 struct h_list *wizp = wiz_help;
757 #endif
758 register char helpch;
759 register int cnt;
760
761 msg("Character you want help for (* for all): ");
762 helpch = readchar();
763 mpos = 0;
764 /*
765 * If its not a *, print the right help string
766 * or an error if he typed a funny character.
767 */
768 if (helpch != '*') {
769 wmove(msgw, 0, 0);
770 while (strp->h_ch) {
771 if (strp->h_ch == helpch) {
772 msg("%s%s", unctrl(strp->h_ch), strp->h_desc);
773 return;
774 }
775 strp++;
776 }
777 #ifdef WIZARD
778 if (wizard) {
779 while (wizp->h_ch) {
780 if (wizp->h_ch == helpch) {
781 msg("%s%s", unctrl(wizp->h_ch), wizp->h_desc);
782 return;
783 }
784 wizp++;
785 }
786 }
787 #endif
788
789 msg("Unknown character '%s'", unctrl(helpch));
790 return;
791 }
792 /*
793 * Here we print help for everything.
794 * Then wait before we return to command mode
795 */
796 wclear(hw);
797 cnt = 0;
798 while (strp->h_ch) {
799 mvwaddstr(hw, cnt % 23, cnt > 22 ? 40 : 0, unctrl(strp->h_ch));
800 waddstr(hw, strp->h_desc);
801 strp++;
802 if (++cnt >= 46 && strp->h_ch) {
803 wmove(hw, lines-1, 0);
804 wprintw(hw, morestr);
805 draw(hw);
806 wait_for(' ');
807 wclear(hw);
808 cnt = 0;
809 }
810 }
811 #ifdef WIZARD
812 if (wizard) {
813 while (wizp->h_ch) {
814 mvwaddstr(hw, cnt % 23, cnt > 22 ? 40 : 0, unctrl(wizp->h_ch));
815 waddstr(hw, wizp->h_desc);
816 wizp++;
817 if (++cnt >= 46 && wizp->h_ch) {
818 wmove(hw, lines-1, 0);
819 wprintw(hw, morestr);
820 draw(hw);
821 wait_for(' ');
822 wclear(hw);
823 cnt = 0;
824 }
825 }
826 }
827 #endif
828 wmove(hw, lines-1, 0);
829 wprintw(hw, spacemsg);
830 draw(hw);
831 wait_for(' ');
832 wclear(hw);
833 draw(hw);
834 wmove(cw, 0, 0);
835 wclrtoeol(cw);
836 status(FALSE);
837 touchwin(cw);
838 }
839 /*
840 * identify:
841 * Tell the player what a certain thing is.
842 */
843
844 identify(ch)
845 register char ch;
846 {
847 register char *str;
848
849 if (ch == 0) {
850 msg("What do you want identified? ");
851 ch = readchar();
852 mpos = 0;
853 if (ch == ESCAPE)
854 {
855 msg("");
856 return;
857 }
858 }
859 if (isalpha(ch))
860 str = monsters[id_monst(ch)].m_name;
861 else switch(ch)
862 {
863 case '|':
864 case '-':
865 str = (levtype == OUTSIDE) ? "boundary of sector"
866 : "wall of a room";
867 when GOLD: str = "gold";
868 when STAIRS : str = (levtype == OUTSIDE) ? "entrance to a dungeon"
869 : "passage leading down";
870 when DOOR: str = "door";
871 when FLOOR: str = (levtype == OUTSIDE) ? "meadow" : "room floor";
872 when VPLAYER: str = "the hero of the game ---> you";
873 when IPLAYER: str = "you (but invisible)";
874 when PASSAGE: str = "passage";
875 when POST: str = "trading post";
876 when POOL: str = (levtype == OUTSIDE) ? "lake"
877 : "a shimmering pool";
878 when TRAPDOOR: str = "trapdoor";
879 when ARROWTRAP: str = "arrow trap";
880 when SLEEPTRAP: str = "sleeping gas trap";
881 when BEARTRAP: str = "bear trap";
882 when TELTRAP: str = "teleport trap";
883 when DARTTRAP: str = "dart trap";
884 when MAZETRAP: str = "entrance to a maze";
885 when FOREST: str = "forest";
886 when POTION: str = "potion";
887 when SCROLL: str = "scroll";
888 when FOOD: str = "food";
889 when WEAPON: str = "weapon";
890 when ' ' : str = "solid rock";
891 when ARMOR: str = "armor";
892 when MM: str = "miscellaneous magic";
893 when RING: str = "ring";
894 when STICK: str = "wand or staff";
895 when SECRETDOOR:str = "secret door";
896 when RELIC: str = "artifact";
897 otherwise: str = "unknown character";
898 }
899 msg("'%s' : %s", unctrl(ch), str);
900 }
901
902 /*
903 * d_level:
904 * He wants to go down a level
905 */
906
907 d_level()
908 {
909 bool no_phase=FALSE;
910 char position = CCHAR( winat(hero.y, hero.x) );
911
912
913 /* If we are on a trading post, go to a trading post level. */
914 if (position == POST) {
915 new_level(POSTLEV);
916 return;
917 }
918
919 /* If we are at a top-level trading post, we probably can't go down */
920 if (levtype == POSTLEV && level == 0 && position != STAIRS) {
921 msg("I see no way down.");
922 return;
923 }
924
925 if (winat(hero.y, hero.x) != STAIRS) {
926 if (off(player, CANINWALL) || /* Must use stairs if can't phase */
927 (levtype == OUTSIDE && rnd(100) < 90)) {
928 msg("I see no way down.");
929 return;
930 }
931
932 /* Is there any dungeon left below? */
933 if (level >= nfloors) {
934 msg("There is only solid rock below.");
935 return;
936 }
937
938 extinguish(unphase); /* Using phase to go down gets rid of it */
939 no_phase = TRUE;
940 }
941
942 /* Is this the bottom? */
943 if (level >= nfloors) {
944 msg("The stairway only goes up.");
945 return;
946 }
947
948 level++;
949 new_level(NORMLEV);
950 if (no_phase) unphase();
951 }
952
953 /*
954 * u_level:
955 * He wants to go up a level
956 */
957
958 u_level()
959 {
960 bool no_phase = FALSE;
961 register struct linked_list *item;
962 struct thing *tp;
963 struct object *obj;
964
965 if (winat(hero.y, hero.x) != STAIRS) {
966 if (off(player, CANINWALL)) { /* Must use stairs if can't phase */
967 msg("I see no way up.");
968 return;
969 }
970
971 extinguish(unphase);
972 no_phase = TRUE;
973 }
974
975 if (level == 0) {
976 msg("The stairway only goes down.");
977 return;
978 }
979
980 /*
981 * does he have the item he was quested to get?
982 */
983 if (level == 1) {
984 for (item = pack; item != NULL; item = next(item)) {
985 obj = OBJPTR(item);
986 if (obj->o_type == RELIC && obj->o_which == quest_item)
987 total_winner();
988 }
989 }
990 /*
991 * check to see if he trapped a UNIQUE, If he did then put it back
992 * in the monster table for next time
993 */
994 for (item = tlist; item != NULL; item = next(item)) {
995 tp = THINGPTR(item);
996 if (on(*tp, ISUNIQUE))
997 monsters[tp->t_index].m_normal = TRUE;
998 }
999 t_free_list(tlist); /* Monsters that fell below are long gone! */
1000
1001 if (levtype != POSTLEV) level--;
1002 if (level > 0) new_level(NORMLEV);
1003 else {
1004 level = -1; /* Indicate that we are new to the outside */
1005 msg("You emerge into the %s", daytime ? "light" : "night");
1006 new_level(OUTSIDE); /* Leaving the dungeon */
1007 }
1008
1009 if (no_phase) unphase();
1010 }
1011
1012 /*
1013 * Let him escape for a while
1014 */
1015
1016 shell()
1017 {
1018 register char *sh;
1019
1020 /*
1021 * Set the terminal back to original mode
1022 */
1023 sh = getenv("SHELL");
1024 wclear(hw);
1025 wmove(hw, lines-1, 0);
1026 draw(hw);
1027 endwin();
1028 in_shell = TRUE;
1029 fflush(stdout);
1030 /*
1031 * Fork and do a shell
1032 */
1033
1034 md_shellescape();
1035
1036 printf(retstr);
1037 noecho();
1038 raw();
1039 keypad(cw,1);
1040 keypad(msgw,1);
1041 in_shell = FALSE;
1042 wait_for('\n');
1043 clearok(cw, TRUE);
1044 touchwin(cw);
1045 }
1046
1047 /*
1048 * see what we want to name -- an item or a monster.
1049 */
1050 nameit()
1051 {
1052 char answer;
1053
1054 msg("Name monster or item (m or i)? ");
1055 answer = readchar();
1056 mpos = 0;
1057
1058 while (answer != 'm' && answer != 'i' && answer != ESCAPE) {
1059 mpos = 0;
1060 msg("Please specify m or i, for monster or item - ");
1061 answer = readchar();
1062 }
1063
1064 switch (answer) {
1065 case 'm': namemonst();
1066 when 'i': nameitem(NULL, FALSE);
1067 }
1068 }
1069
1070 /*
1071 * allow a user to call a potion, scroll, or ring something
1072 */
1073 nameitem(item, mark)
1074 struct linked_list *item;
1075 bool mark;
1076 {
1077 register struct object *obj;
1078 register char **guess, *elsewise;
1079 register bool *know;
1080
1081 if (item == NULL) {
1082 if (mark) item = get_item(pack, "mark", ALL, FALSE, FALSE);
1083 else item = get_item(pack, "name", CALLABLE, FALSE, FALSE);
1084 if (item == NULL) return;
1085 }
1086 /*
1087 * Make certain that it is somethings that we want to wear
1088 */
1089 obj = OBJPTR(item);
1090 switch (obj->o_type)
1091 {
1092 case RING:
1093 guess = r_guess;
1094 know = r_know;
1095 elsewise = (r_guess[obj->o_which] != NULL ?
1096 r_guess[obj->o_which] : r_stones[obj->o_which]);
1097 when POTION:
1098 guess = p_guess;
1099 know = p_know;
1100 elsewise = (p_guess[obj->o_which] != NULL ?
1101 p_guess[obj->o_which] : p_colors[obj->o_which]);
1102 when SCROLL:
1103 guess = s_guess;
1104 know = s_know;
1105 elsewise = (s_guess[obj->o_which] != NULL ?
1106 s_guess[obj->o_which] : s_names[obj->o_which]);
1107 when STICK:
1108 guess = ws_guess;
1109 know = ws_know;
1110 elsewise = (ws_guess[obj->o_which] != NULL ?
1111 ws_guess[obj->o_which] : ws_made[obj->o_which]);
1112 when MM:
1113 guess = m_guess;
1114 know = m_know;
1115 elsewise = (m_guess[obj->o_which] != NULL ?
1116 m_guess[obj->o_which] : "nothing");
1117 otherwise:
1118 if (!mark) {
1119 msg("You can't call that anything.");
1120 return;
1121 }
1122 else know = (bool *) 0;
1123 }
1124 if ((obj->o_flags & ISPOST) || (know && know[obj->o_which]) && !mark) {
1125 msg("That has already been identified.");
1126 return;
1127 }
1128 if (mark) {
1129 if (obj->o_mark[0]) {
1130 addmsg(terse ? "M" : "Was m");
1131 msg("arked \"%s\"", obj->o_mark);
1132 }
1133 msg(terse ? "Mark it: " : "What do you want to mark it? ");
1134 prbuf[0] = '\0';
1135 }
1136 else {
1137 if (elsewise) {
1138 addmsg(terse ? "N" : "Was n");
1139 msg("amed \"%s\"", elsewise);
1140 strcpy(prbuf, elsewise);
1141 }
1142 else prbuf[0] = '\0';
1143 msg(terse ? "Name it: " : "What do you want to name it? ");
1144 }
1145 if (get_str(prbuf, msgw) == NORM) {
1146 if (mark) {
1147 strncpy(obj->o_mark, prbuf, MARKLEN-1);
1148 obj->o_mark[MARKLEN-1] = '\0';
1149 }
1150 else if (prbuf[0] != '\0') {
1151 if (guess[obj->o_which] != NULL)
1152 free(guess[obj->o_which]);
1153 guess[obj->o_which] = new((unsigned int) strlen(prbuf) + 1);
1154 strcpy(guess[obj->o_which], prbuf);
1155 }
1156 }
1157 }
1158
1159 /* Name a monster */
1160
1161 namemonst()
1162 {
1163 register struct thing *tp;
1164 struct linked_list *item;
1165 coord c;
1166
1167 /* Find the monster */
1168 msg("Choose the monster (* for help)");
1169 c = get_coordinates();
1170
1171 /* Make sure we can see it and that it is a monster. */
1172 mpos = 0;
1173 if (!cansee(c.y, c.x)) {
1174 msg("You can't see what is there.");
1175 return;
1176 }
1177
1178 if (isalpha(mvwinch(cw, c.y, c.x))) {
1179 item = find_mons(c.y, c.x);
1180 if (item != NULL) {
1181 tp = THINGPTR(item);
1182 if (tp->t_name == NULL)
1183 strcpy(prbuf, monsters[tp->t_index].m_name);
1184 else
1185 strcpy(prbuf, tp->t_name);
1186
1187 addmsg(terse ? "N" : "Was n");
1188 msg("amed \"%s\"", prbuf);
1189 msg(terse ? "Name it: " : "What do you want to name it? ");
1190
1191 if (get_str(prbuf, msgw) == NORM) {
1192 if (prbuf[0] != '\0') {
1193 if (tp->t_name != NULL)
1194 free(tp->t_name);
1195 tp->t_name = new((unsigned int) strlen(prbuf) + 1);
1196 strcpy(tp->t_name, prbuf);
1197 }
1198 }
1199 return;
1200 }
1201 }
1202
1203 msg("There is no monster there to name.");
1204 }
1205
1206 count_gold()
1207 {
1208 if (player.t_action != C_COUNT) {
1209 msg("You take a break to count your money...");
1210 player.t_using = NULL;
1211 player.t_action = C_COUNT; /* We are counting */
1212 player.t_no_move = (purse/300 + 1) * movement(&player);
1213 return;
1214 }
1215 if (purse > 100)
1216 msg("You think you have about %d gold pieces.", purse);
1217 else
1218 msg("You have %d gold pieces.", purse);
1219 player.t_action = A_NIL;
1220 }