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