Mercurial > hg > early-roguelike
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 } |