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