ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/living.C
(Generate patch)

Comparing deliantra/server/common/living.C (file contents):
Revision 1.110 by root, Sun Mar 28 16:17:27 2010 UTC vs.
Revision 1.136 by root, Sat Nov 17 23:40:00 2018 UTC

1/* 1/*
2 * This file is part of Deliantra, the Roguelike Realtime MMORPG. 2 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 * 3 *
4 * Copyright (©) 2017,2018 Marc Alexander Lehmann / the Deliantra team
4 * Copyright (©) 2005,2006,2007,2008,2009,2010 Marc Alexander Lehmann / Robin Redeker / the Deliantra team 5 * Copyright (©) 2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * Copyright (©) 2002 Mark Wedel & Crossfire Development Team 6 * Copyright (©) 2002 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992 Frank Tore Johansen 7 * Copyright (©) 1992 Frank Tore Johansen
7 * 8 *
8 * Deliantra is free software: you can redistribute it and/or modify it under 9 * Deliantra is free software: you can redistribute it and/or modify it under
9 * the terms of the Affero GNU General Public License as published by the 10 * the terms of the Affero GNU General Public License as published by the
10 * Free Software Foundation, either version 3 of the License, or (at your 11 * Free Software Foundation, either version 3 of the License, or (at your
11 * option) any later version. 12 * option) any later version.
12 * 13 *
13 * This program is distributed in the hope that it will be useful, 14 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 17 * GNU General Public License for more details.
17 * 18 *
18 * You should have received a copy of the Affero GNU General Public License 19 * You should have received a copy of the Affero GNU General Public License
19 * and the GNU General Public License along with this program. If not, see 20 * and the GNU General Public License along with this program. If not, see
20 * <http://www.gnu.org/licenses/>. 21 * <http://www.gnu.org/licenses/>.
21 * 22 *
22 * The authors can be reached via e-mail to <support@deliantra.net> 23 * The authors can be reached via e-mail to <support@deliantra.net>
23 */ 24 */
24 25
25#include <global.h> 26#include <global.h>
26 27
33static const int con_bonus[MAX_STAT + 1] = { 34static const int con_bonus[MAX_STAT + 1] = {
34 -6, -5, -4, -3, -2, -1, -1, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 18, 20, 35 -6, -5, -4, -3, -2, -1, -1, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 18, 20,
35 22, 25, 30, 40, 50 36 22, 25, 30, 40, 50
36}; 37};
37 38
38/* changed the name of this to "sp_bonus" from "int_bonus" 39/* changed the name of this to "sp_bonus" from "int_bonus"
39 * because Pow can now be the stat that controls spellpoint 40 * because Pow can now be the stat that controls spellpoint
40 * advancement. -b.t. 41 * advancement. -b.t.
41 */ 42 */
42static const int sp_bonus[MAX_STAT + 1] = { 43static const int sp_bonus[MAX_STAT + 1] = {
43 -10, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 15, 20, 25, 44 -10, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 15, 20, 25,
47static const int grace_bonus[MAX_STAT + 1] = { 48static const int grace_bonus[MAX_STAT + 1] = {
48 -10, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 15, 20, 25, 49 -10, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 15, 20, 25,
49 30, 40, 50, 70, 100 50 30, 40, 50, 70, 100
50}; 51};
51 52
52/* 0.92.7 Changed way charisma works. Values now 53/* 0.92.7 Changed way charisma works. Values now
53 * represent how much more it costs to buy something than to sell it 54 * represent how much more it costs to buy something than to sell it
54 * (10, a value of 10 means it is that if it costs 50 gp to buy, you 55 * (10, a value of 10 means it is that if it costs 50 gp to buy, you
55 * would only get 5 gp when you sell.) Let query_cost do the calculations 56 * would only get 5 gp when you sell.) Let query_cost do the calculations
56 * on how to really do this. Buy keeping it this simple number, it is 57 * on how to really do this. Buy keeping it this simple number, it is
57 * much easier to know how things will be influenced. A value of '1' means 58 * much easier to know how things will be influenced. A value of '1' means
58 * buying and selling is both the same value - any value less than or equal 59 * buying and selling is both the same value - any value less than or equal
59 * to 1 should not be used. 60 * to 1 should not be used.
60 * At least as of now, the only place that uses this code is query_cost, 61 * At least as of now, the only place that uses this code is query_cost,
61 * in server/shop.c. This bonus is split evenly between buying and selling 62 * in server/shop.c. This bonus is split evenly between buying and selling
62 * (ie, if the bonus is 2.0, then items are bought for 1.33 list, and sold 63 * (ie, if the bonus is 2.0, then items are bought for 1.33 list, and sold
63 * at .667 64 * at .667
64 * This is figured by diff=(y-1)/(1+y), and for buy, it is 1+diff, for sell 65 * This is figured by diff=(y-1)/(1+y), and for buy, it is 1+diff, for sell
108 * These limits are probably overly generous, but being there were no values 109 * These limits are probably overly generous, but being there were no values
109 * before, you need to start someplace. 110 * before, you need to start someplace.
110 */ 111 */
111 112
112const uint32 weight_limit[MAX_STAT + 1] = { 113const uint32 weight_limit[MAX_STAT + 1] = {
113 200000, /* 0 */ 114 200000, /* 0 */
114 250000, 300000, 350000, 400000, 500000, /* 5 */ 115 250000, 300000, 350000, 400000, 500000, /* 5 */
115 600000, 700000, 800000, 900000, 1000000, /* 10 */ 116 600000, 700000, 800000, 900000, 1000000, /* 10 */
116 1100000, 1200000, 1300000, 1400000, 1500000, /* 15 */ 117 1100000, 1200000, 1300000, 1400000, 1500000, /* 15 */
117 1650000, 1800000, 1950000, 2100000, 2250000, /* 20 */ 118 1650000, 1800000, 1950000, 2100000, 2250000, /* 20 */
118 2400000, 2550000, 2700000, 2850000, 3000000, /* 25 */ 119 2400000, 2550000, 2700000, 2850000, 3000000, /* 25 */
119 3250000, 3500000, 3750000, 4000000, 4500000 /*30 */ 120 3250000, 3500000, 3750000, 4000000, 4500000 /* 30 */
120}; 121};
121 122
122const int learn_spell[MAX_STAT + 1] = { 123const int learn_spell[MAX_STAT + 1] = {
123 0, 0, 0, 1, 2, 4, 8, 12, 16, 25, 36, 45, 55, 65, 70, 75, 80, 85, 90, 95, 100, 100, 100, 100, 100, 124 0, 0, 0, 1, 2, 4, 8, 12, 16, 25, 36, 45, 55, 65, 70, 75, 80, 85, 90, 95, 100, 100, 100, 100, 100,
124 100, 100, 100, 100, 100, 100 125 100, 100, 100, 100, 100, 100
139/* 140/*
140 Since this is nowhere defined ... 141 Since this is nowhere defined ...
141 Both come in handy at least in function add_exp() 142 Both come in handy at least in function add_exp()
142*/ 143*/
143 144
144#define MAX_EXPERIENCE levels[settings.max_level] 145#define MAX_EXPERIENCE levels [settings.max_level]
145 146
146/* because exp_obj sum to make the total score, 147/* because exp_obj sum to make the total score,
147 * we cannot allow that sum to exceed the maximum 148 * we cannot allow that sum to exceed the maximum
148 * amount of experience a player can gain. Thus 149 * amount of experience a player can gain. Thus
149 * we define MAX_EXP_IN_OBJ. It is important to try 150 * we define MAX_EXP_IN_OBJ. It is important to try
150 * to make the value of MAX_EXP_CAT close to the 151 * to make the value of MAX_EXP_CAT close to the
151 * actual number of experience objects in the game, 152 * actual number of experience objects in the game,
152 * otherwise the maximum level in any experience 153 * otherwise the maximum level in any experience
153 * category could be quite low. To help the situation 154 * category could be quite low. To help the situation
154 * out a little I added 10 more levels, and jacked 155 * out a little I added 10 more levels, and jacked
155 * up the last level experience value. Its out of 156 * up the last level experience value. Its out of
156 * line with progression of previous levels, so 157 * line with progression of previous levels, so
157 * if more levels are desired, this should be fixed. 158 * if more levels are desired, this should be fixed.
158 * -b.t. 159 * -b.t.
159 */ 160 */
160 161
161#define MAX_EXP_IN_OBJ levels[settings.max_level]/(MAX_EXP_CAT - 1) 162#define MAX_EXP_IN_OBJ MAX_EXP_IN_OBJ / (MAX_EXP_CAT - 1)
162
163extern sint64 *levels;
164 163
165#define MAX_SAVE_LEVEL 110 164#define MAX_SAVE_LEVEL 110
166 165
167/* This no longer needs to be changed anytime the number of 166/* This no longer needs to be changed anytime the number of
168 * levels is increased - rather, did_make_save will do the 167 * levels is increased - rather, did_make_save will do the
339 check_stat_bounds (&op->stats); 338 check_stat_bounds (&op->stats);
340 } /* end of potion handling code */ 339 } /* end of potion handling code */
341 } 340 }
342 341
343 /* reset attributes that update_stats doesn't reset since it doesn't search 342 /* reset attributes that update_stats doesn't reset since it doesn't search
344 * everything to set 343 * everything to set
345 */ 344 */
346 if (flag == -1) 345 if (flag == -1)
347 { 346 {
348 op->attacktype &= ~tmp->attacktype; 347 op->attacktype &= ~tmp->attacktype;
349 op->path_attuned &= ~tmp->path_attuned; 348 op->path_attuned &= ~tmp->path_attuned;
418 if (tmp->move_type & MOVE_SWIM) 417 if (tmp->move_type & MOVE_SWIM)
419 DIFF_MSG (flag, "You feel ready for a swim", "You no longer feel like swimming"); 418 DIFF_MSG (flag, "You feel ready for a swim", "You no longer feel like swimming");
420 } 419 }
421 420
422 /* becoming UNDEAD... a special treatment for this flag. Only those not 421 /* becoming UNDEAD... a special treatment for this flag. Only those not
423 * originally undead may change their status 422 * originally undead may change their status
424 */ 423 */
425 if (!op->arch->flag [FLAG_UNDEAD]) 424 if (!op->arch->flag [FLAG_UNDEAD])
426 if (op->flag [FLAG_UNDEAD] != prev_flag [FLAG_UNDEAD]) 425 if (op->flag [FLAG_UNDEAD] != prev_flag [FLAG_UNDEAD])
427 { 426 {
428 success = 1; 427 success = 1;
449 success = 1; 448 success = 1;
450 DIFF_MSG (flag, "You become transparent.", "You can see yourself."); 449 DIFF_MSG (flag, "You become transparent.", "You can see yourself.");
451 } 450 }
452 451
453 /* blinded you can tell if more blinded since blinded player has minimal 452 /* blinded you can tell if more blinded since blinded player has minimal
454 * vision 453 * vision
455 */ 454 */
456 if (tmp->flag [FLAG_BLIND]) 455 if (tmp->flag [FLAG_BLIND])
457 { 456 {
458 success = 1; 457 success = 1;
459 if (flag > 0) 458 if (flag > 0)
461 if (op->flag [FLAG_WIZ]) 460 if (op->flag [FLAG_WIZ])
462 new_draw_info (NDI_UNIQUE, 0, op, "Your mortal self is blinded."); 461 new_draw_info (NDI_UNIQUE, 0, op, "Your mortal self is blinded.");
463 else 462 else
464 { 463 {
465 new_draw_info (NDI_UNIQUE, 0, op, "You are blinded."); 464 new_draw_info (NDI_UNIQUE, 0, op, "You are blinded.");
466 SET_FLAG (op, FLAG_BLIND); 465 op->set_flag (FLAG_BLIND);
467 if (op->type == PLAYER) 466 if (op->type == PLAYER)
468 op->contr->do_los = 1; 467 op->contr->do_los = 1;
469 } 468 }
470 } 469 }
471 else 470 else
473 if (op->flag [FLAG_WIZ]) 472 if (op->flag [FLAG_WIZ])
474 new_draw_info (NDI_UNIQUE, 0, op, "Your mortal self can now see again."); 473 new_draw_info (NDI_UNIQUE, 0, op, "Your mortal self can now see again.");
475 else 474 else
476 { 475 {
477 new_draw_info (NDI_UNIQUE, 0, op, "Your vision returns."); 476 new_draw_info (NDI_UNIQUE, 0, op, "Your vision returns.");
478 CLEAR_FLAG (op, FLAG_BLIND); 477 op->clr_flag (FLAG_BLIND);
479 if (op->type == PLAYER) 478 if (op->type == PLAYER)
480 op->contr->do_los = 1; 479 op->contr->do_los = 1;
481 } 480 }
482 } 481 }
483 } 482 }
521 { 520 {
522 success = 1; 521 success = 1;
523 DIFF_MSG (flag * tmp->stats.luck, "You feel more lucky.", "You feel less lucky."); 522 DIFF_MSG (flag * tmp->stats.luck, "You feel more lucky.", "You feel less lucky.");
524 } 523 }
525 524
525 if (digest_types [tmp->type])
526 {
526 if (tmp->stats.hp && op->type == PLAYER) 527 if (tmp->stats.hp && op->type == PLAYER)
527 { 528 {
528 success = 1; 529 success = 1;
529 DIFF_MSG (flag * tmp->stats.hp, "You feel much more healthy!", "You feel much less healthy!"); 530 DIFF_MSG (flag * tmp->stats.hp, "You feel much more healthy!", "You feel much less healthy!");
530 } 531 }
531 532
532 if (tmp->stats.sp && op->type == PLAYER && tmp->type != SKILL) 533 if (tmp->stats.sp && op->type == PLAYER
533 { 534 && tmp->type != SKILL && tmp->type != BOW)
535 {
534 success = 1; 536 success = 1;
535 DIFF_MSG (flag * tmp->stats.sp, "You feel one with the powers of magic!", "You suddenly feel very mundane."); 537 DIFF_MSG (flag * tmp->stats.sp, "You feel one with the powers of magic!", "You suddenly feel very mundane.");
536 } 538 }
537 539
538 /* for the future when artifacts set this -b.t. */ 540 /* for the future when artifacts set this -b.t. */
539 if (tmp->stats.grace && op->type == PLAYER) 541 if (tmp->stats.grace && op->type == PLAYER)
540 { 542 {
541 success = 1; 543 success = 1;
542 DIFF_MSG (flag * tmp->stats.grace, "You feel closer to your god!", "You suddenly feel less holy."); 544 DIFF_MSG (flag * tmp->stats.grace, "You feel closer to your god!", "You suddenly feel less holy.");
543 } 545 }
544 546
545 if (tmp->stats.food && op->type == PLAYER) 547 if (tmp->stats.food && op->type == PLAYER)
546 { 548 {
547 success = 1; 549 success = 1;
548 DIFF_MSG (flag * tmp->stats.food, "You feel your digestion slowing down.", "You feel your digestion speeding up."); 550 DIFF_MSG (flag * tmp->stats.food, "You feel your digestion slowing down.", "You feel your digestion speeding up.");
551 }
549 } 552 }
550 553
551 /* Messages for changed resistance */ 554 /* Messages for changed resistance */
552 for (int i = 0; i < NROFATTACKS; i++) 555 for (int i = 0; i < NROFATTACKS; i++)
553 { 556 {
606 609
607 if (!tmp) 610 if (!tmp)
608 { 611 {
609 tmp = at->instance (); 612 tmp = at->instance ();
610 tmp = insert_ob_in_ob (tmp, this); 613 tmp = insert_ob_in_ob (tmp, this);
611 SET_FLAG (tmp, FLAG_APPLIED); 614 tmp->set_flag (FLAG_APPLIED);
612 } 615 }
613 } 616 }
614 617
615 new_draw_info (NDI_UNIQUE, 0, this, drain_msg[deplete_stats]); 618 new_draw_info (NDI_UNIQUE, 0, this, drain_msg[deplete_stats]);
616 change_attr_value (&tmp->stats, deplete_stats, -1); 619 change_attr_value (&tmp->stats, deplete_stats, -1);
636 if (!value) 639 if (!value)
637 return; 640 return;
638 641
639 tmp = at->instance (); 642 tmp = at->instance ();
640 tmp = insert_ob_in_ob (tmp, this); 643 tmp = insert_ob_in_ob (tmp, this);
641 SET_FLAG (tmp, FLAG_APPLIED); 644 tmp->set_flag (FLAG_APPLIED);
642 } 645 }
643 646
644 if (value) 647 if (value)
645 { 648 {
646 /* Limit the luck value of the bad luck object to +/-100. This 649 /* Limit the luck value of the bad luck object to +/-100. This
699 sint8 v = arch->stats.stat (i); 702 sint8 v = arch->stats.stat (i);
700 stats.stat (i) += v; 703 stats.stat (i) += v;
701 contr->orig_stats.stat (i) += v; 704 contr->orig_stats.stat (i) += v;
702 } 705 }
703} 706}
704
705/* These are the items that currently can change digestion, regeneration,
706 * spell point recovery and mana point recovery. Seems sort of an arbitary
707 * list, but other items store other info into stats array.
708 */
709static struct digest_types : std::bitset<NUM_TYPES>
710{
711 digest_types ()
712 {
713 set (WEAPON);
714 set (BOW);
715 set (ARMOUR);
716 set (HELMET);
717 set (SHIELD);
718 set (RING);
719 set (BOOTS);
720 set (GLOVES);
721 set (AMULET);
722 set (GIRDLE);
723 set (BRACERS);
724 set (CLOAK);
725 set (DISEASE);
726 set (FORCE);
727 set (SKILL);
728 }
729} digest_types;
730 707
731static struct copy_flags : object::flags_t 708static struct copy_flags : object::flags_t
732{ 709{
733 copy_flags () 710 copy_flags ()
734 { 711 {
753 * spell system split, grace points now added to system --peterm 730 * spell system split, grace points now added to system --peterm
754 */ 731 */
755void 732void
756object::update_stats () 733object::update_stats ()
757{ 734{
758 float f, max_speed = 9, added_speed = 0, bonus_speed = 0, speed_reduce_from_disease = 1; 735 float max_speed = 9, added_speed = 0, bonus_speed = 0, speed_reduce_from_disease = 1;
759 int weapon_weight = 0, weapon_speed = 0; 736 weight_t weapon_weight = 0;
737 int weapon_speed = 0;
760 int best_wc = 0, best_ac = 0, wc = 0, ac = 0; 738 int best_wc = 0, best_ac = 0, wc = 0, ac = 0;
761 int prot[NROFATTACKS], vuln[NROFATTACKS], potion_resist[NROFATTACKS]; 739 int prot[NROFATTACKS], vuln[NROFATTACKS], potion_resist[NROFATTACKS];
762 object *grace_obj = NULL, *mana_obj = NULL, *tmp; 740 object *grace_obj = NULL, *mana_obj = NULL, *tmp;
763 float old_speed = speed; 741 float old_speed = speed;
764 int stat_sum [NUM_STATS]; 742 int stat_sum [NUM_STATS];
784 contr->gen_grace = 0; 762 contr->gen_grace = 0;
785 contr->gen_sp_armour = 10; 763 contr->gen_sp_armour = 10;
786 contr->item_power = 0; 764 contr->item_power = 0;
787 } 765 }
788 766
789 for (int i = NUM_BODY_LOCATIONS; i--; ) 767 for (int i = 0; i < NUM_BODY_LOCATIONS; ++i)
790 slot[i].used = slot[i].info; 768 slot[i].used = slot[i].info;
791 769
792 slaying = 0; 770 slaying = 0;
793 771
794 if (!QUERY_FLAG (this, FLAG_WIZ)) 772 if (!this->flag [FLAG_WIZ])
795 {
796 CLEAR_FLAG (this, FLAG_XRAYS);
797 CLEAR_FLAG (this, FLAG_MAKE_INVIS);
798 } 773 {
774 this->clr_flag (FLAG_XRAYS);
775 this->clr_flag (FLAG_MAKE_INVIS);
776 }
799 777
800 CLEAR_FLAG (this, FLAG_LIFESAVE); 778 this->clr_flag (FLAG_LIFESAVE);
801 CLEAR_FLAG (this, FLAG_STEALTH); 779 this->clr_flag (FLAG_STEALTH);
802 CLEAR_FLAG (this, FLAG_BLIND); 780 this->clr_flag (FLAG_BLIND);
803 781
804 if (!QUERY_FLAG (arch, FLAG_REFL_SPELL )) CLEAR_FLAG (this, FLAG_REFL_SPELL); 782 if (!arch->flag [FLAG_REFL_SPELL ]) this->clr_flag (FLAG_REFL_SPELL);
805 if (!QUERY_FLAG (arch, FLAG_REFL_MISSILE)) CLEAR_FLAG (this, FLAG_REFL_MISSILE); 783 if (!arch->flag [FLAG_REFL_MISSILE]) this->clr_flag (FLAG_REFL_MISSILE);
806 if (!QUERY_FLAG (arch, FLAG_UNDEAD )) CLEAR_FLAG (this, FLAG_UNDEAD); 784 if (!arch->flag [FLAG_UNDEAD ]) this->clr_flag (FLAG_UNDEAD);
807 if (!QUERY_FLAG (arch, FLAG_SEE_IN_DARK )) CLEAR_FLAG (this, FLAG_SEE_IN_DARK); 785 if (!arch->flag [FLAG_SEE_IN_DARK ]) this->clr_flag (FLAG_SEE_IN_DARK);
808 786
809 path_attuned = arch->path_attuned; 787 path_attuned = arch->path_attuned;
810 path_repelled = arch->path_repelled; 788 path_repelled = arch->path_repelled;
811 path_denied = arch->path_denied; 789 path_denied = arch->path_denied;
812 glow_radius = arch->glow_radius; 790 glow_radius = arch->glow_radius;
813 move_type = arch->move_type; 791 move_type = arch->move_type;
814 792
815 object *chosen_skill = 0;
816
817 /* initializing resistances from the values in player/monster's 793 /* initializing resistances from the values in player/monster's
818 * archetype clone 794 * archetype clone
819 */ 795 */
820 memcpy (&resist, &arch->resist, sizeof (resist)); 796 memcpy (&resist, &arch->resist, sizeof (resist));
821 797
822 for (int i = 0; i < NROFATTACKS; i++) 798 for (int i = 0; i < NROFATTACKS; i++)
823 { 799 {
824 if (resist[i] > 0) 800 if (resist[i] > 0)
825 prot[i] = resist[i], vuln[i] = 0; 801 prot[i] = resist[i], vuln[i] = 0;
826 else 802 else
827 vuln[i] = -(resist[i]), prot[i] = 0; 803 vuln[i] = -resist[i], prot[i] = 0;
828 804
829 potion_resist[i] = 0; 805 potion_resist[i] = -1000;
830 } 806 }
831 807
832 wc = arch->stats.wc; 808 wc = arch->stats.wc;
833 stats.dam = arch->stats.dam; 809 stats.dam = arch->stats.dam;
834 810
835 /* for players which cannot use armour, they gain AC -1 per 3 levels, 811 /* for players which cannot use armour, they gain AC -1 per 3 levels,
836 * plus a small amount of physical resist, those poor suckers. ;) 812 * plus a small amount of physical resist, those poor suckers. ;)
837 * the fact that maxlevel is factored in could be considered sort of bogus - 813 * the fact that maxlevel is factored in could be considered sort of bogus -
838 * we should probably give them some bonus and cap it off - otherwise, 814 * we should probably give them some bonus and cap it off - otherwise,
839 * basically, if a server updates its max level, these playes may find 815 * basically, if a server updates its max level, these playes may find
840 * that their protection from physical goes down 816 * that their protection from physical goes down
841 */ 817 */
842 if (!QUERY_FLAG (this, FLAG_USE_ARMOUR) && type == PLAYER) 818 if (!this->flag [FLAG_USE_ARMOUR] && type == PLAYER)
843 { 819 {
844 ac = max (-10, arch->stats.ac - level / 3); 820 ac = max (-10, arch->stats.ac - level / 3);
845 prot[ATNR_PHYSICAL] += ((100 - prot[AT_PHYSICAL]) * (80 * level / settings.max_level)) / 100; 821 prot[ATNR_PHYSICAL] += ((100 - prot[AT_PHYSICAL]) * (80 * level / settings.max_level)) / 100;
846 } 822 }
847 else 823 else
848 ac = arch->stats.ac; 824 ac = arch->stats.ac;
849 825
850 stats.luck = arch->stats.luck; 826 stats.luck = arch->stats.luck;
851 speed = arch->speed; 827 speed = arch->speed;
828
829 chosen_skill = 0;
852 830
853 /* OK - we've reset most all the objects attributes to sane values. 831 /* OK - we've reset most all the objects attributes to sane values.
854 * now go through and make adjustments for what the player has equipped. 832 * now go through and make adjustments for what the player has equipped.
855 */ 833 */
856 for (tmp = inv; tmp; tmp = tmp->below) 834 for (tmp = inv; tmp; tmp = tmp->below)
857 { 835 {
858 /* This happens because apply_potion calls change_abil with the potion 836 /* This happens because apply_potion calls change_abil with the potion
859 * applied so we can tell the player what changed. But change_abil 837 * applied so we can tell the player what changed. But change_abil
860 * then calls this function. 838 * then calls this function.
861 */ 839 */
862 if (QUERY_FLAG (tmp, FLAG_APPLIED) && tmp->type == POTION) 840 if (tmp->flag [FLAG_APPLIED] && tmp->type == POTION)
863 continue; 841 continue;
864 842
865 glow_radius += tmp->glow_radius; 843 glow_radius += tmp->glow_radius;
866 844
867 /* For some things, we don't care what is equipped */ 845 /* For some things, we don't care what is equipped */
885 } 863 }
886 } 864 }
887 865
888 /* Container objects are not meant to adjust players, but other applied 866 /* Container objects are not meant to adjust players, but other applied
889 * objects need to make adjustments. 867 * objects need to make adjustments.
890 * This block should handle all player specific changes 868 * This block should handle all player specific changes
891 * The check for Praying is a bit of a hack - god given bonuses are put 869 * The check for Praying is a bit of a hack - god given bonuses are put
892 * in the praying skill, and the player should always get those. 870 * in the praying skill, and the player should always get those.
893 * It also means we need to put in additional checks for applied below, 871 * It also means we need to put in additional checks for applied below,
894 * because the skill shouldn't count against body positions being used 872 * because the skill shouldn't count against body positions being used
895 * up, etc. 873 * up, etc.
896 */ 874 */
897 if ((tmp->flag [FLAG_APPLIED] 875 if ((tmp->flag [FLAG_APPLIED]
898 && tmp->type != CONTAINER 876 && tmp->type != CONTAINER
899 && tmp->type != CLOSE_CON) 877 && tmp->type != CLOSE_CON
878 && tmp->type != SPELL)
900 || (tmp->type == SKILL && tmp->subtype == SK_PRAYING)) 879 || (tmp->type == SKILL && tmp->subtype == SK_PRAYING))
901 { 880 {
902 if (type == PLAYER) 881 if (type == PLAYER)
903 { 882 {
904 contr->item_power += tmp->item_power; 883 contr->item_power += tmp->item_power;
905
906 if (tmp == contr->combat_ob || tmp == contr->ranged_ob)
907 if (tmp != current_weapon
908 && (tmp->type != SKILL || tmp->subtype != SK_PRAYING)
909 && !tmp->flag [FLAG_CURSED]
910 && !tmp->flag [FLAG_DAMNED])
911 continue;
912 884
913 for (int i = 0; i < NUM_STATS; i++) 885 for (int i = 0; i < NUM_STATS; i++)
914 stat_sum [i] += tmp->stats.stat (i); 886 stat_sum [i] += tmp->stats.stat (i);
915 887
916 if (digest_types [tmp->type]) 888 if (digest_types [tmp->type])
928 if (tmp->type == WEAPON) 900 if (tmp->type == WEAPON)
929 current_weapon = tmp; 901 current_weapon = tmp;
930 } 902 }
931 903
932 /* Update slots used for items */ 904 /* Update slots used for items */
933 if (QUERY_FLAG (tmp, FLAG_APPLIED)) 905 if (tmp->flag [FLAG_APPLIED]) // exclude praying...
934 for (int i = 0; i < NUM_BODY_LOCATIONS; i++) 906 for (int i = 0; i < NUM_BODY_LOCATIONS; ++i)
935 slot[i].used += tmp->slot[i].info; 907 slot[i].used += tmp->slot[i].info;
936 908
937 if (tmp->type == SYMPTOM) 909 if (tmp->type == SYMPTOM)
938 min_it (speed_reduce_from_disease, tmp->last_sp ? tmp->last_sp / 100.f : 1.f); 910 min_it (speed_reduce_from_disease, tmp->last_sp ? tmp->last_sp / 100.f : 1.f);
939 911
940 /* Pos. and neg. protections are counted separate (-> pro/vuln). 912 /* Pos. and neg. protections are counted separate (-> pro/vuln).
941 * (Negative protections are calculated exactly like positive.) 913 * (Negative protections are calculated exactly like positive.)
942 * Resistance from potions are treated special as well. If there's 914 * Resistance from potions are treated special as well. If there's
943 * more than one potion-effect, the bigger prot.-value is taken. 915 * more than one potion-effect, the bigger prot.-value is taken.
944 */ 916 */
945 if (tmp->type != POTION) 917 if (tmp->type == POTION_EFFECT)
946 {
947 for (int i = 0; i < NROFATTACKS; i++) 918 for (int i = 0; i < NROFATTACKS; i++)
948 {
949 /* Potential for cursed potions, in which case we just can use
950 * a straight MAX, as potion_resist is initialised to zero.
951 */
952 if (tmp->type == POTION_EFFECT)
953 {
954 if (potion_resist[i])
955 potion_resist[i] = max (potion_resist[i], tmp->resist[i]);
956 else
957 potion_resist[i] = tmp->resist[i]; 919 max_it (potion_resist[i], tmp->resist[i]);
958 } 920 else if (tmp->type != POTION)
921 for (int i = 0; i < NROFATTACKS; i++)
959 else if (tmp->resist[i] > 0) 922 if (tmp->resist[i] > 0)
960 prot[i] += ((100 - prot[i]) * tmp->resist[i]) / 100; 923 prot[i] += (100 - prot[i]) * tmp->resist[i] / 100;
961 else if (tmp->resist[i] < 0) 924 else if (tmp->resist[i] < 0)
962 vuln[i] += ((100 - vuln[i]) * -tmp->resist[i]) / 100; 925 vuln[i] += (100 - vuln[i]) * -tmp->resist[i] / 100;
963 }
964 }
965 926
966 /* There may be other things that should not adjust the attacktype */ 927 /* There may be other things that should not adjust the attacktype */
967 if (tmp->type != SYMPTOM) 928 if (tmp->type != SYMPTOM)
968 { 929 {
969 attacktype |= tmp->attacktype; 930 attacktype |= tmp->attacktype;
974 stats.luck += tmp->stats.luck; 935 stats.luck += tmp->stats.luck;
975 } 936 }
976 937
977 flag |= tmp->flag & copy_flags; 938 flag |= tmp->flag & copy_flags;
978 939
979 if (QUERY_FLAG (tmp, FLAG_UNDEAD) && !QUERY_FLAG (arch, FLAG_UNDEAD)) 940 if (tmp->flag [FLAG_UNDEAD] && !arch->flag [FLAG_UNDEAD])
980 SET_FLAG (this, FLAG_UNDEAD); 941 this->set_flag (FLAG_UNDEAD);
981 942
982 if (QUERY_FLAG (tmp, FLAG_MAKE_INVIS)) 943 //TODO: copy_flags?
944 if (tmp->flag [FLAG_MAKE_INVIS])
983 { 945 {
984 SET_FLAG (this, FLAG_MAKE_INVIS); 946 set_flag (FLAG_MAKE_INVIS);
985 invisible = 1; 947 invisible = 1;
986 } 948 }
987 949
988 if (tmp->stats.exp && tmp->type != SKILL) 950 if (tmp->stats.exp && tmp->type != SKILL)
989 { 951 {
996 added_speed += tmp->stats.exp; 958 added_speed += tmp->stats.exp;
997 } 959 }
998 960
999 switch (tmp->type) 961 switch (tmp->type)
1000 { 962 {
1001 /* skills modifying the character -b.t. */
1002 /* for all skills and skill granting objects */
1003 case SKILL: 963 case SKILL:
1004 { 964 {
965 // some skills will end up here without counting as "applied"
1005 if (!QUERY_FLAG (tmp, FLAG_APPLIED) || skill_flags [tmp->subtype] & SF_APPLY) 966 if (!tmp->flag [FLAG_APPLIED] || skill_flags [tmp->subtype] & SF_AUTARK)
1006 break; 967 break;
1007 968
1008 if (chosen_skill) 969 if (chosen_skill)
1009 { 970 {
1010 LOG (llevDebug, "fix_player, op %s has multiple skills applied (%s and %s)\n", 971 LOG (llevDebug, "fix_player, op %s has multiple skills applied (%s and %s)\n",
1012 973
1013 tmp->flag [FLAG_APPLIED] = false; 974 tmp->flag [FLAG_APPLIED] = false;
1014 update_stats (); 975 update_stats ();
1015 return; 976 return;
1016 } 977 }
1017 else 978
1018 chosen_skill = tmp; 979 chosen_skill = tmp;
1019 980
1020 if (tmp->stats.dam > 0) 981 if (tmp->stats.dam > 0)
1021 { /* skill is a 'weapon' */ 982 { /* skill is a 'weapon' */
1022 if (!QUERY_FLAG (this, FLAG_READY_WEAPON)) 983 if (!this->flag [FLAG_READY_WEAPON])
1023 weapon_speed = WEAPON_SPEED (tmp); 984 weapon_speed = max (0, WEAPON_SPEED (tmp));
1024
1025 if (weapon_speed < 0)
1026 weapon_speed = 0;
1027 985
1028 weapon_weight = tmp->weight; 986 weapon_weight = tmp->weight;
1029 stats.dam += 1 + chosen_skill->level * tmp->stats.dam / 9; 987 stats.dam += 1 + chosen_skill->level * tmp->stats.dam / 9;
1030 988
1031 if (tmp->magic) 989 if (tmp->magic)
1040 998
1041 if (tmp->stats.ac) 999 if (tmp->stats.ac)
1042 ac -= tmp->stats.ac + tmp->magic; 1000 ac -= tmp->stats.ac + tmp->magic;
1043 1001
1044 if (settings.spell_encumbrance == TRUE && type == PLAYER) 1002 if (settings.spell_encumbrance == TRUE && type == PLAYER)
1045 contr->encumbrance += 3 * tmp->weight / 1000; 1003 contr->encumbrance += weight_to_kg_approx (3 * tmp->weight);
1046 } 1004 }
1047 1005
1048 break; 1006 break;
1049 1007
1050 case SHIELD: 1008 case SHIELD:
1051 if (settings.spell_encumbrance == TRUE && type == PLAYER) 1009 if (settings.spell_encumbrance == TRUE && type == PLAYER)
1052 contr->encumbrance += tmp->weight / 2000; 1010 contr->encumbrance += weight_to_kg_approx (tmp->weight) >> 1;
1053 //FALLTHROUGH 1011 //FALLTHROUGH
1054 case RING: 1012 case RING:
1055 case AMULET: 1013 case AMULET:
1056 case GIRDLE: 1014 case GIRDLE:
1057 case HELMET: 1015 case HELMET:
1067 if (tmp->stats.ac) 1025 if (tmp->stats.ac)
1068 ac -= tmp->stats.ac + tmp->magic; 1026 ac -= tmp->stats.ac + tmp->magic;
1069 1027
1070 break; 1028 break;
1071 1029
1072 case WAND: 1030 case RANGED:
1073 case ROD:
1074 case HORN:
1075 case SKILL_TOOL:
1076 if (type != PLAYER)
1077 chosen_skill = find_skill_by_name (this, tmp->skill);
1078 break;
1079
1080 case BOW: 1031 case BOW:
1081 case WEAPON: 1032 case WEAPON:
1082 if (type != PLAYER || current_weapon == tmp)
1083 {
1084 chosen_skill = find_skill_by_name (this, tmp->skill);
1085
1086 wc -= tmp->stats.wc + tmp->magic; 1033 wc -= tmp->stats.wc + tmp->magic;
1087 1034
1088 if (tmp->stats.ac && tmp->stats.ac + tmp->magic > 0) 1035 if (tmp->stats.ac && tmp->stats.ac + tmp->magic > 0)
1089 ac -= tmp->stats.ac + tmp->magic; 1036 ac -= tmp->stats.ac + tmp->magic;
1090 1037
1091 stats.dam += tmp->stats.dam + tmp->magic; 1038 stats.dam += tmp->stats.dam + tmp->magic;
1092 weapon_weight = tmp->weight; 1039 weapon_weight = tmp->weight;
1093 weapon_speed = (WEAPON_SPEED (tmp) * 2 - tmp->magic) / 2; 1040 weapon_speed = (WEAPON_SPEED (tmp) * 2 - tmp->magic) / 2;
1094 1041
1095 if (weapon_speed < 0) 1042 if (weapon_speed < 0)
1096 weapon_speed = 0; 1043 weapon_speed = 0;
1097 1044
1098 slaying = tmp->slaying; 1045 slaying = tmp->slaying;
1099 1046
1100 /* If there is desire that two handed weapons should do 1047 /* If there is desire that two handed weapons should do
1101 * extra strength damage, this is where the code should 1048 * extra strength damage, this is where the code should
1102 * go. 1049 * go.
1103 */ 1050 */
1104 1051
1105 if (type == PLAYER) 1052 if (type == PLAYER)
1106 if (settings.spell_encumbrance) 1053 if (settings.spell_encumbrance)
1107 contr->encumbrance += tmp->weight * 3 / 1000; 1054 contr->encumbrance += weight_to_kg_approx (3 * tmp->weight);
1108 }
1109 1055
1110 break; 1056 break;
1111 1057
1112 case ARMOUR: /* Only the best of these three are used: */ 1058 case ARMOUR: /* Only the best of these three are used: */
1113 if (settings.spell_encumbrance == TRUE && type == PLAYER) 1059 if (settings.spell_encumbrance == TRUE && type == PLAYER)
1114 contr->encumbrance += tmp->weight / 1000; 1060 contr->encumbrance += weight_to_kg_approx (tmp->weight);
1115 1061
1116 case BRACERS: 1062 case BRACERS:
1117 case FORCE: 1063 case FORCE:
1118 if (tmp->stats.wc) 1064 if (tmp->stats.wc)
1119 { 1065 {
1142 1088
1143 if (tmp->stats.ac) 1089 if (tmp->stats.ac)
1144 ac -= tmp->stats.ac + tmp->magic; 1090 ac -= tmp->stats.ac + tmp->magic;
1145 1091
1146 if (ARMOUR_SPEED (tmp)) 1092 if (ARMOUR_SPEED (tmp))
1147 max_speed = min (max_speed, ARMOUR_SPEED (tmp) / 10.f); 1093 min_it (max_speed, ARMOUR_SPEED (tmp) / 10.f);
1148 1094
1149 break; 1095 break;
1150 } /* switch tmp->type */ 1096 } /* switch tmp->type */
1151 } /* item is equipped */ 1097 } /* item is equipped */
1152 } /* for loop of items */ 1098 } /* for loop of items */
1153 1099
1154 if (type != PLAYER)
1155 this->chosen_skill = chosen_skill;
1156
1157 glow_radius = min (glow_radius, MAX_LIGHT_RADIUS); 1100 min_it (glow_radius, MAX_LIGHT_RADIUS);
1158 1101
1159 /* We've gone through all the objects the player has equipped. For many things, we 1102 /* We've gone through all the objects the player has equipped. For many things, we
1160 * have generated intermediate values which we now need to assign. 1103 * have generated intermediate values which we now need to assign.
1161 */ 1104 */
1162 1105
1163 /* 'total resistance = total protections - total vulnerabilities'. 1106 /* 'total resistance = total protections - total vulnerabilities'.
1164 * If there is an uncursed potion in effect, granting more protection 1107 * If there is an uncursed potion in effect, granting more protection
1165 * than that, we take: 'total resistance = resistance from potion'. 1108 * than that, we take: 'total resistance = resistance from potion'.
1166 * If there is a cursed (and no uncursed) potion in effect, we take 1109 * If there is a cursed (and no uncursed) potion in effect, we take
1167 * 'total resistance = vulnerability from cursed potion'. 1110 * 'total resistance = vulnerability from cursed potion'.
1168 */ 1111 */
1169 for (int i = 0; i < NROFATTACKS; i++) 1112 for (int i = 0; i < NROFATTACKS; i++)
1170 { 1113 {
1171 resist[i] = prot[i] - vuln[i]; 1114 resist[i] = prot[i] - vuln[i];
1172 1115
1173 if (potion_resist[i] && ((potion_resist[i] > resist[i]) || (potion_resist[i] < 0))) 1116 if (potion_resist[i] != -1000
1117 && (potion_resist[i] < 0 || potion_resist[i] > resist[i]))
1174 resist[i] = potion_resist[i]; 1118 resist[i] = potion_resist[i];
1175 } 1119 }
1176 1120
1177 if (type == PLAYER) 1121 if (type == PLAYER)
1178 { 1122 {
1209 stats.maxhp += 2 * max (0, level - 10); 1153 stats.maxhp += 2 * max (0, level - 10);
1210 1154
1211 if (stats.hp > stats.maxhp) 1155 if (stats.hp > stats.maxhp)
1212 stats.hp = stats.maxhp; 1156 stats.hp = stats.maxhp;
1213 1157
1214 /* Sp gain is controlled by the level of the player's 1158 /* Sp gain is controlled by the level of the player's
1215 * relevant experience object (mana_obj, see above) 1159 * relevant experience object (mana_obj, see above)
1216 */ 1160 */
1217 /* following happen when skills system is not used */ 1161 /* following happen when skills system is not used */
1218 if (!mana_obj) 1162 if (!mana_obj)
1219 mana_obj = this; 1163 mana_obj = this;
1220 1164
1290 wc += 4; 1234 wc += 4;
1291 } 1235 }
1292 else 1236 else
1293 ac -= dex_bonus[stats.Dex]; 1237 ac -= dex_bonus[stats.Dex];
1294 1238
1295 /* In new exp/skills system, wc bonuses are related to 1239 /* In new exp/skills system, wc bonuses are related to
1296 * the players level in a relevant exp object (wc_obj) 1240 * the players level in a relevant exp object (wc_obj)
1297 * not the general player level -b.t. 1241 * not the general player level -b.t.
1298 * I changed this slightly so that wc bonuses are better 1242 * I changed this slightly so that wc bonuses are better
1299 * than before. This is to balance out the fact that 1243 * than before. This is to balance out the fact that
1300 * the player no longer gets a personal weapon w/ 1 1244 * the player no longer gets a personal weapon w/ 1
1301 * improvement every level, now its fighterlevel/5. So 1245 * improvement every level, now its fighterlevel/5. So
1302 * we give the player a bonus here in wc and dam 1246 * we give the player a bonus here in wc and dam
1303 * to make up for the change. Note that I left the 1247 * to make up for the change. Note that I left the
1304 * monster bonus the same as before. -b.t. 1248 * monster bonus the same as before. -b.t.
1305 */ 1249 */
1306 object *wc_obj = chosen_skill; 1250 object *wc_obj = chosen_skill;
1307 1251
1308 if (contr && wc_obj && wc_obj->level > 1) 1252 if (contr && wc_obj && wc_obj->level > 1)
1347 /* f is a number the represents the number of kg above (positive num) 1291 /* f is a number the represents the number of kg above (positive num)
1348 * or below (negative number) that the player is carrying. If above 1292 * or below (negative number) that the player is carrying. If above
1349 * weight limit, then player suffers a speed reduction based on how 1293 * weight limit, then player suffers a speed reduction based on how
1350 * much above he is, and what is max carry is 1294 * much above he is, and what is max carry is
1351 */ 1295 */
1352 float f = (carrying / 1000) - max_carry[stats.Str]; 1296 float f = (sint32)weight_to_kg_approx (carrying) - max_carry[stats.Str];
1353 if (f > 0.f) 1297 if (f > 0.f)
1354 speed = speed / (1.f + f / max_carry[stats.Str]); 1298 speed /= (1.f + f / max_carry[stats.Str]);
1355 } 1299 }
1356 1300
1357 speed += bonus_speed / 10.f; /* Not affected by limits */ 1301 speed += bonus_speed / 10.f; /* Not affected by limits */
1358 speed *= speed_reduce_from_disease; 1302 speed *= speed_reduce_from_disease;
1359 1303
1435 update_all_los (env->map, env->x, env->y); 1379 update_all_los (env->map, env->x, env->y);
1436 } 1380 }
1437} 1381}
1438 1382
1439/* 1383/*
1440 * Returns true if the given player is a legal class.
1441 * The function to add and remove class-bonuses to the stats doesn't
1442 * check if the stat becomes negative, thus this function
1443 * merely checks that all stats are 1 or more, and returns
1444 * false otherwise.
1445 */
1446int
1447allowed_class (const object *op)
1448{
1449 return op->stats.Dex > 0
1450 && op->stats.Str > 0
1451 && op->stats.Con > 0
1452 && op->stats.Int > 0
1453 && op->stats.Wis > 0
1454 && op->stats.Pow > 0
1455 && op->stats.Cha > 0;
1456}
1457
1458/*
1459 * set the new dragon name after gaining levels or 1384 * set the new dragon name after gaining levels or
1460 * changing ability focus (later this can be extended to 1385 * changing ability focus (later this can be extended to
1461 * eventually change the player's face and animation) 1386 * eventually change the player's face and animation)
1462 */ 1387 */
1463void 1388void
1526 /* if the force is missing -> bail out */ 1451 /* if the force is missing -> bail out */
1527 if (abil == NULL) 1452 if (abil == NULL)
1528 return; 1453 return;
1529 1454
1530 /* The ability_force keeps track of maximum level ever achieved. 1455 /* The ability_force keeps track of maximum level ever achieved.
1531 * New abilties can only be gained by surpassing this max level 1456 * New abilties can only be gained by surpassing this max level
1532 */ 1457 */
1533 if (who->level > abil->level) 1458 if (who->level > abil->level)
1534 { 1459 {
1535 /* increase our focused ability */ 1460 /* increase our focused ability */
1536 abil->resist[abil->stats.exp]++; 1461 abil->resist[abil->stats.exp]++;
1578 } 1503 }
1579 1504
1580 /* clear the flag - exp goes into this bucket, but player 1505 /* clear the flag - exp goes into this bucket, but player
1581 * still doesn't know it. 1506 * still doesn't know it.
1582 */ 1507 */
1583 CLEAR_FLAG (skill_obj, FLAG_CAN_USE_SKILL); 1508 skill_obj->clr_flag (FLAG_CAN_USE_SKILL);
1584 skill_obj->stats.exp = 0; 1509 skill_obj->stats.exp = 0;
1585 skill_obj->level = 1; 1510 skill_obj->level = 1;
1586 op->insert (skill_obj); 1511 op->insert (skill_obj);
1587 1512
1588 if (player *pl = op->contr) 1513 if (player *pl = op->contr)
1665 */ 1590 */
1666 1591
1667sint64 1592sint64
1668level_exp (int level, double expmul) 1593level_exp (int level, double expmul)
1669{ 1594{
1670 if (level > settings.max_level) 1595 return expmul * level_to_min_exp (level);
1671 return (sint64) (expmul * levels[settings.max_level]);
1672
1673 return (sint64) (expmul * levels[level]);
1674} 1596}
1675 1597
1676/* 1598/*
1677 * Ensure that the permanent experience requirements in an exp object are met. 1599 * Ensure that the permanent experience requirements in an exp object are met.
1678 * This really just checks 'op to make sure the perm_exp value is within 1600 * This really just checks 'op to make sure the perm_exp value is within
1684calc_perm_exp (object *op) 1606calc_perm_exp (object *op)
1685{ 1607{
1686 int p_exp_min; 1608 int p_exp_min;
1687 1609
1688 /* Ensure that our permanent experience minimum is met. 1610 /* Ensure that our permanent experience minimum is met.
1689 * permenent_exp_ratio is an integer percentage, we divide by 100 1611 * permenent_exp_ratio is an integer percentage, we divide by 100
1690 * to get the fraction */ 1612 * to get the fraction */
1691 p_exp_min = (int) (settings.permanent_exp_ratio * (float) (op->stats.exp) / 100); 1613 p_exp_min = (int) (settings.permanent_exp_ratio * (float) (op->stats.exp) / 100);
1692 1614
1693 if (op->perm_exp < p_exp_min) 1615 if (op->perm_exp < p_exp_min)
1694 op->perm_exp = p_exp_min; 1616 op->perm_exp = p_exp_min;
1706 * NULL, in which case exp increases the players general 1628 * NULL, in which case exp increases the players general
1707 * total, but not any particular skill. 1629 * total, but not any particular skill.
1708 * flag is what to do if the player doesn't have the skill: 1630 * flag is what to do if the player doesn't have the skill:
1709 */ 1631 */
1710static void 1632static void
1711add_player_exp (object *op, sint64 exp, const char *skill_name, int flag) 1633add_player_exp (object *op, sint64 exp, shstr_tmp skill_name, int flag)
1712{ 1634{
1713 object *skill_obj; 1635 object *skill_obj;
1714 sint64 limit, exp_to_add; 1636 sint64 limit, exp_to_add;
1715 int i;
1716 1637
1717 /* prevents some forms of abuse. */ 1638 /* prevents some forms of abuse. */
1718 if (op->contr->braced) 1639 if (op->contr->braced)
1719 exp /= 5; 1640 exp /= 5;
1720 1641
1746 { 1667 {
1747 /* Basically, you can never gain more experience in one shot 1668 /* Basically, you can never gain more experience in one shot
1748 * than half what you need to gain for next level. 1669 * than half what you need to gain for next level.
1749 */ 1670 */
1750 exp_to_add = exp; 1671 exp_to_add = exp;
1751 limit = (levels[op->level + 1] - levels[op->level]) / 2; 1672 limit = (levels [op->level + 1] - levels [op->level]) / 2;
1752 if (exp_to_add > limit) 1673 if (exp_to_add > limit)
1753 exp_to_add = limit; 1674 exp_to_add = limit;
1754 1675
1755 ADD_EXP (op->stats.exp, (sint64) ((float) exp_to_add * (skill_obj ? skill_obj->expmul : 1))); 1676 ADD_EXP (op->stats.exp, (sint64) ((float) exp_to_add * (skill_obj ? skill_obj->expmul : 1)));
1756 if (settings.permanent_exp_ratio) 1677 if (settings.permanent_exp_ratio)
1763 } 1684 }
1764 1685
1765 if (skill_obj) 1686 if (skill_obj)
1766 { 1687 {
1767 exp_to_add = exp; 1688 exp_to_add = exp;
1768 limit = (levels[skill_obj->level + 1] - levels[skill_obj->level]) / 2; 1689 limit = (levels [skill_obj->level + 1] - levels [skill_obj->level]) / 2;
1769 if (exp_to_add > limit) 1690 if (exp_to_add > limit)
1770 exp_to_add = limit; 1691 exp_to_add = limit;
1771 1692
1772 ADD_EXP (skill_obj->stats.exp, exp_to_add); 1693 ADD_EXP (skill_obj->stats.exp, exp_to_add);
1773 if (settings.permanent_exp_ratio) 1694 if (settings.permanent_exp_ratio)
1830 * where everything is at the minimum perm exp, he would lose nothing. 1751 * where everything is at the minimum perm exp, he would lose nothing.
1831 * exp is the amount of exp to subtract - thus, it should be 1752 * exp is the amount of exp to subtract - thus, it should be
1832 * a postive number. 1753 * a postive number.
1833 */ 1754 */
1834static void 1755static void
1835subtract_player_exp (object *op, sint64 exp, const char *skill, int flag) 1756subtract_player_exp (object *op, sint64 exp, shstr_tmp skill, int flag)
1836{ 1757{
1837 float fraction = (float) exp / (float) op->stats.exp; 1758 float fraction = (float) exp / (float) op->stats.exp;
1838 object *tmp; 1759 object *tmp;
1839 sint64 del_exp; 1760 sint64 del_exp;
1840 1761
1841 for (tmp = op->inv; tmp; tmp = tmp->below) 1762 for (tmp = op->inv; tmp; tmp = tmp->below)
1842 if (tmp->type == SKILL && tmp->stats.exp) 1763 if (tmp->type == SKILL && tmp->stats.exp)
1843 { 1764 {
1844 if (flag == SK_SUBTRACT_SKILL_EXP && skill && !strcmp (&tmp->skill, skill)) 1765 if (flag == SK_SUBTRACT_SKILL_EXP && skill && tmp->skill == skill)
1845 { 1766 {
1846 del_exp = check_exp_loss (tmp, exp); 1767 del_exp = check_exp_loss (tmp, exp);
1847 tmp->stats.exp -= del_exp; 1768 tmp->stats.exp -= del_exp;
1848 player_lvl_adj (op, tmp); 1769 player_lvl_adj (op, tmp);
1849 } 1770 }
1850 else if (flag != SK_SUBTRACT_SKILL_EXP) 1771 else if (flag != SK_SUBTRACT_SKILL_EXP)
1851 { 1772 {
1852 /* only want to process other skills if we are not trying 1773 /* only want to process other skills if we are not trying
1853 * to match a specific skill. 1774 * to match a specific skill.
1854 */ 1775 */
1855 del_exp = check_exp_loss (tmp, (sint64) (tmp->stats.exp * fraction)); 1776 del_exp = check_exp_loss (tmp, tmp->stats.exp * fraction);
1856 tmp->stats.exp -= del_exp; 1777 tmp->stats.exp -= del_exp;
1857 player_lvl_adj (op, tmp); 1778 player_lvl_adj (op, tmp);
1858 } 1779 }
1859 } 1780 }
1860 1781
1874 * skill_name is the skill that should get the exp added. 1795 * skill_name is the skill that should get the exp added.
1875 * flag is what to do if player doesn't have the skill. 1796 * flag is what to do if player doesn't have the skill.
1876 * these last two values are only used for players. 1797 * these last two values are only used for players.
1877 */ 1798 */
1878void 1799void
1879change_exp (object *op, sint64 exp, const char *skill_name, int flag) 1800change_exp (object *op, sint64 exp, shstr_tmp skill_name, int flag)
1880{ 1801{
1881#ifdef EXP_DEBUG 1802#ifdef EXP_DEBUG
1882 LOG (llevDebug, "change_exp() called for %s, exp = %" PRId64 "\n", query_name (op), exp); 1803 LOG (llevDebug, "change_exp() called for %s, exp = %" PRId64 "\n", query_name (op), exp);
1883#endif 1804#endif
1884 1805
1893 * won't do anything if the value is 0 anyways. 1814 * won't do anything if the value is 0 anyways.
1894 */ 1815 */
1895 if (exp == 0) 1816 if (exp == 0)
1896 return; 1817 return;
1897 1818
1898 /* Monsters are easy - we just adjust their exp - we 1819 /* Monsters are easy - we just adjust their exp - we
1899 * don't adjust level, since in most cases it is unrelated to 1820 * don't adjust level, since in most cases it is unrelated to
1900 * the exp they have - the monsters exp represents what its 1821 * the exp they have - the monsters exp represents what its
1901 * worth. 1822 * worth.
1902 */ 1823 */
1903 if (op->type != PLAYER) 1824 if (op->type != PLAYER)
1904 { 1825 {
1905 /* Sanity check */ 1826 /* Sanity check */
1906 if (!QUERY_FLAG (op, FLAG_ALIVE)) 1827 if (!op->flag [FLAG_ALIVE])
1907 return; 1828 return;
1908 1829
1909 /* reset exp to max allowed value. We subtract from 1830 /* reset exp to max allowed value. We subtract from
1910 * MAX_EXPERIENCE to prevent overflows. If the player somehow has 1831 * MAX_EXPERIENCE to prevent overflows. If the player somehow has
1911 * more than max exp, just return. 1832 * more than max exp, just return.
1930 */ 1851 */
1931 subtract_player_exp (op, abs (exp), skill_name, flag); 1852 subtract_player_exp (op, abs (exp), skill_name, flag);
1932 } 1853 }
1933} 1854}
1934 1855
1935/* Applies a death penalty experience, the size of this is defined by the 1856/* Applies a death penalty experience, the size of this is defined by the
1936 * settings death_penalty_percentage and death_penalty_levels, and by the 1857 * settings death_penalty_percentage and death_penalty_levels, and by the
1937 * amount of permenent experience, whichever gives the lowest loss. 1858 * amount of permenent experience, whichever gives the lowest loss.
1938 */ 1859 */
1939void 1860void
1940apply_death_exp_penalty (object *op) 1861apply_death_exp_penalty (object *op)
1962 tmp->stats.exp -= loss; 1883 tmp->stats.exp -= loss;
1963 player_lvl_adj (op, tmp); 1884 player_lvl_adj (op, tmp);
1964 } 1885 }
1965 1886
1966 percentage_loss = op->stats.exp * settings.death_penalty_ratio / 100; 1887 percentage_loss = op->stats.exp * settings.death_penalty_ratio / 100;
1967 level_loss = op->stats.exp - levels[max (0, op->level - settings.death_penalty_level)]; 1888 level_loss = op->stats.exp - levels [max (0, op->level - settings.death_penalty_level)];
1968 1889
1969 if (level_loss < 0) 1890 if (level_loss < 0)
1970 level_loss = 0; 1891 level_loss = 0;
1971 1892
1972 loss = check_exp_loss (op, min (level_loss, percentage_loss)); 1893 loss = check_exp_loss (op, min (level_loss, percentage_loss));

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines