1 /* $Id$ */
2 /* Purpose: Angband game engine */
3 
4 /*
5  * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
6  *
7  * This software may be copied and distributed for educational, research, and
8  * not for profit purposes provided that this copyright and statement are
9  * included in all such copies.
10  */
11 
12 #define SERVER
13 
14 #include "angband.h"
15 #include "externs.h"
16 
17 /* chance of townie respawning like other monsters, randint(chance)==0 means respawn */
18  /* Default */
19 #define TOWNIE_RESPAWN_CHANCE	250
20 /* better for Halloween event */
21 #define HALLOWEEN_TOWNIE_RESPAWN_CHANCE	125
22 
23 /* if defined, player ghost loses exp slowly. [10000]
24  * see GHOST_XP_CASHBACK in xtra2.c also.
25  */
26 #define GHOST_FADING	10000
27 
28 /* How fast HP/MP regenerate when 'resting'. [3] */
29 #define RESTING_RATE	(cfg.resting_rate)
30 
31 /* Chance of items damaged when drowning, in % [3] */
32 #define WATER_ITEM_DAMAGE_CHANCE	3
33 
34 /* Maximum wilderness radius a player can travel with WoR [16]
35  * TODO: Add another method to allow wilderness travels */
36 #define RECALL_MAX_RANGE	24
37 
38 /* duration of GoI when getting recalled.        [2] (Must be 0<=n<=4) */
39 #define RECALL_GOI_LENGTH        3
40 
41 
42 /* forward declarations */
43 static void process_firework_creation(void);
44 #ifndef CLIENT_SIDE_WEATHER
45 static void process_weather_control(void);
46 static void process_weather_effect_creation(void);
47 #else
48  #ifndef CLIENT_WEATHER_GLOBAL
49 
50 static void wild_weather_init(void);
51 static void process_wild_weather(void);
52 static void cloud_set_movement(int i);
53 static void cloud_move(int i, bool newly_created);
54 static void cloud_erase(int i);
55  /* cdsum*87/200 : sin 60 deg */
56 #define CLOUD_XS(cx1, cy1, cx2, cy2, cdsum) ((cx1 - (cdsum - (cx2 - cx1)) / 2) / MAX_WID)
57 #define CLOUD_YS(cx1, cy1, cx2, cy2, cdsum) ((cy1 - ((cdsum * 87) / 200)) / MAX_HGT)
58 #define CLOUD_XD(cx1, cy1, cx2, cy2, cdsum) ((cx2 + (cdsum - (cx2 - cx1)) / 2) / MAX_WID)
59 #define CLOUD_YD(cx1, cy1, cx2, cy2, cdsum) ((cy2 + ((cdsum * 87) / 200)) / MAX_HGT)
60 
61 /* Enable wind in general? */
62 #define WEATHER_WINDS
63 
64 /* Activate hack that disables all cloud movement,
65    as a workaround for the 'eternal rain' bug for now - C. Blue */
66 #define WEATHER_NO_CLOUD_MOVEMENT
67 
68  #else
69 
70 static void process_weather_control(void);
71  #endif
72 #endif
73 
74 #define SHUTDOWN_IGNORE_IDDC(p_ptr) \
75     (in_irondeepdive(&(p_ptr)->wpos) \
76     && (p_ptr)->idle_char > 900) /* just after 15 minutes flat */
77     //&& p_ptr->afk
78     //&& p_ptr->idle_char > STARVE_KICK_TIMER) //reuse idle-starve-kick-timer for this
79 
80 
81 /*
82  * Return a "feeling" (or NULL) about an item.  Method 1 (Heavy).
83  */
value_check_aux1(object_type * o_ptr)84 cptr value_check_aux1(object_type *o_ptr)
85 {
86 	object_kind *k_ptr = &k_info[o_ptr->k_idx];
87 
88 	/* Artifacts */
89 	if (artifact_p(o_ptr)) {
90 		/* Cursed/Broken */
91 		if (cursed_p(o_ptr) || broken_p(o_ptr)) return "terrible";
92 
93 		/* Normal */
94 		return "special";
95 	}
96 
97 	/* Ego-Items */
98 	if (ego_item_p(o_ptr)) {
99 		/* Hack for Stormbringer, so it doesn't show as "worthless" */
100 		if (o_ptr->name2 == EGO_STORMBRINGER) return "terrible";
101 
102 #if 0
103 		/* Cursed/Broken */
104 		if (cursed_p(o_ptr) || broken_p(o_ptr)) return "worthless";
105 #else
106 		/* Cursed items */
107 		if (cursed_p(o_ptr)) return "cursed";
108 
109 		/* Broken items */
110 		if (broken_p(o_ptr)) return "worthless";
111 #endif
112 
113 		/* Normal */
114 
115 		/* All exploding or ego-ammo is excellent */
116 		if (is_ammo(o_ptr->tval) && (o_ptr->pval || o_ptr->name2 || o_ptr->name2b)) return "excellent";
117 
118 		if (!object_value(0, o_ptr)) return "worthless";
119 		if (object_value(0, o_ptr) < 4000) return "good";
120 		return "excellent";
121 	}
122 
123 	/* Cursed items */
124 	if (cursed_p(o_ptr)) return "cursed";
125 
126 	/* Broken items */
127 	if (broken_p(o_ptr)) return "broken";
128 
129 	/* Valid "tval" codes */
130 	switch (o_ptr->tval) {
131 	case TV_DIGGING:
132 	case TV_BLUNT:
133 	case TV_POLEARM:
134 	case TV_SWORD:
135 	case TV_BOOTS:
136 	case TV_GLOVES:
137 	case TV_HELM:
138 	case TV_CROWN:
139 	case TV_SHIELD:
140 	case TV_CLOAK:
141 	case TV_SOFT_ARMOR:
142 	case TV_HARD_ARMOR:
143 	case TV_DRAG_ARMOR:
144 	case TV_AXE:
145 	case TV_SHOT:
146 	case TV_ARROW:
147 	case TV_BOLT:
148 	case TV_BOW:
149 	case TV_BOOMERANG:
150 		/* Good "armor" bonus */
151 		if ((o_ptr->to_a > k_ptr->to_a) &&
152 		    (o_ptr->to_a > 0)) return "good";
153 		/* Good "weapon" bonus */
154 		if ((o_ptr->to_h - k_ptr->to_h + o_ptr->to_d - k_ptr->to_d > 0) &&
155 		    (o_ptr->to_h > 0 || o_ptr->to_d > 0)) return "good";
156 		break;
157 	default:
158 		/* Good "armor" bonus */
159 		if (o_ptr->to_a > 0) return "good";
160 		/* Good "weapon" bonus */
161 		if (o_ptr->to_h + o_ptr->to_d > 0) return "good";
162 		break;
163 	}
164 
165 	/* Default to "average" */
166 	return "average";
167 }
168 
value_check_aux1_magic(object_type * o_ptr)169 cptr value_check_aux1_magic(object_type *o_ptr)
170 {
171 	object_kind *k_ptr = &k_info[o_ptr->k_idx];
172 
173 
174 	switch (o_ptr->tval) {
175 	/* Scrolls, Potions, Wands, Staves and Rods */
176 	case TV_SCROLL:
177 		/* hack for cheques */
178 		if (k_ptr->sval == SV_SCROLL_CHEQUE) return "good";
179 	case TV_POTION:
180 	case TV_POTION2:
181 	case TV_WAND:
182 	case TV_STAFF:
183 	case TV_ROD:
184 	case TV_ROD_MAIN:
185 		/* "Cursed" scrolls/potions have a cost of 0 */
186 		if (k_ptr->cost == 0) return "bad";//"terrible";
187 
188 		/* Artifacts */
189 		if (artifact_p(o_ptr)) return "special";
190 
191 		/* Scroll of Nothing, Apple Juice, etc. */
192 		if (k_ptr->cost < 3) return "worthless"; //"average" or "worthless"
193 
194 		/*
195 		 * Identify, Phase Door, Cure Light Wounds, etc. are
196 		 * just average
197 		 */
198 		if (k_ptr->cost < 100) return "average";
199 
200 		/* Enchant Armor, *Identify*, Restore Stat, etc. */
201 		if (k_ptr->cost < 4000) return "good";
202 
203 		/* Acquirement, Deincarnation, Strength, Blood of Life, ... */
204 		if (k_ptr->cost >= 4000) return "excellent";
205 
206 		break;
207 	/* Food */
208 	case TV_FOOD:
209 		/* "Cursed" food */
210 		if (k_ptr->cost == 0) return "bad";//"terrible";
211 
212 		/* Artifacts */
213 		if (artifact_p(o_ptr)) return "special";
214 
215 		/* Normal food (no magical properties) */
216 		if (k_ptr->cost <= 10) return "average";
217 
218 		/* Everything else is good */
219 		if (k_ptr->cost > 10) return "good";
220 
221 		break;
222 	}
223 
224 	/* No feeling */
225 //	return "";
226 	return (NULL);
227 }
228 
229 
230 /*
231  * Return a "feeling" (or NULL) about an item.  Method 2 (Light).
232  */
value_check_aux2(object_type * o_ptr)233 cptr value_check_aux2(object_type *o_ptr)
234 {
235 	object_kind *k_ptr = &k_info[o_ptr->k_idx];
236 
237 	/* Cursed items (all of them) */
238 	if (cursed_p(o_ptr)) return "cursed";
239 
240 	/* Broken items (all of them) */
241 	if (broken_p(o_ptr)) return "broken";
242 
243 	/* Artifacts -- except cursed/broken ones */
244 	if (artifact_p(o_ptr)) return "good";
245 
246 	/* Ego-Items -- except cursed/broken ones */
247 	if (!k_ptr->cost) return "broken";
248 	if (ego_item_p(o_ptr)) {
249 		if (!object_value(0, o_ptr)) return "worthless";
250 		return "good";
251 	}
252 
253 	switch (o_ptr->tval) {
254 	case TV_DIGGING:
255 	case TV_BLUNT:
256 	case TV_POLEARM:
257 	case TV_SWORD:
258 	case TV_BOOTS:
259 	case TV_GLOVES:
260 	case TV_HELM:
261 	case TV_CROWN:
262 	case TV_SHIELD:
263 	case TV_CLOAK:
264 	case TV_SOFT_ARMOR:
265 	case TV_HARD_ARMOR:
266 	case TV_DRAG_ARMOR:
267 	case TV_AXE:
268 	case TV_SHOT:
269 	case TV_ARROW:
270 	case TV_BOLT:
271 	case TV_BOW:
272 	case TV_BOOMERANG:
273 		/* Good "armor" bonus */
274 		if (o_ptr->to_a > k_ptr->to_a) return "good";
275 		/* Good "weapon" bonus */
276 		if (o_ptr->to_h - k_ptr->to_h + o_ptr->to_d - k_ptr->to_d > 0) return "good";
277 		break;
278 	default:
279 		/* Good "armor" bonus */
280 		if (o_ptr->to_a > 0) return "good";
281 		/* Good "weapon" bonus */
282 		if (o_ptr->to_h + o_ptr->to_d > 0) return "good";
283 		break;
284 	}
285 
286 	/* No feeling */
287 	return (NULL);
288 }
289 
value_check_aux2_magic(object_type * o_ptr)290 cptr value_check_aux2_magic(object_type *o_ptr)
291 {
292 	object_kind *k_ptr = &k_info[o_ptr->k_idx];
293 
294 
295 	switch (o_ptr->tval) {
296 	/* Scrolls, Potions, Wands, Staves and Rods */
297 	case TV_SCROLL:
298 		/* hack for cheques */
299 		if (k_ptr->sval == SV_SCROLL_CHEQUE) return "good";
300 	case TV_POTION:
301 	case TV_POTION2:
302 	case TV_WAND:
303 	case TV_STAFF:
304 	case TV_ROD:
305 		/* "Cursed" scrolls/potions have a cost of 0 */
306 		if (k_ptr->cost == 0) return "bad";//"cursed";
307 
308 		/* Artifacts */
309 		if (artifact_p(o_ptr)) return "good";
310 
311 		/* Scroll of Nothing, Apple Juice, etc. */
312 		if (k_ptr->cost < 3) return "average";//or "worthless"
313 
314 		/*
315 		 * Identify, Phase Door, Cure Light Wounds, etc. are
316 		 * just average
317 		 */
318 		if (k_ptr->cost < 100) return "average";
319 
320 		/* Enchant Armor, *Identify*, Restore Stat, etc. */
321 		if (k_ptr->cost < 4000) return "good";
322 
323 		/* Acquirement, Deincarnation, Strength, Blood of Life, ... */
324 		if (k_ptr->cost >= 4000) return "good";
325 
326 		break;
327 
328 	/* Food */
329 	case TV_FOOD:
330 		/* "Cursed" food */
331 		if (k_ptr->cost == 0) return "bad";//"cursed";
332 
333 		/* Artifacts */
334 		if (artifact_p(o_ptr)) return "good";
335 
336 		/* Normal food (no magical properties) */
337 		if (k_ptr->cost <= 10) return "average";
338 
339 		/* Everything else is good */
340 		if (k_ptr->cost > 10) return "good";
341 
342 		break;
343 	}
344 
345 	/* No feeling */
346 //	return "";
347 	return (NULL);
348 }
349 
350 /*
351  * Sense the inventory
352  */
sense_inventory(int Ind)353 static void sense_inventory(int Ind)
354 {
355 	player_type *p_ptr = Players[Ind];
356 
357 	int		i;
358 
359 	bool heavy = FALSE, heavy_magic = FALSE, heavy_archery = FALSE;
360 	bool ok_combat = FALSE, ok_magic = FALSE, ok_archery = FALSE;
361 	bool ok_curse = FALSE;
362 
363 	cptr	feel;
364 	bool	felt_heavy;
365 
366 	object_type *o_ptr;
367 	char o_name[ONAME_LEN];
368 
369 
370 	/*** Check for "sensing" ***/
371 
372 	/* No sensing when confused */
373 	if (p_ptr->confused) return;
374 
375 #if 0 /* no more linear ;) */
376 	if (!rand_int(133 - get_skill_scale(p_ptr, SKILL_COMBAT, 130))) ok_combat = TRUE;
377 	if (!rand_int(133 - get_skill_scale(p_ptr, SKILL_ARCHERY, 130))) ok_archery = TRUE;
378 	if (!rand_int(133 - get_skill_scale(p_ptr, SKILL_MAGIC, 130))) {
379 		ok_magic = TRUE;
380 		ok_curse = TRUE;
381 	}
382 	if (!rand_int(133 - get_skill_scale(p_ptr, SKILL_PRAY, 130))) ok_curse = TRUE;
383 #else
384      /* instead, allow more use at lower SKILL_COMBAT levels already,
385 	otherwise huge stacks of ID scrolls will remain mandatory for maybe too long a time - C. Blue */
386 //	if (!rand_int(399 / (get_skill_scale(p_ptr, SKILL_COMBAT, 97) + 3))) ok_combat = TRUE;
387 //	if (!rand_int(2 * (101 - (get_skill_scale(p_ptr, SKILL_COMBAT, 70) + 30)))) ok_combat = TRUE;
388 //	if (!rand_int(102 - (get_skill_scale(p_ptr, SKILL_COMBAT, 80) + 20))) ok_combat = TRUE;
389 //	if (!rand_int(102 - (get_skill_scale(p_ptr, SKILL_COMBAT, 70) + 30))) ok_combat = TRUE;
390 //	if (!rand_int(2000 / (get_skill_scale(p_ptr, SKILL_COMBAT, 80) + 20) - 18)) ok_combat = TRUE;
391 	if (!rand_int(3000 / (get_skill_scale(p_ptr, SKILL_COMBAT, 80) + 20) - 28)) ok_combat = TRUE;
392 	if (!rand_int(3000 / (get_skill_scale(p_ptr, SKILL_ARCHERY, 80) + 20) - 28)) ok_archery = TRUE;
393 	if (!rand_int(3000 / (get_skill_scale(p_ptr, SKILL_MAGIC, 80) + 20) - 28)) {
394 		ok_magic = TRUE;
395 		ok_curse = TRUE;
396 	}
397 	/* note: SKILL_PRAY is currently unused */
398 	if (!rand_int(3000 / (get_skill_scale(p_ptr, SKILL_PRAY, 80) + 20) - 28)) ok_curse = TRUE;
399 #endif
400 
401 	/* A powerful warrior can pseudo-id ranged weapons and ammo too,
402 	   even if (s)he's not good at archery in general */
403 	if (get_skill(p_ptr, SKILL_COMBAT) >= 31) {
404 #if 1 /* (apply 33% chance, see below) - allow basic feelings */
405 		ok_archery = TRUE;
406 #else /* (apply 33% chance, see below) - allow more distinctive feelings */
407 		heavy_archery = TRUE;
408 #endif
409 	}
410 
411 	/* A very powerful warrior can even distinguish magic items */
412 	if (get_skill(p_ptr, SKILL_COMBAT) >= 41) {
413 #if 0 /* too much? */
414 		ok_magic = TRUE;
415 #endif
416 		ok_curse = TRUE;
417 	}
418 
419 #if 1
420 	/* extra class-specific boni */
421 	i = 150 - ((p_ptr->lev <= 50) ? (p_ptr->lev * 2) : (p_ptr->lev + 50));
422 	if ((p_ptr->pclass == CLASS_PRIEST) && !rand_int(i)) ok_curse = TRUE;
423  #if 0 /* out of line? */
424 	if ((p_ptr->pclass == CLASS_ISTAR ||
425 	    p_ptr->pclass == CLASS_SHAMAN) && !rand_int(i)) ok_magic = TRUE;
426 	if ((p_ptr->pclass == CLASS_MINDCRAFTER) && !rand_int(i)) {
427 		ok_curse = TRUE;
428 		ok_magic = TRUE;
429 		ok_combat = TRUE;
430 	}
431  #endif
432 #endif
433 
434 	/* nothing to feel? exit */
435 	if (!ok_combat && !ok_magic && !ok_archery) return;
436 
437 	heavy = (get_skill(p_ptr, SKILL_COMBAT) >= 11) ? TRUE : FALSE;
438 	heavy_magic = (get_skill(p_ptr, SKILL_MAGIC) >= 11) ? TRUE : FALSE;
439 	heavy_archery = (get_skill(p_ptr, SKILL_ARCHERY) >= 11) ? TRUE : FALSE;
440 
441 	/*** Sense everything ***/
442 
443 	/* Check everything */
444 	for (i = 0; i < INVEN_TOTAL; i++) {
445 		o_ptr = &p_ptr->inventory[i];
446 
447 		/* Skip empty slots */
448 		if (!o_ptr->k_idx) continue;
449 		/* We know about it already, do not tell us again */
450 		if (o_ptr->ident & ID_SENSE) continue;
451 		/* It is fully known, no information needed */
452 		if (object_known_p(Ind, o_ptr)) continue;
453 		/* Occasional failure on inventory items */
454 		if ((i < INVEN_WIELD) &&
455 		    (magik(80) || UNAWARENESS(p_ptr))) continue;
456 
457 		feel = NULL;
458 		felt_heavy = FALSE;
459 
460 		if (ok_curse && cursed_p(o_ptr)) feel = value_check_aux1(o_ptr);
461 
462 		/* Valid "tval" codes */
463 		switch (o_ptr->tval) {
464 		case TV_DIGGING:
465 		case TV_BLUNT:
466 		case TV_POLEARM:
467 		case TV_SWORD:
468 		case TV_BOOTS:
469 		case TV_GLOVES:
470 		case TV_HELM:
471 		case TV_CROWN:
472 		case TV_SHIELD:
473 		case TV_CLOAK:
474 		case TV_SOFT_ARMOR:
475 		case TV_HARD_ARMOR:
476 		case TV_DRAG_ARMOR:
477 		case TV_AXE:
478 		case TV_TRAPKIT:
479 			if (ok_combat)
480 				feel = (heavy ? value_check_aux1(o_ptr) :
481 						value_check_aux2(o_ptr));
482 			if (heavy) felt_heavy = TRUE;
483 			break;
484 		case TV_MSTAFF:
485 			if (ok_magic)
486 				feel = (heavy_magic ? value_check_aux1(o_ptr) :
487 						value_check_aux2(o_ptr));
488 			if (heavy_magic) felt_heavy = TRUE;
489 			break;
490 		case TV_SCROLL:
491 			/* hack for cheques: Don't try to pseudo-id them at all. */
492 			if (o_ptr->sval == SV_SCROLL_CHEQUE) continue;
493 		case TV_POTION:
494 		case TV_POTION2:
495 		case TV_WAND:
496 		case TV_STAFF:
497 		case TV_ROD:
498 		case TV_FOOD:
499 			if (ok_magic && !object_aware_p(Ind, o_ptr))
500 				feel = (heavy_magic ? value_check_aux1_magic(o_ptr) :
501 				    value_check_aux2_magic(o_ptr));
502 			if (heavy_magic) felt_heavy = TRUE;
503 			break;
504 		case TV_SHOT:
505 		case TV_ARROW:
506 		case TV_BOLT:
507 		case TV_BOW:
508 		case TV_BOOMERANG:
509 			if (ok_archery || (ok_combat && magik(25)))
510 				feel = (heavy_archery ? value_check_aux1(o_ptr) :
511 				    value_check_aux2(o_ptr));
512 			if (heavy_archery) felt_heavy = TRUE;
513 			break;
514 		}
515 
516 		/* Skip non-feelings */
517 		if (!feel) continue;
518 
519 		/* Stop everything */
520 		if (p_ptr->disturb_minor) disturb(Ind, 0, 0);
521 
522 		/* Get an object description */
523 		object_desc(Ind, o_name, o_ptr, FALSE, 0);
524 
525 		/* Hack -- suppress messages */
526 		if (p_ptr->taciturn_messages) suppress_message = TRUE;
527 
528 		/* Message (equipment) */
529 		if (i >= INVEN_WIELD) {
530 			msg_format(Ind, "You feel the %s (%c) you are %s %s %s...",
531 			    o_name, index_to_label(i), describe_use(Ind, i),
532 			    ((o_ptr->number == 1) ? "is" : "are"), feel);
533 		}
534 		/* Message (inventory) */
535 		else {
536 			msg_format(Ind, "You feel the %s (%c) in your pack %s %s...",
537 			    o_name, index_to_label(i),
538 			    ((o_ptr->number == 1) ? "is" : "are"), feel);
539 		}
540 
541 		suppress_message = FALSE;
542 
543 		/* We have "felt" it */
544 		o_ptr->ident |= (ID_SENSE | ID_SENSED_ONCE);
545 		if (felt_heavy) o_ptr->ident |= ID_SENSE_HEAVY;
546 
547 		/* Remember feeling of that flavour, if and only if an item is always the same!
548 		   For example, rings might be cursed by ego power. Wands may not.
549 		   Other than that, this way an interesting middle-way between RPG-style
550 		   remember-items-seen-in-shops and normal ID-remembrance can be created:
551 		   Remember static items seen in shops just by feeling before having IDed one. :)
552 		    - C. Blue */
553 		switch(o_ptr->tval) {
554 		case TV_WAND:
555 		case TV_STAFF:
556 		case TV_ROD:
557 		case TV_ROD_MAIN:
558 		case TV_SCROLL:
559 		case TV_POTION:
560 		case TV_POTION2:
561 		case TV_FOOD:
562 			p_ptr->obj_felt[o_ptr->k_idx] = TRUE;
563 			if (felt_heavy) p_ptr->obj_felt_heavy[o_ptr->k_idx] = TRUE;
564 		}
565 
566 		/* Inscribe it textually */
567 #if 0 /* make pseudo-id remove previous unique tag? */
568 		if (!o_ptr->note || o_ptr->note_utag) {
569 			o_ptr->note = quark_add(feel);
570 			o_ptr->note_utag = 0;
571 		}
572 #else /* keep unique tag until removed manually by player? */
573 		if (!o_ptr->note) o_ptr->note = quark_add(feel);
574 #endif
575 		/* Still add an inscription, so unique loot doesn't cause major annoyances - C. Blue */
576 		/* for items that were already pseudo-id-inscribed but then forgotten:
577 		   only add inscription if it doesn't exist on the item yet (*) - 2 checks */
578 		else if (strcmp(quark_str(o_ptr->note), feel)) { // (*) check 1 of 2 (exact match)
579 			strcpy(o_name, feel); /* just abusing o_name for this since it's not needed anymore anyway */
580 			strcat(o_name, "-");
581 			if (!strstr(quark_str(o_ptr->note), o_name)) { // (*) check 2 of 2 (partial match)
582 				strcat(o_name, quark_str(o_ptr->note));
583 				o_ptr->note = quark_add(o_name);
584 			}
585 		}
586 
587 		/* Combine / Reorder the pack (later) */
588 		p_ptr->notice |= (PN_COMBINE | PN_REORDER);
589 
590 		/* Window stuff */
591 		p_ptr->window |= (PW_INVEN | PW_EQUIP);
592 	}
593 }
594 
595 #if 0 /* the results might be too incorrect! for example 'average' can still mean enchantment, etc. */
596 /* for NEW_ID_SCREEN's pseudo-id handling: */
597 
598 static int quality_check_aux1(object_type *o_ptr) {
599 	object_kind *k_ptr = &k_info[o_ptr->k_idx];
600 
601 	if (artifact_p(o_ptr)) return 3;
602 
603 	if (ego_item_p(o_ptr)) {
604 		if (o_ptr->name2 == EGO_STORMBRINGER) return 3;
605 		if (cursed_p(o_ptr) || broken_p(o_ptr)) return 2;
606 		if (is_ammo(o_ptr->tval) && (o_ptr->pval || o_ptr->name2 || o_ptr->name2b)) return 2;
607 		if (object_value(0, o_ptr) < 4000) return 1;
608 		return 2;
609 	}
610 
611 	if (cursed_p(o_ptr)) return -1;
612 	if (broken_p(o_ptr)) return -1;
613 
614 	switch (o_ptr->tval) {
615 	case TV_DIGGING:
616 	case TV_BLUNT:
617 	case TV_POLEARM:
618 	case TV_SWORD:
619 	case TV_BOOTS:
620 	case TV_GLOVES:
621 	case TV_HELM:
622 	case TV_CROWN:
623 	case TV_SHIELD:
624 	case TV_CLOAK:
625 	case TV_SOFT_ARMOR:
626 	case TV_HARD_ARMOR:
627 	case TV_DRAG_ARMOR:
628 	case TV_AXE:
629 	case TV_SHOT:
630 	case TV_ARROW:
631 	case TV_BOLT:
632 	case TV_BOW:
633 	case TV_BOOMERANG:
634 		if ((o_ptr->ident & ID_SENSE_GOOD)) return 1;
635 		break;
636 	default:
637 		if ((o_ptr->ident & ID_SENSE_GOOD)) return 1;
638 	}
639 
640 	return 0;
641 }
642 
643 /*
644  * Return a "feeling" (or NULL) about an item.  Method 2 (Light).
645  */
646 static int quality_check_aux2(object_type *o_ptr) {
647 	object_kind *k_ptr = &k_info[o_ptr->k_idx];
648 
649 	if (cursed_p(o_ptr)) -1;
650 	if (broken_p(o_ptr)) -1;
651 	if (artifact_p(o_ptr)) return 1;
652 	if (!k_ptr->cost) return -1;
653 	if (ego_item_p(o_ptr)) {
654 		return 1;
655 	}
656 
657 	switch (o_ptr->tval) {
658 	case TV_DIGGING:
659 	case TV_BLUNT:
660 	case TV_POLEARM:
661 	case TV_SWORD:
662 	case TV_BOOTS:
663 	case TV_GLOVES:
664 	case TV_HELM:
665 	case TV_CROWN:
666 	case TV_SHIELD:
667 	case TV_CLOAK:
668 	case TV_SOFT_ARMOR:
669 	case TV_HARD_ARMOR:
670 	case TV_DRAG_ARMOR:
671 	case TV_AXE:
672 	case TV_SHOT:
673 	case TV_ARROW:
674 	case TV_BOLT:
675 	case TV_BOW:
676 	case TV_BOOMERANG:
677 		if ((o_ptr->ident & ID_SENSE_GOOD)) return 1;
678 		break;
679 	default:
680 		if ((o_ptr->ident & ID_SENSE_GOOD)) return 1;
681 	}
682 
683 	return 0;
684 }
685 
686 int pseudo_id_result(object_type *o_ptr) {
687 	int quality = 0;
688 
689 	switch (o_ptr->tval) {
690 	case TV_DIGGING:
691 	case TV_BLUNT:
692 	case TV_POLEARM:
693 	case TV_SWORD:
694 	case TV_BOOTS:
695 	case TV_GLOVES:
696 	case TV_HELM:
697 	case TV_CROWN:
698 	case TV_SHIELD:
699 	case TV_CLOAK:
700 	case TV_SOFT_ARMOR:
701 	case TV_HARD_ARMOR:
702 	case TV_DRAG_ARMOR:
703 	case TV_AXE:
704 	case TV_TRAPKIT:
705 
706 	case TV_MSTAFF:
707 
708 	case TV_SHOT:
709 	case TV_ARROW:
710 	case TV_BOLT:
711 	case TV_BOW:
712 	case TV_BOOMERANG:
713 		quality = ((o_ptr->ident & ID_SENSE_HEAVY) ? quality_check_aux1(o_ptr) :
714 		    quality_check_aux2(o_ptr));
715 		break;
716 
717 	case TV_SCROLL:
718 	case TV_POTION:
719 	case TV_POTION2:
720 	case TV_WAND:
721 	case TV_STAFF:
722 	case TV_ROD:
723 	case TV_FOOD:
724 		return 0;
725 	}
726 
727 	return quality;
728 }
729 #endif
730 
731 /*
732  * Regenerate hit points				-RAK-
733  */
regenhp(int Ind,int percent)734 static void regenhp(int Ind, int percent)
735 {
736 	player_type *p_ptr = Players[Ind];
737 
738 	s32b        new_chp, new_chp_frac;
739 	int                   old_chp;
740 	int freeze_test_heal = p_ptr->test_heal;
741 
742 	/* Save the old hitpoints */
743 	old_chp = p_ptr->chp;
744 
745 	/* Extract the new hitpoints */
746 	new_chp = ((s32b)p_ptr->mhp) * percent + PY_REGEN_HPBASE;
747 	/* Apply the healing */
748 	hp_player_quiet(Ind, new_chp >> 16, TRUE);
749 	//p_ptr->chp += new_chp >> 16;   /* div 65536 */
750 
751 	/* check for overflow -- this is probably unneccecary */
752 	if ((p_ptr->chp < 0) && (old_chp > 0)) p_ptr->chp = MAX_SHORT;
753 
754 	/* handle fractional hit point healing */
755 	new_chp_frac = (new_chp & 0xFFFF) + p_ptr->chp_frac;	/* mod 65536 */
756 	if (new_chp_frac >= 0x10000L) {
757 		hp_player_quiet(Ind, 1, TRUE);
758 		p_ptr->chp_frac = new_chp_frac - 0x10000L;
759 	} else {
760 		p_ptr->chp_frac = new_chp_frac;
761 	}
762 
763 	p_ptr->test_heal = freeze_test_heal;
764 }
765 
766 
767 /*
768  * Regenerate mana points				-RAK-
769  */
regenmana(int Ind,int percent)770 static void regenmana(int Ind, int percent) {
771 	player_type *p_ptr = Players[Ind];
772 	s32b        new_mana, new_mana_frac;
773 	int                   old_csp;
774 
775 	old_csp = p_ptr->csp;
776 	new_mana = ((s32b)p_ptr->msp) * percent + PY_REGEN_MNBASE;
777 
778 	p_ptr->csp += new_mana >> 16;	/* div 65536 */
779 	/* check for overflow */
780 	if ((p_ptr->csp < 0) && (old_csp > 0))
781 		p_ptr->csp = MAX_SHORT;
782 
783 	new_mana_frac = (new_mana & 0xFFFF) + p_ptr->csp_frac;	/* mod 65536 */
784 	if (new_mana_frac >= 0x10000L) {
785 		p_ptr->csp_frac = new_mana_frac - 0x10000L;
786 		p_ptr->csp++;
787 	} else {
788 		p_ptr->csp_frac = new_mana_frac;
789 	}
790 
791 	/* Must set frac to zero even if equal */
792 	if (p_ptr->csp >= p_ptr->msp) {
793 		p_ptr->csp = p_ptr->msp;
794 		p_ptr->csp_frac = 0;
795 	}
796 
797 	/* Redraw mana */
798 	if (old_csp != p_ptr->csp) {
799 		/* Redraw */
800 		p_ptr->redraw |= (PR_MANA);
801 
802 		/* Window stuff */
803 		p_ptr->window |= (PW_PLAYER);
804 	}
805 }
806 
807 
808 #define pelpel
809 #ifdef pelpel
810 
811 /* Wipeout the effects	- Jir - */
erase_effects(int effect)812 static void erase_effects(int effect)
813 {
814 	int i, j, l;
815 	effect_type *e_ptr = &effects[effect];
816 	worldpos *wpos = &e_ptr->wpos;
817 	cave_type **zcave;
818 	cave_type *c_ptr;
819 	int rad = e_ptr->rad;
820 	int cy = e_ptr->cy;
821 	int cx = e_ptr->cx;
822 
823 	e_ptr->time = 0;
824 
825 	e_ptr->interval = 0;
826 	e_ptr->type = 0;
827 	e_ptr->dam = 0;
828 	e_ptr->time = 0;
829 	e_ptr->flags = 0;
830 	e_ptr->sx = 0;
831 	e_ptr->sy = 0;
832 	e_ptr->cx = 0;
833 	e_ptr->cy = 0;
834 	e_ptr->rad = 0;
835 
836 	if (!(zcave = getcave(wpos))) return;
837 
838 	/* XXX +1 is needed.. */
839 	for (l = 0; l < tdi[rad + 0]; l++)
840 	{
841 		j = cy + tdy[l];
842 		i = cx + tdx[l];
843 		if (!in_bounds2(wpos, j, i)) continue;
844 
845 		c_ptr = &zcave[j][i];
846 
847 		if (c_ptr->effect == effect)
848 		{
849 			c_ptr->effect = 0;
850 			everyone_lite_spot(wpos, j, i);
851 		}
852 	}
853 }
854 
855 /*
856  * Handle staying spell effects once every 10 game turns
857  */
858 /*
859  * TODO:
860  * - excise dead effect for efficiency
861  * - allow players/monsters to 'cancel' the effect
862  * - implement EFF_LAST eraser (for now, no spell has this flag)
863  * - reduce the use of everyone_lite_spot (one call, one packet)
864  */
865 /*
866  * XXX Check it:
867  * - what happens if the player dies?
868  * - what happens to the storm/wave when player changes floor?
869  *   (A. the storm is left on the original floor, and still try to follow
870  *    the caster, pfft)
871  */
872 /* Set these to animate the colours of an effect if they aren't already flickering
873    colours such as TERM_POIS etc. but instead static colours that are picked randomly
874    in spell_color(). - C. Blue */
875 #define ANIMATE_EFFECTS /* animates spell_color() randomness, costs more bandwidth */
876 #define FREQUENT_EFFECT_ANIMATION /* costs even more bandwidth */
process_effects(void)877 static void process_effects(void) {
878 	int i, j, k, l;
879 	worldpos *wpos;
880 	cave_type **zcave;
881 	cave_type *c_ptr;
882 	int who = PROJECTOR_EFFECT;
883 	player_type *p_ptr;
884 
885 	/* Every 10 game turns */
886 //	if (turn % 10) return;
887 
888 	/* Not in the small-scale wilderness map */
889 //	if (p_ptr->wild_mode) return;
890 
891 
892 	for (k = 0; k < MAX_EFFECTS; k++) {
893 		// int e = cave[j][i].effect;
894 		effect_type *e_ptr = &effects[k];
895 
896 		/* Skip empty slots */
897 		if (e_ptr->time == 0) continue;
898 
899 		wpos = &e_ptr->wpos;
900 		if (!(zcave = getcave(wpos))) {
901 			e_ptr->time = 0;
902 			/* TODO - excise it */
903 			continue;
904 		}
905 
906 #ifdef ARCADE_SERVER
907  #if 0
908                 if ((e_ptr->flags & EFF_CROSSHAIR_A) || (e_ptr->flags & EFF_CROSSHAIR_B) || (e_ptr->flags & EFF_CROSSHAIR_C)) {
909 
910                         /* e_ptr->interval is player who controls it */
911                         if (e_ptr->interval >= NumPlayers) {
912                                 p_ptr = Players[e_ptr->interval];
913                                 if (k == p_ptr->e) {
914                                         if (e_ptr->cy != p_ptr->arc_b || e_ptr->cx != p_ptr->arc_a) {
915                                                 if (!in_bounds2(wpos, e_ptr->cy, e_ptr->cx)) continue;
916                                                 c_ptr = &zcave[e_ptr->cy][e_ptr->cx];
917                                                 c_ptr->effect = 0;
918                                                 everyone_lite_spot(wpos, e_ptr->cy, e_ptr->cx);
919                                                 e_ptr->cy = p_ptr->arc_b;
920                                                 e_ptr->cx = p_ptr->arc_a;
921                                                 if (!in_bounds2(wpos, e_ptr->cy, e_ptr->cx)) continue;
922                                                 c_ptr = &zcave[e_ptr->cy][e_ptr->cx];
923                                                 c_ptr->effect = k;
924                                                 everyone_lite_spot(wpos, e_ptr->cy, e_ptr->cx);
925                                         }
926 
927                                 } else {
928 	                                erase_effects(k);
929                                 }
930                         } else {
931 	                        erase_effects(k);
932                         }
933 			continue;
934                 }
935  #endif
936 #endif
937 
938 #ifndef EXTENDED_TERM_COLOURS
939  #ifdef ANIMATE_EFFECTS
940   #ifdef FREQUENT_EFFECT_ANIMATION
941 		/* hack: animate the effect! Note that this is independant of the effect interval,
942 		   as opposed to the other animation code below. - C. Blue */
943 		if (!(turn % (cfg.fps / 5)) && e_ptr->time && spell_color_animation(e_ptr->type))
944 			for (l = 0; l < tdi[e_ptr->rad]; l++) {
945 				j = e_ptr->cy + tdy[l];
946 				i = e_ptr->cx + tdx[l];
947 				if (!in_bounds2(wpos, j, i)) continue;
948 				everyone_lite_spot(wpos, j, i);
949 			}
950   #endif
951  #endif
952 #endif
953 
954 		/* check if it's time to process this effect now (depends on level_speed) */
955 		if ((turn % (e_ptr->interval * level_speed(wpos) / (level_speeds[0] * 5))) != 0) continue;
956 
957 		/* Reduce duration */
958 		e_ptr->time--;
959 
960 		/* It ends? */
961 		if (e_ptr->time <= 0) {
962 			erase_effects(k);
963 			continue;
964 		}
965 
966 		/* effect belongs to a non-player? */
967 		if (e_ptr->who > 0) who = e_ptr->who;
968 		else { /* or to a player? */
969 			/* Make the effect friendly after logging out - mikaelh */
970 			who = PROJECTOR_PLAYER;
971 
972 			/* XXX Hack -- is the trapper online? */
973 			for (i = 1; i <= NumPlayers; i++) {
974 				p_ptr = Players[i];
975 
976 				/* Check if they are in here */
977 				if (e_ptr->who != 0 - p_ptr->id) continue;
978 
979 				/* additionally check if player left level --
980 				   avoids panic save on killing a dungeon boss with a lasting effect while
981 				   already having been prematurely recalled to town meanwhile (insta-res!) - C. Blue */
982 				if (!inarea(&p_ptr->wpos, wpos)) break;
983 
984 				/* it's fine */
985 				who = 0 - i;
986 				break;
987 			}
988 		}
989 
990 		/* Storm ends if the cause is gone */
991 		if  (e_ptr->flags & EFF_STORM && (who == PROJECTOR_EFFECT || who == PROJECTOR_PLAYER)) {
992 			erase_effects(k);
993 			continue;
994 		}
995 
996 		/* Snowflakes disappear if they reach end of traversed screen */
997 		if ((e_ptr->flags & EFF_SNOWING) && e_ptr->cy == MAX_HGT - 2) {
998 			erase_effects(k);
999 			continue;
1000 		}
1001 		/* Raindrops disappear if they reach end of traversed screen */
1002 		if ((e_ptr->flags & EFF_RAINING) && e_ptr->cy == MAX_HGT - 2) {
1003 			erase_effects(k);
1004 			continue;
1005 		}
1006 
1007 		/* Handle spell effects */
1008 		for (l = 0; l < tdi[e_ptr->rad]; l++) {
1009 			j = e_ptr->cy + tdy[l];
1010 			i = e_ptr->cx + tdx[l];
1011 			if (!in_bounds2(wpos, j, i)) continue;
1012 
1013 			c_ptr = &zcave[j][i];
1014 
1015 			//if (c_ptr->effect != k) continue;
1016 			if (c_ptr->effect != k) /* Nothing */;
1017 			else {
1018 				if (e_ptr->time) {
1019 					int flg = PROJECT_NORF | PROJECT_GRID | PROJECT_KILL | PROJECT_ITEM | PROJECT_HIDE | PROJECT_JUMP;
1020 						    //PROJECT_KILL | PROJECT_ITEM | PROJECT_HIDE | PROJECT_JUMP
1021 
1022 					flg = mod_ball_spell_flags(e_ptr->type, flg);
1023 
1024 					/* Apply damage */
1025 					project(who, 0, wpos, j, i, e_ptr->dam, e_ptr->type, flg, "");
1026 
1027 					/* Oh, destroyed? RIP */
1028 					if (who < 0 && who != PROJECTOR_EFFECT && who != PROJECTOR_PLAYER &&
1029 							Players[0 - who]->conn == NOT_CONNECTED)
1030 					{
1031 						/* Make the effect friendly after death - mikaelh */
1032 						who = PROJECTOR_PLAYER;
1033 					}
1034 
1035 #ifndef EXTENDED_TERM_COLOURS
1036  #ifdef ANIMATE_EFFECTS
1037   #ifndef FREQUENT_EFFECT_ANIMATION
1038 					/* C. Blue - hack: animate effects inbetween
1039 					   ie allow random changes in spell_color().
1040 					   Note: animation speed depends on effect interval. */
1041 					if (spell_color_animation(e_ptr->type))
1042 					    everyone_lite_spot(wpos, j, i);
1043   #endif
1044  #endif
1045 #endif
1046 				} else {
1047 					c_ptr->effect = 0;
1048 					everyone_lite_spot(wpos, j, i);
1049 				}
1050 
1051 				/* Hack -- notice death */
1052 				//	if (!alive || death) return;
1053 				/* Storm ends if the cause is gone */
1054 				if (e_ptr->flags & EFF_STORM &&
1055 				    (who == PROJECTOR_PLAYER || Players[0 - who]->death)) {
1056 					erase_effects(k);
1057 					break;
1058 				}
1059 			}
1060 
1061 
1062 #if 0
1063 			if (((e_ptr->flags & EFF_WAVE) && !(e_ptr->flags & EFF_LAST)) || ((e_ptr->flags & EFF_STORM) && !(e_ptr->flags & EFF_LAST))) {
1064 				if (distance(e_ptr->cy, e_ptr->cx, j, i) < e_ptr->rad - 2)
1065 					c_ptr->effect = 0;
1066 			}
1067 #else	// 0
1068 
1069 			if (!(e_ptr->flags & EFF_LAST)) {
1070 				if ((e_ptr->flags & EFF_WAVE)) {
1071 					if (distance(e_ptr->cy, e_ptr->cx, j, i) < e_ptr->rad - 2) {
1072 						c_ptr->effect = 0;
1073 						everyone_lite_spot(wpos, j, i);
1074 					}
1075 				} else if ((e_ptr->flags & EFF_STORM)) {
1076 					c_ptr->effect = 0;
1077 					everyone_lite_spot(wpos, j, i);
1078 				} else if ((e_ptr->flags & EFF_SNOWING)) {
1079 					c_ptr->effect = 0;
1080 					everyone_lite_spot(wpos, j, i);
1081 				} else if ((e_ptr->flags & EFF_RAINING)) {
1082 					c_ptr->effect = 0;
1083 					everyone_lite_spot(wpos, j, i);
1084 				} else if (e_ptr->flags & (EFF_FIREWORKS1 | EFF_FIREWORKS2 | EFF_FIREWORKS3)) {
1085 					c_ptr->effect = 0;
1086 					everyone_lite_spot(wpos, j, i);
1087  #if 0 /* no need to erase inbetween, while effect is still expanding - at the same time this fixes ugly tile flickering from redrawing (lava!) */
1088 				} else if (e_ptr->flags & (EFF_LIGHTNING1 | EFF_LIGHTNING2 | EFF_LIGHTNING3)) {
1089 					c_ptr->effect = 0;
1090 					everyone_lite_spot(wpos, j, i);
1091  #endif
1092 				}
1093 			}
1094 #endif	// 0
1095 
1096 			/* Creates a "wave" effect*/
1097 			if (e_ptr->flags & EFF_WAVE) {
1098 				if (los(wpos, e_ptr->cy, e_ptr->cx, j, i) &&
1099 				    (distance(e_ptr->cy, e_ptr->cx, j, i) == e_ptr->rad)) {
1100 					c_ptr->effect = k;
1101 					everyone_lite_spot(wpos, j, i);
1102 				}
1103 			}
1104 
1105                         /* Generate fireworks effects */
1106 			if (e_ptr->flags & (EFF_FIREWORKS1 | EFF_FIREWORKS2 | EFF_FIREWORKS3)) {
1107 				int semi = (e_ptr->time + e_ptr->rad) / 2;
1108 				/* until half-time (or half-radius) the fireworks rise into the air */
1109 				if (e_ptr->rad < e_ptr->time) {
1110 					if (i == e_ptr->cx && j == e_ptr->cy - e_ptr->rad) {
1111 						c_ptr->effect = k;
1112 						everyone_lite_spot(wpos, j, i);
1113 					}
1114 				} else { /* after that, they explode (w00t) */
1115 					/* explosion is faster than flying upwards */
1116 //doesn't work					e_ptr->interval = 2;
1117 
1118 #ifdef USE_SOUND_2010
1119 					if (e_ptr->rad == e_ptr->time) {
1120 						if ((e_ptr->flags & EFF_FIREWORKS3))
1121 							//sound_near_site(e_ptr->cy, e_ptr->cx, wpos, 0, "fireworks_big", "", SFX_TYPE_AMBIENT, FALSE);
1122 							sound_floor_vol(wpos, "fireworks_big", "", SFX_TYPE_AMBIENT, randint(26) + 75);
1123 						else if ((e_ptr->flags & EFF_FIREWORKS2))
1124 							//sound_near_site(e_ptr->cy, e_ptr->cx, wpos, 0, "fireworks_norm", "", SFX_TYPE_AMBIENT, FALSE);
1125 							sound_floor_vol(wpos, "fireworks_norm", "", SFX_TYPE_AMBIENT, randint(26) + 75);
1126 						else
1127 							//sound_near_site(e_ptr->cy, e_ptr->cx, wpos, 0, "fireworks_small", "", SFX_TYPE_AMBIENT, FALSE);
1128 							sound_floor_vol(wpos, "fireworks_small", "", SFX_TYPE_AMBIENT, randint(26) + 75);
1129 					}
1130 #endif
1131 
1132 #if 0
1133 					if (e_ptr->flags & EFF_FIREWORKS1) { /* simple rocket (line) */
1134 						if (i == e_ptr->cx && j == e_ptr->cy - e_ptr->rad) {
1135 							c_ptr->effect = k;
1136 							everyone_lite_spot(wpos, j, i);
1137 						}
1138 #endif
1139 					if (e_ptr->flags & EFF_FIREWORKS1) { /* 3-star */
1140 						if (((i == e_ptr->cx && j >= e_ptr->cy - e_ptr->rad) && /* up */
1141 						    (i == e_ptr->cx && j <= e_ptr->cy + 1 - e_ptr->rad)) ||
1142 						    ((i >= e_ptr->cx + semi - e_ptr->rad && j == e_ptr->cy - semi) && /* left */
1143 						    (i <= e_ptr->cx + semi + 1 - e_ptr->rad && j == e_ptr->cy - semi)) ||
1144 						    ((i <= e_ptr->cx - semi + e_ptr->rad && j == e_ptr->cy - semi) && /* right */
1145 						    (i >= e_ptr->cx - semi - 1 + e_ptr->rad && j == e_ptr->cy - semi))) {
1146 							c_ptr->effect = k;
1147 							everyone_lite_spot(wpos, j, i);
1148 						}
1149 					} else if (e_ptr->flags & EFF_FIREWORKS2) { /* 5-star */
1150 						if (((i == e_ptr->cx && j >= e_ptr->cy - e_ptr->rad) && /* up */
1151 						    (i == e_ptr->cx && j <= e_ptr->cy + 1 - e_ptr->rad)) ||
1152 						    ((i >= e_ptr->cx + semi - e_ptr->rad && j >= e_ptr->cy - e_ptr->rad) && /* up-left */
1153 						    (i <= e_ptr->cx + semi + 1 - e_ptr->rad && j <= e_ptr->cy + 1 - e_ptr->rad)) ||
1154 						    ((i <= e_ptr->cx - semi + e_ptr->rad && j >= e_ptr->cy - e_ptr->rad) && /* up-right */
1155 						    (i >= e_ptr->cx - semi - 1 + e_ptr->rad && j <= e_ptr->cy + 1 - e_ptr->rad)) ||
1156 						    ((i >= e_ptr->cx + semi - e_ptr->rad && j <= e_ptr->cy - 2 * semi + e_ptr->rad) && /* down-left */
1157 						    (i <= e_ptr->cx + semi + 1 - e_ptr->rad && j >= e_ptr->cy - 0 - 2 * semi + e_ptr->rad)) ||
1158 						    ((i <= e_ptr->cx - semi + e_ptr->rad && j <= e_ptr->cy - 2 * semi + e_ptr->rad) && /* down-right */
1159 						    (i >= e_ptr->cx - semi - 1 + e_ptr->rad && j >= e_ptr->cy - 0 - 2 * semi + e_ptr->rad))) {
1160 							c_ptr->effect = k;
1161 							everyone_lite_spot(wpos, j, i);
1162 						}
1163 					} else { /* EFF_FIREWORKS3 */ /* 7-star whoa */
1164 						if (((i == e_ptr->cx && j >= e_ptr->cy - e_ptr->rad) && /* up */
1165 						    (i == e_ptr->cx && j <= e_ptr->cy + 1 - e_ptr->rad)) ||
1166 						    ((i >= e_ptr->cx + semi - e_ptr->rad && j == e_ptr->cy - semi) && /* left */
1167 						    (i <= e_ptr->cx + semi + 1 - e_ptr->rad && j == e_ptr->cy - semi)) ||
1168 						    ((i <= e_ptr->cx - semi + e_ptr->rad && j == e_ptr->cy - semi) && /* right */
1169 						    (i >= e_ptr->cx - semi - 1 + e_ptr->rad && j == e_ptr->cy - semi)) ||
1170 						    ((i >= e_ptr->cx + semi - e_ptr->rad && j >= e_ptr->cy - e_ptr->rad) && /* up-left */
1171 						    (i <= e_ptr->cx + semi + 1 - e_ptr->rad && j <= e_ptr->cy + 1 - e_ptr->rad)) ||
1172 						    ((i <= e_ptr->cx - semi + e_ptr->rad && j >= e_ptr->cy - e_ptr->rad) && /* up-right */
1173 						    (i >= e_ptr->cx - semi - 1 + e_ptr->rad && j <= e_ptr->cy + 1 - e_ptr->rad)) ||
1174 						    ((i >= e_ptr->cx + semi - e_ptr->rad && j <= e_ptr->cy - 2 * semi + e_ptr->rad) && /* down-left */
1175 						    (i <= e_ptr->cx + semi + 1 - e_ptr->rad && j >= e_ptr->cy - 0 - 2 * semi + e_ptr->rad)) ||
1176 						    ((i <= e_ptr->cx - semi + e_ptr->rad && j <= e_ptr->cy - 2 * semi + e_ptr->rad) && /* down-right */
1177 						    (i >= e_ptr->cx - semi - 1 + e_ptr->rad && j >= e_ptr->cy - 0 - 2 * semi + e_ptr->rad))) {
1178 							c_ptr->effect = k;
1179 							everyone_lite_spot(wpos, j, i);
1180 						}
1181 					}
1182 				}
1183 			}
1184 
1185                         /* Generate lightning effects -- effect_xtra: -1\ 0| 1/ 2_ */
1186 			if (e_ptr->flags & (EFF_LIGHTNING1 | EFF_LIGHTNING2 | EFF_LIGHTNING3)) {
1187 				int mirrored = (e_ptr->dam == 0) ? -1 : 1;
1188 
1189 				if ((e_ptr->flags & EFF_LIGHTNING1)) {
1190 					int stage = e_ptr->rad;
1191 
1192 					if (stage > 15) stage = 15; /* afterglow */
1193 
1194 					switch (stage) {
1195 					case 15:
1196 						if (i == e_ptr->cx + mirrored * 14 && j == e_ptr->cy + 4) {///
1197 							c_ptr->effect = k;
1198 							c_ptr->effect_xtra = -mirrored;
1199 							everyone_lite_spot(wpos, j, i);
1200 						}
1201 					case 14:
1202 						if (i == e_ptr->cx + mirrored * 13 && j == e_ptr->cy + 3) {//_
1203 							c_ptr->effect = k;
1204 							c_ptr->effect_xtra = 2;
1205 							everyone_lite_spot(wpos, j, i);
1206 						}
1207 					case 13:
1208 						if (i == e_ptr->cx + mirrored * 12 && j == e_ptr->cy + 3) {///
1209 							c_ptr->effect = k;
1210 							c_ptr->effect_xtra = -mirrored;
1211 							everyone_lite_spot(wpos, j, i);
1212 						}
1213 						if (i == e_ptr->cx + mirrored * 6 && j == e_ptr->cy + 5) {//_
1214 							c_ptr->effect = k;
1215 							c_ptr->effect_xtra = 2;
1216 							everyone_lite_spot(wpos, j, i);
1217 						}
1218 					case 12:
1219 						if (i == e_ptr->cx + mirrored * 11 && j == e_ptr->cy + 2) {//_
1220 							c_ptr->effect = k;
1221 							c_ptr->effect_xtra = 2;
1222 							everyone_lite_spot(wpos, j, i);
1223 						}
1224 						if (i == e_ptr->cx + mirrored * 5 && j == e_ptr->cy + 5) {//_
1225 							c_ptr->effect = k;
1226 							c_ptr->effect_xtra = 2;
1227 							everyone_lite_spot(wpos, j, i);
1228 						}
1229 					case 11:
1230 						if (i == e_ptr->cx + mirrored * 10 && j == e_ptr->cy + 2) {//_
1231 							c_ptr->effect = k;
1232 							c_ptr->effect_xtra = 2;
1233 							everyone_lite_spot(wpos, j, i);
1234 						}
1235 						if (i == e_ptr->cx + mirrored * 4 && j == e_ptr->cy + 5) {///
1236 							c_ptr->effect = k;
1237 							c_ptr->effect_xtra = -mirrored;
1238 							everyone_lite_spot(wpos, j, i);
1239 						}
1240 					case 10:
1241 						if (i == e_ptr->cx + mirrored * 9 && j == e_ptr->cy + 2) {//_
1242 							c_ptr->effect = k;
1243 							c_ptr->effect_xtra = 2;
1244 							everyone_lite_spot(wpos, j, i);
1245 						}
1246 						if (i == e_ptr->cx + mirrored * 3 && j == e_ptr->cy + 4) {///
1247 							c_ptr->effect = k;
1248 							c_ptr->effect_xtra = -mirrored;
1249 							everyone_lite_spot(wpos, j, i);
1250 						}
1251 					case 9:
1252 						if (i == e_ptr->cx + mirrored * 8 && j == e_ptr->cy + 2) {///
1253 							c_ptr->effect = k;
1254 							c_ptr->effect_xtra = -mirrored;
1255 							everyone_lite_spot(wpos, j, i);
1256 						}
1257 						if (i == e_ptr->cx + mirrored * 3 && j == e_ptr->cy + 3) {//_
1258 							c_ptr->effect = k;
1259 							c_ptr->effect_xtra = 2;
1260 							everyone_lite_spot(wpos, j, i);
1261 						}
1262 					case 8:
1263 						if (i == e_ptr->cx + mirrored * 7 && j == e_ptr->cy + 1) {//_
1264 							c_ptr->effect = k;
1265 							c_ptr->effect_xtra = 2;
1266 							everyone_lite_spot(wpos, j, i);
1267 						}
1268 						if (i == e_ptr->cx + mirrored * 4 && j == e_ptr->cy + 3) {//`
1269 							c_ptr->effect = k;
1270 							c_ptr->effect_xtra = mirrored;
1271 							everyone_lite_spot(wpos, j, i);
1272 						}
1273 					case 7:
1274 						if (i == e_ptr->cx + mirrored * 6 && j == e_ptr->cy + 1) {//_
1275 							c_ptr->effect = k;
1276 							c_ptr->effect_xtra = 2;
1277 							everyone_lite_spot(wpos, j, i);
1278 						}
1279 						if (i == e_ptr->cx + mirrored * 5 && j == e_ptr->cy + 2) {//`
1280 							c_ptr->effect = k;
1281 							c_ptr->effect_xtra = mirrored;
1282 							everyone_lite_spot(wpos, j, i);
1283 						}
1284 					case 6:
1285 						if (i == e_ptr->cx + mirrored * 5 && j == e_ptr->cy + 1) {//_
1286 							c_ptr->effect = k;
1287 							c_ptr->effect_xtra = 2;
1288 							everyone_lite_spot(wpos, j, i);
1289 						}
1290 					case 5:
1291 						if (i == e_ptr->cx + mirrored * 4 && j == e_ptr->cy + 1) {///
1292 							c_ptr->effect = k;
1293 							c_ptr->effect_xtra = -mirrored;
1294 							everyone_lite_spot(wpos, j, i);
1295 						}
1296 					case 4:
1297 						if (i == e_ptr->cx + mirrored * 3 && j == e_ptr->cy) {//_
1298 							c_ptr->effect = k;
1299 							c_ptr->effect_xtra = 2;
1300 							everyone_lite_spot(wpos, j, i);
1301 						}
1302 					case 3:
1303 						if (i == e_ptr->cx + mirrored * 2 && j == e_ptr->cy) {//_
1304 							c_ptr->effect = k;
1305 							c_ptr->effect_xtra = 2;
1306 							everyone_lite_spot(wpos, j, i);
1307 						}
1308 					case 2:
1309 						if (i == e_ptr->cx + mirrored * 1 && j == e_ptr->cy) {//_
1310 							c_ptr->effect = k;
1311 							c_ptr->effect_xtra = 2;
1312 							everyone_lite_spot(wpos, j, i);
1313 						}
1314 					case 1:
1315 						if (i == e_ptr->cx && j == e_ptr->cy) {//_
1316 							c_ptr->effect = k;
1317 							c_ptr->effect_xtra = 2;
1318 							everyone_lite_spot(wpos, j, i);
1319 						}
1320 					}
1321 				} else if ((e_ptr->flags & EFF_LIGHTNING2)) {
1322 					int stage = e_ptr->rad;
1323 
1324 					if (stage > 8) stage = 8; /* afterglow */
1325 
1326 					switch (stage) {
1327 					case 8:
1328 						if (i == e_ptr->cx + mirrored * 6 && j == e_ptr->cy + 5) {
1329 							c_ptr->effect = k;
1330 							c_ptr->effect_xtra = mirrored;
1331 							everyone_lite_spot(wpos, j, i);
1332 						}
1333 					case 7:
1334 						if (i == e_ptr->cx + mirrored * 6 && j == e_ptr->cy + 4) {
1335 							c_ptr->effect = k;
1336 							c_ptr->effect_xtra = -mirrored;
1337 							everyone_lite_spot(wpos, j, i);
1338 						}
1339 					case 6:
1340 						if (i == e_ptr->cx + mirrored * 5 && j == e_ptr->cy + 3) {
1341 							c_ptr->effect = k;
1342 							c_ptr->effect_xtra = 2;
1343 							everyone_lite_spot(wpos, j, i);
1344 						}
1345 						if (i == e_ptr->cx - mirrored * (4+1) && j == e_ptr->cy + 3) {
1346 							c_ptr->effect = k;
1347 							c_ptr->effect_xtra = 2;
1348 							everyone_lite_spot(wpos, j, i);
1349 						}
1350 					case 5:
1351 						if (i == e_ptr->cx + mirrored * 4 && j == e_ptr->cy + 3) {
1352 							c_ptr->effect = k;
1353 							c_ptr->effect_xtra = -mirrored;
1354 							everyone_lite_spot(wpos, j, i);
1355 						}
1356 						if (i == e_ptr->cx - mirrored * (3+1) && j == e_ptr->cy + 3) {
1357 							c_ptr->effect = k;
1358 							c_ptr->effect_xtra = 2;
1359 							everyone_lite_spot(wpos, j, i);
1360 						}
1361 					case 4:
1362 						if (i == e_ptr->cx + mirrored * 3 && j == e_ptr->cy + 2) {
1363 							c_ptr->effect = k;
1364 							c_ptr->effect_xtra = 2;
1365 							everyone_lite_spot(wpos, j, i);
1366 						}
1367 						if (i == e_ptr->cx - mirrored * (2+1) && j == e_ptr->cy + 3) {
1368 							c_ptr->effect = k;
1369 							c_ptr->effect_xtra = mirrored;
1370 							everyone_lite_spot(wpos, j, i);
1371 						}
1372 					case 3:
1373 						if (i == e_ptr->cx + mirrored * 2 && j == e_ptr->cy + 2) {
1374 							c_ptr->effect = k;
1375 							c_ptr->effect_xtra = -mirrored;
1376 							everyone_lite_spot(wpos, j, i);
1377 						}
1378 						if (i == e_ptr->cx - mirrored * 2 && j == e_ptr->cy + 2) {
1379 							c_ptr->effect = k;
1380 							c_ptr->effect_xtra = 0;
1381 							everyone_lite_spot(wpos, j, i);
1382 						}
1383 					case 2:
1384 						if (i == e_ptr->cx + mirrored * 1 && j == e_ptr->cy + 1) {
1385 							c_ptr->effect = k;
1386 							c_ptr->effect_xtra = -mirrored;
1387 							everyone_lite_spot(wpos, j, i);
1388 						}
1389 						if (i == e_ptr->cx - mirrored * 1 && j == e_ptr->cy + 1) {
1390 							c_ptr->effect = k;
1391 							c_ptr->effect_xtra = mirrored;
1392 							everyone_lite_spot(wpos, j, i);
1393 						}
1394 					case 1:
1395 						if (i == e_ptr->cx && j == e_ptr->cy) {
1396 							c_ptr->effect = k;
1397 							c_ptr->effect_xtra = 0;
1398 							everyone_lite_spot(wpos, j, i);
1399 						}
1400 					}
1401 				} else if ((e_ptr->flags & EFF_LIGHTNING3)) {
1402 					int stage = e_ptr->rad;
1403 
1404 					if (stage > 10) stage = 10; /* afterglow */
1405 
1406 					switch (stage) {
1407 					case 10:
1408 						if (i == e_ptr->cx - mirrored * 8 && j == e_ptr->cy + 6) {
1409 							c_ptr->effect = k;
1410 							c_ptr->effect_xtra = 0;
1411 							everyone_lite_spot(wpos, j, i);
1412 						}
1413 					case 9:
1414 						if (i == e_ptr->cx - mirrored * 7 && j == e_ptr->cy + 5) {
1415 							c_ptr->effect = k;
1416 							c_ptr->effect_xtra = mirrored;
1417 							everyone_lite_spot(wpos, j, i);
1418 						}
1419 					case 8:
1420 						if (i == e_ptr->cx - mirrored * 6 && j == e_ptr->cy + 4) {
1421 							c_ptr->effect = k;
1422 							c_ptr->effect_xtra = mirrored;
1423 							everyone_lite_spot(wpos, j, i);
1424 						}
1425 					case 7:
1426 						if (i == e_ptr->cx - mirrored * 5 && j == e_ptr->cy + 3) {
1427 							c_ptr->effect = k;
1428 							c_ptr->effect_xtra = 0;
1429 							everyone_lite_spot(wpos, j, i);
1430 						}
1431 					case 6:
1432 						if (i == e_ptr->cx - mirrored * 5 && j == e_ptr->cy + 2) {
1433 							c_ptr->effect = k;
1434 							c_ptr->effect_xtra = mirrored;
1435 							everyone_lite_spot(wpos, j, i);
1436 						}
1437 						if (i == e_ptr->cx - mirrored && j == e_ptr->cy + 4) {
1438 							c_ptr->effect = k;
1439 							c_ptr->effect_xtra = 0;
1440 							everyone_lite_spot(wpos, j, i);
1441 						}
1442 					case 5:
1443 						if (i == e_ptr->cx - mirrored * 4 && j == e_ptr->cy + 1) {
1444 							c_ptr->effect = k;
1445 							c_ptr->effect_xtra = 2;
1446 							everyone_lite_spot(wpos, j, i);
1447 						}
1448 						if (i == e_ptr->cx - mirrored * 2 && j == e_ptr->cy + 3) {
1449 							c_ptr->effect = k;
1450 							c_ptr->effect_xtra = -mirrored;
1451 							everyone_lite_spot(wpos, j, i);
1452 						}
1453 					case 4:
1454 						if (i == e_ptr->cx - mirrored * 3 && j == e_ptr->cy + 1) {
1455 							c_ptr->effect = k;
1456 							c_ptr->effect_xtra = 2;
1457 							everyone_lite_spot(wpos, j, i);
1458 						}
1459 						if (i == e_ptr->cx - mirrored * 3 && j == e_ptr->cy + 2) {
1460 							c_ptr->effect = k;
1461 							c_ptr->effect_xtra = 0;
1462 							everyone_lite_spot(wpos, j, i);
1463 						}
1464 					case 3:
1465 						if (i == e_ptr->cx - mirrored * 2 && j == e_ptr->cy + 1) {
1466 							c_ptr->effect = k;
1467 							c_ptr->effect_xtra = mirrored;
1468 							everyone_lite_spot(wpos, j, i);
1469 						}
1470 					case 2:
1471 						if (i == e_ptr->cx - mirrored * 1 && j == e_ptr->cy) {
1472 							c_ptr->effect = k;
1473 							c_ptr->effect_xtra = 2;
1474 							everyone_lite_spot(wpos, j, i);
1475 						}
1476 					case 1:
1477 						if (i == e_ptr->cx && j == e_ptr->cy) {
1478 							c_ptr->effect = k;
1479 							c_ptr->effect_xtra = mirrored;
1480 							everyone_lite_spot(wpos, j, i);
1481 						}
1482 					}
1483 				}
1484 			}
1485 		}
1486 
1487 		if (e_ptr->flags & EFF_WAVE) e_ptr->rad++;
1488 		/* Creates a "storm" effect*/
1489 		else if (e_ptr->flags & EFF_STORM && who > PROJECTOR_EFFECT) {
1490 			p_ptr = Players[0 - who];
1491 
1492 			e_ptr->cy = p_ptr->py;
1493 			e_ptr->cx = p_ptr->px;
1494 
1495 			for (l = 0; l < tdi[e_ptr->rad]; l++) {
1496 				j = e_ptr->cy + tdy[l];
1497 				i = e_ptr->cx + tdx[l];
1498 				if (!in_bounds2(wpos, j, i)) continue;
1499 
1500 				c_ptr = &zcave[j][i];
1501 
1502 				if (los(wpos, e_ptr->cy, e_ptr->cx, j, i) &&
1503 						(distance(e_ptr->cy, e_ptr->cx, j, i) <= e_ptr->rad))
1504 				{
1505 					c_ptr->effect = k;
1506 					everyone_lite_spot(wpos, j, i);
1507 				}
1508 			}
1509 		}
1510 		/* snowflakes */
1511 		else if (e_ptr->flags & EFF_SNOWING) {
1512 			e_ptr->cy++; /* for now just fall straight downwards */
1513 			/* gusts of wind */
1514 			if (wind_gust > 0) {
1515 				e_ptr->cx--;
1516 				if (e_ptr->cx < 1) e_ptr->cx = MAX_WID - 2;
1517 			}
1518 			if (wind_gust < 0) {
1519 				e_ptr->cx++;
1520 				if (e_ptr->cx >= MAX_WID - 1) e_ptr->cx = 1;
1521 			}
1522 			c_ptr = &zcave[e_ptr->cy][e_ptr->cx];
1523 			c_ptr->effect = k;
1524 			everyone_lite_spot(wpos, e_ptr->cy, e_ptr->cx);
1525 		}
1526 		/* raindrops */
1527 		else if (e_ptr->flags & EFF_RAINING) {
1528 			e_ptr->cy++; /* for now just fall straight downwards */
1529 			/* gusts of wind */
1530 			if (wind_gust > 0) {
1531 				e_ptr->cx--;
1532 				if (e_ptr->cx < 1) e_ptr->cx = MAX_WID - 2;
1533 			}
1534 			if (wind_gust < 0) {
1535 				e_ptr->cx++;
1536 				if (e_ptr->cx >= MAX_WID - 1) e_ptr->cx = 1;
1537 			}
1538 			c_ptr = &zcave[e_ptr->cy][e_ptr->cx];
1539 			c_ptr->effect = k;
1540 			everyone_lite_spot(wpos, e_ptr->cy, e_ptr->cx);
1541 		}
1542 
1543 		/* fireworks */
1544 		else if (e_ptr->flags & (EFF_FIREWORKS1 | EFF_FIREWORKS2 | EFF_FIREWORKS3)) {
1545 			e_ptr->rad++; /* while radius < time/2 -> "rise into the air", otherwise "explode" */
1546 		}
1547 
1548 		/* lightning */
1549 		else if ((e_ptr->flags & (EFF_LIGHTNING1 | EFF_LIGHTNING2 | EFF_LIGHTNING3))
1550 		    && e_ptr->rad < 15) {
1551 			e_ptr->rad++;
1552 		}
1553 	}
1554 
1555 
1556 
1557 	/* Apply sustained effect in the player grid, if any */
1558 //	apply_effect(py, px);
1559 }
1560 
1561 #endif /* pelpel */
1562 
1563 
1564 
1565 /*
1566  * Queued drawing at the beginning of a new turn.
1567  */
1568 static void process_lite_later(void)
1569 {
1570 	int i;
1571 	struct worldspot *wspot;
1572 
1573 	for (i = 0; i < lite_later_num; i++)
1574 	{
1575 		wspot = &lite_later[i];
1576 
1577 		/* Draw now */
1578 		everyone_lite_spot(&wspot->wpos, wspot->y, wspot->x);
1579 	}
1580 
1581 	/* All done */
1582 	lite_later_num = 0;
1583 }
1584 
1585 
1586 
1587 /*
1588  * Regenerate the monsters (once per 100 game turns)
1589  *
1590  * XXX XXX XXX Should probably be done during monster turns.
1591  */
1592 /* Note that since this is done in real time, monsters will regenerate
1593  * faster in game time the deeper they are in the dungeon.
1594  */
1595 static void regen_monsters(void)
1596 {
1597 	int i, frac;
1598 
1599 	/* Regenerate everyone */
1600 	for (i = 1; i < m_max; i++)
1601 	{
1602 		/* Check the i'th monster */
1603 		monster_type *m_ptr = &m_list[i];
1604                 monster_race *r_ptr = race_inf(m_ptr);
1605 
1606 		/* Skip dead monsters */
1607 		if (!m_ptr->r_idx) continue;
1608 
1609 		/* Allow regeneration (if needed) */
1610 		if (m_ptr->hp < m_ptr->maxhp)
1611 		{
1612 			/* Hack -- Base regeneration */
1613 			frac = m_ptr->maxhp / 100;
1614 
1615 			/* Hack -- Minimal regeneration rate */
1616 			if (!frac) frac = 1;
1617 
1618 			/* Hack -- Some monsters regenerate quickly */
1619 			if (r_ptr->flags2 & RF2_REGENERATE) frac *= 2;
1620 
1621 			/* Hack -- Regenerate */
1622 			m_ptr->hp += frac;
1623 
1624 			/* Do not over-regenerate */
1625 			if (m_ptr->hp > m_ptr->maxhp) m_ptr->hp = m_ptr->maxhp;
1626 
1627 			/* Update health bars */
1628 			update_health(i);
1629 		}
1630 	}
1631 }
1632 
1633 
1634 
1635 /* update a particular player's view to daylight, assuming he's on world surface */
1636 bool player_day(int Ind) {
1637 	player_type *p_ptr = Players[Ind];
1638 	int x, y;
1639 	struct dun_level *l_ptr = getfloor(&p_ptr->wpos);
1640 
1641 	if (p_ptr->wpos.wz) return FALSE;
1642 	if (in_sector00(&p_ptr->wpos))
1643 		return FALSE;
1644 	if (l_ptr && (l_ptr->flags2 & LF2_INDOORS)) return FALSE;
1645 
1646 //	if (p_ptr->tim_watchlist) p_ptr->tim_watchlist--;
1647 	if (p_ptr->prace == RACE_VAMPIRE ||
1648 	    (p_ptr->body_monster && r_info[p_ptr->body_monster].d_char == 'V'))
1649 		calc_boni(Ind); /* daylight */
1650 
1651 	/* Hack -- Scan the level */
1652 	for (y = 0; y < MAX_HGT; y++)
1653 	for (x = 0; x < MAX_WID; x++) {
1654 		/* Hack -- Memorize lit grids if allowed */
1655 		if (istownarea(&p_ptr->wpos, MAX_TOWNAREA)
1656 		    && (p_ptr->view_perma_grids)) {
1657 			p_ptr->cave_flag[y][x] |= CAVE_MARK;
1658 		}
1659 		note_spot(Ind, y, x);
1660 	}
1661 
1662 	/* Update the monsters */
1663 	p_ptr->update |= (PU_MONSTERS);
1664 	/* Redraw map */
1665 	p_ptr->redraw |= (PR_MAP);
1666 	/* Window stuff */
1667 	p_ptr->window |= (PW_OVERHEAD);
1668 
1669 #ifdef USE_SOUND_2010
1670 	if (p_ptr->is_day) return FALSE;
1671 	p_ptr->is_day = TRUE;
1672 	handle_music(Ind);
1673 	{
1674 		cave_type **zcave;
1675 		if (!(zcave = getcave(&p_ptr->wpos))) {
1676 			s_printf("DEBUG_DAY: Ind %d, wpos %d,%d,%d\n", Ind, p_ptr->wpos.wx, p_ptr->wpos.wy, p_ptr->wpos.wz);
1677 			return FALSE; /* paranoia */
1678 		}
1679 		handle_ambient_sfx(Ind, &zcave[p_ptr->py][p_ptr->px], &p_ptr->wpos, TRUE);
1680 	}
1681 #endif
1682 
1683 	return TRUE;
1684 }
1685 /* update a particular player's view to night, assuming he's on world surface */
1686 bool player_night(int Ind) {
1687 	player_type *p_ptr = Players[Ind];
1688 	cave_type **zcave = getcave(&p_ptr->wpos);
1689 	int x, y;
1690 	struct dun_level *l_ptr = getfloor(&p_ptr->wpos);
1691 
1692 	if (!zcave) return FALSE; /* paranoia */
1693 
1694 	if (p_ptr->wpos.wz) return FALSE;
1695 	if (in_sector00(&p_ptr->wpos))
1696 		return FALSE;
1697 	if (l_ptr && (l_ptr->flags2 & LF2_INDOORS)) return FALSE;
1698 
1699 //	if (p_ptr->tim_watchlist) p_ptr->tim_watchlist--;
1700 	if (p_ptr->prace == RACE_VAMPIRE ||
1701 	    (p_ptr->body_monster && r_info[p_ptr->body_monster].d_char == 'V'))
1702 		calc_boni(Ind); /* no more daylight */
1703 
1704 	/* Hack -- Scan the level */
1705 	for (y = 0; y < MAX_HGT; y++)
1706 	for (x = 0; x < MAX_WID; x++) {
1707 		/*  Darken "boring" features */
1708 		if (cave_plain_floor_grid(&zcave[y][x]) && !(zcave[y][x].info & CAVE_ROOM)) { /* keep house grids */
1709 			/* Forget the grid */
1710 			p_ptr->cave_flag[y][x] &= ~CAVE_MARK;
1711 		/* Always remember interesting features in town areas */
1712 		} else if (istownarea(&p_ptr->wpos, MAX_TOWNAREA)
1713 		    && (p_ptr->view_perma_grids)) {
1714 			p_ptr->cave_flag[y][x] |= CAVE_MARK;
1715 		}
1716 
1717 		note_spot(Ind, y, x);
1718 	}
1719 
1720 	/* Update the monsters */
1721 	p_ptr->update |= (PU_MONSTERS);
1722 	/* Redraw map */
1723 	p_ptr->redraw |= (PR_MAP);
1724 	/* Window stuff */
1725 	p_ptr->window |= (PW_OVERHEAD);
1726 
1727 #ifdef USE_SOUND_2010
1728 	if (!p_ptr->is_day) return FALSE;
1729 	p_ptr->is_day = FALSE;
1730 	handle_music(Ind);
1731  #if 0 /*done above already*/
1732 	{
1733 		cave_type **zcave;
1734 		if (!(zcave = getcave(&p_ptr->wpos))) {
1735 			s_printf("DEBUG_NIGHT: Ind %d, wpos %d,%d,%d\n", Ind, p_ptr->wpos.wx, p_ptr->wpos.wy, p_ptr->wpos.wz);
1736 			return FALSE; /* paranoia */
1737 		}
1738 		handle_ambient_sfx(Ind, &zcave[p_ptr->py][p_ptr->px], &p_ptr->wpos, TRUE);
1739 	}
1740  #else
1741 	handle_ambient_sfx(Ind, &zcave[p_ptr->py][p_ptr->px], &p_ptr->wpos, TRUE);
1742  #endif
1743 #endif
1744 
1745 	return TRUE;
1746 }
1747 
1748 /* update a particular player's view as a town looks at night, just for dungeon towns */
1749 void player_dungeontown(int Ind) {
1750 	player_type *p_ptr = Players[Ind];
1751 	cave_type **zcave = getcave(&p_ptr->wpos);
1752 	int x, y;
1753 
1754 	if (!zcave) return; /* paranoia */
1755 	s_printf("DUNGEON_TOWN_MAP: %s\n", p_ptr->name);
1756 
1757 	/* Hack -- Scan the level */
1758 	for (y = 0; y < MAX_HGT; y++)
1759 	for (x = 0; x < MAX_WID; x++) {
1760 		/* Always remember interesting features in town areas */
1761 #if 0
1762 		if (!(cave_plain_floor_grid(&zcave[y][x]) && !(zcave[y][x].info & CAVE_ROOM))
1763 		    && p_ptr->view_perma_grids)
1764 #endif
1765 		if (!(cave_plain_floor_grid(&zcave[y][x])) || (zcave[y][x].info & CAVE_ROOM))
1766 			p_ptr->cave_flag[y][x] |= CAVE_MARK;
1767 
1768 		note_spot(Ind, y, x);
1769 	}
1770 
1771 	/* Update the monsters */
1772 	p_ptr->update |= (PU_MONSTERS);
1773 	/* Redraw map */
1774 	p_ptr->redraw |= (PR_MAP);
1775 	/* Window stuff */
1776 	p_ptr->window |= (PW_OVERHEAD);
1777 }
1778 
1779 /* turn an allocated wpos to bright day and update view of players on it */
1780 void world_surface_day(struct worldpos *wpos) {
1781 	cave_type **zcave = getcave(wpos), *c_ptr;
1782 	struct dun_level *l_ptr = getfloor(wpos);
1783 	int y, x;
1784 
1785 	if (!zcave) return; /* paranoia */
1786 
1787 	if (sector00separation && 0 == WPOS_SECTOR00_Z &&
1788 	    wpos->wx == WPOS_SECTOR00_X && wpos->wy == WPOS_SECTOR00_Y) return;
1789 	if (l_ptr && (l_ptr->flags2 & LF2_INDOORS)) return;
1790 
1791 	/* Hack -- Scan the level */
1792 	for (y = 0; y < MAX_HGT; y++)
1793 	for (x = 0; x < MAX_WID; x++) {
1794 		/* Get the cave grid */
1795 		c_ptr = &zcave[y][x];
1796 
1797 		/* Assume lit */
1798 		c_ptr->info |= CAVE_GLOW;
1799 		c_ptr->info &= ~CAVE_DARKEN;
1800 	}
1801 }
1802 
1803 /* turn an allocated wpos to dark night and update view of players on it */
1804 void world_surface_night(struct worldpos *wpos) {
1805 	cave_type **zcave = getcave(wpos), *c_ptr;
1806 	struct dun_level *l_ptr = getfloor(wpos);
1807 	int y, x;
1808 	int stores = 0, y1, x1, i;
1809 	byte sx[255], sy[255];
1810 
1811 	if (!zcave) return; /* paranoia */
1812 
1813 	if (sector00separation && 0 == WPOS_SECTOR00_Z &&
1814 	    wpos->wx == WPOS_SECTOR00_X && wpos->wy == WPOS_SECTOR00_Y) return;
1815 	if (l_ptr && (l_ptr->flags2 & LF2_INDOORS)) return;
1816 
1817 	/* Hack -- Scan the level */
1818 	for (y = 0; y < MAX_HGT; y++)
1819 	for (x = 0; x < MAX_WID; x++) {
1820 		/* Get the cave grid */
1821 		c_ptr = &zcave[y][x];
1822 
1823 		/* darken all */
1824 		if (!(f_info[c_ptr->feat].flags1 & FF1_PROTECTED) &&
1825 		    !(c_ptr->info & CAVE_ROOM)) { /* keep houses' contents lit */
1826 			c_ptr->info &= ~CAVE_GLOW;
1827 			c_ptr->info |= CAVE_DARKEN;
1828 		}
1829 
1830 		if (c_ptr->feat == FEAT_SHOP && stores < 254) {
1831 			sx[stores] = x;
1832 			sy[stores] = y;
1833 			stores++;
1834 		}
1835 	}
1836 
1837 	/* Hack -- illuminate the stores */
1838 	for (i = 0; i < stores; i++) {
1839 		x = sx[i];
1840 		y = sy[i];
1841 
1842 		for (y1 = y - 1; y1 <= y + 1; y1++)
1843 		for (x1 = x - 1; x1 <= x + 1; x1++) {
1844 			/* Get the grid */
1845 			c_ptr = &zcave[y1][x1];
1846 
1847 			/* Illuminate the store */
1848 //			c_ptr->info |= CAVE_ROOM | CAVE_GLOW;
1849 			c_ptr->info |= CAVE_GLOW;
1850 		}
1851 	}
1852 }
1853 
1854 /* Day starts */
1855 static void sun_rises() {
1856 	struct worldpos wrpos;
1857 	int wx, wy, i;
1858 
1859 	night_surface = FALSE;
1860 	wrpos.wz = 0;
1861 
1862 	/* scan through all currently allocated world surface levels */
1863 	for (wx = 0; wx < MAX_WILD_X; wx++)
1864 	for (wy = 0; wy < MAX_WILD_Y; wy++) {
1865 		wrpos.wx = wx;
1866 		wrpos.wy = wy;
1867 		world_surface_day(&wrpos);
1868 	}
1869 
1870 	/* Message all players who witness switch */
1871 	for (i = 1; i <= NumPlayers; i++) {
1872 		if (Players[i]->conn == NOT_CONNECTED) continue;
1873 		if (player_day(i)) msg_print(i, "The sun has risen.");
1874 	}
1875 }
1876 
1877 /* Night starts */
1878 static void night_falls() {
1879 	struct worldpos wrpos;
1880 	int wx, wy, i;
1881 
1882 	night_surface = TRUE;
1883 	wrpos.wz = 0;
1884 
1885 	/* scan through all currently allocated world surface levels */
1886 	for (wx = 0; wx < MAX_WILD_X; wx++)
1887 	for (wy = 0; wy < MAX_WILD_Y; wy++) {
1888 		wrpos.wx = wx;
1889 		wrpos.wy = wy;
1890 		world_surface_night(&wrpos);
1891 	}
1892 
1893 	/* Message all players who witness switch */
1894 	for (i = 1; i <= NumPlayers; i++) {
1895 		if (Players[i]->conn == NOT_CONNECTED) continue;
1896 		if (player_night(i)) msg_print(i, "The sun has fallen.");
1897 	}
1898 
1899 	/* If it's new year's eve, start the fireworks! */
1900 	if (season_newyearseve) fireworks = 1;
1901 }
1902 
1903 /* take care of day/night changes, on world surface.
1904    NOTE: assumes that it gets called every HOUR turns only! */
1905 static void process_day_and_night() {
1906 	bool sunrise, nightfall;
1907 
1908 	/* Check for sunrise or nightfall */
1909 	sunrise = (((turn / HOUR) % 24) == SUNRISE) && IS_DAY; /* IS_DAY checks for events, that's why it's here. - C. Blue */
1910 	nightfall = (((turn / HOUR) % 24) == NIGHTFALL) && IS_NIGHT; /* IS_NIGHT is pointless at the time of coding this, just for consistencies sake with IS_DAY above. */
1911 
1912 	/* Day breaks - not during Halloween {>_>} or during NEW_YEARS_EVE (fireworks)! -- covered by IS_DAY now. */
1913 	if (sunrise)
1914 		sun_rises();
1915 	/* Night falls - but only if it was actually day so far:
1916 	   During HALLOWEEN as well as NEW_YEARS_EVE it stays night all the time >:) (see above) */
1917 	else if (nightfall && !night_surface)
1918 		night_falls();
1919 }
1920 
1921 /* Called when the server starts up */
1922 static void init_day_and_night() {
1923 	if (IS_DAY)
1924 		sun_rises();
1925 	else /* assume IS_NIGHT ;) */
1926 		night_falls();
1927 }
1928 
1929 /*
1930  * Handle certain things once every 50 game turns
1931  */
1932 
1933 static void process_world(int Ind)
1934 {
1935 	player_type *p_ptr = Players[Ind];
1936 	int	i;
1937 //	int	regen_amount, NumPlayers_old = NumPlayers;
1938 
1939 
1940 	/*** Process the monsters ***/
1941 	/* Note : since monsters are added at a constant rate in real time,
1942 	 * this corresponds in game time to them appearing at faster rates
1943 	 * deeper in the dungeon.
1944 	 */
1945 
1946 #if 0 //see below o_O
1947 	/* Check for creature generation */
1948 	if ((!istown(&p_ptr->wpos) && (rand_int(MAX_M_ALLOC_CHANCE) == 0)) ||
1949  #ifndef HALLOWEEN
1950 	    (istown(&p_ptr->wpos) && (rand_int(TOWNIE_RESPAWN_CHANCE * ((3 / NumPlayers) + 1)) == 0)))
1951  #else
1952 	    (istown(&p_ptr->wpos) && (rand_int((in_bree(&p_ptr->wpos) ?
1953 	    HALLOWEEN_TOWNIE_RESPAWN_CHANCE : TOWNIE_RESPAWN_CHANCE) * ((3 / NumPlayers) + 1)) == 0)))
1954  #endif
1955 #endif//0
1956 
1957 	/* Check for creature generation */
1958 #if 0 /* too many people idling all day.. ;) */
1959 	if ((!istown(&p_ptr->wpos) && (rand_int(MAX_M_ALLOC_CHANCE) == 0)) ||
1960 	    (!season_halloween && (istown(&p_ptr->wpos) && (rand_int(TOWNIE_RESPAWN_CHANCE * ((3 / NumPlayers) + 1)) == 0))) ||
1961 	    (season_halloween && (istown(&p_ptr->wpos) && (rand_int((in_bree(&p_ptr->wpos) ?
1962 		HALLOWEEN_TOWNIE_RESPAWN_CHANCE : TOWNIE_RESPAWN_CHANCE) * ((3 / NumPlayers) + 1)) == 0))))
1963 #else /* ..so no longer depending on amount of players in town: */
1964 	if ((!istown(&p_ptr->wpos) && (rand_int(MAX_M_ALLOC_CHANCE) == 0)) ||
1965 	    (!season_halloween && istown(&p_ptr->wpos) && (rand_int(TOWNIE_RESPAWN_CHANCE) == 0)) ||
1966 	    (season_halloween && istown(&p_ptr->wpos) &&
1967 	    (rand_int(in_bree(&p_ptr->wpos) ?
1968 	    HALLOWEEN_TOWNIE_RESPAWN_CHANCE : TOWNIE_RESPAWN_CHANCE) == 0)))
1969 #endif
1970 	{
1971 		dun_level *l_ptr = getfloor(&p_ptr->wpos);
1972 		/* Should we disallow those with MULTIPLY flags to spawn on surface? */
1973 		if (!l_ptr || !(l_ptr->flags1 & LF1_NO_NEW_MONSTER))
1974 		{
1975 			/* Set the monster generation depth */
1976 			monster_level = getlevel(&p_ptr->wpos);
1977 
1978 			if (p_ptr->wpos.wz) (void)alloc_monster(&p_ptr->wpos, MAX_SIGHT + 5, FALSE);
1979 			else wild_add_monster(&p_ptr->wpos);
1980 		}
1981 	}
1982 
1983 	/* Every 1500 turns, warn about any Black Breath not gotten from an equipped
1984 	 * object, and stop any resting. -LM-
1985 	 */
1986 	/* Probably better done in process_player_end?	- Jir - */
1987 	if (!(turn % 3000) && (p_ptr->black_breath))
1988 	{
1989 		msg_print(Ind, "\377WThe Black Breath saps your soul!");
1990 
1991 		/* alert to the neighbors also */
1992 		msg_format_near(Ind, "\377WA dark aura seems to surround %s!", p_ptr->name);
1993 
1994 		disturb(Ind, 0, 0);
1995 	}
1996 
1997 	/* Cold Turkey  */
1998 	i = (p_ptr->csane << 7) / p_ptr->msane;
1999 	if (!(turn % 4200) && !magik(i))
2000 	{
2001 		msg_print(Ind, "\377rA flashback storms your head!");
2002 
2003 		/* alert to the neighbors also */
2004 		if (magik(20)) msg_format_near(Ind, "You see %s's eyes bloodshot.", p_ptr->name);
2005 
2006 		set_image(Ind, p_ptr->image + 12 - i / 8);
2007 		disturb(Ind, 0, 0);
2008 	}
2009 
2010 #ifdef GHOST_FADING
2011 		if (p_ptr->ghost && !p_ptr->admin_dm &&
2012 //			!(turn % GHOST_FADING))
2013 //			!(turn % ((5100L - p_ptr->lev * 50)*GHOST_FADING)))
2014 			!(turn % (GHOST_FADING / p_ptr->lev * 50)))
2015 //			(rand_int(10000) < p_ptr->lev * p_ptr->lev))
2016 			take_xp_hit(Ind, 1 + p_ptr->lev / 5 + p_ptr->max_exp / 10000L, "fading", TRUE, TRUE, FALSE);
2017 #endif	// GHOST_FADING
2018 
2019 }
2020 
2021 /*
2022  * Quick hack to allow mimics to retaliate with innate powers	- Jir -
2023  * It's high time we redesign auto-retaliator	XXX
2024  */
2025 static int retaliate_mimic_power(int Ind, int choice)
2026 {
2027 	player_type *p_ptr = Players[Ind];
2028 	int i, k, num = 3;
2029 
2030 	/* Check for "okay" spells */
2031 	for (k = 0; k < 3; k++) {
2032 		for (i = 0; i < 32; i++) {
2033 			/* Look for "okay" spells */
2034 			if (p_ptr->innate_spells[k] & (1L << i)) {
2035 				if (num == choice) return (k * 32 + i);
2036 				num++;
2037 			}
2038 		}
2039 	}
2040 
2041 	return (0);
2042 }
2043 
2044 /*
2045  * Handle items for auto-retaliation  - Jir -
2046  * use_old_target is *strongly* recommended to actually make use of it.
2047  * If fallback is TRUE the melee weapon will be used if the intended means failed. - C. Blue
2048  */
2049 static bool retaliate_item(int Ind, int item, cptr inscription, bool fallback) {
2050 	player_type *p_ptr = Players[Ind];
2051 	object_type *o_ptr;;
2052 	int cost, choice = 0, spell = 0;
2053 
2054 	if (item < 0) return FALSE;
2055 	o_ptr = &p_ptr->inventory[item];
2056 	if (!o_ptr->k_idx) return FALSE;
2057 
2058 	/* 'Do nothing' inscription */
2059 	if (inscription != NULL && *inscription == 'x') return TRUE;
2060 
2061 	/* Is it variant @Ot for town-only auto-retaliation? - C. Blue */
2062 	if (*inscription == 't') {
2063 		if (!istownarea(&p_ptr->wpos, MAX_TOWNAREA)) return FALSE;
2064 		inscription++;
2065 	}
2066 
2067 #ifndef AUTO_RET_CMD
2068 	/* Hack -- use innate power via inscription on any item */
2069 	if (inscription != NULL && *inscription == 'M' && get_skill(p_ptr, SKILL_MIMIC)) {
2070 		/* Spell to cast */
2071 		if (*(inscription + 1)) {
2072 			choice = *(inscription + 1) - 97;
2073 
2074 			/* valid inscription? */
2075 			if (choice >= 0) {
2076 				/* shape-changing for retaliation is not so nice idea, eh? */
2077 				if (choice < 4) {	/* 3 polymorph powers + immunity preference */
2078 #if 1
2079 					return FALSE;
2080 #else
2081 					/* hack: prevent 'polymorph into...' power */
2082 					if (choice == 2) do_cmd_mimic(Ind, 1, 5);
2083 					else do_cmd_mimic(Ind, choice, 5);
2084 					return TRUE;
2085 #endif
2086 				} else {
2087 					int power = retaliate_mimic_power(Ind, choice - 1); /* immunity preference */
2088 					bool dir = FALSE;
2089 					if (innate_powers[power].smana > p_ptr->csp && fallback) return (p_ptr->fail_no_melee);
2090 #if 0
2091 					if (power) {
2092 						/* undirected power? */
2093 						switch (power) {
2094 						case 0:
2095 						case 64: case 66:
2096 						case 68: case 69:
2097 						case 76:
2098 							do_cmd_mimic(Ind, power + 3, 0);
2099 							return TRUE;
2100 						}
2101 						/* power requires direction? */
2102 						do_cmd_mimic(Ind, power + 3, 5);
2103 						return TRUE;
2104 					}
2105 #else
2106 					switch (power / 32) {
2107 					case 0: dir = monster_spells4[power].uses_dir;
2108 						break;
2109 					case 1: dir = monster_spells5[power - 32].uses_dir;
2110 						break;
2111 					case 2: dir = monster_spells6[power - 64].uses_dir;
2112 						break;
2113 					}
2114 					do_cmd_mimic(Ind, power + 3, dir ? 5 : 0);
2115 					return TRUE;
2116 #endif
2117 				}
2118 			}
2119 		}
2120 		return FALSE;
2121 	}
2122 #endif
2123 
2124 #ifndef AUTO_RET_NEW
2125 	/* Only fighter classes can use various items for this */
2126 	if (is_fighter(p_ptr)) {
2127 #if 0
2128 		/* item with {@O-} is used only when in danger */
2129 		if (*inscription == '-' && p_ptr->chp > p_ptr->mhp / 2) return FALSE;
2130 #endif
2131 
2132 		switch (o_ptr->tval) {
2133 		/* non-directional ones */
2134 		case TV_SCROLL:
2135 			do_cmd_read_scroll(Ind, item);
2136 			return TRUE;
2137 		case TV_POTION:
2138 			do_cmd_quaff_potion(Ind, item);
2139 			return TRUE;
2140 		case TV_STAFF:
2141 			do_cmd_use_staff(Ind, item);
2142 			return TRUE;
2143 		case TV_ROD:
2144 			do_cmd_zap_rod(Ind, item, 5);
2145 			return TRUE;
2146 		case TV_WAND:
2147 			do_cmd_aim_wand(Ind, item, 5);
2148 			return TRUE;
2149 		}
2150 	}
2151 #else
2152 	switch (o_ptr->tval) {
2153 	case TV_STAFF:
2154 		if (((o_ptr->ident & ID_EMPTY) || ((o_ptr->ident & ID_KNOWN) && o_ptr->pval == 0))
2155 		    && fallback)
2156 			return (p_ptr->fail_no_melee);
2157 		do_cmd_use_staff(Ind, item);
2158 		return TRUE;
2159 	case TV_ROD:
2160 		if (o_ptr->pval != 0 && fallback)
2161 			return (p_ptr->fail_no_melee);
2162 		do_cmd_zap_rod(Ind, item, 5);
2163 		return TRUE;
2164 	case TV_WAND:
2165 		if (((o_ptr->ident & ID_EMPTY) || ((o_ptr->ident & ID_KNOWN) && o_ptr->pval == 0))
2166 		    && fallback)
2167 			return (p_ptr->fail_no_melee);
2168 		do_cmd_aim_wand(Ind, item, 5);
2169 		return TRUE;
2170 	}
2171 #endif
2172 
2173 	/* Accept reasonable targets:
2174 	 * This prevents a player from getting stuck when facing a
2175 	 * monster inside a wall.
2176 	 * NOTE: The above statement becomes obsolete nowadays if
2177 	 * PY_PROJ_ and similar are defined.
2178 	 */
2179 	if (!target_able(Ind, p_ptr->target_who)) return FALSE;
2180 
2181 	/* Spell to cast */
2182 	if (inscription != NULL) {
2183 		choice = *inscription - 96 - 1;
2184 		if (choice < 0 || choice > 9) choice = 0;
2185 	}
2186 
2187 	switch (o_ptr->tval) {
2188 		/* weapon -- attack normally! */
2189 		case TV_MSTAFF:
2190 		case TV_BLUNT:
2191 		case TV_POLEARM:
2192 		case TV_SWORD:
2193 		case TV_AXE:
2194 //redundant?->		if (item == INVEN_WIELD) return FALSE;
2195 			return FALSE;
2196 			break;
2197 
2198 		/* directional ones */
2199 		case TV_SHOT:
2200 		case TV_ARROW:
2201 		case TV_BOLT:
2202 		case TV_BOW:
2203 //		case TV_BOOMERANG:
2204 //		case TV_INSTRUMENT:
2205 			if (item == INVEN_BOW || item == INVEN_AMMO) {
2206 				if (!p_ptr->inventory[INVEN_AMMO].k_idx ||
2207 					!p_ptr->inventory[INVEN_AMMO].number)
2208 					break;
2209 
2210 				retaliating_cmd = TRUE;
2211 				do_cmd_fire(Ind, 5);
2212 				if (p_ptr->ranged_double) do_cmd_fire(Ind, 5);
2213 				return TRUE;
2214 			}
2215 			break;
2216 
2217 		case TV_BOOMERANG:
2218 			if (item == INVEN_BOW)
2219 			{
2220 				retaliating_cmd = TRUE;
2221 				do_cmd_fire(Ind, 5);
2222 				return TRUE;
2223 			}
2224 			break;
2225 
2226 		/* spellbooks - mikaelh */
2227 		case TV_BOOK:
2228 			if (o_ptr->sval == SV_SPELLBOOK) {
2229 				/* It's a spellbook */
2230 
2231 				/* There's only one spell in a spellbook */
2232 				spell = o_ptr->pval;
2233 			} else {
2234 				/* It's a tome */
2235 
2236 				/* Get the spell */
2237 				if (MY_VERSION < (4 << 12 | 4 << 8 | 1 << 4 | 8)) {
2238 					/* no longer supported! to make s_aux.lua slimmer */
2239 					spell = exec_lua(Ind, format("return spell_x(%d, %d, %d)", o_ptr->sval, o_ptr->pval, choice));
2240 				} else {
2241 					spell = exec_lua(Ind, format("return spell_x2(%d, %d, %d, %d)", item, o_ptr->sval, o_ptr->pval, choice));
2242 				}
2243 			}
2244 
2245 			cost = exec_lua(Ind, format("return get_mana(%d, %d)", Ind, spell));
2246 			if (cost > p_ptr->csp && fallback) return (p_ptr->fail_no_melee);
2247 
2248 			/* Check that it's ok... more checks needed here? */
2249 			/* Limit amount of mana used? */
2250 			if (!p_ptr->blind && !no_lite(Ind) && !p_ptr->confused && cost <= p_ptr->csp &&
2251 				exec_lua(Ind, format("return is_ok_spell(%d, %d)", Ind, spell)))
2252 			{
2253 				cast_school_spell(Ind, item, spell, 5, -1, 0);
2254 				return TRUE;
2255 			}
2256 			break;
2257 
2258 
2259 		case TV_RUNE: { //Format: @O<t?><imperative><form> {!R}
2260 
2261 			/* Validate Rune */
2262 			if (o_ptr->sval < 0 || o_ptr->sval > RCRAFT_MAX_PROJECTIONS) break;
2263 			u16b e_flags = r_projections[o_ptr->sval].flags, m_flags = 0;
2264 			byte m_index = 0;
2265 
2266 			/* Validate Imperative */
2267 			if (*inscription != '\0') {
2268 				m_index = *inscription - 'a';
2269 				if (m_index < 0 || m_index > RCRAFT_MAX_IMPERATIVES) m_flags |= I_MINI;
2270 				else m_flags |= r_imperatives[m_index].flag;
2271 			}
2272 			else {
2273 				if (cast_rune_spell(Ind, 5, e_flags, I_MINI | T_BOLT, 0, 1) == 2) return (p_ptr->fail_no_melee);
2274 				return TRUE;
2275 			}
2276 
2277 			/* Next Letter */
2278 			inscription++;
2279 
2280 			/* Validate Form */
2281 			if (*inscription != '\0') {
2282 				m_index = *inscription - 'a';
2283 				if (m_index < 0 || m_index > RCRAFT_MAX_TYPES || r_types[m_index].flag == T_SIGN || r_types[m_index].flag == T_RUNE || r_types[m_index].flag == T_ENCH) m_flags |= T_BOLT; //Hack -- Disallow 'self' types...
2284 				else m_flags |= r_types[m_index].flag;
2285 			}
2286 			else {
2287 				if (cast_rune_spell(Ind, 5, e_flags, I_MINI | T_BOLT, 0, 1) == 2) return (p_ptr->fail_no_melee);
2288 				return TRUE;
2289 			}
2290 
2291 			/* Retaliate or Melee */
2292 			if (cast_rune_spell(Ind, 5, e_flags, m_flags, 0, 1) == 2) return (p_ptr->fail_no_melee);
2293 			return TRUE;
2294 
2295 		break; }
2296 	}
2297 
2298 	/* If all fails, then melee */
2299 	return (p_ptr->fail_no_melee);
2300 }
2301 
2302 #ifdef AUTO_RET_CMD
2303 /* Check auto-retaliation set via slash command /autoret or /ar.
2304    This was added for mimics to use their powers without having to inscribe
2305    a random item as a workaround. - C. Blue */
2306 static bool retaliate_cmd(int Ind, bool fallback) {
2307 	player_type *p_ptr = Players[Ind];
2308 	int ar = p_ptr->autoret;
2309 
2310 	/* Is it variant @Ot for town-only auto-retaliation? - C. Blue */
2311 	if (ar >= 100) {
2312 		if (!istownarea(&p_ptr->wpos, MAX_TOWNAREA)) return FALSE;
2313 		ar -= 100;
2314 	}
2315 
2316 	/* no autoret set? */
2317 	if (!ar) return FALSE;
2318 
2319 	/* Hack -- use innate power via inscription on any item */
2320 	if (get_skill(p_ptr, SKILL_MIMIC)) {
2321 		/* Spell to cast */
2322 		int choice = ar - 1;
2323 
2324 		if (choice < 4)	/* 3 polymorph powers + immunity preference */
2325 			return FALSE;
2326 
2327 		int power = retaliate_mimic_power(Ind, choice - 1);
2328 		bool dir = FALSE;
2329 		if (innate_powers[power].smana > p_ptr->csp && fallback) return (p_ptr->fail_no_melee);
2330 		switch (power / 32) {
2331 		case 0: dir = monster_spells4[power].uses_dir;
2332 			break;
2333 		case 1: dir = monster_spells5[power - 32].uses_dir;
2334 			break;
2335 		case 2: dir = monster_spells6[power - 64].uses_dir;
2336 			break;
2337 		}
2338 
2339 		/* Accept reasonable targets:
2340 		 * This prevents a player from getting stuck when facing a
2341 		 * monster inside a wall.
2342 		 * NOTE: The above statement becomes obsolete nowadays if
2343 		 * PY_PROJ_ and similar are defined.
2344 		 */
2345 		if (!target_able(Ind, p_ptr->target_who)) return FALSE;
2346 
2347 		do_cmd_mimic(Ind, power + 3, dir ? 5 : 0);
2348 		return TRUE;
2349 	}
2350 
2351 	/* If all fails, then melee */
2352 	return (p_ptr->fail_no_melee);
2353 }
2354 #endif
2355 
2356 /*
2357  * Check for nearby players or monsters and attempt to do something useful.
2358  *
2359  * This function should only be called if the player is "lagging" and helpless
2360  * to do anything about the situation.  This is not intended to be incredibly
2361  * useful, merely to prevent deaths due to extreme lag.
2362  */
2363  /* This function returns a 0 if no attack has been performed, a 1 if an attack
2364   * has been performed and there are still monsters around, and a 2 if an attack
2365   * has been performed and all of the surrounding monsters are dead.
2366   * (This difference between 1 and 2 isn't used anywhere... but I leave it for
2367   *  future use.	Jir)
2368   */
2369   /* We now intelligently try to decide which monster to autoattack.  Our current
2370    * algorithm is to fight first Q's, then any monster that is 20 levels higher
2371    * than its peers, then the most proportionatly wounded monster, then the highest
2372    * level monster, then the monster with the least hit points.
2373    */
2374 /* Now a player can choose the way of auto-retaliating;		- Jir -
2375  * Item marked with inscription {@O} will be used automatically.
2376  * For spellbooks this should be {@Oa} to specify which spell to use.
2377  * You can also choose to 'do nothing' by inscribing it on not-suitable item.
2378  *
2379  * Fighters are allowed to use {@O-}, which is only used if his HP is 1/2 or less.
2380  * ({@O-} feature is commented out)
2381  */
2382 /* handle RF7_NO_TARGET monsters so they won't block auto-retaliation?
2383    This involves checking for retal-item before checking for retal-target.
2384    That is probably much more expensive on CPU than the other way round.
2385    Also see CHEAP_NO_TARGET_TEST. - C. Blue
2386    NOTE: I added code that prevents auto-ret with physical attacks against a
2387    wraithed target, this code is in EXPENSIVE_NO_TARGET_TEST only, so it won't
2388    work if this isn't defined. This was already the case for melee, just not for @O ranged. */
2389 #define EXPENSIVE_NO_TARGET_TEST
2390 static int auto_retaliate(int Ind) {
2391 	player_type *p_ptr = Players[Ind], *q_ptr, *p_target_ptr = NULL, *prev_p_target_ptr = NULL;
2392 	int d, i, tx, ty, target, prev_target, item = -1;
2393 //	char friends = 0;
2394 	monster_type *m_ptr, *m_target_ptr = NULL, *prev_m_target_ptr = NULL;
2395 	monster_race *r_ptr = NULL, *r_ptr2, *r_ptr0;
2396 	object_type *o_ptr;
2397 	cptr inscription = NULL, at_O_inscription = NULL;
2398 	bool no_melee = FALSE, fallback = FALSE;
2399 	bool skip_monsters = (p_ptr->cloaked || p_ptr->shadow_running) && !p_ptr->stormbringer;
2400 	cave_type **zcave;
2401 	/* are we dealing just physical damage? for wraithform checks (stormbringer ignores everything and just attacks anyway..): */
2402 	bool physical = TRUE, wraith = (p_ptr->tim_wraith != 0) && !p_ptr->stormbringer;
2403 
2404 	if (!(zcave = getcave(&p_ptr->wpos))) return(FALSE);
2405 
2406 	if (p_ptr->new_level_flag) return 0;
2407 
2408 	/* disable auto-retaliation if we skip monsters/hostile players and blood-bonded players likewise */
2409 	if (skip_monsters && !p_ptr->blood_bond) return 0;
2410 
2411 	/* Just to kill compiler warnings */
2412 	target = prev_target = 0;
2413 
2414 #ifdef EXPENSIVE_NO_TARGET_TEST
2415 	/* Pick an item with {@O} inscription */
2416 	for (i = 0; i < INVEN_TOTAL; i++) {
2417 		o_ptr = &p_ptr->inventory[i];
2418 		if (!o_ptr->tval) continue;
2419 
2420 		inscription = quark_str(o_ptr->note);
2421 
2422 		/* check for a valid inscription */
2423 		if (inscription == NULL) continue;
2424 
2425 		/* scan the inscription for @O */
2426 		while (*inscription != '\0') {
2427 			if (*inscription == '@') {
2428 				inscription++;
2429 
2430 				/* a valid @O has been located */
2431 				/* @O shouldn't work on weapons or ammo in inventory - mikaelh */
2432 				if ((*inscription == 'O' || *inscription == 'Q') && !(i < INVEN_WIELD &&
2433 				    (is_weapon(o_ptr->tval) || is_ammo(o_ptr->tval) ||
2434 				    is_armour(o_ptr->tval) || o_ptr->tval == TV_MSTAFF ||
2435 				    o_ptr->tval == TV_BOW || o_ptr->tval == TV_BOOMERANG))) {
2436 					if (*inscription == 'Q') fallback = TRUE;
2437 					inscription++;
2438 
2439 					/* Skip this item in case it has @Ox */
2440 					if (*inscription == 'x') {
2441 						p_ptr->warning_autoret = 99; /* seems he knows what he's doing! */
2442 						break;
2443 					}
2444 
2445 					/* Select the first usable item with @O */
2446 					item = i;
2447 					i = INVEN_TOTAL;
2448 
2449 					/* Remember the inscription */
2450 					at_O_inscription = inscription;
2451 
2452 					p_ptr->warning_autoret = 99; /* seems he knows what he's doing! */
2453 					break;
2454 				}
2455 			}
2456 			inscription++;
2457 		}
2458 	}
2459 
2460 	/* check if we're using physical damage attacks */
2461 	if (item != -1) physical = is_weapon(o_ptr->tval) || o_ptr->tval == TV_MSTAFF || is_ranged_weapon(o_ptr->tval) || is_ammo(o_ptr->tval);
2462 
2463 	/* Scan for @Ox to disable auto-retaliation only if no @O was found - mikaelh */
2464 	for (i = INVEN_WIELD; i < INVEN_TOTAL; i++) {
2465 		o_ptr = &p_ptr->inventory[i];
2466 		if (!o_ptr->tval) continue;
2467 
2468 		inscription = quark_str(o_ptr->note);
2469 
2470 		/* check for a valid inscription */
2471 		if (inscription == NULL) continue;
2472 
2473 		/* scan the inscription for @O */
2474 		while (*inscription != '\0') {
2475 			if (inscription[0] == '@' && (inscription[1] == 'O' || inscription[1] == 'Q') && inscription[2] == 'x') {
2476 				p_ptr->warning_autoret = 99; /* seems he knows what he's doing! */
2477 
2478 				if (i == INVEN_WIELD || i == INVEN_ARM) {
2479 					/* Prevent melee retaliation - mikaelh */
2480 					no_melee = TRUE;
2481 				}
2482 
2483 				if (item == -1) {
2484 					/* Select the item with @Ox */
2485 					item = i;
2486 
2487 					/* Make at_O_inscription point to the 'x' */
2488 					at_O_inscription = inscription + 2;
2489 
2490 					i = INVEN_TOTAL; /* exit the outer loop too */
2491 					break;
2492 				}
2493 			}
2494 			inscription++;
2495 		}
2496 	}
2497 
2498 	/* no specific item inscribed -> use default melee attacks */
2499 	if (item == -1) physical = TRUE;
2500 #endif
2501 
2502 	/* check for monster/player targets */
2503 	for (d = 1; d <= 9; d++) {
2504 		if (d == 5) continue;
2505 
2506 		tx = p_ptr->px + ddx[d];
2507 		ty = p_ptr->py + ddy[d];
2508 
2509 		if (!in_bounds(ty, tx)) continue;
2510 
2511 		if (!(i = zcave[ty][tx].m_idx)) continue;
2512 		if (i > 0) {
2513 			m_ptr = &m_list[i];
2514 			r_ptr0 = race_inf(m_ptr);
2515 
2516 			/* Paranoia -- Skip dead monsters */
2517 			if (!m_ptr->r_idx) continue;
2518 
2519 			/* Make sure that the player can see this monster */
2520 			if (!p_ptr->mon_vis[i]) continue;
2521 
2522 			/* Stop annoying auto-retaliation against certain 'monsters' */
2523 			if (r_ptr0->flags8 & RF8_NO_AUTORET) continue;
2524 
2525 #ifdef EXPENSIVE_NO_TARGET_TEST
2526 			/* Skip monsters we cannot actually target! (Sparrows) */
2527 			if ((r_ptr0->flags7 & RF7_NO_TARGET) &&
2528 			    is_ranged_item(Ind, &p_ptr->inventory[item]))
2529 				continue;
2530 
2531 			/* New - wraithform checks: Don't attack monsters that we'd deal 0 damage against and just wake up */
2532 			if (wraith && physical && !(r_ptr0->flags2 & RF2_PASS_WALL)) continue;
2533 #endif
2534 
2535 			/* Protect pets/golems */
2536 #if 0 /* Only vs our own pet/golem? */
2537 			if (p_ptr->id == m_ptr->owner && !p_ptr->stormbringer) continue;
2538 #else /* vs own+other players' pets/golems? */
2539 			if (m_ptr->owner && !p_ptr->stormbringer) continue;
2540 #endif
2541 
2542 			/* specialty: don't auto-retaliate charmed monsters.
2543 			   Maybe slightly inconsistent with the fact that we still auto-ret sleeping monsters ;). */
2544 			if (m_ptr->charmedignore && !p_ptr->stormbringer) continue;
2545 
2546 			/* Figure out if this is the best target so far */
2547 			if (!m_target_ptr) {
2548 				prev_m_target_ptr = m_target_ptr;
2549 				m_target_ptr = m_ptr;
2550 				r_ptr = race_inf(m_ptr);
2551 				prev_target = target;
2552 				target = i;
2553 			} else {
2554 				/* Target dummy should always be the last one to get attacked - mikaelh */
2555 				if (m_ptr->r_idx == RI_TARGET_DUMMY1 || m_ptr->r_idx == RI_TARGET_DUMMY2 ||
2556 				    m_ptr->r_idx == RI_TARGET_DUMMYA1 || m_ptr->r_idx == RI_TARGET_DUMMYA2)
2557 					continue;
2558 
2559 				r_ptr2 = r_ptr;
2560 				r_ptr = race_inf(m_ptr);
2561 
2562 				/* If it is a Q, then make it our new target. */
2563 				/* We don't handle the case of choosing between two
2564 				 * Q's because if the player is standing next to two Q's
2565 				 * he deserves whatever punishment he gets.
2566 				 */
2567                                 if (r_ptr->d_char == 'Q') {
2568 					prev_m_target_ptr = m_target_ptr;
2569 					m_target_ptr = m_ptr;
2570 					prev_target = target;
2571 					target = i;
2572 				}
2573 				/* Otherwise if it is 20 levels higher than everything
2574 				 * else attack it.
2575 				 */
2576 				else if ((r_ptr->level - 20) >= r_ptr2->level) {
2577 					prev_m_target_ptr = m_target_ptr;
2578 					m_target_ptr = m_ptr;
2579 					prev_target = target;
2580 					target = i;
2581 				}
2582 				/* Otherwise if it is the most proportionatly wounded monster
2583 				 * attack it.
2584 				 */
2585 				else if (m_ptr->hp * m_target_ptr->maxhp < m_target_ptr->hp * m_ptr->maxhp) {
2586 					prev_m_target_ptr = m_target_ptr;
2587 					m_target_ptr = m_ptr;
2588 					prev_target = target;
2589 					target = i;
2590 				}
2591 				/* If it is a tie attack the higher level monster */
2592 				else if (m_ptr->hp * m_target_ptr->maxhp == m_target_ptr->hp * m_ptr->maxhp) {
2593 					if (r_ptr->level > r_ptr2->level) {
2594 						prev_m_target_ptr = m_target_ptr;
2595 						m_target_ptr = m_ptr;
2596 						prev_target = target;
2597 						target = i;
2598 					}
2599 					/* If it is a tie attack the monster with less hit points */
2600 					else if (r_ptr->level == r_ptr2->level) {
2601 						if (m_ptr->hp < m_target_ptr->hp) {
2602 							prev_m_target_ptr = m_target_ptr;
2603 							m_target_ptr = m_ptr;
2604 							prev_target = target;
2605 							target = i;
2606 						}
2607 					}
2608 				}
2609 			}
2610 		} else if (cfg.use_pk_rules != PK_RULES_NEVER) {
2611 			i = -i;
2612 			if (!(q_ptr = Players[i])) continue;
2613 
2614 			/* Skip non-connected players */
2615 			if (q_ptr->conn == NOT_CONNECTED) continue;
2616 
2617 			/* Skip players we aren't hostile to */
2618 			if (!check_hostile(Ind, i) && !p_ptr->stormbringer) continue;
2619 
2620 			/* Skip players we cannot see */
2621 			if (!p_ptr->play_vis[i]) continue;
2622 
2623 			/* Figure out if this is the best target so far */
2624 			if (p_target_ptr) {
2625 				/* If we are 15 levels over the old target, make this
2626 				 * player our new target.
2627 				 */
2628 				if ((q_ptr->lev - 15) >= p_target_ptr->lev) {
2629 					prev_p_target_ptr = p_target_ptr;
2630 					p_target_ptr = q_ptr;
2631 					prev_target = target;
2632 					target = -i;
2633 				}
2634 				/* Otherwise attack this player if he is more proportionatly
2635 				 * wounded than our old target.
2636 				 */
2637 				else if (q_ptr->chp * p_target_ptr->mhp < p_target_ptr->chp * q_ptr->mhp) {
2638 					prev_p_target_ptr = p_target_ptr;
2639 					p_target_ptr = q_ptr;
2640 					prev_target = target;
2641 					target = -i;
2642 				}
2643 				/* If it is a tie attack the higher level player */
2644 				else if (q_ptr->chp * p_target_ptr->mhp == p_target_ptr->chp * q_ptr->mhp) {
2645 					if (q_ptr->lev > p_target_ptr->lev) {
2646 						prev_p_target_ptr = p_target_ptr;
2647 						p_target_ptr = q_ptr;
2648 						prev_target = target;
2649 						target = -i;
2650 					}
2651 					/* If it is a tie attack the player with less hit points */
2652 					else if (q_ptr->lev == p_target_ptr->lev) {
2653 						if (q_ptr->chp < p_target_ptr->chp) {
2654 							prev_p_target_ptr = p_target_ptr;
2655 							p_target_ptr = q_ptr;
2656 							prev_target = target;
2657 							target = -i;
2658 						}
2659 					}
2660 				}
2661 			} else {
2662 				prev_p_target_ptr = p_target_ptr;
2663 				p_target_ptr = q_ptr;
2664 				prev_target = target;
2665 				target = -i;
2666 			}
2667 		}
2668 	}
2669 
2670 	/* Nothing to attack */
2671 	if (!p_target_ptr && !m_target_ptr) {
2672 		/* Hack: If we don't have a 'continuous attack' ie are out of
2673 		   adjacent targets, which just happened here, stop 'piercing' attacks */
2674 		if (p_ptr->piercing && !p_ptr->piercing_charged) p_ptr->piercing = 0;
2675 
2676 		return 0;
2677 	}
2678 
2679 #ifndef EXPENSIVE_NO_TARGET_TEST
2680 	/* Pick an item with {@O} inscription */
2681 	for (i = 0; i < INVEN_TOTAL; i++) {
2682 		o_ptr = &p_ptr->inventory[i];
2683 		if (!o_ptr->tval) continue;
2684 
2685 		inscription = quark_str(o_ptr->note);
2686 
2687 		/* check for a valid inscription */
2688 		if (inscription == NULL) continue;
2689 
2690 		/* scan the inscription for @O */
2691 		while (*inscription != '\0') {
2692 			if (*inscription == '@') {
2693 				inscription++;
2694 
2695 				/* a valid @O has been located */
2696 				/* @O shouldn't work on weapons or ammo in inventory - mikaelh */
2697 				if ((*inscription == 'O' || *inscription == 'Q') && !(i < INVEN_WIELD &&
2698 				    (is_weapon(o_ptr->tval) || is_ammo(o_ptr->tval) ||
2699 				    is_armour(o_ptr->tval) || o_ptr->tval == TV_MSTAFF ||
2700 				    o_ptr->tval == TV_BOW || o_ptr->tval == TV_BOOMERANG))) {
2701 					if (*inscription == 'Q') fallback = TRUE;
2702 					inscription++;
2703 
2704 					/* Skip this item in case it has @Ox */
2705 					if (*inscription == 'x') {
2706 						p_ptr->warning_autoret = 99; /* seems he knows what he's doing! */
2707 						break;
2708 					}
2709 
2710 					/* Select the first usable item with @O */
2711 					item = i;
2712 					i = INVEN_TOTAL;
2713 
2714 					/* Remember the inscription */
2715 					at_O_inscription = inscription;
2716 
2717 					p_ptr->warning_autoret = 99; /* seems he knows what he's doing! */
2718 					break;
2719 				}
2720 			}
2721 			inscription++;
2722 		}
2723 	}
2724 
2725 	/* Scan for @Ox to disable auto-retaliation only if no @O was found - mikaelh */
2726 	for (i = INVEN_WIELD; i < INVEN_TOTAL; i++) {
2727 		o_ptr = &p_ptr->inventory[i];
2728 		if (!o_ptr->tval) continue;
2729 
2730 		inscription = quark_str(o_ptr->note);
2731 
2732 		/* check for a valid inscription */
2733 		if (inscription == NULL) continue;
2734 
2735 		/* scan the inscription for @O */
2736 		while (*inscription != '\0') {
2737 			if (inscription[0] == '@' && (inscription[1] == 'O' || inscription[1] == 'Q') && inscription[2] == 'x') {
2738 				p_ptr->warning_autoret = 99; /* seems he knows what he's doing! */
2739 
2740 				if (i == INVEN_WIELD || i == INVEN_ARM) {
2741 					/* Prevent melee retaliation - mikaelh */
2742 					no_melee = TRUE;
2743 				}
2744 
2745 				if (item == -1) {
2746 					/* Select the item with @Ox */
2747 					item = i;
2748 
2749 					/* Make at_O_inscription point to the 'x' */
2750 					at_O_inscription = inscription + 2;
2751 
2752 					i = INVEN_TOTAL; /* exit the outer loop too */
2753 					break;
2754 				}
2755 			}
2756 			inscription++;
2757 		}
2758 	}
2759 #endif
2760 
2761 	/* If we have a player target, attack him. */
2762 	if (p_target_ptr) {
2763 		/* set the target */
2764 		p_ptr->target_who = target;
2765 
2766 		/* Attack him */
2767 		/* Stormbringer bypasses everything!! */
2768 //		py_attack(Ind, p_target_ptr->py, p_target_ptr->px);
2769 		if (p_ptr->stormbringer || (
2770 #ifdef AUTO_RET_CMD
2771 		    !retaliate_cmd(Ind, fallback) &&
2772 #endif
2773 		    !retaliate_item(Ind, item, at_O_inscription, fallback) &&
2774 		    !p_ptr->afraid && !no_melee)) {
2775 			py_attack(Ind, p_target_ptr->py, p_target_ptr->px, FALSE);
2776 		}
2777 
2778 		/* Check if he is still alive or another targets exists */
2779 		if ((!p_target_ptr->death) || (prev_p_target_ptr) || (m_target_ptr)) {
2780 			/* We attacked something */
2781 			return 1;
2782 		} else {
2783 			/* Otherwise return 2 to indicate we are no longer
2784 			 * autoattacking anything.
2785 			 */
2786 			return 2;
2787 		}
2788 	}
2789 
2790 	/* The dungeon master does not fight his or her offspring */
2791 	if (p_ptr->admin_dm) return 0;
2792 
2793 	/* If we have a target to attack, attack it! */
2794 	if (m_target_ptr) {
2795 		/* set the target */
2796 		p_ptr->target_who = target;
2797 		if (m_target_ptr->pet) { //a pet?
2798 			return 0;
2799 		}
2800 
2801 		/* Attack it */
2802 //		py_attack(Ind, m_target_ptr->fy, m_target_ptr->fx);
2803 		if (p_ptr->stormbringer || (
2804 #ifdef AUTO_RET_CMD
2805 		    !retaliate_cmd(Ind, fallback) &&
2806 #endif
2807 		    !retaliate_item(Ind, item, at_O_inscription, fallback) &&
2808 		    !p_ptr->afraid && !no_melee)) {
2809 			py_attack(Ind, m_target_ptr->fy, m_target_ptr->fx, FALSE);
2810 
2811 			/* manage autoretaliation warning for newbies (reset it) */
2812 			if (p_ptr->warning_autoret != 99) p_ptr->warning_autoret = 0;
2813 		}
2814 
2815 		/* Check if it is still alive or another targets exists */
2816 		if ((m_target_ptr->r_idx) || (prev_m_target_ptr) || (p_target_ptr)) {
2817 			/* We attacked something */
2818 			return 1;
2819 		} else {
2820 			/* Otherwise return 2 to indicate we are no longer
2821 			 * autoattacking anything.
2822 			 */
2823 			return 2;
2824 		}
2825 	}
2826 
2827 	/* Nothing was attacked. */
2828 	return 0;
2829 }
2830 
2831 /*
2832  * Player processing that occurs at the beginning of a new turn
2833  */
2834 static void process_player_begin(int Ind)
2835 {
2836 	player_type *p_ptr = Players[Ind];
2837 
2838 	/* for AT_VALINOR: */
2839 	int i, x, y, xstart = 0, ystart = 0, ox, oy;
2840 	dungeon_type *d_ptr;
2841 	cave_type **zcave;
2842 	dun_level *l_ptr;
2843 
2844 	p_ptr->heal_turn_20 +=  p_ptr->heal_turn[0] - p_ptr->heal_turn[20];
2845 	p_ptr->heal_turn_10 +=  p_ptr->heal_turn[0] - p_ptr->heal_turn[10];
2846 	p_ptr->heal_turn_5 +=  p_ptr->heal_turn[0] - p_ptr->heal_turn[5];
2847 	p_ptr->dam_turn_20 = p_ptr->dam_turn[0] - p_ptr->dam_turn[20];
2848 	p_ptr->dam_turn_10 = p_ptr->dam_turn[0] - p_ptr->dam_turn[10];
2849 	p_ptr->dam_turn_5 = p_ptr->dam_turn[0] - p_ptr->dam_turn[5];
2850 	for (i = 20; i > 0; i--) {
2851 	/* move internal heal/turn register for C_BLUE_AI */
2852 		p_ptr->heal_turn[i] = p_ptr->heal_turn[i - 1];
2853 	/* move internal dam/turn register for C_BLUE_AI */
2854 		p_ptr->dam_turn[i] = p_ptr->dam_turn[i - 1];
2855 	}
2856 	p_ptr->heal_turn[0] = 0; /* prepared to store healing that might happen */
2857 	p_ptr->dam_turn[0] = 0; /* prepared to store damage dealing that might happen */
2858 
2859 	/* Perform pending automatic transportation */
2860 	switch (p_ptr->auto_transport) {
2861 	case AT_BLINK: teleport_player_force(Ind, 10); p_ptr->auto_transport = 0; break;
2862 	case AT_TPORT: teleport_player_force(Ind, 100); p_ptr->auto_transport = 0; break;
2863 	case AT_VALINOR: /* allocate Valinor; recall player there */
2864 #if 0
2865 		if (players_on_depth(wpos) && !getcave(wpos)) {
2866 			/* Allocate space for it */
2867 			alloc_dungeon_level(wpos);
2868 			/* Generate a dungeon level there */
2869 			generate_cave(wpos, p_ptr);
2870 		}
2871 		zcave = getcave(wpos);
2872 		l_ptr = getfloor(wpos);
2873 #endif
2874 #if 1
2875 		for (y = 0; y < MAX_WILD_Y; y++) {
2876 			for (x = 0; x < MAX_WILD_X; x++) {
2877 				if ((d_ptr = wild_info[y][x].tower) && (!strcmp(d_name + d_info[d_ptr->type].name, "The Shores of Valinor"))) {
2878 					p_ptr->recall_pos.wx = x;
2879 					p_ptr->recall_pos.wy = y;
2880 					p_ptr->recall_pos.wz = 1;
2881 					p_ptr->new_level_method = LEVEL_OUTSIDE_RAND;
2882 					recall_player(Ind, "");
2883 					break;
2884 				}
2885 				if ((d_ptr = wild_info[y][x].dungeon) && (!strcmp(d_name + d_info[d_ptr->type].name, "The Shores of Valinor"))) {
2886 				        p_ptr->recall_pos.wx = x;
2887 				        p_ptr->recall_pos.wy = y;
2888 					p_ptr->recall_pos.wz = -1;
2889 					// let's try LEVEL_OUTSIDE_RAND (5) instead of LEVEL_OUTSIDE (4) - C. Blue :)
2890 				        p_ptr->new_level_method = LEVEL_OUTSIDE_RAND;
2891 				        recall_player(Ind, "");
2892 					break;
2893 				}
2894 		        }
2895 		}
2896 		p_ptr->auto_transport = AT_VALINOR2;
2897 		break;
2898 #endif
2899 	case AT_VALINOR2: /* (re-)generate Valinor from scratch; move player into position; lite it up for the show; place 'monsters' */
2900 		zcave = getcave(&p_ptr->wpos);
2901 		l_ptr = getfloor(&p_ptr->wpos);
2902 		/* Get rid of annoying level flags */
2903 		l_ptr->flags1 &= ~(LF1_NO_MAP | LF1_NO_MAGIC_MAP);
2904 		for (y = 0; y < MAX_HGT / 3; y++) {
2905 			for (x = 0; x < MAX_WID; x++) {
2906 				zcave[y][x].feat = FEAT_HIGH_MOUNT_SOLID;
2907 				zcave[y + MAX_HGT / 3][x].feat = FEAT_GLIT_WATER;
2908 				zcave[y + (MAX_HGT * 2) / 3][x].feat = FEAT_GLIT_WATER;
2909 			}
2910 		}
2911 		/* Wipe any monsters/objects */
2912 		wipe_o_list_safely(&p_ptr->wpos);
2913 		wipe_m_list(&p_ptr->wpos);
2914 		/* Regenerate the level from fixed layout */
2915 		process_dungeon_file("t_valinor.txt", &p_ptr->wpos, &ystart, &xstart, 21, 66, TRUE);
2916 		for (x = 0; x <= 65; x++) zcave[21][x].feat = FEAT_GLIT_WATER;
2917 		zcave[20][0].feat = FEAT_GLIT_WATER;
2918 		zcave[20][65].feat = FEAT_GLIT_WATER;
2919 		/* Some lil hacks */
2920 		msg_format(Ind, "\377%cYou enter the shores of Valinor..", COLOUR_DUNGEON);
2921 		wiz_lite(Ind);
2922 		/* Move @ to designated starting position (level_rand_x/y()) and redraw */
2923 		oy = p_ptr->py;
2924 		ox = p_ptr->px;
2925 		p_ptr->py = 15;
2926 		p_ptr->px = 16;
2927 		zcave[oy][ox].m_idx = 0;
2928 		zcave[p_ptr->py][p_ptr->px].m_idx = 0 - Ind;
2929 		everyone_lite_spot(&p_ptr->wpos, oy, ox);
2930 		everyone_lite_spot(&p_ptr->wpos, p_ptr->py, p_ptr->px);
2931 		/* Summon 'monsters' */
2932 		place_monster_one(&p_ptr->wpos, 7, 10, RI_BRIGHTLANCE, 0, 0, 0, 0, 0);
2933 		everyone_lite_spot(&p_ptr->wpos, 7, 10);
2934 		place_monster_one(&p_ptr->wpos, 7, 15, RI_BRIGHTLANCE, 0, 0, 0, 0, 0);
2935 		everyone_lite_spot(&p_ptr->wpos, 7, 15);
2936 		place_monster_one(&p_ptr->wpos, 10, 25, RI_OROME, 0, 0, 0, 0, 0);
2937 		everyone_lite_spot(&p_ptr->wpos, 10, 25);
2938 		p_ptr->update |= PU_LITE;
2939 		p_ptr->update |= (PU_VIEW | PU_LITE | PU_FLOW);
2940 		p_ptr->update |= (PU_DISTANCE);
2941 		redraw_stuff(Ind);
2942 		p_ptr->auto_transport = AT_VALINOR3;
2943 		break;
2944 	case AT_VALINOR3:	/* Orome mumbles */
2945 		if (turn % 300) break; /* cool down.. */
2946 		msg_print(Ind, "\374 ");
2947 		msg_print(Ind, "\374\377oOrome, The Hunter, mumbles something about a spear..");
2948 		p_ptr->auto_transport = AT_VALINOR4;
2949 		break;
2950 	case AT_VALINOR4:	/* Orome looks */
2951 		if (turn % 500) break; /* cool down.. */
2952 		msg_print(Ind, "\374 ");
2953 		msg_print(Ind, "\374\377oOrome, The Hunter, notices you and surprise crosses his face!");
2954 		p_ptr->auto_transport = AT_VALINOR5;
2955 		break;
2956 	case AT_VALINOR5:	/* Orome laughs */
2957 		if (turn % 500) break; /* cool down.. */
2958 		msg_print(Ind, "\374 ");
2959 		msg_print(Ind, "\374\377oOrome, The Hunter, laughs out loudly!");
2960 		set_afraid(Ind, 8);
2961 		p_ptr->auto_transport = AT_VALINOR6;
2962 		break;
2963 	case AT_VALINOR6:	/* Orome offers */
2964 		if (turn % 500) break; /* cool down.. */
2965 		msg_print(Ind, "\374 ");
2966 		msg_print(Ind, "\374\377oOrome, The Hunter, offers you to stay here!");
2967 		msg_print(Ind, "\374\377y  (You may hit the suicide keys in order to retire here,");
2968 		msg_print(Ind, "\374\377y  or take the staircase back to the mundane world.)");
2969 		msg_print(Ind, "\374 ");
2970 		p_ptr->auto_transport = 0;
2971 		break;
2972 	}
2973 
2974 
2975 	/* Give the player some energy */
2976 	p_ptr->energy += extract_energy[p_ptr->pspeed];
2977 	limit_energy(p_ptr);
2978 
2979 	/* clear 'quaked' flag for p_ptr->impact limiting */
2980 	p_ptr->quaked = FALSE;
2981 
2982 	/* Check "resting" status */
2983 	if (p_ptr->resting) {
2984 		/* No energy availiable while resting */
2985 		// This prevents us from instantly waking up.
2986 		p_ptr->energy = 0;
2987 	}
2988 
2989 	/* Handle paralysis here */
2990 #ifndef ARCADE_SERVER
2991 	if (p_ptr->paralyzed || p_ptr->stun > 100)
2992 		p_ptr->energy = 0;
2993 #else
2994 	if (p_ptr->paralyzed)
2995 		p_ptr->energy = 0;
2996 #endif
2997 
2998 
2999 	/* Hack -- semi-constant hallucination */
3000 	if (p_ptr->image && (randint(10) < 1)) p_ptr->redraw |= (PR_MAP);
3001 
3002 	/* Mega-Hack -- Random teleportation XXX XXX XXX */
3003 	if ((p_ptr->teleport) && (rand_int(100) < 1)
3004 	    /* not during highlander tournament */
3005 	    && (p_ptr->wpos.wx || p_ptr->wpos.wy || !sector00separation))
3006 	{
3007 		/* Teleport player */
3008 		teleport_player(Ind, 40, FALSE);
3009 	}
3010 
3011 }
3012 
3013 
3014 /*
3015  * Generate the feature effect
3016  */
3017 static void apply_effect(int Ind)
3018 {
3019 	player_type *p_ptr = Players[Ind];
3020 	int y = p_ptr->py, x = p_ptr->px;
3021 	cave_type *c_ptr;
3022 	feature_type *f_ptr;
3023 
3024 	cave_type **zcave;
3025 	if (!(zcave = getcave(&p_ptr->wpos))) return;
3026 
3027 	c_ptr = &zcave[y][x];
3028 	f_ptr = &f_info[c_ptr->feat];
3029 
3030 	if (f_ptr->d_frequency[0] != 0) {
3031 		int i;
3032 
3033 		for (i = 0; i < 4; i++) {
3034 			/* Check the frequency */
3035 			if (f_ptr->d_frequency[i] == 0) continue;
3036 
3037 			/* XXX it's no good to use 'turn' here */
3038 //			if (((turn % f_ptr->d_frequency[i]) == 0) &&
3039 
3040 			if ((!rand_int(f_ptr->d_frequency[i])) &&
3041 			    ((f_ptr->d_side[i] != 0) || (f_ptr->d_dice[i] != 0)))
3042 			{
3043 				int l, dam = 0;
3044 				int d = f_ptr->d_dice[i], s = f_ptr->d_side[i];
3045 
3046 				if (d == -1) d = p_ptr->lev;
3047 				if (s == -1) s = p_ptr->lev;
3048 
3049 				/* Roll damage */
3050 				for (l = 0; l < d; l++) {
3051 					dam += randint(s);
3052 				}
3053 
3054 				/* Apply damage */
3055 				project(PROJECTOR_TERRAIN, 0, &p_ptr->wpos, y, x, dam, f_ptr->d_type[i],
3056 				        PROJECT_NORF | PROJECT_KILL | PROJECT_HIDE | PROJECT_JUMP, "");
3057 
3058 				/* Hack -- notice death */
3059 //				if (!alive || death) return;
3060 				if (p_ptr->death) return;
3061 			}
3062 		}
3063 	}
3064 }
3065 
3066 #if 0
3067 /* admin can summon a player anywhere he/she wants */
3068 void summon_player(int victim, struct worldpos *wpos, char *message){
3069 	struct player_type *p_ptr;
3070 	p_ptr = Players[victim];
3071 	p_ptr->recall_pos.wx = wpos->wx;
3072 	p_ptr->recall_pos.wy = wpos->wy;
3073 	p_ptr->recall_pos.wz = wpos->wz;
3074 	recall_player(victim, message);
3075 }
3076 #endif
3077 
3078 /* actually recall a player with no questions asked */
3079 void recall_player(int Ind, char *message) {
3080 	struct player_type *p_ptr;
3081 	cave_type **zcave;
3082 	struct worldpos old_wpos;
3083 	char buf[MAX_CHARS_WIDE];
3084 
3085 	p_ptr = Players[Ind];
3086 
3087 	if(!p_ptr) return;
3088 	if(!(zcave = getcave(&p_ptr->wpos))) return;	// eww
3089 
3090 	break_cloaking(Ind, 0);
3091 	break_shadow_running(Ind);
3092 	stop_precision(Ind);
3093 	stop_shooting_till_kill(Ind);
3094 
3095 #ifdef USE_SOUND_2010
3096 	sound(Ind, "teleport", NULL, SFX_TYPE_COMMAND, FALSE);
3097 #endif
3098 
3099 	/* Remove the player */
3100 	zcave[p_ptr->py][p_ptr->px].m_idx = 0;
3101 
3102 	/* Show everyone that he's left */
3103 	everyone_lite_spot(&p_ptr->wpos, p_ptr->py, p_ptr->px);
3104 
3105 	msg_print(Ind, message);
3106 
3107 	/* Forget his lite and view */
3108 	forget_lite(Ind);
3109 	forget_view(Ind);
3110 
3111 #if 1 //todo: fix again after it broke: actually this code should instead have been done already in process_player_change_wpos() or related functions >.>
3112 	/* sanity check on recall coordinates */
3113 	p_ptr->recall_pos.wx %= MAX_WILD_X;
3114 	p_ptr->recall_pos.wy %= MAX_WILD_Y;
3115 	if (p_ptr->recall_pos.wz < 0) {
3116 		if (wild_info[p_ptr->recall_pos.wy][p_ptr->recall_pos.wx].dungeon) {
3117 			if (-p_ptr->recall_pos.wz > wild_info[p_ptr->recall_pos.wy][p_ptr->recall_pos.wx].dungeon->maxdepth)
3118 				p_ptr->recall_pos.wz = -wild_info[p_ptr->recall_pos.wy][p_ptr->recall_pos.wx].dungeon->maxdepth;
3119 		} else p_ptr->recall_pos.wz = 0;
3120 	} else if (p_ptr->recall_pos.wz > 0) {
3121 		if (wild_info[p_ptr->recall_pos.wy][p_ptr->recall_pos.wx].tower) {
3122 			if (p_ptr->recall_pos.wz > wild_info[p_ptr->recall_pos.wy][p_ptr->recall_pos.wx].tower->maxdepth)
3123 				p_ptr->recall_pos.wz = wild_info[p_ptr->recall_pos.wy][p_ptr->recall_pos.wx].tower->maxdepth;
3124 		} else p_ptr->recall_pos.wz = 0;
3125 	}
3126 #endif
3127 
3128 	/* Change the wpos */
3129 	wpcopy(&old_wpos, &p_ptr->wpos);
3130 	wpcopy(&p_ptr->wpos, &p_ptr->recall_pos);
3131 
3132 	/* One less person here */
3133 	new_players_on_depth(&old_wpos, -1, TRUE);
3134 
3135 	/* Log it */
3136 	s_printf("Recalled: %s from %d,%d,%d to %d,%d,%d.\n", p_ptr->name,
3137 	    old_wpos.wx, old_wpos.wy, old_wpos.wz,
3138 	    p_ptr->recall_pos.wx, p_ptr->recall_pos.wy, p_ptr->recall_pos.wz);
3139 
3140 	/* One more person here */
3141 	new_players_on_depth(&p_ptr->wpos, 1, TRUE);
3142 
3143 	p_ptr->new_level_flag = TRUE;
3144 
3145 	/* He'll be safe for some turns */
3146 	set_invuln_short(Ind, RECALL_GOI_LENGTH);	// It runs out if attacking anyway
3147 
3148 	/* cancel any user recalls */
3149 	p_ptr->word_recall = 0;
3150 
3151 
3152 	/* check for /tpto admin command that allows changing between 2 wz positions that are both != 0: */
3153 	if (p_ptr->wpos.wz) return;
3154 
3155 
3156 	/* Update wilderness map! This is for RECALL_MAX_RANGE:
3157 	   We learn about the intermediate world map sectors we land on. */
3158 	if (!p_ptr->ghost)
3159 		p_ptr->wild_map[(p_ptr->wpos.wx + p_ptr->wpos.wy * MAX_WILD_X) / 8] |=
3160 		    (1 << ((p_ptr->wpos.wx + p_ptr->wpos.wy * MAX_WILD_X) % 8));
3161 
3162 	/* Did we really make it through all floors of the ironman challenge dungeon? */
3163 	if (in_irondeepdive(&old_wpos)
3164 	    && !is_admin(p_ptr)) {
3165 		int i, j;
3166 #ifdef IRONDEEPDIVE_FIXED_TOWN_WITHDRAWAL
3167 		bool success = TRUE;
3168 		if (getlevel(&old_wpos) == 40 || getlevel(&old_wpos) == 80) success = FALSE;
3169 		if (success)
3170 #endif
3171 		for (i = 0; i < IDDC_HIGHSCORE_SIZE; i++) {
3172 #ifdef IDDC_THROUGH_IS_FIRST /* 0->always replace first entry! */
3173 			if (deep_dive_level[i] == -1) {
3174  #ifdef IDDC_RESTRICT_ACC_CLASS /* only allow one entry of same account+class? : discard new entry */
3175 				if (!strcmp(deep_dive_account[i], p_ptr->accountname) &&
3176 				    deep_dive_class[i] == p_ptr->pclass) {
3177 					i = IDDC_HIGHSCORE_DISPLAYED;
3178 					break;
3179 				}
3180  #endif
3181 				continue;
3182 			}
3183 #endif
3184 #ifdef IDDC_RESTRICT_ACC_CLASS /* only allow one entry of same account+class? : discard previous entry */
3185 			for (j = i; j < IDDC_HIGHSCORE_SIZE - 1; j++) {
3186 				if (!strcmp(deep_dive_account[j], p_ptr->accountname) &&
3187 				    deep_dive_class[j] == p_ptr->pclass) {
3188 					int k;
3189 
3190 					/* pull up all succeeding entries by 1  */
3191 					for (k = j; k < IDDC_HIGHSCORE_SIZE - 1; k++) {
3192 						deep_dive_level[k] = deep_dive_level[k + 1];
3193 						strcpy(deep_dive_name[k], deep_dive_name[k + 1]);
3194 						strcpy(deep_dive_char[k], deep_dive_char[k + 1]);
3195 						strcpy(deep_dive_account[k], deep_dive_account[k + 1]);
3196 						deep_dive_class[k] = deep_dive_class[k + 1];
3197 					}
3198 					break;
3199 				}
3200 			}
3201 #endif
3202 			/* push down all entries by 1, to make room for inserting new entry */
3203 			for (j = IDDC_HIGHSCORE_SIZE - 1; j > i; j--) {
3204 				deep_dive_level[j] = deep_dive_level[j - 1];
3205 				strcpy(deep_dive_name[j], deep_dive_name[j - 1]);
3206 				strcpy(deep_dive_char[j], deep_dive_char[j - 1]);
3207 				strcpy(deep_dive_account[j], deep_dive_account[j - 1]);
3208 				deep_dive_class[j] = deep_dive_class[j - 1];
3209 			}
3210 			deep_dive_level[i] = -1;
3211 			//strcpy(deep_dive_name[i], p_ptr->name);
3212 #ifdef IDDC_HISCORE_SHOWS_ICON
3213 			sprintf(deep_dive_name[i], "%s, %s %s (\\{%c%c\\{s/\\{%c%d\\{s),",
3214 			    p_ptr->name, get_prace(p_ptr), class_info[p_ptr->pclass].title, color_attr_to_char(p_ptr->cp_ptr->color), p_ptr->fruit_bat ? 'b' : '@',
3215 			    p_ptr->ghost ? 'r' : 's', p_ptr->max_plv);
3216 #else
3217 			sprintf(deep_dive_name[i], "%s, %s %s (\\{%c%d\\{s),",
3218 			    p_ptr->name, get_prace(p_ptr), class_info[p_ptr->pclass].title,
3219 			    p_ptr->ghost ? 'r' : 's', p_ptr->max_plv);
3220 #endif
3221 			strcpy(deep_dive_char[i], p_ptr->name);
3222 			strcpy(deep_dive_account[i], p_ptr->accountname);
3223 			deep_dive_class[i] = p_ptr->pclass;
3224 			break;
3225 		}
3226 
3227 #ifdef IRONDEEPDIVE_ALLOW_INCOMPAT
3228 		/* need to leave party, since we might be teamed up with incompatible char mode players! */
3229 		if (p_ptr->party && !p_ptr->admin_dm &&
3230 		    compat_mode(p_ptr->mode, parties[p_ptr->party].cmode))
3231 			party_leave(Ind, FALSE);
3232 #endif
3233 
3234 #ifdef IRONDEEPDIVE_FIXED_TOWN_WITHDRAWAL
3235 		if (success) {
3236 #endif
3237 			p_ptr->iron_winner = TRUE;
3238 			msg_print(Ind, "\374\377L***\377aYou made it through the Ironman Deep Dive challenge!\377L***");
3239 			sprintf(buf, "\374\377L***\377a%s made it through the Ironman Deep Dive challenge!\377L***", p_ptr->name);
3240 			msg_broadcast(Ind, buf);
3241 			l_printf("%s \\{U%s (%d) made it through the Ironman Deep Dive challenge\n", showdate(), p_ptr->name, p_ptr->lev);
3242 #ifdef TOMENET_WORLDS
3243 	                if (cfg.worldd_events) world_msg(buf);
3244 #endif
3245 		        /* enforce dedicated Ironman Deep Dive Challenge character slot usage */
3246 		        if (p_ptr->mode & MODE_DED_IDDC) {
3247 		                msg_print(Ind, "\377aYou return to town and may retire ('Q') when ready.");
3248 		                msg_print(Ind, "\377aIf you enter a dungeon or tower, \377Rretirement\377a is assumed \377Rautomatically\377a.");
3249 
3250 				process_player_change_wpos(Ind);
3251 				p_ptr->recall_pos.wx = cfg.town_x;
3252 				p_ptr->recall_pos.wy = cfg.town_y;
3253 
3254 				wpcopy(&old_wpos, &p_ptr->wpos);
3255 				wpcopy(&p_ptr->wpos, &p_ptr->recall_pos);
3256 				new_players_on_depth(&old_wpos, -1, TRUE);
3257 				s_printf("Recalled: %s from %d,%d,%d to %d,%d,%d.\n", p_ptr->name,
3258 				    old_wpos.wx, old_wpos.wy, old_wpos.wz,
3259 				    p_ptr->recall_pos.wx, p_ptr->recall_pos.wy, p_ptr->recall_pos.wz);
3260 				new_players_on_depth(&p_ptr->wpos, 1, TRUE);
3261 				p_ptr->new_level_flag = TRUE;
3262 				set_invuln_short(Ind, RECALL_GOI_LENGTH);	// It runs out if attacking anyway
3263 				p_ptr->word_recall = 0;
3264 				process_player_change_wpos(Ind);
3265 
3266 				/* Restrict character to world surface */
3267 				p_ptr->iron_winner_ded = TRUE;
3268 			}
3269 
3270 			p_ptr->IDDC_flags = 0x0; //clear IDDC specialties
3271 #ifdef IRONDEEPDIVE_FIXED_TOWN_WITHDRAWAL
3272 		} else {
3273 		        /* enforce dedicated Ironman Deep Dive Challenge character slot usage */
3274 		        if (p_ptr->mode & MODE_DED_IDDC) {
3275 		                msg_print(Ind, "\377RYou failed to complete the Ironman Deep Dive Challenge!");
3276 		                strcpy(p_ptr->died_from, "indetermination");
3277 		                p_ptr->deathblow = 0;
3278 		                p_ptr->death = TRUE;
3279 		                return;
3280 		        }
3281 
3282 			sprintf(buf, "\374\377s%s withdrew from the Ironman Deep Dive challenge.", p_ptr->name);
3283 			msg_broadcast(0, buf);
3284  #ifdef TOMENET_WORLDS
3285 	                if (cfg.worldd_events) world_msg(buf);
3286  #endif
3287 
3288 			/* reduce his accumulated mimicry form knowledge somewhat
3289 			   (keep some of the benefits of IDDC hunting) */
3290  #ifdef IDDC_MIMICRY_BOOST
3291 			if (IDDC_MIMICRY_BOOST <= 2) j = 5;
3292 			else if (IDDC_MIMICRY_BOOST == 3) j = 6;
3293 			else if (IDDC_MIMICRY_BOOST == 4) j = 7;
3294 			else if (IDDC_MIMICRY_BOOST <= 6) j = 10;
3295 			else j = 13;
3296 			for (i = 1; i < max_r_idx; i++) {
3297 				if ((r_info[i].flags1 & RF1_UNIQUE)) continue;
3298 				p_ptr->r_killed[i] = (p_ptr->r_killed[i] * 5) / j;
3299 			}
3300 			/* In case he can no longer use his current form */
3301 			do_mimic_change(Ind, 0, TRUE);
3302  #endif
3303 
3304 			p_ptr->IDDC_flags = 0x0; //clear IDDC specialties
3305 
3306 			/* Be nice: Actually set all his true artifacts to non-iddc timeouting
3307 			   (for IDDC_ARTIFACT_FAST_TIMEOUT) */
3308 			for (i = 0; i < INVEN_TOTAL; i++) {
3309 				if (!p_ptr->inventory[i].k_idx) continue;
3310 				if (!p_ptr->inventory[i].name1 || p_ptr->inventory[i].name1 == ART_RANDART) continue;
3311 				a_info[p_ptr->inventory[i].name1].iddc = FALSE;
3312 			}
3313 		}
3314 #endif
3315 	}
3316 
3317 	/* Specialty: Did we make it through the Halls of Mandos?
3318 	   Those are now ironman, so they're a 'pure', traditional ironman challenge.
3319 	   However, this dungeon can be entered at any level, so it might be less of a challenge. */
3320 	if (in_hallsofmandos(&old_wpos)) {
3321 		msg_print(Ind, "\374\377a***\377sYou made it through the Halls of Mandos!\377a***");
3322 		sprintf(buf, "\374\377a***\377s%s made it through the Halls of Mandos!\377a***", p_ptr->name);
3323 		msg_broadcast(Ind, buf);
3324 		l_printf("%s \\{U%s (%d) made it through the Halls of Mandos\n", showdate(), p_ptr->name, p_ptr->lev);
3325 	}
3326 }
3327 
3328 
3329 /* Handles WoR
3330  * XXX dirty -- REWRITEME
3331  */
3332 static void do_recall(int Ind, bool bypass)
3333 {
3334 	player_type *p_ptr = Players[Ind];
3335 	char *message = NULL;
3336 
3337 	/* sorta circumlocution? */
3338 	worldpos new_pos;
3339 	bool recall_ok = TRUE;
3340 
3341 	/* Disturbing! */
3342 	disturb(Ind, 0, 0);
3343 
3344 	/* special restriction for global events (Highlander Tournament) */
3345 	if (sector00separation && !is_admin(p_ptr) && (
3346 	    (!p_ptr->recall_pos.wx && !p_ptr->recall_pos.wy) ||
3347 	    (!p_ptr->wpos.wx && !p_ptr->wpos.wy))) {
3348 		if (p_ptr->global_event_temp & PEVF_PASS_00) {
3349 			p_ptr->global_event_temp &= ~PEVF_PASS_00;
3350 		} else {
3351 			msg_print(Ind, "A tension leaves the air around you...");
3352 			p_ptr->redraw |= (PR_DEPTH);
3353 			return;
3354 		}
3355 	}
3356 
3357 	if (!p_ptr->wpos.wz && !bypass) {
3358 		wilderness_type *w_ptr = &wild_info[p_ptr->recall_pos.wy][p_ptr->recall_pos.wx];
3359 		dungeon_type *d_ptr = NULL;
3360 		if (p_ptr->recall_pos.wz < 0 && (w_ptr->flags & WILD_F_DOWN))
3361 			d_ptr = w_ptr->dungeon;
3362 		else if (p_ptr->recall_pos.wz > 0 && (w_ptr->flags & WILD_F_UP))
3363 			d_ptr = w_ptr->tower;
3364 
3365 #ifdef OBEY_DUNGEON_LEVEL_REQUIREMENTS
3366 		if (d_ptr){
3367 			if ((d_ptr->type && d_info[d_ptr->type].min_plev > p_ptr->lev) ||
3368 			    (!d_ptr->type && d_ptr->baselevel <= (p_ptr->lev * 3) / 2 + 7)) {
3369 				msg_print(Ind,"\377rAs you attempt to recall, you are gripped by an uncontrollable fear.");
3370 				msg_print(Ind, "A tension leaves the air around you...");
3371 				p_ptr->redraw |= (PR_DEPTH);
3372 				if (!is_admin(p_ptr)) {
3373 					set_afraid(Ind, 10);// + (d_ptr->baselevel - p_ptr->max_dlv));
3374 					return;
3375 				}
3376 			}
3377 		}
3378 #endif
3379 	        /* Nether Realm only for Kings/Queens (currently paranoia, since NR is NO_RECALL_INTO) */
3380     		if (d_ptr && (d_ptr->type == DI_NETHER_REALM) && !p_ptr->total_winner) {
3381     	    		msg_print(Ind,"\377rAs you attempt to recall, you are gripped by an uncontrollable fear.");
3382 	        	if (!is_admin(p_ptr)) {
3383     		        	set_afraid(Ind, 10);//+(d_ptr->baselevel-p_ptr->max_dlv));
3384 	    	                return;
3385 	                }
3386 	        }
3387 	}
3388 
3389 	/* Determine the level */
3390 	/* recalling to surface */
3391 	if (p_ptr->wpos.wz && !bypass) {
3392 		struct dungeon_type *d_ptr;
3393 		d_ptr = getdungeon(&p_ptr->wpos);
3394 
3395 		/* Messages */
3396 		if (((d_ptr->flags2 & DF2_IRON || d_ptr->flags1 & DF1_FORCE_DOWN) && d_ptr->maxdepth > ABS(p_ptr->wpos.wz)) ||
3397 		    (d_ptr->flags1 & DF1_NO_RECALL)) {
3398 			if (!(getfloor(&p_ptr->wpos)->flags1 & LF1_IRON_RECALL)) {
3399 				msg_print(Ind, "You feel yourself being pulled toward the surface!");
3400 				if (!is_admin(p_ptr)) {
3401 					recall_ok = FALSE;
3402 					/* Redraw the depth(colour) */
3403 					p_ptr->redraw |= (PR_DEPTH);
3404 				}
3405 			} else if ((p_ptr->mode & MODE_DED_IDDC) && in_irondeepdive(&p_ptr->wpos)) {
3406 				msg_print(Ind, "You have dedicated yourself to the Ironman Deep Dive Challenge!");
3407 				if (!is_admin(p_ptr)) {
3408 					recall_ok = FALSE;
3409 					/* Redraw the depth(colour) */
3410 					p_ptr->redraw |= (PR_DEPTH);
3411 				}
3412 			}
3413 		}
3414 		if (recall_ok) {
3415 			msg_format(Ind, "\377%cYou are transported out of %s..", COLOUR_DUNGEON, get_dun_name(p_ptr->wpos.wx, p_ptr->wpos.wy, p_ptr->wpos.wz > 0, d_ptr, 0, FALSE));
3416 			if (p_ptr->wpos.wz > 0) {
3417 				message = "You feel yourself yanked downwards!";
3418 				msg_format_near(Ind, "%s is yanked downwards!", p_ptr->name);
3419 			} else {
3420 				message = "You feel yourself yanked upwards!";
3421 				msg_format_near(Ind, "%s is yanked upwards!", p_ptr->name);
3422 			}
3423 
3424 			/* New location */
3425 			new_pos.wx = p_ptr->wpos.wx;
3426 			new_pos.wy = p_ptr->wpos.wy;
3427 			new_pos.wz = 0;
3428 #if 0
3429 			p_ptr->new_level_method = ( istown(&new_pos) ? LEVEL_RAND : LEVEL_OUTSIDE_RAND );
3430 #endif
3431 			p_ptr->new_level_method = (p_ptr->wpos.wz>0 ? LEVEL_RECALL_DOWN : LEVEL_RECALL_UP);
3432 		}
3433 	}
3434 	/* beware! bugs inside! (jir) (no longer I hope) */
3435 	/* world travel */
3436 	/* why wz again? (jir) */
3437 	else if ((!(p_ptr->recall_pos.wz) || !(wild_info[p_ptr->wpos.wy][p_ptr->wpos.wx].flags & (WILD_F_UP|WILD_F_DOWN))) && !bypass) {
3438 		int dis;
3439 
3440 		if (((!(p_ptr->wild_map[(wild_idx(&p_ptr->recall_pos))/8] &
3441 		    (1 << (wild_idx(&p_ptr->recall_pos))%8))) &&
3442 		    !is_admin(p_ptr) ) ||
3443 		    inarea(&p_ptr->wpos, &p_ptr->recall_pos))
3444 		{
3445 			/* back to the last town (s)he visited.
3446 			 * (This can fail if gone too far) */
3447 			p_ptr->recall_pos.wx = p_ptr->town_x;
3448 			p_ptr->recall_pos.wy = p_ptr->town_y;
3449 		}
3450 
3451 #ifdef RECALL_MAX_RANGE
3452 		dis = distance(p_ptr->recall_pos.wy, p_ptr->recall_pos.wx,
3453 				p_ptr->wpos.wy, p_ptr->wpos.wx);
3454 		if (dis > RECALL_MAX_RANGE && !is_admin(p_ptr)) {
3455 			new_pos.wx = p_ptr->wpos.wx + (p_ptr->recall_pos.wx - p_ptr->wpos.wx) * RECALL_MAX_RANGE / dis;
3456 			new_pos.wy = p_ptr->wpos.wy + (p_ptr->recall_pos.wy - p_ptr->wpos.wy) * RECALL_MAX_RANGE / dis;
3457 		}
3458 		else
3459 #endif	// RECALL_MAX_RANGE
3460 		{
3461 			new_pos.wx = p_ptr->recall_pos.wx;
3462 			new_pos.wy = p_ptr->recall_pos.wy;
3463 		}
3464 
3465 		new_pos.wz = 0;
3466 
3467 		/* Messages */
3468 		message = "You feel yourself yanked sideways!";
3469 		msg_format_near(Ind, "%s is yanked sideways!", p_ptr->name);
3470 
3471 		/* New location */
3472 		p_ptr->new_level_method = LEVEL_OUTSIDE_RAND;
3473 	}
3474 
3475 	/* into dungeon/tower */
3476 	/* even at runlevel 2048 players may still recall..for now */
3477 	else if (cfg.runlevel > 4 && cfg.runlevel != 2049) {
3478 		wilderness_type *w_ptr = &wild_info[p_ptr->recall_pos.wy][p_ptr->recall_pos.wx];
3479 //		wilderness_type *w_ptr = &wild_info[p_ptr->wpos.wy][p_ptr->wpos.wx];
3480 		/* Messages */
3481 		if (p_ptr->recall_pos.wz < 0 && w_ptr->flags & WILD_F_DOWN) {
3482 			dungeon_type *d_ptr = wild_info[p_ptr->recall_pos.wy][p_ptr->recall_pos.wx].dungeon;
3483 #ifdef SEPARATE_RECALL_DEPTHS
3484 			int d = -get_recall_depth(&p_ptr->recall_pos, p_ptr);
3485 #endif
3486 
3487 			/* check character/dungeon limits */
3488 			if (-p_ptr->recall_pos.wz > w_ptr->dungeon->maxdepth)
3489 				p_ptr->recall_pos.wz = 0 - w_ptr->dungeon->maxdepth;
3490 			if (p_ptr->inval && -p_ptr->recall_pos.wz > 10)
3491 				p_ptr->recall_pos.wz = -10;
3492 #ifdef SEPARATE_RECALL_DEPTHS
3493 			if (d > p_ptr->recall_pos.wz) p_ptr->recall_pos.wz = d;
3494 			if ( /* ??? */
3495 #else
3496 			if (p_ptr->max_dlv < w_ptr->dungeon->baselevel - p_ptr->recall_pos.wz)
3497 				p_ptr->recall_pos.wz = w_ptr->dungeon->baselevel - p_ptr->max_dlv - 1;
3498 			//if(d_ptr->baselevel-p_ptr->max_dlv>2){
3499 			if ((!d_ptr->type && d_ptr->baselevel - p_ptr->max_dlv > 2) || /* ??? */
3500 #endif
3501 #ifdef OBEY_DUNGEON_LEVEL_REQUIREMENTS
3502 			    (d_ptr->type && d_info[d_ptr->type].min_plev > p_ptr->lev) ||
3503 #endif
3504 			    (d_ptr->flags1 & (DF1_NO_RECALL | DF1_NO_UP | DF1_FORCE_DOWN)) ||
3505 #ifdef RPG_SERVER /* Prevent recalling into NO_DEATH dungeons */
3506 			    (d_ptr->flags2 & (DF2_NO_DEATH)) ||
3507 #endif
3508 #if 0
3509 			    (d_ptr->flags2 & (DF2_IRON | DF2_NO_RECALL_INTO)) ||
3510 #else /* allow recalling into town dungeons every 1000 ft now? Adjusted Moltor's suggestion */
3511 			    (d_ptr->flags2 & (DF2_NO_RECALL_INTO)) ||
3512 			    ((d_ptr->flags2 & DF2_IRON) && wild_info[p_ptr->recall_pos.wy][p_ptr->recall_pos.wx].type != WILD_TOWN) ||
3513 			    ((d_ptr->flags2 & DF2_IRON) && ((p_ptr->recall_pos.wz + 1) % 20)) ||
3514 #endif
3515 			    (d_ptr->flags2 & DF2_NO_ENTRY_WOR))
3516 			{
3517 				if (!is_admin(p_ptr))
3518 					p_ptr->recall_pos.wz = 0;
3519 				else if (p_ptr->recall_pos.wz != 0) /* got zero already from get_max_depth()? then don't give 'nowhere' msg twice */
3520 					msg_print(Ind, "You feel yourself yanked toward nowhere...");
3521 			}
3522 
3523 			if (p_ptr->recall_pos.wz >= 0) {
3524 				p_ptr->recall_pos.wz = 0;
3525 			} else {
3526 				message = "You feel yourself yanked downwards!";
3527 		                msg_format(Ind, "\377%cYou are transported into %s..", COLOUR_DUNGEON, get_dun_name(p_ptr->recall_pos.wx, p_ptr->recall_pos.wy, FALSE, d_ptr, 0, FALSE));
3528 				msg_format_near(Ind, "%s is yanked downwards!", p_ptr->name);
3529 			}
3530 		}
3531 		else if (p_ptr->recall_pos.wz > 0 && w_ptr->flags & WILD_F_UP) {
3532 			dungeon_type *d_ptr = wild_info[p_ptr->recall_pos.wy][p_ptr->recall_pos.wx].tower;
3533 #ifdef SEPARATE_RECALL_DEPTHS
3534 			int d = get_recall_depth(&p_ptr->recall_pos, p_ptr);
3535 #endif
3536 
3537 			/* check character/tower limits */
3538 			if (p_ptr->recall_pos.wz > w_ptr->tower->maxdepth)
3539 				p_ptr->recall_pos.wz = w_ptr->tower->maxdepth;
3540 			if (p_ptr->inval && p_ptr->recall_pos.wz > 10)
3541 				p_ptr->recall_pos.wz = 10;
3542 #ifdef SEPARATE_RECALL_DEPTHS
3543 			if (d < p_ptr->recall_pos.wz) p_ptr->recall_pos.wz = d;
3544 			if ( /* ??? */
3545 #else
3546 			if (p_ptr->max_dlv < w_ptr->tower->baselevel + p_ptr->recall_pos.wz + 1)
3547 				p_ptr->recall_pos.wz = 0 - w_ptr->tower->baselevel + p_ptr->max_dlv + 1;
3548 			//if(d_ptr->baselevel-p_ptr->max_dlv>2){
3549 			if ((!d_ptr->type && d_ptr->baselevel-p_ptr->max_dlv > 2) || /* ??? */
3550 #endif
3551 #ifdef OBEY_DUNGEON_LEVEL_REQUIREMENTS
3552 			    (d_ptr->type && d_info[d_ptr->type].min_plev > p_ptr->lev) ||
3553 #endif
3554 			    (d_ptr->flags1 & (DF1_NO_RECALL | DF1_NO_UP | DF1_FORCE_DOWN)) ||
3555 #ifdef RPG_SERVER /* Prevent recalling into NO_DEATH towers */
3556 			    (d_ptr->flags2 & (DF2_NO_DEATH)) ||
3557 #endif
3558 #if 0
3559 			    (d_ptr->flags2 & (DF2_IRON | DF2_NO_RECALL_INTO)) ||
3560 #else /* allow recalling into town dungeons every 1000 ft now? Adjusted Moltor's suggestion */
3561 			    (d_ptr->flags2 & (DF2_NO_RECALL_INTO)) ||
3562 			    ((d_ptr->flags2 & DF2_IRON) && wild_info[p_ptr->recall_pos.wy][p_ptr->recall_pos.wx].type != WILD_TOWN) ||
3563 			    ((d_ptr->flags2 & DF2_IRON) && ((p_ptr->recall_pos.wz - 1) % 20)) ||
3564 #endif
3565 			    (d_ptr->flags2 & DF2_NO_ENTRY_WOR))
3566 			{
3567 				if (!is_admin(p_ptr))
3568 					p_ptr->recall_pos.wz = 0;
3569 				else if (p_ptr->recall_pos.wz != 0) /* got zero already from get_max_depth()? then don't give 'nowhere' msg twice */
3570 					msg_print(Ind, "You feel yourself yanked toward nowhere...");
3571 			}
3572 
3573 			if (p_ptr->recall_pos.wz <= 0) {
3574 				p_ptr->recall_pos.wz = 0;
3575 			} else {
3576 				message = "You feel yourself yanked upwards!";
3577 		                msg_format(Ind, "\377%cYou are transported into %s..", COLOUR_DUNGEON, get_dun_name(p_ptr->recall_pos.wx, p_ptr->recall_pos.wy, TRUE, d_ptr, 0, FALSE));
3578 				msg_format_near(Ind, "%s is yanked upwards!", p_ptr->name);
3579 			}
3580 		} else {
3581 			p_ptr->recall_pos.wz = 0;
3582 		}
3583 
3584 		/* prevent 'cross-recalling' except for admins (ie change of x,y and z at once) */
3585 		if (p_ptr->recall_pos.wz && !is_admin(p_ptr) &&
3586 		    (p_ptr->wpos.wx != p_ptr->recall_pos.wx || p_ptr->wpos.wy != p_ptr->recall_pos.wy)) {
3587 			p_ptr->recall_pos.wx = p_ptr->wpos.wx;
3588 			p_ptr->recall_pos.wy = p_ptr->wpos.wy;
3589 			p_ptr->recall_pos.wz = 0;
3590 		}
3591 
3592 		new_pos.wx = p_ptr->recall_pos.wx;
3593 		new_pos.wy = p_ptr->recall_pos.wy;
3594 		new_pos.wz = p_ptr->recall_pos.wz;
3595 		if (p_ptr->recall_pos.wz == 0) {
3596 			message = "You feel yourself yanked toward nowhere...";
3597 			p_ptr->new_level_method = LEVEL_OUTSIDE_RAND;
3598 		}
3599 		else p_ptr->new_level_method = LEVEL_RAND;
3600 	} else {
3601 		/* new_pos isn't set so recalling shouldn't be allowed - mikaelh */
3602 		recall_ok = FALSE;
3603 		p_ptr->redraw |= (PR_DEPTH);
3604 	}
3605 
3606 	if (recall_ok) {
3607 		/* back into here */
3608 		wpcopy(&p_ptr->recall_pos, &new_pos);
3609 		recall_player(Ind, message);
3610 	}
3611 }
3612 
3613 /* Does player have ball? */
3614 int has_ball (player_type *p_ptr) {
3615 	int i;
3616 	for (i = 0; i < INVEN_WIELD; i++) {
3617 		if (p_ptr->inventory[i].tval == TV_GAME && p_ptr->inventory[i].sval == SV_GAME_BALL)
3618 			break;
3619 	}
3620 	if (i == INVEN_WIELD) i = -1;
3621 	return(i);
3622 }
3623 
3624 /*
3625  * Handle misc. 'timed' things on the player.
3626  * returns FALSE if player no longer exists.
3627  *
3628  * TODO: find a better way for timed spells(set_*).
3629  */
3630 static bool process_player_end_aux(int Ind) {
3631 	player_type *p_ptr = Players[Ind];
3632 	cave_type		*c_ptr;
3633 	object_type		*o_ptr;
3634 	int		i, j;
3635 	int		regen_amount; //, NumPlayers_old = NumPlayers;
3636 	dun_level *l_ptr = getfloor(&p_ptr->wpos);
3637 	dungeon_type *d_ptr = getdungeon(&p_ptr->wpos);
3638 
3639 	/* Unbelievers "resist" magic */
3640 	//		int minus = (p_ptr->anti_magic)?3:1;
3641 	int minus = 1;
3642 	int minus_magic = 1 + get_skill_scale_fine(p_ptr, SKILL_ANTIMAGIC, 2); /* was 3 before, trying slightly less harsh 2 now */
3643 	int minus_health = get_skill_scale_fine(p_ptr, SKILL_HEALTH, 2); /* was 3, but then HEALTH didn't give HP.. */
3644 	int minus_combat = get_skill_scale_fine(p_ptr, SKILL_COMBAT, 3);
3645 
3646 	cave_type **zcave;
3647 	if (!(zcave = getcave(&p_ptr->wpos))) return(FALSE);
3648 
3649 	c_ptr = &zcave[p_ptr->py][p_ptr->px];
3650 
3651 	/* Anything done here cannot be reduced by GoI/Manashield etc */
3652 	bypass_invuln = TRUE;
3653 
3654 	/*** Damage over Time ***/
3655 
3656 	/* Take damage from poison */
3657 	if (p_ptr->poisoned) {
3658 		if (p_ptr->slow_poison == 1) {
3659 			p_ptr->slow_poison = 2;
3660 			/* Take damage */
3661 			take_hit(Ind, 1, "poison", p_ptr->poisoned_attacker);
3662 		} else if (p_ptr->slow_poison == 2) {
3663 			p_ptr->slow_poison = 1;
3664 		} else {
3665 			/* Take damage */
3666 			take_hit(Ind, 1, "poison", p_ptr->poisoned_attacker);
3667 		}
3668 	}
3669 
3670 	/* Misc. terrain effects */
3671 	if (!p_ptr->ghost) {
3672 		/* Generic terrain effects */
3673 		apply_effect(Ind);
3674 
3675 		/* Drowning, but not ghosts */
3676 		if (c_ptr->feat == FEAT_DEEP_WATER) {
3677 			bool carry_wood = FALSE;
3678 
3679 			for (i = 0; i < INVEN_PACK; i++) {
3680 				o_ptr = &p_ptr->inventory[i];
3681 				if (!o_ptr->k_idx) break;
3682 				if (o_ptr->tval == TV_GOLEM && o_ptr->sval == SV_GOLEM_WOOD) {
3683 					carry_wood = TRUE;
3684 					break;
3685 				}
3686 			}
3687 
3688 			/* note: TODO (bug): items should get damaged even if player can_swim,
3689 			   but this might devalue swimming too much compared to levitation. Dunno. */
3690 			if ((!p_ptr->tim_wraith) && (!p_ptr->levitate) && (!p_ptr->can_swim)
3691 			    && !carry_wood
3692 			    ) {
3693 				/* Take damage */
3694 				if (!(p_ptr->body_monster) || (
3695 				    !(r_info[p_ptr->body_monster].flags7 &
3696 				    (RF7_AQUATIC | RF7_CAN_SWIM)) ))
3697 				{
3698 					int hit = p_ptr->mhp >> 6;
3699 					int swim = get_skill_scale(p_ptr, SKILL_SWIM, 4500);
3700 					hit += randint(p_ptr->mhp >> 5);
3701 					if (!hit) hit = 1;
3702 
3703 					/* Take CON into consideration(max 30%) */
3704 					//note: if hit was 1, this can each result in 0 aka no hit!
3705 					hit = (hit * (80 - adj_str_wgt[p_ptr->stat_ind[A_CON]])) / 75;
3706 					if (p_ptr->suscep_life) hit >>= 1;
3707 
3708 					/* temporary abs weight calc */
3709 					if (p_ptr->wt + p_ptr->total_weight/10 > 170 + swim * 2) { // 190
3710 						long factor = (p_ptr->wt + p_ptr->total_weight / 10) - 150 - swim * 2; // 170
3711 						/* too heavy, always drown? */
3712 						if (factor < 300 && randint(factor) < 20) hit = 0;
3713 
3714 						/* Hack: Take STR and DEX into consideration (max 28%) */
3715 						if (magik(adj_str_wgt[p_ptr->stat_ind[A_STR]] / 2) ||
3716 						    magik(adj_str_wgt[p_ptr->stat_ind[A_DEX]]) / 2)
3717 							hit = 0;
3718 
3719 						if (magik(swim)) hit = 0;
3720 
3721 						if (hit) msg_print(Ind,"\377rYou're drowning!");
3722 
3723 						/* harm equipments (even hit == 0) */
3724 						if (TOOL_EQUIPPED(p_ptr) != SV_TOOL_TARPAULIN &&
3725 						    magik(WATER_ITEM_DAMAGE_CHANCE) && !p_ptr->levitate &&
3726 						    !p_ptr->immune_water) {
3727 							if (!p_ptr->resist_water || magik(50)) {
3728 								if (!magik(get_skill_scale(p_ptr, SKILL_SWIM, 4900)))
3729 									inven_damage(Ind, set_water_destroy, 1);
3730 								equip_damage(Ind, GF_WATER);
3731 							}
3732 						}
3733 
3734 						if (randint(1000 - factor) < 10) {
3735 							//if (p_ptr->prace != RACE_HALF_TROLL) {
3736 							if (!p_ptr->sustain_str) {
3737 								msg_print(Ind,"\377oYou are weakened by the exertion of swimming!");
3738 								//do_dec_stat(Ind, A_STR, STAT_DEC_TEMPORARY);
3739 								dec_stat(Ind, A_STR, 10, STAT_DEC_TEMPORARY);
3740 							}
3741 						}
3742 						take_hit(Ind, hit, "drowning", 0);
3743 					}
3744 				}
3745 			}
3746 		}
3747 		/* Aquatic anoxia */
3748 		else if ((p_ptr->body_monster) &&
3749 		    ((r_info[p_ptr->body_monster].flags7 & RF7_AQUATIC) &&
3750 		    !(r_info[p_ptr->body_monster].flags3 & RF3_UNDEAD))
3751 		    && ((c_ptr->feat != FEAT_SHAL_WATER) ||
3752 		    r_info[p_ptr->body_monster].weight > 700)
3753 		    /* new: don't get stunned from crossing door/stair grids every time - C. Blue */
3754 		    && !is_always_passable(c_ptr->feat)
3755 		    && !p_ptr->tim_wraith)
3756 		{
3757 			long hit = p_ptr->mhp>>6; /* Take damage */
3758 			hit += randint(p_ptr->chp>>5);
3759 			/* Take CON into consideration(max 30%) */
3760 			hit = (hit * (80 - adj_str_wgt[p_ptr->stat_ind[A_CON]])) / 75;
3761 			if (!hit) hit = 1;
3762 
3763 			if (hit) {
3764 				if (c_ptr->feat != FEAT_SHAL_WATER)
3765 					msg_print(Ind,"\377rYou cannot breathe air!");
3766 				else
3767 					msg_print(Ind,"\377rThere's not enough water to breathe!");
3768 			}
3769 
3770 			if (randint(1000) < 10) {
3771 				msg_print(Ind,"\377rYou find it hard to stir!");
3772 //				do_dec_stat(Ind, A_DEX, STAT_DEC_TEMPORARY);
3773 				dec_stat(Ind, A_DEX, 10, STAT_DEC_TEMPORARY);
3774 			}
3775 
3776 			/* very important to actually enforce it, otherwise
3777 			   it won't matter at all, because during a fight
3778 			   you quaff healing potions anyway.
3779 			   if you change the amount, compare it with continuous
3780 			   stun reduction so it won't get neutralized by high combat skill. */
3781 			if (p_ptr->stun < 20) set_stun(Ind, p_ptr->stun + 5);
3782 
3783 			take_hit(Ind, hit, "anoxia", 0);
3784 		}
3785 
3786 		/* Spectres -- take damage when moving through walls */
3787 
3788 		/*
3789 		 * Added: ANYBODY takes damage if inside through walls
3790 		 * without wraith form -- NOTE: Spectres will never be
3791 		 * reduced below 0 hp by being inside a stone wall; others
3792 		 * WILL BE!
3793 		 */
3794 		/* Seemingly the comment above is wrong, dunno */
3795 		if (!cave_floor_bold(zcave, p_ptr->py, p_ptr->px)
3796 		    && !cave_passable(zcave, p_ptr->py, p_ptr->px)) {
3797 			/* Player can walk through trees */
3798 			//if ((PRACE_FLAG(PR1_PASS_TREE) || (get_skill(SKILL_DRUID) > 15)) && (cave[py][px].feat == FEAT_TREE))
3799 #if 0
3800 			if ((p_ptr->pass_trees || p_ptr->levitate) &&
3801 					(c_ptr->feat == FEAT_TREE))
3802 #endif
3803 			if (player_can_enter(Ind, c_ptr->feat, FALSE)) {
3804 				/* Do nothing */
3805 			}
3806 			else if (c_ptr->feat == FEAT_HOME){/* rien */}
3807 			//else if (PRACE_FLAG(PR1_SEMI_WRAITH) && (!p_ptr->wraith_form) && (f_info[cave[py][px].feat].flags1 & FF1_CAN_PASS))
3808 			else if (!p_ptr->tim_wraith &&
3809 			    !p_ptr->master_move_hook)	/* Hack -- builder is safe */
3810 			{
3811 //				int amt = 1 + ((p_ptr->lev)/5) + p_ptr->mhp / 100;
3812 				/* Currently it only serves to reduce 'stuck' players' HP,
3813 				   so we might lower it a bit - C. Blue */
3814 				int amt = 1 + ((p_ptr->lev)/10) + p_ptr->mhp / 100;
3815 				int amt2 = p_ptr->msp / 35;
3816 
3817 				/* hack: disruption shield suffers a lot if it's got to withstand the walls oO */
3818 				if (p_ptr->tim_manashield) {
3819 					amt += amt2;
3820 
3821 					/* Be nice and don't let the disruption shield dissipate */
3822 					if (p_ptr->pclass == CLASS_MAGE) {
3823 						if (amt > p_ptr->csp - 1) amt = p_ptr->csp - 1;
3824 					} else {
3825 						/* Other classes take double damage */
3826 						if (2 * amt > p_ptr->csp - 1) amt = (p_ptr->csp - 1) / 2;
3827 					}
3828 
3829 					/* Disruption shield protects from this type of damage */
3830 					bypass_invuln = FALSE;
3831 					take_hit(Ind, amt, " walls ...", 0);
3832 					bypass_invuln = TRUE;
3833 				} else {
3834 					if (amt > p_ptr->chp - 1) amt = p_ptr->chp - 1;
3835 					take_hit(Ind, amt, " walls ...", 0);
3836 				}
3837 			}
3838 		}
3839 
3840 		/* specialty for Cloud Planes: continuous icy winds */
3841 		if (d_ptr && d_ptr->type == DI_CLOUD_PLANES) {
3842 #if 0 /* questionable - same as floor terrain effects? (kills potions) */
3843 			project(PROJECTOR_TERRAIN, 0, &p_ptr->wpos, p_ptr->py, p_ptr->px, randint(20), GF_COLD,
3844 			    PROJECT_NORF | PROJECT_KILL | PROJECT_HIDE | PROJECT_JUMP, "freezing winds");
3845 #else /* seems better/cleaner */
3846 			if (!p_ptr->immune_cold) {
3847 				int dam;
3848 				bool destroy = FALSE; /* note: inven damage should be same probability/extent, with or without <res xor opp>! */
3849 
3850 				if (p_ptr->resist_cold && p_ptr->oppose_cold) dam = randint(10);
3851 				else if (p_ptr->resist_cold || p_ptr->oppose_cold) {
3852 					dam = randint(20);
3853 					if (!rand_int(3)) destroy = TRUE;
3854 				} else {
3855 					dam = randint(40);
3856 					if (!rand_int(3)) destroy = TRUE;
3857 				}
3858 				msg_format(Ind, "You are hit by freezing winds for \377o%d\377w damage.", dam);
3859 				bypass_invuln = FALSE; /* Disruption shield protects from this type of damage */
3860 				take_hit(Ind, dam, "freezing winds", 0);
3861 				bypass_invuln = TRUE;
3862 				if (destroy) inven_damage(Ind, set_cold_destroy, 1);
3863 			}
3864 #endif
3865 		}
3866 	}
3867 
3868 
3869 	/* Take damage from cuts */
3870 	if (p_ptr->cut) {
3871 		/* Mortal wound or Deep Gash */
3872 		if (p_ptr->cut > 200) i = 3;
3873 		/* Severe cut */
3874 		else if (p_ptr->cut > 100) i = 2;
3875 		/* Other cuts */
3876 		else i = 1;
3877 
3878 		/* Take damage */
3879 		take_hit(Ind, i, "a fatal wound", p_ptr->cut_attacker);
3880 	}
3881 
3882 	/*** Check the Food, and Regenerate ***/
3883 	/* Ent's natural food while in 'Resting Mode' - C. Blue
3884 	   Water helps much, natural floor helps some. */
3885 	if (!p_ptr->ghost && p_ptr->prace == RACE_ENT && p_ptr->resting) {
3886 		if (c_ptr->feat == FEAT_SHAL_WATER || c_ptr->feat == FEAT_DEEP_WATER || c_ptr->feat == FEAT_MUD) {
3887 			i = 500; //Delicious!
3888 		} else if (c_ptr->feat == FEAT_GRASS || c_ptr->feat == FEAT_DIRT) {
3889 			i = 100;
3890 		} else if (c_ptr->feat == FEAT_BUSH || c_ptr->feat == FEAT_TREE) {
3891 			i = 70;
3892 		} else {
3893 			i = 0;
3894 		}
3895 		if (i > 0 && set_food(Ind, p_ptr->food + i)) {
3896 			msg_print(Ind, "You gain some nourishment from around you.");
3897 			switch(i) {
3898 				case 70:
3899 					msg_format_near(Ind, "\374\377wYou hear strange sounds coming from the direction of %s.", p_ptr->name);
3900 					break;
3901 				case 100:
3902 					msg_format_near(Ind, "\374\377w%s digs %s roots deep into the ground.", p_ptr->name, (p_ptr->male?"his":"her"));
3903 					break;
3904 				case 500:
3905 					msg_format_near(Ind, "\374\377w%s absorbs all the water around %s.", p_ptr->name, (p_ptr->male?"him":"her"));
3906 			}
3907 		}
3908 	}
3909 	/* Ghosts don't need food */
3910 	/* Allow AFK-hivernation if not hungry */
3911 	else if (!p_ptr->ghost && !(p_ptr->afk && p_ptr->food >= PY_FOOD_ALERT) && !p_ptr->admin_dm &&
3912 	    /* Don't starve in town (but recover from being gorged) - C. Blue */
3913 //	    (!istown(&p_ptr->wpos) || p_ptr->food >= PY_FOOD_MAX))
3914 	    (!(istownarea(&p_ptr->wpos, MAX_TOWNAREA) || isdungeontown(&p_ptr->wpos))
3915 	    || p_ptr->food >= PY_FOOD_FULL)) /* allow to digest some to not get gorged in upcoming fights quickly - C. Blue */
3916 	{
3917 		/* Digest normally */
3918 		if (p_ptr->food < PY_FOOD_MAX) {
3919 			/* Every 50/6 level turns */
3920 //			if (!(turn % ((level_speed((&p_ptr->wpos)) * 10) / 12)))
3921 			if (!(turn % ((level_speed((&p_ptr->wpos)) / 120) * 10))) {
3922 				/* Basic digestion rate based on speed */
3923 //				i = (extract_energy[p_ptr->pspeed] / 10) * 2;	// 1.3 (let them starve)
3924 				i = (10 + (extract_energy[p_ptr->pspeed] / 10) * 3) / 2;
3925 
3926 				/* Adrenaline takes more food */
3927 				if (p_ptr->adrenaline) i *= 5;
3928 
3929 				/* Biofeedback takes more food */
3930 				if (p_ptr->biofeedback) i *= 2;
3931 
3932 				/* Regeneration takes more food */
3933 				if (p_ptr->regenerate) i += 30;
3934 
3935 				/* Regeneration takes more food */
3936 				if (p_ptr->tim_regen) i += p_ptr->tim_regen_pow / 10;
3937 
3938 				j = 0;
3939 
3940 				/* Mimics need more food if sustaining heavy forms */
3941 				if (p_ptr->body_monster && r_info[p_ptr->body_monster].weight > 180)
3942 					j = 15 - 7500 / (r_info[p_ptr->body_monster].weight + 320);//180:0, 260:2, 500:~5, 1000:~9, 5000:14, 7270:15
3943 
3944 				/* Draconian and Half-Troll take more food */
3945 				if (p_ptr->prace == RACE_DRACONIAN
3946 				    || p_ptr->prace == RACE_HALF_TROLL) j = 15;
3947 
3948 				/* Use either mimic form induced food consumption increase,
3949 				   or intrinsic one, depending on which is higher. */
3950 				i += j;
3951 
3952 				/* Vampires consume food very quickly,
3953 				   but old vampires don't need food frequently */
3954 				if (p_ptr->prace == RACE_VAMPIRE) {
3955 					if (p_ptr->lev >= 40) i += 60 / (p_ptr->lev - 37);
3956 					else i += 20;
3957 				}
3958 
3959 				/* Invisibility consume a lot of food */
3960 				i += p_ptr->invis / 2;
3961 
3962 				/* Invulnerability consume a lot of food */
3963 				if (p_ptr->invuln) i += 40;
3964 
3965 				/* Wraith Form consume a lot of food */
3966 				if (p_ptr->tim_wraith) i += 30;
3967 
3968 				/* Hitpoints multiplier consume a lot of food */
3969 				if (p_ptr->to_l) i += p_ptr->to_l * 5;
3970 
3971 				/* Slow digestion takes less food */
3972 //				if (p_ptr->slow_digest) i -= 10;
3973 				if (p_ptr->slow_digest) i -= (i > 40) ? i / 4 : 10;
3974 
3975 				/* Never negative */
3976 				if (i < 1) i = 1;
3977 
3978 				/* Cut vampires some slack for Nether Realm:
3979 				   Ancient vampire lords almost don't need any food at all */
3980 				if (p_ptr->prace == RACE_VAMPIRE && p_ptr->total_winner) i = 1;
3981 
3982 				/* Digest some food */
3983 				(void)set_food(Ind, p_ptr->food - i);
3984 			}
3985 		}
3986 
3987 		/* Digest quickly when gorged */
3988 		else {
3989 			/* Digest a lot of food */
3990 			(void)set_food(Ind, p_ptr->food - 100);
3991 		}
3992 
3993 		/* Starve to death (slowly) */
3994 		if (p_ptr->food < PY_FOOD_STARVE) {
3995 			/* Calculate damage */
3996 			i = (PY_FOOD_STARVE - p_ptr->food) / 10;
3997 
3998 			/* Take damage */
3999 			take_hit(Ind, i, "starvation", 0);
4000 		}
4001 	}
4002 
4003 	/* Default regeneration */
4004 	regen_amount = PY_REGEN_NORMAL;
4005 
4006 	/* Amulet of immortality relieves from eating */
4007         if (p_ptr->admin_invuln) p_ptr->food = PY_FOOD_MAX - 1;
4008 
4009 	/* Getting Weak */
4010 	if (p_ptr->food < PY_FOOD_WEAK) {
4011 		/* Lower regeneration */
4012 		if (p_ptr->food < PY_FOOD_STARVE)
4013 			regen_amount = 0;
4014 		else if (p_ptr->food < PY_FOOD_FAINT)
4015 			regen_amount = PY_REGEN_FAINT;
4016 		else
4017 			regen_amount = PY_REGEN_WEAK;
4018 
4019 		/* Getting Faint */
4020 		if (!p_ptr->ghost && p_ptr->food < PY_FOOD_FAINT) {
4021 			/* Faint occasionally */
4022 			if (!p_ptr->paralyzed && (rand_int(100) < 10)) {
4023 				/* Message */
4024 				msg_print(Ind, "You faint from the lack of food.");
4025 				disturb(Ind, 1, 0);
4026 
4027 				/* Hack -- faint (bypass free action) */
4028 				(void)set_paralyzed(Ind, p_ptr->paralyzed + 1 + rand_int(5));
4029 			}
4030 		}
4031 	}
4032 
4033 	/* Resting */
4034 	if (p_ptr->resting && !p_ptr->searching)
4035 		regen_amount = regen_amount * RESTING_RATE;
4036 
4037 	/* Regenerate the mana */
4038 	/* Hack -- regenerate mana 5/3 times faster */
4039 #ifdef ARCADE_SERVER
4040         p_ptr->regen_mana = TRUE;
4041 #endif
4042 	if (p_ptr->csp < p_ptr->msp) {
4043 		if (p_ptr->wpos.wx == WPOS_PVPARENA_X &&
4044 		    p_ptr->wpos.wy == WPOS_PVPARENA_Y &&
4045 		    p_ptr->wpos.wz == WPOS_PVPARENA_Z)
4046 			regenmana(Ind, ((regen_amount * 5 * PVP_MANA_REGEN_BOOST) * (p_ptr->regen_mana ? 2 : 1)) / 3);
4047 		else
4048 			regenmana(Ind, ((regen_amount * 5) * (p_ptr->regen_mana ? 2 : 1)) / 3);
4049 	}
4050 
4051 	/* Regeneration ability */
4052 	if (p_ptr->regenerate)
4053 		regen_amount = regen_amount * 2;
4054 
4055 	/* Health skill improves regen_amount */
4056 	if (minus_health)
4057 		regen_amount = regen_amount * 3 / 2;
4058 
4059 	/* Holy curing gives improved regeneration ability */
4060 	if (get_skill(p_ptr, SKILL_HCURING) >= 30) regen_amount = (regen_amount * (get_skill(p_ptr, SKILL_HCURING) - 10)) / 20;
4061 
4062 	/* Increase regen by tim regen */
4063 	if (p_ptr->tim_regen) regen_amount += p_ptr->tim_regen_pow;
4064 
4065 	/* Poisoned or cut yields no healing */
4066 	if (p_ptr->poisoned || p_ptr->cut || p_ptr->sun_burn)
4067 		regen_amount = 0;
4068 
4069 	/* But Biofeedback always helps */
4070 	if (p_ptr->biofeedback) regen_amount += randint(0x400) + regen_amount;
4071 
4072 	/* Regenerate Hit Points if needed */
4073 	if (p_ptr->chp < p_ptr->mhp && regen_amount)
4074 		regenhp(Ind, regen_amount);
4075 
4076 	/* Undiminish healing penalty in PVP mode */
4077 	if (p_ptr->heal_effect) {
4078 //		p_ptr->heal_effect -= (p_ptr->mhp + p_ptr->lev * 6) / 30;
4079 		p_ptr->heal_effect -= p_ptr->lev / 10;
4080 		if (p_ptr->heal_effect < 0) p_ptr->heal_effect = 0;
4081 	}
4082 
4083 	/* Countdown no-teleport rule in PVP mode */
4084 	if (p_ptr->pvp_prevent_tele) {
4085 		p_ptr->pvp_prevent_tele--;
4086 		if (!p_ptr->pvp_prevent_tele) p_ptr->redraw |= PR_DEPTH;
4087 	}
4088 
4089 	/* Regenerate depleted Stamina */
4090 	if ((p_ptr->cst < p_ptr->mst) && !p_ptr->shadow_running) {
4091 //		int s = 2 * (76 + (adj_con_fix[p_ptr->stat_ind[A_CON]] + minus_health) * 3);
4092 		int s = regen_boost_stamina * (54 + (adj_con_fix[p_ptr->stat_ind[A_CON]] + minus_health) * 3);
4093 		if (p_ptr->resting && !p_ptr->searching) s *= 2;
4094 		p_ptr->cst_frac += s;
4095 		if (p_ptr->cst_frac >= 10000) {
4096 			p_ptr->cst_frac -= 10000;
4097 			p_ptr->cst++;
4098 			if (p_ptr->cst == p_ptr->mst) p_ptr->cst_frac = 0;
4099 			p_ptr->redraw |= (PR_STAMINA);
4100 		}
4101 	}
4102 
4103 	/* Disturb if we are done resting */
4104 	if ((p_ptr->resting) && (p_ptr->chp == p_ptr->mhp) && (p_ptr->csp == p_ptr->msp) && (p_ptr->cst == p_ptr->mst)
4105 	    && !(p_ptr->prace == RACE_ENT && p_ptr->food < PY_FOOD_FULL))
4106 		disturb(Ind, 0, 0);
4107 
4108 	/* Finally, at the end of our turn, update certain counters. */
4109 	/*** Timeout Various Things ***/
4110 
4111 	/* Handle temporary stat drains */
4112 	for (i = 0; i < 6; i++) {
4113 		if (p_ptr->stat_cnt[i] > 0) {
4114 			p_ptr->stat_cnt[i] -= (1 + minus_health);
4115 			if (p_ptr->stat_cnt[i] <= 0) {
4116 				do_res_stat_temp(Ind, i);
4117 			}
4118 		}
4119 	}
4120 
4121 	/* Adrenaline */
4122 	if (p_ptr->adrenaline)
4123 		(void)set_adrenaline(Ind, p_ptr->adrenaline - 1);
4124 
4125 	/* Biofeedback */
4126 	if (p_ptr->biofeedback)
4127 		(void)set_biofeedback(Ind, p_ptr->biofeedback - 1);
4128 
4129 	/* Hack -- Bow Branding */
4130 	if (p_ptr->bow_brand)
4131 		(void)set_bow_brand(Ind, p_ptr->bow_brand - minus_magic, p_ptr->bow_brand_t, p_ptr->bow_brand_d);
4132 
4133 	/* weapon brand time */
4134 	if (p_ptr->brand) {
4135 		(void)set_brand(Ind, p_ptr->brand - minus_magic, p_ptr->brand_t, p_ptr->brand_d);
4136 	}
4137 
4138 	/* Hack -- Timed ESP */
4139 	if (p_ptr->tim_esp)
4140 		(void)set_tim_esp(Ind, p_ptr->tim_esp - minus_magic);
4141 
4142 	/* Hack -- Space/Time Anchor */
4143 	if (p_ptr->st_anchor)
4144 		(void)set_st_anchor(Ind, p_ptr->st_anchor - minus_magic);
4145 
4146 	/* Hack -- Prob travel */
4147 	if (p_ptr->prob_travel)
4148 		(void)set_prob_travel(Ind, p_ptr->prob_travel - minus_magic);
4149 
4150 	/* Hack -- Avoid traps */
4151 	if (p_ptr->tim_traps)
4152 		(void)set_tim_traps(Ind, p_ptr->tim_traps - minus_magic);
4153 
4154 	/* Temporary Mimicry from a Ring of Polymorphing */
4155 	if (p_ptr->tim_mimic && p_ptr->body_monster == p_ptr->tim_mimic_what) {
4156 		/* hack - on hold while in town */
4157 		if (!istownarea(&p_ptr->wpos, MAX_TOWNAREA) && !isdungeontown(&p_ptr->wpos)) {
4158 			/* decrease time left of being polymorphed */
4159 			(void)set_mimic(Ind, p_ptr->tim_mimic - 1, p_ptr->tim_mimic_what);
4160 		}
4161 	}
4162 
4163 	/* Hack -- Timed manashield */
4164 	if (p_ptr->tim_manashield)
4165 		set_tim_manashield(Ind, p_ptr->tim_manashield - minus_magic);
4166 #ifndef KURZEL_PK
4167 	if (cfg.use_pk_rules == PK_RULES_DECLARE) {
4168 		if (p_ptr->tim_pkill) {
4169 			p_ptr->tim_pkill--;
4170 			if (!p_ptr->tim_pkill) {
4171 				if (p_ptr->pkill & PKILL_SET) {
4172 					msg_print(Ind, "You may now kill other players");
4173 					p_ptr->pkill |= PKILL_KILLER;
4174 				} else {
4175 					msg_print(Ind, "You are now protected from other players");
4176 					p_ptr->pkill &= ~PKILL_KILLABLE;
4177 				}
4178 			}
4179 		}
4180 	}
4181 #endif
4182 	if (p_ptr->tim_jail && !p_ptr->wpos.wz) {
4183 		p_ptr->tim_jail--;
4184 		if (!p_ptr->tim_jail) {
4185 #ifdef JAILER_KILLS_WOR
4186 			/* eat his WoR scrolls as suggested? */
4187 			bool found = FALSE, one = TRUE;
4188 			for (j = 0; j < INVEN_WIELD; j++) {
4189 				if (!p_ptr->inventory[j].k_idx) continue;
4190 				o_ptr = &p_ptr->inventory[j];
4191 				if ((o_ptr->tval == TV_ROD) && (o_ptr->sval == SV_ROD_RECALL)) {
4192 					if (found) one = FALSE;
4193 					if (o_ptr->number > 1) one = FALSE;
4194 					o_ptr->pval = 300;
4195 					found = TRUE;
4196 				}
4197 			}
4198 			if (found) {
4199 				msg_format(Ind, "The jailer discharges your rod%s of recall.", one ? "" : "s");
4200 				p_ptr->window |= PW_INVEN;
4201 			}
4202 #endif
4203 
4204 			/* only teleport him if he didn't take the ironman exit.
4205 			   (could add p_ptr->in_jail to handle it 100% safely
4206 			   or just set p_ptr->tim_jail to 0 on wpos change) */
4207 			if (p_ptr->wpos.wz == 0 &&
4208 			    (zcave[p_ptr->py][p_ptr->px].info & CAVE_STCK)) {
4209 				msg_print(Ind, "\377GYou are free to go!");
4210 				teleport_player_force(Ind, 1);
4211 			}
4212 		}
4213 	}
4214 
4215 	/* Hack -- Tunnel */
4216 #if 0	// not used
4217 	if (p_ptr->auto_tunnel)
4218 		p_ptr->auto_tunnel--;
4219 #endif	// 0
4220 	/* Hack -- Meditation */
4221 	if (p_ptr->tim_meditation)
4222 		(void)set_tim_meditation(Ind, p_ptr->tim_meditation - minus);
4223 
4224 	/* Hack -- Wraithform */
4225 	if (p_ptr->tim_wraith)
4226 		(void)set_tim_wraith(Ind, p_ptr->tim_wraith - minus_magic);
4227 
4228 	/* Hack -- Hallucinating */
4229 	if (p_ptr->image) {
4230 		int adjust = 1 + minus_health;
4231 		if (get_skill(p_ptr, SKILL_HCURING) >= 50) adjust++;
4232 		(void)set_image(Ind, p_ptr->image - adjust);
4233 	}
4234 
4235 	/* Blindness */
4236 	if (p_ptr->blind) {
4237 		int adjust = 1 + minus_health;
4238 		if (get_skill(p_ptr, SKILL_HCURING) >= 30) adjust++;
4239 		(void)set_blind(Ind, p_ptr->blind - adjust);
4240 	}
4241 
4242 	/* Times see-invisible */
4243 	if (p_ptr->tim_invis)
4244 		(void)set_tim_invis(Ind, p_ptr->tim_invis - minus_magic);
4245 
4246 	/* Times invisibility */
4247 	if (p_ptr->tim_invisibility) {
4248 		if (p_ptr->aggravate) {
4249 			msg_print(Ind, "Your invisibility shield is broken by your aggravation.");
4250 			(void)set_invis(Ind, 0, 0);
4251 		} else {
4252 			(void)set_invis(Ind, p_ptr->tim_invisibility - minus_magic, p_ptr->tim_invis_power2);
4253 		}
4254 	}
4255 
4256 	/* Timed infra-vision */
4257 	if (p_ptr->tim_infra)
4258 		(void)set_tim_infra(Ind, p_ptr->tim_infra - minus_magic);
4259 
4260 	/* Paralysis */
4261 	if (p_ptr->paralyzed)
4262 		(void)set_paralyzed(Ind, p_ptr->paralyzed - 1 - minus_health);
4263 
4264 	/* Confusion */
4265 	if (p_ptr->confused)
4266 		(void)set_confused(Ind, p_ptr->confused - minus - minus_combat - minus_health);
4267 
4268 	/* Afraid */
4269 	if (p_ptr->afraid)
4270 		(void)set_afraid(Ind, p_ptr->afraid - minus - minus_combat);
4271 
4272 	/* Fast */
4273 	if (p_ptr->fast)
4274 		(void)set_fast(Ind, p_ptr->fast - minus_magic, p_ptr->fast_mod);
4275 
4276 	/* Slow */
4277 	if (p_ptr->slow)
4278 		(void)set_slow(Ind, p_ptr->slow - minus_magic); // - minus_health
4279 
4280 #ifdef ENABLE_MAIA
4281 	if (p_ptr->divine_crit)
4282 		(void)do_divine_crit(Ind, p_ptr->divine_crit - minus_magic, p_ptr->divine_crit_mod);
4283 
4284 	if (p_ptr->divine_hp)
4285 		(void)do_divine_hp(Ind, p_ptr->divine_hp - minus_magic, p_ptr->divine_hp_mod);
4286 
4287 	if (p_ptr->divine_xtra_res_time)
4288 		(void)do_divine_xtra_res_time(Ind, p_ptr->divine_xtra_res_time - minus_magic);
4289 #endif
4290 	/* xtra shot? - the_sandman */
4291 	if (p_ptr->focus_time)
4292 		(void)do_focus_shot(Ind, p_ptr->focus_time - minus_magic, p_ptr->focus_val);
4293 
4294 	/* xtra stats? - the_sandman */
4295 	if (p_ptr->xtrastat)
4296 		(void)do_xtra_stats(Ind, p_ptr->xtrastat - minus_magic, p_ptr->statval);
4297 
4298 	/* Protection from evil */
4299 	if (p_ptr->protevil)
4300 		(void)set_protevil(Ind, p_ptr->protevil - minus_magic);
4301 
4302 	/* Holy Zeal - EA bonus */
4303 	if (p_ptr->zeal)
4304 		(void)set_zeal(Ind, p_ptr->zeal_power, p_ptr->zeal - 1);
4305 
4306 	/* Heart is still boldened */
4307 	if (p_ptr->res_fear_temp)
4308 		(void)set_res_fear(Ind, p_ptr->res_fear_temp - 1);
4309 
4310 	/* Holy Martyr */
4311 	if (p_ptr->martyr)
4312 		(void)set_martyr(Ind, p_ptr->martyr - 1);
4313 	if (p_ptr->martyr_timeout) {
4314 		p_ptr->martyr_timeout--;
4315 		if (!p_ptr->martyr_timeout) msg_print(Ind, "The heavens are ready to accept your martyrium.");
4316 	}
4317 
4318 	/* Mindcrafters' Willpower */
4319 	if (p_ptr->mindboost)
4320 		(void)set_mindboost(Ind, p_ptr->mindboost_power, p_ptr->mindboost - 1);
4321 
4322 	/* Mindcrafters' repulsion shield */
4323 	if (p_ptr->kinetic_shield) (void)set_kinetic_shield(Ind, p_ptr->kinetic_shield - 1);
4324 
4325 	if (p_ptr->cloak_neutralized) p_ptr->cloak_neutralized--;
4326 	if (p_ptr->cloaked > 1) {
4327 		if (--p_ptr->cloaked == 1) {
4328 			msg_print(Ind, "\377DYou cloaked your appearance!");
4329 			msg_format_near(Ind, "\377w%s disappears before your eyes!", p_ptr->name);
4330 			p_ptr->update |= (PU_BONUS | PU_MONSTERS);
4331 			p_ptr->redraw |= (PR_STATE | PR_SPEED);
4332 		        handle_stuff(Ind);
4333 			/* log a hint that newbies got it */
4334 			if (p_ptr->lev == 15) s_printf("CLOAKING-15: %s.\n", p_ptr->name);
4335 			p_ptr->warning_cloak = 1;
4336 		}
4337 	}
4338 
4339 	/* Invulnerability */
4340 	/* Hack -- make -1 permanent invulnerability */
4341 	if (p_ptr->invuln) {
4342 		if (p_ptr->invuln > 0) {
4343 			/* Hack: Don't diminish Stair-GoI by Antimagic: */
4344 			if (p_ptr->invuln_dur >= 5) (void)set_invuln(Ind, p_ptr->invuln - minus_magic);
4345 			else (void)set_invuln(Ind, p_ptr->invuln - 1);
4346 		}
4347 		//if (p_ptr->invuln == 5) msg_print(Ind, "\377vThe invulnerability shield starts to fade...");
4348 	}
4349 
4350 	/* Heroism */
4351 	if (p_ptr->hero)
4352 		(void)set_hero(Ind, p_ptr->hero - 1);
4353 
4354 	/* Super Heroism */
4355 	if (p_ptr->shero)
4356 		(void)set_shero(Ind, p_ptr->shero - 1);
4357 
4358 	/* Furry */
4359 	if (p_ptr->fury)
4360 		(void)set_fury(Ind, p_ptr->fury - 1);
4361 
4362 	/* Berserk #2 */
4363 	if (p_ptr->berserk)
4364 		(void)set_berserk(Ind, p_ptr->berserk - 1);
4365 
4366 	/* Sprint? melee technique */
4367 	if (p_ptr->melee_sprint)
4368 		(void)set_melee_sprint(Ind, p_ptr->melee_sprint - 1);
4369 
4370 	/* Blessed */
4371 	if (p_ptr->blessed)
4372 		(void)set_blessed(Ind, p_ptr->blessed - 1);
4373 
4374 	/* Shield */
4375 	if (p_ptr->shield)
4376 		(void)set_shield(Ind, p_ptr->shield - minus_magic, p_ptr->shield_power, p_ptr->shield_opt, p_ptr->shield_power_opt, p_ptr->shield_power_opt2);
4377 
4378 	/* Timed deflection */
4379 	if (p_ptr->tim_deflect)
4380 		(void)set_tim_deflect(Ind, p_ptr->tim_deflect - minus_magic);
4381 
4382 	/* Timed Feather Falling */
4383 	if (p_ptr->tim_ffall)
4384 		(void)set_tim_ffall(Ind, p_ptr->tim_ffall - 1);
4385 	if (p_ptr->tim_lev)
4386 		(void)set_tim_lev(Ind, p_ptr->tim_lev - 1);
4387 
4388 	/* Timed regen */
4389 	if (p_ptr->tim_regen)
4390 		(void)set_tim_regen(Ind, p_ptr->tim_regen - 1, p_ptr->tim_regen_pow);
4391 
4392 	/* Thunderstorm */
4393 	if (p_ptr->tim_thunder) {
4394                 int dam = damroll(p_ptr->tim_thunder_p1, p_ptr->tim_thunder_p2);
4395 		int i, tries = 600;
4396 		monster_type *m_ptr = NULL;
4397 
4398 		while (tries) {
4399 			/* Access the monster */
4400 			m_ptr = &m_list[i = rand_range(1, m_max - 1)];
4401 
4402 			tries--;
4403 
4404 			/* Ignore "dead" monsters */
4405 			if (!m_ptr->r_idx) continue;
4406 
4407 			/* pfft. not even our level */
4408 
4409 			if (!inarea(&p_ptr->wpos, &m_ptr->wpos)) continue;
4410 			/* Cant see ? cant hit */
4411 			if (!los(&p_ptr->wpos, p_ptr->py, p_ptr->px, m_ptr->fy, m_ptr->fx)) continue;
4412 			if (distance(p_ptr->py, p_ptr->px, m_ptr->fy, m_ptr->fx) > 15) continue;
4413 
4414 			/* Do not hurt friends! */
4415 			/* if (is_friend(m_ptr) >= 0) continue; */
4416 			break;
4417 		}
4418 
4419 		if (tries) {
4420 			char m_name[MNAME_LEN];
4421 
4422 			monster_desc(Ind, m_name, i, 0);
4423 			msg_format(Ind, "Lightning strikes %s.", m_name, i, dam);
4424 			project(-Ind, 0, &p_ptr->wpos, m_ptr->fy, m_ptr->fx, dam, GF_THUNDER,
4425 			        PROJECT_KILL | PROJECT_ITEM | PROJECT_GRID, "");
4426 			//project(-Ind, 0, &p_ptr->wpos, m_ptr->fy, m_ptr->fx, dam / 3, GF_ELEC,
4427 			//        PROJECT_KILL | PROJECT_ITEM, "");
4428 			//project(-Ind, 0, &p_ptr->wpos, m_ptr->fy, m_ptr->fx, dam / 3, GF_LITE,
4429 			//        PROJECT_KILL | PROJECT_ITEM, "");
4430 			//project(-Ind, 0, &p_ptr->wpos, m_ptr->fy, m_ptr->fx, dam / 3, GF_SOUND,
4431 			//        PROJECT_KILL | PROJECT_ITEM, "");
4432 		}
4433 
4434 		(void)set_tim_thunder(Ind, p_ptr->tim_thunder - minus_magic, p_ptr->tim_thunder_p1, p_ptr->tim_thunder_p2);
4435         }
4436 
4437 	/* Oppose Acid */
4438 	if (p_ptr->oppose_acid)
4439 		(void)set_oppose_acid(Ind, p_ptr->oppose_acid - minus_magic);
4440 
4441 	/* Oppose Electricity */
4442 	if (p_ptr->oppose_elec)
4443 		(void)set_oppose_elec(Ind, p_ptr->oppose_elec - minus_magic);
4444 
4445 	/* Oppose Fire */
4446 	if (p_ptr->oppose_fire)
4447 		(void)set_oppose_fire(Ind, p_ptr->oppose_fire - minus_magic);
4448 
4449 	/* Oppose Cold */
4450 	if (p_ptr->oppose_cold)
4451 		(void)set_oppose_cold(Ind, p_ptr->oppose_cold - minus_magic);
4452 
4453 	/* Oppose Poison */
4454 	if (p_ptr->oppose_pois)
4455 		(void)set_oppose_pois(Ind, p_ptr->oppose_pois - minus_magic);
4456 
4457 	/*** Poison and Stun and Cut ***/
4458 
4459 	/* Poison */
4460 	if (p_ptr->poisoned) {
4461 		int adjust = (adj_con_fix[p_ptr->stat_ind[A_CON]] + minus);
4462 		/* Apply some healing */
4463 		if (get_skill(p_ptr, SKILL_HCURING) >= 30) adjust *= 2;
4464 
4465 		//(void)set_poisoned(Ind, p_ptr->poisoned - adjust - minus_health * 2, p_ptr->poisoned_attacker);
4466 		(void)set_poisoned(Ind, p_ptr->poisoned - (adjust + minus_health) * (minus_health + 1), p_ptr->poisoned_attacker);
4467 
4468 		if (!p_ptr->poisoned) p_ptr->slow_poison = 0;
4469 	}
4470 
4471 	/* Stun */
4472 	if (p_ptr->stun) {
4473 #if 0
4474 		int adjust = (adj_con_fix[p_ptr->stat_ind[A_CON]] + minus);
4475 		/* Apply some healing */
4476 		//(void)set_stun(Ind, p_ptr->stun - adjust - minus_health * 2);
4477 		(void)set_stun(Ind, p_ptr->stun - (adjust + minus_health) * (minus_health + 1));
4478 #endif
4479 		int adjust = minus + get_skill_scale_fine(p_ptr, SKILL_COMBAT, 2);
4480 //		if (get_skill(p_ptr, SKILL_HCURING) >= 40) adjust = (adjust * 5) / 3;
4481 		if (get_skill(p_ptr, SKILL_HCURING) >= 40) adjust++;
4482 
4483 		(void)set_stun(Ind, p_ptr->stun - adjust);
4484 	}
4485 
4486 	/* Cut */
4487 	if (p_ptr->cut) {
4488 		int adjust = minus;// = (adj_con_fix[p_ptr->stat_ind[A_CON]] + minus);
4489 
4490 		/* Biofeedback always helps */
4491 		if (p_ptr->biofeedback) adjust += 5;
4492 
4493 		/* Hack -- Truly "mortal" wound */
4494 		if (p_ptr->cut > 1000) adjust = 0;
4495 
4496 		if (get_skill(p_ptr, SKILL_HCURING) >= 40) adjust *= 2;
4497 
4498 
4499 		/* Apply some healing */
4500 		//(void)set_cut(Ind, p_ptr->cut - adjust - minus_health * 2, p_ptr->cut_attacker);
4501 //		(void)set_cut(Ind, p_ptr->cut - (adjust + minus_health) * (minus_health + 1), p_ptr->cut_attacker);
4502 		(void)set_cut(Ind, p_ptr->cut - adjust * (minus_health + 1), p_ptr->cut_attacker);
4503 	}
4504 
4505 	/* Temporary blessing of luck */
4506 	if (p_ptr->bless_temp_luck) (void)bless_temp_luck(Ind, p_ptr->bless_temp_luck_power, p_ptr->bless_temp_luck - 1);
4507 
4508 	/* Temporary auras */
4509 	if (p_ptr->sh_fire_tim) (void)set_sh_fire_tim(Ind, p_ptr->sh_fire_tim - minus_magic);
4510 	if (p_ptr->sh_cold_tim) (void)set_sh_cold_tim(Ind, p_ptr->sh_cold_tim - minus_magic);
4511 	if (p_ptr->sh_elec_tim) (void)set_sh_elec_tim(Ind, p_ptr->sh_elec_tim - minus_magic);
4512 
4513 	/* Still possible effects from another player's support spell on this player? */
4514 	if (p_ptr->support_timer) {
4515 		p_ptr->support_timer--;
4516 		if (!p_ptr->support_timer) p_ptr->supp = p_ptr->supp_top = 0;
4517 	}
4518 
4519 #if POLY_RING_METHOD == 0
4520 	/* Check polymorph rings with timeouts */
4521 	for (i = INVEN_LEFT; i <= INVEN_RIGHT; i++) {
4522 		o_ptr = &p_ptr->inventory[i];
4523 		if ((o_ptr->tval == TV_RING) && (o_ptr->sval == SV_RING_POLYMORPH) && (o_ptr->timeout > 0) &&
4524 		    (p_ptr->body_monster == o_ptr->pval))
4525 		{
4526 			/* Decrease life-span */
4527 			o_ptr->timeout--;
4528 
4529 			/* Hack -- notice interesting energy steps */
4530 			if ((o_ptr->timeout < 100) || (!(o_ptr->timeout % 100))) {
4531 				/* Window stuff */
4532 				p_ptr->window |= (PW_INVEN | PW_EQUIP);
4533 			}
4534 
4535 			/* Hack -- notice interesting fuel steps */
4536 			if ((o_ptr->timeout > 0) && (o_ptr->timeout < 100) && !(o_ptr->timeout % 10))
4537 			{
4538 				if (p_ptr->disturb_minor) disturb(Ind, 0, 0);
4539 				msg_print(Ind, "\376\377LYour ring flickers and fades, flashes of light run over its surface.");
4540 				/* Window stuff */
4541 				p_ptr->window |= (PW_INVEN | PW_EQUIP);
4542 			} else if (o_ptr->timeout == 0) {
4543 				disturb(Ind, 0, 0);
4544 				msg_print(Ind, "\376\377LYour ring disintegrates!");
4545 
4546     			        if ((p_ptr->body_monster == o_ptr->pval) &&
4547 		                    ((p_ptr->r_killed[p_ptr->body_monster] < r_info[p_ptr->body_monster].level) ||
4548 	                    	    (get_skill_scale(p_ptr, SKILL_MIMIC, 100) < r_info[p_ptr->body_monster].level)))
4549 		                {
4550 		                        /* If player hasn't got high enough kill count anymore now, poly back to player form! */
4551 		                        msg_print(Ind, "You polymorph back to your normal form.");
4552 		                        do_mimic_change(Ind, 0, TRUE);
4553 		                }
4554 
4555  				/* Decrease the item, optimize. */
4556 				inven_item_increase(Ind, i, -1);
4557 				inven_item_optimize(Ind, i);
4558 			}
4559 		}
4560 	}
4561 #endif
4562 
4563 	/* Don't accidentally float after dying */
4564 	if (p_ptr->safe_float_turns) p_ptr->safe_float_turns--;
4565 
4566 #ifdef USE_SOUND_2010
4567 	/* Start delayed music for players who were greeted at start via audio */
4568 	if (p_ptr->music_start) {
4569 		p_ptr->music_start--;
4570 		if (p_ptr->music_start == 0) handle_music(Ind);
4571 	}
4572 #endif
4573 
4574 
4575 	/*** Process Light ***/
4576 
4577 	/* Check for light being wielded */
4578 	o_ptr = &p_ptr->inventory[INVEN_LITE];
4579 
4580 	/* Burn some fuel in the current lite */
4581 	if (o_ptr->tval == TV_LITE) {
4582 		u32b f1 = 0 , f2 = 0 , f3 = 0, f4 = 0, f5 = 0, f6 = 0, esp = 0;
4583 
4584 		/* Hack -- Use some fuel (sometimes) */
4585 #if 0
4586 		if (!artifact_p(o_ptr) && !(o_ptr->sval == SV_LITE_DWARVEN)
4587 		    && !(o_ptr->sval == SV_LITE_FEANOR) && (o_ptr->pval > 0) && (!o_ptr->name1))
4588 #endif	// 0
4589 
4590 			/* Extract the item flags */
4591 			object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &f6, &esp);
4592 
4593 		/* Hack -- Use some fuel */
4594 		if ((f4 & TR4_FUEL_LITE) && (o_ptr->timeout > 0)) {
4595 			/* Decrease life-span */
4596 			o_ptr->timeout--;
4597 
4598 			/* Hack -- notice interesting fuel steps */
4599 			if ((o_ptr->timeout < 100) || (!(o_ptr->timeout % 100))) {
4600 				/* Window stuff */
4601 				p_ptr->window |= (PW_INVEN | PW_EQUIP);
4602 			}
4603 
4604 			/* Hack -- Special treatment when blind */
4605 			if (p_ptr->blind) {
4606 				/* Hack -- save some light for later */
4607 				if (o_ptr->timeout == 0) o_ptr->timeout++;
4608 			}
4609 
4610 			/* The light is now out */
4611 			else if (o_ptr->timeout == 0) {
4612 				bool refilled = FALSE;
4613 
4614 				disturb(Ind, 0, 0);
4615 
4616 				/* If flint is ready, refill at once */
4617 				if (TOOL_EQUIPPED(p_ptr) == SV_TOOL_FLINT &&
4618 						!p_ptr->paralyzed)
4619 				{
4620 					msg_print(Ind, "You prepare a flint...");
4621 					refilled = do_auto_refill(Ind);
4622 					if (!refilled)
4623 						msg_print(Ind, "Oops, you're out of fuel!");
4624 				}
4625 
4626 				if (!refilled) {
4627 					msg_print(Ind, "Your light has gone out!");
4628 					/* Calculate torch radius */
4629 					p_ptr->update |= (PU_TORCH | PU_BONUS);
4630 
4631 					if (!p_ptr->warning_lite_refill) {
4632 						p_ptr->warning_lite_refill = 1;
4633 						msg_print(Ind, "\374\377yHINT: Press \377oSHIFT+f\377y to refill your light source. You will need a flask of");
4634 						msg_print(Ind, "\374\377y      oil for lanterns, or another torch to combine with an extinct torch.");
4635 //						s_printf("warning_lite_refill: %s\n", p_ptr->name);
4636 					}
4637 				}
4638 #if 0	/* torch of presentiment goes poof to unlight trap, taken out for now - C. Blue */
4639 				/* Torch disappears */
4640 				if (o_ptr->sval == SV_LITE_TORCH && !o_ptr->timeout) {
4641 					/* Decrease the item, optimize. */
4642 					inven_item_increase(Ind, INVEN_LITE, -1);
4643 					//						inven_item_describe(Ind, INVEN_LITE);
4644 					inven_item_optimize(Ind, INVEN_LITE);
4645 				}
4646 #endif
4647 			}
4648 
4649 			/* The light is getting dim */
4650 			else if ((o_ptr->timeout < 100) && (!(o_ptr->timeout % 10))) {
4651 				if (p_ptr->disturb_minor) disturb(Ind, 0, 0);
4652 				msg_print(Ind, "Your light is growing faint.");
4653 			}
4654 		}
4655 	}
4656 
4657 	/* Calculate torch radius */
4658 	//		p_ptr->update |= (PU_TORCH|PU_BONUS);
4659 
4660 	/* Silyl fun stuff >:) - C. Blue */
4661 	if (p_ptr->corner_turn) {
4662 		p_ptr->corner_turn -= (p_ptr->corner_turn > 2 ? 2 : p_ptr->corner_turn);
4663 		if (p_ptr->corner_turn > 25) {
4664 			p_ptr->corner_turn = 0;
4665 			disturb(Ind, 0, 0);
4666 			msg_print(Ind, "\377oYour head feels dizzy!");
4667 			msg_format_near(Ind, "%s looks dizzy!", p_ptr->name);
4668 			set_confused(Ind, 10 + rand_int(5));
4669 			if (magik(50)) {
4670 				msg_print(Ind, "\377oYou vomit!");
4671 				msg_format_near(Ind, "%s vomits!", p_ptr->name);
4672 				take_hit(Ind, 1, "circulation collapse", 0);
4673 			    if (!p_ptr->suscep_life) {
4674 				if (p_ptr->chp < p_ptr->mhp) /* *invincibility* fix */
4675 					if (p_ptr->food > PY_FOOD_FAINT - 1)
4676 					        (void)set_food(Ind, PY_FOOD_FAINT - 1);
4677 				(void)set_poisoned(Ind, 0, 0);
4678 				if (!p_ptr->free_act && !p_ptr->slow_digest)
4679 				        (void)set_paralyzed(Ind, p_ptr->paralyzed + rand_int(10) + 10);
4680 			    }
4681 			}
4682 		}
4683 	}
4684 
4685 
4686 	/*** Process Inventory ***/
4687 
4688 	/* Handle experience draining */
4689 //	if (p_ptr->drain_exp && (p_ptr->wpos.wz != 0) && magik(30 - (60 / (p_ptr->drain_exp + 2))))
4690 /* experimental: maybe no expdrain or just less expdrain while player is on world surface.
4691    idea: allow classes who lack a *remove curse* spell to make more use of the rings. */
4692 //	if (p_ptr->drain_exp && (p_ptr->wpos.wz != 0) && magik(30 - (60 / (p_ptr->drain_exp + 2))))
4693 //	if (p_ptr->drain_exp && magik(p_ptr->wpos.wz != 0 ? 50 : 0) && magik(30 - (60 / (p_ptr->drain_exp + 2))))
4694 //	if (p_ptr->drain_exp && magik(p_ptr->wpos.wz != 0 ? 50 : (istown(&p_ptr->wpos) ? 0 : 25)) && magik(30 - (60 / (p_ptr->drain_exp + 2))))
4695 	/* changing above line to use istownarea() so you can sort your houses without drain */
4696 	if (p_ptr->drain_exp && magik(
4697 	    p_ptr->wpos.wz != 0 ? (isdungeontown(&p_ptr->wpos) ? 0 : 50) :
4698 	    (istownarea(&p_ptr->wpos, MAX_TOWNAREA) ? 0 : 25)
4699 	    ) && magik(30 - (60 / (p_ptr->drain_exp + 2))))
4700 //		take_xp_hit(Ind, 1 + p_ptr->lev / 5 + p_ptr->max_exp / 50000L, "Draining", TRUE, FALSE, FALSE);
4701 		/* Moltor is right, exp drain was too weak for up to quite high levels. Need to make a new formula.. */
4702 	{
4703 		long exploss = 1 + p_ptr->lev + p_ptr->max_exp / 2000L;
4704 
4705 		/* Reduce exploss the more difficult it is for a race/class combination
4706 		   to aquire exp, ie depending on the character's exp% penalty.
4707 		   Otherwise wearing rings of power on Draconian or Maiar becomes quite harsh,
4708 		   and might require special strategies to counter such as taking ood U pits. */
4709 		exploss = (exploss * 120L) / (50 + p_ptr->expfact / 2);
4710 
4711 		/* Cap it against level thresholds */
4712 #ifdef ALT_EXPRATIO
4713 		if ((p_ptr->lev >= 2) && (player_exp[p_ptr->lev - 2] > p_ptr->exp - exploss))
4714 			exploss = p_ptr->exp - player_exp[p_ptr->lev - 2];
4715 #else
4716 		if ((p_ptr->lev >= 2) && ((((s64b)player_exp[p_ptr->lev - 2]) * ((s64b)p_ptr->expfact)) / 100L > p_ptr->exp - exploss))
4717 			exploss = p_ptr->exp - player_exp[p_ptr->lev - 2];
4718 #endif
4719 
4720 		/* Drain it! */
4721 		if (exploss > 0) take_xp_hit(Ind, exploss, "Draining", TRUE, FALSE, FALSE);
4722 	}
4723 
4724 #if 0
4725 	{
4726 		if ((rand_int(100) < 10) && (p_ptr->exp > 0)) {
4727 			p_ptr->exp--;
4728 			p_ptr->max_exp--;
4729 			check_experience(Ind);
4730 		}
4731 	}
4732 #endif	// 0
4733 
4734 	/* Now implemented here too ;) - C. Blue */
4735 	/* let's say TY_CURSE lowers stats (occurs often) */
4736 	if (p_ptr->ty_curse &&
4737 	    (rand_int(p_ptr->wpos.wz != 0 ? 100 : (istown(&p_ptr->wpos) || isdungeontown(&p_ptr->wpos) ? 0 : 300)) == 1) &&
4738 	    (get_skill(p_ptr, SKILL_HSUPPORT) < 50) && magik(100 - p_ptr->antimagic)) {
4739 		msg_print(Ind, "An ancient foul curse shakes your body!");
4740 #if 0
4741 		if (rand_int(2))
4742 		(void)do_dec_stat(Ind, rand_int(6), STAT_DEC_NORMAL);
4743 		else if (p_ptr->lev != 99) lose_exp(Ind, (p_ptr->exp / 100) * MON_DRAIN_LIFE);
4744 		/* take_xp_hit(Ind, 1 + p_ptr->lev / 5 + p_ptr->max_exp / 50000L, "an ancient foul curse", TRUE, TRUE, TRUE); */
4745 #else
4746 		(void)do_dec_stat(Ind, rand_int(6), STAT_DEC_NORMAL);
4747 #endif
4748 	}
4749 	/* and DG_CURSE randomly summons a monster (non-unique) */
4750 	if (p_ptr->dg_curse && (rand_int(200) == 0) && !istown(&p_ptr->wpos) && !isdungeontown(&p_ptr->wpos) &&
4751 	    (get_skill(p_ptr, SKILL_HSUPPORT) < 50) && magik(100 - p_ptr->antimagic)) {
4752 		msg_print(Ind, "An ancient morgothian curse calls out!");
4753 		summon_specific(&p_ptr->wpos, p_ptr->py, p_ptr->px, p_ptr->lev + 20, 100, SUMMON_MONSTER, 0, 0);
4754 	}
4755 
4756 	/* Handle experience draining.  In Oangband, the effect
4757 	 * is worse, especially for high-level characters.
4758 	 * As per Tolkien, hobbits are resistant.
4759 	 */
4760 	if ((p_ptr->black_breath || p_ptr->black_breath_tmp) &&
4761 	    rand_int((get_skill(p_ptr, SKILL_HCURING) >= 50) ? 250 : 150) < (p_ptr->prace == RACE_HOBBIT || p_ptr->suscep_life ? 2 : 5))
4762 	{
4763 		(void)do_dec_stat_time(Ind, rand_int(6), STAT_DEC_NORMAL, 25, 0, TRUE);
4764 		take_xp_hit(Ind, 1 + p_ptr->lev * 3 + p_ptr->max_exp / 5000L,
4765 		    "Black Breath", TRUE, TRUE, TRUE);
4766 	}
4767 
4768 	/* Drain Mana */
4769 	if (p_ptr->drain_mana && p_ptr->csp) {
4770 		p_ptr->csp -= p_ptr->drain_mana;
4771 		if (magik(30)) p_ptr->csp -= p_ptr->drain_mana;
4772 
4773 		if (p_ptr->csp < 0) p_ptr->csp = 0;
4774 
4775 		/* Redraw */
4776 		p_ptr->redraw |= (PR_MANA);
4777 
4778 		/* Window stuff */
4779 		p_ptr->window |= (PW_PLAYER);
4780 	}
4781 
4782 	/* Drain Hitpoints */
4783 	if (p_ptr->drain_life) {
4784 		int drain = (p_ptr->drain_life) * (rand_int(p_ptr->mhp / 100) + 1);
4785 
4786 		p_ptr->no_alert = TRUE;
4787 		take_hit(Ind, drain < p_ptr->chp ? drain : p_ptr->chp, "life draining", 0);
4788 		p_ptr->no_alert = FALSE;
4789 	}
4790 
4791 	/* Note changes */
4792 	j = 0;
4793 
4794 	/* Process inventory (blood potions going bad) */
4795 	for (i = 0; i < INVEN_PACK; i++) {
4796 		/* Get the object */
4797 		o_ptr = &p_ptr->inventory[i];
4798 
4799 		/* Skip non-objects */
4800 		if (!o_ptr->k_idx) continue;
4801 
4802 		if (!(o_ptr->tval == TV_POTION || o_ptr->tval == TV_FOOD) || !o_ptr->timeout) continue;
4803 
4804 		o_ptr->timeout--;
4805 		/* Notice changes */
4806 		if (!(o_ptr->timeout)) {
4807 			inven_item_increase(Ind, i, -o_ptr->number);
4808 			inven_item_describe(Ind, i);
4809 			inven_item_optimize(Ind, i);
4810 			j++;
4811 		}
4812 	}
4813 
4814 	/* Process equipment */
4815 	for (i = INVEN_WIELD; i < INVEN_TOTAL; i++) {
4816 		/* Get the object */
4817 		o_ptr = &p_ptr->inventory[i];
4818 
4819 		/* Skip non-objects */
4820 		if (!o_ptr->k_idx) continue;
4821 
4822 		/* Recharge activatable objects */
4823 		/* (well, light-src should be handled here too? -Jir- */
4824 		if ((o_ptr->timeout > 0) && ((o_ptr->tval != TV_LITE) || o_ptr->name1) &&
4825 		    !((o_ptr->tval == TV_RING) && (o_ptr->sval == SV_RING_POLYMORPH)))
4826 		{
4827 			/* Recharge */
4828 			o_ptr->timeout--;
4829 
4830 			/* Notice changes */
4831 			if (!(o_ptr->timeout)) j++;
4832 		}
4833 	}
4834 
4835 	/* Recharge rods */
4836 	/* this should be moved to 'timeout'? */
4837 	for (i = 0; i < INVEN_PACK; i++) {
4838 		o_ptr = &p_ptr->inventory[i];
4839 
4840 		/* Examine all charging rods */
4841 		if ((o_ptr->tval == TV_ROD) && (o_ptr->pval)) {
4842 			/* Charge it */
4843 			o_ptr->pval--;
4844 
4845 			/* Charge it further */
4846 			if (o_ptr->pval && magik(p_ptr->skill_dev))
4847 				o_ptr->pval--;
4848 
4849 			/* Notice changes */
4850 			if (!(o_ptr->pval)) j++;
4851 		}
4852 	}
4853 
4854 	/* Notice changes */
4855 	if (j) {
4856 		/* Combine pack */
4857 		p_ptr->notice |= (PN_COMBINE);
4858 
4859 		/* Window stuff */
4860 		p_ptr->window |= (PW_INVEN | PW_EQUIP);
4861 	}
4862 
4863 	/* Feel the inventory */
4864 	if (!p_ptr->admin_dm) sense_inventory(Ind);
4865 
4866 	/*** Involuntary Movement ***/
4867 
4868 
4869 	/* Delayed mind link */
4870 	if (p_ptr->esp_link_end) {
4871 //msg_format(Ind, "ele: %d", p_ptr->esp_link_end);
4872 		p_ptr->esp_link_end--;
4873 
4874 		/* Activate the break */
4875 		if (!p_ptr->esp_link_end) {
4876 			player_type *p_ptr2 = NULL;
4877 			int Ind2;
4878 			if ((Ind2 = get_esp_link(Ind, 0x0, &p_ptr2))) {
4879 				if (!(p_ptr->esp_link_flags & LINKF_HIDDEN)) {
4880 					msg_format(Ind, "\377RYou break the mind link with %s.", p_ptr2->name);
4881 					msg_format(Ind2, "\377R%s breaks the mind link with you.", p_ptr->name);
4882 				}
4883 				if (p_ptr->esp_link_flags & LINKF_VIEW_DEDICATED) p_ptr->update |= PU_MUSIC;
4884 				if (p_ptr2->esp_link_flags & LINKF_VIEW_DEDICATED) p_ptr2->update |= PU_MUSIC;
4885 				p_ptr->esp_link = 0;
4886 				p_ptr->esp_link_type = 0;
4887 				p_ptr->esp_link_flags = 0;
4888 				p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
4889 				p_ptr->update |= (PU_BONUS | PU_VIEW | PU_MANA | PU_HP);
4890 				p_ptr->redraw |= (PR_BASIC | PR_EXTRA | PR_MAP);
4891 				p_ptr2->esp_link = 0;
4892 				p_ptr2->esp_link_type = 0;
4893 				p_ptr2->esp_link_flags = 0;
4894 				p_ptr2->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
4895 				p_ptr2->update |= (PU_BONUS | PU_VIEW | PU_MANA | PU_HP);
4896 				p_ptr2->redraw |= (PR_BASIC | PR_EXTRA | PR_MAP);
4897 			}
4898 		}
4899 	}
4900 
4901 	/* Don't do AFK in a store */
4902 	if (p_ptr->tim_store) {
4903 		if (p_ptr->store_num == -1) p_ptr->tim_store = 0;
4904 #ifdef ENABLE_GO_GAME
4905 		else if (go_game_up && go_engine_player_id == p_ptr->id) p_ptr->tim_store = 0;
4906 #endif
4907 		else if (!admin_p(Ind)) {
4908 			/* Count down towards turnout */
4909 			p_ptr->tim_store--;
4910 
4911 			/* Check if that town is 'crowded' */
4912 			if (p_ptr->tim_store <= 0) {
4913 				player_type *q_ptr;
4914 				bool bye = FALSE;
4915 
4916 				for (j = 1; j < NumPlayers + 1; j++) {
4917 					if (Ind == j) continue;
4918 					if (admin_p(j)) continue;
4919 					q_ptr = Players[j];
4920 					if (!inarea(&p_ptr->wpos, &q_ptr->wpos)) continue;
4921 					if (q_ptr->afk) continue;
4922 
4923 					/* new: other players must wait in line, or at least closely nearby, to kick you out */
4924 					if (ABS(q_ptr->py - p_ptr->py) >= 4 || ABS(q_ptr->px - p_ptr->px) >= 4) continue;
4925 
4926 					bye = TRUE;
4927 					break;
4928 				}
4929 
4930 				if (bye) store_kick(Ind, TRUE);
4931 				else p_ptr->tim_store = STORE_TURNOUT;
4932 			}
4933 		}
4934 	}
4935 
4936 	if (p_ptr->tim_blacklist && !p_ptr->afk) {
4937 		/* Count down towards turnout */
4938 		p_ptr->tim_blacklist--;
4939 	}
4940 
4941 #if 1 /* use turns instead of day/night cycles */
4942 	if (p_ptr->tim_watchlist) {
4943 		/* Count down towards turnout */
4944 		p_ptr->tim_watchlist--;
4945 	}
4946 #endif
4947 
4948 	if (p_ptr->pstealing) {
4949 		/* Count down towards turnout */
4950 		p_ptr->pstealing--;
4951 //		if (!p_ptr->pstealing) msg_print(Ind, "You're calm enough to steal from another player.");
4952 		if (!p_ptr->pstealing) msg_print(Ind, "You're calm enough to attempt to steal something.");
4953 	}
4954 
4955 	/* Delayed Word-of-Recall */
4956 	if (p_ptr->word_recall) {
4957 		/* Count down towards recall */
4958 		p_ptr->word_recall--;
4959 
4960 		/* MEGA HACK: no recall if icky, or in a shop */
4961 		if (!p_ptr->word_recall) {
4962 			if (((p_ptr->anti_tele ||
4963 			    (check_st_anchor(&p_ptr->wpos, p_ptr->py, p_ptr->px) && !p_ptr->admin_dm))
4964 			     && !(l_ptr && (l_ptr->flags2 & LF2_NO_TELE))) ||
4965 			    p_ptr->store_num != -1 ||
4966 			    zcave[p_ptr->py][p_ptr->px].info & CAVE_STCK)
4967 				p_ptr->word_recall = 1;
4968 			else
4969 				/* Activate the recall */
4970 				do_recall(Ind, 0);
4971 		}
4972 	}
4973 
4974 	bypass_invuln = FALSE;
4975 
4976 	/* Evileye, please tell me if it's right */
4977 	if (p_ptr->tim_wraith) {
4978 		if(zcave[p_ptr->py][p_ptr->px].info & CAVE_STCK) {
4979 			p_ptr->tim_wraith = 0;
4980 			msg_print(Ind, "You lose your wraith powers.");
4981 			msg_format_near(Ind, "%s loses %s wraith powers.", p_ptr->name, p_ptr->male ? "his":"her");
4982 		}
4983 	}
4984 
4985 	/* No wraithform on NO_MAGIC levels - C. Blue */
4986 	if (p_ptr->tim_wraith) {
4987 		if (p_ptr->wpos.wz && l_ptr && (l_ptr->flags1 & LF1_NO_MAGIC)) {
4988 			p_ptr->tim_wraith = 0;
4989 			msg_print(Ind, "You lose your wraith powers.");
4990 			msg_format_near(Ind, "%s loses %s wraith powers.", p_ptr->name, p_ptr->male ? "his":"her");
4991 		}
4992 	}
4993 
4994 	return (TRUE);
4995 }
4996 
4997 /* process any team games */
4998 static void process_games(int Ind) {
4999 	player_type *p_ptr = Players[Ind];
5000 	cave_type **zcave;
5001 	cave_type *c_ptr;
5002 	char sstr[80];
5003 	int score = 0;
5004 	if (!(zcave = getcave(&p_ptr->wpos))) return;
5005 	c_ptr = &zcave[p_ptr->py][p_ptr->px];
5006 
5007 	if (c_ptr->feat == FEAT_AGOAL || c_ptr->feat == FEAT_BGOAL) {
5008 		int ball;
5009 		switch(gametype){
5010 			/* rugby type game */
5011 			case EEGAME_RUGBY:
5012 				if ((ball = has_ball(p_ptr)) == -1) break;
5013 
5014 				if (p_ptr->team == 1 && c_ptr->feat == FEAT_BGOAL) {
5015 					teamscore[0]++;
5016 					msg_format_near(Ind, "\377R%s scored a goal!!!", p_ptr->name);
5017 					msg_print(Ind, "\377rYou scored a goal!!!");
5018 					score = 1;
5019 				}
5020 				if (p_ptr->team == 2 && c_ptr->feat == FEAT_AGOAL) {
5021 					teamscore[1]++;
5022 					msg_format_near(Ind, "\377B%s scored a goal!!!", p_ptr->name);
5023 					msg_print(Ind, "\377gYou scored a goal!!!");
5024 					score = 1;
5025 				}
5026 				if (score) {
5027 					object_type tmp_obj;
5028 					s16b ox, oy;
5029 					int try;
5030 					p_ptr->energy = 0;
5031 					snprintf(sstr, 80, "Score: \377RReds: %d  \377BBlues: %d", teamscore[0], teamscore[1]);
5032 					msg_broadcast(0, sstr);
5033 
5034 					for (try = 0; try < 1000; try++) {
5035 						ox = p_ptr->px + 5 - rand_int(10);
5036 						oy = p_ptr->py + 5 - rand_int(10);
5037 						if (!in_bounds(oy, ox)) continue;
5038 						if (!cave_floor_bold(zcave, oy, ox)) continue;
5039 						tmp_obj = p_ptr->inventory[ball];
5040 						tmp_obj.marked2 = ITEM_REMOVAL_NEVER;
5041 						drop_near(&tmp_obj, -1, &p_ptr->wpos, oy, ox);
5042 						printf("dropping at %d %d (%d)\n", ox, oy, try);
5043 						inven_item_increase(Ind, ball, -999);
5044 						inven_item_optimize(Ind, ball);
5045 						break;
5046 					}
5047 					/* Move the player from the goal area */
5048 					teleport_player_force(Ind, 20);
5049 				}
5050 				break;
5051 			/* capture the flag */
5052 			case EEGAME_CTF:
5053 				break;
5054 			default:
5055 				break; /* gcc 3.4 actually wants this - mikaelh */
5056 		}
5057 	}
5058 }
5059 
5060 /*
5061  * Player processing that occurs at the end of a turn
5062  */
5063 static void process_player_end(int Ind) {
5064 	player_type *p_ptr = Players[Ind];
5065 
5066 //	int		x, y, i, j, new_depth, new_world_x, new_world_y;
5067 //	int		regen_amount, NumPlayers_old = NumPlayers;
5068 	char		attackstatus;
5069 
5070 //	byte			*w_ptr;
5071 
5072 	/* slower 'running' movement over certain terrain */
5073 	int real_speed = cfg.running_speed;
5074 	cave_type *c_ptr, **zcave;
5075 	if(!(zcave = getcave(&p_ptr->wpos))) return;
5076 	c_ptr = &zcave[p_ptr->py][p_ptr->px];
5077 
5078 	if (Players[Ind]->conn == NOT_CONNECTED) return;
5079 
5080 	/* count turns online, afk, and idle */
5081 	p_ptr->turns_online++;
5082 	if (p_ptr->afk) p_ptr->turns_afk++;
5083 	if (p_ptr->idle) p_ptr->turns_idle++;
5084 	else if (!p_ptr->afk) p_ptr->turns_active++;
5085 
5086 	/* count how long they stay on a level (for EXTRA_LEVEL_FEELINGS) */
5087 	p_ptr->turns_on_floor++;
5088 	/* hack to indicate it to the player */
5089 	if (p_ptr->turns_on_floor == TURNS_FOR_EXTRA_FEELING) Send_depth(Ind, &p_ptr->wpos);
5090 
5091 	/* calculate effective running speed */
5092 	eff_running_speed(&real_speed, p_ptr, c_ptr);
5093 
5094 	/* Try to execute any commands on the command queue. */
5095 	process_pending_commands(p_ptr->conn);
5096 
5097 	/* Mind Fusion/Control disable the char */
5098 	if (p_ptr->esp_link && p_ptr->esp_link_type && (p_ptr->esp_link_flags & LINKF_OBJ)) return;
5099 
5100 
5101 	/* Check for fire-till-kill and auto-retaliation */
5102 	if (!p_ptr->requires_energy && /* <- new, required for allowing actions here (fire-till-kill)
5103 					  at <= 100% energy to prevent character lock-up. - C. Blue */
5104 	    !p_ptr->confused && !p_ptr->resting &&
5105 	    (!p_ptr->autooff_retaliator || /* <- these conditions seem buggy/wrong/useless? */
5106 	     !p_ptr->invuln))//&& !p_ptr->tim_manashield)))
5107 	{
5108 		/* Prepare auto-ret/fire-till-kill mode energy requirements.
5109 		   (Note: auto-ret is currently nothing special but always 1 x level_speed() as usual,
5110 		    so for auto-ret nothing changed basically. Therefore firing with auto-ret will also
5111 		    still have that small delay in the beginning, if player could fire multiple shots/round.
5112 		    This cannot be changed easily because here we don't know yet with which methid the
5113 		    player might auto-ret. - C. Blue) */
5114 		int energy = level_speed(&p_ptr->wpos);
5115 
5116 #if 0 /* don't modify energy! the correct amount of energy is deducted in the actual combat routines, and we want to have an extra amount of energy left, to break out quickly */
5117 		/* test ftk type and use according energy requirements */
5118 		if (p_ptr->shooting_till_kill) {
5119 			if (target_okay(Ind)) {
5120 				/* spells always require 1 turn: */
5121 				if (p_ptr->shoot_till_kill_spell || p_ptr->shoot_till_kill_mimic);
5122 				/* runespells excepted (for 'brief' modifier)*/
5123 				else if (p_ptr->shoot_till_kill_rcraft) energy = p_ptr->FTK_energy;
5124 				/* shooting with ranged weapon: */
5125 				else energy = energy / p_ptr->num_fire;
5126 			} else {
5127 				p_ptr->shooting_till_kill = FALSE;
5128 				/* normal auto-retaliation */
5129 				//MIGHT NOT BE A MELEE ATTACK, SO COMMENTED OUT!  else energy = energy / p_ptr->num_blow;
5130 			}
5131 		}
5132 		/* normal auto-retaliation */
5133 		//MIGHT NOT BE A MELEE ATTACK, SO COMMENTED OUT!  else energy = energy / p_ptr->num_blow;
5134 #else
5135 		/* is this line even required at all..? */
5136 		if (p_ptr->shooting_till_kill && !target_okay(Ind)) p_ptr->shooting_till_kill = FALSE;
5137 #endif
5138 
5139 		/* Check for auto-retaliate */
5140 	/* The 'old way' is actually the best way, because the initial delay of the 'new way',
5141 	when it happens, can be very irritating. The best way to fix perceived responsiveness
5142 	(of the old way) would be to not add full floor speed energy all at once, but in multiple
5143 	parts, to (ideally) immediately cover the energy loss for a single attack performed. */
5144 #if 1 /* old way - get the usual 'double initial attack' in. \
5145 	 Drawback: Have to wait for nearly a full turn (1-(1/attacksperround)) \
5146 	 for FTK/meleeret to break out for performing a different action. -- this should be fixed now. May break out in 1/attacksperround now.) */
5147 		if (p_ptr->energy >= energy) {
5148 #else /* new way - allows to instantly break out and perform another action (quaff/read) \
5149 	but doesn't give the 'double initial attack' anymore, just a normal, single attack. \
5150 	Main drawback: Walking into a mob will not smoothly transgress into auto-ret the next turn, \
5151 	but wait for an extra turn before it begins, ie taking 2 turns until first attack got in. */
5152 		if (p_ptr->energy >= energy * 2 - 1) {
5153 #endif
5154 			/* assume nothing will happen here */
5155 			p_ptr->auto_retaliating = FALSE;
5156 
5157 			if (p_ptr->shooting_till_kill) {
5158 				/* stop shooting till kill if target is no longer available,
5159 				   instead of casting a final time into thin air! */
5160 				if (target_okay(Ind)) {
5161 					p_ptr->auto_retaliating = TRUE;
5162 
5163 					if (p_ptr->shoot_till_kill_spell) {
5164 						cast_school_spell(Ind, p_ptr->shoot_till_kill_book, p_ptr->shoot_till_kill_spell - 1, 5, -1, 0);
5165 						if (!p_ptr->shooting_till_kill) p_ptr->shoot_till_kill_spell = 0;
5166 					} else if (p_ptr->shoot_till_kill_rcraft) {
5167 						(void)cast_rune_spell(Ind, 5, p_ptr->FTK_e_flags, p_ptr->FTK_m_flags, 0, 1);
5168 					} else if (p_ptr->shoot_till_kill_mimic) {
5169 						do_cmd_mimic(Ind, p_ptr->shoot_till_kill_mimic - 1 + 3, 5);
5170 					} else {
5171 						do_cmd_fire(Ind, 5);
5172 #if 1 //what was the point of this hack again?..
5173 						p_ptr->auto_retaliating = !p_ptr->auto_retaliating; /* hack, it's unset in do_cmd_fire IF it WAS successfull, ie reverse */
5174 #endif
5175 					}
5176 
5177 					//not required really	if (p_ptr->ranged_double && p_ptr->shooting_till_kill) do_cmd_fire(Ind, 5);
5178 					p_ptr->shooty_till_kill = FALSE; /* if we didn't succeed shooting till kill, then we don't intend it anymore */
5179 				} else {
5180 					p_ptr->shooting_till_kill = FALSE;
5181 				}
5182 			}
5183 
5184 			/* Parania: Don't break fire-till-kill by starting to auto-retaliate when monster enters melee range!
5185 			   (note: that behaviour was reported, but haven't reproduced it in local testing so far) */
5186 			if (!p_ptr->shooting_till_kill) {
5187 				/* Check for nearby monsters and try to kill them */
5188 				/* If auto_retaliate returns nonzero than we attacked
5189 				 * something and so should use energy.
5190 				 */
5191 				p_ptr->auto_retaliaty = TRUE; /* hack: prevent going un-AFK from auto-retaliating */
5192 				if ((!p_ptr->auto_retaliating) /* aren't we doing fire_till_kill already? */
5193 				    && (attackstatus = auto_retaliate(Ind))) /* attackstatus seems to be unused! */
5194 				{
5195 					p_ptr->auto_retaliating = TRUE;
5196 					/* Use energy */
5197 					//p_ptr->energy -= level_speed(p_ptr->dun_depth);
5198 				}
5199 				p_ptr->auto_retaliaty = FALSE;
5200 			}
5201 		} else {
5202 			p_ptr->auto_retaliating = FALSE; /* if no energy left, this is required to turn off the no-run-while-retaliate-hack */
5203 		}
5204 
5205 		/* Reset attack sfx counter in case player enabled half_sfx_attack or cut_sfx_attack. */
5206 		if (!p_ptr->shooting_till_kill && !p_ptr->auto_retaliating) {
5207 			p_ptr->count_cut_sfx_attack = 500;
5208 			p_ptr->half_sfx_attack_state = FALSE;
5209 		}
5210 	}
5211 
5212 
5213 	/* ('Handle running' from above was originally at this place) */
5214 	/* Handle running -- 5 times the speed of walking */
5215 	while (p_ptr->running && p_ptr->energy >= (level_speed(&p_ptr->wpos) * (real_speed + 1)) / real_speed) {
5216 		char consume_full_energy;
5217 		run_step(Ind, 0, &consume_full_energy);
5218 		if (consume_full_energy) {
5219 			/* Consume a full turn of energy in case we have e.g. attacked a monster */
5220 			p_ptr->energy -= level_speed(&p_ptr->wpos);
5221 		} else {
5222 			p_ptr->energy -= level_speed(&p_ptr->wpos) / real_speed;
5223 		}
5224 	}
5225 
5226 
5227 	/* Notice stuff */
5228 	if (p_ptr->notice) notice_stuff(Ind);
5229 
5230 	/* XXX XXX XXX Pack Overflow */
5231 	pack_overflow(Ind);
5232 
5233 	process_games(Ind);
5234 
5235 	/* Process things such as regeneration. */
5236 	/* This used to be processed every 10 turns, but I am changing it to be
5237 	 * processed once every 5/6 of a "dungeon turn". This will make healing
5238 	 * and poison faster with respect to real time < 1750 feet and slower >
5239 	 * 1750 feet. - C. Blue
5240 	 */
5241 	if (!(turn % (level_speed(&p_ptr->wpos) / 120))) {
5242 		if (!process_player_end_aux(Ind)) return;
5243 	}
5244 
5245 
5246 	/* HACK -- redraw stuff a lot, this should reduce perceived latency. */
5247 	/* This might not do anything, I may have been silly when I added this. -APD */
5248 	/* Notice stuff (if needed) */
5249 	if (p_ptr->notice) notice_stuff(Ind);
5250 
5251 	/* Update stuff (if needed) */
5252 	if (p_ptr->update) update_stuff(Ind);
5253 
5254 //	if(zcave[p_ptr->py][p_ptr->px].info & CAVE_STCK) p_ptr->tim_wraith = 0;
5255 
5256 	/* Redraw stuff (if needed) */
5257 	if (p_ptr->redraw) redraw_stuff(Ind);
5258 
5259 	/* Redraw stuff (if needed) */
5260 	if (p_ptr->window) window_stuff(Ind);
5261 }
5262 
5263 
5264 bool stale_level(struct worldpos *wpos, int grace) {
5265 	time_t now;
5266 
5267 	/* Hack -- towns are static for good? too spammy */
5268 //	if (istown(wpos)) return FALSE;
5269 	/* Hack -- make dungeon towns static though? too cheezy */
5270 //	if (isdungeontown(wpos)) return FALSE;
5271 
5272 	/* Hack: In IDDC, all floors are stale for 2 minutes to allow logging back in if
5273 	         someone's connection dropped without the floor going stale right away,
5274 	         and towns to allow for easy item transfers.
5275 	         Small drawback: If someone logs back on after having taken a break from IDDC
5276 	         and he finds himself in a non-accessible area, he'll have to wait for
5277 	         2 minutes instead of the usual 10 seconds till the floor regens. */
5278 	if (in_irondeepdive(wpos) && grace < 120) grace = 120;
5279 
5280 	now = time(&now);
5281 	if (wpos->wz) {
5282 		struct dungeon_type *d_ptr;
5283 		struct dun_level *l_ptr;
5284 		d_ptr = getdungeon(wpos);
5285 		if (!d_ptr) return FALSE;
5286 		l_ptr = &d_ptr->level[ABS(wpos->wz) - 1];
5287 #if DEBUG_LEVEL > 1
5288 		s_printf("%s  now:%d last:%d diff:%d grace:%d players:%d\n", wpos_format(0, wpos), now, l_ptr->lastused, now-l_ptr->lastused,grace, players_on_depth(wpos));
5289 #endif
5290 		if (now - l_ptr->lastused > grace) return TRUE;
5291 	} else if (now - wild_info[wpos->wy][wpos->wx].lastused > grace) {
5292 #if 0
5293 		/* Never allow dealloc where there are houses */
5294 		/* For now at least */
5295 		int i;
5296 
5297 		for (i = 0; i < num_houses; i++) {
5298 			if (inarea(wpos, &houses[i].wpos)) {
5299 				if (!(houses[i].flags & HF_DELETED)) return FALSE;
5300 			}
5301 		}
5302 #endif
5303 		return TRUE;
5304 	}
5305 	return FALSE;
5306 }
5307 
5308 static void do_unstat(struct worldpos *wpos, bool fast_unstat) {
5309 	int j;
5310 
5311 	/* Highlander Tournament sector00 is static while players are in dungeon! */
5312 	if (wpos->wx == WPOS_SECTOR00_X && wpos->wy == WPOS_SECTOR00_Y && wpos->wz == WPOS_SECTOR00_Z && sector00separation) return;
5313 
5314 	/* Arena Monster Challenge */
5315 	if (ge_special_sector && wpos->wx == WPOS_ARENA_X && wpos->wy == WPOS_ARENA_Y && wpos->wz == WPOS_ARENA_Z) return;
5316 
5317 	// Anyone on this depth?
5318 	for (j = 1; j <= NumPlayers; j++)
5319 		if (inarea(&Players[j]->wpos, wpos)) return;
5320 
5321 	// If this level is static and no one is actually on it
5322 //	if (stale_level(wpos)) {
5323 		/* limit static time in Ironman Deep Dive Challenge a lot */
5324 		if (in_irondeepdive(wpos)) {
5325 			if (isdungeontown(wpos)) {
5326 				if (stale_level(wpos, 300)) new_players_on_depth(wpos, 0, FALSE);
5327 			} else if ((getlevel(wpos) < cfg.min_unstatic_level) && (0 < cfg.min_unstatic_level)) {
5328 				/* still 2 minutes static for very shallow levels */
5329 				if (stale_level(wpos, 120)) new_players_on_depth(wpos, 0, FALSE);
5330 			} else if (stale_level(wpos, 600)) new_players_on_depth(wpos, 0, FALSE);
5331 		} else {
5332 #ifdef SAURON_FLOOR_FAST_UNSTAT
5333 			if (fast_unstat) j = 60 * 60; //1h
5334 			else
5335 #endif
5336 			j = cfg.level_unstatic_chance * getlevel(wpos) * 60;
5337 
5338 			/* makes levels between 50ft and min_unstatic_level unstatic on player saving/quiting game/leaving level DEG */
5339 			if (((getlevel(wpos) < cfg.min_unstatic_level) && (0 < cfg.min_unstatic_level)) ||
5340 			    stale_level(wpos, j))
5341 				new_players_on_depth(wpos, 0, FALSE);
5342 		}
5343 //	}
5344 }
5345 
5346 /*
5347  * 24 hourly scan of houses - should the odd house be owned by
5348  * a non player. Hopefully never, but best to save admin work.
5349  */
5350 static void scan_houses()
5351 {
5352 	int i;
5353 	//int lval;
5354 	s_printf("Doing house maintenance\n");
5355 	for(i = 0; i < num_houses; i++) {
5356 		if(!houses[i].dna->owner) continue;
5357 		switch(houses[i].dna->owner_type) {
5358 			case OT_PLAYER:
5359 				if(!lookup_player_name(houses[i].dna->owner)) {
5360 					s_printf("Found old player houses. ID: %d\n", houses[i].dna->owner);
5361 					kill_houses(houses[i].dna->owner, OT_PLAYER);
5362 				}
5363 				break;
5364 			case OT_PARTY:
5365 				if(!strlen(parties[houses[i].dna->owner].name)) {
5366 					s_printf("Found old party houses. ID: %d\n", houses[i].dna->owner);
5367 					kill_houses(houses[i].dna->owner, OT_PARTY);
5368 				}
5369 				break;
5370 			case OT_GUILD:
5371 				if(!strlen(guilds[houses[i].dna->owner].name)) {
5372 					s_printf("Found old guild houses. ID: %d\n", houses[i].dna->owner);
5373 					kill_houses(houses[i].dna->owner, OT_GUILD);
5374 				}
5375 				break;
5376 		}
5377 	}
5378 	s_printf("Finished house maintenance\n");
5379 }
5380 
5381 /* If the level unstaticer is not disabled, try to.
5382  * Now it's done every 60*fps, so better raise the
5383  * rate as such.	- Jir -
5384  */
5385 /*
5386  * Deallocate all non static levels. (evileye)
5387  */
5388 static void purge_old()
5389 {
5390 	int x, y, i;
5391 
5392 //	if (cfg.level_unstatic_chance > 0)
5393 	{
5394 		struct worldpos twpos;
5395 		twpos.wz = 0;
5396 		for(y = 0; y < MAX_WILD_Y; y++) {
5397 			twpos.wy = y;
5398 			for(x = 0; x < MAX_WILD_X; x++) {
5399 				struct wilderness_type *w_ptr;
5400 				struct dungeon_type *d_ptr;
5401 
5402 				twpos.wx = x;
5403 				w_ptr = &wild_info[twpos.wy][twpos.wx];
5404 
5405 				if (cfg.level_unstatic_chance > 0 &&
5406 				    players_on_depth(&twpos))
5407 					do_unstat(&twpos, FALSE);
5408 
5409 				if (!players_on_depth(&twpos) && !istown(&twpos) &&
5410 				    getcave(&twpos) && stale_level(&twpos, cfg.anti_scum))
5411 					dealloc_dungeon_level(&twpos);
5412 
5413 				if (w_ptr->flags & WILD_F_UP) {
5414 					d_ptr = w_ptr->tower;
5415 					for (i = 1; i <= d_ptr->maxdepth; i++) {
5416 						twpos.wz = i;
5417 						if (cfg.level_unstatic_chance > 0 &&
5418 						    players_on_depth(&twpos))
5419 							do_unstat(&twpos, d_ptr->type == DI_MT_DOOM && i == d_ptr->maxdepth);
5420 
5421 						if (!players_on_depth(&twpos) && getcave(&twpos) &&
5422 						    stale_level(&twpos, cfg.anti_scum))
5423 							dealloc_dungeon_level(&twpos);
5424 					}
5425 				}
5426 				if (w_ptr->flags & WILD_F_DOWN) {
5427 					d_ptr = w_ptr->dungeon;
5428 					for (i = 1; i <= d_ptr->maxdepth; i++) {
5429 						twpos.wz = -i;
5430 						if (cfg.level_unstatic_chance > 0 &&
5431 						    players_on_depth(&twpos))
5432 							do_unstat(&twpos, d_ptr->type == DI_MT_DOOM && i == d_ptr->maxdepth);
5433 
5434 						if (!players_on_depth(&twpos) && getcave(&twpos) &&
5435 						    stale_level(&twpos, cfg.anti_scum))
5436 							dealloc_dungeon_level(&twpos);
5437 					}
5438 				}
5439 				twpos.wz = 0;
5440 			}
5441 		}
5442 	}
5443 }
5444 
5445 /*
5446  * TODO: Check for OT_GUILD (or guild will be mere den of cheeze)
5447  */
5448 void cheeze(object_type *o_ptr){
5449 #if CHEEZELOG_LEVEL > 3
5450 	int j;
5451 	/* check for inside a house */
5452 	for(j = 0; j < num_houses; j++){
5453 		if(inarea(&houses[j].wpos, &o_ptr->wpos)){
5454 			if(fill_house(&houses[j], FILL_OBJECT, o_ptr)){
5455 				if(houses[j].dna->owner_type == OT_PLAYER){
5456 					if(o_ptr->owner != houses[j].dna->owner){
5457 						if(o_ptr->level > lookup_player_level(houses[j].dna->owner))
5458 							s_printf("Suspicious item: (%d,%d) Owned by %s, in %s's house. (%d,%d)\n", o_ptr->wpos.wx, o_ptr->wpos.wy, lookup_player_name(o_ptr->owner), lookup_player_name(houses[j].dna->owner), o_ptr->level, lookup_player_level(houses[j].dna->owner));
5459 					}
5460 				}
5461 				else if(houses[j].dna->owner_type == OT_PARTY){
5462 					int owner;
5463 					if((owner = lookup_player_id(parties[houses[j].dna->owner].owner))){
5464 						if(o_ptr->owner != owner){
5465 							if(o_ptr->level > lookup_player_level(owner))
5466 								s_printf("Suspicious item: (%d,%d) Owned by %s, in %s party house. (%d,%d)\n", o_ptr->wpos.wx, o_ptr->wpos.wy, lookup_player_name(o_ptr->owner), parties[houses[j].dna->owner].name, o_ptr->level, lookup_player_level(owner));
5467 						}
5468 					}
5469 				}
5470 				else if(houses[j].dna->owner_type == OT_GUILD){
5471 					int owner;
5472 					if((owner = guilds[houses[j].dna->owner].master)){
5473 						if(o_ptr->owner != owner){
5474 							if(o_ptr->level > lookup_player_level(owner))
5475 								s_printf("Suspicious item: (%d,%d) Owned by %s, in %s party house. (%d,%d)\n", o_ptr->wpos.wx, o_ptr->wpos.wy, lookup_player_name(o_ptr->owner), guilds[houses[j].dna->owner].name, o_ptr->level, lookup_player_level(owner));
5476 						}
5477 					}
5478 				}
5479 				break;
5480 			}
5481 		}
5482 	}
5483 #endif // CHEEZELOG_LEVEL > 3
5484 }
5485 
5486 
5487 /* Traditional (Vanilla) houses version of cheeze()	- Jir - */
5488 #ifndef USE_MANG_HOUSE_ONLY
5489 void cheeze_trad_house()
5490 {
5491 #if CHEEZELOG_LEVEL > 3
5492 	int i, j;
5493 	house_type *h_ptr;
5494 	object_type *o_ptr;
5495 
5496 	/* check for inside a house */
5497 	for(j = 0;j < num_houses; j++) {
5498 		h_ptr = &houses[j];
5499 		if(h_ptr->dna->owner_type == OT_PLAYER) {
5500 			for (i = 0; i < h_ptr->stock_num; i++) {
5501 				o_ptr = &h_ptr->stock[i];
5502 				if(o_ptr->owner != h_ptr->dna->owner) {
5503 					if(o_ptr->level > lookup_player_level(h_ptr->dna->owner))
5504 						s_printf("Suspicious item: (%d,%d) Owned by %s, in %s's trad house(%d). (%d,%d)\n",
5505 								o_ptr->wpos.wx, o_ptr->wpos.wy,
5506 								lookup_player_name(o_ptr->owner),
5507 								lookup_player_name(h_ptr->dna->owner),
5508 								j, o_ptr->level,
5509 								lookup_player_level(h_ptr->dna->owner));
5510 				}
5511 			}
5512 		}
5513 		else if(h_ptr->dna->owner_type == OT_PARTY) {
5514 			int owner;
5515 			if((owner = lookup_player_id(parties[h_ptr->dna->owner].owner))) {
5516 				for (i = 0; i < h_ptr->stock_num; i++) {
5517 					o_ptr = &h_ptr->stock[i];
5518 					if(o_ptr->owner != owner) {
5519 						if(o_ptr->level > lookup_player_level(owner))
5520 							s_printf("Suspicious item: (%d,%d) Owned by %s, in %s party trad house(%d). (%d,%d)\n",
5521 									o_ptr->wpos.wx, o_ptr->wpos.wy,
5522 									lookup_player_name(o_ptr->owner),
5523 									parties[h_ptr->dna->owner].name,
5524 									j, o_ptr->level, lookup_player_level(owner));
5525 					}
5526 				}
5527 			}
5528 		}
5529 		else if(h_ptr->dna->owner_type == OT_GUILD) {
5530 			int owner;
5531 			if((owner = guilds[h_ptr->dna->owner].master)) {
5532 				for (i = 0; i < h_ptr->stock_num; i++) {
5533 					o_ptr = &h_ptr->stock[i];
5534 					if(o_ptr->owner != owner) {
5535 						if(o_ptr->level > lookup_player_level(owner))
5536 							s_printf("Suspicious item: (%d,%d) Owned by %s, in %s guild trad house(%d). (%d,%d)\n",
5537 									o_ptr->wpos.wx, o_ptr->wpos.wy,
5538 									lookup_player_name(o_ptr->owner),
5539 									guilds[h_ptr->dna->owner].name,
5540 									j, o_ptr->level, lookup_player_level(owner));
5541 					}
5542 				}
5543 			}
5544 		}
5545 	}
5546 #endif // CHEEZELOG_LEVEL > 3
5547 }
5548 #endif	// USE_MANG_HOUSE_ONLY
5549 
5550 
5551 /* Change item mode of all items inside a house to the according house owner mode */
5552 void house_contents_chmod(object_type *o_ptr){
5553 #if CHEEZELOG_LEVEL > 3
5554 	int j;
5555 	/* check for inside a house */
5556 	for(j = 0; j < num_houses; j++){
5557 		if(inarea(&houses[j].wpos, &o_ptr->wpos)){
5558 			if(fill_house(&houses[j], FILL_OBJECT, o_ptr)){
5559 				if(houses[j].dna->owner_type == OT_PLAYER){
5560 					o_ptr->mode = lookup_player_mode(houses[j].dna->owner));
5561 				}
5562 				else if(houses[j].dna->owner_type == OT_PARTY){
5563 					int owner;
5564 					if((owner = lookup_player_id(parties[houses[j].dna->owner].owner))){
5565 						o_ptr->mode = lookup_player_mode(owner));
5566 					}
5567 				}
5568 				break;
5569 			}
5570 		}
5571 	}
5572 #endif // CHEEZELOG_LEVEL > 3
5573 }
5574 
5575 
5576 /* Traditional (Vanilla) houses version */
5577 #ifndef USE_MANG_HOUSE_ONLY
5578 void tradhouse_contents_chmod()
5579 {
5580 #if CHEEZELOG_LEVEL > 3
5581 	int i, j;
5582 	house_type *h_ptr;
5583 	object_type *o_ptr;
5584 
5585 	/* check for inside a house */
5586 	for(j = 0; j < num_houses; j++)
5587 	{
5588 		h_ptr = &houses[j];
5589 		if(h_ptr->dna->owner_type == OT_PLAYER)
5590 		{
5591 			for (i = 0; i < h_ptr->stock_num; i++)
5592 			{
5593 				o_ptr = &h_ptr->stock[i];
5594 				o_ptr->mode = lookup_player_mode(houses[j].dna->owner));
5595 			}
5596 		}
5597 		else if(h_ptr->dna->owner_type == OT_PARTY)
5598 		{
5599 			int owner;
5600 			if((owner = lookup_player_id(parties[h_ptr->dna->owner].owner)))
5601 			{
5602 				for (i = 0; i < h_ptr->stock_num; i++)
5603 				{
5604 					o_ptr = &h_ptr->stock[i];
5605 					o_ptr->mode = lookup_player_mode(owner));
5606 				}
5607 			}
5608 		}
5609 	}
5610 #endif // CHEEZELOG_LEVEL > 3
5611 }
5612 #endif	// USE_MANG_HOUSE_ONLY
5613 
5614 
5615 
5616 /*
5617  * The purpose of this function is to scan through all the
5618  * game objects on the surface of the world. Objects which
5619  * are not owned will be ignored. Owned items will be checked.
5620  * If they are in a house, they will be compared against the
5621  * house owner. If this fails, the level difference will be
5622  * used to calculate some chance for the object's deletion.
5623  *
5624  * In the case for non house objects, essentially a TTL is
5625  * set. This protects them from instant loss, should a player
5626  * drop something just at the wrong time, but it should get
5627  * rid of some town junk. Artifacts should probably resist
5628  * this clearing.
5629  */
5630 /*
5631  * TODO:
5632  * - this function should handle items in 'traditional' houses too
5633  * - maybe rename this function (scan_objects and scan_objs...)
5634  */
5635 static void scan_objs() {
5636 	int i, cnt = 0, dcnt = 0;
5637 	bool sj;
5638 	object_type *o_ptr;
5639 	cave_type **zcave;
5640 
5641 	/* objects time-outing disabled? */
5642 	if (!cfg.surface_item_removal && !cfg.dungeon_item_removal) return;
5643 
5644 	for (i = 0; i < o_max; i++) {
5645 		o_ptr = &o_list[i];
5646 		if (!o_ptr->k_idx) continue;
5647 
5648 		sj = FALSE;
5649 		/* not dropped on player death or generated on the floor? (or special stuff) */
5650 		if (o_ptr->marked2 == ITEM_REMOVAL_NEVER ||
5651 		    o_ptr->marked2 == ITEM_REMOVAL_HOUSE)
5652 			continue;
5653 
5654 		/* hack for monster trap items */
5655 		/* XXX noisy warning, eh? */ /* This is unsatisfactory. */
5656 		if (!in_bounds_array(o_ptr->iy, o_ptr->ix) &&
5657 		    /* There was an old woman who swallowed a fly... */
5658 		    in_bounds_array(255 - o_ptr->iy, o_ptr->ix)) {
5659 			sj = TRUE;
5660 			o_ptr->iy = 255 - o_ptr->iy;
5661 		}
5662 
5663 		/* Make town Inns a safe place to store (read: cheeze) items,
5664 		   at least as long as the town level is allocated. - C. Blue */
5665 		if ((zcave = getcave(&o_ptr->wpos))
5666 		    && in_bounds_array(o_ptr->iy, o_ptr->ix) //paranoia or monster trap? or tradhouse?
5667 		    && (f_info[zcave[o_ptr->iy][o_ptr->ix].feat].flags1 & FF1_PROTECTED))
5668 			continue;
5669 
5670 		/* check items on the world's surface */
5671 		if (!o_ptr->wpos.wz && cfg.surface_item_removal) {
5672 			if (in_bounds_array(o_ptr->iy, o_ptr->ix)) { //paranoia or monster trap? or tradhouse?
5673 				/* Artifacts and objects that were inscribed and dropped by
5674 				the dungeon master or by unique monsters on their death
5675 				stay n times as long as cfg.surface_item_removal specifies */
5676 				if (o_ptr->marked2 == ITEM_REMOVAL_QUICK) {
5677 					if (++o_ptr->marked >= 10) {
5678 						/* handle monster trap, if this item was part of one */
5679 						if (sj) {
5680 							erase_mon_trap(&o_ptr->wpos, o_ptr->iy, o_ptr->ix);
5681 							sj = FALSE;
5682 						} else
5683 
5684 						/* normal object */
5685 						delete_object_idx(i, TRUE);
5686 
5687 						dcnt++;
5688 					}
5689 				} else if (o_ptr->marked2 == ITEM_REMOVAL_MONTRAP) {
5690 					if (++o_ptr->marked >= 120) {
5691 						/* handle monster trap, if this item was part of one */
5692 						if (sj) {
5693 							erase_mon_trap(&o_ptr->wpos, o_ptr->iy, o_ptr->ix);
5694 							sj = FALSE;
5695 						} else
5696 
5697 						/* normal object */
5698 						delete_object_idx(i, TRUE);
5699 
5700 						dcnt++;
5701 					}
5702 				} else if (++o_ptr->marked >= ((like_artifact_p(o_ptr) || /* stormy too */
5703 				    (o_ptr->note && !o_ptr->owner))?
5704 				    cfg.surface_item_removal * 3 : cfg.surface_item_removal)
5705 				    + (o_ptr->marked2 == ITEM_REMOVAL_DEATH_WILD ? cfg.death_wild_item_removal : 0)
5706 				    + (o_ptr->marked2 == ITEM_REMOVAL_LONG_WILD ? cfg.long_wild_item_removal : 0)
5707 				    ) {
5708 					/* handle monster trap, if this item was part of one */
5709 					if (sj) {
5710 						erase_mon_trap(&o_ptr->wpos, o_ptr->iy, o_ptr->ix);
5711 						sj = FALSE;
5712 					} else
5713 
5714 					/* normal object */
5715 					delete_object_idx(i, TRUE);
5716 
5717 					dcnt++;
5718 				}
5719 			}
5720 
5721 			/* Also perform a 'cheeze check' */
5722  #if CHEEZELOG_LEVEL > 1
5723 			else
5724   #if CHEEZELOG_LEVEL < 4
5725 			/* ..only once an hour. (logs would fill the hd otherwise ;( */
5726 			if (!(turn % (cfg.fps * 3600)))
5727   #endif	/* CHEEZELOG_LEVEL (4) */
5728 				cheeze(o_ptr);
5729  #endif	/* CHEEZELOG_LEVEL (1) */
5730 
5731 			/* count amount of items that were checked */
5732 			cnt++;
5733 		}
5734 
5735 		/* check items on dungeon/tower floors */
5736 		else if (o_ptr->wpos.wz && cfg.dungeon_item_removal) {
5737 			if (in_bounds_array(o_ptr->iy, o_ptr->ix)) { //paranoia or monster trap? or tradhouse?
5738 				/* Artifacts and objects that were inscribed and dropped by
5739 				the dungeon master or by unique monsters on their death
5740 				stay n times as long as cfg.surface_item_removal specifies */
5741 				if (++o_ptr->marked >= ((artifact_p(o_ptr) ||
5742 				    (o_ptr->note && !o_ptr->owner)) ?
5743 				    cfg.dungeon_item_removal * 3 : cfg.dungeon_item_removal)) {
5744 					/* handle monster trap, if this item was part of one */
5745 					if (sj) {
5746 						erase_mon_trap(&o_ptr->wpos, o_ptr->iy, o_ptr->ix);
5747 						sj = FALSE;
5748 					} else
5749 
5750 					/* normal object */
5751 					delete_object_idx(i, TRUE);
5752 
5753 					dcnt++;
5754 				}
5755 			}
5756 
5757 			/* Also perform a 'cheeze check' */
5758  #if CHEEZELOG_LEVEL > 1
5759 			else
5760   #if CHEEZELOG_LEVEL < 4
5761 			/* ..only once an hour. (logs would fill the hd otherwise ;( */
5762 			if (!(turn % (cfg.fps * 3600)))
5763   #endif	/* CHEEZELOG_LEVEL (4) */
5764 				cheeze(o_ptr);
5765  #endif	/* CHEEZELOG_LEVEL (1) */
5766 
5767 			/* count amount of items that were checked */
5768 			cnt++;
5769 		}
5770 
5771 		/* restore monster trap hack */
5772 		if (sj) o_ptr->iy = 255 - o_ptr->iy; /* mega-hack: never inbounds */
5773 	}
5774 
5775 	/* log result */
5776 	if (dcnt) s_printf("Scanned %d objects. Removed %d.\n", cnt, dcnt);
5777 
5778 #ifndef USE_MANG_HOUSE_ONLY
5779 	/* Additional cheeze check for all those items inside of mangband-style houses */
5780 #if CHEEZELOG_LEVEL > 1
5781 #if CHEEZELOG_LEVEL < 4
5782 	if (!(turn % (cfg.fps * 3600)))
5783 #endif	/* CHEEZELOG_LEVEL (4) */
5784 		cheeze_trad_house();
5785 #endif	/* CHEEZELOG_LEVEL (1) */
5786 #endif	/* USE_MANG_HOUSE_ONLY */
5787 
5788 }
5789 
5790 
5791 /* NOTE: this can cause short freeze if many stores exist,
5792  * so it isn't called from process_various any more.
5793  * the store changes their stocks when a player enters a store.
5794  *
5795  * (However, this function can be called by admin characters)
5796  */
5797 void store_turnover()
5798 {
5799 	int i, n;
5800 
5801 	for(i = 0; i < numtowns; i++) {
5802 		/* Maintain each shop (except home and auction house) */
5803 //		for (n = 0; n < MAX_BASE_STORES - 2; n++)
5804 		for (n = 0; n < max_st_idx; n++) {
5805 			/* Maintain */
5806 			store_maint(&town[i].townstore[n]);
5807 		}
5808 
5809 		/* Sometimes, shuffle the shopkeepers */
5810 		if (rand_int(STORE_SHUFFLE) == 0) {
5811 			/* Shuffle a random shop (except home and auction house) */
5812 //			store_shuffle(&town[i].townstore[rand_int(MAX_BASE_STORES - 2)]);
5813 			store_shuffle(&town[i].townstore[rand_int(max_st_idx)]);
5814 		}
5815 	}
5816 }
5817 
5818 /*
5819  * This function handles "global" things such as the stores,
5820  * day/night in the town, etc.
5821  */
5822 /* Added the japanese unique respawn patch -APD-
5823    It appears that each moment of time is equal to 10 minutes?
5824 */
5825 /* called only every 10 turns
5826 */
5827 /* WARNING: Every if-check in here that tests for turns % cfg.fps
5828    should instead check for turns % cfg.fps*10, because this function
5829    is only called every 10 turns as stated above, otherwise
5830    depending on cfg.fps it might be skipped sometimes, which may or
5831    may not be critical depending on what it does! - C. Blue */
5832 static void process_various(void)
5833 {
5834 	int i, j;
5835 	int h = 0, m = 0, s = 0, dwd = 0, dd = 0, dm = 0, dy = 0;
5836 #ifndef ARCADE_SERVER
5837 	time_t now;
5838 	struct tm *tmp;
5839 #endif
5840 	//cave_type *c_ptr;
5841 	player_type *p_ptr;
5842 
5843 	//char buf[1024];
5844 
5845 	/* this TomeCron stuff could be merged at some point
5846 	   to improve efficiency. ;) */
5847 
5848 	if (!(turn % 2)) {
5849 		do_xfers();	/* handle filetransfers per second
5850 				 * FOR NOW!!! DO NOT TOUCH/CHANGE!!!
5851 				 */
5852 	}
5853 
5854 	/* Save the server state occasionally */
5855 	if (!(turn % ((NumPlayers ? 10L : 1000L) * SERVER_SAVE))) {
5856 		save_server_info();
5857 
5858 		/* Save each player */
5859 		for (i = 1; i <= NumPlayers; i++) {
5860 			/* Save this player */
5861 			save_player(i);
5862 		}
5863 	}
5864 
5865 #if 0 /* might skip an hour if transition is unprecise, ie 1:59 -> 3:00 */
5866 	/* Extra LUA function in custom.lua */
5867 	time(&now);
5868 	tmp = localtime(&now);
5869 	h = tmp->tm_hour;
5870 	m = tmp->tm_min;
5871 	s = tmp->tm_sec;
5872 
5873 	if (!(turn % (cfg.fps * 3600)))
5874 		exec_lua(0, format("cron_1h(\"%s\", %d, %d, %d)", showtime(), h, m, s));
5875 #else
5876  #ifndef ARCADE_SERVER
5877 	if (!(turn % (cfg.fps * 10))) { /* call every 10 seconds instead of every 10 turns, to save some CPU time (yeah well...)*/
5878 		/* Extra LUA function in custom.lua */
5879 		time(&now);
5880 		tmp = localtime(&now);
5881 		h = tmp->tm_hour;
5882 		m = tmp->tm_min;
5883 		s = tmp->tm_sec;
5884 		if (h != cron_1h_last_hour) {
5885 			exec_lua(0, format("cron_1h(\"%s\", %d, %d, %d)", showtime(), h, m, s));
5886 			cron_1h_last_hour = h;
5887 		}
5888 	}
5889  #endif
5890 #endif
5891 
5892 	/* daily maintenance */
5893 	if (!(turn % (cfg.fps * 86400))) {
5894 		s_printf("24 hours maintenance cycle\n");
5895 		scan_players();
5896 		scan_accounts();
5897 		scan_houses();
5898 #ifdef IRONDEEPDIVE_MIXED_TYPES
5899 		(void)scan_iddc();
5900 #endif
5901 		if (cfg.auto_purge) {
5902 			s_printf("previous server status: m_max(%d) o_max(%d)\n",
5903 					m_max, o_max);
5904 			compact_monsters(0, TRUE);
5905 			compact_objects(0, TRUE);
5906 //			compact_traps(0, TRUE);
5907 			s_printf("current server status:  m_max(%d) o_max(%d)\n",
5908 					m_max, o_max);
5909 		}
5910 #if DEBUG_LEVEL > 1
5911 		else s_printf("Current server status:  m_max(%d) o_max(%d)\n",
5912 				m_max, o_max);
5913 #endif
5914 		s_printf("Finished maintenance\n");
5915 		get_date(&dwd, &dd, &dm, &dy);
5916 		exec_lua(0, format("cron_24h(\"%s\", %d, %d, %d, %d, %d, %d, %d)", showtime(), h, m, s, dwd, dd, dm, dy));
5917 
5918 /*		bbs_add_line("--- new day line ---"); */
5919 	}
5920 
5921 	/* every 10 seconds */
5922 	if (!(turn % (cfg.fps * 10))) purge_old();
5923 
5924 #if 0 /* disable for now - mikaelh */
5925 	if (!(turn % (cfg.fps * 50))) {
5926 		/* Tell the scripts that we're alive */
5927 		update_check_file();
5928 	}
5929 #endif
5930 
5931 
5932 	/* Things handled once per hour */
5933 	if (!(turn % (cfg.fps * 3600))) {
5934 		/* Purge leaderless guilds after a while */
5935 		for (i = 0; i < MAX_GUILDS; i++) {
5936 			if (!guilds[i].members) continue;
5937 			if (!lookup_player_name(guilds[i].master) &&
5938 			    guilds[i].timeout++ >= 24 * 7)
5939 				guild_timeout(i);
5940 		}
5941 	}
5942 
5943 
5944 	/* Handle certain things once a minute */
5945 	if (!(turn % (cfg.fps * 60))) {
5946 		monster_race *r_ptr;
5947 
5948 		check_xorders();	/* check for expiry of extermination orders */
5949 		check_banlist();	/* unban some players */
5950 		scan_objs();		/* scan objects and houses */
5951 
5952 		if (dungeon_store_timer) dungeon_store_timer--; /* Timeout */
5953 		if (dungeon_store2_timer) dungeon_store2_timer--; /* Timeout */
5954 
5955 		if (great_pumpkin_timer > 0) great_pumpkin_timer--; /* HALLOWEEN */
5956 		if (great_pumpkin_duration > 0) {
5957 			great_pumpkin_duration--;
5958 			if (!great_pumpkin_duration) {
5959 				monster_type *m_ptr;
5960 				int k, m_idx;
5961 
5962 				for (k = m_top - 1; k >= 0; k--) {
5963 					/* Access the index */
5964 					m_idx = m_fast[k];
5965 					/* Access the monster */
5966 					m_ptr = &m_list[m_idx];
5967 					/* Excise "dead" monsters */
5968 					if (!m_ptr->r_idx) {
5969 					        /* Excise the monster */
5970 						m_fast[k] = m_fast[--m_top];
5971 					        /* Skip */
5972 					        continue;
5973 					}
5974 					/* Players of too high level cannot participate in killing attemps (anti-cheeze) */
5975 					/* search for Great Pumpkins */
5976 					if (m_ptr->r_idx == RI_PUMPKIN1 || m_ptr->r_idx == RI_PUMPKIN2 || m_ptr->r_idx == RI_PUMPKIN3) {
5977 						msg_print_near_monster(m_idx, "\377oThe Great Pumpkin wails and suddenly vanishes into thin air!");
5978 						s_printf("HALLOWEEN: The Great Pumpkin despawned.\n");
5979 						delete_monster_idx(k, TRUE);
5980 						//note_spot_depth(&p_ptr->wpos, y, x);
5981 						great_pumpkin_timer = rand_int(2); /* fast respawn if not killed! */
5982 					}
5983 				}
5984 			}
5985 			else if (great_pumpkin_duration <= 5) {
5986 				monster_type *m_ptr;
5987 				int k, m_idx;
5988 
5989 				for (k = m_top - 1; k >= 0; k--) {
5990 					/* Access the index */
5991 					m_idx = m_fast[k];
5992 					/* Access the monster */
5993 					m_ptr = &m_list[m_idx];
5994 					/* Excise "dead" monsters */
5995 					if (!m_ptr->r_idx) {
5996 					        /* Excise the monster */
5997 						m_fast[k] = m_fast[--m_top];
5998 					        /* Skip */
5999 					        continue;
6000 					}
6001 					/* Players of too high level cannot participate in killing attemps (anti-cheeze) */
6002 					/* search for Great Pumpkins */
6003 					if (m_ptr->r_idx == RI_PUMPKIN1 || m_ptr->r_idx == RI_PUMPKIN2 || m_ptr->r_idx == RI_PUMPKIN3) {
6004 						msg_print_near_monster(m_idx, "\377oThe Great Pumpkin wails and seems to fade..");
6005 						break;
6006 					}
6007 				}
6008 			}
6009 		}
6010 
6011 		if (season_xmas) { /* XMAS */
6012 			if (santa_claus_timer > 0) santa_claus_timer--;
6013 			if (santa_claus_timer == 0) {
6014 				struct worldpos wpos = {cfg.town_x, cfg.town_y, 0};
6015 				cave_type **zcave = getcave(&wpos);
6016 				if (zcave) { /* anyone in town? */
6017 					int x, y, tries = 50;
6018 
6019 					/* Try nine locations */
6020 					while (--tries) {
6021 						/* Pick location nearby hard-coded town centre */
6022 						scatter(&wpos, &y, &x, 34, 96, 10, 0);
6023 
6024 						/* Require "empty" floor grids */
6025 						if (!cave_empty_bold(zcave, y, x)) continue;
6026 
6027 						if (place_monster_aux(&wpos, y, x, RI_SANTA2, FALSE, FALSE, 0, 0) == 0) {
6028 							s_printf("%s XMAS: Generated Santa Claus.\n", showtime());
6029 							santa_claus_timer = -1; /* put generation on hold */
6030 							break;
6031 						}
6032 					}
6033 					if (!tries) santa_claus_timer = 1; /* fast respawn, probably paranoia */
6034 				}
6035 			}
6036 		}
6037 
6038 		for (i = 1; i <= NumPlayers; i++) {
6039 			p_ptr = Players[i];
6040 
6041 			/* Update the player retirement timers */
6042 			// If our retirement timer is set
6043 			if (p_ptr->retire_timer > 0) {
6044 				int k = p_ptr->retire_timer;
6045 
6046 				// Decrement our retire timer
6047 				j = k - 1;
6048 
6049 				// Alert him
6050 				if (j <= 60) {
6051 					msg_format(i, "\377rYou have %d minute%s of tenure left.", j, j > 1 ? "s" : "");
6052 				}
6053 				else if (j <= 1440 && !(k % 60)) {
6054 					msg_format(i, "\377yYou have %d hours of tenure left.", j / 60);
6055 				}
6056 				else if (!(k % 1440)) {
6057 					msg_format(i, "\377GYou have %d days of tenure left.", j / 1440);
6058 				}
6059 
6060 
6061 				// If the timer runs out, forcibly retire
6062 				// this character.
6063 				if (!j) do_cmd_suicide(i);
6064 			}
6065 
6066 			/* reduce warning_rest cooldown */
6067 			if (p_ptr->warning_rest_cooldown) p_ptr->warning_rest_cooldown--;
6068 		}
6069 
6070 		/* Reswpan for kings' joy  -Jir- */
6071 		/* Update the unique respawn timers */
6072 		/* I moved this out of the loop above so this may need some
6073                  * tuning now - mikaelh */
6074 		for (j = 1; j <= NumPlayers; j++) {
6075 			p_ptr = Players[j];
6076 			if (!p_ptr->total_winner) continue;
6077 			if (istownarea(&p_ptr->wpos, MAX_TOWNAREA)) continue; /* allow kings idling instead of having to switch chars */
6078 
6079 			/* Hack -- never Maggot and his dogs :) */
6080 			i = rand_range(60, MAX_R_IDX - 2);
6081 			r_ptr = &r_info[i];
6082 
6083 			/* Make sure we are looking at a dead unique */
6084 			if (!(r_ptr->flags1 & RF1_UNIQUE)) {
6085 				j--;
6086 				continue;
6087 			}
6088 
6089 			if (p_ptr->r_killed[i] != 1) continue;
6090 
6091 			/* Hack -- Sauron and Morgoth are exceptions (and all > Morgy-uniques)
6092 			   --- QUESTOR is currently NOT used!! - C. Blue */
6093 			if (r_ptr->flags1 & RF1_QUESTOR) continue;
6094 			/* ..hardcoding them instead: */
6095 			if (r_ptr->level >= 98) continue; /* Not Michael either */
6096 
6097 			if (r_ptr->flags7 & RF7_NAZGUL) continue; /* No nazguls */
6098 
6099 			/* Dungeon bosses probably shouldn't respawn */
6100 			if (r_ptr->flags0 & RF0_FINAL_GUARDIAN) continue;
6101 
6102 			/* Special-dropping uniques too! */
6103 			/* if (r_ptr->flags1 & RF1_DROP_CHOSEN) continue; */
6104 
6105 			//				if (r_ptr->max_num > 0) continue;
6106 			if (rand_int(cfg.unique_respawn_time * (r_ptr->level + 1)) > 9)
6107 				continue;
6108 
6109 			/* "Ressurect" the unique */
6110 			p_ptr->r_killed[i] = 0;
6111 			Send_unique_monster(j, i);
6112 
6113 			/* Tell the player */
6114 			/* the_sandman: added colour */
6115 			msg_format(j,"\377v%s rises from the dead!",(r_name + r_ptr->name));
6116 		}
6117 
6118 		/* discard reserved character names that exceed their timeout */
6119 		for (i = 0; i < MAX_RESERVED_NAMES; i++) {
6120 			if (!reserved_name_character[i][0]) break;
6121 			if (reserved_name_timeout[i]) {
6122 				reserved_name_timeout[i]--;
6123 				continue;
6124 			}
6125 			for (j = i + 1; j < MAX_RESERVED_NAMES; j++) {
6126 				if (!reserved_name_character[j][0]) {
6127 					reserved_name_character[j - 1][0] = '\0';
6128 					break;
6129 				}
6130 				strcpy(reserved_name_character[j - 1], reserved_name_character[j]);
6131 				strcpy(reserved_name_account[j - 1], reserved_name_account[j]);
6132 				reserved_name_timeout[j - 1] = reserved_name_timeout[j];
6133 			}
6134 			break;
6135 		}
6136 	}
6137 
6138 #if 0
6139 	/* Grow trees very occasionally */
6140 	if (!(turn % (10L * GROW_TREE))) {
6141 		/* Find a suitable location */
6142 		for (i = 1; i < 1000; i++) {
6143 			cave_type *c_ptr;
6144 
6145 			/* Pick a location */
6146 			y = rand_range(1, MAX_HGT - 1);
6147 			x = rand_range(1, MAX_WID - 1);
6148 
6149 			/* Acquire pointer */
6150  #ifdef NEW_DUNGEON
6151 			c_ptr = &zcave[0][y][x];
6152  #else
6153 			c_ptr = &cave[0][y][x];
6154  #endif
6155 
6156 			/* Only allow "dirt" */
6157 			if (c_ptr->feat != FEAT_DIRT) continue;
6158 
6159 			/* Never grow on top of objects or monsters */
6160 			if (c_ptr->m_idx) continue;
6161 			if (c_ptr->o_idx) continue;
6162 
6163 			/* Grow a tree here */
6164 			c_ptr->feat = get_seasonal_tree();
6165 
6166 			/* Show it */
6167 			everyone_lite_spot(0, y, x);
6168 
6169 			/* Done */
6170 			break;
6171 		}
6172 	}
6173 #endif /* if 0 */
6174 }
6175 
6176 int find_player(s32b id)
6177 {
6178 	int i;
6179 
6180 	for (i = 1; i < NumPlayers + 1; i++) {
6181 		player_type *p_ptr = Players[i];
6182 		if (Players[i]->conn == NOT_CONNECTED) return 0;
6183 		if (p_ptr->id == id) return i;
6184 	}
6185 
6186 	/* assume none */
6187 	return 0;
6188 }
6189 
6190 int find_player_name(char *name)
6191 {
6192 	int i;
6193 
6194 	for (i = 1; i < NumPlayers + 1; i++) {
6195 		player_type *p_ptr = Players[i];
6196 
6197 		if (!strcmp(p_ptr->name, name)) return i;
6198 	}
6199 
6200 	/* assume none */
6201 	return 0;
6202 }
6203 
6204 void process_player_change_wpos(int Ind) {
6205 	player_type *p_ptr = Players[Ind];
6206 	worldpos *wpos = &p_ptr->wpos;
6207 	cave_type **zcave;
6208 	//worldpos twpos;
6209 	dun_level *l_ptr;
6210 	int d, j, x, y, startx = 0, starty = 0, m_idx, my, mx, tries, emergency_x, emergency_y, dlv = getlevel(wpos);
6211 	char o_name_short[ONAME_LEN];
6212 	bool smooth_ambient = FALSE, travel_ambient = FALSE;
6213 
6214 	/* IDDC specialties */
6215 	if (in_irondeepdive(&p_ptr->wpos_old)) {
6216 		/* for obtaining statistical IDDC information: */
6217 		if (!is_admin(p_ptr)) {
6218 			s_printf("CVRG-IDDC: '%s' leaves floor %d:\n", p_ptr->name, p_ptr->wpos_old.wz);
6219 			log_floor_coverage(getfloor(&p_ptr->wpos_old), &p_ptr->wpos_old);
6220 		}
6221 
6222 #ifdef IDDC_EASY_SPEED_RINGS
6223  #if IDDC_EASY_SPEED_RINGS > 0
6224 		/* IDDC_EASY_SPEED_RINGS - allow easy speed-ring finding for the first 1-2 rings,
6225 		   from floor 60+ and optionally another one from floor 80+? */
6226 		if (wpos->wz == 60
6227   #if IDDC_EASY_SPEED_RINGS > 1
6228 		    || wpos->wz == 80
6229   #endif
6230 		    ) p_ptr->IDDC_flags++;//hack: abuse 2 flag bits as a counter
6231  #endif
6232 #endif
6233 	}
6234 
6235 	/* Decide whether we stayed long enough on the previous
6236 	   floor to get distinct floor feelings here, and also
6237 	   start counting turns we spend on this floor. */
6238 	//there's no scumming in RPG_SERVER!
6239 #ifdef RPG_SERVER
6240 	p_ptr->distinct_floor_feeling = TRUE;
6241 #else
6242 	if (p_ptr->turns_on_floor >= TURNS_FOR_EXTRA_FEELING)
6243 		p_ptr->distinct_floor_feeling = TRUE;
6244 	else
6245 		p_ptr->distinct_floor_feeling = FALSE;
6246 #endif
6247 	if (p_ptr->new_level_method != LEVEL_OUTSIDE &&
6248 	    p_ptr->new_level_method != LEVEL_OUTSIDE_RAND &&
6249 	    p_ptr->new_level_method != LEVEL_HOUSE)
6250 		p_ptr->turns_on_floor = 0;
6251 
6252 #ifdef ENABLE_MAIA
6253 	/* reset void gate coordinates */
6254 	if (p_ptr->voidx) {
6255 		if (getcave(&p_ptr->wpos_old))
6256 			cave_set_feat(&p_ptr->wpos_old, p_ptr->voidy, p_ptr->voidx, twall_erosion(&p_ptr->wpos_old, p_ptr->voidy, p_ptr->voidx));
6257 		p_ptr->voidx = 0;
6258 		p_ptr->voidy = 0;
6259 	}
6260 #endif
6261 
6262 	/* being on different floors destabilizes mind fusion */
6263 	if (p_ptr->esp_link_type && p_ptr->esp_link)
6264 		change_mind(Ind, FALSE);
6265 
6266 	/* Check "maximum depth" to make sure it's still correct */
6267 	if (wpos->wz != 0 && (!p_ptr->ghost || p_ptr->admin_dm)) {
6268 		if (dlv > p_ptr->max_dlv) p_ptr->max_dlv = dlv;
6269 
6270 #ifdef SEPARATE_RECALL_DEPTHS
6271 		j = recall_depth_idx(wpos, p_ptr);
6272 		if (ABS(wpos->wz) > p_ptr->max_depth[j]) p_ptr->max_depth[j] = ABS(wpos->wz);
6273 #endif
6274 	}
6275 
6276 	/* Make sure the server doesn't think the player is in a store */
6277 	if (p_ptr->store_num != -1) {
6278 		handle_store_leave(Ind);
6279 		Send_store_kick(Ind);
6280 	}
6281 
6282 	/* Hack -- artifacts leave the queen/king */
6283 	/* also checks the artifact list */
6284 	if ((cfg.fallenkings_etiquette || cfg.kings_etiquette) && !is_admin(p_ptr) && cfg.strict_etiquette) {
6285 		object_type *o_ptr;
6286 		char o_name[ONAME_LEN];
6287 		bool no_etiquette =
6288 		    (!(cfg.fallenkings_etiquette && p_ptr->once_winner && !p_ptr->total_winner) &&
6289 		    !(cfg.kings_etiquette && p_ptr->total_winner));
6290 
6291 
6292 		for (j = 0; j < INVEN_TOTAL; j++) {
6293 			o_ptr = &p_ptr->inventory[j];
6294 			if (!o_ptr->k_idx || !true_artifact_p(o_ptr)) continue;
6295 
6296 			/* fix the list */
6297 			handle_art_inumpara(o_ptr->name1);
6298 			if (!a_info[o_ptr->name1].known && (o_ptr->ident & ID_KNOWN))
6299 				a_info[o_ptr->name1].known = TRUE;
6300 
6301 			if (no_etiquette ||
6302 			    winner_artifact_p(o_ptr) || admin_artifact_p(o_ptr)) continue;
6303 
6304 			/* Describe the object */
6305 			object_desc(Ind, o_name, o_ptr, TRUE, 0);
6306 			object_desc(0, o_name_short, o_ptr, TRUE, 256);
6307 
6308 			/* Message */
6309 			msg_format(Ind, "\377y%s bids farewell to you...", o_name);
6310 			handle_art_d(o_ptr->name1);
6311 
6312 			/* Eliminate the item  */
6313 			inven_item_increase(Ind, j, -99);
6314 			inven_item_describe(Ind, j);
6315 			inven_item_optimize(Ind, j);
6316 
6317 			/* Tell everyone */
6318 			msg_broadcast_format(Ind, "\374\377M* \377U%s has been lost once more. \377M*", o_name_short);
6319 
6320 			j--;
6321 		}
6322 	}
6323 
6324 	/* Reset bot hunting variables */
6325 	p_ptr->silly_door_exp = 0;
6326 
6327 	/* For Ironman Deep Dive Challenge */
6328 	p_ptr->IDDC_logscum = 0; /* we changed floor, all fine and dandy.. */
6329 
6330 	/* Somebody has entered an ungenerated level */
6331 	if (players_on_depth(wpos) && !getcave(wpos)) {
6332 		/* Allocate space for it */
6333 		alloc_dungeon_level(wpos);
6334 
6335 		/* Generate a dungeon level there */
6336 		generate_cave(wpos, p_ptr);
6337 
6338 #if 0 /* arena monster challenge - paranoia (should be generated in xtra1.c, and permanently static really) */
6339 //copy/pasted code, non-functional as is, just put it here for later maybe
6340 		new_players_on_depth(&wpos, 1, TRUE); /* make it static */
6341 	        s_printf("EVENT_LAYOUT: Generating arena_tt at %d,%d,%d\n", wpos.wx, wpos.wy, wpos.wz);
6342 	        process_dungeon_file("t_arena_tt.txt", &wpos, &ystart, &xstart, MAX_HGT, MAX_WID, TRUE);
6343 #endif
6344 
6345 		/* allow non-normal (interval-timed) ambient sfx, but depend on our own fast-travel-induced rythm */
6346 		travel_ambient = TRUE;
6347 	} else if (players_on_depth(wpos) == 1) travel_ambient = TRUE; /* exception - if we're the only one here we won't mess up someone else's ambient sfx rythm, so it's ok */
6348 
6349 #ifdef USE_SOUND_2010
6350 	if (travel_ambient) {
6351 		/* hack for single ambient sfx while speed-travelling the wild.
6352 		   (Random info: Travelling a sector horizontally at +4 spd takes ~20s if no obstacles.) */
6353 		if (!wpos->wz && !p_ptr->wpos_old.wz) {
6354 			wilderness_type *w_ptr = &wild_info[wpos->wy][wpos->wx];
6355  #if 0 /* require to travel lots of the same type of terrain to play hacked-rythem ambient sfx? */
6356 			if (w_ptr->type != w_ptr->type)
6357 				p_ptr->ambient_sfx_timer = 0;
6358 			else
6359  #endif
6360 			if (p_ptr->ambient_sfx_timer >= w_ptr->ambient_sfx_timer && !w_ptr->ambient_sfx_dummy) {
6361 				p_ptr->ambient_sfx_timer = 0;
6362 				w_ptr->ambient_sfx_timer = 0;
6363 			}
6364 		} else p_ptr->ambient_sfx_timer = 0;
6365 	}
6366 #endif
6367 
6368 	zcave = getcave(wpos);
6369 	l_ptr = getfloor(wpos);
6370 
6371 	/* Clear the "marked" and "lit" flags for each cave grid */
6372 	for (y = 0; y < MAX_HGT; y++) {
6373 		for (x = 0; x < MAX_WID; x++) {
6374 			p_ptr->cave_flag[y][x] = 0;
6375 		}
6376 	}
6377 	/* Player now starts mapping this dungeon (as far as its flags allow) */
6378 	if (l_ptr) p_ptr->dlev_id = l_ptr->id;
6379 	else p_ptr->dlev_id = 0;
6380 
6381 	/* Memorize the town and all wilderness levels close to town */
6382 	if (istownarea(wpos, MAX_TOWNAREA)) {
6383 		p_ptr->max_panel_rows = MAX_PANEL_ROWS;
6384 		p_ptr->max_panel_cols = MAX_PANEL_COLS;
6385 
6386 		p_ptr->max_tradpanel_rows = MAX_TRADPANEL_ROWS;
6387 		p_ptr->max_tradpanel_cols = MAX_TRADPANEL_COLS;
6388 
6389 		p_ptr->cur_hgt = MAX_HGT;
6390 		p_ptr->cur_wid = MAX_WID;
6391 
6392 		if (istown(wpos)) {
6393 			p_ptr->town_x = wpos->wx;
6394 			p_ptr->town_y = wpos->wy;
6395 
6396 			/* for PVP-mode, reset diminishing healing */
6397 			p_ptr->heal_effect = 0;
6398 			/* and anti-fleeing teleport prevention */
6399 			p_ptr->pvp_prevent_tele = 0;
6400 			p_ptr->redraw |= PR_DEPTH;
6401 		}
6402 	} else if (wpos->wz) {
6403 		/* Hack -- tricky formula, but needed */
6404 		p_ptr->max_panel_rows = MAX_PANEL_ROWS_L;
6405 		p_ptr->max_panel_cols = MAX_PANEL_COLS_L;
6406 
6407 		p_ptr->max_tradpanel_rows = MAX_TRADPANEL_ROWS_L;
6408 		p_ptr->max_tradpanel_cols = MAX_TRADPANEL_COLS_L;
6409 
6410 		p_ptr->cur_hgt = l_ptr->hgt;
6411 		p_ptr->cur_wid = l_ptr->wid;
6412 
6413 		/* only show 'dungeon explore feelings' when entering a dungeon, for now */
6414 #ifdef DUNGEON_VISIT_BONUS
6415 		show_floor_feeling(Ind, (p_ptr->wpos_old.wz == 0));
6416 #else
6417 		show_floor_feeling(Ind, FALSE);
6418 #endif
6419 	} else {
6420 		p_ptr->max_panel_rows = MAX_PANEL_ROWS;
6421 		p_ptr->max_panel_cols = MAX_PANEL_COLS;
6422 
6423 		p_ptr->max_tradpanel_rows = MAX_TRADPANEL_ROWS;
6424 		p_ptr->max_tradpanel_cols = MAX_TRADPANEL_COLS;
6425 
6426 		p_ptr->cur_hgt = MAX_HGT;
6427 		p_ptr->cur_wid = MAX_WID;
6428 	}
6429 
6430 #ifdef BIG_MAP
6431         if (p_ptr->max_panel_rows < 0) p_ptr->max_panel_rows = 0;
6432         if (p_ptr->max_panel_cols < 0) p_ptr->max_panel_cols = 0;
6433 #endif
6434 
6435 #ifdef ALLOW_NR_CROSS_PARTIES
6436         if (p_ptr->party && at_netherrealm(&p_ptr->wpos_old) && !at_netherrealm(&p_ptr->wpos)
6437     	    && compat_mode(p_ptr->mode, parties[p_ptr->party].cmode)
6438             /* actually preserve his nether realm cross party for this,
6439                so he can tell everyone involved about Valinor in party chat: */
6440     	    && p_ptr->auto_transport != AT_VALINOR
6441     	    && !p_ptr->admin_dm)
6442                 /* need to leave party, since we might be teamed up with incompatible char mode players! */
6443                 party_leave(Ind, FALSE);
6444 #endif
6445 #ifdef ALLOW_NR_CROSS_ITEMS
6446 	if (in_netherrealm(&p_ptr->wpos_old) && !in_netherrealm(&p_ptr->wpos))
6447 		for (j = 1; j < INVEN_TOTAL; j++)
6448 			p_ptr->inventory[j].NR_tradable = FALSE;
6449 #endif
6450 #ifdef IDDC_NO_TRADE_CHEEZE
6451 	/* hack: abuse NR_tradable to mark items _untradable_ for first couple of IDDC floors */
6452 	if (p_ptr->wpos.wx == WPOS_IRONDEEPDIVE_X &&
6453 	    p_ptr->wpos.wy == WPOS_IRONDEEPDIVE_Y) {
6454 		/* on entering the first floor, mark all items we already possess for anti-trade-cheeze */
6455 		if (p_ptr->wpos.wz == WPOS_IRONDEEPDIVE_Z) {
6456 			for (j = 1; j < INVEN_TOTAL; j++) {
6457 				if (exceptionally_shareable_item(&p_ptr->inventory[j])) continue;
6458 				p_ptr->inventory[j].NR_tradable = TRUE;
6459 			}
6460 		/* after reaching n-th floor, unmark them to make them freely available for trading again */
6461 		} else if (ABS(p_ptr->wpos_old.wz) < IDDC_NO_TRADE_CHEEZE && ABS(p_ptr->wpos.wz) >= IDDC_NO_TRADE_CHEEZE) {
6462 			for (j = 1; j < INVEN_TOTAL; j++)
6463 				p_ptr->inventory[j].NR_tradable = FALSE;
6464 		}
6465 	}
6466 #endif
6467 
6468 #if defined(DUNGEON_VISIT_BONUS) || defined(ALLOW_NR_CROSS_PARTIES) || defined(ALLOW_NR_CROSS_ITEMS)
6469 	wpcopy(&p_ptr->wpos_old, &p_ptr->wpos);
6470 #endif
6471 
6472 	/* Allow the player again to find another random IDDC town, if he hit a static IDDC town */
6473 	if (is_fixed_irondeepdive_town(&p_ptr->wpos, dlv)) p_ptr->IDDC_found_rndtown = FALSE;
6474 	/* Cover disallowing the same if he enters a random town someone else already generated */
6475 	else if (in_irondeepdive(&p_ptr->wpos) && l_ptr && (l_ptr->flags1 & LF1_RANDOM_TOWN)) p_ptr->IDDC_found_rndtown = TRUE;
6476 
6477 	/* hack -- update night/day in wilderness levels */
6478 	if (!wpos->wz) {
6479 		if (IS_DAY) player_day(Ind);
6480 		else player_night(Ind);
6481 	}
6482 
6483 	/* Determine starting location */
6484 	switch (p_ptr->new_level_method) {
6485 	/* Climbed down */
6486 	case LEVEL_RECALL_DOWN:
6487 	case LEVEL_DOWN:  		starty = level_down_y(wpos);
6488 					startx = level_down_x(wpos);
6489 					break;
6490 
6491 	/* Climbed up */
6492 	case LEVEL_RECALL_UP:
6493 	case LEVEL_UP:    		starty = level_up_y(wpos);
6494 					startx = level_up_x(wpos);
6495 					break;
6496 
6497 	/* Teleported level */
6498 	case LEVEL_RAND:  		starty = level_rand_y(wpos);
6499 					startx = level_rand_x(wpos);
6500 					break;
6501 
6502 	/* Used ghostly travel */
6503 	case LEVEL_PROB_TRAVEL:
6504 	case LEVEL_GHOST: 		starty = p_ptr->py;
6505 					startx = p_ptr->px;
6506 					break;
6507 
6508 	/* Over the river and through the woods */
6509 	case LEVEL_OUTSIDE:
6510 					smooth_ambient = TRUE; /* normal wilderness running */
6511 	case LEVEL_HOUSE:
6512 					starty = p_ptr->py;
6513 					startx = p_ptr->px;
6514 					break;
6515 
6516 		/* this is used instead of extending the level_rand_y/x
6517 		into the negative direction to prevent us from
6518 		alocing so many starting locations.  Although this does
6519 		not make players teleport to simmilar locations, this
6520 		could be achieved by seeding the RNG with the depth. */
6521 
6522 	case LEVEL_OUTSIDE_RAND:
6523 		/* make sure we aren't in an "icky" location */
6524 		emergency_x = 0; emergency_y = 0; tries = 0;
6525 		do {
6526 			starty = rand_int((l_ptr ? l_ptr->hgt : MAX_HGT)-3)+1;
6527 			startx = rand_int((l_ptr ? l_ptr->wid : MAX_WID)-3)+1;
6528 			if (cave_floor_bold(zcave, starty, startx)) {
6529 				emergency_x = startx;
6530 				emergency_y = starty;
6531 			}
6532 		}
6533 		while (  ((zcave[starty][startx].info & CAVE_ICKY)
6534 			|| (zcave[starty][startx].feat == FEAT_DEEP_WATER)
6535 			|| (!cave_floor_bold(zcave, starty, startx)))
6536 			&& (++tries < 10000) );
6537 		if (tries == 10000 && emergency_x) {
6538 			startx = emergency_x;
6539 			starty = emergency_y;
6540 		}
6541 		break;
6542 	case LEVEL_TO_TEMPLE:
6543 		/* Try to find a temple */
6544 		for (y = 0; y < MAX_HGT; y++) {
6545 			for (x = 0; x < MAX_WID; x++) {
6546 				cave_type* c_ptr = &zcave[y][x];
6547 				if (c_ptr->feat == FEAT_SHOP) {
6548 					struct c_special *cs_ptr = GetCS(c_ptr, CS_SHOP);
6549 					if (cs_ptr) {
6550 						int which = cs_ptr->sc.omni;
6551 						if (which == STORE_TEMPLE) {
6552 							/* Found a temple */
6553 							startx = x;
6554 							starty = y;
6555 							break;
6556 						}
6557 					}
6558 				}
6559 			}
6560 			if (startx) break;
6561 		}
6562 
6563 		if (!startx) {
6564 			/* Random coordinates in case there's no temple */
6565 			starty = level_rand_y(wpos);
6566 			startx = level_rand_x(wpos);
6567 		}
6568 		break;
6569 	}
6570 
6571 	/* Highlander Tournament hack: pseudo-teleport the player
6572 	   after he took a staircase inside the highlander dungeon */
6573 	if (sector00separation &&
6574 	    p_ptr->wpos.wx == WPOS_HIGHLANDER_DUN_X &&
6575 	    p_ptr->wpos.wy == WPOS_HIGHLANDER_DUN_Y &&
6576 	    (p_ptr->wpos.wz * WPOS_HIGHLANDER_DUN_Z) > 0
6577 	    && l_ptr)
6578 		starty = l_ptr->hgt + 1; /* for the code right below :) ("Hack -- handle smaller floors") */
6579 
6580 	/* Hack -- handle smaller floors */
6581 	if (l_ptr && (starty > l_ptr->hgt || startx > l_ptr->wid)) {
6582 		/* make sure we aren't in an "icky" location */
6583 		emergency_x = 0; emergency_y = 0; tries = 0;
6584 		do {
6585 			starty = rand_int(l_ptr->hgt-3)+1;
6586 			startx = rand_int(l_ptr->wid-3)+1;
6587 			if (cave_floor_bold(zcave, starty, startx)) {
6588 				emergency_x = startx;
6589 				emergency_y = starty;
6590 			}
6591 		}
6592 		while (  ((zcave[starty][startx].info & CAVE_ICKY)
6593 			|| (!cave_floor_bold(zcave, starty, startx)))
6594 			&& (++tries < 10000) );
6595 		if (tries == 10000 && emergency_x) {
6596 			startx = emergency_x;
6597 			starty = emergency_y;
6598 		}
6599 	}
6600 
6601 	//printf("finding area (%d,%d)\n",startx,starty);
6602 	/* Place the player in an empty space */
6603 	//for (j = 0; j < 1500; ++j)
6604 	for (j = 0; j < 5000; j++) {
6605 		/* Increasing distance */
6606 		d = (j + 149) / 150;
6607 
6608 		/* Pick a location */
6609 		scatter(wpos, &y, &x, starty, startx, d, 1);
6610 
6611 		/* Must have an "empty" grid */
6612 		if (!cave_empty_bold(zcave, y, x)) continue;
6613 
6614 		/* Not allowed to go onto a icky location (house) if Depth <= 0 */
6615 		if (wpos->wz == 0 && !(p_ptr->global_event_temp & PEVF_ICKY_OK)) {
6616 			if((zcave[y][x].info & CAVE_ICKY) && (p_ptr->new_level_method != LEVEL_HOUSE)) continue;
6617 			if(!(zcave[y][x].info & CAVE_ICKY) && (p_ptr->new_level_method == LEVEL_HOUSE)) continue;
6618 		}
6619 
6620 		/* Prevent recalling or prob-travelling into no-tele vaults and monster nests! - C. Blue */
6621 	        if ((zcave[y][x].info & (CAVE_STCK | CAVE_NEST_PIT)) &&
6622 		    (p_ptr->new_level_method == LEVEL_RECALL_UP || p_ptr->new_level_method == LEVEL_RECALL_DOWN ||
6623 		    p_ptr->new_level_method == LEVEL_RAND || p_ptr->new_level_method == LEVEL_OUTSIDE_RAND ||
6624 		    p_ptr->new_level_method == LEVEL_PROB_TRAVEL)
6625 		    && !(p_ptr->global_event_temp & PEVF_STCK_OK))
6626 			continue;
6627 
6628 		/* Prevent landing onto a store entrance */
6629 		if (zcave[y][x].feat == FEAT_SHOP) continue;
6630 
6631 		/* Must be inside the level borders - mikaelh */
6632 		if (x < 1 || y < 1 || x > p_ptr->cur_wid - 2 || y > p_ptr->cur_hgt - 2)
6633 			continue;
6634 
6635 		/* should somewhat stay away from certain locations? */
6636 		if (p_ptr->avoid_loc)
6637 			for (d = 0; d < p_ptr->avoid_loc; d++)
6638 				if (distance(y, x, p_ptr->avoid_loc_y[d], p_ptr->avoid_loc_x[d]) < 8)
6639 					continue;
6640 
6641 		break;
6642 	}
6643 	/* this is required to make sense, isn't it.. */
6644 	if (j == 5000) {
6645 		x = startx;
6646 		y = starty;
6647 	}
6648 
6649 #if 0
6650 	/* Place the player in an empty space */
6651 	for (j = 0; j < 1500; ++j) {
6652 		/* Increasing distance */
6653 		d = (j + 149) / 150;
6654 
6655 		/* Pick a location */
6656 		scatter(wpos, &y, &x, starty, startx, d, 1);
6657 
6658 		/* Must have an "empty" grid */
6659 		if (!cave_empty_bold(zcave, y, x)) continue;
6660 
6661 		/* Not allowed to go onto a icky location (house) if Depth <= 0 */
6662 		if ((wpos->wz == 0) && (zcave[y][x].info & CAVE_ICKY))
6663 			break;
6664 	}
6665 #endif /*0*/
6666 	p_ptr->py = y;
6667 	p_ptr->px = x;
6668 
6669 	grid_affects_player(Ind);
6670 
6671 	/* Update the player location */
6672 	zcave[y][x].m_idx = 0 - Ind;
6673 	cave_midx_debug(wpos, y, x, -Ind);
6674 
6675 	/* Update his golem's location */
6676 	for (m_idx = m_top - 1; m_idx >= 0; m_idx--) {
6677 		monster_type *m_ptr = &m_list[m_fast[m_idx]];
6678 		cave_type **mcave;
6679 		mcave = getcave(&m_ptr->wpos);
6680 
6681 		if (!m_fast[m_idx]) continue;
6682 
6683 		/* Excise "dead" monsters */
6684 		if (!m_ptr->r_idx) continue;
6685 
6686 		if (m_ptr->owner != p_ptr->id) continue;
6687 
6688 		if (m_ptr->mind & GOLEM_GUARD && !(m_ptr->mind & GOLEM_FOLLOW)) continue;
6689 
6690 		/* XXX XXX XXX (merging) */
6691 		starty = m_ptr->fy;
6692 		startx = m_ptr->fx;
6693 		starty = y;
6694 		startx = x;
6695 
6696 		if (!m_ptr->wpos.wz && !(m_ptr->mind & GOLEM_FOLLOW)) continue;
6697 		/*
6698 		   if (m_ptr->mind & GOLEM_GUARD && !(m_ptr->mind&GOLEM_FOLLOW)) continue;
6699 		   */
6700 
6701 		/* Place the golems in an empty space */
6702 		for (j = 0; j < 1500; ++j) {
6703 			/* Increasing distance */
6704 			d = (j + 149) / 150;
6705 
6706 			/* Pick a location */
6707 			scatter(wpos, &my, &mx, starty, startx, d, 0);
6708 
6709 			/* Must have an "empty" grid */
6710 			if (!cave_empty_bold(zcave, my, mx)) continue;
6711 
6712 			/* Not allowed to go onto a icky location (house) if Depth <= 0 */
6713 			if ((wpos->wz == 0) && (zcave[my][mx].info & CAVE_ICKY))
6714 				continue;
6715 			break;
6716 		}
6717 		if (mcave) {
6718 			mcave[m_ptr->fy][m_ptr->fx].m_idx = 0;
6719 			everyone_lite_spot(&m_ptr->wpos, m_ptr->fy, m_ptr->fx);
6720 		}
6721 		wpcopy(&m_ptr->wpos,wpos);
6722 		mcave = getcave(&m_ptr->wpos);
6723 		m_ptr->fx = mx;
6724 		m_ptr->fy = my;
6725 		if (mcave) {
6726 			mcave[m_ptr->fy][m_ptr->fx].m_idx = m_fast[m_idx];
6727 			everyone_lite_spot(&m_ptr->wpos, m_ptr->fy, m_ptr->fx);
6728 		}
6729 
6730 		/* Update the monster (new location) */
6731 		update_mon(m_fast[m_idx], TRUE);
6732 	}
6733 #if 0
6734 	while (TRUE) {
6735 		y = rand_range(1, ((Depth) ? (MAX_HGT - 2) : (SCREEN_HGT - 2)));
6736 		x = rand_range(1, ((Depth) ? (MAX_WID - 2) : (SCREEN_WID - 2)));
6737 
6738 		/* Must be a "naked" floor grid */
6739 		if (!cave_naked_bold(zcave, y, x)) continue;
6740 
6741 		/* Refuse to start on anti-teleport grids */
6742 		if (zcave[y][x].info & CAVE_ICKY) continue;
6743 		break;
6744 	}
6745 #endif
6746 
6747 	panel_calculate(Ind);
6748 
6749 	/* Hack -- remove tracked monster */
6750 	health_track(Ind, 0);
6751 
6752 	p_ptr->redraw |= (PR_MAP);
6753 	p_ptr->redraw |= (PR_DEPTH);
6754 
6755 	forget_view(Ind);
6756 	forget_lite(Ind);
6757 	/* original order: update_view first, then update_lite.  - C. Blue
6758 	   Problem: can't see some grids when entering destroyed levels.
6759 	   Fix: update lite before view.
6760 	   New problem: Had panic save, thought maybe since lite depends on correctly
6761 	    initialized view, but otoh view also seems to depend on lite oO.
6762 	    Turned out that wasn't the panic save (fixed now).
6763 	   Still new problem: Now after changing wpos, lite would be a square
6764 	    instead of circle, until moving.
6765 	   Fix: Add another update_view in the beginning -_-. */
6766 	update_view(Ind);
6767 	update_lite(Ind);
6768 	update_view(Ind);
6769 	update_monsters(TRUE);
6770 	update_players();
6771 
6772 	/* Tell him that he should beware */
6773 	if (wpos->wz == 0 && !istown(wpos)) {
6774 		if (wild_info[wpos->wy][wpos->wx].own) {
6775 			cptr p = lookup_player_name(wild_info[wpos->wy][wpos->wx].own);
6776 			if (p == NULL) p = "Someone";
6777 
6778 			msg_format(Ind, "You enter the land of %s.", p);
6779 		}
6780 	}
6781 
6782 	/* Clear the flag */
6783 	p_ptr->new_level_flag = FALSE;
6784 
6785 	/* Is arriving in a fixed IDDC-town noteworthy maybe? */
6786 	if (is_fixed_irondeepdive_town(&p_ptr->wpos, dlv)) {
6787 		if (dlv == 40) {
6788 			msg_broadcast_format(0, "\374\377s%s has reached Menegroth.", p_ptr->name);
6789 			l_printf("%s \\{s%s reached Menegroth\n", showdate(), p_ptr->name);
6790 		} else if (dlv == 80) {
6791 			msg_broadcast_format(0, "\374\377s%s has reached Nargothrond.", p_ptr->name);
6792 			l_printf("%s \\{s%s reached Nargothrond\n", showdate(), p_ptr->name);
6793 		}
6794 	}
6795 
6796 	/* Did we enter/leave a no-run level? Temporarily disable/reenable warning_run */
6797 	if ((l_ptr && (l_ptr->flags2 & LF2_NO_RUN)) || (in_sector00(&p_ptr->wpos) && (sector00flags2 & LF2_NO_RUN))) {
6798 		if (p_ptr->warning_run < 3) p_ptr->warning_run += 10;
6799 	} else if (p_ptr->warning_run >= 10) p_ptr->warning_run -= 10;
6800 
6801 	/* warning messages, mostly for newbies */
6802 	if (p_ptr->ghost) ; /* don't warn ghosts */
6803 	else if (p_ptr->warning_bpr2 != 1 && p_ptr->num_blow == 1 &&
6804 	    /* and don't spam Martial Arts users or mage-staff wielders ;) */
6805 	    p_ptr->inventory[INVEN_WIELD].k_idx && is_weapon(p_ptr->inventory[INVEN_WIELD].tval)) {
6806 		p_ptr->warning_bpr2 = p_ptr->warning_bpr3 = 1;
6807 		msg_print(Ind, "\374\377yWARNING! You can currently perform only ONE 'blow per round' (attack).");
6808 		msg_print(Ind, "\374\377y    If you rely on close combat, you should get at least 2 BpR!");
6809 		msg_print(Ind, "\374\377y    Possible reasons: Weapon is too heavy or your strength is too low.");
6810 		if (p_ptr->inventory[INVEN_ARM].tval == TV_SHIELD) {
6811 			if (p_ptr->rogue_like_commands)
6812 				msg_print(Ind, "\374\377y    Try taking off your shield (\377oSHIFT+t\377y) and see if that helps.");
6813 			else
6814 				msg_print(Ind, "\374\377y    Try taking off your shield ('\377ot\377y' key) and see if that helps.");
6815 		}
6816 		switch (p_ptr->pclass) {
6817 		case CLASS_WARRIOR:
6818 			msg_print(Ind, "\374\377y    Warriors should try either a dagger, whip, spear or cleaver.");
6819 			break;
6820 		case CLASS_PALADIN:
6821 			msg_print(Ind, "\374\377y    Paladins should try either a dagger, whip, spear or cleaver.");
6822 			break;
6823 		case CLASS_MIMIC:
6824 			msg_print(Ind, "\374\377y    Mimics should try either a dagger, whip, spear or cleaver.");
6825 			break;
6826 		case CLASS_ROGUE:
6827 			msg_print(Ind, "\374\377y    Rogues should try dual-wielding two daggers or main gauches.");
6828 			break;
6829 		case CLASS_RANGER:
6830 			msg_print(Ind, "\374\377y    Rangers should try dual-wielding two daggers or sword & dagger.");
6831 			break;
6832 		}
6833 		s_printf("warning_bpr23: %s\n", p_ptr->name);
6834 	} else if (p_ptr->warning_wield == 0 &&
6835 	    p_ptr->num_blow == 1 && !p_ptr->inventory[INVEN_WIELD].k_idx) {
6836 		p_ptr->warning_wield = 1;
6837 		msg_print(Ind, "\374\377yWARNING: You don't wield a weapon at the moment!");
6838 		msg_print(Ind, "\374\377y    Press '\377Rw\377y' key. It lets you pick a weapon (as well as other items)");
6839 		msg_print(Ind, "\374\377y    from your inventory to wield!");
6840 		msg_print(Ind, "\374\377y    (If you plan to train 'Martial Arts' skill, ignore this warning.)");
6841 		s_printf("warning_wield: %s\n", p_ptr->name);
6842 	}
6843 #if 1
6844 	else if (p_ptr->warning_run < 3) {
6845 		p_ptr->warning_run++;
6846 		msg_print(Ind, "\374\377yHINT: To run fast, use \377oSHIFT+direction\377y keys.");
6847 		msg_print(Ind, "\374\377y      For that, \377oNUMLOCK\377y key must be OFF and no awake monster in sight!");
6848 		s_printf("warning_run: %s\n", p_ptr->name);
6849 	}
6850 #endif
6851 	if (p_ptr->warning_lite == 0 && p_ptr->cur_lite == 0 &&
6852 	    (p_ptr->wpos.wz < 0 || (p_ptr->wpos.wz == 0 && night_surface))) { //Training Tower currently exempt
6853 		if (p_ptr->wpos.wz < 0) p_ptr->warning_lite = 1;
6854 		msg_print(Ind, "\374\377yHINT: You don't wield any light source at the moment!");
6855 		msg_print(Ind, "\374\377y      Press '\377ow\377y' to wield a torch or lantern (or other items).");
6856 		s_printf("warning_lite: %s\n", p_ptr->name);
6857 	}
6858 
6859 	if (!p_ptr->warning_worldmap && p_ptr->wpos.wz == 0 &&
6860 	    !in_sector00(&p_ptr->wpos) &&
6861 	    (ABS(p_ptr->wpos.wx - 32) >= 2 || ABS(p_ptr->wpos.wy - 32) >= 2)) {
6862 		msg_print(Ind, "\374\377yHINT: You can press '\377oM\377y' to browse a worldmap.");
6863 		msg_print(Ind, "\374\377y      Towns, for example Bree, are denoted as yellow 'T'.");
6864 		s_printf("warning_worldmap: %s\n", p_ptr->name);
6865 		p_ptr->warning_worldmap = 1;
6866 	}
6867 
6868 	if (!p_ptr->warning_dungeon && p_ptr->wpos.wz == 0 &&
6869 	    !in_sector00(&p_ptr->wpos) &&
6870 	    (ABS(p_ptr->wpos.wx - 32) >= 3 || ABS(p_ptr->wpos.wy - 32) >= 3)) {
6871 		msg_print(Ind, "\374\377yHINT: Consider going to the Training Tower first, to gain some levels.");
6872 		msg_print(Ind, "\374\377y      After that, seek out a dungeon. The tower is located in Bree.");
6873 		s_printf("warning_dungeon: %s\n", p_ptr->name);
6874 		p_ptr->warning_dungeon = 1;
6875 	}
6876 
6877 	/* Hack -- jail her/him */
6878 	if (!p_ptr->wpos.wz && p_ptr->tim_susp
6879 #ifdef JAIL_TOWN_AREA
6880 	    && istownarea(&p_ptr->wpos, MAX_TOWNAREA)
6881 #endif
6882 	    )
6883 		imprison(Ind, 0, "old crimes");
6884 
6885 	/* daylight problems for vampires */
6886 	if (!p_ptr->wpos.wz && p_ptr->prace == RACE_VAMPIRE) calc_boni(Ind);
6887 
6888 	/* moved here, since it simplifies the wpos-changing process and
6889 	   should keep it highly consistent and linear.
6890 	   Note: Basically every case that sets p_ptr->new_level_flag = TRUE
6891 	   can and should be stripped of immediate check_Morgoth() call and
6892 	   instead rely on its occurance here. Also, there should actually be
6893 	   no existing case of check_Morgoth() that went without setting said flag,
6894 	   with the only exception of server join/leave in nserver.c and Morgoth
6895 	   live spawn (ie not on level generation time) in monster2.c. - C. Blue */
6896 	check_Morgoth(Ind);
6897 	if (p_ptr->new_level_flag) return;
6898 
6899 #ifdef CLIENT_SIDE_WEATHER
6900 	/* update his client-side weather */
6901 	player_weather(Ind, TRUE, TRUE, TRUE);
6902 #endif
6903 
6904 	/* Brightly lit Arena Monster Challenge */
6905 	if (ge_special_sector && p_ptr->wpos.wx == WPOS_ARENA_X &&
6906 	    p_ptr->wpos.wy == WPOS_ARENA_Y && p_ptr->wpos.wz == WPOS_ARENA_Z) {
6907 		wiz_lite(Ind);
6908 		/* Also tell him about this place */
6909 		for (j = 0; j < MAX_GLOBAL_EVENTS; j++) {
6910 			if (global_event[j].getype != GE_ARENA_MONSTER) continue;
6911 			msg_print(Ind, "\377uYou enter the Arena Monster Challenge!");
6912 			msg_format(Ind, "\377uType '\377U/evinfo %d\377u' to learn more or '\377U/evsign %d\377u' to challenge.", j + 1, j + 1);
6913 			break;
6914 		}
6915 	}
6916 
6917 	if (p_ptr->wpos.wx == WPOS_PVPARENA_X && p_ptr->wpos.wy == WPOS_PVPARENA_Y && p_ptr->wpos.wz == WPOS_PVPARENA_Z) {
6918 		/* teleport after entering [the PvP arena],
6919 		   so stairs won't be camped */
6920 		teleport_player(Ind, 200, TRUE);
6921 		/* Brightly lit PvP Arena */
6922 		wiz_lite(Ind);
6923 	}
6924 
6925 	/* PvP-Mode specialties: */
6926 	if ((p_ptr->mode & MODE_PVP) && p_ptr->wpos.wz &&
6927 	    !(p_ptr->wpos.wx == WPOS_PVPARENA_X && p_ptr->wpos.wy == WPOS_PVPARENA_Y && p_ptr->wpos.wz == WPOS_PVPARENA_Z)) { /* <- not in the pvp arena actually */
6928 		/* anti-chicken: Don't allow a high player to 'chase' a very low player */
6929 		for (j = 1; j <= NumPlayers; j++) {
6930 			if (Players[j]->conn == NOT_CONNECTED) continue;
6931 			if (is_admin(Players[j])) continue;
6932 			if (!(Players[j]->mode & MODE_PVP)) continue;
6933 			if (!inarea(&Players[j]->wpos, &p_ptr->wpos)) continue;
6934 			if (Players[j]->max_plv < p_ptr->max_plv - 5) {
6935 				p_ptr->new_level_method = (p_ptr->wpos.wz > 0 ? LEVEL_RECALL_DOWN : LEVEL_RECALL_UP);
6936 				p_ptr->recall_pos.wz = 0;
6937 				p_ptr->recall_pos.wx = p_ptr->wpos.wx;
6938 				p_ptr->recall_pos.wy = p_ptr->wpos.wy;
6939 //				set_recall_timer(Ind, 1);
6940 				p_ptr->word_recall = 1;
6941 				msg_print(Ind, "\377yYou have sudden visions of a bawking chicken while being recalled!");
6942 			}
6943 		}
6944 	}
6945 
6946 	/* Hack: Allow players to pass trees always, while in town */
6947 	if (istown(&p_ptr->wpos) || isdungeontown(&p_ptr->wpos)) p_ptr->town_pass_trees = TRUE;
6948 	else p_ptr->town_pass_trees = FALSE;
6949 
6950 #if 0 /* since digging is pretty awesome now, this is too much, and we should be glad that treasure detection items have some use now actually! */
6951 	/* High digging results in auto-treasure detection */
6952 	if (get_skill(p_ptr, SKILL_DIG) >= 30) floor_detect_treasure(Ind);
6953 #endif
6954 
6955 	/* If he found a town in the dungeon, map it as much as a normal town would be at night */
6956 	if (l_ptr && (l_ptr->flags1 & LF1_DUNGEON_TOWN)) player_dungeontown(Ind);
6957 
6958 	/* Did we enter a no-tele vault? */
6959 	if (zcave[p_ptr->py][p_ptr->px].info & CAVE_STCK) {
6960 		msg_print(Ind, "\377DThe air in here feels very still.");
6961 		p_ptr->redraw |= PR_DEPTH; /* hack: depth colour indicates no-tele */
6962 		/* New: Have bgm indicate no-tele too! (done below in handle_music()) */
6963 	}
6964 
6965 	quest_check_player_location(Ind);
6966 
6967 #ifdef USE_SOUND_2010
6968 	/* clear boss/floor-specific music */
6969 	p_ptr->music_monster = -1;
6970 	handle_music(Ind);
6971 	handle_ambient_sfx(Ind, &(getcave(&p_ptr->wpos)[p_ptr->py][p_ptr->px]), &p_ptr->wpos, smooth_ambient);
6972 #endif
6973 
6974 #ifdef ENABLE_SELF_FLASHING
6975 	/* if not travelling through wilderness smoothly,
6976 	   flicker player for a moment, to allow for easy location */
6977 	if (!smooth_ambient && p_ptr->flash_self >= 0) p_ptr->flash_self = cfg.fps / FLASH_SELF_DIV2; //todo: make client option
6978 #endif
6979 
6980 	clockin(Ind, 7); /* Remember his wpos */
6981 }
6982 
6983 
6984 /*
6985  * Main loop --KLJ--
6986  *
6987  * This is main loop; it is called every 1/FPS seconds.  Usually FPS is about
6988  * 10, so that a normal unhasted unburdened character gets 1 player turn per
6989  * second.  Note that we process every player and the monsters, then quit.
6990  * The "scheduling" code (see sched.c) is the REAL main loop, which handles
6991  * various inputs and timings.
6992  */
6993 
6994 void dungeon(void) {
6995 	int i;
6996 	player_type *p_ptr;
6997 
6998 	/* Return if no one is playing */
6999 	/* if (!NumPlayers) return; */
7000 
7001 	/* Check for death.  Go backwards (very important!) */
7002 	for (i = NumPlayers; i > 0; i--) {
7003 		/* Check connection first */
7004 		if (Players[i]->conn == NOT_CONNECTED)
7005 			continue;
7006 
7007 		/* Check for death */
7008 		if (Players[i]->death)
7009 			player_death(i);
7010 	}
7011 
7012 	/* Check player's depth info */
7013 	for (i = 1; i < NumPlayers + 1; i++) {
7014 		p_ptr = Players[i];
7015 		if (p_ptr->conn == NOT_CONNECTED || !p_ptr->new_level_flag)
7016 			continue;
7017 		if (p_ptr->iron_winner_ded && p_ptr->wpos.wz != 0) {
7018 			p_ptr->new_level_flag = FALSE;
7019 			do_cmd_suicide(i);
7020 			continue;
7021 		}
7022 		process_player_change_wpos(i);
7023 	}
7024 
7025 	/* New meta client implementation */
7026 	meta_tick();
7027 
7028 	/* Handle any network stuff */
7029 	Net_input();
7030 #if 0
7031 	/* Hack -- Compact the object list occasionally */
7032 	if (o_top + 16 > MAX_O_IDX) compact_objects(32, FALSE);
7033 
7034 	/* Hack -- Compact the monster list occasionally */
7035 	if (m_top + 32 > MAX_M_IDX) compact_monsters(64, FALSE);
7036 
7037 	/* Hack -- Compact the trap list occasionally */
7038 	if (t_top + 16 > MAX_TR_IDX) compact_traps(32, FALSE);
7039 #endif
7040 
7041 
7042 
7043 	/* Note -- this is the END of the last turn */
7044 
7045 	/* Do final end of turn processing for each player */
7046 	for (i = 1; i <= NumPlayers; i++) {
7047 		if (Players[i]->conn == NOT_CONNECTED)
7048 			continue;
7049 
7050 		/* Actually process that player */
7051 		process_player_end(i);
7052 	}
7053 
7054 	/* paranoia - It's done twice */
7055 	/* Check for death.  Go backwards (very important!) */
7056 	for (i = NumPlayers; i > 0; i--) {
7057 		/* Check connection first */
7058 		if (Players[i]->conn == NOT_CONNECTED)
7059 			continue;
7060 
7061 		/* Check for death */
7062 		if (Players[i]->death)
7063 			player_death(i);
7064 	}
7065 
7066 
7067 
7068 	///*** BEGIN NEW TURN ***///
7069 	turn++;
7070 
7071 	/* Check for overflow - mikaelh */
7072 #if 0 /* avoid doing this last-minute, since some calcs will already be off */
7073 	if (turn < 0)
7074 #else /* give at least ~30 minutes buffer (eg login process requires that approx.) */
7075 	if (turn == turn_overflow) /* note: turn is s32b */
7076 #endif
7077 	{
7078 		/* Reset the turn counter */
7079 		/* This will cause some weird things */
7080 		/* Players will probably timeout */
7081 		turn = 1;
7082 
7083 		/* Log it */
7084 		s_printf("%s: TURN COUNTER RESET (%d)\n", showtime(), turn_overflow);
7085 
7086 		/* Reset empty party creation times */
7087 		for (i = 1; i < MAX_PARTIES; i++) {
7088 			if (parties[i].members == 0) parties[i].created = 0;
7089 		}
7090 	}
7091 
7092 	/* Do some queued drawing */
7093 	process_lite_later();
7094 
7095 
7096 	/* Process quest (de)activation every minute */
7097 	if (!(turn % (cfg.fps * 60))) process_quests();
7098 
7099 	/* process some things once each second.
7100 	   NOTE: Some of these (global events) mustn't
7101 	   be handled _after_ a player got set to 'dead',
7102 	   or gameplay might in very rare occasions get
7103 	   screwed up (someone dying when he shouldn't) - C. Blue */
7104 	if (!(turn % cfg.fps)) {
7105 		/* Process global_events */
7106 		process_global_events();
7107 
7108 		/* process special event timers */
7109 		process_timers();
7110 
7111 		/* Call a specific lua function every second */
7112 		exec_lua(0, "second_handler()");
7113 
7114 		/* Process weather effects */
7115 #ifdef CLIENT_SIDE_WEATHER
7116  #ifndef CLIENT_WEATHER_GLOBAL
7117 		process_wild_weather();
7118  #else
7119 		process_weather_control();
7120  #endif
7121 #else
7122 		process_weather_control();
7123 #endif
7124 
7125 #ifdef AUCTION_SYSTEM
7126 		/* Process auctions */
7127 		process_auctions();
7128 #endif
7129 
7130 #ifdef USE_SOUND_2010
7131 		process_ambient_sfx();
7132 #endif
7133 
7134 		/* process timed shutdown (/shutrec) */
7135 		if (shutdown_recall_timer) shutdown_recall_timer--;
7136 
7137 		/* process certain player-related timers */
7138 		for (i = 1; i <= NumPlayers; i++) {
7139 			if (Players[i]->redraw_cooldown) Players[i]->redraw_cooldown--;
7140 
7141 			/* Arbitrary max number, just to prevent integer overflow.
7142 			   Should just be higher than the longest interval of any ambient sfx type. */
7143 			if (!Players[i]->wpos.wz && /* <- redundant check sort of, caught in process_player_change_wpos() anyway */
7144 			    Players[i]->ambient_sfx_timer < 200)
7145 				Players[i]->ambient_sfx_timer++;
7146 		}
7147 	}
7148 
7149 	/* process every 1/5th second */
7150 	if (!(turn % (cfg.fps / 5))) {
7151 		if (nether_realm_collapsing && !rand_int(8)) {
7152 			struct worldpos wpos = {netherrealm_wpos_x, netherrealm_wpos_y, netherrealm_end_wz};
7153 			int x = nrc_x, y = nrc_y - 5; /* start somewhat 'above' Zu-Aon's death spot */
7154 
7155 			/* stay in bounds */
7156 			if (x < 20) x = rand_int(37) + 4;//don't cut them off too much
7157 			else if (x >= MAX_WID - 20) x = MAX_WID - 40 + rand_int(36);//don't cut them off too much
7158 			else x = x - 20 + rand_int(41);
7159 			if (y < 15) y = rand_int(16);
7160 			else if (y >= MAX_HGT - 15) y = MAX_HGT - 30 + rand_int(23);//don't cut them off at the bottom border too much
7161 			else y = y - 15 + rand_int(31);
7162 
7163 			//cast_lightning(&wpos, rand_int(MAX_WID - 20) + 10, rand_int(MAX_HGT - 15) + 5);
7164 			cast_lightning(&wpos, x, y);
7165 		}
7166 	}
7167 
7168 #ifndef CLIENT_SIDE_WEATHER
7169 	/* Process server-side weather */
7170 	process_weather_effect_creation();
7171 #endif
7172 
7173 	/* Process server-side visual special fx */
7174 	if (season_newyearseve && fireworks && !(turn % (cfg.fps / 4)))
7175 		process_firework_creation();
7176 
7177 
7178 
7179 	/* Do some beginning of turn processing for each player */
7180 	for (i = 1; i <= NumPlayers; i++) {
7181 		p_ptr = Players[i];
7182 		if (p_ptr->conn == NOT_CONNECTED)
7183 			continue;
7184 
7185 		/* Print queued log messages (anti-spam feature) - C. Blue */
7186 		if (p_ptr->last_gold_drop && turn - p_ptr->last_gold_drop_timer >= cfg.fps * 2) {
7187 			s_printf("Gold dropped (%d by %s at %d,%d,%d) [anti-spam].\n", p_ptr->last_gold_drop, p_ptr->name, p_ptr->wpos.wx, p_ptr->wpos.wy, p_ptr->wpos.wz);
7188 			p_ptr->last_gold_drop = 0;
7189 			p_ptr->last_gold_drop_timer = turn;
7190 		}
7191 
7192 #if 0
7193 			/* experimental water animation, trying to not be obnoxious -
7194 			   strategy: pick a random grid, if it's water, redraw it */
7195 			cave_type **zcave = getcave(&p_ptr->wpos);
7196 			if (zcave) {
7197 				int x = rand_int(p_ptr->panel_col_max - p_ptr->panel_col_min) + p_ptr->panel_col_min;
7198 				int y = rand_int(p_ptr->panel_row_max - p_ptr->panel_row_min) + p_ptr->panel_row_min;
7199 				lite_spot(i, y, x);
7200  #if 0
7201 				struct dun_level *l_ptr = getfloor(&p_ptr->wpos);
7202 				/* outside? */
7203 				if (!l_ptr) {
7204 					int x = rand_int(MAX_WID), y = rand_int(MAX_HGT);
7205 					if (zcave[y][x].feat == FEAT_DEEP_WATER ||
7206 					    zcave[y][x].feat == FEAT_SHAL_WATER)
7207 						lite_spot(i, y, x);
7208 				/* inside? */
7209 				} else {
7210 					int x = rand_int(l_ptr->wid), y = rand_int(l_ptr->hgt);
7211 					if (zcave[y][x].feat == FEAT_DEEP_WATER ||
7212 					    zcave[y][x].feat == FEAT_SHAL_WATER)
7213 						lite_spot(i, y, x);
7214 				}
7215  #endif
7216 			}
7217 #endif
7218 
7219 #ifdef ENABLE_SELF_FLASHING
7220 		/* Check for hilite */
7221 		if (p_ptr->flash_self > 0 && !(turn % (cfg.fps / 15))) {
7222 			p_ptr->flash_self--;
7223 			everyone_lite_spot(&p_ptr->wpos, p_ptr->py, p_ptr->px);
7224 		} else
7225 #endif
7226 		if (!(turn % (cfg.fps / 6))) {
7227 			/* Play server-side animations (consisting of cycling/random colour choices,
7228 			   instead of animated colours which are circled client-side) */
7229 			/* Flicker invisible player? (includes colour animation!) */
7230 //			if (p_ptr->invis) update_player(i);
7231 			if (p_ptr->invis) {
7232 				update_player_flicker(i);
7233 				update_player(i);
7234 			}
7235 			/* Otherwise only take care of colour animation */
7236 //			else { /* && p_ptr->body_monster */
7237 				everyone_lite_spot(&p_ptr->wpos, p_ptr->py, p_ptr->px);
7238 //			}
7239 		}
7240 
7241 		/* Do non-self-related animations and checks too */
7242 		if (!(turn % (cfg.fps / 6))) {
7243 #ifdef TELEPORT_SURPRISES
7244 			/* Teleport-surprise-effect against monsters */
7245 			if (p_ptr->teleported) p_ptr->teleported--;
7246 #endif
7247 		}
7248 
7249 		/* Perform beeping players who are currently being paged by others */
7250 		if (p_ptr->paging && !(turn % (cfg.fps / 4))) {
7251 			Send_beep(i);
7252 			p_ptr->paging--;
7253 		}
7254 
7255 		/* Actually process that player */
7256 		process_player_begin(i);
7257 	}
7258 
7259 	/* Process spell effects */
7260 	process_effects();
7261 
7262 	/* Process projections' teleportation effects on monsters */
7263 	for (i = 0; i < m_top; i++)
7264 		if (m_list[m_fast[i]].do_dist) {
7265 			teleport_away(m_fast[i], m_list[m_fast[i]].do_dist);
7266 			m_list[m_fast[i]].do_dist = FALSE;
7267 		}
7268 
7269 #ifdef FLUENT_ARTIFACT_RESETS
7270 	/* handle in 1-minute resolution - assume we have less artifacts than 60*cfg.fps */
7271 	i = turn % (cfg.fps * 60);
7272 	if (!cfg.persistent_artifacts && i < max_a_idx && a_info[i].timeout > 0) {
7273  #ifdef IDDC_ARTIFACT_FAST_TIMEOUT
7274 		if (a_info[i].iddc) {
7275 			a_info[i].timeout -= 2;
7276 			if (a_info[i].timeout == -1) a_info[i].timeout = 0;
7277 		} else
7278  #endif
7279  #ifdef WINNER_ARTIFACT_FAST_TIMEOUT
7280 		if (a_info[i].winner) {
7281 			a_info[i].timeout -= 2;
7282 			if (a_info[i].timeout == -1) a_info[i].timeout = 0;
7283 		} else
7284  #endif
7285 		a_info[i].timeout--;
7286 
7287 		if (a_info[i].timeout == 0) erase_artifact(i);
7288 		else if (a_info[i].timeout == FLUENT_ARTIFACT_WARNING) {
7289 			int j, k;
7290 			char o_name[ONAME_LEN];
7291 			for (j = 1; j <= NumPlayers; j++) {
7292 				p_ptr = Players[j];
7293 				if (p_ptr->id != a_info[i].carrier) continue;
7294 				if (p_ptr->conn == NOT_CONNECTED) continue;
7295 				for (k = 0; k < INVEN_TOTAL; k++) {
7296 					if (!p_ptr->inventory[k].k_idx) continue;
7297 					if (p_ptr->inventory[k].name1 != i) continue;
7298 					if (!(p_ptr->inventory[k].ident & ID_MENTAL)) continue;
7299 					object_desc(j, o_name, &p_ptr->inventory[k], TRUE, 128);
7300 					msg_format(j, "\374\377RYour %s will vanish soon!", o_name);
7301 					j = NumPlayers;
7302 					break;
7303 				}
7304 			}
7305 		}
7306 	}
7307 #endif
7308 
7309 	/* Process all of the monsters */
7310 	if (!(turn % MONSTER_TURNS))
7311 		process_monsters();
7312 
7313 	/* Process programmable NPCs */
7314 	if (!(turn % NPC_TURNS))
7315 		process_npcs();
7316 
7317 	/* Process all of the objects */
7318 	if ((turn % 10) == 5) process_objects();
7319 
7320 	/* Process the world */
7321 	if (!(turn % 50)) {
7322 		if (cfg.runlevel < 6 && time(NULL) - cfg.closetime > 120)
7323 			set_runlevel(cfg.runlevel - 1);
7324 
7325 		if (cfg.runlevel < 5) {
7326 			for (i = NumPlayers; i > 0 ;i--) {
7327 				if (Players[i]->conn == NOT_CONNECTED) continue;
7328 				if (Players[i]->wpos.wz != 0) break;
7329 			}
7330 			if (!i) set_runlevel(0);
7331 		}
7332 
7333 		if (cfg.runlevel == 2049) {
7334 			shutdown_server();
7335 		} else if (cfg.runlevel == 2052) {
7336 			/* same as /shutdown 0, except server will return -2 instead of -1.
7337 			   can be used by scripts to initiate maintenance downtime etc. */
7338 			set_runlevel(-1);
7339 
7340 			/* paranoia - set_runlevel() will call exit() */
7341 			time(&cfg.closetime);
7342 			return;
7343 		} else if (cfg.runlevel == 2051) {
7344 			int n = 0;
7345 			for (i = NumPlayers; i > 0 ;i--) {
7346 				p_ptr = Players[i];
7347 				if (p_ptr->conn == NOT_CONNECTED) continue;
7348 				/* Ignore admins that are loged in */
7349 				if (admin_p(i)) continue;
7350 				/* count players */
7351 				n++;
7352 
7353 				/* Ignore characters that are afk and not in a dungeon/tower */
7354 //				if((p_ptr->wpos.wz == 0) && (p_ptr->afk)) continue;
7355 
7356 				/* Ignore chars in fixed irondeepdive towns */
7357 				if (is_fixed_irondeepdive_town(&p_ptr->wpos, getlevel(&p_ptr->wpos))) continue;
7358 #ifdef IRONDEEPDIVE_EXTRA_FIXED_TOWNS
7359 				if (is_extra_fixed_irondeepdive_town(&p_ptr->wpos, getlevel(&p_ptr->wpos))) continue;
7360 #endif
7361 
7362 				/* extra, just for /shutempty: Ignore all iddc chars who are afk/idle */
7363 				if (SHUTDOWN_IGNORE_IDDC(p_ptr)) continue;
7364 
7365 				/* Ignore characters that are not in a dungeon/tower */
7366 				if (p_ptr->wpos.wz == 0) {
7367 					/* Don't interrupt events though */
7368 					if (p_ptr->wpos.wx != WPOS_SECTOR00_X || p_ptr->wpos.wy != WPOS_SECTOR00_Y || !sector00separation) continue;
7369 				}
7370 				break;
7371 			}
7372 			if (!i && (n <= 3)) {
7373 				msg_broadcast(-1, "\374\377G<<<\377oServer is being updated, but will be up again in no time.\377G>>>");
7374 				cfg.runlevel = 2049;
7375 			}
7376 		}
7377 #ifdef ENABLE_GO_GAME
7378 		else if (cfg.runlevel == 2048 && !go_game_up) {
7379 #else
7380 		else if (cfg.runlevel == 2048) {
7381 #endif
7382 			for (i = NumPlayers; i > 0 ;i--) {
7383 				p_ptr = Players[i];
7384 				if (p_ptr->conn == NOT_CONNECTED) continue;
7385 
7386 				/* Ignore admins that are loged in */
7387 				if (admin_p(i)) continue;
7388 
7389 				/* Ignore chars in fixed irondeepdive towns */
7390 				if (is_fixed_irondeepdive_town(&p_ptr->wpos, getlevel(&p_ptr->wpos))) continue;
7391 #ifdef IRONDEEPDIVE_EXTRA_FIXED_TOWNS
7392 				if (is_extra_fixed_irondeepdive_town(&p_ptr->wpos, getlevel(&p_ptr->wpos))) continue;
7393 #endif
7394 
7395 				/* extra, just for /shutempty: Ignore all iddc chars who are afk/idle */
7396 				if (SHUTDOWN_IGNORE_IDDC(p_ptr)) continue;
7397 
7398 				/* Ignore characters that are afk and not in a dungeon/tower */
7399 //				if((p_ptr->wpos.wz == 0) && (p_ptr->afk)) continue;
7400 
7401 				/* Ignore characters that are not in a dungeon/tower */
7402 				if (p_ptr->wpos.wz == 0) {
7403 					/* Don't interrupt events though */
7404 					if (p_ptr->wpos.wx != WPOS_SECTOR00_X || p_ptr->wpos.wy != WPOS_SECTOR00_Y || !sector00separation) continue;
7405 				}
7406 				break;
7407 			}
7408 			if (!i) {
7409 				msg_broadcast(-1, "\374\377G<<<\377oServer is being updated, but will be up again in no time.\377G>>>");
7410 				cfg.runlevel = 2049;
7411 			}
7412 		} else if (cfg.runlevel == 2047) {
7413 			int n = 0;
7414 			for (i = NumPlayers; i > 0 ;i--) {
7415 				p_ptr = Players[i];
7416 				if (p_ptr->conn == NOT_CONNECTED) continue;
7417 				/* Ignore admins that are loged in */
7418 				if (admin_p(i)) continue;
7419 				/* count players */
7420 				n++;
7421 
7422 				/* Ignore characters that are afk and not in a dungeon/tower */
7423 //				if((p_ptr->wpos.wz == 0) && (p_ptr->afk)) continue;
7424 
7425 				/* Ignore chars in fixed irondeepdive towns */
7426 				if (is_fixed_irondeepdive_town(&p_ptr->wpos, getlevel(&p_ptr->wpos))) continue;
7427 #ifdef IRONDEEPDIVE_EXTRA_FIXED_TOWNS
7428 				if (is_extra_fixed_irondeepdive_town(&p_ptr->wpos, getlevel(&p_ptr->wpos))) continue;
7429 #endif
7430 
7431 				/* extra, just for /shutempty: Ignore all iddc chars who are afk/idle */
7432 				if (SHUTDOWN_IGNORE_IDDC(p_ptr)) continue;
7433 
7434 				/* Ignore characters that are not in a dungeon/tower */
7435 				if (p_ptr->wpos.wz == 0) {
7436 					/* Don't interrupt events though */
7437 					if (p_ptr->wpos.wx != WPOS_SECTOR00_X || p_ptr->wpos.wy != WPOS_SECTOR00_Y || !sector00separation) continue;
7438 				}
7439 				break;
7440 			}
7441 			if (!i && (n <= 8)) {
7442 				msg_broadcast(-1, "\374\377G<<<\377oServer is being updated, but will be up again in no time.\377G>>>");
7443 				cfg.runlevel = 2049;
7444 			}
7445 		} else if (cfg.runlevel == 2046) {
7446 			int n = 0;
7447 			for (i = NumPlayers; i > 0 ;i--) {
7448 				p_ptr = Players[i];
7449 				if (p_ptr->conn == NOT_CONNECTED) continue;
7450 				/* Ignore admins that are loged in */
7451 				if (admin_p(i)) continue;
7452 				/* count players */
7453 				n++;
7454 
7455 				/* Ignore characters that are afk and not in a dungeon/tower */
7456 //				if((p_ptr->wpos.wz == 0) && (p_ptr->afk)) continue;
7457 
7458 				/* Ignore chars in fixed irondeepdive towns */
7459 				if (is_fixed_irondeepdive_town(&p_ptr->wpos, getlevel(&p_ptr->wpos))) continue;
7460 #ifdef IRONDEEPDIVE_EXTRA_FIXED_TOWNS
7461 				if (is_extra_fixed_irondeepdive_town(&p_ptr->wpos, getlevel(&p_ptr->wpos))) continue;
7462 #endif
7463 
7464 				/* extra, just for /shutempty: Ignore all iddc chars who are afk/idle */
7465 				if (SHUTDOWN_IGNORE_IDDC(p_ptr)) continue;
7466 
7467 				/* Ignore characters that are not in a dungeon/tower */
7468 				if (p_ptr->wpos.wz == 0) {
7469 					/* Don't interrupt events though */
7470 					if (p_ptr->wpos.wx != WPOS_SECTOR00_X || p_ptr->wpos.wy != WPOS_SECTOR00_Y || !sector00separation) continue;
7471 				}
7472 				break;
7473 			}
7474 			if (!i && (n <= 5)) {
7475 				msg_broadcast(-1, "\374\377G<<<\377oServer is being updated, but will be up again in no time.\377G>>>");
7476 				cfg.runlevel = 2049;
7477 			}
7478 		} else if (cfg.runlevel == 2045) {
7479 			int n = 0;
7480 			for (i = NumPlayers; i > 0 ;i--) {
7481 				if (Players[i]->conn == NOT_CONNECTED) continue;
7482 				/* Ignore admins that are loged in */
7483 				if (admin_p(i)) continue;
7484 				/* count players */
7485 				n++;
7486 			}
7487 			if (!n) {
7488 				msg_broadcast(-1, "\374\377G<<<\377oServer is being updated, but will be up again in no time.\377G>>>");
7489 				cfg.runlevel = 2049;
7490 			}
7491 		} else if (cfg.runlevel == 2044) {
7492 			int n = 0;
7493 			for (i = NumPlayers; i > 0 ;i--) {
7494 				p_ptr = Players[i];
7495 				if (p_ptr->conn == NOT_CONNECTED) continue;
7496 
7497 				/* Ignore admins that are loged in */
7498 				if (admin_p(i)) continue;
7499 
7500 				/* Ignore perma-afk players! */
7501 				//if (p_ptr->afk &&
7502 				if (is_inactive(i) >= 30 * 20) /* 20 minutes idle? */
7503 					continue;
7504 
7505 				/* count players */
7506 				n++;
7507 
7508 				/* Ignore characters that are afk and not in a dungeon/tower */
7509 //				if((p_ptr->wpos.wz == 0) && (p_ptr->afk)) continue;
7510 
7511 				/* Ignore chars in fixed irondeepdive towns */
7512 				if (is_fixed_irondeepdive_town(&p_ptr->wpos, getlevel(&p_ptr->wpos))) continue;
7513 #ifdef IRONDEEPDIVE_EXTRA_FIXED_TOWNS
7514 				if (is_extra_fixed_irondeepdive_town(&p_ptr->wpos, getlevel(&p_ptr->wpos))) continue;
7515 #endif
7516 
7517 				/* Ignore characters that are not in a dungeon/tower */
7518 				if (p_ptr->wpos.wz == 0) {
7519 					/* Don't interrupt events though */
7520 					if (p_ptr->wpos.wx != WPOS_SECTOR00_X || p_ptr->wpos.wy != WPOS_SECTOR00_Y || !sector00separation) continue;
7521 				}
7522 				break;
7523 			}
7524 			if (!i && (n <= 6)) {
7525 				msg_broadcast(-1, "\374\377G<<<\377oServer is being updated, but will be up again in no time.\377G>>>");
7526 				cfg.runlevel = 2049;
7527 			}
7528 		}
7529 
7530 		if (cfg.runlevel == 2043 || cfg.runlevel == 2042) {
7531 			if (shutdown_recall_timer <= 60 && shutdown_recall_state < 3) {
7532 				msg_broadcast(0, "\374\377I*** \377RServer shutdown in max 1 minute (auto-recall). \377I***");
7533 				shutdown_recall_state = 3;
7534 			}
7535 			else if (shutdown_recall_timer <= 300 && shutdown_recall_state < 2) {
7536 				msg_broadcast(0, "\374\377I*** \377RServer shutdown in max 5 minutes (auto-recall). \377I***");
7537 				shutdown_recall_state = 2;
7538 			}
7539 			else if (shutdown_recall_timer <= 900 && shutdown_recall_state < 1) {
7540 				msg_broadcast(0, "\374\377I*** \377RServer shutdown in max 15 minutes (auto-recall). \377I***");
7541 				shutdown_recall_state = 1;
7542 			}
7543 			if (!shutdown_recall_timer) {
7544 				for (i = NumPlayers; i > 0 ;i--) {
7545 					p_ptr = Players[i];
7546 					if (p_ptr->conn == NOT_CONNECTED) continue;
7547 
7548 					/* Don't remove loot from ghosts waiting for res */
7549 					if (admin_p(i) || p_ptr->ghost) continue;
7550 
7551 					/* Don't free people from the Ironman Deep Dive Challenge */
7552 					if (in_irondeepdive(&p_ptr->wpos)) continue;
7553 
7554 					if (p_ptr->wpos.wz) {
7555 						p_ptr->recall_pos.wx = p_ptr->wpos.wx;
7556 						p_ptr->recall_pos.wy = p_ptr->wpos.wy;
7557 						p_ptr->recall_pos.wz = 0;
7558 						p_ptr->new_level_method = (p_ptr->wpos.wz > 0 ? LEVEL_RECALL_DOWN : LEVEL_RECALL_UP);
7559 						recall_player(i, "");
7560 					}
7561 				}
7562 				if (cfg.runlevel == 2043) {
7563 					msg_broadcast(-1, "\374\377G<<<\377oServer is being updated, but will be up again in no time.\377G>>>");
7564 					cfg.runlevel = 2049;
7565 				} else { //if (cfg.runlevel == 2042) {
7566 					msg_broadcast(-1, "\374\377G<<<\377oServer is now going down for maintenance.\377G>>>");
7567 					cfg.runlevel = 2052;
7568 				}
7569 			} else {
7570 				for (i = NumPlayers; i > 0 ;i--) {
7571 					p_ptr = Players[i];
7572 					if (p_ptr->conn == NOT_CONNECTED) continue;
7573 
7574 					/* Ignore admins that are loged in */
7575 					if (admin_p(i)) continue;
7576 
7577 					/* Ignore chars in fixed irondeepdive towns */
7578 					if (is_fixed_irondeepdive_town(&p_ptr->wpos, getlevel(&p_ptr->wpos))) continue;
7579 #ifdef IRONDEEPDIVE_EXTRA_FIXED_TOWNS
7580 					if (is_extra_fixed_irondeepdive_town(&p_ptr->wpos, getlevel(&p_ptr->wpos))) continue;
7581 #endif
7582 
7583 					/* Ignore characters that are afk and not in a dungeon/tower */
7584 //						if((p_ptr->wpos.wz == 0) && (p_ptr->afk)) continue;
7585 
7586 					/* Ignore characters that are not in a dungeon/tower */
7587 					if(p_ptr->wpos.wz == 0) {
7588 						/* Don't interrupt events though */
7589 						if (p_ptr->wpos.wx != WPOS_SECTOR00_X || p_ptr->wpos.wy != WPOS_SECTOR00_Y || !sector00separation) continue;
7590 					}
7591 					break;
7592 				}
7593 				if (!i) {
7594 					if (cfg.runlevel == 2043) {
7595 						msg_broadcast(-1, "\374\377G<<<\377oServer is being updated, but will be up again in no time.\377G>>>");
7596 						cfg.runlevel = 2049;
7597 					} else { //if (cfg.runlevel == 2042)
7598 						msg_broadcast(-1, "\374\377G<<<\377oServer is now going down for maintenance.\377G>>>");
7599 						cfg.runlevel = 2052;
7600 					}
7601 				}
7602 			}
7603 		}
7604 
7605 		/* Hack -- Compact the object list occasionally */
7606 		if (o_top + 160 > MAX_O_IDX) compact_objects(320, TRUE);
7607 
7608 		/* Hack -- Compact the monster list occasionally */
7609 		if (m_top + 320 > MAX_M_IDX) compact_monsters(640, TRUE);
7610 
7611 		/* Hack -- Compact the trap list occasionally */
7612 //		if (t_top + 160 > MAX_TR_IDX) compact_traps(320, TRUE);
7613 
7614 		/* Tell a day passed */
7615 //		if (((turn + (DAY_START * 10L)) % (10L * DAY)) == 0)
7616 		if (!(turn % DAY)) { /* midnight */
7617 			char buf[20];
7618 
7619 			snprintf(buf, 20, "%s", get_day(bst(YEAR, turn))); /* hack: abuse get_day()'s capabilities */
7620 			msg_broadcast_format(0,
7621 				"\377GToday it is %s of the %s year of the third age.",
7622 				get_month_name(bst(DAY, turn), FALSE, FALSE), buf);
7623 
7624 #ifdef MUCHO_RUMOURS
7625 	        	/* the_sandman prints a rumour */
7626 		        if (NumPlayers) {
7627 				msg_print(1, "Suddenly a thought comes to your mind:");
7628 				fortune(1, TRUE);
7629 			}
7630 #endif
7631 		}
7632 
7633 		for (i = 1; i < NumPlayers + 1; i++) {
7634 			if (Players[i]->conn == NOT_CONNECTED)
7635 				continue;
7636 
7637 			/* Process the world of that player */
7638 			process_world(i);
7639 		}
7640 	}
7641 
7642 	/* Clean up Bree regularly to prevent too dangerous towns in which weaker characters cant move around */
7643 //	if (!(turn % 650000)) { /* 650k ~ 3hours */
7644 //	if (!(turn % (cfg.fps * 3600))) { /* 1 h */
7645 	if (!(turn % (cfg.fps * 600))) { /* new timing after function was changed to "thin_surface_spawns()" */
7646 		thin_surface_spawns();
7647 //spam		s_printf("%s Surface spawns thinned.\n", showtime());
7648 	}
7649 
7650 	/* Process everything else */
7651 	if (!(turn % 10)) {
7652 		process_various();
7653 
7654 		/* Hack -- Regenerate the monsters every hundred game turns */
7655 		if (!(turn % 100)) regen_monsters();
7656 
7657 		/* process delayed requests */
7658 		for (i = 1; i <= NumPlayers; i++) {
7659 			p_ptr = Players[i];
7660 			if (p_ptr->delay_str) {
7661 				p_ptr->delay_str -= 10;
7662 				if (p_ptr->delay_str <= 0) {
7663 					p_ptr->delay_str = 0;
7664 					Send_request_str(i, p_ptr->delay_str_id, p_ptr->delay_str_prompt, p_ptr->delay_str_std);
7665 				}
7666 			}
7667 			if (p_ptr->delay_cfr) {
7668 				p_ptr->delay_cfr -= 10;
7669 				if (p_ptr->delay_cfr <= 0) {
7670 					p_ptr->delay_cfr = 0;
7671 					Send_request_cfr(i, p_ptr->delay_cfr_id, p_ptr->delay_cfr_prompt, p_ptr->delay_cfr_default_yes);
7672 				}
7673 			}
7674 		}
7675 	}
7676 
7677 #ifdef DUNGEON_VISIT_BONUS
7678 	/* Keep track of frequented dungeons, every minute */
7679 	if (!(turn % (cfg.fps * 60))) {
7680 		dungeon_type *d_ptr;
7681 		wilderness_type *w_ptr;
7682 # ifdef DUNGEON_VISIT_BONUS_DEPTHRANGE
7683 		int depthrange;
7684 # endif
7685 
7686 		for (i = 1; i < NumPlayers + 1; i++) {
7687 			p_ptr = Players[i];
7688 			if (p_ptr->conn == NOT_CONNECTED) continue;
7689 
7690 			if (p_ptr->wpos.wz == 0) continue;
7691 			w_ptr = &wild_info[p_ptr->wpos.wy][p_ptr->wpos.wx];
7692 			if (p_ptr->wpos.wz < 0) d_ptr = w_ptr->dungeon;
7693 			else if (p_ptr->wpos.wz > 0) d_ptr = w_ptr->tower;
7694 			else continue; //paranoia
7695 
7696 # if 0
7697 			/* NOTE: We're currently counting up for -each- player in there.
7698 			   Maybe should be changed to generic 'visited or not visited'. */
7699 			if (dungeon_visit_frequency[d_ptr->id] < VISIT_TIME_CAP)
7700 				dungeon_visit_frequency[d_ptr->id]++;
7701 # else
7702 			/* NOTE about NOTE: Not anymore. Now # of players doesn't matter: */
7703 			if (dungeon_visit_frequency[d_ptr->id] < VISIT_TIME_CAP)
7704 				dungeon_visit_check[d_ptr->id] = TRUE;
7705 # endif
7706 
7707 # ifdef DUNGEON_VISIT_BONUS_DEPTHRANGE
7708 			/* Also keep track of which depths are mostly frequented */
7709 			depthrange = getlevel(&p_ptr->wpos) / 10;
7710 			/* Excempt Valinor (dlv 200) */
7711 			if (depthrange < 20
7712 			    && depthrange_visited[depthrange] < VISIT_TIME_CAP);
7713 				depthrange_visited[depthrange]++;
7714 # endif
7715 		}
7716 
7717 # if 1
7718 		for (i = 1; i <= dungeon_id_max; i++)
7719 			if (dungeon_visit_check[i]) {
7720 				dungeon_visit_check[i] = FALSE;
7721 				dungeon_visit_frequency[i]++;
7722 			}
7723 # endif
7724 	}
7725 	/* Decay visit frequency for all dungeons over time. */
7726 	/* Also update the 'rest bonus' each dungeon gives:
7727 	   Use <startfloor + 2/3 * (startfloor-endfloor)> as main comparison value. */
7728 	if (!(turn % (cfg.fps * 60 * 10))) {
7729 # ifdef DUNGEON_VISIT_BONUS_DEPTHRANGE
7730 		for (i = 0; i < 20; i++) {
7731 			if (depthrange_visited[i])
7732 				depthrange_visited[i]--;
7733 
7734 			/* update the depth-range scale in regards to its most contributing dungeon */
7735 			//todo; see below
7736 		}
7737 # endif
7738 		for (i = 1; i <= dungeon_id_max; i++) {
7739 			if (dungeon_visit_frequency[i])
7740 				dungeon_visit_frequency[i]--;
7741 
7742 			/* update bonus of this dungeon */
7743 # ifdef DUNGEON_VISIT_BONUS_DEPTHRANGE
7744 			/* more sophisticated algoritm.
7745 			   Todo: find a good way how to do this :-p.
7746 			   Idea (C. Blue):
7747 			   players increase the depthrange_visited counter for the dlvl they are on,
7748 			   dungeons then compare it with their average depth (which is as stated above
7749 			   start + 2/3 * (end-start) floor), and only start counting as "not visited"
7750 			   if the dungeon depths that ARE visited actually are comparable to the
7751 			   avg depth of the dungeon in question.
7752 			   Main problem: Handle multiple dungeons adding to the same depthrange in
7753 			   pretty different scales, eg 'player A is all the time in dungeon A which
7754 			   only is lvl 1-9, while player B spends even much more time in the very first
7755 			   level of dungeon B which goes from lvl 1-49. Now how are the numbers scaled
7756 			   down to determine the actual 'visitedness' of dungeon A for example? */
7757 # endif
7758 
7759 			/* straightforward simple way without DUNGEON_VISIT_BONUS_DEPTHRANGE */
7760 			set_dungeon_bonus(i, FALSE);
7761 		}
7762 	}
7763 #endif
7764 
7765 	/* Process day/night changes on world_surface */
7766 	if (!(turn % HOUR)) process_day_and_night();
7767 
7768 	/* Refresh everybody's displays */
7769 	for (i = 1; i < NumPlayers + 1; i++) {
7770 		p_ptr = Players[i];
7771 
7772 		if (p_ptr->conn == NOT_CONNECTED)
7773 			continue;
7774 
7775 		/* Notice stuff */
7776 		if (p_ptr->notice) notice_stuff(i);
7777 
7778 		/* Update stuff */
7779 		if (p_ptr->update) update_stuff(i);
7780 
7781 		/* Redraw stuff */
7782 		if (p_ptr->redraw) redraw_stuff(i);
7783 
7784 		/* Window stuff */
7785 		if (p_ptr->window) window_stuff(i);
7786 	}
7787 
7788 	/* Animate player's @ in his own view here on server side */
7789 	/* This animation is only for mana shield / GOI indication */
7790 	if (!(turn % 5))
7791 	for (i = 1; i < NumPlayers + 1; i++) {
7792 		/* Colour animation is done in lite_spot */
7793 		lite_spot(i, Players[i]->py, Players[i]->px);
7794 	}
7795 
7796 	/* Process debugging/helper functions - C. Blue */
7797 	if (store_debug_mode &&
7798 	    /* '/ 10 ' stands for quick motion, ie time * 10 */
7799 	    (!(turn % ((store_debug_mode * (10L * cfg.store_turns)) / store_debug_quickmotion))))
7800 		store_debug_stock();
7801 
7802 #ifdef ARCADE_SERVER
7803 	/* Process special Arcade Server things */
7804         if (turn % (cfg.fps / 3) == 1) exec_lua(1, "firin()");
7805         if (turn % tron_speed == 1) exec_lua(1, "tron()");
7806 #endif
7807 
7808 #ifdef ENABLE_GO_GAME
7809 	/* Process Go AI engine communication (its replies) */
7810 	if (go_engine_processing) go_engine_process();
7811 #endif
7812 
7813 	/* Send any information over the network */
7814 	Net_output();
7815 }
7816 
7817 void set_runlevel(int val) {
7818 	//static bool meta = TRUE;
7819 
7820 	switch(val) {
7821 		case -1:
7822 			/* terminate: return a value that lets a script know that
7823 			   it must not restart us. */
7824 			cfg.runlevel = -1;
7825 			s_printf("***SERVER MAINTENANCE TERMINATION***\n");
7826 		case 0:
7827 			shutdown_server();
7828 		case 1:
7829 			/* Logout all remaining players except admins */
7830 			msg_broadcast(0, "\377rServer shutdown imminent!");
7831 			break;
7832 		case 2:
7833 			/* Force recalling of all players to town if
7834 			   configured */
7835 			msg_broadcast(0, "\377rServer about to close down. Recall soon");
7836 			break;
7837 		case 3:
7838 			/* Hide from the meta - server socket still open */
7839 			Report_to_meta(META_DIE);
7840 			//meta = FALSE;
7841 			msg_broadcast(0, "\377rServer will close soon.");
7842 			break;
7843 		case 4:
7844 			/* Dungeons are closed */
7845 			msg_broadcast(0, "\377yThe dungeons are now closed.");
7846 			break;
7847 		case 5:
7848 			/* Shutdown warning mode, automatic timer */
7849 //			msg_broadcast(0, "\377yWarning. Server shutdown will take place in five minutes.");
7850 			msg_broadcast(0, "\374\377yWarning. Server shutdown will take place in ten minutes.");
7851 			break;
7852 		case 1024:
7853 			Report_to_meta(META_DIE);
7854 			//meta = FALSE;
7855 			break;
7856 			/* Hack -- character edit (possessor) mode */
7857 		case 2042:
7858 		case 2043:
7859 		case 2044:
7860 		case 2045:
7861 		case 2046:
7862 		case 2047:
7863 		case 2048:
7864 		case 2051:
7865 			/* Shutdown as soon as server is empty (admins don't count) */
7866 			break;
7867 		case 2049:
7868 			/* Usually not called here - just a temporary hack value (see dungeon.c) */
7869 			shutdown_server();
7870 			break;
7871 		case 6:
7872 			/* Running */
7873 		default:
7874 			/* Cancelled shutdown */
7875 			if (cfg.runlevel != 6)
7876 				msg_broadcast(0, "\377GServer shutdown cancelled.");
7877 			Report_to_meta(META_START);
7878 			//meta = TRUE;
7879 			val = 6;
7880 			break;
7881 	}
7882 	time(&cfg.closetime);
7883 	cfg.runlevel = val;
7884 }
7885 
7886 /*
7887  * Actually play a game
7888  *
7889  * If the "new_game" parameter is true, then, after loading the
7890  * server-specific savefiles, we will start anew.
7891  */
7892 void play_game(bool new_game, bool all_terrains, bool dry_Bree, bool new_wilderness, bool new_flavours, bool new_houses) {
7893 	int h = 0, m = 0, s = 0, dwd = 0, dd = 0, dm = 0, dy = 0;
7894 	time_t now;
7895 	struct tm *tmp;
7896 	//int i, n;
7897 
7898 	/* Init the RNG */
7899 	// Is it a good idea ? DGDGDGD --  maybe FIXME
7900 	//	if (Rand_quick)
7901 	{
7902 		u32b seed;
7903 
7904 		/* Basic seed */
7905 		seed = (time(NULL));
7906 
7907 #ifdef SET_UID
7908 
7909 		/* Mutate the seed on Unix machines */
7910 		seed = ((seed >> 3) * (getpid() << 1));
7911 
7912 #endif
7913 
7914 		/* Use the complex RNG */
7915 		Rand_quick = FALSE;
7916 
7917 		/* Seed the "complex" RNG */
7918 		Rand_state_init(seed);
7919 	}
7920 
7921 	/*** Init the wild_info array... for more information see wilderness.c ***/
7922 	init_wild_info();
7923 
7924 	/* Load list of banned players */
7925 	load_banlist();
7926 
7927 	/* Attempt to load the server state information */
7928 	if (!load_server_info()) {
7929 		/* Oops */
7930 		quit("broken server savefile(s)");
7931 	}
7932 
7933 	/* Nothing loaded */
7934 	if (!server_state_loaded) {
7935 		/* Make server state info */
7936 		new_game = TRUE;
7937 
7938 		/* Create a new dungeon */
7939 		server_dungeon = FALSE;
7940 	}
7941 	else server_dungeon = TRUE;
7942 
7943 	/* Roll new town */
7944 	if (new_game) {
7945 		/* Ignore the dungeon */
7946 		server_dungeon = FALSE;
7947 
7948 		/* Start in town */
7949 		/* dlev = 0;*/
7950 
7951 		/* Hack -- seed for flavors */
7952 		seed_flavor = rand_int(0x10000000);
7953 
7954 		/* Hack -- seed for town layout */
7955 		seed_town = rand_int(0x10000000);
7956 
7957 		/* Initialize server state information */
7958 		server_birth();
7959 
7960 		/* Generate the wilderness */
7961 		genwild(all_terrains, dry_Bree);
7962 
7963 		/* Generate the towns */
7964 		wild_spawn_towns();
7965 
7966 		/* Create dungeon index info */
7967 		s_printf("Indexing dungeons..\n");
7968 		reindex_dungeons();
7969 
7970 		/* Hack -- force town surrounding types
7971 		 * This really shouldn't be here; just a makeshift and to be
7972 		 * replaced by multiple-town generator */
7973 		//wild_bulldoze();
7974 
7975 		/* Hack -- enter the world */
7976 		turn = 1;
7977 	} else {
7978 		/* use with lua_forget_map() */
7979 		if (new_wilderness) {
7980 			int i, x, y;
7981 			wilderness_type *w_ptr;
7982 			struct dungeon_type *d_ptr;
7983 
7984 			s_printf("Resetting wilderness..\n");
7985 
7986 			/* Hack -- seed for town layout */
7987 			seed_town = rand_int(0x10000000);
7988 
7989 			/* erase all house information and re-init, consistent with init_other() */
7990 			s_printf("  ..erasing old info..\n");
7991 
7992 			/* free old objects (worldmap/houses/monster inventory) */
7993 		        for (i = 0; i < o_max; i++) {
7994 		                /* Skip dead objects */
7995 		                if (!o_list[i].k_idx) continue;
7996 		            	if (true_artifact_p(&o_list[i])) handle_art_d(o_list[i].name1);
7997 				questitem_d(&o_list[i], o_list[i].number);
7998 		        }
7999 		        C_KILL(o_list, MAX_O_IDX, object_type);
8000 		        C_MAKE(o_list, MAX_O_IDX, object_type);
8001 		        o_max = 1;
8002 		        o_nxt = 1;
8003 		        o_top = 0;
8004 
8005 			/* free old monsters */
8006 		        C_KILL(m_list, MAX_M_IDX, monster_type);
8007 		        C_MAKE(m_list, MAX_M_IDX, monster_type);
8008 		        m_max = 1;
8009 		        m_nxt = 1;
8010 		        m_top = 0;
8011 
8012 			/* free old houses[] info */
8013 			for (i = 0; i < num_houses; i++) {
8014 				KILL(houses[i].dna, struct dna_type);
8015 				if (!(houses[i].flags & HF_RECT))
8016 					C_KILL(houses[i].coords.poly, MAXCOORD, char);
8017 #ifndef USE_MANG_HOUSE_ONLY
8018 				C_KILL(houses[i].stock, houses[i].stock_size, object_type);
8019 #endif
8020 			}
8021 			C_KILL(houses, house_alloc, house_type);
8022 		        house_alloc = 1024;
8023 			C_MAKE(houses, house_alloc, house_type);
8024 	                num_houses = 0;
8025 
8026 			/* free old town[] and town[]->store info */
8027 			if (town) {
8028 			        for (i = 0; i < numtowns; i++) dealloc_stores(i);
8029     				C_KILL(town, numtowns, struct town_type);
8030     			}
8031 	                numtowns = 0;
8032 
8033 			/* free old dungeon/tower info */
8034 		        for (y = 0 ;y < MAX_WILD_Y; y++) {
8035 		                for (x = 0; x < MAX_WILD_X; x++) {
8036 		            		w_ptr = &wild_info[y][x];
8037 		                        if (w_ptr->flags & WILD_F_DOWN) {
8038 		                    		d_ptr = w_ptr->dungeon;
8039         	        	                for (i = 0; i < d_ptr->maxdepth; i++) {
8040 	        	                                C_KILL(d_ptr->level[i].uniques_killed, MAX_R_IDX, char);
8041         	            		        }
8042 				                C_KILL(d_ptr->level, d_ptr->maxdepth, struct dun_level);
8043 						KILL(d_ptr, struct dungeon_type);
8044 				        }
8045 		                        if (w_ptr->flags & WILD_F_UP) {
8046 		                    		d_ptr = w_ptr->tower;
8047         	        	                for (i = 0; i < d_ptr->maxdepth; i++) {
8048 	        	                                C_KILL(d_ptr->level[i].uniques_killed, MAX_R_IDX, char);
8049         	            		        }
8050 				                C_KILL(d_ptr->level, d_ptr->maxdepth, struct dun_level);
8051 						KILL(d_ptr, struct dungeon_type);
8052 				        }
8053 				}
8054 			}
8055 
8056 			/*** Init the wild_info array... for more information see wilderness.c ***/
8057 			init_wild_info();
8058 
8059 			/* Ignore the dungeon */
8060 			server_dungeon = FALSE;
8061 
8062 			/* Generate the wilderness */
8063 			s_printf("  ..generating wilderness..\n");
8064 			genwild(all_terrains, dry_Bree);
8065 
8066 			/* Generate the towns */
8067 			s_printf("  ..spawning towns..\n");
8068 			wild_spawn_towns();
8069 
8070 			/* Discard old dungeon index info */
8071 			s_printf("  ..reindexing dungeons..\n");
8072 			reindex_dungeons();
8073 
8074 			s_printf("..done.\n");
8075 		}
8076 		if (new_flavours) {
8077 			/* use with lua_forget_flavours() */
8078 			s_printf("Resetting flavours.\n");
8079 
8080 			/* Hack -- seed for flavors */
8081 			seed_flavor = rand_int(0x10000000);
8082 		}
8083 		if (new_houses) {
8084 			int i;
8085 
8086 			s_printf("Reinitializing houses.\n");
8087 
8088 			/* free old houses[] info */
8089 			for (i = 0; i < num_houses; i++) {
8090 				KILL(houses[i].dna, struct dna_type);
8091 				if (!(houses[i].flags & HF_RECT))
8092 					C_KILL(houses[i].coords.poly, MAXCOORD, char);
8093 #ifndef USE_MANG_HOUSE_ONLY
8094 				C_KILL(houses[i].stock, houses[i].stock_size, object_type);
8095 #endif
8096 			}
8097 			C_KILL(houses, house_alloc, house_type);
8098 		        house_alloc = 1024;
8099 			C_MAKE(houses, house_alloc, house_type);
8100 	                num_houses = 0;
8101 		}
8102 	}
8103 
8104 	/* Initialize wilderness 'level' */
8105 	init_wild_info_aux(0,0);
8106 
8107 
8108 	/* Flash a message */
8109 	s_printf("Please wait...\n");
8110 
8111 	/* Flavor the objects */
8112 	flavor_init();
8113 
8114 	s_printf("Object flavors initialized...\n");
8115 
8116 	/* Reset the visual mappings */
8117 	reset_visuals();
8118 
8119 	/* Make a town if necessary */
8120 	/*
8121 	 * NOTE: The central town of Angband is handled in a special way;
8122 	 * If it was static when saved, we shouldn't allocate it.
8123 	 * If not static, or it's new game, we should allocate it.
8124 	 */
8125 	/*
8126 	 * For sure, we should redesign it for real multiple-towns!
8127 	 * - Jir -
8128 	 */
8129 	if (!server_dungeon) {
8130 		struct worldpos twpos;
8131 		twpos.wx = cfg.town_x;
8132 		twpos.wy = cfg.town_y;
8133 		twpos.wz = 0;
8134 		/* Allocate space for it */
8135 		alloc_dungeon_level(&twpos);
8136 
8137 		/* Actually generate the town */
8138 		generate_cave(&twpos, NULL);
8139 	}
8140 
8141 	/* Finish initializing dungeon monsters */
8142 	setup_monsters();
8143 
8144 	/* Detect and fix wrong monster counts. Important to keep uniques spawnable:
8145 	   Their counts might have been corrupted by panic save or similar crash. */
8146         /* First set all to zero */
8147         for (h = 0; h < MAX_R_IDX; h++) r_info[h].cur_num = 0;
8148         /* Now count how many monsters there are of each race */
8149         for (h = 0; h < m_max; h++)
8150     		if (m_list[h].r_idx) r_info[m_list[h].r_idx].cur_num++;
8151 
8152 	/* Finish initializing dungeon objects */
8153 	setup_objects();
8154 
8155 	/* Server initialization is now "complete" */
8156 	server_generated = TRUE;
8157 
8158 	/* Set up the contact socket, so we can allow players to connect */
8159 	setup_contact_socket();
8160 
8161 	/* Set up the network server */
8162 	if (Setup_net_server() == -1)
8163 		quit("Couldn't set up net server");
8164 
8165 	/* scan for inactive players */
8166 	scan_players();
8167 	scan_accounts();
8168 	scan_houses();
8169 
8170 #if defined CLIENT_SIDE_WEATHER && !defined CLIENT_WEATHER_GLOBAL
8171 	/* initialize weather */
8172 	wild_weather_init();
8173 #endif
8174 
8175 	init_day_and_night();
8176 
8177 	cfg.runlevel = 6;		/* Server is running */
8178 
8179 	/* Set up the main loop */
8180 	install_timer_tick(dungeon, cfg.fps);
8181 
8182 	/* Execute custom startup script - C. Blue */
8183 	time(&now);
8184 	tmp = localtime(&now);
8185 	h = tmp->tm_hour;
8186 	m = tmp->tm_min;
8187 	s = tmp->tm_sec;
8188 	get_date(&dwd, &dd, &dm, &dy);
8189 	exec_lua(0, format("playloop_startup(\"%s\", %d, %d, %d, %d, %d, %d, %d)", showtime(), h, m, s, dwd, dd, dm, dy));
8190 
8191 	quest_handle_disabled_on_startup();
8192 
8193 	/* Loop forever */
8194 	sched();
8195 
8196 	/* This should never, ever happen */
8197 	s_printf("sched returned!!!\n");
8198 
8199 	/* Close stuff */
8200 	close_game();
8201 
8202 	/* Quit */
8203 	quit(NULL);
8204 }
8205 
8206 
8207 void shutdown_server(void) {
8208 	s_printf("Shutting down.\n");
8209 
8210 	/* Kick every player out and save his game */
8211 	while(NumPlayers > 0) {
8212 		/* Note the we always save the first player */
8213 		player_type *p_ptr = Players[1];
8214 
8215 		/* Notify players who are afk and even pseudo-afk rogues */
8216 #if 0 /* always send a page beep? */
8217 		Send_beep(1);
8218 #endif
8219 #if 0 /* only when afk or idle? */
8220 		if (p_ptr->afk) Send_beep(1);
8221 		else if (p_ptr->turns_idle >= cfg.fps * AUTO_AFK_TIMER) Send_beep(1);
8222 #endif
8223 #if 1 /* send a warning sound (usually same as page beep) */
8224 //		sound(1, "warning", "page", SFX_TYPE_NO_OVERLAP, FALSE);
8225 		sound(1, "page", NULL, SFX_TYPE_NO_OVERLAP, FALSE);
8226 #endif
8227 		Net_output1(1);
8228 
8229 		/* Indicate cause */
8230 		strcpy(p_ptr->died_from, "server shutdown");
8231 
8232 		/* Try to save */
8233 		if (!save_player(1)) Destroy_connection(p_ptr->conn, "Server shutdown (save failed)");
8234 
8235 		/* Successful save */
8236 		if (cfg.runlevel == -1)
8237 			Destroy_connection(p_ptr->conn, "Server is undergoing maintenance and may take a little while to restart.");
8238 		else
8239 			Destroy_connection(p_ptr->conn, "Server has been updated, please login again."); /* was "Server shutdown (save succeeded)" */
8240 	}
8241 
8242 	/* Save list of banned players */
8243 	save_banlist();
8244 
8245 	/* Save dynamic quest info */
8246 	save_quests();
8247 
8248 	/* Save the server state */
8249 	if (!save_server_info()) quit("Server state save failed!");
8250 
8251 	/* Tell the metaserver that we're gone */
8252 	Report_to_meta(META_DIE);
8253 
8254 #ifdef ENABLE_GO_GAME
8255 	/* Shut down Go AI engine and its pipes */
8256 	go_engine_terminate();
8257 #endif
8258 
8259 	if (cfg.runlevel == -1)
8260 		quit("Terminating");
8261 	else
8262 		quit("Server state saved");
8263 }
8264 
8265 void pack_overflow(int Ind) {
8266 	player_type *p_ptr = Players[Ind];
8267 
8268 	/* XXX XXX XXX Pack Overflow */
8269 	if (p_ptr->inventory[INVEN_PACK].k_idx) {
8270 		object_type *o_ptr;
8271 		int amt, i, j = 0;
8272 		u32b f1, f2, f3, f4, f5, f6, esp;
8273 		char o_name[ONAME_LEN];
8274 
8275 		/* Choose an item to spill */
8276 		for (i = INVEN_PACK - 1; i >= 0; i--) {
8277 			o_ptr = &p_ptr->inventory[i];
8278 			object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &f6, &esp);
8279 
8280 			if (!check_guard_inscription(o_ptr->note, 'd') &&
8281 			    !((f4 & TR4_CURSE_NO_DROP) && cursed_p(o_ptr)) &&
8282 			    !o_ptr->questor) {
8283 				j = 1;
8284 				break;
8285 			}
8286 		}
8287 
8288 		if (!j) i = INVEN_PACK;
8289 
8290 		/* Access the slot to be dropped */
8291 		o_ptr = &p_ptr->inventory[i];
8292 
8293 		/* Drop all of that item */
8294 		amt = o_ptr->number;
8295 
8296 		/* Disturbing */
8297 		disturb(Ind, 0, 0);
8298 
8299 		/* Warning */
8300 //		msg_print(Ind, "\376\377oYour pack overflows!");
8301 
8302 		/* Describe */
8303 		object_desc(Ind, o_name, o_ptr, TRUE, 3);
8304 
8305 		/* Message */
8306 		msg_format(Ind, "\376\377oYour pack overflows! You drop %s.", o_name);
8307 
8308 #ifdef USE_SOUND_2010
8309 		sound_item(Ind, o_ptr->tval, o_ptr->sval, "pickup_");
8310 #endif
8311 
8312 		/* Drop it (carefully) near the player */
8313 		drop_near_severe(Ind, o_ptr, 0, &p_ptr->wpos, p_ptr->py, p_ptr->px);
8314 
8315 		/* Decrease the item, optimize. */
8316 		inven_item_increase(Ind, i, -amt);
8317 		inven_item_optimize(Ind, i);
8318 	}
8319 }
8320 
8321 /* Handle special timed events that don't fit in /
8322    aren't related to 'Global Events' routines - C. Blue
8323    (To be called every second.)
8324    Now also used for Go minigame. */
8325 void process_timers() {
8326 	struct worldpos wpos;
8327 	cave_type **zcave;
8328 	int y, x, i;
8329 
8330 #ifdef ENABLE_GO_GAME
8331 	/* Process Go AI engine communication (its replies) */
8332 	if (go_game_up) go_engine_clocks();
8333 #endif
8334 
8335 	/* PvP Arena in 0,0 - Release monsters: */
8336 	if (timer_pvparena1) {
8337 		/* check for existence of arena */
8338 		wpos.wx = WPOS_PVPARENA_X;
8339 		wpos.wy = WPOS_PVPARENA_Y;
8340 		wpos.wz = WPOS_PVPARENA_Z;
8341 		if (!(zcave = getcave(&wpos))) return;
8342 
8343 		timer_pvparena1--;
8344 		if (!timer_pvparena1) {
8345 			/* start next countdown */
8346 			timer_pvparena1 = 90; //45 was too fast, disallowing ppl to leave the arena sort of
8347 
8348 			if ((timer_pvparena3 % 2) == 0) { /* cycle preparation? */
8349 				/* clear old monsters and items */
8350 				wipe_m_list(&wpos);
8351 			        wipe_o_list_safely(&wpos);
8352 				/* close all doors */
8353 				for (i = 1; i <= 6; i++) {
8354 					y = 2;
8355 					x = (i * 10) - 3;
8356 					zcave[y][x].feat = FEAT_SEALED_DOOR;
8357 					everyone_lite_spot(&wpos, y, x);
8358 				}
8359 			}
8360 
8361 			if (timer_pvparena3 == 0) { /* prepare first cycle */
8362 				y = 1;
8363 				x = (1 * 10) - 3;
8364 				summon_override_checks = SO_ALL;
8365 				//866 elite uruk, 563 young red dragon
8366 //				place_monster_aux(&wpos, y, x, 866, FALSE, FALSE, 100, 0);
8367 //				place_monster_one(&wpos, y, x, 866, FALSE, FALSE, FALSE, 100, 0);
8368 				place_monster_one(&wpos, y, x, 102, FALSE, FALSE, FALSE, 100, 0);//large k
8369 				x = (2 * 10) - 3;
8370 				//487 storm giant
8371 //				place_monster_aux(&wpos, y, x, 487, FALSE, FALSE, 100, 0);
8372 //				place_monster_one(&wpos, y, x, 563, FALSE, FALSE, FALSE, 100, 0);
8373 				place_monster_one(&wpos, y, x, 249, FALSE, FALSE, FALSE, 100, 0);//light Z(271) //vlasta(249)
8374 				x = (3 * 10) - 3;
8375 				//609 baron of hell
8376 //				place_monster_aux(&wpos, y, x, 590, FALSE, FALSE, 100, 0);
8377 //				place_monster_one(&wpos, y, x, 487, FALSE, FALSE, FALSE, 100, 0);
8378 				place_monster_one(&wpos, y, x, 866, FALSE, FALSE, FALSE, 100, 0);//elite o
8379 				x = (4 * 10) - 3;
8380 				//590 mature gold d
8381 //				place_monster_aux(&wpos, y, x, 720, FALSE, FALSE, 100, 0);
8382 //				place_monster_one(&wpos, y, x, 720, FALSE, FALSE, FALSE, 100, 0);
8383 				place_monster_one(&wpos, y, x, 563, FALSE, FALSE, FALSE, 100, 0);//young red d
8384 				x = (5 * 10) - 3;
8385 				//995 marilith, 558 colossus
8386 //				place_monster_aux(&wpos, y, x, 558, FALSE, FALSE, 100, 0);
8387 //				place_monster_one(&wpos, y, x, 558, FALSE, FALSE, FALSE, 100, 0);
8388 				place_monster_one(&wpos, y, x, 194, FALSE, FALSE, FALSE, 100, 0);//tengu
8389 				x = (6 * 10) - 3;
8390 				//602 bronze D, 720 barbazu
8391 //				place_monster_aux(&wpos, y, x, 609, FALSE, FALSE, 100, 0);
8392 //				place_monster_one(&wpos, y, x, 609, FALSE, FALSE, FALSE, 100, 0);
8393 				place_monster_one(&wpos, y, x, 321, FALSE, FALSE, FALSE, 100, 0);//stone P
8394 				summon_override_checks = SO_NONE;
8395 				timer_pvparena3++; /* start releasing cycle */
8396 				return;
8397 			} else if (timer_pvparena3 == 2) { /* prepare second cycle */
8398 				summon_override_checks = SO_ALL;
8399 				for (i = 1; i <= 6; i++) {
8400 					y = 1;
8401 					x = (i * 10) - 3;
8402 					//613 hellhound is too tough, 963 aranea im_pois, 986 3-h hydra, 249 vlasta
8403 					//440 5-h hydra, 387 4-h hydra, 341 chimaera, 301 2-h hydra, 325 gold dfly
8404 //					place_monster_aux(&wpos, y, x, 963, FALSE, FALSE, 100, 0);
8405 					//place_monster_one(&wpos, y, x, i % 3 ? i % 2 ? 341 : 325 : 301, FALSE, FALSE, FALSE, 100, 0);
8406 					place_monster_one(&wpos, y, x, i % 3 ? i % 2 ? 295 : 325 : 275, FALSE, FALSE, FALSE, 100, 0);//sphinx,gold dfly,tarantula
8407 					everyone_lite_spot(&wpos, y, x);
8408 				}
8409 				summon_override_checks = SO_NONE;
8410 				timer_pvparena3++; /* start releasing cycle */
8411 				return;
8412 			}
8413 
8414 			/* clear previous monster */
8415 			wipe_m_list_roaming(&wpos);
8416 			if (timer_pvparena2 > 1) {
8417 				/* erase monster that didn't come out of its chamber */
8418 				y = 1;
8419 				x = ((timer_pvparena2 - 1) * 10) - 3;
8420 				if (zcave[y][x].m_idx > 0) delete_monster_idx(zcave[y][x].m_idx, TRUE);
8421 				/* erase monster that stopped on its chamber door */
8422 				y = 2;
8423 				if (zcave[y][x].m_idx > 0) delete_monster_idx(zcave[y][x].m_idx, TRUE);
8424 			}
8425 
8426 			/* open current door to release monster */
8427 			y = 2;
8428 			x = (timer_pvparena2 * 10) - 3;
8429 			zcave[y][x].feat = FEAT_UNSEALED_DOOR;
8430 			everyone_lite_spot(&wpos, y, x);
8431 
8432 			/* after 6th monster, take a break and switch wave cycle */
8433 			if (timer_pvparena2 == 6) {
8434 				/* prepare next cycle next time */
8435 				timer_pvparena3++;
8436 				/* max number of cycles? */
8437 				timer_pvparena3 = timer_pvparena3 % 4;
8438 
8439 				/* next time, begin at monster #1 again */
8440 				timer_pvparena2 = 1;
8441 				return;
8442 			}
8443 
8444 			/* next time, release next monster */
8445 			timer_pvparena2++;
8446 		}
8447 	}
8448 
8449 }
8450 
8451 /* during new years eve, cast fireworks! - C. Blue
8452    NOTE: Called four times per second (if fireworks are enabled). */
8453 static void process_firework_creation() {
8454 	int i;
8455 
8456 	if (!fireworks_delay) { /* fire! */
8457 		worldpos wpos;
8458 		switch(rand_int(4)) {
8459 		case 0:	fireworks_delay = 0; break;
8460 		case 1:	fireworks_delay = 1; break;
8461 		case 2:	fireworks_delay = 4; break;
8462 		case 3:	fireworks_delay = 8; break;
8463 		}
8464 
8465 		/* Fireworks in Bree */
8466 		wpos.wx = 32; wpos.wy = 32; wpos.wz = 0;
8467 
8468 		/* Launch multiple rockets ;) - mikaelh */
8469 		for (i = 0; i < fireworks; i++) {
8470 			/* "type" determines colour and explosion style */
8471 			cast_fireworks(&wpos, rand_int(MAX_WID - 120) + 60, rand_int(MAX_HGT - 40) + 20);
8472 		}
8473 	} else {
8474 		fireworks_delay--;
8475 	}
8476 }
8477 
8478 
8479 #if defined CLIENT_SIDE_WEATHER && defined CLIENT_WEATHER_GLOBAL
8480 /* Update all affected (ie on worldmap surface) players' client-side weather.
8481    NOTE: Called on opportunity of _global_ weather undergoing any change. */
8482 static void players_weather() {
8483 	int i;
8484 
8485 	for (i = 1; i <= NumPlayers; i++) {
8486 		/* Skip non-connected players */
8487 		if (Players[i]->conn == NOT_CONNECTED) continue;
8488 		/* Skip players not on world surface - player_weather() actually checks this too though */
8489 		if (Players[i]->wpos.wz) continue;
8490 
8491 		/* send weather update to him */
8492 		player_weather(i, FALSE, TRUE, FALSE);
8493 	}
8494 }
8495 #endif
8496 
8497 #if defined CLIENT_WEATHER_GLOBAL || !defined CLIENT_SIDE_WEATHER
8498 /* manage and toggle weather and wind state - C. Blue
8499    NOTE: Called once per second,
8500          and for CLIENT_SIDE_WEATHER only if also CLIENT_WEATHER_GLOBAL. */
8501 static void process_weather_control() {
8502 
8503  #ifdef CLIENT_SIDE_WEATHER
8504 /* NOTE: we are only supposed to get here if also CLIENT_WEATHER_GLOBAL. */
8505 
8506 	/* during winter, it snows: */
8507 	if (season == SEASON_WINTER) {
8508 		if (!weather) { /* not snowing? */
8509 			if (weather_duration <= 0 && weather_frequency > 0) { /* change weather? */
8510 				weather = 2; /* snowing now */
8511 				players_weather();
8512 				weather_duration = weather_frequency * 60 * 4;
8513 			} else if (weather_duration > 0) {
8514 				weather_duration--;
8515 			}
8516 		} else { /* it's currently snowing */
8517 			if (weather_duration <= 0 && (4 - weather_frequency) > 0) { /* change weather? */
8518 				weather = 0; /* stop snowing */
8519 				players_weather();
8520 				weather_duration = (4 - weather_frequency) * 60 * 4;
8521 			} else if (weather_duration > 0) {
8522 				weather_duration--;
8523 			}
8524 		}
8525 	/* during spring, summer and autumn, it rains: */
8526 	} else {
8527 		if (weather) { /* it's currently raining */
8528 			if (weather_duration <= 0 && weather_frequency > 0) { /* change weather? */
8529 				weather = 0; /* stop raining */
8530 				players_weather();
8531 //s_printf("WEATHER: Stopping rain.\n");
8532 				weather_duration = rand_int(60 * 30 / weather_frequency) + 60 * 30 / weather_frequency;
8533 			} else weather_duration--;
8534 		} else { /* not raining at the moment */
8535 			if (weather_duration <= 0 && (4 - weather_frequency) > 0) { /* change weather? */
8536 				weather = 1; /* start raining */
8537 				players_weather();
8538 //s_printf("WEATHER: Starting rain.\n");
8539 				weather_duration = rand_int(60 * 9) + 60 * weather_frequency;
8540 			} else if (weather_duration > 0) {
8541 				weather_duration--;
8542 			}
8543 		}
8544 	}
8545 
8546 	/* manage wind */
8547 	if (wind_gust > 0) {
8548 		wind_gust--; /* gust from east */
8549 		if (!wind_gust) players_weather();
8550 	} else if (wind_gust < 0) {
8551 		wind_gust++; /* gust from west */
8552 		if (!wind_gust) players_weather();
8553 	} else if (!wind_gust_delay) { /* gust of wind coming up? */
8554 		wind_gust_delay = 15 + rand_int(240); /* so sometimes no gust at all during 4-min snow periods */
8555 		wind_gust = rand_int(60) + 5;
8556 		if (rand_int(2)) {
8557 			wind_gust = -wind_gust;
8558 		}
8559 		players_weather();
8560 	} else wind_gust_delay--;
8561 
8562  #else /* server-side weather: */
8563 
8564 	/* during winter, it snows: */
8565 	if (season == SEASON_WINTER) {
8566 		if (!weather) { /* not snowing? */
8567 			if (weather_duration <= 0 && weather_frequency > 0) { /* change weather? */
8568 				weather = 1; /* snowing now */
8569 				weather_duration = weather_frequency * 60 * 4;
8570 			} else if (weather_duration > 0) {
8571 				weather_duration--;
8572 			}
8573 		} else { /* it's currently snowing */
8574 			if (weather_duration <= 0 && (4 - weather_frequency) > 0) { /* change weather? */
8575 				weather = 0; /* stop snowing */
8576 				weather_duration = (4 - weather_frequency) * 60 * 4;
8577 			} else if (weather_duration > 0) {
8578 				weather_duration--;
8579 			}
8580 		}
8581 	/* during spring, summer and autumn, it rains: */
8582 	} else {
8583 		if (weather) { /* it's currently raining */
8584 			if (weather_duration <= 0 && weather_frequency > 0) { /* change weather? */
8585 				weather = 0; /* stop raining */
8586 //s_printf("WEATHER: Stopping rain.\n");
8587 				weather_duration = rand_int(60 * 30 / weather_frequency) + 60 * 30 / weather_frequency;
8588 			} else weather_duration--;
8589 		} else { /* not raining at the moment */
8590 			if (weather_duration <= 0 && (4 - weather_frequency) > 0) { /* change weather? */
8591 				weather = 1; /* start raining */
8592 //s_printf("WEATHER: Starting rain.\n");
8593 				weather_duration = rand_int(60 * 9) + 60 * weather_frequency;
8594 			} else if (weather_duration > 0) {
8595 				weather_duration--;
8596 			}
8597 		}
8598 	}
8599 
8600 	/* manage wind */
8601 	if (wind_gust > 0) wind_gust--; /* gust from east */
8602 	else if (wind_gust < 0) wind_gust++; /* gust from west */
8603 	else if (!wind_gust_delay) { /* gust of wind coming up? */
8604 		wind_gust_delay = 15 + rand_int(240); /* so sometimes no gust at all during 4-min snow periods */
8605 		wind_gust = rand_int(60) + 5;
8606 		if (rand_int(2)) wind_gust = -wind_gust;
8607 	} else wind_gust_delay--;
8608 
8609  #endif
8610 
8611 }
8612 #endif
8613 
8614 /* create actual weather effects.
8615    (animating/excising is then done in process_effects())
8616    NOTE: Called each turn. */
8617 #ifndef CLIENT_SIDE_WEATHER
8618 static void process_weather_effect_creation() {
8619 
8620 	/* clear skies or new years eve fireworks? do nothing */
8621 	if (!weather || fireworks) return;
8622 
8623 	/* winter? then it snows: */
8624 	if (season == SEASON_WINTER) {
8625 		if (!(turn % ((cfg.fps + 29) / 30))) {
8626 			worldpos wpos;
8627 			/* Create snowflakes in Bree */
8628 			wpos.wx = 32; wpos.wy = 32; wpos.wz = 0;
8629 			cast_snowflake(&wpos, rand_int(MAX_WID - 2) + 1, 8);
8630 		}
8631 	/* spring, summer or autumn? it rains: */
8632 	} else {
8633 		if (!(turn % ((cfg.fps + 59) / 60))) {
8634 			worldpos wpos;
8635 			/* Create raindrops in Bree */
8636 			wpos.wx = 32; wpos.wy = 32; wpos.wz = 0;
8637 			cast_raindrop(&wpos, rand_int(MAX_WID - 2) + 1);
8638 			cast_raindrop(&wpos, rand_int(MAX_WID - 2) + 1);
8639 		}
8640 	}
8641 }
8642 #endif
8643 
8644 #ifdef CLIENT_SIDE_WEATHER
8645  #ifndef CLIENT_WEATHER_GLOBAL
8646 /* initialize some weather-related variables */
8647 static void wild_weather_init() {
8648 	wilderness_type *w_ptr;
8649 	int i, x, y;
8650 
8651 	/* initialize amount of clouds */
8652 	season_change(season, FALSE);
8653 
8654 	for (x = 0; x < MAX_WILD_X; x++)
8655 	for (y = 0; y < MAX_WILD_Y; y++) {
8656 		w_ptr = &wild_info[y][x];
8657 
8658 		/* initialize weather vars */
8659 
8660 		/* initialize cloud vars */
8661 		for (i = 0; i < 10; i++) {
8662 			w_ptr->cloud_idx[i] = -1; /* be inactive by default */
8663 			w_ptr->cloud_x1[i] = -9999; /* hack for client: disabled */
8664 		}
8665 	}
8666 }
8667 
8668     /* DEBUGGING NOTES - C. Blue
8669        There might be a bug where weather_updated is not TRUE'd for
8670        the player's wilderness sector when using /mkcloud, which might also
8671        be a bug in normal cloud creation. The player will then need to leave
8672        and reenter his sector for the cloud to take effect.
8673        Further bug info: In cloud_erase() the same cloud of a found cloud_idx
8674        (here in /rmcloud) will not be found to be 'touching this sector'.
8675        FURTHER: Seems inconsistent use of cloud_x1/x2/y1/y2:
8676        cloud_create() uses them as start+destination, cloud_move/erase use
8677        them as box-defining points for finding the cloud's covering area. oO */
8678 
8679 
8680 /* Manange and control weather separately for each worldmap sector,
8681    assumed that client-side weather is used, depending on clouds.
8682    NOTE: Called once per second. */
8683 /* Note: Meanings of cloud_state (not implemented):
8684    1..100: growing (decrementing, until reaching 1)
8685    -1..-100: shrinking (incrementing, until reaching -1 or critically low radius
8686 */
8687 static void process_wild_weather() {
8688 	int i;
8689 
8690 	/* process clouds forming, dissolving
8691 	   and moving over world map */
8692 	for (i = 0; i < MAX_CLOUDS; i++) {
8693 		/* does cloud exist? */
8694 		if (cloud_dur[i]) {
8695 			/* hack: allow dur = -1 to last forever */
8696 			if (cloud_dur[i] > 0) {
8697 				/* hack to not have clouds near fireworks */
8698 				if (season_newyearseve) {
8699 					int txm = (cloud_x1[i] + (cloud_x2[i] - cloud_x1[i]) / 2) / MAX_WID; /* central wpos of this cloud */
8700 					int tym = cloud_y1[i] / MAX_HGT;
8701 					if (distance(tym, txm, cfg.town_y, cfg.town_x) <= 4) cloud_dur[i] = 1;
8702 				}
8703 				/* lose essence from raining/snowing */
8704 				cloud_dur[i]--;
8705 				/* if cloud dissolves, keep track */
8706 				if (!cloud_dur[i]) {
8707 //s_printf("erasing %d\n", i);//TEST_SERVER
8708 					cloud_erase(i);
8709 					clouds--;
8710 					/* take a break for this second ;) */
8711 					continue;
8712 				}
8713 			}
8714 			/* Move it */
8715 			cloud_move(i, FALSE);
8716 		}
8717 
8718 		/* create cloud? limit value depends on season */
8719 		else if (clouds < max_clouds_seasonal) {
8720 #ifdef TEST_SERVER /* hack: fixed location for easier live testing? */
8721 			//around Bree
8722 			cloud_create(i, 32 * MAX_HGT, 32 * MAX_WID);
8723 			cloud_state[i] = 1;
8724 #else
8725 			/* create cloud at random starting x, y world _grid_ coords (!) */
8726 			cloud_create(i,
8727 			    rand_int(MAX_WILD_X * MAX_WID),
8728 			    rand_int(MAX_WILD_Y * MAX_HGT));
8729 #endif
8730 		}
8731 	}
8732 
8733 	/* update players' local client-side weather if required */
8734 	local_weather_update();
8735 }
8736 
8737 /* Change a cloud's movement.
8738    (Note: Continuous movement is performed by
8739    clients via buffered direction & duration.)
8740    New note: Negative values should probably work too (inverse direction). */
8741 static void cloud_set_movement(int i) {
8742 #ifdef WEATHER_NO_CLOUD_MOVEMENT
8743 { /* hack: Try to fix the eternal rain bug:
8744      Disable cloud movement for now - C. Blue */
8745        cloud_xm100[i] = 0;
8746        cloud_ym100[i] = 0;
8747        cloud_mdur[i] = 30 + rand_int(300);
8748        return;
8749 }
8750 #endif
8751 
8752 #ifdef TEST_SERVER /* hack: fixed location for easier live testing? */
8753  #if 0
8754 	cloud_xm100[i] = 100;
8755 	cloud_ym100[i] = 100;
8756 	cloud_mdur[i] = 10;
8757  #endif
8758  #if 1
8759 	cloud_xm100[i] = 0;
8760 	cloud_ym100[i] = 0;
8761 	cloud_mdur[i] = 10;
8762  #endif
8763 #else
8764 	if (rand_int(2)) {
8765 		/* no pseudo-wind */
8766 		cloud_xm100[i] = 0;
8767 		cloud_ym100[i] = 0;
8768 	} else {
8769 		/* pseudo-wind */
8770 		cloud_xm100[i] = randint(100);
8771 		cloud_ym100[i] = randint(100);
8772 	}
8773 	cloud_mdur[i] = 30 + rand_int(300); /* seconds */
8774 #endif
8775 }
8776 
8777 /* remove cloud status off all previously affected wilderness sectors,
8778    move & resize cloud,
8779    imprint cloud status on all currently affected wilderness sectors.
8780    Set each affected sector's 'weather_updated' if there was a change.
8781    Note: Wild sectors have a limit of amount of concurrent clouds
8782          they can be affected by (10).
8783    'resend_direction' explanation:
8784    If the direction of this cloud changed. the affected wilderness
8785    sectors will definitely need to be set to weather_updated, so
8786    the clients will by synchronized to the new cloud movement.
8787    NOTE: 'change' means that either cloud movement changes or that
8788          a wild sector toggles affected/unaffected state, simply. */
8789 /* make rain fall down slower? */
8790 #if 1
8791  #define WEATHER_GEN_TICKS 3
8792  #define WEATHER_SNOW_MULT 3
8793 #else
8794 /* make rain fall down faster? (recommended) */
8795  #define WEATHER_GEN_TICKS 2
8796  #define WEATHER_SNOW_MULT 4
8797 #endif
8798 static void cloud_move(int i, bool newly_created) {
8799 	bool resend_dir = FALSE, sector_changed;
8800 	wilderness_type *w_ptr;
8801 	int x, y, xs, ys, xd, yd, j;
8802 	int txm, tym, tgx, tgy, d, dx, dy;
8803 	int xs_add_prev = 0, ys_add_prev = 0, xd_add_prev = 0, yd_add_prev = 0;
8804 	bool was_affected, is_affected, can_become_affected;
8805 	int was_affected_idx = 0; /* slaying compiler warning */
8806 	bool final_cloud_in_sector;
8807 
8808 
8809 /* process cloud shaping & movement  --------------------------------------- */
8810 
8811 	/* perform growing/shrinking (todo: implement) */
8812 	if (cloud_state[i] > 1) {
8813 		cloud_state[i]--;
8814 		/* grow */
8815 	} else if (cloud_state[i] < -1) {
8816 		cloud_state[i]++;
8817 		/* shrink */
8818 	}
8819 
8820 	/* process movement
8821 	   Note: This is done both server- and client-side,
8822 	         and synch'ed whenever movement changes or
8823 	         a new worldmap sector becomes (un)affected
8824 	         which is currently visited by tbe player to
8825 	         synch with. */
8826 	cloud_mdur[i]--;
8827 	/* change in movement? */
8828 	if (!cloud_mdur[i]) {
8829 		cloud_set_movement(i);
8830 		/* update all players' cloud direction information */
8831 		resend_dir = TRUE;
8832 	}
8833 
8834 	/* perform movement */
8835 	cloud_xfrac[i] += cloud_xm100[i];
8836 	cloud_yfrac[i] += cloud_ym100[i];
8837 	x = cloud_xfrac[i] / 100;
8838 	y = cloud_yfrac[i] / 100;
8839 	if (x) {
8840 		cloud_x1[i] += x;
8841 		cloud_x2[i] += x;
8842 		cloud_xfrac[i] -= x * 100;
8843 		/* we possibly left a sector behind by moving on: */
8844 		if (x > 0) xs_add_prev = -1;
8845 		else xd_add_prev = 1;
8846 	}
8847 	if (y) {
8848 		cloud_y1[i] += y;
8849 		cloud_y2[i] += y;
8850 		cloud_yfrac[i] += y * 100;
8851 		/* we possibly left a sector behind by moving on: */
8852 		if (y > 0) ys_add_prev = -1;
8853 		else yd_add_prev = 1;
8854 	}
8855 
8856 
8857 /* imprint new situation on wild sectors locally --------------------------- */
8858 
8859 	/* check all worldmap sectors affected by this cloud
8860 	   and modify local weather situation accordingly if needed */
8861 	/* NOTE regarding hardcoding: These calcs depend on cloud creation algo a lot */
8862 	txm = (cloud_x1[i] + (cloud_x2[i] - cloud_x1[i]) / 2) / MAX_WID; /* central wpos of this cloud */
8863 	tym = cloud_y1[i] / MAX_HGT;
8864 	xs = CLOUD_XS(cloud_x1[i], cloud_y1[i], cloud_x2[i], cloud_y2[i], cloud_dsum[i]);
8865 	xd = CLOUD_XD(cloud_x1[i], cloud_y1[i], cloud_x2[i], cloud_y2[i], cloud_dsum[i]);
8866 	ys = CLOUD_YS(cloud_x1[i], cloud_y1[i], cloud_x2[i], cloud_y2[i], cloud_dsum[i]);
8867 	yd = CLOUD_YD(cloud_x1[i], cloud_y1[i], cloud_x2[i], cloud_y2[i], cloud_dsum[i]);
8868 	/* traverse all wild sectors that could maybe be affected or
8869 	   have been affected by this cloud, very roughly calculated
8870 	   (just a rectangle mask), fine check is done inside. */
8871 	for (x = xs + xs_add_prev; x <= xd + xd_add_prev; x++)
8872 	for (y = ys + ys_add_prev; y <= yd + yd_add_prev; y++) {
8873 		/* skip sectors out of array bounds */
8874 		if (x < 0 || x >= MAX_WILD_X || y < 0 || y >= MAX_WILD_Y) continue;
8875 
8876 		w_ptr = &wild_info[y][x];
8877 
8878 		sector_changed = FALSE; /* assume no change */
8879 		was_affected = FALSE;
8880 		is_affected = FALSE;
8881 		can_become_affected = FALSE; /* assume no free space left in local cloud array of this wild sector */
8882 		final_cloud_in_sector = TRUE; /* assume this cloud is the only one keeping the weather up here */
8883 
8884 		/* was the sector affected before moving? */
8885 		for (j = 0; j < 10; j++) {
8886 			/* cloud occurs in this sector? so sector was already affected */
8887 			if (w_ptr->cloud_idx[j] == i) {
8888 				was_affected = TRUE;
8889 				was_affected_idx = j;
8890 			}
8891 			/* free space in cloud array? means we could add another cloud if we want */
8892 			else if (w_ptr->cloud_idx[j] == -1) can_become_affected = TRUE;
8893 			else if (w_ptr->cloud_idx[j] != -1) final_cloud_in_sector = FALSE;
8894 		}
8895 		if (!was_affected) final_cloud_in_sector = FALSE;
8896 
8897 		/* if this sector wasn't affected before, and we don't
8898 		   have free space left in its local cloud array,
8899 		   then we won't be able to imprint on it anyway, so we
8900 		   may as well ignore and leave this sector now. */
8901 		if (!was_affected && !can_become_affected) continue;
8902 
8903 #ifdef TEST_SERVER
8904 //SPAM(after a short while) s_printf("cloud-debug 1.\n");
8905 #endif
8906 		/* is the sector affected now after moving? */
8907 		/* calculate coordinates for deciding test case */
8908 		/* NOTE regarding hardcoding: These calcs depend on cloud creation algo a lot */
8909 		if (x < txm) tgx = (x + 1) * MAX_WID - 1; /* x: left edge of current sector */
8910 		else if (x > txm) tgx = x * MAX_WID; /* x: right edge of current sector */
8911 		else tgx = cloud_x1[i] + (cloud_x2[i] - cloud_x1[i]) / 2; /* x: center point of current cloud */
8912 		if (y < tym) tgy = (y + 1) * MAX_HGT - 1; /* analogous to x above */
8913 		else if (y > tym) tgy = y * MAX_HGT;
8914 		else tgy = cloud_y1[i];
8915 		/* test whether cloud touches the sector (taken from distance()) */
8916 		/* Calculate distance to cloud focus point 1: */
8917 		dy = (tgy > cloud_y1[i]) ? (tgy - cloud_y1[i]) : (cloud_y1[i] - tgy);
8918 		dx = (tgx > cloud_x1[i]) ? (tgx - cloud_x1[i]) : (cloud_x1[i] - tgx);
8919 		d = (dy > dx) ? (dy + (dx >> 1)) : (dx + (dy >> 1));
8920 		/* Calculate distance to cloud focus point 2: */
8921 		dy = (tgy > cloud_y2[i]) ? (tgy - cloud_y2[i]) : (cloud_y2[i] - tgy);
8922 		dx = (tgx > cloud_x2[i]) ? (tgx - cloud_x2[i]) : (cloud_x2[i] - tgx);
8923 		/* ..and sum them up */
8924 		d += (dy > dx) ? (dy + (dx >> 1)) : (dx + (dy >> 1));
8925 
8926 		/* is sector affected now? add cloud to its local cloud array */
8927 		if (d <= cloud_dsum[i]) {
8928 			is_affected = TRUE;
8929 #ifdef TEST_SERVER
8930 //s_printf("cloud-debug 2.\n");
8931 #endif
8932 
8933 			/* update old cloud data or add a new entry if it didn't exist previously */
8934 			for (j = 0; j < 10; j++) {
8935 				/* unchanged cloud situation leads to continuing.. */
8936 				if (was_affected && w_ptr->cloud_idx[j] != i) continue;
8937 				if (!was_affected && w_ptr->cloud_idx[j] != -1) continue;
8938 #ifdef TEST_SERVER
8939 //s_printf("cloud-debug 3.\n");
8940 #endif
8941 
8942 				/* imprint cloud data to this wild sector's local cloud array */
8943 				w_ptr->cloud_idx[j] = i;
8944 				w_ptr->cloud_x1[j] = cloud_x1[i];
8945 				w_ptr->cloud_y1[j] = cloud_y1[i];
8946 				w_ptr->cloud_x2[j] = cloud_x2[i];
8947 				w_ptr->cloud_y2[j] = cloud_y2[i];
8948 				w_ptr->cloud_dsum[j] = cloud_dsum[i];
8949 				w_ptr->cloud_xm100[j] = cloud_xm100[i];
8950 				w_ptr->cloud_ym100[j] = cloud_ym100[i];
8951 #if 0
8952 				/* meta data for Send_weather() */
8953 				if (!w_ptr->cloud_updated[j]) {
8954 					w_ptr->cloud_updated[j] = TRUE;
8955 					w_ptr->clouds_to_update++;
8956 				}
8957 #endif
8958 				/* define weather situation accordingly */
8959 				switch (w_ptr->type) {
8960 				case WILD_ICE:
8961 					w_ptr->weather_type = 2; /* always snow in icy waste */
8962 					break;
8963 				case WILD_DESERT:
8964 					w_ptr->weather_type = 1; /* never snow in desert */
8965 					break;
8966 				default:
8967 					/* depends on season */
8968 					w_ptr->weather_type = (season == SEASON_WINTER ? 2 : 1);
8969 				}
8970 #ifdef TEST_SERVER
8971 //s_printf("weather_type debug: wt=%d, x,y=%d,%d.\n", w_ptr->weather_type, x, y);
8972 #if 0
8973 if (NumPlayers && Players[NumPlayers]->wpos.wx == x && Players[NumPlayers]->wpos.wy == y) {
8974     s_printf("weather_type debug: wt=%d, x,y=%d,%d.\n", w_ptr->weather_type, x, y);
8975     s_printf("cloud debug all: cidx=%d, x1,y1=%d,%d, dsum=%d.\n",
8976 	w_ptr->cloud_idx[j], w_ptr->cloud_x1[j], w_ptr->cloud_y1[j], w_ptr->cloud_dsum[j]);
8977 }
8978 #endif
8979 #endif
8980 
8981 #ifndef WEATHER_WINDS /* no winds */
8982 				w_ptr->weather_wind = 0; /* todo: change =p (implement winds, actually -- currently we're
8983 				                            using pseudo-winds by just setting random cloud movement - C. Blue */
8984 				w_ptr->weather_wind_vertical = 0;
8985 #else /* winds */
8986  #ifndef WEATHER_NO_CLOUD_MOVEMENT /* Cloud movemenet is disabled as a workaround for the 'eternal rain' bug.. */
8987 				/* note- pretty provisional implementation, since winds shouldnt depend
8988 				   on cloud movement, but actually the other way round ;) This is merely
8989 				   so we get to see some wind already, and these 'winds' would also conflict
8990 				   if multiple clouds moving into different directions met.. - C. Blue */
8991 				if (cloud_xm100[i] > 40) w_ptr->weather_wind = 5 - (2 * ((cloud_xm100[i] - 40) / 21));
8992 				else if (cloud_xm100[i] < -40) w_ptr->weather_wind = 6 - (2 * ((-cloud_xm100[i] - 40) / 21));
8993 				else w_ptr->weather_wind = 0;
8994 				/* also determine vertical pseudo winds, just for server-side running speed calculations */
8995 				if (cloud_ym100[i] > 40) w_ptr->weather_wind_vertical = 5 - (2 * ((cloud_ym100[i] - 40) / 21));
8996 				else if (cloud_ym100[i] < -40) w_ptr->weather_wind_vertical = 6 - (2 * ((-cloud_ym100[i] - 40) / 21));
8997 				else w_ptr->weather_wind_vertical = 0;
8998  #else /* ..so a little hack is needed to bring back 'windy' weather^^ - C. Blue */
8999 				/* hack - randomly assume some winds, that stay sufficiently consistent */
9000 				{
9001 					/* this should allow smooth/consistent winds over slight changes in a player's wilderness position: */
9002 					int seed = (y + x + ((int)((turn / (cfg.fps * 1200)) % 90))) / 3; /* hourly change */
9003 					switch (seed % 30) {
9004 					case 0: case 1: case 2: case 3:		w_ptr->weather_wind = 0; break;
9005 					case 4:	case 5:	case 6:			w_ptr->weather_wind = 5; break;
9006 					case 7:	case 8:				w_ptr->weather_wind = 3; break;
9007 					case 9:					w_ptr->weather_wind = 1; break;
9008 					case 10: case 11:			w_ptr->weather_wind = 3; break;
9009 					case 12: case 13: case 14:		w_ptr->weather_wind = 5; break;
9010 					case 15: case 16: case 17: case 18:	w_ptr->weather_wind = 0; break;
9011 					case 19: case 20: case 21:		w_ptr->weather_wind = 6; break;
9012 					case 22: case 23:			w_ptr->weather_wind = 4; break;
9013 					case 24:				w_ptr->weather_wind = 2; break;
9014 					case 25: case 26:			w_ptr->weather_wind = 4; break;
9015 					case 27: case 28: case 29:		w_ptr->weather_wind = 6; break;
9016 					}
9017 					w_ptr->weather_wind_vertical = 0;
9018 				}
9019  #endif
9020 #endif
9021 
9022 				w_ptr->weather_intensity =
9023 				    (w_ptr->weather_type == 2 && (!w_ptr->weather_wind || w_ptr->weather_wind >= 3)) ?
9024 				    5 : 8;
9025 				w_ptr->weather_speed =
9026 #if 1 /* correct! (this is a different principle than 'weather_intensity' above) */
9027 				    (w_ptr->weather_type == 2) ? WEATHER_SNOW_MULT * WEATHER_GEN_TICKS :
9028 				    /* hack: for non-windy rainfall, accelerate raindrop falling speed by 1: */
9029 				    (w_ptr->weather_wind ? 1 * WEATHER_GEN_TICKS : WEATHER_GEN_TICKS - 1);
9030 #else /* just for testing stuff */
9031 				    (w_ptr->weather_type == 2 && (!w_ptr->weather_wind || w_ptr->weather_wind >= 3)) ?
9032 				    WEATHER_SNOW_MULT * WEATHER_GEN_TICKS : 1 * WEATHER_GEN_TICKS;
9033 #endif
9034 				break;
9035 			}
9036 		}
9037 		/* sector is not affected. If it was previously affected,
9038 		   delete cloud from its local array now. */
9039 		else if (was_affected) {
9040 #ifdef TEST_SERVER
9041 //s_printf("cloud-debug 4.\n");
9042 #endif
9043 			/* erase cloud locally */
9044 			w_ptr->cloud_idx[was_affected_idx] = -1;
9045 			w_ptr->cloud_x1[was_affected_idx] = -9999; /* hack for client: client sees this as 'disabled' */
9046 #if 0
9047 			/* meta data for Send_weather() */
9048 			if (!w_ptr->cloud_updated[was_affected_idx]) {
9049 				w_ptr->cloud_updated[was_affected_idx] = TRUE;
9050 				w_ptr->clouds_to_update++;
9051 			}
9052 #endif
9053 
9054 			/* if this was the last cloud in this sector,
9055 			   define (stop) weather situation accordingly */
9056 			if (final_cloud_in_sector) {
9057 #ifdef TEST_SERVER
9058 //s_printf("cloud-debug 5.\n");
9059 #endif
9060 				w_ptr->weather_type = 0; /* make weather 'run out slowly' */
9061 			}
9062 		}
9063 
9064 		/* so, did this sector actually 'change' after all? */
9065 		if (was_affected != is_affected) sector_changed = TRUE;
9066 
9067 		/* if the local situation did actually change,
9068 		   mark as updated for re-sending it to all players on it */
9069 		if (sector_changed || newly_created || resend_dir)
9070 			w_ptr->weather_updated = TRUE;
9071 	}
9072 }
9073 
9074 static void cloud_erase(int i) {
9075 	wilderness_type *w_ptr;
9076 	int x, y, xs, ys, xd, yd, j;
9077 	bool was_affected;
9078 	int was_affected_idx = 0; /* slaying compiler warning */
9079 	bool final_cloud_in_sector;
9080 
9081 /* imprint new situation on wild sectors locally --------------------------- */
9082 
9083 	/* check all worldmap sectors affected by this cloud
9084 	   and modify local weather situation accordingly if needed */
9085 	/* NOTE regarding hardcoding: These calcs depend on cloud creation algo a lot */
9086 	xs = CLOUD_XS(cloud_x1[i], cloud_y1[i], cloud_x2[i], cloud_y2[i], cloud_dsum[i]);
9087 	xd = CLOUD_XD(cloud_x1[i], cloud_y1[i], cloud_x2[i], cloud_y2[i], cloud_dsum[i]);
9088 	ys = CLOUD_YS(cloud_x1[i], cloud_y1[i], cloud_x2[i], cloud_y2[i], cloud_dsum[i]);
9089 	yd = CLOUD_YD(cloud_x1[i], cloud_y1[i], cloud_x2[i], cloud_y2[i], cloud_dsum[i]);
9090 	/* traverse all wild sectors that could maybe be affected or
9091 	   have been affected by this cloud, very roughly calculated
9092 	   (just a rectangle mask), fine check is done inside. */
9093 	for (x = xs; x <= xd; x++)
9094 	for (y = ys; y <= yd; y++) {
9095 		/* skip sectors out of array bounds */
9096 		if (x < 0 || x >= MAX_WILD_X || y < 0 || y >= MAX_WILD_Y) continue;
9097 
9098 		w_ptr = &wild_info[y][x];
9099 //if (Players[1] && Players[1]->wpos.wx == x && Players[1]->wpos.wy == y) s_printf("p1 here\n");
9100 
9101 		was_affected = FALSE;
9102 		final_cloud_in_sector = TRUE; /* assume this cloud is the only one keeping the weather up here */
9103 
9104 		/* was the sector affected before erasing? */
9105 		for (j = 0; j < 10; j++) {
9106 			/* cloud occurs in this sector? so sector was already affected */
9107 			if (w_ptr->cloud_idx[j] == i) {
9108 				was_affected = TRUE;
9109 				was_affected_idx = j;
9110 			}
9111 			else if (w_ptr->cloud_idx[j] != -1) final_cloud_in_sector = FALSE;
9112 		}
9113 		if (!was_affected) final_cloud_in_sector = FALSE;
9114 
9115 		if (was_affected) {
9116 			/* erase cloud locally */
9117 			w_ptr->cloud_idx[was_affected_idx] = -1;
9118 			w_ptr->cloud_x1[was_affected_idx] = -9999; /* hack for client: client sees this as 'disabled' */
9119 #if 0
9120 			/* meta data for Send_weather() */
9121 			if (!w_ptr->cloud_updated[was_affected_idx]) {
9122 				w_ptr->cloud_updated[was_affected_idx] = TRUE;
9123 				w_ptr->clouds_to_update++;
9124 			}
9125 #endif
9126 
9127 			/* if this was the last cloud in this sector,
9128 			   define (stop) weather situation accordingly */
9129 			if (final_cloud_in_sector) {
9130 				w_ptr->weather_type = 0; /* make weather 'run out slowly' */
9131 			}
9132 
9133 			/* so, did this sector actually 'change' after all? */
9134 			//sector_changed -> TRUE
9135 			/* if the local situation did actually change,
9136 			   mark as updated for re-sending it to all players on it */
9137 			w_ptr->weather_updated = TRUE;
9138 		}
9139 	}
9140 }
9141 
9142 /* Create a new cloud with given index and worldmap _grid_ coords of its center
9143    This does not check whether there will be too many clouds! */
9144 void cloud_create(int i, int cx, int cy) {
9145 	/* cloud dimensions: */
9146 	int sx, sy, dx, dy, dsum;
9147 	/* worldmap coords: */
9148 	int x, y, xs, xd, ys, yd;
9149 
9150 	/* decide on initial size (largest ie horizontal diameter) */
9151 	dsum = MAX_WID + rand_int(MAX_WID * 5);
9152 	sx = cx - dsum / 4;
9153 	sy = cy;
9154 	dx = cx + dsum / 4;
9155 	dy = cy;
9156 
9157 	xs = CLOUD_XS(sx, sy, dx, dy, dsum);
9158 	xd = CLOUD_XD(sx, sy, dx, dy, dsum);
9159 	ys = CLOUD_YS(sx, sy, dx, dy, dsum);
9160 	yd = CLOUD_YD(sx, sy, dx, dy, dsum);
9161 
9162 	/* hack: not many clouds over deserts */
9163 	for (x = xs - 1; x <= xd + 1; x++) {
9164 		for (y = ys - 1; y <= yd + 1; y++) {
9165 			if (in_bounds_wild(y, x) &&
9166 			    wild_info[y][x].type == WILD_DESERT)
9167 				if (rand_int(10)) return;
9168 
9169 				/* leave loops */
9170 				x = 9999;
9171 				break;
9172 		}
9173 	}
9174 
9175 	/* we have one more cloud now */
9176 	clouds++;
9177 	/* create cloud by setting it's life time */
9178 	cloud_dur[i] = 30 + rand_int(600); /* seconds */
9179 	/* set horizontal diameter */
9180 	cloud_dsum[i] = dsum;
9181 	/* set location/destination */
9182 	cloud_x1[i] = sx;
9183 	cloud_y1[i] = sy;
9184 	cloud_x2[i] = dx;
9185 	cloud_y2[i] = dy;
9186 	/* decide on growing/shrinking/constant cloud state */
9187 	cloud_state[i] = rand_int(2) ? 1 : (rand_int(2) ? rand_int(100) : -rand_int(100));
9188 	/* decide on initial movement */
9189 	cloud_set_movement(i);
9190 	/* add this cloud to its initial wild sector(s) */
9191 	cloud_move(i, TRUE);
9192 }
9193 
9194 
9195 /* update players' local client-side weather if required.
9196    called each time by process_wild_weather, aka 1/s. */
9197 void local_weather_update(void) {
9198 	int i;
9199 
9200 	/* HACK part 1: play random thunderclaps if player is receiving harsh weather.
9201 	   Note: this is synched to all players in the same worldmap sector,
9202 	   for consistency. :) */
9203 	int thunderstorm, thunderclap = 999, vol = rand_int(86);
9204 	thunderstorm = (turn / (cfg.fps * 3600)) % 6; /* n out of every 6 world map sector clusters have thunderstorms going */
9205 	if (!(turn % (cfg.fps * 10))) thunderclap = rand_int(5); /* every 10s there is a 1 in 5 chance of thunderclap (in a thunderstorm area) */
9206 
9207 	/* update players' local client-side weather if required */
9208 	for (i = 1; i <= NumPlayers; i++) {
9209 		/* Skip non-connected players */
9210 		if (Players[i]->conn == NOT_CONNECTED) continue;
9211 		/* Skip players not on world surface - player_weather() actually checks this too though */
9212 		if (Players[i]->wpos.wz) continue;
9213 
9214 		/* HACK part 2: if harsh weather, play random world-sector-synched thunderclaps */
9215 #if 0 /* debug */
9216 		if (thunderclap == 0) {
9217 			s_printf("p %d - w %d, t %d\n",
9218 			    ((Players[i]->wpos.wy + Players[i]->wpos.wx) / 5) % 6,
9219 			    thunderstorm,
9220 			    wild_info[Players[i]->wpos.wy][Players[i]->wpos.wx].weather_type);
9221 		}
9222 #endif
9223 		if (thunderclap == 0 &&
9224 		    wild_info[Players[i]->wpos.wy][Players[i]->wpos.wx].weather_type == 1 && /* no blizzards for now, just rainstorms */
9225 		    //wild_info[Players[i]->wpos.wy][Players[i]->wpos.wx].weather_wind &&
9226 		    ((Players[i]->wpos.wy + Players[i]->wpos.wx) / 5) % 6 == thunderstorm) {
9227 			sound_vol(i, "thunder", NULL, SFX_TYPE_WEATHER, FALSE, 15 + (vol + Players[i]->wpos.wy + Players[i]->wpos.wx) % 86);
9228 		}
9229 
9230 		/* no change in local situation? nothing to do then */
9231 		if (!wild_info[Players[i]->wpos.wy][Players[i]->wpos.wx].weather_updated) continue;
9232 		/* update player's local weather */
9233 #ifdef TEST_SERVER /* DEBUG */
9234 #if 0
9235 s_printf("updating weather for player %d.\n", i);
9236 #endif
9237 #endif
9238 		player_weather(i, FALSE, TRUE, FALSE);
9239 	}
9240 	/* reclear 'weather_updated' flag after all players have been updated */
9241 	for (i = 1; i <= NumPlayers; i++)
9242 		wild_info[Players[i]->wpos.wy][Players[i]->wpos.wx].weather_updated = FALSE;
9243 }
9244  #endif /* !CLIENT_WEATHER_GLOBAL */
9245 #endif /* CLIENT_SIDE_WEATHER */
9246 
9247 /* calculate slow-downs of running speed due to environmental circumstances / grid features - C. Blue
9248    Note: a.t.m. Terrain-related slowdowns take precedence over wind-related slowdowns, cancelling them. */
9249 void eff_running_speed(int *real_speed, player_type *p_ptr, cave_type *c_ptr) {
9250 #if 1 /* NEW_RUNNING_FEAT */
9251 	if (!is_admin(p_ptr) && !p_ptr->ghost && !p_ptr->tim_wraith) {
9252 		/* are we in fact running-levitating? */
9253 		//if ((f_info[c_ptr->feat].flags1 & (FF1_CAN_LEVITATE | FF1_CAN_RUN)) && p_ptr->levitate) {
9254 		if ((f_info[c_ptr->feat].flags1 & (FF1_CAN_LEVITATE | FF1_CAN_RUN))) {
9255 			/* Allow level 50 druids to run at full speed */
9256 			if (!(p_ptr->pclass == CLASS_DRUID &&  p_ptr->lev >= 50)) {
9257 				if (f_info[c_ptr->feat].flags1 & FF1_SLOW_LEVITATING_1) *real_speed /= 2;
9258 				if (f_info[c_ptr->feat].flags1 & FF1_SLOW_LEVITATING_2) *real_speed /= 4;
9259 			}
9260 		}
9261     	    /* or running-swimming? */
9262 		else if ((c_ptr->feat == 84 || c_ptr->feat == 103 || c_ptr->feat == 174 || c_ptr->feat == 187) && p_ptr->can_swim) {
9263 			/* Allow Aquatic players run/swim at full speed */
9264 			if (!r_info[p_ptr->body_monster].flags7&RF7_AQUATIC) {
9265 				if (f_info[c_ptr->feat].flags1 & FF1_SLOW_SWIMMING_1) *real_speed /= 2;
9266 				if (f_info[c_ptr->feat].flags1 & FF1_SLOW_SWIMMING_2) *real_speed /= 4;
9267 			}
9268 	        }
9269 		/* or just normally running? */
9270 		else {
9271 			if (f_info[c_ptr->feat].flags1 & FF1_SLOW_RUNNING_1) *real_speed /= 2;
9272 			if (f_info[c_ptr->feat].flags1 & FF1_SLOW_RUNNING_2) *real_speed /= 4;
9273 		}
9274 	}
9275 #endif
9276 
9277 #if 0 /* enable? */
9278  #if defined CLIENT_SIDE_WEATHER && !defined CLIENT_WEATHER_GLOBAL
9279     {	int wind, real_speed_vertical;
9280 	/* hack: wind without rain doesn't count, since it might confuse the players */
9281 	if (!wild_info[p_ptr->wpos.wy][p_ptr->wpos.wx].weather_type) return;
9282 
9283 	real_speed_vertical = *real_speed;
9284 	/* running against strong wind is slower :) - C. Blue */
9285 	wind = wild_info[p_ptr->wpos.wy][p_ptr->wpos.wx].weather_wind;
9286 	if (!wind || *real_speed != cfg.running_speed) ;
9287 		/* if no wind, or if we're already slowed down: nothing */
9288 	else if (wind % 2) {
9289 		/* west wind */
9290 		if (p_ptr->find_current == 1 || p_ptr->find_current == 4 || p_ptr->find_current == 7)
9291 			*real_speed = (*real_speed * (wind + 3)) / 10;
9292 	} else {
9293 		/* east wind */
9294 		if (p_ptr->find_current == 3 || p_ptr->find_current == 6 || p_ptr->find_current == 9)
9295 			*real_speed = (*real_speed * (wind + 6)) / 10;
9296 	}
9297 	/* also check vertical winds (which are only used for exactly this purpose here) */
9298 	wind = wild_info[p_ptr->wpos.wy][p_ptr->wpos.wx].weather_wind_vertical;
9299 	if (!wind || real_speed_vertical != cfg.running_speed) ;
9300 		/* if no wind, or if we're already slowed down: nothing */
9301 	else if (wind % 2) {
9302 		/* west wind */
9303 		if (p_ptr->find_current == 7 || p_ptr->find_current == 8 || p_ptr->find_current == 9)
9304 			real_speed_vertical = (real_speed_vertical * (wind + 3)) / 10;
9305 	} else {
9306 		/* east wind */
9307 		if (p_ptr->find_current == 1 || p_ptr->find_current == 2 || p_ptr->find_current == 3)
9308 			real_speed_vertical = (real_speed_vertical * (wind + 6)) / 10;
9309 	}
9310 	if (real_speed_vertical < *real_speed) *real_speed = real_speed_vertical;
9311     }
9312  #endif
9313 #endif
9314 }
9315 
9316 /* Initiates forced shutdown with all players getting recalled automatically.
9317    Added this for use within LUA files, for automatic seasonal event updating. - C. Blue */
9318 void timed_shutdown(int k, bool terminate) {
9319 	int i;
9320 
9321 //	msg_admins(0, format("\377w* Shutting down in %d minutes *", k));
9322 	if (terminate)
9323 		msg_broadcast_format(0, "\374\377I*** \377RAutomatic recall and server maintenance shutdown in %d minute%s. \377I***", k, (k == 1) ? "" : "s");
9324 	else
9325 		msg_broadcast_format(0, "\374\377I*** \377RAutomatic recall and server restart in %d minute%s. \377I***", k, (k == 1) ? "" : "s");
9326 
9327 	for (i = 1; i <= NumPlayers; i++) {
9328 		if (Players[i]->conn == NOT_CONNECTED) continue;
9329 		if (Players[i]->paging) continue;
9330 		Players[i]->paging = 2;
9331 	}
9332 
9333 	cfg.runlevel = terminate ? 2042 : 2043;
9334 	shutdown_recall_timer = k * 60;
9335 
9336 	/* hack: suppress duplicate message */
9337 	if (k <= 1) shutdown_recall_state = 3;
9338 	else if (k <= 5) shutdown_recall_state = 2;
9339 	else if (k <= 15) shutdown_recall_state = 1;
9340 	else shutdown_recall_state = 0;
9341 
9342 	s_printf("AUTOSHUTREC: %d minute(s).\n", k);
9343 }
9344 
9345 int recall_depth_idx(struct worldpos *wpos, player_type *p_ptr) {
9346 	int j;
9347 
9348 	/* cannot recall in 0,0? */
9349 	if (!wpos->wx && !wpos->wy) return (-1);
9350 
9351 	/* no dungeon/tower here? */
9352 	if (wpos->wz > 0 && !wild_info[wpos->wy][wpos->wx].tower) return (-1);
9353 	if (wpos->wz <= 0 && !wild_info[wpos->wy][wpos->wx].dungeon) return (-1);/* assume basic recall prefers dungeon over tower */
9354 
9355 	for (j = 0; j < MAX_D_IDX * 2; j++) {
9356 		/* it's a dungeon that's new to us - add it! */
9357 		if (!p_ptr->max_depth_wx[j] && !p_ptr->max_depth_wy[j]) {
9358 			p_ptr->max_depth_wx[j] = wpos->wx;
9359 			p_ptr->max_depth_wy[j] = wpos->wy;
9360 			p_ptr->max_depth_tower[j] = (wpos->wz > 0);
9361 			return j;
9362 		}
9363 		/* check dungeons we've already been to */
9364 		if (p_ptr->max_depth_wx[j] == wpos->wx &&
9365 		    p_ptr->max_depth_wy[j] == wpos->wy &&
9366 		    p_ptr->max_depth_tower[j] == (wpos->wz > 0))
9367 			return j;
9368 	}
9369 	s_printf("p_ptr->max_depth[]: TOO MANY DUNGEONS ('%s',%d,%d,%d)!\n", p_ptr->name, wpos->wx, wpos->wy, wpos->wz);
9370 	return (-1);
9371 }
9372 int get_recall_depth(struct worldpos *wpos, player_type *p_ptr) {
9373 	int i = recall_depth_idx(wpos, p_ptr);
9374 	if (i == -1) return 0;
9375 	return p_ptr->max_depth[i];
9376 }
9377