comparison arogue5/player.c @ 63:0ed67132cf10

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