comparison urogue/player.c @ 256:c495a4f288c6

Import UltraRogue from the Roguelike Restoration Project (r1490)
author John "Elwin" Edwards
date Tue, 31 Jan 2017 19:56:04 -0500
parents
children
comparison
equal deleted inserted replaced
253:d9badb9c0179 256:c495a4f288c6
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 }