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