void HandleCancelChanneling(CancelChannelling cancelChanneling) { // ignore for remote control state (for player case) Unit mover = _player.GetUnitBeingMoved(); if (mover != _player && mover.IsTypeId(TypeId.Player)) { return; } var spellInfo = Global.SpellMgr.GetSpellInfo((uint)cancelChanneling.ChannelSpell, mover.GetMap().GetDifficultyID()); if (spellInfo == null) { return; } // not allow remove spells with attr SPELL_ATTR0_CANT_CANCEL if (spellInfo.HasAttribute(SpellAttr0.CantCancel)) { return; } var spell = mover.GetCurrentSpell(CurrentSpellTypes.Channeled); if (spell == null || spell.GetSpellInfo().Id != spellInfo.Id) { return; } mover.InterruptSpell(CurrentSpellTypes.Channeled); }
void HandleUpdateMissileTrajectory(UpdateMissileTrajectory packet) { Unit caster = Global.ObjAccessor.GetUnit(GetPlayer(), packet.Guid); Spell spell = caster ? caster.GetCurrentSpell(CurrentSpellTypes.Generic) : null; if (!spell || spell.m_spellInfo.Id != packet.SpellID || !spell.m_targets.HasDst() || !spell.m_targets.HasSrc()) { return; } Position pos = spell.m_targets.GetSrcPos(); pos.Relocate(packet.FirePos); spell.m_targets.ModSrc(pos); pos = spell.m_targets.GetDstPos(); pos.Relocate(packet.ImpactPos); spell.m_targets.ModDst(pos); spell.m_targets.SetPitch(packet.Pitch); spell.m_targets.SetSpeed(packet.Speed); if (packet.Status.HasValue) { GetPlayer().ValidateMovementInfo(packet.Status.Value); /*public uint opcode; * recvPacket >> opcode; * recvPacket.SetOpcode(CMSG_MOVE_STOP); // always set to CMSG_MOVE_STOP in client SetOpcode * //HandleMovementOpcodes(recvPacket);*/ } }
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); }