diff --git a/Source/Game/Entities/Creature/Gossip.cs b/Source/Game/Entities/Creature/Gossip.cs index 6e4595dd8..96b22cfe9 100644 --- a/Source/Game/Entities/Creature/Gossip.cs +++ b/Source/Game/Entities/Creature/Gossip.cs @@ -22,8 +22,8 @@ using Game.Conditions; using Game.DataStorage; using Game.Entities; using Game.Network.Packets; +using Game.Spells; using System.Collections.Generic; -using System.Linq; namespace Game.Misc { @@ -440,8 +440,20 @@ namespace Game.Misc packet.QuestFlags[1] = (uint)quest.FlagsEx; packet.SuggestedPartyMembers = quest.SuggestedPlayers; - if (quest.SourceSpellID != 0) - packet.LearnSpells.Add(quest.SourceSpellID); + // 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.RewardSpell != 0) + { + SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(quest.RewardSpell); + if (spellInfo.HasEffect(SpellEffectName.LearnSpell)) + { + var effects = spellInfo.GetEffectsForDifficulty(Difficulty.None); + foreach (var spellEffectInfo in effects) + { + if (spellEffectInfo.IsEffect(SpellEffectName.LearnSpell)) + packet.LearnSpells.Add(spellEffectInfo.TriggerSpell); + } + } + } quest.BuildQuestRewards(packet.Rewards, _session.GetPlayer()); diff --git a/Source/Game/Entities/Player/Player.Quest.cs b/Source/Game/Entities/Player/Player.Quest.cs index 9d1474170..3d2bc6b49 100644 --- a/Source/Game/Entities/Player/Player.Quest.cs +++ b/Source/Game/Entities/Player/Player.Quest.cs @@ -774,6 +774,20 @@ namespace Game.Entities UpdatePvPState(); } + if (quest.SourceSpellID > 0) + { + SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(quest.SourceSpellID); + Unit caster = this; + if (questGiver != null && questGiver.isTypeMask(TypeMask.Unit) && !quest.HasFlag(QuestFlags.PlayerCastOnAccept) && !spellInfo.HasTargetType(Targets.UnitCaster) && !spellInfo.HasTargetType(Targets.DestCasterSummon)) + { + Unit unit = questGiver.ToUnit(); + if (unit != null) + unit.CastSpell(this, quest.SourceSpellID, true); + } + + caster.CastSpell(this, quest.SourceSpellID, true); + } + SetQuestSlot(log_slot, quest_id, qtime); m_QuestStatusSave[quest_id] = QuestSaveType.Default; @@ -1076,17 +1090,15 @@ namespace Game.Entities if (quest.RewardSpell > 0) { SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(quest.RewardSpell); - if (questGiver && questGiver.isTypeMask(TypeMask.Unit) - && !spellInfo.HasEffect(Difficulty.None, SpellEffectName.LearnSpell) - && !spellInfo.HasEffect(Difficulty.None, SpellEffectName.CreateItem) - && !spellInfo.HasEffect(Difficulty.None, SpellEffectName.ApplyAura)) + Unit caster = this; + if (questGiver != null && questGiver.isTypeMask(TypeMask.Unit) && !quest.HasFlag(QuestFlags.PlayerCastOnComplete) && !spellInfo.HasTargetType(Targets.UnitCaster)) { Unit unit = questGiver.ToUnit(); - if (unit) - unit.CastSpell(this, quest.RewardSpell, true); + if (unit != null) + caster = unit; } - else - CastSpell(this, quest.RewardSpell, true); + + caster.CastSpell(this, quest.RewardSpell, true); } else { @@ -1095,16 +1107,15 @@ namespace Game.Entities if (quest.RewardDisplaySpell[i] > 0) { SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(quest.RewardDisplaySpell[i]); - if (questGiver && questGiver.IsTypeId(TypeId.Unit) - && !spellInfo.HasEffect(Difficulty.None, SpellEffectName.LearnSpell) - && !spellInfo.HasEffect(Difficulty.None, SpellEffectName.CreateItem)) + Unit caster = this; + if (questGiver != null && questGiver.isTypeMask(TypeMask.Unit) && !quest.HasFlag(QuestFlags.PlayerCastOnComplete) && !spellInfo.HasTargetType(Targets.UnitCaster)) { Unit unit = questGiver.ToUnit(); - if (unit) - unit.CastSpell(this, quest.RewardDisplaySpell[i], true); + if (unit != null) + caster = unit; } - else - CastSpell(this, quest.RewardDisplaySpell[i], true); + + caster.CastSpell(this, quest.RewardDisplaySpell[i], true); } } } diff --git a/Source/Game/Handlers/QuestHandler.cs b/Source/Game/Handlers/QuestHandler.cs index 2ab2d0dd1..1d5c49a13 100644 --- a/Source/Game/Handlers/QuestHandler.cs +++ b/Source/Game/Handlers/QuestHandler.cs @@ -187,9 +187,6 @@ namespace Game _player.PlayerTalkClass.SendCloseGossip(); - if (quest.SourceSpellID > 0) - _player.CastSpell(_player, quest.SourceSpellID, true); - return; } } diff --git a/Source/Game/Spells/SpellInfo.cs b/Source/Game/Spells/SpellInfo.cs index b8b7ec696..aca3bfd2d 100644 --- a/Source/Game/Spells/SpellInfo.cs +++ b/Source/Game/Spells/SpellInfo.cs @@ -3648,6 +3648,30 @@ namespace Game.Spells return null; } + public bool HasTargetType(Targets target) + { + foreach (var pair in _effects) + { + foreach (SpellEffectInfo effect in pair.Value) + { + if (effect != null && (effect.TargetA.GetTarget() == target || effect.TargetB.GetTarget() == target)) + return true; + } + } + return false; + } + + public bool HasTargetType(Difficulty difficulty, Targets target) + { + var effects = GetEffectsForDifficulty(difficulty); + foreach (SpellEffectInfo effect in effects) + { + if (effect != null && (effect.TargetA.GetTarget() == target || effect.TargetB.GetTarget() == target)) + return true; + } + return false; + } + public bool HasAttribute(SpellAttr0 attribute) { return Convert.ToBoolean(Attributes & attribute); } public bool HasAttribute(SpellAttr1 attribute) { return Convert.ToBoolean(AttributesEx & attribute); } public bool HasAttribute(SpellAttr2 attribute) { return Convert.ToBoolean(AttributesEx2 & attribute); }