示例#1
0
        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);
        }
示例#2
0
        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);*/
            }
        }
示例#3
0
        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);
        }