Core/Misc: Reduce number of player spec hardcoded checks

This commit is contained in:
Shauren
2023-08-06 21:40:10 +02:00
parent e71b2f62c1
commit 054723241e
9 changed files with 41 additions and 107 deletions

View File

@@ -406,7 +406,7 @@ Creature* PlayerAI::GetCharmer() const
return nullptr;
}
uint16 PlayerAI::GetSpec(Player const* who /*= nullptr*/) const
uint32 PlayerAI::GetSpec(Player const* who /*= nullptr*/) const
{
return (!who || who == me) ? _selfSpec : who->GetPrimarySpecialization();
}
@@ -416,28 +416,8 @@ bool PlayerAI::IsPlayerHealer(Player const* who)
if (!who)
return false;
switch (who->GetClass())
{
case CLASS_WARRIOR:
case CLASS_HUNTER:
case CLASS_ROGUE:
case CLASS_DEATH_KNIGHT:
case CLASS_MAGE:
case CLASS_WARLOCK:
case CLASS_DEMON_HUNTER:
default:
return false;
case CLASS_PALADIN:
return who->GetPrimarySpecialization() == TALENT_SPEC_PALADIN_HOLY;
case CLASS_PRIEST:
return who->GetPrimarySpecialization() == TALENT_SPEC_PRIEST_DISCIPLINE || who->GetPrimarySpecialization() == TALENT_SPEC_PRIEST_HOLY;
case CLASS_SHAMAN:
return who->GetPrimarySpecialization() == TALENT_SPEC_SHAMAN_RESTORATION;
case CLASS_MONK:
return who->GetPrimarySpecialization() == TALENT_SPEC_MONK_MISTWEAVER;
case CLASS_DRUID:
return who->GetPrimarySpecialization() == TALENT_SPEC_DRUID_RESTORATION;
}
return who->GetPrimarySpecialization()
&& sChrSpecializationStore.AssertEntry(who->GetPrimarySpecialization())->GetRole() == ChrSpecializationRole::Healer;
}
bool PlayerAI::IsPlayerRangedAttacker(Player const* who)
@@ -445,33 +425,8 @@ bool PlayerAI::IsPlayerRangedAttacker(Player const* who)
if (!who)
return false;
switch (who->GetClass())
{
case CLASS_WARRIOR:
case CLASS_PALADIN:
case CLASS_ROGUE:
case CLASS_DEATH_KNIGHT:
default:
return false;
case CLASS_MAGE:
case CLASS_WARLOCK:
return true;
case CLASS_HUNTER:
{
// check if we have a ranged weapon equipped
Item const* rangedSlot = who->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED);
if (ItemTemplate const* rangedTemplate = rangedSlot ? rangedSlot->GetTemplate() : nullptr)
if ((1 << rangedTemplate->GetSubClass()) & ITEM_SUBCLASS_MASK_WEAPON_RANGED)
return true;
return false;
}
case CLASS_PRIEST:
return who->GetPrimarySpecialization() == TALENT_SPEC_PRIEST_SHADOW;
case CLASS_SHAMAN:
return who->GetPrimarySpecialization() == TALENT_SPEC_SHAMAN_ELEMENTAL;
case CLASS_DRUID:
return who->GetPrimarySpecialization() == TALENT_SPEC_DRUID_BALANCE;
}
return who->GetPrimarySpecialization()
&& sChrSpecializationStore.AssertEntry(who->GetPrimarySpecialization())->GetFlags().HasFlag(ChrSpecializationFlag::Ranged);
}
PlayerAI::TargetedSpell PlayerAI::VerifySpellCast(uint32 spellId, Unit* target)
@@ -642,7 +597,7 @@ void PlayerAI::DoAutoAttackIfReady()
void PlayerAI::CancelAllShapeshifts()
{
std::list<AuraEffect*> const& shapeshiftAuras = me->GetAuraEffectsByType(SPELL_AURA_MOD_SHAPESHIFT);
Unit::AuraEffectList const& shapeshiftAuras = me->GetAuraEffectsByType(SPELL_AURA_MOD_SHAPESHIFT);
std::set<Aura*> removableShapeshifts;
for (AuraEffect* auraEff : shapeshiftAuras)
{

View File

@@ -31,7 +31,7 @@ class TC_GAME_API PlayerAI : public UnitAI
Creature* GetCharmer() const;
// helper functions to determine player info
uint16 GetSpec(Player const* who = nullptr) const;
uint32 GetSpec(Player const* who = nullptr) const;
static bool IsPlayerHealer(Player const* who);
bool IsHealer(Player const* who = nullptr) const { return (!who || who == me) ? _isSelfHealer : IsPlayerHealer(who); }
static bool IsPlayerRangedAttacker(Player const* who);
@@ -85,7 +85,7 @@ class TC_GAME_API PlayerAI : public UnitAI
void CancelAllShapeshifts();
private:
uint16 const _selfSpec;
uint32 const _selfSpec;
bool const _isSelfHealer;
bool _isSelfRangedAttacker;
};

View File

@@ -4017,16 +4017,16 @@ int32 GetUnitConditionVariable(Unit const* unit, Unit const* otherUnit, UnitCond
return otherUnit && unit->GetReactionTo(otherUnit) <= REP_HOSTILE;
case UnitConditionVariable::IsSpecMelee:
return unit->IsPlayer() && unit->ToPlayer()->GetPrimarySpecialization()
&& sChrSpecializationStore.AssertEntry(unit->ToPlayer()->GetPrimarySpecialization())->Flags & CHR_SPECIALIZATION_FLAG_MELEE;
&& sChrSpecializationStore.AssertEntry(unit->ToPlayer()->GetPrimarySpecialization())->GetFlags().HasFlag(ChrSpecializationFlag::Melee);
case UnitConditionVariable::IsSpecTank:
return unit->IsPlayer() && unit->ToPlayer()->GetPrimarySpecialization()
&& sChrSpecializationStore.AssertEntry(unit->ToPlayer()->GetPrimarySpecialization())->Role == 0;
&& sChrSpecializationStore.AssertEntry(unit->ToPlayer()->GetPrimarySpecialization())->GetRole() == ChrSpecializationRole::Tank;
case UnitConditionVariable::IsSpecRanged:
return unit->IsPlayer() && unit->ToPlayer()->GetPrimarySpecialization()
&& sChrSpecializationStore.AssertEntry(unit->ToPlayer()->GetPrimarySpecialization())->Flags & CHR_SPECIALIZATION_FLAG_RANGED;
&& sChrSpecializationStore.AssertEntry(unit->ToPlayer()->GetPrimarySpecialization())->GetFlags().HasFlag(ChrSpecializationFlag::Ranged);
case UnitConditionVariable::IsSpecHealer:
return unit->IsPlayer() && unit->ToPlayer()->GetPrimarySpecialization()
&& sChrSpecializationStore.AssertEntry(unit->ToPlayer()->GetPrimarySpecialization())->Role == 1;
&& sChrSpecializationStore.AssertEntry(unit->ToPlayer()->GetPrimarySpecialization())->GetRole() == ChrSpecializationRole::Healer;
case UnitConditionVariable::IsPlayerControlledNPC:
return unit->IsCreature() && unit->HasUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED);
case UnitConditionVariable::IsDying:

View File

@@ -1183,7 +1183,7 @@ uint32 DB2Manager::LoadStores(std::string const& dataPath, LocaleConstant defaul
ASSERT(chrSpec->OrderIndex < MAX_SPECIALIZATIONS);
uint32 storageIndex = chrSpec->ClassID;
if (chrSpec->Flags & CHR_SPECIALIZATION_FLAG_PET_OVERRIDE_SPEC)
if (chrSpec->GetFlags().HasFlag(ChrSpecializationFlag::PetOverrideSpec))
{
ASSERT(!chrSpec->ClassID);
storageIndex = PET_SPEC_OVERRIDE_CLASS_INDEX;

View File

@@ -848,6 +848,9 @@ struct ChrSpecializationEntry
int32 AnimReplacements;
std::array<int32, MAX_MASTERY_SPELLS> MasterySpellID;
EnumFlag<ChrSpecializationFlag> GetFlags() const { return static_cast<ChrSpecializationFlag>(Flags); }
ChrSpecializationRole GetRole() const { return static_cast<ChrSpecializationRole>(Role); }
bool IsPetSpecialization() const
{
return ClassID == 0;

View File

@@ -280,15 +280,23 @@ enum class ChrRacesFlag : int32
DEFINE_ENUM_FLAG(ChrRacesFlag);
enum ChrSpecializationFlag
enum class ChrSpecializationFlag : uint32
{
CHR_SPECIALIZATION_FLAG_CASTER = 0x01,
CHR_SPECIALIZATION_FLAG_RANGED = 0x02,
CHR_SPECIALIZATION_FLAG_MELEE = 0x04,
CHR_SPECIALIZATION_FLAG_UNKNOWN = 0x08,
CHR_SPECIALIZATION_FLAG_DUAL_WIELD_TWO_HANDED = 0x10, // used for CUnitDisplay::SetSheatheInvertedForDualWield
CHR_SPECIALIZATION_FLAG_PET_OVERRIDE_SPEC = 0x20,
CHR_SPECIALIZATION_FLAG_RECOMMENDED = 0x40,
Caster = 0x01,
Ranged = 0x02,
Melee = 0x04,
DualWieldTwoHanded = 0x10, // used for CUnitDisplay::SetSheatheInvertedForDualWield
PetOverrideSpec = 0x20,
Recommended = 0x40,
};
DEFINE_ENUM_FLAG(ChrSpecializationFlag);
enum class ChrSpecializationRole : int8
{
Tank = 0,
Healer = 1,
Dps = 2
};
enum class ContentTuningCalcType : int32

View File

@@ -419,50 +419,18 @@ struct npc_twisted_visage : public ScriptedAI
void AttackStart(Unit* who) override
{
switch (_playerClass)
{
case CLASS_SHAMAN:
switch (_playerSpec)
{
case TALENT_SPEC_SHAMAN_ELEMENTAL:
case TALENT_SPEC_SHAMAN_RESTORATION:
ScriptedAI::AttackStartCaster(who, 25.0f);
break;
default:
break;
}
break;
case CLASS_DRUID:
switch (_playerSpec)
{
case TALENT_SPEC_DRUID_BALANCE:
case TALENT_SPEC_DRUID_RESTORATION:
ScriptedAI::AttackStartCaster(who, 25.0f);
break;
default:
break;
}
break;
case CLASS_PRIEST:
case CLASS_HUNTER:
case CLASS_MAGE:
case CLASS_WARLOCK:
ScriptedAI::AttackStartCaster(who, 25.0f);
break;
case CLASS_ROGUE:
ScriptedAI::AttackStart(who);
break;
default:
ScriptedAI::AttackStart(who);
break;
}
ChrSpecializationEntry const* chrSpecialization = sChrSpecializationStore.LookupEntry(_playerSpec);
if (chrSpecialization && chrSpecialization->GetFlags().HasFlag(ChrSpecializationFlag::Ranged))
ScriptedAI::AttackStartCaster(who, 25.0f);
else
ScriptedAI::AttackStart(who);
}
void SetData(uint32 type, uint32 data) override
{
if (type == DATA_TWISTED_VISAGE_PLAYER_CLASS)
{
if (data > CLASS_NONE && data <= CLASS_DRUID)
if (data > CLASS_NONE && data < MAX_CLASSES)
_playerClass = data;
}
else if (type == DATA_TWISTED_VISAGE_PLAYER_SPEC && _playerClass != CLASS_NONE)

View File

@@ -1099,13 +1099,13 @@ class spell_sindragosa_unchained_magic : public SpellScript
continue;
ChrSpecializationEntry const* specialization = sChrSpecializationStore.LookupEntry(player->GetPrimarySpecialization());
if (specialization->Role == 1)
if (specialization->GetRole() == ChrSpecializationRole::Healer)
{
healers.push_back(target);
continue;
}
if (specialization->Flags & CHR_SPECIALIZATION_FLAG_CASTER)
if (specialization->GetFlags().HasFlag(ChrSpecializationFlag::Caster))
casters.push_back(target);
}

View File

@@ -804,7 +804,7 @@ class spell_dru_innervate : public SpellScript
return SPELL_FAILED_BAD_TARGETS;
ChrSpecializationEntry const* spec = sChrSpecializationStore.LookupEntry(target->GetPrimarySpecialization());
if (!spec || spec->Role != 1)
if (!spec || spec->GetRole() != ChrSpecializationRole::Healer)
return SPELL_FAILED_BAD_TARGETS;
return SPELL_CAST_OK;