Mercurial > hg > early-roguelike
comparison arogue5/command.c @ 63:0ed67132cf10
Import Advanced Rogue 5.8 from the Roguelike Restoration Project (r1490)
author | elwin |
---|---|
date | Thu, 09 Aug 2012 22:58:48 +0000 |
parents | |
children | 7aff18a8d508 |
comparison
equal
deleted
inserted
replaced
62:0ef99244acb8 | 63:0ed67132cf10 |
---|---|
1 /* | |
2 * Read and execute the user commands | |
3 * | |
4 * Advanced Rogue | |
5 * Copyright (C) 1984, 1985 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 #include "curses.h" | |
16 #include <limits.h> | |
17 #include <ctype.h> | |
18 #include <signal.h> | |
19 #include "mach_dep.h" | |
20 #include "rogue.h" | |
21 | |
22 /* | |
23 * command: | |
24 * Process the user commands | |
25 */ | |
26 | |
27 command() | |
28 { | |
29 register char ch; | |
30 register int ntimes = 1; /* Number of player moves */ | |
31 static char countch, direction, newcount = FALSE; | |
32 struct linked_list *item; | |
33 bool an_after = FALSE; | |
34 | |
35 if (on(player, ISHASTE)) { | |
36 ntimes++; | |
37 turns--; /* correct for later */ | |
38 } | |
39 if (on(player, ISSLOW) || on(player, ISDANCE)) { | |
40 if (player.t_turn != TRUE) { | |
41 ntimes--; | |
42 turns++; | |
43 an_after = TRUE; | |
44 } | |
45 player.t_turn ^= TRUE; | |
46 } | |
47 | |
48 /* | |
49 * Let the daemons start up | |
50 */ | |
51 do_daemons(BEFORE); | |
52 do_fuses(BEFORE); | |
53 while (ntimes-- > 0) | |
54 { | |
55 /* One more tick of the clock. */ | |
56 if ((++turns % DAYLENGTH) == 0) { | |
57 daytime ^= TRUE; | |
58 if (levtype == OUTSIDE) { | |
59 if (daytime) msg("The sun rises above the horizon"); | |
60 else msg("The sun sinks below the horizon"); | |
61 } | |
62 light(&hero); | |
63 } | |
64 | |
65 look(after, FALSE); | |
66 if (!running) door_stop = FALSE; | |
67 lastscore = purse; | |
68 wmove(cw, hero.y, hero.x); | |
69 if (!((running || count) && jump)) { | |
70 status(FALSE); | |
71 wmove(cw, hero.y, hero.x); | |
72 draw(cw); /* Draw screen */ | |
73 } | |
74 take = 0; | |
75 after = TRUE; | |
76 /* | |
77 * Read command or continue run | |
78 */ | |
79 if (!no_command) | |
80 { | |
81 if (running) { | |
82 /* If in a corridor or maze, if we are at a turn with only one | |
83 * way to go, turn that way. | |
84 */ | |
85 if ((winat(hero.y, hero.x) == PASSAGE || levtype == MAZELEV) && | |
86 off(player, ISHUH) && (off(player, ISBLIND))) { | |
87 int y, x; | |
88 if (getdelta(runch, &y, &x) == TRUE) { | |
89 corr_move(y, x); | |
90 } | |
91 } | |
92 ch = runch; | |
93 } | |
94 else if (count) ch = countch; | |
95 else | |
96 { | |
97 ch = readchar(); | |
98 if (mpos != 0 && !running) /* Erase message if its there */ | |
99 msg(""); | |
100 } | |
101 } | |
102 else ch = '.'; | |
103 if (no_command) | |
104 { | |
105 if (--no_command == 0) | |
106 msg("You can move again."); | |
107 } | |
108 else | |
109 { | |
110 /* | |
111 * check for prefixes | |
112 */ | |
113 if (isdigit(ch)) | |
114 { | |
115 count = 0; | |
116 newcount = TRUE; | |
117 while (isdigit(ch)) | |
118 { | |
119 count = count * 10 + (ch - '0'); | |
120 if (count > 255) | |
121 count = 255; | |
122 ch = readchar(); | |
123 } | |
124 countch = ch; | |
125 /* | |
126 * turn off count for commands which don't make sense | |
127 * to repeat | |
128 */ | |
129 switch (ch) { | |
130 case 'h': case 'j': case 'k': case 'l': | |
131 case 'y': case 'u': case 'b': case 'n': | |
132 case 'H': case 'J': case 'K': case 'L': | |
133 case 'Y': case 'U': case 'B': case 'N': | |
134 case 'q': case 'r': case 's': case 'f': | |
135 case 't': case 'C': case 'I': case '.': | |
136 case 'z': case 'p': | |
137 break; | |
138 default: | |
139 count = 0; | |
140 } | |
141 } | |
142 | |
143 /* Save current direction */ | |
144 if (!running) /* If running, it is already saved */ | |
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 runch = tolower(ch); | |
151 } | |
152 | |
153 /* Perform the action */ | |
154 switch (ch) { | |
155 case 'f': | |
156 if (!on(player, ISBLIND)) | |
157 { | |
158 door_stop = TRUE; | |
159 firstmove = TRUE; | |
160 } | |
161 if (count && !newcount) | |
162 ch = direction; | |
163 else | |
164 ch = readchar(); | |
165 switch (ch) | |
166 { | |
167 case 'h': case 'j': case 'k': case 'l': | |
168 case 'y': case 'u': case 'b': case 'n': | |
169 ch = toupper(ch); | |
170 } | |
171 direction = ch; | |
172 } | |
173 newcount = FALSE; | |
174 /* | |
175 * execute a command | |
176 */ | |
177 if (count && !running) | |
178 count--; | |
179 switch (ch) | |
180 { | |
181 case '!' : shell(); | |
182 when 'h' : do_move(0, -1); | |
183 when 'j' : do_move(1, 0); | |
184 when 'k' : do_move(-1, 0); | |
185 when 'l' : do_move(0, 1); | |
186 when 'y' : do_move(-1, -1); | |
187 when 'u' : do_move(-1, 1); | |
188 when 'b' : do_move(1, -1); | |
189 when 'n' : do_move(1, 1); | |
190 when 'H' : do_run('h'); | |
191 when 'J' : do_run('j'); | |
192 when 'K' : do_run('k'); | |
193 when 'L' : do_run('l'); | |
194 when 'Y' : do_run('y'); | |
195 when 'U' : do_run('u'); | |
196 when 'B' : do_run('b'); | |
197 when 'N' : do_run('n'); | |
198 when 't': | |
199 if((item=get_item(pack,"throw", ALL)) != NULL && get_dir()) | |
200 missile(delta.y, delta.x, item, &player); | |
201 else | |
202 after = FALSE; | |
203 when 'Q' : after = FALSE; quit(-1); | |
204 when 'i' : after = FALSE; inventory(pack, ALL); | |
205 when 'I' : after = FALSE; picky_inven(); | |
206 when 'd' : drop(NULL); | |
207 when 'P' : grab(hero.y, hero.x); | |
208 when 'q' : quaff(-1, NULL, TRUE); | |
209 when 'r' : read_scroll(-1, NULL, TRUE); | |
210 when 'e' : eat(); | |
211 when 'w' : wield(); | |
212 when 'W' : wear(); | |
213 when 'T' : take_off(); | |
214 when 'o' : option(); | |
215 when 'c' : call(FALSE); | |
216 when 'm' : call(TRUE); | |
217 when '>' : after = FALSE; d_level(); | |
218 when '<' : after = FALSE; u_level(); | |
219 when '?' : after = FALSE; help(); | |
220 when '/' : after = FALSE; identify(); | |
221 when CTRL('U') : use_mm(-1); | |
222 when CTRL('T') : | |
223 if (get_dir()) steal(); | |
224 else after = FALSE; | |
225 when 'D' : dip_it(); | |
226 when 'G' : gsense(); | |
227 when '^' : set_trap(&player, hero.y, hero.x); | |
228 when 's' : search(FALSE, FALSE); | |
229 when 'z' : if (!do_zap(TRUE, NULL, FALSE)) | |
230 after=FALSE; | |
231 when 'p' : pray(); | |
232 when 'C' : cast(); | |
233 when 'a' : | |
234 if (get_dir()) | |
235 affect(); | |
236 else after = FALSE; | |
237 when 'v' : after = FALSE; | |
238 msg("Advanced Rogue Version %s.", | |
239 release); | |
240 when CTRL('L') : after = FALSE; clearok(curscr, TRUE); | |
241 touchwin(cw); /* MMMMMMMMMM */ | |
242 when CTRL('R') : after = FALSE; msg(huh); | |
243 when 'S' : | |
244 after = FALSE; | |
245 if (save_game()) | |
246 { | |
247 wclear(cw); | |
248 draw(cw); | |
249 endwin(); | |
250 printf("\n"); | |
251 exit(0); | |
252 } | |
253 when '.' : ; /* Rest command */ | |
254 when ' ' : after = FALSE; /* Do Nothing */ | |
255 #ifdef WIZARD | |
256 when CTRL('P') : | |
257 after = FALSE; | |
258 if (wizard) | |
259 { | |
260 wizard = FALSE; | |
261 trader = 0; | |
262 msg("Not wizard any more"); | |
263 } | |
264 else | |
265 { | |
266 if (waswizard || passwd()) | |
267 { | |
268 msg("Welcome, oh mighty wizard."); | |
269 wizard = waswizard = TRUE; | |
270 } | |
271 else | |
272 msg("Sorry"); | |
273 } | |
274 #endif | |
275 when ESCAPE : /* Escape */ | |
276 door_stop = FALSE; | |
277 count = 0; | |
278 after = FALSE; | |
279 when '#': | |
280 if (levtype == POSTLEV) /* buy something */ | |
281 buy_it(); | |
282 after = FALSE; | |
283 when '$': | |
284 if (levtype == POSTLEV) /* price something */ | |
285 price_it(); | |
286 after = FALSE; | |
287 when '%': | |
288 if (levtype == POSTLEV) /* sell something */ | |
289 sell_it(); | |
290 after = FALSE; | |
291 otherwise : | |
292 after = FALSE; | |
293 #ifdef WIZARD | |
294 if (wizard) switch (ch) | |
295 { | |
296 case 'M' : create_obj(TRUE, 0, 0); | |
297 when CTRL('W') : wanderer(); | |
298 when CTRL('I') : inventory(lvl_obj, ALL); | |
299 when CTRL('Z') : whatis(NULL); | |
300 when CTRL('D') : level++; new_level(NORMLEV); | |
301 when CTRL('F') : overlay(stdscr,cw); | |
302 when CTRL('X') : overlay(mw,cw); | |
303 when CTRL('J') : teleport(); | |
304 when CTRL('E') : sprintf(outstring,"food left: %d\tfood level: %d", | |
305 food_left, foodlev); | |
306 msg(outstring); | |
307 when CTRL('A') : activity(); | |
308 when CTRL('C') : | |
309 { | |
310 int tlev; | |
311 prbuf[0] = '\0'; | |
312 msg("Which level? "); | |
313 if(get_str(prbuf,cw) == NORM) { | |
314 tlev = atoi(prbuf); | |
315 if(tlev < 1) { | |
316 mpos = 0; | |
317 msg("Illegal level."); | |
318 } | |
319 else if (tlev > 199) { | |
320 levtype = MAZELEV; | |
321 level = tlev - 200 + 1; | |
322 } | |
323 else if (tlev > 99) { | |
324 levtype = POSTLEV; | |
325 level = tlev - 100 + 1; | |
326 } | |
327 else { | |
328 levtype = NORMLEV; | |
329 level = tlev; | |
330 } | |
331 new_level(levtype); | |
332 } | |
333 } | |
334 when CTRL('N') : | |
335 { | |
336 if ((item=get_item(pack, "charge", STICK)) != NULL){ | |
337 (OBJPTR(item))->o_charges=10000; | |
338 } | |
339 } | |
340 when CTRL('H') : | |
341 { | |
342 register int i; | |
343 register struct object *obj; | |
344 | |
345 for (i = 0; i < 9; i++) | |
346 raise_level(TRUE); | |
347 /* | |
348 * Give the rogue a sword | |
349 */ | |
350 if(cur_weapon==NULL || cur_weapon->o_type!=RELIC) { | |
351 item = spec_item(WEAPON, TWOSWORD, 5, 5); | |
352 add_pack(item, TRUE, NULL); | |
353 cur_weapon = OBJPTR(item); | |
354 cur_weapon->o_flags |= (ISKNOW | ISPROT); | |
355 } | |
356 /* | |
357 * And his suit of armor | |
358 */ | |
359 if (player.t_ctype == C_THIEF) | |
360 item = spec_item(ARMOR, STUDDED_LEATHER, 10, 0); | |
361 else | |
362 item = spec_item(ARMOR, PLATE_ARMOR, 7, 0); | |
363 obj = OBJPTR(item); | |
364 obj->o_flags |= (ISKNOW | ISPROT); | |
365 obj->o_weight = armors[PLATE_ARMOR].a_wght; | |
366 cur_armor = obj; | |
367 add_pack(item, TRUE, NULL); | |
368 purse += 20000; | |
369 } | |
370 otherwise : | |
371 msg("Illegal command '%s'.", unctrl(ch)); | |
372 count = 0; | |
373 } | |
374 else | |
375 #endif | |
376 { | |
377 msg("Illegal command '%s'.", unctrl(ch)); | |
378 count = 0; | |
379 after = FALSE; | |
380 } | |
381 } | |
382 /* | |
383 * turn off flags if no longer needed | |
384 */ | |
385 if (!running) | |
386 door_stop = FALSE; | |
387 } | |
388 /* | |
389 * If he ran into something to take, let him pick it up. | |
390 * unless its a trading post | |
391 */ | |
392 if (auto_pickup && take != 0 && levtype != POSTLEV) | |
393 pick_up(take); | |
394 if (!running) | |
395 door_stop = FALSE; | |
396 | |
397 /* If after is true, mark an_after as true so that if | |
398 * we are hasted, the first "after" will be noted. | |
399 * if after is FALSE then stay in this loop | |
400 */ | |
401 if (after) an_after = TRUE; | |
402 else ntimes++; | |
403 } | |
404 | |
405 /* | |
406 * Kick off the rest if the daemons and fuses | |
407 */ | |
408 if (an_after) | |
409 { | |
410 /* | |
411 * If player is infested, take off a hit point | |
412 */ | |
413 if (on(player, HASINFEST)) { | |
414 if ((pstats.s_hpt -= infest_dam) <= 0) death(D_INFESTATION); | |
415 } | |
416 /* | |
417 * if player has body rot then take off five hits | |
418 */ | |
419 if (on(player, DOROT)) { | |
420 if ((pstats.s_hpt -= 5) <= 0) death(D_ROT); | |
421 } | |
422 do_daemons(AFTER); | |
423 do_fuses(AFTER); | |
424 if (!((running || count) && jump)) look(FALSE, FALSE); | |
425 | |
426 | |
427 } | |
428 t_free_list(monst_dead); | |
429 } | |
430 | |
431 /* | |
432 * quit: | |
433 * Have player make certain, then exit. | |
434 */ | |
435 | |
436 void | |
437 quit(int sig) | |
438 { | |
439 NOOP(sig); | |
440 | |
441 /* | |
442 * Reset the signal in case we got here via an interrupt | |
443 */ | |
444 if (signal(SIGINT, &quit) != &quit) | |
445 mpos = 0; | |
446 msg("Really quit? "); | |
447 draw(cw); | |
448 if (readchar() == 'y') | |
449 { | |
450 clear(); | |
451 move(LINES-1, 0); | |
452 draw(stdscr); | |
453 score(pstats.s_exp + (long) purse, CHICKEN, 0); | |
454 exit(0); | |
455 } | |
456 else | |
457 { | |
458 signal(SIGINT, quit); | |
459 wmove(cw, 0, 0); | |
460 wclrtoeol(cw); | |
461 status(FALSE); | |
462 draw(cw); | |
463 mpos = 0; | |
464 count = 0; | |
465 running = FALSE; | |
466 } | |
467 } | |
468 | |
469 /* | |
470 * bugkill: | |
471 * killed by a program bug instead of voluntarily. | |
472 */ | |
473 | |
474 void | |
475 bugkill(sig) | |
476 int sig; | |
477 { | |
478 signal(sig, quit); /* If we get it again, give up */ | |
479 death(D_SIGNAL); /* Killed by a bug */ | |
480 } | |
481 | |
482 | |
483 /* | |
484 * search: | |
485 * Player gropes about him to find hidden things. | |
486 */ | |
487 | |
488 search(is_thief, door_chime) | |
489 register bool is_thief, door_chime; | |
490 { | |
491 register int x, y; | |
492 register char ch, /* The trap or door character */ | |
493 sch, /* Trap or door character (as seen on screen) */ | |
494 mch; /* Monster, if a monster is on the trap or door */ | |
495 register struct linked_list *item; | |
496 register struct thing *mp; /* Status on surrounding monster */ | |
497 | |
498 /* | |
499 * Look all around the hero, if there is something hidden there, | |
500 * give him a chance to find it. If its found, display it. | |
501 */ | |
502 if (on(player, ISBLIND)) | |
503 return; | |
504 for (x = hero.x - 1; x <= hero.x + 1; x++) | |
505 for (y = hero.y - 1; y <= hero.y + 1; y++) | |
506 { | |
507 if (y==hero.y && x==hero.x) | |
508 continue; | |
509 | |
510 /* Mch and ch will be the same unless there is a monster here */ | |
511 mch = CCHAR( winat(y, x) ); | |
512 ch = CCHAR( mvwinch(stdscr, y, x) ); | |
513 sch = CCHAR( mvwinch(cw, y, x) ); /* What's on the screen */ | |
514 | |
515 if (door_chime == FALSE && isatrap(ch)) { | |
516 register struct trap *tp; | |
517 | |
518 /* Is there a monster on the trap? */ | |
519 if (mch != ch && (item = find_mons(y, x)) != NULL) { | |
520 mp = THINGPTR(item); | |
521 if (sch == mch) sch = mp->t_oldch; | |
522 } | |
523 else mp = NULL; | |
524 | |
525 /* | |
526 * is this one found already? | |
527 */ | |
528 if (isatrap(sch)) | |
529 continue; /* give him chance for other traps */ | |
530 tp = trap_at(y, x); | |
531 /* | |
532 * if the thief set it then don't display it. | |
533 * if its not a thief he has 50/50 shot | |
534 */ | |
535 if((tp->tr_flags&ISTHIEFSET) || (!is_thief && rnd(100)>50)) | |
536 continue; /* give him chance for other traps */ | |
537 tp->tr_flags |= ISFOUND; | |
538 | |
539 /* Let's update the screen */ | |
540 if (mp != NULL && CCHAR(mvwinch(cw, y, x)) == mch) | |
541 mp->t_oldch = ch; /* Will change when monst moves */ | |
542 else mvwaddch(cw, y, x, ch); | |
543 | |
544 count = 0; | |
545 running = FALSE; | |
546 msg(tr_name(tp->tr_type)); | |
547 } | |
548 else if (ch == SECRETDOOR) { | |
549 if (door_chime == TRUE || (!is_thief && rnd(100) < 20)) { | |
550 /* Is there a monster on the door? */ | |
551 if (mch != ch && (item = find_mons(y, x)) != NULL) { | |
552 mp = THINGPTR(item); | |
553 | |
554 /* Screen will change when monster moves */ | |
555 if (sch == mch) mp->t_oldch = ch; | |
556 } | |
557 mvaddch(y, x, DOOR); | |
558 count = 0; | |
559 } | |
560 } | |
561 } | |
562 } | |
563 | |
564 | |
565 /* | |
566 * help: | |
567 * Give single character help, or the whole mess if he wants it | |
568 */ | |
569 | |
570 help() | |
571 { | |
572 register struct h_list *strp = helpstr; | |
573 #ifdef WIZARD | |
574 struct h_list *wizp = wiz_help; | |
575 #endif | |
576 register char helpch; | |
577 register int cnt; | |
578 | |
579 msg("Character you want help for (* for all): "); | |
580 helpch = readchar(); | |
581 mpos = 0; | |
582 /* | |
583 * If its not a *, print the right help string | |
584 * or an error if he typed a funny character. | |
585 */ | |
586 if (helpch != '*') { | |
587 wmove(cw, 0, 0); | |
588 while (strp->h_ch) { | |
589 if (strp->h_ch == helpch) { | |
590 sprintf(outstring,"%s%s", unctrl(strp->h_ch), strp->h_desc); | |
591 msg(outstring); | |
592 return; | |
593 } | |
594 strp++; | |
595 } | |
596 #ifdef WIZARD | |
597 if (wizard) { | |
598 while (wizp->h_ch) { | |
599 if (wizp->h_ch == helpch) { | |
600 sprintf(outstring,"%s%s", unctrl(wizp->h_ch), wizp->h_desc); | |
601 msg(outstring); | |
602 return; | |
603 } | |
604 wizp++; | |
605 } | |
606 } | |
607 #endif | |
608 | |
609 msg("Unknown character '%s'", unctrl(helpch)); | |
610 return; | |
611 } | |
612 /* | |
613 * Here we print help for everything. | |
614 * Then wait before we return to command mode | |
615 */ | |
616 wclear(hw); | |
617 cnt = 0; | |
618 while (strp->h_ch) { | |
619 mvwaddstr(hw, cnt % 23, cnt > 22 ? 40 : 0, unctrl(strp->h_ch)); | |
620 waddstr(hw, strp->h_desc); | |
621 strp++; | |
622 if (++cnt >= 46 && strp->h_ch) { | |
623 wmove(hw, LINES-1, 0); | |
624 wprintw(hw, morestr); | |
625 draw(hw); | |
626 wait_for(hw,' '); | |
627 wclear(hw); | |
628 cnt = 0; | |
629 } | |
630 } | |
631 #ifdef WIZARD | |
632 if (wizard) { | |
633 while (wizp->h_ch) { | |
634 mvwaddstr(hw, cnt % 23, cnt > 22 ? 40 : 0, unctrl(wizp->h_ch)); | |
635 waddstr(hw, wizp->h_desc); | |
636 wizp++; | |
637 if (++cnt >= 46 && wizp->h_ch) { | |
638 wmove(hw, LINES-1, 0); | |
639 wprintw(hw, morestr); | |
640 draw(hw); | |
641 wait_for(hw,' '); | |
642 wclear(hw); | |
643 cnt = 0; | |
644 } | |
645 } | |
646 } | |
647 #endif | |
648 wmove(hw, LINES-1, 0); | |
649 wprintw(hw, spacemsg); | |
650 draw(hw); | |
651 wait_for(hw,' '); | |
652 wclear(hw); | |
653 draw(hw); | |
654 wmove(cw, 0, 0); | |
655 wclrtoeol(cw); | |
656 status(FALSE); | |
657 touchwin(cw); | |
658 } | |
659 /* | |
660 * identify: | |
661 * Tell the player what a certain thing is. | |
662 */ | |
663 | |
664 identify() | |
665 { | |
666 register char ch; | |
667 const char *str; | |
668 | |
669 msg("What do you want identified? "); | |
670 ch = readchar(); | |
671 mpos = 0; | |
672 if (ch == ESCAPE) | |
673 { | |
674 msg(""); | |
675 return; | |
676 } | |
677 if (isalpha(ch)) | |
678 str = monsters[id_monst(ch)].m_name; | |
679 else switch(ch) | |
680 { | |
681 case '|': | |
682 case '-': | |
683 str = (levtype == OUTSIDE) ? "boundary of sector" | |
684 : "wall of a room"; | |
685 when GOLD: str = "gold"; | |
686 when STAIRS : str = (levtype == OUTSIDE) ? "entrance to a dungeon" | |
687 : "passage leading down"; | |
688 when DOOR: str = "door"; | |
689 when FLOOR: str = (levtype == OUTSIDE) ? "meadow" : "room floor"; | |
690 when VPLAYER: str = "the hero of the game ---> you"; | |
691 when IPLAYER: str = "you (but invisible)"; | |
692 when PASSAGE: str = "passage"; | |
693 when POST: str = "trading post"; | |
694 when POOL: str = (levtype == OUTSIDE) ? "lake" | |
695 : "a shimmering pool"; | |
696 when TRAPDOOR: str = "trapdoor"; | |
697 when ARROWTRAP: str = "arrow trap"; | |
698 when SLEEPTRAP: str = "sleeping gas trap"; | |
699 when BEARTRAP: str = "bear trap"; | |
700 when TELTRAP: str = "teleport trap"; | |
701 when DARTTRAP: str = "dart trap"; | |
702 when MAZETRAP: str = "entrance to a maze"; | |
703 when FOREST: str = "forest"; | |
704 when POTION: str = "potion"; | |
705 when SCROLL: str = "scroll"; | |
706 when FOOD: str = "food"; | |
707 when WEAPON: str = "weapon"; | |
708 when ' ' : str = "solid rock"; | |
709 when ARMOR: str = "armor"; | |
710 when MM: str = "miscellaneous magic"; | |
711 when RING: str = "ring"; | |
712 when STICK: str = "wand or staff"; | |
713 when SECRETDOOR:str = "secret door"; | |
714 when RELIC: str = "artifact"; | |
715 otherwise: str = "unknown character"; | |
716 } | |
717 sprintf(outstring,"'%s' : %s", unctrl(ch), str); | |
718 msg(outstring); | |
719 } | |
720 | |
721 /* | |
722 * d_level: | |
723 * He wants to go down a level | |
724 */ | |
725 | |
726 d_level() | |
727 { | |
728 bool no_phase=FALSE; | |
729 | |
730 | |
731 /* If we are at a top-level trading post, we probably can't go down */ | |
732 if (levtype == POSTLEV && level == 0 && rnd(100) < 80) { | |
733 msg("I see no way down."); | |
734 return; | |
735 } | |
736 | |
737 if (winat(hero.y, hero.x) != STAIRS) { | |
738 if (off(player, CANINWALL) || /* Must use stairs if can't phase */ | |
739 (levtype == OUTSIDE && rnd(100) < 90)) { | |
740 msg("I see no way down."); | |
741 return; | |
742 } | |
743 | |
744 /* Is there any dungeon left below? */ | |
745 if (level >= nfloors) { | |
746 msg("There is only solid rock below."); | |
747 return; | |
748 } | |
749 | |
750 extinguish(unphase); /* Using phase to go down gets rid of it */ | |
751 no_phase = TRUE; | |
752 } | |
753 | |
754 /* Is this the bottom? */ | |
755 if (level >= nfloors) { | |
756 msg("The stairway only goes up."); | |
757 return; | |
758 } | |
759 | |
760 level++; | |
761 new_level(NORMLEV); | |
762 if (no_phase) unphase(); | |
763 } | |
764 | |
765 /* | |
766 * u_level: | |
767 * He wants to go up a level | |
768 */ | |
769 | |
770 u_level() | |
771 { | |
772 bool no_phase = FALSE; | |
773 register struct linked_list *item; | |
774 struct thing *tp; | |
775 struct object *obj; | |
776 | |
777 if (winat(hero.y, hero.x) != STAIRS) { | |
778 if (off(player, CANINWALL)) { /* Must use stairs if can't phase */ | |
779 msg("I see no way up."); | |
780 return; | |
781 } | |
782 | |
783 extinguish(unphase); | |
784 no_phase = TRUE; | |
785 } | |
786 | |
787 if (level == 0) { | |
788 msg("The stairway only goes down."); | |
789 return; | |
790 } | |
791 | |
792 /* | |
793 * does he have the item he was quested to get? | |
794 */ | |
795 if (level == 1) { | |
796 for (item = pack; item != NULL; item = next(item)) { | |
797 obj = OBJPTR(item); | |
798 if (obj->o_type == RELIC && obj->o_which == quest_item) | |
799 total_winner(); | |
800 } | |
801 } | |
802 /* | |
803 * check to see if he trapped a UNIQUE, If he did then put it back | |
804 * in the monster table for next time | |
805 */ | |
806 for (item = tlist; item != NULL; item = next(item)) { | |
807 tp = THINGPTR(item); | |
808 if (on(*tp, ISUNIQUE)) | |
809 monsters[tp->t_index].m_normal = TRUE; | |
810 } | |
811 t_free_list(tlist); /* Monsters that fell below are long gone! */ | |
812 | |
813 if (levtype != POSTLEV) level--; | |
814 if (level > 0) new_level(NORMLEV); | |
815 else { | |
816 level = -1; /* Indicate that we are new to the outside */ | |
817 msg("You emerge into the %s", daytime ? "light" : "night"); | |
818 new_level(OUTSIDE); /* Leaving the dungeon */ | |
819 } | |
820 | |
821 if (no_phase) unphase(); | |
822 } | |
823 | |
824 /* | |
825 * Let him escape for a while | |
826 */ | |
827 | |
828 shell() | |
829 { | |
830 /* | |
831 * Set the terminal back to original mode | |
832 */ | |
833 wclear(hw); | |
834 wmove(hw, LINES-1, 0); | |
835 draw(hw); | |
836 endwin(); | |
837 in_shell = TRUE; | |
838 fflush(stdout); | |
839 | |
840 md_shellescape(); | |
841 | |
842 printf(retstr); | |
843 fflush(stdout); | |
844 noecho(); | |
845 raw(); | |
846 keypad(cw,1); | |
847 in_shell = FALSE; | |
848 wait_for(hw,'\n'); | |
849 clearok(cw, TRUE); | |
850 touchwin(cw); | |
851 wmove(cw,0,0); | |
852 draw(cw); | |
853 } | |
854 | |
855 /* | |
856 * allow a user to call a potion, scroll, or ring something | |
857 */ | |
858 call(mark) | |
859 bool mark; | |
860 { | |
861 register struct object *obj; | |
862 register struct linked_list *item; | |
863 register char **guess = NULL, *elsewise = NULL; | |
864 register bool *know; | |
865 | |
866 if (mark) item = get_item(pack, "mark", ALL); | |
867 else item = get_item(pack, "call", CALLABLE); | |
868 /* | |
869 * Make certain that it is somethings that we want to wear | |
870 */ | |
871 if (item == NULL) | |
872 return; | |
873 obj = OBJPTR(item); | |
874 switch (obj->o_type) | |
875 { | |
876 case RING: | |
877 guess = r_guess; | |
878 know = r_know; | |
879 elsewise = (r_guess[obj->o_which] != NULL ? | |
880 r_guess[obj->o_which] : r_stones[obj->o_which]); | |
881 when POTION: | |
882 guess = p_guess; | |
883 know = p_know; | |
884 elsewise = (p_guess[obj->o_which] != NULL ? | |
885 p_guess[obj->o_which] : p_colors[obj->o_which]); | |
886 when SCROLL: | |
887 guess = s_guess; | |
888 know = s_know; | |
889 elsewise = (s_guess[obj->o_which] != NULL ? | |
890 s_guess[obj->o_which] : s_names[obj->o_which]); | |
891 when STICK: | |
892 guess = ws_guess; | |
893 know = ws_know; | |
894 elsewise = (ws_guess[obj->o_which] != NULL ? | |
895 ws_guess[obj->o_which] : ws_made[obj->o_which]); | |
896 when MM: | |
897 guess = m_guess; | |
898 know = m_know; | |
899 elsewise = (m_guess[obj->o_which] != NULL ? | |
900 m_guess[obj->o_which] : "nothing"); | |
901 otherwise: | |
902 if (!mark) { | |
903 msg("You can't call that anything."); | |
904 return; | |
905 } | |
906 else know = (bool *) 0; | |
907 } | |
908 if ((obj->o_flags & ISPOST) || (know && know[obj->o_which]) && !mark) { | |
909 msg("That has already been identified."); | |
910 return; | |
911 } | |
912 if (mark) { | |
913 if (obj->o_mark[0]) { | |
914 addmsg(terse ? "M" : "Was m"); | |
915 msg("arked \"%s\"", obj->o_mark); | |
916 } | |
917 msg(terse ? "Mark it: " : "What do you want to mark it? "); | |
918 prbuf[0] = '\0'; | |
919 } | |
920 else { | |
921 addmsg(terse ? "C" : "Was c"); | |
922 msg("alled \"%s\"", elsewise); | |
923 msg(terse ? "Call it: " : "What do you want to call it? "); | |
924 if (guess[obj->o_which] != NULL) | |
925 free(guess[obj->o_which]); | |
926 strcpy(prbuf, elsewise); | |
927 } | |
928 if (get_str(prbuf, cw) == NORM) { | |
929 if (mark) { | |
930 strncpy(obj->o_mark, prbuf, MARKLEN-1); | |
931 obj->o_mark[MARKLEN-1] = '\0'; | |
932 } | |
933 else { | |
934 guess[obj->o_which] = new((unsigned int) strlen(prbuf) + 1); | |
935 strcpy(guess[obj->o_which], prbuf); | |
936 } | |
937 } | |
938 } |