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