using System.Collections.Generic; using System.Linq; using System.Threading; using Code.Game.Cleaning.Player; using Code.Infrastructure.App; using Code.Infrastructure.Camera; using Code.Infrastructure.Generators; using Code.Infrastructure.Input; using Code.Infrastructure.SceneLoader; using Code.Infrastructure.UI; using Code.Infrastructure.Utils; using Code.OfficeGame.BattleMode.Actions; using Code.OfficeGame.BattleMode.Actions.Attacks; using Code.OfficeGame.BattleMode.Actions.Deciders; using Code.OfficeGame.BattleMode.Actions.Player; using Code.OfficeGame.BattleMode.Marker; using Code.OfficeGame.BattleMode.Timeline; using Code.OfficeGame.BattleMode.UI; using Code.OfficeGame.Player; using Cysharp.Threading.Tasks; using KinematicCharacterController; using ObservableCollections; using R3; using Reflex.Core; using Reflex.Enums; using Reflex.Injectors; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.SceneManagement; using Resolution = Reflex.Enums.Resolution; namespace Code.Game.OfficeGame.GameStates { [State(typeof(AppStates), typeof(AppStateMachineContext))] public partial class BattleState { public BattleState(AppStateMachineContext context) : base(context) { } public override AppStates MyState => AppStates.BattleState; private BattleTimeline _battleTimeline; private CancellationTokenSource _battleTokenSource = new CancellationTokenSource(); public override async UniTask EnterState() { #if UNITY_EDITOR Context.InputService.EnableMap(ActionMappings.Debug); Context.InputService.BindActionPerformed((int)ActionMappings.Debug, (int)DebugActions.ToggleBattleMode, ToggleBattleMode); #endif Context.InputService.EnableMap(ActionMappings.BattleMode); ////// T var entities = Object.FindObjectsByType() .ToList(); Container container; if (Context.StateMachine.CurrentState == AppStates.Testing) { var gameplayContainer = Context.SceneContainerManager.ScenesContainers[SceneId.Testing]; var waitForContainer = Context.SceneContainerManager.ScenesContainers .ObserveDictionaryAdd() .Where(x => x.Key == SceneId.Battle) .Take(1) .WaitAsync() .AsUniTask(); var playerDecisionMarkerConfig = new SingleConfig(); var attackActionsConfigs = new MultipleConfig(); await UniTask.WhenAll( attackActionsConfigs.LoadConfigs(), playerDecisionMarkerConfig.LoadConfig()); BattleActionDecisionPanel battleActionDecisionPanel = (BattleActionDecisionPanel)await Context.UIFactory .LoadPanel(UIPanelType.BattleActionDecision, false); BattleTimelinePanel battleTimelinePanel = (BattleTimelinePanel)await Context.UIFactory .LoadPanel(UIPanelType.BattleTimelinePanel, false); void InstallExtra(Scene scene, ContainerBuilder builder) { builder.SetParent(gameplayContainer); builder.RegisterValue(attackActionsConfigs); builder.RegisterValue(playerDecisionMarkerConfig); builder.RegisterType(typeof(MarkerManager), Lifetime.Singleton, Resolution.Eager); builder.RegisterValue(battleActionDecisionPanel); builder.RegisterValue(battleTimelinePanel); builder.RegisterType(typeof(BattleActionMove), new[]{ typeof(BattleAction) }, Lifetime.Singleton, Resolution.Eager); builder.RegisterType(typeof(BattleActionWait), new[]{ typeof(BattleAction) }, Lifetime.Singleton, Resolution.Eager); builder.RegisterType(typeof(BattleActionNone), new[]{ typeof(BattleAction) }, Lifetime.Singleton, Resolution.Eager); builder.RegisterType(typeof(BattleActionPlayerAttackMMA), new[]{ typeof(BattleAction) }, Lifetime.Singleton, Resolution.Eager); builder.RegisterType(typeof(BattleActionStugger), new[]{ typeof(BattleAction) }, Lifetime.Singleton, Resolution.Eager); builder.RegisterType(typeof(BattleActionPositionDecider), new[]{ typeof(BattleActionDecider) } , Lifetime.Singleton, Resolution.Eager); builder.RegisterType(typeof(AsIsBattleActionDecider), new[]{ typeof(BattleActionDecider) } , Lifetime.Singleton, Resolution.Eager); builder.RegisterType(typeof(BattleTimeline), Lifetime.Singleton, Resolution.Eager); } await UniTask.WhenAll( Context.SceneLoader .LoadSceneAsync( SceneId.Battle, LoadSceneMode.Additive, true, InstallExtra), waitForContainer ); container = Context.SceneContainerManager.ScenesContainers[SceneId.Battle]; ///// T GameObjectInjector .InjectRecursiveMany( entities.Select(x => x.gameObject).ToList(), container); ///// _battleTokenSource = new(); _battleTimeline = container.Resolve(); Physics.simulationMode = SimulationMode.Script; KinematicCharacterSystem.EnsureCreation(); KinematicCharacterSystem.Settings.AutoSimulation = false; KinematicCharacterSystem.Settings.Interpolate = false; TogglePlayerBattleMode(container, false); await Context.Camera.SwitchState(CameraMode.BattleMode); foreach (var entity in entities) { entity.animator.enabled = false; } } else { container = Context.SceneContainerManager.ScenesContainers[SceneId.Battle]; } _battleTimeline?.RunBattleLoopAsync(entities, _battleTokenSource.Token).Forget(); await container.Resolve().Open(); } private void TogglePlayerBattleMode(Container container, bool enabled) { container.Resolve().Animator.enabled = enabled; container.Resolve().enabled = enabled; } private void ToggleBattleMode(InputAction.CallbackContext obj) { Context.StateMachine.SwitchState(AppStates.Testing).Forget(); } public override async UniTask ExitState() { if (Context.StateMachine.NextState == AppStates.Testing) { _battleTokenSource.Cancel(); _battleTokenSource.Dispose(); Physics.simulationMode = SimulationMode.FixedUpdate; KinematicCharacterSystem.Settings.AutoSimulation = true; KinematicCharacterSystem.Settings.Interpolate = true; var container = Context.SceneContainerManager.ScenesContainers[SceneId.Battle]; TogglePlayerBattleMode(container, true); await container.Resolve().Close(); // T var entities = Object.FindObjectsByType().ToList(); foreach (var entity in entities) { entity.animator.enabled = false; } await Context.SceneLoader.UnloadSceneAsync(SceneId.Battle); } #if UNITY_EDITOR Context.InputService.DisableMap(ActionMappings.Debug); Context.InputService.UnbindActionPerformed((int)ActionMappings.Debug, (int)DebugActions.ToggleBattleMode, ToggleBattleMode); #endif Context.InputService.DisableMap(ActionMappings.BattleMode); } } }