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.118 by root, Sun Apr 11 00:34:05 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
139/* 139/*
140 Since this is nowhere defined ... 140 Since this is nowhere defined ...
141 Both come in handy at least in function add_exp() 141 Both come in handy at least in function add_exp()
142*/ 142*/
143 143
144#define MAX_EXPERIENCE levels[settings.max_level] 144#define MAX_EXPERIENCE levels [settings.max_level]
145 145
146/* because exp_obj sum to make the total score, 146/* because exp_obj sum to make the total score,
147 * we cannot allow that sum to exceed the maximum 147 * we cannot allow that sum to exceed the maximum
148 * amount of experience a player can gain. Thus 148 * amount of experience a player can gain. Thus
149 * we define MAX_EXP_IN_OBJ. It is important to try 149 * we define MAX_EXP_IN_OBJ. It is important to try
156 * line with progression of previous levels, so 156 * line with progression of previous levels, so
157 * if more levels are desired, this should be fixed. 157 * if more levels are desired, this should be fixed.
158 * -b.t. 158 * -b.t.
159 */ 159 */
160 160
161#define MAX_EXP_IN_OBJ levels[settings.max_level]/(MAX_EXP_CAT - 1) 161#define MAX_EXP_IN_OBJ MAX_EXP_IN_OBJ / (MAX_EXP_CAT - 1)
162
163extern sint64 *levels;
164 162
165#define MAX_SAVE_LEVEL 110 163#define MAX_SAVE_LEVEL 110
166 164
167/* This no longer needs to be changed anytime the number of 165/* This no longer needs to be changed anytime the number of
168 * levels is increased - rather, did_make_save will do the 166 * levels is increased - rather, did_make_save will do the
731 * spell system split, grace points now added to system --peterm 729 * spell system split, grace points now added to system --peterm
732 */ 730 */
733void 731void
734object::update_stats () 732object::update_stats ()
735{ 733{
736 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;
737 int weapon_weight = 0, weapon_speed = 0; 735 weight_t weapon_weight = 0;
736 int weapon_speed = 0;
738 int best_wc = 0, best_ac = 0, wc = 0, ac = 0; 737 int best_wc = 0, best_ac = 0, wc = 0, ac = 0;
739 int prot[NROFATTACKS], vuln[NROFATTACKS], potion_resist[NROFATTACKS]; 738 int prot[NROFATTACKS], vuln[NROFATTACKS], potion_resist[NROFATTACKS];
740 object *grace_obj = NULL, *mana_obj = NULL, *tmp; 739 object *grace_obj = NULL, *mana_obj = NULL, *tmp;
741 float old_speed = speed; 740 float old_speed = speed;
742 int stat_sum [NUM_STATS]; 741 int stat_sum [NUM_STATS];
872 * because the skill shouldn't count against body positions being used 871 * because the skill shouldn't count against body positions being used
873 * up, etc. 872 * up, etc.
874 */ 873 */
875 if ((tmp->flag [FLAG_APPLIED] 874 if ((tmp->flag [FLAG_APPLIED]
876 && tmp->type != CONTAINER 875 && tmp->type != CONTAINER
877 && tmp->type != CLOSE_CON) 876 && tmp->type != CLOSE_CON
877 && tmp->type != SPELL)
878 || (tmp->type == SKILL && tmp->subtype == SK_PRAYING)) 878 || (tmp->type == SKILL && tmp->subtype == SK_PRAYING))
879 { 879 {
880 if (type == PLAYER) 880 if (type == PLAYER)
881 { 881 {
882 contr->item_power += tmp->item_power; 882 contr->item_power += tmp->item_power;
917 for (int i = 0; i < NROFATTACKS; i++) 917 for (int i = 0; i < NROFATTACKS; i++)
918 max_it (potion_resist[i], tmp->resist[i]); 918 max_it (potion_resist[i], tmp->resist[i]);
919 else if (tmp->type != POTION) 919 else if (tmp->type != POTION)
920 for (int i = 0; i < NROFATTACKS; i++) 920 for (int i = 0; i < NROFATTACKS; i++)
921 if (tmp->resist[i] > 0) 921 if (tmp->resist[i] > 0)
922 prot[i] += ((100 - prot[i]) * tmp->resist[i]) / 100; 922 prot[i] += (100 - prot[i]) * tmp->resist[i] / 100;
923 else if (tmp->resist[i] < 0) 923 else if (tmp->resist[i] < 0)
924 vuln[i] += ((100 - vuln[i]) * -tmp->resist[i]) / 100; 924 vuln[i] += (100 - vuln[i]) * -tmp->resist[i] / 100;
925 925
926 /* There may be other things that should not adjust the attacktype */ 926 /* There may be other things that should not adjust the attacktype */
927 if (tmp->type != SYMPTOM) 927 if (tmp->type != SYMPTOM)
928 { 928 {
929 attacktype |= tmp->attacktype; 929 attacktype |= tmp->attacktype;
940 this->set_flag (FLAG_UNDEAD); 940 this->set_flag (FLAG_UNDEAD);
941 941
942 //TODO: copy_flags? 942 //TODO: copy_flags?
943 if (tmp->flag [FLAG_MAKE_INVIS]) 943 if (tmp->flag [FLAG_MAKE_INVIS])
944 { 944 {
945 this->set_flag (FLAG_MAKE_INVIS); 945 set_flag (FLAG_MAKE_INVIS);
946 invisible = 1; 946 invisible = 1;
947 } 947 }
948 948
949 if (tmp->stats.exp && tmp->type != SKILL) 949 if (tmp->stats.exp && tmp->type != SKILL)
950 { 950 {
997 997
998 if (tmp->stats.ac) 998 if (tmp->stats.ac)
999 ac -= tmp->stats.ac + tmp->magic; 999 ac -= tmp->stats.ac + tmp->magic;
1000 1000
1001 if (settings.spell_encumbrance == TRUE && type == PLAYER) 1001 if (settings.spell_encumbrance == TRUE && type == PLAYER)
1002 contr->encumbrance += 3 * tmp->weight / 1000; 1002 contr->encumbrance += weight_to_kg_approx (3 * tmp->weight);
1003 } 1003 }
1004 1004
1005 break; 1005 break;
1006 1006
1007 case SHIELD: 1007 case SHIELD:
1008 if (settings.spell_encumbrance == TRUE && type == PLAYER) 1008 if (settings.spell_encumbrance == TRUE && type == PLAYER)
1009 contr->encumbrance += tmp->weight / 2000; 1009 contr->encumbrance += weight_to_kg_approx (tmp->weight) >> 1;
1010 //FALLTHROUGH 1010 //FALLTHROUGH
1011 case RING: 1011 case RING:
1012 case AMULET: 1012 case AMULET:
1013 case GIRDLE: 1013 case GIRDLE:
1014 case HELMET: 1014 case HELMET:
1024 if (tmp->stats.ac) 1024 if (tmp->stats.ac)
1025 ac -= tmp->stats.ac + tmp->magic; 1025 ac -= tmp->stats.ac + tmp->magic;
1026 1026
1027 break; 1027 break;
1028 1028
1029 case WAND: 1029 case RANGED:
1030 case ROD:
1031 case HORN:
1032 break;
1033
1034 case BOW: 1030 case BOW:
1035 case WEAPON: 1031 case WEAPON:
1036 wc -= tmp->stats.wc + tmp->magic; 1032 wc -= tmp->stats.wc + tmp->magic;
1037 1033
1038 if (tmp->stats.ac && tmp->stats.ac + tmp->magic > 0) 1034 if (tmp->stats.ac && tmp->stats.ac + tmp->magic > 0)
1052 * go. 1048 * go.
1053 */ 1049 */
1054 1050
1055 if (type == PLAYER) 1051 if (type == PLAYER)
1056 if (settings.spell_encumbrance) 1052 if (settings.spell_encumbrance)
1057 contr->encumbrance += tmp->weight * 3 / 1000; 1053 contr->encumbrance += weight_to_kg_approx (3 * tmp->weight);
1058 1054
1059 break; 1055 break;
1060 1056
1061 case ARMOUR: /* Only the best of these three are used: */ 1057 case ARMOUR: /* Only the best of these three are used: */
1062 if (settings.spell_encumbrance == TRUE && type == PLAYER) 1058 if (settings.spell_encumbrance == TRUE && type == PLAYER)
1063 contr->encumbrance += tmp->weight / 1000; 1059 contr->encumbrance += weight_to_kg_approx (tmp->weight);
1064 1060
1065 case BRACERS: 1061 case BRACERS:
1066 case FORCE: 1062 case FORCE:
1067 if (tmp->stats.wc) 1063 if (tmp->stats.wc)
1068 { 1064 {
1091 1087
1092 if (tmp->stats.ac) 1088 if (tmp->stats.ac)
1093 ac -= tmp->stats.ac + tmp->magic; 1089 ac -= tmp->stats.ac + tmp->magic;
1094 1090
1095 if (ARMOUR_SPEED (tmp)) 1091 if (ARMOUR_SPEED (tmp))
1096 max_speed = min (max_speed, ARMOUR_SPEED (tmp) / 10.f); 1092 min_it (max_speed, ARMOUR_SPEED (tmp) / 10.f);
1097 1093
1098 break; 1094 break;
1099 } /* switch tmp->type */ 1095 } /* switch tmp->type */
1100 } /* item is equipped */ 1096 } /* item is equipped */
1101 } /* for loop of items */ 1097 } /* for loop of items */
1294 /* 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)
1295 * or below (negative number) that the player is carrying. If above 1291 * or below (negative number) that the player is carrying. If above
1296 * weight limit, then player suffers a speed reduction based on how 1292 * weight limit, then player suffers a speed reduction based on how
1297 * much above he is, and what is max carry is 1293 * much above he is, and what is max carry is
1298 */ 1294 */
1299 float f = (carrying / 1000) - max_carry[stats.Str]; 1295 float f = (sint32)weight_to_kg_approx (carrying) - max_carry[stats.Str];
1300 if (f > 0.f) 1296 if (f > 0.f)
1301 speed = speed / (1.f + f / max_carry[stats.Str]); 1297 speed /= (1.f + f / max_carry[stats.Str]);
1302 } 1298 }
1303 1299
1304 speed += bonus_speed / 10.f; /* Not affected by limits */ 1300 speed += bonus_speed / 10.f; /* Not affected by limits */
1305 speed *= speed_reduce_from_disease; 1301 speed *= speed_reduce_from_disease;
1306 1302
1612 */ 1608 */
1613 1609
1614sint64 1610sint64
1615level_exp (int level, double expmul) 1611level_exp (int level, double expmul)
1616{ 1612{
1617 if (level > settings.max_level) 1613 return expmul * level_to_min_exp (level);
1618 return (sint64) (expmul * levels[settings.max_level]);
1619
1620 return (sint64) (expmul * levels[level]);
1621} 1614}
1622 1615
1623/* 1616/*
1624 * Ensure that the permanent experience requirements in an exp object are met. 1617 * Ensure that the permanent experience requirements in an exp object are met.
1625 * This really just checks 'op to make sure the perm_exp value is within 1618 * This really just checks 'op to make sure the perm_exp value is within
1653 * NULL, in which case exp increases the players general 1646 * NULL, in which case exp increases the players general
1654 * total, but not any particular skill. 1647 * total, but not any particular skill.
1655 * 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:
1656 */ 1649 */
1657static void 1650static void
1658add_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)
1659{ 1652{
1660 object *skill_obj; 1653 object *skill_obj;
1661 sint64 limit, exp_to_add; 1654 sint64 limit, exp_to_add;
1662 int i;
1663 1655
1664 /* prevents some forms of abuse. */ 1656 /* prevents some forms of abuse. */
1665 if (op->contr->braced) 1657 if (op->contr->braced)
1666 exp /= 5; 1658 exp /= 5;
1667 1659
1693 { 1685 {
1694 /* Basically, you can never gain more experience in one shot 1686 /* Basically, you can never gain more experience in one shot
1695 * than half what you need to gain for next level. 1687 * than half what you need to gain for next level.
1696 */ 1688 */
1697 exp_to_add = exp; 1689 exp_to_add = exp;
1698 limit = (levels[op->level + 1] - levels[op->level]) / 2; 1690 limit = (levels [op->level + 1] - levels [op->level]) / 2;
1699 if (exp_to_add > limit) 1691 if (exp_to_add > limit)
1700 exp_to_add = limit; 1692 exp_to_add = limit;
1701 1693
1702 ADD_EXP (op->stats.exp, (sint64) ((float) exp_to_add * (skill_obj ? skill_obj->expmul : 1))); 1694 ADD_EXP (op->stats.exp, (sint64) ((float) exp_to_add * (skill_obj ? skill_obj->expmul : 1)));
1703 if (settings.permanent_exp_ratio) 1695 if (settings.permanent_exp_ratio)
1710 } 1702 }
1711 1703
1712 if (skill_obj) 1704 if (skill_obj)
1713 { 1705 {
1714 exp_to_add = exp; 1706 exp_to_add = exp;
1715 limit = (levels[skill_obj->level + 1] - levels[skill_obj->level]) / 2; 1707 limit = (levels [skill_obj->level + 1] - levels [skill_obj->level]) / 2;
1716 if (exp_to_add > limit) 1708 if (exp_to_add > limit)
1717 exp_to_add = limit; 1709 exp_to_add = limit;
1718 1710
1719 ADD_EXP (skill_obj->stats.exp, exp_to_add); 1711 ADD_EXP (skill_obj->stats.exp, exp_to_add);
1720 if (settings.permanent_exp_ratio) 1712 if (settings.permanent_exp_ratio)
1777 * 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.
1778 * 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
1779 * a postive number. 1771 * a postive number.
1780 */ 1772 */
1781static void 1773static void
1782subtract_player_exp (object *op, sint64 exp, const char *skill, int flag) 1774subtract_player_exp (object *op, sint64 exp, shstr_tmp skill, int flag)
1783{ 1775{
1784 float fraction = (float) exp / (float) op->stats.exp; 1776 float fraction = (float) exp / (float) op->stats.exp;
1785 object *tmp; 1777 object *tmp;
1786 sint64 del_exp; 1778 sint64 del_exp;
1787 1779
1788 for (tmp = op->inv; tmp; tmp = tmp->below) 1780 for (tmp = op->inv; tmp; tmp = tmp->below)
1789 if (tmp->type == SKILL && tmp->stats.exp) 1781 if (tmp->type == SKILL && tmp->stats.exp)
1790 { 1782 {
1791 if (flag == SK_SUBTRACT_SKILL_EXP && skill && !strcmp (&tmp->skill, skill)) 1783 if (flag == SK_SUBTRACT_SKILL_EXP && skill && tmp->skill == skill)
1792 { 1784 {
1793 del_exp = check_exp_loss (tmp, exp); 1785 del_exp = check_exp_loss (tmp, exp);
1794 tmp->stats.exp -= del_exp; 1786 tmp->stats.exp -= del_exp;
1795 player_lvl_adj (op, tmp); 1787 player_lvl_adj (op, tmp);
1796 } 1788 }
1797 else if (flag != SK_SUBTRACT_SKILL_EXP) 1789 else if (flag != SK_SUBTRACT_SKILL_EXP)
1798 { 1790 {
1799 /* only want to process other skills if we are not trying 1791 /* only want to process other skills if we are not trying
1800 * to match a specific skill. 1792 * to match a specific skill.
1801 */ 1793 */
1802 del_exp = check_exp_loss (tmp, (sint64) (tmp->stats.exp * fraction)); 1794 del_exp = check_exp_loss (tmp, tmp->stats.exp * fraction);
1803 tmp->stats.exp -= del_exp; 1795 tmp->stats.exp -= del_exp;
1804 player_lvl_adj (op, tmp); 1796 player_lvl_adj (op, tmp);
1805 } 1797 }
1806 } 1798 }
1807 1799
1821 * skill_name is the skill that should get the exp added. 1813 * skill_name is the skill that should get the exp added.
1822 * 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.
1823 * these last two values are only used for players. 1815 * these last two values are only used for players.
1824 */ 1816 */
1825void 1817void
1826change_exp (object *op, sint64 exp, const char *skill_name, int flag) 1818change_exp (object *op, sint64 exp, shstr_tmp skill_name, int flag)
1827{ 1819{
1828#ifdef EXP_DEBUG 1820#ifdef EXP_DEBUG
1829 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);
1830#endif 1822#endif
1831 1823
1909 tmp->stats.exp -= loss; 1901 tmp->stats.exp -= loss;
1910 player_lvl_adj (op, tmp); 1902 player_lvl_adj (op, tmp);
1911 } 1903 }
1912 1904
1913 percentage_loss = op->stats.exp * settings.death_penalty_ratio / 100; 1905 percentage_loss = op->stats.exp * settings.death_penalty_ratio / 100;
1914 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)];
1915 1907
1916 if (level_loss < 0) 1908 if (level_loss < 0)
1917 level_loss = 0; 1909 level_loss = 0;
1918 1910
1919 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