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.119 by root, Thu Apr 15 04:56:46 2010 UTC vs.
Revision 1.130 by root, Mon Nov 12 10:32:18 2012 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 (©) 2005,2006,2007,2008,2009,2010 Marc Alexander Lehmann / Robin Redeker / the Deliantra team 4 * Copyright (©) 2005,2006,2007,2008,2009,2010,2011,2012 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * Copyright (©) 2002 Mark Wedel & Crossfire Development Team 5 * Copyright (©) 2002 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992 Frank Tore Johansen 6 * Copyright (©) 1992 Frank Tore Johansen
7 * 7 *
8 * Deliantra is free software: you can redistribute it and/or modify it under 8 * 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 9 * 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 10 * Free Software Foundation, either version 3 of the License, or (at your
11 * option) any later version. 11 * option) any later version.
12 * 12 *
13 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 16 * GNU General Public License for more details.
17 * 17 *
18 * You should have received a copy of the Affero GNU General Public License 18 * 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 19 * and the GNU General Public License along with this program. If not, see
20 * <http://www.gnu.org/licenses/>. 20 * <http://www.gnu.org/licenses/>.
21 * 21 *
22 * The authors can be reached via e-mail to <support@deliantra.net> 22 * The authors can be reached via e-mail to <support@deliantra.net>
23 */ 23 */
24 24
25#include <global.h> 25#include <global.h>
26 26
33static const int con_bonus[MAX_STAT + 1] = { 33static 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, 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 22, 25, 30, 40, 50 35 22, 25, 30, 40, 50
36}; 36};
37 37
38/* changed the name of this to "sp_bonus" from "int_bonus" 38/* changed the name of this to "sp_bonus" from "int_bonus"
39 * because Pow can now be the stat that controls spellpoint 39 * because Pow can now be the stat that controls spellpoint
40 * advancement. -b.t. 40 * advancement. -b.t.
41 */ 41 */
42static const int sp_bonus[MAX_STAT + 1] = { 42static 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, 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,
108 * These limits are probably overly generous, but being there were no values 108 * These limits are probably overly generous, but being there were no values
109 * before, you need to start someplace. 109 * before, you need to start someplace.
110 */ 110 */
111 111
112const uint32 weight_limit[MAX_STAT + 1] = { 112const uint32 weight_limit[MAX_STAT + 1] = {
113 200000, /* 0 */ 113 200000, /* 0 */
114 250000, 300000, 350000, 400000, 500000, /* 5 */ 114 250000, 300000, 350000, 400000, 500000, /* 5 */
115 600000, 700000, 800000, 900000, 1000000, /* 10 */ 115 600000, 700000, 800000, 900000, 1000000, /* 10 */
116 1100000, 1200000, 1300000, 1400000, 1500000, /* 15 */ 116 1100000, 1200000, 1300000, 1400000, 1500000, /* 15 */
117 1650000, 1800000, 1950000, 2100000, 2250000, /* 20 */ 117 1650000, 1800000, 1950000, 2100000, 2250000, /* 20 */
118 2400000, 2550000, 2700000, 2850000, 3000000, /* 25 */ 118 2400000, 2550000, 2700000, 2850000, 3000000, /* 25 */
119 3250000, 3500000, 3750000, 4000000, 4500000 /*30 */ 119 3250000, 3500000, 3750000, 4000000, 4500000 /* 30 */
120}; 120};
121 121
122const int learn_spell[MAX_STAT + 1] = { 122const 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, 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 100, 100, 100, 100, 100, 100 124 100, 100, 100, 100, 100, 100
729 * spell system split, grace points now added to system --peterm 729 * spell system split, grace points now added to system --peterm
730 */ 730 */
731void 731void
732object::update_stats () 732object::update_stats ()
733{ 733{
734 float f, max_speed = 9, added_speed = 0, bonus_speed = 0, speed_reduce_from_disease = 1; 734 float max_speed = 9, added_speed = 0, bonus_speed = 0, speed_reduce_from_disease = 1;
735 int weapon_weight = 0, weapon_speed = 0; 735 weight_t weapon_weight = 0;
736 int weapon_speed = 0;
736 int best_wc = 0, best_ac = 0, wc = 0, ac = 0; 737 int best_wc = 0, best_ac = 0, wc = 0, ac = 0;
737 int prot[NROFATTACKS], vuln[NROFATTACKS], potion_resist[NROFATTACKS]; 738 int prot[NROFATTACKS], vuln[NROFATTACKS], potion_resist[NROFATTACKS];
738 object *grace_obj = NULL, *mana_obj = NULL, *tmp; 739 object *grace_obj = NULL, *mana_obj = NULL, *tmp;
739 float old_speed = speed; 740 float old_speed = speed;
740 int stat_sum [NUM_STATS]; 741 int stat_sum [NUM_STATS];
870 * because the skill shouldn't count against body positions being used 871 * because the skill shouldn't count against body positions being used
871 * up, etc. 872 * up, etc.
872 */ 873 */
873 if ((tmp->flag [FLAG_APPLIED] 874 if ((tmp->flag [FLAG_APPLIED]
874 && tmp->type != CONTAINER 875 && tmp->type != CONTAINER
875 && tmp->type != CLOSE_CON) 876 && tmp->type != CLOSE_CON
877 && tmp->type != SPELL)
876 || (tmp->type == SKILL && tmp->subtype == SK_PRAYING)) 878 || (tmp->type == SKILL && tmp->subtype == SK_PRAYING))
877 { 879 {
878 if (type == PLAYER) 880 if (type == PLAYER)
879 { 881 {
880 contr->item_power += tmp->item_power; 882 contr->item_power += tmp->item_power;
915 for (int i = 0; i < NROFATTACKS; i++) 917 for (int i = 0; i < NROFATTACKS; i++)
916 max_it (potion_resist[i], tmp->resist[i]); 918 max_it (potion_resist[i], tmp->resist[i]);
917 else if (tmp->type != POTION) 919 else if (tmp->type != POTION)
918 for (int i = 0; i < NROFATTACKS; i++) 920 for (int i = 0; i < NROFATTACKS; i++)
919 if (tmp->resist[i] > 0) 921 if (tmp->resist[i] > 0)
920 prot[i] += ((100 - prot[i]) * tmp->resist[i]) / 100; 922 prot[i] += (100 - prot[i]) * tmp->resist[i] / 100;
921 else if (tmp->resist[i] < 0) 923 else if (tmp->resist[i] < 0)
922 vuln[i] += ((100 - vuln[i]) * -tmp->resist[i]) / 100; 924 vuln[i] += (100 - vuln[i]) * -tmp->resist[i] / 100;
923 925
924 /* There may be other things that should not adjust the attacktype */ 926 /* There may be other things that should not adjust the attacktype */
925 if (tmp->type != SYMPTOM) 927 if (tmp->type != SYMPTOM)
926 { 928 {
927 attacktype |= tmp->attacktype; 929 attacktype |= tmp->attacktype;
938 this->set_flag (FLAG_UNDEAD); 940 this->set_flag (FLAG_UNDEAD);
939 941
940 //TODO: copy_flags? 942 //TODO: copy_flags?
941 if (tmp->flag [FLAG_MAKE_INVIS]) 943 if (tmp->flag [FLAG_MAKE_INVIS])
942 { 944 {
943 this->set_flag (FLAG_MAKE_INVIS); 945 set_flag (FLAG_MAKE_INVIS);
944 invisible = 1; 946 invisible = 1;
945 } 947 }
946 948
947 if (tmp->stats.exp && tmp->type != SKILL) 949 if (tmp->stats.exp && tmp->type != SKILL)
948 { 950 {
995 997
996 if (tmp->stats.ac) 998 if (tmp->stats.ac)
997 ac -= tmp->stats.ac + tmp->magic; 999 ac -= tmp->stats.ac + tmp->magic;
998 1000
999 if (settings.spell_encumbrance == TRUE && type == PLAYER) 1001 if (settings.spell_encumbrance == TRUE && type == PLAYER)
1000 contr->encumbrance += 3 * tmp->weight / 1000; 1002 contr->encumbrance += weight_to_kg_approx (3 * tmp->weight);
1001 } 1003 }
1002 1004
1003 break; 1005 break;
1004 1006
1005 case SHIELD: 1007 case SHIELD:
1006 if (settings.spell_encumbrance == TRUE && type == PLAYER) 1008 if (settings.spell_encumbrance == TRUE && type == PLAYER)
1007 contr->encumbrance += tmp->weight / 2000; 1009 contr->encumbrance += weight_to_kg_approx (tmp->weight) >> 1;
1008 //FALLTHROUGH 1010 //FALLTHROUGH
1009 case RING: 1011 case RING:
1010 case AMULET: 1012 case AMULET:
1011 case GIRDLE: 1013 case GIRDLE:
1012 case HELMET: 1014 case HELMET:
1022 if (tmp->stats.ac) 1024 if (tmp->stats.ac)
1023 ac -= tmp->stats.ac + tmp->magic; 1025 ac -= tmp->stats.ac + tmp->magic;
1024 1026
1025 break; 1027 break;
1026 1028
1027 case WAND: 1029 case RANGED:
1028 case ROD:
1029 case HORN:
1030 break;
1031
1032 case BOW: 1030 case BOW:
1033 case WEAPON: 1031 case WEAPON:
1034 wc -= tmp->stats.wc + tmp->magic; 1032 wc -= tmp->stats.wc + tmp->magic;
1035 1033
1036 if (tmp->stats.ac && tmp->stats.ac + tmp->magic > 0) 1034 if (tmp->stats.ac && tmp->stats.ac + tmp->magic > 0)
1050 * go. 1048 * go.
1051 */ 1049 */
1052 1050
1053 if (type == PLAYER) 1051 if (type == PLAYER)
1054 if (settings.spell_encumbrance) 1052 if (settings.spell_encumbrance)
1055 contr->encumbrance += tmp->weight * 3 / 1000; 1053 contr->encumbrance += weight_to_kg_approx (3 * tmp->weight);
1056 1054
1057 break; 1055 break;
1058 1056
1059 case ARMOUR: /* Only the best of these three are used: */ 1057 case ARMOUR: /* Only the best of these three are used: */
1060 if (settings.spell_encumbrance == TRUE && type == PLAYER) 1058 if (settings.spell_encumbrance == TRUE && type == PLAYER)
1061 contr->encumbrance += tmp->weight / 1000; 1059 contr->encumbrance += weight_to_kg_approx (tmp->weight);
1062 1060
1063 case BRACERS: 1061 case BRACERS:
1064 case FORCE: 1062 case FORCE:
1065 if (tmp->stats.wc) 1063 if (tmp->stats.wc)
1066 { 1064 {
1089 1087
1090 if (tmp->stats.ac) 1088 if (tmp->stats.ac)
1091 ac -= tmp->stats.ac + tmp->magic; 1089 ac -= tmp->stats.ac + tmp->magic;
1092 1090
1093 if (ARMOUR_SPEED (tmp)) 1091 if (ARMOUR_SPEED (tmp))
1094 max_speed = min (max_speed, ARMOUR_SPEED (tmp) / 10.f); 1092 min_it (max_speed, ARMOUR_SPEED (tmp) / 10.f);
1095 1093
1096 break; 1094 break;
1097 } /* switch tmp->type */ 1095 } /* switch tmp->type */
1098 } /* item is equipped */ 1096 } /* item is equipped */
1099 } /* for loop of items */ 1097 } /* for loop of items */
1292 /* f is a number the represents the number of kg above (positive num) 1290 /* f is a number the represents the number of kg above (positive num)
1293 * or below (negative number) that the player is carrying. If above 1291 * or below (negative number) that the player is carrying. If above
1294 * weight limit, then player suffers a speed reduction based on how 1292 * weight limit, then player suffers a speed reduction based on how
1295 * much above he is, and what is max carry is 1293 * much above he is, and what is max carry is
1296 */ 1294 */
1297 float f = (carrying / 1000) - max_carry[stats.Str]; 1295 float f = (sint32)weight_to_kg_approx (carrying) - max_carry[stats.Str];
1298 if (f > 0.f) 1296 if (f > 0.f)
1299 speed = speed / (1.f + f / max_carry[stats.Str]); 1297 speed /= (1.f + f / max_carry[stats.Str]);
1300 } 1298 }
1301 1299
1302 speed += bonus_speed / 10.f; /* Not affected by limits */ 1300 speed += bonus_speed / 10.f; /* Not affected by limits */
1303 speed *= speed_reduce_from_disease; 1301 speed *= speed_reduce_from_disease;
1304 1302
1648 * NULL, in which case exp increases the players general 1646 * NULL, in which case exp increases the players general
1649 * total, but not any particular skill. 1647 * total, but not any particular skill.
1650 * flag is what to do if the player doesn't have the skill: 1648 * flag is what to do if the player doesn't have the skill:
1651 */ 1649 */
1652static void 1650static void
1653add_player_exp (object *op, sint64 exp, const char *skill_name, int flag) 1651add_player_exp (object *op, sint64 exp, shstr_tmp skill_name, int flag)
1654{ 1652{
1655 object *skill_obj; 1653 object *skill_obj;
1656 sint64 limit, exp_to_add; 1654 sint64 limit, exp_to_add;
1657 int i;
1658 1655
1659 /* prevents some forms of abuse. */ 1656 /* prevents some forms of abuse. */
1660 if (op->contr->braced) 1657 if (op->contr->braced)
1661 exp /= 5; 1658 exp /= 5;
1662 1659
1772 * where everything is at the minimum perm exp, he would lose nothing. 1769 * where everything is at the minimum perm exp, he would lose nothing.
1773 * exp is the amount of exp to subtract - thus, it should be 1770 * exp is the amount of exp to subtract - thus, it should be
1774 * a postive number. 1771 * a postive number.
1775 */ 1772 */
1776static void 1773static void
1777subtract_player_exp (object *op, sint64 exp, const char *skill, int flag) 1774subtract_player_exp (object *op, sint64 exp, shstr_tmp skill, int flag)
1778{ 1775{
1779 float fraction = (float) exp / (float) op->stats.exp; 1776 float fraction = (float) exp / (float) op->stats.exp;
1780 object *tmp; 1777 object *tmp;
1781 sint64 del_exp; 1778 sint64 del_exp;
1782 1779
1783 for (tmp = op->inv; tmp; tmp = tmp->below) 1780 for (tmp = op->inv; tmp; tmp = tmp->below)
1784 if (tmp->type == SKILL && tmp->stats.exp) 1781 if (tmp->type == SKILL && tmp->stats.exp)
1785 { 1782 {
1786 if (flag == SK_SUBTRACT_SKILL_EXP && skill && !strcmp (&tmp->skill, skill)) 1783 if (flag == SK_SUBTRACT_SKILL_EXP && skill && tmp->skill == skill)
1787 { 1784 {
1788 del_exp = check_exp_loss (tmp, exp); 1785 del_exp = check_exp_loss (tmp, exp);
1789 tmp->stats.exp -= del_exp; 1786 tmp->stats.exp -= del_exp;
1790 player_lvl_adj (op, tmp); 1787 player_lvl_adj (op, tmp);
1791 } 1788 }
1792 else if (flag != SK_SUBTRACT_SKILL_EXP) 1789 else if (flag != SK_SUBTRACT_SKILL_EXP)
1793 { 1790 {
1794 /* only want to process other skills if we are not trying 1791 /* only want to process other skills if we are not trying
1795 * to match a specific skill. 1792 * to match a specific skill.
1796 */ 1793 */
1797 del_exp = check_exp_loss (tmp, (sint64) (tmp->stats.exp * fraction)); 1794 del_exp = check_exp_loss (tmp, tmp->stats.exp * fraction);
1798 tmp->stats.exp -= del_exp; 1795 tmp->stats.exp -= del_exp;
1799 player_lvl_adj (op, tmp); 1796 player_lvl_adj (op, tmp);
1800 } 1797 }
1801 } 1798 }
1802 1799
1816 * skill_name is the skill that should get the exp added. 1813 * skill_name is the skill that should get the exp added.
1817 * flag is what to do if player doesn't have the skill. 1814 * flag is what to do if player doesn't have the skill.
1818 * these last two values are only used for players. 1815 * these last two values are only used for players.
1819 */ 1816 */
1820void 1817void
1821change_exp (object *op, sint64 exp, const char *skill_name, int flag) 1818change_exp (object *op, sint64 exp, shstr_tmp skill_name, int flag)
1822{ 1819{
1823#ifdef EXP_DEBUG 1820#ifdef EXP_DEBUG
1824 LOG (llevDebug, "change_exp() called for %s, exp = %" PRId64 "\n", query_name (op), exp); 1821 LOG (llevDebug, "change_exp() called for %s, exp = %" PRId64 "\n", query_name (op), exp);
1825#endif 1822#endif
1826 1823
1904 tmp->stats.exp -= loss; 1901 tmp->stats.exp -= loss;
1905 player_lvl_adj (op, tmp); 1902 player_lvl_adj (op, tmp);
1906 } 1903 }
1907 1904
1908 percentage_loss = op->stats.exp * settings.death_penalty_ratio / 100; 1905 percentage_loss = op->stats.exp * settings.death_penalty_ratio / 100;
1909 level_loss = op->stats.exp - levels[max (0, op->level - settings.death_penalty_level)]; 1906 level_loss = op->stats.exp - levels [max (0, op->level - settings.death_penalty_level)];
1910 1907
1911 if (level_loss < 0) 1908 if (level_loss < 0)
1912 level_loss = 0; 1909 level_loss = 0;
1913 1910
1914 loss = check_exp_loss (op, min (level_loss, percentage_loss)); 1911 loss = check_exp_loss (op, min (level_loss, percentage_loss));

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines