Ejemplo n.º 1
0
        public uint ExtractSpellIdFromLink(StringArguments args)
        {
            // number or [name] Shift-click form |color|Henchant:recipe_spell_id|h[prof_name: recipe_name]|h|r
            // number or [name] Shift-click form |color|Hglyph:glyph_slot_id:glyph_prop_id|h[value]|h|r
            // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
            // number or [name] Shift-click form |color|Htalent:talent_id, rank|h[name]|h|r
            // number or [name] Shift-click form |color|Htrade:spell_id, skill_id, max_value, cur_value|h[name]|h|r
            string idS = ExtractKeyFromLink(args, spellKeys, out int type, out string param1Str);

            if (string.IsNullOrEmpty(idS))
            {
                return(0);
            }

            if (!uint.TryParse(idS, out uint id))
            {
                return(0);
            }

            switch (type)
            {
            case 0:
                return(id);

            case 1:
            {
                // talent
                TalentRecord talentEntry = CliDB.TalentStorage.LookupByKey(id);
                if (talentEntry == null)
                {
                    return(0);
                }

                return(talentEntry.SpellID);
            }

            case 2:
            case 3:
                return(id);

            case 4:
            {
                if (!uint.TryParse(param1Str, out uint glyph_prop_id))
                {
                    glyph_prop_id = 0;
                }

                GlyphPropertiesRecord glyphPropEntry = CliDB.GlyphPropertiesStorage.LookupByKey(glyph_prop_id);
                if (glyphPropEntry == null)
                {
                    return(0);
                }

                return(glyphPropEntry.SpellID);
            }
            }

            // unknown type?
            return(0);
        }
Ejemplo n.º 2
0
        public bool AddTalent(TalentRecord talent, byte spec, bool learning)
        {
            SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(talent.SpellID);

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

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

            if (talent.OverridesSpellID != 0)
            {
                AddOverrideSpell(talent.OverridesSpellID, talent.SpellID);
            }

            if (GetTalentMap(spec).ContainsKey(talent.Id))
            {
                GetTalentMap(spec)[talent.Id] = PlayerSpellState.Unchanged;
            }
            else
            {
                GetTalentMap(spec)[talent.Id] = learning ? PlayerSpellState.New : PlayerSpellState.Unchanged;
            }

            return(true);
        }
Ejemplo n.º 3
0
        public void RemoveTalent(TalentRecord talent)
        {
            SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(talent.SpellID);

            if (spellInfo == null)
            {
                return;
            }

            RemoveSpell(talent.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 (talent.OverridesSpellID != 0)
            {
                RemoveOverrideSpell(talent.OverridesSpellID, talent.SpellID);
            }

            var talentMap = GetTalentMap(GetActiveTalentGroup());

            // if this talent rank can be found in the PlayerTalentMap, mark the talent as removed so it gets deleted
            if (talentMap.ContainsKey(talent.Id))
            {
                talentMap[talent.Id] = PlayerSpellState.Removed;
            }
        }
Ejemplo n.º 4
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);


                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);
        }
Ejemplo n.º 5
0
        static bool TalentCheck(uint talent_id)
        {
            TalentRecord talentInfo = CliDB.TalentStorage.LookupByKey(talent_id);

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

            return(CliDB.ChrSpecializationStorage.ContainsKey(talentInfo.SpecID));
        }
Ejemplo n.º 6
0
        public bool StoreTo(out TalentRecord val, string arg)
        {
            val = default;

            HyperlinkDataTokenizer t = new(arg);

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

            val = CliDB.TalentStorage.LookupByKey(talentId);
            return(val != null);
        }
Ejemplo n.º 7
0
        public TalentLearnResult LearnTalent(uint talentId, ref int spellOnCooldown)
        {
            if (IsInCombat())
            {
                return(TalentLearnResult.FailedAffectingCombat);
            }

            if (IsDead() || GetMap().IsBattlegroundOrArena())
            {
                return(TalentLearnResult.FailedCantDoThatRightNow);
            }

            if (GetUInt32Value(PlayerFields.CurrentSpecId) == 0)
            {
                return(TalentLearnResult.FailedNoPrimaryTreeSelected);
            }

            TalentRecord talentInfo = CliDB.TalentStorage.LookupByKey(talentId);

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

            if (talentInfo.SpecID != 0 && talentInfo.SpecID != GetUInt32Value(PlayerFields.CurrentSpecId))
            {
                return(TalentLearnResult.FailedUnknown);
            }

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

            // check if we have enough talent points
            if (talentInfo.TierID >= GetUInt32Value(PlayerFields.MaxTalentTiers))
            {
                return(TalentLearnResult.FailedUnknown);
            }

            // TODO: prevent changing talents that are on cooldown

            // Check if there is a different talent for us to learn in selected slot
            // Example situation:
            // Warrior talent row 2 slot 0
            // Talent.dbc has an entry for each specialization
            // but only 2 out of 3 have SpecID != 0
            // We need to make sure that if player is in one of these defined specs he will not learn the other choice
            TalentRecord bestSlotMatch = null;

            foreach (TalentRecord talent in Global.DB2Mgr.GetTalentsByPosition(GetClass(), talentInfo.TierID, talentInfo.ColumnIndex))
            {
                if (talent.SpecID == 0)
                {
                    bestSlotMatch = talent;
                }
                else if (talent.SpecID == GetUInt32Value(PlayerFields.CurrentSpecId))
                {
                    bestSlotMatch = talent;
                    break;
                }
            }

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

            // Check if player doesn't have any talent in current tier
            for (uint c = 0; c < PlayerConst.MaxTalentColumns; ++c)
            {
                foreach (TalentRecord talent in Global.DB2Mgr.GetTalentsByPosition(GetClass(), talentInfo.TierID, c))
                {
                    //Todo test me
                    if (talent.SpecID != GetUInt32Value(PlayerFields.CurrentSpecId))
                    {
                        continue;
                    }

                    if (HasTalent(talent.Id, GetActiveTalentGroup()) && !HasFlag(PlayerFields.Flags, PlayerFlags.Resting) && HasFlag(UnitFields.Flags, UnitFlags.ImmuneToNpc))
                    {
                        return(TalentLearnResult.FailedRestArea);
                    }

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

                    RemoveTalent(talent);
                }
            }

            // spell not set in talent.dbc
            uint spellid = talentInfo.SpellID;

            if (spellid == 0)
            {
                Log.outError(LogFilter.Player, "Player.LearnTalent: Talent.dbc has no spellInfo for talent: {0} (spell id = 0)", talentId);
                return(TalentLearnResult.FailedUnknown);
            }

            // already known
            if (HasTalent(talentId, GetActiveTalentGroup()) || HasSpell(spellid))
            {
                return(TalentLearnResult.FailedUnknown);
            }

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

            LearnSpell(spellid, false);

            Log.outDebug(LogFilter.Misc, "Player.LearnTalent: TalentID: {0} Spell: {1} Group: {2}", talentId, spellid, GetActiveTalentGroup());

            return(TalentLearnResult.LearnOk);
        }
Ejemplo n.º 8
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);
        }