Annotation of early-roguelike/arogue5/player.c, Revision 1.1.1.1
1.1 rubenllo 1: /*
2: * This file contains functions for dealing with special player abilities
3: *
4: * Advanced Rogue
5: * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
6: * All rights reserved.
7: *
8: * See the file LICENSE.TXT for full copyright and licensing information.
9: */
10:
11: #include "curses.h"
12: #include "rogue.h"
13:
14:
15: /*
16: * affect:
17: * cleric affecting undead
18: */
19:
20: void
21: affect(void)
22: {
23: register struct linked_list *item;
24: register struct thing *tp;
25: register const char *mname;
26: bool see;
27: coord new_pos;
28:
29: if (player.t_ctype != C_CLERIC && cur_relic[HEIL_ANKH] == 0) {
30: msg("Only clerics can affect undead.");
31: return;
32: }
33:
34: new_pos.y = hero.y + delta.y;
35: new_pos.x = hero.x + delta.x;
36:
37: if (cansee(new_pos.y, new_pos.x)) see = TRUE;
38: else see = FALSE;
39:
40: /* Anything there? */
41: if (new_pos.y < 0 || new_pos.y > LINES-3 ||
42: new_pos.x < 0 || new_pos.x > COLS-1 ||
43: mvwinch(mw, new_pos.y, new_pos.x) == ' ') {
44: msg("Nothing to affect.");
45: return;
46: }
47:
48: if ((item = find_mons(new_pos.y, new_pos.x)) == NULL) {
49: debug("Affect what @ %d,%d?", new_pos.y, new_pos.x);
50: return;
51: }
52: tp = THINGPTR(item);
53: mname = monsters[tp->t_index].m_name;
54:
55: if (on(player, ISINVIS) && off(*tp, CANSEE)) {
56: sprintf(outstring,"%s%s cannot see you", see ? "The " : "It",
57: see ? mname : "");
58: msg(outstring);
59: return;
60: }
61:
62: if (off(*tp, TURNABLE) || on(*tp, WASTURNED))
63: goto annoy;
64: turn_off(*tp, TURNABLE);
65:
66: /* Can cleric kill it? */
67: if (pstats.s_lvl >= 3 * tp->t_stats.s_lvl) {
68: unsigned long test; /* For overflow check */
69:
70: sprintf(outstring,"You have destroyed %s%s.", see ? "the " : "it", see ? mname : "");
71: msg(outstring);
72: test = pstats.s_exp + tp->t_stats.s_exp;
73:
74: /* Be sure there is no overflow before increasing experience */
75: if (test > pstats.s_exp) pstats.s_exp = test;
76: killed(item, FALSE, TRUE);
77: check_level(TRUE);
78: return;
79: }
80:
81: /* Can cleric turn it? */
82: if (rnd(100) + 1 >
83: (100 * ((2 * tp->t_stats.s_lvl) - pstats.s_lvl)) / pstats.s_lvl) {
84: unsigned long test; /* Overflow test */
85:
86: /* Make the monster flee */
87: turn_on(*tp, WASTURNED); /* No more fleeing after this */
88: turn_on(*tp, ISFLEE);
89: runto(tp, &hero);
90:
91: /* Let player know */
92: sprintf(outstring,"You have turned %s%s.", see ? "the " : "it", see ? mname : "");
93: msg(outstring);
94:
95: /* get points for turning monster -- but check overflow first */
96: test = pstats.s_exp + tp->t_stats.s_exp/2;
97: if (test > pstats.s_exp) pstats.s_exp = test;
98: check_level(TRUE);
99:
100: /* If monster was suffocating, stop it */
101: if (on(*tp, DIDSUFFOCATE)) {
102: turn_off(*tp, DIDSUFFOCATE);
103: extinguish(suffocate);
104: }
105:
106: /* If monster held us, stop it */
107: if (on(*tp, DIDHOLD) && (--hold_count == 0))
108: turn_off(player, ISHELD);
109: turn_off(*tp, DIDHOLD);
110: return;
111: }
112:
113: /* Otherwise -- no go */
114: annoy:
115: sprintf(outstring,"You do not affect %s%s.", see ? "the " : "it", see ? mname : "");
116: msg(outstring);
117:
118: /* Annoy monster */
119: if (off(*tp, ISFLEE)) runto(tp, &hero);
120: }
121:
122: /*
123: * the magic user is going to try and cast a spell
124: */
125: void
126: cast(void)
127: {
128: register int i, num_spells, spell_ability;
129: int which_spell;
130: bool nohw = FALSE;
131:
132: i = num_spells = spell_ability = which_spell = 0;
133:
134: if (player.t_ctype != C_MAGICIAN && pstats.s_intel < 16) {
135: msg("You are not permitted to cast spells.");
136: return;
137: }
138: if (cur_misc[WEAR_CLOAK] != NULL &&
139: cur_misc[WEAR_CLOAK]->o_which == MM_R_POWERLESS) {
140: msg("You can't seem to cast a spell!");
141: return;
142: }
143: num_spells = 0;
144:
145: /* Get the number of avilable spells */
146: if (pstats.s_intel >= 16)
147: num_spells = pstats.s_intel - 15;
148:
149: if (player.t_ctype == C_MAGICIAN)
150: num_spells += pstats.s_lvl;
151:
152: if (num_spells > MAXSPELLS)
153: num_spells = MAXSPELLS;
154:
155: spell_ability = pstats.s_lvl * pstats.s_intel;
156: if (player.t_ctype != C_MAGICIAN)
157: spell_ability /= 2;
158:
159: /* Prompt for spells */
160: msg("Which spell are you casting? (* for list): ");
161:
162: which_spell = (int) (readchar() - 'a');
163: if (which_spell == (int) ESCAPE - (int) 'a') {
164: mpos = 0;
165: msg("");
166: after = FALSE;
167: return;
168: }
169: if (which_spell >= 0 && which_spell < num_spells) nohw = TRUE;
170:
171: else if (slow_invent) {
172: register char c;
173: char *spellp = "";
174:
175: for (i=0; i<num_spells; i++) {
176: msg("");
177: if (magic_spells[i].s_type == TYP_POTION)
178: spellp = p_magic[magic_spells[i].s_which].mi_name;
179: else if (magic_spells[i].s_type == TYP_SCROLL)
180: spellp = s_magic[magic_spells[i].s_which].mi_name;
181: else if (magic_spells[i].s_type == TYP_STICK)
182: spellp = ws_magic[magic_spells[i].s_which].mi_name;
183: mvwprintw(msgw, 0, 0, "[%c] A spell of %s", (char) ((int) 'a' + i),
184: spellp);
185: waddstr(msgw, morestr);
186: draw(msgw);
187: do {
188: c = readchar();
189: } while (c != ' ' && c != ESCAPE);
190: if (c == ESCAPE)
191: break;
192: }
193: msg("");
194: mvwaddstr(msgw, 0, 0, "Which spell are you casting? ");
195: draw(msgw);
196: }
197: else {
198: /* Set up for redraw */
199: msg("");
200: clearok(cw, TRUE);
201: touchwin(cw);
202:
203: /* Now display the possible spells */
204: wclear(hw);
205: touchwin(hw);
206: mvwaddstr(hw, 2, 0, " Cost Spell");
207: mvwaddstr(hw, 3, 0, "-----------------------------------------------");
208: for (i=0; i<num_spells; i++) {
209: mvwaddch(hw, i+4, 0, '[');
210: waddch(hw, (char) ((int) 'a' + i));
211: waddch(hw, ']');
212: sprintf(prbuf, " %3d", magic_spells[i].s_cost);
213: waddstr(hw, prbuf);
214: waddstr(hw, " A spell of ");
215: if (magic_spells[i].s_type == TYP_POTION)
216: waddstr(hw, p_magic[magic_spells[i].s_which].mi_name);
217: else if (magic_spells[i].s_type == TYP_SCROLL)
218: waddstr(hw, s_magic[magic_spells[i].s_which].mi_name);
219: else if (magic_spells[i].s_type == TYP_STICK)
220: waddstr(hw, ws_magic[magic_spells[i].s_which].mi_name);
221: }
222: sprintf(prbuf,"[Current spell power = %d]",spell_ability - spell_power);
223: mvwaddstr(hw, 0, 0, prbuf);
224: waddstr(hw, " Which spell are you casting? ");
225: draw(hw);
226: }
227:
228: if (!nohw) {
229: which_spell = (int) (wgetch(hw) - 'a');
230: while (which_spell < 0 || which_spell >= num_spells) {
231: if (which_spell == (int) ESCAPE - (int) 'a') {
232: after = FALSE;
233: return;
234: }
235: wmove(hw, 0, 0);
236: wclrtoeol(hw);
237: waddstr(hw, "Please enter one of the listed spells. ");
238: draw(hw);
239: which_spell = (int) (wgetch(hw) - 'a');
240: }
241: }
242:
243: if ((spell_power + magic_spells[which_spell].s_cost) > spell_ability) {
244: msg("Your attempt fails.");
245: return;
246: }
247: if (nohw)
248: msg("Your spell is successful.");
249: else {
250: mvwaddstr(hw, 0, 0, "Your spell is successful.--More--");
251: wclrtoeol(hw);
252: draw(hw);
253: wait_for(hw,' ');
254: }
255: if (magic_spells[which_spell].s_type == TYP_POTION)
256: quaff( magic_spells[which_spell].s_which,
257: magic_spells[which_spell].s_flag,
258: FALSE);
259: else if (magic_spells[which_spell].s_type == TYP_SCROLL)
260: read_scroll( magic_spells[which_spell].s_which,
261: magic_spells[which_spell].s_flag,
262: FALSE);
263: else if (magic_spells[which_spell].s_type == TYP_STICK) {
264: if (!do_zap( TRUE,
265: magic_spells[which_spell].s_which,
266: magic_spells[which_spell].s_flag)) {
267: after = FALSE;
268: return;
269: }
270: }
271: spell_power += magic_spells[which_spell].s_cost;
272: }
273:
274: /* Constitution bonus */
275:
276: int
277: const_bonus(void) /* Hit point adjustment for changing levels */
278: {
279: if (pstats.s_const > 6 && pstats.s_const <= 14)
280: return(0);
281: if (pstats.s_const > 14)
282: return(pstats.s_const-14);
283: if (pstats.s_const > 3)
284: return(-1);
285: return(-2);
286: }
287:
288:
289: /* Routines for thieves */
290:
291: /*
292: * gsense:
293: * Sense gold
294: */
295:
296: void
297: gsense(void)
298: {
299: /* Only thieves can do this */
300: if (player.t_ctype != C_THIEF) {
301: msg("You seem to have no gold sense.");
302: return;
303: }
304:
305: if (lvl_obj != NULL) {
306: struct linked_list *gitem;
307: struct object *cur;
308: int gtotal = 0;
309:
310: wclear(hw);
311: for (gitem = lvl_obj; gitem != NULL; gitem = next(gitem)) {
312: cur = OBJPTR(gitem);
313: if (cur->o_type == GOLD) {
314: gtotal += cur->o_count;
315: mvwaddch(hw, cur->o_pos.y, cur->o_pos.x, GOLD);
316: }
317: }
318: if (gtotal) {
319: s_know[S_GFIND] = TRUE;
320: msg("You sense gold!");
321: overlay(hw,cw);
322: return;
323: }
324: }
325: msg("You can sense no gold on this level.");
326: }
327:
328: /*
329: * the cleric asks his deity for a spell
330: */
331: void
332: pray(void)
333: {
334: register int i, num_prayers, prayer_ability;
335: int which_prayer;
336: bool nohw = FALSE;
337:
338: which_prayer = num_prayers = prayer_ability = i = 0;
339:
340: if (player.t_ctype != C_CLERIC && pstats.s_wisdom < 17 &&
341: cur_relic[HEIL_ANKH] == 0) {
342: msg("You are not permitted to pray.");
343: return;
344: }
345: if (cur_misc[WEAR_CLOAK] != NULL &&
346: cur_misc[WEAR_CLOAK]->o_which == MM_R_POWERLESS) {
347: msg("You can't seem to pray!");
348: return;
349: }
350: num_prayers = 0;
351:
352: /* Get the number of avilable prayers */
353: if (pstats.s_wisdom > 16)
354: num_prayers = (pstats.s_wisdom - 15) / 2;
355:
356: if (player.t_ctype == C_CLERIC)
357: num_prayers += pstats.s_lvl;
358:
359: if (cur_relic[HEIL_ANKH]) num_prayers += 3;
360:
361: if (num_prayers > MAXPRAYERS)
362: num_prayers = MAXPRAYERS;
363:
364: prayer_ability = pstats.s_lvl * pstats.s_wisdom;
365: if (player.t_ctype != C_CLERIC)
366: prayer_ability /= 2;
367:
368: if (cur_relic[HEIL_ANKH]) prayer_ability *= 2;
369:
370: /* Prompt for prayer */
371: msg("Which prayer are you offering? (* for list): ");
372: which_prayer = (int) (readchar() - 'a');
373: if (which_prayer == (int) ESCAPE - (int) 'a') {
374: mpos = 0;
375: msg("");
376: after = FALSE;
377: return;
378: }
379: if (which_prayer >= 0 && which_prayer < num_prayers) nohw = TRUE;
380:
381: else if (slow_invent) {
382: register char c;
383: char *prayerp = "";
384:
385: for (i=0; i<num_prayers; i++) {
386: msg("");
387: if (cleric_spells[i].s_type == TYP_POTION)
388: prayerp = p_magic[cleric_spells[i].s_which].mi_name;
389: else if (cleric_spells[i].s_type == TYP_SCROLL)
390: prayerp = s_magic[cleric_spells[i].s_which].mi_name;
391: else if (cleric_spells[i].s_type == TYP_STICK)
392: prayerp = ws_magic[cleric_spells[i].s_which].mi_name;
393: mvwprintw(msgw, 0, 0, "[%c] A prayer for %s",
394: (char) ((int) 'a' + i), prayerp);
395: waddstr(msgw, morestr);
396: draw(msgw);
397: do {
398: c = readchar();
399: } while (c != ' ' && c != ESCAPE);
400: if (c == ESCAPE)
401: break;
402: }
403: msg("");
404: mvwaddstr(msgw, 0, 0, "Which prayer are you offering? ");
405: draw(msgw);
406: }
407: else {
408: /* Set up for redraw */
409: msg("");
410: clearok(cw, TRUE);
411: touchwin(cw);
412:
413: /* Now display the possible prayers */
414: wclear(hw);
415: touchwin(hw);
416: mvwaddstr(hw, 2, 0, " Cost Prayer");
417: mvwaddstr(hw, 3, 0, "-----------------------------------------------");
418: for (i=0; i<num_prayers; i++) {
419: mvwaddch(hw, i+4, 0, '[');
420: waddch(hw, (char) ((int) 'a' + i));
421: waddch(hw, ']');
422: sprintf(prbuf, " %3d", cleric_spells[i].s_cost);
423: waddstr(hw, prbuf);
424: waddstr(hw, " A prayer for ");
425: if (cleric_spells[i].s_type == TYP_POTION)
426: waddstr(hw, p_magic[cleric_spells[i].s_which].mi_name);
427: else if (cleric_spells[i].s_type == TYP_SCROLL)
428: waddstr(hw, s_magic[cleric_spells[i].s_which].mi_name);
429: else if (cleric_spells[i].s_type == TYP_STICK)
430: waddstr(hw, ws_magic[cleric_spells[i].s_which].mi_name);
431: }
432: sprintf(prbuf,"[Current prayer ability = %d]",prayer_ability-pray_time);
433: mvwaddstr(hw, 0, 0, prbuf);
434: waddstr(hw, " Which prayer are you offering? ");
435: draw(hw);
436: }
437:
438: if (!nohw) {
439: which_prayer = (int) (wgetch(hw) - 'a');
440: while (which_prayer < 0 || which_prayer >= num_prayers) {
441: if (which_prayer == (int) ESCAPE - (int) 'a') {
442: after = FALSE;
443: return;
444: }
445: wmove(hw, 0, 0);
446: wclrtoeol(hw);
447: mvwaddstr(hw, 0, 0, "Please enter one of the listed prayers.");
448: draw(hw);
449: which_prayer = (int) (wgetch(hw) - 'a');
450: }
451: }
452:
453:
454: if (cleric_spells[which_prayer].s_cost + pray_time > prayer_ability) {
455: msg("Your prayer fails.");
456: return;
457: }
458:
459: if (nohw) {
460: msg("Your prayer has been granted.--More--");
461: wait_for(msgw,' ');
462: msg("");
463: }
464: else {
465: mvwaddstr(hw, 0, 0, "Your prayer has been granted.--More--");
466: wclrtoeol(hw);
467: draw(hw);
468: wait_for(hw,' ');
469: }
470: if (cleric_spells[which_prayer].s_type == TYP_POTION)
471: quaff( cleric_spells[which_prayer].s_which,
472: cleric_spells[which_prayer].s_flag,
473: FALSE);
474: else if (cleric_spells[which_prayer].s_type == TYP_SCROLL)
475: read_scroll( cleric_spells[which_prayer].s_which,
476: cleric_spells[which_prayer].s_flag,
477: FALSE);
478: else if (cleric_spells[which_prayer].s_type == TYP_STICK) {
479: if (!do_zap( TRUE,
480: cleric_spells[which_prayer].s_which,
481: cleric_spells[which_prayer].s_flag)) {
482: after = FALSE;
483: return;
484: }
485: }
486: pray_time += cleric_spells[which_prayer].s_cost;
487: }
488:
489:
490:
491: /*
492: * steal:
493: * Steal in direction given in delta
494: */
495:
496: void
497: steal(void)
498: {
499: register struct linked_list *item;
500: register struct thing *tp;
501: register const char *mname;
502: coord new_pos;
503: int thief_bonus = -50;
504: bool isinvisible = FALSE;
505:
506: new_pos.y = hero.y + delta.y;
507: new_pos.x = hero.x + delta.x;
508:
509: if (on(player, ISBLIND)) {
510: msg("You can't see anything.");
511: return;
512: }
513:
514: /* Anything there? */
515: if (new_pos.y < 0 || new_pos.y > LINES-3 ||
516: new_pos.x < 0 || new_pos.x > COLS-1 ||
517: mvwinch(mw, new_pos.y, new_pos.x) == ' ') {
518: msg("Nothing to steal from.");
519: return;
520: }
521:
522: if ((item = find_mons(new_pos.y, new_pos.x)) == NULL)
523: debug("Steal from what @ %d,%d?", new_pos.y, new_pos.x);
524: tp = THINGPTR(item);
525: if (isinvisible = invisible(tp)) mname = "creature";
526: else mname = monsters[tp->t_index].m_name;
527:
528: /* Can player steal something unnoticed? */
529: if (player.t_ctype == C_THIEF) thief_bonus = 10;
530: if (on(*tp, ISUNIQUE)) thief_bonus -= 15;
531: if (isinvisible) thief_bonus -= 20;
532: if (on(*tp, ISINWALL) && off(player, CANINWALL)) thief_bonus -= 50;
533:
534: if (rnd(100) <
535: (thief_bonus + 2*dex_compute() + 5*pstats.s_lvl -
536: 5*(tp->t_stats.s_lvl - 3))) {
537: register struct linked_list *s_item, *pack_ptr;
538: int count = 0;
539: unsigned long test; /* Overflow check */
540:
541: s_item = NULL; /* Start stolen goods out as nothing */
542:
543: /* Find a good item to take */
544: for (pack_ptr=tp->t_pack; pack_ptr != NULL; pack_ptr=next(pack_ptr))
545: if ((OBJPTR(pack_ptr))->o_type != RELIC &&
546: rnd(++count) == 0)
547: s_item = pack_ptr;
548:
549: /*
550: * Find anything?
551: *
552: * if we have a merchant, and his pack is empty then the
553: * rogue has already stolen once
554: */
555: if (s_item == NULL) {
556: if (tp->t_index == NUMMONST)
557: msg("The %s seems to be shielding his pack from you.", mname);
558: else
559: msg("The %s apparently has nothing to steal.", mname);
560: return;
561: }
562:
563: /* Take it from monster */
564: if (tp->t_pack) detach(tp->t_pack, s_item);
565:
566: /* Give it to player */
567: if (add_pack(s_item, FALSE, NULL) == FALSE) {
568: (OBJPTR(s_item))->o_pos = hero;
569: fall(s_item, TRUE);
570: }
571:
572: /* Get points for stealing -- but first check for overflow */
573: test = pstats.s_exp + tp->t_stats.s_exp/2;
574: if (test > pstats.s_exp) pstats.s_exp = test;
575:
576: /*
577: * Do adjustments if player went up a level
578: */
579: check_level(TRUE);
580: }
581:
582: else {
583: msg("Your attempt fails.");
584:
585: /* Annoy monster (maybe) */
586: if (rnd(35) >= dex_compute() + thief_bonus) {
587: if (tp->t_index == NUMMONST) {
588: if (!isinvisible)
589: msg("The %s looks insulted and leaves", mname);
590: killed(item, FALSE, FALSE);
591: }
592: else
593: runto(tp, &hero);
594: }
595: }
596: }
CVSweb