1 /**
2  * \file player-util.c
3  * \brief Player utility functions
4  *
5  * Copyright (c) 2011 The Angband Developers. See COPYING.
6  *
7  * This work is free software; you can redistribute it and/or modify it
8  * under the terms of either:
9  *
10  * a) the GNU General Public License as published by the Free Software
11  *    Foundation, version 2, or
12  *
13  * b) the "Angband licence":
14  *    This software may be copied and distributed for educational, research,
15  *    and not for profit purposes provided that this copyright and statement
16  *    are included in all such copies.  Other copyrights may also apply.
17  */
18 
19 #include "angband.h"
20 #include "cave.h"
21 #include "cmd-core.h"
22 #include "cmds.h"
23 #include "game-input.h"
24 #include "game-world.h"
25 #include "generate.h"
26 #include "init.h"
27 #include "obj-chest.h"
28 #include "obj-gear.h"
29 #include "obj-knowledge.h"
30 #include "obj-pile.h"
31 #include "obj-tval.h"
32 #include "obj-util.h"
33 #include "player-calcs.h"
34 #include "player-history.h"
35 #include "player-spell.h"
36 #include "player-timed.h"
37 #include "player-util.h"
38 #include "project.h"
39 #include "score.h"
40 #include "store.h"
41 #include "target.h"
42 #include "trap.h"
43 
44 /**
45  * Increment to the next or decrement to the preceeding level
46    accounting for the stair skip value in constants
47    Keep in mind to check all intermediate level for unskippable
48    quests
49 */
dungeon_get_next_level(int dlev,int added)50 int dungeon_get_next_level(int dlev, int added)
51 {
52 	int target_level, i;
53 
54 	/* Get target level */
55 	target_level = dlev + added * z_info->stair_skip;
56 
57 	/* Don't allow levels below max */
58 	if (target_level > z_info->max_depth - 1)
59 		target_level = z_info->max_depth - 1;
60 
61 	/* Don't allow levels above the town */
62 	if (target_level < 0) target_level = 0;
63 
64 	/* Check intermediate levels for quests */
65 	for (i = dlev; i <= target_level; i++) {
66 		if (is_quest(i)) return i;
67 	}
68 
69 	return target_level;
70 }
71 
72 /**
73  * Set recall depth for a player recalling from town
74  */
player_set_recall_depth(struct player * p)75 void player_set_recall_depth(struct player *p)
76 {
77 	/* Account for forced descent */
78 	if (OPT(p, birth_force_descend)) {
79 		/* Force descent to a lower level if allowed */
80 		if ((p->max_depth < z_info->max_depth - 1) && !is_quest(p->max_depth)) {
81 			p->recall_depth = dungeon_get_next_level(p->max_depth, 1);
82 		}
83 	}
84 
85 	/* Players who haven't left town before go to level 1 */
86 	p->recall_depth = MAX(p->recall_depth, 1);
87 }
88 
89 /**
90  * Give the player the choice of persistent level to recall to.  Note that if
91  * a level greater than the player's maximum depth is chosen, we silently go
92  * to the maximum depth.
93  */
player_get_recall_depth(struct player * p)94 bool player_get_recall_depth(struct player *p)
95 {
96 	bool level_ok = false;
97 	int new = 0;
98 
99 	while (!level_ok) {
100 		char *prompt = "Which level do you wish to return to (0 to cancel)? ";
101 		int i;
102 
103 		/* Choose the level */
104 		new = get_quantity(prompt, p->max_depth);
105 		if (new == 0) {
106 			return false;
107 		}
108 
109 		/* Is that level valid? */
110 		for (i = 0; i < chunk_list_max; i++) {
111 			if (chunk_list[i]->depth == new) {
112 				level_ok = true;
113 				break;
114 			}
115 		}
116 		if (!level_ok) {
117 			msg("You must choose a level you have previously visited.");
118 		}
119 	}
120 	p->recall_depth = new;
121 	return true;
122 }
123 
124 /**
125  * Change dungeon level - e.g. by going up stairs or with WoR.
126  */
dungeon_change_level(struct player * p,int dlev)127 void dungeon_change_level(struct player *p, int dlev)
128 {
129 	/* New depth */
130 	p->depth = dlev;
131 
132 	/* If we're returning to town, update the store contents
133 	   according to how long we've been away */
134 	if (!dlev && daycount)
135 		store_update();
136 
137 	/* Leaving, make new level */
138 	p->upkeep->generate_level = true;
139 
140 	/* Save the game when we arrive on the new level. */
141 	p->upkeep->autosave = true;
142 }
143 
144 
145 /**
146  * Decreases players hit points and sets death flag if necessary
147  *
148  * Hack -- this function allows the user to save (or quit) the game
149  * when he dies, since the "You die." message is shown before setting
150  * the player to "dead".
151  */
take_hit(struct player * p,int dam,const char * kb_str)152 void take_hit(struct player *p, int dam, const char *kb_str)
153 {
154 	int old_chp = p->chp;
155 
156 	int warning = (p->mhp * p->opts.hitpoint_warn / 10);
157 
158 	/* Paranoia */
159 	if (p->is_dead) return;
160 
161 	/* Mega-Hack -- Apply "invulnerability" */
162 	if (p->timed[TMD_INVULN] && (dam < 9000)) return;
163 
164 	/* Apply damage reduction */
165 	dam -= p->state.dam_red;
166 	if (p->state.perc_dam_red) {
167 		dam -= (dam * p->state.perc_dam_red) / 100 ;
168 	}
169 	if (dam <= 0) return;
170 
171 	/* Disturb */
172 	disturb(p);
173 
174 	/* Hurt the player */
175 	p->chp -= dam;
176 
177 	/* Reward COMBAT_REGEN characters with mana for their lost hitpoints
178 	 * Unenviable task of separating what should and should not cause rage
179 	 * If we eliminate the most exploitable cases it should be fine.
180 	 * All traps and lava currently give mana, which could be exploited  */
181 	if (player_has(p, PF_COMBAT_REGEN)  && strcmp(kb_str, "poison")
182 		&& strcmp(kb_str, "a fatal wound") && strcmp(kb_str, "starvation")) {
183 		/* lose X% of hitpoints get X% of spell points */
184 		s32b sp_gain = (MAX((s32b)p->msp, 10) << 16) / (s32b)p->mhp * dam;
185 		player_adjust_mana_precise(p, sp_gain);
186 	}
187 
188 	/* Display the hitpoints */
189 	p->upkeep->redraw |= (PR_HP);
190 
191 	/* Dead player */
192 	if (p->chp < 0) {
193 		/* From hell's heart I stab at thee */
194 		if (p->timed[TMD_BLOODLUST]
195 			&& (p->chp + p->timed[TMD_BLOODLUST] + p->lev >= 0)) {
196 			if (randint0(10)) {
197 				msg("Your lust for blood keeps you alive!");
198 			} else {
199 				msg("So great was his prowess and skill in warfare, the Elves said: ");
200 				msg("'The Mormegil cannot be slain, save by mischance.'");
201 			}
202 		} else if ((p->wizard || OPT(p, cheat_live)) && !get_check("Die? ")) {
203 			event_signal(EVENT_CHEAT_DEATH);
204 		} else {
205 			/* Hack -- Note death */
206 			msgt(MSG_DEATH, "You die.");
207 			event_signal(EVENT_MESSAGE_FLUSH);
208 
209 			/* Note cause of death */
210 			my_strcpy(p->died_from, kb_str, sizeof(p->died_from));
211 
212 			/* No longer a winner */
213 			p->total_winner = false;
214 
215 			/* Note death */
216 			p->is_dead = true;
217 
218 			/* Dead */
219 			return;
220 		}
221 	}
222 
223 	/* Hitpoint warning */
224 	if (p->chp < warning) {
225 		/* Hack -- bell on first notice */
226 		if (old_chp > warning)
227 			bell("Low hitpoint warning!");
228 
229 		/* Message */
230 		msgt(MSG_HITPOINT_WARN, "*** LOW HITPOINT WARNING! ***");
231 		event_signal(EVENT_MESSAGE_FLUSH);
232 	}
233 }
234 
235 /**
236  * Win or not, know inventory, home items and history upon death, enter score
237  */
death_knowledge(struct player * p)238 void death_knowledge(struct player *p)
239 {
240 	struct store *home = &stores[STORE_HOME];
241 	struct object *obj;
242 	time_t death_time = (time_t)0;
243 
244 	/* Retire in the town in a good state */
245 	if (p->total_winner) {
246 		p->depth = 0;
247 		my_strcpy(p->died_from, "Ripe Old Age", sizeof(p->died_from));
248 		p->exp = p->max_exp;
249 		p->lev = p->max_lev;
250 		p->au += 10000000L;
251 	}
252 
253 	player_learn_all_runes(p);
254 	for (obj = p->gear; obj; obj = obj->next) {
255 		object_flavor_aware(obj);
256 		obj->known->effect = obj->effect;
257 		obj->known->activation = obj->activation;
258 	}
259 
260 	for (obj = home->stock; obj; obj = obj->next) {
261 		object_flavor_aware(obj);
262 		obj->known->effect = obj->effect;
263 		obj->known->activation = obj->activation;
264 	}
265 
266 	history_unmask_unknown(p);
267 
268 	/* Get time of death */
269 	(void)time(&death_time);
270 	enter_score(&death_time);
271 
272 	/* Hack -- Recalculate bonuses */
273 	p->upkeep->update |= (PU_BONUS);
274 	handle_stuff(p);
275 }
276 
277 /**
278  * Energy per move, taking extra moves into account
279  */
energy_per_move(struct player * p)280 int energy_per_move(struct player *p)
281 {
282 	int num = p->state.num_moves;
283 	int energy = z_info->move_energy;
284 	return (energy * (1 + ABS(num) - num)) / (1 + ABS(num));
285 }
286 
287 /**
288  * Modify a stat value by a "modifier", return new value
289  *
290  * Stats go up: 3,4,...,17,18,18/10,18/20,...,18/220
291  * Or even: 18/13, 18/23, 18/33, ..., 18/220
292  *
293  * Stats go down: 18/220, 18/210,..., 18/10, 18, 17, ..., 3
294  * Or even: 18/13, 18/03, 18, 17, ..., 3
295  */
modify_stat_value(int value,int amount)296 s16b modify_stat_value(int value, int amount)
297 {
298 	int i;
299 
300 	/* Reward or penalty */
301 	if (amount > 0) {
302 		/* Apply each point */
303 		for (i = 0; i < amount; i++) {
304 			/* One point at a time */
305 			if (value < 18) value++;
306 
307 			/* Ten "points" at a time */
308 			else value += 10;
309 		}
310 	} else if (amount < 0) {
311 		/* Apply each point */
312 		for (i = 0; i < (0 - amount); i++) {
313 			/* Ten points at a time */
314 			if (value >= 18+10) value -= 10;
315 
316 			/* Hack -- prevent weirdness */
317 			else if (value > 18) value = 18;
318 
319 			/* One point at a time */
320 			else if (value > 3) value--;
321 		}
322 	}
323 
324 	/* Return new value */
325 	return (value);
326 }
327 
328 /**
329  * Regenerate one turn's worth of hit points
330  */
player_regen_hp(struct player * p)331 void player_regen_hp(struct player *p)
332 {
333 	s32b hp_gain;
334 	int percent = 0;/* max 32k -> 50% of mhp; more accurately "pertwobytes" */
335 	int fed_pct, old_chp = p->chp;
336 
337 	/* Default regeneration */
338 	if (p->timed[TMD_FOOD] >= PY_FOOD_WEAK) {
339 		percent = PY_REGEN_NORMAL;
340 	} else if (p->timed[TMD_FOOD] >= PY_FOOD_FAINT) {
341 		percent = PY_REGEN_WEAK;
342 	} else if (p->timed[TMD_FOOD] >= PY_FOOD_STARVE) {
343 		percent = PY_REGEN_FAINT;
344 	}
345 
346 	/* Food bonus - better fed players regenerate up to 1/3 faster */
347 	fed_pct = p->timed[TMD_FOOD] / z_info->food_value;
348 	percent *= 100 + fed_pct / 3;
349 	percent /= 100;
350 
351 	/* Various things speed up regeneration */
352 	if (player_of_has(p, OF_REGEN))
353 		percent *= 2;
354 	if (player_resting_can_regenerate(p))
355 		percent *= 2;
356 
357 	/* Some things slow it down */
358 	if (player_of_has(p, OF_IMPAIR_HP) || player_has(p, PF_COMBAT_REGEN))
359 		percent /= 2;
360 
361 	/* Various things interfere with physical healing */
362 	if (p->timed[TMD_PARALYZED]) percent = 0;
363 	if (p->timed[TMD_POISONED]) percent = 0;
364 	if (p->timed[TMD_STUN]) percent = 0;
365 	if (p->timed[TMD_CUT]) percent = 0;
366 
367 	/* Extract the new hitpoints */
368 	hp_gain = (s32b)(p->mhp * percent) + PY_REGEN_HPBASE;
369 	player_adjust_hp_precise(p, hp_gain);
370 
371 	/* Notice changes */
372 	if (old_chp != p->chp) {
373 		equip_learn_flag(p, OF_REGEN);
374 		equip_learn_flag(p, OF_IMPAIR_HP);
375 	}
376 }
377 
378 
379 /**
380  * Regenerate one turn's worth of mana
381  */
player_regen_mana(struct player * p)382 void player_regen_mana(struct player *p)
383 {
384 	s32b sp_gain;
385 	int percent, old_csp = p->csp;
386 
387 	/* Save the old spell points */
388 	old_csp = p->csp;
389 
390 	/* Default regeneration */
391 	percent = PY_REGEN_NORMAL;
392 
393 	/* Various things speed up regeneration, but shouldn't punish healthy BGs */
394 	if (!(player_has(p, PF_COMBAT_REGEN) && p->chp  > p->mhp / 2)) {
395 		if (player_of_has(p, OF_REGEN))
396 			percent *= 2;
397 		if (player_resting_can_regenerate(p))
398 			percent *= 2;
399 	}
400 
401 	/* Some things slow it down */
402 	if (player_has(p, PF_COMBAT_REGEN)) {
403 		percent /= -2;
404 	} else if (player_of_has(p, OF_IMPAIR_MANA)) {
405 		percent /= 2;
406 	}
407 
408 	/* Regenerate mana */
409 	sp_gain = (s32b)(p->msp * percent);
410 	if (percent >= 0)
411 		sp_gain += PY_REGEN_MNBASE;
412 	sp_gain = player_adjust_mana_precise(p, sp_gain);
413 
414 	/* SP degen heals BGs at double efficiency vs casting */
415 	if (sp_gain < 0  && player_has(p, PF_COMBAT_REGEN)) {
416 		convert_mana_to_hp(p, -sp_gain << 2);
417 	}
418 
419 	/* Notice changes */
420 	if (old_csp != p->csp) {
421 		p->upkeep->redraw |= (PR_MANA);
422 		equip_learn_flag(p, OF_REGEN);
423 		equip_learn_flag(p, OF_IMPAIR_MANA);
424 	}
425 }
426 
player_adjust_hp_precise(struct player * p,s32b hp_gain)427 void player_adjust_hp_precise(struct player *p, s32b hp_gain)
428 {
429 	s32b new_chp;
430 	int num, old_chp = p->chp;
431 
432 	/* Load it all into 4 byte format*/
433 	new_chp = (s32b)((p->chp << 16) + p->chp_frac) + hp_gain;
434 
435 	/* Check for overflow */
436 	/*     {new_chp = LONG_MIN;} DAVIDTODO*/
437 	if ((new_chp < 0) && (old_chp > 0) && (hp_gain > 0)) {
438 		new_chp = INT32_MAX;
439 	} else if ((new_chp > 0) && (old_chp < 0) && (hp_gain < 0)) {
440 		new_chp = INT32_MIN;
441 	}
442 
443 	/* Break it back down*/
444 	p->chp = (s16b)(new_chp >> 16);   /* div 65536 */
445 	p->chp_frac = (u16b)(new_chp & 0xFFFF); /* mod 65536 */
446 	/*DAVIDTODO neg new_chp ok? I think so because eg a slightly negative
447 	 * new_chp will give -1 for chp and very high chp_frac.*/
448 
449 	/* Fully healed */
450 	if (p->chp >= p->mhp) {
451 		p->chp = p->mhp;
452 		p->chp_frac = 0;
453 	}
454 
455 	num = p->chp - old_chp;
456 	if (num == 0)
457 		return;
458 
459 	p->upkeep->redraw |= (PR_HP);
460 }
461 
462 
463 /**
464  * Accept a 4 byte signed int, divide it by 65k, and add
465  * to current spell points. p->csp and csp_frac are 2 bytes each.
466  */
player_adjust_mana_precise(struct player * p,s32b sp_gain)467 s32b player_adjust_mana_precise(struct player *p, s32b sp_gain)
468 {
469 	s32b old_csp_long, new_csp_long;
470 	int old_csp_short = p->csp;
471 
472 	if (sp_gain == 0) return 0;
473 
474 	/* Load it all into 4 byte format*/
475 	old_csp_long = (s32b)((p->csp << 16) + p->csp_frac);
476 	new_csp_long = old_csp_long + sp_gain;
477 
478 	/* Check for overflow */
479 
480 	/* new_csp = LONG_MAX LONG_MIN;} DAVIDTODO produces warning*/
481 	if ((new_csp_long < 0) && (old_csp_long > 0) && (sp_gain > 0)) {
482 		new_csp_long = INT32_MAX;
483 		sp_gain = 0;
484 	} else if ((new_csp_long > 0) && (old_csp_long < 0) && (sp_gain < 0)) {
485 		new_csp_long = INT32_MIN;
486 		sp_gain = 0;
487 	}
488 
489 	/* Break it back down*/
490 	p->csp = (s16b)(new_csp_long >> 16);   /* div 65536 */
491 	p->csp_frac = (u16b)(new_csp_long & 0xFFFF);    /* mod 65536 */
492 
493 	/* Max/min SP */
494 	if (p->csp >= p->msp) {
495 		p->csp = p->msp;
496 		p->csp_frac = 0;
497 		sp_gain = 0;
498 	} else if (p->csp < 0) {
499 		p->csp = 0;
500 		p->csp_frac = 0;
501 		sp_gain = 0;
502 	}
503 
504 	/* Notice changes */
505 	if (old_csp_short != p->csp) {
506 		p->upkeep->redraw |= (PR_MANA);
507 	}
508 
509 	if (sp_gain == 0) {
510 		/* Recalculate */
511 		new_csp_long = (s32b)((p->csp << 16) + p->csp_frac);
512 		sp_gain = new_csp_long - old_csp_long;
513 	}
514 
515 	return sp_gain;
516 }
517 
convert_mana_to_hp(struct player * p,s32b sp_long)518 void convert_mana_to_hp(struct player *p, s32b sp_long) {
519 	s32b hp_gain, sp_ratio;
520 
521 	if (sp_long <= 0 || p->msp == 0 || p->mhp == p->chp) return;
522 
523 	/* Total HP from max */
524 	hp_gain = (s32b)((p->mhp - p->chp) << 16);
525 	hp_gain -= (s32b)p->chp_frac;
526 
527 	/* Spend X% of SP get X/2% of lost HP. E.g., at 50% HP get X/4% */
528 	/* Gain stays low at msp<10 because MP gains are generous at msp<10 */
529 	/* sp_ratio is max sp to spent sp, doubled to suit target rate. */
530 	sp_ratio = (MAX(10, (s32b)p->msp) << 16) * 2 / sp_long;
531 
532 	/* Limit max healing to 25% of damage; ergo spending > 50% msp
533 	 * is inefficient */
534 	if (sp_ratio < 4) {sp_ratio = 4;}
535 	hp_gain /= sp_ratio;
536 
537 	/* DAVIDTODO Flavorful comments on large gains would be fun and informative */
538 
539 	player_adjust_hp_precise(p, hp_gain);
540 }
541 
542 /**
543  * Update the player's light fuel
544  */
player_update_light(struct player * p)545 void player_update_light(struct player *p)
546 {
547 	/* Check for light being wielded */
548 	struct object *obj = equipped_item_by_slot_name(p, "light");
549 
550 	/* Burn some fuel in the current light */
551 	if (obj && tval_is_light(obj)) {
552 		bool burn_fuel = true;
553 
554 		/* Turn off the wanton burning of light during the day in the town */
555 		if (!p->depth && is_daytime())
556 			burn_fuel = false;
557 
558 		/* If the light has the NO_FUEL flag, well... */
559 		if (of_has(obj->flags, OF_NO_FUEL))
560 		    burn_fuel = false;
561 
562 		/* Use some fuel (except on artifacts, or during the day) */
563 		if (burn_fuel && obj->timeout > 0) {
564 			/* Decrease life-span */
565 			obj->timeout--;
566 
567 			/* Hack -- notice interesting fuel steps */
568 			if ((obj->timeout < 100) || (!(obj->timeout % 100)))
569 				/* Redraw stuff */
570 				p->upkeep->redraw |= (PR_EQUIP);
571 
572 			/* Hack -- Special treatment when blind */
573 			if (p->timed[TMD_BLIND]) {
574 				/* Hack -- save some light for later */
575 				if (obj->timeout == 0) obj->timeout++;
576 			} else if (obj->timeout == 0) {
577 				/* The light is now out */
578 				disturb(p);
579 				msg("Your light has gone out!");
580 
581 				/* If it's a torch, now is the time to delete it */
582 				if (of_has(obj->flags, OF_BURNS_OUT)) {
583 					bool dummy;
584 					struct object *burnt = gear_object_for_use(obj, 1, false,
585 															   &dummy);
586 					if (burnt->known)
587 						object_delete(&burnt->known);
588 					object_delete(&burnt);
589 				}
590 			} else if ((obj->timeout < 50) && (!(obj->timeout % 20))) {
591 				/* The light is getting dim */
592 				disturb(p);
593 				msg("Your light is growing faint.");
594 			}
595 		}
596 	}
597 
598 	/* Calculate torch radius */
599 	p->upkeep->update |= (PU_TORCH);
600 }
601 
602 /**
603  * Find the player's best digging tool.  If forbid_stack is true, ignores
604  * stacks of more than one item.
605  */
player_best_digger(struct player * p,bool forbid_stack)606 struct object *player_best_digger(struct player *p, bool forbid_stack)
607 {
608 	int weapon_slot = slot_by_name(player, "weapon");
609 	struct object *current_weapon = slot_object(player, weapon_slot);
610 	struct object *obj, *best = NULL;
611 	/* Prefer any melee weapon over unarmed digging, i.e. best == NULL. */
612 	int best_score = -1;
613 	struct player_state local_state;
614 
615 	for (obj = p->gear; obj; obj = obj->next) {
616 		int score, old_number;
617 		if (!tval_is_melee_weapon(obj)) continue;
618 		if (obj->number < 1 || (forbid_stack && obj->number > 1)) continue;
619 
620 		/* Swap temporarily for the calc_bonuses() computation. */
621 		old_number = obj->number;
622 		if (obj != current_weapon) {
623 			obj->number = 1;
624 			p->body.slots[weapon_slot].obj = obj;
625 		}
626 
627 		/*
628 		 * Avoid side effects from using update set to false
629 		 * with calc_bonuses().
630 		 */
631 		local_state.stat_ind[STAT_STR] = 0;
632 		local_state.stat_ind[STAT_DEX] = 0;
633 		calc_bonuses(p, &local_state, true, false);
634 		score = local_state.skills[SKILL_DIGGING];
635 
636 		/* Swap back. */
637 		if (obj != current_weapon) {
638 			obj->number = old_number;
639 			player->body.slots[weapon_slot].obj = current_weapon;
640 		}
641 
642 		if (score > best_score) {
643 			best = obj;
644 			best_score = score;
645 		}
646 	}
647 
648 	return best;
649 }
650 
651 /**
652  * Melee a random adjacent monster
653  */
player_attack_random_monster(struct player * p)654 bool player_attack_random_monster(struct player *p)
655 {
656 	int i, dir = randint0(8);
657 
658 	/* Confused players get a free pass */
659 	if (p->timed[TMD_CONFUSED]) return false;
660 
661 	/* Look for a monster, attack */
662 	for (i = 0; i < 8; i++, dir++) {
663 		struct loc grid = loc_sum(player->grid, ddgrid_ddd[dir % 8]);
664 		if (square_monster(cave, grid)) {
665 			p->upkeep->energy_use = z_info->move_energy;
666 			msg("You angrily lash out at a nearby foe!");
667 			move_player(ddd[dir % 8], false);
668 			return true;
669 		}
670 	}
671 	return false;
672 }
673 
674 /**
675  * Have random bad stuff happen to the player from over-exertion
676  *
677  * This function uses the PY_EXERT_* flags
678  */
player_over_exert(struct player * p,int flag,int chance,int amount)679 void player_over_exert(struct player *p, int flag, int chance, int amount)
680 {
681 	if (chance <= 0) return;
682 
683 	/* CON damage */
684 	if (flag & PY_EXERT_CON) {
685 		if (randint0(100) < chance) {
686 			/* Hack - only permanent with high chance (no-mana casting) */
687 			bool perm = (randint0(100) < chance / 2) && (chance >= 50);
688 			msg("You have damaged your health!");
689 			player_stat_dec(p, STAT_CON, perm);
690 		}
691 	}
692 
693 	/* Fainting */
694 	if (flag & PY_EXERT_FAINT) {
695 		if (randint0(100) < chance) {
696 			msg("You faint from the effort!");
697 
698 			/* Bypass free action */
699 			(void)player_inc_timed(p, TMD_PARALYZED, randint1(amount),
700 								   true, false);
701 		}
702 	}
703 
704 	/* Scrambled stats */
705 	if (flag & PY_EXERT_SCRAMBLE) {
706 		if (randint0(100) < chance) {
707 			(void)player_inc_timed(p, TMD_SCRAMBLE, randint1(amount),
708 								   true, true);
709 		}
710 	}
711 
712 	/* Cut damage */
713 	if (flag & PY_EXERT_CUT) {
714 		if (randint0(100) < chance) {
715 			msg("Wounds appear on your body!");
716 			(void)player_inc_timed(p, TMD_CUT, randint1(amount),
717 								   true, false);
718 		}
719 	}
720 
721 	/* Confusion */
722 	if (flag & PY_EXERT_CONF) {
723 		if (randint0(100) < chance) {
724 			(void)player_inc_timed(p, TMD_CONFUSED, randint1(amount),
725 								   true, true);
726 		}
727 	}
728 
729 	/* Hallucination */
730 	if (flag & PY_EXERT_HALLU) {
731 		if (randint0(100) < chance) {
732 			(void)player_inc_timed(p, TMD_IMAGE, randint1(amount),
733 								   true, true);
734 		}
735 	}
736 
737 	/* Slowing */
738 	if (flag & PY_EXERT_SLOW) {
739 		if (randint0(100) < chance) {
740 			msg("You feel suddenly lethargic.");
741 			(void)player_inc_timed(p, TMD_SLOW, randint1(amount),
742 								   true, false);
743 		}
744 	}
745 
746 	/* HP */
747 	if (flag & PY_EXERT_HP) {
748 		if (randint0(100) < chance) {
749 			msg("You cry out in sudden pain!");
750 			take_hit(p, randint1(amount), "over-exertion");
751 		}
752 	}
753 }
754 
755 
756 /**
757  * See how much damage the player will take from damaging terrain
758  */
player_check_terrain_damage(struct player * p,struct loc grid)759 int player_check_terrain_damage(struct player *p, struct loc grid)
760 {
761 	int dam_taken = 0;
762 
763 	if (square_isfiery(cave, grid)) {
764 		int base_dam = 100 + randint1(100);
765 		int res = p->state.el_info[ELEM_FIRE].res_level;
766 
767 		/* Fire damage */
768 		dam_taken = adjust_dam(p, ELEM_FIRE, base_dam, RANDOMISE, res, false);
769 
770 		/* Feather fall makes one lightfooted. */
771 		if (player_of_has(p, OF_FEATHER)) {
772 			dam_taken /= 2;
773 		}
774 	}
775 
776 	return dam_taken;
777 }
778 
779 /**
780  * Terrain damages the player
781  */
player_take_terrain_damage(struct player * p,struct loc grid)782 void player_take_terrain_damage(struct player *p, struct loc grid)
783 {
784 	int dam_taken = player_check_terrain_damage(p, grid);
785 
786 	if (!dam_taken) {
787 		return;
788 	}
789 
790 	/* Damage the player and inventory */
791 	take_hit(player, dam_taken, square_feat(cave, grid)->die_msg);
792 	if (square_isfiery(cave, grid)) {
793 		msg(square_feat(cave, grid)->hurt_msg);
794 		inven_damage(player, PROJ_FIRE, dam_taken);
795 	}
796 }
797 
798 /**
799  * Find a player shape from the name
800  */
lookup_player_shape(const char * name)801 struct player_shape *lookup_player_shape(const char *name)
802 {
803 	struct player_shape *shape = shapes;
804 	while (shape) {
805 		if (streq(shape->name, name)) {
806 			return shape;
807 		}
808 		shape = shape->next;
809 	}
810 	msg("Could not find %s shape!", name);
811 	return NULL;
812 }
813 
814 /**
815  * Find a player shape index from the shape name
816  */
shape_name_to_idx(const char * name)817 int shape_name_to_idx(const char *name)
818 {
819 	struct player_shape *shape = lookup_player_shape(name);
820 	if (shape) {
821 		return shape->sidx;
822 	} else {
823 		return -1;
824 	}
825 }
826 
827 /**
828  * Find a player shape from the index
829  */
player_shape_by_idx(int index)830 struct player_shape *player_shape_by_idx(int index)
831 {
832 	struct player_shape *shape = shapes;
833 	while (shape) {
834 		if (shape->sidx == index) {
835 			return shape;
836 		}
837 		shape = shape->next;
838 	}
839 	msg("Could not find shape %d!", index);
840 	return NULL;
841 }
842 
843 /**
844  * Revert to normal shape
845  */
player_resume_normal_shape(struct player * p)846 void player_resume_normal_shape(struct player *p)
847 {
848 	p->shape = lookup_player_shape("normal");
849 	msg("You resume your usual shape.");
850 
851 	/* Kill vampire attack */
852 	(void) player_clear_timed(p, TMD_ATT_VAMP, true);
853 
854 	/* Update */
855 	player->upkeep->update |= (PU_BONUS);
856 	player->upkeep->redraw |= (PR_TITLE | PR_MISC);
857 	handle_stuff(player);
858 }
859 
860 /**
861  * Check if the player is shapechanged
862  */
player_is_shapechanged(struct player * p)863 bool player_is_shapechanged(struct player *p)
864 {
865 	return streq(p->shape->name, "normal") ? false : true;
866 }
867 
868 /**
869  * Check if the player is immune from traps
870  */
player_is_trapsafe(struct player * p)871 bool player_is_trapsafe(struct player *p)
872 {
873 	if (p->timed[TMD_TRAPSAFE]) return true;
874 	if (player_of_has(p, OF_TRAP_IMMUNE)) return true;
875 	return false;
876 }
877 
878 /**
879  * Return true if the player can cast a spell.
880  *
881  * \param p is the player
882  * \param show_msg should be set to true if a failure message should be
883  * displayed.
884  */
player_can_cast(struct player * p,bool show_msg)885 bool player_can_cast(struct player *p, bool show_msg)
886 {
887 	if (!p->class->magic.total_spells) {
888 		if (show_msg) {
889 			msg("You cannot pray or produce magics.");
890 		}
891 		return false;
892 	}
893 
894 	if (p->timed[TMD_BLIND] || no_light()) {
895 		if (show_msg) {
896 			msg("You cannot see!");
897 		}
898 		return false;
899 	}
900 
901 	if (p->timed[TMD_CONFUSED]) {
902 		if (show_msg) {
903 			msg("You are too confused!");
904 		}
905 		return false;
906 	}
907 
908 	return true;
909 }
910 
911 /**
912  * Return true if the player can study a spell.
913  *
914  * \param p is the player
915  * \param show_msg should be set to true if a failure message should be
916  * displayed.
917  */
player_can_study(struct player * p,bool show_msg)918 bool player_can_study(struct player *p, bool show_msg)
919 {
920 	if (!player_can_cast(p, show_msg))
921 		return false;
922 
923 	if (!p->upkeep->new_spells) {
924 		if (show_msg) {
925 			int count;
926 			struct magic_realm *r = class_magic_realms(p->class, &count), *r1;
927 			char buf[120];
928 
929 			my_strcpy(buf, r->spell_noun, sizeof(buf));
930 			my_strcat(buf, "s", sizeof(buf));
931 			r1 = r->next;
932 			mem_free(r);
933 			r = r1;
934 			if (count > 1) {
935 				while (r) {
936 					count--;
937 					if (count) {
938 						my_strcat(buf, ", ", sizeof(buf));
939 					} else {
940 						my_strcat(buf, " or ", sizeof(buf));
941 					}
942 					my_strcat(buf, r->spell_noun, sizeof(buf));
943 					my_strcat(buf, "s", sizeof(buf));
944 					r1 = r->next;
945 					mem_free(r);
946 					r = r1;
947 				}
948 			}
949 			msg("You cannot learn any new %s!", buf);
950 		}
951 		return false;
952 	}
953 
954 	return true;
955 }
956 
957 /**
958  * Return true if the player can read scrolls or books.
959  *
960  * \param p is the player
961  * \param show_msg should be set to true if a failure message should be
962  * displayed.
963  */
player_can_read(struct player * p,bool show_msg)964 bool player_can_read(struct player *p, bool show_msg)
965 {
966 	if (p->timed[TMD_BLIND]) {
967 		if (show_msg)
968 			msg("You can't see anything.");
969 
970 		return false;
971 	}
972 
973 	if (no_light()) {
974 		if (show_msg)
975 			msg("You have no light to read by.");
976 
977 		return false;
978 	}
979 
980 	if (p->timed[TMD_CONFUSED]) {
981 		if (show_msg)
982 			msg("You are too confused to read!");
983 
984 		return false;
985 	}
986 
987 	if (p->timed[TMD_AMNESIA]) {
988 		if (show_msg)
989 			msg("You can't remember how to read!");
990 
991 		return false;
992 	}
993 
994 	return true;
995 }
996 
997 /**
998  * Return true if the player can fire something with a launcher.
999  *
1000  * \param p is the player
1001  * \param show_msg should be set to true if a failure message should be
1002  * displayed.
1003  */
player_can_fire(struct player * p,bool show_msg)1004 bool player_can_fire(struct player *p, bool show_msg)
1005 {
1006 	struct object *obj = equipped_item_by_slot_name(p, "shooting");
1007 
1008 	/* Require a usable launcher */
1009 	if (!obj || !p->state.ammo_tval) {
1010 		if (show_msg)
1011 			msg("You have nothing to fire with.");
1012 		return false;
1013 	}
1014 
1015 	return true;
1016 }
1017 
1018 /**
1019  * Return true if the player can refuel their light source.
1020  *
1021  * \param p is the player
1022  * \param show_msg should be set to true if a failure message should be
1023  * displayed.
1024  */
player_can_refuel(struct player * p,bool show_msg)1025 bool player_can_refuel(struct player *p, bool show_msg)
1026 {
1027 	struct object *obj = equipped_item_by_slot_name(p, "light");
1028 
1029 	if (obj && of_has(obj->flags, OF_TAKES_FUEL)) {
1030 		return true;
1031 	}
1032 
1033 	if (show_msg) {
1034 		msg("Your light cannot be refuelled.");
1035 	}
1036 
1037 	return false;
1038 }
1039 
1040 /**
1041  * Prerequiste function for command. See struct cmd_info in cmd-process.c.
1042  */
player_can_cast_prereq(void)1043 bool player_can_cast_prereq(void)
1044 {
1045 	return player_can_cast(player, true);
1046 }
1047 
1048 /**
1049  * Prerequiste function for command. See struct cmd_info in cmd-process.c.
1050  */
player_can_study_prereq(void)1051 bool player_can_study_prereq(void)
1052 {
1053 	return player_can_study(player, true);
1054 }
1055 
1056 /**
1057  * Prerequiste function for command. See struct cmd_info in cmd-process.c.
1058  */
player_can_read_prereq(void)1059 bool player_can_read_prereq(void)
1060 {
1061 	return player_can_read(player, true);
1062 }
1063 
1064 /**
1065  * Prerequiste function for command. See struct cmd_info in cmd-process.c.
1066  */
player_can_fire_prereq(void)1067 bool player_can_fire_prereq(void)
1068 {
1069 	return player_can_fire(player, true);
1070 }
1071 
1072 /**
1073  * Prerequiste function for command. See struct cmd_info in cmd-process.c.
1074  */
player_can_refuel_prereq(void)1075 bool player_can_refuel_prereq(void)
1076 {
1077 	return player_can_refuel(player, true);
1078 }
1079 
1080 /**
1081  * Return true if the player has access to a book that has unlearned spells.
1082  *
1083  * \param p is the player
1084  */
player_book_has_unlearned_spells(struct player * p)1085 bool player_book_has_unlearned_spells(struct player *p)
1086 {
1087 	int i, j;
1088 	int item_max = z_info->pack_size + z_info->floor_size;
1089 	struct object **item_list = mem_zalloc(item_max * sizeof(struct object *));
1090 	int item_num;
1091 
1092 	/* Check if the player can learn new spells */
1093 	if (!p->upkeep->new_spells) {
1094 		mem_free(item_list);
1095 		return false;
1096 	}
1097 
1098 	/* Check through all available books */
1099 	item_num = scan_items(item_list, item_max, USE_INVEN | USE_FLOOR,
1100 						  obj_can_study);
1101 	for (i = 0; i < item_num; i++) {
1102 		const struct class_book *book = player_object_to_book(p, item_list[i]);
1103 		if (!book) continue;
1104 
1105 		/* Extract spells */
1106 		for (j = 0; j < book->num_spells; j++)
1107 			if (spell_okay_to_study(book->spells[j].sidx)) {
1108 				/* There is a spell the player can study */
1109 				mem_free(item_list);
1110 				return true;
1111 			}
1112 	}
1113 
1114 	mem_free(item_list);
1115 	return false;
1116 }
1117 
1118 /**
1119  * Apply confusion, if needed, to a direction
1120  *
1121  * Display a message and return true if direction changes.
1122  */
player_confuse_dir(struct player * p,int * dp,bool too)1123 bool player_confuse_dir(struct player *p, int *dp, bool too)
1124 {
1125 	int dir = *dp;
1126 
1127 	if (p->timed[TMD_CONFUSED]) {
1128 		if ((dir == 5) || (randint0(100) < 75)) {
1129 			/* Random direction */
1130 			dir = ddd[randint0(8)];
1131 		}
1132 
1133 	/* Running attempts always fail */
1134 	if (too) {
1135 		msg("You are too confused.");
1136 		return true;
1137 	}
1138 
1139 	if (*dp != dir) {
1140 		msg("You are confused.");
1141 		*dp = dir;
1142 		return true;
1143 	}
1144 	}
1145 
1146 	return false;
1147 }
1148 
1149 /**
1150  * Return true if the provided count is one of the conditional REST_ flags.
1151  */
player_resting_is_special(s16b count)1152 bool player_resting_is_special(s16b count)
1153 {
1154 	switch (count) {
1155 		case REST_COMPLETE:
1156 		case REST_ALL_POINTS:
1157 		case REST_SOME_POINTS:
1158 			return true;
1159 	}
1160 
1161 	return false;
1162 }
1163 
1164 /**
1165  * Return true if the player is resting.
1166  */
player_is_resting(struct player * p)1167 bool player_is_resting(struct player *p)
1168 {
1169 	return (p->upkeep->resting > 0 ||
1170 			player_resting_is_special(p->upkeep->resting));
1171 }
1172 
1173 /**
1174  * Return the remaining number of resting turns.
1175  */
player_resting_count(struct player * p)1176 s16b player_resting_count(struct player *p)
1177 {
1178 	return p->upkeep->resting;
1179 }
1180 
1181 /**
1182  * In order to prevent the regeneration bonus from the first few turns, we have
1183  * to store the number of turns the player has rested. Otherwise, the first
1184  * few turns will have the bonus and the last few will not.
1185  */
1186 static int player_turns_rested = 0;
1187 static bool player_rest_disturb = false;
1188 
1189 /**
1190  * Set the number of resting turns.
1191  *
1192  * \param count is the number of turns to rest or one of the REST_ constants.
1193  */
player_resting_set_count(struct player * p,s16b count)1194 void player_resting_set_count(struct player *p, s16b count)
1195 {
1196 	/* Cancel if player is disturbed */
1197 	if (player_rest_disturb) {
1198 		p->upkeep->resting = 0;
1199 		player_rest_disturb = false;
1200 		return;
1201 	}
1202 
1203 	/* Ignore if the rest count is negative. */
1204 	if ((count < 0) && !player_resting_is_special(count)) {
1205 		p->upkeep->resting = 0;
1206 		return;
1207 	}
1208 
1209 	/* Save the rest code */
1210 	p->upkeep->resting = count;
1211 
1212 	/* Truncate overlarge values */
1213 	if (p->upkeep->resting > 9999) p->upkeep->resting = 9999;
1214 }
1215 
1216 /**
1217  * Cancel current rest.
1218  */
player_resting_cancel(struct player * p,bool disturb)1219 void player_resting_cancel(struct player *p, bool disturb)
1220 {
1221 	player_resting_set_count(p, 0);
1222 	player_turns_rested = 0;
1223 	player_rest_disturb = disturb;
1224 }
1225 
1226 /**
1227  * Return true if the player should get a regeneration bonus for the current
1228  * rest.
1229  */
player_resting_can_regenerate(struct player * p)1230 bool player_resting_can_regenerate(struct player *p)
1231 {
1232 	return player_turns_rested >= REST_REQUIRED_FOR_REGEN ||
1233 		player_resting_is_special(p->upkeep->resting);
1234 }
1235 
1236 /**
1237  * Perform one turn of resting. This only handles the bookkeeping of resting
1238  * itself, and does not calculate any possible other effects of resting (see
1239  * process_world() for regeneration).
1240  */
player_resting_step_turn(struct player * p)1241 void player_resting_step_turn(struct player *p)
1242 {
1243 	/* Timed rest */
1244 	if (p->upkeep->resting > 0) {
1245 		/* Reduce rest count */
1246 		p->upkeep->resting--;
1247 
1248 		/* Redraw the state */
1249 		p->upkeep->redraw |= (PR_STATE);
1250 	}
1251 
1252 	/* Take a turn */
1253 	p->upkeep->energy_use = z_info->move_energy;
1254 
1255 	/* Increment the resting counters */
1256 	p->resting_turn++;
1257 	player_turns_rested++;
1258 }
1259 
1260 /**
1261  * Handle the conditions for conditional resting (resting with the REST_
1262  * constants).
1263  */
player_resting_complete_special(struct player * p)1264 void player_resting_complete_special(struct player *p)
1265 {
1266 	/* Complete resting */
1267 	if (!player_resting_is_special(p->upkeep->resting)) return;
1268 
1269 	if (p->upkeep->resting == REST_ALL_POINTS) {
1270 		if ((p->chp == p->mhp) && (p->csp == p->msp))
1271 			/* Stop resting */
1272 			disturb(p);
1273 	} else if (p->upkeep->resting == REST_COMPLETE) {
1274 		if ((p->chp == p->mhp) &&
1275 			(p->csp == p->msp || player_has(p, PF_COMBAT_REGEN)) &&
1276 			!p->timed[TMD_BLIND] && !p->timed[TMD_CONFUSED] &&
1277 			!p->timed[TMD_POISONED] && !p->timed[TMD_AFRAID] &&
1278 			!p->timed[TMD_TERROR] && !p->timed[TMD_STUN] &&
1279 			!p->timed[TMD_CUT] && !p->timed[TMD_SLOW] &&
1280 			!p->timed[TMD_PARALYZED] && !p->timed[TMD_IMAGE] &&
1281 			!p->word_recall && !p->deep_descent)
1282 			/* Stop resting */
1283 			disturb(p);
1284 	} else if (p->upkeep->resting == REST_SOME_POINTS) {
1285 		if ((p->chp == p->mhp) || (p->csp == p->msp))
1286 			/* Stop resting */
1287 			disturb(p);
1288 	}
1289 }
1290 
1291 /* Record the player's last rest count for repeating */
1292 static int player_resting_repeat_count = 0;
1293 
1294 /**
1295  * Get the number of resting turns to repeat.
1296  *
1297  * \param p The current player.
1298  */
player_get_resting_repeat_count(struct player * p)1299 int player_get_resting_repeat_count(struct player *p)
1300 {
1301 	return player_resting_repeat_count;
1302 }
1303 
1304 /**
1305  * Set the number of resting turns to repeat.
1306  *
1307  * \param count is the number of turns requested for rest most recently.
1308  */
player_set_resting_repeat_count(struct player * p,s16b count)1309 void player_set_resting_repeat_count(struct player *p, s16b count)
1310 {
1311 	player_resting_repeat_count = count;
1312 }
1313 
1314 /**
1315  * Check if the player state has the given OF_ flag.
1316  */
player_of_has(struct player * p,int flag)1317 bool player_of_has(struct player *p, int flag)
1318 {
1319 	assert(p);
1320 	return of_has(p->state.flags, flag);
1321 }
1322 
1323 /**
1324  * Check if the player resists (or better) an element
1325  */
player_resists(struct player * p,int element)1326 bool player_resists(struct player *p, int element)
1327 {
1328 	return (p->state.el_info[element].res_level > 0);
1329 }
1330 
1331 /**
1332  * Check if the player resists (or better) an element
1333  */
player_is_immune(struct player * p,int element)1334 bool player_is_immune(struct player *p, int element)
1335 {
1336 	return (p->state.el_info[element].res_level == 3);
1337 }
1338 
1339 /**
1340  * Places the player at the given coordinates in the cave.
1341  */
player_place(struct chunk * c,struct player * p,struct loc grid)1342 void player_place(struct chunk *c, struct player *p, struct loc grid)
1343 {
1344 	assert(!square_monster(c, grid));
1345 
1346 	/* Save player location */
1347 	p->grid = grid;
1348 
1349 	/* Mark cave grid */
1350 	square_set_mon(c, grid, -1);
1351 
1352 	/* Clear stair creation */
1353 	p->upkeep->create_down_stair = false;
1354 	p->upkeep->create_up_stair = false;
1355 }
1356 
1357 /*
1358  * Something has happened to disturb the player.
1359  *
1360  * The first arg indicates a major disturbance, which affects search.
1361  *
1362  * The second arg is currently unused, but could induce output flush.
1363  *
1364  * All disturbance cancels repeated commands, resting, and running.
1365  *
1366  * XXX-AS: Make callers either pass in a command
1367  * or call cmd_cancel_repeat inside the function calling this
1368  */
disturb(struct player * p)1369 void disturb(struct player *p)
1370 {
1371 	/* Cancel repeated commands */
1372 	cmd_cancel_repeat();
1373 
1374 	/* Cancel Resting */
1375 	if (player_is_resting(p)) {
1376 		player_resting_cancel(p, true);
1377 		p->upkeep->redraw |= PR_STATE;
1378 	}
1379 
1380 	/* Cancel running */
1381 	if (p->upkeep->running) {
1382 		p->upkeep->running = 0;
1383 
1384 		/* Cancel queued commands */
1385 		cmdq_flush();
1386 
1387 		/* Check for new panel if appropriate */
1388 		event_signal(EVENT_PLAYERMOVED);
1389 		p->upkeep->update |= PU_TORCH;
1390 
1391 		/* Mark the whole map to be redrawn */
1392 		event_signal_point(EVENT_MAP, -1, -1);
1393 	}
1394 
1395 	/* Flush input */
1396 	event_signal(EVENT_INPUT_FLUSH);
1397 }
1398 
1399 /**
1400  * Search for traps or secret doors
1401  */
search(struct player * p)1402 void search(struct player *p)
1403 {
1404 	struct loc grid;
1405 
1406 	/* Various conditions mean no searching */
1407 	if (p->timed[TMD_BLIND] || no_light() ||
1408 		p->timed[TMD_CONFUSED] || p->timed[TMD_IMAGE])
1409 		return;
1410 
1411 	/* Search the nearby grids, which are always in bounds */
1412 	for (grid.y = (p->grid.y - 1); grid.y <= (p->grid.y + 1); grid.y++) {
1413 		for (grid.x = (p->grid.x - 1); grid.x <= (p->grid.x + 1); grid.x++) {
1414 			struct object *obj;
1415 
1416 			/* Secret doors */
1417 			if (square_issecretdoor(cave, grid)) {
1418 				msg("You have found a secret door.");
1419 				place_closed_door(cave, grid);
1420 				disturb(p);
1421 			}
1422 
1423 			/* Traps on chests */
1424 			for (obj = square_object(cave, grid); obj; obj = obj->next) {
1425 				if (!obj->known || !is_trapped_chest(obj))
1426 					continue;
1427 
1428 				if (obj->known->pval != obj->pval) {
1429 					msg("You have discovered a trap on the chest!");
1430 					obj->known->pval = obj->pval;
1431 					disturb(p);
1432 				}
1433 			}
1434 		}
1435 	}
1436 }
1437