(client) feat:支持定义实体的碰撞体大小和偏移;建筑支持定义实体建筑和瓦片建筑,建筑支持指定按钮回调;添加存档管理器;Dev支持设置是否暂停;实体允许定义事件组;添加基地界面 (#57)

Co-authored-by: m0_75251201 <m0_75251201@noreply.gitcode.com>
Reviewed-on: http://47.107.252.169:3000/Roguelite-Game-Developing-Team/Gen_Hack-and-Slash-Roguelite/pulls/57
This commit is contained in:
2025-09-28 15:02:57 +08:00
parent 87a8abe86c
commit aff747be17
232 changed files with 39203 additions and 4161 deletions

View File

@@ -1,10 +1,11 @@
using System;
using Data;
using System.Collections.Generic;
using System.Linq;
namespace Managers
{
public class SkillTreeManager : Utils.Singleton<SkillTreeManager>, ILaunchManager
public class SkillTreeManager : Utils.Singleton<SkillTreeManager>, ILaunchManager, ISavableSingleton
{
public string StepDescription => "正在加载技能树";
@@ -12,7 +13,19 @@ namespace Managers
private Dictionary<string, SkillTreeDef> _skillNodesByDefName;
private Dictionary<string, List<SkillTreeDef>> _skillNodesByTag;
private Dictionary<string, List<SkillTreeDef>> _skillNodesByFaction;
private Dictionary<string, List<SkillTreeDef>> _childrenOfNode; // key: parent defName, value: list of children nodes
private Dictionary<string, List<SkillTreeDef>> _childrenOfNode;
[Savable] public HashSet<string> UnlockedSkillTrees { get; set; } = new();
public SkillTreeManager()
{
SaveManager.Instance.RegisterSavable(this);
}
~SkillTreeManager()
{
SaveManager.Instance.UnregisterSavable(this);
}
public void Init()
{
@@ -51,6 +64,7 @@ namespace Managers
{
_skillNodesByTag[node.tag] = new List<SkillTreeDef>();
}
_skillNodesByTag[node.tag].Add(node);
}
@@ -62,6 +76,7 @@ namespace Managers
{
_skillNodesByFaction[node.faction.defName] = new List<SkillTreeDef>();
}
_skillNodesByFaction[node.faction.defName].Add(node);
}
}
@@ -75,12 +90,14 @@ namespace Managers
foreach (var prerequisite in childNode.prerequisites)
{
// 确保父节点在 _skillNodesByDefName 中存在,避免野指针或无效引用
if (prerequisite != null && _skillNodesByDefName.TryGetValue(prerequisite.defName, out var parentNode))
if (prerequisite != null &&
_skillNodesByDefName.TryGetValue(prerequisite.defName, out var parentNode))
{
if (!_childrenOfNode.ContainsKey(parentNode.defName))
{
_childrenOfNode[parentNode.defName] = new List<SkillTreeDef>();
}
_childrenOfNode[parentNode.defName].Add(childNode);
}
else if (prerequisite != null)
@@ -148,7 +165,7 @@ namespace Managers
public string[] GetAllTag()
{
return _skillNodesByTag.Keys.ToArray();
return _skillNodesByTag.Keys.ToArray();
}
// --- 父子关系查询 ---
@@ -162,7 +179,8 @@ namespace Managers
public bool IsDirectParentOf(SkillTreeDef baseNode, SkillTreeDef targetNode)
{
if (baseNode == null || targetNode == null || targetNode.prerequisites == null) return false;
return targetNode.prerequisites.Any(prerequisite => prerequisite != null && prerequisite.defName == baseNode.defName);
return targetNode.prerequisites.Any(prerequisite =>
prerequisite != null && prerequisite.defName == baseNode.defName);
}
/// <summary>
@@ -217,8 +235,8 @@ namespace Managers
if (node == null || node.prerequisites == null) return new List<SkillTreeDef>();
// 确保返回的是真实存在于管理器中的节点,而不是可能无效的引用
return node.prerequisites.Where(p => p != null && _skillNodesByDefName.ContainsKey(p.defName))
.Select(p => _skillNodesByDefName[p.defName])
.ToList();
.Select(p => _skillNodesByDefName[p.defName])
.ToList();
}
/// <summary>
@@ -250,7 +268,8 @@ namespace Managers
{
foreach (var directParentRef in node.prerequisites)
{
if (directParentRef != null && _skillNodesByDefName.TryGetValue(directParentRef.defName, out var parentNode))
if (directParentRef != null &&
_skillNodesByDefName.TryGetValue(directParentRef.defName, out var parentNode))
{
if (!ancestors.Contains(parentNode))
{
@@ -269,7 +288,8 @@ namespace Managers
{
foreach (var prerequisiteRef in current.prerequisites)
{
if (prerequisiteRef != null && _skillNodesByDefName.TryGetValue(prerequisiteRef.defName, out var actualParentNode))
if (prerequisiteRef != null &&
_skillNodesByDefName.TryGetValue(prerequisiteRef.defName, out var actualParentNode))
{
if (!ancestors.Contains(actualParentNode))
{
@@ -280,6 +300,7 @@ namespace Managers
}
}
}
return ancestors.ToList();
}
@@ -326,7 +347,54 @@ namespace Managers
}
}
}
return descendants.ToList();
}
/// <summary>
/// 确保技能树定义名称有效。
/// </summary>
/// <param name="skillTreeDefName">要验证的技能树定义名称。</param>
/// <exception cref="ArgumentException">如果技能树定义名称无效(不在 _skillNodesByDefName 中),则抛出。</exception>
private bool ValidateSkillTreeDefName(string skillTreeDefName)
{
return _skillNodesByDefName.ContainsKey(skillTreeDefName);
}
/// <summary>
/// 尝试解锁一个技能树。
/// 必须是有效的 skillTreeDefName否则会抛出 ArgumentException。
/// </summary>
/// <param name="skillTreeDefName">要解锁的技能树的定义名称。</param>
/// <returns>如果技能树成功解锁(之前未解锁),则为 true如果技能树已经解锁则为 false。</returns>
/// <exception cref="ArgumentException">如果 skillTreeDefName 无效。</exception>
public bool UnlockSkillTree(string skillTreeDefName)
{
return ValidateSkillTreeDefName(skillTreeDefName) && UnlockedSkillTrees.Add(skillTreeDefName);
}
/// <summary>
/// 尝试加锁(锁定)一个技能树。
/// 必须是有效的 skillTreeDefName否则会抛出 ArgumentException。
/// </summary>
/// <param name="skillTreeDefName">要加锁的技能树的定义名称。</param>
/// <returns>如果技能树成功加锁(之前已解锁),则为 true如果技能树已经加锁则为 false。</returns>
/// <exception cref="ArgumentException">如果 skillTreeDefName 无效。</exception>
public bool LockSkillTree(string skillTreeDefName)
{
return ValidateSkillTreeDefName(skillTreeDefName) && UnlockedSkillTrees.Remove(skillTreeDefName);
}
/// <summary>
/// 查询指定技能树是否已解锁。
/// 必须是有效的 skillTreeDefName否则会抛出 ArgumentException。
/// </summary>
/// <param name="skillTreeDefName">要查询的技能树的定义名称。</param>
/// <returns>如果技能树已解锁,则为 true否则为 false。</returns>
/// <exception cref="ArgumentException">如果 skillTreeDefName 无效。</exception>
public bool IsSkillTreeUnlocked(string skillTreeDefName)
{
return ValidateSkillTreeDefName(skillTreeDefName) && UnlockedSkillTrees.Contains(skillTreeDefName);
}
}
}