comparison arogue7/player.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 f9ef86cf22b2
comparison
equal deleted inserted replaced
124:d10fc4a065ac 125:adfa37e67084
1 /*
2 * player.c - This file contains functions for dealing with special player
3 * abilities
4 *
5 * Advanced Rogue
6 * Copyright (C) 1984, 1985, 1986 Michael Morgan, Ken Dalka and AT&T
7 * All rights reserved.
8 *
9 * Based on "Rogue: Exploring the Dungeons of Doom"
10 * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
11 * All rights reserved.
12 *
13 * See the file LICENSE.TXT for full copyright and licensing information.
14 */
15
16 /*
17 * This file contains functions for dealing with special player abilities
18 */
19
20 #include <ctype.h>
21 #include "curses.h"
22 #include "rogue.h"
23 #ifdef PC7300
24 #include "menu.h"
25 #endif
26
27
28 /*
29 * affect:
30 * cleric affecting undead
31 */
32
33 affect()
34 {
35 register struct linked_list *item;
36 register struct thing *tp;
37 register char *mname;
38 bool see;
39 coord new_pos;
40 int lvl;
41
42 if (!(player.t_ctype == C_CLERIC ||
43 (player.t_ctype == C_PALADIN && pstats.s_lvl > 4) ||
44 cur_relic[HEIL_ANKH] != 0)) {
45 msg("You cannot affect undead.");
46 return;
47 }
48
49 new_pos.y = hero.y + player.t_newpos.y;
50 new_pos.x = hero.x + player.t_newpos.x;
51
52 if (cansee(new_pos.y, new_pos.x)) see = TRUE;
53 else see = FALSE;
54
55 /* Anything there? */
56 if (new_pos.y < 0 || new_pos.y > lines-3 ||
57 new_pos.x < 0 || new_pos.x > cols-1 ||
58 mvwinch(mw, new_pos.y, new_pos.x) == ' ') {
59 msg("Nothing to affect.");
60 return;
61 }
62
63 if ((item = find_mons(new_pos.y, new_pos.x)) == NULL) {
64 debug("Affect what @ %d,%d?", new_pos.y, new_pos.x);
65 return;
66 }
67 tp = THINGPTR(item);
68 mname = monster_name(tp);
69
70 if (on(player, ISINVIS) && off(*tp, CANSEE)) {
71 msg("%s%s cannot see you", see ? "The " : "It",
72 see ? mname : "");
73 return;
74 }
75
76 if (off(*tp, TURNABLE) || on(*tp, WASTURNED))
77 goto annoy;
78 turn_off(*tp, TURNABLE);
79
80 lvl = pstats.s_lvl;
81 if (player.t_ctype == C_PALADIN && cur_relic[HEIL_ANKH] == 0) {
82 lvl -= 4;
83 }
84 /* Can cleric kill it? */
85 if (lvl >= 3 * tp->t_stats.s_lvl) {
86 unsigned long test; /* For overflow check */
87
88 msg("You have destroyed %s%s.", see ? "the " : "it", see ? mname : "");
89 test = pstats.s_exp + tp->t_stats.s_exp;
90
91 /* Be sure there is no overflow before increasing experience */
92 if (test > pstats.s_exp) pstats.s_exp = test;
93 killed(item, FALSE, TRUE, TRUE);
94 check_level();
95 return;
96 }
97
98 /* Can cleric turn it? */
99 if (rnd(100) + 1 >
100 (100 * ((2 * tp->t_stats.s_lvl) - lvl)) / lvl) {
101 unsigned long test; /* Overflow test */
102
103 /* Make the monster flee */
104 turn_on(*tp, WASTURNED); /* No more fleeing after this */
105 turn_on(*tp, ISFLEE);
106 runto(tp, &hero);
107
108 /* Disrupt it */
109 dsrpt_monster(tp, TRUE, TRUE);
110
111 /* Let player know */
112 msg("You have turned %s%s.", see ? "the " : "it", see ? mname : "");
113
114 /* get points for turning monster -- but check overflow first */
115 test = pstats.s_exp + tp->t_stats.s_exp/2;
116 if (test > pstats.s_exp) pstats.s_exp = test;
117 check_level();
118
119 /* If monster was suffocating, stop it */
120 if (on(*tp, DIDSUFFOCATE)) {
121 turn_off(*tp, DIDSUFFOCATE);
122 extinguish(suffocate);
123 }
124
125 /* If monster held us, stop it */
126 if (on(*tp, DIDHOLD) && (--hold_count == 0))
127 turn_off(player, ISHELD);
128 turn_off(*tp, DIDHOLD);
129
130 /* It is okay to turn tail */
131 tp->t_oldpos = tp->t_pos;
132
133 return;
134 }
135
136 /* Otherwise -- no go */
137 annoy:
138 if (see && tp->t_stats.s_intel > 16)
139 msg("%s laughs at you...", prname(mname, TRUE));
140 else
141 msg("You do not affect %s%s.", see ? "the " : "it", see ? mname : "");
142
143 /* Annoy monster */
144 if (off(*tp, ISFLEE)) runto(tp, &hero);
145 }
146
147 /*
148 * the magic user is going to try and cast a spell
149 */
150 cast()
151 {
152 int spell_ability,
153 which_spell,
154 num_spells;
155
156 if (player.t_ctype != C_MAGICIAN && player.t_ctype != C_RANGER) {
157 msg("You are not permitted to cast spells.");
158 return;
159 }
160 spell_ability = pstats.s_lvl * pstats.s_intel;
161 if (player.t_ctype != C_MAGICIAN)
162 spell_ability /= 3;
163
164 if (player.t_action != C_CAST) {
165 /*
166 * Get the number of avilable spells
167 */
168 num_spells = 0;
169 if (pstats.s_intel >= 16)
170 num_spells += pstats.s_intel - 15;
171 num_spells += pstats.s_lvl;
172 if (player.t_ctype != C_MAGICIAN)
173 num_spells /= 3;
174 if (num_spells > MAXSPELLS)
175 num_spells = MAXSPELLS;
176 if (num_spells < 1) {
177 msg("You are not allowed to cast spells yet.");
178 return;
179 }
180 if (pick_spell( magic_spells,
181 spell_ability,
182 num_spells,
183 spell_power,
184 "cast",
185 "spell"))
186 player.t_action = C_CAST;
187 return;
188 }
189
190 /* We've waited our required casting time. */
191 which_spell = player.t_selection;
192 player.t_selection = 0;
193 player.t_using = NULL;
194 player.t_action = A_NIL;
195
196 if ((spell_power + magic_spells[which_spell].s_cost) > spell_ability) {
197 msg("Your attempt fails.");
198 return;
199 }
200
201 msg("Your spell is successful.");
202
203 if (magic_spells[which_spell].s_type == TYP_POTION)
204 quaff( magic_spells[which_spell].s_which,
205 NULL,
206 magic_spells[which_spell].s_flag,
207 FALSE);
208 else if (magic_spells[which_spell].s_type == TYP_SCROLL)
209 read_scroll( magic_spells[which_spell].s_which,
210 magic_spells[which_spell].s_flag,
211 FALSE);
212 else if (magic_spells[which_spell].s_type == TYP_STICK) {
213 if (!player_zap(magic_spells[which_spell].s_which,
214 magic_spells[which_spell].s_flag)) {
215 after = FALSE;
216 return;
217 }
218 }
219 spell_power += magic_spells[which_spell].s_cost;
220 }
221
222 /*
223 * the druid asks his deity for a spell
224 */
225 chant()
226 {
227 register int num_chants,
228 chant_ability,
229 which_chant;
230
231 which_chant = num_chants = chant_ability = 0;
232
233 if (player.t_ctype != C_DRUID && player.t_ctype != C_RANGER) {
234 msg("You are not permitted to chant.");
235 return;
236 }
237 if (cur_misc[WEAR_CLOAK] != NULL &&
238 cur_misc[WEAR_CLOAK]->o_which == MM_R_POWERLESS) {
239 msg("You can't seem to chant!");
240 return;
241 }
242 chant_ability = pstats.s_lvl * pstats.s_wisdom;
243 if (player.t_ctype != C_DRUID)
244 chant_ability /= 3;
245
246 if (player.t_action != C_CHANT) {
247 num_chants = 0;
248
249 /* Get the number of avilable chants */
250 if (pstats.s_wisdom > 16)
251 num_chants = (pstats.s_wisdom - 15) / 2;
252
253 num_chants += pstats.s_lvl;
254
255 if (player.t_ctype != C_DRUID)
256 num_chants /= 3;
257
258 if (num_chants > MAXCHANTS)
259 num_chants = MAXCHANTS;
260
261 if (num_chants < 1) {
262 msg("You are not permitted to chant yet.");
263 return;
264 }
265
266 /* Prompt for chant */
267 if (pick_spell( druid_spells,
268 chant_ability,
269 num_chants,
270 chant_time,
271 "sing",
272 "chant"))
273 player.t_action = C_CHANT;
274
275 return;
276 }
277
278 /* We've waited our required chanting time. */
279 which_chant = player.t_selection;
280 player.t_selection = 0;
281 player.t_using = NULL;
282 player.t_action = A_NIL;
283
284 if (druid_spells[which_chant].s_cost + chant_time > chant_ability) {
285 msg("Your chant fails.");
286 return;
287 }
288
289 msg("Your chant has been granted.");
290
291 if (druid_spells[which_chant].s_type == TYP_POTION)
292 quaff( druid_spells[which_chant].s_which,
293 NULL,
294 druid_spells[which_chant].s_flag,
295 FALSE);
296 else if (druid_spells[which_chant].s_type == TYP_SCROLL)
297 read_scroll( druid_spells[which_chant].s_which,
298 druid_spells[which_chant].s_flag,
299 FALSE);
300 else if (druid_spells[which_chant].s_type == TYP_STICK) {
301 if (!player_zap(druid_spells[which_chant].s_which,
302 druid_spells[which_chant].s_flag)) {
303 after = FALSE;
304 return;
305 }
306 }
307 chant_time += druid_spells[which_chant].s_cost;
308 }
309
310 /* Constitution bonus */
311
312 const_bonus() /* Hit point adjustment for changing levels */
313 {
314 register int bonus;
315 if (pstats.s_const > 6 && pstats.s_const <= 14)
316 bonus = 0;
317 else if (pstats.s_const > 14)
318 bonus = pstats.s_const-14;
319 else if (pstats.s_const > 3)
320 bonus = -1;
321 else
322 bonus = -2;
323 switch(player.t_ctype) {
324 case C_FIGHTER: bonus = min(bonus, 11);
325 when C_MAGICIAN: bonus = min(bonus, 4);
326 when C_CLERIC: bonus = min(bonus, 4);
327 when C_THIEF: bonus = min(bonus, 4);
328 when C_RANGER: bonus = min(bonus, 6);
329 when C_PALADIN: bonus = min(bonus, 8);
330 when C_ASSASIN: bonus = min(bonus, 4);
331 when C_MONK: bonus = min(bonus, 6);
332 when C_DRUID: bonus = min(bonus, 4);
333 otherwise: bonus = min(bonus, 4);
334 }
335 return(bonus);
336 }
337
338
339 /* Routines for thieves */
340
341 /*
342 * gsense:
343 * Sense gold
344 */
345
346 gsense()
347 {
348 /* Only thieves can do this */
349 if (player.t_ctype != C_THIEF && player.t_ctype != C_ASSASIN) {
350 msg("You seem to have no gold sense.");
351 return;
352 }
353
354 read_scroll(S_GFIND, NULL, FALSE);
355 }
356
357 /*
358 * the cleric asks his deity for a spell
359 */
360 pray()
361 {
362 register int num_prayers,
363 prayer_ability,
364 which_prayer;
365
366 which_prayer = num_prayers = prayer_ability = 0;
367
368 if (player.t_ctype != C_CLERIC &&
369 player.t_ctype != C_PALADIN &&
370 cur_relic[HEIL_ANKH] == 0) {
371 msg("You are not permitted to pray.");
372 return;
373 }
374 if (cur_misc[WEAR_CLOAK] != NULL &&
375 cur_misc[WEAR_CLOAK]->o_which == MM_R_POWERLESS) {
376 msg("You can't seem to pray!");
377 return;
378 }
379
380 prayer_ability = pstats.s_lvl * pstats.s_wisdom;
381 if (player.t_ctype != C_CLERIC)
382 prayer_ability /= 3;
383
384 if (cur_relic[HEIL_ANKH]) prayer_ability *= 2;
385
386 if (player.t_action != C_PRAY) {
387 num_prayers = 0;
388
389 /* Get the number of avilable prayers */
390 if (pstats.s_wisdom > 16)
391 num_prayers += (pstats.s_wisdom - 15) / 2;
392
393 num_prayers += pstats.s_lvl;
394 if (cur_relic[HEIL_ANKH]) num_prayers += 3;
395
396 if (player.t_ctype != C_CLERIC)
397 num_prayers /= 3;
398
399 if (num_prayers > MAXPRAYERS)
400 num_prayers = MAXPRAYERS;
401 if (num_prayers < 1) {
402 msg("You are not permitted to pray yet.");
403 return;
404 }
405
406 /* Prompt for prayer */
407 if (pick_spell( cleric_spells,
408 prayer_ability,
409 num_prayers,
410 pray_time,
411 "offer",
412 "prayer"))
413 player.t_action = C_PRAY;
414
415 return;
416 }
417
418 /* We've waited our required praying time. */
419 which_prayer = player.t_selection;
420 player.t_selection = 0;
421 player.t_using = NULL;
422 player.t_action = A_NIL;
423
424 if (cleric_spells[which_prayer].s_cost + pray_time > prayer_ability) {
425 msg("Your prayer fails.");
426 return;
427 }
428
429 msg("Your prayer has been granted.");
430
431 if (cleric_spells[which_prayer].s_type == TYP_POTION)
432 quaff( cleric_spells[which_prayer].s_which,
433 NULL,
434 cleric_spells[which_prayer].s_flag,
435 FALSE);
436 else if (cleric_spells[which_prayer].s_type == TYP_SCROLL)
437 read_scroll( cleric_spells[which_prayer].s_which,
438 cleric_spells[which_prayer].s_flag,
439 FALSE);
440 else if (cleric_spells[which_prayer].s_type == TYP_STICK) {
441 if (!player_zap(cleric_spells[which_prayer].s_which,
442 cleric_spells[which_prayer].s_flag)) {
443 after = FALSE;
444 return;
445 }
446 }
447 pray_time += cleric_spells[which_prayer].s_cost;
448 }
449
450
451
452 /*
453 * steal:
454 * Steal in direction given in delta
455 */
456
457 steal()
458 {
459 register struct linked_list *item;
460 register struct thing *tp;
461 register char *mname;
462 coord new_pos;
463 int thief_bonus = -50;
464 bool isinvisible = FALSE;
465
466 if (player.t_ctype != C_THIEF && player.t_ctype != C_ASSASIN) {
467 msg("Only thieves and assassins can steal.");
468 return;
469 }
470 if (on(player, ISBLIND)) {
471 msg("You can't see anything.");
472 return;
473 }
474
475 new_pos.y = hero.y + player.t_newpos.y;
476 new_pos.x = hero.x + player.t_newpos.x;
477
478 /* Anything there? */
479 if (new_pos.y < 0 || new_pos.y > lines-3 ||
480 new_pos.x < 0 || new_pos.x > cols-1 ||
481 mvwinch(mw, new_pos.y, new_pos.x) == ' ') {
482 msg("Nothing to steal from.");
483 return;
484 }
485
486 if ((item = find_mons(new_pos.y, new_pos.x)) == NULL)
487 debug("Steal from what @ %d,%d?", new_pos.y, new_pos.x);
488 tp = THINGPTR(item);
489 if (on(*tp, ISSTONE)) {
490 msg ("You can't steal from stone!");
491 return;
492 }
493 if (isinvisible = invisible(tp)) mname = "creature";
494 else mname = monster_name(tp);
495
496 /* Can player steal something unnoticed? */
497 if (player.t_ctype == C_THIEF) thief_bonus = 10;
498 if (player.t_ctype == C_ASSASIN) thief_bonus = 0;
499 if (on(*tp, ISUNIQUE)) thief_bonus -= 15;
500 if (isinvisible) thief_bonus -= 20;
501 if (on(*tp, ISINWALL) && off(player, CANINWALL)) thief_bonus -= 50;
502
503 if (on(*tp, ISHELD) || tp->t_action == A_FREEZE ||
504 rnd(100) <
505 (thief_bonus + 2*dex_compute() + 5*pstats.s_lvl -
506 5*(tp->t_stats.s_lvl - 3))) {
507 register struct linked_list *s_item, *pack_ptr;
508 int count = 0;
509 unsigned long test; /* Overflow check */
510
511 s_item = NULL; /* Start stolen goods out as nothing */
512
513 /* Find a good item to take */
514 for (pack_ptr=tp->t_pack; pack_ptr != NULL; pack_ptr=next(pack_ptr))
515 if ((OBJPTR(pack_ptr))->o_type != RELIC &&
516 pack_ptr != tp->t_using && /* Monster can't be using it */
517 rnd(++count) == 0)
518 s_item = pack_ptr;
519
520 /*
521 * Find anything?
522 */
523 if (s_item == NULL) {
524 msg("%s apparently has nothing to steal.", prname(mname, TRUE));
525 return;
526 }
527
528 /* Take it from monster */
529 if (tp->t_pack) detach(tp->t_pack, s_item);
530
531 /* Recalculate the monster's encumberance */
532 updpack(TRUE, tp);
533
534 /* Give it to player */
535 if (add_pack(s_item, FALSE, NULL) == FALSE) {
536 (OBJPTR(s_item))->o_pos = hero;
537 fall(s_item, TRUE);
538 }
539
540 /* Get points for stealing -- but first check for overflow */
541 test = pstats.s_exp + tp->t_stats.s_exp/2;
542 if (test > pstats.s_exp) pstats.s_exp = test;
543
544 /*
545 * Do adjustments if player went up a level
546 */
547 check_level();
548 }
549
550 else {
551 msg("Your attempt fails.");
552
553 /* Annoy monster (maybe) */
554 if (rnd(35) >= dex_compute() + thief_bonus) {
555 /*
556 * If this is a charmed creature, there is a chance it
557 * will become uncharmed.
558 */
559 if (on(*tp, ISCHARMED) && save(VS_MAGIC, tp, 0)) {
560 msg("The eyes of %s turn clear.", prname(mname, FALSE));
561 turn_off(*tp, ISCHARMED);
562 }
563 if (on(*tp, CANSELL)) {
564 turn_off(*tp, CANSELL);
565 tp->t_action = A_NIL;
566 tp->t_movement = 0;
567 if (rnd(100) < 50) /* make him steal something */
568 turn_on(*tp, STEALMAGIC);
569 else
570 turn_on(*tp, STEALGOLD);
571 if (!isinvisible)
572 msg("%s looks insulted.", prname(mname, TRUE));
573 }
574 runto(tp, &hero);
575 }
576 }
577 }
578
579 #ifdef PC7300
580 /* Use MAXSPELLS or whatever is the biggest number of spells/prayers/etc */
581 static menu_t Display; /* The menu structure */
582 static mitem_t Dispitems[MAXSPELLS+1]; /* Info for each line */
583 static char Displines[MAXSPELLS+1][LINELEN+1]; /* The lines themselves */
584 #endif
585
586 /*
587 * this routine lets the player pick the spell that they
588 * want to cast regardless of character class
589 */
590 pick_spell(spells, ability, num_spells, power, prompt, type)
591 struct spells spells[]; /* spell list */
592 int ability; /* spell ability */
593 int num_spells; /* number of spells that can be cast */
594 int power; /* spell power */
595 char *prompt; /* prompt for spell list */
596 char *type; /* type of thing--> spell, prayer, chant */
597 {
598 bool nohw = FALSE;
599 register int i;
600 int curlen,
601 maxlen,
602 dummy,
603 which_spell,
604 spell_left;
605 #ifdef PC7300
606 char label[LINELEN], /* For menu label */
607 title[LINELEN]; /* For menu title */
608 #endif
609
610 if (cur_misc[WEAR_CLOAK] != NULL &&
611 cur_misc[WEAR_CLOAK]->o_which == MM_R_POWERLESS) {
612 msg("You can't seem to start a %s!", type);
613 return(FALSE);
614 }
615
616 /* Prompt for spells */
617 msg("Which %s are you %sing? (* for list): ", type, prompt);
618
619 which_spell = (int) (readchar() - 'a');
620 msg(""); /* Get rid of the prompt */
621 if (which_spell == (int) ESCAPE - (int) 'a') {
622 after = FALSE;
623 return(FALSE);
624 }
625 if (which_spell >= 0 && which_spell < num_spells) nohw = TRUE;
626
627 else if (slow_invent) {
628 register char c;
629
630 nohw = TRUE;
631 do {
632 for (i=0; i<num_spells; i++) {
633 msg("");
634 mvwaddch(msgw, 0, 0, '[');
635 waddch(msgw, (char) ((int) 'a' + i));
636 wprintw(msgw, "] A %s of ", type);
637 if (spells[i].s_type == TYP_POTION)
638 waddstr(msgw, p_magic[spells[i].s_which].mi_name);
639 else if (spells[i].s_type == TYP_SCROLL)
640 waddstr(msgw, s_magic[spells[i].s_which].mi_name);
641 else if (spells[i].s_type == TYP_STICK)
642 waddstr(msgw, ws_magic[spells[i].s_which].mi_name);
643 waddstr(msgw, morestr);
644 wclrtobot(msgw);
645 clearok(msgw, FALSE);
646 draw(msgw);
647 do {
648 c = readchar();
649 } while (c != ' ' && c != ESCAPE);
650 if (c == ESCAPE)
651 break;
652 }
653 msg("");
654 wmove(msgw, 0, 0);
655 wprintw(msgw, "Which %s are you %sing? ", type, prompt);
656 clearok(msgw, FALSE);
657 draw(msgw);
658
659 which_spell = (int) (readchar() - 'a');
660 } while (which_spell != (int) (ESCAPE - 'a') &&
661 (which_spell < 0 || which_spell >= num_spells));
662
663 if (which_spell == (int) (ESCAPE - 'a')) {
664 mpos = 0;
665 msg("");
666 after = FALSE;
667 return(FALSE);
668 }
669 }
670 else {
671 /* Now display the possible spells */
672 wclear(hw);
673 touchwin(hw);
674 wmove(hw, 2, 0);
675 *type = toupper(*type);
676 wprintw(hw, " Cost %s", type);
677 *type = tolower(*type);
678 mvwaddstr(hw, 3, 0,
679 "-----------------------------------------------");
680 maxlen = 47; /* Maximum width of header */
681
682 for (i=0; i<num_spells; i++) {
683 sprintf(prbuf, "[%c] %3d A %s of ",
684 (char) ((int) 'a' + i), spells[i].s_cost, type);
685 if (spells[i].s_type == TYP_POTION)
686 strcat(prbuf, p_magic[spells[i].s_which].mi_name);
687 else if (spells[i].s_type == TYP_SCROLL)
688 strcat(prbuf, s_magic[spells[i].s_which].mi_name);
689 else if (spells[i].s_type == TYP_STICK)
690 strcat(prbuf, ws_magic[spells[i].s_which].mi_name);
691 mvwaddstr(hw, i+4, 0, prbuf);
692
693 /* Get the length of the line */
694 getyx(hw, dummy, curlen);
695 if (maxlen < curlen) maxlen = curlen;
696
697 #ifdef PC7300
698 /* Put it into the PC menu display */
699 strcpy(Displines[i], prbuf);
700 Dispitems[i].mi_name = Displines[i];
701 Dispitems[i].mi_flags = 0;
702 Dispitems[i].mi_val = i;
703 #endif
704 }
705
706 spell_left = ability - power;
707 if (spell_left < 0) {
708 spell_left = 0;
709 if (spell_left < -20) power = ability + 20;
710 }
711 sprintf(prbuf, "[Current %s power = %d]", type, spell_left);
712
713 mvwaddstr(hw, 0, 0, prbuf);
714 wprintw(hw, " Which %s are you %sing? ", type, prompt);
715 getyx(hw, dummy, curlen);
716 if (maxlen < curlen) maxlen = curlen;
717
718 #ifdef PC7300
719 /* Place an end marker for the items */
720 Dispitems[num_spells].mi_name = 0;
721
722 /* Design prompts */
723 sprintf(label, "Current %s power is %d", type, spell_left);
724 *type = toupper(*type);
725 sprintf(title, " Cost %s", type);
726 *type = tolower(*type);
727 sprintf(prbuf, "Select a %s or press Cancl to continue.", type);
728
729 /* Set up the main menu structure */
730 Display.m_label = label;
731 Display.m_title = title;
732 Display.m_prompt = prbuf;
733 Display.m_curptr = '\0';
734 Display.m_markptr = '\0';
735 Display.m_flags = M_ASISTITLE;
736 Display.m_selcnt = 1;
737 Display.m_items = Dispitems;
738 Display.m_curi = 0;
739
740 /*
741 * Try to display the menu. If we don't have a local terminal,
742 * the call will fail and we will just continue with the
743 * normal mode.
744 */
745 if (menu(&Display) >= 0) {
746 if (Display.m_selcnt == 0) {
747 /* Menu was cancelled */
748 after = FALSE;
749 return FALSE; /* all done if abort */
750 }
751 else which_spell = (int) Display.m_curi->mi_val;
752 goto got_spell;
753 }
754 #endif
755 /* Should we overlay? */
756 if (menu_overlay && num_spells + 3 < lines / 2) {
757 over_win(cw, hw, num_spells + 5, maxlen + 3, 0, curlen, NULL);
758 }
759 else draw(hw);
760 }
761
762 if (!nohw) {
763 which_spell = (int) (readchar() - 'a');
764 while (which_spell < 0 || which_spell >= num_spells) {
765 if (which_spell == (int) ESCAPE - (int) 'a') {
766 after = FALSE;
767
768 /* Restore the screen */
769 touchwin(cw);
770 if (num_spells + 3 < lines / 2) clearok(cw, FALSE);
771 else clearok(cw, TRUE);
772 return(FALSE);
773 }
774 wmove(hw, 0, 0);
775 wclrtoeol(hw);
776 wprintw(hw, "Please enter one of the listed %ss. ", type);
777 getyx(hw, dummy, curlen);
778 if (maxlen < curlen) maxlen = curlen;
779
780 /* Should we overlay? */
781 if (menu_overlay && num_spells + 3 < lines / 2) {
782 over_win(cw, hw, num_spells + 5, maxlen + 3,
783 0, curlen, NULL);
784 }
785 else draw(hw);
786
787 which_spell = (int) (readchar() - 'a');
788 }
789 }
790
791 /* Now restore the screen if we have to */
792 if (!nohw) {
793 touchwin(cw);
794 if (num_spells + 3 < lines / 2) clearok(cw, FALSE);
795 else clearok(cw, TRUE);
796 }
797
798 #ifdef PC7300
799 got_spell:
800 #endif
801 if (spells[which_spell].s_type == TYP_STICK &&
802 need_dir(STICK, spells[which_spell].s_which)) {
803 if (!get_dir(&player.t_newpos)) {
804 after = FALSE;
805 return(FALSE);
806 }
807 }
808 player.t_selection = which_spell;
809 player.t_using = NULL;
810 player.t_no_move = (which_spell/3 + 1) * movement(&player);
811 return(TRUE);
812 }