Files
Cielonos/Assets/Scripts/MainGame/Items/Submodules/ComboSubmodule.cs
SoulliesOfficial 649b7a5ddc 更新
2026-05-23 08:27:50 -04:00

203 lines
6.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
using System.Linq;
using Cielonos.MainGame.Characters;
using UniRx;
using UnityEngine;
namespace Cielonos.MainGame.Inventory
{
public partial class ComboSubmodule : SubmoduleBase<ItemBase>
{
public Dictionary<string, ComboTree> comboTrees;
public ComboTree main => comboTrees["Main"];
public ComboTree this[string name] => comboTrees[name];
public ComboSubmodule(ItemBase owner, ComboData asset) : base(owner)
{
this.comboTrees = new Dictionary<string, ComboTree>();
foreach (KeyValuePair<string, ComboTreeData> treeData in asset.comboTrees)
{
comboTrees[treeData.Key] = treeData.Value.ToRuntime(this);
comboTrees[treeData.Key].Reset();
}
}
}
public partial class ComboSubmodule
{
public partial class ComboTree : SubmoduleBase<ComboSubmodule>
{
private Player player => owner.owner.player;
private IDisposable comboTimer;
private IDisposable suspender;
private float resetTime;
public List<Node> nodes;
public Node lastNode;
public Node currentNode;
public ComboTree(ComboSubmodule owner, float resetTime) : base(owner)
{
this.resetTime = resetTime;
this.nodes = new List<Node>();
}
public void AddNode(int index, string referenceName)
{
nodes.Add(new Node(index, referenceName));
}
public void AddBranch(int nodeIndex, int nextNodeIndex, string operation)
{
nodes[nodeIndex].branches.Add(new Branch(nextNodeIndex, operation));
}
public void RemoveBranch(int nodeIndex, int nextNodeIndex, string operation)
{
int branchIndex = nodes[nodeIndex].branches.FindIndex(x => x.nextNodeIndex == nextNodeIndex && x.operation == operation);
nodes[nodeIndex].branches.RemoveAt(branchIndex);
}
public void Reset()
{
currentNode = nodes[0];
}
}
public partial class ComboTree
{
/// <summary>
/// 设置连击计时器,在指定时间后重置连击树
/// </summary>
/// <param name="overrideResetTime">连击计时器持续时间若小于等于0则使用默认时间</param>
public void Setup(float overrideResetTime = -1)
{
overrideResetTime = overrideResetTime <= 0 ? resetTime : overrideResetTime;
comboTimer = player.selfTimeSm.AddLocalTimer(overrideResetTime, Reset);
}
/// <summary>
/// 暂停连击计时器,在指定时间后继续重新设置连击计时器
/// </summary>
public void SuspendThenSetup(float duration)
{
comboTimer?.Dispose();
suspender?.Dispose();
suspender = player.selfTimeSm.AddLocalTimer(duration, () => Setup());
}
/// <summary>
/// 获取当前连招节点的引用名称
/// </summary>
public string GetCurrentNodeName()
{
return currentNode.referenceName;
}
/// <summary>
/// 获取当前连招节点的下一个节点的引用名称,如果没有符合条件的下一个节点,则返回首个节点的引用名称
/// </summary>
public string GetNextNodeName(string operation)
{
foreach (var branch in currentNode.branches.Where(branch => branch.operation == operation))
{
return nodes[branch.nextNodeIndex].referenceName;
}
return nodes[0].branches.Where(branch => branch.operation == operation)
.Select(branch => nodes[branch.nextNodeIndex].referenceName).FirstOrDefault();
}
/// <summary>
/// 根据操作指令进入下一个连招节点
/// </summary>
/// <param name="operation">操作指令字符串,例如"L""R"</param>
/// <param name="autoReset">若无法进入下一个节点,是否返回首个节点</param>
/// <returns>是否成功进入下一个节点</returns>
public bool NextCombo(string operation, bool autoReset = true)
{
if (currentNode.branches.Count == 0)
{
Reset();
}
foreach (var branch in currentNode.branches.Where(branch => branch.operation == operation))
{
lastNode = currentNode;
currentNode = nodes[branch.nextNodeIndex];
return true;
}
if (autoReset)
{
Reset();
NextCombo(operation);
}
return false;
}
/// <summary>
/// 直接设置连招节点
/// </summary>
/// <param name="index">节点索引</param>
public void SetCombo(int index)
{
lastNode = currentNode;
currentNode = nodes[index];
}
/// <summary>
/// 直接设置连招节点
/// </summary>
/// <param name="refName">节点引用名称</param>
public void SetCombo(string refName)
{
lastNode = currentNode;
currentNode = nodes.Find(x => x.referenceName == refName);
}
/// <summary>
/// 回退到上一个连招节点
/// </summary>
public void RevertCombo()
{
currentNode = lastNode;
}
}
public partial class ComboTree
{
[Serializable]
public class Node
{
public int nodeIndex;
public string referenceName;
public List<Branch> branches;
public Node(int nodeIndex, string referenceName)
{
this.nodeIndex = nodeIndex;
this.referenceName = referenceName;
this.branches = new List<Branch>();
}
}
[Serializable]
public class Branch
{
public int nextNodeIndex;
public string operation;
public Branch(int nextNodeIndex, string operation)
{
this.nextNodeIndex = nextNodeIndex;
this.operation = operation;
}
}
}
}
}