public override void InvokeDamageEvent(byte eventId, AbilityDamageInfo damageInfo, Unit eventInstigator)
        {
            if (BuffState != (byte)EBuffState.Running)
            {
                return;
            }

            if (Interlocked.CompareExchange(ref BuffTimerLock, 1, 0) != 0)
            {
                return;
            }

            if (_nextResTime > TCPManager.GetTimeStampMS())
            {
                Interlocked.Exchange(ref BuffTimerLock, 0);
                return;
            }

            _nextResTime = TCPManager.GetTimeStampMS() + 1000;
            Interlocked.Exchange(ref BuffTimerLock, 0);

            if (Caster.Region == Target.Region && Caster.Get2DDistanceToObject(Target) <= 300)
            {
                _masterInterface?.Notify_DarkProtectorHit();
            }
        }
Exemplo n.º 2
0
        public override void ModifyDamageIn(AbilityDamageInfo incDamage)
        {
            switch (incDamage.SubDamageType)
            {
            case SubDamageTypes.Cleave:
                incDamage.DamageReduction *= 0.1f;
                break;

            case SubDamageTypes.Artillery:
                incDamage.Damage *= 0.35f;
                break;

            case SubDamageTypes.None:
                switch (incDamage.DamageType)
                {
                case DamageTypes.Physical:
                    incDamage.DamageEvent = (byte)CombatEvent.COMBATEVENT_BLOCK;
                    break;

                case DamageTypes.RawDamage:
                    incDamage.Damage *= 0.1f;
                    break;

                default:
                    incDamage.DamageReduction *= 0.1f;
                    break;
                }
                break;
            }
        }
        public AbilityDamageInfo Clone()
        {
            AbilityDamageInfo cDmgInfo = (AbilityDamageInfo)MemberwiseClone();

            cDmgInfo.ExclusiveBonusApplied     = new bool[5];
            cDmgInfo.ExclusiveReductionApplied = new bool[5];

            return(cDmgInfo);
        }
        public AbilityDamageInfo Clone(Unit damageInstigator)
        {
            AbilityDamageInfo cDmgInfo = (AbilityDamageInfo)MemberwiseClone();

            cDmgInfo.ExclusiveBonusApplied     = new bool[5];
            cDmgInfo.ExclusiveReductionApplied = new bool[5];

            damageInstigator.ModifyDamageOut(cDmgInfo);

            return(cDmgInfo);
        }
        public override void InvokeDamageEvent(byte eventId, AbilityDamageInfo damageInfo, Unit eventInstigator)
        {
            if (BuffState != (byte)EBuffState.Running)
            {
                return;
            }

            if (Caster.Region == Target.Region && Caster.Get2DDistanceToObject(Target) <= 300)
            {
                _masterInterface?.Notify_OathFriendHit(eventInstigator);
            }
        }
        private void UpdateCombustion()
        {
            byte curResLevel  = GetLocalResourceLevel(_careerResource);
            byte lastResLevel = GetLocalResourceLevel(_lastResource);

            if (AutoBacklash || (lastResLevel != 0 && _careerResource >= _lastResource && StaticRandom.Instance.Next(0, 100) <= _critBonuses[lastResLevel - 1]))
            {
                PacketOut damageOut = new PacketOut((byte)Opcodes.F_CAST_PLAYER_EFFECT, 18);

                // This is abrasive, but a tactic needs to process the Combustion self-damage event
                // Should probably just create this and reuse it
                AbilityDamageInfo backDamageInfo = new AbilityDamageInfo
                {
                    NoCrits = true,
                    Entry   = _backlashID,
                    Damage  = (int)((_backlashBase + (_backlashGain * (myPlayer.Level - 1) / 39)) * 0.1f * _critDmgBonuses[lastResLevel > 0 ? lastResLevel - 1 : 0])
                };


                damageOut.WriteUInt16(myPlayer.Oid);
                damageOut.WriteUInt16(myPlayer.Oid);
                damageOut.WriteUInt16(_backlashID);

                damageOut.WriteByte(2);
                damageOut.WriteByte(0); // DAMAGE EVENT
                damageOut.WriteByte(0x7);

                damageOut.WriteZigZag((int)-backDamageInfo.Damage);
                damageOut.WriteByte(0);
                myPlayer.DispatchPacketUnreliable(damageOut, true, null);

                myPlayer.ReceiveDamage(myPlayer, backDamageInfo);

                myPlayer.BuffInterface.NotifyCombatEvent((byte)BuffCombatEvents.Manual, backDamageInfo, myPlayer);

                AutoBacklash = false;
            }

            if (curResLevel != lastResLevel)
            {
                if (lastResLevel != 0)
                {
                    myPlayer.StsInterface.RemoveBonusStat(Stats.CriticalHitRate, _critBonuses[lastResLevel - 1], BuffClass.Career);
                    myPlayer.StsInterface.RemoveBonusStat(Stats.CriticalDamage, _critDmgBonuses[lastResLevel - 1], BuffClass.Career);
                }

                if (curResLevel != 0)
                {
                    myPlayer.StsInterface.AddBonusStat(Stats.CriticalHitRate, _critBonuses[curResLevel - 1], BuffClass.Career);
                    myPlayer.StsInterface.AddBonusStat(Stats.CriticalDamage, _critDmgBonuses[curResLevel - 1], BuffClass.Career);
                }
            }
        }
Exemplo n.º 7
0
        public void CheckGuard(AbilityDamageInfo damageInfo, Unit attacker)
        {
            if (_guardBuffs == null)
            {
                return;
            }

            foreach (GuardBuff g in _guardBuffs)
            {
                if (g.SplitDamage(attacker, damageInfo))
                {
                    return;
                }
            }
        }
Exemplo n.º 8
0
 public override void InvokeDamageEvent(byte eventId, AbilityDamageInfo damageInfo, Unit eventInstigator)
 {
     if (BuffState != (byte)EBuffState.Running)
     {
         return;
     }
     if (!string.IsNullOrEmpty(EventCommands[0].Item2.EventCheck) && !BuffEffectInvoker.PerformCheck(this, damageInfo, EventCommands[0].Item2, eventInstigator))
     {
         return;
     }
     if (!CanHitTarget(eventInstigator))
     {
         return;
     }
     BuffEffectInvoker.InvokeDamageEventCommand(this, EventCommands[0].Item2, damageInfo, Target, eventInstigator);
 }
        public bool SplitDamage(Unit attacker, AbilityDamageInfo damageInfo)
        {
            if (damageInfo.ExclusiveReductionApplied[0])
            {
                return(true);
            }
            if (Caster.IsDead || !Caster.ObjectWithinRadiusFeet(Target, 30))
            {
                return(false);
            }

            damageInfo.Damage     *= _damageSplitFactor;
            damageInfo.Mitigation *= _damageSplitFactor;

            CombatManager.InflictGuardDamage(attacker, (Player)Caster, Entry, damageInfo);

            return(true);
        }
Exemplo n.º 10
0
        public void NotifyCombatEvent(byte eventID, AbilityDamageInfo damageInfo, Unit eventInstigator)
        {
            if (_buffCombatSubs[eventID - 1].Count == 0)
            {
                return;
            }

            List <NewBuff> localSubs;

            lock (_buffCombatSubs[eventID - 1])
            {
                localSubs = new List <NewBuff>(_buffCombatSubs[eventID - 1]);
            }

            foreach (var buff in localSubs)
            {
                buff.InvokeDamageEvent(eventID, damageInfo, eventInstigator);
            }
        }
        public override void Update(long tick)
        {
            if (tick <= _rezTime)
            {
                return;
            }

            _slayerChoppa.RezUnit(_slayerChoppa.Realm == Realms.REALMS_REALM_ORDER ? (ushort)1489 : (ushort)1795, 25, true);

            AbilityDamageInfo damageThisPass = AbilityMgr.GetExtraDamageFor(_slayerChoppa.Realm == Realms.REALMS_REALM_ORDER ? (ushort)1489 : (ushort)1795, 0, 0);

            List <Object> objects;

            lock (_slayerChoppa.PlayersInRange)
                objects = new List <Object>(_slayerChoppa.ObjectsInRange);

            int count = 0;

            foreach (Object obj in objects)
            {
                Unit unit = obj as Unit;
                if (unit == null || unit == _slayerChoppa)
                {
                    continue;
                }

                if (unit.ObjectWithinRadiusFeet(_slayerChoppa, 40) && CombatInterface.CanAttack(_slayerChoppa, unit) && _slayerChoppa.LOSHit(unit))
                {
                    CombatManager.InflictDamage(damageThisPass.Clone(), _slayerChoppa.AbtInterface.GetMasteryLevelFor(3), _slayerChoppa, unit);
                }

                ++count;

                if (count == 9)
                {
                    break;
                }
            }

            Dispose();
        }
        public override bool ShouldDefend(Unit attacker, AbilityDamageInfo incDamage)
        {
            if (attacker is Pet)
            {
                return(true);
            }

            CreatureSubTypes subType = (CreatureSubTypes)Spawn.Proto.CreatureSubType;

            switch (incDamage.SubDamageType)
            {
            case SubDamageTypes.Oil:
                return(true);

            case SubDamageTypes.None:
                if (subType == CreatureSubTypes.SIEGE_RAM)
                {
                    return(incDamage.StatUsed != 1);
                }
                return(incDamage.DamageType == DamageTypes.Physical && incDamage.StatUsed != 1);
            }

            return(false);
        }
        /// <summary>
        /// Reduces the damage a siege weapon takes from regular types of attack.
        /// </summary>
        /// <param name="incDamage"></param>
        public override void ModifyDamageIn(AbilityDamageInfo incDamage)
        {
            CreatureSubTypes subType = (CreatureSubTypes)Spawn.Proto.CreatureSubType;

            if (subType == CreatureSubTypes.SIEGE_RAM)
            {
                switch (incDamage.SubDamageType)
                {
                case SubDamageTypes.Cleave:
                    incDamage.DamageReduction = 0.15f;
                    break;

                case SubDamageTypes.Artillery:
                    incDamage.Mitigation = incDamage.Damage * 0.975f;
                    incDamage.Damage    *= 0.025f;
                    break;

                case SubDamageTypes.Oil:
                    incDamage.Damage          = 0;
                    incDamage.PrecalcDamage   = 0;
                    incDamage.DamageReduction = 0f;
                    incDamage.DamageEvent     = (byte)CombatEvent.COMBATEVENT_BLOCK;
                    break;

                case SubDamageTypes.Cannon:
                    if (SiegeInterface.IsDeployed)
                    {
                        incDamage.Mitigation = incDamage.Damage * 0.95f;
                        incDamage.Damage    *= 0.05f;
                    }
                    else
                    {
                        incDamage.Mitigation = incDamage.Damage * 0.75f;
                        incDamage.Damage    *= 0.25f;
                    }
                    break;

                case SubDamageTypes.None:
                    switch (incDamage.DamageType)
                    {
                    case DamageTypes.Physical:
                        if (incDamage.StatUsed != 1)
                        {
                            incDamage.Damage          = 0;
                            incDamage.PrecalcDamage   = 0;
                            incDamage.DamageReduction = 0f;
                            incDamage.DamageEvent     = (byte)CombatEvent.COMBATEVENT_BLOCK;
                        }
                        else
                        {
                            incDamage.DamageReduction *= 0.066f;
                        }
                        break;

                    case DamageTypes.RawDamage:
                        incDamage.Mitigation        = incDamage.Damage * 0.99f;
                        incDamage.Damage           *= 0.01f;
                        incDamage.PrecalcMitigation = incDamage.PrecalcDamage * 0.99f;
                        incDamage.PrecalcDamage    *= 0.01f;
                        break;

                    default:
                        incDamage.DamageReduction *= 0.005f;
                        break;
                    }
                    break;
                }
            }

            else
            {
                switch (incDamage.SubDamageType)
                {
                case SubDamageTypes.Cleave:
                    incDamage.DamageReduction *= 0.8f;
                    break;

                case SubDamageTypes.Artillery:
                    incDamage.Mitigation = incDamage.Damage * 0.95f;
                    incDamage.Damage    *= 0.05f;
                    break;

                case SubDamageTypes.Oil:
                    incDamage.Damage          = 0;
                    incDamage.PrecalcDamage   = 0;
                    incDamage.DamageReduction = 0f;
                    incDamage.DamageEvent     = (byte)CombatEvent.COMBATEVENT_BLOCK;
                    break;

                case SubDamageTypes.Cannon:
                    incDamage.Mitigation = incDamage.Damage * 0.5f;
                    incDamage.Damage    *= 0.5f;
                    break;

                case SubDamageTypes.None:
                    switch (incDamage.DamageType)
                    {
                    case DamageTypes.Physical:
                        if (incDamage.StatUsed == 8)
                        {
                            incDamage.Damage          = 0;
                            incDamage.PrecalcDamage   = 0;
                            incDamage.DamageReduction = 0f;
                            incDamage.DamageEvent     = (byte)CombatEvent.COMBATEVENT_BLOCK;
                        }
                        else
                        {
                            incDamage.DamageReduction *= 0.4f;
                        }
                        break;

                    case DamageTypes.RawDamage:
                        incDamage.Mitigation = incDamage.Damage * 0.5f;
                        incDamage.Damage    *= 0.5f;
                        break;

                    default:
                        incDamage.DamageReduction *= 0.05f;
                        break;
                    }
                    break;
                }
            }
        }
        public static void LoadNewAbilityInfo()
        {
            Log.Info("AbilityMgr", "Loading New Ability Info...");

            IObjectDatabase db = WorldMgr.Database;

            #region Database

            List <DBAbilityInfo> dbAbilities = (List <DBAbilityInfo>)db.SelectAllObjects <DBAbilityInfo>();

            List <AbilityInfo> abVolatiles = AbilityInfo.Convert(dbAbilities);
            Dictionary <ushort, AbilityConstants> abConstants = AbilityConstants.Convert(dbAbilities).ToDictionary(key => key.Entry);
            List <AbilityDamageInfo>  abDmgHeals = AbilityDamageInfo.Convert(db.SelectAllObjects <DBAbilityDamageInfo>().OrderBy(dmg => dmg.ParentCommandID).ThenBy(dmg => dmg.ParentCommandSequence).ToList());
            List <AbilityCommandInfo> abCommands = AbilityCommandInfo.Convert(db.SelectAllObjects <DBAbilityCommandInfo>().OrderBy(cmd => cmd.CommandID).ToList());

            IList <AbilityModifierCheck>  abChecks = db.SelectAllObjects <AbilityModifierCheck>().OrderBy(check => check.ID).ToList();
            IList <AbilityModifierEffect> abMods   = db.SelectAllObjects <AbilityModifierEffect>().OrderBy(mod => mod.Sequence).ToList();

            List <BuffInfo>        buffInfos    = BuffInfo.Convert((List <DBBuffInfo>)db.SelectAllObjects <DBBuffInfo>());
            List <BuffCommandInfo> buffCommands = BuffCommandInfo.Convert(db.SelectAllObjects <DBBuffCommandInfo>().OrderBy(buffcmd => buffcmd.CommandID).ToList());

            IList <AbilityKnockbackInfo> knockbackInfos = db.SelectAllObjects <AbilityKnockbackInfo>().OrderBy(kbinfo => kbinfo.Id).ToList();

            List <AbilityCommandInfo> slaveCommands     = new List <AbilityCommandInfo>();
            List <BuffCommandInfo>    slaveBuffCommands = new List <BuffCommandInfo>();

            Dictionary <ushort, int> damageTypeDictionary = new Dictionary <ushort, int>();
            #endregion

            for (byte i = 0; i < 24; ++i)
            {
                CareerAbilities[i] = new List <AbilityInfo>();
            }

            #region AbilityChecks

            foreach (AbilityModifierCheck check in abChecks)
            {
                switch (check.PreOrPost)
                {
                case 0:
                    if (!AbilityPreCastModifiers.ContainsKey(check.Entry))
                    {
                        AbilityPreCastModifiers.Add(check.Entry, new List <AbilityModifier>());

                        while (AbilityPreCastModifiers[check.Entry].Count < check.ID + 1)
                        {
                            AbilityPreCastModifiers[check.Entry].Add(new AbilityModifier(check.Entry, check.Affecting));
                        }

                        AbilityPreCastModifiers[check.Entry][check.ID].AddCheck(check);
                    }

                    else
                    {
                        if (AbilityPreCastModifiers[check.Entry].Count == check.ID)
                        {
                            AbilityPreCastModifiers[check.Entry].Add(new AbilityModifier(check.Entry, check.Affecting));
                        }
                        AbilityPreCastModifiers[check.Entry][check.ID].AddCheck(check);
                    }
                    break;

                case 1:
                    if (!AbilityModifiers.ContainsKey(check.Entry))
                    {
                        AbilityModifiers.Add(check.Entry, new List <AbilityModifier>());

                        while (AbilityModifiers[check.Entry].Count < check.ID + 1)
                        {
                            AbilityModifiers[check.Entry].Add(new AbilityModifier(check.Entry, check.Affecting));
                        }
                        AbilityModifiers[check.Entry][check.ID].AddCheck(check);
                    }

                    else
                    {
                        if (AbilityModifiers[check.Entry].Count == check.ID)
                        {
                            AbilityModifiers[check.Entry].Add(new AbilityModifier(check.Entry, check.Affecting));
                        }
                        AbilityModifiers[check.Entry][check.ID].AddCheck(check);
                    }
                    break;

                case 2:
                    if (!BuffModifiers.ContainsKey(check.Entry))
                    {
                        BuffModifiers.Add(check.Entry, new List <AbilityModifier>());
                        while (BuffModifiers[check.Entry].Count < check.ID + 1)
                        {
                            BuffModifiers[check.Entry].Add(new AbilityModifier(check.Entry, check.Affecting));
                        }
                        BuffModifiers[check.Entry][check.ID].AddCheck(check);
                    }

                    else
                    {
                        if (BuffModifiers[check.Entry].Count == check.ID)
                        {
                            BuffModifiers[check.Entry].Add(new AbilityModifier(check.Entry, check.Affecting));
                        }
                        BuffModifiers[check.Entry][check.ID].AddCheck(check);
                    }
                    break;

                case 3:
                    if (!AbilityDelayedModifiers.ContainsKey(check.Entry))
                    {
                        AbilityDelayedModifiers.Add(check.Entry, new List <AbilityModifier>());

                        while (AbilityDelayedModifiers[check.Entry].Count < check.ID + 1)
                        {
                            AbilityDelayedModifiers[check.Entry].Add(new AbilityModifier(check.Entry, check.Affecting));
                        }

                        AbilityDelayedModifiers[check.Entry][check.ID].AddCheck(check);
                    }

                    else
                    {
                        if (AbilityDelayedModifiers[check.Entry].Count == check.ID)
                        {
                            AbilityDelayedModifiers[check.Entry].Add(new AbilityModifier(check.Entry, check.Affecting));
                        }
                        AbilityDelayedModifiers[check.Entry][check.ID].AddCheck(check);
                    }
                    break;
                }
            }

            #endregion

            #region AbilityModifiers

            foreach (AbilityModifierEffect effect in abMods)
            {
                switch (effect.PreOrPost)
                {
                case 0:
                    if (!AbilityPreCastModifiers.ContainsKey(effect.Entry))
                    {
                        AbilityPreCastModifiers.Add(effect.Entry, new List <AbilityModifier>());
                        AbilityPreCastModifiers[effect.Entry].Add(new AbilityModifier(effect.Entry, effect.Affecting));
                        AbilityPreCastModifiers[effect.Entry][0].AddModifier(effect);
                    }

                    else
                    {
                        if (AbilityPreCastModifiers[effect.Entry].Count == effect.Sequence)
                        {
                            AbilityPreCastModifiers[effect.Entry].Add(new AbilityModifier(effect.Entry, effect.Affecting));
                        }
                        AbilityPreCastModifiers[effect.Entry][effect.Sequence].AddModifier(effect);
                    }
                    break;

                case 1:
                    if (!AbilityModifiers.ContainsKey(effect.Entry))
                    {
                        AbilityModifiers.Add(effect.Entry, new List <AbilityModifier>());
                        AbilityModifiers[effect.Entry].Add(new AbilityModifier(effect.Entry, effect.Affecting));
                        AbilityModifiers[effect.Entry][0].AddModifier(effect);
                    }

                    else
                    {
                        if (AbilityModifiers[effect.Entry].Count == effect.Sequence)
                        {
                            AbilityModifiers[effect.Entry].Add(new AbilityModifier(effect.Entry, effect.Affecting));
                        }
                        AbilityModifiers[effect.Entry][effect.Sequence].AddModifier(effect);
                    }
                    break;

                case 2:
                    if (!BuffModifiers.ContainsKey(effect.Entry))
                    {
                        BuffModifiers.Add(effect.Entry, new List <AbilityModifier>());
                        BuffModifiers[effect.Entry].Add(new AbilityModifier(effect.Entry, effect.Affecting));
                        BuffModifiers[effect.Entry][0].AddModifier(effect);
                    }

                    else
                    {
                        if (BuffModifiers[effect.Entry].Count == effect.Sequence)
                        {
                            BuffModifiers[effect.Entry].Add(new AbilityModifier(effect.Entry, effect.Affecting));
                        }
                        BuffModifiers[effect.Entry][effect.Sequence].AddModifier(effect);
                    }
                    break;

                case 3:
                    if (!AbilityDelayedModifiers.ContainsKey(effect.Entry))
                    {
                        AbilityDelayedModifiers.Add(effect.Entry, new List <AbilityModifier>());
                        AbilityDelayedModifiers[effect.Entry].Add(new AbilityModifier(effect.Entry, effect.Affecting));
                        AbilityDelayedModifiers[effect.Entry][0].AddModifier(effect);
                    }

                    else
                    {
                        if (AbilityDelayedModifiers[effect.Entry].Count == effect.Sequence)
                        {
                            AbilityDelayedModifiers[effect.Entry].Add(new AbilityModifier(effect.Entry, effect.Affecting));
                        }
                        AbilityDelayedModifiers[effect.Entry][effect.Sequence].AddModifier(effect);
                    }
                    break;
                }
            }
            #endregion

            #region CommandInfo

            // Ability commands
            foreach (AbilityCommandInfo abCommand in abCommands)
            {
                if (abCommand.CommandSequence != 0)
                {
                    slaveCommands.Add(abCommand);
                }

                else
                {
                    if (!AbilityCommandInfos.ContainsKey(abCommand.Entry))
                    {
                        AbilityCommandInfos.Add(abCommand.Entry, new List <AbilityCommandInfo>());
                    }

                    AbilityCommandInfos[abCommand.Entry].Add(abCommand);
                }
            }

            foreach (AbilityCommandInfo slaveCommand in slaveCommands)
            {
                if (AbilityCommandInfos.ContainsKey(slaveCommand.Entry))
                {
                    AbilityCommandInfos[slaveCommand.Entry][slaveCommand.CommandID].AddCommandToChain(slaveCommand);
                }
                else
                {
                    Log.Debug("AbilityMgr", "Slave command with entry " + slaveCommand.Entry + " and depending upon master command ID " + slaveCommand.CommandID + " has no master!");
                }
            }

            #endregion

            #region BuffCommands

            foreach (BuffCommandInfo buffCommand in buffCommands)
            {
                if (buffCommand.CommandSequence != 0)
                {
                    slaveBuffCommands.Add(buffCommand);
                }
                else
                {
                    if (!BuffCommandInfos.ContainsKey(buffCommand.Entry))
                    {
                        BuffCommandInfos.Add(buffCommand.Entry, new List <BuffCommandInfo>());
                    }
                    BuffCommandInfos[buffCommand.Entry].Add(buffCommand);
                }
            }

            foreach (BuffCommandInfo slaveBuffCommand in slaveBuffCommands)
            {
                if (BuffCommandInfos.ContainsKey(slaveBuffCommand.Entry))
                {
                    BuffCommandInfos[slaveBuffCommand.Entry][slaveBuffCommand.CommandID].AddCommandToChain(slaveBuffCommand);
                }
                else
                {
                    Log.Debug("AbilityMgr", "Slave buff command with entry " + slaveBuffCommand.Entry + " and depending upon master command ID " + slaveBuffCommand.CommandID + " has no master!");
                }
            }

            #endregion

            #region Damage/Heals

            // Damage and heal info gets tacked onto the command that's going to use it
            foreach (AbilityDamageInfo abDmgHeal in abDmgHeals)
            {
                if (abDmgHeal.DisplayEntry == 0)
                {
                    abDmgHeal.DisplayEntry = abDmgHeal.Entry;
                }
                switch (abDmgHeal.Index)
                {
                case 0:
                    if (AbilityCommandInfos.ContainsKey(abDmgHeal.Entry))
                    {
                        AbilityCommandInfo desiredCommand = AbilityCommandInfos[abDmgHeal.Entry][abDmgHeal.ParentCommandID].GetSubcommand(abDmgHeal.ParentCommandSequence);
                        if (desiredCommand != null)
                        {
                            desiredCommand.DamageInfo = abDmgHeal;
                        }
                    }

                    if (!damageTypeDictionary.ContainsKey(abDmgHeal.Entry))
                    {
                        damageTypeDictionary.Add(abDmgHeal.Entry, (int)abDmgHeal.DamageType);
                    }
                    break;

                case 1:
                    if (BuffCommandInfos.ContainsKey(abDmgHeal.Entry))
                    {
                        try
                        {
                            BuffCommandInfo desiredCommand = BuffCommandInfos[abDmgHeal.Entry][abDmgHeal.ParentCommandID].GetSubcommand(abDmgHeal.ParentCommandSequence);
                            if (desiredCommand != null)
                            {
                                desiredCommand.DamageInfo = abDmgHeal;
                            }
                        }
                        catch
                        {
                            Log.Error("AbilityMgr", "Failed Load: " + abDmgHeal.Entry + " " + abDmgHeal.ParentCommandID);
                        }

                        if (!damageTypeDictionary.ContainsKey(abDmgHeal.Entry))
                        {
                            damageTypeDictionary.Add(abDmgHeal.Entry, (int)abDmgHeal.DamageType);
                        }
                    }
                    break;

                case 2:
                    if (!ExtraDamage.ContainsKey(abDmgHeal.Entry))
                    {
                        ExtraDamage.Add(abDmgHeal.Entry, new List <List <AbilityDamageInfo> >());
                    }
                    if (ExtraDamage[abDmgHeal.Entry].Count == abDmgHeal.ParentCommandID)
                    {
                        ExtraDamage[abDmgHeal.Entry].Add(new List <AbilityDamageInfo>());
                    }
                    ExtraDamage[abDmgHeal.Entry][abDmgHeal.ParentCommandID].Add(abDmgHeal);
                    break;

                default:
                    throw new Exception("Invalid index specified for ability damage with ID " + abDmgHeal.Entry);
                }
            }

            #endregion

            #region KnockbackInfo

            foreach (var kbInfo in knockbackInfos)
            {
                if (!KnockbackInfos.ContainsKey(kbInfo.Entry))
                {
                    KnockbackInfos.Add(kbInfo.Entry, new List <AbilityKnockbackInfo>());
                }
                KnockbackInfos[kbInfo.Entry].Add(kbInfo);
            }

            #endregion

            // Volatiles -> Constants
            //           -> Commands -> DamageHeals
            foreach (AbilityInfo abVolatile in abVolatiles)
            {
                if (!NewAbilityVolatiles.ContainsKey(abVolatile.Entry))
                {
                    NewAbilityVolatiles.Add(abVolatile.Entry, abVolatile);
                }

                if (AbilityCommandInfos.ContainsKey(abVolatile.Entry))
                {
                    abVolatile.TargetType = AbilityCommandInfos[abVolatile.Entry][0].TargetType;
                    if (AbilityCommandInfos[abVolatile.Entry][0].AoESource != 0)
                    {
                        abVolatile.TargetType = AbilityCommandInfos[abVolatile.Entry][0].AoESource;
                    }
                }
            }

            #region ConstantInfo

            foreach (AbilityConstants abConstant in abConstants.Values)
            {
                if (NewAbilityVolatiles.ContainsKey(abConstant.Entry))
                {
                    NewAbilityVolatiles[abConstant.Entry].ConstantInfo = abConstant;

                    if (damageTypeDictionary.ContainsKey(abConstant.Entry))
                    {
                        if (damageTypeDictionary[abConstant.Entry] == (ushort)DamageTypes.Healing || damageTypeDictionary[abConstant.Entry] == (ushort)DamageTypes.RawHealing)
                        {
                            abConstant.IsHealing = true;
                        }
                        else
                        {
                            abConstant.IsDamaging = true;
                        }
                    }

                    uint careerRequirement = abConstant.CareerLine;
                    byte count             = 0;

                    while (careerRequirement > 0 && count < 24)
                    {
                        if ((careerRequirement & 1) > 0)
                        {
                            CareerAbilities[count].Add(NewAbilityVolatiles[abConstant.Entry]);
                        }
                        careerRequirement = careerRequirement >> 1;
                        count++;
                    }
                }
            }

            #endregion

            #region Damage to ConstantInfo linkage

            foreach (AbilityDamageInfo damageInfo in abDmgHeals)
            {
                if (abConstants.ContainsKey(damageInfo.Entry))
                {
                    damageInfo.MasteryTree = abConstants[damageInfo.Entry].MasteryTree;
                }
            }

            #endregion

            #region Buff/Command linkage

            foreach (BuffInfo buffInfo in buffInfos)
            {
                if (!BuffInfos.ContainsKey(buffInfo.Entry))
                {
                    BuffInfos.Add(buffInfo.Entry, buffInfo);
                }

                if (BuffCommandInfos.ContainsKey(buffInfo.Entry))
                {
                    buffInfo.CommandInfo = BuffCommandInfos[buffInfo.Entry];
                }

                if (abConstants.ContainsKey(buffInfo.Entry))
                {
                    buffInfo.MasteryTree = abConstants[buffInfo.Entry].MasteryTree;
                }
            }

            #endregion

            Log.Success("AbilityMgr", "Finished loading " + NewAbilityVolatiles.Count + " abilities and " + BuffInfos.Count + " buffs!");

            LoadCreatureAbilities();
        }
 public override void InvokeDamageEvent(byte eventId, AbilityDamageInfo damageInfo, Unit eventInstigator)
 {
     TryCancel();
 }
        public virtual void InvokeDamageEvent(byte eventId, AbilityDamageInfo damageInfo, Unit eventInstigator)
        {
            if (BuffState != (byte)EBuffState.Running)
            {
                return;
            }

            BuffCommandInfo myCommand = EventCommands.Find(evtpair => evtpair.Item1 == eventId).Item2;

            if (myCommand == null)
            {
                return;
            }

            if (!string.IsNullOrEmpty(myCommand.EventCheck) && !BuffEffectInvoker.PerformCheck(this, damageInfo, myCommand, eventInstigator))
            {
                return;
            }

            if (myCommand.EventChance > 0 && StaticRandom.Instance.Next(0, 100) > myCommand.EventChance)
            {
                return;
            }

            if (myCommand.RetriggerInterval != 0)
            {
                // If two threads clash here, we're guaranteed to be setting the next time anyway
                // so the thread which can't get the lock should just return
                if (Interlocked.CompareExchange(ref BuffTimerLock, 1, 0) != 0)
                {
                    return;
                }

                if (myCommand.NextTriggerTime != 0 && myCommand.NextTriggerTime > TCPManager.GetTimeStampMS())
                {
                    Interlocked.Exchange(ref BuffTimerLock, 0);
                    return;
                }

                myCommand.NextTriggerTime = TCPManager.GetTimeStampMS() + myCommand.RetriggerInterval;
                Interlocked.Exchange(ref BuffTimerLock, 0);
            }

            if (myCommand.ConsumesStack)
            {
                while (Interlocked.CompareExchange(ref BuffStackLock, 1, 0) != 0)
                {
                    ;
                }

                if (StackLevel == 0)
                {
                    Interlocked.Exchange(ref BuffStackLock, 0);
                    return;
                }

                RemoveStack();

                if (Entry == 8090 || Entry == 9393)
                {
                    ((Player)Caster).SendClientMessage((eventInstigator?.Name ?? "Something") + "'s " + AbilityMgr.GetAbilityNameFor(damageInfo.DisplayEntry) + " broke your stealth.");
                }


                Interlocked.Exchange(ref BuffStackLock, 0);
            }

            if (myCommand.CommandName == "None")
            {
                return;
            }

            BuffEffectInvoker.InvokeDamageEventCommand(this, myCommand, damageInfo, Target, eventInstigator);
        }
 /// <summary>Inflicts damage upon this unit and returns whether lethal damage was dealt.</summary>
 public virtual bool ReceiveDamage(Unit caster, AbilityDamageInfo damageInfo)
 {
     return(ReceiveDamage(caster, (uint)damageInfo.Damage, damageInfo.HatredScale, (uint)damageInfo.Mitigation));
 }
 /// <summary>
 /// Save the damage a siege weapon inflicts as a measure of contribution.
 /// </summary>
 public override void ModifyDamageOut(AbilityDamageInfo outDamage)
 {
     _damageOut += outDamage.GetDamageForLevel(10) / 100;
     base.ModifyDamageOut(outDamage);
 }
 /// <summary>
 /// Returns true if this unit should block the particular type of incoming damage.
 /// </summary>
 public virtual bool ShouldDefend(Unit attacker, AbilityDamageInfo incDamage)
 {
     return(false);
 }
 /// <summary>
 /// Provides an opportunity for this unit to modify outgoing ability damage it deals.
 /// </summary>
 public virtual void ModifyDamageOut(AbilityDamageInfo outDamage)
 {
 }
 /// <summary>
 /// Provides an opportunity for this unit to modify incoming ability damage from enemies.
 /// </summary>
 public virtual void ModifyDamageIn(AbilityDamageInfo incDamage)
 {
 }
 /// <summary>
 /// Provides an opportunity for this unit to check the caster of the incoming ability damage from enemies.
 /// </summary>
 public virtual void CheckDamageCaster(Unit caster, AbilityDamageInfo incDamage)
 {
 }