Files
Hasebe/Assets/Code/OfficeGame/BattleMode/BattleState.cs
T
2026-11-06 19:40:08 +03:00

215 lines
8.6 KiB
C#

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.Particles;
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<EntityProperties>()
.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<PlayerDecisionMarkerConfig>();
var attackActionsConfigs = new MultipleConfig<BattleActionParameters>();
await UniTask.WhenAll(
attackActionsConfigs.LoadConfigs(),
playerDecisionMarkerConfig.LoadConfig(),
Context.ParticleLoader.LoadParticleSystems(ParticlePartition.HitParticles));
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(RotationBattleActionDecider), 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<BattleTimeline>();
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<BattleTimelinePanel>().Open();
}
private void TogglePlayerBattleMode(Container container, bool enabled)
{
container.Resolve<EntityAnimator>().Animator.enabled = enabled;
container.Resolve<PlayerControlsProvider>().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<BattleTimelinePanel>().Close();
// T
var entities =
Object.FindObjectsByType<EntityProperties>().ToList();
foreach (var entity in entities)
{
entity.animator.enabled = false;
}
Context.ParticleLoader.ReleaseParticles(ParticlePartition.HitParticles);
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);
}
}
}