예제 #1
0
        bool AddPvpTalent(PvpTalentRecord talent, byte activeTalentGroup, byte slot)
        {
            //ASSERT(talent);
            SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(talent.SpellID, Difficulty.None);

            if (spellInfo == null)
            {
                Log.outError(LogFilter.Spells, $"Player.AddPvpTalent: Spell (ID: {talent.SpellID}) does not exist.");
                return(false);
            }

            if (!Global.SpellMgr.IsSpellValid(spellInfo, this, false))
            {
                Log.outError(LogFilter.Spells, $"Player.AddPvpTalent: Spell (ID: {talent.SpellID}) is invalid");
                return(false);
            }

            if (HasPvpRulesEnabled())
            {
                LearnSpell(talent.SpellID, false);
            }

            // Move this to toggle ?
            if (talent.OverridesSpellID != 0)
            {
                AddOverrideSpell(talent.OverridesSpellID, talent.SpellID);
            }

            GetPvpTalentMap(activeTalentGroup)[slot] = talent.Id;

            return(true);
        }
예제 #2
0
        void RemovePvpTalent(PvpTalentRecord talent)
        {
            SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(talent.SpellID, Difficulty.None);

            if (spellInfo == null)
            {
                return;
            }

            RemoveSpell(talent.SpellID, true);

            // Move this to toggle ?
            if (talent.OverridesSpellID != 0)
            {
                RemoveOverrideSpell(talent.OverridesSpellID, talent.SpellID);
            }

            // if this talent rank can be found in the PlayerTalentMap, mark the talent as removed so it gets deleted
            var talents = GetPvpTalentMap(GetActiveTalentGroup());

            for (var i = 0; i < PlayerConst.MaxPvpTalentSlots; ++i)
            {
                if (talents[i] == talent.Id)
                {
                    talents[i] = 0;
                }
            }
        }
예제 #3
0
        public bool StoreTo(out PvpTalentRecord val, string arg)
        {
            val = default;

            HyperlinkDataTokenizer t = new(arg);

            if (!(t.TryConsumeTo(out uint pvpTalentId) && t.IsEmpty()))
            {
                return(false);
            }

            val = CliDB.PvpTalentStorage.LookupByKey(pvpTalentId);
            return(val != null);
        }
예제 #4
0
        public void TogglePvpTalents(bool enable)
        {
            var pvpTalents = GetPvpTalentMap(GetActiveTalentGroup());

            foreach (var pair in pvpTalents)
            {
                PvpTalentRecord pvpTalentInfo = CliDB.PvpTalentStorage.LookupByKey(pair.Key);
                if (enable && pair.Value != PlayerSpellState.Removed)
                {
                    LearnSpell(pvpTalentInfo.SpellID, false);
                }
                else
                {
                    RemoveSpell(pvpTalentInfo.SpellID, true);
                }
            }
        }
예제 #5
0
        public void TogglePvpTalents(bool enable)
        {
            var pvpTalents = GetPvpTalentMap(GetActiveTalentGroup());

            foreach (uint pvpTalentId in pvpTalents)
            {
                PvpTalentRecord pvpTalentInfo = CliDB.PvpTalentStorage.LookupByKey(pvpTalentId);
                if (pvpTalentInfo != null)
                {
                    if (enable)
                    {
                        LearnSpell(pvpTalentInfo.SpellID, false);
                    }
                    else
                    {
                        RemoveSpell(pvpTalentInfo.SpellID, true);
                    }
                }
            }
        }
예제 #6
0
        void RemovePvpTalent(PvpTalentRecord talent)
        {
            SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(talent.SpellID);

            if (spellInfo == null)
            {
                return;
            }

            RemoveSpell(talent.SpellID, true);

            // Move this to toggle ?
            if (talent.OverridesSpellID != 0)
            {
                RemoveOverrideSpell(talent.OverridesSpellID, talent.SpellID);
            }

            //todo check this
            // if this talent rank can be found in the PlayerTalentMap, mark the talent as removed so it gets deleted
            GetPvpTalentMap(GetActiveTalentGroup()).Remove(talent.Id);
        }
예제 #7
0
        bool AddPvpTalent(PvpTalentRecord talent, byte activeTalentGroup, bool learning)
        {
            //ASSERT(talent);
            SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(talent.SpellID);

            if (spellInfo == null)
            {
                Log.outError(LogFilter.Spells, $"Player.AddPvpTalent: Spell (ID: {talent.SpellID}) does not exist.");
                return(false);
            }

            if (!Global.SpellMgr.IsSpellValid(spellInfo, this, false))
            {
                Log.outError(LogFilter.Spells, $"Player.AddPvpTalent: Spell (ID: {talent.SpellID}) is invalid");
                return(false);
            }

            if (HasPvpRulesEnabled())
            {
                LearnSpell(talent.SpellID, false);
            }

            // Move this to toggle ?
            if (talent.OverridesSpellID != 0)
            {
                AddOverrideSpell(talent.OverridesSpellID, talent.SpellID);
            }

            if (learning)
            {
                GetPvpTalentMap(activeTalentGroup)[talent.Id] = PlayerSpellState.New;
            }
            else
            {
                GetPvpTalentMap(activeTalentGroup)[talent.Id] = PlayerSpellState.Unchanged;
            }

            return(true);
        }
예제 #8
0
        public TalentLearnResult LearnPvpTalent(uint talentID, byte slot, ref uint spellOnCooldown)
        {
            if (slot >= PlayerConst.MaxPvpTalentSlots)
            {
                return(TalentLearnResult.FailedUnknown);
            }

            if (IsInCombat())
            {
                return(TalentLearnResult.FailedAffectingCombat);
            }

            if (IsDead())
            {
                return(TalentLearnResult.FailedCantDoThatRightNow);
            }

            PvpTalentRecord talentInfo = CliDB.PvpTalentStorage.LookupByKey(talentID);

            if (talentInfo == null)
            {
                return(TalentLearnResult.FailedUnknown);
            }

            if (talentInfo.SpecID != GetPrimarySpecialization())
            {
                return(TalentLearnResult.FailedUnknown);
            }

            if (talentInfo.LevelRequired > GetLevel())
            {
                return(TalentLearnResult.FailedUnknown);
            }

            if (Global.DB2Mgr.GetRequiredLevelForPvpTalentSlot(slot, GetClass()) > GetLevel())
            {
                return(TalentLearnResult.FailedUnknown);
            }

            PvpTalentCategoryRecord talentCategory = CliDB.PvpTalentCategoryStorage.LookupByKey(talentInfo.PvpTalentCategoryID);

            if (talentCategory != null)
            {
                if (!Convert.ToBoolean(talentCategory.TalentSlotMask & (1 << slot)))
                {
                    return(TalentLearnResult.FailedUnknown);
                }
            }

            // Check if player doesn't have this talent in other slot
            if (HasPvpTalent(talentID, GetActiveTalentGroup()))
            {
                return(TalentLearnResult.FailedUnknown);
            }

            PvpTalentRecord talent = CliDB.PvpTalentStorage.LookupByKey(GetPvpTalentMap(GetActiveTalentGroup())[slot]);

            if (talent != null)
            {
                if (!HasPlayerFlag(PlayerFlags.Resting) && !HasUnitFlag2(UnitFlags2.AllowChangingTalents))
                {
                    return(TalentLearnResult.FailedRestArea);
                }

                if (GetSpellHistory().HasCooldown(talent.SpellID))
                {
                    spellOnCooldown = talent.SpellID;
                    return(TalentLearnResult.FailedCantRemoveTalent);
                }

                RemovePvpTalent(talent);
            }

            if (!AddPvpTalent(talentInfo, GetActiveTalentGroup(), slot))
            {
                return(TalentLearnResult.FailedUnknown);
            }

            return(TalentLearnResult.LearnOk);
        }
예제 #9
0
        public void SendTalentsInfoData()
        {
            UpdateTalentData packet = new UpdateTalentData();

            packet.Info.PrimarySpecialization = GetPrimarySpecialization();

            for (byte i = 0; i < PlayerConst.MaxSpecializations; ++i)
            {
                ChrSpecializationRecord spec = Global.DB2Mgr.GetChrSpecializationByIndex(GetClass(), i);
                if (spec == null)
                {
                    continue;
                }

                var talents    = GetTalentMap(i);
                var pvpTalents = GetPvpTalentMap(i);

                UpdateTalentData.TalentGroupInfo groupInfoPkt = new UpdateTalentData.TalentGroupInfo();
                groupInfoPkt.SpecID = spec.Id;

                foreach (var pair in talents)
                {
                    if (pair.Value == PlayerSpellState.Removed)
                    {
                        continue;
                    }

                    TalentRecord talentInfo = CliDB.TalentStorage.LookupByKey(pair.Key);
                    if (talentInfo == null)
                    {
                        Log.outError(LogFilter.Player, "Player {0} has unknown talent id: {1}", GetName(), pair.Key);
                        continue;
                    }

                    SpellInfo spellEntry = Global.SpellMgr.GetSpellInfo(talentInfo.SpellID, Difficulty.None);
                    if (spellEntry == null)
                    {
                        Log.outError(LogFilter.Player, "Player {0} has unknown talent spell: {1}", GetName(), talentInfo.SpellID);
                        continue;
                    }

                    groupInfoPkt.TalentIDs.Add((ushort)pair.Key);
                }

                for (byte slot = 0; slot < PlayerConst.MaxPvpTalentSlots; ++slot)
                {
                    if (pvpTalents[slot] == 0)
                    {
                        continue;
                    }

                    PvpTalentRecord talentInfo = CliDB.PvpTalentStorage.LookupByKey(pvpTalents[slot]);
                    if (talentInfo == null)
                    {
                        Log.outError(LogFilter.Player, $"Player.SendTalentsInfoData: Player '{GetName()}' ({GetGUID()}) has unknown pvp talent id: {pvpTalents[slot]}");
                        continue;
                    }

                    SpellInfo spellEntry = Global.SpellMgr.GetSpellInfo(talentInfo.SpellID, Difficulty.None);
                    if (spellEntry == null)
                    {
                        Log.outError(LogFilter.Player, $"Player.SendTalentsInfoData: Player '{GetName()}' ({GetGUID()}) has unknown pvp talent spell: {talentInfo.SpellID}");
                        continue;
                    }

                    PvPTalent pvpTalent = new PvPTalent();
                    pvpTalent.PvPTalentID = (ushort)pvpTalents[slot];
                    pvpTalent.Slot        = slot;
                    groupInfoPkt.PvPTalents.Add(pvpTalent);
                }

                if (i == GetActiveTalentGroup())
                {
                    packet.Info.ActiveGroup = (byte)packet.Info.TalentGroups.Count;
                }

                if (!groupInfoPkt.TalentIDs.Empty() || !groupInfoPkt.PvPTalents.Empty() || i == GetActiveTalentGroup())
                {
                    packet.Info.TalentGroups.Add(groupInfoPkt);
                }
            }

            SendPacket(packet);
        }
예제 #10
0
        public void ActivateTalentGroup(ChrSpecializationRecord spec)
        {
            if (GetActiveTalentGroup() == spec.OrderIndex)
            {
                return;
            }

            if (IsNonMeleeSpellCast(false))
            {
                InterruptNonMeleeSpells(false);
            }

            SQLTransaction trans = new SQLTransaction();

            _SaveActions(trans);
            DB.Characters.CommitTransaction(trans);

            // TO-DO: We need more research to know what happens with warlock's reagent
            Pet pet = GetPet();

            if (pet)
            {
                RemovePet(pet, PetSaveMode.NotInSlot);
            }

            ClearAllReactives();
            UnsummonAllTotems();
            ExitVehicle();
            RemoveAllControlled();

            // remove single target auras at other targets
            var scAuras = GetSingleCastAuras();

            foreach (var aura in scAuras)
            {
                if (aura.GetUnitOwner() != this)
                {
                    aura.Remove();
                }
            }

            // Let client clear his current Actions
            SendActionButtons(2);
            foreach (var talentInfo in CliDB.TalentStorage.Values)
            {
                // unlearn only talents for character class
                // some spell learned by one class as normal spells or know at creation but another class learn it as talent,
                // to prevent unexpected lost normal learned spell skip another class talents
                if (talentInfo.ClassID != (int)GetClass())
                {
                    continue;
                }

                if (talentInfo.SpellID == 0)
                {
                    continue;
                }

                SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(talentInfo.SpellID, Difficulty.None);
                if (spellInfo == null)
                {
                    continue;
                }

                RemoveSpell(talentInfo.SpellID, true);

                // search for spells that the talent teaches and unlearn them
                foreach (SpellEffectInfo effect in spellInfo.GetEffects())
                {
                    if (effect != null && effect.TriggerSpell > 0 && effect.Effect == SpellEffectName.LearnSpell)
                    {
                        RemoveSpell(effect.TriggerSpell, true);
                    }
                }

                if (talentInfo.OverridesSpellID != 0)
                {
                    RemoveOverrideSpell(talentInfo.OverridesSpellID, talentInfo.SpellID);
                }
            }

            foreach (var talentInfo in CliDB.PvpTalentStorage.Values)
            {
                SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(talentInfo.SpellID, Difficulty.None);
                if (spellInfo == null)
                {
                    continue;
                }

                RemoveSpell(talentInfo.SpellID, true);

                // search for spells that the talent teaches and unlearn them
                foreach (SpellEffectInfo effect in spellInfo.GetEffects())
                {
                    if (effect != null && effect.TriggerSpell > 0 && effect.Effect == SpellEffectName.LearnSpell)
                    {
                        RemoveSpell(effect.TriggerSpell, true);
                    }
                }

                if (talentInfo.OverridesSpellID != 0)
                {
                    RemoveOverrideSpell(talentInfo.OverridesSpellID, talentInfo.SpellID);
                }
            }

            // Remove spec specific spells
            RemoveSpecializationSpells();

            foreach (uint glyphId in GetGlyphs(GetActiveTalentGroup()))
            {
                RemoveAurasDueToSpell(CliDB.GlyphPropertiesStorage.LookupByKey(glyphId).SpellID);
            }

            SetActiveTalentGroup(spec.OrderIndex);
            SetPrimarySpecialization(spec.Id);

            foreach (var talentInfo in CliDB.TalentStorage.Values)
            {
                // learn only talents for character class
                if (talentInfo.ClassID != (int)GetClass())
                {
                    continue;
                }

                if (talentInfo.SpellID == 0)
                {
                    continue;
                }

                if (HasTalent(talentInfo.Id, GetActiveTalentGroup()))
                {
                    LearnSpell(talentInfo.SpellID, false);      // add the talent to the PlayerSpellMap
                    if (talentInfo.OverridesSpellID != 0)
                    {
                        AddOverrideSpell(talentInfo.OverridesSpellID, talentInfo.SpellID);
                    }
                }
            }

            for (byte slot = 0; slot < PlayerConst.MaxPvpTalentSlots; ++slot)
            {
                PvpTalentRecord talentInfo = CliDB.PvpTalentStorage.LookupByKey(GetPvpTalentMap(GetActiveTalentGroup())[slot]);
                if (talentInfo == null)
                {
                    continue;
                }

                if (talentInfo.SpellID == 0)
                {
                    continue;
                }

                AddPvpTalent(talentInfo, GetActiveTalentGroup(), slot);
            }

            LearnSpecializationSpells();

            if (CanUseMastery())
            {
                for (uint i = 0; i < PlayerConst.MaxMasterySpells; ++i)
                {
                    uint mastery = spec.MasterySpellID[i];
                    if (mastery != 0)
                    {
                        LearnSpell(mastery, false);
                    }
                }
            }

            InitTalentForLevel();

            PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_CHARACTER_ACTIONS_SPEC);

            stmt.AddValue(0, GetGUID().GetCounter());
            stmt.AddValue(1, GetActiveTalentGroup());

            WorldSession mySess = GetSession();

            mySess.GetQueryProcessor().AddCallback(DB.Characters.AsyncQuery(stmt).WithCallback(result =>
            {
                // in case player logs out before db response (player would be deleted in that case)
                Player thisPlayer = mySess.GetPlayer();
                if (thisPlayer != null)
                {
                    thisPlayer.LoadActions(result);
                }
            }));

            UpdateDisplayPower();
            PowerType pw = GetPowerType();

            if (pw != PowerType.Mana)
            {
                SetPower(PowerType.Mana, 0); // Mana must be 0 even if it isn't the active power type.
            }
            SetPower(pw, 0);
            UpdateItemSetAuras(false);

            // update visible transmog
            for (byte i = EquipmentSlot.Start; i < EquipmentSlot.End; ++i)
            {
                Item equippedItem = GetItemByPos(InventorySlots.Bag0, i);
                if (equippedItem)
                {
                    SetVisibleItemSlot(i, equippedItem);
                }
            }

            foreach (uint glyphId in GetGlyphs(spec.OrderIndex))
            {
                CastSpell(this, CliDB.GlyphPropertiesStorage.LookupByKey(glyphId).SpellID, true);
            }

            ActiveGlyphs activeGlyphs = new ActiveGlyphs();

            foreach (uint glyphId in GetGlyphs(spec.OrderIndex))
            {
                List <uint> bindableSpells = Global.DB2Mgr.GetGlyphBindableSpells(glyphId);
                foreach (uint bindableSpell in bindableSpells)
                {
                    if (HasSpell(bindableSpell) && !m_overrideSpells.ContainsKey(bindableSpell))
                    {
                        activeGlyphs.Glyphs.Add(new GlyphBinding(bindableSpell, (ushort)glyphId));
                    }
                }
            }

            activeGlyphs.IsFullUpdate = true;
            SendPacket(activeGlyphs);

            Item item = GetItemByEntry(PlayerConst.ItemIdHeartOfAzeroth, ItemSearchLocation.Everywhere);

            if (item != null)
            {
                AzeriteItem azeriteItem = item.ToAzeriteItem();
                if (azeriteItem != null)
                {
                    if (azeriteItem.IsEquipped())
                    {
                        ApplyAllAzeriteEmpoweredItemMods(false);
                        ApplyAzeritePowers(azeriteItem, false);
                    }

                    azeriteItem.SetSelectedAzeriteEssences(spec.Id);

                    if (azeriteItem.IsEquipped())
                    {
                        ApplyAzeritePowers(azeriteItem, true);
                        ApplyAllAzeriteEmpoweredItemMods(true);
                    }

                    azeriteItem.SetState(ItemUpdateState.Changed, this);
                }
            }

            var shapeshiftAuras = GetAuraEffectsByType(AuraType.ModShapeshift);

            foreach (AuraEffect aurEff in shapeshiftAuras)
            {
                aurEff.HandleShapeshiftBoosts(this, false);
                aurEff.HandleShapeshiftBoosts(this, true);
            }
        }
예제 #11
0
        public TalentLearnResult LearnPvpTalent(uint talentID, ref uint spellOnCooldown)
        {
            if (IsInCombat())
            {
                return(TalentLearnResult.FailedAffectingCombat);
            }

            if (getLevel() < PlayerConst.LevelMinHonor)
            {
                return(TalentLearnResult.FailedUnknown);
            }

            PvpTalentRecord talentInfo = CliDB.PvpTalentStorage.LookupByKey(talentID);

            if (talentInfo == null)
            {
                return(TalentLearnResult.FailedUnknown);
            }

            if (talentInfo.SpecID != 0)
            {
                if (talentInfo.SpecID != GetInt32Value(PlayerFields.CurrentSpecId))
                {
                    return(TalentLearnResult.FailedUnknown);
                }
            }
            else if (talentInfo.Role < 7)
            {
                if (talentInfo.Role != CliDB.ChrSpecializationStorage.LookupByKey(GetUInt32Value(PlayerFields.CurrentSpecId)).Role)
                {
                    return(TalentLearnResult.FailedUnknown);
                }
            }

            // prevent learn talent for different class (cheating)
            if (talentInfo.ClassID != 0 && talentInfo.ClassID != (int)GetClass())
            {
                return(TalentLearnResult.FailedUnknown);
            }

            if (GetPrestigeLevel() == 0)
            {
                if (Global.DB2Mgr.GetRequiredHonorLevelForPvpTalent(talentInfo) > GetHonorLevel())
                {
                    return(TalentLearnResult.FailedUnknown);
                }
            }

            // Check if player doesn't have any talent in current tier
            for (uint c = 0; c < PlayerConst.MaxPvpTalentColumns; ++c)
            {
                foreach (PvpTalentRecord talent in Global.DB2Mgr.GetPvpTalentsByPosition((uint)GetClass(), (uint)talentInfo.TierID, c))
                {
                    if (HasPvpTalent(talent.Id, GetActiveTalentGroup()) && !HasFlag(PlayerFields.Flags, PlayerFlags.Resting) && HasFlag(UnitFields.Flags, UnitFlags.ImmuneToNpc))
                    {
                        return(TalentLearnResult.FailedRestArea);
                    }

                    if (GetSpellHistory().HasCooldown(talent.SpellID))
                    {
                        spellOnCooldown = talent.SpellID;
                        return(TalentLearnResult.FailedCantRemoveTalent);
                    }

                    RemovePvpTalent(talent);
                }
            }

            if (!AddPvpTalent(talentInfo, GetActiveTalentGroup(), true))
            {
                return(TalentLearnResult.FailedUnknown);
            }

            return(TalentLearnResult.LearnOk);
        }
예제 #12
0
        public void SendTalentsInfoData()
        {
            UpdateTalentData packet = new UpdateTalentData();

            packet.Info.PrimarySpecialization = GetPrimarySpecialization();
            packet.Info.ActiveGroup           = GetActiveTalentGroup();

            for (byte i = 0; i < PlayerConst.MaxSpecializations; ++i)
            {
                ChrSpecializationRecord spec = Global.DB2Mgr.GetChrSpecializationByIndex(GetClass(), i);
                if (spec == null)
                {
                    continue;
                }

                var talents    = GetTalentMap(i);
                var pvpTalents = GetPvpTalentMap(i);

                UpdateTalentData.TalentGroupInfo groupInfoPkt = new UpdateTalentData.TalentGroupInfo();
                groupInfoPkt.SpecID = spec.Id;

                foreach (var pair in talents)
                {
                    if (pair.Value == PlayerSpellState.Removed)
                    {
                        continue;
                    }

                    TalentRecord talentInfo = CliDB.TalentStorage.LookupByKey(pair.Key);
                    if (talentInfo == null)
                    {
                        Log.outError(LogFilter.Player, "Player {0} has unknown talent id: {1}", GetName(), pair.Key);
                        continue;
                    }

                    if (talentInfo.ClassID != (uint)GetClass())
                    {
                        continue;
                    }

                    SpellInfo spellEntry = Global.SpellMgr.GetSpellInfo(talentInfo.SpellID);
                    if (spellEntry == null)
                    {
                        Log.outError(LogFilter.Player, "Player {0} has unknown talent spell: {1}", GetName(), talentInfo.SpellID);
                        continue;
                    }

                    groupInfoPkt.TalentIDs.Add((ushort)pair.Key);
                }

                foreach (var pair in pvpTalents)
                {
                    if (pair.Value == PlayerSpellState.Removed)
                    {
                        continue;
                    }

                    PvpTalentRecord talentInfo = CliDB.PvpTalentStorage.LookupByKey(pair.Key);
                    if (talentInfo == null)
                    {
                        Log.outError(LogFilter.Player, $"Player.SendTalentsInfoData: Player '{GetName()}' ({GetGUID().ToString()}) has unknown pvp talent id: {pair.Key}");
                        continue;
                    }

                    if (talentInfo.ClassID != 0 && talentInfo.ClassID != (int)GetClass())
                    {
                        continue;
                    }

                    SpellInfo spellEntry = Global.SpellMgr.GetSpellInfo(talentInfo.SpellID);
                    if (spellEntry == null)
                    {
                        Log.outError(LogFilter.Player, $"Player.SendTalentsInfoData: Player '{GetName()}' ({GetGUID().ToString()}) has unknown pvp talent spell: {talentInfo.SpellID}");
                        continue;
                    }

                    groupInfoPkt.PvPTalentIDs.Add((ushort)pair.Key);
                }

                packet.Info.TalentGroups.Add(groupInfoPkt);
            }

            SendPacket(packet);
        }