Esempio n. 1
0
        /// <summary>
        /// <para>Creates and returns a new buff applied to the owner of this AbilityInterface.</para>
        /// </summary>
        public NewBuff TryCreateBuff(BuffQueueInfo buffQueueInfo)
        {
            if (buffQueueInfo.BuffInfo == null)
            {
                Log.Error("TryCreateBuff", "NULL BUFFINFO");
                return(null);
            }

            #if DEBUG && ABILITY_DEVELOPMENT
            _Owner.Say("+++ " + buffQueueInfo.BuffInfo.Name + " (" + buffQueueInfo.BuffInfo.Type + ")");
            #endif

            // Cap the level of same-faction buffs
            if (buffQueueInfo.Caster.Realm == _unitOwner.Realm && (float)buffQueueInfo.Caster.EffectiveLevel / _unitOwner.EffectiveLevel > 1.3f)
            {
                buffQueueInfo.DesiredLevel = _unitOwner.EffectiveLevel;
            }

            Tuple <ushort, byte> buffSlotInfo = CanAcceptBuff(buffQueueInfo);

            if (buffSlotInfo == null || buffSlotInfo.Item1 == 32000)
            {
                return(null);
            }

            NewBuff myBuff = buffQueueInfo.BuffCreator == null ? new NewBuff() : buffQueueInfo.BuffCreator();

            if (myBuff != null)
            {
                myBuff.Initialize(buffQueueInfo.Caster, (Unit)_Owner, buffSlotInfo.Item1,
                                  buffQueueInfo.DesiredLevel, Math.Min(buffQueueInfo.BuffInfo.MaxStack, buffSlotInfo.Item2),
                                  buffQueueInfo.BuffInfo, this);

                if (myBuff.BuffGroup == BuffGroups.SelfClassBuff)
                {
                    _careerBuffs[0] = myBuff;
                }
                else if (myBuff.BuffGroup == BuffGroups.SelfClassSecondaryBuff)
                {
                    _careerBuffs[1] = myBuff;
                }
                else if (myBuff.BuffGroup == BuffGroups.Guard && _Owner != myBuff.Caster)
                {
                    myBuff.IsGroupBuff = true;
                    _backingGuardBuffs?.Add((GuardBuff)myBuff);
                    _guardsChanged = true;
                }
                else if (myBuff is AuraBuff && myBuff.Caster == _Owner)
                {
                    _auraCount++;
                }
            }

            return(myBuff);
        }
Esempio n. 2
0
        public void InsertUnstoppable(BuffQueueInfo bqi)
        {
            NewBuff buff = TryCreateBuff(bqi);

            if (buff != null)
            {
                _pendingBuffs.Add(buff);
                _filledSlots[buff.BuffId] = true;
            }

            buff?.StartBuff();
        }
Esempio n. 3
0
        public void QueueBuff(BuffQueueInfo queueInfo)
        {
            if (Stopping || (DetauntWard && queueInfo.BuffInfo.Group == BuffGroups.Detaunt))
            {
                return;
            }
            if (queueInfo.BuffInfo == null)
            {
                Log.Error("BuffInterface", "Attempt to queue a null Buff Info: " + queueInfo.BuffInfo); //Environment.StackTrace);
            }
            else
            {
                lock (_queuedInfo)
                    _queuedInfo.Add(queueInfo);
            }

            if (_unitOwner != null && _unitOwner.CbtInterface.IsInCombat)
            {
                queueInfo.Caster.CbtInterface.RefreshCombatTimer();
            }
        }
Esempio n. 4
0
        /// <summary>
        /// <para>Checks whether a buff can be added to the list.</para>
        /// <para>Handles buffs which are grouped (Blade Enchantments, etc) and multiple copies of buffs.</para>
        /// </summary>
        /// <returns>The slot into which a new buff could be inserted, or 255 if no such slot exists.</returns>
        private Tuple <ushort, byte> CanAcceptBuff(BuffQueueInfo newInfo)
        {
            NewBuff        existingBuff;
            List <NewBuff> existingBuffs;
            byte           desiredStackLevel = (byte)newInfo.BuffInfo.InitialStacks;

            switch (newInfo.BuffInfo.Group)
            {
                #region Guard
            case BuffGroups.Guard:
                existingBuffs = _pendingBuffs.FindAll(buff => buff.BuffGroup == newInfo.BuffInfo.Group);

                if (existingBuffs.Any(buff => buff.Caster == newInfo.Caster))
                {
                    return(null);
                }

                return(new Tuple <ushort, byte>(GetFreeSlot(), desiredStackLevel));

                #endregion
                #region Hold The Line
            case BuffGroups.HoldTheLine:
                existingBuffs = _pendingBuffs.FindAll(buff => buff.BuffGroup == newInfo.BuffInfo.Group);
                if (existingBuffs.Count >= 3)
                {
                    if (newInfo.Caster != _Owner)
                    {
                        return(null);
                    }

                    existingBuffs[0].BuffHasExpired = true;
                    ushort newSlot = existingBuffs[0].BuffId;
                    RemoveFromPending(existingBuffs[0]);
                    return(new Tuple <ushort, byte>(newSlot, desiredStackLevel));
                }

                if (existingBuffs.Any(buff => buff.Caster == newInfo.Caster))
                {
                    return(null);
                }

                return(new Tuple <ushort, byte>(GetFreeSlot(), desiredStackLevel));

                #endregion
                #region Oath Friend
            case BuffGroups.OathFriend:
                existingBuffs = _pendingBuffs.FindAll(buff => buff.BuffGroup == newInfo.BuffInfo.Group);
                if (existingBuffs.Count > 0)
                {
                    // Self component of Oath Friend. Remove any existing version
                    if (newInfo.Caster == _Owner)
                    {
                        foreach (NewBuff buff in existingBuffs)
                        {
                            if (buff.Caster != _Owner)
                            {
                                continue;
                            }

                            buff.BuffHasExpired = true;
                            ushort newSlot2 = buff.BuffId;
                            RemoveFromPending(buff);
                            return(new Tuple <ushort, byte>(newSlot2, desiredStackLevel));
                        }
                    }

                    else
                    {
                        foreach (NewBuff buff in existingBuffs)
                        {
                            // Look for and replace existing OF/DP from the caster
                            if (buff.Caster != newInfo.Caster)
                            {
                                continue;
                            }

                            buff.BuffHasExpired = true;
                            ushort newSlot2 = buff.BuffId;
                            RemoveFromPending(buff);
                            return(new Tuple <ushort, byte>(newSlot2, desiredStackLevel));
                        }
                    }
                }

                // Oath friend on enemy. Always apply.
                return(new Tuple <ushort, byte>(GetFreeSlot(), desiredStackLevel));

                #endregion
                #region Class self-buffs
            case BuffGroups.SelfClassBuff:
                existingBuff = _pendingBuffs.Find(buff => buff.BuffGroup == newInfo.BuffInfo.Group);
                if (existingBuff != null)
                {
                    if (existingBuff.Entry == newInfo.BuffInfo.Entry && !newInfo.BuffInfo.CanRefresh)
                    {
                        return(null);
                    }
                    ushort newSlot = existingBuff.BuffId;
                    RemoveFromPending(existingBuff);
                    return(new Tuple <ushort, byte>(newSlot, desiredStackLevel));
                }
                return(new Tuple <ushort, byte>(GetFreeSlot(), desiredStackLevel));

                #endregion
                #region Class buffs for others
            case BuffGroups.OtherClassBuff:
                existingBuffs = _pendingBuffs.FindAll(buff => buff.BuffGroup == newInfo.BuffInfo.Group);
                foreach (var buff in existingBuffs)
                {
                    if (buff.Entry == newInfo.BuffInfo.Entry)
                    {
                        if (buff.Caster != newInfo.Caster)
                        {
                            return(null);
                        }
                        //if (!newInfo.BuffInfo.CanRefresh)
                        //    return null;
                    }
                    if (buff.Caster == newInfo.Caster)
                    {
                        ushort newSlot = buff.BuffId;
                        RemoveFromPending(buff);
                        return(new Tuple <ushort, byte>(newSlot, desiredStackLevel));
                    }
                }
                return(new Tuple <ushort, byte>(GetFreeSlot(), desiredStackLevel));

                #endregion
                #region Auras

            case BuffGroups.Aura:
                existingBuff = _pendingBuffs.Find(buff => buff.Entry == newInfo.BuffInfo.Entry);
                if (existingBuff != null)
                {
                    // The owner's version of an aura must always persist over all others
                    if (existingBuff.Caster == _Owner)
                    {
                        return(null);
                    }

                    if (newInfo.Caster == _Owner)
                    {
                        ushort newSlot = existingBuff.BuffId;
                        RemoveFromPending(existingBuff);
                        return(new Tuple <ushort, byte>(newSlot, desiredStackLevel));
                    }

                    return(null);
                }
                return(new Tuple <ushort, byte>(GetFreeSlot(), desiredStackLevel));

                #endregion
                #region Potion Stat Buffs and other exclusives
            case BuffGroups.HealPotion:
            case BuffGroups.StatPotion:
            case BuffGroups.DefensePotion:
            case BuffGroups.SharedCooldown1:
            case BuffGroups.Vanity:
                existingBuff = _pendingBuffs.Find(buff => buff.BuffGroup == newInfo.BuffInfo.Group);
                if (existingBuff != null)
                {
                    RemoveFromPending(existingBuff);
                }
                return(new Tuple <ushort, byte>(GetFreeSlot(), desiredStackLevel));

                #endregion
                #region Resurrection
            case BuffGroups.Resurrection:
                existingBuff = _pendingBuffs.Find(buff => buff.BuffGroup == newInfo.BuffInfo.Group || buff.Entry == 1608 || buff.Entry == 8567);
                if (existingBuff == null)
                {
                    return(new Tuple <ushort, byte>(GetFreeSlot(), desiredStackLevel));
                }
                if (newInfo.DesiredLevel > existingBuff.BuffLevel)
                {
                    RemoveFromPending(existingBuff);
                    return(new Tuple <ushort, byte>(GetFreeSlot(), desiredStackLevel));
                }
                return(null);

                #endregion
                #region Other buffs
            default:
                if (newInfo.BuffInfo.MaxCopies == 0)
                {
                    existingBuff = _pendingBuffs.Find(buff => buff.Entry == newInfo.BuffInfo.Entry && buff.Caster == newInfo.Caster);
                    if (existingBuff == null || newInfo.BuffInfo.StacksFromCaster)
                    {
                        return(new Tuple <ushort, byte>(GetFreeSlot(), desiredStackLevel));
                    }
                    if (newInfo.BuffInfo.CanRefresh)
                    {
                        desiredStackLevel += existingBuff.StackLevel;
                        ushort newSlot = existingBuff.BuffId;
                        RemoveFromPending(existingBuff, true);
                        return(new Tuple <ushort, byte>(newSlot, desiredStackLevel));
                    }

                    return(null);
                }

                existingBuffs = _pendingBuffs.FindAll(buff => buff.Entry == newInfo.BuffInfo.Entry);

                if (existingBuffs.Count > 0)
                {
                    foreach (var buff in existingBuffs)
                    {
                        if (buff.Caster == newInfo.Caster || buff.BuffLevel < newInfo.DesiredLevel)
                        {
                            if (newInfo.BuffInfo.CanRefresh)
                            {
                                desiredStackLevel += buff.StackLevel;
                                ushort newSlot = buff.BuffId;
                                RemoveFromPending(buff, true);
                                return(new Tuple <ushort, byte>(newSlot, desiredStackLevel));
                            }
                        }
                    }

                    if (existingBuffs.Count >= newInfo.BuffInfo.MaxCopies)     // B.MaxCopies)
                    {
                        return(null);
                    }
                }

                return(new Tuple <ushort, byte>(GetFreeSlot(), desiredStackLevel));

                #endregion
            }
        }