--- deliantra/server/common/living.C 2010/04/15 04:56:46 1.119 +++ deliantra/server/common/living.C 2018/11/17 22:02:14 1.134 @@ -1,24 +1,24 @@ /* * This file is part of Deliantra, the Roguelike Realtime MMORPG. - * - * Copyright (©) 2005,2006,2007,2008,2009,2010 Marc Alexander Lehmann / Robin Redeker / the Deliantra team + * + * Copyright (©) 2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016 Marc Alexander Lehmann / Robin Redeker / the Deliantra team * Copyright (©) 2002 Mark Wedel & Crossfire Development Team * Copyright (©) 1992 Frank Tore Johansen - * + * * Deliantra is free software: you can redistribute it and/or modify it under * the terms of the Affero GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your * option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the Affero GNU General Public License * and the GNU General Public License along with this program. If not, see * . - * + * * The authors can be reached via e-mail to */ @@ -35,7 +35,7 @@ 22, 25, 30, 40, 50 }; -/* changed the name of this to "sp_bonus" from "int_bonus" +/* changed the name of this to "sp_bonus" from "int_bonus" * because Pow can now be the stat that controls spellpoint * advancement. -b.t. */ @@ -49,14 +49,14 @@ 30, 40, 50, 70, 100 }; -/* 0.92.7 Changed way charisma works. Values now +/* 0.92.7 Changed way charisma works. Values now * represent how much more it costs to buy something than to sell it * (10, a value of 10 means it is that if it costs 50 gp to buy, you * would only get 5 gp when you sell.) Let query_cost do the calculations * on how to really do this. Buy keeping it this simple number, it is * much easier to know how things will be influenced. A value of '1' means * buying and selling is both the same value - any value less than or equal - * to 1 should not be used. + * to 1 should not be used. * At least as of now, the only place that uses this code is query_cost, * in server/shop.c. This bonus is split evenly between buying and selling * (ie, if the bonus is 2.0, then items are bought for 1.33 list, and sold @@ -110,13 +110,13 @@ */ const uint32 weight_limit[MAX_STAT + 1] = { - 200000, /* 0 */ - 250000, 300000, 350000, 400000, 500000, /* 5 */ - 600000, 700000, 800000, 900000, 1000000, /* 10 */ + 200000, /* 0 */ + 250000, 300000, 350000, 400000, 500000, /* 5 */ + 600000, 700000, 800000, 900000, 1000000, /* 10 */ 1100000, 1200000, 1300000, 1400000, 1500000, /* 15 */ 1650000, 1800000, 1950000, 2100000, 2250000, /* 20 */ 2400000, 2550000, 2700000, 2850000, 3000000, /* 25 */ - 3250000, 3500000, 3750000, 4000000, 4500000 /*30 */ + 3250000, 3500000, 3750000, 4000000, 4500000 /* 30 */ }; const int learn_spell[MAX_STAT + 1] = { @@ -152,8 +152,8 @@ * otherwise the maximum level in any experience * category could be quite low. To help the situation * out a little I added 10 more levels, and jacked - * up the last level experience value. Its out of - * line with progression of previous levels, so + * up the last level experience value. Its out of + * line with progression of previous levels, so * if more levels are desired, this should be fixed. * -b.t. */ @@ -339,7 +339,7 @@ } /* reset attributes that update_stats doesn't reset since it doesn't search - * everything to set + * everything to set */ if (flag == -1) { @@ -418,7 +418,7 @@ } /* becoming UNDEAD... a special treatment for this flag. Only those not - * originally undead may change their status + * originally undead may change their status */ if (!op->arch->flag [FLAG_UNDEAD]) if (op->flag [FLAG_UNDEAD] != prev_flag [FLAG_UNDEAD]) @@ -449,7 +449,7 @@ } /* blinded you can tell if more blinded since blinded player has minimal - * vision + * vision */ if (tmp->flag [FLAG_BLIND]) { @@ -731,8 +731,9 @@ void object::update_stats () { - float f, max_speed = 9, added_speed = 0, bonus_speed = 0, speed_reduce_from_disease = 1; - int weapon_weight = 0, weapon_speed = 0; + float max_speed = 9, added_speed = 0, bonus_speed = 0, speed_reduce_from_disease = 1; + weight_t weapon_weight = 0; + int weapon_speed = 0; int best_wc = 0, best_ac = 0, wc = 0, ac = 0; int prot[NROFATTACKS], vuln[NROFATTACKS], potion_resist[NROFATTACKS]; object *grace_obj = NULL, *mana_obj = NULL, *tmp; @@ -762,7 +763,7 @@ contr->item_power = 0; } - for (int i = NUM_BODY_LOCATIONS; i--; ) + for (int i = 0; i < NUM_BODY_LOCATIONS; ++i) slot[i].used = slot[i].info; slaying = 0; @@ -807,7 +808,7 @@ stats.dam = arch->stats.dam; /* for players which cannot use armour, they gain AC -1 per 3 levels, - * plus a small amount of physical resist, those poor suckers. ;) + * plus a small amount of physical resist, those poor suckers. ;) * the fact that maxlevel is factored in could be considered sort of bogus - * we should probably give them some bonus and cap it off - otherwise, * basically, if a server updates its max level, these playes may find @@ -863,16 +864,17 @@ /* Container objects are not meant to adjust players, but other applied * objects need to make adjustments. - * This block should handle all player specific changes + * This block should handle all player specific changes * The check for Praying is a bit of a hack - god given bonuses are put * in the praying skill, and the player should always get those. - * It also means we need to put in additional checks for applied below, + * It also means we need to put in additional checks for applied below, * because the skill shouldn't count against body positions being used * up, etc. */ if ((tmp->flag [FLAG_APPLIED] && tmp->type != CONTAINER - && tmp->type != CLOSE_CON) + && tmp->type != CLOSE_CON + && tmp->type != SPELL) || (tmp->type == SKILL && tmp->subtype == SK_PRAYING)) { if (type == PLAYER) @@ -904,12 +906,12 @@ slot[i].used += tmp->slot[i].info; if (tmp->type == SYMPTOM) - min_it (speed_reduce_from_disease, tmp->last_sp ? tmp->last_sp / 100.f : 1.f); + min_it (speed_reduce_from_disease, tmp->last_sp ? tmp->last_sp / 100.f : 1.f); /* Pos. and neg. protections are counted separate (-> pro/vuln). * (Negative protections are calculated exactly like positive.) * Resistance from potions are treated special as well. If there's - * more than one potion-effect, the bigger prot.-value is taken. + * more than one potion-effect, the bigger prot.-value is taken. */ if (tmp->type == POTION_EFFECT) for (int i = 0; i < NROFATTACKS; i++) @@ -917,9 +919,9 @@ else if (tmp->type != POTION) for (int i = 0; i < NROFATTACKS; i++) if (tmp->resist[i] > 0) - prot[i] += ((100 - prot[i]) * tmp->resist[i]) / 100; + prot[i] += (100 - prot[i]) * tmp->resist[i] / 100; else if (tmp->resist[i] < 0) - vuln[i] += ((100 - vuln[i]) * -tmp->resist[i]) / 100; + vuln[i] += (100 - vuln[i]) * -tmp->resist[i] / 100; /* There may be other things that should not adjust the attacktype */ if (tmp->type != SYMPTOM) @@ -940,7 +942,7 @@ //TODO: copy_flags? if (tmp->flag [FLAG_MAKE_INVIS]) { - this->set_flag (FLAG_MAKE_INVIS); + set_flag (FLAG_MAKE_INVIS); invisible = 1; } @@ -997,14 +999,14 @@ ac -= tmp->stats.ac + tmp->magic; if (settings.spell_encumbrance == TRUE && type == PLAYER) - contr->encumbrance += 3 * tmp->weight / 1000; + contr->encumbrance += weight_to_kg_approx (3 * tmp->weight); } break; case SHIELD: if (settings.spell_encumbrance == TRUE && type == PLAYER) - contr->encumbrance += tmp->weight / 2000; + contr->encumbrance += weight_to_kg_approx (tmp->weight) >> 1; //FALLTHROUGH case RING: case AMULET: @@ -1024,11 +1026,7 @@ break; - case WAND: - case ROD: - case HORN: - break; - + case RANGED: case BOW: case WEAPON: wc -= tmp->stats.wc + tmp->magic; @@ -1052,13 +1050,13 @@ if (type == PLAYER) if (settings.spell_encumbrance) - contr->encumbrance += tmp->weight * 3 / 1000; + contr->encumbrance += weight_to_kg_approx (3 * tmp->weight); break; case ARMOUR: /* Only the best of these three are used: */ if (settings.spell_encumbrance == TRUE && type == PLAYER) - contr->encumbrance += tmp->weight / 1000; + contr->encumbrance += weight_to_kg_approx (tmp->weight); case BRACERS: case FORCE: @@ -1091,7 +1089,7 @@ ac -= tmp->stats.ac + tmp->magic; if (ARMOUR_SPEED (tmp)) - max_speed = min (max_speed, ARMOUR_SPEED (tmp) / 10.f); + min_it (max_speed, ARMOUR_SPEED (tmp) / 10.f); break; } /* switch tmp->type */ @@ -1108,7 +1106,7 @@ * If there is an uncursed potion in effect, granting more protection * than that, we take: 'total resistance = resistance from potion'. * If there is a cursed (and no uncursed) potion in effect, we take - * 'total resistance = vulnerability from cursed potion'. + * 'total resistance = vulnerability from cursed potion'. */ for (int i = 0; i < NROFATTACKS; i++) { @@ -1156,8 +1154,8 @@ if (stats.hp > stats.maxhp) stats.hp = stats.maxhp; - /* Sp gain is controlled by the level of the player's - * relevant experience object (mana_obj, see above) + /* Sp gain is controlled by the level of the player's + * relevant experience object (mana_obj, see above) */ /* following happen when skills system is not used */ if (!mana_obj) @@ -1237,15 +1235,15 @@ else ac -= dex_bonus[stats.Dex]; - /* In new exp/skills system, wc bonuses are related to + /* In new exp/skills system, wc bonuses are related to * the players level in a relevant exp object (wc_obj) - * not the general player level -b.t. + * not the general player level -b.t. * I changed this slightly so that wc bonuses are better - * than before. This is to balance out the fact that + * than before. This is to balance out the fact that * the player no longer gets a personal weapon w/ 1 * improvement every level, now its fighterlevel/5. So * we give the player a bonus here in wc and dam - * to make up for the change. Note that I left the + * to make up for the change. Note that I left the * monster bonus the same as before. -b.t. */ object *wc_obj = chosen_skill; @@ -1294,9 +1292,9 @@ * weight limit, then player suffers a speed reduction based on how * much above he is, and what is max carry is */ - float f = (carrying / 1000) - max_carry[stats.Str]; + float f = (sint32)weight_to_kg_approx (carrying) - max_carry[stats.Str]; if (f > 0.f) - speed = speed / (1.f + f / max_carry[stats.Str]); + speed /= (1.f + f / max_carry[stats.Str]); } speed += bonus_speed / 10.f; /* Not affected by limits */ @@ -1382,25 +1380,6 @@ } /* - * Returns true if the given player is a legal class. - * The function to add and remove class-bonuses to the stats doesn't - * check if the stat becomes negative, thus this function - * merely checks that all stats are 1 or more, and returns - * false otherwise. - */ -int -allowed_class (const object *op) -{ - return op->stats.Dex > 0 - && op->stats.Str > 0 - && op->stats.Con > 0 - && op->stats.Int > 0 - && op->stats.Wis > 0 - && op->stats.Pow > 0 - && op->stats.Cha > 0; -} - -/* * set the new dragon name after gaining levels or * changing ability focus (later this can be extended to * eventually change the player's face and animation) @@ -1473,7 +1452,7 @@ return; /* The ability_force keeps track of maximum level ever achieved. - * New abilties can only be gained by surpassing this max level + * New abilties can only be gained by surpassing this max level */ if (who->level > abil->level) { @@ -1628,7 +1607,7 @@ int p_exp_min; /* Ensure that our permanent experience minimum is met. - * permenent_exp_ratio is an integer percentage, we divide by 100 + * permenent_exp_ratio is an integer percentage, we divide by 100 * to get the fraction */ p_exp_min = (int) (settings.permanent_exp_ratio * (float) (op->stats.exp) / 100); @@ -1650,11 +1629,10 @@ * flag is what to do if the player doesn't have the skill: */ static void -add_player_exp (object *op, sint64 exp, const char *skill_name, int flag) +add_player_exp (object *op, sint64 exp, shstr_tmp skill_name, int flag) { object *skill_obj; sint64 limit, exp_to_add; - int i; /* prevents some forms of abuse. */ if (op->contr->braced) @@ -1774,7 +1752,7 @@ * a postive number. */ static void -subtract_player_exp (object *op, sint64 exp, const char *skill, int flag) +subtract_player_exp (object *op, sint64 exp, shstr_tmp skill, int flag) { float fraction = (float) exp / (float) op->stats.exp; object *tmp; @@ -1783,7 +1761,7 @@ for (tmp = op->inv; tmp; tmp = tmp->below) if (tmp->type == SKILL && tmp->stats.exp) { - if (flag == SK_SUBTRACT_SKILL_EXP && skill && !strcmp (&tmp->skill, skill)) + if (flag == SK_SUBTRACT_SKILL_EXP && skill && tmp->skill == skill) { del_exp = check_exp_loss (tmp, exp); tmp->stats.exp -= del_exp; @@ -1794,7 +1772,7 @@ /* only want to process other skills if we are not trying * to match a specific skill. */ - del_exp = check_exp_loss (tmp, (sint64) (tmp->stats.exp * fraction)); + del_exp = check_exp_loss (tmp, tmp->stats.exp * fraction); tmp->stats.exp -= del_exp; player_lvl_adj (op, tmp); } @@ -1818,7 +1796,7 @@ * these last two values are only used for players. */ void -change_exp (object *op, sint64 exp, const char *skill_name, int flag) +change_exp (object *op, sint64 exp, shstr_tmp skill_name, int flag) { #ifdef EXP_DEBUG LOG (llevDebug, "change_exp() called for %s, exp = %" PRId64 "\n", query_name (op), exp); @@ -1837,7 +1815,7 @@ if (exp == 0) return; - /* Monsters are easy - we just adjust their exp - we + /* Monsters are easy - we just adjust their exp - we * don't adjust level, since in most cases it is unrelated to * the exp they have - the monsters exp represents what its * worth. @@ -1874,7 +1852,7 @@ } } -/* Applies a death penalty experience, the size of this is defined by the +/* Applies a death penalty experience, the size of this is defined by the * settings death_penalty_percentage and death_penalty_levels, and by the * amount of permenent experience, whichever gives the lowest loss. */ @@ -1906,7 +1884,7 @@ } percentage_loss = op->stats.exp * settings.death_penalty_ratio / 100; - level_loss = op->stats.exp - levels[max (0, op->level - settings.death_penalty_level)]; + level_loss = op->stats.exp - levels [max (0, op->level - settings.death_penalty_level)]; if (level_loss < 0) level_loss = 0;