Files
Cielonos/Assets/Scripts/MainGame/Items/Submodules/FunctionSubmodule.cs

115 lines
4.0 KiB
C#
Raw Normal View History

2025-11-25 08:19:33 -05:00
using System.Collections.Generic;
2026-01-03 18:19:39 -05:00
using System.Linq;
2025-11-25 08:19:33 -05:00
using Cielonos.MainGame.Characters;
2026-02-13 09:22:11 -05:00
using Cielonos.MainGame.UI;
2025-11-25 08:19:33 -05:00
using Sirenix.OdinInspector;
2026-02-13 09:22:11 -05:00
using SLSUtilities.General;
2025-11-25 08:19:33 -05:00
using UnityEngine;
2026-05-23 08:27:50 -04:00
namespace Cielonos.MainGame.Inventory
2025-11-25 08:19:33 -05:00
{
public class FunctionSubmodule : SubmoduleBase<ItemBase>
{
[ReadOnly]
public Dictionary<string, RuntimeFunctionUnit> functionUnits;
2026-01-03 18:19:39 -05:00
public RuntimeFunctionUnit mainFunction => functionUnits.Count > 0 ? functionUnits.Values.First() : null;
2025-11-25 08:19:33 -05:00
public RuntimeFunctionUnit this[string functionName] => functionUnits.ContainsKey(functionName) ? functionUnits[functionName] : null;
public FunctionSubmodule(ItemBase owner, FunctionData data) : base(owner)
{
functionUnits = new Dictionary<string, RuntimeFunctionUnit>();
2026-05-27 15:15:28 -04:00
foreach (var unit in data.functionUnitList)
2025-11-25 08:19:33 -05:00
{
2026-05-27 15:15:28 -04:00
functionUnits[unit.unitName] = new RuntimeFunctionUnit(this, unit);
2025-11-25 08:19:33 -05:00
}
}
public void Update(float deltaTime)
{
foreach (var unit in functionUnits.Values)
{
unit.Update(deltaTime);
}
}
}
public class RuntimeFunctionUnit : SubmoduleBase<FunctionSubmodule>
{
private CharacterBase character => owner.owner.player;
2025-12-23 19:47:06 -05:00
public FunctionData.FunctionUnit data;
2025-11-25 08:19:33 -05:00
public float currentCooldown;
public float maxCooldown;
2025-12-23 19:47:06 -05:00
public RuntimeFunctionUnit(FunctionSubmodule owner, FunctionData.FunctionUnit data) : base(owner)
2025-11-25 08:19:33 -05:00
{
this.data = data;
2026-05-27 15:15:28 -04:00
maxCooldown = data.cooldown;
2025-11-25 08:19:33 -05:00
currentCooldown = 0f;
}
public void Update(float deltaTime)
{
currentCooldown -= deltaTime;
2025-12-08 05:27:53 -05:00
currentCooldown = Mathf.Max(currentCooldown, 0f);
2025-11-25 08:19:33 -05:00
}
public bool IsAvailable()
{
bool cooldownAvailable = currentCooldown <= 0f;
2026-05-23 08:27:50 -04:00
bool energyAvailable = character.attributeSm[CharacterAttribute.Energy] >= GetEffectiveEnergyCost();
2026-05-27 15:15:28 -04:00
bool available = cooldownAvailable && energyAvailable;
if (!available)
{
if(character is Player && owner.owner is MainWeaponBase)
{
if (data.shownInUI || data.isMain)
{
PlayerCanvas.MainWeaponUIArea.functionIconDict[data.unitName].SetFrameOutline(0.25f, Color.red);
}
}
}
return available;
2025-11-25 08:19:33 -05:00
}
2025-12-08 05:27:53 -05:00
public RuntimeFunctionUnit Execute()
2025-11-25 08:19:33 -05:00
{
2025-12-08 05:27:53 -05:00
ResetCooldown();
ConsumeEnergy();
2026-05-27 15:15:28 -04:00
if(character is Player && owner.owner is MainWeaponBase)
{
if (data.shownInUI || data.isMain)
{
PlayerCanvas.MainWeaponUIArea.functionIconDict[data.unitName].SetFrameOutline(0.25f);
}
}
2025-11-25 08:19:33 -05:00
return this;
}
2026-05-27 15:15:28 -04:00
private const float MaxCooldownReduction = 0.9f;
2026-05-23 08:27:50 -04:00
private const float MaxEnergyCostReduction = 0.9f;
/// <summary> 计算应用 EnergyCostReduction 后的实际能量消耗。 </summary>
private float GetEffectiveEnergyCost()
{
2026-05-27 15:15:28 -04:00
float energyCostReduction = Mathf.Clamp(character.attributeSm[CharacterAttribute.EnergyCostReduction], 0f, MaxEnergyCostReduction);
return data.energyCost * (1f - energyCostReduction);
2026-05-23 08:27:50 -04:00
}
2025-12-08 05:27:53 -05:00
private void ResetCooldown()
2025-11-25 08:19:33 -05:00
{
2026-05-27 15:15:28 -04:00
float cooldownReduction = Mathf.Clamp(character.attributeSm[CharacterAttribute.CooldownReduction], 0f, MaxCooldownReduction);
currentCooldown = maxCooldown * (1f - cooldownReduction);
2025-12-08 05:27:53 -05:00
}
private void ConsumeEnergy()
{
2026-05-23 08:27:50 -04:00
float cost = GetEffectiveEnergyCost();
character.attributeSm[CharacterAttribute.Energy] -= cost;
// onEnergyChanged 已由 AttributeSubmodule 值变更回调自动触发
2025-11-25 08:19:33 -05:00
}
}
}