This commit is contained in:
2025-10-21 20:09:31 +08:00
commit 2a79a885eb
21 changed files with 1309 additions and 0 deletions

107
history/HealthBarPatch.cs Normal file
View File

@@ -0,0 +1,107 @@
using HarmonyLib;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
namespace test
{
/// <summary>
/// Harmony补丁类用于修改HealthBar的行为
/// 添加血量数值显示功能
/// </summary>
[HarmonyPatch]
public class HealthBarPatch
{
// 使用字典来存储每个HealthBar实例对应的血量文本
private static readonly Dictionary<Duckov.UI.HealthBar, TextMeshProUGUI> healthTexts = new Dictionary<Duckov.UI.HealthBar, TextMeshProUGUI>();
/// <summary>
/// 补丁HealthBar的Setup方法初始化血量文本
/// </summary>
[HarmonyPostfix]
[HarmonyPatch(typeof(Duckov.UI.HealthBar), "Setup")]
static void SetupPostfix(Duckov.UI.HealthBar __instance)
{
// 如果这个HealthBar已经有对应的文本先清理
if (healthTexts.ContainsKey(__instance))
{
CleanupHealthText(__instance);
}
// 创建血量文本对象
GameObject textObj = new GameObject("HealthText");
textObj.transform.SetParent(__instance.transform);
// 设置文本组件
TextMeshProUGUI healthText = textObj.AddComponent<TextMeshProUGUI>();
healthText.fontSize = 12;
healthText.color = Color.white;
healthText.alignment = TextAlignmentOptions.Center;
// 设置文本位置
RectTransform rectTransform = textObj.GetComponent<RectTransform>();
rectTransform.anchorMin = new Vector2(0, 0);
rectTransform.anchorMax = new Vector2(1, 1);
rectTransform.offsetMin = new Vector2(0, 0);
rectTransform.offsetMax = new Vector2(0, 0);
// 将文本对象存储到字典中
healthTexts[__instance] = healthText;
// 更新血量文本
UpdateHealthText(__instance);
}
/// <summary>
/// 补丁HealthBar的Refresh方法更新血量文本
/// </summary>
[HarmonyPostfix]
[HarmonyPatch(typeof(Duckov.UI.HealthBar), "Refresh")]
static void RefreshPostfix(Duckov.UI.HealthBar __instance)
{
UpdateHealthText(__instance);
}
/// <summary>
/// 补丁HealthBar的Release方法清理血量文本
/// </summary>
[HarmonyPostfix]
[HarmonyPatch(typeof(Duckov.UI.HealthBar), "Release")]
static void ReleasePostfix(Duckov.UI.HealthBar __instance)
{
CleanupHealthText(__instance);
}
/// <summary>
/// 清理与HealthBar关联的血量文本
/// </summary>
static void CleanupHealthText(Duckov.UI.HealthBar healthBar)
{
if (healthTexts.TryGetValue(healthBar, out TextMeshProUGUI textComponent))
{
if (textComponent != null && textComponent.gameObject != null)
{
Object.DestroyImmediate(textComponent.gameObject);
}
healthTexts.Remove(healthBar);
}
}
/// <summary>
/// 更新血量文本显示
/// </summary>
static void UpdateHealthText(Duckov.UI.HealthBar healthBar)
{
if (!healthTexts.TryGetValue(healthBar, out TextMeshProUGUI textComponent) ||
textComponent == null ||
healthBar.target == null)
return;
float currentHealth = healthBar.target.CurrentHealth;
float maxHealth = healthBar.target.MaxHealth;
// 显示当前血量和最大血量
textComponent.text = $"{currentHealth:F0}/{maxHealth:F0}";
}
}
}

View File

@@ -0,0 +1,88 @@
using Duckov.UI;
using Duckov.Utilities;
using ItemStatsSystem;
using TMPro;
using UnityEngine;
// 物品价值显示类
// 用于在物品悬停UI中显示物品的价值
namespace test
{
/// <summary>
/// test模组的主要行为类
/// 继承自Duckov.Modding.ModBehaviour用于在游戏UI中显示物品价值
/// </summary>
public class ModBehaviour : Duckov.Modding.ModBehaviour
{
private TextMeshProUGUI? _text = null;
private TextMeshProUGUI Text
{
get
{
// 如果文本组件尚未创建,则实例化一个新的
if (_text == null)
{
// 使用游戏UI样式模板创建文本组件
_text = Instantiate(GameplayDataSettings.UIStyle.TemplateTextUGUI);
}
return _text;
}
}
/// <summary>
/// 模组初始化时调用,类似于构造函数
/// 在此记录模组加载日志
/// </summary>
void Awake()
{
// 在控制台输出模组加载成功的日志信息
Debug.Log("DisplayItemValue Loaded!!!");
}
/// <summary>
/// 模组销毁时调用,用于清理资源
/// 确保创建的文本组件被正确销毁,避免内存泄漏
/// </summary>
void OnDestroy()
{
// 检查文本组件是否存在
if (_text != null)
// 销毁文本组件以释放资源
Destroy(_text);
}
void OnEnable()
{
// 注册物品悬停UI设置事件的监听器
ItemHoveringUI.onSetupItem += OnSetupItemHoveringUI;
}
/// <summary>
/// 模组禁用时调用,取消事件监听器
/// 取消订阅事件,防止在模组禁用后仍然响应事件
/// </summary>
void OnDisable()
{
// 取消注册物品悬停UI设置事件的监听器
ItemHoveringUI.onSetupItem -= OnSetupItemHoveringUI;
}
private void OnSetupItemHoveringUI(ItemHoveringUI uiInstance, Item item)
{
if (item == null)
{
Text.gameObject.SetActive(false);
return;
}
Text.gameObject.SetActive(true);
Text.transform.SetParent(uiInstance.LayoutParent);
Text.transform.localScale = Vector3.one;
Text.transform.SetSiblingIndex(1);
Text.text = $"${item.GetTotalRawValue() / 2}";
Text.fontSize = 20f;
Text.color = Color.green;
}
}
}

37
history/ModBehaviour.cs Normal file
View File

@@ -0,0 +1,37 @@
namespace test
{
/// <summary>
/// 基础模板
/// 继承自Duckov.Modding.ModBehaviour
/// </summary>
public class ModBehaviour : Duckov.Modding.ModBehaviour
{
/// <summary>
/// 模组初始化时调用,类似于构造函数
/// </summary>
void Awake()
{
}
/// <summary>
/// 模组销毁时调用,用于清理资源
/// </summary>
void OnDestroy()
{
}
void OnEnable()
{
}
/// <summary>
/// 模组禁用时调用,取消事件监听器
/// 取消订阅事件,防止在模组禁用后仍然响应事件
/// </summary>
void OnDisable()
{
}
}
}

View File

@@ -0,0 +1,60 @@
using HarmonyLib;
namespace test
{
/// <summary>
/// test模组的主要行为类
/// 继承自Duckov.Modding.ModBehaviour用于在游戏UI中显示物品价值
/// </summary>
public class ModBehaviour : Duckov.Modding.ModBehaviour
{
private static Harmony? harmony;
private static bool patched = false;
/// <summary>
/// 模组初始化时调用,类似于构造函数
/// </summary>
void Awake()
{
// 只在第一次初始化时创建Harmony实例
if (harmony == null)
{
harmony = new Harmony("com.test.healthdisplay");
}
// 只在未打补丁时应用补丁
if (!patched)
{
harmony.PatchAll();
patched = true;
}
}
/// <summary>
/// 模组销毁时调用,用于清理资源
/// </summary>
void OnDestroy()
{
// 只在已打补丁时取消补丁
if (patched && harmony != null)
{
harmony.UnpatchAll("com.test.healthdisplay");
patched = false;
}
}
void OnEnable()
{
}
/// <summary>
/// 模组禁用时调用,取消事件监听器
/// 取消订阅事件,防止在模组禁用后仍然响应事件
/// </summary>
void OnDisable()
{
}
}
}