comparison xrogue/command.c @ 133:e6179860cb76

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