From f7ad69440c21587d21375f93b8f2f8f5cc0ede3b Mon Sep 17 00:00:00 2001 From: Cold-Mint Date: Sun, 9 Jun 2024 22:05:49 +0800 Subject: [PATCH] =?UTF-8?q?Add=20a=20loot=20table.=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=88=98=E5=88=A9=E5=93=81=E8=A1=A8=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/character/CharacterTemplate.cs | 12 +++ scripts/inventory/LootData.cs | 7 ++ scripts/inventory/LootEntry.cs | 32 ++++++++ scripts/inventory/LootList.cs | 88 ++++++++++++++++++++ scripts/inventory/LootListManager.cs | 107 +++++++++++++++++++++++++ 5 files changed, 246 insertions(+) create mode 100644 scripts/inventory/LootData.cs create mode 100644 scripts/inventory/LootEntry.cs create mode 100644 scripts/inventory/LootList.cs create mode 100644 scripts/inventory/LootListManager.cs diff --git a/scripts/character/CharacterTemplate.cs b/scripts/character/CharacterTemplate.cs index b5547d7..3e76c5d 100644 --- a/scripts/character/CharacterTemplate.cs +++ b/scripts/character/CharacterTemplate.cs @@ -112,6 +112,11 @@ public partial class CharacterTemplate : CharacterBody2D public string CampId = null!; private DamageNumberNodeSpawn? _damageNumber; + /// + /// Character referenced loot table + /// 角色引用的战利品表 + /// + private LootList? _lootList; private HealthBar? _healthBar; private DateTime _lastDamageTime; @@ -207,6 +212,13 @@ public partial class CharacterTemplate : CharacterBody2D CharacterName = GetMeta("Name", Name).AsString(); CampId = GetMeta("CampId", Config.CampId.Default).AsString(); MaxHp = GetMeta("MaxHp", Config.DefaultMaxHp).AsInt32(); + string lootListId = GetMeta("LootListId", string.Empty).AsString(); + if (!string.IsNullOrEmpty(lootListId)) + { + //If a loot table is specified, get the loot table. + //如果指定了战利品表,那么获取战利品表。 + _lootList = LootListManager.GetLootList(lootListId); + } if (MaxHp <= 0) { //If Max blood volume is 0 or less, set Max blood volume to 10 diff --git a/scripts/inventory/LootData.cs b/scripts/inventory/LootData.cs new file mode 100644 index 0000000..6a92357 --- /dev/null +++ b/scripts/inventory/LootData.cs @@ -0,0 +1,7 @@ +namespace ColdMint.scripts.inventory; + +public class LootData +{ + public string? ResPath { get; set; } + public int Quantity { get; set; } +} \ No newline at end of file diff --git a/scripts/inventory/LootEntry.cs b/scripts/inventory/LootEntry.cs new file mode 100644 index 0000000..0c4b2fa --- /dev/null +++ b/scripts/inventory/LootEntry.cs @@ -0,0 +1,32 @@ +namespace ColdMint.scripts.inventory; + +/// +/// Loot entry +/// 战利品条目 +/// +public class LootEntry +{ + /// + /// generation probability + /// 生成概率 + /// + public double? Chance { get; set; } + + /// + /// Minimum number of generated + /// 最小生成多少个 + /// + public int MinQuantity { get; set; } + + /// + /// The maximum number of files to be generated + /// 最多生成多少个 + /// + public int MaxQuantity { get; set; } + + /// + /// resources path + /// 资源路径 + /// + public string? ResPath { get; set; } +} \ No newline at end of file diff --git a/scripts/inventory/LootList.cs b/scripts/inventory/LootList.cs new file mode 100644 index 0000000..28fa1c9 --- /dev/null +++ b/scripts/inventory/LootList.cs @@ -0,0 +1,88 @@ +using System.Collections.Generic; +using Godot; + +namespace ColdMint.scripts.inventory; + +/// +/// Loot list +/// 战利品表 +/// +public class LootList +{ + /// + /// Id + /// 战利品表的Id + /// + public string? Id { get; set; } + + private List? _lootEntrieList; + + /// + /// Add loot entry + /// 添加战利品条目 + /// + /// + public void AddLootEntry(LootEntry lootEntry) + { + if (_lootEntrieList == null) + { + _lootEntrieList = new List(); + } + + _lootEntrieList.Add(lootEntry); + } + + + /// + /// GenerateLootData + /// 生成战利品数据 + /// + /// + public List GenerateLootData() + { + var lootDataList = new List(); + if (_lootEntrieList == null) + { + return lootDataList; + } + + foreach (var lootEntry in _lootEntrieList) + { + var chance = GD.Randf(); + if (chance > lootEntry.Chance) + { + //If the random number is greater than the generation probability, skip the current loop. + //如果随机数大于生成概率,则跳过当前循环。 + continue; + } + //We generate a loot data for each loot entry. + //我们为每个战利品条目生成一个战利品数据。 + var quantity = GD.RandRange(lootEntry.MinQuantity, lootEntry.MaxQuantity); + var lootData = new LootData + { + ResPath = lootEntry.ResPath, + Quantity = quantity + }; + lootDataList.Add(lootData); + } + + return lootDataList; + } + + + /// + /// Remove loot entry + /// 移除战利品条目 + /// + /// + /// + public bool RemoveLootEntry(LootEntry lootEntry) + { + if (_lootEntrieList == null) + { + return false; + } + + return _lootEntrieList.Remove(lootEntry); + } +} \ No newline at end of file diff --git a/scripts/inventory/LootListManager.cs b/scripts/inventory/LootListManager.cs new file mode 100644 index 0000000..dce16f7 --- /dev/null +++ b/scripts/inventory/LootListManager.cs @@ -0,0 +1,107 @@ +using System.Collections.Generic; +using Godot; + +namespace ColdMint.scripts.inventory; + +/// +/// LootListManager +/// 战利品表管理器 +/// +public static class LootListManager +{ + private static Dictionary? _lootListDictionary; + + + /// + /// Register loot table + /// 注册战利品表 + /// + /// + /// + public static bool RegisterLootList(string id, LootList lootList) + { + if (_lootListDictionary != null) return _lootListDictionary.TryAdd(id, lootList); + _lootListDictionary = new Dictionary { { id, lootList } }; + return true; + } + + /// + /// Get Loot List + /// 获取战利品表 + /// + /// + /// + public static LootList? GetLootList(string id) + { + return _lootListDictionary?.GetValueOrDefault(id); + } + + /// + /// Generate loot objects + /// 生成战利品对象 + /// + /// + ///lootDataArray + ///战利品数组 + /// + /// + ///parentNode + ///父节点 + /// + public static void GenerateLootObjects(LootData[] lootDataArray, Node parentNode) + { + if (lootDataArray.Length == 0) + { + return; + } + + Dictionary packedSceneDictionary = new(); + foreach (var lootData in lootDataArray) + { + if (string.IsNullOrEmpty(lootData.ResPath)) + { + continue; + } + + if (!packedSceneDictionary.TryGetValue(lootData.ResPath, out var packedScene)) + { + packedScene = GD.Load(lootData.ResPath); + packedSceneDictionary.TryAdd(lootData.ResPath, packedScene); + } + + CreateLootObject(packedScene, parentNode); + } + } + + private static void CreateLootObject(PackedScene? packedScene, Node parent) + { + if (packedScene == null) + { + return; + } + + var lootObject = packedScene.Instantiate(); + if (lootObject is not Node2D node2D) + { + return; + } + + parent.AddChild(node2D); + } + + /// + /// Remove loot list + /// 移除战利品表 + /// + /// + /// + public static bool UnregisterLootList(string id) + { + if (_lootListDictionary == null) + { + return false; + } + + return _lootListDictionary.Remove(id); + } +} \ No newline at end of file