Add a loot table.
添加战利品表。
This commit is contained in:
parent
05763c25b1
commit
f7ad69440c
|
@ -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
|
||||
|
|
7
scripts/inventory/LootData.cs
Normal file
7
scripts/inventory/LootData.cs
Normal file
|
@ -0,0 +1,7 @@
|
|||
namespace ColdMint.scripts.inventory;
|
||||
|
||||
public class LootData
|
||||
{
|
||||
public string? ResPath { get; set; }
|
||||
public int Quantity { get; set; }
|
||||
}
|
32
scripts/inventory/LootEntry.cs
Normal file
32
scripts/inventory/LootEntry.cs
Normal 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; }
|
||||
}
|
88
scripts/inventory/LootList.cs
Normal file
88
scripts/inventory/LootList.cs
Normal 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);
|
||||
}
|
||||
}
|
107
scripts/inventory/LootListManager.cs
Normal file
107
scripts/inventory/LootListManager.cs
Normal 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);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user