diff options
-rw-r--r-- | src/game/Spell.cpp | 35 | ||||
-rw-r--r-- | src/game/SpellMgr.cpp | 59 | ||||
-rw-r--r-- | src/game/SpellMgr.h | 11 | ||||
-rw-r--r-- | src/game/Unit.cpp | 12 |
4 files changed, 69 insertions, 48 deletions
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index a3fb99fe405..41d79e5203c 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -922,6 +922,14 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target) if(m_caster->GetTypeId() == TYPEID_UNIT && ((Creature*)m_caster)->AI()) ((Creature*)m_caster)->AI()->SpellHitTarget(unit, m_spellInfo); + + if(int32 spell_triggered = spellmgr.GetSpellLinked(m_spellInfo->Id, 1)) + { + if(spell_triggered > 0) + m_caster->CastSpell(unit, spell_triggered, true); + else + unit->RemoveAurasDueToSpell(-spell_triggered); + } } void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask) @@ -1286,16 +1294,17 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap) else radius = GetSpellMaxRange(sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex)); - if(m_originalCaster) - if(Player* modOwner = m_originalCaster->GetSpellModOwner()) - modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RADIUS, radius,this); - uint32 EffectChainTarget = m_spellInfo->EffectChainTarget[i]; + uint32 unMaxTargets = m_spellInfo->MaxAffectedTargets; if(m_originalCaster) + { if(Player* modOwner = m_originalCaster->GetSpellModOwner()) + { + modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RADIUS, radius,this); modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_JUMP_TARGETS, EffectChainTarget, this); + } + } - uint32 unMaxTargets = m_spellInfo->MaxAffectedTargets; switch(cur) { // specific unit @@ -1551,9 +1560,15 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap) else if(goScriptTarget) m_targets.setDestination(goScriptTarget->GetPositionX(),goScriptTarget->GetPositionY(),goScriptTarget->GetPositionZ()); } + else + { + if(creatureScriptTarget) + TagUnitMap.push_back(creatureScriptTarget); + else if(goScriptTarget) + AddGOTarget(goScriptTarget, i); + } }break; - // dummy case TARGET_AREAEFFECT_CUSTOM_2: { @@ -2177,6 +2192,14 @@ void Spell::cast(bool skipCheck) } } + if(int32 spell_triggered = spellmgr.GetSpellLinked(m_spellInfo->Id, 0)) + { + if(spell_triggered > 0) + m_caster->CastSpell(m_targets.getUnitTarget() ? m_targets.getUnitTarget() : m_caster, spell_triggered, true); + else + m_caster->RemoveAurasDueToSpell(-spell_triggered); + } + // traded items have trade slot instead of guid in m_itemTargetGUID // set to real guid to be sent later to the client m_targets.updateTradeSlotItem(); diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index cd934534c2f..dec7225e4b5 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -2051,14 +2051,14 @@ void SpellMgr::LoadSpellLinked() mSpellLinkedMap.clear(); // need for reload case uint32 count = 0; - // 0 1 - QueryResult *result = WorldDatabase.Query("SELECT spell0, spell1 FROM spell_linked_spell"); + // 0 1 2 + QueryResult *result = WorldDatabase.Query("SELECT spell_trigger, spell_effect, type FROM spell_linked_spell"); if( !result ) { barGoLink bar( 1 ); bar.step(); sLog.outString(); - sLog.outString( ">> Loaded %u spell pet auras", count ); + sLog.outString( ">> Loaded %u linked spells", count ); return; } @@ -2070,54 +2070,35 @@ void SpellMgr::LoadSpellLinked() bar.step(); - uint16 spell = fields[0].GetUInt16(); - uint16 pet = fields[1].GetUInt16(); - uint16 aura = fields[2].GetUInt16(); + int32 trigger = fields[0].GetInt32(); + int32 effect = fields[1].GetInt32(); + int32 type = fields[2].GetInt32(); - SpellPetAuraMap::iterator itr = mSpellPetAuraMap.find(spell); - if(itr != mSpellPetAuraMap.end()) + SpellEntry const* spellInfo = sSpellStore.LookupEntry(abs(trigger)); + if (!spellInfo) { - itr->second.AddAura(pet, aura); + sLog.outErrorDb("Spell %u listed in `spell_linked_spell` does not exist", abs(trigger)); + continue; } - else + spellInfo = sSpellStore.LookupEntry(abs(effect)); + if (!spellInfo) { - SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell); - if (!spellInfo) - { - sLog.outErrorDb("Spell %u listed in `spell_pet_auras` does not exist", spell); - continue; - } - int i = 0; - for(; i < 3; ++i) - if((spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA && - spellInfo->EffectApplyAuraName[i] == SPELL_AURA_DUMMY) || - spellInfo->Effect[i] == SPELL_EFFECT_DUMMY) - break; - - if(i == 3) - { - sLog.outError("Spell %u listed in `spell_pet_auras` does not have dummy aura or dummy effect", spell); - continue; - } - - SpellEntry const* spellInfo2 = sSpellStore.LookupEntry(aura); - if (!spellInfo2) - { - sLog.outErrorDb("Aura %u listed in `spell_pet_auras` does not exist", aura); - continue; - } - - PetAura pa(pet, aura, spellInfo->EffectImplicitTargetA[i] == TARGET_PET, spellInfo->EffectBasePoints[i] + spellInfo->EffectBaseDice[i]); - mSpellPetAuraMap[spell] = pa; + sLog.outErrorDb("Spell %u listed in `spell_linked_spell` does not exist", abs(effect)); + continue; } + SpellLinkedSpell linkedSpell; + linkedSpell.spell = effect; + linkedSpell.type = type; + mSpellLinkedMap[trigger] = linkedSpell; + ++count; } while( result->NextRow() ); delete result; sLog.outString(); - sLog.outString( ">> Loaded %u spell pet auras", count ); + sLog.outString( ">> Loaded %u linked spells", count ); } /// Some checks for spells, to prevent adding depricated/broken spells for trainers, spell book, etc diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index b374b65857d..4e4f524a8dc 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -648,7 +648,12 @@ struct SpellExtraAttribute typedef std::map<uint32, SpellExtraAttribute> SpellExtraAttrMap; -typedef std::map<int32, int32> SpellLinkedMap; +struct SpellLinkedSpell +{ + int32 spell; + uint32 type; +}; +typedef std::map<int32, SpellLinkedSpell> SpellLinkedMap; class SpellMgr { @@ -857,11 +862,11 @@ class SpellMgr return 0; } - int32 GetSpellLinked(int32 spell_id) const + int32 GetSpellLinked(int32 spell_id, uint32 type) const { SpellLinkedMap::const_iterator itr = mSpellLinkedMap.find(spell_id); if(itr != mSpellLinkedMap.end()) - return itr->second; + return itr->second.type == type ? itr->second.spell : 0; else return 0; } diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index d079219588b..118fa71c761 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -4163,6 +4163,18 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode) if(caster->GetTypeId()==TYPEID_UNIT && ((Creature*)caster)->isTotem() && ((Totem*)caster)->GetTotemType()==TOTEM_STATUE) statue = ((Totem*)caster); + + if(int32 spell_triggered = spellmgr.GetSpellLinked(-(int32)Aur->GetSpellProto()->Id, 0)) + { + if(spell_triggered > 0) + { + if(Unit* caster = Aur->GetCaster()) + CastSpell(this, spell_triggered, true, 0, 0, caster->GetGUID()); + } + else + RemoveAurasDueToSpell(-spell_triggered); + } + sLog.outDebug("Aura %u now is remove mode %d",Aur->GetModifier()->m_auraname, mode); Aur->ApplyModifier(false,true); Aur->_RemoveAura(); |