diff --git a/zone/bot.cpp b/zone/bot.cpp index 9a68f843f..0857a9a1c 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -2287,7 +2287,7 @@ bool Bot::TryMeditate() { if (!IsMoving() && !spellend_timer.Enabled()) { if (GetTarget() && AI_EngagedCastCheck()) { BotMeditate(false); - } else if (GetArchetype() == ARCHETYPE_CASTER) { + } else if (GetArchetype() == Archetype::Caster) { BotMeditate(true); } @@ -2755,7 +2755,7 @@ Mob* Bot::GetBotTarget(Client* bot_owner) } } - if (GetArchetype() == ARCHETYPE_CASTER) { + if (GetArchetype() == Archetype::Caster) { BotMeditate(true); } } @@ -5189,31 +5189,26 @@ void Bot::ProcessBotOwnerRefDelete(Mob* botOwner) { } } -int64 Bot::CalcMaxMana() { - switch(GetCasterClass()) { - case 'I': - max_mana = (GenerateBaseManaPoints() + itembonuses.Mana + spellbonuses.Mana + aabonuses.Mana + GroupLeadershipAAManaEnhancement()); - max_mana += itembonuses.heroic_max_mana; - case 'W': { - max_mana = (GenerateBaseManaPoints() + itembonuses.Mana + spellbonuses.Mana + aabonuses.Mana + GroupLeadershipAAManaEnhancement()); - max_mana += itembonuses.heroic_max_mana; - break; - } - case 'N': { - max_mana = 0; - break; - } - default: { - LogDebug("Invalid Class [{}] in CalcMaxMana", GetCasterClass()); - max_mana = 0; - break; - } +int64 Bot::CalcMaxMana() +{ + if (IsIntelligenceCasterClass() || IsWisdomCasterClass()) { + max_mana = ( + GenerateBaseManaPoints() + + itembonuses.Mana + + spellbonuses.Mana + + aabonuses.Mana + + GroupLeadershipAAManaEnhancement() + ); + max_mana += itembonuses.heroic_max_mana; + } else { + max_mana = 0; } - if (current_mana > max_mana) + if (current_mana > max_mana) { current_mana = max_mana; - else if (max_mana < 0) + } else if (max_mana < 0) { max_mana = 0; + } return max_mana; } @@ -5528,87 +5523,107 @@ bool Bot::DoCastSpell(uint16 spell_id, uint16 target_id, EQ::spells::CastingSlot return Result; } -int32 Bot::GenerateBaseManaPoints() { - int32 bot_mana = 0; - int32 WisInt = 0; +int32 Bot::GenerateBaseManaPoints() +{ + int32 bot_mana = 0; + int32 WisInt = 0; int32 MindLesserFactor, MindFactor; - int wisint_mana = 0; - int base_mana = 0; - int ConvertedWisInt = 0; - switch(GetCasterClass()) { - case 'I': - WisInt = INT; - if (GetOwner() && GetOwner()->CastToClient() && GetOwner()->CastToClient()->ClientVersion() >= EQ::versions::ClientVersion::SoD && RuleB(Character, SoDClientUseSoDHPManaEnd)) { - if (WisInt > 100) { - ConvertedWisInt = (((WisInt - 100) * 5 / 2) + 100); - if (WisInt > 201) - ConvertedWisInt -= ((WisInt - 201) * 5 / 4); - } - else - ConvertedWisInt = WisInt; + int wisint_mana = 0; + int base_mana = 0; + int ConvertedWisInt = 0; - if (GetLevel() < 41) { - wisint_mana = (GetLevel() * 75 * ConvertedWisInt / 1000); - base_mana = (GetLevel() * 15); - } else if (GetLevel() < 81) { - wisint_mana = ((3 * ConvertedWisInt) + ((GetLevel() - 40) * 15 * ConvertedWisInt / 100)); - base_mana = (600 + ((GetLevel() - 40) * 30)); - } else { - wisint_mana = (9 * ConvertedWisInt); - base_mana = (1800 + ((GetLevel() - 80) * 18)); + if (IsIntelligenceCasterClass()) { + WisInt = INT; + + if ( + GetOwner() && + GetOwner()->CastToClient() && + GetOwner()->CastToClient()->ClientVersion() >= EQ::versions::ClientVersion::SoD && + RuleB(Character, SoDClientUseSoDHPManaEnd) + ) { + if (WisInt > 100) { + ConvertedWisInt = (((WisInt - 100) * 5 / 2) + 100); + if (WisInt > 201) { + ConvertedWisInt -= ((WisInt - 201) * 5 / 4); } - bot_mana = (base_mana + wisint_mana); } else { - if (((WisInt - 199) / 2) > 0) - MindLesserFactor = ((WisInt - 199) / 2); - else - MindLesserFactor = 0; - - MindFactor = WisInt - MindLesserFactor; - if (WisInt > 100) - bot_mana = (((5 * (MindFactor + 20)) / 2) * 3 * GetLevel() / 40); - else - bot_mana = (((5 * (MindFactor + 200)) / 2) * 3 * GetLevel() / 100); + ConvertedWisInt = WisInt; } - break; - case 'W': - WisInt = WIS; - if (GetOwner() && GetOwner()->CastToClient() && GetOwner()->CastToClient()->ClientVersion() >= EQ::versions::ClientVersion::SoD && RuleB(Character, SoDClientUseSoDHPManaEnd)) { - if (WisInt > 100) { - ConvertedWisInt = (((WisInt - 100) * 5 / 2) + 100); - if (WisInt > 201) - ConvertedWisInt -= ((WisInt - 201) * 5 / 4); - } else - ConvertedWisInt = WisInt; - if (GetLevel() < 41) { - wisint_mana = (GetLevel() * 75 * ConvertedWisInt / 1000); - base_mana = (GetLevel() * 15); - } else if (GetLevel() < 81) { - wisint_mana = ((3 * ConvertedWisInt) + ((GetLevel() - 40) * 15 * ConvertedWisInt / 100)); - base_mana = (600 + ((GetLevel() - 40) * 30)); - } else { - wisint_mana = (9 * ConvertedWisInt); - base_mana = (1800 + ((GetLevel() - 80) * 18)); - } - bot_mana = (base_mana + wisint_mana); + if (GetLevel() < 41) { + wisint_mana = (GetLevel() * 75 * ConvertedWisInt / 1000); + base_mana = (GetLevel() * 15); + } else if (GetLevel() < 81) { + wisint_mana = ((3 * ConvertedWisInt) + ((GetLevel() - 40) * 15 * ConvertedWisInt / 100)); + base_mana = (600 + ((GetLevel() - 40) * 30)); } else { - if (((WisInt - 199) / 2) > 0) - MindLesserFactor = ((WisInt - 199) / 2); - else - MindLesserFactor = 0; - - MindFactor = (WisInt - MindLesserFactor); - if (WisInt > 100) - bot_mana = (((5 * (MindFactor + 20)) / 2) * 3 * GetLevel() / 40); - else - bot_mana = (((5 * (MindFactor + 200)) / 2) * 3 * GetLevel() / 100); + wisint_mana = (9 * ConvertedWisInt); + base_mana = (1800 + ((GetLevel() - 80) * 18)); } - break; - default: - bot_mana = 0; - break; + + bot_mana = (base_mana + wisint_mana); + } else { + if (((WisInt - 199) / 2) > 0) { + MindLesserFactor = ((WisInt - 199) / 2); + } else { + MindLesserFactor = 0; + } + + MindFactor = WisInt - MindLesserFactor; + if (WisInt > 100) { + bot_mana = (((5 * (MindFactor + 20)) / 2) * 3 * GetLevel() / 40); + } else { + bot_mana = (((5 * (MindFactor + 200)) / 2) * 3 * GetLevel() / 100); + } + } + } else if (IsWisdomCasterClass()) { + WisInt = WIS; + + if ( + GetOwner() && + GetOwner()->CastToClient() && + GetOwner()->CastToClient()->ClientVersion() >= EQ::versions::ClientVersion::SoD && + RuleB(Character, SoDClientUseSoDHPManaEnd) + ) { + if (WisInt > 100) { + ConvertedWisInt = (((WisInt - 100) * 5 / 2) + 100); + if (WisInt > 201) { + ConvertedWisInt -= ((WisInt - 201) * 5 / 4); + } + } else { + ConvertedWisInt = WisInt; + } + + if (GetLevel() < 41) { + wisint_mana = (GetLevel() * 75 * ConvertedWisInt / 1000); + base_mana = (GetLevel() * 15); + } else if (GetLevel() < 81) { + wisint_mana = ((3 * ConvertedWisInt) + ((GetLevel() - 40) * 15 * ConvertedWisInt / 100)); + base_mana = (600 + ((GetLevel() - 40) * 30)); + } else { + wisint_mana = (9 * ConvertedWisInt); + base_mana = (1800 + ((GetLevel() - 80) * 18)); + } + + bot_mana = (base_mana + wisint_mana); + } else { + if (((WisInt - 199) / 2) > 0) { + MindLesserFactor = ((WisInt - 199) / 2); + } else { + MindLesserFactor = 0; + } + + MindFactor = (WisInt - MindLesserFactor); + if (WisInt > 100) { + bot_mana = (((5 * (MindFactor + 20)) / 2) * 3 * GetLevel() / 40); + } else { + bot_mana = (((5 * (MindFactor + 200)) / 2) * 3 * GetLevel() / 100); + } + } + } else { + bot_mana = 0; } + max_mana = bot_mana; return bot_mana; } diff --git a/zone/botspellsai.cpp b/zone/botspellsai.cpp index d42b02024..bb3ffca78 100644 --- a/zone/botspellsai.cpp +++ b/zone/botspellsai.cpp @@ -591,7 +591,7 @@ bool Bot::BotCastCombatBuff(Mob* tar, uint8 botLevel, uint8 botClass) { //Only check archetype if spell is not a group spell //Hybrids get all buffs switch (tar->GetArchetype()) { - case ARCHETYPE_CASTER: + case Archetype::Caster: //TODO: probably more caster specific spell effects in here if ( ( @@ -606,7 +606,7 @@ bool Bot::BotCastCombatBuff(Mob* tar, uint8 botLevel, uint8 botClass) { continue; } break; - case ARCHETYPE_MELEE: + case Archetype::Melee: if ( ( IsEffectInSpell(s.SpellId, SE_IncreaseSpellHaste) || @@ -899,7 +899,7 @@ bool Bot::BotCastBuff(Mob* tar, uint8 botLevel, uint8 botClass) { switch (tar->GetArchetype()) { - case ARCHETYPE_CASTER: + case Archetype::Caster: //TODO: probably more caster specific spell effects in here if (IsEffectInSpell(s.SpellId, SE_AttackSpeed) || IsEffectInSpell(s.SpellId, SE_ATK) || IsEffectInSpell(s.SpellId, SE_STR) || IsEffectInSpell(s.SpellId, SE_ReverseDS)) @@ -907,7 +907,7 @@ bool Bot::BotCastBuff(Mob* tar, uint8 botLevel, uint8 botClass) { continue; } break; - case ARCHETYPE_MELEE: + case Archetype::Melee: if (IsEffectInSpell(s.SpellId, SE_IncreaseSpellHaste) || IsEffectInSpell(s.SpellId, SE_ManaPool) || IsEffectInSpell(s.SpellId, SE_CastingLevel) || IsEffectInSpell(s.SpellId, SE_ManaRegen_v2) || IsEffectInSpell(s.SpellId, SE_CurrentMana)) diff --git a/zone/client_mods.cpp b/zone/client_mods.cpp index 43d6a9838..61c383a7e 100644 --- a/zone/client_mods.cpp +++ b/zone/client_mods.cpp @@ -523,28 +523,26 @@ int32 Client::GetRawItemAC() int64 Client::CalcMaxMana() { - switch (GetCasterClass()) { - case 'I': - case 'W': { - max_mana = (CalcBaseMana() + itembonuses.Mana + spellbonuses.Mana + aabonuses.Mana + GroupLeadershipAAManaEnhancement()); - break; - } - case 'N': { - max_mana = 0; - break; - } - default: { - LogSpells("Invalid Class [{}] in CalcMaxMana", GetCasterClass()); - max_mana = 0; - break; - } + if (IsIntelligenceCasterClass() || IsWisdomCasterClass()) { + max_mana = ( + CalcBaseMana() + + itembonuses.Mana + + spellbonuses.Mana + + aabonuses.Mana + + GroupLeadershipAAManaEnhancement() + ); + } else { + max_mana = 0; } + if (max_mana < 0) { max_mana = 0; } + if (current_mana > max_mana) { current_mana = max_mana; } + int mana_perc_cap = spellbonuses.ManaPercCap[SBIndex::RESOURCE_PERCENT_CAP]; if (mana_perc_cap) { int curMana_cap = (max_mana * mana_perc_cap) / 100; @@ -552,96 +550,90 @@ int64 Client::CalcMaxMana() current_mana = curMana_cap; } } + LogSpells("for [{}] returning [{}]", GetName(), max_mana); return max_mana; } int64 Client::CalcBaseMana() { - int ConvertedWisInt = 0; - int MindLesserFactor, MindFactor; - int WisInt = 0; - int64 base_mana = 0; - int wisint_mana = 0; - int64 max_m = 0; - switch (GetCasterClass()) { - case 'I': - WisInt = GetINT(); - if (ClientVersion() >= EQ::versions::ClientVersion::SoF && RuleB(Character, SoDClientUseSoDHPManaEnd)) { - ConvertedWisInt = WisInt; - int over200 = WisInt; - if (WisInt > 100) { - if (WisInt > 200) { - over200 = (WisInt - 200) / -2 + WisInt; - } - ConvertedWisInt = (3 * over200 - 300) / 2 + over200; - } - auto base_data = zone->GetBaseData(GetLevel(), GetClass()); - if (base_data.level == GetLevel()) { - max_m = base_data.mana + (ConvertedWisInt * base_data.mana_fac) + itembonuses.heroic_max_mana; + int ConvertedWisInt = 0; + int MindLesserFactor, MindFactor; + int WisInt = 0; + int64 base_mana = 0; + int wisint_mana = 0; + int64 max_m = 0; + + if (IsIntelligenceCasterClass()) { + WisInt = GetINT(); + + if (ClientVersion() >= EQ::versions::ClientVersion::SoF && RuleB(Character, SoDClientUseSoDHPManaEnd)) { + ConvertedWisInt = WisInt; + + int over200 = WisInt; + if (WisInt > 100) { + if (WisInt > 200) { + over200 = (WisInt - 200) / -2 + WisInt; } + ConvertedWisInt = (3 * over200 - 300) / 2 + over200; } - else { - if ((( WisInt - 199 ) / 2) > 0) { - MindLesserFactor = ( WisInt - 199 ) / 2; - } - else { - MindLesserFactor = 0; - } - MindFactor = WisInt - MindLesserFactor; - if (WisInt > 100) { - max_m = (((5 * (MindFactor + 20)) / 2) * 3 * GetLevel() / 40); - } - else { - max_m = (((5 * (MindFactor + 200)) / 2) * 3 * GetLevel() / 100); - } + + auto base_data = zone->GetBaseData(GetLevel(), GetClass()); + if (base_data.level == GetLevel()) { + max_m = base_data.mana + (ConvertedWisInt * base_data.mana_fac) + itembonuses.heroic_max_mana; } - break; - case 'W': - WisInt = GetWIS(); - if (ClientVersion() >= EQ::versions::ClientVersion::SoF && RuleB(Character, SoDClientUseSoDHPManaEnd)) { - ConvertedWisInt = WisInt; - int over200 = WisInt; - if (WisInt > 100) { - if (WisInt > 200) { - over200 = (WisInt - 200) / -2 + WisInt; - } - ConvertedWisInt = (3 * over200 - 300) / 2 + over200; - } - auto base_data = zone->GetBaseData(GetLevel(), GetClass()); - if (base_data.level == GetLevel()) { - max_m = base_data.mana + (ConvertedWisInt * base_data.mana_fac) + itembonuses.heroic_max_mana; - } + } else { + if (((WisInt - 199) / 2) > 0) { + MindLesserFactor = (WisInt - 199) / 2; + } else { + MindLesserFactor = 0; } - else { - if ((( WisInt - 199 ) / 2) > 0) { - MindLesserFactor = ( WisInt - 199 ) / 2; - } - else { - MindLesserFactor = 0; - } - MindFactor = WisInt - MindLesserFactor; - if (WisInt > 100) { - max_m = (((5 * (MindFactor + 20)) / 2) * 3 * GetLevel() / 40); - } - else { - max_m = (((5 * (MindFactor + 200)) / 2) * 3 * GetLevel() / 100); - } + + MindFactor = WisInt - MindLesserFactor; + + if (WisInt > 100) { + max_m = (((5 * (MindFactor + 20)) / 2) * 3 * GetLevel() / 40); + } else { + max_m = (((5 * (MindFactor + 200)) / 2) * 3 * GetLevel() / 100); } - break; - case 'N': { - max_m = 0; - break; + } + } else if (IsWisdomCasterClass()) { + WisInt = GetWIS(); + + if (ClientVersion() >= EQ::versions::ClientVersion::SoF && RuleB(Character, SoDClientUseSoDHPManaEnd)) { + ConvertedWisInt = WisInt; + + int over200 = WisInt; + if (WisInt > 100) { + if (WisInt > 200) { + over200 = (WisInt - 200) / -2 + WisInt; + } + ConvertedWisInt = (3 * over200 - 300) / 2 + over200; } - default: { - LogDebug("Invalid Class [{}] in CalcMaxMana", GetCasterClass()); - max_m = 0; - break; + + auto base_data = zone->GetBaseData(GetLevel(), GetClass()); + if (base_data.level == GetLevel()) { + max_m = base_data.mana + (ConvertedWisInt * base_data.mana_fac) + itembonuses.heroic_max_mana; } + } else { + if (((WisInt - 199) / 2) > 0) { + MindLesserFactor = (WisInt - 199) / 2; + } else { + MindLesserFactor = 0; + } + + MindFactor = WisInt - MindLesserFactor; + + if (WisInt > 100) { + max_m = (((5 * (MindFactor + 20)) / 2) * 3 * GetLevel() / 40); + } else { + max_m = (((5 * (MindFactor + 200)) / 2) * 3 * GetLevel() / 100); + } + } + } else { + max_m = 0; } - #if EQDEBUG >= 11 - LogDebug("Client::CalcBaseMana() called for [{}] - returning [{}]", GetName(), max_m); - #endif + return max_m; } diff --git a/zone/common.h b/zone/common.h index 9bbc75751..db56c41cf 100644 --- a/zone/common.h +++ b/zone/common.h @@ -19,9 +19,11 @@ #define HEAD_POSITION 0.9f //ratio of GetSize() where NPCs see from #define SEE_POSITION 0.5f //ratio of GetSize() where NPCs try to see for LOS -#define ARCHETYPE_HYBRID 1 -#define ARCHETYPE_CASTER 2 -#define ARCHETYPE_MELEE 3 +namespace Archetype { + constexpr uint8 Hybrid = 1; + constexpr uint8 Caster = 2; + constexpr uint8 Melee = 3; +}; #define CON_GREEN 2 #define CON_LIGHTBLUE 18 diff --git a/zone/lua_mob.cpp b/zone/lua_mob.cpp index ea4450e87..3320c5914 100644 --- a/zone/lua_mob.cpp +++ b/zone/lua_mob.cpp @@ -3333,6 +3333,30 @@ void Lua_Mob::RestoreMana() self->RestoreMana(); } +std::string Lua_Mob::GetArchetypeName() +{ + Lua_Safe_Call_String(); + return self->GetArchetypeName(); +} + +bool Lua_Mob::IsIntelligenceCasterClass() +{ + Lua_Safe_Call_Bool(); + return self->IsIntelligenceCasterClass(); +} + +bool Lua_Mob::IsPureMeleeClass() +{ + Lua_Safe_Call_Bool(); + return self->IsPureMeleeClass(); +} + +bool Lua_Mob::IsWisdomCasterClass() +{ + Lua_Safe_Call_Bool(); + return self->IsWisdomCasterClass(); +} + luabind::scope lua_register_mob() { return luabind::class_("Mob") .def(luabind::constructor<>()) @@ -3524,6 +3548,7 @@ luabind::scope lua_register_mob() { .def("GetAggroRange", (float(Lua_Mob::*)(void))&Lua_Mob::GetAggroRange) .def("GetAllowBeneficial", (bool(Lua_Mob::*)(void))&Lua_Mob::GetAllowBeneficial) .def("GetAppearance", (uint32(Lua_Mob::*)(void))&Lua_Mob::GetAppearance) + .def("GetArchetypeName", &Lua_Mob::GetArchetypeName) .def("GetAssistRange", (float(Lua_Mob::*)(void))&Lua_Mob::GetAssistRange) .def("GetBaseGender", &Lua_Mob::GetBaseGender) .def("GetBaseRace", &Lua_Mob::GetBaseRace) @@ -3732,6 +3757,7 @@ luabind::scope lua_register_mob() { .def("IsFindable", (bool(Lua_Mob::*)(void))&Lua_Mob::IsFindable) .def("IsHorse", &Lua_Mob::IsHorse) .def("IsImmuneToSpell", (bool(Lua_Mob::*)(int,Lua_Mob))&Lua_Mob::IsImmuneToSpell) + .def("IsIntelligenceCasterClass", &Lua_Mob::IsIntelligenceCasterClass) .def("IsInvisible", (bool(Lua_Mob::*)(Lua_Mob))&Lua_Mob::IsInvisible) .def("IsInvisible", (bool(Lua_Mob::*)(void))&Lua_Mob::IsInvisible) .def("IsMeleeDisabled", (bool(Lua_Mob::*)(void))&Lua_Mob::IsMeleeDisabled) @@ -3742,6 +3768,7 @@ luabind::scope lua_register_mob() { .def("IsPetOwnerBot", &Lua_Mob::IsPetOwnerBot) .def("IsPetOwnerClient", &Lua_Mob::IsPetOwnerClient) .def("IsPetOwnerNPC", &Lua_Mob::IsPetOwnerNPC) + .def("IsPureMeleeClass", &Lua_Mob::IsPureMeleeClass) .def("IsRoamer", (bool(Lua_Mob::*)(void))&Lua_Mob::IsRoamer) .def("IsRooted", (bool(Lua_Mob::*)(void))&Lua_Mob::IsRooted) .def("IsRunning", (bool(Lua_Mob::*)(void))&Lua_Mob::IsRunning) @@ -3753,6 +3780,7 @@ luabind::scope lua_register_mob() { .def("IsTemporaryPet", &Lua_Mob::IsTemporaryPet) .def("IsTrackable", (bool(Lua_Mob::*)(void))&Lua_Mob::IsTrackable) .def("IsWarriorClass", &Lua_Mob::IsWarriorClass) + .def("IsWisdomCasterClass", &Lua_Mob::IsWisdomCasterClass) .def("Kill", (void(Lua_Mob::*)(void))&Lua_Mob::Kill) .def("Mesmerize", (void(Lua_Mob::*)(void))&Lua_Mob::Mesmerize) .def("Message", &Lua_Mob::Message) diff --git a/zone/lua_mob.h b/zone/lua_mob.h index 9a4ecb808..d5ce442ac 100644 --- a/zone/lua_mob.h +++ b/zone/lua_mob.h @@ -586,6 +586,10 @@ public: void RestoreEndurance(); void RestoreHealth(); void RestoreMana(); + std::string GetArchetypeName(); + bool IsIntelligenceCasterClass(); + bool IsPureMeleeClass(); + bool IsWisdomCasterClass(); }; #endif diff --git a/zone/merc.cpp b/zone/merc.cpp index e01350073..b3cd88a37 100644 --- a/zone/merc.cpp +++ b/zone/merc.cpp @@ -489,23 +489,12 @@ int64 Merc::CalcBaseHP() int64 Merc::CalcMaxMana() { - switch(GetCasterClass()) - { - case 'I': - case 'W': { + if (IsIntelligenceCasterClass() || IsWisdomCasterClass()) { max_mana = (CalcBaseMana() + itembonuses.Mana + spellbonuses.Mana + GroupLeadershipAAManaEnhancement()); - break; - } - case 'N': { + } else { max_mana = 0; - break; - } - default: { - LogDebug("Invalid Class [{}] in CalcMaxMana", GetCasterClass()); - max_mana = 0; - break; - } } + if (max_mana < 0) { max_mana = 0; } @@ -565,12 +554,13 @@ int64 Merc::CalcManaRegen() regen = mana_regen + spellbonuses.ManaRegen + itembonuses.ManaRegen; } - if(GetCasterClass() == 'I') + if (IsIntelligenceCasterClass()) { regen += (itembonuses.HeroicINT / 25); - else if(GetCasterClass() == 'W') + } else if (IsWisdomCasterClass()) { regen += (itembonuses.HeroicWIS / 25); - else + } else { regen = 0; + } //AAs regen += aabonuses.ManaRegen; @@ -581,14 +571,11 @@ int64 Merc::CalcManaRegen() int64 Merc::CalcManaRegenCap() { int64 cap = RuleI(Character, ItemManaRegenCap) + aabonuses.ItemManaRegenCap; - switch(GetCasterClass()) - { - case 'I': + + if (IsIntelligenceCasterClass()) { cap += (itembonuses.HeroicINT / 25); - break; - case 'W': + } else if (IsWisdomCasterClass()) { cap += (itembonuses.HeroicWIS / 25); - break; } return (cap * RuleI(Character, ManaRegenMultiplier) / 100); @@ -1166,7 +1153,7 @@ void Merc::AI_Process() { float newX = 0; float newY = 0; float newZ = 0; - if (PlotPositionAroundTarget(GetTarget(), newX, newY, newZ, false) && GetArchetype() != ARCHETYPE_CASTER) { + if (PlotPositionAroundTarget(GetTarget(), newX, newY, newZ, false) && GetArchetype() != Archetype::Caster) { RunTo(newX, newY, newZ); return; } @@ -1314,7 +1301,7 @@ void Merc::AI_Process() { if(AI_EngagedCastCheck()) { MercMeditate(false); } - else if(GetArchetype() == ARCHETYPE_CASTER) + else if(GetArchetype() == Archetype::Caster) MercMeditate(true); } } @@ -1337,7 +1324,7 @@ void Merc::AI_Process() { //TODO: Implement passive stances. //if(GetStance() != MercStancePassive) { if(!AI_IdleCastCheck() && !IsCasting()) { - if(GetArchetype() == ARCHETYPE_CASTER) { + if(GetArchetype() == Archetype::Caster) { MercMeditate(true); } } @@ -1792,7 +1779,7 @@ bool Merc::AICastSpell(int8 iChance, uint32 iSpellTypes) { if( !IsImmuneToSpell(selectedMercSpell.spellid, this) && (CanBuffStack(selectedMercSpell.spellid, mercLevel, true) >= 0)) { - if( GetArchetype() == ARCHETYPE_MELEE && IsEffectInSpell(selectedMercSpell.spellid, SE_IncreaseSpellHaste)) { + if( GetArchetype() == Archetype::Melee && IsEffectInSpell(selectedMercSpell.spellid, SE_IncreaseSpellHaste)) { continue; } @@ -1819,7 +1806,7 @@ bool Merc::AICastSpell(int8 iChance, uint32 iSpellTypes) { if( !tar->IsImmuneToSpell(selectedMercSpell.spellid, this) && (tar->CanBuffStack(selectedMercSpell.spellid, mercLevel, true) >= 0)) { - if( tar->GetArchetype() == ARCHETYPE_MELEE && IsEffectInSpell(selectedMercSpell.spellid, SE_IncreaseSpellHaste)) { + if( tar->GetArchetype() == Archetype::Melee && IsEffectInSpell(selectedMercSpell.spellid, SE_IncreaseSpellHaste)) { continue; } diff --git a/zone/mob.cpp b/zone/mob.cpp index 75e6c710e..9d2ca6b2b 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -940,19 +940,16 @@ int Mob::_GetFearSpeed() const { return speed_mod; } -int64 Mob::CalcMaxMana() { - switch (GetCasterClass()) { - case 'I': - max_mana = (((GetINT()/2)+1) * GetLevel()) + spellbonuses.Mana + itembonuses.Mana; - break; - case 'W': - max_mana = (((GetWIS()/2)+1) * GetLevel()) + spellbonuses.Mana + itembonuses.Mana; - break; - case 'N': - default: - max_mana = 0; - break; +int64 Mob::CalcMaxMana() +{ + if (IsIntelligenceCasterClass()) { + max_mana = (((GetINT() / 2) + 1) * GetLevel()) + spellbonuses.Mana + itembonuses.Mana; + } else if (IsWisdomCasterClass()) { + max_mana = (((GetWIS() / 2) + 1) * GetLevel()) + spellbonuses.Mana + itembonuses.Mana; + } else { + max_mana = 0; } + if (max_mana < 0) { max_mana = 0; } @@ -981,90 +978,155 @@ int64 Mob::GetSpellHPBonuses() { return spell_hp; } -char Mob::GetCasterClass() const { - switch(class_) - { - case Class::Cleric: - case Class::Paladin: - case Class::Ranger: - case Class::Druid: - case Class::Shaman: - case Class::Beastlord: - case Class::ClericGM: - case Class::PaladinGM: - case Class::RangerGM: - case Class::DruidGM: - case Class::ShamanGM: - case Class::BeastlordGM: - return 'W'; - break; - - case Class::ShadowKnight: - case Class::Bard: - case Class::Necromancer: - case Class::Wizard: - case Class::Magician: - case Class::Enchanter: - case Class::ShadowKnightGM: - case Class::BardGM: - case Class::NecromancerGM: - case Class::WizardGM: - case Class::MagicianGM: - case Class::EnchanterGM: - return 'I'; - break; - - default: - return 'N'; - break; +bool Mob::IsIntelligenceCasterClass() const +{ + switch (GetClass()) { + case Class::ShadowKnight: + case Class::Bard: + case Class::Necromancer: + case Class::Wizard: + case Class::Magician: + case Class::Enchanter: + case Class::ShadowKnightGM: + case Class::BardGM: + case Class::NecromancerGM: + case Class::WizardGM: + case Class::MagicianGM: + case Class::EnchanterGM: + return true; } + + return false; } -uint8 Mob::GetArchetype() const { - switch(class_) - { - case Class::Paladin: - case Class::Ranger: - case Class::ShadowKnight: - case Class::Bard: - case Class::Beastlord: - case Class::PaladinGM: - case Class::RangerGM: - case Class::ShadowKnightGM: - case Class::BardGM: - case Class::BeastlordGM: - return ARCHETYPE_HYBRID; - break; - case Class::Cleric: - case Class::Druid: - case Class::Shaman: - case Class::Necromancer: - case Class::Wizard: - case Class::Magician: - case Class::Enchanter: - case Class::ClericGM: - case Class::DruidGM: - case Class::ShamanGM: - case Class::NecromancerGM: - case Class::WizardGM: - case Class::MagicianGM: - case Class::EnchanterGM: - return ARCHETYPE_CASTER; - break; - case Class::Warrior: - case Class::Monk: - case Class::Rogue: - case Class::Berserker: - case Class::WarriorGM: - case Class::MonkGM: - case Class::RogueGM: - case Class::BerserkerGM: - return ARCHETYPE_MELEE; - break; - default: - return ARCHETYPE_HYBRID; - break; +bool Mob::IsPureMeleeClass() const +{ + switch (GetClass()) { + case Class::Warrior: + case Class::Monk: + case Class::Rogue: + case Class::Berserker: + case Class::WarriorGM: + case Class::MonkGM: + case Class::RogueGM: + case Class::BerserkerGM: + return true; + default: + break; } + + return false; +} + +bool Mob::IsWarriorClass() const +{ + switch (GetClass()) { + case Class::Warrior: + case Class::Paladin: + case Class::Ranger: + case Class::ShadowKnight: + case Class::Monk: + case Class::Bard: + case Class::Rogue: + case Class::Beastlord: + case Class::Berserker: + case Class::WarriorGM: + case Class::PaladinGM: + case Class::RangerGM: + case Class::ShadowKnightGM: + case Class::MonkGM: + case Class::BardGM: + case Class::RogueGM: + case Class::BeastlordGM: + case Class::BerserkerGM: + return true; + default: + break; + } + + return false; +} + +bool Mob::IsWisdomCasterClass() const +{ + switch (GetClass()) { + case Class::Cleric: + case Class::Paladin: + case Class::Ranger: + case Class::Druid: + case Class::Shaman: + case Class::Beastlord: + case Class::ClericGM: + case Class::PaladinGM: + case Class::RangerGM: + case Class::DruidGM: + case Class::ShamanGM: + case Class::BeastlordGM: + return true; + } + + return false; +} + +uint8 Mob::GetArchetype() const +{ + switch (GetClass()) { + case Class::Paladin: + case Class::Ranger: + case Class::ShadowKnight: + case Class::Bard: + case Class::Beastlord: + case Class::PaladinGM: + case Class::RangerGM: + case Class::ShadowKnightGM: + case Class::BardGM: + case Class::BeastlordGM: + return Archetype::Hybrid; + case Class::Cleric: + case Class::Druid: + case Class::Shaman: + case Class::Necromancer: + case Class::Wizard: + case Class::Magician: + case Class::Enchanter: + case Class::ClericGM: + case Class::DruidGM: + case Class::ShamanGM: + case Class::NecromancerGM: + case Class::WizardGM: + case Class::MagicianGM: + case Class::EnchanterGM: + return Archetype::Caster; + case Class::Warrior: + case Class::Monk: + case Class::Rogue: + case Class::Berserker: + case Class::WarriorGM: + case Class::MonkGM: + case Class::RogueGM: + case Class::BerserkerGM: + return Archetype::Melee; + default: + break; + } + + return Archetype::Hybrid; +} + +const std::string& Mob::GetArchetypeName() +{ + switch (GetArchetype()) { + case Archetype::Hybrid: + return "Hybrid"; + case Archetype::Caster: + return "Caster"; + case Archetype::Melee: + return "Melee"; + default: + break; + } + + return "Hybrid"; } void Mob::SetSpawnLastNameByClass(NewSpawn_Struct* ns) @@ -4586,39 +4648,6 @@ bool Mob::CanThisClassTripleAttack() const } } -bool Mob::IsWarriorClass(void) const -{ - switch(GetClass()) - { - case Class::Warrior: - case Class::WarriorGM: - case Class::Rogue: - case Class::RogueGM: - case Class::Monk: - case Class::MonkGM: - case Class::Paladin: - case Class::PaladinGM: - case Class::ShadowKnight: - case Class::ShadowKnightGM: - case Class::Ranger: - case Class::RangerGM: - case Class::Beastlord: - case Class::BeastlordGM: - case Class::Berserker: - case Class::BerserkerGM: - case Class::Bard: - case Class::BardGM: - { - return true; - } - default: - { - return false; - } - } - -} - bool Mob::CanThisClassParry(void) const { if(!IsClient()) { diff --git a/zone/mob.h b/zone/mob.h index 7045a1001..49331a808 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -838,8 +838,11 @@ public: virtual void MakePet(uint16 spell_id, const char* pettype, const char *petname = nullptr); virtual void MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower, const char *petname = nullptr, float in_size = 0.0f); bool IsWarriorClass() const; - char GetCasterClass() const; + bool IsIntelligenceCasterClass() const; + bool IsPureMeleeClass() const; + bool IsWisdomCasterClass() const; uint8 GetArchetype() const; + const std::string& GetArchetypeName(); void SetZone(uint32 zone_id, uint32 instance_id); void SendStatsWindow(Client* c, bool use_window); void ShowStats(Client* client); diff --git a/zone/npc.cpp b/zone/npc.cpp index fa86bf8a2..70516656f 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -2756,35 +2756,28 @@ void NPC::SetSwarmTarget(int target_id) int64 NPC::CalcMaxMana() { if (npc_mana == 0) { - switch (GetCasterClass()) { - case 'I': - max_mana = (((GetINT() / 2) + 1) * GetLevel()) + spellbonuses.Mana + itembonuses.Mana; - break; - case 'W': - max_mana = (((GetWIS() / 2) + 1) * GetLevel()) + spellbonuses.Mana + itembonuses.Mana; - break; - default: - max_mana = 0; - break; + if (IsIntelligenceCasterClass()) { + max_mana = (((GetINT() / 2) + 1) * GetLevel()) + spellbonuses.Mana + itembonuses.Mana; + } else if (IsWisdomCasterClass()) { + max_mana = (((GetWIS() / 2) + 1) * GetLevel()) + spellbonuses.Mana + itembonuses.Mana; + } else { + max_mana = 0; } + if (max_mana < 0) { max_mana = 0; } return max_mana; - } - else { - switch (GetCasterClass()) { - case 'I': - max_mana = npc_mana + spellbonuses.Mana + itembonuses.Mana; - break; - case 'W': - max_mana = npc_mana + spellbonuses.Mana + itembonuses.Mana; - break; - default: - max_mana = 0; - break; + } else { + if (IsIntelligenceCasterClass()) { + max_mana = npc_mana + spellbonuses.Mana + itembonuses.Mana; + } else if (IsWisdomCasterClass()) { + max_mana = npc_mana + spellbonuses.Mana + itembonuses.Mana; + } else { + max_mana = 0; } + if (max_mana < 0) { max_mana = 0; } diff --git a/zone/perl_mob.cpp b/zone/perl_mob.cpp index a90ed7148..20b8db30b 100644 --- a/zone/perl_mob.cpp +++ b/zone/perl_mob.cpp @@ -3448,6 +3448,26 @@ void Perl_Mob_RestoreMana(Mob* self) self->RestoreMana(); } +std::string Perl_Mob_GetArchetypeName(Mob* self) +{ + return self->GetArchetypeName(); +} + +bool Perl_Mob_IsIntelligenceCasterClass(Mob* self) +{ + return self->IsIntelligenceCasterClass(); +} + +bool Perl_Mob_IsPureMeleeClass(Mob* self) +{ + return self->IsPureMeleeClass(); +} + +bool Perl_Mob_IsWisdomCasterClass(Mob* self) +{ + return self->IsWisdomCasterClass(); +} + void perl_register_mob() { perl::interpreter perl(PERL_GET_THX); @@ -3620,6 +3640,7 @@ void perl_register_mob() package.add("GetAggroRange", &Perl_Mob_GetAggroRange); package.add("GetAllowBeneficial", &Perl_Mob_GetAllowBeneficial); package.add("GetAppearance", &Perl_Mob_GetAppearance); + package.add("GetArchetypeName", &Perl_Mob_GetArchetypeName); package.add("GetArmorTint", &Perl_Mob_GetArmorTint); package.add("GetAssistRange", &Perl_Mob_GetAssistRange); package.add("GetBaseGender", &Perl_Mob_GetBaseGender); @@ -3843,6 +3864,7 @@ void perl_register_mob() package.add("IsFindable", &Perl_Mob_IsFindable); package.add("IsHorse", &Perl_Mob_IsHorse); package.add("IsImmuneToSpell", &Perl_Mob_IsImmuneToSpell); + package.add("IsIntelligenceCasterClass", &Perl_Mob_IsIntelligenceCasterClass); package.add("IsInvisible", (bool(*)(Mob*))&Perl_Mob_IsInvisible); package.add("IsInvisible", (bool(*)(Mob*, Mob*))&Perl_Mob_IsInvisible); package.add("IsMeleeDisabled", &Perl_Mob_IsMeleeDisabled); @@ -3861,6 +3883,7 @@ void perl_register_mob() package.add("IsPetOwnerClient", &Perl_Mob_IsPetOwnerClient); package.add("IsPetOwnerNPC", &Perl_Mob_IsPetOwnerNPC); package.add("IsPlayerCorpse", &Perl_Mob_IsPlayerCorpse); + package.add("IsPureMeleeClass", &Perl_Mob_IsPureMeleeClass); package.add("IsRoamer", &Perl_Mob_IsRoamer); package.add("IsRooted", &Perl_Mob_IsRooted); package.add("IsRunning", &Perl_Mob_IsRunning); @@ -3873,6 +3896,7 @@ void perl_register_mob() package.add("IsTrackable", &Perl_Mob_IsTrackable); package.add("IsTrap", &Perl_Mob_IsTrap); package.add("IsWarriorClass", &Perl_Mob_IsWarriorClass); + package.add("IsWisdomCasterClass", &Perl_Mob_IsWisdomCasterClass); package.add("Kill", &Perl_Mob_Kill); package.add("MakePet", (void(*)(Mob*, uint16, const char*))&Perl_Mob_MakePet); package.add("MakePet", (void(*)(Mob*, uint16, const char*, const char*))&Perl_Mob_MakePet); diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index 32a226302..b8059d0f6 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -456,7 +456,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove if(GetClass() == Class::Bard) break; if(IsManaTapSpell(spell_id)) { - if(GetCasterClass() != 'N') { + if (!IsPureMeleeClass()) { #ifdef SPELL_EFFECT_SPAM snprintf(effect_desc, _EDLEN, "Current Mana: %+i", effect_value); #endif @@ -578,12 +578,12 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove GetPet()->BuffFadeByEffect(SE_Charm); } } - + CastToClient()->MovePC(zone->GetZoneID(), zone->GetInstanceID(), x, y, z, heading, 0, EvacToSafeCoords); } else { GMMove(x, y, z, heading); } - + if (RuleB(Spells, EvacClearAggroInSameZone)) { entity_list.ClearAggro(this); } @@ -1058,7 +1058,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove cd->hit_heading = action->hit_heading; CastToClient()->QueuePacket(action_packet); - + if (caster->IsClient() && caster != this) { caster->CastToClient()->QueuePacket(action_packet); } @@ -1068,7 +1068,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove if (caster->IsClient() && caster != this) { caster->CastToClient()->QueuePacket(message_packet); } - + CastToClient()->SetBindPoint(spells[spell_id].base_value[i] - 1); Save(); safe_delete(action_packet); @@ -1105,7 +1105,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove } break; } - + DispelMagic(caster, spell_id, effect_value); break; } @@ -7369,7 +7369,7 @@ bool Mob::PassLimitClass(uint32 Classes_, uint16 Class_) return false; } -void Mob::DispelMagic(Mob* caster, uint16 spell_id, int effect_value) +void Mob::DispelMagic(Mob* caster, uint16 spell_id, int effect_value) { for (int slot = 0; slot < GetMaxTotalSlots(); slot++) { if ( diff --git a/zone/spells.cpp b/zone/spells.cpp index 315cce126..db04292b1 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -224,8 +224,12 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot, if(GetTarget() && IsManaTapSpell(spell_id)) { // If melee, block if ManaTapsOnAnyClass rule is false // if caster, block if ManaTapsRequireNPCMana and no mana - bool melee_block = !RuleB(Spells, ManaTapsOnAnyClass); - bool caster_block = (GetTarget()->GetCasterClass() != 'N' && RuleB(Spells, ManaTapsRequireNPCMana) && GetTarget()->GetMana() == 0); + bool melee_block = !RuleB(Spells, ManaTapsOnAnyClass); + bool caster_block = ( + !GetTarget()->IsPureMeleeClass() && + RuleB(Spells, ManaTapsRequireNPCMana) && + GetTarget()->GetMana() == 0 + ); if (melee_block || caster_block) { InterruptSpell(TARGET_NO_MANA, 0x121, spell_id); return false; @@ -1105,10 +1109,10 @@ bool Client::CheckFizzle(uint16 spell_id) // CALCULATE EFFECTIVE CASTING STAT VALUE float prime_stat_reduction = 0.0f; - if (GetCasterClass() == 'W') { - prime_stat_reduction = (GetWIS() - 75) / 10.0; - } else if (GetCasterClass() == 'I') { + if (IsIntelligenceCasterClass()) { prime_stat_reduction = (GetINT() - 75) / 10.0; + } else if (IsWisdomCasterClass()) { + prime_stat_reduction = (GetWIS() - 75) / 10.0; } // BARDS ARE SPECIAL - they add both CHA and DEX mods to get casting rates similar to full casters without spec skill @@ -1183,10 +1187,10 @@ bool Client::CheckFizzle(uint16 spell_id) // if you have high int/wis you fizzle less, you fizzle more if you are stupid if (GetClass() == Class::Bard) { diff -= (GetCHA() - 110) / 20.0; - } else if (GetCasterClass() == 'W') { - diff -= (GetWIS() - 125) / 20.0; - } else if (GetCasterClass() == 'I') { + } else if (IsIntelligenceCasterClass()) { diff -= (GetINT() - 125) / 20.0; + } else if (IsWisdomCasterClass()) { + diff -= (GetWIS() - 125) / 20.0; } // base fizzlechance is lets say 5%, we can make it lower for AA skills or whatever