示例#1
0
        public override void StartBuff()
        {
            if (_buffInfo.CommandInfo != null)
            {
                for (byte i = 0; i < _buffInfo.CommandInfo.Count; ++i)
                {
                    if ((_buffInfo.CommandInfo[i].InvokeOn & BuffState) > 0)
                    {
                        BuffEffectInvoker.InvokeCommand(this, _buffInfo.CommandInfo[i], Target);
                    }
                }
            }

            BuffState = (byte)EBuffState.Running;

            NextTickTime = TCPManager.GetTimeStampMS() + _buffInfo.Interval;

            if (BuffLines.Count != 0)
            {
                SendBounceStart();
            }
            else
            {
                BuffHasExpired = true;
            }
        }
示例#2
0
        public override void Update(long tick)
        {
            if (BuffState != (byte)EBuffState.Running)
            {
                return;
            }

            long curTime = TCPManager.GetTimeStampMS();

            if (EndTime > 0 && curTime >= EndTime)
            {
                BuffEnded(false, false);
            }
            else
            {
                if (NextTickTime > 0 && curTime >= NextTickTime)
                {
                    NextTickTime += _buffInfo.Interval;

                    foreach (BuffCommandInfo command in _buffInfo.CommandInfo)
                    {
                        if ((command.InvokeOn & (byte)EBuffState.Running) > 0)
                        {
                            BuffEffectInvoker.InvokeCommand(this, command, Target);
                        }
                    }
                }

                if (_nextAuraPropagationTime <= tick)
                {
                    _nextAuraPropagationTime = tick + _propInterval;
                    SpreadAura();
                }
            }
        }
示例#3
0
        public override void Update(long tick)
        {
            if (BuffState != (byte)EBuffState.Running)
            {
                return;
            }

            long curTime = TCPManager.GetTimeStampMS();

            if (EndTime > 0 && curTime >= EndTime)
            {
                BuffEnded(false, false);
            }
            else if (NextTickTime > 0 && curTime >= NextTickTime)
            {
                NextTickTime += _buffInfo.Interval;

                OnUpdate?.Invoke(this, HeldObject, tick);

                if (_buffInfo.CommandInfo != null)
                {
                    foreach (BuffCommandInfo command in _buffInfo.CommandInfo)
                    {
                        if ((command.InvokeOn & (byte)EBuffState.Running) > 0)
                        {
                            BuffEffectInvoker.InvokeCommand(this, command, Target);
                        }
                    }
                }
            }
        }
示例#4
0
        /// <summary>
        /// Reload abilities.
        /// </summary>
        /// <param name="plr">Player that initiated the command</param>
        /// <param name="values">List of command arguments (after command name)</param>
        /// <returns>True if command was correctly handled, false if operation was canceled</returns>
        public static bool ReloadAbilities(Player plr, ref List <string> values)
        {
            lock (Player._Players)
            {
                foreach (Player player in Player._Players)
                {
                    player.SendClientMessage("[System] Recaching ability tables...", ChatLogFilters.CHATLOGFILTERS_CSR_TELL_RECEIVE);
                }
            }

            AbilityMgr.ReloadAbilities();
            AbilityMgr.LoadCreatureAbilities();
            AbilityModifierInvoker.LoadModifierCommands();
            BuffEffectInvoker.LoadBuffCommands();

            lock (Player._Players)
            {
                foreach (Player player in Player._Players)
                {
                    player.SendClientMessage("[System] Ability tables successfully recached.", ChatLogFilters.CHATLOGFILTERS_CSR_TELL_RECEIVE);
                }
            }

            return(true);
        }
        public void InvokeItemEvent(byte eventID, Item_Info itmInfo)
        {
            if (BuffState != (byte)EBuffState.Running)
            {
                return;
            }
            BuffCommandInfo myCommand = EventCommands.Find(evtpair => evtpair.Item1 == eventID).Item2;

            if (myCommand == null)
            {
                return;
            }

            BuffEffectInvoker.InvokeItemCommand(this, myCommand, itmInfo);
        }
示例#6
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);
 }
示例#7
0
        protected override void BuffEnded(bool wasRemoved, bool wasManual)
        {
            if (Interlocked.CompareExchange(ref BuffEndLock, 1, 0) != 0)
            {
                return;
            }

            BuffHasExpired     = true;
            WasManuallyRemoved = wasManual;

            if (wasRemoved)
            {
                BuffState = (byte)EBuffState.Removed;
            }
            else
            {
                BuffState = (byte)EBuffState.Ended;
            }

            Interlocked.Exchange(ref BuffEndLock, 0);

            if (_buffInfo.CommandInfo != null)
            {
                foreach (BuffCommandInfo Command in _buffInfo.CommandInfo)
                {
                    if ((Command.InvokeOn & (byte)EBuffState.Ended) > 0)
                    {
                        BuffEffectInvoker.InvokeCommand(this, Command, Target);
                    }
                }
            }

            SendBounceEnd();

            if (_linkedBuff != null && !_linkedBuff.BuffHasExpired)
            {
                _linkedBuff.BuffHasExpired = true;
            }
        }
        public void InvokePetEvent(byte eventID, Pet myPet)
        {
            if (BuffState != (byte)EBuffState.Running)
            {
                return;
            }
            BuffCommandInfo myCommand = EventCommands.Find(evtpair => evtpair.Item1 == eventID).Item2;

            if (myCommand == null)
            {
                return;
            }

            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.InvokePetCommand(this, myCommand, myPet);
        }
示例#9
0
        protected override void BuffEnded(bool wasRemoved, bool wasManual)
        {
            if (Interlocked.CompareExchange(ref BuffEndLock, 1, 0) != 0)
            {
                return;
            }

            BuffHasExpired     = true;
            WasManuallyRemoved = wasManual;

            if (wasRemoved)
            {
                BuffState = (byte)EBuffState.Removed;
            }
            else
            {
                BuffState = (byte)EBuffState.Ended;
            }

            Interlocked.Exchange(ref BuffEndLock, 0);

            if (_buffInfo.CommandInfo != null)
            {
                foreach (BuffCommandInfo command in _buffInfo.CommandInfo)
                {
                    if ((command.InvokeOn & (byte)EBuffState.Ended) > 0)
                    {
                        BuffEffectInvoker.InvokeCommand(this, command, Target);
                    }
                }
            }

            if (EventCommands.Count > 0)
            {
                foreach (var evtpair in EventCommands)
                {
                    _buffInterface.RemoveEventSubscription(this, evtpair.Item1);
                }
            }

            BuffHasExpired = true;

            BuffState = (byte)EBuffState.Removed;

            Player player = (Player)Caster;

            if (player.HeldObject != HeldObject)
            {
                Log.Error(player.Name, "Holding multiple objects!");
            }
            else
            {
                player.HeldObject = null;
            }

            HeldObject.HolderDied();

            Caster.OSInterface.RemoveEffect(0xB);

            SendEnded();
        }
        public void InvokeResourceEvent(byte eventID, byte oldVal, ref byte change)
        {
            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;
            }

            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();

                Interlocked.Exchange(ref BuffStackLock, 0);
            }

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

            BuffEffectInvoker.InvokeResourceCommand(this, myCommand, oldVal, ref change);
        }
        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);
        }
        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);
        }
        protected virtual void BuffEnded(bool wasRemoved, bool wasManual)
        {
            if (Interlocked.CompareExchange(ref BuffEndLock, 1, 0) != 0)
            {
                return;
            }

            BuffHasExpired     = true;
            WasManuallyRemoved = wasManual;

            if (wasRemoved)
            {
                BuffState = (byte)EBuffState.Removed;
            }
            else
            {
                BuffState = (byte)EBuffState.Ended;
            }

            Interlocked.Exchange(ref BuffEndLock, 0);

            // Flag exhaustion needs to send end before performing the swap
            if (Entry == 14323)
            {
                SendEnded();
            }

            if (_buffInfo.CommandInfo != null)
            {
                foreach (BuffCommandInfo command in _buffInfo.CommandInfo)
                {
                    if ((command.InvokeOn & (byte)EBuffState.Ended) > 0)
                    {
                        BuffEffectInvoker.InvokeCommand(this, command, Target);
                    }
                }
            }

            if (EventCommands.Count > 0)
            {
                foreach (var evtpair in EventCommands)
                {
                    _buffInterface.RemoveEventSubscription(this, evtpair.Item1);
                }
            }

            if (_buffInfo.CommandInfo != null)
            {
                foreach (BuffCommandInfo command in _buffInfo.CommandInfo)
                {
                    if (command.InvokeOn == 8 && command.TargetType == CommandTargetTypes.Caster)
                    {
                        Caster.BuffInterface.RemoveEventSubscription(this, command.EventID);
                    }
                }
            }

            if (Entry != 14323)
            {
                SendEnded();
            }

            if (_linkedBuff != null && !_linkedBuff.BuffHasExpired)
            {
                _linkedBuff.BuffHasExpired = true;
            }
        }
        public virtual void StartBuff()
        {
            if (_buffInfo.StackLine != 0)
            {
                AddBuffParameter(_buffInfo.StackLine, StackLevel);
            }

            // Invoke commands and register event subscriptions.
            if (_buffInfo.CommandInfo != null)
            {
                for (byte i = 0; i < _buffInfo.CommandInfo.Count; ++i)
                {
                    BuffCommandInfo command = _buffInfo.CommandInfo[i];

                    if (command.EventID != 0)
                    {
                        EventCommands.Add(new Tuple <byte, BuffCommandInfo>(command.EventID, command));
                        _buffInterface.AddEventSubscription(this, command.EventID);
                        //InvokeOn override - 8 == Invoke as permanent conditional effect while buff is active (for Channel)
                        if (command.InvokeOn == 8 && command.TargetType == CommandTargetTypes.Caster)
                        {
                            Caster.BuffInterface.AddEventSubscription(this, command.EventID);
                        }

                        if (command.InvokeOn == 0 && command.BuffLine > 0)
                        {
                            AddBuffParameter(command.BuffLine, command.PrimaryValue);
                        }
                    }
                    if ((command.InvokeOn & BuffState) > 0)
                    {
                        BuffEffectInvoker.InvokeCommand(this, command, Target);
                    }
                }
            }

            BuffState = (byte)EBuffState.Running;

            #region Check for CC block or no tooltip text
            // If a buff is crowd control and no tooltip text was added, a CC immunity blocked it.
            // In this case the buff is removed here.
            if (BuffLines.Count != 0)
            {
                if (Duration > 0)
                {
                    if (CrowdControl == 1)
                    {
                        DurationMs = (uint)(DurationMs * Target.StsInterface.GetStatReductionModifier(Stats.SnareDuration));
                        EndTime    = TCPManager.GetTimeStampMS() + DurationMs;
                    }
                    if (CrowdControl == 16)
                    {
                        DurationMs = (uint)(DurationMs * Target.StsInterface.GetStatReductionModifier(Stats.KnockdownDuration));
                        EndTime    = TCPManager.GetTimeStampMS() + DurationMs;
                    }
                }

                SendStart(null);

                ChannelHandler?.NotifyBuffStarted();
            }
            else
            {
                #if DEBUG
                Log.Info("Buff " + _buffInfo.Entry, "Couldn't find any buff lines.");
                if (CrowdControl == 0 && Caster is Player)
                {
                    ((Player)Caster).SendClientMessage(Entry + " " + AbilityMgr.GetAbilityNameFor(Entry) + ": Couldn't find any buff lines.");
                }
                #endif
                BuffHasExpired = true;
            }
            #endregion
        }