public void ResetTalentSpecialization()
        {
            // Reset only talents that have different spells for each spec
            Class class_ = GetClass();

            for (uint t = 0; t < PlayerConst.MaxTalentTiers; ++t)
            {
                for (uint c = 0; c < PlayerConst.MaxTalentColumns; ++c)
                {
                    if (Global.DB2Mgr.GetTalentsByPosition(class_, t, c).Count > 1)
                    {
                        foreach (TalentRecord talent in Global.DB2Mgr.GetTalentsByPosition(class_, t, c))
                        {
                            RemoveTalent(talent);
                        }
                    }
                }
            }

            RemoveSpecializationSpells();

            ChrSpecializationRecord defaultSpec = Global.DB2Mgr.GetDefaultChrSpecializationForClass(GetClass());

            SetPrimarySpecialization(defaultSpec.Id);
            SetActiveTalentGroup(defaultSpec.OrderIndex);
            SetUInt32Value(PlayerFields.CurrentSpecId, defaultSpec.Id);

            LearnSpecializationSpells();

            SendTalentsInfoData();
            UpdateItemSetAuras(false);
        }
        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);


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

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

            SendPacket(packet);
        }
Beispiel #3
0
 void HandleSetLootSpecialization(SetLootSpecialization packet)
 {
     if (packet.SpecID != 0)
     {
         ChrSpecializationRecord chrSpec = CliDB.ChrSpecializationStorage.LookupByKey(packet.SpecID);
         if (chrSpec != null)
         {
             if (chrSpec.ClassID == (uint)GetPlayer().GetClass())
             {
                 GetPlayer().SetLootSpecId(packet.SpecID);
             }
         }
     }
     else
     {
         GetPlayer().SetLootSpecId(0);
     }
 }
Beispiel #4
0
        public bool IsUsableByLootSpecialization(Player player, bool alwaysAllowBoundToAccount)
        {
            if (GetFlags().HasAnyFlag(ItemFlags.IsBoundToAccount) && alwaysAllowBoundToAccount)
            {
                return(true);
            }

            uint spec = player.GetUInt32Value(PlayerFields.LootSpecId);

            if (spec == 0)
            {
                spec = player.GetUInt32Value(PlayerFields.CurrentSpecId);
            }
            if (spec == 0)
            {
                spec = player.GetDefaultSpecId();
            }

            ChrSpecializationRecord chrSpecialization = CliDB.ChrSpecializationStorage.LookupByKey(spec);

            if (chrSpecialization == null)
            {
                return(false);
            }

            int levelIndex = 0;

            if (player.getLevel() >= 110)
            {
                levelIndex = 2;
            }
            else if (player.getLevel() > 40)
            {
                levelIndex = 1;
            }

            return(Specializations[levelIndex].Get(CalculateItemSpecBit(chrSpecialization)));
        }
Beispiel #5
0
 public static int CalculateItemSpecBit(ChrSpecializationRecord spec)
 {
     return((int)((spec.ClassID - 1) * PlayerConst.MaxSpecializations + spec.OrderIndex));
 }
        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();

            // 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);
                if (spellInfo == null)
                {
                    continue;
                }

                RemoveSpell(talentInfo.SpellID, true);

                // search for spells that the talent teaches and unlearn them
                foreach (SpellEffectInfo effect in spellInfo.GetEffectsForDifficulty(Difficulty.None))
                {
                    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);
            SetUInt32Value(PlayerFields.CurrentSpecId, spec.Id);
            if (GetPrimarySpecialization() == 0)
            {
                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.SpellID, GetActiveTalentGroup()))
                {
                    LearnSpell(talentInfo.SpellID, false);      // add the talent to the PlayerSpellMap
                    if (talentInfo.OverridesSpellID != 0)
                    {
                        AddOverrideSpell(talentInfo.OverridesSpellID, talentInfo.SpellID);
                    }
                }
            }

            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());
            _LoadActions(DB.Characters.Query(stmt));

            SendActionButtons(1);

            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);
        }
Beispiel #7
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);
        }
Beispiel #8
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);
            }
        }