diff options
| author | Shauren <shauren.trinity@gmail.com> | 2015-01-30 23:58:16 +0100 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2015-01-30 23:58:16 +0100 |
| commit | 3f28fd304d833eadefff8d343ab45caf8d0575c2 (patch) | |
| tree | d62b98f75a4607bd1e7cdc2944dce7f730981f6d /src/server/game/Spells | |
| parent | beb1a06ea56526de838cc8e0de15317660a9ddcf (diff) | |
Core/Spells: Reimplemented automatic spell learning
* Fixed learning/unlearning talents
Diffstat (limited to 'src/server/game/Spells')
| -rw-r--r-- | src/server/game/Spells/Spell.cpp | 113 | ||||
| -rw-r--r-- | src/server/game/Spells/Spell.h | 14 | ||||
| -rw-r--r-- | src/server/game/Spells/SpellEffects.cpp | 39 | ||||
| -rw-r--r-- | src/server/game/Spells/SpellInfo.cpp | 68 | ||||
| -rw-r--r-- | src/server/game/Spells/SpellInfo.h | 1 | ||||
| -rw-r--r-- | src/server/game/Spells/SpellMgr.cpp | 82 | ||||
| -rw-r--r-- | src/server/game/Spells/SpellMgr.h | 1 |
7 files changed, 172 insertions, 146 deletions
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index d729d76a1d5..173c9a027b2 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -109,34 +109,43 @@ void SpellDestination::RelocateOffset(Position const& offset) _position.RelocateOffset(offset); } -SpellCastTargets::SpellCastTargets() : m_elevation(0), m_speed(0), m_strTarget() +SpellCastTargets::SpellCastTargets() : m_targetMask(0), m_objectTarget(nullptr), m_itemTarget(nullptr), + m_itemTargetEntry(0), m_elevation(0.0f), m_speed(0.0f) { - m_objectTarget = NULL; - m_itemTarget = NULL; - - m_itemTargetEntry = 0; - - m_targetMask = 0; } -SpellCastTargets::SpellCastTargets(Unit* caster, uint32 targetMask, ObjectGuid targetGuid, ObjectGuid itemTargetGuid, ObjectGuid srcTransportGuid, ObjectGuid destTransportGuid, Position srcPos, Position destPos, float elevation, float missileSpeed, std::string targetString) : - m_targetMask(targetMask), m_objectTargetGUID(targetGuid), m_itemTargetGUID(itemTargetGuid), m_elevation(elevation), m_speed(missileSpeed), m_strTarget(targetString) +SpellCastTargets::SpellCastTargets(Unit* caster, WorldPackets::Spells::SpellTargetData const& spellTargetData) : + m_targetMask(spellTargetData.Flags), m_objectTarget(nullptr), m_itemTarget(nullptr), + m_objectTargetGUID(spellTargetData.Unit), m_itemTargetGUID(spellTargetData.Item), + m_itemTargetEntry(0), m_elevation(0.0f), m_speed(0.0f), m_strTarget(spellTargetData.Name) { - m_objectTarget = NULL; - m_itemTarget = NULL; - m_itemTargetEntry = 0; + if (spellTargetData.SrcLocation.HasValue) + { + m_src._transportGUID = spellTargetData.SrcLocation.Value.Transport; + Position* pos; + if (!m_src._transportGUID.IsEmpty()) + pos = &m_src._transportOffset; + else + pos = &m_src._position; - m_src._transportGUID = srcTransportGuid; - if (m_src._transportGUID != ObjectGuid::Empty) - m_src._transportOffset.Relocate(srcPos); - else - m_src._position.Relocate(srcPos); + pos->Relocate(spellTargetData.SrcLocation.Value.Location); + if (spellTargetData.Orientation.HasValue) + pos->SetOrientation(spellTargetData.Orientation.Value); + } - m_dst._transportGUID = destTransportGuid; - if (m_dst._transportGUID != ObjectGuid::Empty) - m_dst._transportOffset.Relocate(destPos); - else - m_dst._position.Relocate(destPos); + if (spellTargetData.DstLocation.HasValue) + { + m_dst._transportGUID = spellTargetData.DstLocation.Value.Transport; + Position* pos; + if (!m_dst._transportGUID.IsEmpty()) + pos = &m_dst._transportOffset; + else + pos = &m_dst._position; + + pos->Relocate(spellTargetData.DstLocation.Value.Location); + if (spellTargetData.Orientation.HasValue) + pos->SetOrientation(spellTargetData.Orientation.Value); + } Update(caster); } @@ -230,39 +239,6 @@ void SpellCastTargets::Write(WorldPackets::Spells::SpellTargetData& data) if (m_targetMask & TARGET_FLAG_STRING) data.Name = m_strTarget; - /*data << uint32(m_targetMask); - - if (m_targetMask & (TARGET_FLAG_UNIT | TARGET_FLAG_CORPSE_ALLY | TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_CORPSE_ENEMY | TARGET_FLAG_UNIT_MINIPET)) - data << m_objectTargetGUID.WriteAsPacked(); - - if (m_targetMask & (TARGET_FLAG_ITEM | TARGET_FLAG_TRADE_ITEM)) - { - if (m_itemTarget) - data << m_itemTarget->GetPackGUID(); - else - data << uint8(0); - } - - if (m_targetMask & TARGET_FLAG_SOURCE_LOCATION) - { - data << m_src._transportGUID.WriteAsPacked(); // relative position guid here - transport for example - if (!m_src._transportGUID.IsEmpty()) - data << m_src._transportOffset.PositionXYZStream(); - else - data << m_src._position.PositionXYZStream(); - } - - if (m_targetMask & TARGET_FLAG_DEST_LOCATION) - { - data << m_dst._transportGUID.WriteAsPacked(); // relative position guid here - transport for example - if (!m_dst._transportGUID.IsEmpty()) - data << m_dst._transportOffset.PositionXYZStream(); - else - data << m_dst._position.PositionXYZStream(); - } - - if (m_targetMask & TARGET_FLAG_STRING) - data << m_strTarget;*/ } ObjectGuid SpellCastTargets::GetOrigUnitTargetGUID() const @@ -665,7 +641,7 @@ m_spellValue(new SpellValue(caster->GetMap()->GetDifficultyID(), m_spellInfo)), m_procEx = 0; focusObject = NULL; m_cast_count = 0; - m_glyphIndex = 0; + m_misc.Data = 0; m_preCastSpell = 0; m_triggeredByAuraSpell = NULL; m_spellAura = NULL; @@ -3744,7 +3720,7 @@ void Spell::SendCastResult(SpellCastResult result) if (m_caster->ToPlayer()->GetSession()->PlayerLoading()) // don't send cast results at loading time return; - SendCastResult(m_caster->ToPlayer(), m_spellInfo, m_cast_count, result, m_customError); + SendCastResult(m_caster->ToPlayer(), m_spellInfo, m_cast_count, result, m_customError, SMSG_CAST_FAILED, m_misc.Data); } void Spell::SendPetCastResult(SpellCastResult result) @@ -3756,10 +3732,10 @@ void Spell::SendPetCastResult(SpellCastResult result) if (!owner || owner->GetTypeId() != TYPEID_PLAYER) return; - SendCastResult(owner->ToPlayer(), m_spellInfo, m_cast_count, result, SPELL_CUSTOM_ERROR_NONE, SMSG_PET_CAST_FAILED); + SendCastResult(owner->ToPlayer(), m_spellInfo, m_cast_count, result, SPELL_CUSTOM_ERROR_NONE, SMSG_PET_CAST_FAILED, m_misc.Data); } -void Spell::SendCastResult(Player* caster, SpellInfo const* spellInfo, uint8 cast_count, SpellCastResult result, SpellCustomErrors customError /*= SPELL_CUSTOM_ERROR_NONE*/, OpcodeServer opcode /*= SMSG_CAST_FAILED*/) +void Spell::SendCastResult(Player* caster, SpellInfo const* spellInfo, uint8 cast_count, SpellCastResult result, SpellCustomErrors customError /*= SPELL_CUSTOM_ERROR_NONE*/, OpcodeServer opcode /*= SMSG_CAST_FAILED*/, uint32 misc /*= 0*/) { if (result == SPELL_CAST_OK) return; @@ -3870,6 +3846,12 @@ void Spell::SendCastResult(Player* caster, SpellInfo const* spellInfo, uint8 cas packet.FailedArg1 = missingItem; // first missing item break; } + case SPELL_FAILED_CANT_UNTALENT: + { + if (TalentEntry const* talent = sTalentStore.LookupEntry(misc)) + packet.FailedArg1 = talent->SpellID; + break; + } // TODO: SPELL_FAILED_NOT_STANDING default: break; @@ -5606,12 +5588,25 @@ SpellCastResult Spell::CheckCast(bool strict) break; } case SPELL_EFFECT_TALENT_SPEC_SELECT: + { // can't change during already started arena/battleground if (m_caster->GetTypeId() == TYPEID_PLAYER) if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground()) if (bg->GetStatus() == STATUS_IN_PROGRESS) return SPELL_FAILED_NOT_IN_BATTLEGROUND; break; + } + case SPELL_EFFECT_REMOVE_TALENT: + { + if (m_caster->GetTypeId() != TYPEID_PLAYER) + return SPELL_FAILED_BAD_TARGETS; + TalentEntry const* talent = sTalentStore.LookupEntry(m_misc.TalentId); + if (!talent) + return SPELL_FAILED_DONT_REPORT; + if (m_caster->ToPlayer()->HasSpellCooldown(talent->SpellID)) + return SPELL_FAILED_CANT_UNTALENT; + break; + } default: break; } diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index a8ff53b5cb1..48a62ab0e10 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -107,7 +107,7 @@ class SpellCastTargets { public: SpellCastTargets(); - SpellCastTargets(Unit* caster, uint32 targetMask, ObjectGuid targetGuid, ObjectGuid itemTargetGuid, ObjectGuid srcTransportGuid, ObjectGuid destTransportGuid, Position srcPos, Position destPos, float elevation, float missileSpeed, std::string targetString); + SpellCastTargets(Unit* caster, WorldPackets::Spells::SpellTargetData const& spellTargetData); ~SpellCastTargets(); void Read(ByteBuffer& data, Unit* caster); @@ -364,6 +364,7 @@ class Spell void EffectGiveCurrency(SpellEffIndex effIndex); void EffectResurrectWithAura(SpellEffIndex effIndex); void EffectCreateAreaTrigger(SpellEffIndex effIndex); + void EffectRemoveTalent(SpellEffIndex effIndex); typedef std::set<Aura*> UsedSpellMods; @@ -444,7 +445,7 @@ class Spell void CheckSrc() { if (!m_targets.HasSrc()) m_targets.SetSrc(*m_caster); } void CheckDst() { if (!m_targets.HasDst()) m_targets.SetDst(*m_caster); } - static void SendCastResult(Player* caster, SpellInfo const* spellInfo, uint8 cast_count, SpellCastResult result, SpellCustomErrors customError = SPELL_CUSTOM_ERROR_NONE, OpcodeServer opcode = SMSG_CAST_FAILED); + static void SendCastResult(Player* caster, SpellInfo const* spellInfo, uint8 cast_count, SpellCastResult result, SpellCustomErrors customError = SPELL_CUSTOM_ERROR_NONE, OpcodeServer opcode = SMSG_CAST_FAILED, uint32 misc = 0); void SendCastResult(SpellCastResult result); void SendPetCastResult(SpellCastResult result); void SendSpellStart(); @@ -475,7 +476,14 @@ class Spell ObjectGuid m_castItemGUID; uint32 m_castItemEntry; uint8 m_cast_count; - uint32 m_glyphIndex; + union + { + // Alternate names for this value + uint32 TalentId; + uint32 GlyphSlot; + + uint32 Data; + } m_misc; uint32 m_preCastSpell; SpellCastTargets m_targets; int8 m_comboPointGain; diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 64e74424f70..7c5ab810ce4 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -250,7 +250,7 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]= &Spell::EffectUnused, //178 SPELL_EFFECT_178 unused &Spell::EffectCreateAreaTrigger, //179 SPELL_EFFECT_CREATE_AREATRIGGER &Spell::EffectNULL, //180 SPELL_EFFECT_UPDATE_AREATRIGGER - &Spell::EffectNULL, //181 SPELL_EFFECT_REMOVE_TALENT + &Spell::EffectRemoveTalent, //181 SPELL_EFFECT_REMOVE_TALENT &Spell::EffectNULL, //182 SPELL_EFFECT_182 &Spell::EffectNULL, //183 SPELL_EFFECT_183 &Spell::EffectNULL, //184 SPELL_EFFECT_REPUTATION @@ -3938,7 +3938,7 @@ void Spell::EffectStuck(SpellEffIndex /*effIndex*/) { if (!player->GetDeathTimer()) player->RepopAtGraveyard(); - + return; } @@ -3948,7 +3948,7 @@ void Spell::EffectStuck(SpellEffIndex /*effIndex*/) player->Kill(player); return; } - + player->TeleportTo(player->m_homebindMapId, player->m_homebindX, player->m_homebindY, player->m_homebindZ, player->GetOrientation(), TELE_TO_SPELL); // Stuck spell trigger Hearthstone cooldown @@ -4005,7 +4005,7 @@ void Spell::EffectApplyGlyph(SpellEffIndex /*effIndex*/) if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT) return; - if (m_glyphIndex >= MAX_GLYPH_SLOT_INDEX) + if (m_misc.GlyphSlot >= MAX_GLYPH_SLOT_INDEX) return; Player* player = m_caster->ToPlayer(); @@ -4014,7 +4014,7 @@ void Spell::EffectApplyGlyph(SpellEffIndex /*effIndex*/) // glyph sockets level requirement uint8 minLevel = 0; - switch (m_glyphIndex) + switch (m_misc.GlyphSlot) { case 0: case 1: @@ -4038,7 +4038,7 @@ void Spell::EffectApplyGlyph(SpellEffIndex /*effIndex*/) { if (GlyphPropertiesEntry const* newGlyphProperties = sGlyphPropertiesStore.LookupEntry(newGlyph)) { - if (GlyphSlotEntry const* newGlyphSlot = sGlyphSlotStore.LookupEntry(player->GetGlyphSlot(m_glyphIndex))) + if (GlyphSlotEntry const* newGlyphSlot = sGlyphSlotStore.LookupEntry(player->GetGlyphSlot(m_misc.GlyphSlot))) { if (newGlyphProperties->Type != newGlyphSlot->Type) { @@ -4048,26 +4048,26 @@ void Spell::EffectApplyGlyph(SpellEffIndex /*effIndex*/) } // remove old glyph - if (uint32 oldGlyph = player->GetGlyph(player->GetActiveTalentGroup(), m_glyphIndex)) + if (uint32 oldGlyph = player->GetGlyph(player->GetActiveTalentGroup(), m_misc.GlyphSlot)) { if (GlyphPropertiesEntry const* oldGlyphProperties = sGlyphPropertiesStore.LookupEntry(oldGlyph)) { player->RemoveAurasDueToSpell(oldGlyphProperties->SpellID); - player->SetGlyph(m_glyphIndex, 0); + player->SetGlyph(m_misc.GlyphSlot, 0); } } player->CastSpell(m_caster, newGlyphProperties->SpellID, true); - player->SetGlyph(m_glyphIndex, newGlyph); + player->SetGlyph(m_misc.GlyphSlot, newGlyph); player->SendTalentsInfoData(); } } - else if (uint32 oldGlyph = player->GetGlyph(player->GetActiveTalentGroup(), m_glyphIndex)) // Removing the glyph, get the old one + else if (uint32 oldGlyph = player->GetGlyph(player->GetActiveTalentGroup(), m_misc.GlyphSlot)) // Removing the glyph, get the old one { if (GlyphPropertiesEntry const* oldGlyphProperties = sGlyphPropertiesStore.LookupEntry(oldGlyph)) { player->RemoveAurasDueToSpell(oldGlyphProperties->SpellID); - player->SetGlyph(m_glyphIndex, 0); + player->SetGlyph(m_misc.GlyphSlot, 0); player->SendTalentsInfoData(); } } @@ -5768,3 +5768,20 @@ void Spell::EffectCreateAreaTrigger(SpellEffIndex /*effIndex*/) if (!areaTrigger->CreateAreaTrigger(sObjectMgr->GetGenerator<HighGuid::AreaTrigger>()->Generate(), triggerEntry, GetCaster(), GetSpellInfo(), pos)) delete areaTrigger; } + +void Spell::EffectRemoveTalent(SpellEffIndex effIndex) +{ + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + + TalentEntry const* talent = sTalentStore.LookupEntry(m_misc.TalentId); + if (!talent) + return; + + Player* player = unitTarget ? unitTarget->ToPlayer() : nullptr; + if (!player) + return; + + player->RemoveTalent(talent); + player->SendTalentsInfoData(); +} diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 1f6b5238137..a70c73de6df 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -875,9 +875,71 @@ SpellEffectInfo::StaticData SpellEffectInfo::_data[TOTAL_SPELL_EFFECTS] = {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 177 SPELL_EFFECT_177 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 178 SPELL_EFFECT_178 {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 179 SPELL_EFFECT_CREATE_AREATRIGGER - {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 180 SPELL_EFFECT_180 - {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 181 SPELL_EFFECT_181 - {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 182 SPELL_EFFECT_182 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 180 SPELL_EFFECT_UPDATE_AREATRIGGER + {EFFECT_IMPLICIT_TARGET_CASTER, TARGET_OBJECT_TYPE_UNIT}, // 181 SPELL_EFFECT_REMOVE_TALENT + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 182 SPELL_EFFECT_182 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 183 SPELL_EFFECT_183 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 184 SPELL_EFFECT_REPUTATION_2 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 185 SPELL_EFFECT_185 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 186 SPELL_EFFECT_186 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 187 SPELL_EFFECT_RANDOMIZE_ARCHAEOLOGY_DIGSITES + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 188 SPELL_EFFECT_188 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 189 SPELL_EFFECT_LOOT + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 190 SPELL_EFFECT_190 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 191 SPELL_EFFECT_TELEPORT_TO_DIGSITE + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 192 SPELL_EFFECT_192 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 193 SPELL_EFFECT_193 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 194 SPELL_EFFECT_194 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 195 SPELL_EFFECT_195 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 196 SPELL_EFFECT_196 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 197 SPELL_EFFECT_197 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 198 SPELL_EFFECT_198 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 199 SPELL_EFFECT_199 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 200 SPELL_EFFECT_HEAL_BATTLEPET_PCT + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 201 SPELL_EFFECT_ENABLE_BATTLE_PETS + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 202 SPELL_EFFECT_202 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 203 SPELL_EFFECT_203 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 204 SPELL_EFFECT_204 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 205 SPELL_EFFECT_205 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 206 SPELL_EFFECT_206 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 207 SPELL_EFFECT_207 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 208 SPELL_EFFECT_208 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 209 SPELL_EFFECT_209 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 210 SPELL_EFFECT_210 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 211 SPELL_EFFECT_211 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 212 SPELL_EFFECT_212 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 213 SPELL_EFFECT_213 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 214 SPELL_EFFECT_214 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 215 SPELL_EFFECT_215 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 216 SPELL_EFFECT_216 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 217 SPELL_EFFECT_217 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 218 SPELL_EFFECT_218 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 219 SPELL_EFFECT_219 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 220 SPELL_EFFECT_220 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 221 SPELL_EFFECT_221 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 222 SPELL_EFFECT_222 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 223 SPELL_EFFECT_223 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 224 SPELL_EFFECT_224 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 225 SPELL_EFFECT_225 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 226 SPELL_EFFECT_226 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 227 SPELL_EFFECT_227 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 228 SPELL_EFFECT_228 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 229 SPELL_EFFECT_229 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 230 SPELL_EFFECT_230 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 231 SPELL_EFFECT_231 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 232 SPELL_EFFECT_232 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 233 SPELL_EFFECT_233 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 234 SPELL_EFFECT_234 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 235 SPELL_EFFECT_235 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 236 SPELL_EFFECT_236 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 237 SPELL_EFFECT_237 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 238 SPELL_EFFECT_238 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 239 SPELL_EFFECT_239 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 240 SPELL_EFFECT_240 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 241 SPELL_EFFECT_241 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 242 SPELL_EFFECT_242 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 243 SPELL_EFFECT_243 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 244 SPELL_EFFECT_244 }; SpellInfo::SpellInfo(SpellEntry const* spellEntry, SpellEffectEntryMap effects) diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h index 5b9cfacb56b..b585588726e 100644 --- a/src/server/game/Spells/SpellInfo.h +++ b/src/server/game/Spells/SpellInfo.h @@ -186,6 +186,7 @@ enum SpellCustomAttributes SPELL_ATTR0_CU_CONE_LINE = 0x00000004, SPELL_ATTR0_CU_SHARE_DAMAGE = 0x00000008, SPELL_ATTR0_CU_NO_INITIAL_THREAT = 0x00000010, + SPELL_ATTR0_CU_IS_TALENT = 0x00000020, SPELL_ATTR0_CU_AURA_CC = 0x00000040, SPELL_ATTR0_CU_DIRECT_DAMAGE = 0x00000100, SPELL_ATTR0_CU_CHARGE = 0x00000200, diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index d8bfed43c2b..85a04c6bf4e 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -1251,73 +1251,8 @@ void SpellMgr::UnloadSpellInfoChains() mSpellChains.clear(); } -void SpellMgr::LoadSpellTalentRanks() -{ - /* TODO: 6.x remove this - // cleanup core data before reload - remove reference to ChainNode from SpellInfo - UnloadSpellInfoChains(); - - for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i) - { - TalentEntry const* talentInfo = sTalentStore.LookupEntry(i); - if (!talentInfo) - continue; - - SpellInfo const* lastSpell = NULL; - for (uint8 rank = MAX_TALENT_RANK - 1; rank > 0; --rank) - { - if (talentInfo->RankID[rank]) - { - lastSpell = GetSpellInfo(talentInfo->RankID[rank]); - break; - } - } - - if (!lastSpell) - continue; - - SpellInfo const* firstSpell = GetSpellInfo(talentInfo->RankID[0]); - if (!firstSpell) - { - TC_LOG_ERROR("spells", "SpellMgr::LoadSpellTalentRanks: First Rank Spell %u for TalentEntry %u does not exist.", talentInfo->RankID[0], i); - continue; - } - - SpellInfo const* prevSpell = NULL; - for (uint8 rank = 0; rank < MAX_TALENT_RANK; ++rank) - { - uint32 spellId = talentInfo->RankID[rank]; - if (!spellId) - break; - - SpellInfo const* currentSpell = GetSpellInfo(spellId); - if (!currentSpell) - { - TC_LOG_ERROR("spells", "SpellMgr::LoadSpellTalentRanks: Spell %u (Rank: %u) for TalentEntry %u does not exist.", spellId, rank + 1, i); - break; - } - - SpellChainNode node; - node.first = firstSpell; - node.last = lastSpell; - node.rank = rank + 1; - - node.prev = prevSpell; - node.next = node.rank < MAX_TALENT_RANK ? GetSpellInfo(talentInfo->RankID[node.rank]) : NULL; - - mSpellChains[spellId] = node; - mSpellInfoMap[spellId]->ChainEntry = &mSpellChains[spellId]; - - prevSpell = currentSpell; - } - }*/ -} - void SpellMgr::LoadSpellRanks() { - // cleanup data and load spell ranks for talents from dbc - LoadSpellTalentRanks(); - uint32 oldMSTime = getMSTime(); // 0 1 2 @@ -1553,7 +1488,8 @@ void SpellMgr::LoadSpellLearnSpells() node.active = fields[2].GetBool(); node.autoLearned = false; - if (!GetSpellInfo(spell_id)) + SpellInfo const* spellInfo = GetSpellInfo(spell_id); + if (!spellInfo) { TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_learn_spell` does not exist", spell_id); continue; @@ -1565,7 +1501,7 @@ void SpellMgr::LoadSpellLearnSpells() continue; } - if (GetTalentBySpellID(node.spell)) + if (spellInfo->HasAttribute(SPELL_ATTR0_CU_IS_TALENT)) { TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_learn_spell` attempt learning talent spell %u, skipped", spell_id, node.spell); continue; @@ -1603,7 +1539,7 @@ void SpellMgr::LoadSpellLearnSpells() // talent or passive spells or skill-step spells auto-cast and not need dependent learning, // pet teaching spells must not be dependent learning (cast) // other required explicit dependent learning - dbc_node.autoLearned = effect->TargetA.GetTarget() == TARGET_UNIT_PET || GetTalentBySpellID(spell) || entry->IsPassive() || entry->HasEffect(SPELL_EFFECT_SKILL_STEP); + dbc_node.autoLearned = effect->TargetA.GetTarget() == TARGET_UNIT_PET || entry->HasAttribute(SPELL_ATTR0_CU_IS_TALENT) || entry->IsPassive() || entry->HasEffect(SPELL_EFFECT_SKILL_STEP); SpellLearnSpellMapBounds db_node_bounds = dbSpellLearnSpells.equal_range(spell); @@ -1654,7 +1590,7 @@ void SpellMgr::LoadSpellLearnSpells() { if (itr->second.spell == mastery) { - TC_LOG_ERROR("sql.sql", "Found redundant record (entry: %u, SpellID: %u) in `spell_learn_spell`, spell added automatically as mastery learned spell from TalentTab.dbc", masteryMainSpell, mastery); + TC_LOG_ERROR("sql.sql", "Found redundant record (entry: %u, SpellID: %u) in `spell_learn_spell`, spell added automatically as mastery learned spell from ChrSpecialization.dbc", masteryMainSpell, mastery); found = true; break; } @@ -2873,6 +2809,11 @@ void SpellMgr::LoadSpellInfoCustomAttributes() TC_LOG_INFO("server.loading", ">> Loaded %u spell custom attributes from DB in %u ms", count, GetMSTimeDiffToNow(oldMSTime2)); } + std::set<uint32> talentSpells; + for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i) + if (TalentEntry const* talentInfo = sTalentStore.LookupEntry(i)) + talentSpells.insert(talentInfo->SpellID); + for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i) { spellInfo = mSpellInfoMap[i]; @@ -2986,6 +2927,9 @@ void SpellMgr::LoadSpellInfoCustomAttributes() if (spellInfo->SpellVisual[0] == 3879) spellInfo->AttributesCu |= SPELL_ATTR0_CU_CONE_BACK; + if (talentSpells.count(spellInfo->Id)) + spellInfo->AttributesCu |= SPELL_ATTR0_CU_IS_TALENT; + switch (spellInfo->SpellFamilyName) { case SPELLFAMILY_WARRIOR: diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h index 74423f6e4f3..36ffe105c54 100644 --- a/src/server/game/Spells/SpellMgr.h +++ b/src/server/game/Spells/SpellMgr.h @@ -695,7 +695,6 @@ class SpellMgr // Loading data at server startup void UnloadSpellInfoChains(); - void LoadSpellTalentRanks(); void LoadSpellRanks(); void LoadSpellRequired(); void LoadSpellLearnSkills(); |
