using System; using Cysharp.Threading.Tasks; using SepCore.Event; using SepCore.DataTable; using SepCore.Entity; using SepCore.Definition; using GameFramework.Fsm; using GameFramework.Procedure; using SepCore.EnemyManager; using SepCore.Simulation; using SepCore.Timer; using UnityEngine; namespace SepCore.Procedure { public class GameStateBattle : GameStateBase { public override GameStateType GameStateType => GameStateType.Battle; private EnemyManagerComponent _enemyManager; private int _currentLevel; private TimerHandle _levelTimerHandle; private Player Player => _procedureGame.Player; private ProcedureGame _procedureGame; public void AddBattleDuration(float seconds) { if (seconds <= 0f) return; float remaining = GameEntry.Timer.GetRemainingTime(_levelTimerHandle); if (remaining < 0f) return; GameEntry.Timer.ResetRemainingTime(_levelTimerHandle, remaining + seconds); } #region FSM public override void OnInit(ProcedureGame master) { _enemyManager = GameEntry.EnemyManager; _procedureGame = master; } public override void OnEnter() { _currentLevel = _procedureGame.CurrentLevel; var drLevel = GameEntry.DataTable.GetDataTableRow(_currentLevel); if (drLevel == null) { throw new Exception($"GameStateBattle.OnEnter: {_currentLevel} is not found."); } _levelTimerHandle = GameEntry.Timer.ScheduleOnce(drLevel.Duration, OnLevelTimeUp, this); _enemyManager.OnInit(drLevel, Player); if (Player != null) Player.Enable = true; if (Application.isMobilePlatform) { GameEntry.UIRouter.OpenUIAsync(UIFormType.JoystickForm).Forget(); } } public override void OnUpdate(float elapseSeconds, float realElapseSeconds) { _enemyManager.OnUpdate(elapseSeconds, realElapseSeconds); SimulationWorld simulationWorld = GameEntry.SimulationWorld; if (simulationWorld != null) { Vector3 playerPosition = Player != null ? Player.CachedTransform.position : Vector3.zero; simulationWorld.Tick(new SimulationTickContext(elapseSeconds, realElapseSeconds, playerPosition)); } int timeLeft = Mathf.Max(0, (int)GameEntry.Timer.GetRemainingTime(_levelTimerHandle)); GameEntry.Event.Fire(this, LevelProcessEventArgs.Create(timeLeft)); } private void OnLevelTimeUp() { _procedureGame.BattleToShopOrLevelUp(); } public override void OnLeave() { GameEntry.UIRouter.CloseUIAsync(UIFormType.JoystickForm).Forget(); GameEntry.Timer.Cancel(_levelTimerHandle); _levelTimerHandle = TimerHandle.Invalid; // 隐藏所有敌人实体 _enemyManager.OnReset(); // 停止玩家逻辑 Player.Enable = false; // 隐藏所有掉落物实体 var entities = GameEntry.Entity.GetEntityGroup("Drop").GetAllEntities(); foreach (var entity in entities) { GameEntry.Entity.HideEntity(entity.Id); } HideEntityGroup("Bullet"); HideEntityGroup("Projectile"); HideEntityGroup("EnemyProjectile"); } public override void OnDestroy() { _enemyManager = null; _procedureGame = null; } private static void HideEntityGroup(string groupName) { var entityGroup = GameEntry.Entity.GetEntityGroup(groupName); var entities = entityGroup?.GetAllEntities(); if (entities == null) { return; } foreach (var entity in entities) { GameEntry.Entity.HideEntity(entity.Id); } } #endregion } }