using System; using System.Collections.Generic; using System.Linq; using Cielonos.MainGame.Characters; using UniRx; using UnityEngine; namespace Cielonos.MainGame.Characters.Inventory { public partial class ComboSubmodule : SubmoduleBase { public Dictionary 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(); foreach (KeyValuePair treeData in asset.comboTrees) { comboTrees[treeData.Key] = treeData.Value.ToRuntime(this); comboTrees[treeData.Key].Reset(); } } } public partial class ComboSubmodule { public partial class ComboTree : SubmoduleBase { private Player player => owner.owner.player; private IDisposable comboTimer; private IDisposable suspender; private float resetTime; public List nodes; public Node lastNode; public Node currentNode; public ComboTree(ComboSubmodule owner, float resetTime) : base(owner) { this.resetTime = resetTime; this.nodes = new List(); } 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 { /// /// 设置连击计时器,在指定时间后重置连击树 /// /// 连击计时器持续时间,若小于等于0则使用默认时间 public void Setup(float overrideResetTime = -1) { overrideResetTime = overrideResetTime <= 0 ? resetTime : overrideResetTime; comboTimer = player.selfTimeSm.AddLocalTimer(overrideResetTime, Reset); } /// /// 暂停连击计时器,在指定时间后继续重新设置连击计时器 /// public void SuspendThenSetup(float duration) { comboTimer?.Dispose(); suspender?.Dispose(); suspender = player.selfTimeSm.AddLocalTimer(duration, () => Setup()); } /// /// 获取当前连招节点的引用名称 /// public string GetCurrentNodeName() { return currentNode.referenceName; } /// /// 获取当前连招节点的下一个节点的引用名称,如果没有符合条件的下一个节点,则返回首个节点的引用名称 /// 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(); } /// /// 根据操作指令进入下一个连招节点 /// /// 操作指令字符串,例如"L","R" /// 若无法进入下一个节点,是否返回首个节点 /// 是否成功进入下一个节点 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; } /// /// 直接设置连招节点 /// /// 节点索引 public void SetCombo(int index) { lastNode = currentNode; currentNode = nodes[index]; } /// /// 直接设置连招节点 /// /// 节点引用名称 public void SetCombo(string refName) { lastNode = currentNode; currentNode = nodes.Find(x => x.referenceName == refName); } /// /// 回退到上一个连招节点 /// public void RevertCombo() { currentNode = lastNode; } } public partial class ComboTree { [Serializable] public class Node { public int nodeIndex; public string referenceName; public List branches; public Node(int nodeIndex, string referenceName) { this.nodeIndex = nodeIndex; this.referenceName = referenceName; this.branches = new List(); } } [Serializable] public class Branch { public int nextNodeIndex; public string operation; public Branch(int nextNodeIndex, string operation) { this.nextNodeIndex = nextNodeIndex; this.operation = operation; } } } } }