using System; using System.Collections.Generic; using System.Linq; using Cielonos.MainGame.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 List fullBodyFuncAnims = new List(); public AttackData attackData; [HideInInspector] private List registeredFunctionNames = new List(); [TitleGroup("Submodules")] public ActionRecordSubmodule actionRecordSm; [TitleGroup("Subcontrollers")] public BehaviorTree behaviorTree; public NavMeshAgent navMeshAgent; private float getHitTimer; protected override void Start() { base.Start(); //navMeshAgent.baseOffset = -0.08f; RegisterFullBodyFuncAnims(); //RegisterFunctionsToAnimSc(LightAttack0); } 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) { if (base.GetHit(breakthroughType, out recoveryTime, disruptionType, direction)) { if (getHitTimer <= 0) { if(navMeshAgent.enabled) navMeshAgent.isStopped = true; statusSm.AddStatus(StatusType.Stun); getHitTimer = recoveryTime; } else { getHitTimer = Mathf.Max(getHitTimer, recoveryTime); } } return false; } protected virtual void UpdateGetHit() { getHitTimer -= player.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.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 RegisterFullBodyFuncAnims() { foreach (FuncAnimData funcAnim in fullBodyFuncAnims) { animationSc.fullBodyFuncAnimSm.Add(funcAnim); } } protected virtual void RegisterFunctionsToAnimSc(params Action[] functions) { 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(params Action[] functions) { foreach (Action function in functions) { string functionName = function.Method.Name; if (!animationSc.registeredFunctions.TryAdd(functionName, function)) { Debug.LogWarning($"Function {functionName} is already registered."); } else { registeredFunctionNames.Add(functionName); } } } protected void RemoveAllRegisteredFunctions() { foreach (string functionName in registeredFunctionNames) { if (!animationSc.registeredFunctions.Remove(functionName)) { Debug.LogWarning($"Function {functionName} is not found."); } } registeredFunctionNames.Clear(); } protected virtual void RemoveFunctionsFromAnimSc(params Action[] functions) { foreach (Action function in functions) { string functionName = function.Method.Name; if (!animationSc.registeredFunctions.Remove(functionName)) { Debug.LogWarning($"Function {functionName} is not found."); } } } } }