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.18 by elmex, Wed Dec 20 10:31:00 2006 UTC vs.
Revision 1.19 by root, Fri Dec 22 16:34:00 2006 UTC

235 235
236/* 236/*
237 * sets Str/Dex/con/Wis/Cha/Int/Pow in stats to value, depending on 237 * sets Str/Dex/con/Wis/Cha/Int/Pow in stats to value, depending on
238 * what attr is (STR to POW). 238 * what attr is (STR to POW).
239 */ 239 */
240
241void 240void
242set_attr_value (living * stats, int attr, sint8 value) 241set_attr_value (living *stats, int attr, sint8 value)
243{ 242{
244 switch (attr) 243 switch (attr)
245 { 244 {
246 case STR: 245 case STR:
247 stats->Str = value; 246 stats->Str = value;
269 268
270/* 269/*
271 * Like set_attr_value(), but instead the value (which can be negative) 270 * Like set_attr_value(), but instead the value (which can be negative)
272 * is added to the specified stat. 271 * is added to the specified stat.
273 */ 272 */
274
275void 273void
276change_attr_value (living * stats, int attr, sint8 value) 274change_attr_value (living *stats, int attr, sint8 value)
277{ 275{
278 if (value == 0) 276 if (value == 0)
279 return; 277 return;
278
280 switch (attr) 279 switch (attr)
281 { 280 {
282 case STR: 281 case STR:
283 stats->Str += value; 282 stats->Str += value;
284 break; 283 break;
308/* 307/*
309 * returns the specified stat. See also set_attr_value(). 308 * returns the specified stat. See also set_attr_value().
310 */ 309 */
311 310
312sint8 311sint8
313get_attr_value (const living * stats, int attr) 312get_attr_value (const living *stats, int attr)
314{ 313{
315 switch (attr) 314 switch (attr)
316 { 315 {
317 case STR:
318 return (stats->Str); 316 case STR: return stats->Str;
319 case DEX:
320 return (stats->Dex); 317 case DEX: return stats->Dex;
321 case CON:
322 return (stats->Con); 318 case CON: return stats->Con;
323 case WIS:
324 return (stats->Wis); 319 case WIS: return stats->Wis;
325 case CHA:
326 return (stats->Cha); 320 case CHA: return stats->Cha;
327 case INT:
328 return (stats->Int); 321 case INT: return stats->Int;
329 case POW:
330 return (stats->Pow); 322 case POW: return stats->Pow;
331 } 323 }
324
332 return 0; 325 return 0;
333} 326}
334 327
335/* 328/*
336 * Ensures that all stats (str/dex/con/wis/cha/int) are within the 329 * Ensures that all stats (str/dex/con/wis/cha/int) are within the
337 * 1-30 stat limit. 330 * 1-30 stat limit.
338 */ 331 */
339 332
340void 333void
341check_stat_bounds (living * stats) 334check_stat_bounds (living *stats)
342{ 335{
343 int i, v; 336 int i, v;
344 337
345 for (i = 0; i < NUM_STATS; i++) 338 for (i = 0; i < NUM_STATS; i++)
346 if ((v = get_attr_value (stats, i)) > MAX_STAT) 339 if ((v = get_attr_value (stats, i)) > MAX_STAT)
448 441
449 /* call fix_player since op object could have whatever attribute due 442 /* call fix_player since op object could have whatever attribute due
450 * to multiple items. if fix_player always has to be called after 443 * to multiple items. if fix_player always has to be called after
451 * change_ability then might as well call it from here 444 * change_ability then might as well call it from here
452 */ 445 */
453 fix_player (op); 446 op->update_stats ();
454 447
455 /* Fix player won't add the bows ability to the player, so don't 448 /* Fix player won't add the bows ability to the player, so don't
456 * print out message if this is a bow. 449 * print out message if this is a bow.
457 */ 450 */
458 if (tmp->attacktype & AT_CONFUSION && tmp->type != BOW) 451 if (tmp->attacktype & AT_CONFUSION && tmp->type != BOW)
671 * Stat draining by Vick 930307 664 * Stat draining by Vick 930307
672 * (Feeling evil, I made it work as well now. -Frank 8) 665 * (Feeling evil, I made it work as well now. -Frank 8)
673 */ 666 */
674 667
675void 668void
676drain_stat (object *op) 669object::drain_stat ()
677{ 670{
678 drain_specific_stat (op, RANDOM () % NUM_STATS); 671 drain_specific_stat (RANDOM () % NUM_STATS);
679} 672}
680 673
681void 674void
682drain_specific_stat (object *op, int deplete_stats) 675object::drain_specific_stat (int deplete_stats)
683{ 676{
684 object *tmp; 677 object *tmp;
685 archetype *at; 678 archetype *at;
686 679
687 at = archetype::find (ARCH_DEPLETION); 680 at = archetype::find (ARCH_DEPLETION);
690 LOG (llevError, "Couldn't find archetype depletion.\n"); 683 LOG (llevError, "Couldn't find archetype depletion.\n");
691 return; 684 return;
692 } 685 }
693 else 686 else
694 { 687 {
695 tmp = present_arch_in_ob (at, op); 688 tmp = present_arch_in_ob (at, this);
689
696 if (!tmp) 690 if (!tmp)
697 { 691 {
698 tmp = arch_to_object (at); 692 tmp = arch_to_object (at);
699 tmp = insert_ob_in_ob (tmp, op); 693 tmp = insert_ob_in_ob (tmp, this);
700 SET_FLAG (tmp, FLAG_APPLIED); 694 SET_FLAG (tmp, FLAG_APPLIED);
701 } 695 }
702 } 696 }
703 697
704 new_draw_info (NDI_UNIQUE, 0, op, drain_msg[deplete_stats]); 698 new_draw_info (NDI_UNIQUE, 0, this, drain_msg[deplete_stats]);
705 change_attr_value (&tmp->stats, deplete_stats, -1); 699 change_attr_value (&tmp->stats, deplete_stats, -1);
706 fix_player (op); 700 update_stats ();
707} 701}
708 702
709/* 703/*
710 * A value of 0 indicates timeout, otherwise change the luck of the object. 704 * A value of 0 indicates timeout, otherwise change the luck of the object.
711 * via an applied bad_luck object. 705 * via an applied bad_luck object.
712 */ 706 */
713
714void 707void
715change_luck (object *op, int value) 708object::change_luck (int value)
716{ 709{
717 object *tmp;
718 archetype *at;
719 int new_luck;
720
721 at = archetype::find ("luck"); 710 archetype *at = archetype::find ("luck");
722 if (!at) 711 if (!at)
723 LOG (llevError, "Couldn't find archetype luck.\n"); 712 LOG (llevError, "Couldn't find archetype luck.\n");
724 else 713 else
725 { 714 {
726 tmp = present_arch_in_ob (at, op); 715 object *tmp = present_arch_in_ob (at, this);
716
727 if (!tmp) 717 if (!tmp)
728 { 718 {
729 if (!value) 719 if (!value)
730 return; 720 return;
721
731 tmp = arch_to_object (at); 722 tmp = arch_to_object (at);
732 tmp = insert_ob_in_ob (tmp, op); 723 tmp = insert_ob_in_ob (tmp, this);
733 SET_FLAG (tmp, FLAG_APPLIED); 724 SET_FLAG (tmp, FLAG_APPLIED);
734 } 725 }
726
735 if (value) 727 if (value)
736 { 728 {
737 /* Limit the luck value of the bad luck object to +/-100. This 729 /* Limit the luck value of the bad luck object to +/-100. This
738 * (arbitrary) value prevents overflows (both in the bad luck object and 730 * (arbitrary) value prevents overflows (both in the bad luck object and
739 * in op itself). 731 * in op itself).
740 */ 732 */
741 new_luck = tmp->stats.luck + value; 733 int new_luck = tmp->stats.luck + value;
734
742 if (new_luck >= -100 && new_luck <= 100) 735 if (new_luck >= -100 && new_luck <= 100)
743 { 736 {
744 op->stats.luck += value; 737 stats.luck += value;
745 tmp->stats.luck = new_luck; 738 tmp->stats.luck = new_luck;
746 } 739 }
747 } 740 }
748 else 741 else
749 { 742 {
750 if (!tmp->stats.luck) 743 if (!tmp->stats.luck)
751 {
752 return; 744 return;
753 } 745
754 /* Randomly change the players luck. Basically, we move it 746 /* Randomly change the players luck. Basically, we move it
755 * back neutral (if greater>0, subtract, otherwise add) 747 * back neutral (if greater>0, subtract, otherwise add)
756 */ 748 */
757 if (RANDOM () % (FABS (tmp->stats.luck)) >= RANDOM () % 30) 749 if (RANDOM () % (FABS (tmp->stats.luck)) >= RANDOM () % 30)
758 { 750 {
759 int diff = tmp->stats.luck > 0 ? -1 : 1; 751 int diff = tmp->stats.luck > 0 ? -1 : 1;
760 752
761 op->stats.luck += diff; 753 stats.luck += diff;
762 tmp->stats.luck += diff; 754 tmp->stats.luck += diff;
763 } 755 }
764 } 756 }
765 } 757 }
766} 758}
767 759
768/* 760/*
769 * Subtracts stat-bonuses given by the class which the player has chosen. 761 * Subtracts stat-bonuses given by the class which the player has chosen.
770 */ 762 */
771
772void 763void
773remove_statbonus (object *op) 764object::remove_statbonus ()
774{ 765{
775 op->stats.Str -= op->arch->clone.stats.Str; 766 stats.Str -= arch->clone.stats.Str;
776 op->stats.Dex -= op->arch->clone.stats.Dex; 767 stats.Dex -= arch->clone.stats.Dex;
777 op->stats.Con -= op->arch->clone.stats.Con; 768 stats.Con -= arch->clone.stats.Con;
778 op->stats.Wis -= op->arch->clone.stats.Wis; 769 stats.Wis -= arch->clone.stats.Wis;
779 op->stats.Pow -= op->arch->clone.stats.Pow; 770 stats.Pow -= arch->clone.stats.Pow;
780 op->stats.Cha -= op->arch->clone.stats.Cha; 771 stats.Cha -= arch->clone.stats.Cha;
781 op->stats.Int -= op->arch->clone.stats.Int; 772 stats.Int -= arch->clone.stats.Int;
773
782 op->contr->orig_stats.Str -= op->arch->clone.stats.Str; 774 contr->orig_stats.Str -= arch->clone.stats.Str;
783 op->contr->orig_stats.Dex -= op->arch->clone.stats.Dex; 775 contr->orig_stats.Dex -= arch->clone.stats.Dex;
784 op->contr->orig_stats.Con -= op->arch->clone.stats.Con; 776 contr->orig_stats.Con -= arch->clone.stats.Con;
785 op->contr->orig_stats.Wis -= op->arch->clone.stats.Wis; 777 contr->orig_stats.Wis -= arch->clone.stats.Wis;
786 op->contr->orig_stats.Pow -= op->arch->clone.stats.Pow; 778 contr->orig_stats.Pow -= arch->clone.stats.Pow;
787 op->contr->orig_stats.Cha -= op->arch->clone.stats.Cha; 779 contr->orig_stats.Cha -= arch->clone.stats.Cha;
788 op->contr->orig_stats.Int -= op->arch->clone.stats.Int; 780 contr->orig_stats.Int -= arch->clone.stats.Int;
789} 781}
790 782
791/* 783/*
792 * Adds stat-bonuses given by the class which the player has chosen. 784 * Adds stat-bonuses given by the class which the player has chosen.
793 */ 785 */
794
795void 786void
796add_statbonus (object *op) 787object::add_statbonus ()
797{ 788{
798 op->stats.Str += op->arch->clone.stats.Str; 789 stats.Str += arch->clone.stats.Str;
799 op->stats.Dex += op->arch->clone.stats.Dex; 790 stats.Dex += arch->clone.stats.Dex;
800 op->stats.Con += op->arch->clone.stats.Con; 791 stats.Con += arch->clone.stats.Con;
801 op->stats.Wis += op->arch->clone.stats.Wis; 792 stats.Wis += arch->clone.stats.Wis;
802 op->stats.Pow += op->arch->clone.stats.Pow; 793 stats.Pow += arch->clone.stats.Pow;
803 op->stats.Cha += op->arch->clone.stats.Cha; 794 stats.Cha += arch->clone.stats.Cha;
804 op->stats.Int += op->arch->clone.stats.Int; 795 stats.Int += arch->clone.stats.Int;
796
805 op->contr->orig_stats.Str += op->arch->clone.stats.Str; 797 contr->orig_stats.Str += arch->clone.stats.Str;
806 op->contr->orig_stats.Dex += op->arch->clone.stats.Dex; 798 contr->orig_stats.Dex += arch->clone.stats.Dex;
807 op->contr->orig_stats.Con += op->arch->clone.stats.Con; 799 contr->orig_stats.Con += arch->clone.stats.Con;
808 op->contr->orig_stats.Wis += op->arch->clone.stats.Wis; 800 contr->orig_stats.Wis += arch->clone.stats.Wis;
809 op->contr->orig_stats.Pow += op->arch->clone.stats.Pow; 801 contr->orig_stats.Pow += arch->clone.stats.Pow;
810 op->contr->orig_stats.Cha += op->arch->clone.stats.Cha; 802 contr->orig_stats.Cha += arch->clone.stats.Cha;
811 op->contr->orig_stats.Int += op->arch->clone.stats.Int; 803 contr->orig_stats.Int += arch->clone.stats.Int;
812} 804}
813 805
814/* 806/*
815 * Updates all abilities given by applied objects in the inventory 807 * Updates all abilities given by applied objects in the inventory
816 * of the given object. Note: This function works for both monsters 808 * of the given object. Note: This function works for both monsters
822/* July 95 - inserted stuff to handle new skills/exp system - b.t. 814/* July 95 - inserted stuff to handle new skills/exp system - b.t.
823 spell system split, grace points now added to system --peterm 815 spell system split, grace points now added to system --peterm
824 */ 816 */
825 817
826void 818void
827fix_player (object *op) 819object::update_stats ()
828{ 820{
829 int i, j; 821 int i, j;
830 float f, max = 9, added_speed = 0, bonus_speed = 0, sp_tmp, speed_reduce_from_disease = 1; 822 float f, max = 9, added_speed = 0, bonus_speed = 0, sp_tmp, speed_reduce_from_disease = 1;
831 int weapon_weight = 0, weapon_speed = 0; 823 int weapon_weight = 0, weapon_speed = 0;
832 int best_wc = 0, best_ac = 0, wc = 0, ac = 0; 824 int best_wc = 0, best_ac = 0, wc = 0, ac = 0;
833 int prot[NROFATTACKS], vuln[NROFATTACKS], potion_resist[NROFATTACKS]; 825 int prot[NROFATTACKS], vuln[NROFATTACKS], potion_resist[NROFATTACKS];
834 object *grace_obj = NULL, *mana_obj = NULL, *wc_obj = NULL, *tmp; 826 object *grace_obj = NULL, *mana_obj = NULL, *wc_obj = NULL, *tmp;
835 827
836 /* First task is to clear all the values back to their original values */ 828 /* First task is to clear all the values back to their original values */
837 if (op->type == PLAYER) 829 if (type == PLAYER)
838 { 830 {
839 for (i = 0; i < NUM_STATS; i++) 831 for (i = 0; i < NUM_STATS; i++)
840 {
841 set_attr_value (&(op->stats), i, get_attr_value (&(op->contr->orig_stats), i)); 832 set_attr_value (&(stats), i, get_attr_value (&(contr->orig_stats), i));
842 } 833
843 if (settings.spell_encumbrance == TRUE) 834 if (settings.spell_encumbrance == TRUE)
844 op->contr->encumbrance = 0; 835 contr->encumbrance = 0;
845 836
846 op->attacktype = 0; 837 attacktype = 0;
847 op->contr->digestion = 0; 838 contr->digestion = 0;
848 op->contr->gen_hp = 0; 839 contr->gen_hp = 0;
849 op->contr->gen_sp = 0; 840 contr->gen_sp = 0;
850 op->contr->gen_grace = 0; 841 contr->gen_grace = 0;
851 op->contr->gen_sp_armour = 10; 842 contr->gen_sp_armour = 10;
852 op->contr->item_power = 0; 843 contr->item_power = 0;
853 844
854 /* Don't clobber all the range_ values. range_golem otherwise 845 /* Don't clobber all the range_ values. range_golem otherwise
855 * gets reset for no good reason, and we don't want to reset 846 * gets reset for no good reason, and we don't want to reset
856 * range_magic (what spell is readied). These three below 847 * range_magic (what spell is readied). These three below
857 * well get filled in based on what the player has equipped. 848 * well get filled in based on what the player has equipped.
858 */ 849 */
859 op->contr->ranges[range_bow] = NULL; 850 contr->ranges[range_bow] = NULL;
860 op->contr->ranges[range_misc] = NULL; 851 contr->ranges[range_misc] = NULL;
861 op->contr->ranges[range_skill] = NULL; 852 contr->ranges[range_skill] = NULL;
862 } 853 }
854
863 memcpy (op->body_used, op->body_info, sizeof (op->body_info)); 855 memcpy (body_used, body_info, sizeof (body_info));
864 856
865 op->slaying = 0; 857 slaying = 0;
866 858
867 if (!QUERY_FLAG (op, FLAG_WIZ)) 859 if (!QUERY_FLAG (this, FLAG_WIZ))
868 { 860 {
869 CLEAR_FLAG (op, FLAG_XRAYS); 861 CLEAR_FLAG (this, FLAG_XRAYS);
870 CLEAR_FLAG (op, FLAG_MAKE_INVIS); 862 CLEAR_FLAG (this, FLAG_MAKE_INVIS);
871 } 863 }
872 864
873 CLEAR_FLAG (op, FLAG_LIFESAVE); 865 CLEAR_FLAG (this, FLAG_LIFESAVE);
874 CLEAR_FLAG (op, FLAG_STEALTH); 866 CLEAR_FLAG (this, FLAG_STEALTH);
875 CLEAR_FLAG (op, FLAG_BLIND); 867 CLEAR_FLAG (this, FLAG_BLIND);
876 if (!QUERY_FLAG (&op->arch->clone, FLAG_REFL_SPELL))
877 CLEAR_FLAG (op, FLAG_REFL_SPELL);
878 if (!QUERY_FLAG (&op->arch->clone, FLAG_REFL_MISSILE))
879 CLEAR_FLAG (op, FLAG_REFL_MISSILE);
880 if (!QUERY_FLAG (&op->arch->clone, FLAG_UNDEAD))
881 CLEAR_FLAG (op, FLAG_UNDEAD);
882 if (!QUERY_FLAG (&op->arch->clone, FLAG_SEE_IN_DARK))
883 CLEAR_FLAG (op, FLAG_SEE_IN_DARK);
884 868
869 if (!QUERY_FLAG (&arch->clone, FLAG_REFL_SPELL )) CLEAR_FLAG (this, FLAG_REFL_SPELL);
870 if (!QUERY_FLAG (&arch->clone, FLAG_REFL_MISSILE)) CLEAR_FLAG (this, FLAG_REFL_MISSILE);
871 if (!QUERY_FLAG (&arch->clone, FLAG_UNDEAD )) CLEAR_FLAG (this, FLAG_UNDEAD);
872 if (!QUERY_FLAG (&arch->clone, FLAG_SEE_IN_DARK )) CLEAR_FLAG (this, FLAG_SEE_IN_DARK);
873
885 op->path_attuned = op->arch->clone.path_attuned; 874 path_attuned = arch->clone.path_attuned;
886 op->path_repelled = op->arch->clone.path_repelled; 875 path_repelled = arch->clone.path_repelled;
887 op->path_denied = op->arch->clone.path_denied; 876 path_denied = arch->clone.path_denied;
888 op->glow_radius = op->arch->clone.glow_radius; 877 glow_radius = arch->clone.glow_radius;
889 op->move_type = op->arch->clone.move_type; 878 move_type = arch->clone.move_type;
890 op->chosen_skill = NULL; 879 chosen_skill = NULL;
891 880
892 /* initializing resistances from the values in player/monster's 881 /* initializing resistances from the values in player/monster's
893 * archetype clone 882 * archetype clone
894 */ 883 */
895 memcpy (&op->resist, &op->arch->clone.resist, sizeof (op->resist)); 884 memcpy (&resist, &arch->clone.resist, sizeof (resist));
896 885
897 for (i = 0; i < NROFATTACKS; i++) 886 for (i = 0; i < NROFATTACKS; i++)
898 { 887 {
899 if (op->resist[i] > 0) 888 if (resist[i] > 0)
900 prot[i] = op->resist[i], vuln[i] = 0; 889 prot[i] = resist[i], vuln[i] = 0;
901 else 890 else
902 vuln[i] = -(op->resist[i]), prot[i] = 0; 891 vuln[i] = -(resist[i]), prot[i] = 0;
903 potion_resist[i] = 0; 892 potion_resist[i] = 0;
904 } 893 }
905 894
906 wc = op->arch->clone.stats.wc; 895 wc = arch->clone.stats.wc;
907 op->stats.dam = op->arch->clone.stats.dam; 896 stats.dam = arch->clone.stats.dam;
908 897
909 /* for players which cannot use armour, they gain AC -1 per 3 levels, 898 /* for players which cannot use armour, they gain AC -1 per 3 levels,
910 * plus a small amount of physical resist, those poor suckers. ;) 899 * plus a small amount of physical resist, those poor suckers. ;)
911 * the fact that maxlevel is factored in could be considered sort of bogus - 900 * the fact that maxlevel is factored in could be considered sort of bogus -
912 * we should probably give them some bonus and cap it off - otherwise, 901 * we should probably give them some bonus and cap it off - otherwise,
913 * basically, if a server updates its max level, these playes may find 902 * basically, if a server updates its max level, these playes may find
914 * that their protection from physical goes down 903 * that their protection from physical goes down
915 */ 904 */
916 if (!QUERY_FLAG (op, FLAG_USE_ARMOUR) && op->type == PLAYER) 905 if (!QUERY_FLAG (this, FLAG_USE_ARMOUR) && type == PLAYER)
917 { 906 {
918 ac = MAX (-10, op->arch->clone.stats.ac - op->level / 3); 907 ac = MAX (-10, arch->clone.stats.ac - level / 3);
919 prot[ATNR_PHYSICAL] += ((100 - prot[AT_PHYSICAL]) * (80 * op->level / settings.max_level)) / 100; 908 prot[ATNR_PHYSICAL] += ((100 - prot[AT_PHYSICAL]) * (80 * level / settings.max_level)) / 100;
920 } 909 }
921 else 910 else
922 ac = op->arch->clone.stats.ac; 911 ac = arch->clone.stats.ac;
923 912
924 op->stats.luck = op->arch->clone.stats.luck; 913 stats.luck = arch->clone.stats.luck;
925 op->speed = op->arch->clone.speed; 914 speed = arch->clone.speed;
926 915
927 /* OK - we've reset most all the objects attributes to sane values. 916 /* OK - we've reset most all the objects attributes to sane values.
928 * now go through and make adjustments for what the player has equipped. 917 * now go through and make adjustments for what the player has equipped.
929 */ 918 */
930 919
931 for (tmp = op->inv; tmp != NULL; tmp = tmp->below) 920 for (tmp = inv; tmp; tmp = tmp->below)
932 { 921 {
933 /* See note in map.c:update_position about making this additive 922 /* See note in map.c:update_position about making this additive
934 * since light sources are never applied, need to put check here. 923 * since light sources are never applied, need to put check here.
935 */ 924 */
936 if (tmp->glow_radius > op->glow_radius) 925 if (tmp->glow_radius > glow_radius)
937 op->glow_radius = tmp->glow_radius; 926 glow_radius = tmp->glow_radius;
938 927
939 /* This happens because apply_potion calls change_abil with the potion 928 /* This happens because apply_potion calls change_abil with the potion
940 * applied so we can tell the player what chagned. But change_abil 929 * applied so we can tell the player what chagned. But change_abil
941 * then calls this function. 930 * then calls this function.
942 */ 931 */
943 if (QUERY_FLAG (tmp, FLAG_APPLIED) && tmp->type == POTION) 932 if (QUERY_FLAG (tmp, FLAG_APPLIED) && tmp->type == POTION)
944 {
945 continue; 933 continue;
946 }
947 934
948 /* For some things, we don't care what is equipped */ 935 /* For some things, we don't care what is equipped */
949 if (tmp->type == SKILL) 936 if (tmp->type == SKILL)
950 { 937 {
951 /* Want to take the highest skill here. */ 938 /* Want to take the highest skill here. */
954 if (!mana_obj) 941 if (!mana_obj)
955 mana_obj = tmp; 942 mana_obj = tmp;
956 else if (tmp->level > mana_obj->level) 943 else if (tmp->level > mana_obj->level)
957 mana_obj = tmp; 944 mana_obj = tmp;
958 } 945 }
946
959 if (IS_GRACE_SKILL (tmp->subtype)) 947 if (IS_GRACE_SKILL (tmp->subtype))
960 { 948 {
961 if (!grace_obj) 949 if (!grace_obj)
962 grace_obj = tmp; 950 grace_obj = tmp;
963 else if (tmp->level > grace_obj->level) 951 else if (tmp->level > grace_obj->level)
975 * up, etc. 963 * up, etc.
976 */ 964 */
977 if ((QUERY_FLAG (tmp, FLAG_APPLIED) && tmp->type != CONTAINER && tmp->type != CLOSE_CON) || 965 if ((QUERY_FLAG (tmp, FLAG_APPLIED) && tmp->type != CONTAINER && tmp->type != CLOSE_CON) ||
978 (tmp->type == SKILL && tmp->subtype == SK_PRAYING)) 966 (tmp->type == SKILL && tmp->subtype == SK_PRAYING))
979 { 967 {
980 if (op->type == PLAYER) 968 if (type == PLAYER)
981 { 969 {
982 if (tmp->type == BOW) 970 if (tmp->type == BOW)
983 op->contr->ranges[range_bow] = tmp; 971 contr->ranges[range_bow] = tmp;
984 972
985 if (tmp->type == WAND || tmp->type == ROD || tmp->type == HORN) 973 if (tmp->type == WAND || tmp->type == ROD || tmp->type == HORN)
986 op->contr->ranges[range_misc] = tmp; 974 contr->ranges[range_misc] = tmp;
987 975
988 for (i = 0; i < NUM_STATS; i++) 976 for (i = 0; i < NUM_STATS; i++)
989 change_attr_value (&(op->stats), i, get_attr_value (&(tmp->stats), i)); 977 change_attr_value (&(stats), i, get_attr_value (&(tmp->stats), i));
990 978
991 /* these are the items that currently can change digestion, regeneration, 979 /* these are the items that currently can change digestion, regeneration,
992 * spell point recovery and mana point recovery. Seems sort of an arbitary 980 * spell point recovery and mana point recovery. Seems sort of an arbitary
993 * list, but other items store other info into stats array. 981 * list, but other items store other info into stats array.
994 */ 982 */
999 (tmp->type == AMULET) || (tmp->type == GIRDLE) || 987 (tmp->type == AMULET) || (tmp->type == GIRDLE) ||
1000 (tmp->type == BRACERS) || (tmp->type == CLOAK) || 988 (tmp->type == BRACERS) || (tmp->type == CLOAK) ||
1001 (tmp->type == DISEASE) || (tmp->type == FORCE) || 989 (tmp->type == DISEASE) || (tmp->type == FORCE) ||
1002 (tmp->type == SKILL)) 990 (tmp->type == SKILL))
1003 { 991 {
1004 op->contr->digestion += tmp->stats.food; 992 contr->digestion += tmp->stats.food;
1005 op->contr->gen_hp += tmp->stats.hp; 993 contr->gen_hp += tmp->stats.hp;
1006 op->contr->gen_sp += tmp->stats.sp; 994 contr->gen_sp += tmp->stats.sp;
1007 op->contr->gen_grace += tmp->stats.grace; 995 contr->gen_grace += tmp->stats.grace;
1008 op->contr->gen_sp_armour += tmp->gen_sp_armour; 996 contr->gen_sp_armour += tmp->gen_sp_armour;
1009 op->contr->item_power += tmp->item_power; 997 contr->item_power += tmp->item_power;
1010 } 998 }
1011 } /* if this is a player */ 999 } /* if this is a player */
1012 1000
1013 /* Update slots used for items */ 1001 /* Update slots used for items */
1014 if (QUERY_FLAG (tmp, FLAG_APPLIED)) 1002 if (QUERY_FLAG (tmp, FLAG_APPLIED))
1015 {
1016 for (i = 0; i < NUM_BODY_LOCATIONS; i++) 1003 for (i = 0; i < NUM_BODY_LOCATIONS; i++)
1017 op->body_used[i] += tmp->body_info[i]; 1004 body_used[i] += tmp->body_info[i];
1018 }
1019 1005
1020 if (tmp->type == SYMPTOM) 1006 if (tmp->type == SYMPTOM)
1021 { 1007 {
1022 speed_reduce_from_disease = tmp->last_sp / 100.0; 1008 speed_reduce_from_disease = tmp->last_sp / 100.0;
1023 if (speed_reduce_from_disease == 0) 1009 if (speed_reduce_from_disease == 0)
1050 } 1036 }
1051 } 1037 }
1052 1038
1053 /* There may be other things that should not adjust the attacktype */ 1039 /* There may be other things that should not adjust the attacktype */
1054 if (tmp->type != BOW && tmp->type != SYMPTOM) 1040 if (tmp->type != BOW && tmp->type != SYMPTOM)
1055 op->attacktype |= tmp->attacktype; 1041 attacktype |= tmp->attacktype;
1056 1042
1057 op->path_attuned |= tmp->path_attuned; 1043 path_attuned |= tmp->path_attuned;
1058 op->path_repelled |= tmp->path_repelled; 1044 path_repelled |= tmp->path_repelled;
1059 op->path_denied |= tmp->path_denied; 1045 path_denied |= tmp->path_denied;
1060 op->stats.luck += tmp->stats.luck; 1046 stats.luck += tmp->stats.luck;
1061 op->move_type |= tmp->move_type; 1047 move_type |= tmp->move_type;
1062 1048
1063 if (QUERY_FLAG (tmp, FLAG_LIFESAVE)) 1049 if (QUERY_FLAG (tmp, FLAG_LIFESAVE )) SET_FLAG (this, FLAG_LIFESAVE);
1064 SET_FLAG (op, FLAG_LIFESAVE); 1050 if (QUERY_FLAG (tmp, FLAG_REFL_SPELL )) SET_FLAG (this, FLAG_REFL_SPELL);
1065 if (QUERY_FLAG (tmp, FLAG_REFL_SPELL)) 1051 if (QUERY_FLAG (tmp, FLAG_REFL_MISSILE)) SET_FLAG (this, FLAG_REFL_MISSILE);
1066 SET_FLAG (op, FLAG_REFL_SPELL); 1052 if (QUERY_FLAG (tmp, FLAG_STEALTH )) SET_FLAG (this, FLAG_STEALTH);
1067 if (QUERY_FLAG (tmp, FLAG_REFL_MISSILE)) 1053 if (QUERY_FLAG (tmp, FLAG_XRAYS )) SET_FLAG (this, FLAG_XRAYS);
1068 SET_FLAG (op, FLAG_REFL_MISSILE); 1054 if (QUERY_FLAG (tmp, FLAG_BLIND )) SET_FLAG (this, FLAG_BLIND);
1069 if (QUERY_FLAG (tmp, FLAG_STEALTH)) 1055 if (QUERY_FLAG (tmp, FLAG_SEE_IN_DARK )) SET_FLAG (this, FLAG_SEE_IN_DARK);
1070 SET_FLAG (op, FLAG_STEALTH);
1071 if (QUERY_FLAG (tmp, FLAG_XRAYS))
1072 SET_FLAG (op, FLAG_XRAYS);
1073 if (QUERY_FLAG (tmp, FLAG_BLIND))
1074 SET_FLAG (op, FLAG_BLIND);
1075 if (QUERY_FLAG (tmp, FLAG_SEE_IN_DARK))
1076 SET_FLAG (op, FLAG_SEE_IN_DARK);
1077 1056
1078 if (QUERY_FLAG (tmp, FLAG_UNDEAD) && !QUERY_FLAG (&op->arch->clone, FLAG_UNDEAD)) 1057 if (QUERY_FLAG (tmp, FLAG_UNDEAD) && !QUERY_FLAG (&arch->clone, FLAG_UNDEAD))
1079 SET_FLAG (op, FLAG_UNDEAD); 1058 SET_FLAG (this, FLAG_UNDEAD);
1080 1059
1081 if (QUERY_FLAG (tmp, FLAG_MAKE_INVIS)) 1060 if (QUERY_FLAG (tmp, FLAG_MAKE_INVIS))
1082 { 1061 {
1083 SET_FLAG (op, FLAG_MAKE_INVIS); 1062 SET_FLAG (this, FLAG_MAKE_INVIS);
1084 op->invisible = 1; 1063 invisible = 1;
1085 } 1064 }
1086 1065
1087 if (tmp->stats.exp && tmp->type != SKILL) 1066 if (tmp->stats.exp && tmp->type != SKILL)
1088 { 1067 {
1089 if (tmp->stats.exp > 0) 1068 if (tmp->stats.exp > 0)
1104 break; 1083 break;
1105 1084
1106 if (IS_COMBAT_SKILL (tmp->subtype)) 1085 if (IS_COMBAT_SKILL (tmp->subtype))
1107 wc_obj = tmp; 1086 wc_obj = tmp;
1108 1087
1109 if (op->chosen_skill) 1088 if (chosen_skill)
1110 LOG (llevDebug, "fix_player, op %s has multiple skills applied\n", &op->name); 1089 LOG (llevDebug, "fix_player, op %s has multiple skills applied\n", &name);
1111 1090
1112 op->chosen_skill = tmp; 1091 chosen_skill = tmp;
1113 1092
1114 if (tmp->stats.dam > 0) 1093 if (tmp->stats.dam > 0)
1115 { /* skill is a 'weapon' */ 1094 { /* skill is a 'weapon' */
1116 if (!QUERY_FLAG (op, FLAG_READY_WEAPON)) 1095 if (!QUERY_FLAG (this, FLAG_READY_WEAPON))
1117 weapon_speed = (int) WEAPON_SPEED (tmp); 1096 weapon_speed = (int) WEAPON_SPEED (tmp);
1097
1118 if (weapon_speed < 0) 1098 if (weapon_speed < 0)
1119 weapon_speed = 0; 1099 weapon_speed = 0;
1100
1120 weapon_weight = tmp->weight; 1101 weapon_weight = tmp->weight;
1121 op->stats.dam += tmp->stats.dam * (1 + (op->chosen_skill->level / 9)); 1102 stats.dam += tmp->stats.dam * (1 + (chosen_skill->level / 9));
1103
1122 if (tmp->magic) 1104 if (tmp->magic)
1123 op->stats.dam += tmp->magic; 1105 stats.dam += tmp->magic;
1124 } 1106 }
1125 1107
1126 if (tmp->stats.wc) 1108 if (tmp->stats.wc)
1127 wc -= (tmp->stats.wc + tmp->magic); 1109 wc -= (tmp->stats.wc + tmp->magic);
1128 1110
1129 if (tmp->slaying != NULL) 1111 if (tmp->slaying != NULL)
1130 op->slaying = tmp->slaying; 1112 slaying = tmp->slaying;
1131 1113
1132 if (tmp->stats.ac) 1114 if (tmp->stats.ac)
1133 ac -= (tmp->stats.ac + tmp->magic); 1115 ac -= (tmp->stats.ac + tmp->magic);
1116
1134 if (settings.spell_encumbrance == TRUE && op->type == PLAYER) 1117 if (settings.spell_encumbrance == TRUE && type == PLAYER)
1135 op->contr->encumbrance += (int) 3 *tmp->weight / 1000; 1118 contr->encumbrance += (int) 3 *tmp->weight / 1000;
1136 1119
1137 if (op->type == PLAYER) 1120 if (type == PLAYER)
1138 op->contr->ranges[range_skill] = op; 1121 contr->ranges[range_skill] = this;
1122
1139 break; 1123 break;
1140 1124
1141 case SKILL_TOOL: 1125 case SKILL_TOOL:
1142 if (op->chosen_skill) 1126 if (chosen_skill)
1143 {
1144 LOG (llevDebug, "fix_player, op %s has multiple skills applied\n", &op->name); 1127 LOG (llevDebug, "fix_player, op %s has multiple skills applied\n", &name);
1145 } 1128
1146 op->chosen_skill = tmp; 1129 chosen_skill = tmp;
1130
1147 if (op->type == PLAYER) 1131 if (type == PLAYER)
1148 op->contr->ranges[range_skill] = op; 1132 contr->ranges[range_skill] = this;
1149 break; 1133 break;
1150 1134
1151 case SHIELD: 1135 case SHIELD:
1152 if (settings.spell_encumbrance == TRUE && op->type == PLAYER) 1136 if (settings.spell_encumbrance == TRUE && type == PLAYER)
1153 op->contr->encumbrance += (int) tmp->weight / 2000; 1137 contr->encumbrance += (int) tmp->weight / 2000;
1154 case RING: 1138 case RING:
1155 case AMULET: 1139 case AMULET:
1156 case GIRDLE: 1140 case GIRDLE:
1157 case HELMET: 1141 case HELMET:
1158 case BOOTS: 1142 case BOOTS:
1159 case GLOVES: 1143 case GLOVES:
1160 case CLOAK: 1144 case CLOAK:
1161 if (tmp->stats.wc) 1145 if (tmp->stats.wc)
1162 wc -= (tmp->stats.wc + tmp->magic); 1146 wc -= (tmp->stats.wc + tmp->magic);
1147
1163 if (tmp->stats.dam) 1148 if (tmp->stats.dam)
1164 op->stats.dam += (tmp->stats.dam + tmp->magic); 1149 stats.dam += (tmp->stats.dam + tmp->magic);
1150
1165 if (tmp->stats.ac) 1151 if (tmp->stats.ac)
1166 ac -= (tmp->stats.ac + tmp->magic); 1152 ac -= (tmp->stats.ac + tmp->magic);
1153
1167 break; 1154 break;
1168 1155
1169 case WEAPON: 1156 case WEAPON:
1170 wc -= (tmp->stats.wc + tmp->magic); 1157 wc -= (tmp->stats.wc + tmp->magic);
1158
1171 if (tmp->stats.ac && tmp->stats.ac + tmp->magic > 0) 1159 if (tmp->stats.ac && tmp->stats.ac + tmp->magic > 0)
1172 ac -= tmp->stats.ac + tmp->magic; 1160 ac -= tmp->stats.ac + tmp->magic;
1161
1173 op->stats.dam += (tmp->stats.dam + tmp->magic); 1162 stats.dam += (tmp->stats.dam + tmp->magic);
1174 weapon_weight = tmp->weight; 1163 weapon_weight = tmp->weight;
1175 weapon_speed = ((int) WEAPON_SPEED (tmp) * 2 - tmp->magic) / 2; 1164 weapon_speed = ((int) WEAPON_SPEED (tmp) * 2 - tmp->magic) / 2;
1165
1176 if (weapon_speed < 0) 1166 if (weapon_speed < 0)
1177 weapon_speed = 0; 1167 weapon_speed = 0;
1168
1178 op->slaying = tmp->slaying; 1169 slaying = tmp->slaying;
1179 /* If there is desire that two handed weapons should do 1170 /* If there is desire that two handed weapons should do
1180 * extra strength damage, this is where the code should 1171 * extra strength damage, this is where the code should
1181 * go. 1172 * go.
1182 */ 1173 */
1183 op->current_weapon = tmp; 1174 current_weapon = tmp;
1184 if (settings.spell_encumbrance == TRUE && op->type == PLAYER) 1175 if (settings.spell_encumbrance == TRUE && type == PLAYER)
1185 op->contr->encumbrance += (int) 3 *tmp->weight / 1000; 1176 contr->encumbrance += (int) 3 *tmp->weight / 1000;
1186 1177
1187 break; 1178 break;
1188 1179
1189 case ARMOUR: /* Only the best of these three are used: */ 1180 case ARMOUR: /* Only the best of these three are used: */
1190 if (settings.spell_encumbrance == TRUE && op->type == PLAYER) 1181 if (settings.spell_encumbrance == TRUE && type == PLAYER)
1191 op->contr->encumbrance += (int) tmp->weight / 1000; 1182 contr->encumbrance += (int) tmp->weight / 1000;
1192 1183
1193 case BRACERS: 1184 case BRACERS:
1194 case FORCE: 1185 case FORCE:
1195 if (tmp->stats.wc) 1186 if (tmp->stats.wc)
1196 { 1187 {
1200 best_wc = tmp->stats.wc + tmp->magic; 1191 best_wc = tmp->stats.wc + tmp->magic;
1201 } 1192 }
1202 else 1193 else
1203 wc += tmp->stats.wc + tmp->magic; 1194 wc += tmp->stats.wc + tmp->magic;
1204 } 1195 }
1196
1205 if (tmp->stats.ac) 1197 if (tmp->stats.ac)
1206 { 1198 {
1207 if (best_ac < tmp->stats.ac + tmp->magic) 1199 if (best_ac < tmp->stats.ac + tmp->magic)
1208 { 1200 {
1209 ac += best_ac; /* Remove last bonus */ 1201 ac += best_ac; /* Remove last bonus */
1210 best_ac = tmp->stats.ac + tmp->magic; 1202 best_ac = tmp->stats.ac + tmp->magic;
1211 } 1203 }
1212 else /* To nullify the below effect */ 1204 else /* To nullify the below effect */
1213 ac += tmp->stats.ac + tmp->magic; 1205 ac += tmp->stats.ac + tmp->magic;
1214 } 1206 }
1207
1215 if (tmp->stats.wc) 1208 if (tmp->stats.wc)
1216 wc -= (tmp->stats.wc + tmp->magic); 1209 wc -= (tmp->stats.wc + tmp->magic);
1210
1217 if (tmp->stats.ac) 1211 if (tmp->stats.ac)
1218 ac -= (tmp->stats.ac + tmp->magic); 1212 ac -= (tmp->stats.ac + tmp->magic);
1213
1219 if (ARMOUR_SPEED (tmp) && ARMOUR_SPEED (tmp) / 10.0 < max) 1214 if (ARMOUR_SPEED (tmp) && ARMOUR_SPEED (tmp) / 10.0 < max)
1220 max = ARMOUR_SPEED (tmp) / 10.0; 1215 max = ARMOUR_SPEED (tmp) / 10.0;
1216
1221 break; 1217 break;
1222 } /* switch tmp->type */ 1218 } /* switch tmp->type */
1223 } /* item is equipped */ 1219 } /* item is equipped */
1224 } /* for loop of items */ 1220 } /* for loop of items */
1225 1221
1233 * If there is a cursed (and no uncursed) potion in effect, we take 1229 * If there is a cursed (and no uncursed) potion in effect, we take
1234 * 'total resistance = vulnerability from cursed potion'. 1230 * 'total resistance = vulnerability from cursed potion'.
1235 */ 1231 */
1236 for (i = 0; i < NROFATTACKS; i++) 1232 for (i = 0; i < NROFATTACKS; i++)
1237 { 1233 {
1238 op->resist[i] = prot[i] - vuln[i]; 1234 resist[i] = prot[i] - vuln[i];
1235
1239 if (potion_resist[i] && ((potion_resist[i] > op->resist[i]) || (potion_resist[i] < 0))) 1236 if (potion_resist[i] && ((potion_resist[i] > resist[i]) || (potion_resist[i] < 0)))
1240 op->resist[i] = potion_resist[i]; 1237 resist[i] = potion_resist[i];
1241 } 1238 }
1242 1239
1243 /* Figure out the players sp/mana/hp totals. */ 1240 /* Figure out the players sp/mana/hp totals. */
1244 if (op->type == PLAYER) 1241 if (type == PLAYER)
1245 { 1242 {
1246 int pl_level; 1243 int pl_level;
1247 1244
1248 check_stat_bounds (&(op->stats)); 1245 check_stat_bounds (&(stats));
1249 pl_level = op->level; 1246 pl_level = level;
1250 1247
1251 if (pl_level < 1) 1248 if (pl_level < 1)
1252 pl_level = 1; /* safety, we should always get 1 levels worth of hp! */ 1249 pl_level = 1; /* safety, we should always get 1 levels worth of hp! */
1253 1250
1254 /* You basically get half a con bonus/level. But we do take into account rounding, 1251 /* You basically get half a con bonus/level. But we do take into account rounding,
1255 * so if your bonus is 7, you still get 7 worth of bonus every 2 levels. 1252 * so if your bonus is 7, you still get 7 worth of bonus every 2 levels.
1256 */ 1253 */
1257 for (i = 1, op->stats.maxhp = 0; i <= pl_level && i <= 10; i++) 1254 for (i = 1, stats.maxhp = 0; i <= pl_level && i <= 10; i++)
1258 { 1255 {
1259 j = op->contr->levhp[i] + con_bonus[op->stats.Con] / 2; 1256 j = contr->levhp[i] + con_bonus[stats.Con] / 2;
1257
1260 if (i % 2 && con_bonus[op->stats.Con] % 2) 1258 if (i % 2 && con_bonus[stats.Con] % 2)
1261 { 1259 {
1262 if (con_bonus[op->stats.Con] > 0) 1260 if (con_bonus[stats.Con] > 0)
1263 j++; 1261 j++;
1264 else 1262 else
1265 j--; 1263 j--;
1266 } 1264 }
1265
1267 op->stats.maxhp += j > 1 ? j : 1; /* always get at least 1 hp/level */ 1266 stats.maxhp += j > 1 ? j : 1; /* always get at least 1 hp/level */
1268 } 1267 }
1269 1268
1270 for (i = 11; i <= op->level; i++) 1269 for (i = 11; i <= level; i++)
1271 op->stats.maxhp += 2; 1270 stats.maxhp += 2;
1272 1271
1273 if (op->stats.hp > op->stats.maxhp) 1272 if (stats.hp > stats.maxhp)
1274 op->stats.hp = op->stats.maxhp; 1273 stats.hp = stats.maxhp;
1275 1274
1276 /* Sp gain is controlled by the level of the player's 1275 /* Sp gain is controlled by the level of the player's
1277 * relevant experience object (mana_obj, see above) 1276 * relevant experience object (mana_obj, see above)
1278 */ 1277 */
1279 /* following happen when skills system is not used */ 1278 /* following happen when skills system is not used */
1280 if (!mana_obj) 1279 if (!mana_obj)
1281 mana_obj = op; 1280 mana_obj = this;
1281
1282 if (!grace_obj) 1282 if (!grace_obj)
1283 grace_obj = op; 1283 grace_obj = this;
1284
1284 /* set maxsp */ 1285 /* set maxsp */
1285 if (!mana_obj || !mana_obj->level || op->type != PLAYER) 1286 if (!mana_obj || !mana_obj->level || type != PLAYER)
1286 mana_obj = op; 1287 mana_obj = this;
1287 1288
1288 if (mana_obj == op && op->type == PLAYER) 1289 if (mana_obj == this && type == PLAYER)
1289 {
1290 op->stats.maxsp = 1; 1290 stats.maxsp = 1;
1291 }
1292 else 1291 else
1293 { 1292 {
1294 sp_tmp = 0.0; 1293 sp_tmp = 0.0;
1294
1295 for (i = 1; i <= mana_obj->level && i <= 10; i++) 1295 for (i = 1; i <= mana_obj->level && i <= 10; i++)
1296 { 1296 {
1297 float stmp; 1297 float stmp;
1298 1298
1299 /* Got some extra bonus at first level */ 1299 /* Got some extra bonus at first level */
1300 if (i < 2) 1300 if (i < 2)
1301 {
1302 stmp = op->contr->levsp[i] + ((2.0 * (float) sp_bonus[op->stats.Pow] + (float) sp_bonus[op->stats.Int]) / 6.0); 1301 stmp = contr->levsp[i] + ((2.0 * (float) sp_bonus[stats.Pow] + (float) sp_bonus[stats.Int]) / 6.0);
1303 }
1304 else 1302 else
1305 {
1306 stmp = (float) op->contr->levsp[i] + (2.0 * (float) sp_bonus[op->stats.Pow] + (float) sp_bonus[op->stats.Int]) / 12.0; 1303 stmp = (float) contr->levsp[i] + (2.0 * (float) sp_bonus[stats.Pow] + (float) sp_bonus[stats.Int]) / 12.0;
1307 } 1304
1308 if (stmp < 1.0) 1305 if (stmp < 1.0)
1309 stmp = 1.0; 1306 stmp = 1.0;
1307
1310 sp_tmp += stmp; 1308 sp_tmp += stmp;
1311 } 1309 }
1310
1312 op->stats.maxsp = (int) sp_tmp; 1311 stats.maxsp = (int) sp_tmp;
1313 1312
1314 for (i = 11; i <= mana_obj->level; i++) 1313 for (i = 11; i <= mana_obj->level; i++)
1315 op->stats.maxsp += 2; 1314 stats.maxsp += 2;
1316 } 1315 }
1317 /* Characters can get their sp supercharged via rune of transferrance */ 1316 /* Characters can get their sp supercharged via rune of transferrance */
1318 if (op->stats.sp > op->stats.maxsp * 2) 1317 if (stats.sp > stats.maxsp * 2)
1319 op->stats.sp = op->stats.maxsp * 2; 1318 stats.sp = stats.maxsp * 2;
1320 1319
1321 /* set maxgrace, notice 3-4 lines below it depends on both Wis and Pow */ 1320 /* set maxgrace, notice 3-4 lines below it depends on both Wis and Pow */
1322 if (!grace_obj || !grace_obj->level || op->type != PLAYER) 1321 if (!grace_obj || !grace_obj->level || type != PLAYER)
1323 grace_obj = op; 1322 grace_obj = this;
1324 1323
1325 if (grace_obj == op && op->type == PLAYER) 1324 if (grace_obj == this && type == PLAYER)
1326 {
1327 op->stats.maxgrace = 1; 1325 stats.maxgrace = 1;
1328 }
1329 else 1326 else
1330 { 1327 {
1331 /* store grace in a float - this way, the divisions below don't create 1328 /* store grace in a float - this way, the divisions below don't create
1332 * big jumps when you go from level to level - with int's, it then 1329 * big jumps when you go from level to level - with int's, it then
1333 * becomes big jumps when the sums of the bonuses jump to the next 1330 * becomes big jumps when the sums of the bonuses jump to the next
1334 * step of 8 - with floats, even fractional ones are useful. 1331 * step of 8 - with floats, even fractional ones are useful.
1335 */ 1332 */
1336 sp_tmp = 0.0; 1333 sp_tmp = 0.0;
1337 for (i = 1, op->stats.maxgrace = 0; i <= grace_obj->level && i <= 10; i++) 1334 for (i = 1, stats.maxgrace = 0; i <= grace_obj->level && i <= 10; i++)
1338 { 1335 {
1339 float grace_tmp = 0.0; 1336 float grace_tmp = 0.0;
1340 1337
1341 /* Got some extra bonus at first level */ 1338 /* Got some extra bonus at first level */
1342 if (i < 2) 1339 if (i < 2)
1343 {
1344 grace_tmp = op->contr->levgrace[i] + (((float) grace_bonus[op->stats.Pow] + 1340 grace_tmp = contr->levgrace[i] + (((float) grace_bonus[stats.Pow] +
1345 2.0 * (float) grace_bonus[op->stats.Wis]) / 6.0); 1341 2.0 * (float) grace_bonus[stats.Wis]) / 6.0);
1346 }
1347 else 1342 else
1348 {
1349 grace_tmp = (float) op->contr->levgrace[i] 1343 grace_tmp = (float) contr->levgrace[i]
1350 + ((float) grace_bonus[op->stats.Pow] + 2.0 * (float) grace_bonus[op->stats.Wis]) / 12.0; 1344 + ((float) grace_bonus[stats.Pow] + 2.0 * (float) grace_bonus[stats.Wis]) / 12.0;
1351 } 1345
1352 if (grace_tmp < 1.0) 1346 if (grace_tmp < 1.0)
1353 grace_tmp = 1.0; 1347 grace_tmp = 1.0;
1348
1354 sp_tmp += grace_tmp; 1349 sp_tmp += grace_tmp;
1355 } 1350 }
1351
1356 op->stats.maxgrace = (int) sp_tmp; 1352 stats.maxgrace = (int) sp_tmp;
1357 1353
1358 /* two grace points per level after 11 */ 1354 /* two grace points per level after 11 */
1359 for (i = 11; i <= grace_obj->level; i++) 1355 for (i = 11; i <= grace_obj->level; i++)
1360 op->stats.maxgrace += 2; 1356 stats.maxgrace += 2;
1361 } 1357 }
1362 /* No limit on grace vs maxgrace */ 1358 /* No limit on grace vs maxgrace */
1363 1359
1364 if (op->contr->braced) 1360 if (contr->braced)
1365 { 1361 {
1366 ac += 2; 1362 ac += 2;
1367 wc += 4; 1363 wc += 4;
1368 } 1364 }
1369 else 1365 else
1370 ac -= dex_bonus[op->stats.Dex]; 1366 ac -= dex_bonus[stats.Dex];
1371 1367
1372 /* In new exp/skills system, wc bonuses are related to 1368 /* In new exp/skills system, wc bonuses are related to
1373 * the players level in a relevant exp object (wc_obj) 1369 * the players level in a relevant exp object (wc_obj)
1374 * not the general player level -b.t. 1370 * not the general player level -b.t.
1375 * I changed this slightly so that wc bonuses are better 1371 * I changed this slightly so that wc bonuses are better
1379 * we give the player a bonus here in wc and dam 1375 * we give the player a bonus here in wc and dam
1380 * to make up for the change. Note that I left the 1376 * to make up for the change. Note that I left the
1381 * monster bonus the same as before. -b.t. 1377 * monster bonus the same as before. -b.t.
1382 */ 1378 */
1383 1379
1384 if (op->type == PLAYER && wc_obj && wc_obj->level > 1) 1380 if (type == PLAYER && wc_obj && wc_obj->level > 1)
1385 { 1381 {
1386 wc -= (wc_obj->level + thaco_bonus[op->stats.Str]); 1382 wc -= (wc_obj->level + thaco_bonus[stats.Str]);
1387 for (i = 1; i < wc_obj->level; i++) 1383 for (i = 1; i < wc_obj->level; i++)
1388 { 1384 {
1389 /* addtional wc every 6 levels */ 1385 /* addtional wc every 6 levels */
1390 if (!(i % 6)) 1386 if (!(i % 6))
1391 wc--; 1387 wc--;
1392 /* addtional dam every 4 levels. */ 1388 /* addtional dam every 4 levels. */
1393 if (!(i % 4) && (dam_bonus[op->stats.Str] >= 0)) 1389 if (!(i % 4) && (dam_bonus[stats.Str] >= 0))
1394 op->stats.dam += (1 + (dam_bonus[op->stats.Str] / 5)); 1390 stats.dam += (1 + (dam_bonus[stats.Str] / 5));
1395 } 1391 }
1396 } 1392 }
1397 else 1393 else
1398 wc -= (op->level + thaco_bonus[op->stats.Str]); 1394 wc -= (level + thaco_bonus[stats.Str]);
1399 1395
1400 op->stats.dam += dam_bonus[op->stats.Str]; 1396 stats.dam += dam_bonus[stats.Str];
1401 1397
1402 if (op->stats.dam < 1) 1398 if (stats.dam < 1)
1403 op->stats.dam = 1; 1399 stats.dam = 1;
1404 1400
1405 op->speed = 1.0 + speed_bonus[op->stats.Dex]; 1401 speed = 1.0 + speed_bonus[stats.Dex];
1402
1406 if (settings.search_items && op->contr->search_str[0]) 1403 if (settings.search_items && contr->search_str[0])
1407 op->speed -= 1; 1404 speed -= 1;
1405
1408 if (op->attacktype == 0) 1406 if (attacktype == 0)
1409 op->attacktype = op->arch->clone.attacktype; 1407 attacktype = arch->clone.attacktype;
1410 1408
1411 } /* End if player */ 1409 } /* End if player */
1412 1410
1413 if (added_speed >= 0) 1411 if (added_speed >= 0)
1414 op->speed += added_speed / 10.0; 1412 speed += added_speed / 10.0;
1415 else /* Something wrong here...: */ 1413 else /* Something wrong here...: */
1416 op->speed /= (float) (1.0 - added_speed); 1414 speed /= (float) (1.0 - added_speed);
1417 1415
1418 /* Max is determined by armour */ 1416 /* Max is determined by armour */
1419 if (op->speed > max) 1417 if (speed > max)
1420 op->speed = max; 1418 speed = max;
1421 1419
1422 if (op->type == PLAYER) 1420 if (type == PLAYER)
1423 { 1421 {
1424 /* f is a number the represents the number of kg above (positive num) 1422 /* f is a number the represents the number of kg above (positive num)
1425 * or below (negative number) that the player is carrying. If above 1423 * or below (negative number) that the player is carrying. If above
1426 * weight limit, then player suffers a speed reduction based on how 1424 * weight limit, then player suffers a speed reduction based on how
1427 * much above he is, and what is max carry is 1425 * much above he is, and what is max carry is
1428 */ 1426 */
1429 f = (op->carrying / 1000) - max_carry[op->stats.Str]; 1427 f = (carrying / 1000) - max_carry[stats.Str];
1430 if (f > 0) 1428 if (f > 0)
1431 op->speed = op->speed / (1.0 + f / max_carry[op->stats.Str]); 1429 speed = speed / (1.0 + f / max_carry[stats.Str]);
1432 } 1430 }
1433 1431
1434 op->speed += bonus_speed / 10.0; /* Not affected by limits */ 1432 speed += bonus_speed / 10.0; /* Not affected by limits */
1435 1433
1436 /* Put a lower limit on speed. Note with this speed, you move once every 1434 /* Put a lower limit on speed. Note with this speed, you move once every
1437 * 100 ticks or so. This amounts to once every 12 seconds of realtime. 1435 * 100 ticks or so. This amounts to once every 12 seconds of realtime.
1438 */ 1436 */
1439 op->speed = op->speed * speed_reduce_from_disease; 1437 speed = speed * speed_reduce_from_disease;
1440 1438
1441 if (op->speed < 0.01 && op->type == PLAYER) 1439 if (speed < 0.01 && type == PLAYER)
1442 op->speed = 0.01; 1440 speed = 0.01;
1443 1441
1444 if (op->type == PLAYER) 1442 if (type == PLAYER)
1445 { 1443 {
1446 float M, W, s, D, K, S, M2; 1444 float M, W, s, D, K, S, M2;
1447 1445
1448 /* (This formula was made by vidarl@ifi.uio.no) 1446 /* (This formula was made by vidarl@ifi.uio.no)
1449 * Note that we never used these values again - basically 1447 * Note that we never used these values again - basically
1450 * all of these could be subbed into one big equation, but 1448 * all of these could be subbed into one big equation, but
1451 * that would just be a real pain to read. 1449 * that would just be a real pain to read.
1452 */ 1450 */
1453 M = (max_carry[op->stats.Str] - 121) / 121.0; 1451 M = (max_carry[stats.Str] - 121) / 121.0;
1454 M2 = max_carry[op->stats.Str] / 100.0; 1452 M2 = max_carry[stats.Str] / 100.0;
1455 W = weapon_weight / 20000.0; 1453 W = weapon_weight / 20000.0;
1456 s = 2 - weapon_speed / 10.0; 1454 s = 2 - weapon_speed / 10.0;
1457 D = (op->stats.Dex - 14) / 14.0; 1455 D = (stats.Dex - 14) / 14.0;
1458 K = 1 + M / 3.0 - W / (3 * M2) + op->speed / 5.0 + D / 2.0; 1456 K = 1 + M / 3.0 - W / (3 * M2) + speed / 5.0 + D / 2.0;
1459 K *= (4 + op->level) / (float) (6 + op->level) * 1.2; 1457 K *= (4 + level) / (float) (6 + level) * 1.2;
1460 if (K <= 0) 1458 if (K <= 0)
1461 K = 0.01; 1459 K = 0.01;
1462 S = op->speed / (K * s); 1460 S = speed / (K * s);
1463 op->contr->weapon_sp = S; 1461 contr->weapon_sp = S;
1464 } 1462 }
1463
1465 /* I want to limit the power of small monsters with big weapons: */ 1464 /* I want to limit the power of small monsters with big weapons: */
1466 if (op->type != PLAYER && op->arch != NULL && op->stats.dam > op->arch->clone.stats.dam * 3) 1465 if (type != PLAYER && arch != NULL && stats.dam > arch->clone.stats.dam * 3)
1467 op->stats.dam = op->arch->clone.stats.dam * 3; 1466 stats.dam = arch->clone.stats.dam * 3;
1468 1467
1469 /* Prevent overflows of wc - best you can get is ABS(120) - this 1468 /* Prevent overflows of wc - best you can get is ABS(120) - this
1470 * should be more than enough - remember, AC is also in 8 bits, 1469 * should be more than enough - remember, AC is also in 8 bits,
1471 * so its value is the same. 1470 * so its value is the same.
1472 */ 1471 */
1473 if (wc > 120) 1472 if (wc > 120)
1474 wc = 120; 1473 wc = 120;
1475 else if (wc < -120) 1474 else if (wc < -120)
1476 wc = -120; 1475 wc = -120;
1476
1477 op->stats.wc = wc; 1477 stats.wc = wc;
1478 1478
1479 if (ac > 120) 1479 if (ac > 120)
1480 ac = 120; 1480 ac = 120;
1481 else if (ac < -120) 1481 else if (ac < -120)
1482 ac = -120; 1482 ac = -120;
1483
1483 op->stats.ac = ac; 1484 stats.ac = ac;
1484 1485
1485 /* if for some reason the creature doesn't have any move type, 1486 /* if for some reason the creature doesn't have any move type,
1486 * give them walking as a default. 1487 * give them walking as a default.
1487 * The second case is a special case - to more closely mimic the 1488 * The second case is a special case - to more closely mimic the
1488 * old behaviour - if your flying, your not walking - just 1489 * old behaviour - if your flying, your not walking - just
1489 * one or the other. 1490 * one or the other.
1490 */ 1491 */
1491 if (op->move_type == 0) 1492 if (move_type == 0)
1492 op->move_type = MOVE_WALK; 1493 move_type = MOVE_WALK;
1493 else if (op->move_type & (MOVE_FLY_LOW | MOVE_FLY_HIGH)) 1494 else if (move_type & (MOVE_FLY_LOW | MOVE_FLY_HIGH))
1494 op->move_type &= ~MOVE_WALK; 1495 move_type &= ~MOVE_WALK;
1495 1496
1496 update_ob_speed (op); 1497 update_ob_speed (this);
1497 1498
1498 /* It is quite possible that a player's spell costing might have changed, 1499 /* It is quite possible that a player's spell costing might have changed,
1499 * so we will check that now. 1500 * so we will check that now.
1500 */ 1501 */
1501 if (op->type == PLAYER) 1502 if (type == PLAYER)
1503 {
1504 esrv_update_stats (contr);
1502 esrv_update_spells (op->contr); 1505 esrv_update_spells (contr);
1506 }
1503} 1507}
1504 1508
1505/* 1509/*
1506 * Returns true if the given player is a legal class. 1510 * Returns true if the given player is a legal class.
1507 * The function to add and remove class-bonuses to the stats doesn't 1511 * The function to add and remove class-bonuses to the stats doesn't
1508 * check if the stat becomes negative, thus this function 1512 * check if the stat becomes negative, thus this function
1509 * merely checks that all stats are 1 or more, and returns 1513 * merely checks that all stats are 1 or more, and returns
1510 * false otherwise. 1514 * false otherwise.
1511 */ 1515 */
1512
1513int 1516int
1514allowed_class (const object *op) 1517allowed_class (const object *op)
1515{ 1518{
1516 return op->stats.Dex > 0 && op->stats.Str > 0 && op->stats.Con > 0 && 1519 return op->stats.Dex > 0 && op->stats.Str > 0 && op->stats.Con > 0 &&
1517 op->stats.Int > 0 && op->stats.Wis > 0 && op->stats.Pow > 0 && op->stats.Cha > 0; 1520 op->stats.Int > 0 && op->stats.Wis > 0 && op->stats.Pow > 0 && op->stats.Cha > 0;
1702 who->contr->levhp[who->level] = die_roll (2, 4, who, PREFER_HIGH) + 1; 1705 who->contr->levhp[who->level] = die_roll (2, 4, who, PREFER_HIGH) + 1;
1703 who->contr->levsp[who->level] = die_roll (2, 3, who, PREFER_HIGH); 1706 who->contr->levsp[who->level] = die_roll (2, 3, who, PREFER_HIGH);
1704 who->contr->levgrace[who->level] = die_roll (2, 2, who, PREFER_HIGH) - 1; 1707 who->contr->levgrace[who->level] = die_roll (2, 2, who, PREFER_HIGH) - 1;
1705 } 1708 }
1706 1709
1707 fix_player (who); 1710 who->update_stats ();
1708 if (op->level > 1) 1711 if (op->level > 1)
1709 { 1712 {
1710 if (op->type != PLAYER) 1713 if (op->type != PLAYER)
1711 sprintf (buf, "You are now level %d in the %s skill.", op->level, &op->name); 1714 sprintf (buf, "You are now level %d in the %s skill.", op->level, &op->name);
1712 else 1715 else
1717 player_lvl_adj (who, op); /* To increase more levels */ 1720 player_lvl_adj (who, op); /* To increase more levels */
1718 } 1721 }
1719 else if (op->level > 1 && op->stats.exp < level_exp (op->level, who->expmul)) 1722 else if (op->level > 1 && op->stats.exp < level_exp (op->level, who->expmul))
1720 { 1723 {
1721 op->level--; 1724 op->level--;
1722 fix_player (who); 1725 who->update_stats ();
1723 if (op->type != PLAYER) 1726 if (op->type != PLAYER)
1724 { 1727 {
1725 sprintf (buf, "You are now level %d in the %s skill.", op->level, &op->name); 1728 sprintf (buf, "You are now level %d in the %s skill.", op->level, &op->name);
1726 new_draw_info (NDI_UNIQUE | NDI_RED, 0, who, buf); 1729 new_draw_info (NDI_UNIQUE | NDI_RED, 0, who, buf);
1727 } 1730 }
1728 player_lvl_adj (who, op); /* To decrease more levels */ 1731 player_lvl_adj (who, op); /* To decrease more levels */
1729 } 1732 }
1733
1730 /* check if the spell data has changed */ 1734 /* check if the spell data has changed */
1735 esrv_update_stats (who->contr);
1731 esrv_update_spells (who->contr); 1736 esrv_update_spells (who->contr);
1732} 1737}
1733 1738
1734/* 1739/*
1735 * Returns how much experience is needed for a player to become 1740 * Returns how much experience is needed for a player to become
1769 op->perm_exp = 0; 1774 op->perm_exp = 0;
1770 else if (op->perm_exp > (sint64) MAX_EXPERIENCE) 1775 else if (op->perm_exp > (sint64) MAX_EXPERIENCE)
1771 op->perm_exp = MAX_EXPERIENCE; 1776 op->perm_exp = MAX_EXPERIENCE;
1772} 1777}
1773 1778
1774
1775/* Add experience to a player - exp should only be positive. 1779/* Add experience to a player - exp should only be positive.
1776 * Updates permanent exp for the skill we are adding to. 1780 * Updates permanent exp for the skill we are adding to.
1777 * skill_name is the skill to add exp to. Skill name can be 1781 * skill_name is the skill to add exp to. Skill name can be
1778 * NULL, in which case exp increases the players general 1782 * NULL, in which case exp increases the players general
1779 * total, but not any particular skill. 1783 * total, but not any particular skill.
1780 * flag is what to do if the player doesn't have the skill: 1784 * flag is what to do if the player doesn't have the skill:
1781 */ 1785 */
1782
1783static void 1786static void
1784add_player_exp (object *op, sint64 exp, const char *skill_name, int flag) 1787add_player_exp (object *op, sint64 exp, const char *skill_name, int flag)
1785{ 1788{
1786 object *skill_obj = NULL; 1789 object *skill_obj = NULL;
1787 sint64 limit, exp_to_add; 1790 sint64 limit, exp_to_add;
2070 if (level > MAX_SAVE_LEVEL) 2073 if (level > MAX_SAVE_LEVEL)
2071 level = MAX_SAVE_LEVEL; 2074 level = MAX_SAVE_LEVEL;
2072 2075
2073 if ((random_roll (1, 20, op, PREFER_HIGH) + bonus) < savethrow[level]) 2076 if ((random_roll (1, 20, op, PREFER_HIGH) + bonus) < savethrow[level])
2074 return 0; 2077 return 0;
2078
2075 return 1; 2079 return 1;
2076} 2080}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines