using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using Cielonos.MainGame.Characters.Inventory; using Opsive.BehaviorDesigner.Runtime; using Sirenix.OdinInspector; using SLSUtilities.FunctionalAnimation; using UniRx; using UnityEngine; using UnityEngine.AI; namespace Cielonos.MainGame.Characters { public partial class Automata : CharacterBase { public Player player => MainGameManager.Player; [TitleGroup("Data & Presets")] public FuncAnimDataCollection fullBodyFuncAnims; public FuncAnimDataCollection upperBodyFuncAnims; public AttackData attackData; [HideInInspector] private List registeredFunctionNames = new List(); [TitleGroup("Submodules")] public ActionRecordSubmodule actionRecordSm; [TitleGroup("Subcontrollers")] public BehaviorSubcontroller behaviorSc; public BehaviorTree behaviorTree; public NavMeshAgent navMeshAgent; private float getHitTimer; protected override void Start() { base.Start(); RegisterFuncAnims(); RegisterFunctionsToAnimSc(); } protected override void InitializeSubmodules() { base.InitializeSubmodules(); actionRecordSm = new ActionRecordSubmodule(this); } protected override void Update() { base.Update(); UpdateGetHit(); } } public partial class Automata { public override bool GetHit(BreakthroughType breakthroughType, out float recoveryTime, DisruptionType disruptionType = DisruptionType.NormalExternal, Vector3 direction = default, string funcAnimName = "") { if (string.IsNullOrEmpty(funcAnimName)) { funcAnimName = GetHitFuncAnimName(breakthroughType, direction); } if (base.GetHit(breakthroughType, out recoveryTime, disruptionType, direction, funcAnimName)) { if (getHitTimer <= 0) { if(navMeshAgent.enabled) navMeshAgent.isStopped = true; getHitTimer = recoveryTime; } else { getHitTimer = Mathf.Max(getHitTimer, recoveryTime); } return true; } return false; } protected virtual void UpdateGetHit() { getHitTimer -= selfTimeSm.DeltaTime; if (getHitTimer <= 0) { if(navMeshAgent.enabled) navMeshAgent.isStopped = false; //statusSm.RemoveStatus(StatusType.Stun); } } } public partial class Automata { public override void Die() { if (BattleManager.EnemySm.activeEnemiesList.Contains(this)) { BattleManager.EnemySm.activeEnemiesList.Remove(this); } if (fullBodyFuncAnims.animDataList.Any(funcAnimData => funcAnimData.animInfo.animationName == "Death")) { animationSc.fullBodyFuncAnimSm.Play("Death"); behaviorTree.StopBehavior(); navMeshAgent.isStopped = true; collisionSc.DisableAllColliders(); } statusSm.isDead = true; //base.Die(); } } public partial class Automata { public Vector3 PredictPlayerPosition(float timeAhead) { Vector3 currentPosition = player.centerPoint.position; Vector3 currentVelocity = player.landMovementSc.horizontalMovement / player.selfTimeSm.DeltaTime; return currentPosition + currentVelocity * timeAhead; } } public partial class Automata { public void RegisterFuncAnims() { if (fullBodyFuncAnims == null) return; foreach (FuncAnimData funcAnim in fullBodyFuncAnims.animDataList) { animationSc.fullBodyFuncAnimSm.Add(funcAnim); } /*foreach (FuncAnimData funcAnim in upperBodyFuncAnims.animDataList) { animationSc.upperBodyFuncAnimSm.Add(funcAnim); }*/ } protected virtual void RegisterFunctionsToAnimSc(params Action[] functions) { if (fullBodyFuncAnims == null) return; RegisterFunctionsToAnimSc(); foreach (Action function in functions) { string functionName = function.Method.Name; if (!animationSc.registeredFunctions.TryAdd(functionName, anim => function())) { Debug.LogWarning($"Function {functionName} is already registered."); } else { registeredFunctionNames.Add(functionName); } } } protected virtual void RegisterFunctionsToAnimSc() { if (fullBodyFuncAnims == null) return; foreach (CustomFunction function in fullBodyFuncAnims.preloadFunctions) { string functionName = function.functionName; string FAPF_functionName = new StringBuilder(functionName).Insert(0, "FAPF_").ToString(); MethodInfo method = GetType().GetMethod(FAPF_functionName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method == null) { Debug.LogWarning($"Function {functionName} not found in {this.GetType().Name}. Skipping registration."); continue; } Action action = Delegate.CreateDelegate(typeof(Action), this, method) as Action; registeredFunctionNames.Add(functionName); animationSc.registeredFunctions.TryAdd(functionName, action); } } protected void RemoveAllRegisteredFunctions() { foreach (string functionName in registeredFunctionNames) { if (!animationSc.registeredFunctions.Remove(functionName)) { Debug.LogWarning($"Function {functionName} is not found."); } } registeredFunctionNames.Clear(); } } }