void HandleCancelGrowthAura(CancelGrowthAura cancelGrowthAura) { GetPlayer().RemoveAurasByType(AuraType.ModScale, aurApp => { SpellInfo spellInfo = aurApp.GetBase().GetSpellInfo(); return(!spellInfo.HasAttribute(SpellAttr0.CantCancel) && spellInfo.IsPositive() && !spellInfo.IsPassive()); }); }
void HandleCancelMountAura(CancelMountAura packet) { GetPlayer().RemoveAurasByType(AuraType.Mounted, aurApp => { SpellInfo spellInfo = aurApp.GetBase().GetSpellInfo(); return(!spellInfo.HasAttribute(SpellAttr0.CantCancel) && spellInfo.IsPositive() && !spellInfo.IsPassive()); }); }
void HandleCancelAura(CancelAura cancelAura) { SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(cancelAura.SpellID); if (spellInfo == null) { return; } // not allow remove spells with attr SPELL_ATTR0_CANT_CANCEL if (spellInfo.HasAttribute(SpellAttr0.CantCancel)) { return; } // channeled spell case (it currently casted then) if (spellInfo.IsChanneled()) { Spell curSpell = GetPlayer().GetCurrentSpell(CurrentSpellTypes.Channeled); if (curSpell != null) { if (curSpell.GetSpellInfo().Id == cancelAura.SpellID) { GetPlayer().InterruptSpell(CurrentSpellTypes.Channeled); } } return; } // non channeled case: // don't allow remove non positive spells // don't allow cancelling passive auras (some of them are visible) if (!spellInfo.IsPositive() || spellInfo.IsPassive()) { return; } GetPlayer().RemoveOwnedAura(cancelAura.SpellID, cancelAura.CasterGUID, 0, AuraRemoveMode.Cancel); }
void HandleCastSpell(CastSpell cast) { // ignore for remote control state (for player case) Unit mover = GetPlayer().m_unitMovedByMe; if (mover != GetPlayer() && mover.IsTypeId(TypeId.Player)) { return; } SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(cast.Cast.SpellID); if (spellInfo == null) { Log.outError(LogFilter.Network, "WORLD: unknown spell id {0}", cast.Cast.SpellID); return; } if (spellInfo.IsPassive()) { return; } Unit caster = mover; if (caster.IsTypeId(TypeId.Unit) && !caster.ToCreature().HasSpell(spellInfo.Id)) { // If the vehicle creature does not have the spell but it allows the passenger to cast own spells // change caster to player and let him cast if (!GetPlayer().IsOnVehicle(caster) || spellInfo.CheckVehicle(GetPlayer()) != SpellCastResult.SpellCastOk) { return; } caster = GetPlayer(); } // check known spell or raid marker spell (which not requires player to know it) if (caster.IsTypeId(TypeId.Player) && !caster.ToPlayer().HasActiveSpell(spellInfo.Id) && !spellInfo.HasEffect(SpellEffectName.ChangeRaidMarker) && !spellInfo.HasAttribute(SpellAttr8.RaidMarker)) { return; } // Check possible spell cast overrides spellInfo = caster.GetCastSpellInfo(spellInfo); // Client is resending autoshot cast opcode when other spell is casted during shoot rotation // Skip it to prevent "interrupt" message if (spellInfo.IsAutoRepeatRangedSpell() && GetPlayer().GetCurrentSpell(CurrentSpellTypes.AutoRepeat) != null && GetPlayer().GetCurrentSpell(CurrentSpellTypes.AutoRepeat).m_spellInfo == spellInfo) { return; } // can't use our own spells when we're in possession of another unit, if (GetPlayer().isPossessing()) { return; } // client provided targets SpellCastTargets targets = new SpellCastTargets(caster, cast.Cast); // auto-selection buff level base at target level (in spellInfo) if (targets.GetUnitTarget() != null) { SpellInfo actualSpellInfo = spellInfo.GetAuraRankForLevel(targets.GetUnitTarget().GetLevelForTarget(caster)); // if rank not found then function return NULL but in explicit cast case original spell can be casted and later failed with appropriate error message if (actualSpellInfo != null) { spellInfo = actualSpellInfo; } } if (cast.Cast.MoveUpdate.HasValue) { HandleMovementOpcode(ClientOpcodes.MoveStop, cast.Cast.MoveUpdate.Value); } Spell spell = new Spell(caster, spellInfo, TriggerCastFlags.None, ObjectGuid.Empty, false); SpellPrepare spellPrepare = new SpellPrepare(); spellPrepare.ClientCastID = cast.Cast.CastID; spellPrepare.ServerCastID = spell.m_castId; SendPacket(spellPrepare); spell.m_fromClient = true; spell.m_misc.Data0 = cast.Cast.Misc[0]; spell.m_misc.Data1 = cast.Cast.Misc[1]; spell.prepare(targets); }
static bool SpellCheck(uint spell_id) { SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spell_id, Difficulty.None); return(spellInfo != null && !spellInfo.HasAttribute(SpellCustomAttributes.IsTalent)); }
void HandlePetAction(PetAction packet) { ObjectGuid guid1 = packet.PetGUID; //pet guid ObjectGuid guid2 = packet.TargetGUID; //tag guid uint spellid = UnitActionBarEntry.UNIT_ACTION_BUTTON_ACTION(packet.Action); ActiveStates flag = (ActiveStates)UnitActionBarEntry.UNIT_ACTION_BUTTON_TYPE(packet.Action); //delete = 0x07 CastSpell = C1 // used also for charmed creature Unit pet = Global.ObjAccessor.GetUnit(GetPlayer(), guid1); if (!pet) { Log.outError(LogFilter.Network, "HandlePetAction: {0} doesn't exist for {1}", guid1.ToString(), GetPlayer().GetGUID().ToString()); return; } if (pet != GetPlayer().GetFirstControlled()) { Log.outError(LogFilter.Network, "HandlePetAction: {0} does not belong to {1}", guid1.ToString(), GetPlayer().GetGUID().ToString()); return; } if (!pet.IsAlive()) { SpellInfo spell = (flag == ActiveStates.Enabled || flag == ActiveStates.Passive) ? Global.SpellMgr.GetSpellInfo(spellid) : null; if (spell == null) { return; } if (!spell.HasAttribute(SpellAttr0.CastableWhileDead)) { return; } } // @todo allow control charmed player? if (pet.IsTypeId(TypeId.Player) && !(flag == ActiveStates.Command && spellid == (uint)CommandStates.Attack)) { return; } if (GetPlayer().m_Controlled.Count == 1) { HandlePetActionHelper(pet, guid1, spellid, flag, guid2, packet.ActionPosition.X, packet.ActionPosition.Y, packet.ActionPosition.Z); } else { //If a pet is dismissed, m_Controlled will change List <Unit> controlled = new List <Unit>(); foreach (var unit in GetPlayer().m_Controlled) { if (unit.GetEntry() == pet.GetEntry() && unit.IsAlive()) { controlled.Add(unit); } } foreach (var unit in controlled) { HandlePetActionHelper(unit, guid1, spellid, flag, guid2, packet.ActionPosition.X, packet.ActionPosition.Y, packet.ActionPosition.Z); } } }
void HandleCastSpell(CastSpell cast) { // ignore for remote control state (for player case) Unit mover = GetPlayer().GetUnitBeingMoved(); if (mover != GetPlayer() && mover.IsTypeId(TypeId.Player)) { return; } SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(cast.Cast.SpellID, mover.GetMap().GetDifficultyID()); if (spellInfo == null) { Log.outError(LogFilter.Network, "WORLD: unknown spell id {0}", cast.Cast.SpellID); return; } if (spellInfo.IsPassive()) { return; } Unit caster = mover; if (caster.IsTypeId(TypeId.Unit) && !caster.ToCreature().HasSpell(spellInfo.Id)) { // If the vehicle creature does not have the spell but it allows the passenger to cast own spells // change caster to player and let him cast if (!GetPlayer().IsOnVehicle(caster) || spellInfo.CheckVehicle(GetPlayer()) != SpellCastResult.SpellCastOk) { return; } caster = GetPlayer(); } TriggerCastFlags triggerFlag = TriggerCastFlags.None; // client provided targets SpellCastTargets targets = new(caster, cast.Cast); // check known spell or raid marker spell (which not requires player to know it) if (caster.IsTypeId(TypeId.Player) && !caster.ToPlayer().HasActiveSpell(spellInfo.Id) && !spellInfo.HasEffect(SpellEffectName.ChangeRaidMarker) && !spellInfo.HasAttribute(SpellAttr8.RaidMarker)) { bool allow = false; // allow casting of unknown spells for special lock cases GameObject go = targets.GetGOTarget(); if (go != null) { if (go.GetSpellForLock(caster.ToPlayer()) == spellInfo) { allow = true; } } // allow casting of spells triggered by clientside periodic trigger auras if (caster.HasAuraTypeWithTriggerSpell(AuraType.PeriodicTriggerSpellFromClient, spellInfo.Id)) { allow = true; triggerFlag = TriggerCastFlags.FullMask; } if (!allow) { return; } } // Check possible spell cast overrides spellInfo = caster.GetCastSpellInfo(spellInfo); // can't use our own spells when we're in possession of another unit, if (GetPlayer().IsPossessing()) { return; } // Client is resending autoshot cast opcode when other spell is cast during shoot rotation // Skip it to prevent "interrupt" message // Also check targets! target may have changed and we need to interrupt current spell if (spellInfo.IsAutoRepeatRangedSpell()) { Spell autoRepeatSpell = caster.GetCurrentSpell(CurrentSpellTypes.AutoRepeat); if (autoRepeatSpell != null) { if (autoRepeatSpell.m_spellInfo == spellInfo && autoRepeatSpell.m_targets.GetUnitTargetGUID() == targets.GetUnitTargetGUID()) { return; } } } // auto-selection buff level base at target level (in spellInfo) if (targets.GetUnitTarget() != null) { SpellInfo actualSpellInfo = spellInfo.GetAuraRankForLevel(targets.GetUnitTarget().GetLevelForTarget(caster)); // if rank not found then function return NULL but in explicit cast case original spell can be casted and later failed with appropriate error message if (actualSpellInfo != null) { spellInfo = actualSpellInfo; } } if (cast.Cast.MoveUpdate.HasValue) { HandleMovementOpcode(ClientOpcodes.MoveStop, cast.Cast.MoveUpdate.Value); } Spell spell = new(caster, spellInfo, triggerFlag); SpellPrepare spellPrepare = new(); spellPrepare.ClientCastID = cast.Cast.CastID; spellPrepare.ServerCastID = spell.m_castId; SendPacket(spellPrepare); spell.m_fromClient = true; spell.m_misc.Data0 = cast.Cast.Misc[0]; spell.m_misc.Data1 = cast.Cast.Misc[1]; spell.Prepare(targets); }