int32 Client::CalcBaseEndurance() { int32 base_end = 0; if(GetClientVersion() >= EQClientSoF && RuleB(Character, SoDClientUseSoDHPManaEnd)) { double heroic_stats = (GetHeroicSTR() + GetHeroicSTA() + GetHeroicDEX() + GetHeroicAGI()) / 4.0f; double stats = (GetSTR() + GetSTA() + GetDEX() + GetAGI()) / 4.0f; if(stats > 201.0f) { stats = 1.25f * (stats - 201.0f) + 352.5f; } else if(stats > 100.0f) { stats = 2.5f * (stats - 100.0f) + 100.0f; } auto base_data = database.GetBaseData(GetLevel(), GetClass()); if(base_data) { base_end = base_data->base_end + (heroic_stats * 10.0f) + (base_data->endurance_factor * static_cast<int>(stats)); } } else { int Stats = GetSTR()+GetSTA()+GetDEX()+GetAGI(); int LevelBase = GetLevel() * 15; int at_most_800 = Stats; if(at_most_800 > 800) at_most_800 = 800; int Bonus400to800 = 0; int HalfBonus400to800 = 0; int Bonus800plus = 0; int HalfBonus800plus = 0; int BonusUpto800 = int( at_most_800 / 4 ) ; if(Stats > 400) { Bonus400to800 = int( (at_most_800 - 400) / 4 ); HalfBonus400to800 = int( std::max( ( at_most_800 - 400 ), 0 ) / 8 ); if(Stats > 800) { Bonus800plus = int( (Stats - 800) / 8 ) * 2; HalfBonus800plus = int( (Stats - 800) / 16 ); } } int bonus_sum = BonusUpto800 + Bonus400to800 + HalfBonus400to800 + Bonus800plus + HalfBonus800plus; base_end = LevelBase; //take all of the sums from above, then multiply by level*0.075 base_end += ( bonus_sum * 3 * GetLevel() ) / 40; } return base_end; }
int32 Client::CalcEnduranceRegen(bool bCombat) { int base = 0; if (!IsStarved()) { auto base_data = database.GetBaseData(GetLevel(), GetClass()); if (base_data) { base = static_cast<int>(base_data->end_regen); if (!auto_attack && base > 0) base += base / 2; } } // so when we are mounted, our local client SpeedRun is always 0, so this is always false, but the packets we process it to our own shit :P bool is_running = runmode && animation != 0 && GetHorseId() == 0; // TODO: animation is really what MQ2 calls SpeedRun int weight_limit = GetSTR(); auto level = GetLevel(); if (GetClass() == MONK) { if (level > 99) weight_limit = 58; else if (level > 94) weight_limit = 57; else if (level > 89) weight_limit = 56; else if (level > 84) weight_limit = 55; else if (level > 79) weight_limit = 54; else if (level > 64) weight_limit = 53; else if (level > 63) weight_limit = 50; else if (level > 61) weight_limit = 47; else if (level > 59) weight_limit = 45; else if (level > 54) weight_limit = 40; else if (level > 50) weight_limit = 38; else if (level > 44) weight_limit = 36; else if (level > 29) weight_limit = 34; else if (level > 14) weight_limit = 32; else weight_limit = 30; } bool encumbered = (CalcCurrentWeight() / 10) >= weight_limit; if (is_running) base += level / -15; if (encumbered) base += level / -15; auto item_bonus = GetHeroicAGI() + GetHeroicDEX() + GetHeroicSTA() + GetHeroicSTR(); item_bonus = item_bonus / 4 / 50; item_bonus += itembonuses.EnduranceRegen; // this is capped already base += item_bonus; base = base * AreaEndRegen + 0.5f; auto aa_regen = aabonuses.EnduranceRegen; int regen = base; if (!bCombat && CanFastRegen() && (IsSitting() || CanMedOnHorse())) { auto max_end = GetMaxEndurance(); int fast_regen = 6 * (max_end / zone->newzone_data.FastRegenEndurance); if (aa_regen < fast_regen) // weird, but what the client is doing aa_regen = fast_regen; } regen += aa_regen; regen += spellbonuses.EnduranceRegen; // TODO: client does this in buff tick return (regen * RuleI(Character, EnduranceRegenMultiplier) / 100); }
int32 Client::CalcBaseEndurance() { int32 base_end = 0; int32 base_endurance = 0; int32 ConvertedStats = 0; int32 sta_end = 0; int Stats = 0; if(GetClientVersion() >= EQClientSoD && RuleB(Character, SoDClientUseSoDHPManaEnd)) { int HeroicStats = 0; Stats = ((GetSTR() + GetSTA() + GetDEX() + GetAGI()) / 4); HeroicStats = ((GetHeroicSTR() + GetHeroicSTA() + GetHeroicDEX() + GetHeroicAGI()) / 4); if (Stats > 100) { ConvertedStats = (((Stats - 100) * 5 / 2) + 100); if (Stats > 201) { ConvertedStats -= ((Stats - 201) * 5 / 4); } } else { ConvertedStats = Stats; } if (GetLevel() < 41) { sta_end = (GetLevel() * 75 * ConvertedStats / 1000); base_endurance = (GetLevel() * 15); } else if (GetLevel() < 81) { sta_end = ((3 * ConvertedStats) + ((GetLevel() - 40) * 15 * ConvertedStats / 100)); base_endurance = (600 + ((GetLevel() - 40) * 30)); } else { sta_end = (9 * ConvertedStats); base_endurance = (1800 + ((GetLevel() - 80) * 18)); } base_end = (base_endurance + sta_end + (HeroicStats * 10)); } else { Stats = GetSTR()+GetSTA()+GetDEX()+GetAGI(); int LevelBase = GetLevel() * 15; int at_most_800 = Stats; if(at_most_800 > 800) at_most_800 = 800; int Bonus400to800 = 0; int HalfBonus400to800 = 0; int Bonus800plus = 0; int HalfBonus800plus = 0; int BonusUpto800 = int( at_most_800 / 4 ) ; if(Stats > 400) { Bonus400to800 = int( (at_most_800 - 400) / 4 ); HalfBonus400to800 = int( max( ( at_most_800 - 400 ), 0 ) / 8 ); if(Stats > 800) { Bonus800plus = int( (Stats - 800) / 8 ) * 2; HalfBonus800plus = int( (Stats - 800) / 16 ); } } int bonus_sum = BonusUpto800 + Bonus400to800 + HalfBonus400to800 + Bonus800plus + HalfBonus800plus; base_end = LevelBase; //take all of the sums from above, then multiply by level*0.075 base_end += ( bonus_sum * 3 * GetLevel() ) / 40; } return base_end; }