diff options
-rw-r--r-- | src/server/game/Entities/Creature/GossipDef.cpp | 18 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 40 | ||||
-rw-r--r-- | src/server/game/Handlers/QuestHandler.cpp | 3 | ||||
-rw-r--r-- | src/server/game/Spells/SpellInfo.cpp | 24 | ||||
-rw-r--r-- | src/server/game/Spells/SpellInfo.h | 2 |
5 files changed, 64 insertions, 23 deletions
diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp index 743c27d5076..ef9d465dc6e 100644 --- a/src/server/game/Entities/Creature/GossipDef.cpp +++ b/src/server/game/Entities/Creature/GossipDef.cpp @@ -26,6 +26,8 @@ #include "Player.h" #include "QuestDef.h" #include "QuestPackets.h" +#include "SpellInfo.h" +#include "SpellMgr.h" #include "World.h" #include "WorldSession.h" @@ -447,8 +449,20 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const* quest, ObjectGuid npcGU packet.QuestFlags[1] = quest->GetFlagsEx(); packet.SuggestedPartyMembers = quest->GetSuggestedPlayers(); - if (quest->GetSrcSpell()) - packet.LearnSpells.push_back(quest->GetSrcSpell()); + // RewardSpell can teach multiple spells in trigger spell effects. But not all effects must be SPELL_EFFECT_LEARN_SPELL. See example spell 33950 + if (quest->GetRewSpell()) + { + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(quest->GetRewSpell()); + if (spellInfo->HasEffect(SPELL_EFFECT_LEARN_SPELL)) + { + SpellEffectInfoVector effects = spellInfo->GetEffectsForDifficulty(DIFFICULTY_NONE); + for (SpellEffectInfoVector::const_iterator itr = effects.begin(); itr != effects.end(); ++itr) + { + if ((*itr)->IsEffect(SPELL_EFFECT_LEARN_SPELL)) + packet.LearnSpells.push_back((*itr)->TriggerSpell); + } + } + } quest->BuildQuestRewards(packet.Rewards, _session->GetPlayer()); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 6fcbaf5b621..2d61bd36c50 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -15181,6 +15181,17 @@ void Player::AddQuest(Quest const* quest, Object* questGiver) UpdatePvPState(); } + if (quest->GetSrcSpell() > 0) + { + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(quest->GetSrcSpell()); + Unit* caster = this; + if (questGiver && questGiver->isType(TYPEMASK_UNIT) && !quest->HasFlag(QUEST_FLAGS_PLAYER_CAST_ON_ACCEPT) && !spellInfo->HasTargetType(TARGET_UNIT_CASTER) && !spellInfo->HasTargetType(TARGET_DEST_CASTER_SUMMON)) + if (Unit* unit = questGiver->ToUnit()) + unit->CastSpell(this, quest->GetSrcSpell(), true); + + caster->CastSpell(this, quest->GetSrcSpell(), true); + } + SetQuestSlot(log_slot, quest_id, qtime); m_QuestStatusSave[quest_id] = QUEST_DEFAULT_SAVE_TYPE; @@ -15498,16 +15509,12 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver, if (quest->GetRewSpell() > 0) { SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(quest->GetRewSpell()); - if (questGiver && questGiver->isType(TYPEMASK_UNIT) && - !spellInfo->HasEffect(DIFFICULTY_NONE, SPELL_EFFECT_LEARN_SPELL) && - !spellInfo->HasEffect(DIFFICULTY_NONE, SPELL_EFFECT_CREATE_ITEM) && - !spellInfo->HasEffect(DIFFICULTY_NONE, SPELL_EFFECT_APPLY_AURA)) - { + Unit* caster = this; + if (questGiver && questGiver->isType(TYPEMASK_UNIT) && !quest->HasFlag(QUEST_FLAGS_PLAYER_CAST_ON_COMPLETE) && !spellInfo->HasTargetType(TARGET_UNIT_CASTER)) if (Unit* unit = questGiver->ToUnit()) - unit->CastSpell(this, quest->GetRewSpell(), true); - } - else - CastSpell(this, quest->GetRewSpell(), true); + caster = unit; + + caster->CastSpell(this, quest->GetRewSpell(), true); } else { @@ -15516,15 +15523,12 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver, if (quest->RewardDisplaySpell[i] > 0) { SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(quest->RewardDisplaySpell[i]); - if (questGiver && questGiver->isType(TYPEMASK_UNIT) && - !spellInfo->HasEffect(DIFFICULTY_NONE, SPELL_EFFECT_LEARN_SPELL) && - !spellInfo->HasEffect(DIFFICULTY_NONE, SPELL_EFFECT_CREATE_ITEM)) - { - if (Unit* unit = questGiver->ToUnit()) - unit->CastSpell(this, quest->RewardDisplaySpell[i], true); - } - else - CastSpell(this, quest->RewardDisplaySpell[i], true); + Unit* caster = this; + if (questGiver && questGiver->isType(TYPEMASK_UNIT) && !quest->HasFlag(QUEST_FLAGS_PLAYER_CAST_ON_COMPLETE) && !spellInfo->HasTargetType(TARGET_UNIT_CASTER)) + if (Unit * unit = questGiver->ToUnit()) + caster = unit; + + caster->CastSpell(this, quest->RewardDisplaySpell[i], true); } } } diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp index 41c483ea0a1..395832b2788 100644 --- a/src/server/game/Handlers/QuestHandler.cpp +++ b/src/server/game/Handlers/QuestHandler.cpp @@ -201,9 +201,6 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPackets::Quest::QuestG _player->PlayerTalkClass->SendCloseGossip(); - if (quest->GetSrcSpell() > 0) - _player->CastSpell(_player, quest->GetSrcSpell(), true); - return; } } diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index ab364042f68..c93ceb775d1 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -1319,6 +1319,30 @@ bool SpellInfo::HasOnlyDamageEffects() const return true; } +bool SpellInfo::HasTargetType(::Targets target) const +{ + for (auto itr = _effects.begin(); itr != _effects.end(); ++itr) + { + for (SpellEffectInfo const* effect : itr->second) + { + if (effect && (effect->TargetA.GetTarget() == target || effect->TargetB.GetTarget() == target)) + return true; + } + } + return false; +} + +bool SpellInfo::HasTargetType(uint32 difficulty, ::Targets target) const +{ + SpellEffectInfoVector effects = GetEffectsForDifficulty(difficulty); + for (SpellEffectInfo const* effect : effects) + { + if (effect && (effect->TargetA.GetTarget() == target || effect->TargetB.GetTarget() == target)) + return true; + } + return false; +} + bool SpellInfo::HasAnyAuraInterruptFlag() const { return std::find_if(AuraInterruptFlags.begin(), AuraInterruptFlags.end(), [](uint32 flag) { return flag != 0; }) != AuraInterruptFlags.end(); diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h index 004189fc028..f253f4ed065 100644 --- a/src/server/game/Spells/SpellInfo.h +++ b/src/server/game/Spells/SpellInfo.h @@ -534,6 +534,8 @@ class TC_GAME_API SpellInfo bool HasAreaAuraEffect(uint32 difficulty) const; bool HasAreaAuraEffect() const; bool HasOnlyDamageEffects() const; + bool HasTargetType(::Targets target) const; + bool HasTargetType(uint32 difficulty, ::Targets target) const; bool HasAttribute(SpellAttr0 attribute) const { return !!(Attributes & attribute); } bool HasAttribute(SpellAttr1 attribute) const { return !!(AttributesEx & attribute); } |