Annotation of early-roguelike/urogue/player.c, Revision 1.1.1.1
1.1 rubenllo 1: /*
2: player.c - functions for dealing with special player abilities
3:
4: UltraRogue: The Ultimate Adventure in the Dungeons of Doom
5: Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong
6: All rights reserved.
7:
8: Based on "Advanced Rogue"
9: Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka
10: All rights reserved.
11:
12: Based on "Rogue: Exploring the Dungeons of Doom"
13: Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
14: All rights reserved.
15:
16: See the file LICENSE.TXT for full copyright and licensing information.
17: */
18:
19: #include <stdlib.h>
20: #include <ctype.h>
21: #include "rogue.h"
22:
23: /*
24: * Pray to a deity
25: *
26: * 00-10 Good stuff happens
27: * 11-40 A good deity answers
28: * 41-60 Nothing happens
29: * 61-90 A bad deity answers, but with good results
30: * 91-99 You were better off before
31: */
32:
33: void
34: prayer(void)
35: {
36: int chance, i, times;
37: char num_str[20];
38: int ch;
39: struct linked_list *item;
40: struct thing *tp;
41: int is_godly;
42:
43: if (player.t_praycnt > pstats.s_lvl)
44: {
45: msg("Are you sure you want to bother the gods?");
46: ch = readchar();
47:
48: if (tolower(ch) != 'y')
49: {
50: after = FALSE;
51: return;
52: }
53: else
54: msg("Here goes...");
55: }
56:
57: msg("You are surrounded by orange smoke...");
58:
59: if (rnd(3) == 0)
60: luck--;
61:
62: if (is_wearing(R_PIETY) || (rnd(luck) == 0 &&
63: (player.t_ctype == C_DRUID || player.t_ctype == C_CLERIC ||
64: ((player.t_ctype == C_PALADIN || player.t_ctype == C_RANGER)
65: && pstats.s_lvl > 8))))
66: is_godly = ISBLESSED;
67: else
68: is_godly = ISNORMAL;
69:
70: if (is_wearing(R_PIETY))
71: player.t_praycnt += rnd(2);
72: else
73: player.t_praycnt++;
74:
75: if (wizard)
76: {
77: msg("What roll?[0..%d] ", 99);
78: ch = get_string(num_str, cw);
79:
80: if (ch == QUIT)
81: {
82: msg("");
83: return;
84: }
85: chance = atoi(num_str);
86: }
87: else
88: {
89: chance = rnd(100) + roll(10, luck) - 5;
90:
91: if (player.t_praycnt > pstats.s_lvl)
92: chance += 50;
93:
94: if (is_godly)
95: chance -= 50;
96: }
97:
98: chance = max(0, min(chance, 100));
99:
100: if (chance == 0)
101: {
102: msg("The heavens open and glorious radiance surrounds you!");
103:
104: pstats.s_hpt = max_stats.s_hpt;
105: pstats.s_power = max_stats.s_power;
106:
107: if (is_godly)
108: times = 8;
109: else
110: times = 1;
111:
112: /*
113: * kill all monsters surrounding the hero except unique ones
114: * This will change when I implement the deity option. If
115: * The deity is "stronger" than the unique monster, then the
116: * monster will be killed.
117: */
118:
119: for (i = 0; i < times; i++)
120: {
121: item = f_mons_a(player.t_pos.y, player.t_pos.x, TRUE);
122:
123: if (item)
124: {
125: tp = THINGPTR(item);
126:
127: msg("A bolt of eldritch energy strikes down the %s!",
128: monsters[tp->t_index].m_name);
129:
130: killed(NULL, item, NOMESSAGE, POINTS);
131: }
132: }
133: }
134: else if (chance == 2)
135: {
136: msg("Aule, Lord of Crafts, hears your call.");
137: read_scroll(&player, S_MAKEITEMEM, is_godly);
138: }
139:
140: /* Save 3-9 for other wonderful stuff */
141: else if (chance < 15)
142: {
143: msg("Orome, Lord of Forests, hears your call.");
144: read_scroll(&player, S_SUMMON, is_godly);
145: }
146: else if (chance < 20)
147: {
148: msg("Hermes, the Winged Messenger, hears your call.");
149: quaff(&player, P_HASTE, is_godly);
150: }
151: else if (chance < 25)
152: {
153: msg("Lorien, Master of Dreams, hears your call.");
154: read_scroll(&player, S_SLEEP, is_godly);
155: }
156: else if (chance < 30)
157: {
158: msg("Este, Lady of Healing, hears your call.");
159: quaff(&player, P_RESTORE, is_godly);
160: quaff(&player, P_HEALING, is_godly);
161: }
162: else if (chance < 35)
163: {
164: msg("Thor, God of Thunder, hears your call.");
165: msg("A bolt of lighting strikes you!");
166: read_scroll(&player, S_ELECTRIFY, is_godly);
167: }
168: else if (chance < 40)
169: {
170: msg("Lorien, Master of Illusion, hears your call.");
171: quaff(&player, P_DISGUISE, is_godly);
172: }
173: else if (chance < 60) /* Nothing happens */
174: {
175: msg("Boccob, the Uncaring, ignores you.");
176: }
177:
178: /* You don't really want one of these gods answering your call */
179:
180: else if (chance < 65)
181: {
182: msg("Jubilex, Master of Slimes and Oozes, hears your call.");
183: read_scroll(&player, S_HOLD, is_godly);
184: luck++;
185: }
186: else if (chance < 70)
187: {
188: msg("Sauron, Lord of the Ring, hears your call.");
189: quaff(&player, P_INVIS, is_godly);
190: luck++;
191: }
192: else if (chance < 75)
193: {
194: msg("Orcus, Lord of Undead, hears your call.");
195: quaff(&player, P_PHASE, is_godly);
196: luck++;
197: }
198: else if (chance < 80)
199: {
200: msg("Incabulos, God of Evil Sendings, hears your call.");
201: quaff(&player, P_CLEAR, is_godly);
202: luck++;
203: }
204: else if (chance < 85)
205: {
206: msg("Raxivort, Night Flutterer, hears your call.");
207: quaff(&player, P_SEEINVIS, is_godly);
208: luck++;
209: }
210: else if (chance < 90)
211: {
212: msg("Morgoth, Lord of Fire, hears your call.");
213: quaff(&player, P_FIRERESIST, is_godly);
214: luck++;
215: }
216: else if (chance < 100) /* You are in for it now! */
217: {
218: msg("You fall into a horrible trance-like state.");
219: no_command += SLEEPTIME;
220: }
221: if (chance == 100)
222: {
223: msg("The heavens open - but wait!");
224: msg("A bolt of eldritch energy strikes you!");
225:
226: if (pstats.s_hpt > 1)
227: pstats.s_hpt /= 2;
228:
229: msg("The gods must be angry with you.");
230: }
231: }
232:
233: /* Routines for thieves */
234:
235: /*
236: gsense()
237: Sense gold returns TRUE if gold was detected
238: */
239:
240: int
241: gsense(void)
242: {
243: if (lvl_obj != NULL)
244: {
245: struct linked_list *gitem;
246: struct object *cur;
247: int gtotal = 0;
248:
249: wclear(hw);
250:
251: for (gitem = lvl_obj; gitem != NULL; gitem = next(gitem))
252: {
253: cur = OBJPTR(gitem);
254:
255: if (cur->o_type == GOLD)
256: {
257: gtotal += cur->o_count;
258: mvwaddch(hw, cur->o_pos.y, cur->o_pos.x, GOLD);
259:
260: }
261: }
262:
263: if (gtotal)
264: {
265: msg("You sense gold!");
266: overlay(hw, cw);
267: return(TRUE);
268: }
269: }
270:
271: nothing_message(ISNORMAL);
272:
273: return(FALSE);
274: }
275:
276:
277: /*
278: is_stealth()
279: is player quiet about something
280: */
281:
282: int
283: is_stealth(struct thing *tp)
284: {
285: return (rnd(25) < tp->t_stats.s_dext ||
286: (tp == &player && is_wearing(R_STEALTH)));
287: }
288:
289: /*
290: steal()
291: Steal in direction given in delta
292: */
293:
294: void
295: steal(void)
296: {
297: struct linked_list *item;
298: struct thing *tp;
299: coord new_pos;
300: short thief_bonus;
301: char *unsuccess = "";
302: char *gain = "";
303: char *notice = "is not";
304:
305: new_pos.y = hero.y + delta.y;
306: new_pos.x = hero.x + delta.x;
307:
308: /* Anything there? */
309:
310: if (new_pos.y < 0 || new_pos.y > LINES - 3 ||
311: new_pos.x < 0 || new_pos.x > COLS - 1 ||
312: mvwinch(mw, new_pos.y, new_pos.x) == ' ')
313: {
314: msg("There is no one to steal from.");
315: return;
316: }
317:
318: if ((item = find_mons(new_pos.y, new_pos.x)) == NULL)
319: return;
320:
321: tp = THINGPTR(item);
322:
323: /* Can player steal something unnoticed? */
324:
325: if (player.t_ctype == C_THIEF || player.t_ctype == C_NINJA)
326: thief_bonus = 10;
327: else
328: thief_bonus = -50;
329:
330: if (rnd(50) >= 3 * pstats.s_dext + thief_bonus)
331: {
332: chase_it(&new_pos, &player);
333: turn_off(*tp, ISFRIENDLY);
334: notice = "is";
335: }
336:
337: if (rnd(100) <
338: (thief_bonus + 2 * pstats.s_dext + 5 * pstats.s_lvl -
339: 5 * (tp->t_stats.s_lvl - 3)))
340: {
341: struct linked_list *s_item, *pack_ptr;
342: int cnt = 0;
343:
344: s_item = NULL; /* Start stolen goods out as nothing */
345:
346: /* Find a good item to take */
347:
348: if (tp->t_pack != NULL)
349: {
350: /* Count up the number of items in the monster's pack */
351:
352: for (pack_ptr = tp->t_pack; pack_ptr != NULL; pack_ptr = next(pack_ptr))
353: cnt++;
354:
355: /* Pick one */
356: cnt = rnd(cnt);
357:
358: /* Take it from the monster */
359:
360: for (pack_ptr = tp->t_pack; --cnt == 0; pack_ptr = next(pack_ptr))
361: ;
362:
363: s_item = pack_ptr;
364: detach(tp->t_pack, s_item);
365:
366: /* Give it to player */
367:
368: if (add_pack(s_item, MESSAGE) == FALSE)
369: {
370: (OBJPTR(s_item))->o_pos = hero;
371: fall(&player, s_item, TRUE, FALSE);
372: }
373:
374: /* Get points for stealing from unfriendly monsters */
375:
376: if (off(*tp, ISFRIENDLY))
377: {
378: if (player.t_ctype == C_THIEF)
379: pstats.s_exp += 2 * tp->t_stats.s_exp / 3;
380: else
381: pstats.s_exp += tp->t_stats.s_exp / min(pstats.s_lvl, 10);
382:
383: check_level();
384: }
385: }
386: else
387: {
388: gain = " gains you nothing and";
389: }
390: }
391: else
392: {
393: unsuccess = " unsuccessful";
394: }
395:
396: msg("Your%s attempt%s %s noticed.", unsuccess, gain, notice);
397: }
398:
399: /*
400: affect()
401: cleric affecting undead
402: */
403:
404: void
405: affect(void)
406: {
407: struct linked_list *item;
408: struct thing *tp;
409: char *mname;
410: coord new_pos;
411: int is_godly;
412: int effective_level;
413:
414: if (player.t_ctype != C_CLERIC && player.t_ctype != C_PALADIN &&
415: !is_wearing(R_PIETY))
416: {
417: msg("Only clerics and paladins can affect undead.");
418: return;
419: }
420:
421: is_godly = (player.t_ctype == C_CLERIC || player.t_ctype == C_PALADIN);
422:
423: if (is_godly && is_wearing(R_PIETY))
424: effective_level = 2 * pstats.s_lvl;
425: else
426: effective_level = pstats.s_lvl;
427:
428: new_pos.y = hero.y + delta.y;
429: new_pos.x = hero.x + delta.x;
430:
431: /* Anything there? */
432:
433: if (new_pos.y < 0 || new_pos.y > LINES - 3 ||
434: new_pos.x < 0 || new_pos.x > COLS - 1 ||
435: mvwinch(mw, new_pos.y, new_pos.x) == ' ')
436: {
437: msg("Nothing to affect.");
438: return;
439: }
440:
441: if ((item = find_mons(new_pos.y, new_pos.x)) == NULL)
442: {
443: debug("Affect what @ %d,%d?", new_pos.y, new_pos.x);
444: return;
445: }
446:
447: tp = THINGPTR(item);
448: mname = monsters[tp->t_index].m_name;
449:
450: if (off(*tp, ISUNDEAD))
451: {
452: msg("Your holy symbol has no effect on the %s.", mname);
453: goto annoy;
454: }
455:
456: if (on(*tp, WASTURNED))
457: {
458: msg("Your holy symbol merely enrages the %s.", mname);
459: goto annoy;
460: }
461:
462: /* Can cleric destroy it? */
463:
464: if (effective_level >= 3 * tp->t_stats.s_lvl)
465: {
466: msg("You have destroyed the %s.", mname);
467: killed(&player, item, NOMESSAGE, POINTS);
468: return;
469: }
470:
471: /* Can cleric turn it? */
472:
473: if (rnd(100) + 1 >
474: (100 * ((2 * tp->t_stats.s_lvl) - effective_level)) /
475: effective_level)
476: {
477: msg("You have turned the %s.", mname);
478: turn_on(*tp, WASTURNED); /* One turn per monster */
479: turn_on(*tp, ISRUN);
480: turn_on(*tp, ISFLEE);
481:
482: /* If monster was suffocating, stop it */
483: if (on(*tp, DIDSUFFOCATE))
484: {
485: turn_off(*tp, DIDSUFFOCATE);
486: extinguish_fuse(FUSE_SUFFOCATE);
487: }
488:
489: /* If monster held us, stop it */
490: if (on(*tp, DIDHOLD) && (--hold_count == 0))
491: turn_off(player, ISHELD);
492:
493: turn_off(*tp, DIDHOLD);
494:
495: return;
496: }
497:
498: msg("The %s momentarily recoils from your holy symbol.", mname);
499:
500: annoy:
501:
502: if (off(*tp, WASTURNED))
503: chase_it(&new_pos, &player);
504: }
505:
506: /*
507: undead_sense()
508: cleric or paladin finding the ungodly
509: */
510:
511: void
512: undead_sense(void)
513: {
514: struct linked_list *item;
515: struct thing *tp;
516: int showit = FALSE;
517:
518: wclear(hw);
519:
520: for (item = mlist; item != NULL; item = next(item))
521: {
522: tp = THINGPTR(item);
523:
524: if (on(*tp, ISUNDEAD))
525: {
526: mvwaddch(hw, tp->t_pos.y, tp->t_pos.x, '&');
527: showit = TRUE;
528: }
529: }
530:
531: if (showit)
532: {
533: msg("You feel the presense of the ungodly.");
534: overlay(hw, cw);
535: wrefresh(cw);
536: wclear(hw);
537: }
538: }
CVSweb