Пример #1
0
        public bool StartAbility(AbilityInfo abInfo, byte castSequence, byte cooldownGroup, bool foeVisible, bool allyVisible, bool moving)
        {
            _pendingInfo = abInfo;
            _pendingItemCooldownGroup = cooldownGroup;
            _pendingCastSequence      = castSequence;

            //Cut in to manage toggle abilities here.
            if (_pendingInfo.ConstantInfo.ToggleEntry > 0)
            {
                NewBuff toToggle = _caster.BuffInterface.GetBuff(_pendingInfo.ConstantInfo.ToggleEntry, _caster);

                if (toToggle != null)
                {
                    toToggle.BuffHasExpired = true;
                    CancelPendingCast();
                    _abInterface.SetCooldown(abInfo.ConstantInfo.CooldownEntry != 0 ? abInfo.ConstantInfo.CooldownEntry : abInfo.Entry, abInfo.Cooldown * 1000);
                    return(true);
                }
            }

            if (!GetTarget(abInfo, _pendingInfo.Instigator, foeVisible, allyVisible) && _pendingInfo.Range > 0)
            {
                CancelPendingCast();
                return(false);
            }

            byte result = ModifyInitials();

            if (!_pendingInfo.CanCastWhileMoving && _pendingInfo.CastTime > 0 && _pendingInfo.ConstantInfo.ChannelID == 0 && moving)
            {
                CancelPendingCast();
                return(false);
            }

            if (result == 1 || !AllowStartCast())
            {
                CancelPendingCast();
                return(false);
            }

            if (result == 2)
            {
                _abInterface.SetGlobalCooldown();
                CancelPendingCast();
                return(false);
            }

            if (result == 3)
            {
                _abInterface.SetCooldown(_pendingInfo.ConstantInfo.CooldownEntry != 0 ? _pendingInfo.ConstantInfo.CooldownEntry : _pendingInfo.Entry, _pendingInfo.Cooldown * 1000);
                CancelPendingCast();
                return(false);
            }

            if (!_caster.HasActionPoints(_pendingInfo.ApCost))
            {
                CancelPendingCast();
                return(false);
            }
            //fix so that WE/WH cant use all their 3 openers at the same time, this in conjunction with whats in AbilityInterface
            if (_caster is Player)
            {
                if ((_caster as Player).StealthLevel > 0 && (abInfo.Entry == 9406 || abInfo.Entry == 9401 || abInfo.Entry == 9411 || abInfo.Entry == 8091 || abInfo.Entry == 8096 || abInfo.Entry == 8098))
                {
                    (_caster as Player).Uncloak();
                }
            }

            // Cast success. Cancel existing ability if any

            if (AbInfo != null)
            {
                CancelCast(0);
            }

            // Ether Dance / T'ree Hit Combo hold the resource state - need to check if they were broken using an attack of the same level
            if (_pendingInfo.SpecialCost > 0)
            {
                Player plr = _caster as Player;

                if (plr != null)
                {
                    if (_pendingInfo.SpecialCost > 0)
                    {
                        if (!plr.CrrInterface.HasResource((byte)_pendingInfo.SpecialCost))
                        {
                            CancelPendingCast();
                            return(false);
                        }
                    }
                }
            }

            AbInfo       = _pendingInfo;
            _pendingInfo = null;

            _pendingItemCooldownGroup = 0;
            _pendingCastSequence      = 0;

            if (AbInfo.Level == 0)
            {
                AbInfo.Level = _abInterface.GetMasteryLevelFor(AbInfo.ConstantInfo.MasteryTree);
            }

            _castSequence      = castSequence;
            _itemCooldownGroup = cooldownGroup;

            _castStartTime = TCPManager.GetTimeStampMS();

            _caster.BuffInterface.NotifyAbilityStarted(AbInfo);

            SendStart();

            //Secondary system for VFX
            if (abInfo.VFXTarget != null && abInfo.abilityID != 0 && _caster is Player)
            {
                string temp = "";

                if (abInfo.VFXTarget.Contains("Self"))
                {
                    temp = (_caster as Player).Name;
                }

                else if (abInfo.VFXTarget.Contains("Hostile") && (_caster as Player).CbtInterface.GetTarget(TargetTypes.TARGETTYPES_TARGET_ENEMY) != null)
                {
                    temp = (_caster as Player).CbtInterface.GetTarget(TargetTypes.TARGETTYPES_TARGET_ENEMY).Name;
                }

                else if (abInfo.VFXTarget.Contains("Friendly") && (_caster as Player).CbtInterface.GetTarget(TargetTypes.TARGETTYPES_TARGET_ALLY) != null)
                {
                    temp = (_caster as Player).CbtInterface.GetTarget(TargetTypes.TARGETTYPES_TARGET_ALLY).Name;
                }

                //Pets are handled differently, dont ask me why /Natherul
                else if (abInfo.VFXTarget.Contains("Pet") && (_caster as Player).CrrInterface.GetTargetOfInterest() != null)
                {
                    temp = (_caster as Player).CrrInterface.GetTargetOfInterest().Name;
                }

                temp += " " + abInfo.abilityID.ToString();

                if (abInfo.effectID2 != 0)
                {
                    temp += " " + abInfo.effectID2.ToString();
                }

                if (abInfo.Time != 0 && (!abInfo.VFXTarget.Contains("Pet") || (abInfo.VFXTarget.Contains("Hostile") && (_caster as Player).CbtInterface.GetTarget(TargetTypes.TARGETTYPES_TARGET_ENEMY).IsPlayer()) || (abInfo.VFXTarget.Contains("Friendly") && (_caster as Player).CbtInterface.GetTarget(TargetTypes.TARGETTYPES_TARGET_ALLY).IsPlayer())))
                {
                    temp += " " + abInfo.Time.ToString() + " 0";
                }

                if (abInfo.VFXTarget.Contains("aoe"))
                {
                    temp += " " + abInfo.VFXTarget.Remove(0, abInfo.VFXTarget.IndexOf(' ') + 1);
                }


                List <string> paramValue = temp.Split(' ').ToList();
                if (Regex.IsMatch(paramValue[0], @"^[a-zA-Z]+$"))
                {
                    BaseCommands.PlayAbility((_caster as Player), ref paramValue);
                }
            }

            if (!AbInfo.ConstantInfo.IgnoreGlobalCooldown)
            {
                _abInterface.SetGlobalCooldown();
            }

            if (AbInfo.ConstantInfo.ChannelID != 0)
            {
                // Channeled Morale 4s grant immunity and cannot be interrupted
                if (AbInfo.SpecialCost == -4)
                {
                    _caster.AddCrowdControlImmunity((int)CrowdControlTypes.Unstoppable);
                    _caster.IsImmovable = true;
                }

                _channelHandler.Initialize(AbInfo, castSequence);
            }

            // Instants
            else if (AbInfo.CastTime == 0)
            {
                Cast();
            }

            // Casts need to check range 60% of the way in
            else
            {
                _shouldCheckRange = true;
            }

            if (_setbacks.Count > 0)
            {
                lock (_setbacks)
                    _setbacks.Clear();
            }

            return(true);
        }