[Feature] Add Data Bucket support for scaling of Heroic Stats. (#3058)

* [Feature] Add Data Bucket support for scaling of Heroic Stats.

* update

* fixes, still reworking logic

* fixes, still reworking logic

* logic done

* logic done

* fixes

* Cleanup

* Cleanup

* Cleanup naming, verify behaviors

* formatting

* formatting

* fix issue with endurance and mana.

* update rule desc

* cleanup

* DataBucket Struct

* Cleanup data_bucket.cpp and add constants

* cleanup

* changes

* formatting

* fix from merge

* escape keyword `key`

* Add `key` to generator, run repository-generator.pl

* fix for change to key

* cleanup

* formatting

* formatting

* typo
This commit is contained in:
Aeadoin
2023-03-23 21:42:13 -04:00
committed by GitHub
parent abc27ab423
commit 59ad91a140
28 changed files with 433 additions and 243 deletions
+142 -1
View File
@@ -77,6 +77,7 @@ void Client::CalcBonuses()
{
memset(&itembonuses, 0, sizeof(StatBonuses));
CalcItemBonuses(&itembonuses);
CalcHeroicBonuses(&itembonuses);
CalcEdibleBonuses(&itembonuses);
CalcSpellBonuses(&spellbonuses);
CalcAABonuses(&aabonuses);
@@ -204,7 +205,7 @@ void Client::CalcItemBonuses(StatBonuses* newbon) {
}
// These item stat caps depend on spells/AAs so we process them after those are processed
void Client::ProcessItemCaps()
void Mob::ProcessItemCaps()
{
itembonuses.HPRegen = std::min(itembonuses.HPRegen, CalcHPRegenCap());
itembonuses.ManaRegen = std::min(itembonuses.ManaRegen, CalcManaRegenCap());
@@ -219,6 +220,15 @@ void Client::ProcessItemCaps()
}
itembonuses.ATK = std::min(itembonuses.ATK, CalcItemATKCap());
if (itembonuses.SpellDmg > RuleI(Character, ItemSpellDmgCap)) {
itembonuses.SpellDmg = RuleI(Character, ItemSpellDmgCap);
}
if (itembonuses.HealAmt > RuleI(Character, ItemHealAmtCap)) {
itembonuses.HealAmt = RuleI(Character, ItemHealAmtCap);
}
}
void Client::AddItemBonuses(const EQ::ItemInstance *inst, StatBonuses *newbon, bool isAug, bool isTribute, int rec_override, bool ammo_slot_item)
@@ -5634,3 +5644,134 @@ void Mob::NegateSpellEffectBonuses(uint16 spell_id)
}
}
}
void Mob::CalcHeroicBonuses(StatBonuses* newbon)
{
if (GetHeroicSTR()) {
SetHeroicStrBonuses(newbon);
}
if (GetHeroicSTA()) {
SetHeroicStaBonuses(newbon);
}
if (GetHeroicAGI()) {
SetHeroicAgiBonuses(newbon);
}
if (GetHeroicDEX()) {
SetHeroicDexBonuses(newbon);
}
if (GetHeroicINT()) {
SetHeroicIntBonuses(newbon);
}
if (GetHeroicWIS()) {
SetHeroicWisBonuses(newbon);
}
}
void Mob::SetHeroicWisBonuses(StatBonuses* n)
{
n->heroic_max_mana += IsWISCasterClass(GetClass()) ? GetHeroicWIS() * RuleR(Character, HeroicWisdomMultiplier) * 10 : 0;
n->heroic_mana_regen += IsWISCasterClass(GetClass()) ? GetHeroicWIS() * RuleR(Character, HeroicWisdomMultiplier) / 25 : 0;
n->HealAmt += GetHeroicWIS() * RuleR(Character, HeroicWisdomIncreaseHealAmtMultiplier);
if (RuleB(Character, HeroicStatsUseDataBucketsToScale)) {
n->heroic_max_mana += IsWISCasterClass(GetClass()) ? GetHeroicWIS() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::WisMaxMana) * 10 : 0;
n->heroic_mana_regen += IsWISCasterClass(GetClass()) ? GetHeroicWIS() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::WisManaRegen) / 25 : 0;
n->HealAmt += GetHeroicWIS() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::WisHealAmt);
}
}
void Mob::SetHeroicIntBonuses(StatBonuses* n)
{
n->heroic_max_mana += IsINTCasterClass(GetClass()) ? GetHeroicINT() * RuleR(Character, HeroicIntelligenceMultiplier) * 10 : 0;
n->heroic_mana_regen += IsINTCasterClass(GetClass()) ? GetHeroicINT() * RuleR(Character, HeroicIntelligenceMultiplier) / 25 : 0;
n->SpellDmg += GetHeroicINT() * RuleR(Character, HeroicIntelligenceIncreaseSpellDmgMultiplier);
if (RuleB(Character, HeroicStatsUseDataBucketsToScale)) {
n->heroic_max_mana += IsINTCasterClass(GetClass()) ? GetHeroicINT() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::IntMaxMana) * 10 : 0;
n->heroic_mana_regen += IsINTCasterClass(GetClass()) ? GetHeroicINT() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::IntManaRegen) / 25 : 0;
n->SpellDmg += GetHeroicINT() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::IntSpellDmg);
}
}
void Mob::SetHeroicDexBonuses(StatBonuses* n)
{
n->heroic_dex_ranged_damage += GetHeroicDEX() * RuleR(Character, HeroicDexterityMultiplier) / 10;
n->heroic_max_end += GetHeroicDEX() * RuleR(Character, HeroicDexterityMultiplier) / 4 * 10.0f;
n->heroic_end_regen += GetHeroicDEX() * RuleR(Character, HeroicDexterityMultiplier) / 4 / 50;
if (RuleB(Character, HeroicStatsUseDataBucketsToScale)) {
n->heroic_dex_ranged_damage += GetHeroicDEX() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::DexRangedDamage) / 10;
n->heroic_max_end += GetHeroicDEX() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::DexMaxEndurance) / 4 * 10.0f;
n->heroic_end_regen += GetHeroicDEX() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::DexEnduranceRegen) / 4 / 50;
}
}
void Mob::SetHeroicAgiBonuses(StatBonuses* n)
{
n->heroic_agi_avoidance += GetHeroicAGI() * RuleR(Character, HeroicAgilityMultiplier) / 10;
n->heroic_max_end += GetHeroicAGI() * RuleR(Character, HeroicAgilityMultiplier) / 4 * 10.0f;
n->heroic_end_regen += GetHeroicAGI() * RuleR(Character, HeroicAgilityMultiplier) / 4 / 50;
if (RuleB(Character, HeroicStatsUseDataBucketsToScale)) {
n->heroic_agi_avoidance += GetHeroicAGI() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::AgiAvoidance) / 10;
n->heroic_max_end += GetHeroicAGI() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::AgiMaxEndurance) / 4 * 10.0f;
n->heroic_end_regen += GetHeroicAGI() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::AgiEnduranceRegen) / 4 / 50;
}
}
void Mob::SetHeroicStaBonuses(StatBonuses* n)
{
n->heroic_max_hp += GetHeroicSTA() * RuleR(Character, HeroicStaminaMultiplier) * 10;
n->heroic_hp_regen += GetHeroicSTA() * RuleR(Character, HeroicStaminaMultiplier) / 20;
n->heroic_max_end += GetHeroicSTA() * RuleR(Character, HeroicStaminaMultiplier) / 4 * 10.0f;
n->heroic_end_regen += GetHeroicSTA() * RuleR(Character, HeroicStaminaMultiplier) / 4 / 50;
if (RuleB(Character, HeroicStatsUseDataBucketsToScale)) {
n->heroic_max_hp += GetHeroicSTA() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::StaMaxHP) * 10;
n->heroic_hp_regen += GetHeroicSTA() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::StaHPRegen) / 20;
n->heroic_max_end += GetHeroicSTA() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::StaMaxEndurance) / 4 * 10.0f;
n->heroic_end_regen += GetHeroicSTA() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::StaEnduranceRegen) / 4 / 50;
}
}
void Mob::SetHeroicStrBonuses(StatBonuses* n)
{
n->heroic_str_shield_ac += GetHeroicSTR() * RuleR(Character, HeroicStrengthMultiplier) / 10;
n->heroic_str_melee_damage += GetHeroicSTR() * RuleR(Character, HeroicStrengthMultiplier) / 10;
n->heroic_max_end += GetHeroicSTR() * RuleR(Character, HeroicStrengthMultiplier) / 4 * 10.0f;
n->heroic_end_regen += GetHeroicSTR() * RuleR(Character, HeroicStrengthMultiplier) / 4 / 50;
if (RuleB(Character, HeroicStatsUseDataBucketsToScale)) {
n->heroic_str_shield_ac += GetHeroicSTR() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::StrShieldAC) / 10;
n->heroic_str_melee_damage += GetHeroicSTR() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::StrMeleeDamage) / 10;
n->heroic_max_end += GetHeroicSTR() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::StrMaxEndurance) / 4 * 10.0f;
n->heroic_end_regen += GetHeroicSTR() * CheckHeroicBonusesDataBuckets(HeroicBonusBucket::StrEnduranceRegen) / 4 / 50;
}
}
float Mob::CheckHeroicBonusesDataBuckets(std::string bucket_name)
{
std::string bucket_value;
if (!bucket_name.empty()) {
const auto full_name = fmt::format(
"{}-{}",
GetBucketKey(),
bucket_name
);
if (IsOfClientBot()) {
bucket_value = DataBucket::CheckBucketKey(this, full_name);
}
if (bucket_value.empty() || !Strings::IsNumber(bucket_value)) {
return 0.00f;
}
}
return Strings::ToFloat(bucket_value);
}