--- deliantra/server/common/living.C 2007/07/01 05:00:17 1.68 +++ deliantra/server/common/living.C 2007/08/07 21:58:25 1.74 @@ -706,6 +706,46 @@ } } +/* These are the items that currently can change digestion, regeneration, + * spell point recovery and mana point recovery. Seems sort of an arbitary + * list, but other items store other info into stats array. + */ +static struct digest_types : std::bitset +{ + digest_types () + { + set (WEAPON); + set (BOW); + set (ARMOUR); + set (HELMET); + set (SHIELD); + set (RING); + set (BOOTS); + set (GLOVES); + set (AMULET); + set (GIRDLE); + set (BRACERS); + set (CLOAK); + set (DISEASE); + set (FORCE); + set (SKILL); + } +} digest_types; + +static struct copy_flags : object::flags_t +{ + copy_flags () + { + set (FLAG_LIFESAVE); + set (FLAG_REFL_SPELL); + set (FLAG_REFL_MISSILE); + set (FLAG_STEALTH); + set (FLAG_XRAYS); + set (FLAG_BLIND); + set (FLAG_SEE_IN_DARK); + } +} copy_flags; + /* * Updates all abilities given by applied objects in the inventory * of the given object. Note: This function works for both monsters @@ -720,7 +760,7 @@ object::update_stats () { int i, j; - float f, max = 9, added_speed = 0, bonus_speed = 0, sp_tmp, speed_reduce_from_disease = 1; + float f, max_speed = 9, added_speed = 0, bonus_speed = 0, speed_reduce_from_disease = 1; int weapon_weight = 0, weapon_speed = 0; int best_wc = 0, best_ac = 0, wc = 0, ac = 0; int prot[NROFATTACKS], vuln[NROFATTACKS], potion_resist[NROFATTACKS]; @@ -801,7 +841,7 @@ */ if (!QUERY_FLAG (this, FLAG_USE_ARMOUR) && type == PLAYER) { - ac = MAX (-10, arch->stats.ac - level / 3); + ac = max (-10, arch->stats.ac - level / 3); prot[ATNR_PHYSICAL] += ((100 - prot[AT_PHYSICAL]) * (80 * level / settings.max_level)) / 100; } else @@ -866,6 +906,8 @@ { if (type == PLAYER) { + contr->item_power += tmp->item_power; + if (tmp == contr->combat_ob || tmp == contr->ranged_ob) if (tmp != current_weapon && (tmp->type != SKILL || tmp->subtype != SK_PRAYING) @@ -873,28 +915,17 @@ && !tmp->flag [FLAG_DAMNED]) continue; - for (i = 0; i < NUM_STATS; i++) - change_attr_value (&stats, i, tmp->stats.stat (i)); + for (int i = 0; i < NUM_STATS; i++) + if (expect_false (tmp->stats.stat (i))) + stats.stat (i) = clamp (stats.stat (i) + tmp->stats.stat (i), MIN_STAT, MAX_STAT); - /* These are the items that currently can change digestion, regeneration, - * spell point recovery and mana point recovery. Seems sort of an arbitary - * list, but other items store other info into stats array. - */ - if (tmp->type == WEAPON || tmp->type == BOW || - tmp->type == ARMOUR || tmp->type == HELMET || - tmp->type == SHIELD || tmp->type == RING || - tmp->type == BOOTS || tmp->type == GLOVES || - tmp->type == AMULET || tmp->type == GIRDLE || - tmp->type == BRACERS || tmp->type == CLOAK || - tmp->type == DISEASE || tmp->type == FORCE || - tmp->type == SKILL) + if (digest_types [tmp->type]) { - contr->digestion += tmp->stats.food; + contr->digestion = clamp (int (contr->digestion) + tmp->stats.food, MIN_DIGESTION, MAX_DIGESTION); contr->gen_hp += tmp->stats.hp; contr->gen_sp += tmp->stats.sp; contr->gen_grace += tmp->stats.grace; contr->gen_sp_armour += tmp->gen_sp_armour; - contr->item_power += tmp->item_power; } } /* if this is a player */ else @@ -931,7 +962,7 @@ if (tmp->type == POTION_EFFECT) { if (potion_resist[i]) - potion_resist[i] = MAX (potion_resist[i], tmp->resist[i]); + potion_resist[i] = max (potion_resist[i], tmp->resist[i]); else potion_resist[i] = tmp->resist[i]; } @@ -953,13 +984,7 @@ stats.luck += tmp->stats.luck; } - if (QUERY_FLAG (tmp, FLAG_LIFESAVE )) SET_FLAG (this, FLAG_LIFESAVE); - if (QUERY_FLAG (tmp, FLAG_REFL_SPELL )) SET_FLAG (this, FLAG_REFL_SPELL); - if (QUERY_FLAG (tmp, FLAG_REFL_MISSILE)) SET_FLAG (this, FLAG_REFL_MISSILE); - if (QUERY_FLAG (tmp, FLAG_STEALTH )) SET_FLAG (this, FLAG_STEALTH); - if (QUERY_FLAG (tmp, FLAG_XRAYS )) SET_FLAG (this, FLAG_XRAYS); - if (QUERY_FLAG (tmp, FLAG_BLIND )) SET_FLAG (this, FLAG_BLIND); - if (QUERY_FLAG (tmp, FLAG_SEE_IN_DARK )) SET_FLAG (this, FLAG_SEE_IN_DARK); + flag |= tmp->flag & copy_flags; if (QUERY_FLAG (tmp, FLAG_UNDEAD) && !QUERY_FLAG (arch, FLAG_UNDEAD)) SET_FLAG (this, FLAG_UNDEAD); @@ -1126,8 +1151,8 @@ if (tmp->stats.ac) ac -= (tmp->stats.ac + tmp->magic); - if (ARMOUR_SPEED (tmp) && ARMOUR_SPEED (tmp) / 10.f < max) - max = ARMOUR_SPEED (tmp) / 10.f; + if (ARMOUR_SPEED (tmp)) + max_speed = min (max_speed, ARMOUR_SPEED (tmp) / 10.f); break; } /* switch tmp->type */ @@ -1171,12 +1196,10 @@ j = contr->levhp[i] + con_bonus[stats.Con] / 2; if (i % 2 && con_bonus[stats.Con] % 2) - { - if (con_bonus[stats.Con] > 0) - j++; - else - j--; - } + if (con_bonus[stats.Con] > 0) + j++; + else + j--; stats.maxhp += j > 1 ? j : 1; /* always get at least 1 hp/level */ } @@ -1205,9 +1228,9 @@ stats.maxsp = 1; else { - sp_tmp = 0.f; + float sp_tmp = 0.f; - for (i = 1; i <= mana_obj->level && i <= 10; i++) + for (i = 1; i <= min (10, mana_obj->level); i++) { float stmp; @@ -1217,21 +1240,14 @@ else stmp = contr->levsp[i] + (2.f * sp_bonus[stats.Pow] + sp_bonus[stats.Int]) / 12.f; - if (stmp < 1.f) - stmp = 1.f; - - sp_tmp += stmp; + sp_tmp += max (1.f, stmp); } - stats.maxsp = (sint16)sp_tmp; - - for (i = 11; i <= mana_obj->level; i++) - stats.maxsp += 2; + stats.maxsp = int (sp_tmp) + 2 * max (0, mana_obj->level - 10); } /* Characters can get their sp supercharged via rune of transferrance */ - if (stats.sp > stats.maxsp * 2) - stats.sp = stats.maxsp * 2; + stats.sp = min (stats.sp, stats.maxsp * 2); /* set maxgrace, notice 3-4 lines below it depends on both Wis and Pow */ if (!grace_obj || !grace_obj->level || type != PLAYER) @@ -1246,8 +1262,9 @@ * becomes big jumps when the sums of the bonuses jump to the next * step of 8 - with floats, even fractional ones are useful. */ - sp_tmp = 0.f; - for (i = 1, stats.maxgrace = 0; i <= grace_obj->level && i <= 10; i++) + float sp_tmp = 0.f; + + for (i = 1; i <= min (10, grace_obj->level); i++) { float grace_tmp = 0.f; @@ -1257,17 +1274,11 @@ else grace_tmp = contr->levgrace[i] + (grace_bonus[stats.Pow] + 2.f * grace_bonus[stats.Wis]) / 12.f; - if (grace_tmp < 1.f) - grace_tmp = 1.f; - - sp_tmp += grace_tmp; + sp_tmp += max (1.f, grace_tmp); } - stats.maxgrace = (sint16)sp_tmp; - - /* two grace points per level after 11 */ - for (i = 11; i <= grace_obj->level; i++) - stats.maxgrace += 2; + /* two grace points per level after 10 */ + stats.maxgrace = int (sp_tmp) + 2 * max (0, grace_obj->level - 10); } /* No limit on grace vs maxgrace */ @@ -1331,8 +1342,7 @@ speed /= 1.f - added_speed; /* Max is determined by armour */ - if (speed > max) - speed = max; + speed = min (speed, max_speed); if (type == PLAYER) { @@ -1510,14 +1520,11 @@ char buf[MAX_BUF]; /* tmp. string buffer */ /* now grab the 'dragon_ability'-forces from the player's inventory */ - shstr_cmp dragon_ability_force ("dragon_ability_force"); - shstr_cmp dragon_skin_force ("dragon_skin_force"); - for (tmp = who->inv; tmp; tmp = tmp->below) if (tmp->type == FORCE) - if (tmp->arch->archname == dragon_ability_force) + if (tmp->arch->archname == shstr_dragon_ability_force) abil = tmp; - else if (tmp->arch->archname == dragon_skin_force) + else if (tmp->arch->archname == shstr_dragon_skin_force) skin = tmp; /* if the force is missing -> bail out */ @@ -1603,12 +1610,15 @@ player_lvl_adj (object *who, object *op) { char buf[MAX_BUF]; + bool changed = false; if (!op) /* when rolling stats */ op = who; - if (op->level < settings.max_level && op->stats.exp >= level_exp (op->level + 1, who->expmul)) + while (op->level < settings.max_level && op->stats.exp >= level_exp (op->level + 1, who->expmul)) { + changed = true; + op->level++; if (op && op == who && op->stats.exp > 1 && is_dragon_pl (who)) @@ -1622,37 +1632,44 @@ who->contr->levgrace[who->level] = die_roll (2, 2, who, PREFER_HIGH) - 1; } - who->update_stats (); if (op->level > 1) { if (op->type != PLAYER) - sprintf (buf, "You are now level %d in the %s skill.", op->level, &op->name); + { + who->contr->play_sound (sound_find ("skill_up")); + sprintf (buf, "You are now level %d in the %s skill.", op->level, &op->name); + } else - sprintf (buf, "You are now level %d.", op->level); + { + who->contr->play_sound (sound_find ("level_up")); + sprintf (buf, "You are now level %d.", op->level); + } if (who) new_draw_info (NDI_UNIQUE | NDI_RED, 0, who, buf); } - - player_lvl_adj (who, op); /* To increase more levels */ } - else if (op->level > 1 && op->stats.exp < level_exp (op->level, who->expmul)) + + while (op->level > 1 && op->stats.exp < level_exp (op->level, who->expmul)) { + changed = true; + op->level--; - who->update_stats (); if (op->type != PLAYER) { sprintf (buf, "You are now level %d in the %s skill.", op->level, &op->name); new_draw_info (NDI_UNIQUE | NDI_RED, 0, who, buf); } - - player_lvl_adj (who, op); /* To decrease more levels */ } - /* check if the spell data has changed */ - esrv_update_stats (who->contr); - esrv_update_spells (who->contr); + if (changed) + { + who->update_stats (); + esrv_update_stats (who->contr); + /* check if the spell data has changed */ + esrv_update_spells (who->contr); + } } /*