diff --git a/data/itemRegs/weapons.yaml b/data/itemRegs/weapons.yaml
index 171c341..0d8abb7 100644
--- a/data/itemRegs/weapons.yaml
+++ b/data/itemRegs/weapons.yaml
@@ -1,4 +1,8 @@
- id: staff_of_the_undead
scene_path: res://prefab/weapons/staffOfTheUndead.tscn
icon_path: res://sprites/weapon/staffOfTheUndead.png
- max_stack_value: 1
\ No newline at end of file
+ max_stack_value: 1
+ custom_args:
+ - name: FiringIntervalAsMillisecond
+ type: int
+ value: 1000
diff --git a/locals/Log.csv b/locals/Log.csv
index 63ca9e8..4a39692 100644
--- a/locals/Log.csv
+++ b/locals/Log.csv
@@ -23,9 +23,11 @@ log_player_packed_scene_not_exist,玩家预制场景不存在。,Player packed s
log_exit_the_room_debug,节点{0}退出房间{1}。,"Node {0} exits room {1}.",ノード{0}が部屋{1}を退出します。
log_enter_the_room_debug,节点{0}进入房间{1}。,"Node {0} enters room {1}.",ノード{0}が部屋{1}に入ります。
log_death_info,生物{0}被{1}击败。,"Creature {0} was defeated by {1}.",生物{0}が{1}によって打ち負かされました。
+
log_loot_list_has_no_entries,ID为{0}的战利品表,没有指定条目。,"Loot list with ID {0}, no entry specified.",ID{0}の戦利品テーブルは、エントリ指定されていません。
log_not_within_the_loot_spawn_range,给定的数值{0}没有在战利品{1}的生成范围{2}内。,The given value {0} is not within the spawn range {2} of loot {1}.,与えられた数値{0}は戦利品{1}の生成範囲{2}内にありません。
log_loot_data_quantity,有{0}个战利品数据被返回。,{0} loot data was returned.,{0}個の戦利品データが返されます。
+log_loot_data_add,生成战利品{0},Add loot {0},戦利品{0}を生成する
log_warning_node_cannot_cast_to,创建的物品{0}无法被转型为类型{1},Created items {0} cannot be cast into type {1},作成されたアイテム {0} をタイプ {1} にキャストすることはできません。
diff --git a/prefab/entitys/DelivererOfDarkMagic.tscn b/prefab/entitys/DelivererOfDarkMagic.tscn
index f665553..a7535a0 100644
--- a/prefab/entitys/DelivererOfDarkMagic.tscn
+++ b/prefab/entitys/DelivererOfDarkMagic.tscn
@@ -31,10 +31,10 @@ radius = 129.027
collision_layer = 64
collision_mask = 38
script = ExtResource("1_ubaid")
+LootListId = "test"
metadata/CampId = "Mazoku"
metadata/MaxHp = 50
metadata/Name = "死灵法师"
-metadata/LootListId = "Test"
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
position = Vector2(0, 4)
diff --git a/scripts/Config.cs b/scripts/Config.cs
index 5263cc5..119f521 100644
--- a/scripts/Config.cs
+++ b/scripts/Config.cs
@@ -31,7 +31,7 @@ public static class Config
/// A trophy table for testing
/// 测试用的战利品表
///
- public const string Test = "Test";
+ public const string Test = "test";
}
///
diff --git a/scripts/character/CharacterTemplate.cs b/scripts/character/CharacterTemplate.cs
index dac5540..a5eec70 100644
--- a/scripts/character/CharacterTemplate.cs
+++ b/scripts/character/CharacterTemplate.cs
@@ -10,6 +10,7 @@ using ColdMint.scripts.inventory;
using ColdMint.scripts.item;
using ColdMint.scripts.utils;
using ColdMint.scripts.item.weapon;
+using ColdMint.scripts.loot;
using Godot;
@@ -107,11 +108,7 @@ public partial class CharacterTemplate : CharacterBody2D
private DamageNumberNodeSpawn? _damageNumber;
- ///
- /// Character referenced loot table
- /// 角色引用的战利品表
- ///
- private LootList? _lootList;
+ [Export] public string LootListId { get; private set; } = "";
private HealthBar? _healthBar;
private DateTime _lastDamageTime;
@@ -208,12 +205,6 @@ public partial class CharacterTemplate : CharacterBody2D
CampId = GetMeta("CampId", Config.CampId.Default).AsString();
MaxHp = GetMeta("MaxHp", Config.DefaultMaxHp).AsInt32();
var 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)
{
@@ -461,20 +452,11 @@ public partial class CharacterTemplate : CharacterBody2D
///
protected void CreateLootObject()
{
- if (_lootList == null)
- {
- return;
- }
-
- var lootDataArray = _lootList.GenerateLootData();
- if (lootDataArray.Length == 0)
- {
- return;
- }
-
-
+ var lootData = LootListManager.GenerateLootData(LootListId);
var finalGlobalPosition = GlobalPosition;
- CallDeferred("GenerateLootObjects", this, lootDataArray, finalGlobalPosition);
+ //Todo : change name str to nameof(), like this
+ // CallDeferred(nameof(GenerateLootObjects), this, lootData, finalGlobalPosition);
+ GenerateLootObjects(GetParent(), lootData, finalGlobalPosition);
}
///
@@ -482,13 +464,17 @@ public partial class CharacterTemplate : CharacterBody2D
/// 生成战利品对象
///
///
- ///
+ ///
///
public void GenerateLootObjects(Node parentNode,
- LootData[] lootDataArray,
+ IEnumerable lootData,
Vector2 position)
{
- LootListManager.GenerateLootObjects(parentNode, lootDataArray, position);
+ foreach (var lootDatum in lootData)
+ {
+ var (id, amount) = lootDatum.Value;
+ ItemTypeManager.CreateItems(id, amount, parentNode, position);
+ }
}
///
@@ -601,14 +587,8 @@ public partial class CharacterTemplate : CharacterBody2D
//Generates a random number that controls the horizontal velocity of thrown items (range: 0.01 to 1)
//生成一个随机数,用于控制抛出物品的水平方向速度(范围为:0.01到1)
var percent = GD.Randf() + 0.01f;
- if (GD.Randf() > 0.5)
- {
- ThrowItem(i, -1, new Vector2(horizontalDirection * percent, height));
- }
- else
- {
- ThrowItem(i, -1, new Vector2(-horizontalDirection * percent, height));
- }
+ var horizontalVelocity = horizontalDirection * percent * GD.Randf() > 0.5 ? 1f : -1f;
+ ThrowItem(i, -1, new Vector2(horizontalVelocity, height));
}
}
diff --git a/scripts/inventory/LootData.cs b/scripts/inventory/LootData.cs
deleted file mode 100644
index 0a6d863..0000000
--- a/scripts/inventory/LootData.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using Godot;
-
-namespace ColdMint.scripts.inventory;
-
-public partial class LootData : GodotObject
-{
- 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
deleted file mode 100644
index 0c4b2fa..0000000
--- a/scripts/inventory/LootEntry.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-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
deleted file mode 100644
index fe4a924..0000000
--- a/scripts/inventory/LootList.cs
+++ /dev/null
@@ -1,93 +0,0 @@
-using System.Collections.Generic;
-using ColdMint.scripts.debug;
-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 LootData[] GenerateLootData()
- {
- var lootDataList = new List();
- if (_lootEntrieList == null)
- {
- LogCat.LogWithFormat("loot_list_has_no_entries", Id);
- return lootDataList.ToArray();
- }
-
- 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.
- //如果随机数大于生成概率,则跳过当前循环。
- LogCat.LogWithFormat("not_within_the_loot_spawn_range", chance, lootEntry.ResPath, lootEntry.Chance);
- 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);
- }
-
- LogCat.LogWithFormat("loot_data_quantity", lootDataList.Count);
- return lootDataList.ToArray();
- }
-
-
- ///
- /// 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
deleted file mode 100644
index 0b60dcf..0000000
--- a/scripts/inventory/LootListManager.cs
+++ /dev/null
@@ -1,117 +0,0 @@
-using System.Collections.Generic;
-using ColdMint.scripts.utils;
-using Godot;
-
-namespace ColdMint.scripts.inventory;
-
-///
-/// LootListManager
-/// 战利品表管理器
-///
-public static class LootListManager
-{
- private static Dictionary? _lootListDictionary;
-
-
- ///
- /// Register loot table
- /// 注册战利品表
- ///
- ///
- public static bool RegisterLootList(LootList lootList)
- {
- var id = lootList.Id;
- if (id == null)
- {
- return false;
- }
-
- 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
- /// 生成战利品对象
- ///
- public static void GenerateLootObjects(Node parentNode, LootData[] lootDataArray, Vector2 position)
- {
- if (lootDataArray.Length == 0)
- {
- return;
- }
-
- //Cache the loaded PackedScene object.
- //缓存已加载的PackedScene对象。
- Dictionary packedSceneDictionary = new();
- foreach (var lootData in lootDataArray)
- {
- if (string.IsNullOrEmpty(lootData.ResPath) || lootData.Quantity == 0)
- {
- continue;
- }
-
- if (!packedSceneDictionary.TryGetValue(lootData.ResPath, out var packedScene))
- {
- packedScene = GD.Load(lootData.ResPath);
- packedSceneDictionary.TryAdd(lootData.ResPath, packedScene);
- }
-
- for (var i = 0; i < lootData.Quantity; i++)
- {
- //Generate as many loot instance objects as there are loot.
- //有多少个战利品就生成多少个战利品实例对象。
- CreateLootInstanceObject(parentNode, packedScene, position);
- }
- }
- }
-
-
- ///
- /// Create a loot instance object
- /// 创建战利品实例对象
- ///
- private static void CreateLootInstanceObject(Node parent, PackedScene? packedScene, Vector2 position)
- {
- if (packedScene == null)
- {
- return;
- }
-
- var lootObject = NodeUtils.InstantiatePackedScene(packedScene, parent);
- if (lootObject == null)
- {
- return;
- }
-
- lootObject.Position = position;
- }
-
- ///
- /// Remove loot list
- /// 移除战利品表
- ///
- ///
- ///
- public static bool UnregisterLootList(string id)
- {
- if (_lootListDictionary == null)
- {
- return false;
- }
-
- return _lootListDictionary.Remove(id);
- }
-}
\ No newline at end of file
diff --git a/scripts/item/ItemTypeManager.cs b/scripts/item/ItemTypeManager.cs
index 9416d07..cf7261d 100644
--- a/scripts/item/ItemTypeManager.cs
+++ b/scripts/item/ItemTypeManager.cs
@@ -1,13 +1,9 @@
using System.Collections.Generic;
-using ColdMint.scripts.debug;
using ColdMint.scripts.utils;
using Godot;
-using YamlDotNet.Serialization;
-using YamlDotNet.Serialization.NamingConventions;
-
namespace ColdMint.scripts.item;
///
@@ -16,12 +12,6 @@ namespace ColdMint.scripts.item;
///
public static class ItemTypeManager
{
- ///
- /// Register items here
- /// 在这里注册物品
- ///
- public static void StaticRegister() { }
-
private static Dictionary Registry { get; } = [];
private static Texture2D DefaultTexture { get; } = new PlaceholderTexture2D();
@@ -45,9 +35,66 @@ public static class ItemTypeManager
/// Returns null when the id is not registered.
/// 当物品id没有注册时返回null
///
+ ///
public static IItem? NewItem(string id) =>
Registry.TryGetValue(id, out var itemType) ? itemType.NewItemFunc() : null;
+ ///
+ /// Creates new instances in given amount of the item registered to the given id.
+ /// 创建给定数量的注册到给定 id 的物品的新实例。
+ ///
+ ///
+ ///
+ public static IList NewItems(string id, int amount)
+ {
+ IList result = [];
+ for (int i = 0; i < amount; i++)
+ {
+ if (NewItem(id) is { } item) result.Add(item);
+ }
+
+ return result;
+ }
+
+ ///
+ /// Creates new instance of the item registered to the given id, and put it into given position in both node tree and 2D space
+ /// 创建以给定 id 注册的物品的新实例,并将其放到节点树和二维空间中的给定位置
+ ///
+ ///
+ ///
+ ///
+ /// Position in global coordinate
+ /// 全局坐标中的位置
+ ///
+ ///
+ public static void CreateItem(string id, Node? parent = null, Vector2? position = null)
+ {
+ var item = NewItem(id);
+ parent?.AddChild(item as Node);
+ if (item is not Node2D node) return;
+ if (position is { } pos) node.GlobalPosition = pos;
+ }
+
+ ///
+ /// Creates new instances in given amount of the item registered to the given id, and put them into given position in both node tree and 2D space
+ /// 创建以给定 id 注册的物品的给定数量的新实例,并将其放到节点树和二维空间中的给定位置
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// Position in global coordinate
+ /// 全局坐标中的位置
+ ///
+ ///
+ public static void CreateItems(string id, int amount, Node? parent = null, Vector2? position = null)
+ {
+ for (int i = 0; i < amount; i++)
+ {
+ CreateItem(id, parent, position);
+ }
+ }
+
///
/// Get the translated default name of the item type for the given id
/// 获取指定物品id翻译后的物品名
diff --git a/scripts/item/ItemTypeRegister.cs b/scripts/item/ItemTypeRegister.cs
index 9b22422..00b20f2 100644
--- a/scripts/item/ItemTypeRegister.cs
+++ b/scripts/item/ItemTypeRegister.cs
@@ -17,6 +17,12 @@ namespace ColdMint.scripts.item;
///
public static class ItemTypeRegister
{
+ ///
+ /// Register items here
+ /// 在这里注册物品
+ ///
+ public static void StaticRegister() { }
+
///
/// Register items from yaml file
/// 从文件注册物品
diff --git a/scripts/loader/uiLoader/MainMenuLoader.cs b/scripts/loader/uiLoader/MainMenuLoader.cs
index 3659e79..4e7676c 100644
--- a/scripts/loader/uiLoader/MainMenuLoader.cs
+++ b/scripts/loader/uiLoader/MainMenuLoader.cs
@@ -7,6 +7,7 @@ using ColdMint.scripts.deathInfo;
using ColdMint.scripts.debug;
using ColdMint.scripts.inventory;
using ColdMint.scripts.item;
+using ColdMint.scripts.loot;
using ColdMint.scripts.map;
using ColdMint.scripts.map.roomInjectionProcessor;
@@ -43,31 +44,6 @@ public partial class MainMenuLoader : UiLoaderTemplate
LogCat.MinLogLevel = LogCat.DisableAllLogLevel;
}
- //注册测试使用的战利品表
- if (Config.IsDebug())
- {
- var testLootList = new LootList
- {
- Id = Config.LootListId.Test
- };
- var staffOfTheUndead = new LootEntry
- {
- Chance = 0.05f,
- MaxQuantity = 5,
- MinQuantity = 1,
- ResPath = "res://prefab/weapons/staffOfTheUndead.tscn"
- };
- testLootList.AddLootEntry(staffOfTheUndead);
- var packsack = new LootEntry
- {
- Chance = 1f,
- MaxQuantity = 1,
- MinQuantity = 1,
- ResPath = "res://prefab/packsacks/packsack.tscn"
- };
- testLootList.AddLootEntry(packsack);
- LootListManager.RegisterLootList(testLootList);
- }
DeathInfoGenerator.RegisterDeathInfoHandler(new SelfDeathInfoHandler());
MapGenerator.RegisterRoomInjectionProcessor(new ChanceRoomInjectionProcessor());
@@ -82,6 +58,7 @@ public partial class MainMenuLoader : UiLoaderTemplate
Directory.CreateDirectory(dataPath);
}
+
//Registered camp
//注册阵营
var defaultCamp = new Camp(Config.CampId.Default)
@@ -94,13 +71,16 @@ public partial class MainMenuLoader : UiLoaderTemplate
var aborigines = new Camp(Config.CampId.Aborigines);
CampManager.AddCamp(aborigines);
_gameScene = (PackedScene)GD.Load("res://scenes/game.tscn");
-
+
//Register ItemTypes from file
//从文件注册物品类型
ItemTypeRegister.RegisterFromFile();
//Hardcoded ItemTypes Register
//硬编码注册物品类型
- ItemTypeManager.StaticRegister();
+ ItemTypeRegister.StaticRegister();
+
+ //静态注册掉落表
+ LootRegister.StaticRegister();
}
public override void InitializeUi()
diff --git a/scripts/loot/LootDatum.cs b/scripts/loot/LootDatum.cs
new file mode 100644
index 0000000..4053484
--- /dev/null
+++ b/scripts/loot/LootDatum.cs
@@ -0,0 +1,8 @@
+using Godot;
+
+namespace ColdMint.scripts.loot;
+
+public readonly record struct LootDatum(string ItemId, int Quantity)
+{
+ public (string id, int quantity) Value => (ItemId, Quantity);
+}
\ No newline at end of file
diff --git a/scripts/loot/LootEntry.cs b/scripts/loot/LootEntry.cs
new file mode 100644
index 0000000..77a834b
--- /dev/null
+++ b/scripts/loot/LootEntry.cs
@@ -0,0 +1,68 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+using ColdMint.scripts.utils;
+
+namespace ColdMint.scripts.loot;
+
+///
+/// Loot entry
+/// 战利品条目
+///
+public readonly struct LootEntry(string itemId,int minQuantity=1,int maxQuantity = 1,int weight = 1)
+{
+ ///
+ /// ID of item
+ /// 物品ID
+ ///
+ public string ItemId { get; init; } = itemId;
+
+ ///
+ /// Minimum number of generated
+ /// 最小生成多少个
+ ///
+ public int MinQuantity { get; init; } = minQuantity;
+
+ ///
+ /// The maximum number of files to be generated
+ /// 最多生成多少个
+ ///
+ public int MaxQuantity { get; init; } = maxQuantity;
+
+ ///
+ /// Weight of probability within the drop group
+ /// 在掉落组内的生成权重
+ ///
+ public int Weight { get; init; } = weight;
+}
+
+///
+/// Loot Group
+/// 战利品分组
+///
+///
+///
+public readonly record struct LootGroup(double Chance, IEnumerable Entries)
+{
+ private int WeightSum { get; } = Entries.Sum(entry => entry.Weight);
+
+ public LootDatum GenerateLootData()
+ {
+ var random = RandomUtils.Instance;
+ var w = random.Next(WeightSum);
+ LootEntry entry = default;
+ foreach (var e in Entries)
+ {
+ w -= e.Weight;
+ if (w < 0)
+ {
+ entry = e;
+ }
+ }
+
+ var quantity = random.Next(entry.MinQuantity, entry.MaxQuantity + 1);
+
+ return new(entry.ItemId, quantity);
+ }
+}
\ No newline at end of file
diff --git a/scripts/loot/LootList.cs b/scripts/loot/LootList.cs
new file mode 100644
index 0000000..ffba1f3
--- /dev/null
+++ b/scripts/loot/LootList.cs
@@ -0,0 +1,53 @@
+using System;
+using System.Collections.Generic;
+
+using ColdMint.scripts.debug;
+using ColdMint.scripts.utils;
+
+using Godot;
+
+namespace ColdMint.scripts.loot;
+
+///
+/// Loot list
+/// 战利品表
+///
+public readonly struct LootList(string id, IList groups)
+{
+ public string Id { get; } = id;
+ private IList Groups { get; } = groups;
+
+ private static Random Random => RandomUtils.Instance;
+
+ ///
+ /// GenerateLootData
+ /// 生成战利品数据
+ ///
+ ///
+ public LootDatum[] GenerateLootData()
+ {
+ if (Groups is [])
+ {
+ LogCat.LogWithFormat("loot_list_has_no_entries", Id);
+ return [];
+ }
+
+ var lootDataList = new List();
+ foreach (var group in Groups)
+ {
+ //If the random number is greater than the generation probability, skip the current loop.
+ //如果随机数大于生成概率,则跳过当前循环。
+ var rd = Random.NextDouble();
+ if (rd > group.Chance) continue;
+
+ //We generate a loot data for each loot entry.
+ //我们为每个战利品条目生成一个战利品数据。
+ var datum = group.GenerateLootData();
+ lootDataList.Add(datum);
+ LogCat.LogWithFormat("loot_data_add", datum);
+ }
+
+ LogCat.LogWithFormat("loot_data_quantity", lootDataList.Count);
+ return lootDataList.ToArray();
+ }
+}
\ No newline at end of file
diff --git a/scripts/loot/LootListManager.cs b/scripts/loot/LootListManager.cs
new file mode 100644
index 0000000..09e7709
--- /dev/null
+++ b/scripts/loot/LootListManager.cs
@@ -0,0 +1,51 @@
+using System.Collections.Generic;
+
+using ColdMint.scripts.utils;
+
+using Godot;
+
+namespace ColdMint.scripts.loot;
+
+///
+/// LootListManager
+/// 战利品表管理器
+///
+public static class LootListManager
+{
+ private static Dictionary LootListDictionary { get; } = [];
+
+ ///
+ /// Register loot table
+ /// 注册战利品表
+ ///
+ ///
+ public static bool RegisterLootList(LootList lootList)
+ {
+ var id = lootList.Id;
+ if (id is "") return false;
+ return LootListDictionary.TryAdd(id, lootList);
+ }
+
+ ///
+ /// Remove loot list
+ /// 移除战利品表
+ ///
+ ///
+ ///
+ public static bool UnregisterLootList(string id)
+ {
+ return LootListDictionary.Remove(id);
+ }
+
+ ///
+ /// Generate an loot data.
+ /// 获取掉落物品
+ ///
+ ///
+ ///
+ public static IEnumerable GenerateLootData(string id)
+ {
+ if (!LootListDictionary.TryGetValue(id, out var list)) return [];
+ return list.GenerateLootData();
+ }
+}
\ No newline at end of file
diff --git a/scripts/loot/LootRegister.cs b/scripts/loot/LootRegister.cs
new file mode 100644
index 0000000..4ccd9da
--- /dev/null
+++ b/scripts/loot/LootRegister.cs
@@ -0,0 +1,30 @@
+using System.Collections.Generic;
+
+namespace ColdMint.scripts.loot;
+
+public static class LootRegister
+{
+ ///
+ /// Register loots hardcoded here
+ /// 在这里硬编码地注册掉落表
+ ///
+ public static void StaticRegister()
+ {
+ //注册测试使用的战利品表
+ if (Config.IsDebug())
+ {
+ IList lootGroups = [];
+ lootGroups.Add(new LootGroup(1,
+ [
+ new LootEntry("packsack", weight: 2), new LootEntry("staff_of_the_undead", minQuantity: 2, maxQuantity: 4)
+ ]));
+ lootGroups.Add(new LootGroup(0.3,
+ [
+ new LootEntry("packsack")
+ ]));
+
+ var testLootList = new LootList(Config.LootListId.Test, lootGroups);
+ LootListManager.RegisterLootList(testLootList);
+ }
+ }
+}
\ No newline at end of file
diff --git a/scripts/utils/RandomUtils.cs b/scripts/utils/RandomUtils.cs
new file mode 100644
index 0000000..f41a5ba
--- /dev/null
+++ b/scripts/utils/RandomUtils.cs
@@ -0,0 +1,8 @@
+using System;
+
+namespace ColdMint.scripts.utils;
+
+public static class RandomUtils
+{
+ public static Random Instance { get; } = new();
+}
\ No newline at end of file