Example #1
0
        public void RestoreCooldownStateAfterDuel()
        {
            Player player = _owner.ToPlayer();

            if (player)
            {
                // add all profession CDs created while in duel (if any)
                foreach (var c in _spellCooldowns)
                {
                    SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(c.Key);

                    if (spellInfo.RecoveryTime > 10 * Time.Minute * Time.InMilliseconds || spellInfo.CategoryRecoveryTime > 10 * Time.Minute * Time.InMilliseconds)
                    {
                        _spellCooldownsBeforeDuel[c.Key] = _spellCooldowns[c.Key];
                    }
                }

                // check for spell with onHold active before and during the duel
                foreach (var pair in _spellCooldownsBeforeDuel)
                {
                    if (!pair.Value.OnHold && _spellCooldowns.ContainsKey(pair.Key) && !_spellCooldowns[pair.Key].OnHold)
                    {
                        _spellCooldowns[pair.Key] = _spellCooldownsBeforeDuel[pair.Key];
                    }
                }

                // update the client: restore old cooldowns
                SpellCooldownPkt spellCooldown = new SpellCooldownPkt();
                spellCooldown.Caster = _owner.GetGUID();
                spellCooldown.Flags  = SpellCooldownFlags.IncludeEventCooldowns;

                foreach (var c in _spellCooldowns)
                {
                    DateTime now = DateTime.Now;
                    uint     cooldownDuration = c.Value.CooldownEnd > now ? (uint)(c.Value.CooldownEnd - now).TotalMilliseconds : 0;

                    // cooldownDuration must be between 0 and 10 minutes in order to avoid any visual bugs
                    if (cooldownDuration <= 0 || cooldownDuration > 10 * Time.Minute * Time.InMilliseconds || c.Value.OnHold)
                    {
                        continue;
                    }

                    spellCooldown.SpellCooldowns.Add(new SpellCooldownStruct(c.Key, cooldownDuration));
                }

                player.SendPacket(spellCooldown);
            }
        }
Example #2
0
        public void LockSpellSchool(SpellSchoolMask schoolMask, uint lockoutTime)
        {
            DateTime now        = DateTime.Now;
            DateTime lockoutEnd = now + TimeSpan.FromMilliseconds(lockoutTime);

            for (int i = 0; i < (int)SpellSchools.Max; ++i)
            {
                if (Convert.ToBoolean((SpellSchoolMask)(1 << i) & schoolMask))
                {
                    _schoolLockouts[i] = lockoutEnd;
                }
            }

            List <uint> knownSpells = new List <uint>();
            Player      plrOwner    = _owner.ToPlayer();

            if (plrOwner)
            {
                foreach (var p in plrOwner.GetSpellMap())
                {
                    if (p.Value.State != PlayerSpellState.Removed)
                    {
                        knownSpells.Add(p.Key);
                    }
                }
            }
            else if (_owner.IsPet())
            {
                Pet petOwner = _owner.ToPet();
                foreach (var p in petOwner.m_spells)
                {
                    if (p.Value.state != PetSpellState.Removed)
                    {
                        knownSpells.Add(p.Key);
                    }
                }
            }
            else
            {
                Creature creatureOwner = _owner.ToCreature();
                for (byte i = 0; i < SharedConst.MaxCreatureSpells; ++i)
                {
                    if (creatureOwner.m_spells[i] != 0)
                    {
                        knownSpells.Add(creatureOwner.m_spells[i]);
                    }
                }
            }

            SpellCooldownPkt spellCooldown = new SpellCooldownPkt();

            spellCooldown.Caster = _owner.GetGUID();
            spellCooldown.Flags  = SpellCooldownFlags.None;
            foreach (uint spellId in knownSpells)
            {
                SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId);
                if (spellInfo.IsCooldownStartedOnEvent())
                {
                    continue;
                }

                if (!spellInfo.PreventionType.HasAnyFlag(SpellPreventionType.Silence))
                {
                    continue;
                }

                if (Convert.ToBoolean(schoolMask & spellInfo.GetSchoolMask()) && GetRemainingCooldown(spellInfo) < lockoutTime)
                {
                    spellCooldown.SpellCooldowns.Add(new SpellCooldownStruct(spellId, lockoutTime));
                    AddCooldown(spellId, 0, lockoutEnd, 0, now);
                }
            }

            Player player = GetPlayerOwner();

            if (player)
            {
                if (!spellCooldown.SpellCooldowns.Empty())
                {
                    player.SendPacket(spellCooldown);
                }
            }
        }
Example #3
0
        public void StartCooldown(SpellInfo spellInfo, uint itemId, Spell spell = null, bool onHold = false)
        {
            // init cooldown values
            uint categoryId       = 0;
            int  cooldown         = -1;
            int  categoryCooldown = -1;

            GetCooldownDurations(spellInfo, itemId, ref cooldown, ref categoryId, ref categoryCooldown);

            DateTime curTime = DateTime.Now;
            DateTime catrecTime;
            DateTime recTime;
            bool     needsCooldownPacket = false;

            // overwrite time for selected category
            if (onHold)
            {
                // use +MONTH as infinite cooldown marker
                catrecTime = categoryCooldown > 0 ? (curTime + PlayerConst.InfinityCooldownDelay) : curTime;
                recTime    = cooldown > 0 ? (curTime + PlayerConst.InfinityCooldownDelay) : catrecTime;
            }
            else
            {
                // shoot spells used equipped item cooldown values already assigned in GetAttackTime(RANGED_ATTACK)
                // prevent 0 cooldowns set by another way
                if (cooldown <= 0 && categoryCooldown <= 0 && (categoryId == 76 || (spellInfo.IsAutoRepeatRangedSpell() && spellInfo.Id != 75)))
                {
                    cooldown = (int)_owner.GetUInt32Value(UnitFields.RangedAttackTime);
                }

                // Now we have cooldown data (if found any), time to apply mods
                Player modOwner = _owner.GetSpellModOwner();
                if (modOwner)
                {
                    if (cooldown > 0)
                    {
                        modOwner.ApplySpellMod(spellInfo.Id, SpellModOp.Cooldown, ref cooldown, spell);
                    }

                    if (categoryCooldown > 0 && !spellInfo.HasAttribute(SpellAttr6.IgnoreCategoryCooldownMods))
                    {
                        modOwner.ApplySpellMod(spellInfo.Id, SpellModOp.Cooldown, ref categoryCooldown, spell);
                    }
                }

                if (_owner.HasAuraTypeWithAffectMask(AuraType.ModSpellCooldownByHaste, spellInfo))
                {
                    cooldown         = (int)(cooldown * _owner.GetFloatValue(UnitFields.ModCastHaste));
                    categoryCooldown = (int)(categoryCooldown * _owner.GetFloatValue(UnitFields.ModCastHaste));
                }

                if (_owner.HasAuraTypeWithAffectMask(AuraType.ModCooldownByHasteRegen, spellInfo))
                {
                    cooldown         = (int)(cooldown * _owner.GetFloatValue(UnitFields.ModHasteRegen));
                    categoryCooldown = (int)(categoryCooldown * _owner.GetFloatValue(UnitFields.ModHasteRegen));
                }

                int cooldownMod = _owner.GetTotalAuraModifier(AuraType.ModCooldown);
                if (cooldownMod != 0)
                {
                    // Apply SPELL_AURA_MOD_COOLDOWN only to own spells
                    Player playerOwner = GetPlayerOwner();
                    if (!playerOwner || playerOwner.HasSpell(spellInfo.Id))
                    {
                        needsCooldownPacket = true;
                        cooldown           += cooldownMod * Time.InMilliseconds; // SPELL_AURA_MOD_COOLDOWN does not affect category cooldows, verified with shaman shocks
                    }
                }

                // Apply SPELL_AURA_MOD_SPELL_CATEGORY_COOLDOWN modifiers
                // Note: This aura applies its modifiers to all cooldowns of spells with set category, not to category cooldown only
                if (categoryId != 0)
                {
                    int categoryModifier = _owner.GetTotalAuraModifierByMiscValue(AuraType.ModSpellCategoryCooldown, (int)categoryId);
                    if (categoryModifier != 0)
                    {
                        if (cooldown > 0)
                        {
                            cooldown += categoryModifier;
                        }

                        if (categoryCooldown > 0)
                        {
                            categoryCooldown += categoryModifier;
                        }
                    }

                    SpellCategoryRecord categoryEntry = CliDB.SpellCategoryStorage.LookupByKey(categoryId);
                    if (categoryEntry.Flags.HasAnyFlag(SpellCategoryFlags.CooldownExpiresAtDailyReset))
                    {
                        categoryCooldown = (int)(Time.UnixTimeToDateTime(Global.WorldMgr.GetNextDailyQuestsResetTime()) - DateTime.Now).TotalMilliseconds;
                    }
                }

                // replace negative cooldowns by 0
                if (cooldown < 0)
                {
                    cooldown = 0;
                }

                if (categoryCooldown < 0)
                {
                    categoryCooldown = 0;
                }

                // no cooldown after applying spell mods
                if (cooldown == 0 && categoryCooldown == 0)
                {
                    return;
                }

                catrecTime = categoryCooldown != 0 ? curTime + TimeSpan.FromMilliseconds(categoryCooldown) : curTime;
                recTime    = cooldown != 0 ? curTime + TimeSpan.FromMilliseconds(cooldown) : catrecTime;
            }

            // self spell cooldown
            if (recTime != curTime)
            {
                AddCooldown(spellInfo.Id, itemId, recTime, categoryId, catrecTime, onHold);

                if (needsCooldownPacket)
                {
                    Player playerOwner = GetPlayerOwner();
                    if (playerOwner)
                    {
                        SpellCooldownPkt spellCooldown = new SpellCooldownPkt();
                        spellCooldown.Caster = _owner.GetGUID();
                        spellCooldown.Flags  = SpellCooldownFlags.None;
                        spellCooldown.SpellCooldowns.Add(new SpellCooldownStruct(spellInfo.Id, (uint)cooldown));
                        playerOwner.SendPacket(spellCooldown);
                    }
                }
            }
        }