public void Update(long tick)
 {
     if (TCPManager.GetTimeStampMS() >= _channelStartTime + _channelInfo.CastTime)
     {
         SendChannelEnd();
         _parent.NotifyChannelEnded();
         _channelInfo = null;
         _channelBuff = null;
     }
     else if (TCPManager.GetTimeStampMS() >= _nextTickTime)
     {
         if (_channelInfo.ApCost > 0 && !_host.ConsumeActionPoints(_channelInfo.ApCost))
         {
             _parent.CancelCast((byte)GameData.AbilityResult.ABILITYRESULT_AP);
         }
         else if (_playerHost != null && _channelInfo.SpecialCost > 3 && !_playerHost.CrrInterface.ConsumeResource((byte)_channelInfo.SpecialCost, true))
         {
             _parent.CancelCast(1);
         }
         else if (_target != _host && !_host.IsInCastRange(_target, Math.Max((uint)25, _channelInfo.Range)))
         {
             _parent.CancelCast((byte)GameData.AbilityResult.ABILITYRESULT_OUTOFRANGE);
         }
         else if (_checkVisibility && !_host.LOSHit(_target))
         {
             _parent.CancelCast((byte)GameData.AbilityResult.ABILITYRESULT_NOT_VISIBLE);
         }
         else
         {
             _nextTickTime += 1000;
         }
     }
 }
 public void OnCastAbility(AbilityInfo Ab)
 {
     for (int i = 0; i < Scripts.Count; ++i)
     {
         Scripts[i].OnCastAbility(Ab);
     }
 }
        public void ModifyInitials(AbilityInfo abInfo)
        {
            if (_generalPreCastModifiers.Count != 0)
            {
                foreach (var modifier in _generalPreCastModifiers)
                {
                    modifier.ModifyAbility(_myPlayer, abInfo);
                }
            }

            if (abInfo.ConstantInfo.MasteryTree != 0 && _speclinePreCastModifiers.ContainsKey((byte)(abInfo.ConstantInfo.MasteryTree - 1)))
            {
                foreach (var modifier in _speclinePreCastModifiers[(byte)(abInfo.ConstantInfo.MasteryTree - 1)])
                {
                    modifier.ModifyAbility(_myPlayer, abInfo);
                }
            }

            if (_abilityPreCastModifiers.ContainsKey(abInfo.Entry))
            {
                foreach (var modifier in _abilityPreCastModifiers[abInfo.Entry])
                {
                    modifier.ModifyAbility(_myPlayer, abInfo);
                }
            }
        }
        public void ModifyFinals(AbilityInfo abInfo)
        {
            if (_generalModifiers.Count != 0)
            {
                foreach (var modifier in _generalModifiers)
                {
                    modifier.ModifyAbility(_myPlayer, abInfo);
                }
            }

            if (abInfo.ConstantInfo.MasteryTree != 0 && _speclineModifiers.ContainsKey((byte)(abInfo.ConstantInfo.MasteryTree - 1)))
            {
                foreach (var modifier in _speclineModifiers[(byte)(abInfo.ConstantInfo.MasteryTree - 1)])
                {
                    modifier.ModifyAbility(_myPlayer, abInfo);
                }
            }

            if (_abilityModifiers.ContainsKey(abInfo.Entry))
            {
                foreach (var modifier in _abilityModifiers[abInfo.Entry])
                {
                    modifier.ModifyAbility(_myPlayer, abInfo);
                }
            }

            if (_myPlayer.CrrInterface.ExperimentalMode)
            {
                _myPlayer.CrrInterface.ExperimentalModeModifyAbility(abInfo);
            }
        }
Beispiel #5
0
        public void AddAbilities(ushort minBound, ushort maxBound)
        {
            if (maxBound == 0)
            {
                AbilityInfo abInfo = AbilityMgr.GetAbilityInfo(minBound);
                if (abInfo != null && abInfo.ConstantInfo.MinimumRank <= Level)
                {
                    NPCAbility npcAbility = new NPCAbility(abInfo.Entry, abInfo.ConstantInfo.AIRange, (byte)abInfo.Cooldown, true, "");
                    AbtInterface.NPCAbilities.Add(npcAbility);
                    SendPetAbility(npcAbility);
                }
            }

            else
            {
                for (ushort i = minBound; i <= maxBound; ++i)
                {
                    AbilityInfo abInfo = AbilityMgr.GetAbilityInfo(i);
                    if (abInfo == null || abInfo.ConstantInfo.MinimumRank > Level)
                    {
                        continue;
                    }
                    NPCAbility npcAbility = new NPCAbility(abInfo.Entry, abInfo.ConstantInfo.AIRange, (byte)abInfo.Cooldown, true, "");
                    AbtInterface.NPCAbilities.Add(npcAbility);
                    SendPetAbility(npcAbility);
                }
            }
        }
 /// <summary>
 /// Callback to start the channel proper
 /// </summary>
 public void ChannelInitialization(NewBuff channelBuff)
 {
     // Was cancelled before the channel callback
     if (_channelInfo == null || _host == null || _host.IsDead)
     {
         if (channelBuff != null)
         {
             channelBuff.BuffHasExpired = true;
             _channelBuff = null;
         }
     }
     // Couldn't create a channel buff, so cancel
     else if (channelBuff == null)
     {
         _parent.CancelCast(0);
         _channelInfo = null;
     }
     // Successful link
     else
     {
         _channelBuff = channelBuff;
         _channelBuff.ChannelHandler = this;
         // Oil
         if (_host is Siege)
         {
             _channelBuff.OptionalObject = _host;
         }
         _host.BuffInterface.NotifyAbilityCasted(_channelInfo);
     }
 }
        /*
         * public override bool SetExperimentalMode(bool fullExplanation)
         * {
         *  myPlayer.SendClientMessage("Experimental mode for this class is no longer available.", ChatLogFilters.CHATLOGFILTERS_CSR_TELL_RECEIVE);
         *  return false;
         *
         *  if (ExperimentalMode)
         *  {
         *      PrintExModeChangeset();
         *      myPlayer.SendClientMessage("Experimental mode for this class has been forced for a short period, and cannot be disabled.", ChatLogFilters.CHATLOGFILTERS_CSR_TELL_RECEIVE);
         *      return false;
         *  }
         *
         *  CurrentStance = 0;
         *
         *  if (fullExplanation)
         *  {
         *      if (myPlayer.Info.CareerLine == (int) GameData.CareerLine.CAREERLINE_WARRIOR_PRIEST)
         *      {
         *          myPlayer.BuffInterface.RemoveBuffByEntry(8242);
         *          myPlayer.BuffInterface.RemoveBuffByEntry(8243);
         *          myPlayer.BuffInterface.RemoveBuffByEntry(8249);
         *      }
         *      else
         *      {
         *          myPlayer.BuffInterface.RemoveBuffByEntry(9559);
         *          myPlayer.BuffInterface.RemoveBuffByEntry(9563);
         *          myPlayer.BuffInterface.RemoveBuffByEntry(9567);
         *      }
         *  }
         *
         *  ExperimentalMode = !ExperimentalMode;
         *
         *  if (!fullExplanation && ExperimentalMode)
         *  {
         *      myPlayer.SendClientMessage("Experimental mode for Warrior Priest and Disciple of Khaine is currently enabled.", ChatLogFilters.CHATLOGFILTERS_CSR_TELL_RECEIVE);
         *      return true;
         *  }
         *
         *  if (ExperimentalMode)
         *  {
         *      PrintExModeChangeset();
         *  }
         *
         *  else
         *      myPlayer.SendClientMessage("Experimental mode for Warrior Priest and Disciple of Khaine has been disabled.", ChatLogFilters.CHATLOGFILTERS_CSR_TELL_RECEIVE);
         *
         *  return true;
         * }
         *
         * private void PrintExModeChangeset()
         * {
         *  myPlayer.SendClientMessage("Experimental mode for Warrior Priest and Disciple of Khaine has been enabled.", ChatLogFilters.CHATLOGFILTERS_CSR_TELL_RECEIVE);
         *  myPlayer.SendClientMessage("General changes:", ChatLogFilters.CHATLOGFILTERS_CSR_TELL_RECEIVE);
         *  myPlayer.SendClientMessage("- Righteous Fury and Soul Essence regeneration from tomes and chalices is linked to the Morale bonus scaler.");
         *  myPlayer.SendClientMessage("- Switching between Prayers and Covenants invokes a 15 second cooldown for all Prayers and Covenants.");
         *  myPlayer.SendClientMessage("- When switching into or out of the Prayer of Righteousness or the Covenant of Celerity, a 5 minute cooldown is used instead.");
         *  myPlayer.SendClientMessage("- If in combat, switching to or from Righteousness or Celerity consumes all action points and mechanic points.");
         *  myPlayer.SendClientMessage("- The cooldown of Absence of Faith is now 10 seconds.");
         *  myPlayer.SendClientMessage("Prayer of Absolution and Covenant of Tenacity:", ChatLogFilters.CHATLOGFILTERS_CSR_TELL_RECEIVE);
         *  myPlayer.SendClientMessage("+ Provide 8 Righteous Fury / Soul Essence per second.");
         *  myPlayer.SendClientMessage("+ Convert your Strength and Melee Power bonus from items into Willpower and Healing Power.");
         *  myPlayer.SendClientMessage("- Reduce your armor by 50%. This is a multiplicative modifier, and thus also reduces the effect of potions, talismans and debuffs for armor.");
         *  myPlayer.SendClientMessage("Prayer of Devotion and Covenant of Vitality:", ChatLogFilters.CHATLOGFILTERS_CSR_TELL_RECEIVE);
         *  myPlayer.SendClientMessage("+ Convert your Willpower and Healing Power bonus from items into Strength and Melee Power.");
         *  myPlayer.SendClientMessage("- You will inflict 50% less damage.");
         *  myPlayer.SendClientMessage("+ You will gain 50% of your Strength bonus from items as Willpower whenever you strike a target with a Path of Grace or Path of Sacrifice ability.");
         *  myPlayer.SendClientMessage("This effect stacks up to three times and lasts for 12 seconds, and will be removed if you remove the Prayer or Covenant.");
         *  myPlayer.SendClientMessage("+ Your detaunt will gain the effect of the Intimidating Repent or Terrifying Aura tactic, becoming AoE.");
         *  myPlayer.SendClientMessage("- The cooldown of your detaunt increases to 25 seconds.");
         *  myPlayer.SendClientMessage("+ Sigmar's Radiance and Transfer Essence gain 20% strikethrough, and heal for 250% of the damage dealt and mitigated, with no base component.");
         *  myPlayer.SendClientMessage("+ Sigmar's Shield gains 20% strikethrough.");
         *  myPlayer.SendClientMessage("+ Rend Soul and Divine Assault become undefendable, healing for 75% more and healing for the mitigated value as well.");
         *  myPlayer.SendClientMessage("Prayer of Righteousness:", ChatLogFilters.CHATLOGFILTERS_CSR_TELL_RECEIVE);
         *  myPlayer.SendClientMessage("+ Convert your Willpower and Healing Power bonus from items into Strength and Melee Power.");
         *  myPlayer.SendClientMessage("+ The damage inflicted by Path of Wrath skills increases based on your Righteous Fury level, to a maximum of 40%.");
         *  myPlayer.SendClientMessage("- Any time you use a Path of Wrath skill, you will lose 5 Righteous Fury per second for 10 seconds.");
         *  myPlayer.SendClientMessage("+ Absence of Faith will debuff heals by 50%.");
         *  myPlayer.SendClientMessage("+ When you trigger your Prayer of Righteousness, it will increase your movement speed by 20% for 5 seconds. This will only affect you.");
         *  myPlayer.SendClientMessage("Covenant of Celerity:", ChatLogFilters.CHATLOGFILTERS_CSR_TELL_RECEIVE);
         *  myPlayer.SendClientMessage("+ Convert your Willpower and Healing Power bonus from items into Strength and Melee Power.");
         *  myPlayer.SendClientMessage("+ The damage inflicted by Path of Torture skills increases based on your Soul Essence level, to a maximum of 25%.");
         *  myPlayer.SendClientMessage("- Any time you use a Path of Torture skill, you will lose 5 Soul Essence per second for 10 seconds.");
         * }*/

        public override bool ExperimentalModeCheckAbility(AbilityInfo abInfo)
        {
            if (!ExperimentalMode)
            {
                /*// Repent -> Intimidating Repent
                 * if (abInfo.Entry == 8245)
                 * {
                 *  Item mainHand = myPlayer.ItmInterface.GetItemInSlot((ushort) EquipSlot.MAIN_HAND);
                 *
                 *  return mainHand?.Info != null && mainHand.Info.TwoHanded;
                 * }*/

                return(false);
            }

            switch (abInfo.Entry)
            {
            // Repent -> Intimidating Repent if Devotion is on
            // Terrifying Vision -> Terrifying Aura if Vitality is on
            case 8245:
            case 9555:
                return(_currentStance == 2);
            }
            return(true);
        }
        private void StartDelayedCast(object creature)
        {
            var Params = (List <object>)creature;

            Unit   _unit   = Params[0] as Unit;
            ushort Ability = (ushort)Params[1];

            // This is used by random ability cast
            if (_unit != null && !_unit.IsDead)
            {
                _unit.AbtInterface.StartCast(_unit, Ability, 1);

                if (!(_unit is Pet))
                {
                    _unit.MvtInterface.StopMove();
                    AbilityInfo AbiInfo = AbilityMgr.GetAbilityInfo(Ability);
                    if (!AbiInfo.CanCastWhileMoving)
                    {
                        _unit.EvtInterface.AddEvent(DelayedChase, AbiInfo.CastTime + 100, 1);
                    }
                    else
                    {
                        Chase(_unit.CbtInterface.GetCurrentTarget(), true);
                    }
                }
            }
        }
        public static void LoadCreatureAbilities()
        {
            CreatureAbilities.Clear();

            IList <Creature_abilities> creaAbs = WorldMgr.Database.SelectAllObjects <Creature_abilities>();

            Dictionary <uint, List <NPCAbility> > temp = new Dictionary <uint, List <NPCAbility> >();

            foreach (var cAb in creaAbs)
            {
                if (!temp.ContainsKey(cAb.ProtoEntry))
                {
                    temp.Add(cAb.ProtoEntry, new List <NPCAbility>());
                }

                AbilityInfo abInfo = GetAbilityInfo(cAb.AbilityId);
                if (abInfo != null)
                {
                    temp[cAb.ProtoEntry].Add(new NPCAbility(cAb.AbilityId, abInfo.ConstantInfo.AIRange, Math.Max(abInfo.Cooldown, cAb.Cooldown), true, cAb.Text, cAb.TimeStart, cAb.ActivateAtHealthPercent, cAb.AbilityCycle, cAb.Active, cAb.ActivateOnCombatStart, cAb.RandomTarget, cAb.DisableAtHealthPercent, cAb.MinRange));
                }
            }

            foreach (uint key in temp.Keys)
            {
                CreatureAbilities[key] = temp[key].OrderByDescending(x => x.Cooldown).ToList();
            }
        }
        /// <summary>Run to check whether an ability called through the DO_ABILITY packet is valid.</summary>
        public bool IsValidAbility(AbilityInfo info)
        {
            if (!HasPlayer())
            {
                return(true);
            }

            Player plr = GetPlayer();

            // Lock out abilities the player shouldn't have access to
            if (!_abilitySet.Contains(info.Entry))
            {
                return(false);
            }

            if (info.ConstantInfo.MinimumRank > plr.AdjustedLevel || info.ConstantInfo.MinimumRenown > plr.RenownRank)
            {
                return(false);
            }

            if (info.CareerLine != 0 && (plr.Info.CareerFlags & info.ConstantInfo.CareerLine) == 0)
            {
                return(false);
            }

            return(true);
        }
        public bool StartCastAtPos(Unit instigator, ushort abilityID, Point3D worldPos, ushort zoneId, byte castSequence)
        {
            if (PreventCasting)
            {
                if (_Owner is Player)
                {
                    Player owner = _Owner as Player;
                    owner?.SendClientMessage("A developer has disabled all abilities.", ChatLogFilters.CHATLOGFILTERS_USER_ERROR);
                }
                return(false);
            }

            // Allow only interruption of channeled skills of a different ID to the skill being used
            if (IsCasting() && (!_abilityProcessor.IsChannelling || _abilityProcessor.AbInfo.Entry == abilityID))
            {
                return(false);
            }

            AbilityInfo abInfo = AbilityMgr.GetAbilityInfo(abilityID);

            if (abInfo == null || (abInfo.ConstantInfo.Origin != AbilityOrigin.AO_ITEM && !IsValidAbility(abInfo)))
            {
                return(false);
            }
            try
            {
                if (AbilityMgr.HasCommandsFor(abilityID) || abInfo.ConstantInfo.ChannelID != 0)
                {
                    if (_abilityProcessor == null)
                    {
                        _abilityProcessor = new AbilityProcessor(_unitOwner, this);
                    }

                    abInfo.Instigator = instigator;

                    if (!_abilityProcessor.HasInfo())
                    {
                        _abilityProcessor.StartAbilityAtPos(abInfo, castSequence, worldPos, zoneId);
                    }
                    return(true);
                }
                if (_Owner is Player)
                {
                    var owner = _Owner as Player;
                    owner?.SendClientMessage(abilityID + " " + AbilityMgr.GetAbilityNameFor(abilityID) + " has no implementation.", ChatLogFilters.CHATLOGFILTERS_USER_ERROR);
                }
                return(false);
            }

            catch (Exception e)
            {
                if (_Owner is Player)
                {
                    var owner = _Owner as Player;
                    owner?.SendClientMessage(abilityID + " " + AbilityMgr.GetAbilityNameFor(abilityID) + " threw an unhandled " + e.GetType().Name + " from " + e.TargetSite + ".");
                }
                return(false);
            }
        }
Beispiel #12
0
        public AbilityInfo Clone()
        {
            AbilityInfo cAbInfo = (AbilityInfo)MemberwiseClone();

            cAbInfo.CommandInfo = new List <AbilityCommandInfo>();

            return(cAbInfo);
        }
 public void Interrupt()
 {
     _channelInfo = null;
     if (_channelBuff != null && !_channelBuff.BuffHasExpired)
     {
         _channelBuff.RemoveBuff(true);
     }
     _channelBuff = null;
 }
 /*
  * public void Initialize(Unit caster, Unit target, ushort baseEntry, ushort channelId, byte castSequence)
  * {
  *  _target = target;
  *  _caster = caster;
  *  _castSequence = castSequence;
  *  _baseEntry = baseEntry;
  *  _channelInfo = AbilityMgr.GetAbilityInfo(channelId);
  *  if (_channelInfo == null)
  *      Log.Error("NewChannelHandler", "Couldn't find the channel info for ID: " + channelId);
  *  else StartChannel();
  * }
  */
 public void Initialize(AbilityInfo abInfo, byte castSequence)
 {
     _target       = abInfo.Target;
     _caster       = abInfo.Instigator;
     _castSequence = castSequence;
     _baseEntry    = abInfo.Entry;
     _channelInfo  = abInfo;
     StartChannel();
 }
Beispiel #15
0
        public void NotifyAbilityCasted(AbilityInfo abInfo)
        {
            if (_buffCombatSubs[(byte)BuffCombatEvents.AbilityCasted - 1].Count == 0)
            {
                return;
            }

            foreach (var buff in _buffCombatSubs[(byte)BuffCombatEvents.AbilityCasted - 1])
            {
                buff.InvokeCastEvent((byte)BuffCombatEvents.AbilityCasted, abInfo);
            }
        }
        public void CancelPendingCast()
        {
            // Failed attempt to break a channel
            if (AbInfo != null)
            {
                return;
            }

            if (_pendingInfo.ConstantInfo.ChannelID != 0)
            {
                PacketOut Out = new PacketOut((byte)Opcodes.F_SET_ABILITY_TIMER, 12);
                Out.WriteUInt16(_pendingInfo.Entry);
                Out.Fill(0, 4);
                Out.WriteUInt16(0);
                Out.Fill(0, 4);
                if (_caster is Pet)
                {
                    ((Pet)_caster).Owner.SendPacket(Out);
                }
                else if (_caster is Player)
                {
                    ((Player)_caster).SendPacket(Out);
                }
            }

            if (_pendingInfo.SpecialCost < 0)
            {
                Player plr = _caster as Player;

                if (plr != null)
                {
                    PacketOut Out = new PacketOut((byte)Opcodes.F_SET_ABILITY_TIMER, 12);
                    Out.WriteUInt16(0);
                    Out.WriteUInt16(0x200); // Morale timer
                    Out.WriteUInt32(0);     // cooldown
                    Out.WriteUInt32(0);
                    plr.SendPacket(Out);
                }
            }

            AbInfo        = _pendingInfo;
            _castSequence = _pendingCastSequence;

            CancelCast(0);

            AbInfo        = null;
            _castSequence = 0;

            _pendingInfo = null;
            _pendingItemCooldownGroup = 0;
            _pendingCastSequence      = 0;
        }
Beispiel #17
0
        /// <summary>
        /// Modifies the cast time, cooldown, range and AP cost of an ability according to stats.
        /// </summary>
        /// <param name="abInfo"></param>
        public void ModifyAbilityVolatiles(AbilityInfo abInfo)
        {
            if (abInfo.ConstantInfo.ChannelID == 0)
            {
                int castMod = GetStatLinearModifier(Stats.BuildTime);

                if (abInfo.CastTime + castMod <= 0)
                {
                    abInfo.CastTime = 0;
                }
                else
                {
                    abInfo.CastTime = (ushort)((abInfo.CastTime + castMod) * GetStatPercentageModifier(Stats.BuildTime));
                }

                if (abInfo.CastTime == 0)
                {
                    abInfo.CanCastWhileMoving = true;
                }
            }

            if (abInfo.Entry != 9553 && abInfo.Entry != 8239 && abInfo.Entry != 9035 && abInfo.Entry != 1734) // exempt divine mend, khaine's invigoration, sudden shift and changin' da plan
            {
                short cooldownMod = (short)(GetStatLinearModifier(Stats.Cooldown) / 1000);
                if (abInfo.Cooldown + cooldownMod <= 0)
                {
                    abInfo.Cooldown = 0;
                }
                else
                {
                    abInfo.Cooldown = (ushort)((abInfo.Cooldown + cooldownMod) * (GetStatPercentageModifier(Stats.Cooldown)));
                }
            }

            float rangeMod = GetStatPercentageModifier(Stats.Range);

            abInfo.FlightTimeMod = 1f / rangeMod;

            if (abInfo.Range != 0)
            {
                abInfo.Range = (ushort)(abInfo.Range * rangeMod);
            }
            if (abInfo.ApCost != 0)
            {
                abInfo.ApCost = (byte)((abInfo.ApCost + GetTotalStat(Stats.ActionPointCost)) * GetStatPercentageModifier(Stats.ActionPointCost));
            }
        }
        private void Clear()
        {
            if (AbInfo.ConstantInfo.ChannelID != 0 && AbInfo.SpecialCost == -4)
            {
                _caster.RemoveCrowdControlImmunity((int)CrowdControlTypes.Unstoppable);
                _caster.IsImmovable = false;
            }

            AbInfo         = null;
            _castStartTime = 0;

            _inCastCompletion = false;

            _failureCode = 0;

            _shouldCheckRange = false;
        }
        public static void GetCommandsFor(Unit caster, AbilityInfo abInfo)
        {
            if (AbilityCommandInfos.ContainsKey(abInfo.Entry))
            {
                // Add commands to the new info if they're applicable to the player.
                // Has to be done here because of bloody tactics and career crap
                foreach (AbilityCommandInfo abCommand in AbilityCommandInfos[abInfo.Entry])
                {
                    if (!abCommand.NoAutoUse)
                    {
                        abInfo.CommandInfo.Add(abCommand.Clone(caster));

                        for (AbilityCommandInfo slaveCommand = abCommand.NextCommand; slaveCommand != null; slaveCommand = slaveCommand.NextCommand)
                        {
                            if (!slaveCommand.NoAutoUse)
                            {
                                abInfo.CommandInfo[(byte)(abInfo.CommandInfo.Count - 1)].AddCommandToChain(slaveCommand.Clone(caster));
                            }
                        }
                    }
                }
            }
        }
        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 ExperimentalModeModifyAbility(AbilityInfo abInfo)
        {
            switch (abInfo.Entry)
            {
            case 8252:     // Sigmar's Radiance
            case 9562:     // Transfer Essence

                if (_currentStance == 2)
                {
                    foreach (AbilityCommandInfo command in abInfo.CommandInfo)
                    {
                        for (AbilityCommandInfo cmd = command; cmd != null; cmd = cmd.NextCommand)
                        {
                            // Is undefendable, to compensate deals half damage but heals for more
                            if (cmd.CommandName == "StealLife")
                            {
                                cmd.DamageInfo.MinDamage = 0;
                                cmd.DamageInfo.MaxDamage = 0;
                                cmd.PrimaryValue         = (short)(cmd.PrimaryValue * 5f);
                            }
                            else if (cmd.DamageInfo != null)
                            {
                                cmd.DamageInfo.Defensibility -= 20;
                                cmd.DamageInfo.ResultFromRaw  = true;
                            }
                        }
                    }
                }
                break;

            case 8267:     // Sigmar's Shield
                if (_currentStance == 2)
                {
                    foreach (AbilityCommandInfo command in abInfo.CommandInfo)
                    {
                        for (AbilityCommandInfo cmd = command; cmd != null; cmd = cmd.NextCommand)
                        {
                            if (cmd.DamageInfo != null)
                            {
                                cmd.DamageInfo.Defensibility -= 20;
                            }
                        }
                    }
                }
                break;

            case 8270:     // Absence of Faith
                abInfo.Cooldown = 10;
                break;

            case 9555:     // Terrifying Vision
            case 8245:     // Repent
                if (_currentStance == 2)
                {
                    abInfo.Cooldown = 25;
                }
                break;

            case 8242:     // Prayer of Absolution
            case 9563:     // Covenant of Tenacity
            case 8249:     // Prayer of Devotion
            case 9567:     // Covenant of Vitality
                if (_currentStance == 1)
                {
                    abInfo.Cooldown = (ushort)(DPS_SWITCH_CD_MS / 1000);
                }
                else
                {
                    abInfo.Cooldown = (ushort)(SWITCH_CD_MS / 1000);
                }
                break;

            case 8243:     // Prayer of Righteousness
            case 9559:     // Covenant of Celerity
                abInfo.Cooldown = (ushort)(DPS_SWITCH_CD_MS / 1000);
                break;
            }
        }
        public virtual void InvokeCastEvent(byte eventID, AbilityInfo abInfo)
        {
            if (BuffState != (byte)EBuffState.Running)
            {
                return;
            }
            BuffCommandInfo myCommand = EventCommands.Find(evtpair => evtpair.Item1 == eventID).Item2;

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

            // Lazy checking for some tactics that don't warrant creating new delegates.
            switch (Entry)
            {
            // Scourged Warping (requires Scourge to be the ability casted)
            case 3765:
                if (abInfo.Entry != 8548)
                {
                    return;
                }
                break;

            // Flashfire (requires that the ability have a cast time)
            case 3422:
                if (abInfo.ConstantInfo.BaseCastTime == 0 || abInfo.ConstantInfo.ChannelID > 0 || abInfo.ConstantInfo.Origin == AbilityOrigin.AO_ITEM)
                {
                    return;
                }
                break;

            // Shadow Prowler, Incognito (ability must break)
            case 8090:
            case 9393:
                if (abInfo.ConstantInfo.StealthInteraction == AbilityStealthType.Ignore)
                {
                    return;
                }
                break;
            }

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

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

                RemoveStack();

                Interlocked.Exchange(ref BuffStackLock, 0);
            }

            if (myCommand.CommandName == "None")
            {
                return;
            }
            BuffEffectInvoker.InvokeAbilityUseCommand(this, myCommand, abInfo);
        }
Beispiel #23
0
 public virtual void OnCastAbility(AbilityInfo Ab)
 {
 }
 public override void InvokeCastEvent(byte eventID, AbilityInfo abInfo)
 {
     HasSentEnd = true;
     TryCancel();
 }
        /// <summary>
        /// Sets and transmits the cooldown of the given ability.
        /// </summary>
        /// <param name="abilityId">Ifd of ability to reset</param>
        /// <param name="duration">Cooldown duration in milliseconds, -1 to reset</param>
        /// <param name="silent">False to transmit new value to client, true otherwise</param>
        public void SetCooldown(ushort abilityId, long duration, bool silent = false)
        {
            #if DEBUG && ABILITY_DEVELOPMENT
            duration = 0;
            #endif

            if (abilityId == ushort.MaxValue)
            {
                return;
            }
            AbilityInfo abInfo = AbilityMgr.GetAbilityInfo(abilityId);
            if (abInfo.IgnoreCooldownReduction == 1 && (abInfo.Cooldown * 1000) >= duration)
            {
                long nextTimestamp = 0;
                if (abInfo.CDcap != null && abInfo.CDcap * 1000 > duration)
                {
                    nextTimestamp = (abInfo.CDcap * 1000) + TCPManager.GetTimeStampMS();
                }

                else
                {
                    nextTimestamp = (abInfo.Cooldown * 1000) + TCPManager.GetTimeStampMS();
                }

                Cooldowns[abilityId] = nextTimestamp;

                if (silent)
                {
                    return;
                }

                PacketOut Out = new PacketOut((byte)Opcodes.F_SET_ABILITY_TIMER, 12);
                Out.WriteUInt16(abilityId);
                Out.Fill(0, 2);
                Out.WriteUInt32(((uint)abInfo.Cooldown * 1000));
                Out.Fill(0, 4);
                if (_Owner.IsPet())
                {
                    _Owner.GetPet().Owner.SendPacket(Out);
                }
                else
                {
                    _playerOwner?.SendPacket(Out);
                }
            }

            if (abInfo.IgnoreCooldownReduction != 1 || (abInfo.IgnoreCooldownReduction == 1 && (abInfo.Cooldown * 1000) < duration))
            {
                long nextTimestamp = 0;

                if (abInfo.CDcap != null && abInfo.CDcap * 1000 > duration)
                {
                    nextTimestamp = (abInfo.CDcap * 1000) + TCPManager.GetTimeStampMS();
                }

                else
                {
                    nextTimestamp = (duration) + TCPManager.GetTimeStampMS();
                }

                if (duration == -1 && abInfo.CDcap == null)
                {
                    nextTimestamp = 0;
                }
                Cooldowns[abilityId] = nextTimestamp;

                if (silent)
                {
                    return;
                }

                PacketOut Out = new PacketOut((byte)Opcodes.F_SET_ABILITY_TIMER, 12);
                Out.WriteUInt16(abilityId);
                Out.Fill(0, 2);
                Out.WriteUInt32(duration != -1 ? (uint)duration : 0);
                Out.Fill(0, 4);
                if (_Owner.IsPet())
                {
                    _Owner.GetPet().Owner.SendPacket(Out);
                }
                else
                {
                    _playerOwner?.SendPacket(Out);
                }
            }
        }
 public bool IsOnCooldown(AbilityInfo abInfo)
 {
     return((!CanCastCooldown(0) && !abInfo.ConstantInfo.IgnoreGlobalCooldown) || !CanCastCooldown(abInfo.ConstantInfo.CooldownEntry != 0 ? abInfo.ConstantInfo.CooldownEntry : abInfo.Entry));
 }
 /// <summary>
 /// Queried by the modifier check "Experimental Mode" to determine whether a given ability should be modified.
 /// </summary>
 public virtual bool ExperimentalModeCheckAbility(AbilityInfo abInfo)
 {
     return(_experimentalMode);
 }
 public virtual void ExperimentalModeModifyAbility(AbilityInfo abInfo)
 {
 }
        public bool StartCast(Unit instigator, ushort abilityID, byte castSequence, byte cooldownGroup = 0, byte overrideAbilityLevel = 0, bool enemyVisible = true, bool friendlyVisible = true, bool moving = false)
        {
            if (PreventCasting)
            {
                if (_Owner is Player)
                {
                    (_Owner as Player)?.SendClientMessage("A developer has disabled all abilities.", ChatLogFilters.CHATLOGFILTERS_USER_ERROR);
                }
                return(false);
            }

            // Allow only interruption of channeled skills of a different ID to the skill being used
            if (IsCasting() && (!_abilityProcessor.IsChannelling || _abilityProcessor.AbInfo.Entry == abilityID))
            {
                return(false);
            }

            AbilityInfo abInfo = AbilityMgr.GetAbilityInfo(abilityID);

            if (abInfo == null || (abInfo.ConstantInfo.Origin != AbilityOrigin.AO_ITEM && !IsValidAbility(abInfo)))
            {
                return(false);
            }

            //Fix so that WE/WH cant use all their 3 openers at the same time, this is in conjunction with whats in AbilityProcessor
            if (_Owner is Player)
            {
                if ((_Owner as Player).StealthLevel == 0 && (abilityID == 9406 || abilityID == 9401 || abilityID == 9411 || abilityID == 8091 || abilityID == 8096 || abilityID == 8098))
                {
                    return(false);
                }
            }

            try
            {
                if (AbilityMgr.HasCommandsFor(abilityID) || abInfo.ConstantInfo.ChannelID != 0)
                {
                    if (_abilityProcessor == null)
                    {
                        _abilityProcessor = new AbilityProcessor(_unitOwner, this);
                    }

                    abInfo.Instigator = instigator;
                    abInfo.Level      = overrideAbilityLevel;

                    return(_abilityProcessor.StartAbility(abInfo, castSequence, cooldownGroup, enemyVisible, friendlyVisible, moving));
                }
                if (_Owner is Player)
                {
                    Player owner = _Owner as Player;
                    owner?.SendClientMessage(abilityID + " " + AbilityMgr.GetAbilityNameFor(abilityID) + " has no implementation.", ChatLogFilters.CHATLOGFILTERS_USER_ERROR);
                }
                return(false);
            }

            catch (Exception e)
            {
                if (_Owner is Player)
                {
                    (_Owner as Player)?.SendClientMessage(abilityID + " " + AbilityMgr.GetAbilityNameFor(abilityID) + " threw an unhandled " + e.GetType().Name + " from " + e.TargetSite + ".");
                }
                Log.Error("Ability System", e.ToString());
                return(false);
            }
        }
        /// <summary>
        /// Identifies target of an ability before it is casted and checks its validity (pvp flag, visibility...).
        /// </summary>
        /// <param name="abInfo">Ability that is about to be casted</param>
        /// <param name="instigator">Instigator of the ability</param>
        /// <param name="foeVisible">True if current targeted foe is visible</param>
        /// <param name="allyVisible">True if current targeted ally is visible</param>
        /// <returns>True if target is valid for the ability</returns>
        private bool GetTarget(AbilityInfo abInfo, Unit instigator, bool foeVisible, bool allyVisible)
        {
            if (_pendingInfo.Range == 0 || _pendingInfo.CommandInfo == null)
            {
                _pendingInfo.Target = _caster;
                return(true);
            }

            if (_pendingInfo.TargetType == CommandTargetTypes.SiegeCannon)
            {
                _pendingInfo.Target = ((Creature)_caster).SiegeInterface.BuildTargetList(instigator);
                return(true);
            }

            CommandTargetTypes selectType = (CommandTargetTypes)((int)_pendingInfo.TargetType & 7);

            switch (selectType)
            {
            case CommandTargetTypes.Caster:
                _pendingInfo.Target = _caster;
                break;

            case CommandTargetTypes.Ally:
                if (!allyVisible)
                {
                    return(false);
                }
                _pendingInfo.Target = _caster.CbtInterface.GetTarget(TargetTypes.TARGETTYPES_TARGET_ALLY);
                if (_pendingInfo.Target == _caster || !CombatInterface.IsFriend(_caster, _pendingInfo.Target) || (_pendingInfo.Target is Creature && !(_pendingInfo.Target is Pet)))
                {
                    return(false);
                }
                if (_pendingInfo.TargetType.HasFlag(CommandTargetTypes.Groupmates))
                {
                    Group myGroup = ((Player)_caster).PriorityGroup;
                    if (myGroup == null || !myGroup.HasMember(_pendingInfo.Target))
                    {
                        return(false);
                    }
                }
                break;

            case CommandTargetTypes.AllyOrSelf:
                if (!allyVisible)
                {
                    return(false);
                }
                _pendingInfo.Target = _caster.CbtInterface.GetTarget(TargetTypes.TARGETTYPES_TARGET_ALLY) ?? _caster;

                if (!CombatInterface.IsFriend(_caster, _pendingInfo.Target) || (_pendingInfo.Target is Creature && !(_pendingInfo.Target is Pet)))
                {
                    return(false);
                }
                if (_pendingInfo.Target != _caster)
                {
                    if (_pendingInfo.TargetType.HasFlag(CommandTargetTypes.Groupmates))
                    {
                        Group myGroup = ((Player)_caster).PriorityGroup;
                        if (myGroup == null || !myGroup.HasMember(_pendingInfo.Target))
                        {
                            return(false);
                        }
                    }
                }
                break;

            case CommandTargetTypes.AllyOrCareerTarget:
                if (!allyVisible)
                {
                    return(false);
                }
                _pendingInfo.Target = _caster.CbtInterface.GetTarget(TargetTypes.TARGETTYPES_TARGET_ALLY);

                if (!CombatInterface.IsFriend(_caster, _pendingInfo.Target) || _pendingInfo.Target != null && (_pendingInfo.Target is Creature && !(_pendingInfo.Target is Pet)))
                {
                    return(false);
                }
                if (_pendingInfo.Target != null && _pendingInfo.Target != _caster)
                {
                    if (_pendingInfo.TargetType.HasFlag(CommandTargetTypes.Groupmates))
                    {
                        Group myGroup = ((Player)_caster).PriorityGroup;
                        if (myGroup == null || !myGroup.HasMember(_pendingInfo.Target))
                        {
                            return(false);
                        }
                    }
                }
                else
                {
                    Player petCareerPlr = null;
                    if (_caster is Player)
                    {
                        petCareerPlr = _caster as Player;
                    }
                    if (petCareerPlr != null)
                    {
                        _pendingInfo.Target = petCareerPlr.CrrInterface.GetTargetOfInterest();
                    }

                    if (_pendingInfo.Target == null || _pendingInfo.Target == _caster)
                    {
                        _pendingInfo.Target = null;
                        return(false);
                    }
                }

                break;

            case CommandTargetTypes.Enemy:
                if (!foeVisible)
                {
                    return(false);
                }
                _pendingInfo.Target = _caster.CbtInterface.GetTarget(TargetTypes.TARGETTYPES_TARGET_ENEMY);
                if (!CombatInterface.CanAttack(_caster, _pendingInfo.Target))
                {
                    _pendingInfo.Target = null;
                }
                else
                {
                    if (!_caster.CbtInterface.IsPvp)
                    {
                        Player plrCaster = _caster as Player;
                        if (plrCaster != null && _pendingInfo.Target.CbtInterface.IsPvp)
                        {
                            ((CombatInterface_Player)plrCaster.CbtInterface).EnablePvp();
                        }
                    }
                }

                Player plrTarget = _pendingInfo.Target as Player;

                if (plrTarget != null && plrTarget.Palisade != null && (plrTarget.Palisade.IsObjectInFront(_caster, 180) ^ plrTarget.Palisade.IsObjectInFront(plrTarget, 180)))
                {
                    _pendingInfo.Target = plrTarget.Palisade;
                }

                //8410 - Terrible Embrace ; 9057 - Wings of Heaven ; 9178 - Fetch! ; 9186 - Pounce
                if (_pendingInfo.Target != null &&
                    (abInfo.Entry == 8410 || abInfo.Entry == 9057 || abInfo.Entry == 9178 || abInfo.Entry == 9186) &&
                    Math.Abs(_caster.Z - _pendingInfo.Target.Z) > 300)
                {
                    _caster.AbtInterface.SetCooldown(abInfo.Entry, -1);
                    return(false);
                }

                break;

            case CommandTargetTypes.CareerTarget:     // Target of Interest (oath friend/dark protector/pet if player, master if pet)
                var player = _caster as Player;
                if (player != null)
                {
                    _pendingInfo.Target = player.CrrInterface.GetTargetOfInterest();
                }
                else
                {
                    var pet = _caster as Pet;
                    if (pet != null)
                    {
                        _pendingInfo.Target = pet.Owner;
                    }
                    else
                    {
                        Log.Error("NewAbility", "Ability " + _pendingInfo.Entry + " with targettype 5 has no target!");
                        _pendingInfo.Target = null;
                    }
                }
                break;

            default:
                Log.Error("NewAbility", "Ability " + _pendingInfo.Entry + " with TargetType zero in 3 LSBs!");
                _pendingInfo.Target = _caster;
                break;
            }

            if (_pendingInfo.TargetType.HasFlag(CommandTargetTypes.Groupmates) && _pendingInfo.Target != _caster)
            {
                Group myGroup = ((Player)_caster).PriorityGroup;
                if (myGroup == null || !myGroup.HasMember(_pendingInfo.Target))
                {
                    return(false);
                }
            }

            return(_pendingInfo.Target != null);
        }