diff --git a/Source/Framework/Constants/CliDBConst.cs b/Source/Framework/Constants/CliDBConst.cs index be89cc1ef..0c7b400c2 100644 --- a/Source/Framework/Constants/CliDBConst.cs +++ b/Source/Framework/Constants/CliDBConst.cs @@ -42,7 +42,8 @@ namespace Framework.Constants public enum AbilityLearnType : byte { OnSkillValue = 1, // Spell state will update depending on skill value - OnSkillLearn = 2 // Spell will be learned/removed together with entire skill + OnSkillLearn = 2, // Spell will be learned/removed together with entire skill + RewardedFromQuest = 4 // Learned as quest reward, also re-learned if missing } public enum Anim diff --git a/Source/Game/Entities/Player/Player.Quest.cs b/Source/Game/Entities/Player/Player.Quest.cs index 7c75fad03..bfd82ae9a 100644 --- a/Source/Game/Entities/Player/Player.Quest.cs +++ b/Source/Game/Entities/Player/Player.Quest.cs @@ -119,12 +119,19 @@ namespace Game.Entities uint learned_0 = effect.TriggerSpell; if (!HasSpell(learned_0)) { - SpellInfo learnedInfo = Global.SpellMgr.GetSpellInfo(learned_0); - if (learnedInfo == null) - return; + found = false; + var skills = Global.SpellMgr.GetSkillLineAbilityMapBounds(learned_0); + foreach (var skillLine in skills) + { + if (skillLine.AcquireMethod == AbilityLearnType.RewardedFromQuest) + { + found = true; + break; + } + } // profession specialization can be re-learned from npc - if (learnedInfo.GetEffect(0).Effect == SpellEffectName.TradeSkill && learnedInfo.GetEffect(1).Effect == 0 && learnedInfo.SpellLevel == 0) + if (!found) return; } diff --git a/Source/Game/Spells/Spell.cs b/Source/Game/Spells/Spell.cs index b5e2ac770..cac0a9d10 100644 --- a/Source/Game/Spells/Spell.cs +++ b/Source/Game/Spells/Spell.cs @@ -4346,7 +4346,8 @@ namespace Game.Spells public SpellCastResult CheckCast(bool strict, ref uint param1, ref uint param2) { - SpellCastResult castResult = SpellCastResult.SpellCastOk; + SpellCastResult castResult; + // check death state if (!m_caster.IsAlive() && !m_spellInfo.IsPassive() && !(m_spellInfo.HasAttribute(SpellAttr0.CastableWhileDead) || (IsTriggered() && m_triggeredByAuraSpell == null))) return SpellCastResult.CasterDead; @@ -4527,18 +4528,6 @@ namespace Game.Spells Unit unitTarget = m_targets.GetUnitTarget(); if (unitTarget != null) { - // do not allow to cast on hostile targets in sanctuary - if (!m_caster.IsFriendlyTo(unitTarget)) - { - if (m_caster.IsInSanctuary() || unitTarget.IsInSanctuary()) - { - // fix for duels - Player playerDuel = m_caster.ToPlayer(); - if (!playerDuel || playerDuel.duel == null || unitTarget != playerDuel.duel.opponent) - return SpellCastResult.NothingToDispel; - } - } - castResult = m_spellInfo.CheckTarget(m_caster, unitTarget, m_caster.GetEntry() == SharedConst.WorldTrigger); // skip stealth checks for GO casts if (castResult != SpellCastResult.SpellCastOk) return castResult; @@ -4718,9 +4707,6 @@ namespace Game.Spells } case SpellEffectName.LearnSpell: { - if (!m_caster.IsTypeId(TypeId.Player)) - return SpellCastResult.BadTargets; - if (effect.TargetA.GetTarget() != Targets.UnitPet) break; @@ -5123,26 +5109,6 @@ namespace Game.Spells if (m_targets.GetUnitTarget() == null || m_targets.GetUnitTarget() == m_caster) return SpellCastResult.BadTargets; - uint dispelMask = SpellInfo.GetDispelMask((DispelType)effect.MiscValue); - bool hasStealableAura = false; - foreach (AuraApplication visibleAura in m_targets.GetUnitTarget().GetVisibleAuras()) - { - if (!visibleAura.IsPositive()) - continue; - - Aura aura = visibleAura.GetBase(); - if (!aura.GetSpellInfo().GetDispelMask().HasAnyFlag(dispelMask)) - continue; - - if (aura.IsPassive() || aura.GetSpellInfo().HasAttribute(SpellAttr4.NotStealable)) - continue; - - hasStealableAura = true; - break; - } - - if (!hasStealableAura) - return SpellCastResult.NothingToSteal; break; } case SpellEffectName.LeapBack: