diff options
author | Shauren <shauren.trinity@gmail.com> | 2021-03-12 21:59:10 +0100 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2021-03-12 21:59:10 +0100 |
commit | 2bd70b41eb0d2d2aad16ddb17525c2f24acde2c5 (patch) | |
tree | 0c740f968e5b8e1a1154e2f058a1b55ae2b94e95 /src | |
parent | efdca47aff354079bc73d248e022c2e914d94e7b (diff) |
Core/Spells: Restore serverside spells fuinctionality
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Miscellaneous/SharedDefines.h | 2 | ||||
-rw-r--r-- | src/server/game/Spells/SpellInfo.cpp | 308 | ||||
-rw-r--r-- | src/server/game/Spells/SpellInfo.h | 189 | ||||
-rw-r--r-- | src/server/game/Spells/SpellMgr.cpp | 270 | ||||
-rw-r--r-- | src/server/game/Spells/SpellMgr.h | 1 | ||||
-rw-r--r-- | src/server/game/World/World.cpp | 3 |
6 files changed, 532 insertions, 241 deletions
diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index e91dbcc6e67..12746ad6b81 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -1262,7 +1262,7 @@ enum SpellEffectName SPELL_EFFECT_LEARN_GARRISON_BUILDING = 210, SPELL_EFFECT_LEARN_GARRISON_SPECIALIZATION = 211, SPELL_EFFECT_REMOVE_AURA_BY_SPELL_LABEL = 212, - SPELL_EFFECT_JUMP_DEST_2 = 213, + SPELL_EFFECT_JUMP_DEST_2 = 213, SPELL_EFFECT_CREATE_GARRISON = 214, SPELL_EFFECT_UPGRADE_CHARACTER_SPELLS = 215, // Unlocks boosted players' spells (ChrUpgrade*.db2) SPELL_EFFECT_CREATE_SHIPMENT = 216, diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 2e6c6acb76f..53a732c1390 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -371,41 +371,40 @@ SpellImplicitTargetInfo::StaticData SpellImplicitTargetInfo::_data[TOTAL_SPELL_ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_AREA, TARGET_CHECK_ENEMY, TARGET_DIR_NONE}, // 151 }; -SpellEffectInfo::SpellEffectInfo(SpellInfo const* spellInfo, SpellEffectEntry const* _effect) +SpellEffectInfo::SpellEffectInfo(SpellInfo const* spellInfo, SpellEffectEntry const& _effect) : EffectAttributes(SpellEffectAttributes::None) { ASSERT(spellInfo); - ASSERT(_effect); _spellInfo = spellInfo; - EffectIndex = _effect->EffectIndex; - Effect = _effect->Effect; - ApplyAuraName = _effect->EffectAura; - ApplyAuraPeriod = _effect->EffectAuraPeriod; - RealPointsPerLevel = _effect->EffectRealPointsPerLevel; - BasePoints = _effect->EffectBasePoints; - PointsPerResource = _effect->EffectPointsPerResource; - Amplitude = _effect->EffectAmplitude; - ChainAmplitude = _effect->EffectChainAmplitude; - BonusCoefficient = _effect->EffectBonusCoefficient; - MiscValue = _effect->EffectMiscValue[0]; - MiscValueB = _effect->EffectMiscValue[1]; - Mechanic = Mechanics(_effect->EffectMechanic); - PositionFacing = _effect->EffectPosFacing; - TargetA = SpellImplicitTargetInfo(_effect->ImplicitTarget[0]); - TargetB = SpellImplicitTargetInfo(_effect->ImplicitTarget[1]); - RadiusEntry = sSpellRadiusStore.LookupEntry(_effect->EffectRadiusIndex[0]); - MaxRadiusEntry = sSpellRadiusStore.LookupEntry(_effect->EffectRadiusIndex[1]); - ChainTargets = _effect->EffectChainTargets; - ItemType = _effect->EffectItemType; - TriggerSpell = _effect->EffectTriggerSpell; - SpellClassMask = _effect->EffectSpellClassMask; - BonusCoefficientFromAP = _effect->BonusCoefficientFromAP; - Scaling.Coefficient = _effect->Coefficient; - Scaling.Variance = _effect->Variance; - Scaling.ResourceCoefficient = _effect->ResourceCoefficient; + EffectIndex = _effect.EffectIndex; + Effect = _effect.Effect; + ApplyAuraName = _effect.EffectAura; + ApplyAuraPeriod = _effect.EffectAuraPeriod; + BasePoints = _effect.EffectBasePoints; + RealPointsPerLevel = _effect.EffectRealPointsPerLevel; + PointsPerResource = _effect.EffectPointsPerResource; + Amplitude = _effect.EffectAmplitude; + ChainAmplitude = _effect.EffectChainAmplitude; + BonusCoefficient = _effect.EffectBonusCoefficient; + MiscValue = _effect.EffectMiscValue[0]; + MiscValueB = _effect.EffectMiscValue[1]; + Mechanic = Mechanics(_effect.EffectMechanic); + PositionFacing = _effect.EffectPosFacing; + TargetA = SpellImplicitTargetInfo(_effect.ImplicitTarget[0]); + TargetB = SpellImplicitTargetInfo(_effect.ImplicitTarget[1]); + RadiusEntry = sSpellRadiusStore.LookupEntry(_effect.EffectRadiusIndex[0]); + MaxRadiusEntry = sSpellRadiusStore.LookupEntry(_effect.EffectRadiusIndex[1]); + ChainTargets = _effect.EffectChainTargets; + ItemType = _effect.EffectItemType; + TriggerSpell = _effect.EffectTriggerSpell; + SpellClassMask = _effect.EffectSpellClassMask; + BonusCoefficientFromAP = _effect.BonusCoefficientFromAP; + Scaling.Coefficient = _effect.Coefficient; + Scaling.Variance = _effect.Variance; + Scaling.ResourceCoefficient = _effect.ResourceCoefficient; ImplicitTargetConditions = nullptr; - EffectAttributes = _effect->GetEffectAttributes(); + EffectAttributes = _effect.GetEffectAttributes(); } bool SpellEffectInfo::IsEffect() const @@ -1081,10 +1080,8 @@ SpellEffectInfo::StaticData SpellEffectInfo::_data[TOTAL_SPELL_EFFECTS] = }; SpellInfo::SpellInfo(SpellNameEntry const* spellName, ::Difficulty difficulty, SpellInfoLoadHelper const& data, SpellVisualVector&& visuals) + : Id(spellName->ID), Difficulty(difficulty) { - Id = spellName->ID; - Difficulty = difficulty; - _effects.reserve(32); for (SpellEffectEntry const* spellEffect : data.Effects) { @@ -1094,106 +1091,123 @@ SpellInfo::SpellInfo(SpellNameEntry const* spellName, ::Difficulty difficulty, S if (uint32(spellEffect->EffectIndex) >= _effects.size()) _effects.resize(spellEffect->EffectIndex + 1); - _effects[spellEffect->EffectIndex] = new SpellEffectInfo(this, spellEffect); + _effects[spellEffect->EffectIndex] = new SpellEffectInfo(this, *spellEffect); } _effects.shrink_to_fit(); SpellName = &spellName->Name; // SpellMiscEntry - SpellMiscEntry const* _misc = data.Misc; - Attributes = _misc ? _misc->Attributes[0] : 0; - AttributesEx = _misc ? _misc->Attributes[1] : 0; - AttributesEx2 = _misc ? _misc->Attributes[2] : 0; - AttributesEx3 = _misc ? _misc->Attributes[3] : 0; - AttributesEx4 = _misc ? _misc->Attributes[4] : 0; - AttributesEx5 = _misc ? _misc->Attributes[5] : 0; - AttributesEx6 = _misc ? _misc->Attributes[6] : 0; - AttributesEx7 = _misc ? _misc->Attributes[7] : 0; - AttributesEx8 = _misc ? _misc->Attributes[8] : 0; - AttributesEx9 = _misc ? _misc->Attributes[9] : 0; - AttributesEx10 = _misc ? _misc->Attributes[10] : 0; - AttributesEx11 = _misc ? _misc->Attributes[11] : 0; - AttributesEx12 = _misc ? _misc->Attributes[12] : 0; - AttributesEx13 = _misc ? _misc->Attributes[13] : 0; - AttributesEx14 = _misc ? _misc->Attributes[14] : 0; - CastTimeEntry = _misc ? (_misc->CastingTimeIndex ? sSpellCastTimesStore.LookupEntry(_misc->CastingTimeIndex) : nullptr) : nullptr; - DurationEntry = _misc ? (_misc->DurationIndex ? sSpellDurationStore.LookupEntry(_misc->DurationIndex) : nullptr) : nullptr; - RangeIndex = _misc ? _misc->RangeIndex : 0; - RangeEntry = _misc ? (_misc->RangeIndex ? sSpellRangeStore.LookupEntry(_misc->RangeIndex) : nullptr) : nullptr; - Speed = _misc ? _misc->Speed : 0; - LaunchDelay = _misc ? _misc->LaunchDelay : 0; - SchoolMask = _misc ? _misc->SchoolMask : 0; - AttributesCu = 0; - IconFileDataId = _misc ? _misc->SpellIconFileDataID : 0; - ActiveIconFileDataId = _misc ? _misc->ActiveIconFileDataID : 0; - ContentTuningId = _misc ? _misc->ContentTuningID : 0; - ShowFutureSpellPlayerConditionID = _misc ? _misc->ShowFutureSpellPlayerConditionID : 0; + if (SpellMiscEntry const* _misc = data.Misc) + { + Attributes = _misc->Attributes[0]; + AttributesEx = _misc->Attributes[1]; + AttributesEx2 = _misc->Attributes[2]; + AttributesEx3 = _misc->Attributes[3]; + AttributesEx4 = _misc->Attributes[4]; + AttributesEx5 = _misc->Attributes[5]; + AttributesEx6 = _misc->Attributes[6]; + AttributesEx7 = _misc->Attributes[7]; + AttributesEx8 = _misc->Attributes[8]; + AttributesEx9 = _misc->Attributes[9]; + AttributesEx10 = _misc->Attributes[10]; + AttributesEx11 = _misc->Attributes[11]; + AttributesEx12 = _misc->Attributes[12]; + AttributesEx13 = _misc->Attributes[13]; + AttributesEx14 = _misc->Attributes[14]; + CastTimeEntry = sSpellCastTimesStore.LookupEntry(_misc->CastingTimeIndex); + DurationEntry = sSpellDurationStore.LookupEntry(_misc->DurationIndex); + RangeEntry = sSpellRangeStore.LookupEntry(_misc->RangeIndex); + Speed = _misc->Speed; + LaunchDelay = _misc->LaunchDelay; + SchoolMask = _misc->SchoolMask; + IconFileDataId = _misc->SpellIconFileDataID; + ActiveIconFileDataId = _misc->ActiveIconFileDataID; + ContentTuningId = _misc->ContentTuningID; + ShowFutureSpellPlayerConditionID = _misc->ShowFutureSpellPlayerConditionID; + } _visuals = std::move(visuals); // SpellScalingEntry - SpellScalingEntry const* _scaling = data.Scaling; - Scaling.Class = _scaling ? _scaling->Class : 0; - Scaling.MinScalingLevel = _scaling ? _scaling->MinScalingLevel : 0; - Scaling.MaxScalingLevel = _scaling ? _scaling->MaxScalingLevel : 0; - Scaling.ScalesFromItemLevel = _scaling ? _scaling->ScalesFromItemLevel : 0; + if (SpellScalingEntry const* _scaling = data.Scaling) + { + Scaling.Class = _scaling->Class; + Scaling.MinScalingLevel = _scaling->MinScalingLevel; + Scaling.MaxScalingLevel = _scaling->MaxScalingLevel; + Scaling.ScalesFromItemLevel = _scaling->ScalesFromItemLevel; + } // SpellAuraOptionsEntry - SpellAuraOptionsEntry const* _options = data.AuraOptions; - SpellProcsPerMinuteEntry const* _ppm = _options ? sSpellProcsPerMinuteStore.LookupEntry(_options->SpellProcsPerMinuteID) : nullptr; - ProcFlags = _options ? _options->ProcTypeMask[0] : 0; - ProcChance = _options ? _options->ProcChance : 0; - ProcCharges = _options ? _options->ProcCharges : 0; - ProcCooldown = _options ? _options->ProcCategoryRecovery : 0; - ProcBasePPM = _ppm ? _ppm->BaseProcRate : 0.0f; - if (_options) - ProcPPMMods = sDB2Manager.GetSpellProcsPerMinuteMods(_options->SpellProcsPerMinuteID); - StackAmount = _options ? _options->CumulativeAura : 0; + if (SpellAuraOptionsEntry const* _options = data.AuraOptions) + { + ProcFlags = _options->ProcTypeMask[0]; + ProcChance = _options->ProcChance; + ProcCharges = _options->ProcCharges; + ProcCooldown = _options->ProcCategoryRecovery; + StackAmount = _options->CumulativeAura; + if (SpellProcsPerMinuteEntry const* _ppm = sSpellProcsPerMinuteStore.LookupEntry(_options->SpellProcsPerMinuteID)) + { + ProcBasePPM = _ppm->BaseProcRate; + ProcPPMMods = sDB2Manager.GetSpellProcsPerMinuteMods(_ppm->ID); + } + } // SpellAuraRestrictionsEntry - SpellAuraRestrictionsEntry const* _aura = data.AuraRestrictions; - CasterAuraState = _aura ? _aura->CasterAuraState : 0; - TargetAuraState = _aura ? _aura->TargetAuraState : 0; - ExcludeCasterAuraState = _aura ? _aura->ExcludeCasterAuraState : 0; - ExcludeTargetAuraState = _aura ? _aura->ExcludeTargetAuraState : 0; - CasterAuraSpell = _aura ? _aura->CasterAuraSpell : 0; - TargetAuraSpell = _aura ? _aura->TargetAuraSpell : 0; - ExcludeCasterAuraSpell = _aura ? _aura->ExcludeCasterAuraSpell : 0; - ExcludeTargetAuraSpell = _aura ? _aura->ExcludeTargetAuraSpell : 0; + if (SpellAuraRestrictionsEntry const* _aura = data.AuraRestrictions) + { + CasterAuraState = _aura->CasterAuraState; + TargetAuraState = _aura->TargetAuraState; + ExcludeCasterAuraState = _aura->ExcludeCasterAuraState; + ExcludeTargetAuraState = _aura->ExcludeTargetAuraState; + CasterAuraSpell = _aura->CasterAuraSpell; + TargetAuraSpell = _aura->TargetAuraSpell; + ExcludeCasterAuraSpell = _aura->ExcludeCasterAuraSpell; + ExcludeTargetAuraSpell = _aura->ExcludeTargetAuraSpell; + } // SpellCastingRequirementsEntry - SpellCastingRequirementsEntry const* _castreq = data.CastingRequirements; - RequiresSpellFocus = _castreq ? _castreq->RequiresSpellFocus : 0; - FacingCasterFlags = _castreq ? _castreq->FacingCasterFlags : 0; - RequiredAreasID = _castreq ? _castreq->RequiredAreasID : -1; + if (SpellCastingRequirementsEntry const* _castreq = data.CastingRequirements) + { + RequiresSpellFocus = _castreq->RequiresSpellFocus; + FacingCasterFlags = _castreq->FacingCasterFlags; + RequiredAreasID = _castreq->RequiredAreasID; + } // SpellCategoriesEntry - SpellCategoriesEntry const* _categorie = data.Categories; - CategoryId = _categorie ? _categorie->Category : 0; - Dispel = _categorie ? _categorie->DispelType : 0; - Mechanic = _categorie ? _categorie->Mechanic : 0; - StartRecoveryCategory = _categorie ? _categorie->StartRecoveryCategory : 0; - DmgClass = _categorie ? _categorie->DefenseType : 0; - PreventionType = _categorie ? _categorie->PreventionType : 0; - ChargeCategoryId = _categorie ? _categorie->ChargeCategory : 0; + if (SpellCategoriesEntry const* _categories = data.Categories) + { + CategoryId = _categories->Category; + Dispel = _categories->DispelType; + Mechanic = _categories->Mechanic; + StartRecoveryCategory = _categories->StartRecoveryCategory; + DmgClass = _categories->DefenseType; + PreventionType = _categories->PreventionType; + ChargeCategoryId = _categories->ChargeCategory; + } // SpellClassOptionsEntry - SpellClassOptionsEntry const* _class = data.ClassOptions; - SpellFamilyName = _class ? _class->SpellClassSet : 0; - SpellFamilyFlags = _class ? _class->SpellClassMask : flag128(); + if (SpellClassOptionsEntry const* _class = data.ClassOptions) + { + SpellFamilyName = _class->SpellClassSet; + SpellFamilyFlags = _class->SpellClassMask; + } // SpellCooldownsEntry - SpellCooldownsEntry const* _cooldowns = data.Cooldowns; - RecoveryTime = _cooldowns ? _cooldowns->RecoveryTime : 0; - CategoryRecoveryTime = _cooldowns ? _cooldowns->CategoryRecoveryTime : 0; - StartRecoveryTime = _cooldowns ? _cooldowns->StartRecoveryTime : 0; + if (SpellCooldownsEntry const* _cooldowns = data.Cooldowns) + { + RecoveryTime = _cooldowns->RecoveryTime; + CategoryRecoveryTime = _cooldowns->CategoryRecoveryTime; + StartRecoveryTime = _cooldowns->StartRecoveryTime; + } // SpellEquippedItemsEntry - SpellEquippedItemsEntry const* _equipped = data.EquippedItems; - EquippedItemClass = _equipped ? _equipped->EquippedItemClass : -1; - EquippedItemSubClassMask = _equipped ?_equipped->EquippedItemSubclass : 0; - EquippedItemInventoryTypeMask = _equipped ? _equipped->EquippedItemInvTypes : 0; + if (SpellEquippedItemsEntry const* _equipped = data.EquippedItems) + { + EquippedItemClass = _equipped->EquippedItemClass; + EquippedItemSubClassMask = _equipped->EquippedItemSubclass; + EquippedItemInventoryTypeMask = _equipped->EquippedItemInvTypes; + } // SpellInterruptsEntry if (SpellInterruptsEntry const* _interrupt = data.Interrupts) @@ -1202,57 +1216,65 @@ SpellInfo::SpellInfo(SpellNameEntry const* spellName, ::Difficulty difficulty, S std::copy(std::begin(_interrupt->AuraInterruptFlags), std::end(_interrupt->AuraInterruptFlags), AuraInterruptFlags.begin()); std::copy(std::begin(_interrupt->ChannelInterruptFlags), std::end(_interrupt->ChannelInterruptFlags), ChannelInterruptFlags.begin()); } - else - { - InterruptFlags = 0; - AuraInterruptFlags.fill(0); - ChannelInterruptFlags.fill(0); - } // SpellLevelsEntry - SpellLevelsEntry const* _levels = data.Levels; - MaxLevel = _levels ? _levels->MaxLevel : 0; - BaseLevel = _levels ? _levels->BaseLevel : 0; - SpellLevel = _levels ? _levels->SpellLevel : 0; + if (SpellLevelsEntry const* _levels = data.Levels) + { + MaxLevel = _levels->MaxLevel; + BaseLevel = _levels->BaseLevel; + SpellLevel = _levels->SpellLevel; + } // SpellPowerEntry PowerCosts = data.Powers; // SpellReagentsEntry - SpellReagentsEntry const* _reagents = data.Reagents; - for (uint8 i = 0; i < MAX_SPELL_REAGENTS; ++i) - Reagent[i] = _reagents ? _reagents->Reagent[i] : 0; - for (uint8 i = 0; i < MAX_SPELL_REAGENTS; ++i) - ReagentCount[i] = _reagents ? _reagents->ReagentCount[i] : 0; + if (SpellReagentsEntry const* _reagents = data.Reagents) + { + std::copy(std::begin(_reagents->Reagent), std::end(_reagents->Reagent), Reagent.begin()); + std::copy(std::begin(_reagents->ReagentCount), std::end(_reagents->ReagentCount), ReagentCount.begin()); + } // SpellShapeshiftEntry - SpellShapeshiftEntry const* _shapeshift = data.Shapeshift; - Stances = _shapeshift ? MAKE_PAIR64(_shapeshift->ShapeshiftMask[0], _shapeshift->ShapeshiftMask[1]) : 0; - StancesNot = _shapeshift ? MAKE_PAIR64(_shapeshift->ShapeshiftExclude[0], _shapeshift->ShapeshiftExclude[1]) : 0; + if (SpellShapeshiftEntry const* _shapeshift = data.Shapeshift) + { + Stances = MAKE_PAIR64(_shapeshift->ShapeshiftMask[0], _shapeshift->ShapeshiftMask[1]); + StancesNot = MAKE_PAIR64(_shapeshift->ShapeshiftExclude[0], _shapeshift->ShapeshiftExclude[1]); + } // SpellTargetRestrictionsEntry - SpellTargetRestrictionsEntry const* _target = data.TargetRestrictions; - ConeAngle = _target ? _target->ConeDegrees : 0.f; - Width = _target ? _target->Width : 0.f; - Targets = _target ? _target->Targets : 0; - TargetCreatureType = _target ? _target->TargetCreatureType : 0; - MaxAffectedTargets = _target ? _target->MaxTargets : 0; - MaxTargetLevel = _target ? _target->MaxTargetLevel : 0; + if (SpellTargetRestrictionsEntry const* _target = data.TargetRestrictions) + { + ConeAngle = _target->ConeDegrees; + Width = _target->Width; + Targets = _target->Targets; + TargetCreatureType = _target->TargetCreatureType; + MaxAffectedTargets = _target->MaxTargets; + MaxTargetLevel = _target->MaxTargetLevel; + } // SpellTotemsEntry - SpellTotemsEntry const* _totem = data.Totems; - for (uint8 i = 0; i < 2; ++i) - TotemCategory[i] = _totem ? _totem->RequiredTotemCategoryID[i] : 0; - for (uint8 i = 0; i < 2; ++i) - Totem[i] = _totem ? _totem->Totem[i] : 0; + if (SpellTotemsEntry const* _totem = data.Totems) + { + std::copy(std::begin(_totem->RequiredTotemCategoryID), std::end(_totem->RequiredTotemCategoryID), TotemCategory.begin()); + std::copy(std::begin(_totem->Totem), std::end(_totem->Totem), Totem.begin()); + } +} - ChainEntry = nullptr; - ExplicitTargetMask = 0; +SpellInfo::SpellInfo(SpellNameEntry const* spellName, ::Difficulty difficulty, std::vector<SpellEffectEntry> const& effects) + : Id(spellName->ID), Difficulty(difficulty) +{ + SpellName = &spellName->Name; - _spellSpecific = SPELL_SPECIFIC_NORMAL; - _auraState = AURA_STATE_NONE; + _effects.reserve(32); + for (SpellEffectEntry const& spellEffect : effects) + { + if (uint32(spellEffect.EffectIndex) >= _effects.size()) + _effects.resize(spellEffect.EffectIndex + 1); - _allowedMechanicMask = 0; + _effects[spellEffect.EffectIndex] = new SpellEffectInfo(this, spellEffect); + } + _effects.shrink_to_fit(); } SpellInfo::~SpellInfo() diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h index 85ff0682e26..5b129755826 100644 --- a/src/server/game/Spells/SpellInfo.h +++ b/src/server/game/Spells/SpellInfo.h @@ -334,8 +334,8 @@ public: uint32 Effect; uint32 ApplyAuraName; uint32 ApplyAuraPeriod; - float RealPointsPerLevel; int32 BasePoints; + float RealPointsPerLevel; float PointsPerResource; float Amplitude; float ChainAmplitude; @@ -364,11 +364,12 @@ public: } Scaling; SpellEffectInfo() : _spellInfo(nullptr), EffectIndex(0), Effect(0), ApplyAuraName(0), ApplyAuraPeriod(0), - RealPointsPerLevel(0), BasePoints(0), PointsPerResource(0), Amplitude(0), ChainAmplitude(0), + BasePoints(0), RealPointsPerLevel(0), PointsPerResource(0), Amplitude(0), ChainAmplitude(0), BonusCoefficient(0), MiscValue(0), MiscValueB(0), Mechanic(MECHANIC_NONE), PositionFacing(0), - RadiusEntry(nullptr), ChainTargets(0), ItemType(0), TriggerSpell(0), BonusCoefficientFromAP(0.0f), - ImplicitTargetConditions(nullptr), EffectAttributes(SpellEffectAttributes::None) { } - SpellEffectInfo(SpellInfo const* spellInfo, SpellEffectEntry const* effect); + RadiusEntry(nullptr), MaxRadiusEntry(nullptr), ChainTargets(0), ItemType(0), TriggerSpell(0), + BonusCoefficientFromAP(0.0f), ImplicitTargetConditions(nullptr), + EffectAttributes(SpellEffectAttributes::None), Scaling() { } + SpellEffectInfo(SpellInfo const* spellInfo, SpellEffectEntry const& effect); bool IsEffect() const; bool IsEffect(SpellEffectName effectName) const; @@ -440,103 +441,103 @@ class TC_GAME_API SpellInfo friend class SpellMgr; public: - uint32 Id; - ::Difficulty Difficulty; - uint32 CategoryId; - uint32 Dispel; - uint32 Mechanic; - uint32 Attributes; - uint32 AttributesEx; - uint32 AttributesEx2; - uint32 AttributesEx3; - uint32 AttributesEx4; - uint32 AttributesEx5; - uint32 AttributesEx6; - uint32 AttributesEx7; - uint32 AttributesEx8; - uint32 AttributesEx9; - uint32 AttributesEx10; - uint32 AttributesEx11; - uint32 AttributesEx12; - uint32 AttributesEx13; - uint32 AttributesEx14; - uint32 AttributesCu; + uint32 const Id = 0; + ::Difficulty const Difficulty = DIFFICULTY_NONE; + uint32 CategoryId = 0; + uint32 Dispel = 0; + uint32 Mechanic = 0; + uint32 Attributes = 0; + uint32 AttributesEx = 0; + uint32 AttributesEx2 = 0; + uint32 AttributesEx3 = 0; + uint32 AttributesEx4 = 0; + uint32 AttributesEx5 = 0; + uint32 AttributesEx6 = 0; + uint32 AttributesEx7 = 0; + uint32 AttributesEx8 = 0; + uint32 AttributesEx9 = 0; + uint32 AttributesEx10 = 0; + uint32 AttributesEx11 = 0; + uint32 AttributesEx12 = 0; + uint32 AttributesEx13 = 0; + uint32 AttributesEx14 = 0; + uint32 AttributesCu = 0; std::bitset<MAX_SPELL_EFFECTS> NegativeEffects; - uint64 Stances; - uint64 StancesNot; - uint32 Targets; - uint32 TargetCreatureType; - uint32 RequiresSpellFocus; - uint32 FacingCasterFlags; - uint32 CasterAuraState; - uint32 TargetAuraState; - uint32 ExcludeCasterAuraState; - uint32 ExcludeTargetAuraState; - uint32 CasterAuraSpell; - uint32 TargetAuraSpell; - uint32 ExcludeCasterAuraSpell; - uint32 ExcludeTargetAuraSpell; - SpellCastTimesEntry const* CastTimeEntry; - uint32 RecoveryTime; - uint32 CategoryRecoveryTime; - uint32 StartRecoveryCategory; - uint32 StartRecoveryTime; - uint32 InterruptFlags; - std::array<uint32, MAX_SPELL_AURA_INTERRUPT_FLAGS> AuraInterruptFlags; - std::array<uint32, MAX_SPELL_AURA_INTERRUPT_FLAGS> ChannelInterruptFlags; - uint32 ProcFlags; - uint32 ProcChance; - uint32 ProcCharges; - uint32 ProcCooldown; - float ProcBasePPM; + uint64 Stances = 0; + uint64 StancesNot = 0; + uint32 Targets = 0; + uint32 TargetCreatureType = 0; + uint32 RequiresSpellFocus = 0; + uint32 FacingCasterFlags = 0; + uint32 CasterAuraState = 0; + uint32 TargetAuraState = 0; + uint32 ExcludeCasterAuraState = 0; + uint32 ExcludeTargetAuraState = 0; + uint32 CasterAuraSpell = 0; + uint32 TargetAuraSpell = 0; + uint32 ExcludeCasterAuraSpell = 0; + uint32 ExcludeTargetAuraSpell = 0; + SpellCastTimesEntry const* CastTimeEntry = nullptr; + uint32 RecoveryTime = 0; + uint32 CategoryRecoveryTime = 0; + uint32 StartRecoveryCategory = 0; + uint32 StartRecoveryTime = 0; + uint32 InterruptFlags = 0; + std::array<uint32, MAX_SPELL_AURA_INTERRUPT_FLAGS> AuraInterruptFlags = {}; + std::array<uint32, MAX_SPELL_AURA_INTERRUPT_FLAGS> ChannelInterruptFlags = {}; + uint32 ProcFlags = 0; + uint32 ProcChance = 0; + uint32 ProcCharges = 0; + uint32 ProcCooldown = 0; + float ProcBasePPM = 0.0f; std::vector<SpellProcsPerMinuteModEntry const*> ProcPPMMods; - uint32 MaxLevel; - uint32 BaseLevel; - uint32 SpellLevel; - SpellDurationEntry const* DurationEntry; - std::array<SpellPowerEntry const*, MAX_POWERS_PER_SPELL> PowerCosts; - uint32 RangeIndex; - SpellRangeEntry const* RangeEntry; - float Speed; - float LaunchDelay; - uint32 StackAmount; - uint32 Totem[MAX_SPELL_TOTEMS]; - int32 Reagent[MAX_SPELL_REAGENTS]; - uint32 ReagentCount[MAX_SPELL_REAGENTS]; - int32 EquippedItemClass; - int32 EquippedItemSubClassMask; - int32 EquippedItemInventoryTypeMask; - uint32 TotemCategory[MAX_SPELL_TOTEMS]; - uint32 IconFileDataId; - uint32 ActiveIconFileDataId; - uint32 ContentTuningId; - uint32 ShowFutureSpellPlayerConditionID; - LocalizedString const* SpellName; - float ConeAngle; - float Width; - uint32 MaxTargetLevel; - uint32 MaxAffectedTargets; - uint32 SpellFamilyName; + uint32 MaxLevel = 0; + uint32 BaseLevel = 0; + uint32 SpellLevel = 0; + SpellDurationEntry const* DurationEntry = nullptr; + std::array<SpellPowerEntry const*, MAX_POWERS_PER_SPELL> PowerCosts = {}; + SpellRangeEntry const* RangeEntry = nullptr; + float Speed = 0.0f; + float LaunchDelay = 0.0f; + uint32 StackAmount = 0; + std::array<uint32, MAX_SPELL_TOTEMS> Totem = {}; + std::array<uint32, MAX_SPELL_TOTEMS> TotemCategory = {}; + std::array<int32, MAX_SPELL_REAGENTS> Reagent = {}; + std::array<uint32, MAX_SPELL_REAGENTS> ReagentCount = {}; + int32 EquippedItemClass = -1; + int32 EquippedItemSubClassMask = 0; + int32 EquippedItemInventoryTypeMask = 0; + uint32 IconFileDataId = 0; + uint32 ActiveIconFileDataId = 0; + uint32 ContentTuningId = 0; + uint32 ShowFutureSpellPlayerConditionID = 0; + LocalizedString const* SpellName = nullptr; + float ConeAngle = 0.0f; + float Width = 0.0f; + uint32 MaxTargetLevel = 0; + uint32 MaxAffectedTargets = 0; + uint32 SpellFamilyName = 0; flag128 SpellFamilyFlags; - uint32 DmgClass; - uint32 PreventionType; - int32 RequiredAreasID; - uint32 SchoolMask; - uint32 ChargeCategoryId; + uint32 DmgClass = 0; + uint32 PreventionType = 0; + int32 RequiredAreasID = -1; + uint32 SchoolMask = 0; + uint32 ChargeCategoryId = 0; // SpellScalingEntry struct ScalingInfo { - int32 Class; - uint32 MinScalingLevel; - uint32 MaxScalingLevel; - uint32 ScalesFromItemLevel; + int32 Class = 0; + uint32 MinScalingLevel = 0; + uint32 MaxScalingLevel = 0; + uint32 ScalesFromItemLevel = 0; } Scaling; - uint32 ExplicitTargetMask; - SpellChainNode const* ChainEntry; + uint32 ExplicitTargetMask = 0; + SpellChainNode const* ChainEntry = nullptr; SpellInfo(SpellNameEntry const* spellName, ::Difficulty difficulty, SpellInfoLoadHelper const& data, SpellVisualVector&& visuals); + SpellInfo(SpellNameEntry const* spellName, ::Difficulty difficulty, std::vector<SpellEffectEntry> const& effects); ~SpellInfo(); uint32 GetCategory() const; @@ -711,11 +712,11 @@ class TC_GAME_API SpellInfo private: SpellEffectInfoVector _effects; SpellVisualVector _visuals; - SpellSpecificType _spellSpecific; - AuraStateType _auraState; + SpellSpecificType _spellSpecific = SPELL_SPECIFIC_NORMAL; + AuraStateType _auraState = AURA_STATE_NONE; SpellDiminishInfo _diminishInfo; - uint32 _allowedMechanicMask; + uint32 _allowedMechanicMask = 0; }; #endif // _SPELLINFO_H diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 295c4331fc2..8a907aacf66 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -49,17 +49,50 @@ namespace boost::multi_index::tag<SpellIdDifficultyIndex>, boost::multi_index::composite_key< SpellInfo, - boost::multi_index::member<SpellInfo, uint32, &SpellInfo::Id>, - boost::multi_index::member<SpellInfo, Difficulty, &SpellInfo::Difficulty> + boost::multi_index::member<SpellInfo, uint32 const, &SpellInfo::Id>, + boost::multi_index::member<SpellInfo, Difficulty const, &SpellInfo::Difficulty> > >, boost::multi_index::hashed_non_unique< boost::multi_index::tag<SpellIdIndex>, - boost::multi_index::member<SpellInfo, uint32, &SpellInfo::Id> + boost::multi_index::member<SpellInfo, uint32 const, &SpellInfo::Id> > > > mSpellInfoMap; + struct ServersideSpellName + { + explicit ServersideSpellName(uint32 id, std::string name) : NameStorage(std::move(name)) + { + Name.ID = id; + InitPointers(); + } + + ServersideSpellName(ServersideSpellName const& right) : NameStorage(right.NameStorage) + { + Name.ID = right.Name.ID; + InitPointers(); + } + + ServersideSpellName(ServersideSpellName&& right) noexcept : NameStorage(std::move(right.NameStorage)) + { + Name.ID = right.Name.ID; + InitPointers(); + right.InitPointers(); + } + + SpellNameEntry Name; + std::string NameStorage; + + private: + void InitPointers() + { + std::fill(std::begin(Name.Name.Str), std::end(Name.Name.Str), NameStorage.c_str()); + } + }; + + std::vector<ServersideSpellName> mServersideSpellNames; + std::unordered_map<std::pair<uint32, Difficulty>, SpellProcEntry> mSpellProcMap; } @@ -2585,6 +2618,7 @@ void SpellMgr::LoadSpellInfoStore() void SpellMgr::UnloadSpellInfoStore() { mSpellInfoMap.clear(); + mServersideSpellNames.clear(); } void SpellMgr::UnloadSpellInfoImplicitTargetConditionLists() @@ -2593,6 +2627,236 @@ void SpellMgr::UnloadSpellInfoImplicitTargetConditionLists() const_cast<SpellInfo&>(spellInfo)._UnloadImplicitTargetConditionLists(); } +void SpellMgr::LoadSpellInfoServerside() +{ + uint32 oldMSTime = getMSTime(); + + std::unordered_map<std::pair<uint32, Difficulty>, std::vector<SpellEffectEntry>> spellEffects; + + // 0 1 2 3 4 5 6 + QueryResult effectsResult = WorldDatabase.Query("SELECT SpellID, EffectIndex, DifficultyID, Effect, EffectAura, EffectAmplitude, EffectAttributes, " + // 7 8 9 10 11 12 13 + "EffectAuraPeriod, EffectBonusCoefficient, EffectChainAmplitude, EffectChainTargets, EffectItemType, EffectMechanic, EffectPointsPerResource, " + // 14 15 16 17 18 19 20 + "EffectPosFacing, EffectRealPointsPerLevel, EffectTriggerSpell, BonusCoefficientFromAP, PvpMultiplier, Coefficient, Variance, " + // 21 22 23 24 25 26 + "ResourceCoefficient, GroupSizeBasePointsCoefficient, EffectBasePoints, EffectMiscValue1, EffectMiscValue2, EffectRadiusIndex1, " + // 27 28 29 30 31 32 + "EffectRadiusIndex2, EffectSpellClassMask1, EffectSpellClassMask2, EffectSpellClassMask3, EffectSpellClassMask4, ImplicitTarget1, " + // 33 + "ImplicitTarget2 FROM serverside_spell_effect"); + if (effectsResult) + { + do + { + Field* fields = effectsResult->Fetch(); + uint32 spellId = fields[0].GetUInt32(); + Difficulty difficulty = Difficulty(fields[2].GetUInt32()); + SpellEffectEntry effect{ }; + effect.EffectIndex = fields[1].GetInt32(); + effect.Effect = fields[3].GetInt32(); + effect.EffectAura = fields[4].GetInt16(); + effect.EffectAmplitude = fields[5].GetFloat(); + effect.EffectAttributes = fields[6].GetInt32(); + effect.EffectAuraPeriod = fields[7].GetInt32(); + effect.EffectBonusCoefficient = fields[8].GetFloat(); + effect.EffectChainAmplitude = fields[9].GetFloat(); + effect.EffectChainTargets = fields[10].GetInt32(); + effect.EffectItemType = fields[11].GetInt32(); + effect.EffectMechanic = Mechanics(fields[12].GetInt32()); + effect.EffectPointsPerResource = fields[13].GetFloat(); + effect.EffectPosFacing = fields[14].GetFloat(); + effect.EffectRealPointsPerLevel = fields[15].GetFloat(); + effect.EffectTriggerSpell = fields[16].GetInt32(); + effect.BonusCoefficientFromAP = fields[17].GetFloat(); + effect.PvpMultiplier = fields[18].GetFloat(); + effect.Coefficient = fields[19].GetFloat(); + effect.Variance = fields[20].GetFloat(); + effect.ResourceCoefficient = fields[21].GetFloat(); + effect.GroupSizeBasePointsCoefficient = fields[22].GetFloat(); + effect.EffectBasePoints = fields[23].GetFloat(); + effect.EffectMiscValue[0] = fields[24].GetInt32(); + effect.EffectMiscValue[1] = fields[25].GetInt32(); + effect.EffectRadiusIndex[0] = fields[26].GetUInt32(); + effect.EffectRadiusIndex[1] = fields[27].GetUInt32(); + effect.EffectSpellClassMask = flag128(fields[28].GetInt32(), fields[29].GetInt32(), fields[30].GetInt32(), fields[31].GetInt32()); + effect.ImplicitTarget[0] = fields[32].GetInt16(); + effect.ImplicitTarget[1] = fields[33].GetInt16(); + + auto existingSpellBounds = _GetSpellInfo(spellId); + if (existingSpellBounds.begin() != existingSpellBounds.end()) + { + TC_LOG_ERROR("sql.sql", "Serverside spell %u difficulty %u effext index %u references a regular spell loaded from file. Adding serverside effects to existing spells is not allowed.", + spellId, uint32(difficulty), effect.EffectIndex); + continue; + } + + if (difficulty != DIFFICULTY_NONE && !sDifficultyStore.HasRecord(difficulty)) + { + TC_LOG_ERROR("sql.sql", "Serverside spell %u effect index %u references non-existing difficulty %u, skipped", + spellId, effect.EffectIndex, uint32(difficulty)); + continue; + } + + if (effect.EffectIndex >= MAX_SPELL_EFFECTS) + { + TC_LOG_ERROR("sql.sql", "Serverside spell %u difficulty %u has more than 32 effects, effect at index %u skipped", + spellId, uint32(difficulty), effect.EffectIndex); + continue; + } + + if (effect.Effect >= TOTAL_SPELL_EFFECTS) + { + TC_LOG_ERROR("sql.sql", "Serverside spell %u difficulty %u has invalid effect type %u at index %u, skipped", + spellId, uint32(difficulty), effect.Effect, effect.EffectIndex); + continue; + } + + if (effect.EffectAura >= int32(TOTAL_AURAS)) + { + TC_LOG_ERROR("sql.sql", "Serverside spell %u difficulty %u has invalid aura type %u at index %u, skipped", + spellId, uint32(difficulty), effect.EffectAura, effect.EffectIndex); + continue; + } + + if (effect.ImplicitTarget[0] >= TOTAL_SPELL_TARGETS) + { + TC_LOG_ERROR("sql.sql", "Serverside spell %u difficulty %u has invalid targetA type %u at index %u, skipped", + spellId, uint32(difficulty), effect.ImplicitTarget[0], effect.EffectIndex); + continue; + } + + if (effect.ImplicitTarget[1] >= TOTAL_SPELL_TARGETS) + { + TC_LOG_ERROR("sql.sql", "Serverside spell %u difficulty %u has invalid targetB type %u at index %u, skipped", + spellId, uint32(difficulty), effect.ImplicitTarget[1], effect.EffectIndex); + continue; + } + + if (effect.EffectRadiusIndex[0] && !sSpellRadiusStore.HasRecord(effect.EffectRadiusIndex[0])) + { + TC_LOG_ERROR("sql.sql", "Serverside spell %u difficulty %u has invalid radius id %u at index %u, set to 0", + spellId, uint32(difficulty), effect.EffectRadiusIndex[0], effect.EffectIndex); + } + + if (effect.EffectRadiusIndex[1] && !sSpellRadiusStore.HasRecord(effect.EffectRadiusIndex[1])) + { + TC_LOG_ERROR("sql.sql", "Serverside spell %u difficulty %u has invalid max radius id %u at index %u, set to 0", + spellId, uint32(difficulty), effect.EffectRadiusIndex[1], effect.EffectIndex); + } + + spellEffects[{ spellId, difficulty }].push_back(std::move(effect)); + + } while (effectsResult->NextRow()); + } + + // 0 1 2 3 4 5 6 7 8 + QueryResult spellsResult = WorldDatabase.Query("SELECT Id, DifficultyID, CategoryId, Dispel, Mechanic, Attributes, AttributesEx, AttributesEx2, AttributesEx3, " + // 9 10 11 12 13 14 15 16 17 18 + "AttributesEx4, AttributesEx5, AttributesEx6, AttributesEx7, AttributesEx8, AttributesEx9, AttributesEx10, AttributesEx11, AttributesEx12, AttributesEx13, " + // 19 20 21 22 23 24 25 26 27 + "AttributesEx14, Stances, StancesNot, Targets, TargetCreatureType, RequiresSpellFocus, FacingCasterFlags, CasterAuraState, TargetAuraState, " + // 28 29 30 31 32 33 34 + "ExcludeCasterAuraState, ExcludeTargetAuraState, CasterAuraSpell, TargetAuraSpell, ExcludeCasterAuraSpell, ExcludeTargetAuraSpell, CastingTimeIndex, " + // 35 36 37 38 39 40 41 + "RecoveryTime, CategoryRecoveryTime, StartRecoveryCategory, StartRecoveryTime, InterruptFlags, AuraInterruptFlags1, AuraInterruptFlags2, " + // 42 43 44 45 46 47 48 49 50 51 + "ChannelInterruptFlags1, ChannelInterruptFlags2, ProcFlags, ProcChance, ProcCharges, ProcCooldown, ProcBasePPM, MaxLevel, BaseLevel, SpellLevel, " + // 52 53 54 55 56 57 58 59 60 + "DurationIndex, RangeIndex, Speed, LaunchDelay, StackAmount, EquippedItemClass, EquippedItemSubClassMask, EquippedItemInventoryTypeMask, ContentTuningId, " + // 61 62 63 64 65 66 67 68 69 70 + "SpellName, ConeAngle, ConeWidth, MaxTargetLevel, MaxAffectedTargets, SpellFamilyName, SpellFamilyFlags1, SpellFamilyFlags2, SpellFamilyFlags3, SpellFamilyFlags4, " + // 71 72 73 74 75 + "DmgClass, PreventionType, AreaGroupId, SchoolMask, ChargeCategoryId FROM serverside_spell"); + if (spellsResult) + { + mServersideSpellNames.reserve(spellsResult->GetRowCount()); + + do + { + Field* fields = spellsResult->Fetch(); + uint32 spellId = fields[0].GetUInt32(); + Difficulty difficulty = Difficulty(fields[2].GetUInt32()); + mServersideSpellNames.emplace_back(spellId, fields[61].GetString()); + + SpellInfo& spellInfo = const_cast<SpellInfo&>(*mSpellInfoMap.emplace(&mServersideSpellNames.back().Name, difficulty, spellEffects[{ spellId, difficulty }]).first); + spellInfo.CategoryId = fields[2].GetUInt32(); + spellInfo.Dispel = fields[3].GetUInt32(); + spellInfo.Mechanic = fields[4].GetUInt32(); + spellInfo.Attributes = fields[5].GetUInt32(); + spellInfo.AttributesEx = fields[6].GetUInt32(); + spellInfo.AttributesEx2 = fields[7].GetUInt32(); + spellInfo.AttributesEx3 = fields[8].GetUInt32(); + spellInfo.AttributesEx4 = fields[9].GetUInt32(); + spellInfo.AttributesEx5 = fields[10].GetUInt32(); + spellInfo.AttributesEx6 = fields[11].GetUInt32(); + spellInfo.AttributesEx7 = fields[12].GetUInt32(); + spellInfo.AttributesEx8 = fields[13].GetUInt32(); + spellInfo.AttributesEx9 = fields[14].GetUInt32(); + spellInfo.AttributesEx10 = fields[15].GetUInt32(); + spellInfo.AttributesEx11 = fields[16].GetUInt32(); + spellInfo.AttributesEx12 = fields[17].GetUInt32(); + spellInfo.AttributesEx13 = fields[18].GetUInt32(); + spellInfo.AttributesEx14 = fields[19].GetUInt32(); + spellInfo.Stances = fields[20].GetUInt64(); + spellInfo.StancesNot = fields[21].GetUInt64(); + spellInfo.Targets = fields[22].GetUInt32(); + spellInfo.TargetCreatureType = fields[23].GetUInt32(); + spellInfo.RequiresSpellFocus = fields[24].GetUInt32(); + spellInfo.FacingCasterFlags = fields[25].GetUInt32(); + spellInfo.CasterAuraState = fields[26].GetUInt32(); + spellInfo.TargetAuraState = fields[27].GetUInt32(); + spellInfo.ExcludeCasterAuraState = fields[28].GetUInt32(); + spellInfo.ExcludeTargetAuraState = fields[29].GetUInt32(); + spellInfo.CasterAuraSpell = fields[30].GetUInt32(); + spellInfo.TargetAuraSpell = fields[31].GetUInt32(); + spellInfo.ExcludeCasterAuraSpell = fields[32].GetUInt32(); + spellInfo.ExcludeTargetAuraSpell = fields[33].GetUInt32(); + spellInfo.CastTimeEntry = sSpellCastTimesStore.LookupEntry(fields[34].GetUInt32()); + spellInfo.RecoveryTime = fields[35].GetUInt32(); + spellInfo.CategoryRecoveryTime = fields[36].GetUInt32(); + spellInfo.StartRecoveryCategory = fields[37].GetUInt32(); + spellInfo.StartRecoveryTime = fields[38].GetUInt32(); + spellInfo.InterruptFlags = fields[39].GetUInt32(); + spellInfo.AuraInterruptFlags[0] = fields[40].GetUInt32(); + spellInfo.AuraInterruptFlags[1] = fields[41].GetUInt32(); + spellInfo.ChannelInterruptFlags[0] = fields[42].GetUInt32(); + spellInfo.ChannelInterruptFlags[1] = fields[43].GetUInt32(); + spellInfo.ProcFlags = fields[44].GetUInt32(); + spellInfo.ProcChance = fields[45].GetUInt32(); + spellInfo.ProcCharges = fields[46].GetUInt32(); + spellInfo.ProcCooldown = fields[47].GetUInt32(); + spellInfo.ProcBasePPM = fields[48].GetFloat(); + spellInfo.MaxLevel = fields[49].GetUInt32(); + spellInfo.BaseLevel = fields[50].GetUInt32(); + spellInfo.SpellLevel = fields[51].GetUInt32(); + spellInfo.DurationEntry = sSpellDurationStore.LookupEntry(fields[52].GetUInt32()); + spellInfo.RangeEntry = sSpellRangeStore.LookupEntry(fields[53].GetUInt32()); + spellInfo.Speed = fields[54].GetFloat(); + spellInfo.LaunchDelay = fields[55].GetFloat(); + spellInfo.StackAmount = fields[56].GetUInt32(); + spellInfo.EquippedItemClass = fields[57].GetInt32(); + spellInfo.EquippedItemSubClassMask = fields[58].GetInt32(); + spellInfo.EquippedItemInventoryTypeMask = fields[59].GetInt32(); + spellInfo.ContentTuningId = fields[60].GetUInt32(); + spellInfo.ConeAngle = fields[62].GetFloat(); + spellInfo.Width = fields[63].GetFloat(); + spellInfo.MaxTargetLevel = fields[64].GetUInt32(); + spellInfo.MaxAffectedTargets = fields[65].GetUInt32(); + spellInfo.SpellFamilyName = fields[66].GetUInt32(); + spellInfo.SpellFamilyFlags = flag128(fields[67].GetUInt32(), fields[68].GetUInt32(), fields[69].GetUInt32(), fields[70].GetUInt32()); + spellInfo.DmgClass = fields[71].GetUInt32(); + spellInfo.PreventionType = fields[72].GetUInt32(); + spellInfo.RequiredAreasID = fields[73].GetInt32(); + spellInfo.SchoolMask = fields[74].GetUInt32(); + spellInfo.ChargeCategoryId = fields[75].GetUInt32(); + + } while (spellsResult->NextRow()); + } + + TC_LOG_INFO("server.loading", ">> Loaded " SZFMTD " serverside spells %u ms", mServersideSpellNames.size(), GetMSTimeDiffToNow(oldMSTime)); +} + void SpellMgr::LoadSpellInfoCustomAttributes() { uint32 oldMSTime = getMSTime(); diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h index dd2df66dbf6..a1f7a5d555d 100644 --- a/src/server/game/Spells/SpellMgr.h +++ b/src/server/game/Spells/SpellMgr.h @@ -749,6 +749,7 @@ class TC_GAME_API SpellMgr void LoadSpellInfoStore(); void UnloadSpellInfoStore(); void UnloadSpellInfoImplicitTargetConditionLists(); + void LoadSpellInfoServerside(); void LoadSpellInfoCustomAttributes(); void LoadSpellInfoCorrections(); void LoadSpellInfoSpellSpecificAndAuraState(); diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 4dada5a5091..c6413aaddef 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1758,6 +1758,9 @@ void World::SetInitialWorldSettings() TC_LOG_INFO("server.loading", "Loading SpellInfo store..."); sSpellMgr->LoadSpellInfoStore(); + TC_LOG_INFO("server.loading", "Loading serverside spells..."); + sSpellMgr->LoadSpellInfoServerside(); + TC_LOG_INFO("server.loading", "Loading SpellInfo corrections..."); sSpellMgr->LoadSpellInfoCorrections(); |