aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLopfest <lopfest@gmail.com>2019-08-30 19:36:10 +0200
committerShauren <shauren.trinity@gmail.com>2019-08-30 19:36:10 +0200
commit7d2cbd4e7cec5737c742437e126ddb745d65f6a9 (patch)
tree9a7dee26c1e379d3edde648cdeceef106947325c /src
parent3df2e379eff98eba2c86bc6823cde1def6213afa (diff)
Core/Quests: Implement new logic for selecting spell casters for accept/reward spells based on quest flags (#21316)
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Creature/GossipDef.cpp18
-rw-r--r--src/server/game/Entities/Player/Player.cpp40
-rw-r--r--src/server/game/Handlers/QuestHandler.cpp3
-rw-r--r--src/server/game/Spells/SpellInfo.cpp24
-rw-r--r--src/server/game/Spells/SpellInfo.h2
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); }