1 /* $Id$ */
2 /* File: misc.c */
3 
4 /* Purpose: misc code */
5 
6 /*
7  * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
8  *
9  * This software may be copied and distributed for educational, research, and
10  * not for profit purposes provided that this copyright and statement are
11  * included in all such copies.
12  */
13 
14 #define SERVER
15 
16 #include "angband.h"
17 
18 
19 /*
20  * Modifier for martial-arts AC bonus; it's needed to balance martial-arts
21  * and dodging skills. in percent. [50]
22  */
23 #define MARTIAL_ARTS_AC_ADJUST	50
24 
25 /* Hack: Martial arts to-damage bonus is partially counted as 'imaginary object +dam bonus' instead of purely 'skill bonus'?
26    This is relevant for shapeshifters, because to_d_melee gets averaged, while to_d (from weapons) gets flat added!
27    This is a pretty ugly hack. :( */
28 #define MARTIAL_TO_D_HACK
29 /* Mimic +dam bonus from forms takes a 'dent' in the slightly above-average region? (Recommended)
30    This helps Jabberwock form to shine vs more "08/15" forms such as Maulotaur in terms of damage output! */
31 #ifdef MARTIAL_TO_D_HACK
32  #define MIMIC_TO_D_DENTHACK /* optional */
33 #else
34  #define MIMIC_TO_D_DENTHACK /* should always be on */
35 #endif
36 
37 /* Announce global events every 900 seconds */
38 #define GE_ANNOUNCE_INTERVAL 900
39 
40 /* Seconds left when to fire a final announcement */
41 #define GE_FINAL_ANNOUNCEMENT 300 /* 240 */
42 
43 /* Allow ego monsters in Arena Challenge global event? */
44 #define GE_ARENA_ALLOW_EGO
45 
46 /* Experimental and also silly ;) - reward players for wearing arts of similar name - C. Blue */
47 #define EQUIPMENT_SET_BONUS
48 
49 /* Do not lower HP of mimics if the monster form has lower HP than their @ form. - C. Blue
50    Could be extended onto to-dam and even Speed maybe. Shouldn't be extended onto AC. */
51 #define MIMICRY_BOOST_WEAK_FORM
52 
53 
54 /*
55  * Converts stat num into a six-char (right justified) string
56  */
cnv_stat(int val,char * out_val)57 void cnv_stat(int val, char *out_val)
58 {
59 	/* Above 18 */
60 	if (val > 18)
61 	{
62 		int bonus = (val - 18);
63 
64 		if (bonus >= 220)
65 		{
66 			sprintf(out_val, "18/%3s", "***");
67 		}
68 		else if (bonus >= 100)
69 		{
70 			sprintf(out_val, "18/%03d", bonus);
71 		}
72 		else
73 		{
74 			sprintf(out_val, " 18/%02d", bonus);
75 		}
76 	}
77 
78 	/* From 3 to 18 */
79 	else
80 	{
81 		sprintf(out_val, "    %2d", val);
82 	}
83 }
84 
85 
86 
87 /*
88  * Modify a stat value by a "modifier", return new value
89  *
90  * Stats go up: 3,4,...,17,18,18/10,18/20,...,18/220
91  * Or even: 18/13, 18/23, 18/33, ..., 18/220
92  *
93  * Stats go down: 18/220, 18/210,..., 18/10, 18, 17, ..., 3
94  * Or even: 18/13, 18/03, 18, 17, ..., 3
95  */
modify_stat_value(int value,int amount)96 s16b modify_stat_value(int value, int amount)
97 {
98 	int i;
99 
100 	/* Reward */
101 	if (amount > 0)
102 	{
103 		/* Apply each point */
104 		for (i = 0; i < amount; i++)
105 		{
106 			/* One point at a time */
107 			if (value < 18) value++;
108 
109 			/* Ten "points" at a time */
110 			else value += 10;
111 		}
112 	}
113 
114 	/* Penalty */
115 	else if (amount < 0)
116 	{
117 		/* Apply each point */
118 		for (i = 0; i < (0 - amount); i++)
119 		{
120 			/* Ten points at a time */
121 			if (value >= 18+10) value -= 10;
122 
123 			/* Hack -- prevent weirdness */
124 			else if (value > 18) value = 18;
125 
126 			/* One point at a time */
127 			else if (value > 3) value--;
128 		}
129 	}
130 
131 	/* Return new value */
132 	return (value);
133 }
134 
135 
136 
137 
138 
139 /*
140  * Print character stat in given row, column
141  */
prt_stat(int Ind,int stat)142 static void prt_stat(int Ind, int stat)
143 {
144 	player_type *p_ptr = Players[Ind];
145 	Send_stat(Ind, stat, p_ptr->stat_top[stat], p_ptr->stat_use[stat], p_ptr->stat_ind[stat], p_ptr->stat_max[stat]);
146 }
147 
148 
149 
150 
151 /*
152  * Prints "title", including "wizard" or "winner" as needed.
153  */
prt_title(int Ind)154 static void prt_title(int Ind) {
155 	player_type *p_ptr = Players[Ind];
156 	cptr p = "";
157 
158 	/* Ghost */
159 	if (p_ptr->ghost) p = "\377rGhost (dead)";
160 
161 	/* Winner */
162 #if 0
163 	else if (p_ptr->total_winner || (p_ptr->lev > PY_MAX_LEVEL)) {
164 		if (p_ptr->mode & (MODE_HARD | MODE_NO_GHOST))
165 			p = (p_ptr->male ? "**EMPEROR**" : "**EMPRESS**");
166 		else
167 			p = (p_ptr->male ? "**KING**" : "**QUEEN**");
168 	}
169 #else
170 	else if (p_ptr->total_winner || (p_ptr->lev > PY_MAX_LEVEL)) {
171 		char t[MAX_CHARS];
172 		strcpy(t, "\377v");
173 		strcat(t, get_ptitle(p_ptr, TRUE));
174 		Send_title(Ind, t);
175 		return;
176 	}
177 #endif
178 	/* Normal */
179 	else p = get_ptitle(p_ptr, TRUE);
180 
181 	Send_title(Ind, p);
182 }
183 
184 
185 /*
186  * Prints level
187  */
prt_level(int Ind)188 static void prt_level(int Ind) {
189 	player_type *p_ptr = Players[Ind];
190 	s64b adv_exp, adv_exp_prev = 0;
191 
192 	if (p_ptr->lev >= (is_admin(p_ptr) ? PY_MAX_LEVEL : PY_MAX_PLAYER_LEVEL))
193 		adv_exp = 0;
194 #ifndef ALT_EXPRATIO
195 	else adv_exp = (s64b)((s64b)player_exp[p_ptr->lev - 1] * (s64b)p_ptr->expfact / 100L);
196 #else
197 	else adv_exp = (s64b)player_exp[p_ptr->lev - 1];
198 #endif
199 
200 	if (p_ptr->lev > 1)
201 #ifndef ALT_EXPRATIO
202 		adv_exp_prev = (s64b)((s64b)player_exp[p_ptr->lev - 2] * (s64b)p_ptr->expfact / 100L);
203 #else
204 		adv_exp_prev = (s64b)player_exp[p_ptr->lev - 2];
205 #endif
206 
207 	Send_experience(Ind, p_ptr->lev, p_ptr->max_exp, p_ptr->exp, adv_exp, adv_exp_prev);
208 }
209 
210 
211 /*
212  * Display the experience
213  */
prt_exp(int Ind)214 static void prt_exp(int Ind) {
215 	player_type *p_ptr = Players[Ind];
216 	s64b adv_exp, adv_exp_prev = 0;
217 
218 	if (p_ptr->lev >= (is_admin(p_ptr) ? PY_MAX_LEVEL : PY_MAX_PLAYER_LEVEL))
219 		adv_exp = 0;
220 #ifndef ALT_EXPRATIO
221 	else adv_exp = (s64b)((s64b)player_exp[p_ptr->lev - 1] * (s64b)p_ptr->expfact / 100L);
222 #else
223 	else adv_exp = (s64b)player_exp[p_ptr->lev - 1];
224 #endif
225 
226 	if (p_ptr->lev > 1)
227 #ifndef ALT_EXPRATIO
228 		adv_exp_prev = (s64b)((s64b)player_exp[p_ptr->lev - 2] * (s64b)p_ptr->expfact / 100L);
229 #else
230 		adv_exp_prev = (s64b)player_exp[p_ptr->lev - 2];
231 #endif
232 
233 	Send_experience(Ind, p_ptr->lev, p_ptr->max_exp, p_ptr->exp, adv_exp, adv_exp_prev);
234 }
235 
236 
237 /*
238  * Prints current gold
239  */
prt_gold(int Ind)240 static void prt_gold(int Ind)
241 {
242 	player_type *p_ptr = Players[Ind];
243 
244 	Send_gold(Ind, p_ptr->au, p_ptr->balance);
245 }
246 
247 
248 
249 /*
250  * Prints current AC
251  */
prt_ac(int Ind)252 static void prt_ac(int Ind)
253 {
254 	player_type *p_ptr = Players[Ind];
255 
256 	Send_ac(Ind, p_ptr->dis_ac, p_ptr->dis_to_a);
257 }
258 
prt_sanity(int Ind)259 static void prt_sanity(int Ind)
260 {
261 #ifdef SHOW_SANITY	// No.
262 	player_type *p_ptr = Players[Ind];
263 #if 0
264 	Send_sanity(Ind, p_ptr->msane, p_ptr->csane);
265 #else	// 0
266 	char buf[20];
267 	byte attr = TERM_L_GREEN;
268 	int skill = get_skill(p_ptr, SKILL_HEALTH);
269 	int ratio;
270 	ratio = p_ptr->msane ? (p_ptr->csane * 100) / p_ptr->msane : 100;
271 
272 	/* Mindcrafters get better sanity display for free by levelling up */
273 	if (p_ptr->pclass == CLASS_MINDCRAFTER &&
274 	    p_ptr->lev >= skill)
275 		skill = p_ptr->lev;
276 
277 	/* Vague */
278 	if (ratio < 0) {
279 		/* This guy should be dead - for tombstone */
280 		attr = TERM_RED;
281 		strcpy(buf, "Vegetable");
282 	} else if (ratio < 10) {
283 //		attr = TERM_RED;
284 		attr = TERM_MULTI;
285 		strcpy(buf, "      MAD");
286 	} else if (ratio < 25) {
287 		attr = TERM_SHIELDI;
288 		strcpy(buf, "   Insane");
289 	} else if (ratio < 50) {
290 		attr = TERM_ORANGE;
291 		strcpy(buf, "   Crazy");
292 	} else if (ratio < 75) {
293 		attr = TERM_YELLOW;
294 		strcpy(buf, "    Weird");
295 	} else if (ratio < 90) {
296 		attr = TERM_GREEN;
297 		strcpy(buf, "     Sane");
298 	} else {
299 		attr = TERM_L_GREEN;
300 		strcpy(buf, "    Sound");
301 	}
302 
303 	switch (p_ptr->sanity_bar) {
304 	case 3: /* Full */
305 		snprintf(buf, sizeof(buf), "%4d/%4d", p_ptr->csane, p_ptr->msane);
306 		break;
307 	case 2: /* Percentile */
308 		snprintf(buf, sizeof(buf), "     %3d%%", ratio);
309 		break;
310 	case 1: /* Sanity Bar */
311 		{
312 			int tmp = ratio / 11;
313 			strcpy(buf, "---------");
314 			if (tmp > 0) strncpy(buf, "*********", tmp);
315 			break;
316 		}
317 	}
318 	/* Terminate */
319 	buf[9] = '\0';
320 
321 	/* Send it */
322 	Send_sanity(Ind, attr, buf);
323 
324 #endif	// 0
325 #endif	// SHOW_SANITY
326 }
327 
328 /*
329  * Prints Cur/Max hit points
330  */
prt_hp(int Ind)331 static void prt_hp(int Ind)
332 {
333 	player_type *p_ptr = Players[Ind];
334 
335 	Send_hp(Ind, p_ptr->mhp, p_ptr->chp);
336 }
337 
338 /*
339  * Prints Cur/Max stamina points
340  */
prt_stamina(int Ind)341 static void prt_stamina(int Ind)
342 {
343 	player_type *p_ptr = Players[Ind];
344 
345 	Send_stamina(Ind, p_ptr->mst, p_ptr->cst);
346 }
347 
348 /*
349  * Prints players max/cur spell points
350  */
prt_sp(int Ind)351 static void prt_sp(int Ind)
352 {
353 	player_type *p_ptr = Players[Ind];
354 
355 	/* Do not show mana unless it matters */
356 	Send_sp(Ind, p_ptr->msp, p_ptr->csp);
357 }
358 
359 
360 /*
361  * Prints depth in stat area
362  */
prt_depth(int Ind)363 static void prt_depth(int Ind)
364 {
365 	player_type *p_ptr = Players[Ind];
366 
367 	Send_depth(Ind, &p_ptr->wpos);
368 }
369 
370 
371 /*
372  * Prints status of hunger
373  */
prt_hunger(int Ind)374 static void prt_hunger(int Ind)
375 {
376 	player_type *p_ptr = Players[Ind];
377 
378 	Send_food(Ind, p_ptr->food);
379 }
380 
381 
382 /*
383  * Prints Blind status
384  */
prt_blind(int Ind)385 static void prt_blind(int Ind)
386 {
387 	player_type *p_ptr = Players[Ind];
388 
389 	if (p_ptr->blind) Send_blind(Ind, TRUE);
390 	else Send_blind(Ind, FALSE);
391 }
392 
393 
394 /*
395  * Prints Confusion status
396  */
prt_confused(int Ind)397 static void prt_confused(int Ind)
398 {
399 	player_type *p_ptr = Players[Ind];
400 
401 	if (p_ptr->confused) Send_confused(Ind, TRUE);
402 	else Send_confused(Ind, FALSE);
403 }
404 
405 
406 /*
407  * Prints Fear status
408  */
prt_afraid(int Ind)409 static void prt_afraid(int Ind)
410 {
411 	player_type *p_ptr = Players[Ind];
412 
413 	if (p_ptr->afraid) Send_fear(Ind, TRUE);
414 	else Send_fear(Ind, FALSE);
415 }
416 
417 
418 /*
419  * Prints Poisoned status
420  */
prt_poisoned(int Ind)421 static void prt_poisoned(int Ind)
422 {
423 	player_type *p_ptr = Players[Ind];
424 
425 	if (p_ptr->poisoned) Send_poison(Ind, TRUE);
426 	else Send_poison(Ind, FALSE);
427 }
428 
429 
430 /*
431  * Prints Searching, Resting, Paralysis, or 'count' status
432  * Display is always exactly 10 characters wide (see below)
433  *
434  * This function was a major bottleneck when resting, so a lot of
435  * the text formatting code was optimized in place below.
436  */
prt_state(int Ind)437 static void prt_state(int Ind)
438 {
439 	player_type *p_ptr = Players[Ind];
440 
441 	bool p, s, r;
442 
443 	/* Paralysis */
444 	if (p_ptr->paralyzed)
445 	{
446 		p = TRUE;
447 	}
448 	else
449 	{
450 		p = FALSE;
451 	}
452 
453 	/* Searching */
454 	if (p_ptr->searching)
455 	{
456 		s = TRUE;
457 	}
458 	else
459 	{
460 		s = FALSE;
461 	}
462 
463 	/* Resting */
464 	if (p_ptr->resting)
465 	{
466 		r = TRUE;
467 	}
468 	else
469 	{
470 		r = FALSE;
471 	}
472 
473 	Send_state(Ind, p, s, r);
474 }
475 
476 
477 /*
478  * Prints the speed of a character.			-CJS-
479  */
prt_speed(int Ind)480 static void prt_speed(int Ind)
481 {
482 	player_type *p_ptr = Players[Ind];
483 
484 	int i = p_ptr->pspeed;
485 
486 #if 0	/* methinks we'd better tell it to players.. - Jir - */
487 	/* Hack -- Visually "undo" the Search Mode Slowdown */
488 	/* And this formula can be wrong for hellish */
489 //	if (p_ptr->searching) i += (p_ptr->mode & MODE_HARD ? 5 : 10);
490 	if (p_ptr->searching) i += 10;
491 #endif	// 0
492 
493 	Send_speed(Ind, i - 110);
494 }
495 
496 
prt_study(int Ind)497 static void prt_study(int Ind)
498 {
499 	player_type *p_ptr = Players[Ind];
500 
501 	if (p_ptr->skill_points)
502 	{
503 		Send_study(Ind, TRUE);
504 	}
505 	else
506 	{
507 		Send_study(Ind, FALSE);
508 	}
509 }
510 
511 
prt_bpr(int Ind)512 static void prt_bpr(int Ind)
513 {
514 	player_type *p_ptr = Players[Ind];
515 	byte attr = TERM_L_GREEN;
516 
517 	switch (p_ptr->pclass) {
518 	case CLASS_WARRIOR:
519 	case CLASS_MIMIC:
520 	case CLASS_PALADIN:
521 	case CLASS_RANGER:
522 	case CLASS_ROGUE:
523 	case CLASS_MINDCRAFTER:
524 		if (p_ptr->num_blow == 1) attr = TERM_ORANGE;
525 		else if (p_ptr->num_blow == 2) attr = TERM_YELLOW;
526 		break;
527 	case CLASS_SHAMAN:
528 	case CLASS_ADVENTURER:
529 	case CLASS_RUNEMASTER:
530 	case CLASS_PRIEST:
531 	case CLASS_DRUID:
532 		if (p_ptr->num_blow == 1) attr = TERM_YELLOW;
533 		break;
534 	case CLASS_MAGE:
535 	case CLASS_ARCHER:
536 		break;
537 	}
538 
539 	Send_bpr(Ind, p_ptr->num_blow, attr);
540 }
541 
542 
prt_cut(int Ind)543 static void prt_cut(int Ind)
544 {
545 	player_type *p_ptr = Players[Ind];
546 //	cave_type **zcave;
547 	int c = p_ptr->cut;
548 
549 #if 0 /* deprecated */
550 	/* hack: no-tele indicator takes priority. */
551 	if ((zcave = getcave(&p_ptr->wpos)))
552 		if (zcave[p_ptr->py][p_ptr->px].info & CAVE_STCK) return;
553 #endif
554 	Send_cut(Ind, c); /* need to send this always since the client doesn't clear the whole field */
555 }
556 
557 
558 
prt_stun(int Ind)559 static void prt_stun(int Ind)
560 {
561 	player_type *p_ptr = Players[Ind];
562 
563 	int s = p_ptr->stun;
564 
565 	Send_stun(Ind, s);
566 }
567 
prt_history(int Ind)568 static void prt_history(int Ind)
569 {
570 	player_type *p_ptr = Players[Ind];
571 	int i;
572 
573 	for (i = 0; i < 4; i++)
574 	{
575 		Send_history(Ind, i, p_ptr->history[i]);
576 	}
577 }
578 
prt_various(int Ind)579 static void prt_various(int Ind)
580 {
581 	player_type *p_ptr = Players[Ind];
582 
583 	Send_various(Ind, p_ptr->ht, p_ptr->wt, p_ptr->age, p_ptr->sc, r_name + r_info[p_ptr->body_monster].name);
584 }
585 
prt_plusses(int Ind)586 static void prt_plusses(int Ind)
587 {
588 	player_type *p_ptr = Players[Ind];
589 	int bmh = 0, bmd = 0;
590 
591 	int show_tohit_m = p_ptr->dis_to_h + p_ptr->to_h_melee;
592 	int show_todam_m = p_ptr->dis_to_d + p_ptr->to_d_melee;
593 /*	int show_tohit_m = p_ptr->to_h_melee;
594 	int show_todam_m = p_ptr->to_d_melee;
595 */
596 	int show_tohit_r = p_ptr->dis_to_h + p_ptr->to_h_ranged;
597 	int show_todam_r = p_ptr->to_d_ranged;
598 
599 	/* well, about dual-wield.. we can only display the boni of one weapon or their average until we add another line
600 	   to squeeze info about the secondary weapon there too. so for now let's just stick with this. - C. Blue */
601 	object_type *o_ptr = &p_ptr->inventory[INVEN_WIELD];
602 	object_type *o_ptr2 = &p_ptr->inventory[INVEN_BOW];
603 	object_type *o_ptr3 = &p_ptr->inventory[INVEN_AMMO];
604 	object_type *o_ptr4 = &p_ptr->inventory[INVEN_ARM];
605 
606 	/* Hack -- add in weapon info if known */
607         if (object_known_p(Ind, o_ptr)) {
608 		bmh += o_ptr->to_h;
609 		bmd += o_ptr->to_d;
610 	}
611 	if (object_known_p(Ind, o_ptr2)) {
612 		show_tohit_r += o_ptr2->to_h;
613 		show_todam_r += o_ptr2->to_d;
614 	}
615 	if (object_known_p(Ind, o_ptr3)) {
616 		show_tohit_r += o_ptr3->to_h;
617 		show_todam_r += o_ptr3->to_d;
618 	}
619 	/* dual-wield..*/
620 	if (o_ptr4->k_idx && o_ptr4->tval != TV_SHIELD && p_ptr->dual_mode) {
621 		if (object_known_p(Ind, o_ptr4)) {
622 			bmh += o_ptr4->to_h;
623 			bmd += o_ptr4->to_d;
624 		}
625 		if (object_known_p(Ind, o_ptr) && object_known_p(Ind, o_ptr4)) {
626 			/* average of both */
627 			bmh /= 2;
628 			bmd /= 2;
629 		}
630 	}
631 	show_tohit_m += bmh;
632 	show_todam_m += bmd;
633 
634 //	Send_plusses(Ind, show_tohit_m, show_todam_m, show_tohit_r, show_todam_r, p_ptr->to_h_melee, p_ptr->to_d_melee);
635 	Send_plusses(Ind, 0, 0, show_tohit_r, show_todam_r, show_tohit_m, show_todam_m);
636 
637 	/* (not game-play relevant, just for easier handling in LUA scripts:) */
638 	p_ptr->overall_tohit_r = show_tohit_r;
639 	p_ptr->overall_todam_r = show_todam_r;
640 	p_ptr->overall_tohit_m = show_tohit_m;
641 	p_ptr->overall_todam_m = show_todam_m;
642 }
643 
prt_skills(int Ind)644 static void prt_skills(int Ind)
645 {
646 	Send_skills(Ind);
647 }
648 
prt_AFK(int Ind)649 static void prt_AFK(int Ind)
650 {
651 	player_type *p_ptr = Players[Ind];
652 
653 	byte afk = (p_ptr->afk ? 1 : 0);
654 
655 	Send_AFK(Ind, afk);
656 }
657 
prt_encumberment(int Ind)658 static void prt_encumberment(int Ind) {
659 	player_type *p_ptr = Players[Ind];
660 
661 	byte cumber_armor = p_ptr->cumber_armor ? 1 : 0;
662 	byte awkward_armor = p_ptr->awkward_armor ? 1 : 0;
663 	/* Hack - For mindcrafters, it's the helmet, not the gloves,
664 	   but they fortunately use the same item symbol :) */
665 	byte cumber_glove = p_ptr->cumber_glove || p_ptr->cumber_helm ? 1 : 0;
666 	byte heavy_wield = p_ptr->heavy_wield ? 1 : 0;
667 	byte heavy_shield = p_ptr->heavy_shield ? 1 : 0; /* added in 4.4.0f */
668 	byte heavy_shoot = p_ptr->heavy_shoot ? 1 : 0;
669 	byte icky_wield = p_ptr->icky_wield ? 1 : 0;
670 	byte awkward_wield = p_ptr->awkward_wield ? 1 : 0;
671 	byte easy_wield = p_ptr->easy_wield ? 1 : 0;
672 	byte cumber_weight = p_ptr->cumber_weight ? 1 : 0;
673 	/* See next line. Also, we're already using all 12 spaces we have available for icons.
674 	byte rogue_heavy_armor = p_ptr->rogue_heavyarmor ? 1 : 0; */
675 	 /* Hack - MA also gives dodging, which relies on rogue_heavy_armor anyway. */
676 	byte monk_heavyarmor, rogue_heavyarmor = 0;
677 	byte awkward_shoot = p_ptr->awkward_shoot ? 1 : 0;
678 	bool heavy_swim = p_ptr->heavy_swim ? 1 : 0;
679 	if (!is_newer_than(&p_ptr->version, 4, 4, 2, 0, 0, 0)) {
680 		monk_heavyarmor = (p_ptr->monk_heavyarmor || p_ptr->rogue_heavyarmor) ? 1 : 0;
681 	} else {
682 		monk_heavyarmor = p_ptr->monk_heavyarmor ? 1 : 0;
683 		rogue_heavyarmor = p_ptr->rogue_heavyarmor ? 1 : 0;
684 	}
685 
686 	if (p_ptr->pclass == CLASS_WARRIOR || p_ptr->pclass == CLASS_ARCHER) {
687 		awkward_armor = 0; /* they don't use magic or SP */
688 /* todo: make cumber_glove and awkward_armor either both get checked here, or in xtra1.c,
689    not one here, one in xtra1.c .. (cleaning-up measurements) */
690 	}
691 
692 	Send_encumberment(Ind, cumber_armor, awkward_armor, cumber_glove, heavy_wield, heavy_shield, heavy_shoot,
693                 icky_wield, awkward_wield, easy_wield, cumber_weight, monk_heavyarmor, rogue_heavyarmor, awkward_shoot, heavy_swim);
694 }
695 
prt_extra_status(int Ind)696 static void prt_extra_status(int Ind)
697 {
698 	player_type *p_ptr = Players[Ind];
699 	char status[12 + 24]; /* 24 for potential colours */
700 
701 	if (!is_newer_than(&p_ptr->version, 4, 4, 1, 5, 0, 0)) return;
702 
703 	/* add combat stance indicator */
704 	if (get_skill(p_ptr, SKILL_STANCE)) {
705 		switch(p_ptr->combat_stance) {
706 		case 0: strcpy(status, "\377sBl ");
707 			break;
708 		case 1: strcpy(status, "\377uDf ");
709 			break;
710 		case 2: strcpy(status, "\377oOf ");
711 			break;
712 		}
713 	} else strcpy(status, "   ");
714 
715 	/* add dual-wield mode indicator */
716 	if (get_skill(p_ptr, SKILL_DUAL) && p_ptr->dual_wield) {
717 		if (p_ptr->dual_mode)
718 			strcat(status, "\377sDH ");
719 		else
720 			strcat(status, "\377DMH ");
721 	} else strcat(status, "   ");
722 
723 	/* add fire-till-kill indicator */
724 	if (p_ptr->shoot_till_kill)
725 		strcat(status, "\377sFK ");
726 	else
727 		strcat(status, "   ");
728 
729 	/* add project-spells indicator */
730 	if (p_ptr->spell_project)
731 		strcat(status, "\377sPj ");
732 	else
733 		strcat(status, "   ");
734 
735 	Send_extra_status(Ind, status);
736 }
737 
738 
739 /*
740  * Redraw the "monster health bar"	-DRS-
741  * Rather extensive modifications by	-BEN-
742  *
743  * The "monster health bar" provides visual feedback on the "health"
744  * of the monster currently being "tracked".  There are several ways
745  * to "track" a monster, including targetting it, attacking it, and
746  * affecting it (and nobody else) with a ranged attack.
747  *
748  * Display the monster health bar (affectionately known as the
749  * "health-o-meter").  Clear health bar if nothing is being tracked.
750  * Auto-track current target monster when bored.  Note that the
751  * health-bar stops tracking any monster that "disappears".
752  */
753 
754 
health_redraw(int Ind)755 static void health_redraw(int Ind)
756 {
757 	player_type *p_ptr = Players[Ind];
758 
759 #ifdef DRS_SHOW_HEALTH_BAR
760 
761 	/* Not tracking */
762 	if (p_ptr->health_who == 0) {
763 		/* Erase the health bar */
764 		Send_monster_health(Ind, 0, 0);
765 	}
766 
767 	/* Tracking a hallucinatory monster */
768 	else if (p_ptr->image) {
769 		/* Indicate that the monster health is "unknown" */
770 		Send_monster_health(Ind, 0, TERM_WHITE);
771 	}
772 
773 	/* Tracking a player */
774 	else if (p_ptr->health_who < 0) {
775 		player_type *q_ptr = Players[0 - p_ptr->health_who];
776 
777 		if (Players[Ind]->conn == NOT_CONNECTED) {
778 			/* Send_monster_health(Ind, 0, 0); */
779 			return;
780 		}
781 
782 		if (0 - p_ptr->health_who < NumPlayers) {
783 			if(Players[0-p_ptr->health_who]->conn == NOT_CONNECTED ) {
784 				Send_monster_health(Ind, 0, 0);
785 				return;
786 			};
787 		} else {
788 			Send_monster_health(Ind, 0, 0);
789 			return;
790 		}
791 
792 
793 		/* Tracking a bad player (?) */
794 		if (!q_ptr) {
795 			/* Erase the health bar */
796 			Send_monster_health(Ind, 0, 0);
797 		}
798 
799 		/* Tracking an unseen player */
800 		else if (!p_ptr->play_vis[0 - p_ptr->health_who] && !is_admin(p_ptr)) {
801 			/* Indicate that the player health is "unknown" */
802 			Send_monster_health(Ind, 0, TERM_WHITE);
803 		}
804 
805 		/* Tracking a visible player */
806 		else {
807 			int pct, len;
808 
809 			/* Default to almost dead */
810 			byte attr = TERM_RED;
811 
812 			/* Extract the "percent" of health */
813 			pct = 100L * q_ptr->chp / q_ptr->mhp;
814 
815 			/* Badly wounded */
816 			if (pct >= 10) attr = TERM_L_RED;
817 
818 			/* Wounded */
819 			if (pct >= 25) attr = TERM_ORANGE;
820 
821 			/* Somewhat Wounded */
822 			if (pct >= 60) attr = TERM_YELLOW;
823 
824 			/* Healthy */
825 			if (pct >= 100) attr = TERM_L_GREEN;
826 
827 			/* Afraid */
828 			if (q_ptr->afraid) attr = TERM_VIOLET;
829 
830 			/* Asleep (?) */
831 			if (q_ptr->paralyzed) attr = TERM_BLUE;
832 
833 			/* Convert percent into "health" */
834 			len = (pct < 10) ? 1 : (pct < 90) ? (pct / 10 + 1) : 10;
835 
836 			/* Send the health */
837 			Send_monster_health(Ind, len, attr);
838 		}
839 	}
840 
841 	/* Tracking a bad monster (?) */
842 	else if (!m_list[p_ptr->health_who].r_idx) {
843 		/* Erase the health bar */
844 		Send_monster_health(Ind, 0, 0);
845 	}
846 
847 	/* Tracking an unseen monster */
848 	else if (!p_ptr->mon_vis[p_ptr->health_who] && !is_admin(p_ptr)) {
849 		/* Indicate that the monster health is "unknown" */
850 		Send_monster_health(Ind, 0, TERM_WHITE);
851 	}
852 
853 	/* Tracking a dead monster (???) */
854 	else if (m_list[p_ptr->health_who].hp < 0) {
855 		/* Indicate that the monster health is "unknown" */
856 		Send_monster_health(Ind, 0, TERM_WHITE);
857 	}
858 
859 	/* Tracking a visible monster */
860 	else {
861 		int pct, len;
862 
863 		monster_type *m_ptr = &m_list[p_ptr->health_who];
864 
865 		/* Default to almost dead */
866 		byte attr = TERM_RED;
867 
868 		/* Crash once occurred here, m_ptr->hp -296, m_ptr->maxhp 0 - C. Blue
869 		   --also occurred in xtra2.c:8237, mon_take_hit() */
870 		if (m_ptr->maxhp == 0) {
871 			Send_monster_health(Ind, 0, 0);
872 			s_printf("DBG_MAXHP_4 %d,%d\n", m_ptr->r_idx, m_ptr->ego);
873 			return;
874 		}
875 
876 		/* Extract the "percent" of health */
877 		pct = 100L * m_ptr->hp / m_ptr->maxhp;
878 
879 		/* Badly wounded */
880 		if (pct >= 10) attr = TERM_L_RED;
881 
882 		/* Wounded */
883 		if (pct >= 25) attr = TERM_ORANGE;
884 
885 		/* Somewhat Wounded */
886 		if (pct >= 60) attr = TERM_YELLOW;
887 
888 		/* Healthy */
889 		if (pct >= 100) attr = TERM_L_GREEN;
890 
891 		/* Afraid */
892 		if (m_ptr->monfear) attr = TERM_VIOLET;
893 
894 		/* Asleep */
895 		if (m_ptr->csleep) attr = TERM_BLUE;
896 
897 		/* Convert percent into "health" */
898 		len = (pct < 10) ? 1 : (pct < 90) ? (pct / 10 + 1) : 10;
899 
900 		/* Send the health */
901 		Send_monster_health(Ind, len, attr);
902 	}
903 
904 #endif
905 
906 }
907 
908 
909 
910 /*
911  * Display basic info (mostly left of map)
912  */
prt_frame_basic(int Ind)913 static void prt_frame_basic(int Ind)
914 {
915 	player_type *p_ptr = Players[Ind];
916 	int i;
917 
918 	/* Race and Class */
919 	Send_char_info(Ind, p_ptr->prace, p_ptr->pclass, p_ptr->ptrait, p_ptr->male, p_ptr->mode, p_ptr->name);
920 
921 	/* Title */
922 	prt_title(Ind);
923 
924 	/* Level/Experience */
925 	prt_level(Ind);
926 	prt_exp(Ind);
927 
928 	/* All Stats */
929 	for (i = 0; i < 6; i++) prt_stat(Ind, i);
930 
931 	/* Armor */
932 	prt_ac(Ind);
933 
934 	/* Hitpoints */
935 	prt_hp(Ind);
936 
937 	/* Sanity */
938 #ifdef SHOW_SANITY
939 	prt_sanity(Ind);
940 #endif
941 
942 	/* Spellpoints */
943 	prt_sp(Ind);
944 
945 	/* Stamina */
946 	prt_stamina(Ind);
947 
948 	/* Gold */
949 	prt_gold(Ind);
950 
951 	/* Current depth */
952 	prt_depth(Ind);
953 
954 	/* Special */
955 	health_redraw(Ind);
956 }
957 
958 
959 /*
960  * Display extra info (mostly below map)
961  */
prt_frame_extra(int Ind)962 static void prt_frame_extra(int Ind)
963 {
964 #if 0 /* deprecated */
965 	/* Mega-Hack : display AFK status in place of 'stun' status! */
966 #endif
967 	prt_AFK(Ind);
968 
969 	/* Give monster health priority over AFK status display */
970 	health_redraw(Ind);
971 
972 	/* Cut/Stun */
973 	prt_cut(Ind);
974 #if 0 /* deprecated */
975 	/* Mega-Hack : AFK and Stun share a field */
976 	if (Players[Ind]->stun || !Players[Ind]->afk) prt_stun(Ind);
977 #else
978 	prt_stun(Ind);
979 #endif
980 
981 	/* Food */
982 	prt_hunger(Ind);
983 
984 	/* Various */
985 	prt_blind(Ind);
986 	prt_confused(Ind);
987 	prt_afraid(Ind);
988 	prt_poisoned(Ind);
989 
990 	/* State */
991 	prt_state(Ind);
992 
993 	/* Speed */
994 	prt_speed(Ind);
995 
996 	if (is_older_than(&Players[Ind]->version, 4, 4, 8, 5, 0, 0))
997 		/* Study spells */
998 		prt_study(Ind);
999 	else
1000 		/* Blows/Round */
1001 		prt_bpr(Ind);
1002 }
1003 
1004 
1005 /*
1006  * Hack -- display inventory in sub-windows
1007  */
fix_inven(int Ind)1008 static void fix_inven(int Ind)
1009 {
1010 	/* Resend the inventory */
1011 	display_inven(Ind);
1012 }
1013 
1014 
1015 
1016 /*
1017  * Hack -- display equipment in sub-windows
1018  */
fix_equip(int Ind)1019 static void fix_equip(int Ind)
1020 {
1021 	/* Resend the equipment */
1022 	display_equip(Ind);
1023 }
1024 
1025 /*
1026  * Hack -- display character in sub-windows
1027  */
fix_player(int Ind)1028 static void fix_player(int Ind)
1029 {
1030 }
1031 
1032 
1033 
1034 /*
1035  * Hack -- display recent messages in sub-windows
1036  *
1037  * XXX XXX XXX Adjust for width and split messages
1038  */
fix_message(int Ind)1039 static void fix_message(int Ind)
1040 {
1041 }
1042 
1043 
1044 /*
1045  * Hack -- display overhead view in sub-windows
1046  *
1047  * Note that the "player" symbol does NOT appear on the map.
1048  */
fix_overhead(int Ind)1049 static void fix_overhead(int Ind)
1050 {
1051 }
1052 
1053 
1054 /*
1055  * Hack -- display monster recall in sub-windows
1056  */
fix_monster(int Ind)1057 static void fix_monster(int Ind)
1058 {
1059 }
1060 
1061 /*
1062  * Calculate the player's sanity
1063  */
1064 
calc_sanity(int Ind)1065 static void calc_sanity(int Ind) {
1066 	player_type *p_ptr = Players[Ind];
1067 	int bonus, msane;
1068 	/* Don't make the capacity too large */
1069 	int lev = p_ptr->lev > 50 ? 50 : p_ptr->lev;
1070 
1071 	/* Hack -- use the con/hp table for sanity/wis */
1072 	bonus = ((int)(adj_wis_msane[p_ptr->stat_ind[A_WIS]]) - 128);
1073 
1074 	/* Hack -- assume 5 sanity points per level. */
1075 	msane = 5*(lev+1) + (bonus * lev / 2);
1076 
1077 	if (msane < lev + 1) msane = lev + 1;
1078 
1079 	if (p_ptr->msane != msane) {
1080 
1081 		/* Sanity carries over between levels. */
1082 		p_ptr->csane += (msane - p_ptr->msane);
1083 		/* If sanity just dropped to 0 or lower, die! */
1084                 if (p_ptr->csane < 0) {
1085 			if (!p_ptr->safe_sane) {
1086 	                        /* Hack -- Note death */
1087 	                        msg_print(Ind, "\377vYou turn into an unthinking vegetable.");
1088 				(void)strcpy(p_ptr->died_from, "insanity");
1089 				(void)strcpy(p_ptr->really_died_from, "insanity");
1090 		                if (!p_ptr->ghost) {
1091 			                strcpy(p_ptr->died_from_list, "insanity");
1092 			                p_ptr->died_from_depth = getlevel(&p_ptr->wpos);
1093 					/* Hack to remember total winning */
1094 		                        if (p_ptr->total_winner) strcat(p_ptr->died_from_list, "\001");
1095 				}
1096 	            		/* No longer a winner */
1097 //			        p_ptr->total_winner = FALSE;
1098 				/* Note death */
1099 				p_ptr->death = TRUE;
1100 		                p_ptr->deathblow = 0;
1101 			} else {
1102 				p_ptr->csane = 0;
1103 			}
1104 		}
1105 
1106 		p_ptr->msane = msane;
1107 
1108 		if (p_ptr->csane >= msane) {
1109 			p_ptr->csane = msane;
1110 			p_ptr->csane_frac = 0;
1111 		}
1112 
1113 		p_ptr->redraw |= (PR_SANITY);
1114 		p_ptr->window |= (PW_PLAYER);
1115 	}
1116 }
1117 
1118 
1119 /*
1120  * Calculate maximum mana.  You do not need to know any spells.
1121  * Note that mana is lowered by heavy (or inappropriate) armor.
1122  *
1123  * This function induces status messages.
1124  */
1125 //static void calc_mana(int Ind)
calc_mana(int Ind)1126 void calc_mana(int Ind) {
1127 	player_type *p_ptr = Players[Ind];
1128 	player_type *p_ptr2 = NULL; /* silence the warning */
1129 	int Ind2;
1130 
1131 	int levels, cur_wgt, max_wgt, tmp_lev;
1132 	s32b new_mana = 0;
1133 
1134 	object_type *o_ptr;
1135 	u32b f1, f2, f3, f4, f5, f6, esp;
1136 
1137 	if ((Ind2 = get_esp_link(Ind, LINKF_PAIN, &p_ptr2))) {
1138 	}
1139 
1140 	/* Extract "effective" player level */
1141 	tmp_lev = p_ptr->lev * 10;
1142 	if (p_ptr->lev <= 50) levels = tmp_lev;
1143 	/* Less additional mana gain for each further post-king level */
1144 	else if (p_ptr->lev <= 70) levels = 500 + (tmp_lev - 500) / 2;
1145 	else if (p_ptr->lev <= 85) levels = 500 + 100 + (tmp_lev - 700) / 3;
1146 	else levels = 500 + 100 + 50 + (tmp_lev - 850) / 4;
1147 
1148 	/* Hack -- no negative mana */
1149 	if (levels < 0) levels = 0;
1150 
1151 	/* Extract total mana */
1152 	switch(p_ptr->pclass) {
1153 	case CLASS_MAGE:
1154 		/* much Int, few Wis */
1155 		new_mana = get_skill_scale(p_ptr, SKILL_MAGIC, 200) +
1156 			    (adj_mag_mana[p_ptr->stat_ind[A_INT]] * 85 * levels  +
1157 			    adj_mag_mana[p_ptr->stat_ind[A_WIS]] * 15 * levels) / 3000;
1158 		break;
1159 	case CLASS_RANGER:
1160 		/* much Int, few Wis --180 */
1161 		new_mana = get_skill_scale(p_ptr, SKILL_MAGIC, 200) +
1162 			    (adj_mag_mana[p_ptr->stat_ind[A_INT]] * 85 * levels +
1163 			    adj_mag_mana[p_ptr->stat_ind[A_WIS]] * 15 * levels) / 5000;
1164 		break;
1165 	case CLASS_PRIEST:
1166 		/* few Int, much Wis --170 */
1167 		new_mana = get_skill_scale(p_ptr, SKILL_MAGIC, 200) +
1168 			    (adj_mag_mana[p_ptr->stat_ind[A_INT]] * 15 * levels +
1169 			    adj_mag_mana[p_ptr->stat_ind[A_WIS]] * 85 * levels) / 3750;
1170 		break;
1171 	case CLASS_DRUID:
1172 		/* few Int, much Wis --170 */
1173 		new_mana = get_skill_scale(p_ptr, SKILL_MAGIC, 200) +
1174 			    (adj_mag_mana[p_ptr->stat_ind[A_INT]] * 15 * levels +
1175 			    adj_mag_mana[p_ptr->stat_ind[A_WIS]] * 85 * levels) / 4000;
1176 		break;
1177 	case CLASS_PALADIN:
1178 		/* few Int, much Wis --140 */
1179 		new_mana = get_skill_scale(p_ptr, SKILL_MAGIC, 200) +
1180 			    (adj_mag_mana[p_ptr->stat_ind[A_INT]] * 15 * levels +
1181 			    adj_mag_mana[p_ptr->stat_ind[A_WIS]] * 85 * levels) / 5500;
1182 		break;
1183 	case CLASS_ROGUE:
1184 		/* much Int, few Wis --160 */
1185 		new_mana = get_skill_scale(p_ptr, SKILL_MAGIC, 200) +
1186 			    (adj_mag_mana[p_ptr->stat_ind[A_INT]] * 85 * levels +
1187 			    adj_mag_mana[p_ptr->stat_ind[A_WIS]] * 15 * levels) / 5500;
1188 	case CLASS_MIMIC:
1189 		/* much Int, few Wis --160 */
1190 		new_mana = get_skill_scale(p_ptr, SKILL_MAGIC, 200) +
1191 			    (adj_mag_mana[p_ptr->stat_ind[A_INT]] * 85 * levels +
1192 			    adj_mag_mana[p_ptr->stat_ind[A_WIS]] * 15 * levels) / 5000;
1193 		break;
1194 	case CLASS_ARCHER:
1195 	case CLASS_WARRIOR:
1196 		new_mana = 0;
1197 		break;
1198 	case CLASS_SHAMAN:
1199 #if 0
1200 		/* more Wis than Int --180 */
1201 		new_mana = get_skill_scale(p_ptr, SKILL_MAGIC, 200) +
1202 			    (adj_mag_mana[p_ptr->stat_ind[A_INT]] * 35 * levels +
1203 			    adj_mag_mana[p_ptr->stat_ind[A_WIS]] * 65 * levels) / 4000;
1204 #else
1205 		/* Depends on what's better, his WIS or INT --180 */
1206 		new_mana = get_skill_scale(p_ptr, SKILL_MAGIC, 200) +
1207 			    ((p_ptr->stat_ind[A_INT] > p_ptr->stat_ind[A_WIS]) ?
1208 			    (adj_mag_mana[p_ptr->stat_ind[A_INT]] * 100 * levels) :
1209 			    (adj_mag_mana[p_ptr->stat_ind[A_WIS]] * 100 * levels)) / 4000;
1210 #endif
1211 		break;
1212 	case CLASS_RUNEMASTER:
1213 		//Spells are now much closer in cost to mage spells. Returning to a similar mode
1214 		new_mana = get_skill_scale(p_ptr, SKILL_MAGIC, 200) +
1215 		    (adj_mag_mana[p_ptr->stat_ind[A_INT]] * 65 * levels +
1216 		    adj_mag_mana[p_ptr->stat_ind[A_DEX]] * 35 * levels) / 3000;
1217 		break;
1218 	case CLASS_MINDCRAFTER:
1219 		/* much Int, some Chr (yeah!), little Wis */
1220 		new_mana = get_skill_scale(p_ptr, SKILL_MAGIC, 200) + /* <- seems this might be important actually */
1221 			    (adj_mag_mana[p_ptr->stat_ind[A_INT]] * 85 * levels +
1222 			    adj_mag_mana[p_ptr->stat_ind[A_CHR]] * 10 * levels +
1223 			    adj_mag_mana[p_ptr->stat_ind[A_WIS]] * 5 * levels) / 4000;
1224 		break;
1225 
1226 	case CLASS_ADVENTURER:
1227 //	case CLASS_BARD:
1228 	default:
1229 		/* 50% Int, 50% Wis --160 */
1230 		new_mana = get_skill_scale(p_ptr, SKILL_MAGIC, 200) +
1231 		(adj_mag_mana[p_ptr->stat_ind[A_INT]] * 50 * levels +
1232 		adj_mag_mana[p_ptr->stat_ind[A_WIS]] * 50 * levels) / 5500;
1233 		break;
1234 	}
1235 
1236 	/* Hack -- usually add one mana */
1237 	if (new_mana) new_mana++;
1238 
1239 	/* Get the gloves */
1240 	o_ptr = &p_ptr->inventory[INVEN_HANDS];
1241 
1242 	/* Examine the gloves */
1243 	object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &f6, &esp);
1244 
1245 	/* Only Sorcery/Magery users are affected */
1246 	if (get_skill(p_ptr, SKILL_SORCERY) || get_skill(p_ptr, SKILL_MAGERY)) {
1247 		/* Assume player is not encumbered by gloves */
1248 		p_ptr->cumber_glove = FALSE;
1249 
1250 		/* Normal gloves hurt mage-type spells */
1251 		if (o_ptr->k_idx &&
1252 		    !(f2 & TR2_FREE_ACT) && !(f1 & TR1_MANA) &&
1253 		    !((f1 & TR1_DEX) && (o_ptr->pval > 0)) &&
1254 		    !(o_ptr->tval == TV_GLOVES && o_ptr->sval == SV_SET_OF_ELVEN_GLOVES)) //Elven Gloves -> no penalty
1255 		{
1256 			/* Encumbered */
1257 			p_ptr->cumber_glove = TRUE;
1258 
1259 			/* Reduce mana */
1260 			new_mana = (3 * new_mana) / 4;
1261 		}
1262 	}
1263 
1264 	/* Mindcrafting is obstructed by heavy helmets (even non-tin foil) */
1265 	/* Get the helm */
1266 	o_ptr = &p_ptr->inventory[INVEN_HEAD];
1267 
1268 	/* Only mindcraft-users are affected (CLASS_MINDCRAFTER) */
1269 	if (get_skill(p_ptr, SKILL_PPOWER) ||
1270 	    get_skill(p_ptr, SKILL_TCONTACT) ||
1271 	    get_skill(p_ptr, SKILL_MINTRUSION))
1272 	{
1273 		/* Assume player is not encumbered by helm */
1274 		p_ptr->cumber_helm = FALSE;
1275 
1276 		/* too heavy helm? */
1277 		if (o_ptr->weight > 40) {
1278 			/* Encumbered */
1279 			p_ptr->cumber_helm = TRUE;
1280 
1281 			/* Reduce mana */
1282 			new_mana = (3 * new_mana) / 4;
1283 		}
1284 	}
1285 
1286 	if (new_mana <= 0) new_mana = 1;
1287 
1288 	/* adjustment so paladins won't become OoD sentry guns and
1289 	   rangers won't become invulnerable manashield tanks, and
1290 	   priests won't become OoD wizards.. (C. Blue)
1291 	   Removed ranger mana penalty here, added handicap in spells1.c
1292 	   where disruption shield is calculated. (C. Blue) */
1293 	switch(p_ptr->pclass) {
1294 	case CLASS_MAGE:
1295 	case CLASS_RANGER:
1296 		if (p_ptr->to_m) new_mana += new_mana * p_ptr->to_m / 100;
1297 		break;
1298 	case CLASS_ADVENTURER:
1299 	case CLASS_SHAMAN:
1300 	case CLASS_DRUID:
1301 	/* in theory these actually don't use 'magic mana' at all?: */
1302 	case CLASS_PRIEST: /* maybe Shamans are treated too good in comparison here */
1303 		if (p_ptr->to_m) new_mana += new_mana * p_ptr->to_m / 130;
1304 		break;
1305 	case CLASS_PALADIN:
1306 		if (p_ptr->to_m) new_mana += new_mana * p_ptr->to_m / 200;
1307 		break;
1308 	/* non-holy again: -- hm not sure if they still need to get reduced effect*/
1309 	case CLASS_MIMIC:
1310 	case CLASS_ROGUE:
1311 #if 0
1312 		if (p_ptr->to_m) new_mana += new_mana * p_ptr->to_m / 150;
1313 #else /* why not.. */
1314 		if (p_ptr->to_m) new_mana += new_mana * p_ptr->to_m / 100;
1315 #endif
1316 		break;
1317 	/* hybrids & more */
1318 	case CLASS_MINDCRAFTER:
1319 	case CLASS_RUNEMASTER:
1320 	default:
1321 		if (p_ptr->to_m) new_mana += new_mana * p_ptr->to_m / 100;
1322 		break;
1323 	}
1324 
1325 	/* Meditation increase mana at the cost of hp */
1326 	if (p_ptr->tim_meditation) new_mana += (new_mana * get_skill(p_ptr, SKILL_SORCERY)) / 100;
1327 
1328 	/* Disruption Shield now increases hp at the cost of mana */
1329 	if (p_ptr->tim_manashield) {
1330 	/* commented out (evileye for power) */
1331 	/*	new_mana -= new_mana / 2; */
1332 	}
1333 
1334 #if 1 /* now not anymore done in calc_boni (which is called before calc_mana) */
1335 	/* Assume player not encumbered by armor */
1336 	p_ptr->awkward_armor = FALSE;
1337 
1338 	/* Weigh the armor */
1339 	cur_wgt = worn_armour_weight(p_ptr);
1340 
1341 	/* Determine the weight allowance */
1342 //	max_wgt = 200 + get_skill_scale(p_ptr, SKILL_COMBAT, 250); break;
1343 	switch (p_ptr->pclass) {
1344 	case CLASS_MAGE: max_wgt = 150 + get_skill_scale(p_ptr, SKILL_COMBAT, 150); break;
1345 	case CLASS_RANGER: max_wgt = 240 + get_skill_scale(p_ptr, SKILL_COMBAT, 150); break;
1346 	case CLASS_PRIEST: max_wgt = 250 + get_skill_scale(p_ptr, SKILL_COMBAT, 150); break;
1347 	case CLASS_PALADIN: max_wgt = 300 + get_skill_scale(p_ptr, SKILL_COMBAT, 150); break;
1348 	case CLASS_DRUID: max_wgt = 200 + get_skill_scale(p_ptr, SKILL_COMBAT, 150); break;
1349 	case CLASS_SHAMAN: max_wgt = 170 + get_skill_scale(p_ptr, SKILL_COMBAT, 150); break;
1350 	case CLASS_ROGUE: max_wgt = 200 + get_skill_scale(p_ptr, SKILL_COMBAT, 150); break;
1351 	case CLASS_RUNEMASTER: max_wgt = 230 + get_skill_scale(p_ptr, SKILL_COMBAT, 150); break;/*was 270*/
1352 	case CLASS_MIMIC: max_wgt = 280 + get_skill_scale(p_ptr, SKILL_COMBAT, 150); break;
1353 	case CLASS_ADVENTURER: max_wgt = 210 + get_skill_scale(p_ptr, SKILL_COMBAT, 150); break;
1354 //	case CLASS_MINDCRAFTER: max_wgt = 230 + get_skill_scale(p_ptr, SKILL_COMBAT, 150); break;
1355 	case CLASS_MINDCRAFTER: max_wgt = 260 + get_skill_scale(p_ptr, SKILL_COMBAT, 150); break;
1356 	case CLASS_WARRIOR:
1357 	case CLASS_ARCHER:
1358 	default: max_wgt = 1000; break;
1359 	}
1360 
1361 	/* Heavy armor penalizes mana */
1362 //	if (((cur_wgt - max_wgt) / 10) > 0) {
1363 	if ((cur_wgt - max_wgt) > 0) {
1364 		/* Reduce mana */
1365 //		new_mana -= ((cur_wgt - max_wgt) * 2 / 3);
1366 
1367 		/* square root - C. Blue */
1368 /*		long tmp, tmp2;
1369 		tmp = (cur_wgt - max_wgt) * 1000;
1370 		tmp2 = 1000;
1371 		if (tmp > 1000) do {
1372 			tmp *= 1000;
1373 			tmp /= 1320;
1374 			tmp2 *= 1149;
1375 			tmp2 /= 1000;
1376 		} while (tmp > 1000)
1377 		tmp2 /= 1000;
1378 		new_mana *= (10 - tmp2);
1379 */
1380 		new_mana -= (new_mana * (cur_wgt - max_wgt > 100 ? 100 : cur_wgt - max_wgt)) / 100;
1381 
1382 		/* Encumbered */
1383 		p_ptr->awkward_armor = TRUE;
1384 	}
1385 #endif
1386 
1387 	if (Ind2) new_mana += p_ptr2->msp / 2;
1388 
1389 	/* Mana can never be negative */
1390 	if (new_mana < 0) new_mana = 0;
1391 
1392 	/* Some classes dont use mana */
1393 	if ((p_ptr->pclass == CLASS_WARRIOR) ||
1394 	    (p_ptr->pclass == CLASS_ARCHER))
1395 		new_mana = 0;
1396 
1397 #ifdef ARCADE_SERVER
1398         new_mana = 100;
1399 #endif
1400 
1401 	/* Maximum mana has changed */
1402 	if (p_ptr->msp != new_mana) {
1403 		/* Player has no mana now */
1404 		if (!new_mana) {
1405 			/* No mana left */
1406 			p_ptr->csp = 0;
1407 			p_ptr->csp_frac = 0;
1408 		}
1409 
1410 		/* Player had no mana, has some now */
1411 		else if (!p_ptr->msp) {
1412 			/* Reset mana */
1413 #if 0 /* completely cheezable restoration */
1414 			p_ptr->csp = new_mana;
1415 #endif
1416 			p_ptr->csp_frac = 0;
1417 		}
1418 
1419 		/* Player had some mana, adjust current mana */
1420 		else {
1421 			s32b value;
1422 
1423 			/* change current mana proportionately to change of max mana, */
1424 			/* divide first to avoid overflow, little loss of accuracy */
1425 			value = ((((long)p_ptr->csp << 16) + p_ptr->csp_frac) /
1426 				p_ptr->msp * new_mana);
1427 
1428 			/* Extract mana components */
1429 			p_ptr->csp = (value >> 16);
1430 			p_ptr->csp_frac = (value & 0xFFFF);
1431 		}
1432 
1433 		/* Save new mana */
1434 		p_ptr->msp = new_mana;
1435 
1436 		/* Display mana later */
1437 		p_ptr->redraw |= (PR_MANA);
1438 
1439 		/* Window stuff */
1440 		p_ptr->window |= (PW_PLAYER);
1441 	}
1442 
1443 	/* Take note when "glove state" changes */
1444 	if (p_ptr->old_cumber_glove != p_ptr->cumber_glove) {
1445 		/* Message */
1446 		if (p_ptr->cumber_glove)
1447 			msg_print(Ind, "\377oYour covered hands feel unsuitable for spellcasting.");
1448 		else
1449 			msg_print(Ind, "\377gYour hands feel more suitable for spellcasting.");
1450 
1451 		/* Save it */
1452 		p_ptr->old_cumber_glove = p_ptr->cumber_glove;
1453 	}
1454 
1455 	/* Take note when "helm state" changes */
1456 	if (p_ptr->old_cumber_helm != p_ptr->cumber_helm) {
1457 		/* Message */
1458 		if (p_ptr->cumber_helm)
1459 			msg_print(Ind, "\377oYour heavy headgear feels unsuitable for mindcrafting.");
1460 		else
1461 			msg_print(Ind, "\377gYour headgear feels more suitable for mindcrafting.");
1462 
1463 		/* Save it */
1464 		p_ptr->old_cumber_helm = p_ptr->cumber_helm;
1465 	}
1466 
1467 
1468 	/* Take note when "armor state" changes */
1469 	if (p_ptr->old_awkward_armor != p_ptr->awkward_armor) {
1470 		if (p_ptr->pclass != CLASS_WARRIOR && p_ptr->pclass != CLASS_ARCHER) {
1471 			/* Message */
1472 			if (p_ptr->awkward_armor)
1473 				msg_print(Ind, "\377oThe weight of your armour strains your spellcasting.");
1474 			else
1475 				msg_print(Ind, "\377gYou feel able to cast more freely.");
1476 		}
1477 		/* Save it */
1478 		p_ptr->old_awkward_armor = p_ptr->awkward_armor;
1479 	}
1480 
1481 	/* refresh encumberment status line */
1482 //	p_ptr->redraw |= PR_ENCUMBERMENT;// <- causes bad packet bugs when shopping
1483 }
1484 
1485 
1486 
1487 /*
1488  * Calculate the players (maximal) hit points
1489  * Adjust current hitpoints if necessary
1490  */
1491 
1492 /* An option of giving mages an extra hit point per level has been added,
1493  * to hopefully facilitate them making it down to 1600ish and finding
1494  * Constitution potions.  This should probably be changed to stop after level
1495  * 30.
1496  */
1497 
calc_hitpoints(int Ind)1498 void calc_hitpoints(int Ind) {
1499 	player_type *p_ptr = Players[Ind], *p_ptr2 = NULL; /* silence the warning */
1500 	int player_hp_eff; /* replacement for accessing player_hp[] directly */
1501 
1502 //	object_type *o_ptr;
1503 //	u32b f1, f2, f3, f4, f5, f6, esp;
1504 
1505 	int bonus, Ind2 = 0, cr_mhp = p_ptr->cp_ptr->c_mhp + p_ptr->rp_ptr->r_mhp;
1506 	long mhp, mhp_playerform, weakling_boost;
1507 	u32b mHPLim, finalHP;
1508 	int bonus_cap, to_life;
1509 
1510 	if ((Ind2 = get_esp_link(Ind, LINKF_PAIN, &p_ptr2))) {
1511 	}
1512 
1513 	/* do not increase a character's hit points too high post-king.
1514 	   They will just become immortal and that's no fun either. */
1515 	if (p_ptr->lev <= 50) player_hp_eff = p_ptr->player_hp[p_ptr->lev - 1]; /* the usual way */
1516 	else {
1517 		/* reduce post-king gain */
1518 		player_hp_eff = p_ptr->player_hp[50 - 1];
1519 		if (p_ptr->lev <= 70) player_hp_eff += (p_ptr->player_hp[p_ptr->lev - 1] - p_ptr->player_hp[50 - 1]) / 2;
1520 		else {
1521 			player_hp_eff += (p_ptr->player_hp[70 - 1] - p_ptr->player_hp[50 - 1]) / 2;
1522 			if (p_ptr->lev <= 85) player_hp_eff += (p_ptr->player_hp[p_ptr->lev - 1] - p_ptr->player_hp[70 - 1]) / 3;
1523 			else {
1524 				player_hp_eff += (p_ptr->player_hp[85 - 1] - p_ptr->player_hp[70 - 1]) / 3;
1525 				player_hp_eff += (p_ptr->player_hp[p_ptr->lev - 1] - p_ptr->player_hp[85 - 1]) / 4;
1526 			}
1527 		}
1528 	}
1529 
1530 	/* Un-inflate "half-hitpoint bonus per level" value */
1531 	bonus = ((int)(adj_con_mhp[p_ptr->stat_ind[A_CON]]) - 128);
1532 
1533 	/* Calculate hitpoints */
1534 	if (!cfg.bonus_calc_type) {
1535 		/* The traditional way.. */
1536 		mhp = player_hp_eff + (bonus * p_ptr->lev / 2);
1537 	} else {
1538 		/* Don't exaggerate with HP on low levels (especially Ents) (bonus range is -5..+25) */
1539 		bonus_cap = ((p_ptr->lev + 5) * (p_ptr->lev + 5)) / 100;
1540 		if (bonus > bonus_cap) bonus = bonus_cap;
1541 
1542 		/* And here I made the formula slightly more complex to fit better :> - C. Blue -
1543 		   Explanation why I made If-clauses for Istari (Mage) and Yeeks:
1544 		   - Istari are extremely low on HP compared to other classes,
1545 		   but in order to reduce the insta-kill chance when trying to win
1546 		   they get an out-of-line HP boost here when they come closer to
1547 		   level 50, which starts to diminish again after they won and
1548 		   further raise in levels!
1549 		   - Yeeks do get the same boost as all the others, but since yeeks
1550 		   hitdice ratio is extraordinarily bad it would nearly become
1551 		   cancelled out by the added boost, so the boost is slightly reduced
1552 		   for them (except for the ultra-weak Yeek Istari) to fit their
1553 		   low exp% better.
1554 		   This can logically be done well by making IF-exceptions since the
1555 		   help-kinging-boost is added and not multiplied by a character's
1556 		   exp-ratio, and the race-hitpoint dice have no influence on it.
1557 		   - The penalty is finely tuned to make Yeek Priests still a deal
1558 		   tougher than Istari, even without sorcery, while keeping in account
1559 		   the relation to all stronger classes as well. - C. Blue */
1560 		mhp = (player_hp_eff * 2 * (20 + bonus)) / 45;
1561 
1562 		/* I think it might be better to dimish the boost for yeeks after level 50 slowly towards level 100
1563 		   while granting the full boost at the critical level 50 instead of just a minor boost. Reason is:
1564 		   They don't have Morgoth's crown yet so they are unlikely to reach *** CON, but after winning
1565 		   they will be way stronger! On the other hand yeeks are already so weak that ultra-high Yeek
1566 		   Istari could still be instakilled (max. sorcery skill) if the boost is diminished,
1567 		   so only Yeek Mimics whose HP greatly reduces the low hitdice effect should be affected,
1568 		   as well as Adventurer-Mimics.. since it cannot be skill-based (might change anytime) nor
1569 		   class-based, we just punish all Yeeks, that's what they're for after all >;) */
1570 		/* Slowly diminishing boost? */
1571 		/* new (July 2008): take class+race hit dice into account, not just class hit dice */
1572 		weakling_boost = (p_ptr->lev <= 50) ?
1573 			(((p_ptr->lev * p_ptr->lev * p_ptr->lev) / 2500) * ((576 - cr_mhp * cr_mhp) + 105)) / 105 : /* <- full bonus */
1574 #if 1
1575 			/* this #if 1 is needed, because otherwise hdice differences would be too big in end-game :/
1576 			In fact this is but a bad hack - what should be done is adjusting hdice tables for races/classes instead. */
1577 			(50 * ((576 - cr_mhp * cr_mhp) + 105)) / 105; /* <- keep (!) full bonus for the rest of career up to level 99 */
1578 #else
1579 			/* currently discrepancies between yeek/human priest and ent warrior would be TOO big at end-game (>> level 50) */
1580 			((100 - p_ptr->lev) * ((576 - cr_mhp * cr_mhp) + 105)) / 105; /* <- above 50, bonus is slowly diminishing again towards level 99 (PY_MAX_PLAYER_LEVEL) */
1581 #endif
1582 
1583 		/* Help very weak characters close to level 50 to avoid instakill on trying to win */
1584 #if 0 /* not possible, because a weak character would LOSE HP when going from 50 -> 51 */
1585 		mhp += (weakling_boost * 50) / ((p_ptr->pclass == CLASS_MAGE && p_ptr->lev > 50) ? p_ptr->lev : 50); /* Istari have disruption shield, they don't need HP for 'tanking' */
1586 #else
1587 		mhp += weakling_boost;
1588 #endif
1589 	}
1590 
1591 	/* instead let's make it an option to weak chars, instead of further buffing chars with don't
1592 	   need it at all (warriors, druids, mimics, etc). However, now chars can get this AND +LIFE items.
1593 	   So in total it might be even more. A scale to 100 is hopefully ok. *experimental* */
1594 	mhp += get_skill_scale(p_ptr, SKILL_HEALTH, 100);
1595 
1596 #ifdef ENABLE_MAIA
1597 	/* Extra bonus hp (2 per level) for the evil path */
1598 	if (p_ptr->prace == RACE_MAIA && (p_ptr->ptrait == TRAIT_CORRUPTED) && p_ptr->lev >= 20) {
1599 		mhp += (p_ptr->lev - 20) * 2;
1600 	}
1601 #endif
1602 
1603 	/* Now we calculated the base player form mhp. Save it for use with
1604 	   +LIFE bonus. This will prevent mimics from total uber HP,
1605 	   and giving them an excellent chance to compensate a form that
1606 	   provides bad HP. - C. Blue */
1607 	mhp_playerform = mhp;
1608 
1609 
1610 	if (p_ptr->body_monster) {
1611 		long rhp = ((long)(r_info[p_ptr->body_monster].hdice)) * ((long)(r_info[p_ptr->body_monster].hside));
1612 
1613 		/* assume human mimic HP for calculation; afterwards, add up our 'extra' hit points if we're a stronger race */
1614 		/* additionally, scale form HP better with very high character levels */
1615 		/* Reduce the effect of racial hit dice when in monster form? [3..6]
1616 		   3 = no reduction, 6 = high reduction */
1617 		#define FORM_REDUCES_RACE_DICE_INFLUENCE 6
1618 		long raceHPbonus;
1619 #ifndef MIMICRY_BOOST_WEAK_FORM
1620 		long levD, hpD;
1621 #endif
1622 		mHPLim = (50000 / ((50000 / rhp) + 20));
1623 
1624 #if 0 /* done below */
1625 		/* add flat bonus to maximum HP limit for char levels > 50, if form is powerful, to keep it useful */
1626 		mHPLim += p_ptr->lev > 50 ? (((p_ptr->lev - 50) * (r_info[p_ptr->body_monster].level + 30)) / 100) * 20 : 0;
1627 #endif
1628 
1629 		raceHPbonus = mhp - ((mhp * 16) / p_ptr->hitdie); /* 10 human + 6 mimic */
1630 		mhp -= (raceHPbonus * 3) / FORM_REDUCES_RACE_DICE_INFLUENCE;
1631 #if 0 /* nonsense^^ */
1632 		/* compensate overall HP gain for values > 3 */
1633 		mhp -= ((raceHPbonus - (raceHPbonus * 3) / FORM_REDUCES_RACE_DICE_INFLUENCE) * 5) / 3;
1634 #endif
1635 		if (mHPLim < mhp) {
1636 #ifdef MIMICRY_BOOST_WEAK_FORM
1637 			mHPLim = mhp;
1638 #else
1639 			levD = p_ptr->lev - r_info[p_ptr->body_monster].level;
1640 			if (levD < 0) levD = 0;
1641 			if (levD > 20) levD = 20;
1642 			hpD = mhp - mHPLim;
1643 		        mHPLim = mhp - (hpD * levD) / 20; /* When your form is 20 or more levels below your charlevel,
1644 							   you receive the full HP difference in the formula below. */
1645 #endif
1646 		}
1647 
1648 		finalHP = (mHPLim < mhp) ? (((mhp * 4) + (mHPLim * 1)) / 5) : (((mHPLim * 2) + (mhp * 3)) / 5);
1649 		finalHP += (raceHPbonus * 3) / FORM_REDUCES_RACE_DICE_INFLUENCE;
1650 
1651 		/* done */
1652 		mhp = finalHP;
1653 	}
1654 
1655 	/* Always have at least one hitpoint per level */
1656 	if (mhp < p_ptr->lev + 1) mhp = p_ptr->lev + 1;
1657 
1658 	/* for C_BLUE_AI */
1659 	if (!p_ptr->body_monster) p_ptr->form_hp_ratio = 100;
1660 	else p_ptr->form_hp_ratio = (mhp * 100) / mhp_playerform;
1661 
1662 	/* calculate +LIFE bonus */
1663 	to_life = p_ptr->to_l;
1664 
1665 #ifdef ENABLE_MAIA
1666 	/* Bonus from RACE_MAIA */
1667 	if (p_ptr->divine_hp > 0) {
1668 		/* count as if from item? */
1669 		to_life += p_ptr->divine_hp_mod;
1670 	}
1671 #endif
1672 
1673 	/* cap it at +30% HP and at -100% HP */
1674 	if (to_life > 3 && !is_admin(p_ptr)) to_life = 3;
1675 	if (to_life < -10) to_life = -10;
1676 
1677 	/* new hack (see below): if life bonus is negative, dont apply player form hp */
1678 	if (to_life > 0) {
1679 		/* Reduce use of +LIFE items for mimics while in monster-form */
1680 		if (mhp > mhp_playerform) {
1681 			if (to_life > 0)
1682 				mhp += (mhp_playerform * to_life * mhp_playerform) / (10 * mhp);
1683 			else
1684 				mhp += (mhp_playerform * to_life) / 10;
1685 		} else {
1686 			mhp += (mhp * to_life) / 10;
1687 		}
1688 	}
1689 
1690 #if 1
1691 	if (p_ptr->body_monster) {
1692 		/* add flat bonus to maximum HP limit for char levels > 50, if form is powerful, to keep it useful */
1693 		mhp += (p_ptr->lev > 50) ?
1694 		    (((p_ptr->lev - 50) * ((r_info[p_ptr->body_monster].level > 80 ? 80 :
1695  #if 0 /* for 15..17/32 hp birth calc */
1696 		    r_info[p_ptr->body_monster].level) + 30)) / 100) * 5 : 0;
1697  #else /* for 31..33/64 hp birth calc */
1698 		    r_info[p_ptr->body_monster].level) + 30)) / 25) : 0;
1699  #endif
1700 	}
1701 #endif
1702 
1703 	/* new hack (see above): player form hp doesn't matter if life bonus is negative */
1704 	if (to_life < 0) mhp += (mhp * to_life) / 10;
1705 	/* some places divide by mhp, so hack it for now */
1706 	if (mhp == 0) mhp = 1;
1707 
1708 	/* Factor in the hero / superhero settings.
1709 	   Specialty: It's applied AFTER mimic form HP influence. */
1710 	if (p_ptr->hero) mhp += 10;
1711 	if (p_ptr->shero) mhp += 20;
1712 #if 1 /* hmm */
1713 	else if (p_ptr->fury) mhp += 20;
1714 	else if (p_ptr->berserk) mhp += 20;
1715 #endif
1716 
1717 #if 0 /* p_ptr->to_hp is unused atm! */
1718 	/* Fixed Hit Point Bonus */
1719 	if (!is_admin(p_ptr) && p_ptr->to_hp > 200) p_ptr->to_hp = 200;
1720 
1721 	if (mhp > mhp_playerform) {
1722 		/* Reduce the use for mimics (while in monster-form) */
1723 		if (p_ptr->to_hp > 0)
1724 			mhp += (mhp_playerform * p_ptr->to_hp) / mhp;
1725 		else
1726 			mhp += p_ptr->to_hp;
1727 	} else {
1728 		mhp += p_ptr->to_hp;
1729 	}
1730 #endif
1731 
1732 	/* Meditation increase mana at the cost of hp */
1733 	if (p_ptr->tim_meditation) mhp = mhp * 3 / 5;
1734 
1735 	/* New maximum hitpoints */
1736 	if (mhp != p_ptr->mhp) {
1737 		s32b value;
1738 
1739 		/* change current hit points proportionately to change of mhp */
1740 		/* divide first to avoid overflow, little loss of accuracy */
1741 		value = (((long)p_ptr->chp << 16) + p_ptr->chp_frac) / p_ptr->mhp;
1742 		value = value * mhp;
1743 		p_ptr->chp = (value >> 16);
1744 		p_ptr->chp_frac = (value & 0xFFFF);
1745 
1746 		/* Save the new max-hitpoints */
1747 		p_ptr->mhp = mhp;
1748 
1749 		/* Little fix (chp = mhp+1 sometimes) */
1750 		if (p_ptr->chp > p_ptr->mhp) p_ptr->chp = p_ptr->mhp;
1751 
1752 		/* Display hitpoints (later) */
1753 		p_ptr->redraw |= (PR_HP);
1754 
1755 		/* Window stuff */
1756 		p_ptr->window |= (PW_PLAYER);
1757 	}
1758 }
1759 
1760 
1761 
1762 /*
1763  * Extract and set the current "lite radius"
1764  */
1765 /*
1766  * XXX currently, this function does almost nothing; if lite radius
1767  * should be changed, call calc_boni too.
1768  */
calc_torch(int Ind)1769 static void calc_torch(int Ind) {
1770 	player_type *p_ptr = Players[Ind];
1771 
1772 #if 0
1773 	object_type *o_ptr = &p_ptr->inventory[INVEN_LITE];
1774 
1775 	/* Base light radius */
1776 	p_ptr->cur_lite = p_ptr->lite;
1777 
1778 	/* Examine actual lites */
1779 	if (o_ptr->tval == TV_LITE) {
1780 		/* Torches (with fuel) provide some lite */
1781 		if ((o_ptr->sval == SV_LITE_TORCH) && (o_ptr->pval > 0))
1782 			p_ptr->cur_lite += 1;
1783 
1784 		/* Lanterns (with fuel) provide more lite */
1785 		if ((o_ptr->sval == SV_LITE_LANTERN) && (o_ptr->pval > 0))
1786 			p_ptr->cur_lite += 2;
1787 
1788 		/* Dwarven lanterns provide permanent radius 2 lite */
1789 		if (o_ptr->sval == SV_LITE_DWARVEN)
1790 			p_ptr->cur_lite += 2;
1791 
1792 		/* Feanorian lanterns provide permanent, bright, lite */
1793 		if (o_ptr->sval == SV_LITE_FEANOR)
1794 			p_ptr->cur_lite += 3;
1795 
1796 		/* Artifact Lites provide permanent, bright, lite */
1797 		if (artifact_p(o_ptr)) p_ptr->cur_lite += 3;
1798 	}
1799 #endif	// 0
1800 
1801 	/* Reduce lite when running if requested */
1802 	if (p_ptr->running && p_ptr->view_reduce_lite) {
1803 		/* Reduce the lite radius if needed */
1804 		if (p_ptr->cur_lite > 1) p_ptr->cur_lite = 1;
1805 		if (p_ptr->cur_vlite > 1) p_ptr->cur_vlite = 1;
1806 	}
1807 
1808 	/* Notice changes in the "lite radius" */
1809 	if ((p_ptr->old_lite != p_ptr->cur_lite) || (p_ptr->old_vlite != p_ptr->cur_vlite)) {
1810 		/* Update the lite */
1811 		p_ptr->update |= (PU_LITE);
1812 
1813 		/* Update the monsters */
1814 		p_ptr->update |= (PU_MONSTERS);
1815 
1816 		/* Remember the old lite */
1817 		p_ptr->old_lite = p_ptr->cur_lite;
1818 		p_ptr->old_vlite = p_ptr->cur_vlite;
1819 	}
1820 }
1821 
1822 
1823 
1824 /*
1825  * Computes current weight limit.
1826  */
weight_limit(int Ind)1827 static int weight_limit(int Ind) /* max. 3000 atm */
1828 {
1829 	player_type *p_ptr = Players[Ind];
1830 
1831 	int i;
1832 
1833 	/* Weight limit based only on strength */
1834 	i = adj_str_wgt[p_ptr->stat_ind[A_STR]] * 100;
1835 
1836 	/* Return the result */
1837 	return (i);
1838 }
1839 
1840 
1841 /* Should be called by every calc_bonus call */
calc_body_bonus(int Ind,boni_col * csheet_boni)1842 static void calc_body_bonus(int Ind, boni_col * csheet_boni) {
1843 	player_type *p_ptr = Players[Ind];
1844 	dun_level *l_ptr = getfloor(&p_ptr->wpos);
1845 	cave_type **zcave;
1846 	if (!(zcave = getcave(&p_ptr->wpos))) return;
1847 
1848 	int d, immunities = 0, immunity[7], immrand;
1849 	int i, j;
1850 	monster_race *r_ptr = &r_info[p_ptr->body_monster];
1851 	char mname[MNAME_LEN];
1852 
1853 	/* If in the player body nothing have to be done */
1854 	if (!p_ptr->body_monster) return;
1855 
1856 	immunity[1] = 0; immunity[2] = 0; immunity[3] = 0;
1857 	immunity[4] = 0; immunity[5] = 0; immunity[6] = 0;
1858 	immrand = 0;
1859 
1860 	/* Prepare lower-case'd name for worry-free testing */
1861 	strcpy(mname, r_name + r_ptr->name);
1862 	mname[0] = tolower(mname[0]);
1863 
1864 	/* keep random monster-body abilities static over quit/rejoin */
1865 	Rand_value = p_ptr->mimic_seed;
1866 	Rand_quick = TRUE;
1867 
1868 	if (!r_ptr->body_parts[BODY_WEAPON]) p_ptr->num_blow = 1;
1869 
1870 	d = 0;
1871 	for (i = 0; i < 4; i++) {
1872 		j = (r_ptr->blow[i].d_dice * r_ptr->blow[i].d_side);
1873 
1874 		switch (r_ptr->blow[i].effect) {
1875 			case RBE_EXP_10:
1876 			case RBE_EXP_20:
1877 			case RBE_EXP_40:
1878 			case RBE_EXP_80:
1879 				p_ptr->hold_life = TRUE;
1880 				csheet_boni->cb[5] |= CB6_RLIFE;
1881 				break;
1882 			case RBE_SHATTER:
1883 				p_ptr->stat_add[A_STR]++;
1884 				csheet_boni->pstr++;
1885 				break;
1886 			case RBE_LOSE_STR:
1887 				p_ptr->sustain_str = TRUE;
1888 				csheet_boni->cb[11] |= CB12_RSSTR;
1889 				break;
1890 			case RBE_LOSE_INT:
1891 				p_ptr->sustain_int = TRUE;
1892 				csheet_boni->cb[11] |= CB12_RSINT;
1893 				break;
1894 			case RBE_LOSE_WIS:
1895 				p_ptr->sustain_wis = TRUE;
1896 				csheet_boni->cb[11] |= CB12_RSWIS;
1897 				break;
1898 			case RBE_LOSE_DEX:
1899 				p_ptr->sustain_dex = TRUE;
1900 				csheet_boni->cb[11] |= CB12_RSDEX;
1901 				break;
1902 			case RBE_LOSE_CON:
1903 				p_ptr->sustain_con = TRUE;
1904 				csheet_boni->cb[11] |= CB12_RSCON;
1905 				break;
1906 			case RBE_LOSE_CHR:
1907 				p_ptr->sustain_chr = TRUE;
1908 				csheet_boni->cb[11] |= CB12_RSCHR;
1909 				break;
1910 			case RBE_LOSE_ALL:
1911 				p_ptr->sustain_str = TRUE;
1912 				csheet_boni->cb[11] |= CB12_RSSTR;
1913 				p_ptr->sustain_int = TRUE;
1914 				csheet_boni->cb[11] |= CB12_RSINT;
1915 				p_ptr->sustain_wis = TRUE;
1916 				csheet_boni->cb[11] |= CB12_RSWIS;
1917 				p_ptr->sustain_dex = TRUE;
1918 				csheet_boni->cb[11] |= CB12_RSDEX;
1919 				p_ptr->sustain_con = TRUE;
1920 				csheet_boni->cb[11] |= CB12_RSCON;
1921 				p_ptr->sustain_chr = TRUE;
1922 				csheet_boni->cb[11] |= CB12_RSCHR;
1923 				break;
1924 		}
1925 
1926 		d += (j * 2);
1927 	}
1928 	d /= 4;
1929 
1930 	/* Apply STR bonus/malus, derived from form damage and race */
1931 	/* <damage> */
1932 	if (!d) d = 1;
1933 	/* 0..147 (greater titan) -> 0..5 -> -1..+4 */
1934 	i = (((15000 / ((15000 / d) + 50)) / 29) - 1);
1935 	/* <corpse weight> : Non-light creatures won't get a STR malus,
1936 	   even if they don't deal much damage. */
1937 	if (r_ptr->weight >= 1500 && i < 0) i = 0;
1938 	if (r_ptr->weight >= 4500 && i < 1) i++;
1939 	if (r_ptr->weight >= 20000 && i < 2) i++;
1940 	if (r_ptr->weight >= 100000 && i < 3) i++;
1941 	/* <race> */
1942 	if (strstr(mname, "bear") && (r_ptr->flags3 & RF3_ANIMAL)) i++; /* Bears get +1 STR */
1943 	if (r_ptr->flags3 & RF3_TROLL) i += 1;
1944 	if (r_ptr->flags3 & RF3_GIANT) i += 1;
1945 	if ((r_ptr->flags3 & RF3_DRAGON) && (strstr(mname, "mature ") ||
1946 	    (r_ptr->d_char == 'D')))
1947 		i += 1; /* only +1 since more bonus is coming from its damage already */
1948 	p_ptr->stat_add[A_STR] += i;
1949 	csheet_boni->pstr += i;
1950 
1951 	/* Cats, rogues, martial artists (mystics/ninjas) and skilled warriors are very agile */
1952 	if (r_ptr->d_char == 'f') { p_ptr->stat_add[A_DEX] += 2; csheet_boni->pdex += 2; }/* Cats! */
1953 	if (r_ptr->d_char == 'p' && r_ptr->d_attr == TERM_BLUE) { /* Rogues and master rogues */
1954 		if (r_ptr->level >= 23) { p_ptr->stat_add[A_DEX] += 2; csheet_boni->pdex += 2; }
1955 		else { p_ptr->stat_add[A_DEX]++; csheet_boni->pdex++; }
1956 	}
1957 	if (r_ptr->d_char == 'p' && r_ptr->d_attr == TERM_UMBER && strstr(mname, "master")) { p_ptr->stat_add[A_DEX]++; csheet_boni->pdex++; } /* Skilled warriors */
1958 	if (r_ptr->d_char == 'p' && r_ptr->d_attr == TERM_ORANGE) { p_ptr->stat_add[A_DEX] += 2; csheet_boni->pdex += 2; } /* Mystics */
1959 	if (p_ptr->body_monster == 370) { p_ptr->stat_add[A_DEX]++; csheet_boni->pdex++; }/* Jade Monk */
1960 	if (p_ptr->body_monster == 492) { p_ptr->stat_add[A_DEX]++; csheet_boni->pdex++; }/* Ivory Monk */
1961 	if (p_ptr->body_monster == 532) { p_ptr->stat_add[A_DEX]++; csheet_boni->pdex++; }/* Dagashi */
1962 	if (p_ptr->body_monster == 485) { p_ptr->stat_add[A_DEX] += 2; csheet_boni->pdex += 2; } /* Ninja */
1963 
1964 	if (r_ptr->speed < 110) {
1965 		/* let slowdown not be that large that players will never try that form */
1966 		p_ptr->pspeed = 110 - (((110 - r_ptr->speed) * 20) / 100);
1967 	} else {
1968 		/* let speed bonus not be that high that players won't try any slower form */
1969 		//p_ptr->pspeed = (((r_ptr->speed - 110) * 30) / 100) + 110;//was 50%, 30% for RPG_SERVER originally
1970 		//Pfft, include the -speed into the calculation, too. Seems lame how -speed is counted for 100% but not + bonus.
1971 		//But really, if physical-race-intrinsic bonuses/maluses are counted in mimicry, then dwarves
1972 		//should be able to keep their climbing ability past 30 when mimicked, TLs could fly, etc etc =/
1973 		p_ptr->pspeed = (((r_ptr->speed - 110 - (p_ptr->prace == RACE_ENT ? 2 : 0) ) * 30) / 100) + 110;//was 50%, 30% for RPG_SERVER originally
1974 	}
1975 	csheet_boni->spd = p_ptr->pspeed - 110;
1976 
1977 #if 0 /* Should forms affect your searching/perception skills? Probably not. */
1978  #if 0
1979 	/* Base skill -- searching ability */
1980 	p_ptr->skill_srh /= 2;
1981 	p_ptr->skill_srh += r_ptr->aaf / 10;
1982 
1983 	/* Base skill -- searching frequency */
1984 	p_ptr->skill_fos /= 2;
1985 	p_ptr->skill_fos += r_ptr->aaf / 10;
1986  #else
1987 	/* Base skill -- searching ability */
1988 	p_ptr->skill_srh += r_ptr->aaf / 20 - 5;
1989 
1990 	/* Base skill -- searching frequency */
1991 	p_ptr->skill_fos += r_ptr->aaf / 20 - 5;
1992  #endif
1993 #endif
1994 
1995 	/* Stealth ability is influenced by weight (-> size) of the monster */
1996 	if (r_ptr->weight <= 500) { p_ptr->skill_stl += 2; csheet_boni->slth += 2; }
1997 	else if (r_ptr->weight <= 500) { p_ptr->skill_stl += 2; csheet_boni->slth += 2; }
1998 	else if (r_ptr->weight <= 1000) { p_ptr->skill_stl += 1; csheet_boni->slth += 1; }
1999 	else if (r_ptr->weight <= 1500) { p_ptr->skill_stl += 0; csheet_boni->slth += 0; }
2000 	else if (r_ptr->weight <= 4500) { p_ptr->skill_stl -= 1; csheet_boni->slth -= 1; }
2001 	else if (r_ptr->weight <= 20000) { p_ptr->skill_stl -= 2; csheet_boni->slth -= 2; }
2002 	else if (r_ptr->weight <= 100000) { p_ptr->skill_stl -= 3; csheet_boni->slth -= 3; }
2003 	else { p_ptr->skill_stl -= 4; csheet_boni->slth -= 4; }
2004 
2005 	/* Extra fire if good archer */
2006 	/*  1_IN_1  -none-
2007 	    1_IN_2  Grandmaster Thief
2008 	    1_IN_3  Halfling Slinger, Ranger Chieftain
2009 	    1_IN_4  Ranger
2010 	*/
2011 	if ((r_ptr->flags4 & (RF4_ARROW_1 | RF4_ARROW_2 | RF4_ARROW_3)) &&	/* 1=BOW,2=XBOW,3=SLING; 4=generic missile */
2012 	    (p_ptr->inventory[INVEN_BOW].k_idx) && (p_ptr->inventory[INVEN_BOW].tval == TV_BOW))
2013 	{
2014 #if 0
2015  #if 0 /* normal way to handle xbow <-> sling/bow shot frequency */
2016 		if ((p_ptr->inventory[INVEN_BOW].sval == SV_SLING) ||
2017 		    (p_ptr->inventory[INVEN_BOW].sval == SV_SHORT_BOW) ||
2018 		    (p_ptr->inventory[INVEN_BOW].sval == SV_LONG_BOW)) p_ptr->num_fire++;
2019 		if (r_ptr->freq_innate > 30) p_ptr->num_fire++; /* this time for crossbows too */
2020  #else /* give xbow an advantage */
2021 		if (r_ptr->freq_innate > 30)
2022 		if ((p_ptr->inventory[INVEN_BOW].sval == SV_SLING) ||
2023 		    (p_ptr->inventory[INVEN_BOW].sval == SV_SHORT_BOW) ||
2024 		    (p_ptr->inventory[INVEN_BOW].sval == SV_LONG_BOW)) p_ptr->num_fire++;
2025 		p_ptr->num_fire++; /* this time for crossbows too */
2026  #endif
2027 #else /* xbows only get +1ES from fast shooters, not already from slower ARROW_ shooters */
2028 		if ((p_ptr->inventory[INVEN_BOW].sval == SV_SLING) ||
2029 		    (p_ptr->inventory[INVEN_BOW].sval == SV_SHORT_BOW) ||
2030 		    (p_ptr->inventory[INVEN_BOW].sval == SV_LONG_BOW)) { p_ptr->num_fire++; csheet_boni->shot++; }
2031 		if (r_ptr->freq_innate > 30)
2032 			{ p_ptr->num_fire++; csheet_boni->shot++; } /* this time for crossbows too */
2033 #endif
2034 	}
2035 
2036 	/* Extra casting if good spellcaster */
2037 	if ((r_ptr->flags4 & RF4_SPELLCASTER_MASK) ||
2038 	    (r_ptr->flags5 & RF5_SPELLCASTER_MASK) ||
2039 	    (r_ptr->flags6 & RF6_SPELLCASTER_MASK)) {
2040 		if (r_ptr->freq_innate > 30) {
2041 			p_ptr->num_spell++;	// 1_IN_3
2042 			p_ptr->stat_add[A_INT] += 1; csheet_boni->pint += 1;
2043 			p_ptr->to_m += 20; csheet_boni->mxmp += 2;
2044 		}
2045 		if (r_ptr->freq_innate >= 50) {
2046 			p_ptr->num_spell++;	// 1_IN_2
2047 			p_ptr->stat_add[A_INT] += 2; csheet_boni->pint += 2;
2048 			p_ptr->to_m += 15; csheet_boni->mxmp += 1;
2049 		}
2050 		if (r_ptr->freq_innate == 100) { /* well, drujs and quylthulgs >_> */
2051 			p_ptr->num_spell++;	// 1_IN_1
2052 			p_ptr->stat_add[A_INT] += 1;  csheet_boni->pint += 1;
2053 			p_ptr->to_m += 15; csheet_boni->mxmp += 2;
2054 		}
2055 	}
2056 
2057 
2058 	/* Racial boni depending on the form's race */
2059 	switch(p_ptr->body_monster) {
2060 		/* Bats get feather falling */
2061 		case 37:	case 114:	case 187:	case 235:	case 351:
2062 		case 377:	case 391:	case 406:	case 484:	case 968:
2063 			p_ptr->feather_fall = TRUE;
2064 			csheet_boni->cb[4] |= CB5_RFALL;
2065 			/* Vampire bats are vampiric */
2066 			if (p_ptr->body_monster == 391) { p_ptr->vampiric_melee = 100; csheet_boni->cb[6] |= CB7_RVAMP; }
2067 #if 0 /* only real/chauvesouris ones for now, or spider/crow/wild cat forms would be obsolete! */
2068 			/* Fruit bats get some life leech */
2069 			if (p_ptr->body_monster == 37 && p_ptr->vampiric_melee < 50) { p_ptr->vampiric_melee = 50; csheet_boni->cb[6] |= CB7_RVAMP; }
2070 #endif
2071 			break;
2072 
2073 		case 365: /* Vampiric mist is vampiric */
2074 			p_ptr->vampiric_melee = 100; csheet_boni->cb[6] |= CB7_RVAMP;
2075 			break;
2076 		case 927: /* Vampiric ixitxachitl is vampiric */
2077 			if (p_ptr->vampiric_melee < 50) p_ptr->vampiric_melee = 50;
2078 			csheet_boni->cb[6] |= CB7_RVAMP;
2079 			break;
2080 
2081 		/* Elves get resist_lite, Dark-Elves get resist_dark */
2082 		case 122:	case 400:	case 178:	case 182:	case 226:
2083 		case 234:	case 348:	case 375:	case 564:	case 657:
2084 			p_ptr->resist_dark = TRUE; csheet_boni->cb[2] |= CB3_RDARK;
2085 			break;
2086 		case 864:
2087 			p_ptr->resist_lite = TRUE; csheet_boni->cb[2] |= CB3_RLITE;
2088 			break;
2089 
2090 		/* Hobbits/Halflings get the no-shoes-bonus */
2091 		case 74:	case 539:
2092 			if (!p_ptr->inventory[INVEN_FEET].k_idx)
2093 				{ p_ptr->stat_add[A_DEX] += 2; csheet_boni->pdex += 2; }
2094 			break;
2095 
2096 		/* Gnomes get free_act */
2097 		case 258:	case 281:
2098 			p_ptr->free_act = TRUE; csheet_boni->cb[4] |= CB5_RPARA;
2099 			break;
2100 
2101 		/* Dwarves get res_blind & climbing ability */
2102 		case 111:	case 865:
2103 			p_ptr->resist_blind = TRUE; csheet_boni->cb[4] |= CB5_RBLND;
2104 			if (p_ptr->lev >= 30) { p_ptr->climb = TRUE; csheet_boni->cb[6] |= CB7_RCLMB; }
2105 			break;
2106 
2107 		/* High-elves resist_lite & see_inv */
2108 		case 945:
2109 			p_ptr->resist_lite = TRUE; csheet_boni->cb[2] |= CB3_RLITE;
2110 			p_ptr->see_inv = TRUE; csheet_boni->cb[5] |= CB6_RSINV;
2111 			break;
2112 
2113 		/* Yeeks get feather_fall */
2114 		case 52:	case 141:	case 179:	case 224:
2115 			p_ptr->feather_fall = TRUE; csheet_boni->cb[4] |= CB5_RFALL;
2116 			break;
2117 
2118 		/* Ents */
2119 		case 708:
2120 			p_ptr->slow_digest = TRUE; csheet_boni->cb[4] |= CB5_RFOOD;
2121 			//if (p_ptr->prace != RACE_ENT)
2122 			p_ptr->pspeed -= 2;
2123 			p_ptr->suscep_fire = TRUE; csheet_boni->cb[0] |= CB1_SFIRE;
2124 			p_ptr->resist_water = TRUE; csheet_boni->cb[2] |= CB3_RWATR;
2125 /* not form-dependant:			if (p_ptr->lev >= 4) p_ptr->see_inv = TRUE; */
2126 			p_ptr->can_swim = TRUE; csheet_boni->cb[12] |= CB13_XSWIM; /* wood? */
2127 			p_ptr->pass_trees = TRUE; csheet_boni->cb[12] |= CB13_XTREE;
2128 			break;
2129 
2130 		/* Ghosts get additional boni - undead see below */
2131 		case 65:	case 100:	case 133:	case 152:	case 231:
2132 		case 385:	case 394:	case 477:	case 507:	case 508:
2133 		case 533:	case 534:	case 553:	case 630:	case 665:
2134 		case 667:	case 690:	case 774:	case 895:
2135 		case 929:	case 930:	case 931:	case 932:	case 933:
2136 		case 967:	case 973:	case 974:
2137 			/* I'd prefer ghosts having a radius of awareness, like a 'pseudo-light source',
2138 			since atm ghosts are completely blind in the dark :( -C. Blue */
2139 			p_ptr->see_inv = TRUE; csheet_boni->cb[5] |= CB6_RSINV;
2140 	//		p_ptr->invis += 5; */ /* No. */
2141 			break;
2142 
2143 		/* Vampires have VAMPIRIC attacks */
2144 		case 432:	case 520:	case 521:	case 623:	case 989:
2145 			if (p_ptr->vampiric_melee < 50) { p_ptr->vampiric_melee = 50; csheet_boni->cb[6] |= CB7_RVAMP; }
2146 			p_ptr->suscep_lite = TRUE; csheet_boni->cb[1] |= CB2_SLITE;
2147 			break;
2148 
2149 		/* Angels resist light, blindness and poison (usually immunity) */
2150 		case 417:	case 456:	case 511:	case 605:
2151 		case 661:	case 1071:	case 1072:	case 1073:
2152 			p_ptr->see_inv = TRUE; csheet_boni->cb[5] |= CB6_RSINV;
2153 		/* Fallen Angel */
2154 		case 652:
2155 			p_ptr->resist_blind = TRUE; csheet_boni->cb[4] |= CB5_RBLND;
2156 			break;
2157 	}
2158 
2159 	/* If monster has a lite source, but doesn't prove a torso (needed
2160 	   to use a lite source, yellow light) or can breathe light (light
2161 	   hound), add to the player's light radius! */
2162 	if ((r_ptr->flags9 & RF9_HAS_LITE) &&
2163 	     ((!r_ptr->body_parts[BODY_TORSO]) || (r_ptr->flags4 & RF4_BR_LITE)))
2164 		{ p_ptr->cur_lite += 1; csheet_boni->lite += 1; }
2165 
2166 	/* Forms that occur in the woods are able to pass them, so are animals */
2167 	if ((r_ptr->flags8 & RF8_WILD_WOOD) || (r_ptr->flags3 & RF3_ANIMAL))
2168 		{ p_ptr->pass_trees = TRUE; csheet_boni->cb[12] |= CB13_XTREE; }
2169 
2170 	/* Forms that occur in the mountains are able to pass them */
2171 	if (r_ptr->flags8 & (RF8_WILD_MOUNTAIN | RF8_WILD_VOLCANO))
2172 		{ p_ptr->climb = TRUE; csheet_boni->cb[6] |= CB7_RCLMB; }
2173 	/* Spiders can always climb */
2174 	if (r_ptr->flags7 & RF7_SPIDER) { p_ptr->climb = TRUE; csheet_boni->cb[6] |= CB7_RCLMB; }
2175 
2176 	/* Orcs get resist_dark */
2177 	if(r_ptr->flags3 & RF3_ORC) { p_ptr->resist_dark = TRUE; csheet_boni->cb[2] |= CB3_RDARK; }
2178 
2179 	/* Trolls/Giants get sustain_str */
2180 	if ((r_ptr->flags3 & RF3_TROLL) || (r_ptr->flags3 & RF3_GIANT)) { p_ptr->sustain_str = TRUE; csheet_boni->cb[11] |= CB12_RSSTR; }
2181 
2182 	/* Draconian get feather_fall, ESP_DRAGON */
2183 	if (r_ptr->flags3 & RF3_DRAGONRIDER) {
2184 		p_ptr->feather_fall = TRUE; csheet_boni->cb[4] |= CB5_RFALL;
2185 		if (p_ptr->lev >= 5) { p_ptr->telepathy |= ESP_DRAGON; csheet_boni->cb[8] |= CB9_EDRGN; }
2186 		if (p_ptr->lev >= 30) { p_ptr->levitate = TRUE; csheet_boni->cb[6] |= CB7_RRLEV; }
2187 	}
2188 
2189 	/* Undead get lots of stuff similar to player ghosts */
2190 	if (r_ptr->flags3 & RF3_UNDEAD) {
2191 		/* p_ptr->see_inv = TRUE;
2192 		p_ptr->resist_neth = TRUE;
2193 		p_ptr->hold_life = TRUE;
2194 		p_ptr->free_act = TRUE;
2195 		p_ptr->see_infra += 3;
2196 		p_ptr->resist_fear = TRUE;*/
2197 		/*p_ptr->resist_conf = TRUE;*/
2198 		/* p_ptr->resist_pois = TRUE; */ /* instead of immune */
2199 		/* p_ptr->resist_cold = TRUE; */
2200 
2201 		p_ptr->resist_pois = TRUE; csheet_boni->cb[1] |= CB2_RPOIS;
2202 		p_ptr->resist_dark = TRUE; csheet_boni->cb[2] |= CB3_RDARK;
2203 		p_ptr->resist_blind = TRUE; csheet_boni->cb[4] |= CB5_RBLND;
2204 		p_ptr->no_cut = TRUE; csheet_boni->cb[12] |= CB13_XNCUT;
2205 		p_ptr->reduce_insanity = 1; csheet_boni->cb[3] |= CB4_RMIND;
2206 		p_ptr->see_infra += 1; csheet_boni->infr += 1;
2207 
2208 		if (strchr("GWLV", r_ptr->d_char)) {
2209 			p_ptr->see_infra += 4; csheet_boni->infr += 4;
2210 		}
2211 	}
2212 
2213 	/* Non-living got a nice ability set too ;) */
2214 	if (r_ptr->flags3 & RF3_NONLIVING) {
2215 		p_ptr->resist_pois = TRUE; csheet_boni->cb[1] |= CB2_RPOIS;
2216 		p_ptr->resist_fear = TRUE; csheet_boni->cb[4] |= CB5_RFEAR;
2217 		p_ptr->reduce_insanity = 2; csheet_boni->cb[3] |= CB4_RMIND;
2218 	}
2219 
2220 	/* Greater demons resist poison (monsters are immune) */
2221 	if ((r_ptr->d_char == 'U') && (r_ptr->flags3 & RF3_DEMON)) { p_ptr->resist_pois = TRUE; csheet_boni->cb[1] |= CB2_RPOIS; }
2222 
2223 	/* Affect charisma by appearance */
2224 	d = 0;
2225 	if (r_ptr->flags3 & RF3_DRAGONRIDER) d = 1;
2226 	else if (r_ptr->flags3 & RF3_DRAGON) d = 0;
2227 	if (r_ptr->flags3 & RF3_ANIMAL) {
2228 		if (r_ptr->weight <= 450 && strchr("bfqBCR", r_ptr->d_char)) d = 1; /* yes, I included NEWTS */
2229 		else d = 0;
2230 	}
2231 	if (r_ptr->flags7 & RF7_SPIDER) d = -1;
2232 
2233 	if (r_ptr->flags3 & RF3_ORC) d = -1;
2234 
2235 	if (r_ptr->flags3 & RF3_NONLIVING) d = -1;
2236 	if (r_ptr->flags3 & RF3_EVIL) d = -1;
2237 
2238 	if (r_ptr->flags3 & RF3_TROLL) d = -2;
2239 	if (r_ptr->flags3 & RF3_GIANT) d = -2;
2240 
2241 	if (r_ptr->flags3 & RF3_UNDEAD) d = -3;
2242 	if (r_ptr->flags3 & RF3_DEMON) d = -3;
2243 
2244 	if (r_ptr->flags3 & RF3_GOOD) d += 2;
2245 
2246 	p_ptr->stat_add[A_CHR] += d; csheet_boni->pchr += d;
2247 
2248 
2249 	//        if(r_ptr->flags1 & RF1_NEVER_MOVE) p_ptr->immovable = TRUE;
2250 	if (r_ptr->flags2 & RF2_STUPID) { p_ptr->stat_add[A_INT] -= 2; csheet_boni->pint -= 2; }
2251 	if (r_ptr->flags2 & RF2_SMART) { p_ptr->stat_add[A_INT] += 2; csheet_boni->pint += 2; }
2252 	if (r_ptr->flags2 & RF2_INVISIBLE) {
2253 		d = ((r_ptr->level > 100 ? 50 : r_ptr->level / 2) + (p_ptr->lev > 50 ? 50 : p_ptr->lev)) / 2;
2254 		p_ptr->tim_invis_power = d * 4 / 5; csheet_boni->cb[6] |= CB7_RINVS;
2255 	}
2256 	if (r_ptr->flags2 & RF2_REGENERATE) { p_ptr->regenerate = TRUE; csheet_boni->cb[5] |= CB6_RRGHP; }
2257 	/* Immaterial forms (WRAITH / PASS_WALL) drain the mimic's HP! */
2258 	if (r_ptr->flags2 & RF2_PASS_WALL) {
2259 		if (!(zcave[p_ptr->py][p_ptr->px].info & CAVE_STCK) &&
2260 		    !(p_ptr->wpos.wz && (l_ptr->flags1 & LF1_NO_MAGIC)))
2261 		{
2262 //BAD!(recursion)			set_tim_wraith(Ind, 30000);
2263 			p_ptr->tim_wraith = 30000; csheet_boni->cb[5] |= CB6_RWRTH;
2264 		}
2265 		p_ptr->drain_life++; csheet_boni->cb[5] |= CB6_SRGHP;
2266 	}
2267 	if (r_ptr->flags2 & RF2_KILL_WALL) { p_ptr->auto_tunnel = TRUE; csheet_boni->cb[12] |= CB13_XWALL; }
2268 	if (r_ptr->flags2 & RF2_AURA_FIRE) { p_ptr->sh_fire = p_ptr->sh_fire_fix = TRUE; csheet_boni->cb[10] |= CB11_AFIRE; }
2269 	if (r_ptr->flags2 & RF2_AURA_ELEC) { p_ptr->sh_elec = p_ptr->sh_elec_fix = TRUE; csheet_boni->cb[10] |= CB11_AELEC; }
2270 	if (r_ptr->flags3 & RF3_AURA_COLD) { p_ptr->sh_cold = p_ptr->sh_cold_fix = TRUE; csheet_boni->cb[10] |= CB11_ACOLD; }
2271 
2272 	if (r_ptr->flags5 & RF5_MIND_BLAST) { p_ptr->reduce_insanity = 1; csheet_boni->cb[3] |= CB4_RMIND; }
2273 	if (r_ptr->flags5 & RF5_BRAIN_SMASH) { p_ptr->reduce_insanity = 2; csheet_boni->cb[3] |= CB4_RMIND; }
2274 
2275 	if (r_ptr->flags3 & RF3_SUSCEP_FIRE) { p_ptr->suscep_fire = TRUE; csheet_boni->cb[0] |= CB1_SFIRE; }
2276 	if (r_ptr->flags3 & RF3_SUSCEP_COLD) { p_ptr->suscep_cold = TRUE; csheet_boni->cb[0] |= CB1_SCOLD; }
2277 /* Imho, there should be only suspec fire and cold since these two are opposites.
2278 Something which is fire-related will usually be suspectible to cold and vice versa.
2279 Exceptions are rare, like Ent, who as a being of wood is suspectible to fire. (C. Blue) */
2280 	if (r_ptr->flags9 & RF9_SUSCEP_ELEC) { p_ptr->suscep_elec = TRUE; csheet_boni->cb[0] |= CB1_SELEC; }
2281 	if (r_ptr->flags9 & RF9_SUSCEP_ACID) { p_ptr->suscep_acid = TRUE; csheet_boni->cb[1] |= CB2_SACID; }
2282 	if (r_ptr->flags9 & RF9_SUSCEP_POIS) { p_ptr->suscep_pois = TRUE; csheet_boni->cb[1] |= CB2_SPOIS; }
2283 
2284 	if (r_ptr->flags9 & RF9_RES_ACID) { p_ptr->resist_acid = TRUE; csheet_boni->cb[1] |= CB2_RACID; }
2285 	if (r_ptr->flags9 & RF9_RES_ELEC) { p_ptr->resist_elec = TRUE; csheet_boni->cb[0] |= CB1_RELEC; }
2286 	if (r_ptr->flags9 & RF9_RES_FIRE) { p_ptr->resist_fire = TRUE; csheet_boni->cb[0] |= CB1_RFIRE; }
2287 	if (r_ptr->flags9 & RF9_RES_COLD) { p_ptr->resist_cold = TRUE; csheet_boni->cb[0] |= CB1_RCOLD; }
2288 	if (r_ptr->flags9 & RF9_RES_POIS) { p_ptr->resist_pois = TRUE; csheet_boni->cb[1] |= CB2_RPOIS; }
2289 
2290 	if (r_ptr->flags3 & RF3_HURT_LITE) { p_ptr->suscep_lite = TRUE; csheet_boni->cb[1] |= CB2_SLITE; }
2291 #if 0 /* for now let's say EVIL is a state of mind, so the mimic isn't necessarily evil */
2292 	if (r_ptr->flags3 & RF3_EVIL) p_ptr->suscep_good = TRUE;
2293 #else /* the appearance is important for damage though - let's keep it restricted to demon/undead for now */
2294 	if (r_ptr->flags3 & RF3_DEMON || r_ptr->flags3 & RF3_UNDEAD) p_ptr->suscep_good = TRUE;
2295 #endif
2296 	if (r_ptr->flags3 & RF3_UNDEAD) p_ptr->suscep_life = TRUE;
2297 	if (r_ptr->flags3 & RF3_GOOD) p_ptr->suscep_evil = TRUE;
2298 
2299 	/* Grant a mimic a maximum of 2 immunities for now. All further immunities
2300 	are turned into resistances. Which ones is random. */
2301 	if (r_ptr->flags3 & RF3_IM_ACID) {
2302 		immunities += 1;
2303 		immunity[immunities] = 1;
2304 		p_ptr->resist_acid = TRUE; csheet_boni->cb[1] |= CB2_RACID;
2305 	}
2306 	if (r_ptr->flags3 & RF3_IM_ELEC) {
2307 		immunities += 1;
2308 		immunity[immunities] = 2;
2309 		p_ptr->resist_elec = TRUE; csheet_boni->cb[0] |= CB1_RELEC;
2310 	}
2311 	if (r_ptr->flags3 & RF3_IM_FIRE) {
2312 		immunities += 1;
2313 		immunity[immunities] = 3;
2314 		p_ptr->resist_fire = TRUE; csheet_boni->cb[0] |= CB1_RFIRE;
2315 	}
2316 	if (r_ptr->flags3 & RF3_IM_COLD) {
2317 		immunities += 1;
2318 		immunity[immunities] = 4;
2319 		p_ptr->resist_cold = TRUE; csheet_boni->cb[0] |= CB1_RCOLD;
2320 	}
2321 	if (r_ptr->flags3 & RF3_IM_POIS) {
2322 		immunities += 1;
2323 		immunity[immunities] = 5;
2324 		p_ptr->resist_pois = TRUE; csheet_boni->cb[1] |= CB2_RPOIS;
2325 	}
2326 	if (r_ptr->flags9 & RF9_IM_WATER) {
2327 		immunities += 1;
2328 		immunity[immunities] = 6;
2329 		p_ptr->resist_water = TRUE; csheet_boni->cb[2] |= CB3_RWATR;
2330 	}
2331 
2332 	/* gain not more than 1 immunities at the same time from a form */
2333 	if (immunities == 1) {
2334 		if (r_ptr->flags3 & RF3_IM_ACID) { p_ptr->immune_acid = TRUE; csheet_boni->cb[1] |= CB2_IACID; }
2335 		if (r_ptr->flags3 & RF3_IM_ELEC) { p_ptr->immune_elec = TRUE; csheet_boni->cb[1] |= CB2_IELEC; }
2336 		if (r_ptr->flags3 & RF3_IM_FIRE) { p_ptr->immune_fire = TRUE; csheet_boni->cb[0] |= CB1_IFIRE; }
2337 		if (r_ptr->flags3 & RF3_IM_COLD) { p_ptr->immune_cold = TRUE; csheet_boni->cb[0] |= CB1_ICOLD; }
2338 		if (r_ptr->flags3 & RF3_IM_POIS) { p_ptr->immune_poison = TRUE; csheet_boni->cb[1] |= CB2_IPOIS; }
2339 		if (r_ptr->flags9 & RF9_IM_WATER) { p_ptr->immune_water = TRUE; csheet_boni->cb[2] |= CB3_IWATR; }
2340 	} else {
2341 		immrand = 1 + rand_int(immunities);
2342 
2343 		switch (p_ptr->mimic_immunity) {
2344 		case 1:
2345 			if (r_ptr->flags3 & RF3_IM_ELEC) immunity[immrand] = 2;
2346 			break;
2347 		case 2:
2348 			if (r_ptr->flags3 & RF3_IM_COLD) immunity[immrand] = 4;
2349 			break;
2350 		case 3:
2351 			if (r_ptr->flags3 & RF3_IM_ACID) immunity[immrand] = 1;
2352 			break;
2353 		case 4:
2354 			if (r_ptr->flags3 & RF3_IM_FIRE) immunity[immrand] = 3;
2355 			break;
2356 		case 5:
2357 			if (r_ptr->flags3 & RF3_IM_POIS) immunity[immrand] = 5;
2358 			break;
2359 		case 6:
2360 			if (r_ptr->flags9 & RF9_IM_WATER) immunity[immrand] = 6;
2361 			break;
2362 		}
2363 
2364 		if (immunity[immrand] == 1) { p_ptr->immune_acid = TRUE; csheet_boni->cb[1] |= CB2_IACID; }
2365 		if (immunity[immrand] == 2) { p_ptr->immune_elec = TRUE; csheet_boni->cb[1] |= CB2_IELEC; }
2366 		if (immunity[immrand] == 3) { p_ptr->immune_fire = TRUE; csheet_boni->cb[0] |= CB1_IFIRE; }
2367 		if (immunity[immrand] == 4) { p_ptr->immune_cold = TRUE; csheet_boni->cb[0] |= CB1_ICOLD; }
2368 		if (immunity[immrand] == 5) { p_ptr->immune_poison = TRUE; csheet_boni->cb[1] |= CB2_IPOIS; }
2369 		if (immunity[immrand] == 6) { p_ptr->immune_water = TRUE; csheet_boni->cb[2] |= CB3_IWATR; }
2370 	}
2371 
2372 	if (r_ptr->flags9 & RF9_RES_LITE) { p_ptr->resist_lite = TRUE; csheet_boni->cb[2] |= CB3_RLITE; }
2373 	if (r_ptr->flags9 & RF9_RES_DARK) { p_ptr->resist_dark = TRUE; csheet_boni->cb[2] |= CB3_RDARK; }
2374 	if (r_ptr->flags9 & RF9_RES_BLIND) { p_ptr->resist_blind = TRUE; csheet_boni->cb[4] |= CB5_RBLND; }
2375 	if (r_ptr->flags9 & RF9_RES_SOUND) { p_ptr->resist_sound = TRUE; csheet_boni->cb[2] |= CB3_RSOUN; }
2376 	if (r_ptr->flags3 & RF3_RES_PLAS) { p_ptr->resist_plasma = TRUE; csheet_boni->cb[2] |= CB3_RPLAS; }
2377 	if (r_ptr->flags9 & RF9_RES_CHAOS) { p_ptr->resist_chaos = TRUE; csheet_boni->cb[3] |= CB4_RCHAO; }
2378 	if (r_ptr->flags9 & RF9_RES_TIME) { p_ptr->resist_time = TRUE; csheet_boni->cb[3] |= CB4_RTIME; }
2379 	if (r_ptr->flags9 & RF9_RES_MANA) { p_ptr->resist_mana = TRUE; csheet_boni->cb[3] |= CB4_RMANA; }
2380 	if ((r_ptr->flags9 & RF9_RES_SHARDS) || (r_ptr->flags3 & RF3_HURT_ROCK))
2381 		{ p_ptr->resist_shard = TRUE;  csheet_boni->cb[2] |= CB3_RSHRD; }
2382 
2383 	if (r_ptr->flags3 & RF3_RES_TELE) { p_ptr->res_tele = TRUE; csheet_boni->cb[4] |= CB5_RTELE; }
2384 	if (r_ptr->flags9 & RF9_IM_TELE) { p_ptr->res_tele = TRUE; csheet_boni->cb[4] |= CB5_RTELE; }
2385 	if (r_ptr->flags3 & RF3_RES_PLAS) {
2386 	    p_ptr->resist_fire = TRUE; csheet_boni->cb[0] |= CB1_RFIRE;
2387 	    /* p_ptr->oppose_fire = TRUE; */
2388 	}
2389 	if (r_ptr->flags3 & RF3_RES_WATE) { p_ptr->resist_water = TRUE; csheet_boni->cb[2] |= CB3_RWATR; }
2390 	if (r_ptr->flags3 & RF3_RES_NETH) { p_ptr->resist_neth = TRUE; csheet_boni->cb[3] |= CB4_RNETH; }
2391 	if (r_ptr->flags3 & RF3_RES_NEXU) { p_ptr->resist_nexus = TRUE; csheet_boni->cb[3] |= CB4_RNEXU; }
2392 	if (r_ptr->flags3 & RF3_RES_DISE) { p_ptr->resist_disen = TRUE; csheet_boni->cb[3] |= CB4_RDISE; }
2393 	if (r_ptr->flags3 & RF3_NO_FEAR) { p_ptr->resist_fear = TRUE; csheet_boni->cb[4] |= CB5_RFEAR; }
2394 	if (r_ptr->flags3 & RF3_NO_SLEEP) { p_ptr->free_act = TRUE; csheet_boni->cb[4] |= CB5_RPARA; }
2395 	if (r_ptr->flags3 & RF3_NO_CONF) { p_ptr->resist_conf = TRUE; csheet_boni->cb[2] |= CB3_RCONF; }
2396 	if (r_ptr->flags3 & RF3_NO_STUN) { p_ptr->resist_sound = TRUE; csheet_boni->cb[2] |= CB3_RSOUN; }
2397 	if (r_ptr->flags8 & RF8_NO_CUT) { p_ptr->no_cut = TRUE; csheet_boni->cb[12] |= CB13_XNCUT; }
2398 	if (r_ptr->flags7 & RF7_CAN_FLY) {
2399 		p_ptr->levitate = TRUE; csheet_boni->cb[6] |= CB7_RRLEV;
2400 		p_ptr->feather_fall = TRUE; csheet_boni->cb[4] |= CB5_RFALL;
2401 	}
2402 	if (r_ptr->flags7 & RF7_CAN_SWIM) { p_ptr->can_swim = TRUE; csheet_boni->cb[12] |= CB13_XSWIM; }
2403 	if (r_ptr->flags2 & RF2_REFLECTING) { p_ptr->reflect = TRUE; csheet_boni->cb[6] |= CB7_RREFL; }
2404 	if (r_ptr->flags7 & RF7_DISBELIEVE) {
2405 #if 0
2406 		p_ptr->antimagic += r_ptr->level / 2 + 20; csheet_boni->amfi += r_ptr->level / 2 + 20;
2407 		p_ptr->antimagic_dis += r_ptr->level / 15 + 3;
2408 #else /* a bit stricter for mimics.. */
2409 		p_ptr->antimagic += r_ptr->level / 2 + 10; csheet_boni->amfi += r_ptr->level / 2 + 10;
2410 		p_ptr->antimagic_dis += r_ptr->level / 50 + 2;
2411 #endif
2412 	}
2413 
2414 	if ((r_ptr->flags2 & RF2_WEIRD_MIND) ||
2415 	    (r_ptr->flags9 & RF9_RES_PSI))
2416 		{ p_ptr->reduce_insanity = 1; csheet_boni->cb[3] |= CB4_RMIND; }
2417 	if ((r_ptr->flags2 & RF2_EMPTY_MIND) ||
2418 	    (r_ptr->flags9 & RF9_IM_PSI))
2419 		{ p_ptr->reduce_insanity = 2; csheet_boni->cb[3] |= CB4_RMIND; }
2420 
2421 	/* as long as not all resistances are implemented in r_info, use workaround via breaths */
2422 	if (r_ptr->flags4 & RF4_BR_LITE) { p_ptr->resist_lite = TRUE; csheet_boni->cb[2] |= CB3_RLITE; }
2423 	if (r_ptr->flags4 & RF4_BR_DARK) { p_ptr->resist_dark = TRUE; csheet_boni->cb[2] |= CB3_RDARK; }
2424 	/* if (r_ptr->flags & RF__) p_ptr->resist_blind = TRUE; */
2425 	if (r_ptr->flags4 & RF4_BR_SOUN) { p_ptr->resist_sound = TRUE; csheet_boni->cb[2] |= CB3_RSOUN; }
2426 	if (r_ptr->flags4 & RF4_BR_SHAR) { p_ptr->resist_shard = TRUE; csheet_boni->cb[2] |= CB3_RSHRD; }
2427 	if (r_ptr->flags4 & RF4_BR_CHAO) { p_ptr->resist_chaos = TRUE; csheet_boni->cb[3] |= CB4_RCHAO; }
2428 	if (r_ptr->flags4 & RF4_BR_TIME) { p_ptr->resist_time = TRUE; csheet_boni->cb[3] |= CB4_RTIME; }
2429 	if (r_ptr->flags4 & RF4_BR_MANA) { p_ptr->resist_mana = TRUE; csheet_boni->cb[3] |= CB4_RMANA; }
2430 	if (r_ptr->flags4 & RF4_BR_PLAS) {
2431 	    p_ptr->resist_fire = TRUE; csheet_boni->cb[0] |= CB1_RFIRE;
2432 	    /* p_ptr->oppose_fire = TRUE; */
2433 	}
2434 	/* if ((r_ptr->flags4 & RF4_BR_WATE) || <- does not exist */
2435 	if (r_ptr->flags7 & RF7_AQUATIC) { p_ptr->resist_water = TRUE; csheet_boni->cb[2] |= CB3_RWATR; }
2436 	if (r_ptr->flags4 & RF4_BR_NETH) { p_ptr->resist_neth = TRUE; csheet_boni->cb[3] |= CB4_RNETH; }
2437 	/* res_neth_somewhat: (r_ptr->flags3 & RF3_EVIL) */
2438 	if (r_ptr->flags4 & RF4_BR_NEXU) { p_ptr->resist_nexus = TRUE; csheet_boni->cb[3] |= CB4_RNEXU; }
2439 	if (r_ptr->flags4 & RF4_BR_DISE) { p_ptr->resist_disen = TRUE; csheet_boni->cb[3] |= CB4_RDISE; }
2440 
2441 	/* The following BR-to-RES will be needed even with all of above RES implemented: */
2442 	if (r_ptr->flags4 & RF4_BR_GRAV) { p_ptr->feather_fall = TRUE; csheet_boni->cb[4] |= CB5_RFALL; }
2443 	if (r_ptr->flags4 & RF4_BR_INER) { p_ptr->free_act = TRUE; csheet_boni->cb[4] |= CB5_RPARA; }
2444 
2445 	/* If not changed, spells didnt changed too, no need to send them */
2446 	if (!p_ptr->body_changed) {
2447 		/* restore RNG */
2448 		Rand_quick = FALSE;
2449 		return;
2450 	}
2451 	p_ptr->body_changed = FALSE;
2452 
2453 #if 0	/* moved so that 2 handed weapons etc can be checked for */
2454 	/* Take off what is no more usable */
2455 	do_takeoff_impossible(Ind);
2456 #endif
2457 
2458 	/* Hack -- cancel wraithform upon form change  */
2459 	if (!(r_ptr->flags2 & RF2_PASS_WALL) && p_ptr->tim_wraith)
2460 		p_ptr->tim_wraith = 1;
2461 
2462 	/* Update the innate spells */
2463 	calc_body_spells(Ind);
2464 
2465 	/* restore RNG */
2466 	Rand_quick = FALSE;
2467 }
2468 
2469 /* update innate spells */
calc_body_spells(int Ind)2470 void calc_body_spells(int Ind) {
2471 	player_type *p_ptr = Players[Ind];
2472 	monster_race *r_ptr;
2473 
2474 	/* If in the player body nothing has to be done */
2475 	if (!p_ptr->body_monster) return;
2476 
2477 	r_ptr = &r_info[p_ptr->body_monster];
2478 
2479 	p_ptr->innate_spells[0] = r_ptr->flags4 & RF4_PLAYER_SPELLS;
2480 	p_ptr->innate_spells[1] = r_ptr->flags5 & RF5_PLAYER_SPELLS;
2481 	p_ptr->innate_spells[2] = r_ptr->flags6 & RF6_PLAYER_SPELLS;
2482 	Send_spell_info(Ind, 0, 0, 0, "nothing");
2483 }
2484 
2485 #if 0	// moved to defines.h
2486 bool monk_heavy_armor(int Ind) {
2487  #if 1 // DGDGDGDG -- no more monks for the time being
2488 	player_type *p_ptr = Players[Ind];
2489 	u16b monk_arm_wgt = 0;
2490 
2491 //	if (!(p_ptr->pclass == CLASS_MONK)) return FALSE;
2492 	if (!get_skill(p_ptr, SKILL_MARTIAL_ARTS)) return FALSE;
2493 
2494 	/* Weight the armor */
2495 	monk_arm_wgt = armour_weight(p_ptr);
2496   #if 0
2497 	monk_arm_wgt += p_ptr->inventory[INVEN_BODY].weight;
2498 	monk_arm_wgt += p_ptr->inventory[INVEN_HEAD].weight;
2499 	monk_arm_wgt += p_ptr->inventory[INVEN_ARM].weight;
2500 	monk_arm_wgt += p_ptr->inventory[INVEN_OUTER].weight;
2501 	monk_arm_wgt += p_ptr->inventory[INVEN_HANDS].weight;
2502 	monk_arm_wgt += p_ptr->inventory[INVEN_FEET].weight;
2503   #endif	// 0
2504 
2505 //	return (monk_arm_wgt > ( 100 + (p_ptr->lev * 4))) ;
2506 	return (monk_arm_wgt > 50 + get_skill_scale(p_ptr, SKILL_MARTIAL_ARTS, 200));
2507  #endif
2508 }
2509 #endif	// 0
2510 
2511 /* Are all the weapons wielded of the right type ? */
get_weaponmastery_skill(player_type * p_ptr,object_type * o_ptr)2512 int get_weaponmastery_skill(player_type *p_ptr, object_type *o_ptr) {
2513 	int skill = 0;
2514 
2515 	if (!o_ptr->k_idx || o_ptr->tval == TV_SHIELD) return -1;
2516 
2517 	switch (o_ptr->tval) {
2518 	case TV_SWORD:
2519 		if ((!skill) || (skill == SKILL_SWORD)) skill = SKILL_SWORD;
2520 		else skill = -1;
2521 		break;
2522 	case TV_AXE:
2523 		if ((!skill) || (skill == SKILL_AXE)) skill = SKILL_AXE;
2524 		else skill = -1;
2525 		break;
2526 	case TV_BLUNT:
2527 		if ((!skill) || (skill == SKILL_BLUNT)) skill = SKILL_BLUNT;
2528 		else skill = -1;
2529 		break;
2530 //	case SKILL_POLEARM:
2531 	case TV_POLEARM:
2532 		if ((!skill) || (skill == SKILL_POLEARM)) skill = SKILL_POLEARM;
2533 		else skill = -1;
2534 		break;
2535 	}
2536 
2537 	/* Everything is ok */
2538 	return skill;
2539 }
2540 
2541 /* Are all the ranged weapons wielded of the right type ? */
get_archery_skill(player_type * p_ptr)2542 int get_archery_skill(player_type *p_ptr) {
2543 	int skill = 0;
2544 	object_type *o_ptr;
2545 
2546 	o_ptr = &p_ptr->inventory[INVEN_BOW];
2547 
2548 	if (!o_ptr->k_idx) return -1;
2549 
2550 	/* Hack -- Boomerang skill */
2551 	if (o_ptr->tval == TV_BOOMERANG) return SKILL_BOOMERANG;
2552 
2553 	switch (o_ptr->sval / 10) {
2554 		case 0:
2555 			if ((!skill) || (skill == SKILL_SLING)) skill = SKILL_SLING;
2556 			else skill = -1;
2557 			break;
2558 		case 1:
2559 			if ((!skill) || (skill == SKILL_BOW)) skill = SKILL_BOW;
2560 			else skill = -1;
2561 			break;
2562 		case 2:
2563 			if ((!skill) || (skill == SKILL_XBOW)) skill = SKILL_XBOW;
2564 			else skill = -1;
2565 			break;
2566 	}
2567 
2568 	/* Everything is ok */
2569 	return skill;
2570 }
2571 
2572 
calc_blows_obj(int Ind,object_type * o_ptr)2573 int calc_blows_obj(int Ind, object_type *o_ptr) {
2574 	player_type *p_ptr = Players[Ind];
2575 	int str_index, dex_index, eff_weight = o_ptr->weight;
2576 	u32b f1;
2577 	artifact_type *a_ptr;
2578 
2579 	int num = 0, wgt = 0, mul = 0, div = 0, num_blow = 0, str_adj, xblow = 0;
2580 
2581 	/* cap for Grond. Heaviest normal weapon is MoD at 40.0, which Grond originally was, too. - C. Blue */
2582 	if (eff_weight > 400) eff_weight = 400;
2583 
2584 	/* Weapons which can be wielded 2-handed are easier to swing
2585 	   than with one hand - experimental - C. Blue */
2586 	if ((!p_ptr->inventory[INVEN_ARM].k_idx || /* don't forget dual-wield.. weapon might be in the other hand! */
2587 	    (!p_ptr->inventory[INVEN_WIELD].k_idx && p_ptr->inventory[INVEN_ARM].tval != TV_SHIELD)) &&
2588 	    (k_info[o_ptr->k_idx].flags4 & (TR4_SHOULD2H | TR4_MUST2H | TR4_COULD2H)))
2589 		eff_weight = (eff_weight * 2) / 3; /* probably more sensible, but..see the line below :/ */
2590 //too easy!	eff_weight = (eff_weight * 1) / 2; /* get 2bpr with 18/30 str even with broad axe starting weapon */
2591 
2592 	/* Analyze the class */
2593 	switch (p_ptr->pclass) {
2594 							/* Adevnturer */
2595 		case CLASS_ADVENTURER: num = 4; wgt = 35; mul = 4; break;//wgt=35, but MA is too easy in comparison.
2596 //was num = 5; ; mul = 6
2597 							/* Warrior */
2598 		case CLASS_WARRIOR: num = 6; wgt = 30; mul = 5; break;
2599 
2600 							/* Mage */
2601 		case CLASS_MAGE: num = 1; wgt = 40; mul = 2; break;
2602 //was num = 3; ;
2603 							/* Priest */
2604 		case CLASS_PRIEST: num = 4; wgt = 35; mul = 4; break;//mul3
2605 //was num = 5; ;
2606 							/* Rogue */
2607 		case CLASS_ROGUE: num = 5; wgt = 30; mul = 4; break; /* was mul = 3 - C. Blue - EXPERIMENTAL */
2608 
2609 		/* I'm a rogue like :-o */
2610 		case CLASS_RUNEMASTER: num = 4; wgt = 30; mul = 4; break;//was wgt = 40
2611 							/* Mimic */
2612 //trying 5bpr	case CLASS_MIMIC: num = 4; wgt = 30; mul = 4; break;//mul3
2613 		case CLASS_MIMIC: num = 5; wgt = 35; mul = 5; break;//mul3; mul4!
2614 
2615 							/* Archer */
2616 //		case CLASS_ARCHER: num = 3; wgt = 30; mul = 3; break;
2617 		case CLASS_ARCHER: num = 3; wgt = 35; mul = 4; break;
2618 
2619 							/* Paladin */
2620 		case CLASS_PALADIN: num = 5; wgt = 35; mul = 5; break;//mul4
2621 
2622 							/* Ranger */
2623 		case CLASS_RANGER: num = 5; wgt = 35; mul = 4; break;//mul4
2624 
2625 
2626 		case CLASS_DRUID: num = 4; wgt = 35; mul = 4; break;
2627 
2628 /* if he is to become a spellcaster, necro working on spell-kills:
2629 		case CLASS_SHAMAN: num = 2; wgt = 40; mul = 3; break;
2630     however, then Martial Arts would require massive nerfing too for this class (or being removed even).
2631 otherwise, let's compromise for now: */
2632 		case CLASS_SHAMAN: num = 4; wgt = 35; mul = 4; break;
2633 
2634 		case CLASS_MINDCRAFTER: num = 5; wgt = 35; mul = 4; break;//was 4,30,4
2635 
2636 /*		case CLASS_BARD: num = 4; wgt = 35; mul = 4; break; */
2637 	}
2638 
2639 	/* Enforce a minimum "weight" (tenth pounds) */
2640 	div = ((eff_weight < wgt) ? wgt : eff_weight);
2641 
2642 	/* Access the strength vs weight */
2643 	str_adj = adj_str_blow[p_ptr->stat_ind[A_STR]];
2644 	if (str_adj == 240) str_adj = 426; /* hack to reach 6 bpr with 400 lb weapons (max) at *** STR - C. Blue */
2645 	str_index = ((str_adj * mul) / div);
2646 
2647 	/* Maximal value */
2648 	if (str_index > 11) str_index = 11;
2649 
2650 	/* Index by dexterity */
2651 	dex_index = (adj_dex_blow[p_ptr->stat_ind[A_DEX]]);
2652 
2653 	/* Maximal value */
2654 	if (dex_index > 11) dex_index = 11;
2655 
2656 	/* Use the blows table */
2657 	num_blow = blows_table[str_index][dex_index];
2658 
2659 	/* Maximal value */
2660 	if (num_blow > num) num_blow = num;
2661 
2662 	/* Require at least one blow */
2663 	if (num_blow < 1) num_blow = 1;
2664 
2665 	/* Boost blows with masteries */
2666 	if (get_weaponmastery_skill(p_ptr, o_ptr) != -1)
2667 		num_blow += get_skill_scale(p_ptr, get_weaponmastery_skill(p_ptr, o_ptr), 2);
2668 
2669 #if 0
2670 	f1 = k_info[o_ptr->k_idx].flags1;
2671 #else
2672 	u32b f2, f3, f4, f5, f6, esp;
2673 	/* Extract the item flags */
2674 	object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &f6, &esp);
2675 #endif
2676 	if (f1 & (TR1_BLOWS)) xblow = o_ptr->bpval;
2677 	if (o_ptr->name2) {
2678 		a_ptr = ego_make(o_ptr);
2679 		f1 &= ~(k_info[o_ptr->k_idx].flags1 & TR1_PVAL_MASK & ~a_ptr->flags1);
2680 	}
2681 	if (o_ptr->name1 == ART_RANDART) {
2682 		a_ptr = randart_make(o_ptr);
2683 		f1 &= ~(k_info[o_ptr->k_idx].flags1 & TR1_PVAL_MASK & ~a_ptr->flags1);
2684 	}
2685 	if ((f1 & TR1_BLOWS)
2686 #if 1 /* this appearently works */
2687 	    && o_ptr->pval > xblow) xblow = o_ptr->pval;
2688 #else /* this is how it's done in xtra1.c though */
2689       /* this allows shadow blade of ea (+2) (+n) to give +2+n EA */
2690 		) xblow += o_ptr->pval;
2691 #endif
2692 	num_blow += xblow;
2693 
2694 	return (num_blow);
2695 }
2696 
calc_blows_weapons(int Ind)2697 int calc_blows_weapons(int Ind) {
2698 	player_type *p_ptr = Players[Ind];
2699 	int num_blow = 0, blows1 = 0, blows2 = 0;
2700 
2701 
2702 	/* calculate blows with weapons (includes weaponmastery boni already) */
2703 
2704 	if (p_ptr->inventory[INVEN_WIELD].k_idx) blows1 = calc_blows_obj(Ind, &p_ptr->inventory[INVEN_WIELD]);
2705 	else if (p_ptr->inventory[INVEN_ARM].k_idx) blows1 = calc_blows_obj(Ind, &p_ptr->inventory[INVEN_ARM]);
2706 	if (p_ptr->dual_wield) blows2 = calc_blows_obj(Ind, &p_ptr->inventory[INVEN_ARM]);
2707 
2708 
2709 	/* apply dual-wield boni and calculations */
2710 
2711 	/* mediate for dual-wield */
2712 #if 0 /* round down? (see bpr bonus below too) (encourages bpr gloves/crit weapons - makes more sense?) */
2713 	if (p_ptr->dual_wield && p_ptr->dual_mode) num_blow = (blows1 + blows2) / 2;
2714 #elif 0 /* round up? (see bpr bonus below too) (encounrages crit gloves/bpr weapons) */
2715 	if (p_ptr->dual_wield && p_ptr->dual_mode) num_blow = (blows1 + blows2 + 1) / 2;
2716 #else /* round up, but only if we aren't anti-dual-wield-encumbered! */
2717 	if (p_ptr->dual_wield && p_ptr->dual_mode) {
2718 		if (!p_ptr->rogue_heavyarmor) num_blow = (blows1 + blows2 + 1) / 2;
2719 		/* if encumbered, we cannot gain any dual-wield advantage! */
2720 		else num_blow = (blows1 + blows2) / 2;
2721 	}
2722 #endif
2723 	else num_blow = blows1;
2724 
2725 	/* add dual-wield bonus if we wear light armour! */
2726 	if (!p_ptr->rogue_heavyarmor && p_ptr->dual_wield && p_ptr->dual_mode)
2727 #if 0 /* if rounding down, add percentage bpr bonus maybe */
2728 //		num_blow += (1 + (num_blow - 1) / 5);
2729 		num_blow++;
2730 #else /* if rounding up, add fixed (ie small) bpr bonus! */
2731 //		num_blow += (1 + (num_blow - 1) / 5);  <- warriors could rightfully complain I think, mh.
2732 		num_blow++;
2733 #endif
2734 
2735 
2736 	/* done */
2737 
2738 	return num_blow;
2739 }
2740 
calc_crit_obj(int Ind,object_type * o_ptr)2741 int calc_crit_obj(int Ind, object_type *o_ptr) {
2742 	artifact_type *a_ptr;
2743 	int xcrit = 0;
2744 	u32b f1, f2, f3, f4, f5, f6, esp;
2745 	object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &f6, &esp);
2746 
2747 	if (f5 & (TR5_CRIT)) xcrit = o_ptr->bpval;
2748 	/* check for either.. */
2749 	if (o_ptr->name2) {
2750 		/* additional crits from an ego power, or.. */
2751 		a_ptr = ego_make(o_ptr);
2752 		f5 &= ~(k_info[o_ptr->k_idx].flags5 & TR5_PVAL_MASK & ~a_ptr->flags5);
2753 	}
2754 	if (o_ptr->name1 == ART_RANDART) {
2755 		/* additional crits from a randart power. */
2756 		a_ptr = randart_make(o_ptr);
2757 		f5 &= ~(k_info[o_ptr->k_idx].flags5 & TR5_PVAL_MASK & ~a_ptr->flags5);
2758 	}
2759 	if ((f5 & TR5_CRIT)
2760 #if 0 /* this appearently works */
2761 	    && o_ptr->pval > xcrit) xcrit = o_ptr->pval;
2762 #else /* this is how it's done in xtra1.c though */
2763 		) xcrit += o_ptr->pval; /* no intrinsic +CRIT items in k_info.txt at the moment anyway, so it doesn't matter which way we choose */
2764 #endif
2765 	return (xcrit);
2766 }
2767 
2768 
2769 /*
2770  * Calculate the players current "state", taking into account
2771  * not only race/class intrinsics, but also objects being worn
2772  * and temporary spell effects.
2773  *
2774  * See also calc_mana() and calc_hitpoints().
2775  *
2776  * Take note of the new "speed code", in particular, a very strong
2777  * player will start slowing down as soon as he reaches 150 pounds,
2778  * but not until he reaches 450 pounds will he be half as fast as
2779  * a normal kobold.  This both hurts and helps the player, hurts
2780  * because in the old days a player could just avoid 300 pounds,
2781  * and helps because now carrying 300 pounds is not very painful.
2782  *
2783  * The "weapon" and "bow" do *not* add to the bonuses to hit or to
2784  * damage, since that would affect non-combat things.  These values
2785  * are actually added in later, at the appropriate place.
2786  *
2787  * This function induces various "status" messages.
2788  */
calc_boni(int Ind)2789 void calc_boni(int Ind) {
2790 	cptr inscription = NULL;
2791 //	char tmp[80];
2792 
2793 	player_type *p_ptr = Players[Ind];
2794 	dun_level *l_ptr = getfloor(&p_ptr->wpos);
2795 	cave_type **zcave;
2796 
2797 	/* Note: For vampires with auto-ID this is required, because of the 3
2798 	   times that calc_boni() is called on logging in, for those vampires
2799 	   (or V-form users) the first one will be in non-ready connection
2800 	   state, while for other characters all three are actually in ready
2801 	   connection state.
2802 	   This will cause inventory/equipment to be 'broken' for vampires. */
2803 	bool logged_in = get_conn_state_ok(Ind);
2804 
2805 	if (!(zcave = getcave(&p_ptr->wpos))) {
2806 		/* for stair-goi: try to repeat this failed calc_boni() call asap - C. Blue */
2807 		p_ptr->update |= PU_BONUS;
2808 		return;
2809 	}
2810 
2811 	int kk, jj;
2812 	boni_col csheet_boni[15];
2813 	/* Wipe the boni column data */
2814 	for (kk = 0; kk < 15; kk++) {
2815 		csheet_boni[kk].i = kk;
2816 		csheet_boni[kk].spd = 0;
2817 		csheet_boni[kk].slth = 0;
2818 		csheet_boni[kk].srch = 0;
2819 		csheet_boni[kk].infr = 0;
2820 		csheet_boni[kk].lite = 0;
2821 		csheet_boni[kk].dig = 0;
2822 		csheet_boni[kk].blow = 0;
2823 		csheet_boni[kk].crit = 0;
2824 		csheet_boni[kk].shot = 0;
2825 		csheet_boni[kk].migh = 0;
2826 		csheet_boni[kk].mxhp = 0;
2827 		csheet_boni[kk].mxmp = 0;
2828 		csheet_boni[kk].luck = 0;
2829 		csheet_boni[kk].pstr = 0;
2830 		csheet_boni[kk].pint = 0;
2831 		csheet_boni[kk].pwis = 0;
2832 		csheet_boni[kk].pdex = 0;
2833 		csheet_boni[kk].pcon = 0;
2834 		csheet_boni[kk].pchr = 0;
2835 		csheet_boni[kk].amfi = 0;
2836 		csheet_boni[kk].sigl = 0;
2837 		/* Clear the byte flags */
2838 		for (jj = 0; jj < 13; jj++)
2839 			csheet_boni[kk].cb[jj] = 0;
2840 		csheet_boni[kk].color = TERM_DARK;
2841 		csheet_boni[kk].symbol = ' '; //Empty item / form slot.
2842 	}
2843 
2844 	int			j, hold, minus, am_bonus = 0, am_temp;
2845 	long			w, i;
2846 
2847 	int			old_speed;
2848 	int			old_num_blow;
2849 
2850 	u32b			old_telepathy;
2851 	int			old_see_inv;
2852 
2853 	int			old_dis_ac;
2854 	int			old_dis_to_a;
2855 
2856 	int			old_dis_to_h, old_to_h_melee;
2857 	int			old_dis_to_d, old_to_d_melee;
2858 
2859 //	int			extra_blows;
2860 	int			extra_shots;
2861 	int			extra_spells;
2862 
2863 	object_type		*o_ptr, *o2_ptr;
2864 	object_kind		*k_ptr;
2865 
2866 	long int d, toac = 0, body = 0;
2867 	monster_race *r_ptr = &r_info[p_ptr->body_monster];
2868 
2869 	u32b f1, f2, f3, f4, f5, f6, esp;
2870 	s16b pval;
2871 
2872 	bool old_auto_id = p_ptr->auto_id;
2873 	bool old_dual_wield = p_ptr->dual_wield;
2874 
2875 	bool old_sun_burn;
2876 
2877 	int lite_inc_norm = 0, lite_inc_white = 0, old_lite_type;
2878 
2879 #ifdef EQUIPMENT_SET_BONUS
2880 	/* for boni of artifact "sets" ie arts of (about) identical name - C. Blue */
2881 	int equipment_set[INVEN_TOTAL - INVEN_WIELD], equipment_set_amount[INVEN_TOTAL - INVEN_WIELD];
2882 	char equipment_set_name[INVEN_TOTAL - INVEN_WIELD][80];
2883 	int equipment_set_bonus = 0;
2884 	char tmp_name[ONAME_LEN], *tmp_name_ptr;
2885 
2886 	for (i = 0; i < INVEN_TOTAL - INVEN_WIELD; i++) {
2887 		equipment_set[i] = 0;
2888 		equipment_set_name[i][0] = 0;
2889 	}
2890 #endif
2891 
2892 	/* Save the old speed */
2893 	old_speed = p_ptr->pspeed;
2894 
2895 	/* Save the old vision stuff */
2896 	old_telepathy = p_ptr->telepathy;
2897 	old_see_inv = p_ptr->see_inv;
2898 
2899 	/* Save the old armor class */
2900 	old_dis_ac = p_ptr->dis_ac;
2901 	old_dis_to_a = p_ptr->dis_to_a;
2902 
2903 	/* Save the old hit/damage bonuses */
2904 	old_dis_to_h = p_ptr->dis_to_h;
2905 	old_dis_to_d = p_ptr->dis_to_d;
2906 
2907 	old_to_h_melee = p_ptr->to_h_melee;
2908 	old_to_d_melee = p_ptr->to_d_melee;
2909 
2910 	/* Clear extra blows/shots */
2911 //	extra_blows = extra_shots = extra_spells = 0;
2912 	extra_shots = extra_spells = 0;
2913 
2914 	/* Clear the stat modifiers */
2915 	for (i = 0; i < 6; i++) p_ptr->stat_add[i] = 0;
2916 
2917 	/* Druidism bonuses */
2918 	if (p_ptr->xtrastat > 0) {
2919 		p_ptr->stat_add[A_STR] = p_ptr->xstr;
2920 		p_ptr->stat_add[A_INT] = p_ptr->xint;
2921 		p_ptr->stat_add[A_DEX] = p_ptr->xdex;
2922 		p_ptr->stat_add[A_CON] = p_ptr->xcon;
2923 		p_ptr->stat_add[A_CHR] = p_ptr->xchr;
2924 	}
2925 
2926 	/* Clear the Displayed/Real armor class */
2927 	p_ptr->dis_ac = p_ptr->ac = 0;
2928 
2929 	/* Clear the Displayed/Real Bonuses */
2930 	p_ptr->dis_to_h = p_ptr->to_h = p_ptr->to_h_melee = p_ptr->to_h_ranged = 0;
2931 	p_ptr->dis_to_d = p_ptr->to_d = p_ptr->to_d_melee = p_ptr->to_d_ranged = 0;
2932 	p_ptr->dis_to_a = p_ptr->to_a = 0;
2933 
2934 
2935 	/* Clear all the flags */
2936 	p_ptr->aggravate = FALSE;
2937 	p_ptr->teleport = FALSE;
2938 	p_ptr->drain_exp = 0;
2939 	p_ptr->drain_mana = 0;
2940 	p_ptr->drain_life = 0;
2941 	p_ptr->bless_blade = FALSE;
2942 	p_ptr->xtra_might = 0;
2943 	p_ptr->impact = FALSE;
2944 	p_ptr->see_inv = FALSE;
2945 	p_ptr->free_act = FALSE;
2946 	p_ptr->slow_digest = FALSE;
2947 	p_ptr->regenerate = FALSE;
2948 	p_ptr->resist_time = FALSE;
2949 	p_ptr->resist_mana = FALSE;
2950 	p_ptr->resist_plasma = FALSE;
2951 	p_ptr->immune_poison = FALSE;
2952 	p_ptr->immune_water = FALSE;
2953 	p_ptr->resist_water = FALSE;
2954 	p_ptr->regen_mana = FALSE;
2955 	p_ptr->feather_fall = FALSE;
2956 	p_ptr->hold_life = FALSE;
2957 	p_ptr->telepathy = 0;
2958 	p_ptr->lite = FALSE;
2959 	p_ptr->cur_lite = 0;
2960 	p_ptr->cur_vlite = 0;
2961 	p_ptr->sustain_str = FALSE;
2962 	p_ptr->sustain_int = FALSE;
2963 	p_ptr->sustain_wis = FALSE;
2964 	p_ptr->sustain_con = FALSE;
2965 	p_ptr->sustain_dex = FALSE;
2966 	p_ptr->sustain_chr = FALSE;
2967 	p_ptr->resist_acid = FALSE;
2968 	p_ptr->resist_elec = FALSE;
2969 	p_ptr->resist_fire = FALSE;
2970 	p_ptr->resist_cold = FALSE;
2971 	p_ptr->resist_pois = FALSE;
2972 	p_ptr->resist_conf = FALSE;
2973 	p_ptr->resist_sound = FALSE;
2974 	p_ptr->resist_lite = FALSE;
2975 	p_ptr->resist_dark = FALSE;
2976 	p_ptr->resist_chaos = FALSE;
2977 	p_ptr->resist_disen = FALSE;
2978 	p_ptr->resist_shard = FALSE;
2979 	p_ptr->resist_nexus = FALSE;
2980 	p_ptr->resist_blind = FALSE;
2981 	p_ptr->resist_neth = FALSE;
2982 	p_ptr->resist_fear = FALSE;
2983 	p_ptr->immune_acid = FALSE;
2984 	p_ptr->immune_elec = FALSE;
2985 	p_ptr->immune_fire = FALSE;
2986 	p_ptr->immune_cold = FALSE;
2987 	p_ptr->sh_fire = p_ptr->sh_fire_fix = FALSE;
2988 	p_ptr->sh_elec = p_ptr->sh_elec_fix = FALSE;
2989 	p_ptr->sh_cold = p_ptr->sh_cold_fix = FALSE;
2990 	p_ptr->brand_fire = FALSE;
2991 	p_ptr->brand_cold = FALSE;
2992 	p_ptr->brand_elec = FALSE;
2993 	p_ptr->brand_acid = FALSE;
2994 	p_ptr->brand_pois = FALSE;
2995 	p_ptr->auto_tunnel = FALSE;
2996 	p_ptr->levitate = FALSE;
2997 	p_ptr->can_swim = FALSE;
2998 	p_ptr->climb = FALSE;
2999 	p_ptr->pass_trees = FALSE;
3000 	p_ptr->luck = 0;
3001 	p_ptr->reduc_fire = 0;
3002 	p_ptr->reduc_cold = 0;
3003 	p_ptr->reduc_elec = 0;
3004 	p_ptr->reduc_acid = 0;
3005 	p_ptr->anti_magic = FALSE;
3006 	p_ptr->auto_id = FALSE;
3007 	p_ptr->reflect = FALSE;
3008 	p_ptr->shield_deflect = 0;
3009 	p_ptr->weapon_parry = 0;
3010 	p_ptr->no_cut = FALSE;
3011 	p_ptr->reduce_insanity = 0;
3012 //	p_ptr->to_s = 0;
3013 	p_ptr->to_m = 0;
3014 	p_ptr->to_l = 0;
3015 	p_ptr->to_hp = 0;
3016 	p_ptr->black_breath_tmp = FALSE;
3017 
3018 	p_ptr->dual_wield = FALSE;
3019 	if (p_ptr->inventory[INVEN_WIELD].k_idx &&
3020 	    p_ptr->inventory[INVEN_ARM].k_idx && p_ptr->inventory[INVEN_ARM].tval != TV_SHIELD) {
3021 		p_ptr->dual_wield = TRUE;
3022 		/* Don't kill warnings by inspecting weapons/armour in stores! */
3023 		if (!suppress_message)
3024 		if (p_ptr->warning_dual_mode == 0 && !old_dual_wield && !p_ptr->dual_mode) {
3025 			msg_print(Ind, "\374\377yHINT: Dual-wield mode isn't enabled! Press '\377om\377y' to toggle it!");
3026 			s_printf("warning_dual_mode: %s\n", p_ptr->name);
3027 			p_ptr->warning_dual_mode = 1;
3028 		}
3029 	}
3030 
3031 	p_ptr->stormbringer = FALSE;
3032 
3033 	/* Invisibility */
3034 	p_ptr->invis = 0;
3035 	p_ptr->tim_invis_power = 0;
3036 
3037 	p_ptr->immune_neth = FALSE;
3038 	p_ptr->anti_tele = FALSE;
3039 	p_ptr->res_tele = FALSE;
3040 	p_ptr->antimagic = 0;
3041 	p_ptr->antimagic_dis = 0;
3042 	p_ptr->xtra_crit = 0;
3043 	p_ptr->dodge_level = 1; /* everyone may get a lucky evasion :) - C. Blue */
3044 
3045 	p_ptr->suscep_fire = FALSE;
3046 	p_ptr->suscep_cold = FALSE;
3047 	p_ptr->suscep_elec = FALSE;
3048 	p_ptr->suscep_acid = FALSE;
3049 	p_ptr->suscep_pois = FALSE;
3050 	p_ptr->suscep_lite = FALSE;
3051 	p_ptr->suscep_good = FALSE;
3052 	p_ptr->suscep_evil = FALSE;
3053 	p_ptr->suscep_life = FALSE;
3054 	p_ptr->resist_continuum = FALSE;
3055 	p_ptr->vampiric_melee = 0;
3056 	p_ptr->vampiric_ranged = 0;
3057 
3058 	/* nastiness */
3059 	p_ptr->ty_curse = FALSE;
3060 	p_ptr->dg_curse = FALSE;
3061 
3062 	/* Start with a single blow per turn */
3063 	old_num_blow = p_ptr->num_blow;
3064 	p_ptr->num_blow = 1;
3065 	p_ptr->extra_blows = 0;
3066 	/* Start with a single shot per turn */
3067 	p_ptr->num_fire = 1;
3068 	/* Start with a single spell per turn */
3069 	p_ptr->num_spell = 1;
3070 
3071 	/* Reset the "xtra" tval */
3072 	p_ptr->tval_xtra = 0;
3073 	/* Reset the "ammo" tval */
3074 	p_ptr->tval_ammo = 0;
3075 
3076 	/* Base infravision (purely racial) */
3077 	p_ptr->see_infra = p_ptr->rp_ptr->infra;
3078 	//csheet_boni[14].infr = p_ptr->see_infra;
3079 
3080 	/* Base skill -- disarming */
3081 	p_ptr->skill_dis = p_ptr->rp_ptr->r_dis + p_ptr->cp_ptr->c_dis;
3082 	/* Base skill -- magic devices */
3083 	p_ptr->skill_dev = p_ptr->rp_ptr->r_dev + p_ptr->cp_ptr->c_dev;
3084 	/* Base skill -- saving throw */
3085 	p_ptr->skill_sav = p_ptr->rp_ptr->r_sav + p_ptr->cp_ptr->c_sav;
3086 	/* Base skill -- stealth */
3087 	p_ptr->skill_stl = p_ptr->rp_ptr->r_stl + p_ptr->cp_ptr->c_stl;
3088 	/* Base skill -- searching ability */
3089 	p_ptr->skill_srh = p_ptr->rp_ptr->r_srh + p_ptr->cp_ptr->c_srh;
3090 	/* Base skill -- searching frequency */
3091 	p_ptr->skill_fos = p_ptr->rp_ptr->r_fos + p_ptr->cp_ptr->c_fos;
3092 	/* Base skill -- combat (normal) */
3093 	p_ptr->skill_thn = p_ptr->rp_ptr->r_thn + p_ptr->cp_ptr->c_thn;
3094 	/* Base skill -- combat (shooting) */
3095 	p_ptr->skill_thb = p_ptr->rp_ptr->r_thb + p_ptr->cp_ptr->c_thb;
3096 	/* Base skill -- combat (throwing) */
3097 	p_ptr->skill_tht = p_ptr->rp_ptr->r_thb + p_ptr->cp_ptr->c_thb;
3098 
3099 	/* Base skill -- digging */
3100 	p_ptr->skill_dig = 0;
3101 
3102 	/* Special admin items */
3103 	p_ptr->admin_invuln = p_ptr->admin_invinc = FALSE;
3104 
3105 	p_ptr->no_heal = FALSE;
3106 
3107 
3108 	/* Not a limit, but good place maybe */
3109 	if ((l_ptr && (l_ptr->flags2 & LF2_NO_RES_HEAL)) ||
3110 	    (in_sector00(&p_ptr->wpos) && (sector00flags2 & LF2_NO_RES_HEAL)))
3111 		p_ptr->no_heal = TRUE;
3112 
3113 
3114 	/* Calc bonus body */
3115 	if (!p_ptr->body_monster) {
3116 		/* Show the '@' with class colour for the boni page */
3117 		csheet_boni[14].symbol = (p_ptr->fruit_bat) ? 'b' : '@';
3118 		csheet_boni[14].color = class_info[p_ptr->pclass].color;
3119 	} else {
3120 		/* Show the monster form if the player is polymorphed */
3121 		csheet_boni[14].symbol = r_info[p_ptr->body_monster].d_char;
3122 		csheet_boni[14].color = r_info[p_ptr->body_monster].d_attr;
3123 	}
3124 	if (p_ptr->body_monster) calc_body_bonus(Ind, &csheet_boni[14]);
3125 	else {	// if if or switch to switch, that is the problem :)
3126 			/* I vote for p_info ;) */
3127 		/* Update the innate spells */
3128 		p_ptr->innate_spells[0] = 0x0;
3129 		p_ptr->innate_spells[1] = 0x0;
3130 		p_ptr->innate_spells[2] = 0x0;
3131 		if (!suppress_boni && logged_in) Send_spell_info(Ind, 0, 0, 0, "nothing");
3132 
3133 		/* Start with "normal" speed */
3134 		p_ptr->pspeed = 110;
3135 
3136 #ifdef ARCADE_SERVER
3137 		p_ptr->pspeed = 130;
3138 		if (p_ptr->stun > 0) p_ptr->pspeed -= 3;
3139 #endif
3140 
3141 		/* Bats get +10 speed ... they need it!*/
3142 		if (p_ptr->fruit_bat) {
3143 			if (p_ptr->fruit_bat == 1)
3144 				p_ptr->pspeed += 10; //disabled due to bat-party-powerlevel-cheezing
3145 //				p_ptr->pspeed += (3 + (p_ptr->lev > 49 ? 7 : p_ptr->lev / 7)); // +10 eventually.
3146 //				p_ptr->pspeed += (3 + (p_ptr->lev > 42 ? 7 : p_ptr->lev / 6)); // +10 eventually.
3147 //				p_ptr->pspeed += (3 + (p_ptr->lev > 35 ? 7 : p_ptr->lev / 5)); // +10 eventually.
3148 			else
3149 				p_ptr->pspeed += 3;
3150 			p_ptr->levitate = TRUE; csheet_boni[14].cb[6] |= CB7_RRLEV;
3151 			p_ptr->feather_fall = TRUE; csheet_boni[14].cb[4] |= CB5_RFALL;
3152 			if (p_ptr->vampiric_melee < 50) { p_ptr->vampiric_melee = 50; csheet_boni->cb[6] |= CB7_RVAMP; }
3153 		}
3154 
3155 		csheet_boni[14].spd = p_ptr->pspeed - 110;
3156 	/* Choosing a race just for its HP or low exp% shouldn't be what we want -C. Blue- */
3157 	}
3158 
3159 
3160 	/* Half-Elf */
3161 	if (p_ptr->prace == RACE_HALF_ELF) {
3162 		p_ptr->resist_lite = TRUE; csheet_boni[14].cb[2] |= CB3_RLITE;
3163 	}
3164 
3165 	/* Elf */
3166 	else if (p_ptr->prace == RACE_ELF) {
3167 		p_ptr->see_inv = TRUE; csheet_boni[14].cb[5] |= CB6_RSINV;
3168 		p_ptr->resist_lite = TRUE; csheet_boni[14].cb[2] |= CB3_RLITE;
3169 	}
3170 
3171 	/* Hobbit */
3172 	else if (p_ptr->prace == RACE_HOBBIT) {
3173 		p_ptr->sustain_dex = TRUE; csheet_boni[14].cb[11] |= CB12_RSDEX;
3174 
3175 		/* DEX bonus for NOT wearing shoes */
3176 		/* not while in mimicried form */
3177 		if (!p_ptr->body_monster && !p_ptr->inventory[INVEN_FEET].k_idx)
3178 			{ p_ptr->stat_add[A_DEX] += 2;  csheet_boni[14].pdex += 2; }
3179 	}
3180 
3181 	/* Gnome */
3182 	else if (p_ptr->prace == RACE_GNOME) { p_ptr->free_act = TRUE; csheet_boni[14].cb[4] |= CB5_RPARA; }
3183 
3184 	/* Dwarf */
3185 	else if (p_ptr->prace == RACE_DWARF) {
3186 		p_ptr->resist_blind = TRUE; csheet_boni[14].cb[4] |= CB5_RBLND;
3187 		/* not while in mimicried form */
3188 		if (!p_ptr->body_monster && p_ptr->lev >= 30) { p_ptr->climb = TRUE; csheet_boni[14].cb[6] |= CB7_RCLMB; }
3189 	}
3190 
3191 	/* Half-Orc */
3192 	else if (p_ptr->prace == RACE_HALF_ORC) { p_ptr->resist_dark = TRUE; csheet_boni[14].cb[2] |= CB3_RDARK; }
3193 
3194 	/* Half-Troll */
3195 	else if (p_ptr->prace == RACE_HALF_TROLL) {
3196 		p_ptr->sustain_str = TRUE; csheet_boni[14].cb[11] |= CB12_RSSTR;
3197 		p_ptr->regenerate = TRUE; csheet_boni[14].cb[5] |= CB6_RRGHP;
3198 	}
3199 
3200 	/* Dunadan */
3201 	else if (p_ptr->prace == RACE_DUNADAN) { p_ptr->sustain_con = TRUE;  csheet_boni[14].cb[11] |= CB12_RSCON; }
3202 
3203 	/* High Elf */
3204 	else if (p_ptr->prace == RACE_HIGH_ELF) {
3205 		p_ptr->resist_lite = TRUE; csheet_boni[14].cb[2] |= CB3_RLITE;
3206 		p_ptr->see_inv = TRUE; csheet_boni[14].cb[5] |= CB6_RSINV;
3207 		p_ptr->resist_time = TRUE; csheet_boni[14].cb[3] |= CB4_RTIME;
3208 	}
3209 
3210 	/* Yeek */
3211 	else if (p_ptr->prace == RACE_YEEK) {
3212 		p_ptr->feather_fall = TRUE; csheet_boni[14].cb[4] |= CB5_RFALL;
3213 		/* not while in mimicried form */
3214 		if (!p_ptr->body_monster) p_ptr->pass_trees = TRUE; csheet_boni[14].cb[12] |= CB13_XTREE;
3215 	}
3216 
3217 	/* Goblin */
3218 	else if (p_ptr->prace == RACE_GOBLIN) {
3219 		p_ptr->resist_dark = TRUE; csheet_boni[14].cb[2] |= CB3_RDARK;
3220 		/* not while in mimicried form */
3221 		/*if (!p_ptr->body_monster) p_ptr->feather_fall = TRUE;*/
3222 	}
3223 
3224 	/* Ent */
3225 	else if (p_ptr->prace == RACE_ENT) {
3226 		/* always a bit slowish */
3227 		p_ptr->slow_digest = TRUE; csheet_boni[14].cb[4] |= CB5_RFOOD;
3228 		/* even while in different form? */
3229 		p_ptr->suscep_fire = TRUE; csheet_boni[14].cb[0] |= CB1_SFIRE;
3230 		p_ptr->resist_water = TRUE; csheet_boni[14].cb[2] |= CB3_RWATR;
3231 
3232 		/* not while in mimicried form */
3233 		if (!p_ptr->body_monster) {
3234 			p_ptr->pspeed -= 2; csheet_boni[14].spd -= 2;
3235 			p_ptr->can_swim = TRUE; csheet_boni[14].cb[12] |= CB13_XSWIM; /* wood? */
3236 			p_ptr->pass_trees = TRUE; csheet_boni[14].cb[12] |= CB13_XTREE;
3237 		} else { p_ptr->pspeed -= 1; csheet_boni[14].spd -= 1; } /* it's cost of ent's power, isn't it? */
3238 
3239 		if (p_ptr->lev >= 4) { p_ptr->see_inv = TRUE; csheet_boni[14].cb[5] |= CB6_RSINV; }
3240 
3241 		if (p_ptr->lev >= 10) { p_ptr->telepathy |= ESP_ANIMAL; csheet_boni[14].cb[7] |= CB8_EANIM; }
3242 		if (p_ptr->lev >= 15) { p_ptr->telepathy |= ESP_ORC; csheet_boni[14].cb[7] |= CB8_EORCS; }
3243 		if (p_ptr->lev >= 20) { p_ptr->telepathy |= ESP_TROLL; csheet_boni[14].cb[7] |= CB8_ETROL; }
3244 		if (p_ptr->lev >= 25) { p_ptr->telepathy |= ESP_GIANT; csheet_boni[14].cb[7] |= CB8_EGIAN; }
3245 		if (p_ptr->lev >= 30) { p_ptr->telepathy |= ESP_DRAGON; csheet_boni[14].cb[8] |= CB9_EDRGN; }
3246 		if (p_ptr->lev >= 40) { p_ptr->telepathy |= ESP_DEMON; csheet_boni[14].cb[8] |= CB9_EDEMN; }
3247 		if (p_ptr->lev >= 50) { p_ptr->telepathy |= ESP_EVIL; csheet_boni[14].cb[9] |= CB10_EEVIL; }
3248 	}
3249 
3250 	/* Draconian (former Dragonrider, Thunderlord) */
3251 	else if (p_ptr->prace == RACE_DRACONIAN) {
3252 		/* not while in mimicried form */
3253 		if (!p_ptr->body_monster) { p_ptr->feather_fall = TRUE; csheet_boni[14].cb[4] |= CB5_RFALL; }
3254 
3255 		if (p_ptr->lev >= 5) { p_ptr->telepathy |= ESP_DRAGON; csheet_boni[14].cb[8] |= CB9_EDRGN; }
3256 #ifndef ENABLE_DRACONIAN_TRAITS
3257 		if (p_ptr->lev >= 10) { p_ptr->resist_fire = TRUE; csheet_boni[14].cb[0] |= CB1_RFIRE; }
3258 		if (p_ptr->lev >= 15) { p_ptr->resist_cold = TRUE; csheet_boni[14].cb[0] |= CB1_RCOLD; }
3259 		if (p_ptr->lev >= 20) { p_ptr->resist_acid = TRUE; csheet_boni[14].cb[1] |= CB2_RACID; }
3260 		if (p_ptr->lev >= 25) { p_ptr->resist_elec = TRUE; csheet_boni[14].cb[0] |= CB1_RELEC; }
3261 #endif
3262 		/* not while in mimicried form */
3263 		if (!p_ptr->body_monster)
3264 		    if (p_ptr->lev >= 30) { p_ptr->levitate = TRUE; csheet_boni[14].cb[6] |= CB7_RRLEV; }
3265 	}
3266 
3267 	/* Dark-Elves */
3268 	else if (p_ptr->prace == RACE_DARK_ELF) {
3269 		p_ptr->suscep_lite = TRUE; csheet_boni[14].cb[1] |= CB2_SLITE;
3270 //		p_ptr->suscep_good = TRUE;//maybe too harsh
3271 		p_ptr->resist_dark = TRUE; csheet_boni[14].cb[2] |= CB3_RDARK;
3272 		if (p_ptr->lev >= 20) { p_ptr->see_inv = TRUE; csheet_boni[14].cb[5] |= CB6_RSINV; }
3273 	}
3274 
3275 	/* Vampires */
3276 	else if (p_ptr->prace == RACE_VAMPIRE) {
3277 		p_ptr->suscep_lite = TRUE; csheet_boni[14].cb[1] |= CB2_SLITE;
3278 		p_ptr->suscep_good = TRUE;
3279 		p_ptr->suscep_life = TRUE;
3280 
3281 		p_ptr->resist_time = TRUE; csheet_boni[14].cb[3] |= CB4_RTIME;
3282 		p_ptr->resist_dark = TRUE; csheet_boni[14].cb[2] |= CB3_RDARK;
3283 		p_ptr->resist_neth = TRUE; csheet_boni[14].cb[3] |= CB4_RNETH;
3284 		p_ptr->resist_pois = TRUE; csheet_boni[14].cb[1] |= CB2_RPOIS;
3285 		p_ptr->hold_life = TRUE; csheet_boni[14].cb[5] |= CB6_RLIFE;
3286 
3287 		p_ptr->reduce_insanity = 1; csheet_boni[14].cb[3] |= CB4_RMIND;
3288 
3289 		if (p_ptr->vampiric_melee < 50) p_ptr->vampiric_melee = 50; /* mimic forms give 50 (50% bite attacks) - 33 was actually pretty ok, for lower levels at least */
3290 		csheet_boni[14].cb[6] |= CB7_RVAMP;
3291 		/* sense surroundings without light source! (virtual lite / dark light) */
3292 		p_ptr->cur_vlite = 1 + p_ptr->lev / 10; csheet_boni[14].lite = 1 + p_ptr->lev / 10;
3293 		csheet_boni[14].cb[12] |= CB13_XLITE;
3294 //		if (p_ptr->lev >= 30) p_ptr->levitate = TRUE; can poly into bat instead
3295 	}
3296 #ifdef ENABLE_MAIA
3297 	else if (p_ptr->prace == RACE_MAIA) {
3298 		//Help em out a little.. (to locate candlebearer/darkling)
3299 		p_ptr->telepathy |= ESP_DEMON; csheet_boni[14].cb[8] |= CB9_EDEMN;
3300 		p_ptr->telepathy |= ESP_GOOD; csheet_boni[14].cb[9] |= CB10_EGOOD;
3301 
3302 		if (p_ptr->ptrait == TRAIT_ENLIGHTENED) {
3303 			if (p_ptr->lev >= 20) csheet_boni[14].cb[5] |= CB6_IFOOD;
3304 			if (p_ptr->lev >= 50)  csheet_boni[14].cb[9] |= CB10_SEVIL;
3305 			p_ptr->suscep_evil = TRUE;
3306 
3307 			p_ptr->see_inv = TRUE; csheet_boni[14].cb[5] |= CB6_RSINV;
3308 			p_ptr->resist_lite = TRUE; csheet_boni[14].cb[2] |= CB3_RLITE;
3309 			if (p_ptr->lev >= 20) {
3310 				p_ptr->cur_lite += 1 + (p_ptr->lev - 20) / 6; csheet_boni[14].lite = 1 + p_ptr->lev / 10; //REAL light!
3311 				csheet_boni[14].cb[12] |= CB13_XLITE;
3312 				lite_inc_white += 1 + (p_ptr->lev - 20) / 6;
3313 				p_ptr->to_a += (p_ptr->lev - 20)/2;
3314 				p_ptr->dis_to_a += (p_ptr->lev - 20)/2;
3315 			}
3316 
3317 			if (p_ptr->lev >= 50) {
3318 				p_ptr->resist_pois = TRUE; csheet_boni[14].cb[1] |= CB2_RPOIS;
3319 				p_ptr->resist_elec = TRUE; csheet_boni[14].cb[0] |= CB1_RELEC;
3320 				p_ptr->sh_elec = TRUE; csheet_boni[14].cb[10] |= CB11_AELEC;
3321 				p_ptr->resist_cold = TRUE; csheet_boni[14].cb[0] |= CB1_RCOLD;
3322 				p_ptr->sh_cold = TRUE; csheet_boni[14].cb[10] |= CB11_ACOLD;
3323 				p_ptr->levitate = TRUE; csheet_boni[14].cb[6] |= CB7_RRLEV;
3324 				p_ptr->feather_fall = TRUE; csheet_boni[14].cb[4] |= CB5_RFALL;
3325 			}
3326 
3327 			/* Bonus resistance for the good side */
3328 			if (p_ptr->divine_xtra_res_time > 0)
3329 				p_ptr->resist_time = TRUE;
3330 		} else if (p_ptr->ptrait == TRAIT_CORRUPTED) {
3331 			if (p_ptr->lev >= 20) csheet_boni[14].cb[5] |= CB6_IFOOD;
3332 			p_ptr->suscep_good = TRUE;
3333 
3334 			p_ptr->resist_fire = TRUE; csheet_boni[14].cb[0] |= CB1_RFIRE;
3335 			p_ptr->resist_dark = TRUE; csheet_boni[14].cb[2] |= CB3_RDARK;
3336 
3337 			if (p_ptr->lev >= 50) {
3338 				p_ptr->resist_pois = TRUE; csheet_boni[14].cb[1] |= CB2_RPOIS;
3339 				p_ptr->immune_fire = TRUE; csheet_boni[14].cb[0] |= CB1_IFIRE;
3340 				p_ptr->sh_fire = p_ptr->sh_fire_fix = TRUE; csheet_boni[14].cb[10] |= CB11_AFIRE;
3341 			}
3342 
3343 			/* Bonus crit for the bad side */
3344 			if (p_ptr->divine_crit > 0)
3345 				p_ptr->xtra_crit = p_ptr->divine_crit_mod;
3346 		} else { p_ptr->slow_digest = TRUE; csheet_boni[14].cb[4] |= CB5_RFOOD; }
3347 	}
3348 #endif
3349 #ifdef ENABLE_KOBOLD
3350 	/* Kobolds */
3351 	else if (p_ptr->prace == RACE_KOBOLD)
3352 		{ p_ptr->resist_pois = TRUE; csheet_boni[14].cb[1] |= CB2_RPOIS; }
3353 #endif
3354 
3355 	/* Apply boni from racial special traits */
3356 	switch (p_ptr->ptrait) {
3357 	case TRAIT_NONE: /* N/A */
3358 	default:
3359 		break;
3360 #ifdef ENABLE_DRACONIAN_TRAITS
3361 	case TRAIT_BLUE: /* Draconic Blue */
3362 		if (p_ptr->lev >= 5) { p_ptr->brand_elec = TRUE; csheet_boni[14].cb[10] |= CB11_BELEC; }
3363 		if (p_ptr->lev >= 15) { p_ptr->sh_elec = TRUE; csheet_boni[14].cb[10] |= CB11_AELEC; }
3364 		if (p_ptr->lev < 25) { p_ptr->resist_elec = TRUE; csheet_boni[14].cb[0] |= CB1_RELEC; }
3365 		else { p_ptr->immune_elec = TRUE; csheet_boni[14].cb[1] |= CB2_IELEC; }
3366 		break;
3367 	case TRAIT_WHITE: /* Draconic White */
3368 		p_ptr->suscep_fire = TRUE; csheet_boni[14].cb[0] |= CB1_SFIRE;
3369 		if (p_ptr->lev >= 15) { p_ptr->sh_cold = TRUE; csheet_boni[14].cb[10] |= CB11_ACOLD; }
3370 		if (p_ptr->lev < 25) { p_ptr->resist_cold = TRUE; csheet_boni[14].cb[0] |= CB1_RCOLD; }
3371 		else { p_ptr->immune_cold = TRUE; csheet_boni[14].cb[0] |= CB1_ICOLD; }
3372 		break;
3373 	case TRAIT_RED: /* Draconic Red */
3374 		p_ptr->suscep_cold = TRUE; csheet_boni[14].cb[0] |= CB1_SCOLD;
3375 		if (p_ptr->lev < 25) { p_ptr->resist_fire = TRUE; csheet_boni[14].cb[0] |= CB1_RFIRE; }
3376 		else { p_ptr->immune_fire = TRUE; csheet_boni[14].cb[0] |= CB1_IFIRE; }
3377 		break;
3378 	case TRAIT_BLACK: /* Draconic Black */
3379 		if (p_ptr->lev < 25) { p_ptr->resist_acid = TRUE; csheet_boni[14].cb[1] |= CB2_RACID; }
3380 		else { p_ptr->immune_acid = TRUE; csheet_boni[14].cb[1] |= CB2_IACID; }
3381 		break;
3382 	case TRAIT_GREEN: /* Draconic Green */
3383 		if (p_ptr->lev < 25) { p_ptr->resist_pois = TRUE; csheet_boni[14].cb[1] |= CB2_RPOIS; }
3384 		else { p_ptr->immune_poison = TRUE; csheet_boni[14].cb[1] |= CB2_IPOIS; }
3385 		break;
3386 	case TRAIT_MULTI: /* Draconic Multi-hued */
3387 		if (p_ptr->lev >= 5) { p_ptr->resist_elec = TRUE; csheet_boni[14].cb[0] |= CB1_RELEC; }
3388 		if (p_ptr->lev >= 10) { p_ptr->resist_cold = TRUE; csheet_boni[14].cb[0] |= CB1_RCOLD; }
3389 		if (p_ptr->lev >= 15) { p_ptr->resist_fire = TRUE; csheet_boni[14].cb[0] |= CB1_RFIRE; }
3390 		if (p_ptr->lev >= 20) { p_ptr->resist_acid = TRUE; csheet_boni[14].cb[1] |= CB2_RACID; }
3391 		if (p_ptr->lev >= 25) { p_ptr->resist_pois = TRUE; csheet_boni[14].cb[1] |= CB2_RPOIS; }
3392 		break;
3393 	case TRAIT_BRONZE: /* Draconic Bronze */
3394 		if (p_ptr->lev >= 5) { p_ptr->resist_conf = TRUE; csheet_boni[14].cb[2] |= CB3_RCONF; }
3395 		if (p_ptr->lev >= 10) { p_ptr->resist_elec = TRUE; csheet_boni[14].cb[0] |= CB1_RELEC; }
3396 		if (p_ptr->lev >= 10) { p_ptr->free_act = TRUE; csheet_boni[14].cb[4] |= CB5_RPARA; }
3397 		if (p_ptr->lev >= 20) { p_ptr->reflect = TRUE; csheet_boni[14].cb[6] |= CB7_RREFL; }
3398 		break;
3399 	case TRAIT_SILVER: /* Draconic Silver */
3400 		if (p_ptr->lev >= 5) { p_ptr->resist_cold = TRUE; csheet_boni[14].cb[0] |= CB1_RCOLD; }
3401 		if (p_ptr->lev >= 10) { p_ptr->resist_acid = TRUE; csheet_boni[14].cb[1] |= CB2_RACID; }
3402 		if (p_ptr->lev >= 15) { p_ptr->resist_pois = TRUE; csheet_boni[14].cb[1] |= CB2_RPOIS; }
3403 		if (p_ptr->lev >= 20) { p_ptr->reflect = TRUE; csheet_boni[14].cb[6] |= CB7_RREFL; }
3404 		break;
3405 	case TRAIT_GOLD: /* Draconic Gold */
3406 		if (p_ptr->lev >= 5) { p_ptr->resist_fire = TRUE; csheet_boni[14].cb[0] |= CB1_RFIRE; }
3407 		if (p_ptr->lev >= 10) { p_ptr->resist_acid = TRUE; csheet_boni[14].cb[1] |= CB2_RACID; }
3408 		if (p_ptr->lev >= 15) { p_ptr->resist_sound = TRUE; csheet_boni[14].cb[2] |= CB3_RSOUN; }
3409 		if (p_ptr->lev >= 20) { p_ptr->reflect = TRUE; csheet_boni[14].cb[6] |= CB7_RREFL; }
3410 		break;
3411 	case TRAIT_LAW: /* Draconic Law */
3412 		if (p_ptr->lev >= 5) { p_ptr->resist_shard = TRUE; csheet_boni[14].cb[2] |= CB3_RSHRD; }
3413 		if (p_ptr->lev >= 10) { p_ptr->free_act = TRUE; csheet_boni[14].cb[4] |= CB5_RPARA; }
3414 		if (p_ptr->lev >= 15) { p_ptr->resist_sound = TRUE; csheet_boni[14].cb[2] |= CB3_RSOUN; }
3415 		break;
3416 	case TRAIT_CHAOS: /* Draconic Chaos */
3417 		if (p_ptr->lev >= 5) { p_ptr->resist_conf = TRUE; csheet_boni[14].cb[2] |= CB3_RCONF; }
3418 		if (p_ptr->lev >= 15) { p_ptr->resist_chaos = TRUE; csheet_boni[14].cb[3] |= CB4_RCHAO; }
3419 		if (p_ptr->lev >= 20) { p_ptr->resist_disen = TRUE; csheet_boni[14].cb[3] |= CB4_RDISE; }
3420 		break;
3421 	case TRAIT_BALANCE: /* Draconic Balance */
3422 		if (p_ptr->lev >= 10) { p_ptr->resist_disen = TRUE; csheet_boni[14].cb[3] |= CB4_RDISE; }
3423 		if (p_ptr->lev >= 20) { p_ptr->resist_sound = TRUE; csheet_boni[14].cb[2] |= CB3_RSOUN; }
3424 		break;
3425 	case TRAIT_POWER: /* Draconic Power */
3426 		p_ptr->resist_fear = TRUE; csheet_boni[14].cb[4] |= CB5_RFEAR;
3427 		if (p_ptr->lev >= 5) { p_ptr->resist_blind = TRUE; csheet_boni[14].cb[4] |= CB5_RBLND; }
3428 		if (p_ptr->lev >= 20) { p_ptr->reflect = TRUE; csheet_boni[14].cb[6] |= CB7_RREFL; }
3429 		break;
3430 #endif
3431 	}
3432 
3433 	if (p_ptr->pclass == CLASS_RANGER) {
3434 		if (p_ptr->lev >= 15) { p_ptr->pass_trees = TRUE; csheet_boni[14].cb[12] |= CB13_XTREE; }
3435 		if (p_ptr->lev >= 25) { p_ptr->can_swim = TRUE; csheet_boni[14].cb[12] |= CB13_XSWIM; }
3436 	}
3437 
3438 	if (p_ptr->pclass == CLASS_SHAMAN)
3439 		if (p_ptr->lev >= 20) { p_ptr->see_inv = TRUE; csheet_boni[14].cb[5] |= CB6_RSINV; }
3440 
3441 	if (p_ptr->pclass == CLASS_DRUID)
3442 		if (p_ptr->lev >= 10) { p_ptr->pass_trees = TRUE; csheet_boni[14].cb[12] |= CB13_XTREE; }
3443 
3444 	if (p_ptr->pclass == CLASS_MINDCRAFTER) {
3445 		if (p_ptr->lev >= 20) { p_ptr->reduce_insanity = 2; csheet_boni[14].cb[3] |= CB4_RMIND; }
3446 		else if (p_ptr->lev >= 10) { p_ptr->reduce_insanity = 1; csheet_boni[14].cb[3] |= CB4_RMIND; }
3447 	}
3448 
3449 
3450 	/* Check ability skills */
3451 	if (get_skill(p_ptr, SKILL_CLIMB) >= 1) { p_ptr->climb = TRUE; csheet_boni[14].cb[6] |= CB7_RCLMB; }
3452 	if (get_skill(p_ptr, SKILL_LEVITATE) >= 1) {
3453 		p_ptr->levitate = TRUE; csheet_boni[14].cb[6] |= CB7_RRLEV;
3454 		p_ptr->feather_fall = TRUE; csheet_boni[14].cb[4] |= CB5_RFALL;
3455 	}
3456 	if (get_skill(p_ptr, SKILL_FREEACT) >= 1) { p_ptr->free_act = TRUE; csheet_boni[14].cb[4] |= CB5_RPARA; }
3457 	if (get_skill(p_ptr, SKILL_RESCONF) >= 1) { p_ptr->resist_conf = TRUE; csheet_boni[14].cb[2] |= CB3_RCONF; }
3458 
3459 
3460 	/* Compute antimagic */
3461 	if (get_skill(p_ptr, SKILL_ANTIMAGIC)) {
3462 //		p_ptr->anti_magic = TRUE;	/* it means 95% saving-throw!! */
3463 #ifdef NEW_ANTIMAGIC_RATIO
3464 		p_ptr->antimagic += get_skill_scale(p_ptr, SKILL_ANTIMAGIC, 50); csheet_boni[14].amfi += get_skill_scale(p_ptr, SKILL_ANTIMAGIC, 50);
3465 		p_ptr->antimagic_dis += 1 + (get_skill(p_ptr, SKILL_ANTIMAGIC) / 10); /* was /11, but let's reward max skill! */
3466 #else
3467 		p_ptr->antimagic += get_skill_scale(p_ptr, SKILL_ANTIMAGIC, 30); csheet_boni[14].amfi += get_skill_scale(p_ptr, SKILL_ANTIMAGIC, 30);
3468 		p_ptr->antimagic_dis += 1 + (get_skill(p_ptr, SKILL_ANTIMAGIC) / 10); /* was /11, but let's reward max skill! */
3469 #endif
3470 	}
3471 
3472 	/* Ghost */
3473 	if (p_ptr->ghost) {
3474 		p_ptr->see_inv = TRUE; csheet_boni[14].cb[5] |= CB6_RSINV;
3475 		/* p_ptr->resist_neth = TRUE;
3476 		p_ptr->hold_life = TRUE; */
3477 		p_ptr->free_act = TRUE; csheet_boni[14].cb[4] |= CB5_RPARA;
3478 		p_ptr->see_infra += 3; csheet_boni[14].infr += 3;
3479 		p_ptr->resist_dark = TRUE; csheet_boni[14].cb[2] |= CB3_RDARK;
3480 		p_ptr->resist_blind = TRUE; csheet_boni[14].cb[4] |= CB5_RBLND;
3481 		p_ptr->immune_poison = TRUE; csheet_boni[14].cb[1] |= CB2_IPOIS;
3482 		p_ptr->resist_cold = TRUE; csheet_boni[14].cb[0] |= CB1_RCOLD;
3483 		p_ptr->resist_fear = TRUE; csheet_boni[14].cb[4] |= CB5_RFEAR;
3484 		p_ptr->resist_conf = TRUE; csheet_boni[14].cb[2] |= CB3_RCONF;
3485 		p_ptr->no_cut = TRUE; csheet_boni[14].cb[12] |= CB13_XNCUT;
3486 		p_ptr->reduce_insanity = 1; csheet_boni[14].cb[3] |= CB4_RMIND;
3487 		p_ptr->levitate = TRUE; csheet_boni[14].cb[6] |= CB7_RRLEV; /* redundant */
3488 		p_ptr->feather_fall = TRUE; csheet_boni[14].cb[4] |= CB5_RFALL;
3489 		/*p_ptr->tim_wraith = 30000; redundant*/
3490 //		p_ptr->invis += 5; */ /* No. */
3491 	}
3492 
3493 	/* Hack -- apply racial/class stat maxes */
3494 	if (p_ptr->maximize) {
3495 		/* Apply the racial modifiers */
3496 		for (i = 0; i < 6; i++) {
3497 			/* Modify the stats for "race" */
3498 			/* yeek mimic no longer rocks too much */
3499 //			if (!p_ptr->body_monster) p_ptr->stat_add[i] += (p_ptr->rp_ptr->r_adj[i]);
3500 //done in calc_body_bonus()!			p_ptr->stat_add[i] += (p_ptr->rp_ptr->r_adj[i]) * 3 / (p_ptr->body_monster ? 4 : 3);
3501 			p_ptr->stat_add[i] += p_ptr->rp_ptr->r_adj[i];
3502 			p_ptr->stat_add[i] += p_ptr->cp_ptr->c_adj[i];
3503 		}
3504 	}
3505 
3506 	/* Apply the racial modifiers */
3507 	if (p_ptr->mode & MODE_HARD) {
3508 		for (i = 0; i < 6; i++) {
3509 			/* Modify the stats for "race" */
3510 			p_ptr->stat_add[i]--;
3511 		}
3512 	}
3513 
3514 
3515 	/* Hack -- the dungeon master gets +50 speed. */
3516 	if (p_ptr->admin_dm) {
3517 		p_ptr->pspeed += 50; //csheet_boni[14].spd += 50; //Don't show these for the admin/tester
3518 		p_ptr->telepathy |= ESP_ALL;
3519 		/* Flag all the ESPs for ESP_ALL */
3520 		//csheet_boni[14].cb[7] |= (CB8_ESPID | CB8_EANIM | CB8_EORCS | CB8_ETROL | CB8_EGIAN);
3521 		//csheet_boni[14].cb[8] |= (CB9_EDRGN | CB9_EDEMN | CB9_EUNDD);
3522 		//csheet_boni[14].cb[9] |= (CB10_EEVIL | CB10_EDGRI | CB10_EGOOD | CB10_ENONL | CB10_EUNIQ);
3523 	}
3524 
3525 	/* Hack -- recalculate inventory weight and count */
3526 	p_ptr->total_weight = 0;
3527 	p_ptr->inven_cnt = 0;
3528 
3529 	for (i = 0; i < INVEN_PACK; i++) {
3530 		o_ptr = &p_ptr->inventory[i];
3531 
3532 		/* Skip missing items */
3533 		if (!o_ptr->k_idx) break;
3534 
3535 		p_ptr->inven_cnt++;
3536 		p_ptr->total_weight += o_ptr->weight * o_ptr->number;
3537 	}
3538 
3539 	/* Apply the bonus from Druidism */
3540 	p_ptr->to_h += p_ptr->focus_val;
3541 	p_ptr->dis_to_h += p_ptr->focus_val;
3542 
3543 	p_ptr->to_h_ranged += p_ptr->focus_val;
3544 	p_ptr->dis_to_h_ranged += p_ptr->focus_val;
3545 
3546 	/* Scan the usable inventory */
3547 	for (i = INVEN_WIELD; i < INVEN_TOTAL; i++) {
3548 		o_ptr = &p_ptr->inventory[i];
3549 		k_ptr = &k_info[o_ptr->k_idx];
3550 		pval = o_ptr->pval;
3551 
3552 		/* Skip missing items */
3553 		if (!o_ptr->k_idx) {
3554 			csheet_boni[i-INVEN_WIELD].cb[12] |= CB13_XNOEQ; //Nothing equipped, grey out the table column
3555 			continue;
3556 		}
3557 
3558 		/* Set item display info */
3559 		csheet_boni[i-INVEN_WIELD].color = k_info[o_ptr->k_idx].d_attr;
3560 		csheet_boni[i-INVEN_WIELD].symbol = k_info[o_ptr->k_idx].d_char;
3561 
3562 		/* Special admin items */
3563 		if (o_ptr->tval == TV_AMULET) {
3564 			switch (o_ptr->sval) {
3565 			case SV_AMULET_INVINCIBILITY:
3566 				p_ptr->admin_invinc = TRUE;
3567 				/* fall through */
3568 			case SV_AMULET_INVULNERABILITY:
3569 				p_ptr->admin_invuln = TRUE;
3570 			}
3571 		}
3572 
3573 #ifdef EQUIPMENT_SET_BONUS
3574 		if (o_ptr->name1 == ART_RANDART) {
3575 			/* paranoia maybe? Make sure name4 field has been set: */
3576 			randart_name(o_ptr, tmp_name, tmp_name);
3577 			/* compare */
3578 			for (j = 0; j < i - INVEN_WIELD; j++)
3579 				if (equipment_set[j] == o_ptr->name4 + 1) {
3580 					equipment_set_amount[j]++;
3581 					break;
3582 				} else if (!strcmp(equipment_set_name[j], tmp_name)) {
3583 					equipment_set_amount[j]++;
3584 					/* for faster randart handling in future loop passes (pft) */
3585 					equipment_set[j] = o_ptr->name4 + 1;
3586 					break;
3587 				}
3588 			if (j == i - INVEN_WIELD) {
3589 				equipment_set[j] = o_ptr->name4 + 1;
3590 				equipment_set_amount[j] = 1;
3591 				/* and for true arts: */
3592 				strcpy(equipment_set_name[j], tmp_name);
3593 			}
3594 		} else if (o_ptr->name1) {
3595 			strcpy(tmp_name, a_name + a_info[o_ptr->name1].name);
3596 			tmp_name_ptr = tmp_name;
3597 			/* trim leading and terminating ' characters */
3598 			if (tmp_name[0] == '\'') {
3599 				tmp_name_ptr++;
3600 				tmp_name[strlen(tmp_name_ptr)] = 0;
3601 			/* trim leading "of " */
3602 			} else if (tmp_name[0] == 'o' && tmp_name[1] == 'f' && tmp_name[2] == ' ')
3603 				tmp_name_ptr += 3;
3604 #if 1
3605 			/* maybe: strip 'the' too */
3606 			if (tmp_name_ptr[0] == 't' && tmp_name_ptr[1] == 'h' && tmp_name_ptr[2] == 'e' && tmp_name_ptr[3] == ' ')
3607 				tmp_name_ptr += 4;
3608 #endif
3609 			/* compare */
3610 			for (j = 0; j < i - INVEN_WIELD; j++)
3611 				if (!strcmp(equipment_set_name[j], tmp_name_ptr)) {
3612 					equipment_set_amount[j]++;
3613 					break;
3614 				}
3615 			if (j == i - INVEN_WIELD) {
3616 				strcpy(equipment_set_name[j], tmp_name_ptr);
3617 				equipment_set_amount[j] = 1;
3618 				/* enable (use -1 since true arts don't use randart codes) */
3619 				equipment_set[j] = -1;
3620 			}
3621 		}
3622 #endif
3623 
3624 		p_ptr->total_weight += o_ptr->weight * o_ptr->number;
3625 
3626 		/* Extract the item flags */
3627 		object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &f6, &esp);
3628 
3629 		/* Note cursed/hidden status... */
3630 		if ((f3 & TR3_CURSED) || (f3 & TR3_HEAVY_CURSE) || (f3 & TR3_PERMA_CURSE)) csheet_boni[i-INVEN_WIELD].cb[12] |= CB13_XCRSE;
3631 		if (!object_fully_known_p(Ind, o_ptr) && !(o_ptr->tval == TV_SWORD && o_ptr->sval == SV_DARK_SWORD)) csheet_boni[i-INVEN_WIELD].cb[11] |= CB12_XHIDD;
3632 
3633 		/* Not-burning light source does nothing, good or bad */
3634 		if ((f4 & TR4_FUEL_LITE) && (o_ptr->timeout < 1)) continue;
3635 
3636 		/* Anti-Cheeze (DWing in MH mode on heavy armoured warriors):
3637 		   Dual-wielding won't apply the second weapon if encumbered */
3638 		if (i == INVEN_ARM && o_ptr->tval != TV_SHIELD && rogue_heavy_armor(p_ptr)) continue;
3639 
3640 		/* MEGA ugly hack -- set spacetime distortion resistance */
3641 		if (o_ptr->name1 == ART_ANCHOR) {
3642 			p_ptr->resist_continuum = TRUE;
3643 		}
3644 #if 0
3645 		/* another bad hack, for when Morgoth's crown gets its pval
3646 		   reduced experimentally, to keep massive +IV (for Q-quests^^): */
3647 		if (o_ptr->name1 == ART_MORGOTH) {
3648 			p_ptr->see_infra += 50;
3649 		}
3650 #endif
3651 
3652 		/* Hack -- first add any "base bonuses" of the item.  A new
3653 		 * feature in MAngband 0.7.0 is that the magnitude of the
3654 		 * base bonuses is stored in bpval instead of pval, making the
3655 		 * magnitude of "base bonuses" and "ego bonuses" independent
3656 		 * from each other.
3657 		 * An example of an item that uses this independency is an
3658 		 * Orcish Shield of the Avari that gives +1 to STR and +3 to
3659 		 * CON. (base bonus from the shield +1 STR,CON, ego bonus from
3660 		 * the Avari +2 CON).
3661 		 * Of course, the proper fix would be to redesign the object
3662 		 * type so that each of the ego bonuses has its own independent
3663 		 * parameter.
3664 		 */
3665 		/* If we have any base bonuses to add, add them */
3666 		if (k_ptr->flags1 & TR1_PVAL_MASK) {
3667 			/* Affect stats */
3668 			if (k_ptr->flags1 & TR1_STR) { p_ptr->stat_add[A_STR] += o_ptr->bpval; csheet_boni[i-INVEN_WIELD].pstr += o_ptr->bpval; }
3669 			if (k_ptr->flags1 & TR1_INT) { p_ptr->stat_add[A_INT] += o_ptr->bpval; csheet_boni[i-INVEN_WIELD].pint += o_ptr->bpval; }
3670 			if (k_ptr->flags1 & TR1_WIS) { p_ptr->stat_add[A_WIS] += o_ptr->bpval; csheet_boni[i-INVEN_WIELD].pwis += o_ptr->bpval; }
3671 			if (k_ptr->flags1 & TR1_DEX) { p_ptr->stat_add[A_DEX] += o_ptr->bpval; csheet_boni[i-INVEN_WIELD].pdex += o_ptr->bpval; }
3672 			if (k_ptr->flags1 & TR1_CON) { p_ptr->stat_add[A_CON] += o_ptr->bpval; csheet_boni[i-INVEN_WIELD].pcon += o_ptr->bpval; }
3673 			if (k_ptr->flags1 & TR1_CHR) { p_ptr->stat_add[A_CHR] += o_ptr->bpval; csheet_boni[i-INVEN_WIELD].pchr += o_ptr->bpval; }
3674 
3675 			/* Affect stealth */
3676 			if (k_ptr->flags1 & TR1_STEALTH) { p_ptr->skill_stl += o_ptr->bpval; csheet_boni[i-INVEN_WIELD].slth += o_ptr->bpval; }
3677 			/* Affect searching ability (factor of five) */
3678 			if (k_ptr->flags1 & TR1_SEARCH) { p_ptr->skill_srh += (o_ptr->bpval * 5); csheet_boni[i-INVEN_WIELD].srch += o_ptr->bpval; }
3679 			/* Affect searching frequency (factor of five) */
3680 			if (k_ptr->flags1 & TR1_SEARCH) p_ptr->skill_fos += (o_ptr->bpval * 3);
3681 			/* Affect infravision */
3682 			if (k_ptr->flags1 & TR1_INFRA) { p_ptr->see_infra += o_ptr->bpval; csheet_boni[i-INVEN_WIELD].infr += o_ptr->bpval; }
3683 
3684 			/* Affect digging (factor of 20) */
3685 			if (k_ptr->flags1 & TR1_TUNNEL) { p_ptr->skill_dig += (o_ptr->bpval * 20); csheet_boni[i-INVEN_WIELD].dig += o_ptr->bpval; }
3686 
3687 			/* Affect speed */
3688 			if (k_ptr->flags1 & TR1_SPEED) { p_ptr->pspeed += o_ptr->bpval; csheet_boni[i-INVEN_WIELD].spd += o_ptr->bpval; }
3689 
3690 			/* Affect blows */
3691 #if 1 /* for dual-wield this is too much, it's done in calc_blows_obj() now */
3692 /* There are no known weapons so far that adds bpr intrinsically. Need this for e.g., ring of EA */
3693 			if (k_ptr->flags1 & TR1_BLOWS) { p_ptr->extra_blows += o_ptr->bpval; csheet_boni[i-INVEN_WIELD].blow += o_ptr->bpval; }
3694 #endif
3695 			/* Affect spells */
3696 			if (k_ptr->flags1 & TR1_SPELL) extra_spells += o_ptr->bpval;
3697 //			if (k_ptr->flags1 & TR1_SPELL_SPEED) extra_spells += o_ptr->bpval;
3698 
3699 			/* Affect mana capacity */
3700 			if (f1 & (TR1_MANA)) {
3701 				if ((f4 & TR4_SHOULD2H) &&
3702 				    (p_ptr->inventory[INVEN_WIELD].k_idx && p_ptr->inventory[INVEN_ARM].k_idx))
3703 					{ p_ptr->to_m += (o_ptr->bpval * 20) / 3; csheet_boni[i-INVEN_WIELD].mxmp += o_ptr->bpval; }
3704 				else
3705 					{ p_ptr->to_m += o_ptr->bpval * 10; csheet_boni[i-INVEN_WIELD].mxmp += o_ptr->bpval; }
3706 			}
3707 
3708 			/* Affect life capacity */
3709 			if ((f1 & (TR1_LIFE)) &&
3710 			    ((o_ptr->name1 != ART_RANDART) ||
3711 			    (make_resf(p_ptr) & RESF_LIFE) ||
3712 			    o_ptr->bpval < 0))
3713 				{ p_ptr->to_l += o_ptr->bpval; csheet_boni[i-INVEN_WIELD].mxhp += o_ptr->bpval; }
3714 		}
3715 
3716 		if (k_ptr->flags5 & TR5_PVAL_MASK) {
3717 			if (f5 & TR5_DISARM) p_ptr->skill_dis += (o_ptr->bpval) * 5;
3718 			if (f5 & TR5_LUCK) { p_ptr->luck += o_ptr->bpval; csheet_boni[i-INVEN_WIELD].luck += o_ptr->bpval; }
3719 #if 1 /* this is too much for dual-wield, done in calc_blows_obj() now */
3720 /* There are no known weapons so far that adds to crit intrinsically. */
3721 			if (f5 & TR5_CRIT) { p_ptr->xtra_crit += o_ptr->bpval; csheet_boni[i-INVEN_WIELD].crit += o_ptr->bpval; }
3722 #endif
3723 		}
3724 
3725 		/* bad hack for certain double-egos, sorry. need redesign of boni - C. Blue
3726 		    *** deprecated, because VAMPIRIC no longer gives -LIFE ***
3727 		   fixes the vampiric shadow blade bug / affects all -life +basestealth weapons:
3728 		   (+2)(-2stl) -> life remains unchanged, stealth is increased by 2:
3729 		   both mods affect the life! Correct mod affects the stealth, but it's displayed wrong.
3730 		   pval should contain life bonus, bpval stealth. */
3731 /*		if (o_ptr->name2 == EGO_VAMPIRIC || o_ptr->name2b == EGO_VAMPIRIC)	*/
3732 		if ((f1 & (TR1_LIFE)) && o_ptr->pval != 0 && o_ptr->bpval != 0) {
3733 			/* first we remove both effects on +LIFE */
3734 			p_ptr->to_l -= o_ptr->pval + o_ptr->bpval;
3735 			/* then we add the correct one, which is the wrong one ;) */
3736 /*			if (o_ptr->pval < 0) p_ptr->to_l += o_ptr->pval;
3737 			if (o_ptr->bpval < 0) p_ptr->to_l += o_ptr->bpval;		*/
3738 			p_ptr->to_l += o_ptr->pval;
3739 		}
3740 
3741 		/* Next, add our ego bonuses */
3742 		/* Hack -- clear out any pval bonuses that are in the base item
3743 		 * bonus but not the ego bonus so we don't add them twice.
3744 		*/
3745 #if 1
3746 //		if (o_ptr->name2 && o_ptr->tval != TV_RING) // pls see apply_magic ;)
3747 		if (o_ptr->name2) {
3748 			artifact_type *a_ptr;
3749 
3750 			a_ptr =	ego_make(o_ptr);
3751 			f1 &= ~(k_ptr->flags1 & TR1_PVAL_MASK & ~a_ptr->flags1);
3752 			f5 &= ~(k_ptr->flags5 & TR5_PVAL_MASK & ~a_ptr->flags5);
3753 
3754 			/* Hack: Stormbringer! */
3755 			if (o_ptr->name2 == EGO_STORMBRINGER) {
3756 				p_ptr->stormbringer = TRUE;
3757 				break_cloaking(Ind, 0);
3758 				break_shadow_running(Ind);
3759 				if (cfg.use_pk_rules == PK_RULES_DECLARE) {
3760 #ifndef KURZEL_PK
3761 					p_ptr->pkill |= PKILL_KILLABLE;
3762 					if (!(p_ptr->pkill & PKILL_KILLER) &&
3763 							!(p_ptr->pkill & PKILL_SET))
3764 						set_pkill(Ind, 50);
3765 #else
3766 					p_ptr->pkill |= PKILL_SET; //Flag ON
3767 #endif
3768 				}
3769 			}
3770 		}
3771 
3772 		if (o_ptr->name1 == ART_RANDART) {
3773 			artifact_type *a_ptr;
3774 
3775 			a_ptr =	randart_make(o_ptr);
3776 			f1 &= ~(k_ptr->flags1 & TR1_PVAL_MASK & ~a_ptr->flags1);
3777 			f5 &= ~(k_ptr->flags5 & TR5_PVAL_MASK & ~a_ptr->flags5);
3778 		}
3779 #endif
3780 
3781 
3782 		/* Affect stats */
3783 		if (f1 & TR1_STR) { p_ptr->stat_add[A_STR] += pval; csheet_boni[i-INVEN_WIELD].pstr += pval; }
3784 		if (f1 & TR1_INT) { p_ptr->stat_add[A_INT] += pval; csheet_boni[i-INVEN_WIELD].pint += pval; }
3785 		if (f1 & TR1_WIS) { p_ptr->stat_add[A_WIS] += pval; csheet_boni[i-INVEN_WIELD].pwis += pval; }
3786 		if (f1 & TR1_DEX) { p_ptr->stat_add[A_DEX] += pval; csheet_boni[i-INVEN_WIELD].pdex += pval; }
3787 		if (f1 & TR1_CON) { p_ptr->stat_add[A_CON] += pval; csheet_boni[i-INVEN_WIELD].pcon += pval; }
3788 		if (f1 & TR1_CHR) { p_ptr->stat_add[A_CHR] += pval; csheet_boni[i-INVEN_WIELD].pchr += pval; }
3789 
3790 		/* Affect luck */
3791 		if (f5 & (TR5_LUCK)) { p_ptr->luck += pval; csheet_boni[i-INVEN_WIELD].luck += pval; }
3792 
3793 		/* Affect spell power */
3794 //		if (f1 & (TR1_SPELL)) p_ptr->to_s += pval;
3795 
3796 		/* Affect mana capacity */
3797 		if (f1 & (TR1_MANA)) {
3798 			if ((f4 & TR4_SHOULD2H) &&
3799 			    (p_ptr->inventory[INVEN_WIELD].k_idx && p_ptr->inventory[INVEN_ARM].k_idx))
3800 				{ p_ptr->to_m += (pval * 20) / 3; csheet_boni[i-INVEN_WIELD].mxmp += pval; }
3801 			else
3802 				{ p_ptr->to_m += pval * 10; csheet_boni[i-INVEN_WIELD].mxmp += pval; }
3803 		}
3804 
3805 		/* Affect life capacity */
3806 		if ((f1 & (TR1_LIFE)) &&
3807 		    (o_ptr->name1 != ART_RANDART ||
3808 		    (make_resf(p_ptr) & RESF_LIFE) ||
3809 		    o_ptr->pval < 0))
3810 			{ p_ptr->to_l += o_ptr->pval; csheet_boni[i-INVEN_WIELD].mxhp += o_ptr->pval; }
3811 
3812 		/* Affect stealth */
3813 		if (f1 & TR1_STEALTH) { p_ptr->skill_stl += pval; csheet_boni[i-INVEN_WIELD].slth += pval; }
3814 		/* Affect searching ability (factor of five) */
3815 		if (f1 & TR1_SEARCH) { p_ptr->skill_srh += (pval * 5); csheet_boni[i-INVEN_WIELD].srch += pval; }
3816 		/* Affect searching frequency (factor of five) */
3817 		if (f1 & TR1_SEARCH) p_ptr->skill_fos += (pval * 3);
3818 		/* Affect infravision */
3819 		if (f1 & TR1_INFRA) { p_ptr->see_infra += pval; csheet_boni[i-INVEN_WIELD].infr += pval; }
3820 
3821 		/* Affect digging (factor of 20) */
3822 		if (f1 & TR1_TUNNEL) { p_ptr->skill_dig += (pval * 20); csheet_boni[i-INVEN_WIELD].dig += pval; }
3823 
3824 		/* Affect speed */
3825 		if (f1 & TR1_SPEED) { p_ptr->pspeed += pval; csheet_boni[i-INVEN_WIELD].spd += pval; }
3826 
3827 		/* Affect spellss */
3828 //		if (f1 & TR1_SPELL_SPEED) extra_spells += pval;
3829 		if (f1 & TR1_SPELL) extra_spells += pval;
3830 
3831 		/* Affect disarming (factor of 20) */
3832 		if (f5 & (TR5_DISARM)) p_ptr->skill_dis += pval * 5;
3833 
3834 		/* Hack -- Sensible */
3835 /* not yet implemented
3836 		if (f5 & (TR5_SENS_FIRE)) p_ptr->suscep_fire = TRUE;
3837 		if (f5 & (TR6_SENS_COLD)) p_ptr->suscep_cold = TRUE;
3838 		if (f5 & (TR6_SENS_ELEC)) p_ptr->suscep_elec = TRUE;
3839 		if (f5 & (TR6_SENS_ACID)) p_ptr->suscep_acid = TRUE;
3840 		if (f5 & (TR6_SENS_POIS)) p_ptr->suscep_acid = TRUE; */
3841 
3842 		/* Boost shots */
3843 //		if (f3 & TR3_KNOWLEDGE) p_ptr->auto_id = TRUE;
3844 		if (f4 & TR4_AUTO_ID) { p_ptr->auto_id = TRUE; csheet_boni[i-INVEN_WIELD].cb[6] |= CB7_RIDNT; }
3845 
3846 		/* Boost shots */
3847 		if (f3 & TR3_XTRA_SHOTS) { extra_shots++; csheet_boni[i-INVEN_WIELD].shot++; }
3848 
3849 		/* Make the 'useless' curses interesting >:) - C. Blue */
3850 		if ((f3 & TR3_TY_CURSE) && (o_ptr->ident & ID_CURSED)) p_ptr->ty_curse = TRUE;
3851 		if ((f4 & TR4_DG_CURSE) && (o_ptr->ident & ID_CURSED)) p_ptr->dg_curse = TRUE;
3852 
3853 		/* Various flags */
3854 		if (f3 & TR3_AGGRAVATE) {
3855 			p_ptr->aggravate = TRUE; csheet_boni[i-INVEN_WIELD].cb[6] |= CB7_RAGGR;
3856 			break_cloaking(Ind, 0);
3857 		}
3858 //		if (f3 & TR3_TELEPORT) p_ptr->teleport = TRUE;
3859 		if (f3 & TR3_TELEPORT) {
3860 			p_ptr->teleport = TRUE; csheet_boni[i-INVEN_WIELD].cb[4] |= CB5_STELE;
3861 			//inscription = (unsigned char *) quark_str(o_ptr->note);
3862 			inscription = quark_str(p_ptr->inventory[i].note);
3863 			/* check for a valid inscription */
3864 			if ((inscription != NULL) && (!(o_ptr->ident & ID_CURSED))) {
3865 				/* scan the inscription for .. */
3866 				while (*inscription != '\0') {
3867 					if (*inscription == '.') {
3868 						inscription++;
3869 						/* a valid .. has been located */
3870 						if (*inscription == '.') {
3871 							inscription++;
3872 							p_ptr->teleport = FALSE; csheet_boni[i-INVEN_WIELD].cb[4] &= (~CB5_STELE);
3873 							break;
3874 						}
3875 					}
3876 					inscription++;
3877 				}
3878 			}
3879 		}
3880 		if (f3 & TR3_DRAIN_EXP) p_ptr->drain_exp++;
3881 		if (f5 & (TR5_DRAIN_MANA)) { p_ptr->drain_mana++; csheet_boni[i-INVEN_WIELD].cb[5] |= CB6_SRGMP; }
3882 		if (f5 & (TR5_DRAIN_HP)) { p_ptr->drain_life++; csheet_boni[i-INVEN_WIELD].cb[5] |= CB6_SRGHP; }
3883 		if (f5 & (TR5_INVIS)) {
3884 			j = (p_ptr->lev > 50 ? 50 : p_ptr->lev) * 4 / 5;
3885 			/* better than invis from monster form we're using? */
3886 			if (j > p_ptr->tim_invis_power) p_ptr->tim_invis_power = j;
3887 			csheet_boni[i-INVEN_WIELD].cb[6] |= CB7_RINVS;
3888 		}
3889 		if (f3 & TR3_BLESSED) p_ptr->bless_blade = TRUE;
3890 		if (f3 & TR3_XTRA_MIGHT) { p_ptr->xtra_might++; csheet_boni[i-INVEN_WIELD].migh++; }
3891 		if (f3 & TR3_SLOW_DIGEST) { p_ptr->slow_digest = TRUE; csheet_boni[i-INVEN_WIELD].cb[4] |= CB5_RFOOD; }
3892 		if (f3 & TR3_REGEN) { p_ptr->regenerate = TRUE; csheet_boni[i-INVEN_WIELD].cb[5] |= CB6_RRGHP; }
3893 		if (f5 & TR5_RES_PLASMA) { p_ptr->resist_plasma = TRUE; csheet_boni[i-INVEN_WIELD].cb[2] |= CB3_RPLAS; }
3894 		if (f5 & TR5_RES_TIME) { p_ptr->resist_time = TRUE; csheet_boni[i-INVEN_WIELD].cb[3] |= CB4_RTIME; }
3895 		if (f5 & TR5_RES_MANA) { p_ptr->resist_mana = TRUE; csheet_boni[i-INVEN_WIELD].cb[3] |= CB4_RMANA; }
3896 		if (f5 & TR5_IM_POISON) { p_ptr->immune_poison = TRUE; csheet_boni[i-INVEN_WIELD].cb[1] |= CB2_IPOIS; }
3897 		if (f5 & TR5_IM_WATER) { p_ptr->immune_water = TRUE; csheet_boni[i-INVEN_WIELD].cb[2] |= CB3_IWATR; }
3898 		if (f5 & TR5_RES_WATER) { p_ptr->resist_water = TRUE; csheet_boni[i-INVEN_WIELD].cb[2] |= CB3_RWATR; }
3899 		if (f5 & TR5_PASS_WATER) { p_ptr->can_swim = TRUE; csheet_boni[i-INVEN_WIELD].cb[12] |= CB13_XSWIM; }
3900 		if (f5 & TR5_REGEN_MANA) { p_ptr->regen_mana = TRUE; csheet_boni[i-INVEN_WIELD].cb[5] |= CB6_RRGMP; }
3901 		if (esp) {
3902 			p_ptr->telepathy |= esp;
3903 			/* Flag all the ESPs for ESP_ALL */
3904 			if (esp & ESP_ALL) {
3905 				csheet_boni[i-INVEN_WIELD].cb[7] |= (CB8_ESPID | CB8_EANIM | CB8_EORCS | CB8_ETROL | CB8_EGIAN);
3906 				csheet_boni[i-INVEN_WIELD].cb[8] |= (CB9_EDRGN | CB9_EDEMN | CB9_EUNDD);
3907 				csheet_boni[i-INVEN_WIELD].cb[9] |= (CB10_EEVIL | CB10_EDGRI | CB10_EGOOD | CB10_ENONL | CB10_EUNIQ);
3908 			} else {
3909 				if (esp & ESP_SPIDER) csheet_boni[i-INVEN_WIELD].cb[7] |= CB8_ESPID;
3910 				if (esp & ESP_ANIMAL) csheet_boni[i-INVEN_WIELD].cb[7] |= CB8_EANIM;
3911 				if (esp & ESP_ORC) csheet_boni[i-INVEN_WIELD].cb[7] |= CB8_EORCS;
3912 				if (esp & ESP_TROLL) csheet_boni[i-INVEN_WIELD].cb[7] |= CB8_ETROL;
3913 				if (esp & ESP_GIANT) csheet_boni[i-INVEN_WIELD].cb[7] |= CB8_EGIAN;
3914 				if (esp & ESP_DRAGON) csheet_boni[i-INVEN_WIELD].cb[8] |= CB9_EDRGN;
3915 				if (esp & ESP_DEMON) csheet_boni[i-INVEN_WIELD].cb[8] |= CB9_EDEMN;
3916 				if (esp & ESP_UNDEAD) csheet_boni[i-INVEN_WIELD].cb[8] |= CB9_EUNDD;
3917 				if (esp & ESP_EVIL) csheet_boni[i-INVEN_WIELD].cb[9] |= CB10_EEVIL;
3918 				if (esp & ESP_DRAGONRIDER) csheet_boni[i-INVEN_WIELD].cb[9] |= CB10_EDGRI;
3919 				if (esp & ESP_GOOD) csheet_boni[i-INVEN_WIELD].cb[9] |= CB10_EGOOD;
3920 				if (esp & ESP_NONLIVING) csheet_boni[i-INVEN_WIELD].cb[9] |= CB10_ENONL;
3921 				if (esp & ESP_UNIQUE) csheet_boni[i-INVEN_WIELD].cb[9] |= CB10_EUNIQ;
3922 			}
3923 		}
3924 //		if (f3 & TR3_TELEPATHY) p_ptr->telepathy = TRUE;
3925 //		if (f3 & TR3_LITE1) p_ptr->lite += 1;
3926 		if (f3 & TR3_SEE_INVIS) { p_ptr->see_inv = TRUE; csheet_boni[i-INVEN_WIELD].cb[5] |= CB6_RSINV; }
3927 		if (f3 & TR3_FEATHER) { p_ptr->feather_fall = TRUE; csheet_boni[i-INVEN_WIELD].cb[4] |= CB5_RFALL; }
3928 		if (f2 & TR2_FREE_ACT) { p_ptr->free_act = TRUE; csheet_boni[i-INVEN_WIELD].cb[4] |= CB5_RPARA; }
3929 		if (f2 & TR2_HOLD_LIFE) { p_ptr->hold_life = TRUE; csheet_boni[i-INVEN_WIELD].cb[5] |= CB6_RLIFE; }
3930 
3931 		/* Light(consider doing it on calc_torch) */
3932 //		if (((f4 & TR4_FUEL_LITE) && (o_ptr->timeout > 0)) || (!(f4 & TR4_FUEL_LITE)))
3933 		{
3934 			j = 0;
3935 			if (f3 & TR3_LITE1) j++;
3936 			if (f4 & TR4_LITE2) j += 2;
3937 			if (f4 & TR4_LITE3) j += 3;
3938 
3939 			p_ptr->cur_lite += j;
3940 			if (f5 & TR5_WHITE_LIGHT) lite_inc_white += j;
3941 			else lite_inc_norm += j;
3942 			if (j && !(f4 & TR4_FUEL_LITE)) p_ptr->lite = TRUE;
3943 
3944 			/* Permanent lite gets the 'sustain' colour */
3945 			csheet_boni[i-INVEN_WIELD].lite += j;
3946 			if (!(f4 & TR4_FUEL_LITE)) csheet_boni[i-INVEN_WIELD].cb[12] |= CB13_XLITE;
3947 		}
3948 
3949 		/* powerful lights and anti-undead/evil items damage vampires */
3950 		if (p_ptr->prace == RACE_VAMPIRE && anti_undead(o_ptr)) p_ptr->drain_life++;
3951 
3952 		/* Immunity flags */
3953 		if (f2 & TR2_IM_FIRE) { p_ptr->immune_fire = TRUE; csheet_boni[i-INVEN_WIELD].cb[0] |= CB1_IFIRE; }
3954 		if (f2 & TR2_IM_ACID) { p_ptr->immune_acid = TRUE; csheet_boni[i-INVEN_WIELD].cb[1] |= CB2_IACID; }
3955 		if (f2 & TR2_IM_COLD) { p_ptr->immune_cold = TRUE; csheet_boni[i-INVEN_WIELD].cb[0] |= CB1_ICOLD; }
3956 		if (f2 & TR2_IM_ELEC) { p_ptr->immune_elec = TRUE; csheet_boni[i-INVEN_WIELD].cb[1] |= CB2_IELEC; }
3957 
3958 		if (f2 & TR2_REDUC_FIRE) p_ptr->reduc_fire += 5 * o_ptr->to_a;
3959 		if (f2 & TR2_REDUC_COLD) p_ptr->reduc_cold += 5 * o_ptr->to_a;
3960 		if (f2 & TR2_REDUC_ELEC) p_ptr->reduc_elec += 5 * o_ptr->to_a;
3961 		if (f2 & TR2_REDUC_ACID) p_ptr->reduc_acid += 5 * o_ptr->to_a;
3962 
3963 		/* Resistance flags */
3964 		if (f2 & TR2_RES_ACID) { p_ptr->resist_acid = TRUE; csheet_boni[i-INVEN_WIELD].cb[1] |= CB2_RACID; }
3965 		if (f2 & TR2_RES_ELEC) { p_ptr->resist_elec = TRUE; csheet_boni[i-INVEN_WIELD].cb[0] |= CB1_RELEC; }
3966 		if (f2 & TR2_RES_FIRE) { p_ptr->resist_fire = TRUE; csheet_boni[i-INVEN_WIELD].cb[0] |= CB1_RFIRE; }
3967 		if (f2 & TR2_RES_COLD) { p_ptr->resist_cold = TRUE; csheet_boni[i-INVEN_WIELD].cb[0] |= CB1_RCOLD; }
3968 		if (f2 & TR2_RES_POIS) { p_ptr->resist_pois = TRUE; csheet_boni[i-INVEN_WIELD].cb[1] |= CB2_RPOIS; }
3969 		if (f2 & TR2_RES_FEAR) { p_ptr->resist_fear = TRUE; csheet_boni[i-INVEN_WIELD].cb[4] |= CB5_RFEAR; }
3970 		if (f2 & TR2_RES_CONF) { p_ptr->resist_conf = TRUE; csheet_boni[i-INVEN_WIELD].cb[2] |= CB3_RCONF; }
3971 		if (f2 & TR2_RES_SOUND) { p_ptr->resist_sound = TRUE; csheet_boni[i-INVEN_WIELD].cb[2] |= CB3_RSOUN; }
3972 		if (f2 & TR2_RES_LITE) { p_ptr->resist_lite = TRUE; csheet_boni[i-INVEN_WIELD].cb[2] |= CB3_RLITE; }
3973 		if (f2 & TR2_RES_DARK) { p_ptr->resist_dark = TRUE; csheet_boni[i-INVEN_WIELD].cb[2] |= CB3_RDARK; }
3974 		if (f2 & TR2_RES_CHAOS) { p_ptr->resist_chaos = TRUE; csheet_boni[i-INVEN_WIELD].cb[3] |= CB4_RCHAO; }
3975 		if (f2 & TR2_RES_DISEN) { p_ptr->resist_disen = TRUE; csheet_boni[i-INVEN_WIELD].cb[3] |= CB4_RDISE; }
3976 		if (f2 & TR2_RES_SHARDS) { p_ptr->resist_shard = TRUE; csheet_boni[i-INVEN_WIELD].cb[2] |= CB3_RSHRD; }
3977 		if (f2 & TR2_RES_NEXUS) { p_ptr->resist_nexus = TRUE; csheet_boni[i-INVEN_WIELD].cb[3] |= CB4_RNEXU; }
3978 		if (f5 & TR5_RES_TELE) { p_ptr->res_tele = TRUE; csheet_boni[i-INVEN_WIELD].cb[4] |= CB5_RTELE; }
3979 		if (f2 & TR2_RES_BLIND) { p_ptr->resist_blind = TRUE; csheet_boni[i-INVEN_WIELD].cb[4] |= CB5_RBLND; }
3980 		if (f2 & TR2_RES_NETHER) { p_ptr->resist_neth = TRUE; csheet_boni[i-INVEN_WIELD].cb[3] |= CB4_RNETH; }
3981 //		if (f2 & TR2_ANTI_MAGIC) p_ptr->anti_magic = TRUE;
3982 
3983 		/* Sustain flags */
3984 		if (f2 & TR2_SUST_STR) { p_ptr->sustain_str = TRUE; csheet_boni[i-INVEN_WIELD].cb[11] |= CB12_RSSTR; }
3985 		if (f2 & TR2_SUST_INT) { p_ptr->sustain_int = TRUE; csheet_boni[i-INVEN_WIELD].cb[11] |= CB12_RSINT; }
3986 		if (f2 & TR2_SUST_WIS) { p_ptr->sustain_wis = TRUE; csheet_boni[i-INVEN_WIELD].cb[11] |= CB12_RSWIS; }
3987 		if (f2 & TR2_SUST_DEX) { p_ptr->sustain_dex = TRUE; csheet_boni[i-INVEN_WIELD].cb[11] |= CB12_RSDEX; }
3988 		if (f2 & TR2_SUST_CON) { p_ptr->sustain_con = TRUE; csheet_boni[i-INVEN_WIELD].cb[11] |= CB12_RSCON; }
3989 		if (f2 & TR2_SUST_CHR) { p_ptr->sustain_chr = TRUE; csheet_boni[i-INVEN_WIELD].cb[11] |= CB12_RSCHR; }
3990 
3991 		/* PernA flags */
3992 		if (f3 & (TR3_WRAITH)) {
3993 			//p_ptr->wraith_form = TRUE;
3994 			if (!(zcave[p_ptr->py][p_ptr->px].info & CAVE_STCK) &&
3995 			    !(p_ptr->wpos.wz && (l_ptr->flags1 & LF1_NO_MAGIC))) {
3996 //BAD!(recursion)				set_tim_wraith(Ind, 30000);
3997 				p_ptr->tim_wraith = 30000; csheet_boni[i-INVEN_WIELD].cb[5] |= CB6_RWRTH;
3998 			}
3999 		}
4000 		if (f4 & (TR4_LEVITATE)) {
4001 			p_ptr->levitate = TRUE; csheet_boni[i-INVEN_WIELD].cb[6] |= CB7_RRLEV;
4002 			p_ptr->feather_fall = TRUE; csheet_boni[i-INVEN_WIELD].cb[4] |= CB5_RFALL;
4003 		}
4004 		if (f4 & (TR4_CLIMB)) {
4005 			/* hack: climbing kit is made for humanoids, so it won't work for other forms! */
4006 			if (o_ptr->tval != TV_TOOL || o_ptr->sval != SV_TOOL_CLIMB || !p_ptr->body_monster)
4007 				{ p_ptr->climb = TRUE; csheet_boni[i-INVEN_WIELD].cb[6] |= CB7_RCLMB; } /* item isn't a climbing kit or player is in normal @ form */
4008 #if 0
4009 			else if ((r_ptr->flags3 & (RF3_ORC | RF3_TROLL | RF3_DRAGONRIDER)) || (strchr("hkptyuVsLW", r_ptr->d_char)))
4010 				{ p_ptr->climb = TRUE;  csheet_boni[i-INVEN_WIELD].cb[6] |= CB7_RCLMB; } /* only for normal-sized humanoids (well..trolls, would be unfair to half-trolls) */
4011 #else
4012 			else if (r_ptr->body_parts[BODY_FINGER] && r_ptr->body_parts[BODY_ARMS])
4013 				{ p_ptr->climb = TRUE; csheet_boni[i-INVEN_WIELD].cb[6] |= CB7_RCLMB; } /* everyone with arms and fingers may use it. ok? */
4014 #endif
4015 		}
4016 		/* The Ring of Phasing, exclusively */
4017 		if (f4 & (TR4_IM_NETHER)) { p_ptr->immune_neth = TRUE; csheet_boni[i-INVEN_WIELD].cb[3] |= CB4_INETH; }
4018 		if ((f5 & (TR5_REFLECT)) &&
4019 		    (o_ptr->tval != TV_SHIELD || !p_ptr->heavy_shield))
4020 			{ p_ptr->reflect = TRUE; csheet_boni[i-INVEN_WIELD].cb[6] |= CB7_RREFL; }
4021 		if (f3 & (TR3_SH_FIRE)) { p_ptr->sh_fire = p_ptr->sh_fire_fix = TRUE; csheet_boni[i-INVEN_WIELD].cb[10] |= CB11_AFIRE; }
4022 		if (f5 & (TR5_SH_COLD)) { p_ptr->sh_cold = p_ptr->sh_cold_fix = TRUE; csheet_boni[i-INVEN_WIELD].cb[10] |= CB11_ACOLD; }
4023 		if (f3 & (TR3_SH_ELEC)) { p_ptr->sh_elec = p_ptr->sh_elec_fix = TRUE; csheet_boni[i-INVEN_WIELD].cb[10] |= CB11_AELEC; }
4024 		if (f3 & (TR3_NO_MAGIC)) { p_ptr->anti_magic = TRUE; csheet_boni[i-INVEN_WIELD].cb[6] |= CB7_RAMSH; }
4025 		if (f3 & (TR3_NO_TELE)) { p_ptr->anti_tele = TRUE; csheet_boni[i-INVEN_WIELD].cb[4] |= CB5_ITELE; }
4026 
4027 		/* Additional flags from PernAngband */
4028 
4029 		if (f4 & (TR4_IM_NETHER)) p_ptr->immune_neth = TRUE;
4030 
4031 		/* Limit use of disenchanted DarkSword for non-unbe */
4032 		minus = o_ptr->to_h + o_ptr->to_d; // + pval;// + (o_ptr->to_a / 4);
4033 		if (minus < 0) minus = 0;
4034 		am_temp = 0;
4035 		if (f4 & TR4_ANTIMAGIC_50) am_temp += 50;
4036 		if (f4 & TR4_ANTIMAGIC_30) am_temp += 30;
4037 		if (f4 & TR4_ANTIMAGIC_20) am_temp += 20;
4038 		if (f4 & TR4_ANTIMAGIC_10) am_temp += 10;
4039 		am_temp -= minus;
4040 		/* Weapons may not give more than 50% AM */
4041 		if (am_temp > 50) am_temp = 50;
4042 #ifdef NEW_ANTIMAGIC_RATIO
4043 		am_temp = (am_temp * 3) / 5;
4044 #endif
4045 		/* Choose item with biggest AM field we find */
4046 		if (am_temp > 0) csheet_boni[i-INVEN_WIELD].amfi = am_temp; //Track individual item boni, knowing they don't stack
4047 		if (am_temp > am_bonus) am_bonus = am_temp;
4048 
4049 		if (f4 & (TR4_BLACK_BREATH)) p_ptr->black_breath_tmp = TRUE;
4050 
4051 //		if (f5 & (TR5_IMMOVABLE)) p_ptr->immovable = TRUE;
4052 
4053 		/* note: TR1_VAMPIRIC isn't directly applied for melee
4054 		   weapons here, but instead in the py_attack... functions
4055 		   in cmd1.c. Reason is that dual-wielding might hit with
4056 		   a vampiric or a non-vampiric weapon randomly - C. Blue */
4057 
4058 
4059 
4060 		/* Modify the base armor class */
4061 #ifdef USE_NEW_SHIELDS
4062 		if (o_ptr->tval != TV_SHIELD)
4063 #else
4064 		if (o_ptr->tval == TV_SHIELD && p_ptr->heavy_shield)
4065 			p_ptr->ac += o_ptr->ac / 2;
4066 		else
4067 #endif
4068 		p_ptr->ac += o_ptr->ac;
4069 
4070 		/* The base armor class is always known */
4071 #ifdef USE_NEW_SHIELDS
4072 		if (o_ptr->tval != TV_SHIELD)
4073 #else
4074 		if (o_ptr->tval == TV_SHIELD && p_ptr->heavy_shield)
4075 			p_ptr->dis_ac += o_ptr->ac / 2;
4076 		else
4077 #endif
4078 		p_ptr->dis_ac += o_ptr->ac;
4079 
4080 #ifndef NEW_SHIELDS_NO_AC
4081 		/* Apply the bonuses to armor class */
4082 		if (o_ptr->tval == TV_SHIELD && p_ptr->heavy_shield)
4083 			p_ptr->to_a += o_ptr->to_a / 2;
4084 		else
4085 			p_ptr->to_a += o_ptr->to_a;
4086 #else
4087 		p_ptr->to_a += o_ptr->to_a;
4088 #endif
4089 
4090 		/* Apply the mental bonuses to armor class, if known */
4091 		if (object_known_p(Ind, o_ptr)) {
4092 #ifndef NEW_SHIELDS_NO_AC
4093 			if (o_ptr->tval == TV_SHIELD && p_ptr->heavy_shield)
4094 				p_ptr->dis_to_a += o_ptr->to_a / 2;
4095 			else
4096 				p_ptr->dis_to_a += o_ptr->to_a;
4097 #else
4098 			p_ptr->dis_to_a += o_ptr->to_a;
4099 #endif
4100 		}
4101 
4102 		/* Brands/slays */
4103 		if (f1 & TR1_SLAY_ANIMAL) csheet_boni[i-INVEN_WIELD].cb[7] |= CB8_SANIM;
4104 		if (f1 & TR1_SLAY_EVIL) csheet_boni[i-INVEN_WIELD].cb[9] |= CB10_SEVIL;
4105 		if (f1 & TR1_SLAY_UNDEAD) csheet_boni[i-INVEN_WIELD].cb[9] |= CB10_SUNDD;
4106 		if (f1 & TR1_SLAY_DEMON) csheet_boni[i-INVEN_WIELD].cb[8] |= CB9_SDEMN;
4107 		if (f1 & TR1_SLAY_ORC) csheet_boni[i-INVEN_WIELD].cb[7] |= CB8_SORCS;
4108 		if (f1 & TR1_SLAY_TROLL) csheet_boni[i-INVEN_WIELD].cb[7] |= CB8_STROL;
4109 		if (f1 & TR1_SLAY_GIANT) csheet_boni[i-INVEN_WIELD].cb[8] |= CB9_SGIAN;
4110 		if (f1 & TR1_SLAY_DRAGON) csheet_boni[i-INVEN_WIELD].cb[8] |= CB9_SDRGN;
4111 		if (f1 & TR1_KILL_DRAGON) csheet_boni[i-INVEN_WIELD].cb[8] |= CB9_KDRGN;
4112 		if (f1 & TR1_KILL_DEMON) csheet_boni[i-INVEN_WIELD].cb[8] |= CB9_KDEMN;
4113 		if (f1 & TR1_KILL_UNDEAD) csheet_boni[i-INVEN_WIELD].cb[9] |= CB10_KUNDD;
4114 		if (f1 & TR1_BRAND_POIS) csheet_boni[i-INVEN_WIELD].cb[10] |= CB11_BPOIS;
4115 		if (f1 & TR1_BRAND_ACID) csheet_boni[i-INVEN_WIELD].cb[10] |= CB11_BACID;
4116 		if (f1 & TR1_BRAND_ELEC) csheet_boni[i-INVEN_WIELD].cb[10] |= CB11_BELEC;
4117 		if (f1 & TR1_BRAND_FIRE) csheet_boni[i-INVEN_WIELD].cb[10] |= CB11_BFIRE;
4118 		if (f1 & TR1_BRAND_COLD) csheet_boni[i-INVEN_WIELD].cb[10] |= CB11_BCOLD;
4119 		if (f5 & TR5_VORPAL) csheet_boni[i-INVEN_WIELD].cb[11] |= CB12_BVORP;
4120 
4121 		/* Hack -- do not apply "weapon", "bow", "ammo", or "tool"  boni */
4122 		if ((i == INVEN_WIELD) || (i == INVEN_ARM && o_ptr->tval != TV_SHIELD)) {
4123 			if (f1 & TR1_BLOWS) csheet_boni[i-INVEN_WIELD].blow += pval;
4124 			if (f5 & TR5_CRIT) csheet_boni[i-INVEN_WIELD].crit += pval;
4125 			if (f1 & TR1_VAMPIRIC) csheet_boni[i-INVEN_WIELD].cb[6] |= CB7_RVAMP;
4126 			continue;
4127 		}
4128 
4129 		if (i == INVEN_AMMO || i == INVEN_BOW) {
4130 			if (f1 & TR1_VAMPIRIC) { p_ptr->vampiric_ranged = 100; csheet_boni[i-INVEN_WIELD].cb[6] |= CB7_RVAMP; }
4131 			continue;
4132 		}
4133 		if (i == INVEN_TOOL) continue;
4134 
4135 		if (f1 & TR1_BLOWS) { p_ptr->extra_blows += pval; csheet_boni[i-INVEN_WIELD].blow += pval; }
4136 		if (f5 & TR5_CRIT) { p_ptr->xtra_crit += pval; csheet_boni[i-INVEN_WIELD].crit += pval; }
4137 
4138 		/* Hack -- cause earthquakes */
4139 		if (f5 & TR5_IMPACT) p_ptr->impact = TRUE; /* non-weapons/tools, so this could be gloves or jewelry, but those don't exist at this time */
4140 		if (f5 & TR5_VORPAL) csheet_boni[i-INVEN_WIELD].cb[11] |= CB12_BVORP;
4141 
4142 		/* Generally vampiric? */
4143 		if (f1 & TR1_VAMPIRIC) {
4144 			csheet_boni[i-INVEN_WIELD].cb[6] |= CB7_RVAMP; //Display the flag always...
4145 			if (p_ptr->vampiric_melee < NON_WEAPON_VAMPIRIC_CHANCE) p_ptr->vampiric_melee = NON_WEAPON_VAMPIRIC_CHANCE;
4146 			if (p_ptr->vampiric_ranged < NON_WEAPON_VAMPIRIC_CHANCE_RANGED) p_ptr->vampiric_ranged = NON_WEAPON_VAMPIRIC_CHANCE_RANGED;
4147 		}
4148 
4149 		/* Hack MHDSM: */
4150 		if (o_ptr->tval == TV_DRAG_ARMOR && o_ptr->sval == SV_DRAGON_MULTIHUED) {
4151 			if (o_ptr->xtra2 & 0x01) { p_ptr->immune_fire = TRUE; csheet_boni[i-INVEN_WIELD].cb[0] |= CB1_IFIRE; }
4152 			if (o_ptr->xtra2 & 0x02) { p_ptr->immune_cold = TRUE; csheet_boni[i-INVEN_WIELD].cb[0] |= CB1_ICOLD; }
4153 			if (o_ptr->xtra2 & 0x04) { p_ptr->immune_elec = TRUE; csheet_boni[i-INVEN_WIELD].cb[1] |= CB2_IELEC; }
4154 			if (o_ptr->xtra2 & 0x08) { p_ptr->immune_acid = TRUE; csheet_boni[i-INVEN_WIELD].cb[1] |= CB2_IACID; }
4155 			if (o_ptr->xtra2 & 0x10) { p_ptr->immune_poison = TRUE; csheet_boni[i-INVEN_WIELD].cb[1] |= CB2_IPOIS; }
4156 		}
4157 
4158 		/* Apply the bonuses to hit/damage */
4159 		p_ptr->to_h += o_ptr->to_h;
4160 		p_ptr->to_d += o_ptr->to_d;
4161 
4162 		/* Apply the mental bonuses tp hit/damage, if known */
4163 		if (object_known_p(Ind, o_ptr)) p_ptr->dis_to_h += o_ptr->to_h;
4164 		if (object_known_p(Ind, o_ptr)) p_ptr->dis_to_d += o_ptr->to_d;
4165 
4166 	}
4167 
4168 	p_ptr->antimagic += am_bonus;
4169 #ifdef NEW_ANTIMAGIC_RATIO
4170 	p_ptr->antimagic_dis += (am_bonus / 9);
4171 #else
4172 	p_ptr->antimagic_dis += (am_bonus / 15);
4173 #endif
4174 
4175 	/* Hard/Hellish mode also gives mana penalty */
4176 	if (p_ptr->mode & MODE_HARD) p_ptr->to_m = (p_ptr->to_m * 2) / 3;
4177 
4178 	/* Check for temporary blessings */
4179 	if (p_ptr->bless_temp_luck) {
4180 		p_ptr->luck += p_ptr->bless_temp_luck_power;
4181 		/* abuse '@ form' luck column for this for now */
4182 		csheet_boni[14].luck += p_ptr->bless_temp_luck_power;
4183 	}
4184 
4185 #ifdef EQUIPMENT_SET_BONUS
4186 	for (i = 0; i < INVEN_TOTAL - INVEN_WIELD; i++) {
4187 		if (!equipment_set[i]) continue;
4188 		if (equipment_set_amount[i] > equipment_set_bonus)
4189 			equipment_set_bonus = equipment_set_amount[i];
4190 	}
4191 	if (equipment_set_bonus >= 2) {
4192 		/* Display the luck boni on each involved item */
4193 		//for (i = 0; i < INVEN_TOTAL - INVEN_WIELD; i++) //Mh, this doesn't really always work, needs better tracking in the luck calculation code?
4194 			//if (equipment_set_amount[i]) csheet_boni[i].luck += equipment_set_bonus;
4195 //		equipment_set_bonus = (equipment_set_bonus * equipment_set_bonus) / 2;
4196 //		equipment_set_bonus = (equipment_set_bonus - 1) * 4;
4197 //		equipment_set_bonus = (equipment_set_bonus * equipment_set_bonus);
4198 		equipment_set_bonus = (equipment_set_bonus * (equipment_set_bonus + 1)) / 2;
4199 		/* just prevent numerical overflows in p_ptr->luck (paranoiaish) */
4200 		if (equipment_set_bonus > 40) equipment_set_bonus = 40;
4201 		p_ptr->luck += equipment_set_bonus;
4202 		/* abuse '@ form' luck column for this for now */
4203 		csheet_boni[14].luck += equipment_set_bonus;
4204 	}
4205 #endif
4206 
4207 	if (p_ptr->antimagic > ANTIMAGIC_CAP) p_ptr->antimagic = ANTIMAGIC_CAP; /* AM cap */
4208 	if (p_ptr->luck < -10) p_ptr->luck = -10; /* luck caps at -10 */
4209 	if (p_ptr->luck > 40) p_ptr->luck = 40; /* luck caps at 40 */
4210 
4211 	old_sun_burn = p_ptr->sun_burn;
4212 	p_ptr->sun_burn = FALSE;
4213 	if ((p_ptr->prace == RACE_VAMPIRE ||
4214 	    (p_ptr->body_monster && r_info[p_ptr->body_monster].d_char == 'V'))
4215 	    && !p_ptr->ghost && !(p_ptr->global_event_temp & PEVF_INDOORS_00)
4216 	    && !(l_ptr && (l_ptr->flags2 & LF2_INDOORS))
4217 	    && !(in_sector00(&p_ptr->wpos) && (sector00flags2 & LF2_INDOORS))) {
4218 		/* damage from sunlight */
4219 		if (!p_ptr->wpos.wz && !night_surface && //!(zcave[p_ptr->py][p_ptr->px].info & CAVE_ICKY) &&
4220 		    !p_ptr->resist_lite && (TOOL_EQUIPPED(p_ptr) != SV_TOOL_WRAPPING) &&
4221 //		    !(p_ptr->inventory[INVEN_NECK].k_idx && p_ptr->inventory[INVEN_NECK].sval == SV_AMULET_HIGHLANDS2) &&
4222 		    !(zcave[p_ptr->py][p_ptr->px].info & CAVE_PROT) &&
4223 		    !(f_info[zcave[p_ptr->py][p_ptr->px].feat].flags1 & FF1_PROTECTED) &&
4224 		    zcave[p_ptr->py][p_ptr->px].feat != FEAT_SHOP) {
4225 			p_ptr->sun_burn = TRUE;
4226 			if (!old_sun_burn) msg_print(Ind, "\377RYou burn in the sunlight!");
4227 			/* vampire bats can stay longer under the sunlight than actual vampire form */
4228 			if (p_ptr->body_monster != RI_VAMPIRE_BAT) {
4229 				i = (turn % DAY) / HOUR;
4230 				i = 5 - ABS(i - (SUNRISE + (NIGHTFALL - SUNRISE) / 2)) / 2; /* for calculate day time distance to noon -> max burn!: 2..5*/
4231 				if (p_ptr->total_winner) i = (i + 1) / 2;//1..3
4232 				p_ptr->drain_life += i;
4233 			} else p_ptr->drain_life++;
4234 		}
4235 	}
4236 
4237 
4238 	/* Apply temporary "stun" */
4239 	if (p_ptr->stun > 50) {
4240 		p_ptr->to_h /= 2;
4241 		p_ptr->dis_to_h /= 2;
4242 		p_ptr->to_d /= 2;
4243 		p_ptr->dis_to_d /= 2;
4244 	} else if (p_ptr->stun) {
4245 		p_ptr->to_h = (p_ptr->to_h * 2) / 3;
4246 		p_ptr->dis_to_h = (p_ptr->dis_to_h * 2) / 3;
4247 		p_ptr->to_d = (p_ptr->to_d * 2) / 3;
4248 		p_ptr->dis_to_d = (p_ptr->dis_to_h * 2) / 3;
4249 	}
4250 
4251 	/* Adrenaline effects */
4252 	if (p_ptr->adrenaline) {
4253 		int i;
4254 
4255 		i = p_ptr->lev / 7;
4256 		if (i > 3) i = 3;//was 5, untested hmm
4257 		p_ptr->stat_add[A_CON] += i;
4258 		p_ptr->stat_add[A_STR] += i;
4259 		p_ptr->stat_add[A_DEX] += (i + 1) / 2;
4260 		p_ptr->to_h += 12;
4261 		p_ptr->dis_to_h += 12;
4262 		if (p_ptr->adrenaline & 1) {
4263 			p_ptr->to_d += 8;
4264 			p_ptr->dis_to_d += 8;
4265 		}
4266 		if (p_ptr->adrenaline & 2) p_ptr->extra_blows++;
4267 		p_ptr->to_a -= 20;
4268 		p_ptr->dis_to_a -= 20;
4269 	}
4270 
4271 	/* At least +1, max. +3 */
4272 	if (p_ptr->zeal) p_ptr->extra_blows += p_ptr->zeal_power / 10 > 3 ? 3 : (p_ptr->zeal_power / 10 < 1 ? 1 : p_ptr->zeal_power / 10);
4273 	else if (p_ptr->mindboost && p_ptr->mindboost_power >= 65) p_ptr->extra_blows++;
4274 
4275 	if (p_ptr->mindboost) p_ptr->skill_sav += p_ptr->mindboost_power / 5;
4276 
4277 	/* Temporary "Levitation" */
4278 	if (p_ptr->tim_ffall || p_ptr->tim_lev) p_ptr->feather_fall = TRUE;
4279 	if (p_ptr->tim_lev) p_ptr->levitate = TRUE;
4280 
4281 	/* Temp ESP */
4282 	if (p_ptr->tim_esp) {
4283 //		p_ptr->telepathy = TRUE;
4284 		p_ptr->telepathy |= ESP_ALL;
4285 	}
4286 
4287 	/* Temporary invisibility */
4288 	if (p_ptr->tim_invis_power > p_ptr->tim_invis_power2)
4289 		p_ptr->invis = p_ptr->tim_invis_power;
4290 	else
4291 		p_ptr->invis = p_ptr->tim_invis_power2;
4292 
4293 	/* Temporary deflection */
4294 	if (p_ptr->tim_deflect) p_ptr->reflect = TRUE;
4295 
4296 	/* Temporary "Hero" */
4297 	if (p_ptr->hero || (p_ptr->mindboost && p_ptr->mindboost_power >= 5)) {
4298 		p_ptr->to_h += 12;
4299 		p_ptr->dis_to_h += 12;
4300 	}
4301 
4302 	/* Temporary "Berserk Strength" (potion) */
4303 	if (p_ptr->shero) {
4304 #if 0 /* disabled, since the bonus to A_STR below already increases the damage greatly, even by more than +10 usually.. */
4305 		p_ptr->to_h += 5;//24
4306 		p_ptr->dis_to_h += 5;//24
4307 		p_ptr->to_d += 10;
4308 		p_ptr->dis_to_d += 10;
4309 #endif
4310 		p_ptr->to_a -= 10;//10
4311 		p_ptr->dis_to_a -= 10;//10
4312 
4313 		/* mainly to help bashing doors open, but makes sense in general, also helps tunnelling now.. */
4314 		p_ptr->stat_add[A_STR] += 10;
4315 	}
4316 
4317 	/* Temporary "Berserk" */
4318 	if (p_ptr->berserk) {
4319 		p_ptr->to_h -= 5;
4320 		p_ptr->dis_to_h -= 5;
4321 		p_ptr->to_d += 15;
4322 		p_ptr->dis_to_d += 15;
4323 		p_ptr->to_a -= 10;
4324 		p_ptr->dis_to_a -= 10;
4325 		p_ptr->extra_blows++;
4326 	}
4327 
4328 	/* Temporary "Fury" */
4329 	if (p_ptr->fury) {
4330 		p_ptr->to_h -= 10;
4331 		p_ptr->dis_to_h -= 10;
4332 		p_ptr->to_d += 20;
4333 		p_ptr->dis_to_d += 20;
4334 		p_ptr->pspeed += 5;
4335 		p_ptr->to_a -= 30;
4336 		p_ptr->dis_to_a -= 30;
4337 	}
4338 
4339 	/* Temporary "fast" */
4340 	if (p_ptr->fast) p_ptr->pspeed += p_ptr->fast_mod;
4341 
4342 	/* Temporary "slow" */
4343 	if (p_ptr->slow) p_ptr->pspeed -= 10;
4344 
4345 	/* Temporary see invisible */
4346 	if (p_ptr->tim_invis) p_ptr->see_inv = TRUE;
4347 
4348 	/* Temporary infravision boost */
4349 	if (p_ptr->tim_infra) {
4350 //		p_ptr->see_infra++;
4351 		p_ptr->see_infra += 5;
4352 	}
4353 
4354 	/* Hack -- Res Chaos -> Res Conf */
4355 	if (p_ptr->resist_chaos) p_ptr->resist_conf = TRUE;
4356 
4357 	/* Heart is boldened */
4358 	if (p_ptr->res_fear_temp || p_ptr->hero || p_ptr->shero ||
4359 	    p_ptr->fury || p_ptr->berserk || p_ptr->mindboost)
4360 		p_ptr->resist_fear = TRUE;
4361 
4362 
4363 	/* Hack -- Telepathy Change */
4364 	if (p_ptr->telepathy != old_telepathy) p_ptr->update |= (PU_MONSTERS);
4365 
4366 	/* Hack -- See Invis Change */
4367 	if (p_ptr->see_inv != old_see_inv) p_ptr->update |= (PU_MONSTERS);
4368 
4369 	/* Temporary space-time anchor */
4370 	if (p_ptr->st_anchor) {
4371 		p_ptr->anti_tele = TRUE;
4372 		p_ptr->resist_continuum = TRUE;
4373 	}
4374 
4375 
4376 	/* Bloating slows the player down (a little) */
4377 	if (p_ptr->food >= PY_FOOD_MAX) p_ptr->pspeed -= 10;
4378 
4379 	/* Searching slows the player down */
4380 	/* -APD- adding "stealth mode" for rogues... will probably need to tweek this */
4381 	/* XXX this can be out of place; maybe better done
4382 	 * after skill bonuses are added?	- Jir - */
4383 	if (p_ptr->searching) {
4384 		int stealth = get_skill(p_ptr, SKILL_STEALTH);
4385 		int sneakiness = get_skill(p_ptr, SKILL_SNEAKINESS);
4386 		p_ptr->pspeed -= 10 - sneakiness / 7;
4387 		csheet_boni[14].spd -= 10 - sneakiness / 7;
4388 #if 1
4389 		if (stealth >= 10) {
4390 			p_ptr->skill_stl = p_ptr->skill_stl + stealth / 10;
4391 		}
4392 #endif
4393 		if (sneakiness >= 0) {
4394 			/* prevent TLs from getting glitched abysmal stealth here.. */
4395 			if (p_ptr->skill_srh >= 0) p_ptr->skill_srh = (p_ptr->skill_srh * (sneakiness + 50)) / 50;
4396 //			p_ptr->skill_srh = p_ptr->skill_srh + sneakiness / 3;
4397 //			p_ptr->skill_fos = p_ptr->skill_fos * sneakiness / 10;
4398 		}
4399 	}
4400 
4401 	if (p_ptr->cloaked) {
4402 #if 0 /* for now, light is simply dimmed in cloaking mode, instead of breaking it. */
4403 	/*  might need to give rogues a special ability to see in the dark like vampires. or not, pft. - C. Blue */
4404 	/* cannot be cloaked if wielding a (real, not vampire vision) light source */
4405 		if (p_ptr->cur_lite) break_cloaking(Ind, 0);
4406 #else
4407 		if (p_ptr->cur_lite) p_ptr->cur_lite = 1; /* dim it */
4408 #endif
4409 	}
4410 	if (p_ptr->cloaked == 1) {
4411 		p_ptr->pspeed -= 10 - get_skill_scale(p_ptr, SKILL_SNEAKINESS, 3);
4412 		csheet_boni[14].spd -= 10 - get_skill_scale(p_ptr, SKILL_SNEAKINESS, 3);
4413 		p_ptr->skill_stl = p_ptr->skill_stl + 25;
4414 		csheet_boni[14].slth += 25;
4415 		p_ptr->skill_srh = p_ptr->skill_srh + 10;
4416 		csheet_boni[14].srch += 10;
4417 	}
4418 
4419 	if (p_ptr->shadow_running) { p_ptr->pspeed += 10; csheet_boni[14].spd += 10; }
4420 
4421 	if (p_ptr->sh_fire_tim) p_ptr->sh_fire = TRUE;
4422 	if (p_ptr->sh_cold_tim) p_ptr->sh_cold = TRUE;
4423 	if (p_ptr->sh_elec_tim) p_ptr->sh_elec = TRUE;
4424 
4425 	/* Bonus from +LIFE items (should be weapons only -- not anymore, Bladeturner / Randarts etc.!).
4426 	   Also, cap it at +3 (boomerang + weapon could result in +6) (Boomerangs can't have +LIFE anymore) */
4427 	if (!is_admin(p_ptr) && p_ptr->to_l > 3) p_ptr->to_l = 3;
4428 
4429 
4430 	/* Calculate stats */
4431 	for (i = 0; i < 6; i++) {
4432 		int top, use, ind;
4433 
4434 		/* Extract the new "stat_use" value for the stat */
4435 		top = modify_stat_value(p_ptr->stat_max[i], p_ptr->stat_add[i]);
4436 
4437 		/* Notice changes */
4438 		if (p_ptr->stat_top[i] != top) {
4439 			/* Save the new value */
4440 			p_ptr->stat_top[i] = top;
4441 
4442 			/* Redisplay the stats later */
4443 			p_ptr->redraw |= (PR_STATS);
4444 			/* Window stuff */
4445 			p_ptr->window |= (PW_PLAYER);
4446 		}
4447 
4448 
4449 		/* Extract the new "stat_use" value for the stat */
4450 		use = modify_stat_value(p_ptr->stat_cur[i], p_ptr->stat_add[i]);
4451 
4452 		/* Notice changes */
4453 		if (p_ptr->stat_use[i] != use) {
4454 			/* Save the new value */
4455 			p_ptr->stat_use[i] = use;
4456 
4457 			/* Redisplay the stats later */
4458 			p_ptr->redraw |= (PR_STATS);
4459 			/* Window stuff */
4460 			p_ptr->window |= (PW_PLAYER);
4461 		}
4462 
4463 
4464 		/* Values: 3, 4, ..., 17 */
4465 		if (use <= 18) ind = (use - 3);
4466 		/* Ranges: 18/00-18/09, ..., 18/210-18/219 */
4467 		else if (use <= 18 + 219) ind = (15 + (use - 18) / 10);
4468 		/* Range: 18/220+ */
4469 		else ind = (37);
4470 
4471 		/* Notice changes */
4472 		if (p_ptr->stat_ind[i] != ind) {
4473 			/* Save the new index */
4474 			p_ptr->stat_ind[i] = ind;
4475 
4476 			/* Change in CON affects Hitpoints */
4477 			if (i == A_CON) p_ptr->update |= (PU_HP);
4478 
4479 			/* Changes that may affect Mana/Spells (dex for runemaster, chr for mindcrafter) */
4480 			else if (i == A_INT || i == A_WIS || i == A_DEX || i == A_CHR)
4481 				p_ptr->update |= (PU_MANA);
4482 
4483 			/* Window stuff */
4484 			p_ptr->window |= (PW_PLAYER);
4485 		}
4486 	}
4487 
4488 
4489 	/* Assume player not encumbered by armor */
4490 	p_ptr->cumber_armor = FALSE;
4491 	/* Heavy armor penalizes to-hit and sneakiness speed */
4492 	if (((armour_weight(p_ptr) - (100 + get_skill_scale(p_ptr, SKILL_COMBAT, 300)
4493 	    + adj_str_hold[p_ptr->stat_ind[A_STR]] * 6)) / 10) > 0) {
4494 		/* Encumbered */
4495 		p_ptr->cumber_armor = TRUE;
4496 	}
4497 	/* Take note when "armor state" changes */
4498 	if (p_ptr->old_cumber_armor != p_ptr->cumber_armor) {
4499 		/* Message */
4500 		if (p_ptr->cumber_armor)
4501 			msg_print(Ind, "\377oThe weight of your armour encumbers your movement.");
4502 		else
4503 			msg_print(Ind, "\377gYou feel able to move more freely.");
4504 
4505 		/* Save it */
4506 		p_ptr->old_cumber_armor = p_ptr->cumber_armor;
4507 	}
4508 
4509 
4510 	p_ptr->rogue_heavyarmor = rogue_heavy_armor(p_ptr);
4511 	if (p_ptr->old_rogue_heavyarmor != p_ptr->rogue_heavyarmor) {
4512 		/* Don't kill warnings by inspecting weapons/armour in stores! */
4513 		if (!suppress_boni) {
4514 			if (p_ptr->rogue_heavyarmor) {
4515 				msg_print(Ind, "\377RThe weight of your armour strains your flexibility and awareness.");
4516 				break_cloaking(Ind, 0);
4517 				break_shadow_running(Ind);
4518 				if (!p_ptr->warning_dual && p_ptr->dual_wield && p_ptr->pclass != CLASS_ROGUE) {
4519 					p_ptr->warning_dual = 1;
4520 					msg_print(Ind, "\374\377yHINT: You cannot dual-wield effectively if your armour is too heavy!");
4521 					msg_print(Ind, "\374\377y      If you don't want to use lighter armour, consider using one weapon");
4522 					msg_print(Ind, "\374\377y      and a shield, or (if your STRength is VERY high) a two-handed weapon.");
4523 					s_printf("warning_dual: %s\n", p_ptr->name);
4524 				}
4525 			}
4526 			/* do we still wear armour, and are still rogue or dual-wielding? */
4527 			else if (armour_weight(p_ptr)) {
4528 				if (p_ptr->pclass == CLASS_ROGUE || p_ptr->dual_wield) {
4529 					msg_print(Ind, "\377gYour armour is comfortable and flexible.");
4530 				} else { /* we took off a weapon, not armour.. */
4531 					msg_print(Ind, "\377gYou feel comfortable again.");
4532 				}
4533 			}
4534 			/* if not, give a slightly different msg */
4535 			else if (p_ptr->pclass == CLASS_ROGUE || p_ptr->dual_wield) {
4536 				msg_print(Ind, "\377gYou feel comfortable and flexible again.");
4537 			} else { /* we took off a weapon, not armour.. */
4538 				msg_print(Ind, "\377gYou feel comfortable again.");
4539 			}
4540 		}
4541 		p_ptr->old_rogue_heavyarmor = p_ptr->rogue_heavyarmor;
4542 	}
4543 
4544 	if (p_ptr->stormbringer && !suppress_boni) {
4545 		if (p_ptr->cloaked) {
4546 			msg_print(Ind, "\377yYou cannot remain cloaked effectively while wielding the stormbringer!");
4547 			break_cloaking(Ind, 0);
4548 		}
4549 		if (p_ptr->shadow_running) {
4550 			msg_print(Ind, "\377yThe stormbringer hinders effective shadow running!");
4551 			break_shadow_running(Ind);
4552 		}
4553 	}
4554 	if (p_ptr->aggravate && !suppress_boni) {
4555 		if (p_ptr->cloaked) {
4556 			msg_print(Ind, "\377yYou cannot remain cloaked effectively while using aggravating items!");
4557 			break_cloaking(Ind, 0);
4558 		}
4559 	}
4560 	if (p_ptr->inventory[INVEN_WIELD].k_idx &&
4561 	    (k_info[p_ptr->inventory[INVEN_WIELD].k_idx].flags4 & (TR4_MUST2H | TR4_SHOULD2H))
4562 	    && !suppress_boni) {
4563 		if (p_ptr->cloaked && !instakills(Ind)) {
4564 			msg_print(Ind, "\377yYour weapon is too large to remain cloaked effectively.");
4565 			break_cloaking(Ind, 0);
4566 		}
4567 		if (p_ptr->shadow_running && !instakills(Ind)) {
4568 			msg_print(Ind, "\377yYour weapon is too large for effective shadow running.");
4569 			break_shadow_running(Ind);
4570 		}
4571 	}
4572 	if (p_ptr->inventory[INVEN_ARM].k_idx && p_ptr->inventory[INVEN_ARM].tval == TV_SHIELD
4573 	    && !suppress_boni) {
4574 		if (p_ptr->cloaked) {
4575 			msg_print(Ind, "\377yYou cannot remain cloaked effectively while wielding a shield.");
4576 			break_cloaking(Ind, 0);
4577 		}
4578 		if (p_ptr->shadow_running) {
4579 			msg_print(Ind, "\377yYour shield hinders effective shadow running.");
4580 			break_shadow_running(Ind);
4581 		}
4582 	}
4583 
4584 	p_ptr->monk_heavyarmor = monk_heavy_armor(p_ptr);
4585 	if (p_ptr->old_monk_heavyarmor != p_ptr->monk_heavyarmor) {
4586 		if (p_ptr->monk_heavyarmor)
4587 			msg_print(Ind, "\377oThe weight of your armour strains your martial arts performance.");
4588 		else
4589 			msg_print(Ind, "\377gYour armour is comfortable for using martial arts.");
4590 		p_ptr->old_monk_heavyarmor = p_ptr->monk_heavyarmor;
4591 	}
4592 	if (get_skill(p_ptr, SKILL_MARTIAL_ARTS) && !monk_heavy_armor(p_ptr)) {
4593 		long int k = get_skill_scale(p_ptr, SKILL_MARTIAL_ARTS, 5), w = 0;
4594 
4595 		if (k) {
4596 			/* Extract the current weight (in tenth pounds) */
4597 			w = p_ptr->total_weight;
4598 
4599 			/* Extract the "weight limit" (in tenth pounds) */
4600 			i = weight_limit(Ind) + 500;
4601 
4602 			/* XXX XXX XXX Apply "encumbrance" from weight */
4603 			if (w > i / 5) k -= ((w - (i / 5)) / (i / 10));
4604 
4605 			/* Assume unencumbered */
4606 			p_ptr->cumber_weight = FALSE;
4607 
4608 			if (k > 0) {
4609 				/* Feather Falling if unencumbered at level 10 */
4610 				if  (get_skill(p_ptr, SKILL_MARTIAL_ARTS) > 9)
4611 					{ p_ptr->feather_fall = TRUE; csheet_boni[14].cb[4] |= CB5_RFALL; }
4612 
4613 				/* Fear Resistance if unencumbered at level 15 */
4614 				if  (get_skill(p_ptr, SKILL_MARTIAL_ARTS) > 14)
4615 					{ p_ptr->resist_fear = TRUE; csheet_boni[14].cb[4] |= CB5_RFEAR; }
4616 
4617 				/* Confusion Resistance if unencumbered at level 20 */
4618 				if  (get_skill(p_ptr, SKILL_MARTIAL_ARTS) > 19)
4619 					{ p_ptr->resist_conf = TRUE; csheet_boni[14].cb[2] |= CB3_RCONF; }
4620 
4621 				/* Free action if unencumbered at level 25 */
4622 				if  (get_skill(p_ptr, SKILL_MARTIAL_ARTS) > 24)
4623 					{ p_ptr->free_act = TRUE; csheet_boni[14].cb[4] |= CB5_RPARA; }
4624 
4625 				/* Swimming if unencumbered at level 30 */
4626 				if  (get_skill(p_ptr, SKILL_MARTIAL_ARTS) > 29)
4627 					{ p_ptr->can_swim = TRUE; csheet_boni[14].cb[12] |= CB13_XSWIM; }
4628 
4629 				/* Climbing if unencumbered at level 40 */
4630 				if  (get_skill(p_ptr, SKILL_MARTIAL_ARTS) > 39)
4631 					{ p_ptr->climb = TRUE; csheet_boni[14].cb[6] |= CB7_RCLMB; }
4632 
4633 				/* Levitating if unencumbered at level 50 */
4634 				if  (get_skill(p_ptr, SKILL_MARTIAL_ARTS) > 49) {
4635 					p_ptr->levitate = TRUE; csheet_boni[14].cb[6] |= CB7_RRLEV;
4636 					p_ptr->feather_fall = TRUE; csheet_boni[14].cb[4] |= CB5_RFALL;
4637 				}
4638 
4639 				w = 0;
4640 				if (p_ptr->inventory[INVEN_ARM].k_idx) w += k_info[p_ptr->inventory[INVEN_ARM].k_idx].weight;
4641 				if (p_ptr->inventory[INVEN_BOW].k_idx) w += k_info[p_ptr->inventory[INVEN_BOW].k_idx].weight;
4642 				if (p_ptr->inventory[INVEN_WIELD].k_idx) w += k_info[p_ptr->inventory[INVEN_WIELD].k_idx].weight;
4643 				if (w < 150) {
4644 					/* give a speed bonus */
4645 					p_ptr->pspeed += k; csheet_boni[14].spd += k;
4646 
4647 					/* give a stealth bonus */
4648 					p_ptr->skill_stl += k; csheet_boni[14].slth += k;
4649 				}
4650 			}
4651 			else p_ptr->cumber_weight = TRUE;
4652 
4653 			if (p_ptr->old_cumber_weight != p_ptr->cumber_weight) {
4654 				if (p_ptr->cumber_weight)
4655 					msg_print(Ind, "\377RYou can't move freely due to your backpack weight.");
4656 				else
4657 					msg_print(Ind, "\377gYour backpack is very comfortable to wear.");
4658 				p_ptr->old_cumber_weight = p_ptr->cumber_weight;
4659 			}
4660 		}
4661 
4662 		/* Monks get extra ac for wearing very light or no armour at all */
4663 #ifndef ENABLE_MA_BOOMERANG
4664 		if (!p_ptr->inventory[INVEN_BOW].k_idx &&
4665 #else
4666 		if (p_ptr->inventory[INVEN_BOW].tval != TV_BOW &&
4667 #endif
4668 		    !p_ptr->inventory[INVEN_WIELD].k_idx &&
4669 		    (!p_ptr->inventory[INVEN_ARM].k_idx || p_ptr->inventory[INVEN_ARM].tval == TV_SHIELD) && /* for dual-wielders */
4670 		    !p_ptr->cumber_weight) {
4671 			int marts = get_skill_scale(p_ptr, SKILL_MARTIAL_ARTS, 60);
4672 			int martsbonus, martsweight, martscapacity;
4673 
4674 			martsbonus = (marts * 3) / 2 * MARTIAL_ARTS_AC_ADJUST / 100;
4675 			martsweight = p_ptr->inventory[INVEN_BODY].weight;
4676 			martscapacity = get_skill_scale(p_ptr, SKILL_MARTIAL_ARTS, 80) + 20;//(90/100/110) wire fleece/hard leather armour = 100; rhino hide/hard studded leather = 110
4677 			if (!(p_ptr->inventory[INVEN_BODY].k_idx)) {
4678 				p_ptr->to_a += martsbonus;
4679 				p_ptr->dis_to_a += martsbonus;
4680 			} else if (martsweight <= martscapacity) {
4681 				martsbonus /= 2;
4682 				p_ptr->to_a += (martsbonus * (martscapacity - martsweight / 3) / (martscapacity + 40));
4683 				p_ptr->dis_to_a += (martsbonus * (martscapacity - martsweight / 3) / (martscapacity + 40));
4684 			}
4685 
4686 			martsbonus = ((marts - 13) / 3) * MARTIAL_ARTS_AC_ADJUST / 100;
4687 			martsweight = p_ptr->inventory[INVEN_OUTER].weight;
4688 			martscapacity = get_skill_scale(p_ptr, SKILL_MARTIAL_ARTS, 40);
4689 			if (!(p_ptr->inventory[INVEN_OUTER].k_idx) && (marts > 15)) {
4690 				p_ptr->to_a += martsbonus;
4691 				p_ptr->dis_to_a += martsbonus;
4692 			} else if ((martsweight <= martscapacity) && (marts > 15)) {
4693 				martsbonus /= 2;
4694 				p_ptr->to_a += (martsbonus * (martscapacity - martsweight / 3) / (martscapacity + 15));
4695 				p_ptr->dis_to_a += (martsbonus * (martscapacity - martsweight / 3) / (martscapacity + 15));
4696 			}
4697 
4698 			martsbonus = ((marts - 8) / 3) * MARTIAL_ARTS_AC_ADJUST / 100;
4699 			martsweight = p_ptr->inventory[INVEN_ARM].weight;
4700 			martscapacity = get_skill_scale(p_ptr, SKILL_MARTIAL_ARTS, 30);
4701 			if ((!p_ptr->inventory[INVEN_ARM].k_idx ||
4702 			    p_ptr->inventory[INVEN_ARM].tval != TV_SHIELD) && (marts > 10)) { /* for dual-wielders */
4703 				p_ptr->to_a += martsbonus;
4704 				p_ptr->dis_to_a += martsbonus;
4705 			} else if ((martsweight <= martscapacity) && (marts > 10)) {
4706 				martsbonus /= 2;
4707 				p_ptr->to_a += (martsbonus * (martscapacity - martsweight) / (martscapacity + 0));
4708 				p_ptr->dis_to_a += (martsbonus * (martscapacity - martsweight) / (martscapacity + 0));
4709 			}
4710 
4711 			martsbonus = (marts - 2) / 3 * MARTIAL_ARTS_AC_ADJUST / 100;
4712 			martsweight = p_ptr->inventory[INVEN_HEAD].weight;
4713 			martscapacity = get_skill_scale(p_ptr, SKILL_MARTIAL_ARTS, 50);
4714 			if (!(p_ptr->inventory[INVEN_HEAD].k_idx)&& (marts > 4)) {
4715 				p_ptr->to_a += martsbonus;
4716 				p_ptr->dis_to_a += martsbonus;
4717 			} else if ((martsweight <= martscapacity) && (marts > 4)) {
4718 				martsbonus /= 2;
4719 				p_ptr->to_a += (martsbonus * (martscapacity - martsweight / 3) / (martscapacity + 20));
4720 				p_ptr->dis_to_a += (martsbonus * (martscapacity - martsweight / 3) / (martscapacity + 20));
4721 			}
4722 
4723 			martsbonus = (marts / 2) * MARTIAL_ARTS_AC_ADJUST / 100;
4724 			martsweight = p_ptr->inventory[INVEN_HANDS].weight;
4725 			martscapacity = get_skill_scale(p_ptr, SKILL_MARTIAL_ARTS, 20);
4726 			if (!(p_ptr->inventory[INVEN_HANDS].k_idx)) {
4727 				p_ptr->to_a += martsbonus;
4728 				p_ptr->dis_to_a += martsbonus;
4729 			} else if (martsweight <= martscapacity) {
4730 				martsbonus /= 2;
4731 				p_ptr->to_a += (martsbonus * (martscapacity - martsweight / 2) / (martscapacity + 10));
4732 				p_ptr->dis_to_a += (martsbonus * (martscapacity - martsweight / 2) / (martscapacity + 10));
4733 			}
4734 
4735 			martsbonus = (marts / 3) * MARTIAL_ARTS_AC_ADJUST / 100;
4736 			martsweight = p_ptr->inventory[INVEN_FEET].weight;
4737 			martscapacity = get_skill_scale(p_ptr, SKILL_MARTIAL_ARTS, 45);
4738 			if (!(p_ptr->inventory[INVEN_FEET].k_idx)) {
4739 				p_ptr->to_a += martsbonus;
4740 				p_ptr->dis_to_a += martsbonus;
4741 			} else if (martsweight <= martscapacity) {
4742 				martsbonus /= 2;
4743 				p_ptr->to_a += (martsbonus * (martscapacity - martsweight / 3) / (martscapacity + 20));
4744 				p_ptr->dis_to_a += (martsbonus * (martscapacity - martsweight / 3) / (martscapacity + 20));
4745 			}
4746 		}
4747 	}
4748 
4749 	/* Actual Modifier Bonuses (Un-inflate stat bonuses) */
4750 	p_ptr->to_a += ((int)(adj_dex_ta[p_ptr->stat_ind[A_DEX]]) - 128);
4751 	p_ptr->to_d_melee += ((int)(adj_str_td[p_ptr->stat_ind[A_STR]]) - 128);
4752 #if 1 /* addition */
4753 	p_ptr->to_h_melee += ((int)(adj_dex_th[p_ptr->stat_ind[A_DEX]]) - 128);
4754 #else /* multiplication (percent) -- TODO FIRST!!: would need to be before all penalties but after marts/etc +hit boni! */
4755 	p_ptr->to_h_melee = ((int)((p_ptr->to_h_melee * adj_dex_th_mul[p_ptr->stat_ind[A_DEX]]) / 100));
4756 #endif
4757 //	p_ptr->to_d += ((int)(adj_str_td[p_ptr->stat_ind[A_STR]]) - 128);
4758 //	p_ptr->to_h += ((int)(adj_dex_th[p_ptr->stat_ind[A_DEX]]) - 128);
4759 //	p_ptr->to_h += ((int)(adj_str_th[p_ptr->stat_ind[A_STR]]) - 128);
4760 
4761 	/* Displayed Modifier Bonuses (Un-inflate stat bonuses) */
4762 	p_ptr->dis_to_a += ((int)(adj_dex_ta[p_ptr->stat_ind[A_DEX]]) - 128);
4763 //	p_ptr->dis_to_d += ((int)(adj_str_td[p_ptr->stat_ind[A_STR]]) - 128);
4764 //	p_ptr->dis_to_h += ((int)(adj_dex_th[p_ptr->stat_ind[A_DEX]]) - 128);
4765 //	p_ptr->dis_to_h += ((int)(adj_str_th[p_ptr->stat_ind[A_STR]]) - 128);
4766 
4767 	/* Modify ranged weapon boni. DEX now very important for to_hit */
4768 #if 1 /* addition */
4769 	p_ptr->to_h_ranged += ((int)(adj_dex_th[p_ptr->stat_ind[A_DEX]]) - 128);
4770 #else /* multiplication (percent) -- TODO FIRST!!: would need to be before all penalties but after marts/etc +hit boni! */
4771 	if (p_ptr->to_h_ranged > 0) p_ptr->to_h_ranged = ((int)((p_ptr->to_h_ranged * adj_dex_th_mul[p_ptr->stat_ind[A_DEX]]) / 100));
4772 	else p_ptr->to_h_ranged = ((int)((p_ptr->to_h_ranged * 100) / adj_dex_th_mul[p_ptr->stat_ind[A_DEX]]));
4773 #endif
4774 
4775 
4776 	/* Evaluate monster AC (if skin or armor etc) */
4777 	if (p_ptr->body_monster) {
4778 		if (p_ptr->pclass == CLASS_DRUID)
4779 			body = 1 + 3 + 0 + 0; /* 0 1 0 2 1 0 = typical ANIMAL pattern,
4780 						need to hardcode it here to balance
4781 						'Spectral tyrannosaur' form especially.
4782 						(weap, tors, arms, finger, head, leg) */
4783 		else if ((p_ptr->pclass == CLASS_SHAMAN) && mimic_shaman_fulleq(r_ptr->d_char))
4784 			body = 1 + 3 + 2 + 1; /* they can wear all items even in these 000000 forms! */
4785 		else /* normal mimicry */
4786 			body = (r_ptr->body_parts[BODY_HEAD] ? 1 : 0)
4787 				+ (r_ptr->body_parts[BODY_TORSO] ? 3 : 0)
4788 				+ (r_ptr->body_parts[BODY_ARMS] ? 2 : 0)
4789 				+ (r_ptr->body_parts[BODY_LEGS] ? 1 : 0);
4790 
4791 		toac = r_ptr->ac * 14 / (7 + body);
4792 		/* p_ptr->ac += toac;
4793 		p_ptr->dis_ac += toac; - similar to HP calculation: */
4794 		if (toac < (p_ptr->ac + p_ptr->to_a)) {
4795 			p_ptr->ac = (p_ptr->ac * 3) / 4;
4796 			p_ptr->to_a = ((p_ptr->to_a * 3) + toac) / 4;
4797 			p_ptr->dis_ac = (p_ptr->dis_ac * 3) / 4;
4798 			p_ptr->dis_to_a = ((p_ptr->dis_to_a * 3) + toac) / 4;
4799 		} else {
4800 			p_ptr->ac = (p_ptr->ac * 1) / 2;
4801 			p_ptr->to_a = ((p_ptr->to_a * 1) + (toac * 1)) / 2;
4802 			p_ptr->dis_ac = (p_ptr->dis_ac * 1) / 2;
4803 			p_ptr->dis_to_a = ((p_ptr->dis_to_a * 1) + (toac * 1)) / 2;
4804 		}
4805 		/*	p_ptr->dis_ac = (toac < p_ptr->dis_ac) ?
4806 		(((p_ptr->dis_ac * 2) + (toac * 1)) / 3) :
4807 		(((p_ptr->dis_ac * 1) + (toac * 1)) / 2);*/
4808 	}
4809 
4810 
4811 	/* -------------------- AC mods unaffected by body_monster: -------------------- */
4812 
4813 	/* Invulnerability */
4814 	if (p_ptr->invuln) {
4815 		p_ptr->to_a += 100;
4816 		p_ptr->dis_to_a += 100;
4817 	}
4818 
4819 	/* Temporary blessing */
4820 	if (p_ptr->blessed) {
4821 		p_ptr->to_a += p_ptr->blessed_power;
4822 		p_ptr->dis_to_a += p_ptr->blessed_power;
4823 		p_ptr->to_h += p_ptr->blessed_power / 2;
4824 		p_ptr->dis_to_h += p_ptr->blessed_power / 2;
4825 	}
4826 
4827 	/* Temporary shield */
4828 	if (p_ptr->shield) {
4829 		p_ptr->to_a += p_ptr->shield_power;
4830 		p_ptr->dis_to_a += p_ptr->shield_power;
4831 	}
4832 
4833 	if (p_ptr->combat_stance == 2) {
4834 		p_ptr->to_a -= 30;
4835 		p_ptr->dis_to_a -= 30;
4836 	}
4837 
4838 	if (p_ptr->mode & MODE_HARD) {
4839 		if (p_ptr->dis_to_a > 0) p_ptr->dis_to_a = (p_ptr->dis_to_a * 2) / 3;
4840 		if (p_ptr->to_a > 0) p_ptr->to_a = (p_ptr->to_a * 2) / 3;
4841 	}
4842 
4843 
4844 	/* Redraw armor (if needed) */
4845 	if ((p_ptr->dis_ac != old_dis_ac) || (p_ptr->dis_to_a != old_dis_to_a)) {
4846 		/* Redraw */
4847 		p_ptr->redraw |= (PR_ARMOR);
4848 		/* Window stuff */
4849 		p_ptr->window |= (PW_PLAYER);
4850 	}
4851 
4852 
4853 	/* Obtain the "hold" value */
4854 	hold = adj_str_hold[p_ptr->stat_ind[A_STR]];
4855 
4856 	/* Examine the "current bow" */
4857 	o_ptr = &p_ptr->inventory[INVEN_BOW];
4858 
4859 	/* Assume not heavy */
4860 	p_ptr->heavy_shoot = FALSE;
4861 
4862 	/* It is hard to carholdry a heavy bow */
4863 	if (o_ptr->k_idx && hold < o_ptr->weight / 10) {
4864 		/* Hard to wield a heavy bow */
4865 		p_ptr->to_h += 2 * (hold - o_ptr->weight / 10);
4866 		p_ptr->dis_to_h += 2 * (hold - o_ptr->weight / 10);
4867 
4868 		/* Heavy Bow */
4869 		p_ptr->heavy_shoot = TRUE;
4870 	}
4871 
4872 	/* Compute "extra shots" if needed */
4873 	if (o_ptr->k_idx && !p_ptr->heavy_shoot) {
4874 		int archery = get_archery_skill(p_ptr);
4875 
4876 		p_ptr->tval_ammo = 0;
4877 
4878 		/* Take note of required "tval" for missiles */
4879 		switch (o_ptr->sval) {
4880 		case SV_SLING:
4881 			p_ptr->tval_ammo = TV_SHOT;
4882 			break;
4883 		case SV_SHORT_BOW:
4884 		case SV_LONG_BOW:
4885 			p_ptr->tval_ammo = TV_ARROW;
4886 			break;
4887 		case SV_LIGHT_XBOW:
4888 		case SV_HEAVY_XBOW:
4889 			p_ptr->tval_ammo = TV_BOLT;
4890 			break;
4891 		}
4892 
4893 		if (archery != -1) {
4894 			p_ptr->to_h_ranged += get_skill_scale(p_ptr, archery, 25);
4895 			switch (archery) {
4896 			case SKILL_SLING:
4897 				p_ptr->num_fire += get_skill_scale(p_ptr, archery, 500) / 100;
4898 				csheet_boni[14].shot += get_skill_scale(p_ptr, archery, 500) / 100;
4899 				break;
4900 			case SKILL_BOW:
4901 				p_ptr->num_fire += get_skill_scale(p_ptr, archery, 500) / 125;
4902 				csheet_boni[14].shot += get_skill_scale(p_ptr, archery, 500) / 125;
4903 				break;
4904 			case SKILL_XBOW:
4905 #if 1
4906 				// Stagger the EM/ES instead of massive emphasis on 25/50 (Thanks, Vir)
4907 				if (get_skill_scale(p_ptr, archery, 500) >= 125) { //EM
4908 					p_ptr->xtra_might++;
4909 					csheet_boni[14].migh++;
4910 				}
4911 				if (get_skill_scale(p_ptr, archery, 500) >= 250) { //ES
4912 					p_ptr->num_fire++;
4913 					csheet_boni[14].shot++;
4914 				}
4915 				if (get_skill_scale(p_ptr, archery, 500) >= 375) { //EM
4916 					p_ptr->xtra_might++;
4917 					csheet_boni[14].migh++;
4918 				}
4919 				if (get_skill_scale(p_ptr, archery, 500) == 500) { //ES
4920 					p_ptr->num_fire++;
4921 					csheet_boni[14].shot++;
4922 				}
4923 #else
4924 				p_ptr->num_fire += get_skill_scale(p_ptr, archery, 500) / 250;
4925 				csheet_boni[14].shot += get_skill_scale(p_ptr, archery, 500) / 250;
4926 				p_ptr->xtra_might += get_skill_scale(p_ptr, archery, 500) / 250;
4927 				csheet_boni[14].migh += get_skill_scale(p_ptr, archery, 500) / 250;
4928 #endif
4929 				break;
4930 			case SKILL_BOOMERANG:
4931 				if (get_skill_scale(p_ptr, archery, 500) >= 500) { p_ptr->num_fire++; csheet_boni[14].shot++; }
4932 				if (get_skill_scale(p_ptr, archery, 500) >= 333) { p_ptr->num_fire++; csheet_boni[14].shot++; }
4933 				if (get_skill_scale(p_ptr, archery, 500) >= 166) { p_ptr->num_fire++; csheet_boni[14].shot++; }
4934 
4935 				/* Boomerang-mastery directly increases damage! - C. Blue */
4936 				p_ptr->to_d_ranged += get_skill_scale(p_ptr, archery, 20);
4937 				break;
4938 			}
4939 			if (archery != SKILL_BOOMERANG) {
4940 #if 1//pfft, too disrupting vs slingers to disable this I guess.. need to think harder of a good way :|
4941 /* temporarily disabled, need to talk first if we
4942    really want to boost the 50.000 skill this much,
4943    especially considering xbows who gain TWO xmight with this at once,
4944    but also with bows/slings which get ES _and_ EM at 50,
4945    rendering the power-scale of training the mastery skill
4946    very non-liner with this pull-up. */
4947 #if 1
4948 //Put less emphasis on ARCHERY (which only archers can get and more into the individual skill.
4949 //Make other archers more viable.
4950 				p_ptr->xtra_might += get_skill_scale(p_ptr, archery, 1);
4951 				csheet_boni[14].migh += get_skill_scale(p_ptr, archery, 1);
4952 #else
4953  				p_ptr->xtra_might += (get_skill(p_ptr, SKILL_ARCHERY) / 50);
4954 #endif
4955 #endif
4956 
4957 				p_ptr->to_d_ranged += get_skill_scale(p_ptr, SKILL_ARCHERY, 10);
4958 			}
4959 		}
4960 
4961 		/* Add in the "bonus shots" */
4962 		p_ptr->num_fire += extra_shots;
4963 
4964 		/* Require at least one shot */
4965 		if (p_ptr->num_fire < 1) p_ptr->num_fire = 1;
4966 
4967 /* Turn off the spr cap in rpg? -the_sandman */
4968 		/* Cap shots per round at 5 */
4969 /*		if (p_ptr->num_fire > 5) p_ptr->num_fire = 5;
4970 */
4971 		/* Other classes than archer or ranger have cap at 4 - the_sandman and mikaelh */
4972 /*		if (p_ptr->pclass != CLASS_ARCHER && p_ptr->pclass != CLASS_RANGER && p_ptr->num_fire > 4) p_ptr->num_fire = 4;
4973 */
4974 	}
4975 
4976 	/* Add in the "bonus spells" */
4977 	p_ptr->num_spell += extra_spells;
4978 
4979 
4980 	/* Examine the "tool" */
4981 	o_ptr = &p_ptr->inventory[INVEN_TOOL];
4982 
4983 	/* Boost digging skill by tool weight */
4984 	if (o_ptr->k_idx && o_ptr->tval == TV_DIGGING) {
4985 		p_ptr->skill_dig += (o_ptr->weight / 10);
4986 
4987 		/* Hack -- to_h/to_d added to digging (otherwise meanless) */
4988 		p_ptr->skill_dig += o_ptr->to_h;
4989 		p_ptr->skill_dig += o_ptr->to_d;
4990 
4991 		p_ptr->skill_dig += p_ptr->skill_dig *
4992 		    get_skill_scale(p_ptr, SKILL_DIG, 200) / 100;
4993 	}
4994 
4995 
4996 	/* Examine the "shield" */
4997 	o_ptr = &p_ptr->inventory[INVEN_ARM];
4998 	/* Assume not heavy */
4999 	p_ptr->heavy_shield = FALSE;
5000 	/* It is hard to hold a heavy shield */
5001 	if (o_ptr->k_idx && o_ptr->tval == TV_SHIELD && (hold < (o_ptr->weight / 10 - 4) * 7)) /* dual-wielder? */
5002 		p_ptr->heavy_shield = TRUE;
5003 
5004 #ifdef USE_BLOCKING
5005 	if (o_ptr->k_idx && o_ptr->tval == TV_SHIELD) { /* might be dual-wielder */
5006 		int malus;
5007  #ifdef USE_NEW_SHIELDS
5008 		p_ptr->shield_deflect = o_ptr->ac * 10; /* add a figure by multiplying by _10_ for more accuracy */
5009  #else
5010 		p_ptr->shield_deflect = 20 * (o_ptr->ac + 3); /* add a figure by multiplying by 2*_10_ for more accuracy */
5011  #endif
5012 		malus = (o_ptr->weight / 10 - 4) * 7 - hold;
5013 		p_ptr->shield_deflect /= malus > 0 ? 10 + (malus + 4) / 3 : 10;
5014 
5015 		/* adjust class-dependantly! */
5016 		switch (p_ptr->pclass) {
5017 		case CLASS_ADVENTURER: p_ptr->shield_deflect = (p_ptr->shield_deflect * 4 + 2) / 6; break;
5018 		case CLASS_WARRIOR: p_ptr->shield_deflect = p_ptr->shield_deflect; break;
5019 		case CLASS_PRIEST: p_ptr->shield_deflect = (p_ptr->shield_deflect * 3 + 3) / 6; break;
5020 		case CLASS_MAGE: p_ptr->shield_deflect = (p_ptr->shield_deflect * 2 + 4) / 6; break;
5021 		case CLASS_ARCHER: p_ptr->shield_deflect = (p_ptr->shield_deflect * 4 + 2) / 6; break;
5022 		case CLASS_ROGUE: p_ptr->shield_deflect = (p_ptr->shield_deflect * 4 + 2) / 6; break;
5023 		case CLASS_MIMIC: p_ptr->shield_deflect = (p_ptr->shield_deflect * 5 + 1) / 6; break;
5024 		case CLASS_RANGER: p_ptr->shield_deflect = (p_ptr->shield_deflect * 4 + 2) / 6; break;
5025 		case CLASS_PALADIN: p_ptr->shield_deflect = p_ptr->shield_deflect; break;
5026 		case CLASS_SHAMAN: p_ptr->shield_deflect = (p_ptr->shield_deflect * 3 + 3) / 6; break;
5027 		case CLASS_DRUID: p_ptr->shield_deflect = (p_ptr->shield_deflect * 4 + 2) / 6; break;
5028 		case CLASS_RUNEMASTER: p_ptr->shield_deflect = (p_ptr->shield_deflect * 4 + 2) / 6; break;
5029 		case CLASS_MINDCRAFTER: p_ptr->shield_deflect = (p_ptr->shield_deflect * 4 + 2) / 6; break;
5030 		}
5031 	}
5032 #endif
5033 
5034 
5035 	/* Examine the "main weapon" */
5036 	/* note- for dual-wield we don't need to run the main parry checks again on the secondary weapon,
5037 	   because you are not allowed to hold 2h or 1.5h weapons in secondary slot. this leaves only one
5038 	   possibility for dual-wield: 1h - which we can cover in a single test at the end - C. Blue */
5039 	o_ptr = &p_ptr->inventory[INVEN_WIELD];
5040 	/* if dual-wielder only has weapon in second hand, use that one! (assume left-handed person ;)) */
5041 	if (!o_ptr->k_idx && p_ptr->inventory[INVEN_ARM].k_idx && p_ptr->inventory[INVEN_ARM].tval != TV_SHIELD)
5042 		o_ptr = &p_ptr->inventory[INVEN_ARM];
5043 	/* Assume not heavy */
5044 	p_ptr->heavy_wield = FALSE;
5045 #ifdef USE_PARRYING
5046 	/* Do we have a weapon equipped at all? */
5047 	if (o_ptr->k_idx) {
5048 		if (k_info[o_ptr->k_idx].flags4 & TR4_MUST2H) {
5049 			p_ptr->weapon_parry = 10 + get_skill_scale(p_ptr, SKILL_MASTERY, 20);
5050 		} else if (k_info[o_ptr->k_idx].flags4 & TR4_SHOULD2H) {
5051 			if (!p_ptr->inventory[INVEN_ARM].k_idx) p_ptr->weapon_parry = 10 + get_skill_scale(p_ptr, SKILL_MASTERY, 15);
5052 			else p_ptr->weapon_parry = 3 + get_skill_scale(p_ptr, SKILL_MASTERY, 7);
5053 		} else if (k_info[o_ptr->k_idx].flags4 & TR4_COULD2H) {
5054 			if (!p_ptr->inventory[INVEN_ARM].k_idx || !p_ptr->inventory[INVEN_WIELD].k_idx)
5055 				p_ptr->weapon_parry = 10 + get_skill_scale(p_ptr, SKILL_MASTERY, 10);
5056 			else p_ptr->weapon_parry = 5 + get_skill_scale(p_ptr, SKILL_MASTERY, 10);
5057 		} else {
5058 			p_ptr->weapon_parry = 5 + get_skill_scale(p_ptr, SKILL_MASTERY, 10);
5059 		}
5060 		/* for dual-wielders, get a parry bonus for second weapon: */
5061 		if (p_ptr->dual_wield && p_ptr->dual_mode && !p_ptr->rogue_heavyarmor)
5062 			//p_ptr->weapon_parry += 5 + get_skill_scale(p_ptr, SKILL_MASTERY, 5);//was +0(+10)
5063 			p_ptr->weapon_parry += 10;//pretty high, because independent of mastery skill^^
5064 
5065 		/* adjust class-dependantly! */
5066 		switch (p_ptr->pclass) {
5067 		case CLASS_ADVENTURER: p_ptr->weapon_parry = (p_ptr->weapon_parry * 4 + 2) / 6; break;
5068 		case CLASS_WARRIOR: p_ptr->weapon_parry = p_ptr->weapon_parry; break;
5069 		case CLASS_PRIEST: p_ptr->weapon_parry = (p_ptr->weapon_parry * 3 + 3) / 6; break;
5070 		case CLASS_MAGE: p_ptr->weapon_parry = (p_ptr->weapon_parry * 2 + 4) / 6; break;
5071 		case CLASS_ARCHER: p_ptr->weapon_parry = (p_ptr->weapon_parry * 4 + 2) / 6; break;
5072 		case CLASS_ROGUE: p_ptr->weapon_parry = p_ptr->weapon_parry; break;
5073 		case CLASS_MIMIC: p_ptr->weapon_parry = (p_ptr->weapon_parry * 5 + 1) / 6; break;
5074 		case CLASS_RANGER: p_ptr->weapon_parry = p_ptr->weapon_parry; break;
5075 		case CLASS_PALADIN: p_ptr->weapon_parry = (p_ptr->weapon_parry * 5 + 1) / 6; break;
5076 		case CLASS_SHAMAN: p_ptr->weapon_parry = (p_ptr->weapon_parry * 3 + 3) / 6; break;
5077 		case CLASS_DRUID: p_ptr->weapon_parry = (p_ptr->weapon_parry * 4 + 2) / 6; break;
5078 		case CLASS_RUNEMASTER: p_ptr->weapon_parry = (p_ptr->weapon_parry * 4 + 2) / 6; break;
5079 		case CLASS_MINDCRAFTER: p_ptr->weapon_parry = (p_ptr->weapon_parry * 5 + 1) / 6; break;
5080 		}
5081 	}
5082 #endif
5083 
5084 
5085 	/* It is hard to hold a heavy weapon */
5086 	o_ptr = &p_ptr->inventory[INVEN_WIELD];
5087 	if (o_ptr->k_idx && hold < o_ptr->weight / 10) {
5088 		/* Hard to wield a heavy weapon */
5089 		p_ptr->to_h += 2 * (hold - o_ptr->weight / 10);
5090 		p_ptr->dis_to_h += 2 * (hold - o_ptr->weight / 10);
5091 
5092 		if (p_ptr->weapon_parry > 0) p_ptr->weapon_parry /= 2; /* easy for now */
5093 
5094 		/* Heavy weapon */
5095 		p_ptr->heavy_wield = TRUE;
5096 	}
5097 
5098 	/* dual-wield */
5099 	/* It is hard to hold a heavy weapon */
5100 	o_ptr = &p_ptr->inventory[INVEN_ARM];
5101 	if (o_ptr->k_idx && o_ptr->tval != TV_SHIELD && hold < o_ptr->weight / 10) {
5102 		/* Hard to wield a heavy weapon */
5103 		p_ptr->to_h += 2 * (hold - o_ptr->weight / 10);
5104 		p_ptr->dis_to_h += 2 * (hold - o_ptr->weight / 10);
5105 
5106 		if (p_ptr->weapon_parry > 0) p_ptr->weapon_parry /= 2; /* easy for now */
5107 
5108 		/* Heavy weapon */
5109 		p_ptr->heavy_wield = TRUE;
5110 	}
5111 
5112 
5113 	/* Normal weapons */
5114 	o_ptr = &p_ptr->inventory[INVEN_WIELD];
5115 	o2_ptr = &p_ptr->inventory[INVEN_ARM];
5116 	if ((o_ptr->k_idx || (o2_ptr->k_idx && o2_ptr->tval != TV_SHIELD)) && !p_ptr->heavy_wield) {
5117 		int lev1 = -1, lev2 = -1;
5118 
5119 		p_ptr->num_blow = calc_blows_weapons(Ind);
5120 
5121 		/* Get intrinsic blow boni for column display (so everything adds up) */
5122 		if (get_weaponmastery_skill(p_ptr, o_ptr) != -1)
5123 			csheet_boni[14].blow += get_skill_scale(p_ptr, get_weaponmastery_skill(p_ptr, o_ptr), 2);
5124 
5125 		p_ptr->num_blow += p_ptr->extra_blows;
5126 		/* Boost blows with masteries */
5127 		/* note for dual-wield: instead of using two different p_ptr->to_h/d_melee for each
5128 		   weapon, we just average the mastery boni we'd receive on each - C. Blue */
5129 		if (get_weaponmastery_skill(p_ptr, &p_ptr->inventory[INVEN_WIELD]) != -1)
5130 			lev1 = get_skill(p_ptr, get_weaponmastery_skill(p_ptr, &p_ptr->inventory[INVEN_WIELD]));
5131 		if (get_weaponmastery_skill(p_ptr, &p_ptr->inventory[INVEN_ARM]) != -1)
5132 			lev2 = get_skill(p_ptr, get_weaponmastery_skill(p_ptr, &p_ptr->inventory[INVEN_ARM]));
5133 		/* if we don't wear any weapon at all, we get 0 bonus */
5134 		if (lev1 == -1 && lev2 == -1) lev2 = 0;
5135 		/* if we don't dual-wield, we mustn't average things */
5136 		if (lev1 == -1) lev1 = lev2;
5137 		if (lev2 == -1) lev2 = lev1;
5138 		/* average for dual-wield */
5139 		if (p_ptr->dual_mode) {
5140 			p_ptr->to_h_melee += ((lev1 + lev2) / 2);
5141 			p_ptr->to_d_melee += ((lev1 + lev2) / 6);
5142 		} else { /* treat main-hand mode basically like weapon+shield, in terms of accuracy/damage (ie no loss) */
5143 			p_ptr->to_h_melee += lev1;
5144 			p_ptr->to_d_melee += lev1 / 3;
5145 		}
5146 	}
5147 
5148 
5149 	/* Different calculation for monks with empty hands */
5150 	if (get_skill(p_ptr, SKILL_MARTIAL_ARTS) && !o_ptr->k_idx &&
5151 #ifndef ENABLE_MA_BOOMERANG
5152 	    !(p_ptr->inventory[INVEN_BOW].k_idx)) {
5153 #else
5154 	    p_ptr->inventory[INVEN_BOW].tval != TV_BOW) {
5155 #endif
5156 		int marts = get_skill_scale(p_ptr, SKILL_MARTIAL_ARTS, 50);
5157 		p_ptr->num_blow = 0;
5158 
5159 		/*the_sandman for the RPG server (might as well stay for all servers ^^ - C. Blue) */
5160 		if (marts >  0) { p_ptr->num_blow++; csheet_boni[14].blow++; }
5161 		if (marts >  9) { p_ptr->num_blow++; csheet_boni[14].blow++; }
5162 		if (marts > 19) { p_ptr->num_blow++; csheet_boni[14].blow++; }
5163 		if (marts > 29) { p_ptr->num_blow++; csheet_boni[14].blow++; }
5164 //		if (marts > 34) p_ptr->num_blow++; csheet_boni[14].blow++; } /* This _could_ be added if really required */
5165 		if (marts > 39) { p_ptr->num_blow++; csheet_boni[14].blow++; }
5166 		if (marts > 44) { p_ptr->num_blow++; csheet_boni[14].blow++; }
5167 		if (marts > 49) { p_ptr->num_blow++; csheet_boni[14].blow++; }
5168 
5169 		if (monk_heavy_armor(p_ptr)) p_ptr->num_blow /= 2;
5170 
5171 		p_ptr->num_blow += 1 + p_ptr->extra_blows;
5172 
5173 		if (!monk_heavy_armor(p_ptr)) {
5174 			p_ptr->to_h_melee += (marts * 4) / 2;//was *3/2
5175 
5176 #if 1 /* new boost */
5177 			p_ptr->to_d_melee += ((marts * 3) / 5); /* new MA boost */
5178 #elif 1 /* experimental */
5179 			p_ptr->to_d_melee += ((marts * 2) / 5); /* for better form influence of MA mimics */
5180 #else
5181 			p_ptr->to_d_melee += (marts / 2); /* was 3 */
5182 #endif
5183 
5184 			/* Testing: added a new bonus. No more single digit dmg at lvl 20, I hope, esp as warrior. the_sandman */
5185 			/* changed by C. Blue, so it's available to mimics too */
5186 #ifndef MARTIAL_TO_D_HACK
5187 			p_ptr->to_d_melee += 20 - (400 / (marts + 20)); /* get strong quickly and early - quite special ;-o */
5188 #else /* Instead of to_d_melee, we use to_d here. The idea is that shapechanger shouldn't get too low +dam from high-power forms. ugly hack :( */
5189 			/* actually we shouldn't do this. AC can no longer be reduced by weak forms,
5190 			   so weapons shouldn't count as part of the form either, hence MA dmg fully counts as part of the form now.. */
5191 			p_ptr->to_d += 20 - (400 / (marts + 20)); /* get strong quickly and early - quite special ;-o */
5192 			p_ptr->dis_to_d += 20 - (400 / (marts + 20));
5193 #endif
5194 		}
5195 
5196 	} else { /* make cumber_armor have effect on to-hit for non-martial artists too - C. Blue */
5197 		if (p_ptr->cumber_armor && (p_ptr->to_h_melee > 0)) p_ptr->to_h_melee = (p_ptr->to_h_melee * 2) / 3;
5198 	}
5199 
5200 //	p_ptr->pspeed += get_skill_scale(p_ptr, SKILL_AGILITY, 10);
5201 	if (p_ptr->cumber_armor) {
5202 		p_ptr->pspeed += get_skill_scale(p_ptr, SKILL_SNEAKINESS, 4);
5203 		csheet_boni[14].spd += get_skill_scale(p_ptr, SKILL_SNEAKINESS, 4);
5204 	} else {
5205 		p_ptr->pspeed += get_skill_scale(p_ptr, SKILL_SNEAKINESS, 7);
5206 		csheet_boni[14].spd += get_skill_scale(p_ptr, SKILL_SNEAKINESS, 7);
5207 	}
5208 
5209 	p_ptr->redraw |= (PR_SPEED | PR_EXTRA) ;
5210 
5211 	/* Hard mode */
5212 	if ((p_ptr->mode & MODE_HARD)) {
5213 		if (p_ptr->pspeed > 110) {
5214 			int speed = p_ptr->pspeed - 110;
5215 			speed = (speed + 1) / 2;
5216 			p_ptr->pspeed = speed + 110;
5217 		}
5218 		if (p_ptr->num_blow > 1) p_ptr->num_blow--;
5219 	}
5220 
5221 	/* PvP mode */
5222 	if ((p_ptr->mode & MODE_PVP)) {
5223 		/* don't reduce +speed bonus from sneakiness skill */
5224 		if (p_ptr->pspeed > 110) {
5225 			int sneak = get_skill_scale(p_ptr, SKILL_SNEAKINESS, 7), speed = p_ptr->pspeed - 110 - sneak;
5226 			speed = (speed + 1) / 2;
5227 			p_ptr->pspeed = speed + 110 + sneak;
5228 		}
5229 
5230 		p_ptr->to_d = (p_ptr->to_d + 1) / 2;
5231 		p_ptr->dis_to_d = (p_ptr->dis_to_d + 1) / 2;
5232 
5233 		p_ptr->to_h = (p_ptr->to_h + 1) / 2;
5234 		p_ptr->dis_to_h = (p_ptr->dis_to_h + 1) / 2;
5235 
5236 #if 0
5237 		p_ptr->to_a = (p_ptr->to_a + 1) / 2;
5238 		p_ptr->dis_to_a = (p_ptr->dis_to_a + 1) / 2;
5239 #endif
5240 
5241 		p_ptr->xtra_crit = (p_ptr->xtra_crit + 2) / 3;
5242 
5243 		/* extra_blows, extra_might, extra_shots */
5244 	}
5245 
5246 	/* A perma_cursed weapon stays even in weapon-less body form, reduce blows for that: */
5247 	if ((p_ptr->inventory[INVEN_WIELD].k_idx ||
5248 	    (p_ptr->inventory[INVEN_ARM].k_idx && p_ptr->inventory[INVEN_ARM].tval != TV_SHIELD)) &&
5249 	    (!r_info[p_ptr->body_monster].body_parts[BODY_WEAPON]) &&
5250 	    (p_ptr->num_blow > 1)) p_ptr->num_blow = 1;
5251 
5252 	/* Weaponmastery bonus to damage - not for MA!- C. Blue */
5253 	if (get_skill(p_ptr, SKILL_MASTERY) && o_ptr->k_idx) {
5254 		int lev = get_skill(p_ptr, SKILL_MASTERY);
5255 		p_ptr->to_h_melee += lev / 3;
5256 		p_ptr->to_d_melee += lev / 10;
5257 	}
5258 
5259 	if (get_skill(p_ptr, SKILL_DODGE) && !p_ptr->rogue_heavyarmor)
5260 //	if (!(r_ptr->flags1 & RF1_NEVER_MOVE));		// not for now
5261 	{
5262 #ifndef NEW_DODGING /* reworking dodge, see #else.. */
5263 		/* use a long var temporarily to handle v.high total_weight */
5264 		long temp_chance;
5265 		/* Get the armor weight */
5266 		int cur_wgt = armour_weight(p_ptr); /* change to worn_armour_weight if ever reactivated, and possibly adjust values */
5267 		/* Base dodge chance */
5268 		temp_chance = get_skill_scale(p_ptr, SKILL_DODGE, 150);
5269 		/* Armor weight bonus/penalty */
5270 //		p_ptr->dodge_level -= cur_wgt * 2;
5271 		temp_chance -= cur_wgt;		/* XXX adjust me */
5272 		/* Encumberance bonus/penalty */
5273 		temp_chance -= p_ptr->total_weight / 100;
5274 		/* Penalty for bad conditions */
5275 		temp_chance -= UNAWARENESS(p_ptr);
5276 		/* never below 0 */
5277 		if (temp_chance < 0) temp_chance = 0;
5278 		/* write long back to int */
5279 		p_ptr->dodge_level = temp_chance;
5280 #else /* reworking dodge here - C. Blue */
5281 		/* I think it's cool to have a skill which for once doesn't depend on friggin armour_weight,
5282 		   but on total weight for a change. Cool variation. - C. Blue */
5283 		/* also see new helper function apply_dodge_chance() */
5284 
5285 		/* ok, different idea: Treating inventory+equipment separately. Added 'equip_weight' */
5286 		/* inven = 50.0 without loot/books, equip ~ 25.0 with light stuff, non-armour 15~30 (digger y/n) */
5287 		/* rules here: backpack grows exponentially; non-weapons grow exponentially; weapons grow linear;
5288 		               also special is that although backpack and non-weapons grow similar, they grow separately! */
5289 		/* note: rings, amulet, light source and tool are simplifiedly counted to "weapons" here */
5290 		long int e = equip_weight(p_ptr), w = e - armour_weight(p_ptr), i = p_ptr->total_weight - e; /* possibly change to worn_armour_weight, but not really much difference/needed imho - C. Blue */
5291 		e = e - w;
5292 
5293 		/* prevent any weird overflows if 'someone' collects gronds */
5294 		if (i >= 5000) i = 1;
5295 		else {
5296 			//i = i / 5 + 10; /* 0:-0 25:-2 50:-8 75:-18 100:-31 125:-48 150:-68 */
5297 			i = i / 7 + 10; /* 0:-0 25:-1 50:-4 75:-9 100:-16 125:-25 150:-35 */
5298 			i = (i * i) / 1400;
5299 
5300 			e = e / 8 + 10; /* -0...-6 (up to 15.0 lb armour weight; avg -3) */
5301 			e = (e * e) / 100 - 1;
5302 
5303 			w = w / 50; /* -0...-11 (avg -3; 2x heavy 1-h + mattock + misc items. note: ammo can get heavy too!) */
5304 
5305 			i = 100 - i - e - w;
5306 		}
5307 
5308 		i = (i * 100) / (100 + UNAWARENESS(p_ptr) * 4);
5309 		/* fix bottom limit (1) */
5310 		if (i < 1) i = 1; /* minimum, everyone may dodge even if not skilled :) */
5311 		/* fix top limit (100) - just paranoia: if above calculations were correct we can't go above 100. */
5312 		if (i > 100) i = 100;
5313 		/* write back to int */
5314 		p_ptr->dodge_level = i;
5315 #endif
5316 	}
5317 
5318 	/* Assume okay */
5319 	p_ptr->icky_wield = FALSE;
5320 	p_ptr->awkward_wield = FALSE;
5321 	p_ptr->easy_wield = FALSE;
5322 	p_ptr->awkward_shoot = FALSE;
5323 
5324 	/* 2handed weapon and shield = less damage */
5325 //	if (inventory[INVEN_WIELD + i].k_idx && inventory[INVEN_ARM + i].k_idx)
5326 	if (p_ptr->inventory[INVEN_WIELD].k_idx && p_ptr->inventory[INVEN_ARM].k_idx) {
5327 		/* Extract the item flags */
5328 		object_flags(&p_ptr->inventory[INVEN_WIELD], &f1, &f2, &f3, &f4, &f5, &f6, &esp);
5329 
5330 		if (f4 & TR4_SHOULD2H) {
5331 			/* Reduce the real bonuses */
5332 			if (p_ptr->to_h > 0) p_ptr->to_h = (2 * p_ptr->to_h) / 3;
5333 			if (p_ptr->to_d > 0) p_ptr->to_d = (2 * p_ptr->to_d) / 3;
5334 
5335 			/* Reduce the mental bonuses */
5336 			if (p_ptr->dis_to_h > 0) p_ptr->dis_to_h = (2 * p_ptr->dis_to_h) / 3;
5337 			if (p_ptr->dis_to_d > 0) p_ptr->dis_to_d = (2 * p_ptr->dis_to_d) / 3;
5338 
5339 			/* Reduce the weaponmastery bonuses */
5340 			if (p_ptr->to_h_melee > 0) p_ptr->to_h_melee = (2 * p_ptr->to_h_melee) / 3;
5341 			if (p_ptr->to_d_melee > 0) p_ptr->to_d_melee = (2 * p_ptr->to_d_melee) / 3;
5342 
5343 			p_ptr->awkward_wield = TRUE;
5344 		}
5345 	}
5346 	if (p_ptr->inventory[INVEN_WIELD].k_idx && !p_ptr->inventory[INVEN_ARM].k_idx) {
5347 		object_flags(&p_ptr->inventory[INVEN_WIELD], &f1, &f2, &f3, &f4, &f5, &f6, &esp);
5348 		if (f4 & TR4_COULD2H) p_ptr->easy_wield = TRUE;
5349 	}
5350 	/* for dual-wield..*/
5351 	if (!p_ptr->inventory[INVEN_WIELD].k_idx &&
5352 	    p_ptr->inventory[INVEN_ARM].k_idx && p_ptr->inventory[INVEN_ARM].tval != TV_SHIELD) {
5353 		object_flags(&p_ptr->inventory[INVEN_ARM], &f1, &f2, &f3, &f4, &f5, &f6, &esp);
5354 		if (f4 & TR4_COULD2H) p_ptr->easy_wield = TRUE;
5355 	}
5356 
5357 	/* Equipment weight affects shooting */
5358 	/* allow malus even */
5359 	/* examples: 10.0: 0, 20.0: -4, 30.0: -13, 40.0: -32, 47.0: -50 cap */
5360 	i = armour_weight(p_ptr) / 10;
5361 	i = (i * i * i) / 2000;
5362 	if (i > 50) i = 50; /* reached at 470.0 lb */
5363 	p_ptr->to_h_ranged -= i;
5364 
5365 	/* also: shield and ranged weapon = less accuracy for ranged weapon! */
5366 	/* dual-wield currently does not affect shooting (!) */
5367 	if (p_ptr->inventory[INVEN_BOW].k_idx && p_ptr->inventory[INVEN_ARM].k_idx
5368 	    && p_ptr->inventory[INVEN_ARM].tval == TV_SHIELD) {
5369 		/* can't aim well while carrying a shield on the arm! */
5370 
5371 		/* the following part punishes all +hit/+dam for ranged weapons;
5372 		   trained fighters suffer more than untrained ones! - C. Blue */
5373 		if (p_ptr->to_h_ranged >= 25) p_ptr->to_h_ranged = 0;
5374 		/* note: it's to be interpreted as "larger shield -> harder to shoot", not "heavier", ie STR doesn't matter here: */
5375 		else if (p_ptr->to_h_ranged >= 0) p_ptr->to_h_ranged -= 10 + (p_ptr->to_h_ranged * (160 + p_ptr->inventory[INVEN_ARM].weight) / 350); /* 3/5..4/5 depending on shield */
5376 		else p_ptr->to_h_ranged -= 10;
5377 
5378 		p_ptr->awkward_shoot = TRUE;
5379 	}
5380 
5381 	/* Priest weapon penalty for non-blessed edged weapons */
5382 	if (p_ptr->inventory[INVEN_WIELD].k_idx &&
5383 	    (p_ptr->pclass == CLASS_PRIEST) && (!p_ptr->bless_blade) &&
5384 	    ((o_ptr->tval == TV_SWORD) || (o_ptr->tval == TV_POLEARM) ||
5385 	    (o_ptr->tval == TV_AXE))) {
5386 		/* Reduce the real bonuses */
5387 		/*p_ptr->to_h -= 2;
5388 		p_ptr->to_d -= 2;*/
5389 		p_ptr->to_h = p_ptr->to_h * 3 / 5;
5390 		p_ptr->to_d = p_ptr->to_d * 3 / 5;
5391 		p_ptr->to_h_melee = p_ptr->to_h_melee * 3 / 5;
5392 		p_ptr->to_d_melee = p_ptr->to_d_melee * 3 / 5;
5393 
5394 		/* Reduce the mental bonuses */
5395 		/*p_ptr->dis_to_h -= 2;
5396 		p_ptr->dis_to_d -= 2;*/
5397 		p_ptr->dis_to_h = p_ptr->dis_to_h * 3 / 5;
5398 		p_ptr->dis_to_d = p_ptr->dis_to_d * 3 / 5;
5399 
5400 		/* Icky weapon */
5401 		p_ptr->icky_wield = TRUE;
5402 	}
5403 
5404 	if (p_ptr->body_monster) {
5405 		d = 0;
5406 		for (i = 0; i < 4; i++) {
5407 			j = (r_ptr->blow[i].d_dice * r_ptr->blow[i].d_side);
5408 			j += r_ptr->blow[i].d_dice;
5409 			j /= 2;
5410 
5411 			d += j; /* adding up average monster damage per round */
5412 		}
5413 
5414 		/* GWoP: 472, GB: 270, Green DR: 96 */
5415 		/* GWoP: 254, GT: 364, GB: 149, GDR: 56 */
5416 		/* Quarter the damage and cap against 150 (unreachable though)
5417 		- even The Destroyer form would reach just 138 ;) */
5418 		d /= 4; /* average monster damage per blow */
5419 		/* GWoP: 63, GT: 91, GB: 37, GDR: 14 */
5420 #ifndef MIMIC_TO_D_DENTHACK /* a bit too little distinguishment for high-dam MA forms (Jabberwock vs Maulotaur for druids -> almost NO difference!) */
5421 		//d = (3200 / ((900 / (d + 4)) + 22)) - 10; //still too high
5422 		//d = (3200 / ((800 / (d + 4)) + 22)) - 20; //not enough, but on the way
5423 		//d = (2850 / ((650 / (d + 4)) + 22)) - 20; //not quite there yet
5424 		//d = (2500 / ((500 / (d + 4)) + 22)) - 20; //final target: Aim at +27 to-dam increase, which is still a lot --still too high ~~
5425 		d = (2200 / ((250 / (d + 4)) + 22)) - 20;
5426 		//d = (2000 / ((130 / (d + 4)) + 22)) - 20;//too little +dam increase
5427 #else /* add a 'dent' for '08/15 forms' :-p to help Jabberwock shine moar vs Maulotaur */
5428 		/* problem: these won't cut it - need cubic splines or something..
5429 		   Goal: rise quickly, stay flat in mid-range, increase again in top range but cap quickly. */
5430 		/* mhhh, instead let's try to subtract one polynomial from another, to add a "dent" (downwards) into the power curve
5431 		   at 'common/boring' monster damage ranges (Maulotaur for example, although slightly better than most lame average^^) */
5432 		//WRONG: this formula was for double values of d, oops (as if Maulo had 55 and Jabber 112)
5433 		//d = (2500 / ((500 / (d + 4)) + 22)) - 20 - 10000 / ((d - 50) * (d - 50) + 490);
5434 		//Maulo@25, Jabber@55, this seems fine:
5435 		//d = (2500 / ((500 / (d + 4)) + 22)) - 20 - 700 / ((d - 25) * (d - 25) + 70);//geez :/ it's the Godzilla of the the mimic formulas I think..
5436 		//d = (2500 / ((500 / (d + 4)) + 22)) - 20 - 1300 / ((d - 26) * (d - 26) + 90);//was ok
5437 		d = (2200 / ((250 / (d + 4)) + 22)) - 20 - 950 / ((d - 25) * (d - 25) + 100);
5438 		//d = (2000 / ((130 / (d + 4)) + 22)) - 20 - 650 / ((d - 25) * (d - 25) + 90);//too little
5439 #endif
5440 
5441 		/* Calculate new averaged to-dam bonus */
5442 		if (d < p_ptr->to_d_melee)
5443 #ifndef MIMICRY_BOOST_WEAK_FORM
5444 			p_ptr->to_d_melee = (p_ptr->to_d_melee * 5 + d * 2) / 7;
5445 		else
5446 #else
5447 			d = p_ptr->to_d_melee;
5448 #endif
5449 			p_ptr->to_d_melee = (p_ptr->to_d_melee + d) / 2;
5450 	}
5451 
5452 
5453 #if 0 /* disabled atm (it's already not easy to find two weapons that both deal great damage) */
5454 	/* dual-wielding gets a slight to-hit malus */
5455 	if (p_ptr->dual_wield && p_ptr->dual_mode) p_ptr->to_h_melee = (p_ptr->to_h_melee * 17) / 20; /* 85% */
5456 #endif
5457 
5458 
5459 	/* Note that stances currently factor in AFTER mimicry effect has been calculated!
5460 	   Reason I chose this for now is that currently mimicry does not effect shield_deflect,
5461 	   but does affect to_h and to_d. This would cause odd balance, so this way neither
5462 	   shield_deflect nor to_h/to_d are affected. Might need fixing/adjusting later. - C. Blue */
5463 #ifdef ENABLE_STANCES
5464  #ifdef USE_BLOCKING /* need blocking to make use of defensive stance */
5465 		if ((p_ptr->combat_stance == 1) &&
5466 		    (p_ptr->inventory[INVEN_ARM].tval == TV_SHIELD)) switch (p_ptr->combat_stance_power) {
5467 			/* note that defensive stance also increases chance to actually prefer shield over parrying in melee.c */
5468 			case 0: p_ptr->shield_deflect += 8;
5469 				p_ptr->dis_to_d = (p_ptr->dis_to_d * 7) / 10;
5470 				p_ptr->to_d = (p_ptr->to_d * 7) / 10;
5471 				p_ptr->to_d_melee = (p_ptr->to_d_melee * 7) / 10;
5472 				p_ptr->to_d_ranged = (p_ptr->to_d_ranged * 5) / 10;
5473 				break;
5474 			case 1: p_ptr->shield_deflect += 10;
5475 				p_ptr->dis_to_d = (p_ptr->dis_to_d * 7) / 10;
5476 				p_ptr->to_d = (p_ptr->to_d * 7) / 10;
5477 				p_ptr->to_d_melee = (p_ptr->to_d_melee * 7) / 10;
5478 				p_ptr->to_d_ranged = (p_ptr->to_d_ranged * 5) / 10;
5479 				break;
5480 			case 2: p_ptr->shield_deflect += 12;
5481 				p_ptr->dis_to_d = (p_ptr->dis_to_d * 7) / 10;
5482 				p_ptr->to_d = (p_ptr->to_d * 7) / 10;
5483 				p_ptr->to_d_melee = (p_ptr->to_d_melee * 7) / 10;
5484 				p_ptr->to_d_ranged = (p_ptr->to_d_ranged * 5) / 10;
5485 				break;
5486 			case 3: p_ptr->shield_deflect += 20;
5487 				p_ptr->dis_to_d = (p_ptr->dis_to_d * 8) / 10;
5488 				p_ptr->to_d = (p_ptr->to_d * 8) / 10;
5489 				p_ptr->to_d_melee = (p_ptr->to_d_melee * 8) / 10;
5490 				p_ptr->to_d_ranged = (p_ptr->to_d_ranged * 5) / 10;
5491 				break;
5492 		}
5493  #endif
5494  #ifdef USE_PARRYING /* need parrying to make use of offensive stance */
5495 		if (p_ptr->combat_stance == 2) switch (p_ptr->combat_stance_power) {
5496 			case 0: p_ptr->weapon_parry = (p_ptr->weapon_parry * 2) / 10;
5497 				p_ptr->dodge_level = (p_ptr->dodge_level * 2) / 10;
5498 				break;
5499 			case 1: p_ptr->weapon_parry = (p_ptr->weapon_parry * 3) / 10;
5500 				p_ptr->dodge_level = (p_ptr->dodge_level * 3) / 10;
5501 				break;
5502 			case 2: p_ptr->weapon_parry = (p_ptr->weapon_parry * 4) / 10;
5503 				p_ptr->dodge_level = (p_ptr->dodge_level * 4) / 10;
5504 				break;
5505 			case 3: p_ptr->weapon_parry = (p_ptr->weapon_parry * 5) / 10;
5506 				p_ptr->dodge_level = (p_ptr->dodge_level * 5) / 10;
5507 				break;
5508 		}
5509   #ifdef ALLOW_SHIELDLESS_DEFENSIVE_STANCE
5510 		else if ((p_ptr->combat_stance == 1) &&
5511 		    (p_ptr->inventory[INVEN_ARM].tval != TV_SHIELD)) switch (p_ptr->combat_stance_power) {
5512 			case 0: p_ptr->weapon_parry = (p_ptr->weapon_parry * 13) / 10;
5513 				p_ptr->dis_to_d = (p_ptr->dis_to_d * 6) / 10;
5514 				p_ptr->to_d = (p_ptr->to_d * 6) / 10;
5515 				p_ptr->to_d_melee = (p_ptr->to_d_melee * 6) / 10;
5516 				p_ptr->to_d_ranged = (p_ptr->to_d_ranged * 5) / 10;
5517 				break;
5518 			case 1: p_ptr->weapon_parry = (p_ptr->weapon_parry * 13) / 10;
5519 				p_ptr->dis_to_d = (p_ptr->dis_to_d * 7) / 10;
5520 				p_ptr->to_d = (p_ptr->to_d * 7) / 10;
5521 				p_ptr->to_d_melee = (p_ptr->to_d_melee * 7) / 10;
5522 				p_ptr->to_d_ranged = (p_ptr->to_d_ranged * 5) / 10;
5523 				break;
5524 			case 2: p_ptr->weapon_parry = (p_ptr->weapon_parry * 14) / 10;
5525 				p_ptr->dis_to_d = (p_ptr->dis_to_d * 7) / 10;
5526 				p_ptr->to_d = (p_ptr->to_d * 7) / 10;
5527 				p_ptr->to_d_melee = (p_ptr->to_d_melee * 7) / 10;
5528 				p_ptr->to_d_ranged = (p_ptr->to_d_ranged * 5) / 10;
5529 				break;
5530 			case 3: p_ptr->weapon_parry = (p_ptr->weapon_parry * 17) / 10;
5531 				p_ptr->dis_to_d = (p_ptr->dis_to_d * 7) / 10;
5532 				p_ptr->to_d = (p_ptr->to_d * 7) / 10;
5533 				p_ptr->to_d_melee = (p_ptr->to_d_melee * 7) / 10;
5534 				p_ptr->to_d_ranged = (p_ptr->to_d_ranged * 5) / 10;
5535 				break;
5536 		}
5537   #endif
5538  #endif
5539 #endif
5540 
5541 
5542 
5543 	/* mali for blocking/parrying */
5544 	if (p_ptr->paralyzed || p_ptr->stun > 100) {
5545 		p_ptr->shield_deflect /= 4;
5546 		p_ptr->weapon_parry = 0;
5547 		/* also give a stealth bonus? (Sav's suggestion) */
5548 	} else if (p_ptr->blind || p_ptr->confused) {
5549 		p_ptr->shield_deflect /= 3;
5550 		p_ptr->weapon_parry /= 3;
5551 	} else if (p_ptr->stun) {
5552 		p_ptr->shield_deflect /= 2;
5553 		p_ptr->weapon_parry /= 2;
5554 	}
5555 
5556 
5557 
5558 	/* Redraw plusses to hit/damage if necessary */
5559 	if (p_ptr->dis_to_h != old_dis_to_h || p_ptr->dis_to_d != old_dis_to_d ||
5560 	    p_ptr->to_h_melee != old_to_h_melee || p_ptr->to_d_melee != old_to_d_melee) {
5561 		/* Redraw plusses */
5562 		p_ptr->redraw |= (PR_PLUSSES);
5563 	}
5564 
5565 	/* Affect Skill -- stealth (bonus one) */
5566 	p_ptr->skill_stl += 1; /* <- ??? */
5567 
5568 	/* Affect Skill -- disarming (DEX and INT) */
5569 	p_ptr->skill_dis += adj_dex_dis[p_ptr->stat_ind[A_DEX]];
5570 	p_ptr->skill_dis += adj_int_dis[p_ptr->stat_ind[A_INT]];
5571 
5572 	/* Affect Skill -- magic devices (INT) */
5573 	p_ptr->skill_dev += get_skill_scale(p_ptr, SKILL_DEVICE, 20);
5574 
5575 	/* Affect Skill -- saving throw (WIS) */
5576 	p_ptr->skill_sav += adj_wis_sav[p_ptr->stat_ind[A_WIS]];
5577 
5578 	/* Affect Skill -- digging (STR) */
5579 	p_ptr->skill_dig += adj_str_dig[p_ptr->stat_ind[A_STR]];
5580 
5581 	/* Affect Skill -- disarming (Level, by Class) */
5582 //	p_ptr->skill_dis += (p_ptr->cp_ptr->x_dis * get_skill(p_ptr, SKILL_DISARM) / 10);
5583 	p_ptr->skill_dis += (p_ptr->cp_ptr->x_dis * get_skill(p_ptr, SKILL_TRAPPING) / 10);
5584 
5585 	/* Affect Skill -- magic devices (Level, by Class) */
5586 	p_ptr->skill_dev += (p_ptr->cp_ptr->x_dev * get_skill(p_ptr, SKILL_DEVICE) / 10);
5587 	p_ptr->skill_dev += adj_int_dev[p_ptr->stat_ind[A_INT]];
5588 
5589 	/* Affect Skill -- saving throw (Level, by Class) */
5590 	p_ptr->skill_sav += (p_ptr->cp_ptr->x_sav * p_ptr->lev / 10);
5591 
5592 	/* Affect Skill -- stealth (Level, by Class) */
5593 	p_ptr->skill_stl += (get_skill_scale(p_ptr, SKILL_STEALTH, p_ptr->cp_ptr->x_stl * 5)) + get_skill_scale(p_ptr, SKILL_STEALTH, 25);
5594 	csheet_boni[14].slth += (get_skill_scale(p_ptr, SKILL_STEALTH, p_ptr->cp_ptr->x_stl * 5)) + get_skill_scale(p_ptr, SKILL_STEALTH, 25);
5595 
5596 	/* Affect Skill -- search ability (Level, by Class) */
5597 	p_ptr->skill_srh += (get_skill_scale(p_ptr, SKILL_SNEAKINESS, p_ptr->cp_ptr->x_srh * 2));// + get_skill(p_ptr, SKILL_SNEAKINESS);
5598 
5599 	/* Affect Skill -- search frequency (Level, by Class) */
5600 	p_ptr->skill_fos += (get_skill_scale(p_ptr, SKILL_SNEAKINESS, p_ptr->cp_ptr->x_fos * 2));// + get_skill(p_ptr, SKILL_SNEAKINESS);
5601 
5602 	/* Affect Skill -- combat (normal) (Level, by Class) */
5603         p_ptr->skill_thn += (p_ptr->cp_ptr->x_thn * (((2 * get_skill(p_ptr, SKILL_MASTERY)) + (1 * get_skill(p_ptr, SKILL_COMBAT))) / 10) / 10);
5604 
5605 	/* Affect Skill -- combat (shooting) (Level, by Class) */
5606 	//p_ptr->skill_thb += (p_ptr->cp_ptr->x_thb * (((2 * get_skill(p_ptr, SKILL_ARCHERY)) + (1 * get_skill(p_ptr, SKILL_COMBAT))) / 10) / 10);
5607 	p_ptr->skill_thb += (p_ptr->cp_ptr->x_thb * (((get_skill(p_ptr, SKILL_ARCHERY) + get_skill(p_ptr, get_archery_skill(p_ptr))) + (1 * get_skill(p_ptr, SKILL_COMBAT))) / 10) / 10);
5608 
5609 	/* Affect Skill -- combat (throwing) (Level, by Class) */
5610 	p_ptr->skill_tht += (p_ptr->cp_ptr->x_thb * get_skill_scale(p_ptr, SKILL_COMBAT, 10));
5611 
5612 
5613 
5614 
5615 	/* Knowledge in magic schools can give permanent extra boni */
5616 	/* - SKILL_EARTH gives resistance in earthquake() */
5617 	if (get_skill(p_ptr, SKILL_EARTH) >= 30) { p_ptr->resist_shard = TRUE; csheet_boni[14].cb[2] |= CB3_RSHRD; }
5618 	if (get_skill(p_ptr, SKILL_AIR) >= 30) { p_ptr->feather_fall = TRUE; csheet_boni[14].cb[4] |= CB5_RFALL; }
5619 	if (get_skill(p_ptr, SKILL_AIR) >= 40) { p_ptr->resist_pois = TRUE; csheet_boni[14].cb[1] |= CB2_RPOIS; }
5620 	if (get_skill(p_ptr, SKILL_AIR) >= 50) {
5621 		p_ptr->levitate = TRUE; csheet_boni[14].cb[6] |= CB7_RRLEV;
5622 		p_ptr->feather_fall = TRUE; csheet_boni[14].cb[4] |= CB5_RFALL;
5623 	}
5624 	if (get_skill(p_ptr, SKILL_WATER) >= 30) { p_ptr->resist_water = TRUE; csheet_boni[14].cb[2] |= CB3_RWATR; }
5625 	if (get_skill(p_ptr, SKILL_WATER) >= 40) { p_ptr->can_swim = TRUE; csheet_boni[14].cb[12] |= CB13_XSWIM; }
5626 	if (get_skill(p_ptr, SKILL_WATER) >= 50) { p_ptr->immune_water = TRUE; csheet_boni[14].cb[2] |= CB3_IWATR; }
5627 	if (get_skill(p_ptr, SKILL_FIRE) >= 30) { p_ptr->resist_fire = TRUE; csheet_boni[14].cb[0] |= CB1_RFIRE; }
5628 	if (get_skill(p_ptr, SKILL_FIRE) >= 50) { p_ptr->immune_fire = TRUE; csheet_boni[14].cb[0] |= CB1_IFIRE; }
5629 	if (get_skill(p_ptr, SKILL_MANA) >= 40) { p_ptr->resist_mana = TRUE; csheet_boni[14].cb[3] |= CB4_RMANA; }
5630 	if (get_skill(p_ptr, SKILL_CONVEYANCE) >= 30) { p_ptr->res_tele = TRUE; csheet_boni[14].cb[4] |= CB5_RTELE; }
5631 	if (get_skill(p_ptr, SKILL_DIVINATION) >= 50) { p_ptr->auto_id = TRUE; csheet_boni[14].cb[6] |= CB7_RIDNT; }
5632 	if (get_skill(p_ptr, SKILL_NATURE) >= 30) { p_ptr->regenerate = TRUE; csheet_boni[14].cb[5] |= CB6_RRGHP; }
5633 	if (get_skill(p_ptr, SKILL_NATURE) >= 30) { p_ptr->pass_trees = TRUE; csheet_boni[14].cb[12] |= CB13_XTREE; }
5634 	if (get_skill(p_ptr, SKILL_NATURE) >= 40) { p_ptr->can_swim = TRUE; csheet_boni[14].cb[12] |= CB13_XSWIM; }
5635 	/* - SKILL_MIND also helps to reduce hallucination time in set_image() */
5636 	if (get_skill(p_ptr, SKILL_MIND) >= 40 && !p_ptr->reduce_insanity) { p_ptr->reduce_insanity = 1; csheet_boni[14].cb[3] |= CB4_RMIND; }
5637 	if (get_skill(p_ptr, SKILL_MIND) >= 50) { p_ptr->reduce_insanity = 2; csheet_boni[14].cb[3] |= CB4_RMIND; }
5638 	if (get_skill(p_ptr, SKILL_TEMPORAL) >= 50) { p_ptr->resist_time = TRUE; csheet_boni[14].cb[3] |= CB4_RTIME; }
5639 	if (get_skill(p_ptr, SKILL_UDUN) >= 30) { p_ptr->res_tele = TRUE; csheet_boni[14].cb[4] |= CB5_RTELE; }
5640 	if (get_skill(p_ptr, SKILL_UDUN) >= 40) { p_ptr->hold_life = TRUE; csheet_boni[14].cb[5] |= CB6_RLIFE; }
5641 	if (get_skill(p_ptr, SKILL_META) >= 20) p_ptr->skill_sav += get_skill(p_ptr, SKILL_META) - 20;
5642 	/* - SKILL_HOFFENSE gives slay mods in brand/slay function tot_dam_aux() */
5643 	/* - SKILL_HDEFENSE gives auto protection-from-evil */
5644 //	if (get_skill(p_ptr, SKILL_HDEFENSE) >= 40) { p_ptr->resist_lite = TRUE; p_ptr->resist_dark = TRUE; }
5645 	/* - SKILL_HCURING gives extra high regeneration in regen function, and reduces various effects */
5646 //	if (get_skill(p_ptr, SKILL_HCURING) >= 50) p_ptr->reduce_insanity = 1;
5647 	/* - SKILL_HSUPPORT renders DG/TY_CURSE effectless and prevents hunger */
5648 
5649 	if (get_skill(p_ptr, SKILL_HSUPPORT) >= 40) csheet_boni[14].cb[5] |= CB6_IFOOD;
5650 
5651 	/* slay/brand boni check here... */
5652 	if (get_skill(p_ptr, SKILL_HOFFENSE) >= 50) csheet_boni[14].cb[9] |= CB10_SEVIL;
5653 	if (get_skill(p_ptr, SKILL_HOFFENSE) >= 40) csheet_boni[14].cb[8] |= CB9_SDEMN;
5654 	if (get_skill(p_ptr, SKILL_HOFFENSE) >= 30) csheet_boni[14].cb[9] |= CB10_SUNDD;
5655 	//prob: it's melee only! if (get_skill(p_ptr, SKILL_HCURING) >= 50) csheet_boni[14].cb[9] |= CB10_SUNDD;
5656 
5657 	/* Take note when "heavy bow" changes */
5658 	if (p_ptr->old_heavy_shoot != p_ptr->heavy_shoot) {
5659 		/* Message */
5660 		if (p_ptr->heavy_shoot)
5661 			msg_print(Ind, "\377oYou have trouble wielding such a heavy bow.");
5662 		else if (p_ptr->inventory[INVEN_BOW].k_idx)
5663 			msg_print(Ind, "\377gYou have no trouble wielding your bow.");
5664 		else
5665 			msg_print(Ind, "\377gYou feel relieved to put down your heavy bow.");
5666 
5667 		/* Save it */
5668 		p_ptr->old_heavy_shoot = p_ptr->heavy_shoot;
5669 	}
5670 
5671 
5672 	/* Take note when "heavy weapon" changes */
5673 	if (p_ptr->old_heavy_wield != p_ptr->heavy_wield) {
5674 		/* Message */
5675 		if (p_ptr->heavy_wield)
5676 			msg_print(Ind, "\377oYou have trouble wielding such a heavy weapon.");
5677 		else if (p_ptr->inventory[INVEN_WIELD].k_idx || /* dual-wield */
5678 		    (p_ptr->inventory[INVEN_ARM].k_idx && p_ptr->inventory[INVEN_ARM].tval != TV_SHIELD))
5679 			msg_print(Ind, "\377gYou have no trouble wielding your weapon.");
5680 		else
5681 			msg_print(Ind, "\377gYou feel relieved to put down your heavy weapon.");
5682 
5683 		/* Save it */
5684 		p_ptr->old_heavy_wield = p_ptr->heavy_wield;
5685 	}
5686 
5687 	/* Take note when "heavy shield" changes */
5688 	if (p_ptr->old_heavy_shield != p_ptr->heavy_shield) {
5689 		/* Message */
5690 		if (p_ptr->heavy_shield)
5691 			msg_print(Ind, "\377oYou have trouble wielding such a heavy shield.");
5692 		else if (p_ptr->inventory[INVEN_ARM].k_idx && p_ptr->inventory[INVEN_ARM].tval == TV_SHIELD) /* dual-wielders */
5693 			msg_print(Ind, "\377gYou have no trouble wielding your shield.");
5694 		else
5695 			msg_print(Ind, "\377gYou feel relieved to put down your heavy shield.");
5696 
5697 		/* Save it */
5698 		p_ptr->old_heavy_shield = p_ptr->heavy_shield;
5699 	}
5700 
5701 	/* Take note when "illegal weapon" changes */
5702 	if (p_ptr->old_icky_wield != p_ptr->icky_wield) {
5703 		/* Message */
5704 		if (p_ptr->icky_wield)
5705 			msg_print(Ind, "\377oYou do not feel comfortable with your weapon.");
5706 		else if (p_ptr->inventory[INVEN_WIELD].k_idx || /* dual-wield */
5707 		    (p_ptr->inventory[INVEN_ARM].k_idx && p_ptr->inventory[INVEN_ARM].tval != TV_SHIELD))
5708 			msg_print(Ind, "\377gYou feel comfortable with your weapon.");
5709 		else
5710 			msg_print(Ind, "\377gYou feel more comfortable after removing your weapon.");
5711 
5712 		/* Save it */
5713 		p_ptr->old_icky_wield = p_ptr->icky_wield;
5714 	}
5715 
5716 	/* Take note when "illegal weapon" changes */
5717 	if (p_ptr->old_awkward_wield != p_ptr->awkward_wield) {
5718 		/* Message */
5719 		if (p_ptr->awkward_wield)
5720 			msg_print(Ind, "\377oYou find it hard to fight with your weapon and shield.");
5721 		else if (p_ptr->inventory[INVEN_WIELD].k_idx)
5722 			msg_print(Ind, "\377gYou feel comfortable with your weapon.");
5723 		else if (!p_ptr->inventory[INVEN_ARM].k_idx)
5724 			msg_print(Ind, "\377gYou feel more dexterous after removing your shield.");
5725 
5726 		/* Save it */
5727 		p_ptr->old_awkward_wield = p_ptr->awkward_wield;
5728 	}
5729 
5730 	if (p_ptr->old_easy_wield != p_ptr->easy_wield) {
5731 		/* suppress message if we're heavy-wielding */
5732 		if (!p_ptr->heavy_wield) {
5733 			/* Message */
5734 			if (p_ptr->easy_wield) {
5735 				if (get_skill(p_ptr, SKILL_DUAL)) /* dual-wield */
5736 					msg_print(Ind, "\377wWithout shield or secondary weapon, your weapon feels especially easy to swing.");
5737 				else
5738 					msg_print(Ind, "\377wWithout shield, your weapon feels especially easy to swing.");
5739 			} else if (p_ptr->inventory[INVEN_WIELD].k_idx) {
5740 /*					msg_print(Ind, "\377wWith shield, your weapon feels normally comfortable.");
5741 				this above line does also show if you don't equip a shield but just switch from a
5742 				may_2h to a normal weapon, hence confusing. */
5743 				msg_print(Ind, "\377wYour weapon feels comfortable as usual.");
5744 			}
5745 		}
5746 		/* Save it */
5747 		p_ptr->old_easy_wield = p_ptr->easy_wield;
5748 	}
5749 
5750 	/* Take note when "illegal weapon" changes */
5751 	if (p_ptr->old_awkward_shoot != p_ptr->awkward_shoot) {
5752 		/* Message */
5753 		if (p_ptr->awkward_shoot) {
5754 			if (p_ptr->inventory[INVEN_ARM].tval == TV_SHIELD)
5755 				msg_print(Ind, "\377yYou find it harder to aim your ranged weapon while wielding a shield.");
5756 			else /* maybe leave awkward_shoot at FALSE if secondary slot isn't a shield! */
5757 				msg_print(Ind, "\377yYou find it harder to aim your ranged weapon while dual-wielding weapons.");
5758 		} else if (p_ptr->inventory[INVEN_BOW].k_idx)
5759 			msg_print(Ind, "\377gYou find it easier to aim your ranged weapon.");
5760 
5761 		/* Save it */
5762 		p_ptr->old_awkward_shoot = p_ptr->awkward_shoot;
5763 	}
5764 
5765 #if 0 /* doesn't work well because it's mostly a continuous increase from hardly-noticing to massive-drowning */
5766 	/* Swimming-indicator (maybe a bit too cheezy) */
5767 	p_ptr->heavy_swim = FALSE;
5768 	//if ((!p_ptr->tim_wraith) && (!p_ptr->levitate) && (!p_ptr->can_swim)) { --actually don't count these in
5769 	if (!p_ptr->can_swim) {
5770 		if (!(p_ptr->body_monster) || (
5771 		    !(r_info[p_ptr->body_monster].flags7 &
5772 		    (RF7_AQUATIC | RF7_CAN_SWIM)))) {
5773 			int swim = get_skill_scale(p_ptr, SKILL_SWIM, 4500);
5774 
5775 			/* temporary abs weight calc */
5776 			if (p_ptr->wt + p_ptr->total_weight / 10 > 170 + swim * 2) {
5777 				long factor = (p_ptr->wt + p_ptr->total_weight / 10) - 150 - swim * 2;
5778 
5779 				if (factor >= 20) p_ptr->heavy_swim = TRUE;
5780 			}
5781 		}
5782 	}
5783 	if (p_ptr->old_heavy_swim != p_ptr->heavy_swim) {
5784 		if (p_ptr->heavy_swim)
5785 			msg_print(Ind, "\377yYou're too heavy to swim.");
5786 		else
5787 			msg_print(Ind, "\377gYou're light enough to swim.");
5788 	}
5789 	p_ptr->old_heavy_swim = p_ptr->heavy_swim;
5790 #endif
5791 
5792 
5793 	/* resistance to fire cancel sensibility to fire */
5794 	if (p_ptr->resist_fire || p_ptr->oppose_fire || p_ptr->immune_fire)
5795 		p_ptr->suscep_fire = FALSE;
5796 	/* resistance to cold cancel sensibility to cold */
5797 	if (p_ptr->resist_cold || p_ptr->oppose_cold || p_ptr->immune_cold)
5798 		p_ptr->suscep_cold = FALSE;
5799 	/* resistance to electricity cancel sensibility to fire */
5800 	if (p_ptr->resist_elec || p_ptr->oppose_elec || p_ptr->immune_elec)
5801 		p_ptr->suscep_elec = FALSE;
5802 	/* resistance to acid cancel sensibility to fire */
5803 	if (p_ptr->resist_acid || p_ptr->oppose_acid || p_ptr->immune_acid)
5804 		p_ptr->suscep_acid = FALSE;
5805 	/* resistance to light cancels sensibility to light */
5806 	if (p_ptr->resist_lite) p_ptr->suscep_lite = FALSE;
5807 
5808 
5809 #if 0 /* in the making.. */
5810 	/* reduce speeds, so high-level players can duel each other even in Bree - C. Blue */
5811 	if (p_ptr->blood_bond && (Ind2 = find_player(p_ptr->blood_bond))) {
5812 		int factor1 = 10, factor2 = 10, reduction;
5813 		if (p_ptr->pspeed < 110) {
5814 			factor2 = (factor2 * (10 + (110 - p_ptr->pspeed))) / 10;
5815 		} else {
5816 			factor1 = (factor1 * (10 + (p_ptr->pspeed - 110))) / 10;
5817 		}
5818 		if (Players[Ind2]->pspeed < 110) {
5819 			factor1 = (factor1 * (10 + (110 - Players[Ind2]->pspeed))) / 10;
5820 		} else {
5821 			factor2 = (factor2 * (10 + (Players[Ind2]->pspeed - 110))) / 10;
5822 		}
5823 		if (factor1 >= factor2) { /* player 1 is faster or equal speed */
5824 			if (p_ptr->pspeed > 120) /* top (cur atm) speed for moving during blood bond */
5825 				p_ptr->pspeed = 120;
5826 //				reduction = p_ptr->pspeed - 120;
5827 			if (factor1 >= (p_ptr->pspeed - 110) + 10) {
5828 				factor1 = (factor * 10) / (p_ptr->pspeed - 110) + 10;
5829 				Players[Ind2]->pspeed = 110 - factor1 + 10;
5830 			}
5831 		} else { /* player 2 is faster or equal speed */
5832 			if (Players[Ind2]->pspeed > 120) /* top (cur atm) speed for moving during blood bond */
5833 				Players[Ind2]->pspeed = 120;
5834 //				reduction = Players[Ind2]->pspeed - 120;
5835 		}
5836 	}
5837 #endif
5838 
5839 
5840 	/* Extract the current weight (in tenth pounds) */
5841 	w = p_ptr->total_weight;
5842 
5843 	/* Extract the "weight limit" (in tenth pounds) */
5844 	i = weight_limit(Ind);
5845 
5846 	/* XXX XXX XXX Apply "encumbrance" from weight */
5847 	if (w > i / 2) {
5848 		/* protect pspeed from uberflow O_o */
5849 //		if (w > 61500) p_ptr->pspeed = 10; /* roughly ;-p */
5850 		if (w > 70000) p_ptr->pspeed = 10; /* roughly ;-p */
5851 		else p_ptr->pspeed -= ((w - (i / 2)) / (i / 10));
5852 	}
5853 
5854 	/* Display the speed (if needed) */
5855 	if (p_ptr->pspeed != old_speed) p_ptr->redraw |= (PR_SPEED);
5856 
5857 
5858 	/* swapping in AUTO_ID items will instantly ID inventory and equipment.
5859 	   Careful, we're called from birth->player_setup->player_night maybe,
5860 	   when we aren't READY|PLAYING yet: */
5861 	if (p_ptr->auto_id && !old_auto_id && !suppress_boni && logged_in) {
5862 #if 0 /* currently doesn't work ok with client-side auto-inscriptions */
5863 		for (i = 0; i < INVEN_TOTAL; i++) {
5864 			o_ptr = &p_ptr->inventory[i];
5865 			object_aware(Ind, o_ptr);
5866 			object_known(o_ptr);
5867 		}
5868 #else /* why not just this, simply.. :) */
5869 		identify_pack(Ind);
5870 #endif
5871 
5872 #if 0 /* moved to client-side, clean! */
5873 		/* hack: trigger client-side auto-inscriptions for convenience,
5874 		   if it isn't due anyway.  */
5875 		if (!p_ptr->inventory_changes) Send_inventory_revision(Ind);
5876 #endif
5877 	}
5878 
5879 
5880 /* -------------------- Limits -------------------- */
5881 
5882 	/* Make sure we don't get negative stealth from monster body malus */
5883 	if (p_ptr->skill_stl < 0) p_ptr->skill_stl = 0;
5884 
5885 #ifdef FUNSERVER
5886 	/* Limit AC?.. */
5887 	if (!is_admin(p_ptr)) {
5888 		if ((p_ptr->to_a > 400) && (!p_ptr->total_winner)) p_ptr->to_a = 400; /* Lebohaum / Illuvatar bonus */
5889 		if ((p_ptr->to_a > 300) && (p_ptr->total_winner)) p_ptr->to_a = 300;
5890 		if (p_ptr->ac > 100) p_ptr->ac = 100;
5891 	}
5892 #endif
5893 
5894 	if (((l_ptr && (l_ptr->flags2 & LF2_NO_SPEED)) ||
5895 	    (in_sector00(&p_ptr->wpos) && (sector00flags2 & LF2_NO_SPEED)))
5896 	    && p_ptr->pspeed > 110 && !p_ptr->admin_dm)
5897 		p_ptr->pspeed = 110;
5898 
5899 	if (((l_ptr && (l_ptr->flags2 & LF2_NO_RES_HEAL)) ||
5900 	    (in_sector00(&p_ptr->wpos) && (sector00flags2 & LF2_NO_RES_HEAL)))
5901 	    && !p_ptr->admin_dm) {
5902 		p_ptr->resist_acid = FALSE;
5903 		p_ptr->resist_elec = FALSE;
5904 		p_ptr->resist_fire = FALSE;
5905 		p_ptr->resist_cold = FALSE;
5906 		p_ptr->resist_pois = FALSE;
5907 		p_ptr->resist_conf = FALSE;
5908 		p_ptr->resist_sound = FALSE;
5909 		p_ptr->resist_lite = FALSE;
5910 		p_ptr->resist_dark = FALSE;
5911 		p_ptr->resist_chaos = FALSE;
5912 		p_ptr->resist_disen = FALSE;
5913 		p_ptr->resist_shard = FALSE;
5914 		p_ptr->resist_nexus = FALSE;
5915 		p_ptr->resist_neth = FALSE;
5916 		p_ptr->resist_plasma = FALSE;
5917 		p_ptr->resist_water = FALSE;
5918 		p_ptr->resist_time = FALSE;
5919 		p_ptr->resist_mana = FALSE;
5920 		p_ptr->immune_acid = FALSE;
5921 		p_ptr->immune_elec = FALSE;
5922 		p_ptr->immune_fire = FALSE;
5923 		p_ptr->immune_cold = FALSE;
5924 		p_ptr->immune_poison = FALSE;
5925 		p_ptr->immune_water = FALSE;
5926 		p_ptr->immune_neth = FALSE;
5927 	}
5928 
5929 	/* Limit mana capacity bonus */
5930 	if ((p_ptr->to_m > 300) && !is_admin(p_ptr)) p_ptr->to_m = 300;
5931 
5932 	/* Limit Skill -- stealth from 0 to 30 */
5933 	if (p_ptr->skill_stl > 30) p_ptr->skill_stl = 30;
5934 	if (p_ptr->skill_stl < 0) p_ptr->skill_stl = 0;
5935 	if (p_ptr->aggravate) p_ptr->skill_stl = 0;
5936 
5937 	/* Limit Skill -- digging from 1 up */
5938 	if (p_ptr->skill_dig < 1) p_ptr->skill_dig = 1;
5939 
5940 	if ((p_ptr->anti_magic) && (p_ptr->skill_sav < 95)) p_ptr->skill_sav = 95;
5941 
5942 	/* Limit Skill -- saving throw upto 95 */
5943 	if (p_ptr->skill_sav > 95) p_ptr->skill_sav = 95;
5944 
5945 	/* Limit critical hits bonus */
5946 	if ((p_ptr->xtra_crit > 50) && !is_admin(p_ptr)) p_ptr->xtra_crit = 50;
5947 
5948 	/* Limit speed penalty from total_weight */
5949 	if ((p_ptr->pspeed < 10) && !is_admin(p_ptr)) p_ptr->pspeed = 10;
5950 	if (p_ptr->pspeed < 100 && is_admin(p_ptr)) p_ptr->pspeed = 100;
5951 
5952 	/* Limit speed */
5953 	if ((p_ptr->pspeed > 210) && !is_admin(p_ptr)) p_ptr->pspeed = 210;
5954 
5955 	/* Limit blows per round (just paranoia^^) */
5956 	if (p_ptr->num_blow < 0) p_ptr->num_blow = 0;
5957 	if ((p_ptr->num_blow > 20) && !is_admin(p_ptr)) p_ptr->num_blow = 20;
5958 	/* ghost-dive limit to not destroy the real gameplay */
5959 	if (p_ptr->ghost && !is_admin(p_ptr)) p_ptr->num_blow = (p_ptr->lev + 15) / 16;
5960 
5961 
5962 	/* Determine colour of our light radius */
5963 	old_lite_type = p_ptr->lite_type;
5964 	if (p_ptr->cur_vlite > p_ptr->cur_lite) p_ptr->lite_type = 1; /* vampiric */
5965 	else if (lite_inc_white > lite_inc_norm) p_ptr->lite_type = 2; /* artificial */
5966 	else p_ptr->lite_type = 0; /* normal, fiery */
5967 	if (old_lite_type != p_ptr->lite_type) {
5968 		if (p_ptr->px /* calc_boni() is called once on birth, where player isn't positioned yet. */
5969 		    && !suppress_boni) {
5970 			forget_lite(Ind);
5971 			update_lite(Ind);
5972 		}
5973 		old_lite_type = p_ptr->lite_type; /* erm, this isnt needed? */
5974 	}
5975 
5976 
5977 	/* XXX - Always resend skills */
5978 	p_ptr->redraw |= (PR_SKILLS);
5979 	/* also redraw encumberment status line */
5980 	p_ptr->redraw |= (PR_ENCUMBERMENT);
5981 	if (is_newer_than(&p_ptr->version, 4, 4, 8, 4, 0, 0))
5982 		/* Redraw BpR */
5983 		p_ptr->redraw |= PR_BPR;
5984 
5985 	/* Send all the columns */
5986 	if (is_newer_than(&p_ptr->version, 4, 5, 3, 2, 0, 0) && logged_in)
5987 		for (i = 0; i < 15; i++) {
5988 			f1 = f2 = f3 = f4 = f5 = f6 = esp = 0x0;
5989 			if (csheet_boni[i].cb[11] & CB12_XHIDD) {
5990 				/* Wipe the boni column data */
5991 				csheet_boni[i].i = i;
5992 				csheet_boni[i].spd = 0;
5993 				csheet_boni[i].slth = 0;
5994 				csheet_boni[i].srch = 0;
5995 				csheet_boni[i].infr = 0;
5996 				csheet_boni[i].lite = 0;
5997 				csheet_boni[i].dig = 0;
5998 				csheet_boni[i].blow = 0;
5999 				csheet_boni[i].crit = 0;
6000 				csheet_boni[i].shot = 0;
6001 				csheet_boni[i].migh = 0;
6002 				csheet_boni[i].mxhp = 0;
6003 				csheet_boni[i].mxmp = 0;
6004 				csheet_boni[i].luck = 0;
6005 				csheet_boni[i].pstr = 0;
6006 				csheet_boni[i].pint = 0;
6007 				csheet_boni[i].pwis = 0;
6008 				csheet_boni[i].pdex = 0;
6009 				csheet_boni[i].pcon = 0;
6010 				csheet_boni[i].pchr = 0;
6011 				csheet_boni[i].amfi = 0;
6012 				csheet_boni[i].sigl = 0;
6013 				/* Clear the byte flags */
6014 				for (jj = 0; jj < 13; jj++)
6015 					csheet_boni[i].cb[jj] = 0;
6016 				//Actually, keep the item representation :)
6017 				//csheet_boni[i].color = TERM_DARK;
6018 				//csheet_boni[i].symbol = ' '; //Empty item / form slot.
6019 
6020 				 //Actually give the basic item data instead of hiding it all. See object1.cf
6021 				bool can_have_hidden_powers = TRUE;
6022 #ifdef NEW_ID_SCREEN
6023 				can_have_hidden_powers = FALSE;
6024 //				bool not_identified_at_all = TRUE;
6025 				if (i != 14) {
6026 					o_ptr = &p_ptr->inventory[i + INVEN_WIELD];
6027 					k_ptr = &k_info[o_ptr->k_idx];
6028 					/* Build the flags */
6029 					//object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &f6, &esp);
6030 					if (object_aware_p(Ind, o_ptr)) {
6031 						f1 = k_info[o_ptr->k_idx].flags1;
6032 						f2 = k_info[o_ptr->k_idx].flags2;
6033 						f3 = k_info[o_ptr->k_idx].flags3;
6034 						f4 = k_info[o_ptr->k_idx].flags4;
6035 						f5 = k_info[o_ptr->k_idx].flags5;
6036 						f6 = k_info[o_ptr->k_idx].flags6;
6037 						esp = k_info[o_ptr->k_idx].esp;
6038 						/* hack: granted pval-abilities */
6039 						if (o_ptr->tval == TV_MSTAFF && o_ptr->pval) f1 |= TR1_MANA;
6040 						if (o_ptr->name1) can_have_hidden_powers = TRUE; //artifact
6041 					} else can_have_hidden_powers = TRUE; //unknown jewelry type
6042 					/* Assume we must *id* (just once) to learn sigil powers */
6043 					if (o_ptr->sigil && !object_fully_known_p(Ind, o_ptr)) can_have_hidden_powers = TRUE;
6044 					ego_item_type *e_ptr;
6045 					if (object_known_p(Ind, o_ptr)) {
6046 						if (o_ptr->name2) {
6047 							e_ptr = &e_info[o_ptr->name2];
6048 							for (j = 0; j < 5; j++) {
6049 								if (e_ptr->rar[j] == 0) continue;
6050 								/* hack: can *identifying* actually make a difference at all? */
6051 
6052 								/* any non-trivial (on the object name itself visible) abilities? */
6053 								if ((e_ptr->fego1[j] & ETR1_EASYKNOW_MASK) ||
6054 								    (e_ptr->fego2[j] & ETR2_EASYKNOW_MASK) ||
6055 								    /* random ego mods (R_xxx)? */
6056 								    (e_ptr->esp[j] & ESP_R_MASK)) {
6057 									can_have_hidden_powers = TRUE;
6058 								}
6059 
6060 								/* random base mods? */
6061 								if (e_ptr->rar[j] != 100) {
6062 									if (e_ptr->flags1[j] | e_ptr->flags2[j] | e_ptr->flags3[j] |
6063 									    e_ptr->flags4[j] | e_ptr->flags5[j] | e_ptr->flags6[j] |
6064 									    e_ptr->esp[j]) {
6065 										can_have_hidden_powers = TRUE;
6066 										continue;
6067 									}
6068 								}
6069 
6070 								/* fixed base mods, ie which we absolutely know will be on the item even without *id*ing */
6071 								f1 |= e_ptr->flags1[j];
6072 								f2 |= e_ptr->flags2[j];
6073 								f3 |= e_ptr->flags3[j];
6074 								f4 |= e_ptr->flags4[j];
6075 								f5 |= e_ptr->flags5[j];
6076 								f6 |= e_ptr->flags6[j];
6077 								esp |= e_ptr->esp[j]; /* & ~ESP_R_MASK -- not required */
6078 							}
6079 						}
6080 						if (o_ptr->name2b) {
6081 							e_ptr = &e_info[o_ptr->name2b];
6082 							for (j = 0; j < 5; j++) {
6083 								if (e_ptr->rar[j] == 0) continue;
6084 								/* hack: can *identifying* actually make a difference at all? */
6085 
6086 								/* any non-trivial (on the object name itself visible) abilities? */
6087 								if ((e_ptr->fego1[j] & ETR1_EASYKNOW_MASK) ||
6088 								    (e_ptr->fego2[j] & ETR2_EASYKNOW_MASK) ||
6089 								    /* random ego mods (R_xxx)? */
6090 								    (e_ptr->esp[j] & ESP_R_MASK)) {
6091 									can_have_hidden_powers = TRUE;
6092 								}
6093 
6094 								/* random base mods? */
6095 								if (e_ptr->rar[j] != 100) {
6096 									if (e_ptr->flags1[j] | e_ptr->flags2[j] | e_ptr->flags3[j] |
6097 									    e_ptr->flags4[j] | e_ptr->flags5[j] | e_ptr->flags6[j] |
6098 									    e_ptr->esp[j]) {
6099 										can_have_hidden_powers = TRUE;
6100 										continue;
6101 									}
6102 								}
6103 
6104 								/* fixed base mods, ie which we absolutely know will be on the item even without *id*ing */
6105 								f1 |= e_ptr->flags1[j];
6106 								f2 |= e_ptr->flags2[j];
6107 								f3 |= e_ptr->flags3[j];
6108 								f4 |= e_ptr->flags4[j];
6109 								f5 |= e_ptr->flags5[j];
6110 								f6 |= e_ptr->flags6[j];
6111 								esp |= e_ptr->esp[j]; /* & ~ESP_R_MASK -- not required */
6112 							}
6113 						}
6114 					} else can_have_hidden_powers = TRUE; //not identified
6115 
6116 					//Translate item flags to PKT data
6117 					if (object_aware_p(Ind, o_ptr)) { //must know base item type to see anything
6118 						/* Table A - Skip impossible flags for items... */
6119 						if (f2 & TR2_RES_FIRE) csheet_boni[i].cb[0] |= CB1_RFIRE;
6120 						if (f2 & TR2_IM_FIRE) csheet_boni[i].cb[0] |= CB1_IFIRE;
6121 						if (f2 & TR2_RES_COLD) csheet_boni[i].cb[0] |= CB1_RCOLD;
6122 						if (f2 & TR2_IM_COLD) csheet_boni[i].cb[0] |= CB1_ICOLD;
6123 						if (f2 & TR2_RES_ELEC) csheet_boni[i].cb[0] |= CB1_RELEC;
6124 						if (f2 & TR2_IM_ELEC) csheet_boni[i].cb[1] |= CB2_IELEC;
6125 						if (f2 & TR2_RES_ACID) csheet_boni[i].cb[1] |= CB2_RACID;
6126 						if (f2 & TR2_IM_ACID) csheet_boni[i].cb[1] |= CB2_IACID;
6127 						if (f2 & TR2_RES_POIS) csheet_boni[i].cb[1] |= CB2_RPOIS;
6128 						if (f5 & TR5_IM_POISON) csheet_boni[i].cb[1] |= CB2_IPOIS;
6129 						if (f2 & TR2_RES_LITE) csheet_boni[i].cb[2] |= CB3_RLITE;
6130 						if (f2 & TR2_RES_DARK) csheet_boni[i].cb[2] |= CB3_RDARK;
6131 						if (f2 & TR2_RES_CONF) csheet_boni[i].cb[2] |= CB3_RCONF;
6132 						if (f5 & TR5_RES_PLASMA) csheet_boni[i].cb[2] |= CB3_RPLAS; //runecraft sigil
6133 						if (f2 & TR2_RES_SOUND) csheet_boni[i].cb[2] |= CB3_RSOUN;
6134 						if (f2 & TR2_RES_SHARDS) csheet_boni[i].cb[2] |= CB3_RSHRD;
6135 						if (f5 & TR5_RES_WATER) csheet_boni[i].cb[2] |= CB3_RWATR;
6136 						if (f5 & TR5_IM_WATER) csheet_boni[i].cb[2] |= CB3_IWATR; //ocean soul
6137 						if (f2 & TR2_RES_NEXUS) csheet_boni[i].cb[3] |= CB4_RNEXU;
6138 						if (f2 & TR2_RES_NETHER) csheet_boni[i].cb[3] |= CB4_RNETH;
6139 						if (f4 & TR4_IM_NETHER) csheet_boni[i].cb[3] |= CB4_INETH; //ring of phasing
6140 						if (f2 & TR2_RES_CHAOS) csheet_boni[i].cb[3] |= CB4_RCHAO;
6141 						if (f2 & TR2_RES_DISEN) csheet_boni[i].cb[3] |= CB4_RDISE;
6142 						if (f5 & TR5_RES_TIME) csheet_boni[i].cb[3] |= CB4_RTIME;
6143 						if (f5 & TR5_RES_MANA) csheet_boni[i].cb[3] |= CB4_RMANA;
6144 
6145 						/* Table B */
6146 						if (f2 & TR2_RES_FEAR) csheet_boni[i].cb[4] |= CB5_RFEAR;
6147 						if (f2 & TR2_FREE_ACT) csheet_boni[i].cb[4] |= CB5_RPARA;
6148 						if (f2 & TR2_RES_BLIND) csheet_boni[i].cb[4] |= CB5_RBLND;
6149 						if (f3 & TR3_TELEPORT) {
6150 							csheet_boni[i].cb[4] |= CB5_STELE;
6151 							//inscription = (unsigned char *) quark_str(o_ptr->note);
6152 							inscription = quark_str(p_ptr->inventory[i].note);
6153 							/* check for a valid inscription */
6154 							if ((inscription != NULL) && (!(o_ptr->ident & ID_CURSED))) {
6155 								/* scan the inscription for .. */
6156 								while (*inscription != '\0') {
6157 									if (*inscription == '.') {
6158 										inscription++;
6159 										/* a valid .. has been located */
6160 										if (*inscription == '.') {
6161 											inscription++;
6162 											csheet_boni[i].cb[4] &= (~CB5_STELE);
6163 											break;
6164 										}
6165 									}
6166 									inscription++;
6167 								}
6168 							}
6169 						}
6170 						if (f5 & TR5_RES_TELE) csheet_boni[i].cb[4] |= CB5_RTELE;
6171 						if (f3 & TR3_NO_TELE) csheet_boni[i].cb[4] |= CB5_ITELE;
6172 						if (f3 & TR3_FEATHER) csheet_boni[i].cb[4] |= CB5_RFALL;
6173 						if (f3 & TR3_SLOW_DIGEST) csheet_boni[i].cb[4] |= CB5_RFOOD;
6174 						if (f2 & TR2_HOLD_LIFE) csheet_boni[i].cb[5] |= CB6_RLIFE;
6175 						if (f5 & TR5_DRAIN_HP) csheet_boni[i].cb[5] |= CB6_SRGHP;
6176 						if (f3 & TR3_REGEN) csheet_boni[i].cb[5] |= CB6_RRGHP;
6177 						if (f5 & TR5_DRAIN_MANA) csheet_boni[i].cb[5] |= CB6_SRGMP;
6178 						if (f5 & TR5_REGEN_MANA) csheet_boni[i].cb[5] |= CB6_RRGMP;
6179 						if (f3 & TR3_SEE_INVIS) csheet_boni[i].cb[5] |= CB6_RSINV;
6180 						if (f3 & (TR3_WRAITH)) csheet_boni[i].cb[5] |= CB6_RWRTH;
6181 						if (f5 & TR5_REFLECT) csheet_boni[i].cb[6] |= CB7_RREFL;
6182 						if (f5 & TR5_INVIS) csheet_boni[i].cb[6] |= CB7_RINVS;
6183 						if (f1 & TR1_VAMPIRIC) csheet_boni[i].cb[6] |= CB7_RVAMP;
6184 						if (f4 & TR4_AUTO_ID) csheet_boni[i].cb[6] |= CB7_RIDNT;
6185 						if (f4 & TR4_LEVITATE) {
6186 							csheet_boni[i].cb[6] |= CB7_RRLEV;
6187 							csheet_boni[i].cb[4] |= CB5_RFALL;
6188 						}
6189 						if (f4 & TR4_CLIMB) csheet_boni[i].cb[6] |= CB7_RCLMB; //climbing kit
6190 						if (f3 & TR3_NO_MAGIC) csheet_boni[i].cb[6] |= CB7_RAMSH;
6191 						if (f3 & TR3_AGGRAVATE) csheet_boni[i].cb[6] |= CB7_RAGGR;
6192 
6193 						/* Table C */
6194 						if (object_known_p(Ind, o_ptr)) { //must be identified to see PVAL
6195 							pval = o_ptr->pval;
6196 
6197 							/*todo: build a_ptr for ego/art powers and mask out k1/k5 pval mask from it,
6198 							  to get the -real- pvals (no more witans +8 stealth if +10 speed..) */
6199 							if (o_ptr->name2) {
6200 								artifact_type *a_ptr = ego_make(o_ptr);
6201 								f1 &= ~(k_ptr->flags1 & TR1_PVAL_MASK & ~a_ptr->flags1);
6202 								f5 &= ~(k_ptr->flags5 & TR5_PVAL_MASK & ~a_ptr->flags5);
6203 							} else if (o_ptr->name1 == ART_RANDART) {
6204 								artifact_type *a_ptr = randart_make(o_ptr);
6205 								f1 &= ~(k_ptr->flags1 & TR1_PVAL_MASK & ~a_ptr->flags1);
6206 								f5 &= ~(k_ptr->flags5 & TR5_PVAL_MASK & ~a_ptr->flags5);
6207 							}
6208 
6209 							if (f1 & TR1_SPEED) csheet_boni[i].spd += pval;
6210 							if (f1 & TR1_STEALTH) csheet_boni[i].slth += pval;
6211 							if (f1 & TR1_SEARCH) csheet_boni[i].srch += pval;
6212 							if (f1 & TR1_INFRA) csheet_boni[i].infr += pval;
6213 							if (f1 & TR1_TUNNEL) csheet_boni[i].dig += pval;
6214 							if (f1 & TR1_BLOWS) csheet_boni[i].blow += pval;
6215 							if (f5 & TR5_CRIT) csheet_boni[i].crit += pval;
6216 							if (f5 & TR5_LUCK) csheet_boni[i].luck += pval;
6217 
6218 							if (f1 & TR1_STR) csheet_boni[i].pstr += pval;
6219 							if (f1 & TR1_INT) csheet_boni[i].pint += pval;
6220 							if (f1 & TR1_WIS) csheet_boni[i].pwis += pval;
6221 							if (f1 & TR1_DEX) csheet_boni[i].pdex += pval;
6222 							if (f1 & TR1_CON) csheet_boni[i].pcon += pval;
6223 							if (f1 & TR1_CHR) csheet_boni[i].pchr += pval;
6224 
6225 							if (f1 & TR1_MANA) csheet_boni[i].mxmp += pval;
6226 							if (f1 & TR1_LIFE) csheet_boni[i].mxhp += pval;
6227 
6228 							{ //lite
6229 								j = 0;
6230 								if (f3 & TR3_LITE1) j++;
6231 								if (f4 & TR4_LITE2) j += 2;
6232 								if (f4 & TR4_LITE3) j += 3;
6233 								csheet_boni[i].lite += j;
6234 								if (!(f4 & TR4_FUEL_LITE)) csheet_boni[i].cb[12] |= CB13_XLITE;
6235 							}
6236 
6237 							if (f3 & TR3_XTRA_SHOTS) csheet_boni[i].shot++;
6238 							if (f3 & TR3_XTRA_MIGHT) csheet_boni[i].migh++;
6239 							if (f2 & TR2_SUST_STR) csheet_boni[i].cb[11] |= CB12_RSSTR;
6240 							if (f2 & TR2_SUST_INT) csheet_boni[i].cb[11] |= CB12_RSINT;
6241 							if (f2 & TR2_SUST_WIS) csheet_boni[i].cb[11] |= CB12_RSWIS;
6242 							if (f2 & TR2_SUST_DEX) csheet_boni[i].cb[11] |= CB12_RSDEX;
6243 							if (f2 & TR2_SUST_CON) csheet_boni[i].cb[11] |= CB12_RSCON;
6244 							if (f2 & TR2_SUST_CHR) csheet_boni[i].cb[11] |= CB12_RSCHR;
6245 
6246 							/* And now the base PVAL of the item... */
6247 							if (k_ptr->flags1 & TR1_PVAL_MASK) {
6248 								if (k_ptr->flags1 & TR1_STR) csheet_boni[i].pstr += o_ptr->bpval;
6249 								if (k_ptr->flags1 & TR1_INT) csheet_boni[i].pint += o_ptr->bpval;
6250 								if (k_ptr->flags1 & TR1_WIS) csheet_boni[i].pwis += o_ptr->bpval;
6251 								if (k_ptr->flags1 & TR1_DEX) csheet_boni[i].pdex += o_ptr->bpval;
6252 								if (k_ptr->flags1 & TR1_CON) csheet_boni[i].pcon += o_ptr->bpval;
6253 								if (k_ptr->flags1 & TR1_CHR) csheet_boni[i].pchr += o_ptr->bpval;
6254 
6255 								if (k_ptr->flags1 & TR1_STEALTH) csheet_boni[i].slth += o_ptr->bpval;
6256 								if (k_ptr->flags1 & TR1_SEARCH) csheet_boni[i].srch += o_ptr->bpval;
6257 								if (k_ptr->flags1 & TR1_INFRA) csheet_boni[i].infr += o_ptr->bpval;
6258 								if (k_ptr->flags1 & TR1_TUNNEL) csheet_boni[i].dig += o_ptr->bpval;
6259 								if (k_ptr->flags1 & TR1_SPEED) csheet_boni[i].spd += o_ptr->bpval;
6260 								if (k_ptr->flags1 & TR1_BLOWS) csheet_boni[i].blow += o_ptr->bpval;
6261 							}
6262 							if (k_ptr->flags5 & TR5_PVAL_MASK) {
6263 								if (f5 & TR5_LUCK) csheet_boni[i].luck += o_ptr->bpval;
6264 								if (f5 & TR5_CRIT) csheet_boni[i].crit += o_ptr->bpval;
6265 							}
6266 						}
6267 
6268 						/* Table D */
6269 						if (f1 & TR1_SLAY_ANIMAL) csheet_boni[i].cb[7] |= CB8_SANIM;
6270 						if (f1 & TR1_SLAY_EVIL) csheet_boni[i].cb[9] |= CB10_SEVIL;
6271 						if (f1 & TR1_SLAY_UNDEAD) csheet_boni[i].cb[9] |= CB10_SUNDD;
6272 						if (f1 & TR1_SLAY_DEMON) csheet_boni[i].cb[8] |= CB9_SDEMN;
6273 						if (f1 & TR1_SLAY_ORC) csheet_boni[i].cb[7] |= CB8_SORCS;
6274 						if (f1 & TR1_SLAY_TROLL) csheet_boni[i].cb[7] |= CB8_STROL;
6275 						if (f1 & TR1_SLAY_GIANT) csheet_boni[i].cb[8] |= CB9_SGIAN;
6276 						if (f1 & TR1_SLAY_DRAGON) csheet_boni[i].cb[8] |= CB9_SDRGN;
6277 						if (f1 & TR1_KILL_DRAGON) csheet_boni[i].cb[8] |= CB9_KDRGN;
6278 						if (f1 & TR1_KILL_DEMON) csheet_boni[i].cb[8] |= CB9_KDEMN;
6279 						if (f1 & TR1_KILL_UNDEAD) csheet_boni[i].cb[9] |= CB10_KUNDD;
6280 						if (esp & ESP_ALL) {
6281 							csheet_boni[i].cb[7] |= (CB8_ESPID | CB8_EANIM | CB8_EORCS | CB8_ETROL | CB8_EGIAN);
6282 							csheet_boni[i].cb[8] |= (CB9_EDRGN | CB9_EDEMN | CB9_EUNDD);
6283 							csheet_boni[i].cb[9] |= (CB10_EEVIL | CB10_EDGRI | CB10_EGOOD | CB10_ENONL | CB10_EUNIQ);
6284 						} else {
6285 							if (esp & ESP_SPIDER) csheet_boni[i].cb[7] |= CB8_ESPID;
6286 							if (esp & ESP_ANIMAL) csheet_boni[i].cb[7] |= CB8_EANIM;
6287 							if (esp & ESP_ORC) csheet_boni[i].cb[7] |= CB8_EORCS;
6288 							if (esp & ESP_TROLL) csheet_boni[i].cb[7] |= CB8_ETROL;
6289 							if (esp & ESP_GIANT) csheet_boni[i].cb[7] |= CB8_EGIAN;
6290 							if (esp & ESP_DRAGON) csheet_boni[i].cb[8] |= CB9_EDRGN;
6291 							if (esp & ESP_DEMON) csheet_boni[i].cb[8] |= CB9_EDEMN;
6292 							if (esp & ESP_UNDEAD) csheet_boni[i].cb[8] |= CB9_EUNDD;
6293 							if (esp & ESP_EVIL) csheet_boni[i].cb[9] |= CB10_EEVIL;
6294 							if (esp & ESP_DRAGONRIDER) csheet_boni[i].cb[9] |= CB10_EDGRI;
6295 							if (esp & ESP_GOOD) csheet_boni[i].cb[9] |= CB10_EGOOD;
6296 							if (esp & ESP_NONLIVING) csheet_boni[i].cb[9] |= CB10_ENONL;
6297 							if (esp & ESP_UNIQUE) csheet_boni[i].cb[9] |= CB10_EUNIQ;
6298 						}
6299 						if (f1 & TR1_BRAND_FIRE) csheet_boni[i].cb[10] |= CB11_BFIRE;
6300 						if (f3 & TR3_SH_FIRE) csheet_boni[i].cb[10] |= CB11_AFIRE;
6301 						if (f1 & TR1_BRAND_COLD) csheet_boni[i].cb[10] |= CB11_BCOLD;
6302 						if (f5 & TR5_SH_COLD) csheet_boni[i].cb[10] |= CB11_ACOLD;
6303 						if (f1 & TR1_BRAND_ELEC) csheet_boni[i].cb[10] |= CB11_BELEC;
6304 						if (f3 & TR3_SH_ELEC) csheet_boni[i].cb[10] |= CB11_AELEC;
6305 						if (f1 & TR1_BRAND_ACID) csheet_boni[i].cb[10] |= CB11_BACID;
6306 						if (f1 & TR1_BRAND_POIS) csheet_boni[i].cb[10] |= CB11_BPOIS;
6307 						if (f5 & TR5_VORPAL) csheet_boni[i].cb[11] |= CB12_BVORP;
6308 					}
6309 				}
6310 #endif
6311 				/* conclude hack: can *identifying* actually make a difference at all? */
6312 				if (can_have_hidden_powers) csheet_boni[i].cb[11] |= CB12_XHIDD;
6313 			}
6314 			Send_boni_col(Ind, csheet_boni[i]);
6315 		}
6316 
6317 	/* Don't kill warnings by inspecting weapons/armour in stores! */
6318 	if (!suppress_message) {
6319 		/* warning messages, mostly for newbies */
6320 		if (p_ptr->warning_bpr == 0 && /* limit, so it won't annoy priests anymore who use zeal spell */
6321 		    p_ptr->num_blow == 1 && old_num_blow > 1 &&
6322 		    p_ptr->inventory[INVEN_WIELD].k_idx && is_weapon(p_ptr->inventory[INVEN_WIELD].tval)) {
6323 			p_ptr->warning_bpr = 1;
6324 			msg_print(Ind, "\374\377yWARNING! Your number of melee attacks per round has just dropped to ONE.");
6325 			msg_print(Ind, "\374\377y    If you rely on melee combat, it is strongly advised to try and");
6326 			msg_print(Ind, "\374\377y    get AT LEAST TWO blows/round (shown in the bottom status line).");
6327 			msg_print(Ind, "\374\377yPossible reasons are: Weapon is too heavy; too little STR or DEX; You");
6328 			msg_print(Ind, "\374\377y    just equipped too heavy armour or a shield - depending on your class.");
6329 			msg_print(Ind, "\374\377y    Also, some classes can dual-wield to get an extra blow/round.");
6330 			s_printf("warning_bpr: %s\n", p_ptr->name);
6331 		}
6332 		if (p_ptr->warning_bpr3 == 2 &&
6333 		    p_ptr->num_blow == 1 && old_num_blow == 1 &&
6334 		    /* and don't spam Martial Arts users or mage-staff wielders ;) */
6335 		    p_ptr->inventory[INVEN_WIELD].k_idx && is_weapon(p_ptr->inventory[INVEN_WIELD].tval)) {
6336 			p_ptr->warning_bpr2 = p_ptr->warning_bpr3 = 1;
6337 			msg_print(Ind, "\374\377yWARNING! You can currently perform only ONE 'blow per round' (attack).");
6338 			msg_print(Ind, "\374\377y    If you rely on close combat, you should get at least 2 BpR!");
6339 			msg_print(Ind, "\374\377y    Possible reasons: Weapon is too heavy or your strength is too low.");
6340 			if (p_ptr->inventory[INVEN_ARM].tval == TV_SHIELD) {
6341 				if (p_ptr->rogue_like_commands)
6342 					msg_print(Ind, "\374\377y    Try taking off your shield ('\377oSHIFT+t\377y') and see if that helps.");
6343 				else
6344 					msg_print(Ind, "\374\377y    Try taking off your shield ('\377ot\377y' key) and see if that helps.");
6345 			}
6346 			switch (p_ptr->pclass) {
6347 			case CLASS_WARRIOR:
6348 				msg_print(Ind, "\374\377y    Warriors should try either a dagger, whip, spear or cleaver.");
6349 				break;
6350 			case CLASS_PALADIN:
6351 				msg_print(Ind, "\374\377y    Paladins should try either a dagger, whip, spear or cleaver.");
6352 				break;
6353 			case CLASS_MIMIC:
6354 				msg_print(Ind, "\374\377y    Mimics should try either a dagger, whip, spear or cleaver.");
6355 				break;
6356 			case CLASS_ROGUE:
6357 				msg_print(Ind, "\374\377y    Rogues should try dual-wielding two daggers or main gauches.");
6358 				break;
6359 			case CLASS_RANGER:
6360 				msg_print(Ind, "\374\377y    Rangers should try dual-wielding two daggers or sword & dagger.");
6361 				break;
6362 			}
6363 			s_printf("warning_bpr23: %s\n", p_ptr->name);
6364 		}
6365 	} /* suppress_message */
6366 }
6367 
6368 
6369 
6370 /*
6371  * Handle "p_ptr->notice"
6372  */
6373 void notice_stuff(int Ind)
6374 {
6375 	player_type *p_ptr = Players[Ind];
6376 
6377 	/* Notice stuff */
6378 	if (!p_ptr->notice) return;
6379 
6380 
6381 	/* Combine the pack */
6382 	if (p_ptr->notice & PN_COMBINE) {
6383 		p_ptr->notice &= ~(PN_COMBINE);
6384 		combine_pack(Ind);
6385 	}
6386 
6387 	/* Reorder the pack */
6388 	if (p_ptr->notice & PN_REORDER) {
6389 		p_ptr->notice &= ~(PN_REORDER);
6390 		reorder_pack(Ind);
6391 	}
6392 }
6393 
6394 
6395 /*
6396  * Handle "p_ptr->update"
6397  */
6398 void update_stuff(int Ind)
6399 {
6400 	player_type *p_ptr = Players[Ind];
6401 
6402 	/* Update stuff */
6403 	if (!p_ptr->update) return;
6404 
6405 	/* This should only be sent once. This data
6406 	   does not change in runtime */
6407 	if (p_ptr->update & PU_SKILL_INFO) {
6408 		int i;
6409 
6410 		calc_techniques(Ind);
6411 
6412 		p_ptr->update &= ~(PU_SKILL_INFO);
6413 		for (i = 0; i < MAX_SKILLS; i++) {
6414 			if (s_info[i].name) {
6415 				Send_skill_init(Ind, i);
6416 			}
6417 		}
6418 	}
6419 
6420 	if (p_ptr->update & PU_SKILL_MOD) {
6421 		int i;
6422 
6423 		p_ptr->update &= ~(PU_SKILL_MOD);
6424 		for (i = 0; i < MAX_SKILLS; i++) {
6425 			if (s_info[i].name && p_ptr->s_info[i].touched) {
6426 				Send_skill_info(Ind, i, FALSE);
6427 				p_ptr->s_info[i].touched = FALSE;
6428 			}
6429 		}
6430 		Send_skill_points(Ind);
6431 	}
6432 
6433 	if (p_ptr->update & PU_BONUS) {
6434 		p_ptr->update &= ~(PU_BONUS);
6435 		/* Take off what is no more usable, BEFORE calculating boni */
6436 		do_takeoff_impossible(Ind);
6437 		calc_boni(Ind);
6438 	}
6439 
6440 	if (p_ptr->update & PU_TORCH) {
6441 		p_ptr->update &= ~(PU_TORCH);
6442 		calc_torch(Ind);
6443 	}
6444 
6445 	if (p_ptr->update & PU_HP) {
6446 		p_ptr->update &= ~(PU_HP);
6447 		calc_hitpoints(Ind);
6448 	}
6449 
6450 	if (p_ptr->update & (PU_SANITY)) {
6451 		p_ptr->update &= ~(PU_SANITY);
6452 		calc_sanity(Ind);
6453 	}
6454 
6455 	if (p_ptr->update & PU_MANA) {
6456 		p_ptr->update &= ~(PU_MANA);
6457 		calc_mana(Ind);
6458 	}
6459 
6460 	/* Character is not ready yet, no screen updates */
6461 	/*if (!character_generated) return;*/
6462 
6463 	/* Character has changed depth very recently, no screen updates */
6464 	if (p_ptr->new_level_flag) return;
6465 
6466 	if (p_ptr->update & PU_UN_LITE) {
6467 		p_ptr->update &= ~(PU_UN_LITE);
6468 		forget_lite(Ind);
6469 	}
6470 
6471 	if (p_ptr->update & PU_UN_VIEW) {
6472 		p_ptr->update &= ~(PU_UN_VIEW);
6473 		forget_view(Ind);
6474 	}
6475 
6476 
6477 	if (p_ptr->update & PU_VIEW) {
6478 		p_ptr->update &= ~(PU_VIEW);
6479 		update_view(Ind);
6480 	}
6481 
6482 	if (p_ptr->update & PU_LITE) {
6483 		p_ptr->update &= ~(PU_LITE);
6484 		update_lite(Ind);
6485 	}
6486 
6487 
6488 	if (p_ptr->update & PU_FLOW) {
6489 		p_ptr->update &= ~(PU_FLOW);
6490 		update_flow();
6491 	}
6492 
6493 
6494 	if (p_ptr->update & PU_DISTANCE) {
6495 		p_ptr->update &= ~(PU_DISTANCE);
6496 		p_ptr->update &= ~(PU_MONSTERS);
6497 		update_monsters(TRUE);
6498 		update_players();
6499 	}
6500 
6501 	if (p_ptr->update & PU_MONSTERS) {
6502 		p_ptr->update &= ~(PU_MONSTERS);
6503 		update_monsters(FALSE);
6504 		update_players();
6505 	}
6506 
6507 
6508 #ifdef USE_SOUND_2010
6509 	/* Have we freshly forged or broken a mind link? */
6510 	if (p_ptr->update & PU_MUSIC) {
6511 		p_ptr->update &= ~PU_MUSIC;
6512 		/* hack: update music, if we're mind-linked to someone */
6513 		int Ind2;
6514 		player_type *p_ptr2;
6515 		u32b f;
6516 
6517 		/* we just forged a link (and we are sender) */
6518 		if ((Ind2 = get_esp_link(Ind, LINKF_VIEW, &p_ptr2))) {
6519 			/* hack: temporarily remove the dedicated mind-link flag, to allow Send_music() */
6520 			f = Players[Ind2]->esp_link_flags;
6521 			Players[Ind2]->esp_link_flags &= ~LINKF_VIEW_DEDICATED;
6522 			Send_music(Ind2, Players[Ind]->music_current, Players[Ind]->musicalt_current);
6523 			/* ultra hack-- abuse this for ambient sfx too ^^ */
6524 			Send_sfx_ambient(Ind2, Players[Ind]->sound_ambient, FALSE);
6525 			Players[Ind2]->esp_link_flags = f;
6526 		}
6527 		/* we just broke a link (and we were receiver) */
6528 		else {
6529 			handle_music(Ind); /* restore music after a mind-link has been broken */
6530 			/* ultra hack-- abuse this for ambient sfx too ^^ */
6531 			handle_ambient_sfx(Ind, &(getcave(&p_ptr->wpos)[p_ptr->py][p_ptr->px]), &p_ptr->wpos, FALSE);
6532 		}
6533 	}
6534 #endif
6535 
6536 
6537 	if (p_ptr->update & PU_LUA) {
6538 		/* update the client files */
6539 		p_ptr->update &= ~(PU_LUA);
6540 		p_ptr->warning_lua_update = p_ptr->warning_lua_count = 0;
6541 		exec_lua(Ind, "update_client()");
6542 	}
6543 }
6544 
6545 
6546 /*
6547  * Handle "p_ptr->redraw"
6548  */
6549 void redraw_stuff(int Ind)
6550 {
6551 	player_type *p_ptr = Players[Ind];
6552 
6553 	/* Redraw stuff */
6554 	if (!p_ptr->redraw) return;
6555 
6556 
6557 	/* Character is not ready yet, no screen updates */
6558 	/*if (!character_generated) return;*/
6559 
6560 	/* Hack -- clear the screen */
6561 	if (p_ptr->redraw & PR_WIPE) {
6562 		p_ptr->redraw &= ~PR_WIPE;
6563 		msg_print(Ind, NULL);
6564 	}
6565 
6566 
6567 	if (p_ptr->redraw & PR_MAP) {
6568 		p_ptr->redraw &= ~(PR_MAP);
6569 		prt_map(Ind);
6570 
6571 #ifdef CLIENT_SIDE_WEATHER
6572 		/* hack: update weather if it was just a panel-change
6573 		   (ie level-sector) and not a level-change.
6574 		   Note: this could become like PR_WEATHER_PANEL,
6575 		   however, PR_ flags are already in use completely atm. */
6576 		if (p_ptr->panel_changed) player_weather(Ind, FALSE, FALSE, TRUE);
6577 #endif
6578 		p_ptr->panel_changed = FALSE;
6579 	}
6580 
6581 
6582 	if (p_ptr->redraw & PR_BASIC) {
6583 		p_ptr->redraw &= ~(PR_BASIC);
6584 		p_ptr->redraw &= ~(PR_MISC | PR_TITLE | PR_STATS);
6585 		p_ptr->redraw &= ~(PR_LEV | PR_EXP | PR_GOLD);
6586 		p_ptr->redraw &= ~(PR_ARMOR | PR_HP | PR_MANA | PR_STAMINA);
6587 		p_ptr->redraw &= ~(PR_DEPTH | PR_HEALTH);
6588 		prt_frame_basic(Ind);
6589 	}
6590 
6591 	if (p_ptr->redraw & PR_ENCUMBERMENT) {
6592 		p_ptr->redraw &= ~(PR_ENCUMBERMENT);
6593 		prt_encumberment(Ind);
6594 	}
6595 
6596 	if (p_ptr->redraw & PR_MISC) {
6597 		p_ptr->redraw &= ~(PR_MISC);
6598 		Send_char_info(Ind, p_ptr->prace, p_ptr->pclass, p_ptr->ptrait, p_ptr->male, p_ptr->mode, p_ptr->name);
6599 	}
6600 
6601 	if (p_ptr->redraw & PR_TITLE) {
6602 		p_ptr->redraw &= ~(PR_TITLE);
6603 		prt_title(Ind);
6604 	}
6605 
6606 	if (p_ptr->redraw & PR_LEV) {
6607 		p_ptr->redraw &= ~(PR_LEV);
6608 		prt_level(Ind);
6609 	}
6610 
6611 	if (p_ptr->redraw & PR_EXP) {
6612 		p_ptr->redraw &= ~(PR_EXP);
6613 		prt_exp(Ind);
6614 	}
6615 
6616 	if (p_ptr->redraw & PR_STATS) {
6617 		p_ptr->redraw &= ~(PR_STATS);
6618 		prt_stat(Ind, A_STR);
6619 		prt_stat(Ind, A_INT);
6620 		prt_stat(Ind, A_WIS);
6621 		prt_stat(Ind, A_DEX);
6622 		prt_stat(Ind, A_CON);
6623 		prt_stat(Ind, A_CHR);
6624 	}
6625 
6626 	if (p_ptr->redraw & PR_ARMOR) {
6627 		p_ptr->redraw &= ~(PR_ARMOR);
6628 		prt_ac(Ind);
6629 	}
6630 
6631 	if (p_ptr->redraw & PR_HP) {
6632 		p_ptr->redraw &= ~(PR_HP);
6633 		prt_hp(Ind);
6634 	}
6635 
6636 	if (p_ptr->redraw & PR_STAMINA) {
6637 		p_ptr->redraw &= ~(PR_STAMINA);
6638 		prt_stamina(Ind);
6639 	}
6640 
6641 	if (p_ptr->redraw & PR_SANITY) {
6642 		p_ptr->redraw &= ~(PR_SANITY);
6643 #ifdef SHOW_SANITY
6644 		prt_sanity(Ind);
6645 #endif
6646 	}
6647 
6648 	if (p_ptr->redraw & PR_MANA) {
6649 		p_ptr->redraw &= ~(PR_MANA);
6650 		prt_sp(Ind);
6651 	}
6652 
6653 	if (p_ptr->redraw & PR_GOLD) {
6654 		p_ptr->redraw &= ~(PR_GOLD);
6655 		prt_gold(Ind);
6656 	}
6657 
6658 	if (p_ptr->redraw & PR_DEPTH) {
6659 		p_ptr->redraw &= ~(PR_DEPTH);
6660 		prt_depth(Ind);
6661 	}
6662 
6663 	if (p_ptr->redraw & PR_HEALTH) {
6664 		p_ptr->redraw &= ~(PR_HEALTH);
6665 		health_redraw(Ind);
6666 	}
6667 
6668 	if (p_ptr->redraw & PR_HISTORY) {
6669 		p_ptr->redraw &= ~(PR_HISTORY);
6670 		prt_history(Ind);
6671 	}
6672 
6673 	if (p_ptr->redraw & PR_VARIOUS) {
6674 		p_ptr->redraw &= ~(PR_VARIOUS);
6675 		prt_various(Ind);
6676 	}
6677 
6678 	if (p_ptr->redraw & PR_PLUSSES) {
6679 		p_ptr->redraw &= ~(PR_PLUSSES);
6680 		prt_plusses(Ind);
6681 	}
6682 
6683 	if (p_ptr->redraw & PR_SKILLS) {
6684 		p_ptr->redraw &= ~(PR_SKILLS);
6685 		prt_skills(Ind);
6686 	}
6687 
6688 	if (p_ptr->redraw & PR_EXTRA) {
6689 		p_ptr->redraw &= ~(PR_EXTRA);
6690 		p_ptr->redraw &= ~(PR_CUT | PR_STUN);
6691 		p_ptr->redraw &= ~(PR_HUNGER);
6692 		p_ptr->redraw &= ~(PR_BLIND | PR_CONFUSED);
6693 		p_ptr->redraw &= ~(PR_AFRAID | PR_POISONED);
6694 		p_ptr->redraw &= ~(PR_STATE | PR_SPEED);
6695 		if (is_older_than(&p_ptr->version, 4, 4, 8, 5, 0, 0)) p_ptr->redraw &= ~PR_STUDY;
6696 		prt_frame_extra(Ind);
6697 		prt_extra_status(Ind);
6698 	}
6699 
6700 	if (p_ptr->redraw & PR_CUT) {
6701 		p_ptr->redraw &= ~(PR_CUT);
6702 		prt_cut(Ind);
6703 	}
6704 
6705 	if (p_ptr->redraw & PR_STUN) {
6706 		p_ptr->redraw &= ~(PR_STUN);
6707 		prt_stun(Ind);
6708 	}
6709 
6710 	if (p_ptr->redraw & PR_HUNGER) {
6711 		p_ptr->redraw &= ~(PR_HUNGER);
6712 		prt_hunger(Ind);
6713 	}
6714 
6715 	if (p_ptr->redraw & PR_BLIND) {
6716 		p_ptr->redraw &= ~(PR_BLIND);
6717 		prt_blind(Ind);
6718 	}
6719 
6720 	if (p_ptr->redraw & PR_CONFUSED) {
6721 		p_ptr->redraw &= ~(PR_CONFUSED);
6722 		prt_confused(Ind);
6723 	}
6724 
6725 	if (p_ptr->redraw & PR_AFRAID) {
6726 		p_ptr->redraw &= ~(PR_AFRAID);
6727 		prt_afraid(Ind);
6728 	}
6729 
6730 	if (p_ptr->redraw & PR_POISONED) {
6731 		p_ptr->redraw &= ~(PR_POISONED);
6732 		prt_poisoned(Ind);
6733 	}
6734 
6735 	if (p_ptr->redraw & PR_STATE) {
6736 		p_ptr->redraw &= ~(PR_STATE);
6737 		prt_state(Ind);
6738 		prt_extra_status(Ind);
6739 	}
6740 
6741 	if (p_ptr->redraw & PR_SPEED) {
6742 		p_ptr->redraw &= ~(PR_SPEED);
6743 		prt_speed(Ind);
6744 	}
6745 
6746 	if (is_older_than(&p_ptr->version, 4, 4, 8, 5, 0, 0)) {
6747 		if (p_ptr->redraw & PR_STUDY) {
6748 			p_ptr->redraw &= ~(PR_STUDY);
6749 			prt_study(Ind);
6750 		}
6751 	} else {
6752 		if (p_ptr->redraw & PR_BPR) {
6753 			p_ptr->redraw &= ~(PR_BPR);
6754 			prt_bpr(Ind);
6755 		}
6756 	}
6757 }
6758 
6759 
6760 /*
6761  * Handle "p_ptr->window"
6762  */
6763 void window_stuff(int Ind)
6764 {
6765 	player_type *p_ptr = Players[Ind];
6766 
6767 	/* Window stuff */
6768 	if (!p_ptr->window) return;
6769 
6770 	/* Display inventory */
6771 	if (p_ptr->window & PW_INVEN) {
6772 		p_ptr->window &= ~(PW_INVEN);
6773 		fix_inven(Ind);
6774 	}
6775 
6776 	/* Display equipment */
6777 	if (p_ptr->window & PW_EQUIP) {
6778 		p_ptr->window &= ~(PW_EQUIP);
6779 		fix_equip(Ind);
6780 	}
6781 
6782 	/* Display player */
6783 	if (p_ptr->window & PW_PLAYER) {
6784 		p_ptr->window &= ~(PW_PLAYER);
6785 		fix_player(Ind);
6786 	}
6787 
6788 	/* Display overhead view */
6789 	if (p_ptr->window & PW_MESSAGE) {
6790 		p_ptr->window &= ~(PW_MESSAGE);
6791 		fix_message(Ind);
6792 	}
6793 
6794 	/* Display overhead view */
6795 	if (p_ptr->window & PW_OVERHEAD) {
6796 		p_ptr->window &= ~(PW_OVERHEAD);
6797 		fix_overhead(Ind);
6798 	}
6799 
6800 	/* Display monster recall */
6801 	if (p_ptr->window & PW_MONSTER) {
6802 		p_ptr->window &= ~(PW_MONSTER);
6803 		fix_monster(Ind);
6804 	}
6805 }
6806 
6807 
6808 /*
6809  * Handle "p_ptr->update" and "p_ptr->redraw" and "p_ptr->window"
6810  */
6811 void handle_stuff(int Ind)
6812 {
6813 	player_type *p_ptr = Players[Ind];
6814 
6815 	/* Hack -- delay updating */
6816 	if (p_ptr->new_level_flag) return;
6817 
6818 	/* Update stuff */
6819 	if (p_ptr->update) update_stuff(Ind);
6820 
6821 	/* Redraw stuff */
6822 	if (p_ptr->redraw) redraw_stuff(Ind);
6823 
6824 	/* Window stuff */
6825 	if (p_ptr->window) window_stuff(Ind);
6826 }
6827 
6828 
6829 /*
6830  * Start a global_event (highlander tournament etc.) - C. Blue
6831  * IMPORTANT: Ind may be 0 if this is called from custom.lua !
6832  */
6833 int start_global_event(int Ind, int getype, char *parm) {
6834 	int n, i;
6835 	player_type *p_ptr = NULL;
6836 	global_event_type *ge;
6837 	if (Ind) p_ptr = Players[Ind];
6838 #if 1 /* randomize the global_event's ID? (makes sense if you have 'hidden' events) */
6839 	int f = 0, c;
6840 	for (n = 0; n < MAX_GLOBAL_EVENTS; n++) if (global_event[n].getype == GE_NONE) f++;
6841 	if (!f) return(1); /* error, no more global events */
6842 	c = randint(f);
6843 	f = 0;
6844 	for (n = 0; n < MAX_GLOBAL_EVENTS; n++) if (global_event[n].getype == GE_NONE) {
6845 		f++;
6846 		if (f == c) break;
6847 	}
6848 #else
6849 	for (n = 0; n < MAX_GLOBAL_EVENTS; n++) if (global_event[n].getype == GE_NONE) break;/* success */
6850 	if (n == MAX_GLOBAL_EVENTS) return(1); /* error, no more global events */
6851 #endif
6852 
6853 	ge = &global_event[n];
6854 	ge->getype = getype;
6855 	ge->creator = 0;
6856 	if (Ind) ge->creator = p_ptr->id;
6857 	ge->announcement_time = 1800; /* time until event finally starts, announced every 15 mins */
6858 	ge->signup_time = 0; /* 0 = during announcement time */
6859 	ge->first_announcement = TRUE; /* first announcement will also display available commands */
6860 	ge->start_turn = turn;
6861 //	ge->start_turn = turn + 1; /* +1 is a small hack, to prevent double-announcement */
6862 	/* hack - synch start_turn to cfg.fps, since process_global_events is only called every
6863 	   (turn % cfg.fps == 0), and its announcement timer checks will fail otherwise */
6864 	ge->start_turn += (cfg.fps - (turn % cfg.fps));
6865 	time(&ge->started);
6866 	ge->paused = FALSE;
6867 	ge->paused_turns = 0; /* counter for real turns the event "missed" while being paused */
6868 	for (i = 0; i < 64; i++) {/* yeah I could use WIPE.. */
6869 	        ge->state[i] = 0;
6870 		ge->participant[i] = 0;
6871 		ge->extra[i] = 0;
6872 	}
6873 	ge->end_turn = 0;
6874 	ge->ending = 0;
6875 	strcpy(ge->title, "(UNTITLED EVENT)");
6876 	for (i = 0; i < 10; i++) strcpy(ge->description[i], "");
6877 	strcpy(ge->description[0], "(NO DESCRIPTION AVAILABLE)");
6878 	ge->hidden = FALSE;
6879 	ge->min_participants = 0; /* no minimum */
6880 	ge->limited = 0; /* no maximum */
6881 	ge->cleanup = 0; /* no cleaning up needed so far (for when the event ends) */
6882 	ge->noghost = FALSE;
6883 
6884 	/* IMPORTANT: state[0] == 255 is used as indicator that cleaning-up must be done, event has ended. */
6885 	switch(getype) {
6886 	case GE_HIGHLANDER:	/* 'Highlander Tournament' */
6887 		/* parameters:
6888 		[<int != 0>]	set announcement time to this (seconds)
6889 		['>']		create staircases leading back into the dungeon from surface */
6890 
6891 		strcpy(ge->title, "Highlander Tournament");
6892 		strcpy(ge->description[0], " Create a new level 1 character, then sign him on for this deathmatch! ");
6893 		strcpy(ge->description[1], " You're teleported into a dungeon and you have 10 minutes to level up. ");
6894 		strcpy(ge->description[2], " After that, everyone will meet under the sky for a bloody slaughter.  ");
6895 		strcpy(ge->description[3], " Add amulets of defeated opponents to yours to increase its power!     ");
6896 		strcpy(ge->description[4], " Hints: When it starts you receive an amulet, don't forget to wear it! ");
6897 		strcpy(ge->description[5], "        Buy your equipment BEFORE it starts. Or you'll go naked.       ");
6898 		strcpy(ge->description[6], " Rules: Make sure that you don't gain ANY experience until it starts.  ");
6899 		strcpy(ge->description[7], "        Also, you aren't allowed to pick up ANY gold/items from another");
6900 		strcpy(ge->description[8], "        player before the tournament begins!                           ");
6901 		strcpy(ge->description[9], "");
6902 		ge->noghost = TRUE;
6903 		ge->end_turn = ge->start_turn + cfg.fps * 60 * 90 ; /* 90 minutes max. duration,
6904 								most of the time is just for announcing it
6905 								so players will sign on via /evsign <n> */
6906 		switch(rand_int(2)) { /* Determine terrain type! */
6907 		case 0: ge->extra[2] = WILD_WASTELAND; break;
6908 //		case 1: ge->extra[2] = WILD_SWAMP; break; swamp maybe too annoying
6909 		case 1: ge->extra[2] = WILD_GRASSLAND; break;
6910 		}
6911 		switch(rand_int(3)) { /* Load premade layout? (Arenas) */
6912 		case 0: ge->extra[4] = 1; break;
6913 		}
6914 		if (!ge->extra[0]) ge->extra[0] = 95; /* there are no objects of lvl 96..99 anyways */
6915 		if (atoi(parm)) ge->announcement_time = atoi(parm);
6916 		ge->min_participants = 2;
6917 		ge->extra[5] = 0; /* 0 = don't create staircases into the dungeon, 1 = do create */
6918 		if (strstr(parm, ">")) ge->extra[5] = 1;
6919 		break;
6920 	case GE_ARENA_MONSTER:	/* 'Arena Monster Challenge' */
6921 		/* parameters: none */
6922 
6923 		strcpy(ge->title, "Arena Monster Challenge");
6924 		strcpy(ge->description[0], " During the duration of Bree's Arena Monster Challenge, you just type  ");
6925 		strcpy(ge->description[1], format(" '\377U/evsign %d <Monster Name>\377w' and you'll have a chance to challenge  ", n+1));
6926 		strcpy(ge->description[2], " it for an illusion death match in Bree's upper training tower floor.  ");
6927 		strcpy(ge->description[3], " Neither the monster nor you will really die in person, just illusions ");
6928 		strcpy(ge->description[4], " of you, created by the wizards of 'Arena Monster Challenge (tm)' will ");
6929 		strcpy(ge->description[5], " actually do the fighting. For the duration of the spell it will seem  ");
6930 		strcpy(ge->description[6], " completely real to you though, and you can even use and consume items!");
6931 //		strcpy(ge->description[7], " (Note: Some creatures might be beyond the wizards' abilities.)");
6932 		strcpy(ge->description[7], format(" (Example: '\377U/evsign %d black orc vet\377w' gets you a veteran archer!)", n+1));
6933 		strcpy(ge->description[8], "");
6934 		strcpy(ge->description[9], "");
6935 		ge->end_turn = ge->start_turn + cfg.fps * 60 * 30 ; /* 30 minutes max. duration, insta-start */
6936 #if 0
6937 		switch(rand_int(2)) { /* Determine terrain type! */
6938 		case 0: ge->extra[2] = WILD_WASTELAND; break;
6939 //		case 1: ge->extra[2] = WILD_SWAMP; break; swamp maybe too annoying
6940 		case 1: ge->extra[2] = WILD_GRASSLAND; break;
6941 		}
6942 		switch(rand_int(3)) { /* Load premade layout? (Arenas) */
6943 		case 0: ge->extra[4] = 1; break;
6944 		}
6945 #endif
6946 		ge->announcement_time = 0;
6947 		ge->signup_time = 60 * 30;
6948 		ge->min_participants = 0;
6949 		break;
6950 	case GE_DUNGEON_KEEPER:	/* 'Dungeon Keeper' Labyrinth */
6951 		strcpy(ge->title, "Dungeon Keeper");
6952 		strcpy(ge->description[0], " Characters up to level 14 are eligible to sign up for this race for   ");
6953 		strcpy(ge->description[1], " your life, through a labyrinth that is guarded by the Horned Reaper!  ");
6954 		strcpy(ge->description[2], " Rules: Running, teleporting, healing, detection, maps and speed boni  ");
6955 		strcpy(ge->description[3], "        do NOT work. You don't need any items for this event, except   ");
6956 		strcpy(ge->description[4], "        for a brass lantern which you can buy from town store '1'.     ");
6957 		strcpy(ge->description[5], " Your goal is to find one of the escape beacons (light green '>') in   ");
6958 		strcpy(ge->description[6], " time, before the horned reaper finds you or the dungeon is flooded    ");
6959 		strcpy(ge->description[7], " with lava (begins after 5 minutes, after 8 minutes it is submerged    ");
6960 		strcpy(ge->description[8], " which will mean certain death, even if you are immune to fire).       ");
6961 		strcpy(ge->description[9], " The escape beacons are self-illuminating so you won't miss them.");
6962 		ge->noghost = TRUE;
6963 		ge->end_turn = ge->start_turn + cfg.fps * 60 * 60 ; /* 60 minutes max. duration,
6964 								most of the time is just for announcing it
6965 								so players will sign on via /evsign <n> */
6966 		ge->extra[0] = 95; /* there are no objects of lvl 96..99 anyways */
6967 		ge->min_participants = 1; /* EXPERIMENTAL */
6968 		if (atoi(parm)) ge->announcement_time = atoi(parm);
6969 		break;
6970 	}
6971 
6972 	/* Fix limits */
6973 	if (ge->limited > MAX_GE_PARTICIPANTS) ge->limited = MAX_GE_PARTICIPANTS;
6974 
6975 #if 0
6976 	/* give feedback to the creator; tell all admins if this was called from a script */
6977 /*	if (Ind) {
6978 		msg_format(Ind, "Reward item level = %d.", ge->extra[0]);
6979 		msg_format(Ind, "Created new event #%d of type %d parms='%s'.", n + 1, getype, parm);
6980 	} else */{
6981 		for (i = 1;i <= NumPlayers; i++)
6982 		    if (is_admin(Players[i])) {
6983 			msg_format(i, "Reward item level = %d.", ge->extra[0]);
6984 			msg_format(i, "Created new event #%d of type %d parms='%s'.", n + 1, getype, parm);
6985 		}
6986 	}
6987 #endif
6988 	s_printf("%s EVENT_CREATE: #%d of type %d parms='%s'\n", showtime(), n + 1, getype, parm);
6989 
6990 	/* extra announcement if announcement time isn't the usual multiple of announcement intervals */
6991 #if 1 /* this is ok, and leaving it for now */
6992 	if ((ge->announcement_time % GE_ANNOUNCE_INTERVAL) && (ge->announcement_time % GE_FINAL_ANNOUNCEMENT)) announce_global_event(n);
6993 #else /* this would be even finer, but actually it's not needed as long as start_global_event() is called with sensible announcement_time :) */
6994 /* note that this else-branch is missing the GE_FINAL_ANNOUNCEMENT-check atm */
6995 	if (ge->announcement_time >= 120 && !(GE_ANNOUNCE_INTERVAL % 60)) { /* if we announce in x-minute-steps, and have at least 2 minutes left.. */
6996 		if ((ge->announcement_time / 60) % (GE_ANNOUNCE_INTERVAL / 60)) announce_global_event(n); /* ..then don't double-announce for this whole minute */
6997 	} else { /* if we announce in second-steps or weird fractions of minutes, or if we display the remaining time in seconds anyway because it's <120s.. */
6998 		if (ge->announcement_time % GE_ANNOUNCE_INTERVAL) announce_global_event(n);/* ..then don't double-announce just for this second */
6999 	}
7000 #endif
7001 	return(0);
7002 }
7003 
7004 /*
7005  * Stop a global event :(
7006  */
7007 void stop_global_event(int Ind, int n) {
7008 	global_event_type *ge = &global_event[n];
7009 	msg_format(Ind, "Wiping event #%d of type %d.", n+1, ge->getype);
7010 	s_printf("%s EVENT_STOP: #%d of type %d\n", showtime(), n+1, ge->getype);
7011 	if (ge->getype) msg_broadcast_format(0, "\377y[Event '%s' (%d) was cancelled.]", ge->title, n+1);
7012 #if 0
7013 	ge->getype = GE_NONE;
7014 	for (i = 1; i <= NumPlayers; i++) Players[i]->global_event_type[n] = GE_NONE;
7015 #else /* we really need to call the clean-up instead of just GE_NONEing it: */
7016  #if 0 /* of for normal cases */
7017 	ge->announcement_time = -1; /* enter the processing phase, */
7018  #else /* for turn overflow situations */
7019 	ge->paused_turns = 0; /* potentially fix turn counter */
7020 	ge->start_turn = turn;
7021 	ge->announcement_time = -1; /* enter the processing phase, */
7022  #endif
7023 	ge->state[0] = 255; /* ..and process clean-up! */
7024 #endif
7025 	return;
7026 }
7027 
7028 void announce_global_event(int ge_id) {
7029 	global_event_type *ge = &global_event[ge_id];
7030 	int time_left = ge->announcement_time - ((turn - ge->start_turn) / cfg.fps);
7031 
7032 	/* display minutes, if at least 120s left */
7033 	//if (time_left >= 120) msg_broadcast_format(0, "\374\377W[%s (%d) starts in %d minutes. See \377s/evinfo\377W]", ge->title, ge_id + 1, time_left / 60);
7034 	//if (time_left >= 120) msg_broadcast_format(0, "\374\377U[\377W%s (\377U%d\377W) starts in %d minutes - see /evinfo\377U]", ge->title, ge_id + 1, time_left / 60);
7035 	//if (time_left >= 120) msg_broadcast_format(0, "\374\377U[\377W%s (\377U%d\377W) starts in %d minutes\377U]", ge->title, ge_id + 1, time_left / 60);
7036 	if (time_left >= 120) msg_broadcast_format(0, "\374\377W[%s (\377U%d\377W) starts in %d minutes]", ge->title, ge_id + 1, time_left / 60);
7037 	/* otherwise just seconds */
7038 	else msg_broadcast_format(0, "\374\377W[%s (%d) starts in %d seconds!]", ge->title, ge_id + 1, time_left);
7039 
7040 	/* display additional commands on first advertisement */
7041 	if (ge->first_announcement) {
7042 		msg_broadcast_format(0, " \377WType '\377U/evinfo %d\377W' to learn more and '\377U/evsign %d\377W' to sign up.", ge_id + 1, ge_id + 1);
7043 		ge->first_announcement = FALSE;
7044 	}
7045 }
7046 
7047 /*
7048  * A player signs on for a global_event - C. Blue
7049  */
7050 void global_event_signup(int Ind, int n, cptr parm) {
7051 	int i, p, max_p;
7052 	bool fake_signup = FALSE;
7053 	global_event_type *ge = &global_event[n];
7054 	player_type *p_ptr = Players[Ind];
7055 
7056 	char parm_log[60] = "";
7057 
7058 	/* for monster type: */
7059 	char c[80], parm2[80], *cp, *p2p;
7060 	int r_found = 0;
7061 
7062 #ifdef GE_ARENA_ALLOW_EGO
7063 	/* for ego monsters: */
7064 	int re_found = 0, re_r = 0;//compiler warning
7065 	bool re_impossible = FALSE, no_ego = FALSE, perfect_ego = FALSE;
7066 	char ce[80], *cep, parm2e[80], *p2ep;
7067 	char *separator;
7068 
7069 	int r_found_tmp = 0, re_found_tmp = 0, re_r_tmp = 0;
7070 	int r_found_tmp_len = 0, r_found_len = 0;
7071 #endif
7072 
7073 	/* Still room for more participants? */
7074 	max_p = MAX_GE_PARTICIPANTS;
7075 	if (ge->limited) max_p = ge->limited; /* restricted number of participants? */
7076 	for (p = 0; p < max_p; p++) if (!ge->participant[p]) break;/* success */
7077 	if (p == max_p) {
7078 		msg_print(Ind, "\377ySorry, maximum number of possible participants has been reached.");
7079 		return;
7080 	}
7081 
7082 	for (i = 0; i < max_p; i++) if (ge->participant[i] == p_ptr->id) {
7083 		msg_print(Ind, "\377sYou have already signed up!");
7084 		return;
7085 	}
7086 
7087 	if (p_ptr->inval) {
7088 		msg_print(Ind, "\377ySorry, only validated accounts may participate.");
7089 		return;
7090 	}
7091 
7092 	/* check individual event restrictions against player */
7093 	switch (ge->getype) {
7094 	case GE_HIGHLANDER:	/* Highlander Tournament */
7095 		if (p_ptr->mode & MODE_DED_IDDC) {
7096 			msg_print(Ind, "\377ySorry, as a dedicated ironman deep diver you may not participate.");
7097 			if (!is_admin(p_ptr)) return;
7098 		}
7099 		if (p_ptr->mode & MODE_PVP) {
7100 			msg_print(Ind, "\377ySorry, PvP characters may not participate.");
7101 			if (!is_admin(p_ptr)) return;
7102 		}
7103 		if (p_ptr->global_event_participated[ge->getype]) {
7104 			msg_print(Ind, "\377ySorry, a character may participate only once in this event.");
7105 			if (!is_admin(p_ptr)) return;
7106 		}
7107 		if (p_ptr->max_exp > 0 || p_ptr->max_plv > 1) {
7108 			msg_print(Ind, "\377ySorry, only newly created characters may sign up for this event.");
7109 			if (!is_admin(p_ptr)) return;
7110 		}
7111 		if (p_ptr->fruit_bat == 1) { /* 1 = native bat, 2 = from chauve-souris */
7112 			msg_print(Ind, "\377ySorry, native fruit bats are not eligible to join this event.");
7113 			if (!is_admin(p_ptr)) return;
7114 		}
7115 		break;
7116 	case GE_ARENA_MONSTER:	/* Arena Monster Challenge */
7117 		if (ge->state[0] != 1) { /* in case we do add an announcement time.. */
7118 			msg_print(Ind, "\377yYou have to wait until it starts to sign up for this event!");
7119 			return;
7120 		}
7121 #if 0 /* need to be in Bree or in the arena? */
7122 		if (!in_bree(&p_ptr->wpos) &&
7123 		    (p_ptr->wpos.wx != WPOS_ARENA_X || p_ptr->wpos.wy != WPOS_ARENA_Y || p_ptr->wpos.wz != WPOS_ARENA_Z)) {
7124 			msg_print(Ind, "\377yYou have to be in Bree or in the arena to sign up for this event!");
7125 #else /* need to be in Bree or in the training tower? */
7126 		if (!in_bree(&p_ptr->wpos) && !in_trainingtower(&p_ptr->wpos)
7127 		    && !is_admin(p_ptr)) {
7128 			msg_print(Ind, "\377yYou have to be in Bree or in the training tower to sign up for this event!");
7129 #endif
7130 			return;
7131 		}
7132 		if ((parm == NULL) || !strlen(parm)) {
7133 			msg_format(Ind, "\377yYou have to specify a monster name:  /evsign %d monstername", n+1);
7134 			return;
7135 		}
7136 
7137 		/* lower case */
7138 		strcpy(parm2, parm);
7139 		p2p = parm2;
7140 		while (*p2p) {*p2p = tolower(*p2p); p2p++;}
7141 
7142 		/* trim spaces */
7143 		p2p = parm2;
7144 		while (*p2p == ' ') p2p++;
7145 		while (p2p[strlen(p2p) - 1] == ' ') p2p[strlen(p2p) - 1] = 0;
7146 
7147 		/* Scan the monster races */
7148 		for (i = 1; i < MAX_R_IDX - 1; i++) {
7149 			/* get monster race name */
7150 			strcpy(c, r_info[i].name + r_name);
7151 			if (!strlen(c)) continue;
7152 
7153 			/* lower case */
7154 			cp = c;
7155 			while (*cp) {*cp = tolower(*cp); cp++;}
7156 
7157 
7158 			/* exact match? */
7159 			if (!strcmp(p2p, c)) {
7160 				r_found = i;
7161 				no_ego = TRUE;
7162 				re_found = 0;
7163 
7164 				/* done. No room for ego power. */
7165 				break;
7166 			}
7167 
7168 #ifndef GE_ARENA_ALLOW_EGO
7169 			if (strstr(p2p, c)) {
7170 				r_found = i;
7171 				r_found_len = strlen(c);
7172 			}
7173 #else
7174 			/* partial match? could have ego power too. */
7175 			if ((separator = strstr(p2p, c))) {
7176 				/* test for ego power for the rest of the string */
7177 				if (separator == p2p) { /* monster name begins with race name? */
7178 					strcpy(parm2e, p2p + strlen(c)); /* then ego power begins afterwards and goes till the end of the monster name */
7179 				} else if (strlen(separator) < strlen(c)) { /* error: race name has chars before AND afterwards */
7180 					continue;
7181 				} else { /* monster name ends with race name? */
7182 					strncpy(parm2e, p2p, strlen(p2p) - strlen(c)); /* then ego power starts at the beginning of the monster name */
7183 					parm2e[strlen(p2p) - strlen(c)] = 0;
7184 				}
7185 
7186 				/* if we already found both, a matching monster + ego, be wary of this new result!
7187 				   Otherwise, 'black orc vet' will result in a plain 'Black' getting spawned.. */
7188 				if (r_found && re_found) {
7189 					r_found_tmp = r_found;
7190 					re_found_tmp = re_found;
7191 					re_r_tmp = re_r;
7192 				} else if (r_found) {
7193 					r_found_tmp = r_found;
7194 					r_found_tmp_len = r_found_len;
7195 				}
7196 
7197 				/* remember choice in case we don't find anything better */
7198 				r_found = i;
7199 				r_found_len = strlen(c);
7200 
7201 				/* check ego power - if exact match then we're done */
7202 				/* trim spaces just to be sure */
7203 				p2ep = parm2e;
7204 				while (*p2ep == ' ') p2ep++;
7205 				while (p2ep[strlen(p2ep) - 1] == ' ') p2ep[strlen(p2ep) - 1] = 0;
7206 
7207 				/* IMPOSSIBLE-- no ego power specified, it was just spaces? */
7208 				//if (!strlen(parm2e))
7209 
7210 			        for (p = 1; p < MAX_RE_IDX; p++) {
7211 					/* get monster ego name */
7212 					strcpy(ce, re_info[p].name + re_name);
7213 
7214 					/* lower case */
7215 					cep = ce;
7216 					while (*cep) {*cep = tolower(*cep); cep++;}
7217 
7218 					/* exact match? */
7219 					if (!strcmp(p2ep, ce)) {
7220 						if (mego_ok(i, p)) {
7221 							/* done, success */
7222 							re_impossible = FALSE;
7223 							re_found = p;
7224 							re_r = i;
7225 							perfect_ego = TRUE;
7226 
7227 #if 1
7228 							/* special hack: check all remaining races and prefer them if EXACT match - added for 'Fallen Angel'! */
7229 							//actually, with ne addition of 'r_found_len' this should now be obsolete?
7230 							while (++i < MAX_R_IDX - 1) {
7231 								/* get monster race name */
7232 								strcpy(c, r_info[i].name + r_name);
7233 								if (!strlen(c)) continue;
7234 
7235 								/* lower case */
7236 								cp = c;
7237 								while (*cp) {*cp = tolower(*cp); cp++;}
7238 
7239 								/* exact match? */
7240 								if (!strcmp(p2p, c)) {
7241 									if (!is_admin(p_ptr) &&
7242 									    ((r_info[i].flags1 & RF1_UNIQUE) ||
7243 									    (r_info[i].flags1 & RF1_QUESTOR) ||
7244 									    (r_info[i].flags7 & RF7_NEVER_ACT) ||
7245 									    (r_info[i].flags7 & RF7_PET) ||
7246 									    (r_info[i].flags7 & RF7_NEUTRAL) ||
7247 									    (r_info[i].flags7 & RF7_FRIENDLY) ||
7248 									    (r_info[i].flags8 & RF8_JOKEANGBAND) ||
7249 									    (r_info[i].rarity == 255)))
7250 										continue;
7251 
7252 									/* done. Discard perfect 'ego power+base race' in favour for just plain perfect base race,
7253 									   to allow 'Fallen Angel' base monster instead of 'Fallen' ego type on 'Angel' base monster. */
7254 									r_found = i;
7255 									r_found_len = strlen(c);
7256 									no_ego = TRUE;
7257 									re_found = 0;
7258 									break;
7259 								}
7260 							}
7261 #endif
7262 
7263 							break;
7264 						}
7265 						/* impossible ego power -- keep searching in case we find something better */
7266 						re_impossible = TRUE;
7267 					} else if (re_impossible) continue; /* don't allow partial matches if an exact match already failed us */
7268 
7269 					/* partial match? */
7270 					//else if (strstr(p2ep, ce)) {
7271 					else if (strstr(ce, p2ep)) {
7272 						if (mego_ok(i, p)) {
7273 							/* remember choice in case we don't find anything better */
7274 							re_found = p;
7275 							re_r = i;
7276 						}
7277 					}
7278 				}
7279 				if (perfect_ego) break;
7280 #endif
7281 			}
7282 
7283 			/* if we already found both, a matching monster + ego, be wary of this new result!
7284 			   Otherwise, 'black orc vet' will result in a plain 'Black' getting spawned.. */
7285 			if (r_found_tmp && re_found_tmp && !re_found) {
7286 				r_found = r_found_tmp;
7287 				re_found = re_found_tmp;
7288 				re_r = re_r_tmp;
7289 			}
7290 			/* if we still found no ego power, at least choose the base type that matches a longer string.
7291 			   Otherwise 'black orc vet' will result in a Black spawning.. */
7292 			else if (r_found_tmp && !re_found_tmp && !re_found && r_found_tmp_len > r_found_len)
7293 				r_found = r_found_tmp;
7294 		}
7295 
7296 		if (!r_found) {
7297 			msg_format(Ind, "\377yCouldn't find base monster (punctuation and name must be exact).", n);
7298 			return;
7299 		}
7300 #ifdef GE_ARENA_ALLOW_EGO
7301 		if (re_impossible) {
7302 			msg_print(Ind, "\377ySorry, that ego creature is beyond the wizards' abilities.");
7303 			return;
7304 		}
7305 		/* if we didn't find a race+ego combo, we at least found a raw race, use it */
7306 		if (!re_found && !no_ego) {
7307 			msg_print(Ind, "\377yCouldn't find matching ego power, going with base version..");
7308 		}
7309 #endif
7310 
7311 		/* if we found a race and ego that somewhat fit, prefer that over just a race without ego, that somewhat fits */
7312 		if (re_found) r_found = re_r;
7313 
7314 		/* base monster type is not allowed? */
7315 		if (!is_admin(p_ptr) &&
7316 		    ((r_info[r_found].flags1 & RF1_UNIQUE) ||
7317 		    (r_info[r_found].flags1 & RF1_QUESTOR) ||
7318 		    (r_info[r_found].flags7 & RF7_NEVER_ACT) ||
7319 		    (r_info[r_found].flags7 & RF7_PET) ||
7320 		    (r_info[r_found].flags7 & RF7_NEUTRAL) ||
7321 		    (r_info[r_found].flags7 & RF7_FRIENDLY) ||
7322 		    (r_info[r_found].flags8 & RF8_JOKEANGBAND) ||
7323 		    (r_info[r_found].rarity == 255))) {
7324 			msg_print(Ind, "\377ySorry, that creature is beyond the wizards' abilities.");
7325 			return;
7326 		}
7327 
7328 		ge->extra[1] = r_found;
7329 #ifndef GE_ARENA_ALLOW_EGO
7330 		monster_race_desc(0, c, r_found_race_only, 0x188);
7331 		msg_broadcast_format(0, "\376\377c** %s challenges %s! **", p_ptr->name, c);
7332 		strcpy(parm_log, r_name + r_info[r_found].name);
7333 #else
7334 		ge->extra[3] = re_found;
7335 		ge->extra[5] = Ind;
7336 
7337 		/* rebuild parm from definite ego+monster name */
7338 		if (re_found) {
7339 			strcpy(parm_log, re_name + re_info[re_found].name);
7340 			strcat(parm_log, " ");
7341 			strcat(parm_log, r_name + r_info[r_found].name);
7342 		} else {
7343 			strcpy(parm_log, r_name + r_info[r_found].name);
7344 		}
7345 #endif
7346 
7347 		fake_signup = TRUE;
7348 		break;
7349 	case GE_DUNGEON_KEEPER:	/* 'Dungeon Keeper' labyrinth race */
7350 		if (p_ptr->mode & MODE_DED_IDDC) {
7351 			msg_print(Ind, "\377ySorry, as a dedicated ironman deep diver you may not participate.");
7352 			if (!is_admin(p_ptr)) return;
7353 		}
7354 		if (p_ptr->mode & MODE_PVP) {
7355 			msg_print(Ind, "\377ySorry, PvP characters may not participate.");
7356 			if (!is_admin(p_ptr)) return;
7357 		}
7358 		if (p_ptr->max_plv > 14) {
7359 			msg_print(Ind, "\377ySorry, you must be at most level 14 to sign up for this event.");
7360 			if (!is_admin(p_ptr)) return;
7361 		}
7362 #if 0 /* fine now since speed is limited to +0 via floor flag */
7363 		if (p_ptr->fruit_bat == 1) { /* 1 = native bat, 2 = from chauve-souris */
7364 			msg_print(Ind, "\377ySorry, native fruit bats are not eligible to join this event.");
7365 			if (!is_admin(p_ptr)) return;
7366 		}
7367 #endif
7368 		if (p_ptr->ghost) {
7369 			msg_print(Ind, "\377ySorry, ghosts may not participate in this event.");
7370 			if (!is_admin(p_ptr)) return;
7371 		}
7372 		if (p_ptr->global_event_participated[ge->getype]) {
7373 			msg_print(Ind, "\377ySorry, a character may participate only once in this event.");
7374 			if (!is_admin(p_ptr)) return;
7375 		}
7376 		break;
7377 	}
7378 
7379 	if (parm_log[0]) s_printf("%s EVENT_SIGNUP: %d (%s): %s (%s).\n", showtime(), n + 1, ge->title, p_ptr->name, parm_log);
7380 	else s_printf("%s EVENT_SIGNUP: %d (%s): %s.\n", showtime(), n + 1, ge->title, p_ptr->name);
7381 	if (fake_signup) return;
7382 
7383 	/* currently no warning/error/solution if you try to sign on for multiple events at the same time :|
7384 	   However, player_type has MAX_GLOBAL_EVENTS sized data arrays for each event, so a player *could*
7385 	   theoretically participate in all events at once at this time.. */
7386 	msg_format(Ind, "\374\377c>>You signed up for %s!<<", ge->title);
7387 	msg_broadcast_format(Ind, "\374\377c%s signed up for %s.", p_ptr->name, ge->title);
7388 	ge->participant[p] = p_ptr->id;
7389 	p_ptr->global_event_type[n] = ge->getype;
7390 	time(&p_ptr->global_event_signup[n]);
7391 	p_ptr->global_event_started[n] = ge->started;
7392 	for (i = 0; i < 4; i++) p_ptr->global_event_progress[n][i] = 0; /* WIPE :p */
7393 }
7394 
7395 /*
7396  * Process a global event - C. Blue
7397  */
7398 static void process_global_event(int ge_id) {
7399 	global_event_type *ge = &global_event[ge_id];
7400 	player_type *p_ptr;
7401 	object_type forge, *o_ptr = &forge; /* for creating a reward, for example */
7402 	worldpos wpos;
7403         struct wilderness_type *wild;
7404 	struct dungeon_type *d_ptr;
7405 	int participants = 0;
7406 	int i, j = 0, n, k, x, y; /* misc variables, used by the events */
7407 	cave_type **zcave, *c_ptr;
7408 	int xstart = 0, ystart = 0; /* for arena generation */
7409 	long elapsed, elapsed_turns; /* amounts of seconds elapsed since the event was started (created) */
7410 	char m_name[MNAME_LEN], buf[MSG_LEN];
7411 	int m_idx, tries = 0;
7412 	time_t now;
7413 
7414 	time(&now);
7415 	/* real timer will sometimes fail when using in a function which isn't sync'ed against it but instead relies
7416 	    on the game's FPS for timining ..strange tho :s */
7417 	elapsed_turns = turn - ge->start_turn - ge->paused_turns;
7418 	elapsed = elapsed_turns / cfg.fps;
7419 
7420 	wpos.wx = WPOS_SECTOR00_X; /* sector 0,0 by default, for 'sector00separation' */
7421 	wpos.wy = WPOS_SECTOR00_Y;
7422 	wpos.wz = WPOS_SECTOR00_Z;
7423 
7424 	/* catch absurdities (happens on turn overflow) */
7425 	if (elapsed_turns > 100000 * cfg.fps) {
7426 		ge->paused_turns = 0;
7427 		ge->start_turn = turn; /* fix turn counter */
7428 		elapsed_turns = 0;
7429 		ge->announcement_time = -1; /* enter the processing phase, */
7430 		ge->state[0] = 255; /* ..and process clean-up! */
7431 	}
7432 
7433 	/* extra warning at T - x min for last minute subscribers */
7434 	if (ge->announcement_time * cfg.fps - elapsed_turns == GE_FINAL_ANNOUNCEMENT * cfg.fps) {
7435 		announce_global_event(ge_id);
7436 		return; /* not yet >:) */
7437 
7438 	/* Start/announce event */
7439 	} else if (ge->announcement_time * cfg.fps - elapsed_turns >= 0) {
7440 //debug		msg_format(1, ".%d.%d", ge->announcement_time * cfg.fps - elapsed_turns, elapsed_turns);
7441 
7442 		/* Start/announce event, take two */
7443 		if (!((ge->announcement_time * cfg.fps - elapsed_turns) % (GE_ANNOUNCE_INTERVAL * cfg.fps))) {
7444 
7445 			/* we're still just announcing the event -- nothing more to do for now */
7446 			if (ge->announcement_time * cfg.fps - elapsed_turns > 0L) {
7447 				announce_global_event(ge_id);
7448 				return; /* not yet >:) */
7449 
7450 			/* prepare to start the event! */
7451 			} else {
7452 				dungeon_type *d_ptr;
7453 
7454 				/* count participants first, to see if there are enough to start the event */
7455 				for (i = 0; i < MAX_GE_PARTICIPANTS; i++) {
7456 					if (!ge->participant[i]) continue;
7457 
7458 					/* Check that the player really is here - mikaelh */
7459 					for (j = 1; j <= NumPlayers; j++)
7460 						if (Players[j]->id == ge->participant[i]) break;
7461 					if (j > NumPlayers) {
7462 						s_printf("EVENT_CHECK_PARTICIPANTS: ID %d no longer available.\n", ge->participant[i]);
7463 						continue;
7464 					}
7465 
7466 					p_ptr = Players[j];
7467 					d_ptr = getdungeon(&p_ptr->wpos);
7468 
7469 					/* Check that he still fulfils requirements, if any */
7470 					switch (ge->getype) {
7471 					case GE_HIGHLANDER:
7472 						if ((p_ptr->max_exp || p_ptr->max_plv > 1) && !is_admin(p_ptr)) {
7473 							s_printf("EVENT_CHECK_PARTICIPANTS: Player '%s' no longer eligible.\n", p_ptr->name);
7474 							msg_print(j, "\377oCharacters need to have 0 experience to be eligible.");
7475 							p_ptr->global_event_type[ge_id] = GE_NONE;
7476 							ge->participant[i] = 0;
7477 							continue;
7478 						}
7479 						if (d_ptr && ((d_ptr->flags1 & (DF1_FORCE_DOWN | DF1_NO_RECALL)) || (d_ptr->flags2 & (DF2_IRON | DF2_NO_EXIT_WOR)))) {
7480 							s_printf("EVENT_CHECK_PARTICIPANTS: Player '%s' stuck in dungeon.\n", p_ptr->name);
7481 							msg_print(j, "\377oEvent participation failed because your dungeon doesn't allow recalling.");
7482 							p_ptr->global_event_type[ge_id] = GE_NONE;
7483 							ge->participant[i] = 0;
7484 							continue;
7485 						}
7486 						break;
7487 					case GE_DUNGEON_KEEPER:
7488 						if ((p_ptr->max_plv > 14) && !is_admin(p_ptr)) {
7489 							s_printf("EVENT_CHECK_PARTICIPANTS: Player '%s' no longer eligible.\n", p_ptr->name);
7490 							msg_print(j, "\377oCharacters need to have 0 experience to be eligible.");
7491 							p_ptr->global_event_type[ge_id] = GE_NONE;
7492 							ge->participant[i] = 0;
7493 							continue;
7494 						}
7495 						if (d_ptr && ((d_ptr->flags1 & (DF1_FORCE_DOWN | DF1_NO_RECALL)) || (d_ptr->flags2 & (DF2_IRON | DF2_NO_EXIT_WOR)))) {
7496 							s_printf("EVENT_CHECK_PARTICIPANTS: Player '%s' stuck in dungeon.\n", p_ptr->name);
7497 							msg_print(j, "\377oEvent participation failed because your dungeon doesn't allow recalling.");
7498 							p_ptr->global_event_type[ge_id] = GE_NONE;
7499 							ge->participant[i] = 0;
7500 							continue;
7501 						}
7502 						break;
7503 					}
7504 
7505 					/* Player is valid for entering */
7506 					participants++;
7507 				}
7508 
7509 				/* not enough participants? Don't hand out reward for free to someone. */
7510 				if (ge->min_participants && (participants < ge->min_participants)) {
7511 					msg_broadcast_format(0, "\377y%s needs at least %d participant%s.", ge->title, ge->min_participants, ge->min_participants == 1 ? "" : "s");
7512 					s_printf("%s EVENT_NOPLAYERS: %d (%s) has only %d/%d participants.\n", showtime(), ge_id + 1, ge->title, participants, ge->min_participants);
7513 					/* remove players who DID sign up from being 'participants' */
7514 					for (j = 1; j <= NumPlayers; j++)
7515 						if (Players[j]->global_event_type[ge_id] == ge->getype)
7516 							Players[j]->global_event_type[ge_id] = GE_NONE;
7517 					ge->getype = GE_NONE;
7518 
7519 				/* Participants are ok, event now starts! */
7520 				} else {
7521 					s_printf("%s EVENT_STARTS: %d (%s) has %d participants.\n", showtime(), ge_id + 1, ge->title, participants);
7522 					msg_broadcast_format(0, "\374\377U[>>\377C%s (\377U%d\377C) starts now!\377U<<]", ge->title, ge_id + 1);
7523 
7524 					/* memorize each character's participation */
7525 					for (j = 0; j < MAX_GE_PARTICIPANTS; j++) {
7526 						if (!ge->participant[j]) continue;
7527 
7528 						for (i = 1; i <= NumPlayers; i++) {
7529 							if (Players[i]->id != ge->participant[j]) continue;
7530 							Players[i]->global_event_participated[ge->getype]++;
7531 						}
7532 					}
7533 				}
7534 			}
7535 
7536 		/* we're still just announcing the event -- nothing more to do for now */
7537 		} else {
7538 			return; /* still announcing */
7539 		}
7540 	}
7541 
7542 	/* Event starts immediately without announcement time? Still display a hint message. */
7543 	if (!ge->announcement_time && !ge->state[0])
7544 		msg_broadcast_format(0, " \377WType '\377U/evinfo %d\377W' to learn more and '\377U/evsign %d\377W' to sign up.", ge_id + 1, ge_id + 1);
7545 
7546 	/* if event is not yet over, check if it could be.. */
7547 	if (ge->state[0] != 255) {
7548 		/* Time Over? :( */
7549 		if ((ge->end_turn && turn >= ge->end_turn) ||
7550 		    (ge->ending && now >= ge->ending)) {
7551 			ge->state[0] = 255; /* state[0] is used as indicator for clean-up phase of any event */
7552 			msg_broadcast_format(0, "\377y>>%s ends due to time limit!<<", ge->title);
7553 			s_printf("%s EVENT_TIMEOUT: %d - %s.\n", showtime(), ge_id + 1, ge->title);
7554 		}
7555 		/* Time warning at T-5minutes! (only if the whole event lasts MORE THAN 10 minutes) */
7556 		/* Note: paused turns will be added to the running time, IF the event end is given in "turns" */
7557 		if ((ge->end_turn && ge->end_turn - ge->start_turn - ge->paused_turns > 600 * cfg.fps && turn - ge->paused_turns == ge->end_turn - 300 * cfg.fps) ||
7558 		    /* However, paused turns will be ignored if the event end is given as absolute time! */
7559 		    (!ge->end_turn && ge->ending && ge->ending - ge->started > 600 && now == ge->ending - 360)) {
7560 			msg_broadcast_format(0, "\377y[%s (%d) comes to an end in 6 more minutes!]", ge->title, ge_id + 1);
7561 		}
7562 	}
7563 
7564 	/* Event is running! Process its stages... */
7565 	switch (ge->getype) {
7566 	/* Highlander Tournament */
7567 	case GE_HIGHLANDER:
7568 		switch (ge->state[0]) {
7569 		case 0: /* prepare level, gather everyone, start exp'ing */
7570 			ge->cleanup = 1;
7571 			sector00separation++; /* separate sector 0,0 from the worldmap - participants have access ONLY */
7572 			sector00flags1 = sector00flags2 = 0x0;
7573 			wipe_m_list(&wpos); /* clear any (powerful) spawns */
7574 			wipe_o_list_safely(&wpos); /* and objects too */
7575 			unstatic_level(&wpos);/* get rid of any other person, by unstaticing ;) */
7576 
7577 			if (!getcave(&wpos)) alloc_dungeon_level(&wpos);
7578 			/* generate solid battleground, not oceans and stuff */
7579 			ge->extra[1] = wild_info[wpos.wy][wpos.wx].type;
7580 			s_printf("EVENT_LAYOUT: Generating wild %d at %d,%d,%d\n", ge->extra[2], wpos.wx, wpos.wy, wpos.wz);
7581 			wild_info[wpos.wy][wpos.wx].type = ge->extra[2];
7582 			wilderness_gen(&wpos);
7583 			/* make it static */
7584 //			static_level(&wpos); /* preserve layout while players dwell in dungeon (for arena layouts) */
7585 			new_players_on_depth(&wpos, 1, FALSE);
7586 			/* wipe obstacles away so ranged chars vs melee chars won't end in people waiting inside trees */
7587 			zcave = getcave(&wpos);
7588 			for (x = 1; x < MAX_WID - 1; x++)
7589 			for (y = 1; y < MAX_HGT - 1; y++) {
7590 				c_ptr = &zcave[y][x];
7591 				if (c_ptr->feat == FEAT_IVY ||
7592 				    c_ptr->feat == FEAT_BUSH ||
7593 				    c_ptr->feat == FEAT_DEAD_TREE ||
7594 				    c_ptr->feat == FEAT_TREE)
7595 					switch (ge->extra[2]) {
7596 					case WILD_WASTELAND: c_ptr->feat = FEAT_DIRT; break;
7597 					case WILD_GRASSLAND:
7598 					default: c_ptr->feat = FEAT_GRASS; break;
7599 					}
7600 			}
7601 			if (ge->extra[4]) {
7602 				/* Generate the level from fixed arena layout */
7603 				s_printf("EVENT_LAYOUT: Generating arena %d at %d,%d,%d\n", ge->extra[4], wpos.wx, wpos.wy, wpos.wz);
7604 				process_dungeon_file(format("t_arena%d.txt", ge->extra[4]), &wpos, &ystart, &xstart, MAX_HGT, MAX_WID, TRUE);
7605 			}
7606 
7607 			/* actually create temporary Highlander dungeon! */
7608 			if (!wild_info[wpos.wy][wpos.wx].dungeon) {
7609 				/* add staircase downwards into the dungeon? */
7610 				if (!ge->extra[5]) {
7611 					s_printf("EVENT_LAYOUT: Adding dungeon (no entry).\n");
7612 					add_dungeon(&wpos, 1, 50, DF1_NO_RECALL, DF2_IRON | DF2_NO_EXIT_MASK |
7613 					    DF2_NO_ENTRY_MASK,
7614 					    DF3_NO_SIMPLE_STORES | DF3_NO_DUNGEON_BONUS | DF3_EXP_20, FALSE, 0, 0, 0, 0);
7615 				} else {
7616 					s_printf("EVENT_LAYOUT: Adding dungeon (entry ok).\n");
7617 					add_dungeon(&wpos, 1, 50, DF1_NO_RECALL, DF2_IRON | DF2_NO_EXIT_MASK |
7618 					    DF2_NO_ENTRY_WOR | DF2_NO_ENTRY_PROB | DF2_NO_ENTRY_FLOAT,
7619 					    DF3_NO_SIMPLE_STORES | DF3_NO_DUNGEON_BONUS | DF3_EXP_20, FALSE, 0, 0, 0, 0);
7620 
7621 					/* place staircase on an empty accessible grid */
7622 					do {
7623 						y = rand_int((MAX_HGT) - 3) + 1;
7624 						x = rand_int((MAX_WID) - 3) + 1;
7625 					} while (!cave_floor_bold(zcave, y, x)
7626 					    && (++tries < 1000));
7627 					zcave[y][x].feat = FEAT_MORE;
7628 					/* remember for dungeon removal at the end */
7629 					ge->extra[6] = x;
7630 					ge->extra[7] = y;
7631 
7632 					sector00downstairs++;
7633 				}
7634 			} else {
7635 				s_printf("EVENT_LAYOUT: Dungeon already in place.\n");
7636 			}
7637 
7638 			/* teleport the participants into the dungeon */
7639 			for (j = 0; j < MAX_GE_PARTICIPANTS; j++) {
7640 				if (!ge->participant[j]) continue;
7641 
7642 				for (i = 1; i <= NumPlayers; i++) {
7643 					if (Players[i]->id != ge->participant[j]) continue;
7644 
7645 					p_ptr = Players[i];
7646 
7647 					if (p_ptr->wpos.wx != WPOS_SECTOR00_X || p_ptr->wpos.wy != WPOS_SECTOR00_Y) {
7648 						p_ptr->recall_pos.wx = WPOS_SECTOR00_X;
7649 						p_ptr->recall_pos.wy = WPOS_SECTOR00_Y;
7650 						p_ptr->recall_pos.wz = -1;
7651 						p_ptr->global_event_temp = PEVF_PASS_00 | PEVF_NOGHOST_00 |
7652 						    PEVF_SAFEDUN_00 | PEVF_SEPDUN_00;
7653 						p_ptr->new_level_method = LEVEL_OUTSIDE_RAND;
7654 						recall_player(i, "");
7655 					}
7656 					/* Give him the amulet of the highlands */
7657 					invcopy(o_ptr, lookup_kind(TV_AMULET, SV_AMULET_HIGHLANDS));
7658 					o_ptr->number = 1;
7659 					o_ptr->level = 0;
7660 					o_ptr->discount = 0;
7661 					o_ptr->ident |= ID_MENTAL;
7662 					o_ptr->owner = p_ptr->id;
7663 					o_ptr->mode = p_ptr->mode;
7664 					object_aware(i, o_ptr);
7665 					object_known(o_ptr);
7666 					inven_carry(i, o_ptr);
7667 					/* may only take part in one tournament per char */
7668 					gain_exp(i, 1);
7669 					/* give some safe time for exp'ing */
7670 #ifndef KURZEL_PK
7671 					if (cfg.use_pk_rules == PK_RULES_DECLARE) {
7672 						p_ptr->pkill &= ~PKILL_KILLABLE;
7673 					}
7674 #endif
7675 					p_ptr->global_event_progress[ge_id][0] = 1; /* now in 0,0,0-dungeon! */
7676 				}
7677 			}
7678 
7679 			ge->state[0] = 1;
7680 			break;
7681 		case 1: /* exp phase - end prematurely if all players pseudo-died in dungeon */
7682 			n = 0;
7683 			k = 0;
7684 			for (i = 1; i <= NumPlayers; i++)
7685 				if (!Players[i]->admin_dm && Players[i]->wpos.wx == WPOS_SECTOR00_X && Players[i]->wpos.wy == WPOS_SECTOR00_Y) {
7686 					n++;
7687 					j = i;
7688 					/* count players who have already been kicked out of the dungeon by pseudo-dying */
7689 					if (!Players[i]->wpos.wz) k++;
7690 				}
7691 
7692 			if (!n) ge->state[0] = 255; /* double kill by monsters or something? ew. */
7693 			else if (n == 1) { /* early ending, everyone died to monsters in the dungeon */
7694 				ge->state[0] = 6;
7695 				ge->extra[3] = j;
7696 			}
7697 			else if ((n == k) && !ge->extra[5]) ge->state[0] = 3; /* all players are already at the surface,
7698 										because all of them were defeated by monsters,
7699 										and there's no staircase to re-enter the dungeon.. */
7700 			else if (elapsed - ge->announcement_time >= 600 - 45) { /* give a warning, peace ends soon */
7701 				for (i = 1; i <= NumPlayers; i++)
7702 					if (Players[i]->wpos.wx == WPOS_SECTOR00_X && Players[i]->wpos.wy == WPOS_SECTOR00_Y)
7703 						msg_print(i, "\377f[The slaughter will begin soon!]");
7704 				ge->state[0] = 2;
7705 			}
7706 			break;
7707 		case 2: /* final exp phase after the warning has been issued - end prematurely if needed (see above) */
7708 			n = 0;
7709 			k = 0;
7710 			for (i = 1; i <= NumPlayers; i++)
7711 				if (!Players[i]->admin_dm && Players[i]->wpos.wx == WPOS_SECTOR00_X && Players[i]->wpos.wy == WPOS_SECTOR00_Y) {
7712 					n++;
7713 					j = i;
7714 					if (!Players[i]->wpos.wz) k++;
7715 				}
7716 
7717 			if (!n) ge->state[0] = 255; /* double kill or something? ew. */
7718 			else if (n == 1) { /* early ending, everyone died to monsters in the dungeon */
7719 				ge->state[0] = 6;
7720 				ge->extra[3] = j;
7721 			}
7722 			else if ((n == k) && !ge->extra[5]) ge->state[0] = 3; /* start deathmatch already (see above, state 1) */
7723 			else if (elapsed - ge->announcement_time >= 600) ge->state[0] = 3; /* start deathmatch phase */
7724 			break;
7725 		case 3: /* get people out of the dungeon (if not all pseudo-died already) and make them fight each other properly */
7726 			/* remember time stamp when we entered deathmatch phase (for spawning a baddy) */
7727 			ge->state[2] = turn - ge->start_turn; /* this keeps it /gefforward friendly */
7728 			ge->state[3] = 0;
7729 			sector00music = 47; /* death match theme */
7730 
7731 			/* got a staircase to remove? */
7732 			if (ge->extra[5]) {
7733 				zcave = getcave(&wpos);
7734 				zcave[ge->extra[7]][ge->extra[6]].feat = FEAT_DIRT;
7735 				everyone_lite_spot(&wpos, ge->extra[7], ge->extra[6]);
7736 				sector00downstairs--;
7737 				ge->extra[5] = 0;
7738 			}
7739 
7740 			for (i = 1; i <= NumPlayers; i++) {
7741 				p_ptr = Players[i];
7742 				if (p_ptr->admin_dm || p_ptr->wpos.wx != WPOS_SECTOR00_X || p_ptr->wpos.wy != WPOS_SECTOR00_Y) continue;
7743 
7744 				if (p_ptr->party) {
7745 					for (j = 1; j <= NumPlayers; j++) {
7746 						if (j == i) continue;
7747 						if (Players[j]->wpos.wx != WPOS_SECTOR00_X || Players[j]->wpos.wy != WPOS_SECTOR00_Y) continue;
7748 						/* leave party */
7749 						if (Players[j]->party == p_ptr->party) party_leave(i, FALSE);
7750 					}
7751 				}
7752 
7753 				/* change "normal" Highlands amulet to v2 with ESP? */
7754 				for (j = INVEN_TOTAL - 1; j >= 0; j--)
7755 					if (p_ptr->inventory[j].tval == TV_AMULET && p_ptr->inventory[j].sval == SV_AMULET_HIGHLANDS) {
7756 						invcopy(&p_ptr->inventory[j], lookup_kind(TV_AMULET, SV_AMULET_HIGHLANDS2));
7757 						p_ptr->inventory[j].number = 1;
7758 						p_ptr->inventory[j].level = 0;
7759 						p_ptr->inventory[j].discount = 0;
7760 						p_ptr->inventory[j].ident |= ID_MENTAL;
7761 						p_ptr->inventory[j].owner = p_ptr->id;
7762 						p_ptr->inventory[j].mode = p_ptr->mode;
7763 						object_aware(i, &p_ptr->inventory[j]);
7764 						object_known(&p_ptr->inventory[j]);
7765 					}
7766 				p_ptr->update |= (PU_BONUS | PU_VIEW);
7767 				p_ptr->window |= (PW_INVEN | PW_EQUIP);
7768 				handle_stuff(i);
7769 
7770 				p_ptr->global_event_temp &= ~PEVF_SAFEDUN_00; /* no longer safe from death */
7771 				p_ptr->global_event_temp |= PEVF_AUTOPVP_00;
7772 
7773 				if (Players[i]->wpos.wz) {
7774 					p_ptr->recall_pos.wx = WPOS_SECTOR00_X;
7775 					p_ptr->recall_pos.wy = WPOS_SECTOR00_Y;
7776 					p_ptr->recall_pos.wz = 0;
7777 					p_ptr->new_level_method = LEVEL_OUTSIDE_RAND;
7778 					recall_player(i, "");
7779 				}
7780 
7781 				p_ptr->global_event_progress[ge_id][0] = 4; /* now before deathmatch */
7782 				msg_print(i, "\377fThe bloodshed begins!");
7783 				handle_music(i);
7784 			}
7785 
7786 			ge->state[0] = 4;
7787 			break;
7788 		case 4: /* teleport them around first */
7789 			/* NOTE: the no-tele vault stuff might just need fixing, ie ignoring the no-tele when auto-recalling */
7790 			for (i = 1; i <= NumPlayers; i++)
7791 				if (inarea(&Players[i]->wpos, &wpos)) {
7792 					p_ptr = Players[i];
7793 					wiz_lite(i); /* no tourneys at night, chars with low IV lose */
7794 					teleport_player(i, 200, TRUE);
7795 					/* in case some player waited in a NO_TELE vault..!: */
7796 					if (p_ptr->wpos.wz && !p_ptr->admin_dm) {
7797 						msg_print(i, "\377rThe whole dungeon suddenly COLLAPSES!");
7798 						strcpy(p_ptr->died_from,"a mysterious accident");
7799 						p_ptr->global_event_temp = PEVF_NONE; /* clear no-WoR/perma-death/no-death flags */
7800 						p_ptr->deathblow = 0;
7801 						player_death(i);
7802 					}
7803 					p_ptr->global_event_progress[ge_id][0] = 5; /* now in deathmatch */
7804 				}
7805 			ge->state[0] = 5;
7806 			break;
7807 		case 5: /* deathmatch phase -- might add some random teleportation for more fun */
7808 			/* NOTE: the mysterious-accident is deprecated, since we use extra[5] now */
7809 			n = 0;
7810 			for (i = 1; i <= NumPlayers; i++) {
7811 				if (Players[i]->admin_dm) continue;
7812 				/* in case some player tries to go > again^^ */
7813 				if (!Players[i]->wpos.wx && !Players[i]->wpos.wy && Players[i]->wpos.wz
7814 				    && Players[i]->global_event_type[ge_id] == GE_HIGHLANDER) {
7815 					msg_print(i, "\377rThe whole dungeon suddenly COLLAPSES!");
7816 					strcpy(Players[i]->died_from,"a mysterious accident");
7817 					Players[i]->global_event_temp = PEVF_NONE; /* clear no-WoR/perma-death/no-death flags */
7818 					Players[i]->deathblow = 0;
7819 					player_death(i);
7820 				}
7821 				if (inarea(&Players[i]->wpos, &wpos)) {
7822 					n++;
7823 					j = i;
7824 				}
7825 			}
7826 			if (!n) ge->state[0] = 255; /* double kill or something? ew. */
7827 			if (n == 1) { /* We have a winner! (not a total_winner but anyways..) */
7828 				ge->state[0] = 6;
7829 				ge->extra[3] = j;
7830 			}
7831 
7832 			/* if tournament runs for too long without result, spice it up by
7833 			   throwing in some nasty baddy (Bad Luck Bat from Hell): */
7834 			/* TODO: also spawn something if a player is AFK (or highlandering himself on friend's account -_-) */
7835 //			if (elapsed_turns - (ge->announcement_time * cfg.fps) - 600 == 600) { /* after 10 minutes of deathmatch phase */
7836 			if ((!ge->state[3]) && ((turn - ge->start_turn) - ge->state[2] >= 600 * cfg.fps)) {
7837 				msg_broadcast(0, "\377aThe gods of highlands are displeased by the lack of blood flowing.");
7838 				summon_override_checks = SO_ALL & ~(SO_GRID_EMPTY);
7839 				while (!(summon_detailed_one_somewhere(&wpos, RI_BAD_LUCK_BAT, 0, FALSE, 101)) && (++tries < 1000));
7840 				summon_override_checks = SO_NONE;
7841 				ge->state[3] = 1; /* remember that we already spawned one so we don't keep spawning */
7842 					/* this actually serves if an admin /gefforward's too far, beyond the spawning
7843 					time, so we can still spawn one without the admin taking too much care.. */
7844 			}
7845 
7846 			break;
7847 		case 6: /* we have a winner! */
7848 			j = ge->extra[3];
7849 			if (j > NumPlayers) { /* Make sure the winner didn't die in the 1 turn that just passed! */
7850 				ge->state[0] = 255; /* no winner, d'oh */
7851 				break;
7852 			}
7853 
7854 			p_ptr = Players[j];
7855 			if (p_ptr->wpos.wx != WPOS_SECTOR00_X || p_ptr->wpos.wy != WPOS_SECTOR00_Y
7856 			    || p_ptr->wpos.wz != 0) { /* not ok.. */
7857 				ge->state[0] = 255; /* no winner, d'oh */
7858 				break;
7859 			}
7860 
7861 			sprintf(buf, "\374\377a>>%s wins %s!<<", p_ptr->name, ge->title);
7862 			msg_broadcast_format(0, buf);
7863 #ifdef TOMENET_WORLDS
7864                         if (cfg.worldd_events) world_msg(buf);
7865 #endif
7866 			if (!p_ptr->max_exp) gain_exp(j, 1); /* may only take part in one tournament per char */
7867 
7868 			/* don't create a actual reward here, but just a signed deed that can be turned in (at mayor's office)! */
7869 			k = lookup_kind(TV_PARCHMENT, SV_DEED_HIGHLANDER);
7870 			invcopy(o_ptr, k);
7871 			o_ptr->number = 1;
7872 			object_aware(j, o_ptr);
7873 			object_known(o_ptr);
7874 			o_ptr->discount = 0;
7875 			o_ptr->level = 0;
7876 			o_ptr->ident |= ID_MENTAL;
7877 			//o_ptr->note = quark_add("Tournament reward");
7878 			inven_carry(j, o_ptr);
7879 
7880 			s_printf("%s EVENT_WON: %s wins %d (%s)\n", showtime(), p_ptr->name, ge_id + 1, ge->title);
7881 			l_printf("%s \\{s%s has won %s\n", showdate(), p_ptr->name, ge->title);
7882 
7883 			/* avoid him dying */
7884 			set_poisoned(j, 0, 0);
7885 			set_cut(j, 0, 0);
7886 			set_food(j, PY_FOOD_FULL);
7887 			hp_player_quiet(j, 5000, TRUE);
7888 
7889 			ge->state[0] = 7;
7890 			ge->state[1] = elapsed;
7891 			break;
7892 		case 7: /* chill out for a few seconds (or get killed -- but now there aren't monster spawns anymore) */
7893 			if (elapsed - ge->state[1] >= 5) ge->state[0] = 255;
7894 			break;
7895 		case 255: /* clean-up */
7896 			if (!ge->cleanup) {
7897 				ge->getype = GE_NONE; /* end of event */
7898 				break;
7899 			}
7900 
7901 			for (i = 1; i <= NumPlayers; i++) {
7902 				p_ptr = Players[i];
7903 				if (p_ptr->wpos.wx == WPOS_SECTOR00_X && p_ptr->wpos.wy == WPOS_SECTOR00_Y
7904 				    && p_ptr->wpos.wz == 0) {
7905 					for (j = INVEN_TOTAL; j >= 0; j--) /* Erase the highlander amulets */
7906 						if (p_ptr->inventory[j].tval == TV_AMULET &&
7907 						    ((p_ptr->inventory[j].sval == SV_AMULET_HIGHLANDS) ||
7908 						    (p_ptr->inventory[j].sval == SV_AMULET_HIGHLANDS2))) {
7909 							inven_item_increase(i, j, -p_ptr->inventory[j].number);
7910 							inven_item_optimize(i, j);
7911 						}
7912 					p_ptr->global_event_type[ge_id] = GE_NONE; /* no longer participant */
7913 					p_ptr->recall_pos.wx = cfg.town_x;
7914 					p_ptr->recall_pos.wy = cfg.town_y;
7915 					p_ptr->recall_pos.wz = 0;
7916 					p_ptr->new_level_method = LEVEL_OUTSIDE_RAND;
7917 					p_ptr->global_event_temp = PEVF_PASS_00; /* clear all other flags, allow a final recall out */
7918 					recall_player(i, "");
7919 					/* required, or the double-wpos-change in below's 'unstatic_level()' call will cause
7920 					   panic save due to old wpos possibly still being in non-existant highlander dungeon */
7921 					process_player_change_wpos(i);
7922 				}
7923 			}
7924 
7925 			sector00flags1 = sector00flags2 = 0x0;
7926 			sector00separation--;
7927 
7928 			/* still got a staircase to remove? */
7929 			if (ge->extra[5]) {
7930 				zcave = getcave(&wpos);
7931 				zcave[ge->extra[7]][ge->extra[6]].feat = FEAT_DIRT;
7932 				everyone_lite_spot(&wpos, ge->extra[7], ge->extra[6]);
7933 				sector00downstairs--;
7934 				ge->extra[5] = 0;
7935 			}
7936 
7937 			/* remove temporary Highlander dungeon! */
7938 			if (wild_info[wpos.wy][wpos.wx].dungeon)
7939 				rem_dungeon(&wpos, FALSE);
7940 
7941 			wild_info[wpos.wy][wpos.wx].type = ge->extra[1];
7942 			wipe_m_list(&wpos); /* clear any (powerful) spawns */
7943 			wipe_o_list_safely(&wpos); /* and objects too */
7944 			unstatic_level(&wpos);/* get rid of any other person, by unstaticing ;) */
7945 
7946 			ge->getype = GE_NONE; /* end of event */
7947 			break;
7948 		}
7949 		break;
7950 
7951 	/* Arena Monster Challenge */
7952 	case GE_ARENA_MONSTER:
7953 		wpos.wx = cfg.town_x;
7954 		wpos.wy = cfg.town_y;
7955 		wild = &wild_info[wpos.wy][wpos.wx];
7956 		d_ptr = wild->tower;
7957 		if (!d_ptr) {
7958 			s_printf("FATAL_ERROR: global_event 'Arena Monster Challenge': Bree has no Training Tower.\n");
7959 			return; /* paranoia, Bree should *always* have 'The Training Tower' */
7960 		}
7961 		wpos.wz = d_ptr->maxdepth;
7962 
7963 		switch(ge->state[0]){
7964 		case 0: /* prepare */
7965 #if 0 /* disabled unstaticing for now since it might unstatice the whole 32,32 sector on all depths? dunno */
7966 			unstatic_level(&wpos);/* get rid of any other person, by unstaticing ;) */
7967 #else
7968 			for (i = 1; i <= NumPlayers; i++)
7969 				if (inarea(&Players[i]->wpos, &wpos)) {
7970 					Players[i]->new_level_method = (Players[i]->wpos.wz > 0 ? LEVEL_RECALL_DOWN : LEVEL_RECALL_UP);
7971 					Players[i]->recall_pos.wx = wpos.wx;
7972 					Players[i]->recall_pos.wy = wpos.wy;
7973 					Players[i]->recall_pos.wz = 0;
7974 					recall_player(i, "\377yThe arena wizards teleport you out of here!");
7975 				}
7976 			if (getcave(&wpos)) { /* check that the level is allocated - mikaelh */
7977 				dealloc_dungeon_level(&wpos);
7978 			}
7979 #endif
7980 
7981 			ge_special_sector++;
7982 
7983 			if (!getcave(&wpos)) {
7984 				alloc_dungeon_level(&wpos);
7985 				generate_cave(&wpos, NULL); /* should work =p (see make_resf) */
7986 			}
7987 
7988 			new_players_on_depth(&wpos, 1, TRUE); /* make it static */
7989 			s_printf("EVENT_LAYOUT: Generating arena_tt at %d,%d,%d\n", wpos.wx, wpos.wy, wpos.wz);
7990 			process_dungeon_file("t_arena_tt.txt", &wpos, &ystart, &xstart, MAX_HGT, MAX_WID, TRUE);
7991 
7992 			wipe_m_list(&wpos); /* clear any (powerful) spawns */
7993 			wipe_o_list_safely(&wpos); /* and objects too */
7994 			ge->state[0] = 1;
7995 			break;
7996 		case 1: /* running - not much to do here actually :) it's all handled by global_event_signup */
7997 			if (ge->extra[1]) { /* new challenge to process? */
7998 				if (!getcave(&wpos)) { /* in case nobody was there for a long enough time to unstatice, no idea when/if though.. */
7999 					alloc_dungeon_level(&wpos);
8000 					generate_cave(&wpos, NULL); /* should work =p (see make_resf) */
8001 					new_players_on_depth(&wpos, 1, FALSE); /* make it static */
8002 				}
8003 
8004 				wipe_m_list(&wpos); /* get rid of previous monster */
8005 				summon_override_checks = SO_ALL & ~(SO_PROTECTED | SO_GRID_EMPTY);
8006 #ifndef GE_ARENA_ALLOW_EGO
8007 				while (!summon_specific_race_somewhere(&wpos, ge->extra[1], 100, 1) /* summon new monster */
8008 				    && (++tries < 1000));
8009 #else
8010 				while (!(m_idx = summon_detailed_one_somewhere(&wpos, ge->extra[1], ge->extra[3], FALSE, 101))
8011 				    && (++tries < 1000));
8012 				monster_desc(0, m_name, m_idx, 0x08);
8013 				msg_broadcast_format(0, "\376\377c** %s challenges %s! **", Players[ge->extra[5]]->name, m_name);
8014 #endif
8015 				summon_override_checks = SO_NONE;
8016 
8017 				ge->extra[2] = ge->extra[1]; /* remember it for result announcement later */
8018 #ifdef GE_ARENA_ALLOW_EGO
8019 				ge->extra[4] = ge->extra[3]; /* remember it for result announcement later */
8020 #endif
8021 				ge->extra[1] = 0;
8022 			}
8023 			break;
8024 		case 255: /* clean-up */
8025 			if (getcave(&wpos)) {
8026 				wipe_m_list(&wpos); /* clear any (powerful) spawns */
8027 				wipe_o_list_safely(&wpos); /* and objects too */
8028 #if 0 /* disabled unstaticing for now since it might unstatice the whole 32,32 sector on all depths? dunno */
8029 				unstatic_level(&wpos);/* get rid of any other person, by unstaticing ;) */
8030 #else
8031 				new_players_on_depth(&wpos, -1, TRUE); /* remove forced staticness */
8032 
8033 				for (i = 1; i <= NumPlayers; i++)
8034 					if (inarea(&Players[i]->wpos, &wpos)) {
8035 						Players[i]->new_level_method = (Players[i]->wpos.wz > 0 ? LEVEL_RECALL_DOWN : LEVEL_RECALL_UP);
8036 						Players[i]->recall_pos.wx = wpos.wx;
8037 						Players[i]->recall_pos.wy = wpos.wy;
8038 						Players[i]->recall_pos.wz = 0;
8039 						recall_player(i, "\377yThe arena wizards teleport you out of here!");
8040 					}
8041 				if (getcave(&wpos)) { /* check that the level is allocated - mikaelh */
8042 					dealloc_dungeon_level(&wpos);
8043 				}
8044 #endif /* so if if0'ed, we just have to wait for normal unstaticing routine to take care of stale level :/ */
8045 			}
8046 			ge->getype = GE_NONE; /* end of event */
8047 			ge_special_sector--;
8048 			break;
8049 		}
8050 		break;
8051 
8052 	/* Dungeon Keeper labyrinth race */
8053 	case GE_DUNGEON_KEEPER:
8054 		switch (ge->state[0]) {
8055 		case 0: { /* prepare level, gather everyone, begin */
8056 			int bx[3], by[3];
8057 
8058 			ge->state[1] = 0;
8059 			ge->cleanup = 1;
8060 			sector00separation++; /* separate sector 0,0 from the worldmap - participants have access ONLY */
8061 			sector00music = 46; /* terrifying (notele) music */
8062 			sector00flags1 = LF1_NO_MAGIC_MAP;
8063 			sector00flags2 = LF2_NO_RUN | LF2_NO_TELE | LF2_NO_DETECT | LF2_NO_ESP | LF2_NO_SPEED | LF2_NO_RES_HEAL | LF2_FAIR_TERRAIN_DAM | LF2_INDOORS;
8064 			sector00wall = FEAT_PERM_INNER; //FEAT_PERM_SOLID gets shaded to slate :/
8065 			wipe_m_list(&wpos); /* clear any (powerful) spawns */
8066 			wipe_o_list_safely(&wpos); /* and objects too */
8067 			unstatic_level(&wpos);/* get rid of any other person, by unstaticing ;) */
8068 
8069 			if (!getcave(&wpos)) alloc_dungeon_level(&wpos);
8070 			s_printf("EVENT_LAYOUT: Generating labyrinth at %d,%d,%d\n", wpos.wx, wpos.wy, wpos.wz);
8071 			/* make it static */
8072 			new_players_on_depth(&wpos, 1, FALSE);
8073 			zcave = getcave(&wpos);
8074 
8075 			/* wipe level with floor tiles */
8076 			for (x = 0; x < MAX_WID; x++)
8077 			for (y = 0; y < MAX_HGT; y++) {
8078 				zcave[y][x].feat = FEAT_ASH; /* scary ;) */
8079 				zcave[y][x].info |= CAVE_STCK;//| CAVE_GLOW;
8080 				zcave[y][x].info &= ~CAVE_GLOW; /* scarier! */
8081 			}
8082 
8083 			/* add perma wall borders and basic labyrinth grid (rooms) */
8084 			for (x = 0; x < MAX_WID; x++) {
8085 				for (y = 4; y <= MAX_HGT - 4; y += 4) {
8086 					if (x < MAX_WID - 1) zcave[y][x].feat = FEAT_PERM_INNER;
8087 				}
8088 				/* comply with wilderness generation scheme (or crash when approaching) */
8089 				zcave[0][x].feat = FEAT_PERM_CLEAR;
8090 				zcave[MAX_HGT - 1][x].feat = FEAT_PERM_CLEAR;
8091 			}
8092 			for (y = 0; y < MAX_HGT; y++) {
8093 				for (x = 4; x <= MAX_WID - 4; x += 4) {
8094 					if (y < MAX_HGT - 1) zcave[y][x].feat = FEAT_PERM_INNER;
8095 				}
8096 				/* comply with wilderness generation scheme (or crash when approaching) */
8097 				zcave[y][0].feat = FEAT_PERM_CLEAR;
8098 				zcave[y][MAX_WID - 1].feat = FEAT_PERM_CLEAR;
8099 			}
8100 
8101 			/* generate max # of doors, then remove some randomly */
8102 
8103 			/* pass 1: add all and remove some doors */
8104 
8105 			/* add all possible doors, vertically and horizontally */
8106 			for (x = 2; x < MAX_WID - 1; x += 4)
8107 			for (y = 4; y <= MAX_HGT - 4; y += 4) {
8108 //				if (zcave[y][x].feat != FEAT_PERM_INNER) continue;
8109 				zcave[y][x].feat = FEAT_DOOR_HEAD;
8110 			}
8111 			for (y = 2; y < MAX_HGT - 1; y += 4)
8112 			for (x = 4; x <= MAX_WID - 4; x += 4) {
8113 //				if (zcave[y][x].feat != FEAT_PERM_INNER) continue;
8114 				zcave[y][x].feat = FEAT_DOOR_HEAD;
8115 			}
8116 
8117 			/* remove 0..1. Maybe even ..2? */
8118 			for (x = 2; x < MAX_WID - 1; x += 4)
8119 			for (y = 2; y < MAX_HGT - 1; y += 4) {
8120 				int door_pos[4], doors = 0, doors_exist = 0; /* door_pos are same as dd arrays, ie numpad dirs */
8121 
8122 				/* we're at room centre. Process N/E/S/W doors. */
8123 				if (y > 2) { /* skip N door when at top border */
8124 					/* check for already existing door */
8125 					if (zcave[y + 2 * ddy[8]][x + 2 * ddx[8]].feat == FEAT_DOOR_HEAD) {
8126 						door_pos[doors_exist] = 8;
8127 						doors_exist++;
8128 					} else doors++;
8129 				}
8130 				if (x < MAX_WID - 1 - (MAX_WID - 1) % 4 - 3) { /* skip E door when at right border */
8131 					/* check for already existing door */
8132 					if (zcave[y + 2 * ddy[6]][x + 2 * ddx[6]].feat == FEAT_DOOR_HEAD) {
8133 						door_pos[doors_exist] = 6;
8134 						doors_exist++;
8135 					} else doors++;
8136 				}
8137 				if (y < MAX_HGT - (MAX_HGT - 1) % 4 - 3) { /* skip S door when at bottom border */
8138 					/* check for already existing door */
8139 					if (zcave[y + 2 * ddy[2]][x + 2 * ddx[2]].feat == FEAT_DOOR_HEAD) {
8140 						door_pos[doors_exist] = 2;
8141 						doors_exist++;
8142 					} else doors++;
8143 				}
8144 				if (x > 2) { /* skip W door when at left border */
8145 					/* check for already existing door */
8146 					if (zcave[y + 2 * ddy[4]][x + 2 * ddx[4]].feat == FEAT_DOOR_HEAD) {
8147 						door_pos[doors_exist] = 4;
8148 						doors_exist++;
8149 					} else doors++;
8150 				}
8151 
8152 				/* we already have all non-doors we need? (created by the adjacent rooms) */
8153 				if (doors_exist <= 2 || /* 1 or 2 non-doors exist, or it's a corner */
8154 				    (doors_exist == 3 && doors == 1) || /* sufficient # of non-doors for a centre room (1 out of 4) */
8155 				    (doors_exist == 3 && !rand_int(2))) /* edge rooms don't need non-doors, but sometimes add one anyway (-> 1 out of 3) */
8156 					continue;
8157 
8158 				/* create sufficient number of missing doors */
8159 				if (doors_exist == 3) {
8160 					/* scenario (doors == 0): edge room with 3 doors, we want to remove 1 */
8161 					k = rand_int(3);
8162 					zcave[y + 2 * ddy[door_pos[k]]][x + 2 * ddx[door_pos[k]]].feat = FEAT_PERM_INNER;
8163 				} else {
8164 					/* scenario: centre room with 4 doors, we need to remove 1 */
8165 					k = rand_int(4);
8166 					zcave[y + 2 * ddy[door_pos[k]]][x + 2 * ddx[door_pos[k]]].feat = FEAT_PERM_INNER;
8167 				}
8168 			}
8169 
8170 			/* pass 2 (sanity): make sure each room has at very least ONE door */
8171 
8172 			for (x = 2; x < MAX_WID - 1; x += 4)
8173 			for (y = 2; y < MAX_HGT - 1; y += 4) {
8174 				int door_pos[4], doors = 0; /* door_pos are same as dd arrays, ie numpad dirs */
8175 
8176 				/* we're at room centre. Process N/E/S/W doors. */
8177 				if (y > 2) { /* skip N door when at top border */
8178 					/* check for already existing door */
8179 					if (zcave[y + 2 * ddy[8]][x + 2 * ddx[8]].feat == FEAT_DOOR_HEAD) continue;
8180 					else {
8181 						door_pos[doors] = 8;
8182 						doors++;
8183 					}
8184 				}
8185 				if (x < MAX_WID - 1 - (MAX_WID - 1) % 4 - 3) { /* skip E door when at right border */
8186 					/* check for already existing door */
8187 					if (zcave[y + 2 * ddy[6]][x + 2 * ddx[6]].feat == FEAT_DOOR_HEAD) continue;
8188 					else {
8189 						door_pos[doors] = 6;
8190 						doors++;
8191 					}
8192 				}
8193 				if (y < MAX_HGT - (MAX_HGT - 1) % 4 - 3) { /* skip S door when at bottom border */
8194 					/* check for already existing door */
8195 					if (zcave[y + 2 * ddy[2]][x + 2 * ddx[2]].feat == FEAT_DOOR_HEAD) continue;
8196 					else {
8197 						door_pos[doors] = 2;
8198 						doors++;
8199 					}
8200 				}
8201 				if (x > 2) { /* skip W door when at left border */
8202 					/* check for already existing door */
8203 					if (zcave[y + 2 * ddy[4]][x + 2 * ddx[4]].feat == FEAT_DOOR_HEAD) continue;
8204 					else {
8205 						door_pos[doors] = 4;
8206 						doors++;
8207 					}
8208 				}
8209 
8210 				if (!doors) continue; /* paranoia */
8211 				/* room already has NO door! */
8212 
8213 				/* randomly create one */
8214 				k = rand_int(doors);
8215 				zcave[y + 2 * ddy[door_pos[k]]][x + 2 * ddx[door_pos[k]]].feat = FEAT_DOOR_HEAD;
8216 			}
8217 
8218 #if 1
8219 			/* maybe - randomly add void gate pairs */
8220 			k = 0;
8221 			for (i = 0; i < 6; i++) {
8222 				n = 1000;
8223 				while (--n) {
8224 					x = rand_int(MAX_WID - 1) + 1;
8225 					y = rand_int(MAX_HGT - 1) + 1;
8226 					if ((f_info[zcave[y][x].feat].flags1 & FF1_FLOOR) &&
8227 					    !(f_info[zcave[y][x].feat].flags1 & FF1_DOOR))
8228 						break;
8229 				}
8230 				if (!n) continue;
8231 				place_between_ext(&wpos, y, x, MAX_HGT, MAX_WID);
8232 				k++;
8233 			}
8234 			if (!k) s_printf("..COULDN'T PLACE void jump gates\n");
8235 			else s_printf("..placed %d/6 void jump gates\n", k);
8236 #endif
8237 
8238 			/* place exit beacons [3 -> ~25% win?] */
8239 			k = 0;
8240 			for (i = 0; i < 4; i++) {
8241 				n = 10000;
8242 				while (--n) {
8243 #if 0 /* place them anywhere in a chamber */
8244 					x = rand_int(MAX_WID - 1) + 1;
8245 					y = rand_int(MAX_HGT - 1) + 1;
8246 #else /* place them in the center of a chamber */
8247 					x = rand_int(MAX_WID / 4) * 4 + 2;
8248 					y = rand_int(MAX_HGT / 4) * 4 + 2;
8249 #endif
8250 					/* only place it on floor (that hasn't got a gate/beacon on it yet) */
8251 					if ((f_info[zcave[y][x].feat].flags1 & FF1_FLOOR) &&
8252 					    !(f_info[zcave[y][x].feat].flags1 & FF1_DOOR) &&
8253 					    !(f_info[zcave[y][x].feat].flags1 & FF1_PERMANENT))
8254 						break;
8255 				}
8256 				if (!n) continue;
8257 				cave_set_feat_live(&wpos, y, x, FEAT_BEACON);
8258 				zcave[y][x].info |= CAVE_GLOW; /* make it 100% non-annoying ^^ */
8259 				bx[k] = x; by[k] = y;
8260 				k++;
8261 			}
8262 			if (!k) s_printf("..COULDN'T PLACE exit beacons\n");
8263 			else s_printf("..placed %d/4 exit beacons\n", k);
8264 
8265 			/* place Horned Reaper :D */
8266 			n = 10000;
8267 			while (--n) {
8268 				x = rand_int(MAX_WID - 1) + 1;
8269 				y = rand_int(MAX_HGT - 1) + 1;
8270 				if ((f_info[zcave[y][x].feat].flags1 & FF1_FLOOR) &&
8271 				    !(f_info[zcave[y][x].feat].flags1 & FF1_DOOR))
8272 					break;
8273 			}
8274 			if (!n) s_printf("..COULDN'T PLACE Horned Reaper\n");
8275 			else {
8276 				summon_override_checks = SO_ALL;
8277 				place_monster_one(&wpos, y, x, RI_HORNED_REAPER_GE, FALSE, FALSE, FALSE, 0, 0);
8278 				summon_override_checks = SO_NONE;
8279 				s_printf("..placed Horned Reaper\n");
8280 			}
8281 
8282 			/* teleport the players in */
8283 			for (j = 0; j < MAX_GE_PARTICIPANTS; j++) {
8284 				if (!ge->participant[j]) continue;
8285 
8286 				for (i = 1; i <= NumPlayers; i++) {
8287 					if (Players[i]->id != ge->participant[j]) continue;
8288 					p_ptr = Players[i];
8289 
8290 					if (p_ptr->wpos.wx != WPOS_SECTOR00_X || p_ptr->wpos.wy != WPOS_SECTOR00_Y
8291 					    || p_ptr->wpos.wz != WPOS_SECTOR00_Z) {
8292 						p_ptr->recall_pos.wx = WPOS_SECTOR00_X;
8293 						p_ptr->recall_pos.wy = WPOS_SECTOR00_Y;
8294 						p_ptr->recall_pos.wz = WPOS_SECTOR00_Z;
8295 						p_ptr->global_event_temp = PEVF_PASS_00;
8296 						p_ptr->new_level_method = LEVEL_OUTSIDE_RAND;
8297 						/* don't spawn them too close to a beacon */
8298 						p_ptr->avoid_loc = k;
8299 						p_ptr->avoid_loc_x = bx;
8300 						p_ptr->avoid_loc_y = by;
8301 						recall_player(i, "");
8302 						p_ptr->avoid_loc = 0;
8303 					}
8304 					p_ptr->global_event_temp |= PEVF_NOGHOST_00 | PEVF_NO_RUN_00 | PEVF_NOTELE_00 | PEVF_INDOORS_00 | PEVF_STCK_OK;
8305 					p_ptr->update |= PU_BONUS;
8306 					p_ptr->global_event_progress[ge_id][0] = 1; /* now in 0,0,0 sector */
8307 
8308 					/* make sure they stop running (not really needed though..) */
8309 					disturb(i, 0, 0);
8310 					handle_music(i);
8311 				}
8312 			}
8313 
8314 			ge->state[0] = 1;
8315 			break;
8316 			}
8317 		case 1: /* hunt/race phase - end if all players escape or die or after a timeout */
8318 			/* everyone has escaped or died? */
8319 			n = 0;
8320 			for (i = 1; i <= NumPlayers; i++)
8321 				if (!Players[i]->admin_dm &&
8322 				    Players[i]->wpos.wx == WPOS_SECTOR00_X &&
8323 				    Players[i]->wpos.wy == WPOS_SECTOR00_Y && Players[i]->wpos.wz == WPOS_SECTOR00_Z)
8324 					n++;
8325 			if (!n) {
8326 				ge->state[0] = 255;
8327 				break;
8328 			}
8329 
8330 			/* timeout not yet reached? proceed normally */
8331 			if (elapsed - ge->announcement_time < 300) break;//start after 300s
8332 
8333 			sector00music = 47; /* death match music */
8334 			for (i = 1; i <= NumPlayers; i++)
8335 				handle_music(i);
8336 
8337 			ge->state[0] = 2;
8338 			break;
8339 		case 2: /* fill the labyrinth with more and more lava ^^- */
8340 			/* everyone has escaped or died? */
8341 			n = 0;
8342 			for (i = 1; i <= NumPlayers; i++)
8343 				if (!Players[i]->admin_dm && Players[i]->wpos.wx == WPOS_SECTOR00_X &&
8344 				    Players[i]->wpos.wy == WPOS_SECTOR00_Y && Players[i]->wpos.wz == WPOS_SECTOR00_Z)
8345 					n++;
8346 			if (!n) {
8347 				ge->state[0] = 255;
8348 				break;
8349 			}
8350 
8351 			n = elapsed; /* for how long is the event already up? */
8352 			n -= ge->announcement_time; /* dont factor in the announcement time */
8353 			n -= 300; /* don't factor in the duration of 1st phase */
8354 			n /= 5; /* from here on, act in 5 second intervals */
8355 			if (ge->state[1] >= n || /* next 5s interval is not yet up? */
8356 			    n > 180 / 5) /* we're already 3 min into this phase and termination is imminent */
8357 				break;
8358 			ge->state[1] = n; /* advance into another lava-filling step (lock time interval semaphore) */
8359 
8360 			zcave = getcave(&wpos);
8361 			/* after 3 min in pase 2, fill EVERYTHING -> everyone will die <(* *)> */
8362 			if (n == 180 / 5) {
8363 				for (x = 1; x < MAX_WID - 1; x++)
8364 				for (y = 1; y < MAX_HGT - 1; y++)
8365 					if (zcave[y][x].feat != FEAT_PERM_INNER)
8366 						//cave_set_feat_live(&wpos, y, x, FEAT_DEEP_LAVA);
8367 						zcave[y][x].feat = FEAT_DEEP_LAVA;
8368 						everyone_lite_spot(&wpos, y, x);
8369 				break;
8370 			}
8371 			/* if it's not that late yet, just fill some lava.. */
8372 			for (i = 0; i < 50 + n * 5; i++) {
8373 				j = 100;
8374 				while (--j) {
8375 					x = rand_int(MAX_WID - 1) + 1;
8376 					y = rand_int(MAX_HGT - 1) + 1;
8377 					if ((f_info[zcave[y][x].feat].flags1 & FF1_FLOOR) &&
8378 					    !(f_info[zcave[y][x].feat].flags1 & FF1_DOOR) &&
8379 					    zcave[y][x].feat != FEAT_BEACON &&
8380 					    zcave[y][x].feat != FEAT_DEEP_LAVA)
8381 						break;
8382 				}
8383 				if (!j) continue;
8384 				//cave_set_feat_live(&wpos, y, x, FEAT_DEEP_LAVA);
8385 				zcave[y][x].feat = FEAT_DEEP_LAVA;
8386 				everyone_lite_spot(&wpos, y, x);
8387 			}
8388 			break;
8389 		case 255: /* clean-up */
8390 			if (!ge->cleanup) {
8391 				ge->getype = GE_NONE; /* end of event */
8392 				break;
8393 			}
8394 
8395 			sector00flags1 = sector00flags2 = 0x0;
8396 			sector00separation--;
8397 
8398 			/* cleanly teleport all lingering admins out instead of displacing them into (non-generated) pvp-dungeon ^^ */
8399 			for (i = 1; i <= NumPlayers; i++)
8400 				if (inarea(&Players[i]->wpos, &wpos)) {
8401 					Players[i]->new_level_method = LEVEL_OUTSIDE_RAND;
8402 					Players[i]->recall_pos.wx = cfg.town_x;
8403 					Players[i]->recall_pos.wy = cfg.town_y;
8404 					Players[i]->recall_pos.wz = 0;
8405 					recall_player(i, "");
8406 				}
8407 
8408 			wipe_m_list(&wpos); /* clear any (powerful) spawns */
8409 			wipe_o_list_safely(&wpos); /* and objects too */
8410 			unstatic_level(&wpos);/* get rid of any other person, by unstaticing ;) */
8411 
8412 			ge->getype = GE_NONE; /* end of event */
8413 			break;
8414 		}
8415 		break;
8416 
8417 	default: /* generic clean-up routine for untitled events */
8418 		switch (ge->state[0]) {
8419 		case 255: /* remove an untitled event that has been stopped */
8420 			ge->getype = GE_NONE;
8421 			break;
8422 		}
8423 	}
8424 
8425 	/* Check for end of event */
8426 	if (ge->getype == GE_NONE) {
8427 		msg_broadcast_format(0, "\374\377W[%s has ended]", ge->title);
8428 		s_printf("%s EVENT_END: %d - '%s'.\n", showtime(), ge_id + 1, ge->title);
8429 	}
8430 }
8431 
8432 /*
8433  * Process running global_events - C. Blue
8434  */
8435 void process_global_events(void) {
8436 	int n;
8437 	for (n = 0; n < MAX_GLOBAL_EVENTS; n++)
8438 		if (global_event[n].getype != GE_NONE) {
8439 			if (!global_event[n].paused) process_global_event(n);
8440 			else global_event[n].paused_turns++;
8441 		}
8442 }
8443 
8444 /*
8445  * Update the 'tomenet.check' file
8446  * Currently used by the hangcheck script
8447  *  - mikaelh
8448  */
8449 void update_check_file(void)
8450 {
8451 	FILE *fp;
8452 	char buf[1024];
8453 	path_build(buf, 1024, ANGBAND_DIR_DATA, "tomenet.check");
8454 	fp = fopen(buf, "wb");
8455 	if (fp) {
8456 		/* print the current timestamp into the file */
8457 		fprintf(fp, "%d\n", (int)time(NULL));
8458 		fclose(fp);
8459 	}
8460 }
8461 
8462 
8463 /*
8464  * Clear all current_* variables used by Handle_item() - mikaelh
8465  */
8466 void clear_current(int Ind)
8467 {
8468 	player_type *p_ptr = Players[Ind];
8469 
8470 	p_ptr->using_up_item = -1;
8471 
8472 	p_ptr->current_enchant_h = 0;
8473 	p_ptr->current_enchant_d = 0;
8474 	p_ptr->current_enchant_a = 0;
8475 
8476 	p_ptr->current_identify = 0;
8477 	p_ptr->current_star_identify = 0;
8478 	p_ptr->current_recharge = 0;
8479 	p_ptr->current_artifact = 0;
8480 	p_ptr->current_artifact_nolife = FALSE;
8481 	p_ptr->current_curse = 0;
8482 	p_ptr->current_tome_creation = 0;
8483 	p_ptr->current_rune = 0;
8484 	p_ptr->current_telekinesis = NULL;
8485 }
8486 
8487 void calc_techniques(int Ind) {
8488 	player_type *p_ptr = Players[Ind];
8489 
8490 	p_ptr->melee_techniques = MT_NONE;
8491 	p_ptr->ranged_techniques = RT_NONE;
8492 
8493 	if (mtech_lev[p_ptr->pclass][0] &&
8494 	    p_ptr->lev >= mtech_lev[p_ptr->pclass][0])
8495 		p_ptr->melee_techniques |= MT_SPRINT;
8496 	if (mtech_lev[p_ptr->pclass][1] &&
8497 	    p_ptr->lev >= mtech_lev[p_ptr->pclass][1])
8498 		p_ptr->melee_techniques |= MT_TAUNT;
8499 	if (mtech_lev[p_ptr->pclass][2] &&
8500 	    p_ptr->lev >= mtech_lev[p_ptr->pclass][2])
8501 		p_ptr->melee_techniques |= MT_JUMP;
8502 	if (mtech_lev[p_ptr->pclass][3] &&
8503 	    p_ptr->lev >= mtech_lev[p_ptr->pclass][3])
8504 		p_ptr->melee_techniques |= MT_DISTRACT;
8505 	if (mtech_lev[p_ptr->pclass][4] &&
8506 	    p_ptr->lev >= mtech_lev[p_ptr->pclass][4])
8507 		p_ptr->melee_techniques |= MT_BASH;
8508 	if (mtech_lev[p_ptr->pclass][5] &&
8509 	    p_ptr->lev >= mtech_lev[p_ptr->pclass][5])
8510 		p_ptr->melee_techniques |= MT_KNOCK;
8511 	if (mtech_lev[p_ptr->pclass][6] &&
8512 	    p_ptr->lev >= mtech_lev[p_ptr->pclass][6])
8513 		p_ptr->melee_techniques |= MT_CHARGE;
8514 	if (mtech_lev[p_ptr->pclass][7] &&
8515 	    p_ptr->lev >= mtech_lev[p_ptr->pclass][7])
8516 		p_ptr->melee_techniques |= MT_FLASH;
8517 	if (mtech_lev[p_ptr->pclass][8] &&
8518 	    p_ptr->lev >= mtech_lev[p_ptr->pclass][8])
8519 		p_ptr->melee_techniques |= MT_CLOAK;
8520 	if (mtech_lev[p_ptr->pclass][9] &&
8521 	    p_ptr->lev >= mtech_lev[p_ptr->pclass][9])
8522 		p_ptr->melee_techniques |= MT_SPIN;
8523 	if (mtech_lev[p_ptr->pclass][10] &&
8524 	    p_ptr->lev >= mtech_lev[p_ptr->pclass][10])
8525 		p_ptr->melee_techniques |= MT_ASSA;
8526 	if (mtech_lev[p_ptr->pclass][11] &&
8527 	    p_ptr->lev >= mtech_lev[p_ptr->pclass][11])
8528 		p_ptr->melee_techniques |= MT_BERSERK;
8529 	if (mtech_lev[p_ptr->pclass][12] &&
8530 	    p_ptr->lev >= mtech_lev[p_ptr->pclass][12])
8531 		p_ptr->melee_techniques |= MT_XXX1000;
8532 	if (mtech_lev[p_ptr->pclass][13] &&
8533 	    p_ptr->lev >= mtech_lev[p_ptr->pclass][13])
8534 		p_ptr->melee_techniques |= MT_SJUMP;
8535 	if (mtech_lev[p_ptr->pclass][14] &&
8536 	    p_ptr->lev >= mtech_lev[p_ptr->pclass][14])
8537 		p_ptr->melee_techniques |= MT_SRUN;
8538 	if (mtech_lev[p_ptr->pclass][15] &&
8539 	    p_ptr->lev >= mtech_lev[p_ptr->pclass][15])
8540 		p_ptr->melee_techniques |= MT_ICLOAK;
8541 
8542 	if (get_skill(p_ptr, SKILL_ARCHERY) >= 4) p_ptr->ranged_techniques |= RT_FLARE; /* Flare missile */
8543 	if (get_skill(p_ptr, SKILL_ARCHERY) >= 8) p_ptr->ranged_techniques |= RT_PRECS; /* Precision shot */
8544 	if (get_skill(p_ptr, SKILL_ARCHERY) >= 10) p_ptr->ranged_techniques |= RT_CRAFT; /* Craft some ammunition */
8545 	if (get_skill(p_ptr, SKILL_ARCHERY) >= 16) p_ptr->ranged_techniques |= RT_DOUBLE; /* Double-shot */
8546 	if (get_skill(p_ptr, SKILL_ARCHERY) >= 25) p_ptr->ranged_techniques |= RT_BARRAGE; /* Barrage */
8547 
8548 	Send_technique_info(Ind);
8549 }
8550 
8551 /* helper function to provide shortcut for checking for mind-linked player.
8552    flags == 0x0 means 'accept all flags'. */
8553 int get_esp_link(int Ind, u32b flags, player_type **p2_ptr) {
8554 	player_type *p_ptr = Players[Ind];
8555 	int Ind2 = 0;
8556 	(*p2_ptr) = NULL;
8557 
8558 	if (p_ptr->esp_link_type &&
8559 	    p_ptr->esp_link &&
8560 	    ((p_ptr->esp_link_flags & flags) || flags == 0x0)) {
8561 		Ind2 = find_player(p_ptr->esp_link);
8562 		if (!Ind2) {
8563 			end_mind(Ind, FALSE);
8564 		} else {
8565 			(*p2_ptr) = Players[Ind2];
8566 		}
8567 	}
8568 	return Ind2;
8569 }
8570 /* helper function to provide shortcut for controlling mind-linked player.
8571    flags == 0x0 means 'accept all flags'. */
8572 //void use_esp_link(int *Ind, u32b flags, player_type *p_ptr) {
8573 void use_esp_link(int *Ind, u32b flags) {
8574 	int Ind2;
8575 //	p_ptr = Players[*Ind];
8576 	player_type *p_ptr = Players[(*Ind)];
8577 
8578 	if (p_ptr->esp_link_type &&
8579 	    p_ptr->esp_link &&
8580 	    ((p_ptr->esp_link_flags & flags) || flags == 0x0)) {
8581 		Ind2 = find_player(p_ptr->esp_link);
8582 		if (!Ind2) end_mind((*Ind), FALSE);
8583 		else {
8584 //			p_ptr = Players[Ind2];
8585 			(*Ind) = Ind2;
8586 		}
8587 	}
8588 }
8589 
8590 /* Handle string input request replies */
8591 void handle_request_return_str(int Ind, int id, char *str) {
8592 	player_type *p_ptr = Players[Ind];
8593 
8594 	/* verify that the ID is actually valid */
8595 	if (id != p_ptr->request_id) return;
8596 	p_ptr->request_id = RID_NONE;
8597 	/* verify that a string had been requested */
8598 	if (RTYPE_STR != p_ptr->request_type) return;
8599 
8600 	/* quests occupy an id broadband */
8601 	if (id >= RID_QUEST) {
8602 		str[30] = '\0'; /* arbitrary buffer limit */
8603 		quest_reply(Ind, id - RID_QUEST, str);
8604 		return;
8605 	}
8606 
8607 	switch (id) {
8608 #ifdef ENABLE_GO_GAME
8609 	case RID_GO_MOVE:
8610 		if (p_ptr->store_num == -1) return; /* Discard if we left the building */
8611 		str[160] = '\0'; /* prevent possile buffer overflow */
8612 		go_engine_move_human(Ind, str);
8613 		return;
8614 #endif
8615 	case RID_GUILD_RENAME:
8616 		str[40] = '\0'; /* prevent possile buffer overflow */
8617 		if (str[0] == '\e' || !str[0]) return; /* user ESCaped */
8618 		guild_rename(Ind, str);
8619 		return;
8620 	default:;
8621 	}
8622 }
8623 
8624 /* Handle number input request replies */
8625 void handle_request_return_num(int Ind, int id, int num) {
8626 	player_type *p_ptr = Players[Ind];
8627 
8628 	/* verify that the ID is actually valid */
8629 	if (id != p_ptr->request_id) return;
8630 	p_ptr->request_id = RID_NONE;
8631 	/* verify that a number had been requested */
8632 	if (RTYPE_NUM != p_ptr->request_type) return;
8633 
8634 	switch (id) {
8635 	default:;
8636 	}
8637 }
8638 
8639 /* Handle key input request replies */
8640 void handle_request_return_key(int Ind, int id, char c) {
8641 	player_type *p_ptr = Players[Ind];
8642 
8643 	/* verify that the ID is actually valid */
8644 	if (id != p_ptr->request_id) return;
8645 	p_ptr->request_id = RID_NONE;
8646 	/* verify that a key had been requested */
8647 	if (RTYPE_KEY != p_ptr->request_type) return;
8648 
8649 	switch (id) {
8650 #ifdef ENABLE_GO_GAME
8651 	case RID_GO:
8652 		if (p_ptr->store_num == -1) return; /* Discard if we left the building */
8653 		go_challenge_accept(Ind, FALSE);
8654 		return;
8655 	case RID_GO_START:
8656 		if (p_ptr->store_num == -1) return; /* Discard if we left the building */
8657 		go_challenge_start(Ind);
8658 		return;
8659 #endif
8660 	default:;
8661 	}
8662 }
8663 
8664 /* Handle confirmation request replies */
8665 void handle_request_return_cfr(int Ind, int id, bool cfr) {
8666 	player_type *p_ptr = Players[Ind];
8667 
8668 	/* verify that the ID is actually valid */
8669 	if (id != p_ptr->request_id) return;
8670 	p_ptr->request_id = RID_NONE;
8671 	/* verify that a y/n confirmation had been requested */
8672 	if (RTYPE_CFR != p_ptr->request_type) return;
8673 
8674 	/* quests occupy an id broadband */
8675 	if (id >= RID_QUEST_ACQUIRE) {
8676 		if (cfr) quest_acquire_confirmed(Ind, id - RID_QUEST_ACQUIRE, FALSE);
8677 		return;
8678 	}
8679 	else if (id >= RID_QUEST) {
8680 		char str[2];
8681 
8682 		if (cfr) str[0] = 'y';
8683 		else str[0] = 'n';
8684 		str[1] = 0;
8685 		quest_reply(Ind, id - RID_QUEST, str);
8686 		return;
8687 	}
8688 
8689 	switch (id) {
8690 #ifdef ENABLE_GO_GAME
8691 	case RID_GO:
8692 		if (p_ptr->store_num == -1) return; /* Discard if we left the building */
8693 		if (!cfr) {
8694 			Send_store_special_clr(Ind, 5, 18);
8695 			Send_store_special_str(Ind, 8, 8, TERM_ORANGE, "Now you're chickening out huh!");
8696 			p_ptr->store_action = 0;
8697 			return;
8698 		}
8699 		go_challenge_accept(Ind, TRUE);
8700 		return;
8701 #endif
8702 	case RID_GUILD_RENAME:
8703 		if (cfr) Send_request_str(Ind, RID_GUILD_RENAME, "Enter a new guild name: ", "");
8704 		return;
8705 	case RID_GUILD_CREATE:
8706 		if (cfr) guild_create(Ind, p_ptr->cur_file_title);
8707 		p_ptr->cur_file_title[0] = 0;//not really needed
8708 		return;
8709 	default: ;
8710 	}
8711 }
8712 
8713 /* Cap a player's energy:
8714    Make sure they don't have too much, but let them store up some extra.
8715    Storing up extra energy lets us perform actions while we are running */
8716 void limit_energy(player_type *p_ptr) {
8717 	//if (p_ptr->energy > (level_speed(p_ptr->dun_depth) * 6) / 5)
8718 	//	p_ptr->energy = (level_speed(p_ptr->dun_depth) * 6) / 5;
8719 	if (p_ptr->energy > (level_speed(&p_ptr->wpos) * 2) - 1)
8720 		p_ptr->energy = (level_speed(&p_ptr->wpos) * 2) - 1;
8721 }
8722