public TrinitySpell(Unit caster, TrinitySpellInfo info, TriggerCastFlags triggerFlags, Guid originalCasterId, bool skipCheck = false)
    {
        SpellValue = new SpellValue(info);

        Caster    = caster;
        SpellInfo = info;

        CastId         = Guid.NewGuid();
        OriginalCastId = CastId;
        SkipCheck      = skipCheck;

        ExecutedCurrently          = false;
        ApplyMultiplierMask        = 0;
        DamageMultipliers          = new float[3];
        ReferencedFromCurrentSpell = false;

        SpellSchoolMask = SpellInfo.SchoolMask;

        if (originalCasterId != Guid.Empty)
        {
            OriginalCasterGuid = originalCasterId;
        }
        else
        {
            OriginalCasterGuid = caster.Character.Id;
        }

        if (OriginalCasterGuid == caster.Character.Id)
        {
            OriginalCaster = caster;
        }
        else
        {
            OriginalCaster = ArenaManager.ArenaUnits.Find(unit => unit.Character.Id == OriginalCasterGuid);
        }

        SpellState       = SpellState.NONE;
        TriggerCastFlags = triggerFlags;

        UnitTarget       = null;
        DestTarget       = null;
        Damage           = 0;
        Variance         = 0.0f;
        EffectHandleMode = SpellEffectHandleMode.LAUNCH;
        EffectInfo       = null;

        DiminishLevel = DiminishingLevels.LEVEL_1;
        DiminishGroup = DiminishingGroup.NONE;

        EffectDamage  = 0;
        EffectHealing = 0;
        SpellAura     = null;

        SpellVisual = SpellInfo.VisualId;
        CanReflect  = SpellInfo.DamageClass == SpellDamageClass.MAGIC && !SpellInfo.HasAttribute(SpellAttributes.CANT_BE_REFLECTED) &&
                      !SpellInfo.IsPassive() && !SpellInfo.IsPositive();

        UniqueTargets = new List <TargetInfo>();
        SpellEffects  = new List <TrinitySpellEffectInfo>(SpellInfo.SpellEffectInfos);
    }
Beispiel #2
0
        static bool HandleCastCommand(CommandHandler handler, SpellInfo spell, string triggeredStr)
        {
            Unit target = handler.GetSelectedUnit();

            if (!target)
            {
                handler.SendSysMessage(CypherStrings.SelectCharOrCreature);
                return(false);
            }

            if (!CheckSpellExistsAndIsValid(handler, spell))
            {
                return(false);
            }

            TriggerCastFlags triggerFlags = TriggerCastFlags.None;

            if (!triggeredStr.IsEmpty())
            {
                if ("triggered".Contains(triggeredStr)) // check if "triggered" starts with *triggeredStr (e.g. "trig", "trigger", etc.)
                {
                    triggerFlags = TriggerCastFlags.FullDebugMask;
                }
                else
                {
                    return(false);
                }
            }

            handler.GetSession().GetPlayer().CastSpell(target, spell.Id, new CastSpellExtraArgs(triggerFlags));
            return(true);
        }
    public void CastSpell(Unit target, TrinitySpellInfo spellInfo, TriggerCastFlags triggerFlags, AuraEffect triggeredByAura, Guid originalCaster)
    {
        SpellCastTargets targets = new SpellCastTargets();

        targets.UnitTarget = target;
        CastSpell(targets, spellInfo, triggerFlags, triggeredByAura, originalCaster);
    }
Beispiel #4
0
        void HandleScriptEffect(uint effIndex)
        {
            Unit target = GetHitUnit();

            if (target)
            {
                // Cannot be processed while pet is dead
                TriggerCastFlags castMask = (TriggerCastFlags.FullMask & ~TriggerCastFlags.IgnoreCasterAurastate);
                target.CastSpell(target, SpellIds.MastersCallTriggered, castMask);
            }
        }
    public void CastSpell(Unit target, int spellId, TriggerCastFlags triggerFlags, AuraEffect triggeredByAura, Guid originalCaster)
    {
        TrinitySpellInfo spellInfo = WarcraftDatabase.SpellInfos.ContainsKey(spellId) ? WarcraftDatabase.SpellInfos[spellId] : null;

        if (spellInfo == null)
        {
            Debug.LogError("Unknown spell for unit: " + gameObject.name);
            return;
        }

        CastSpell(target, spellInfo, triggerFlags, triggeredByAura, originalCaster);
    }
    public void CastSpell(SpellCastTargets targets, TrinitySpellInfo spellInfo, TriggerCastFlags triggerFlags, AuraEffect triggeredByAura, Guid originalCaster)
    {
        if (spellInfo == null)
        {
            Debug.LogError("Unknown spell for unit: " + gameObject.name);
            return;
        }

        TrinitySpell spell = new TrinitySpell(this, spellInfo, triggerFlags, originalCaster);

        spell.Prepare(targets, triggeredByAura);
    }
    public SpellCastResult CheckCast(bool strict)
    {
        // check death state
        if (!Caster.IsAlive() && !SpellInfo.IsPassive())
        {
            return(SpellCastResult.CASTER_DEAD);
        }

        // check cooldowns to prevent cheating
        if (!SpellInfo.IsPassive())
        {
            if (!Caster.Character.SpellHistory.IsReady(SpellInfo, IsIgnoringCooldowns()))
            {
                if (TriggeredByAuraSpell != null)
                {
                    return(SpellCastResult.DONT_REPORT);
                }
                else
                {
                    return(SpellCastResult.NOT_READY);
                }
            }
        }

        // Check global cooldown
        if (strict && !(TriggerCastFlags.HasFlag(TriggerCastFlags.IGNORE_GCD) && HasGlobalCooldown()))
        {
            return(SpellCastResult.NOT_READY);
        }

        // Check for line of sight for spells with dest

        /*if (m_targets.HasDst())
         * {
         *  float x, y, z;
         *  m_targets.GetDstPos()->GetPosition(x, y, z);
         *
         *  if (!m_spellInfo->HasAttribute(SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) && !DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, NULL, SPELL_DISABLE_LOS) && !m_caster->IsWithinLOS(x, y, z))
         *      return SPELL_FAILED_LINE_OF_SIGHT;
         * }*/

        SpellCastResult castResult = SpellCastResult.SPELL_CAST_OK;

        // Triggered spells also have range check
        /// @todo determine if there is some flag to enable/disable the check
        castResult = CheckRange(strict);
        if (castResult != SpellCastResult.SPELL_CAST_OK)
        {
            return(castResult);
        }

        return(SpellCastResult.SUCCESS);
    }
Beispiel #8
0
        void HandleDummy(uint effIndex)
        {
            Unit ally = GetHitUnit();

            if (ally)
            {
                Player caster = GetCaster().ToPlayer();
                if (caster)
                {
                    Pet target = caster.GetPet();
                    if (target)
                    {
                        TriggerCastFlags castMask = (TriggerCastFlags.FullMask & ~TriggerCastFlags.IgnoreCasterAurastate);
                        target.CastSpell(ally, (uint)GetEffectValue(), castMask);
                    }
                }
            }
        }
 public static bool HasFlag(this TriggerCastFlags baseFlags, TriggerCastFlags flag)
 {
     return((baseFlags & flag) == flag);
 }
Beispiel #10
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);
        }
Beispiel #11
0
        void HandlePetCastSpell(PetCastSpell petCastSpell)
        {
            Unit caster = Global.ObjAccessor.GetUnit(GetPlayer(), petCastSpell.PetGUID);

            if (!caster)
            {
                Log.outError(LogFilter.Network, "WorldSession.HandlePetCastSpell: Caster {0} not found.", petCastSpell.PetGUID.ToString());
                return;
            }

            SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(petCastSpell.Cast.SpellID, caster.GetMap().GetDifficultyID());

            if (spellInfo == null)
            {
                Log.outError(LogFilter.Network, "WorldSession.HandlePetCastSpell: unknown spell id {0} tried to cast by {1}", petCastSpell.Cast.SpellID, petCastSpell.PetGUID.ToString());
                return;
            }

            // This opcode is also sent from charmed and possessed units (players and creatures)
            if (caster != GetPlayer().GetGuardianPet() && caster != GetPlayer().GetCharmed())
            {
                Log.outError(LogFilter.Network, "WorldSession.HandlePetCastSpell: {0} isn't pet of player {1} ({2}).", petCastSpell.PetGUID.ToString(), GetPlayer().GetName(), GetPlayer().GetGUID().ToString());
                return;
            }

            SpellCastTargets targets = new(caster, petCastSpell.Cast);

            TriggerCastFlags triggerCastFlags = TriggerCastFlags.None;

            if (spellInfo.IsPassive())
            {
                return;
            }

            // cast only learned spells
            if (!caster.HasSpell(spellInfo.Id))
            {
                bool allow = false;

                // allow casting of spells triggered by clientside periodic trigger auras
                if (caster.HasAuraTypeWithTriggerSpell(AuraType.PeriodicTriggerSpellFromClient, spellInfo.Id))
                {
                    allow            = true;
                    triggerCastFlags = TriggerCastFlags.FullMask;
                }

                if (!allow)
                {
                    return;
                }
            }

            Spell spell = new(caster, spellInfo, triggerCastFlags);

            spell.m_fromClient = true;
            spell.m_misc.Data0 = petCastSpell.Cast.Misc[0];
            spell.m_misc.Data1 = petCastSpell.Cast.Misc[1];
            spell.m_targets    = targets;

            SpellCastResult result = spell.CheckPetCast(null);

            if (result == SpellCastResult.SpellCastOk)
            {
                Creature creature = caster.ToCreature();
                if (creature)
                {
                    Pet pet = creature.ToPet();
                    if (pet)
                    {
                        // 10% chance to play special pet attack talk, else growl
                        // actually this only seems to happen on special spells, fire shield for imp, torment for voidwalker, but it's stupid to check every spell
                        if (pet.GetPetType() == PetType.Summon && (RandomHelper.IRand(0, 100) < 10))
                        {
                            pet.SendPetTalk(PetTalk.SpecialSpell);
                        }
                        else
                        {
                            pet.SendPetAIReaction(petCastSpell.PetGUID);
                        }
                    }
                }

                SpellPrepare spellPrepare = new();
                spellPrepare.ClientCastID = petCastSpell.Cast.CastID;
                spellPrepare.ServerCastID = spell.m_castId;
                SendPacket(spellPrepare);

                spell.Prepare(targets);
            }
            else
            {
                spell.SendPetCastResult(result);

                if (!caster.GetSpellHistory().HasCooldown(spellInfo.Id))
                {
                    caster.GetSpellHistory().ResetCooldown(spellInfo.Id, true);
                }

                spell.Finish(false);
                spell.Dispose();
            }
        }
Beispiel #12
0
        public Spell(Unit caster, SpellInfo info, TriggerCastFlags triggerFlags, ulong originalCasterGUID = 0, bool skipCheck = false)
        {
            m_spellInfo  = SpellMgr.GetSpellForDifficultyFromSpell(info, caster);
            m_caster     = Convert.ToBoolean(info.AttributesEx6 & SpellAttr6.CastByCharmer) ? null : caster;//&& caster->GetCharmerOrOwner()) ? caster->GetCharmerOrOwner() : caster
            m_spellValue = new SpellValue(m_spellInfo);

            m_customError   = SpellCustomErrors.None;
            m_skipCheck     = skipCheck;
            m_selfContainer = null;
            m_referencedFromCurrentSpell = false;
            m_executedCurrently          = false;
            m_needComboPoints            = m_spellInfo.NeedsComboPoints();
            m_comboPointGain             = 0;
            m_delayStart         = 0;
            m_delayAtDamageCount = 0;

            m_applyMultiplierMask = 0;
            m_auraScaleMask       = 0;

            // Get data for type of attack
            switch (m_spellInfo.DmgClass)
            {
            case SpellDmgClass.Melee:
                if (Convert.ToBoolean(m_spellInfo.AttributesEx3 & SpellAttr3.ReqOffhand))
                {
                    m_attackType = WeaponAttackType.OffAttack;
                }
                else
                {
                    m_attackType = WeaponAttackType.BaseAttack;
                }
                break;

            case SpellDmgClass.Ranged:
                m_attackType = m_spellInfo.IsRangedWeaponSpell() ? WeaponAttackType.RangedAttack : WeaponAttackType.BaseAttack;
                break;

            default:
                // Wands
                if (Convert.ToBoolean(m_spellInfo.AttributesEx2 & SpellAttr2.AutorepeatFlag))
                {
                    m_attackType = WeaponAttackType.RangedAttack;
                }
                else
                {
                    m_attackType = WeaponAttackType.BaseAttack;
                }
                break;
            }

            m_spellSchoolMask = info.GetSchoolMask();           // Can be override for some spell (wand shoot for example)

            if (m_attackType == WeaponAttackType.RangedAttack)
            {
                if ((m_caster.getClassMask() & SharedConst.ClassMaskWandUsers) != 0 && m_caster.GetTypeId() == ObjectType.Player)
                {
                    Item pItem = m_caster.ToPlayer().GetWeaponForAttack(WeaponAttackType.RangedAttack);
                    //if (pItem != null)
                    //m_spellSchoolMask = (SpellSchoolMask)(1 << (int)pItem.ItemInfo.ItemSparse.DamageType);
                }
            }

            if (originalCasterGUID != 0)
            {
                m_originalCasterGUID = originalCasterGUID;
            }
            else
            {
                m_originalCasterGUID = m_caster.GetGUID();
            }

            if (m_originalCasterGUID == m_caster.GetGUID())
            {
                m_originalCaster = m_caster;
            }
            else
            {
                m_originalCaster = ObjMgr.GetObject <Unit>(m_caster, m_originalCasterGUID);
                if (m_originalCaster != null && !m_originalCaster.IsInWorld)
                {
                    m_originalCaster = null;
                }
            }

            m_spellState        = SpellState.None;
            _triggeredCastFlags = triggerFlags;
            if (Convert.ToBoolean(info.AttributesEx4 & SpellAttr4.Triggered))
            {
                _triggeredCastFlags = TriggerCastFlags.FullMask;
            }

            m_CastItem     = null;
            m_castItemGUID = 0;

            unitTarget     = null;
            itemTarget     = null;
            gameObjTarget  = null;
            focusObject    = null;
            m_cast_count   = 0;
            m_glyphIndex   = 0;
            m_preCastSpell = 0;
            //m_triggeredByAuraSpell  = null;
            //m_spellAura = null;

            //Auto Shot & Shoot (wand)
            m_autoRepeat = m_spellInfo.IsAutoRepeatRangedSpell();

            m_runesState = 0;
            m_powerCost  = 0;                                       // setup to correct value in Spell::prepare, must not be used before.
            m_casttime   = 0;                                       // setup to correct value in Spell::prepare, must not be used before.
            m_timer      = 0;                                       // will set to castime in prepare

            //m_channelTargetEffectMask = 0;

            // Determine if spell can be reflected back to the caster
            // Patch 1.2 notes: Spell Reflection no longer reflects abilities
            m_canReflect = m_spellInfo.DmgClass == SpellDmgClass.Magic && !Convert.ToBoolean(m_spellInfo.Attributes & SpellAttr0.Ability) &&
                           !Convert.ToBoolean(m_spellInfo.AttributesEx & SpellAttr1.CantBeReflected) && !Convert.ToBoolean(m_spellInfo.Attributes & SpellAttr0.UnaffectedByInvulnerability) &&
                           !m_spellInfo.IsPassive() && !m_spellInfo.IsPositive();

            CleanupTargetList();

            for (var i = 0; i < SharedConst.MaxSpellEffects; ++i)
            {
                m_destTargets[i] = new SpellDestination(m_caster);
            }
        }
 public bool IsIgnoringCooldowns()
 {
     return(TriggerCastFlags.HasFlag(TriggerCastFlags.IGNORE_SPELL_AND_CATEGORY_CD));
 }