Untitled

Item
 avatar
unknown
csharp
2 months ago
8.6 kB
8
Indexable
using COServer.Client;
using COServer.Database;
using COServer.Game.MsgServer;
using System.Collections.Frozen;
using System.Collections.Generic;

namespace COServer.Game.Items
{
    public static class SkillBookRegistry
    {
        private enum ClassReq : byte { None, Fire, Water, FireOrWater }

        private struct SkillBookEntry
        {
            public ushort SpellID;
            public ushort MinLevel;
            public ushort MinSpirit;
            public ClassReq ClassCheck;
            public ushort WeaponType;   // 0 = no prof check
            public byte ProfLevel;
            public string FailMessage;
            public string ProfFailMessage;
        }

        private static FrozenDictionary<uint, SkillBookEntry> _books;
        private static readonly Dictionary<uint, SkillBookEntry> _booksB = new();

        static SkillBookRegistry()
        {
            // Dance Books
            RegisterSimple(725018, 1380);
            RegisterSimple(725019, 1385);
            RegisterSimple(725020, 1390);
            RegisterSimple(725021, 1395);
            RegisterSimple(725022, 1400);
            RegisterSimple(725023, 1405);
            RegisterSimple(725024, 1410);

            // Magic Skills 
            RegisterSimple(725000, 1000, spirit: 20, failMsg: "You need at least 20 Spirit to learn this spell.");
            RegisterSimple(725001, 1001, level: 40, spirit: 80, failMsg: "You must be level 40+ with at least 80 Spirit to learn this spell.");
            RegisterSimple(725003, 1005, spirit: 30, failMsg: "You need at least 30 Spirit to learn this spell.");
            RegisterSimple(725004, 1010, spirit: 25, failMsg: "You need at least 25 Spirit to learn this spell.");

            // Magic Skills — Class-restricted
            RegisterClass(725002, 1002, level: 90, spirit: 160, classCheck: ClassReq.Fire,
                failMsg: "You must be a Fire Taoist level 90+ with at least 160 Spirit to learn this spell.");
            RegisterClass(725028, 5001, level: 70, classCheck: ClassReq.FireOrWater,
                failMsg: "Only Fire or Water Taoists can learn this spell.");
            RegisterClass(1060100, 1160, level: 80, classCheck: ClassReq.Fire,
                failMsg: "You must be Fire and level 80+ to learn this skill.");
            RegisterClass(1060101, 1165, level: 82, classCheck: ClassReq.Fire,
                failMsg: "You must be Fire and level 82+ to learn this skill.");
            RegisterClass(725015, 1350, level: 54, classCheck: ClassReq.Water,
                failMsg: "You must be Water and level 54+ to learn this skill.");

            // Linear Skills — Proficiency-restricted
            RegisterProf(725005, 1045, level: 40,
                weaponType: (ushort)MagicType.WeaponsType.Blade, profLevel: 5,
                failMsg: "You must be level 40+ to learn this skill.",
                profFailMsg: "Sorry,~you~cannot~learn~this~skill~before~you~practice~your~blade~to~level~5.~Please~train~harder.");
            RegisterProf(725010, 1046, level: 40,
                weaponType: (ushort)MagicType.WeaponsType.Sword, profLevel: 5,
                failMsg: "You must be level 40+ to learn this skill.",
                profFailMsg: "Sorry,~you~cannot~learn~this~skill~before~you~practice~your~sword~to~level~5.~Please~train~harder.");

            // Linear Skills — Simple
            RegisterSimple(725050, 1047, level: 40, failMsg: "You must be level 40+ to learn this skill.");

            // OneHand Skills
            RegisterSimple(725013, 1290, level: 30);
            RegisterSimple(725029, 5030, level: 30);
            RegisterSimple(725030, 5040, level: 30);
            RegisterSimple(725040, 7000, level: 30);
            RegisterSimple(725041, 7010, level: 30);
            RegisterSimple(725042, 7020, level: 30);
            RegisterSimple(725043, 7030, level: 30);
            RegisterSimple(725044, 7040, level: 30);

            // TwoHand Skills
            RegisterSimple(725011, 1250, level: 30);
            RegisterSimple(725012, 1260, level: 30);
            RegisterSimple(725014, 1300, level: 30);
            RegisterSimple(725026, 5010, level: 30);
            RegisterSimple(725027, 5020, level: 30);
            RegisterSimple(725031, 5050, level: 30);

            // Other Skills
            RegisterSimple(721157, (ushort)Role.Flags.SpellID.DragonTail, level: 40);
            RegisterSimple(721158, (ushort)Role.Flags.SpellID.ViperFang,  level: 40);
            RegisterSimple(725016, 1360, level: 70, failMsg: "You must be level 70+ to use NightDevil.");
            RegisterSimple(725025, 1320, level: 40);

            _books = _booksB.ToFrozenDictionary();
        }

        public static bool TryProcess(GameClient client, MsgGameItem item, ServerSockets.Packet stream)
        {
            if (!_books.TryGetValue(item.ITEM_ID, out var book))
                return false;

            // Level check
            if (book.MinLevel > 0 && client.Player.Level < book.MinLevel)
            {
                var msg = book.FailMessage ?? $"You must be level {book.MinLevel}+ to learn this skill.";
                client.SendSysMesage(msg);
                return true;
            }

            // Spirit check
            if (book.MinSpirit > 0 && client.Player.Spirit < book.MinSpirit)
            {
                var msg = book.FailMessage ?? $"You need at least {book.MinSpirit} Spirit to learn this spell.";
                client.SendSysMesage(msg);
                return true;
            }

            // Class check
            if (book.ClassCheck != ClassReq.None)
            {
                bool classOk = book.ClassCheck switch
                {
                    ClassReq.Fire        => AtributesStatus.IsFire(client.Player.Class),
                    ClassReq.Water       => AtributesStatus.IsWater(client.Player.Class),
                    ClassReq.FireOrWater => AtributesStatus.IsFire(client.Player.Class) || AtributesStatus.IsWater(client.Player.Class),
                    _ => true
                };
                if (!classOk)
                {
                    client.SendSysMesage(book.FailMessage ?? "Your class cannot learn this skill.");
                    return true;
                }
            }

            // Proficiency check
            if (book.WeaponType > 0)
            {
                if (!client.MyProfs.CheckProf(book.WeaponType, book.ProfLevel))
                {
                    if (book.ProfFailMessage != null)
                        client.CreateDialog(stream, book.ProfFailMessage, "I~see.");
                    else
                        client.SendSysMesage("Your weapon proficiency is too low.");
                    return true;
                }
            }

            // Already learned check
            if (client.MySpells.ClientSpells.ContainsKey(book.SpellID))
                return true;

            client.Inventory.Update(item, Role.Instance.AddMode.REMOVE, stream);
            client.MySpells.Add(stream, book.SpellID, 0, 0, 0, 0);
            return true;
        }

        private static void RegisterSimple(uint itemId, ushort spellId, ushort level = 0, ushort spirit = 0, string failMsg = null)
            => _booksB[itemId] = new SkillBookEntry
            {
                SpellID = spellId, MinLevel = level, MinSpirit = spirit,
                FailMessage = failMsg ?? (level > 0 ? $"You must be level {level}+ to learn this skill." : null)
            };

        private static void RegisterClass(uint itemId, ushort spellId, ushort level = 0, ushort spirit = 0,
            ClassReq classCheck = ClassReq.None, string failMsg = null)
            => _booksB[itemId] = new SkillBookEntry
            {
                SpellID = spellId, MinLevel = level, MinSpirit = spirit,
                ClassCheck = classCheck, FailMessage = failMsg
            };

        private static void RegisterProf(uint itemId, ushort spellId, ushort level = 0,
            ushort weaponType = 0, byte profLevel = 0, string failMsg = null, string profFailMsg = null)
            => _booksB[itemId] = new SkillBookEntry
            {
                SpellID = spellId, MinLevel = level,
                WeaponType = weaponType, ProfLevel = profLevel,
                FailMessage = failMsg, ProfFailMessage = profFailMsg
            };
    }
}
Editor is loading...
Leave a Comment