1 /**
2  * \file game-world.c
3  * \brief Game core management of the game world
4  *
5  * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
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 "cmds.h"
21 #include "effects.h"
22 #include "game-world.h"
23 #include "generate.h"
24 #include "init.h"
25 #include "mon-make.h"
26 #include "mon-move.h"
27 #include "mon-util.h"
28 #include "obj-curse.h"
29 #include "obj-desc.h"
30 #include "obj-gear.h"
31 #include "obj-knowledge.h"
32 #include "obj-tval.h"
33 #include "obj-util.h"
34 #include "player-calcs.h"
35 #include "player-timed.h"
36 #include "player-util.h"
37 #include "source.h"
38 #include "target.h"
39 #include "trap.h"
40 #include "z-queue.h"
41 
42 u16b daycount = 0;
43 u32b seed_randart;		/* Hack -- consistent random artifacts */
44 u32b seed_flavor;		/* Hack -- consistent object colors */
45 s32b turn;				/* Current game turn */
46 bool character_generated;	/* The character exists */
47 bool character_dungeon;		/* The character has a dungeon */
48 struct level *world;
49 
50 /**
51  * This table allows quick conversion from "speed" to "energy"
52  * The basic function WAS ((S>=110) ? (S-110) : (100 / (120-S)))
53  * Note that table access is *much* quicker than computation.
54  *
55  * Note that the table has been changed at high speeds.  From
56  * "Slow (-40)" to "Fast (+30)" is pretty much unchanged, but
57  * at speeds above "Fast (+30)", one approaches an asymptotic
58  * effective limit of 50 energy per turn.  This means that it
59  * is relatively easy to reach "Fast (+30)" and get about 40
60  * energy per turn, but then speed becomes very "expensive",
61  * and you must get all the way to "Fast (+50)" to reach the
62  * point of getting 45 energy per turn.  After that point,
63  * furthur increases in speed are more or less pointless,
64  * except to balance out heavy inventory.
65  *
66  * Note that currently the fastest monster is "Fast (+30)".
67  */
68 const byte extract_energy[200] =
69 {
70 	/* Slow */     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
71 	/* Slow */     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
72 	/* Slow */     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
73 	/* Slow */     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
74 	/* Slow */     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
75 	/* Slow */     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
76 	/* S-50 */     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
77 	/* S-40 */     2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
78 	/* S-30 */     2,  2,  2,  2,  2,  2,  2,  3,  3,  3,
79 	/* S-20 */     3,  3,  3,  3,  3,  4,  4,  4,  4,  4,
80 	/* S-10 */     5,  5,  5,  5,  6,  6,  7,  7,  8,  9,
81 	/* Norm */    10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
82 	/* F+10 */    20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
83 	/* F+20 */    30, 31, 32, 33, 34, 35, 36, 36, 37, 37,
84 	/* F+30 */    38, 38, 39, 39, 40, 40, 40, 41, 41, 41,
85 	/* F+40 */    42, 42, 42, 43, 43, 43, 44, 44, 44, 44,
86 	/* F+50 */    45, 45, 45, 45, 45, 46, 46, 46, 46, 46,
87 	/* F+60 */    47, 47, 47, 47, 47, 48, 48, 48, 48, 48,
88 	/* F+70 */    49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
89 	/* Fast */    49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
90 };
91 
92 /**
93  * Find a level by its name
94  */
level_by_name(char * name)95 struct level *level_by_name(char *name)
96 {
97 	struct level *lev = world;
98 	while (lev) {
99 		if (streq(lev->name, name)) {
100 			break;
101 		}
102 		lev = lev->next;
103 	}
104 	return lev;
105 }
106 
107 /**
108  * Find a level by its depth
109  */
level_by_depth(int depth)110 struct level *level_by_depth(int depth)
111 {
112 	struct level *lev = world;
113 	while (lev) {
114 		if (lev->depth == depth) {
115 			break;
116 		}
117 		lev = lev->next;
118 	}
119 	return lev;
120 }
121 
122 /**
123  * Say whether it's daytime or not
124  */
is_daytime(void)125 bool is_daytime(void)
126 {
127 	if ((turn % (10L * z_info->day_length)) < ((10L * z_info->day_length) / 2))
128 		return true;
129 
130 	return false;
131 }
132 
133 /**
134  * The amount of energy gained in a turn by a player or monster
135  */
turn_energy(int speed)136 int turn_energy(int speed)
137 {
138 	return extract_energy[speed] * z_info->move_energy / 100;
139 }
140 
141 /**
142  * If player has inscribed the object with "!!", let him know when it's
143  * recharged. -LM-
144  * Also inform player when first item of a stack has recharged. -HK-
145  * Notify all recharges w/o inscription if notify_recharge option set -WP-
146  */
recharged_notice(const struct object * obj,bool all)147 static void recharged_notice(const struct object *obj, bool all)
148 {
149 	char o_name[120];
150 
151 	const char *s;
152 
153 	bool notify = false;
154 
155 	if (OPT(player, notify_recharge)) {
156 		notify = true;
157 	} else if (obj->note) {
158 		/* Find a '!' */
159 		s = strchr(quark_str(obj->note), '!');
160 
161 		/* Process notification request */
162 		while (s) {
163 			/* Find another '!' */
164 			if (s[1] == '!') {
165 				notify = true;
166 				break;
167 			}
168 
169 			/* Keep looking for '!'s */
170 			s = strchr(s + 1, '!');
171 		}
172 	}
173 
174 	if (!notify) return;
175 
176 	/* Describe (briefly) */
177 	object_desc(o_name, sizeof(o_name), obj, ODESC_BASE);
178 
179 	/* Disturb the player */
180 	disturb(player);
181 
182 	/* Notify the player */
183 	if (obj->number > 1) {
184 		if (all) msg("Your %s have recharged.", o_name);
185 		else msg("One of your %s has recharged.", o_name);
186 	} else if (obj->artifact)
187 		msg("The %s has recharged.", o_name);
188 	else
189 		msg("Your %s has recharged.", o_name);
190 }
191 
192 
193 /**
194  * Recharge activatable objects in the player's equipment
195  * and rods in the inventory and on the ground.
196  */
recharge_objects(void)197 static void recharge_objects(void)
198 {
199 	int i;
200 	bool discharged_stack;
201 	struct object *obj;
202 
203 	/* Recharge carried gear */
204 	for (obj = player->gear; obj; obj = obj->next) {
205 		/* Skip non-objects */
206 		assert(obj->kind);
207 
208 		/* Recharge equipment */
209 		if (object_is_equipped(player->body, obj)) {
210 			/* Recharge activatable objects */
211 			if (recharge_timeout(obj)) {
212 				/* Message if an item recharged */
213 				recharged_notice(obj, true);
214 
215 				/* Window stuff */
216 				player->upkeep->redraw |= (PR_EQUIP);
217 			}
218 		} else {
219 			/* Recharge the inventory */
220 			discharged_stack =
221 				(number_charging(obj) == obj->number) ? true : false;
222 
223 			/* Recharge rods, and update if any rods are recharged */
224 			if (tval_can_have_timeout(obj) && recharge_timeout(obj)) {
225 				/* Entire stack is recharged */
226 				if (obj->timeout == 0)
227 					recharged_notice(obj, true);
228 
229 				/* Previously exhausted stack has acquired a charge */
230 				else if (discharged_stack)
231 					recharged_notice(obj, false);
232 
233 				/* Combine pack */
234 				player->upkeep->notice |= (PN_COMBINE);
235 
236 				/* Redraw stuff */
237 				player->upkeep->redraw |= (PR_INVEN);
238 			}
239 		}
240 	}
241 
242 	/* Recharge other level objects */
243 	for (i = 1; i < cave->obj_max; i++) {
244 		obj = cave->objects[i];
245 		if (!obj) continue;
246 
247 		/* Recharge rods */
248 		if (tval_can_have_timeout(obj))
249 			recharge_timeout(obj);
250 	}
251 }
252 
253 
254 /**
255  * Play an ambient sound dependent on dungeon level, and day or night in town
256  */
play_ambient_sound(void)257 void play_ambient_sound(void)
258 {
259 	if (player->depth == 0) {
260 		if (is_daytime())
261 			sound(MSG_AMBIENT_DAY);
262 		else
263 			sound(MSG_AMBIENT_NITE);
264 	} else if (player->depth <= 20) {
265 		sound(MSG_AMBIENT_DNG1);
266 	} else if (player->depth <= 40) {
267 		sound(MSG_AMBIENT_DNG2);
268 	} else if (player->depth <= 60) {
269 		sound(MSG_AMBIENT_DNG3);
270 	} else if (player->depth <= 80) {
271 		sound(MSG_AMBIENT_DNG4);
272 	} else {
273 		sound(MSG_AMBIENT_DNG5);
274 	}
275 }
276 
277 /**
278  * Helper for process_world -- decrement player->timed[] and curse effect fields
279  */
decrease_timeouts(void)280 static void decrease_timeouts(void)
281 {
282 	int adjust = (adj_con_fix[player->state.stat_ind[STAT_CON]] + 1);
283 	int i;
284 
285 	/* Most timed effects decrement by 1 */
286 	for (i = 0; i < TMD_MAX; i++) {
287 		int decr = 1;
288 		if (!player->timed[i])
289 			continue;
290 
291 		/* Special cases */
292 		switch (i) {
293             case TMD_FOOD:
294             {
295                 /* Handled separately */
296                 decr = 0;
297                 break;
298             }
299 
300 			case TMD_CUT:
301 			{
302 				/* Check for truly "mortal" wound */
303 				if (player_timed_grade_eq(player, i, "Mortal Wound")) {
304 					decr = 0;
305 				} else {
306 					decr = adjust;
307 				}
308 
309 				/* Rock players just maintain */
310 				if (player_has(player, PF_ROCK)) {
311 					decr = 0;
312 				}
313 
314 				break;
315 			}
316 
317 			case TMD_POISONED:
318 			case TMD_STUN:
319 			{
320 				decr = adjust;
321 				break;
322 			}
323 
324 			case TMD_COMMAND:
325 			{
326 				struct monster *mon = get_commanded_monster();
327 				if (!los(cave, player->grid, mon->grid)) {
328 					/* Out of sight is out of mind */
329 					mon_clear_timed(mon, MON_TMD_COMMAND, MON_TMD_FLG_NOTIFY);
330 					player_clear_timed(player, TMD_COMMAND, true);
331 				} else {
332 					/* Keep monster timer aligned */
333 					mon_dec_timed(mon, MON_TMD_COMMAND, decr, 0);
334 				}
335 				break;
336 			}
337 		}
338 		/* Decrement the effect */
339 		player_dec_timed(player, i, decr, false);
340 	}
341 
342 	/* Curse effects always decrement by 1 */
343 	for (i = 0; i < player->body.count; i++) {
344 		struct curse_data *curse = NULL;
345 		if (player->body.slots[i].obj == NULL) {
346 			continue;
347 		}
348 		curse = player->body.slots[i].obj->curses;
349 		if (curse) {
350 			int j;
351 			for (j = 0; j < z_info->curse_max; j++) {
352 				if (curse[j].power) {
353 					curse[j].timeout--;
354 					if (!curse[j].timeout) {
355 						struct curse *c = &curses[j];
356 						if (do_curse_effect(j, player->body.slots[i].obj)) {
357 							player_learn_curse(player, c);
358 						}
359 						curse[j].timeout = randcalc(c->obj->time, 0, RANDOMISE);
360 					}
361 				}
362 			}
363 		}
364 	}
365 
366 	return;
367 }
368 
369 
370 /**
371  * Every turn, the character makes enough noise that nearby monsters can use
372  * it to home in.
373  *
374  * This function actually just computes distance from the player; this is
375  * used in combination with the player's stealth value to determine what
376  * monsters can hear.  We mark the player's grid with 0, then fill in the noise
377  * field of every grid that the player can reach with that "noise"
378  * (actally distance) plus the number of steps needed to reach that grid
379  * - so higher values mean further from the player.
380  *
381  * Monsters use this information by moving to adjacent grids with lower noise
382  * values, thereby homing in on the player even though twisty tunnels and
383  * mazes.  Monsters have a hearing value, which is the largest sound value
384  * they can detect.
385  */
make_noise(struct player * p)386 static void make_noise(struct player *p)
387 {
388 	struct loc next = p->grid;
389 	int y, x, d;
390 	int noise = 0;
391 	int noise_increment = p->timed[TMD_COVERTRACKS] ? 4 : 1;
392     struct queue *queue = q_new(cave->height * cave->width);
393 	struct loc decoy = cave_find_decoy(cave);
394 
395 	/* Set all the grids to silence */
396 	for (y = 1; y < cave->height - 1; y++) {
397 		for (x = 1; x < cave->width - 1; x++) {
398 			cave->noise.grids[y][x] = 0;
399 		}
400 	}
401 
402 	/* If there's a decoy, use that instead of the player */
403 	if (!loc_is_zero(decoy)) {
404 		next = decoy;
405 	}
406 
407 	/* Player makes noise */
408 	cave->noise.grids[next.y][next.x] = noise;
409 	q_push_int(queue, grid_to_i(next, cave->width));
410 	noise += noise_increment;
411 
412 	/* Propagate noise */
413 	while (q_len(queue) > 0) {
414 		/* Get the next grid */
415 		i_to_grid(q_pop_int(queue), cave->width, &next);
416 
417 		/* If we've reached the current noise level, put it back and step */
418 		if (cave->noise.grids[next.y][next.x] == noise) {
419 			q_push_int(queue, grid_to_i(next, cave->width));
420 			noise += noise_increment;
421 			continue;
422 		}
423 
424 		/* Assign noise to the children and enqueue them */
425 		for (d = 0; d < 8; d++)	{
426 			/* Child location */
427 			struct loc grid = loc_sum(next, ddgrid_ddd[d]);
428 
429 			if (!square_in_bounds(cave, grid)) continue;
430 
431 			/* Ignore features that don't transmit sound */
432 			if (square_isnoflow(cave, grid)) continue;
433 
434 			/* Skip grids that already have noise */
435 			if (cave->noise.grids[grid.y][grid.x] != 0) continue;
436 
437 			/* Skip the player grid */
438 			if (loc_eq(p->grid, grid)) continue;
439 
440 			/* Save the noise */
441 			cave->noise.grids[grid.y][grid.x] = noise;
442 
443 			/* Enqueue that entry */
444 			q_push_int(queue, grid_to_i(grid, cave->width));
445 		}
446 	}
447 
448 	q_free(queue);
449 }
450 
451 /**
452  * Characters leave scent trails for perceptive monsters to track.
453  *
454  * Scent is rather more limited than sound.  Many creatures cannot use
455  * it at all, it doesn't extend very far outwards from the character's
456  * current position, and monsters can use it to home in the character,
457  * but not to run away.
458  *
459  * Scent is valued according to age.  When a character takes his turn,
460  * scent is aged by one, and new scent is laid down.  Monsters have a smell
461  * value which indicates the oldest scent they can detect.  Grids where the
462  * player has never been will have scent 0.  The player's grid will also have
463  * scent 0, but this is OK as no monster will ever be smelling it.
464  */
update_scent(void)465 static void update_scent(void)
466 {
467 	int y, x;
468 	int scent_strength[5][5] = {
469 		{2, 2, 2, 2, 2},
470 		{2, 1, 1, 1, 2},
471 		{2, 1, 0, 1, 2},
472 		{2, 1, 1, 1, 2},
473 		{2, 2, 2, 2, 2},
474 	};
475 
476 	/* Update scent for all grids */
477 	for (y = 1; y < cave->height - 1; y++) {
478 		for (x = 1; x < cave->width - 1; x++) {
479 			if (cave->scent.grids[y][x] > 0) {
480 				cave->scent.grids[y][x]++;
481 			}
482 		}
483 	}
484 
485 	/* Scentless player */
486 	if (player->timed[TMD_COVERTRACKS]) return;
487 
488 	/* Lay down new scent around the player */
489 	for (y = 0; y < 5; y++) {
490 		for (x = 0; x < 5; x++) {
491 			struct loc scent;
492 			int new_scent = scent_strength[y][x];
493 			int d;
494 			bool add_scent = false;
495 
496 			/* Initialize */
497 			scent.y = y + player->grid.y - 2;
498 			scent.x = x + player->grid.x - 2;
499 
500 			/* Ignore invalid or non-scent-carrying grids */
501 			if (!square_in_bounds(cave, scent)) continue;
502 			if (square_isnoscent(cave, scent)) continue;
503 
504 			/* Check scent is spreading on floors, not going through walls */
505 			for (d = 0; d < 8; d++)	{
506 				struct loc adj = loc_sum(scent, ddgrid_ddd[d]);
507 
508 				if (!square_in_bounds(cave, adj)) {
509 					continue;
510 				}
511 
512 				/* Player grid is always valid */
513 				if (x == 2 && y == 2) {
514 					add_scent = true;
515 				}
516 
517 				/* Adjacent to a closer grid, so valid */
518 				if (cave->scent.grids[adj.y][adj.x] == new_scent - 1) {
519 					add_scent = true;
520 				}
521 			}
522 
523 			/* Not valid */
524 			if (!add_scent) {
525 				continue;
526 			}
527 
528 			/* Mark the scent */
529 			cave->scent.grids[scent.y][scent.x] = new_scent;
530 		}
531 	}
532 }
533 
534 /**
535  * Handle things that need updating once every 10 game turns
536  */
process_world(struct chunk * c)537 void process_world(struct chunk *c)
538 {
539 	int i, y, x;
540 
541 	/* Compact the monster list if we're approaching the limit */
542 	if (cave_monster_count(c) + 32 > z_info->level_monster_max)
543 		compact_monsters(64);
544 
545 	/* Too many holes in the monster list - compress */
546 	if (cave_monster_count(c) + 32 < cave_monster_max(c))
547 		compact_monsters(0);
548 
549 	/*** Check the Time ***/
550 
551 	/* Play an ambient sound at regular intervals. */
552 	if (!(turn % ((10L * z_info->day_length) / 4)))
553 		play_ambient_sound();
554 
555 	/* Handle stores and sunshine */
556 	if (!player->depth) {
557 		/* Daybreak/Nighfall in town */
558 		if (!(turn % ((10L * z_info->day_length) / 2))) {
559 			/* Check for dawn */
560 			bool dawn = (!(turn % (10L * z_info->day_length)));
561 
562 			if (dawn) {
563 				/* Day breaks */
564 				msg("The sun has risen.");
565 			} else {
566 				/* Night falls */
567 				msg("The sun has fallen.");
568 			}
569 
570 			/* Illuminate */
571 			cave_illuminate(c, dawn);
572 		}
573 	} else {
574 		/* Update the stores once a day (while in the dungeon).
575 		   The changes are not actually made until return to town,
576 		   to avoid giving details away in the knowledge menu. */
577 		if (!(turn % (10L * z_info->store_turns))) daycount++;
578 	}
579 
580 	/* Check for light change */
581 	if (player_has(player, PF_UNLIGHT)) {
582 		player->upkeep->update |= PU_BONUS;
583 	}
584 
585 	/* Check for creature generation */
586 	if (one_in_(z_info->alloc_monster_chance))
587 		(void)pick_and_place_distant_monster(c, player, z_info->max_sight + 5,
588 											 true, player->depth);
589 
590 	/*** Damage (or healing) over Time ***/
591 
592 	/* Take damage from poison */
593 	if (player->timed[TMD_POISONED])
594 		take_hit(player, 1, "poison");
595 
596 	/* Take damage from cuts, worse from serious cuts */
597 	if (player->timed[TMD_CUT]) {
598 		if (player_has(player, PF_ROCK)) {
599 			/* Rock players just maintain */
600 			i = 0;
601 		} else if (player_timed_grade_eq(player, TMD_CUT, "Mortal Wound") ||
602 				   player_timed_grade_eq(player, TMD_CUT, "Deep Gash")) {
603 			i = 3;
604 		} else if (player_timed_grade_eq(player, TMD_CUT, "Severe Cut")) {
605 			i = 2;
606 		} else {
607 			i = 1;
608 		}
609 
610 		/* Take damage */
611 		take_hit(player, i, "a fatal wound");
612 	}
613 
614 	/* Side effects of diminishing bloodlust */
615 	if (player->timed[TMD_BLOODLUST]) {
616 		player_over_exert(player, PY_EXERT_HP | PY_EXERT_CUT | PY_EXERT_SLOW,
617 						  MAX(0, 10 - player->timed[TMD_BLOODLUST]),
618 						  player->chp / 10);
619 	}
620 
621 	/* Timed healing */
622 	if (player->timed[TMD_HEAL]) {
623 		bool ident = false;
624 		effect_simple(EF_HEAL_HP, source_player(), "30", 0, 0, 0, 0, 0, &ident);
625 	}
626 
627 	/* Effects of Black Breath */
628 	if (player->timed[TMD_BLACKBREATH]) {
629 		if (one_in_(2)) {
630 			msg("The Black Breath sickens you.");
631 			player_stat_dec(player, STAT_CON, false);
632 		}
633 		if (one_in_(2)) {
634 			msg("The Black Breath saps your strength.");
635 			player_stat_dec(player, STAT_STR, false);
636 		}
637 		if (one_in_(2)) {
638 			/* Life draining */
639 			int drain = 100 + (player->exp / 100) * z_info->life_drain_percent;
640 			msg("The Black Breath dims your life force.");
641 			player_exp_lose(player, drain, false);
642 		}
643 	}
644 
645 	/*** Check the Food, and Regenerate ***/
646 
647 	/* Digest */
648 	if (!player_timed_grade_eq(player, TMD_FOOD, "Full")) {
649 		/* Digest normally */
650 		if (!(turn % 100)) {
651 			/* Basic digestion rate based on speed */
652 			i = turn_energy(player->state.speed);
653 
654 			/* Adjust for food value */
655 			i = (i * 100) / z_info->food_value;
656 
657 			/* Regeneration takes more food */
658 			if (player_of_has(player, OF_REGEN)) i *= 2;
659 
660 			/* Slow digestion takes less food */
661 			if (player_of_has(player, OF_SLOW_DIGEST)) i /= 2;
662 
663 			/* Minimal digestion */
664 			if (i < 1) i = 1;
665 
666 			/* Digest some food */
667 			player_dec_timed(player, TMD_FOOD, i, false);
668 		}
669 
670 		/* Fast metabolism */
671 		if (player->timed[TMD_HEAL]) {
672 			player_dec_timed(player, TMD_FOOD, 8 * z_info->food_value, false);
673 			if (player->timed[TMD_FOOD] < PY_FOOD_HUNGRY) {
674 				player_set_timed(player, TMD_HEAL, 0, true);
675 			}
676 		}
677 	} else {
678 		/* Digest quickly when gorged */
679 		player_dec_timed(player, TMD_FOOD, 5000 / z_info->food_value, false);
680 		player->upkeep->update |= PU_BONUS;
681 	}
682 
683 	/* Faint or starving */
684 	if (player_timed_grade_eq(player, TMD_FOOD, "Faint")) {
685 		/* Faint occasionally */
686 		if (!player->timed[TMD_PARALYZED] && one_in_(10)) {
687 			/* Message */
688 			msg("You faint from the lack of food.");
689 			disturb(player);
690 
691 			/* Faint (bypass free action) */
692 			(void)player_inc_timed(player, TMD_PARALYZED, 1 + randint0(5),
693 								   true, false);
694 		}
695 	} else if (player_timed_grade_eq(player, TMD_FOOD, "Starving")) {
696 		/* Calculate damage */
697 		i = (PY_FOOD_STARVE - player->timed[TMD_FOOD]) / 10;
698 
699 		/* Take damage */
700 		take_hit(player, i, "starvation");
701 	}
702 
703 	/* Regenerate Hit Points if needed */
704 	if (player->chp < player->mhp)
705 		player_regen_hp(player);
706 
707 	/* Regenerate or lose mana */
708 	player_regen_mana(player);
709 
710 	/* Timeout various things */
711 	decrease_timeouts();
712 
713 	/* Process light */
714 	player_update_light(player);
715 
716 	/* Update noise and scent (not if resting) */
717 	if (!player_is_resting(player)) {
718 		make_noise(player);
719 		update_scent();
720 	}
721 
722 
723 	/*** Process Inventory ***/
724 
725 	/* Handle experience draining */
726 	if (player_of_has(player, OF_DRAIN_EXP)) {
727 		if ((player->exp > 0) && one_in_(10)) {
728 			s32b d = damroll(10, 6) +
729 				(player->exp / 100) * z_info->life_drain_percent;
730 			player_exp_lose(player, d / 10, false);
731 		}
732 
733 		equip_learn_flag(player, OF_DRAIN_EXP);
734 	}
735 
736 	/* Recharge activatable objects and rods */
737 	recharge_objects();
738 
739 	/* Notice things after time */
740 	if (!(turn % 100))
741 		equip_learn_after_time(player);
742 
743 	/* Decrease trap timeouts */
744 	for (y = 0; y < c->height; y++) {
745 		for (x = 0; x < c->width; x++) {
746 			struct loc grid = loc(x, y);
747 			struct trap *trap = square(c, grid)->trap;
748 			while (trap) {
749 				if (trap->timeout) {
750 					trap->timeout--;
751 					if (!trap->timeout)
752 						square_light_spot(c, grid);
753 				}
754 				trap = trap->next;
755 			}
756 		}
757 	}
758 
759 
760 	/*** Involuntary Movement ***/
761 
762 	/* Delayed Word-of-Recall */
763 	if (player->word_recall) {
764 		/* Count down towards recall */
765 		player->word_recall--;
766 
767 		/* Activate the recall */
768 		if (!player->word_recall) {
769 			/* Disturbing! */
770 			disturb(player);
771 
772 			/* Determine the level */
773 			if (player->depth) {
774 				msgt(MSG_TPLEVEL, "You feel yourself yanked upwards!");
775 				dungeon_change_level(player, 0);
776 			} else {
777 				msgt(MSG_TPLEVEL, "You feel yourself yanked downwards!");
778 				player_set_recall_depth(player);
779 				dungeon_change_level(player, player->recall_depth);
780 			}
781 		}
782 	}
783 
784 	/* Delayed Deep Descent */
785 	if (player->deep_descent) {
786 		/* Count down towards descent */
787 		player->deep_descent--;
788 
789 		/* Activate the descent */
790 		if (player->deep_descent == 0) {
791 			/* Calculate target depth */
792 			int target_increment = (4 / z_info->stair_skip) + 1;
793 			int target_depth = dungeon_get_next_level(player->max_depth,
794 													  target_increment);
795 			disturb(player);
796 
797 			/* Determine the level */
798 			if (target_depth > player->depth) {
799 				msgt(MSG_TPLEVEL, "The floor opens beneath you!");
800 				dungeon_change_level(player, target_depth);
801 			} else {
802 				/* Otherwise do something disastrous */
803 				msgt(MSG_TPLEVEL, "You are thrown back in an explosion!");
804 				effect_simple(EF_DESTRUCTION, source_none(), "0", 0, 5, 0, 0, 0, NULL);
805 			}
806 		}
807 	}
808 }
809 
810 
811 /**
812  * Housekeeping after the processing of a player command
813  */
process_player_cleanup(void)814 static void process_player_cleanup(void)
815 {
816 	int i;
817 
818 	/* Significant */
819 	if (player->upkeep->energy_use) {
820 		/* Use some energy */
821 		player->energy -= player->upkeep->energy_use;
822 
823 		/* Increment the total energy counter */
824 		player->total_energy += player->upkeep->energy_use;
825 
826 		/* Player can be damaged by terrain */
827 		player_take_terrain_damage(player, player->grid);
828 
829 		/* Do nothing else if player has auto-dropped stuff */
830 		if (!player->upkeep->dropping) {
831 			/* Hack -- constant hallucination */
832 			if (player->timed[TMD_IMAGE])
833 				player->upkeep->redraw |= (PR_MAP);
834 
835 			/* Shimmer multi-hued monsters */
836 			for (i = 1; i < cave_monster_max(cave); i++) {
837 				struct monster *mon = cave_monster(cave, i);
838 				if (!mon->race)
839 					continue;
840 				if (!rf_has(mon->race->flags, RF_ATTR_MULTI))
841 					continue;
842 				square_light_spot(cave, mon->grid);
843 			}
844 
845 			/* Clear NICE flag, and show marked monsters */
846 			for (i = 1; i < cave_monster_max(cave); i++) {
847 				struct monster *mon = cave_monster(cave, i);
848 				mflag_off(mon->mflag, MFLAG_NICE);
849 				if (mflag_has(mon->mflag, MFLAG_MARK)) {
850 					if (!mflag_has(mon->mflag, MFLAG_SHOW)) {
851 						mflag_off(mon->mflag, MFLAG_MARK);
852 						update_mon(mon, cave, false);
853 					}
854 				}
855 			}
856 		}
857 	}
858 
859 	/* Clear SHOW flag and player drop status */
860 	for (i = 1; i < cave_monster_max(cave); i++) {
861 		struct monster *mon = cave_monster(cave, i);
862 		mflag_off(mon->mflag, MFLAG_SHOW);
863 	}
864 	player->upkeep->dropping = false;
865 
866 	/* Hack - update needed first because inventory may have changed */
867 	update_stuff(player);
868 	redraw_stuff(player);
869 }
870 
871 
872 /**
873  * Process player commands from the command queue, finishing when there is a
874  * command using energy (any regular game command), or we run out of commands
875  * and need another from the user, or the character changes level or dies, or
876  * the game is stopped.
877  *
878  * Notice the annoying code to handle "pack overflow", which
879  * must come first just in case somebody manages to corrupt
880  * the savefiles by clever use of menu commands or something. (Can go? NRM)
881  *
882  * Notice the annoying code to handle "monster memory" changes,
883  * which allows us to avoid having to update the window flags
884  * every time we change any internal monster memory field, and
885  * also reduces the number of times that the recall window must
886  * be redrawn.
887  */
process_player(void)888 void process_player(void)
889 {
890 	/* Check for interrupts */
891 	player_resting_complete_special(player);
892 	event_signal(EVENT_CHECK_INTERRUPT);
893 
894 	/* Repeat until energy is reduced */
895 	do {
896 		/* Refresh */
897 		notice_stuff(player);
898 		handle_stuff(player);
899 		event_signal(EVENT_REFRESH);
900 
901 		/* Hack -- Pack Overflow */
902 		pack_overflow(NULL);
903 
904 		/* Assume free turn */
905 		player->upkeep->energy_use = 0;
906 
907 		/* Dwarves detect treasure */
908 		if (player_has(player, PF_SEE_ORE)) {
909 			/* Only if they are in good shape */
910 			if (!player->timed[TMD_IMAGE] &&
911 				!player->timed[TMD_CONFUSED] &&
912 				!player->timed[TMD_AMNESIA] &&
913 				!player->timed[TMD_STUN] &&
914 				!player->timed[TMD_PARALYZED] &&
915 				!player->timed[TMD_TERROR] &&
916 				!player->timed[TMD_AFRAID])
917 				effect_simple(EF_DETECT_GOLD, source_none(), "0", 0, 0, 0, 3, 3, NULL);
918 		}
919 
920 		/* Paralyzed or Knocked Out player gets no turn */
921 		if (player->timed[TMD_PARALYZED] ||
922 			player_timed_grade_eq(player, TMD_STUN, "Knocked Out")) {
923 			cmdq_push(CMD_SLEEP);
924 		}
925 
926 		/* Prepare for the next command */
927 		if (cmd_get_nrepeats() > 0) {
928 			event_signal(EVENT_COMMAND_REPEAT);
929 		} else {
930 			/* Check monster recall */
931 			if (player->upkeep->monster_race)
932 				player->upkeep->redraw |= (PR_MONSTER);
933 
934 			/* Place cursor on player/target */
935 			event_signal(EVENT_REFRESH);
936 		}
937 
938 		/* Get a command from the queue if there is one */
939 		if (!cmdq_pop(CTX_GAME))
940 			break;
941 
942 		if (!player->upkeep->playing)
943 			break;
944 
945 		process_player_cleanup();
946 	} while (!player->upkeep->energy_use &&
947 			 !player->is_dead &&
948 			 !player->upkeep->generate_level);
949 
950 	/* Notice stuff (if needed) */
951 	notice_stuff(player);
952 }
953 
954 /**
955  * Housekeeping on arriving on a new level
956  */
on_new_level(void)957 void on_new_level(void)
958 {
959 	/* Arena levels are not really a level change */
960 	if (!player->upkeep->arena_level) {
961 		/* Play ambient sound on change of level. */
962 		play_ambient_sound();
963 
964 		/* Cancel the target */
965 		target_set_monster(0);
966 
967 		/* Cancel the health bar */
968 		health_track(player->upkeep, NULL);
969 	}
970 
971 	/* Disturb */
972 	disturb(player);
973 
974 	/* Track maximum player level */
975 	if (player->max_lev < player->lev)
976 		player->max_lev = player->lev;
977 
978 	/* Track maximum dungeon level */
979 	if (player->max_depth < player->depth)
980 		player->max_depth = player->recall_depth = player->depth;
981 
982 	/* Flush messages */
983 	event_signal(EVENT_MESSAGE_FLUSH);
984 
985 	/* Update display */
986 	event_signal(EVENT_NEW_LEVEL_DISPLAY);
987 
988 	/* Update player */
989 	player->upkeep->update |= (PU_BONUS | PU_HP | PU_SPELLS | PU_INVEN);
990 	player->upkeep->notice |= (PN_COMBINE);
991 	notice_stuff(player);
992 	update_stuff(player);
993 	redraw_stuff(player);
994 
995 	/* Refresh */
996 	event_signal(EVENT_REFRESH);
997 
998 	if (player->upkeep->arena_level) {
999 		return;
1000 	}
1001 
1002 	/* Announce (or repeat) the feeling */
1003 	if (player->depth)
1004 		display_feeling(false);
1005 
1006 	/* Check the surroundings */
1007 	search(player);
1008 
1009 	/* Give player minimum energy to start a new level, but do not reduce
1010 	 * higher value from savefile for level in progress */
1011 	if (player->energy < z_info->move_energy)
1012 		player->energy = z_info->move_energy;
1013 }
1014 
1015 /**
1016  * Housekeeping on leaving a level
1017  */
on_leave_level(void)1018 static void on_leave_level(void) {
1019 	/* Cancel any command */
1020 	player_clear_timed(player, TMD_COMMAND, false);
1021 
1022 	/* Don't allow command repeat if moved away from item used. */
1023 	if (cmdq_does_previous_use_floor_item()) {
1024 		cmd_disable_repeat();
1025 	}
1026 
1027 	/* Any pending processing */
1028 	notice_stuff(player);
1029 	update_stuff(player);
1030 	redraw_stuff(player);
1031 
1032 	/* Flush messages */
1033 	event_signal(EVENT_MESSAGE_FLUSH);
1034 }
1035 
1036 
1037 /**
1038  * The main game loop.
1039  *
1040  * This function will run until the player needs to enter a command, or closes
1041  * the game, or the character dies.
1042  */
run_game_loop(void)1043 void run_game_loop(void)
1044 {
1045 	/* Tidy up after the player's command */
1046 	process_player_cleanup();
1047 
1048 	/* Keep processing the player until they use some energy or
1049 	 * another command is needed */
1050 	while (player->upkeep->playing) {
1051 		process_player();
1052 		if (player->upkeep->energy_use)
1053 			break;
1054 		else
1055 			return;
1056 	}
1057 
1058 	/* The player may still have enough energy to move, so we run another
1059 	 * player turn before processing the rest of the world */
1060 	while (player->energy >= z_info->move_energy) {
1061 		/* Do any necessary animations */
1062 		event_signal(EVENT_ANIMATE);
1063 
1064 		/* Process monster with even more energy first */
1065 		process_monsters(cave, player->energy + 1);
1066 		if (player->is_dead || !player->upkeep->playing ||
1067 			player->upkeep->generate_level)
1068 			break;
1069 
1070 		/* Process the player until they use some energy */
1071 		while (player->upkeep->playing) {
1072 			process_player();
1073 			if (player->upkeep->energy_use)
1074 				break;
1075 			else
1076 				return;
1077 		}
1078 	}
1079 
1080 	/* Now that the player's turn is fully complete, we run the main loop
1081 	 * until player input is needed again */
1082 	while (true) {
1083 		notice_stuff(player);
1084 		handle_stuff(player);
1085 		event_signal(EVENT_REFRESH);
1086 
1087 		/* Process the rest of the world, give the player energy and
1088 		 * increment the turn counter unless we need to stop playing or
1089 		 * generate a new level */
1090 		if (player->is_dead || !player->upkeep->playing)
1091 			return;
1092 		else if (!player->upkeep->generate_level) {
1093 			/* Process the rest of the monsters */
1094 			process_monsters(cave, 0);
1095 
1096 			/* Mark all monsters as ready to act when they have the energy */
1097 			reset_monsters();
1098 
1099 			/* Refresh */
1100 			notice_stuff(player);
1101 			handle_stuff(player);
1102 			event_signal(EVENT_REFRESH);
1103 			if (player->is_dead || !player->upkeep->playing)
1104 				return;
1105 
1106 			/* Process the world every ten turns */
1107 			if (!(turn % 10) && !player->upkeep->generate_level) {
1108 				process_world(cave);
1109 
1110 				/* Refresh */
1111 				notice_stuff(player);
1112 				handle_stuff(player);
1113 				event_signal(EVENT_REFRESH);
1114 				if (player->is_dead || !player->upkeep->playing)
1115 					return;
1116 			}
1117 
1118 			/* Give the player some energy */
1119 			player->energy += turn_energy(player->state.speed);
1120 
1121 			/* Count game turns */
1122 			turn++;
1123 		}
1124 
1125 		/* Make a new level if requested */
1126 		if (player->upkeep->generate_level) {
1127 			bool arena = false;
1128 			if (character_dungeon) {
1129 				on_leave_level();
1130 				if (cave->name && streq(cave->name, "arena")) {
1131 					arena = true;
1132 				}
1133 			}
1134 
1135 			prepare_next_level(&cave, player);
1136 			on_new_level();
1137 
1138 			player->upkeep->generate_level = false;
1139 
1140 			/* Kill arena monster */
1141 			if (arena) {
1142 				player->upkeep->arena_level = false;
1143 				if (player->upkeep->health_who) {
1144 					kill_arena_monster(player->upkeep->health_who);
1145 				}
1146 			}
1147 		}
1148 
1149 		/* If the player has enough energy to move they now do so, after
1150 		 * any monsters with more energy take their turns */
1151 		while (player->energy >= z_info->move_energy) {
1152 			/* Do any necessary animations */
1153 			event_signal(EVENT_ANIMATE);
1154 
1155 			/* Process monster with even more energy first */
1156 			process_monsters(cave, player->energy + 1);
1157 			if (player->is_dead || !player->upkeep->playing ||
1158 				player->upkeep->generate_level)
1159 				break;
1160 
1161 			/* Process the player until they use some energy */
1162 			while (player->upkeep->playing) {
1163 				process_player();
1164 				if (player->upkeep->energy_use)
1165 					break;
1166 				else
1167 					return;
1168 			}
1169 		}
1170 	}
1171 }
1172