Add a loot table.

添加战利品表。
This commit is contained in:
Cold-Mint 2024-06-09 22:05:49 +08:00
parent 05763c25b1
commit f7ad69440c
Signed by: Cold-Mint
GPG Key ID: C5A9BF8A98E0CE99
5 changed files with 246 additions and 0 deletions

View File

@ -112,6 +112,11 @@ public partial class CharacterTemplate : CharacterBody2D
public string CampId = null!;
private DamageNumberNodeSpawn? _damageNumber;
/// <summary>
/// <para>Character referenced loot table</para>
/// <para>角色引用的战利品表</para>
/// </summary>
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

View File

@ -0,0 +1,7 @@
namespace ColdMint.scripts.inventory;
public class LootData
{
public string? ResPath { get; set; }
public int Quantity { get; set; }
}

View File

@ -0,0 +1,32 @@
namespace ColdMint.scripts.inventory;
/// <summary>
/// <para>Loot entry</para>
/// <para>战利品条目</para>
/// </summary>
public class LootEntry
{
/// <summary>
/// <para>generation probability</para>
/// <para>生成概率</para>
/// </summary>
public double? Chance { get; set; }
/// <summary>
/// <para>Minimum number of generated</para>
/// <para>最小生成多少个</para>
/// </summary>
public int MinQuantity { get; set; }
/// <summary>
/// <para>The maximum number of files to be generated</para>
/// <para>最多生成多少个</para>
/// </summary>
public int MaxQuantity { get; set; }
/// <summary>
/// <para>resources path</para>
/// <para>资源路径</para>
/// </summary>
public string? ResPath { get; set; }
}

View File

@ -0,0 +1,88 @@
using System.Collections.Generic;
using Godot;
namespace ColdMint.scripts.inventory;
/// <summary>
/// <para>Loot list</para>
/// <para>战利品表</para>
/// </summary>
public class LootList
{
/// <summary>
/// <para>Id</para>
/// <para>战利品表的Id</para>
/// </summary>
public string? Id { get; set; }
private List<LootEntry>? _lootEntrieList;
/// <summary>
/// <para>Add loot entry</para>
/// <para>添加战利品条目</para>
/// </summary>
/// <param name="lootEntry"></param>
public void AddLootEntry(LootEntry lootEntry)
{
if (_lootEntrieList == null)
{
_lootEntrieList = new List<LootEntry>();
}
_lootEntrieList.Add(lootEntry);
}
/// <summary>
/// <para>GenerateLootData</para>
/// <para>生成战利品数据</para>
/// </summary>
/// <returns></returns>
public List<LootData> GenerateLootData()
{
var lootDataList = new List<LootData>();
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;
}
/// <summary>
/// <para>Remove loot entry</para>
/// <para>移除战利品条目</para>
/// </summary>
/// <param name="lootEntry"></param>
/// <returns></returns>
public bool RemoveLootEntry(LootEntry lootEntry)
{
if (_lootEntrieList == null)
{
return false;
}
return _lootEntrieList.Remove(lootEntry);
}
}

View File

@ -0,0 +1,107 @@
using System.Collections.Generic;
using Godot;
namespace ColdMint.scripts.inventory;
/// <summary>
/// <para>LootListManager</para>
/// <para>战利品表管理器</para>
/// </summary>
public static class LootListManager
{
private static Dictionary<string, LootList>? _lootListDictionary;
/// <summary>
/// <para>Register loot table</para>
/// <para>注册战利品表</para>
/// </summary>
/// <param name="id"></param>
/// <param name="lootList"></param>
public static bool RegisterLootList(string id, LootList lootList)
{
if (_lootListDictionary != null) return _lootListDictionary.TryAdd(id, lootList);
_lootListDictionary = new Dictionary<string, LootList> { { id, lootList } };
return true;
}
/// <summary>
/// <para>Get Loot List</para>
/// <para>获取战利品表</para>
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public static LootList? GetLootList(string id)
{
return _lootListDictionary?.GetValueOrDefault(id);
}
/// <summary>
/// <para>Generate loot objects</para>
/// <para>生成战利品对象</para>
/// </summary>
/// <param name="lootDataArray">
///<para>lootDataArray</para>
///<para>战利品数组</para>
/// </param>
/// <param name="parentNode">
///<para>parentNode</para>
///<para>父节点</para>
/// </param>
public static void GenerateLootObjects(LootData[] lootDataArray, Node parentNode)
{
if (lootDataArray.Length == 0)
{
return;
}
Dictionary<string, PackedScene> packedSceneDictionary = new();
foreach (var lootData in lootDataArray)
{
if (string.IsNullOrEmpty(lootData.ResPath))
{
continue;
}
if (!packedSceneDictionary.TryGetValue(lootData.ResPath, out var packedScene))
{
packedScene = GD.Load<PackedScene>(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);
}
/// <summary>
/// <para>Remove loot list</para>
/// <para>移除战利品表</para>
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public static bool UnregisterLootList(string id)
{
if (_lootListDictionary == null)
{
return false;
}
return _lootListDictionary.Remove(id);
}
}