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