Beispiel #1
0
        internal Spell(Unit caster, SpellInfo info, SpellCastingOptions options)
        {
            Logging.LogSpell($"Created new spell, current count: {++SpellAliveCount}");

            spellManager        = caster.World.SpellManager;
            spellCastFlags      = options.SpellFlags;
            casterMovementFlags = options.MovementFlags ?? caster.MovementInfo.Flags;
            SchoolMask          = info.SchoolMask;

            CastTime  = CastTimeLeft = EffectDamage = EffectHealing = 0;
            Caster    = OriginalCaster = caster;
            SpellInfo = info;

            IsTriggered = spellCastFlags.HasTargetFlag(SpellCastFlags.TriggeredByAura);

            if (IsTriggered)
            {
                spellCastFlags |= SpellCastFlags.IgnoreTargetCheck | SpellCastFlags.IgnoreRangeCheck;
            }

            if (info.HasAttribute(SpellExtraAttributes.CanCastWhileCasting))
            {
                spellCastFlags |= SpellCastFlags.IgnoreCastInProgress | SpellCastFlags.CastDirectly;
            }

            if (info.HasAttribute(SpellExtraAttributes.IgnoreGcd))
            {
                spellCastFlags |= SpellCastFlags.IgnoreGcd;
            }

            if (info.HasAttribute(SpellExtraAttributes.IgnoreCasterAuras))
            {
                spellCastFlags |= SpellCastFlags.IgnoreCasterAuras;
            }

            CanReflect = SpellInfo.DamageClass == SpellDamageClass.Magic && !SpellInfo.HasAttribute(SpellAttributes.CantBeReflected) &&
                         !SpellInfo.HasAttribute(SpellAttributes.UnaffectedByInvulnerability) && !SpellInfo.IsPassive && !SpellInfo.IsPositive;

            ExplicitTargets = options.Targets ?? new SpellExplicitTargets();
            ImplicitTargets = new SpellImplicitTargets(this);

            spellManager.Add(this);
        }
Beispiel #2
0
 public static bool HasTargetFlag(this SpellCastFlags baseFlags, SpellCastFlags flag)
 {
     return((baseFlags & flag) == flag);
 }
Beispiel #3
0
        void SendSpellGo()
        {
            // not send invisible spell casting
            if (!IsNeedSendToClient())
            {
                return;
            }

            SpellCastFlags castFlags = SpellCastFlags.Unk9;

            // triggered spells with spell visual != 0
            if ((IsTriggered() && !m_spellInfo.IsAutoRepeatRangedSpell()))// || m_triggeredByAuraSpell)
            {
                castFlags |= SpellCastFlags.Pending;
            }

            if ((m_caster.GetTypeId() == ObjectType.Player ||
                 (m_caster.GetTypeId() == ObjectType.Unit && m_caster.ToCreature().isPet())) &&
                m_spellInfo.PowerType != Powers.Health)
            {
                castFlags |= SpellCastFlags.PowerLeftSelf; // should only be sent to self, but the current messaging doesn't make that possible
            }
            if ((m_caster.GetTypeId() == ObjectType.Player) &&
                (m_caster.getClass() == (byte)Class.Deathknight) &&
                m_spellInfo.RuneCostID != 0 &&
                m_spellInfo.PowerType == Powers.Runes)
            {
                castFlags |= SpellCastFlags.Unk19;                   // same as in SMSG_SPELL_START
                castFlags |= SpellCastFlags.RuneList;                // rune cooldowns list
            }

            if (m_spellInfo.HasEffect(SpellEffects.ActivateRune))
            {
                castFlags |= SpellCastFlags.RuneList;                // rune cooldowns list
                castFlags |= SpellCastFlags.Unk19;                   // same as in SMSG_SPELL_START
            }

            if (m_targets.HasTraj())
            {
                castFlags |= SpellCastFlags.AdjustMissile;
            }

            PacketWriter data = new PacketWriter(Opcodes.SMSG_SpellGo);

            if (m_CastItem != null)
            {
                data.WriteUInt64(m_CastItem.GetPackGUID());
            }
            else
            {
                data.WriteUInt64(m_caster.GetPackGUID());
            }

            data.WriteUInt64(m_caster.GetPackGUID());
            data.WriteUInt8(m_cast_count);     // pending spell cast?
            data.WriteUInt32(m_spellInfo.Id);  // spellId
            data.WriteUInt32((uint)castFlags); // cast flags
            data.WriteUInt32(0);               //m_timer);
            data.WriteUnixTime();              // timestamp

            WriteSpellGoTargets(ref data);

            m_targets.Write(ref data);

            //if (castFlags & CAST_FLAG_POWER_LEFT_SELF)
            //data.WriteUInt32(m_caster.GetPower((Powers)m_spellInfo->PowerType));

            if (Convert.ToBoolean(castFlags & SpellCastFlags.RuneList))                   // rune cooldowns list
            {
                //TODO: There is a crash caused by a spell with CAST_FLAG_RUNE_LIST casted by a creature
                //The creature is the mover of a player, so HandleCastSpellOpcode uses it as the caster
                Player player = m_caster.ToPlayer();
                if (player != null)
                {
                    data.WriteUInt8(m_runesState);                     // runes state before
                    //data.WriteUInt8(player.GetRunesState());          // runes state after
                    //for (uint8 i = 0; i < MAX_RUNES; ++i)
                    {
                        // float casts ensure the division is performed on floats as we need float result
                        //float baseCd = float(player->GetRuneBaseCooldown(i));
                        //data << uint8((baseCd - float(player->GetRuneCooldown(i))) / baseCd * 255); // rune cooldown passed
                    }
                }
            }

            if (Convert.ToBoolean(castFlags & SpellCastFlags.AdjustMissile))
            {
                //data << m_targets.GetElevation();
                data.WriteUInt32((uint)m_delayMoment);
            }

            if (Convert.ToBoolean(castFlags & SpellCastFlags.Projectile))
            {
                data.WriteUInt32(0); // Ammo display ID
                data.WriteUInt32(0); // Inventory Type
            }

            if (Convert.ToBoolean(castFlags & SpellCastFlags.VisualChain))
            {
                data.WriteUInt32(0);
                data.WriteUInt32(0);
            }

            //if (m_targets.GetTargetMask() & TARGET_FLAG_DEST_LOCATION)
            {
                //data << uint8(0);
            }

            //if (m_targets.GetTargetMask() & TARGET_FLAG_EXTRA_TARGETS)
            {
                //data.WriteUInt32(0); // Extra targets count

                /*
                 * for (uint8 i = 0; i < count; ++i)
                 * {
                 * data << float(0);   // Target Position X
                 * data << float(0);   // Target Position Y
                 * data << float(0);   // Target Position Z
                 * data << uint64(0);  // Target Guid
                 * }
                 * */
            }

            m_caster.SendMessageToSet(data, true);
        }
Beispiel #4
0
        void SendSpellStart()
        {
            if (!IsNeedSendToClient())
            {
                return;
            }

            SpellCastFlags castFlags = SpellCastFlags.HasTrajectory;

            if ((IsTriggered() && !m_spellInfo.IsAutoRepeatRangedSpell())) //|| m_triggeredByAuraSpell)
            {
                castFlags |= SpellCastFlags.Pending;
            }

            if ((m_caster is Player) || (m_caster is Unit) && m_caster.ToCreature().isPet() &&
                m_spellInfo.PowerType != Powers.Health)
            {
                castFlags |= SpellCastFlags.PowerLeftSelf;
            }

            if (m_spellInfo.RuneCostID != 0 && m_spellInfo.PowerType == Powers.Runes)
            {
                castFlags |= SpellCastFlags.Unk19;
            }

            PacketWriter data = new PacketWriter(Opcodes.SMSG_SpellStart);

            if (m_CastItem != null)
            {
                data.WriteUInt64(m_CastItem.GetPackGUID());
            }
            else
            {
                data.WriteUInt64(m_caster.GetPackGUID());
            }

            data.WriteUInt64(m_caster.GetPackGUID());
            data.WriteUInt8((byte)m_cast_count); // pending spell cast?
            data.WriteUInt32(m_spellInfo.Id);    // spellId
            data.WriteUInt32((uint)castFlags);   // cast flags
            data.WriteUInt32(0);                 //m_timer);                                // delay?
            data.WriteInt32(m_casttime);

            m_targets.Write(ref data);

            //if (castFlags & (SpellCastFlags.PowerLeftSelf))
            //data.WriteUInt32(m_caster.GetPower((Powers)m_spellInfo.PowerType));

            if (Convert.ToBoolean(castFlags & SpellCastFlags.RuneList))                   // rune cooldowns list
            {
                //TODO: There is a crash caused by a spell with CAST_FLAG_RUNE_LIST casted by a creature
                //The creature is the mover of a player, so HandleCastSpellOpcode uses it as the caster
                Player player = m_caster.ToPlayer();
                if (player != null)
                {
                    data.WriteUInt8(m_runesState);                     // runes state before
                    //data.WriteUInt8(player.GetRunesState());          // runes state after

                    //for (var i = 0; i < MAX_RUNES; ++i)
                    {
                        // float casts ensure the division is performed on floats as we need float result
                        //float baseCd = float(player->GetRuneBaseCooldown(i));
                        //data.WriteUInt8((baseCd - float(player->GetRuneCooldown(i))) / baseCd * 255); // rune cooldown passed
                    }
                }
                else
                {
                    data.WriteUInt8(0);
                    data.WriteUInt8(0);
                }
            }

            if (Convert.ToBoolean(castFlags & SpellCastFlags.Projectile))
            {
                data.WriteUInt32(0); // Ammo display ID
                data.WriteUInt32(0); // Inventory Type
            }

            if (Convert.ToBoolean(castFlags & SpellCastFlags.Immunity))
            {
                data.WriteUInt32(0);
                data.WriteUInt32(0);
            }

            if (Convert.ToBoolean(castFlags & SpellCastFlags.HealPrediction))
            {
                data.WriteUInt32(0);
                data.WriteUInt8(0); // unkByte
            }
            m_caster.SendMessageToSet(data, true);
        }
 public SpellCastingOptions(SpellExplicitTargets targets = null, SpellCastFlags castFlags = 0, MovementFlags?movementFlags = null)
 {
     Targets       = targets;
     SpellFlags    = castFlags;
     MovementFlags = movementFlags;
 }
Beispiel #6
0
 internal void TriggerSpell(SpellInfo spellInfo, Unit target, SpellCastFlags extraCastFlags = 0)
 {
     CastSpell(spellInfo, new SpellCastingOptions(new SpellExplicitTargets {
         Target = target
     }, SpellCastFlags.TriggeredByAura | extraCastFlags));
 }