diff --git a/PataNext.Export.Desktop/Updater/SquirrelUpdater.cs b/PataNext.Export.Desktop/Updater/SquirrelUpdater.cs index 0778fdfa..a4fb0e33 100644 --- a/PataNext.Export.Desktop/Updater/SquirrelUpdater.cs +++ b/PataNext.Export.Desktop/Updater/SquirrelUpdater.cs @@ -75,7 +75,7 @@ private async Task checkForUpdate(bool deltaPatching = true) else { notification.State = ProgressNotificationState.Cancelled; - notification.Text = "Update failed :("; + notification.Text = "Update failed :(\nRe-Downloading the full setup is recommended."; Logger.Error(ex, "Update failed!"); } } diff --git a/PataNext.Feature.RhythmEngineAudio/BGM/Directors/BgmDefaultDirectorSoundtrackSystem.cs b/PataNext.Feature.RhythmEngineAudio/BGM/Directors/BgmDefaultDirectorSoundtrackSystem.cs index 9c91889f..f57e72d1 100644 --- a/PataNext.Feature.RhythmEngineAudio/BGM/Directors/BgmDefaultDirectorSoundtrackSystem.cs +++ b/PataNext.Feature.RhythmEngineAudio/BGM/Directors/BgmDefaultDirectorSoundtrackSystem.cs @@ -91,7 +91,10 @@ protected override void OnUpdatePass() var comboState = GameWorld.GetComponentData(LocalEngine); if (state.CurrentBeat < 0) + { + AudioPlayerUtility.Stop(audioPlayer); return; + } var targetAudio = m_LastClip; diff --git a/PataNext.Feature.RhythmEngineAudio/SimulationSystems/ShoutDrumSystem.cs b/PataNext.Feature.RhythmEngineAudio/SimulationSystems/ShoutDrumSystem.cs index 9d86d30a..98098a91 100644 --- a/PataNext.Feature.RhythmEngineAudio/SimulationSystems/ShoutDrumSystem.cs +++ b/PataNext.Feature.RhythmEngineAudio/SimulationSystems/ShoutDrumSystem.cs @@ -86,7 +86,7 @@ protected override void OnDependenciesResolved(IEnumerable dependencies) public override bool CanUpdate() { - return LocalEngine != default && base.CanUpdate(); + return LocalEngine != default && LocalInformation.Elapsed >= TimeSpan.Zero && base.CanUpdate(); } private EntityQuery abilityQuery; diff --git a/PataNext.Simulation.Client/Systems/Inputs/RegisterRhythmEngineInputSystem.cs b/PataNext.Simulation.Client/Systems/Inputs/RegisterRhythmEngineInputSystem.cs index b164c24e..27b59aea 100644 --- a/PataNext.Simulation.Client/Systems/Inputs/RegisterRhythmEngineInputSystem.cs +++ b/PataNext.Simulation.Client/Systems/Inputs/RegisterRhythmEngineInputSystem.cs @@ -38,6 +38,7 @@ using StormiumTeam.GameBase.Camera.Components; using StormiumTeam.GameBase.Roles.Components; using StormiumTeam.GameBase.Roles.Descriptions; +using StormiumTeam.GameBase.SystemBase; using StormiumTeam.GameBase.Time; using StormiumTeam.GameBase.Time.Components; @@ -61,7 +62,7 @@ public struct JInputSettings [UpdateAfter(typeof(SetGameTimeSystem))] [UpdateAfter(typeof(ReceiveInputDataSystem))] [UpdateBefore(typeof(ManageComponentTagSystem))] - public class RegisterRhythmEngineInputSystem : AppSystem, IRhythmEngineSimulationPass + public class RegisterRhythmEngineInputSystem : GameAppSystem, IRhythmEngineSimulationPass { private InputDatabase inputDb; private IManagedWorldTime time; @@ -69,7 +70,7 @@ public class RegisterRhythmEngineInputSystem : AppSystem, IRhythmEngineSimulatio private PlayableUnitProvider playableUnitProvider; private AbilityCollectionSystem abilityCollectionSystem; - private IScheduler scheduler; + private IScheduler scheduler; private GameHostModule module; private JInputSettings inputSettings; @@ -77,12 +78,11 @@ public class RegisterRhythmEngineInputSystem : AppSystem, IRhythmEngineSimulatio public RegisterRhythmEngineInputSystem(WorldCollection collection) : base(collection) { DependencyResolver.Add(() => ref inputDb); - DependencyResolver.Add(() => ref gameWorld); DependencyResolver.Add(() => ref time); DependencyResolver.Add(() => ref playableUnitProvider); DependencyResolver.Add(() => ref abilityCollectionSystem); - + DependencyResolver.Add(() => ref scheduler); DependencyResolver.Add(() => ref module); } @@ -93,9 +93,6 @@ public RegisterRhythmEngineInputSystem(WorldCollection collection) : base(collec private Entity ability1Action; private Entity ability2Action; - private GameWorld gameWorld; - private GameEntity gameEntityTest; - private int spawnInFrame; protected override void OnDependenciesResolved(IEnumerable dependencies) @@ -103,7 +100,7 @@ protected override void OnDependenciesResolved(IEnumerable dependencies) base.OnDependenciesResolved(dependencies); spawnInFrame = 10; - + module.Storage.Subscribe((_, storage) => { module.Storage.UnsubscribeCurrent(); @@ -115,13 +112,12 @@ protected override void OnDependenciesResolved(IEnumerable dependencies) private void CreateInputs(IStorage storage) { rhythmActionMap = new Dictionary(); - + using var stream = new MemoryStream(storage.GetFilesAsync("input.json").Result.First().GetContentAsync().Result); using var reader = new JsonTextReader(new StreamReader(stream)); - + var serializer = new JsonSerializer(); var input = serializer.Deserialize(reader); - Console.WriteLine(input.SliderSensibility); static CInput[] ct(IEnumerable map) => map.Select(str => new CInput(str)).ToArray(); @@ -130,11 +126,11 @@ private void CreateInputs(IStorage storage) rhythmActionMap[1] = inputDb.RegisterSingle(new RhythmInputAction.Layout(lyt, ct(input.PonKeys))); rhythmActionMap[2] = inputDb.RegisterSingle(new RhythmInputAction.Layout(lyt, ct(input.DonKeys))); rhythmActionMap[3] = inputDb.RegisterSingle(new RhythmInputAction.Layout(lyt, ct(input.ChakaKeys))); - + ability0Action = inputDb.RegisterSingle(new PressAction.Layout(lyt, ct(input.Ability0Keys))); ability1Action = inputDb.RegisterSingle(new PressAction.Layout(lyt, ct(input.Ability1Keys))); ability2Action = inputDb.RegisterSingle(new PressAction.Layout(lyt, ct(input.Ability2Keys))); - + panningAction = inputDb.RegisterSingle(new AxisAction.Layout(lyt, ct(input.PanningNegativeKeys), ct(input.PanningPositiveKeys))); inputSettings = input; @@ -147,140 +143,6 @@ protected override void OnUpdate() return; spawnInFrame = -999; - var localKitDb = new GameResourceDb(gameWorld); - var localAttachDb = new GameResourceDb(gameWorld); - var localEquipDb = new GameResourceDb(gameWorld); - - gameEntityTest = gameWorld.CreateEntity(); - gameWorld.AddComponent(gameEntityTest, new PlayerDescription()); - gameWorld.AddComponent(gameEntityTest, new PlayerInputComponent()); - gameWorld.AddComponent(gameEntityTest, new PlayerIsLocal()); - - var unitTarget = gameWorld.CreateEntity(); - gameWorld.AddComponent(unitTarget, new UnitTargetDescription()); - gameWorld.AddComponent(unitTarget, new Position()); - gameWorld.AddComponent(unitTarget, new Relative(gameEntityTest)); - - var rhythmEngine = gameWorld.CreateEntity(); - gameWorld.AddComponent(rhythmEngine, new RhythmEngineDescription()); - gameWorld.AddComponent(rhythmEngine, new RhythmEngineController {State = RhythmEngineState.Playing, StartTime = time.Total.Add(TimeSpan.FromSeconds(2))}); - gameWorld.AddComponent(rhythmEngine, new RhythmEngineSettings {BeatInterval = TimeSpan.FromSeconds(0.5), MaxBeat = 4}); - gameWorld.AddComponent(rhythmEngine, new RhythmEngineLocalState()); - gameWorld.AddComponent(rhythmEngine, new RhythmEngineExecutingCommand()); - gameWorld.AddComponent(rhythmEngine, new Relative(gameEntityTest)); - gameWorld.AddComponent(rhythmEngine, gameWorld.AsComponentType()); - gameWorld.AddComponent(rhythmEngine, gameWorld.AsComponentType()); - gameWorld.AddComponent(rhythmEngine, new GameCommandState()); - gameWorld.AddComponent(rhythmEngine, new IsSimulationOwned()); - GameCombo.AddToEntity(gameWorld, rhythmEngine); - RhythmSummonEnergy.AddToEntity(gameWorld, rhythmEngine); - - for (var i = 0; i != 1; i++) - { - var unit = playableUnitProvider.SpawnEntityWithArguments(new PlayableUnitProvider.Create - { - Statistics = new UnitStatistics - { - BaseWalkSpeed = 2, - FeverWalkSpeed = 2.2f, - MovementAttackSpeed = 3.1f, - Weight = 8.5f, - }, - Direction = UnitDirection.Right - }); - gameWorld.GetComponentData(unit).Value.X += 8; - gameWorld.GetComponentData(unitTarget).Value.X -= 8; - - gameWorld.AddComponent(unit, new UnitCurrentKit(localKitDb.GetOrCreate(new UnitKitResourceKey("taterazay")))); - gameWorld.AddComponent(unit, new Relative(gameEntityTest)); - gameWorld.AddComponent(unit, new Relative(unitTarget)); - gameWorld.AddComponent(unit, new UnitEnemySeekingState()); - gameWorld.AddComponent(unit, new UnitTargetOffset()); - gameWorld.AddComponent(unit, new UnitTargetControlTag()); - - var displayedEquip = gameWorld.AddBuffer(unit); - displayedEquip.Add(new UnitDisplayedEquipment - { - Attachment = localAttachDb.GetOrCreate("Mask"), - Resource = localEquipDb.GetOrCreate("Masks/n_kibadda") - }); - displayedEquip.Add(new UnitDisplayedEquipment - { - Attachment = localAttachDb.GetOrCreate("LeftEquipment"), - Resource = localEquipDb.GetOrCreate("Shields/default_shield") - }); - displayedEquip.Add(new UnitDisplayedEquipment - { - Attachment = localAttachDb.GetOrCreate("RightEquipment"), - Resource = localEquipDb.GetOrCreate("Swords/default_sword") - }); - - abilityCollectionSystem.SpawnFor("march", unit); - abilityCollectionSystem.SpawnFor("backward", unit); - abilityCollectionSystem.SpawnFor("retreat", unit); - abilityCollectionSystem.SpawnFor("jump", unit); - abilityCollectionSystem.SpawnFor("party", unit); - abilityCollectionSystem.SpawnFor("charge", unit); - abilityCollectionSystem.SpawnFor("CTate.BasicDefendFrontal", unit); - abilityCollectionSystem.SpawnFor("CTate.BasicDefendStay", unit, AbilitySelection.Top); - abilityCollectionSystem.SpawnFor("CTate.EnergyField", unit); - - gameWorld.AddComponent(gameEntityTest, new ServerCameraState - { - Data = - { - Mode = CameraMode.Forced, - Offset = RigidTransform.Identity, - Target = unit - } - }); - - gameWorld.AddComponent(unit, new Relative(rhythmEngine)); - } - - // No favor - for (var i = 0; i != 32; i++) - { - var unit = playableUnitProvider.SpawnEntityWithArguments(new PlayableUnitProvider.Create - { - Statistics = new UnitStatistics - { - BaseWalkSpeed = 0.75f, - FeverWalkSpeed = 0.75f, - MovementAttackSpeed = 0.75f, - Weight = 8.5f, - }, - Direction = UnitDirection.Right - }); - - var tt = gameWorld.CreateEntity(); - gameWorld.AddComponent(tt, new UnitTargetDescription()); - gameWorld.AddComponent(tt, new Position()); - gameWorld.GetComponentData(tt).Value.X = i * 10; - - gameWorld.AddComponent(unit, new UnitCurrentKit(localKitDb.GetOrCreate(new UnitKitResourceKey("yarida")))); - gameWorld.AddComponent(unit, new UnitEnemySeekingState()); - gameWorld.AddComponent(unit, new UnitTargetOffset()); - gameWorld.AddComponent(unit, new Relative(tt)); - - var displayedEquip = gameWorld.AddBuffer(unit); - displayedEquip.Add(new UnitDisplayedEquipment - { - Attachment = localAttachDb.GetOrCreate("Mask"), - Resource = localEquipDb.GetOrCreate("Masks/n_yarida") - }); - displayedEquip.Add(new UnitDisplayedEquipment - { - Attachment = localAttachDb.GetOrCreate("RightEquipment"), - Resource = localEquipDb.GetOrCreate("Spears/default_spear") - }); - displayedEquip.Add(new UnitDisplayedEquipment - { - Attachment = localAttachDb.GetOrCreate("LeftEquipment"), - Resource = localEquipDb.GetOrCreate("Masks/n_taterazay") - }); - } - /*Console.WriteLine("BEGIN"); foreach (var pass in World.DefaultSystemCollection.Passes) { @@ -310,16 +172,20 @@ public void OnRhythmEngineSimulationPass() return; GameTime gameTime = default; - foreach (var entity in gameWorld.QueryEntityWith(stackalloc[] {gameWorld.AsComponentType()})) + foreach (var entity in GameWorld.QueryEntityWith(stackalloc[] {GameWorld.AsComponentType()})) { - gameTime = gameWorld.GetComponentData(entity); + gameTime = GameWorld.GetComponentData(entity); break; } if (gameTime.Frame == default) return; - ref var input = ref gameWorld.GetComponentData(gameEntityTest); + var query = GameWorld.QueryEntityWith(stackalloc[] {AsComponentType()}); + if (!query.TryGetFirst(out var playerEntity)) + return; + + ref var input = ref GameWorld.GetComponentData(playerEntity); input.Panning = panningAction.Get().Value; if (ability0Action.Get().HasBeenPressed) diff --git a/PataNext.Simulation.Mixed/Components/GameModes/YaridaTrainingGameModeData.cs b/PataNext.Simulation.Mixed/Components/GameModes/YaridaTrainingGameModeData.cs new file mode 100644 index 00000000..fdfae89a --- /dev/null +++ b/PataNext.Simulation.Mixed/Components/GameModes/YaridaTrainingGameModeData.cs @@ -0,0 +1,27 @@ +using GameHost.Simulation.Features.ShareWorldState.BaseSystems; +using GameHost.Simulation.TabEcs.Interfaces; + +namespace PataNext.Module.Simulation.Components.GameModes +{ + public struct YaridaTrainingGameModeData : IComponentData + { + public enum EPhase + { + Waiting = 0, + March = 1, + + // huehuehuehuheuheueheuheuehuheueheuheuehuehueheueheuheuheuhue + Backward = 2 + } + + public EPhase Phase; + public float CurrUberHeroPos; + public int YaridaOvertakeCount; + + public float LastCheckpointScore; + public float LastCheckpointTime; + + public class Register : RegisterGameHostComponentData + {} + } +} \ No newline at end of file diff --git a/PataNext.Simulation.Mixed/CustomModule.cs b/PataNext.Simulation.Mixed/CustomModule.cs index 8cf6546b..9bdf7599 100644 --- a/PataNext.Simulation.Mixed/CustomModule.cs +++ b/PataNext.Simulation.Mixed/CustomModule.cs @@ -60,6 +60,9 @@ public CustomModule(Entity source, Context ctxParent, GameHostModuleDescription simulationApplication.Data.Collection.GetOrCreate(typeof(Game.RhythmEngine.Systems.GetNextCommandEngineSystem)); simulationApplication.Data.Collection.GetOrCreate(typeof(Game.RhythmEngine.Systems.ApplyCommandEngineSystem)); simulationApplication.Data.Collection.GetOrCreate(typeof(Game.RhythmEngine.Systems.RhythmEngineResizeCommandBufferSystem)); + + simulationApplication.Data.Collection.GetOrCreate(typeof(GameModes.YaridaTrainingGameMode)); + simulationApplication.Data.Collection.GetOrCreate(typeof(GameModes.StartYaridaTrainingGameMode)); } } } diff --git a/PataNext.Simulation.Mixed/Game/RhythmEngine/Systems/OnInputForRhythmEngine.cs b/PataNext.Simulation.Mixed/Game/RhythmEngine/Systems/OnInputForRhythmEngine.cs index ef660fe5..94a92f10 100644 --- a/PataNext.Simulation.Mixed/Game/RhythmEngine/Systems/OnInputForRhythmEngine.cs +++ b/PataNext.Simulation.Mixed/Game/RhythmEngine/Systems/OnInputForRhythmEngine.cs @@ -40,6 +40,8 @@ public override void OnRhythmEngineSimulationPass() ref var executing = ref GameWorld.GetComponentData(entity); var renderBeat = RhythmEngineUtility.GetFlowBeat(state, settings); + if (renderBeat < 0) + return; var progressionBuffer = GameWorld.GetBuffer(entity); var predictedBuffer = GameWorld.GetBuffer(entity); diff --git a/PataNext.Simulation.Mixed/Game/RhythmEngine/Systems/ProcessEngineSystem.cs b/PataNext.Simulation.Mixed/Game/RhythmEngine/Systems/ProcessEngineSystem.cs index 6af261b2..7caa742b 100644 --- a/PataNext.Simulation.Mixed/Game/RhythmEngine/Systems/ProcessEngineSystem.cs +++ b/PataNext.Simulation.Mixed/Game/RhythmEngine/Systems/ProcessEngineSystem.cs @@ -1,4 +1,5 @@ -using GameHost.Core; +using System; +using GameHost.Core; using GameHost.Core.Ecs; using GameHost.Simulation.Utility.EntityQuery; using GameHost.Worlds.Components; @@ -25,7 +26,6 @@ public override void OnRhythmEngineSimulationPass() foreach (var entity in GameWorld.QueryEntityWith(stackalloc[] { - GameWorld.AsComponentType(), GameWorld.AsComponentType(), GameWorld.AsComponentType(), GameWorld.AsComponentType() @@ -40,11 +40,19 @@ public override void OnRhythmEngineSimulationPass() var previousBeats = RhythmEngineUtility.GetActivationBeat(previous, settings.BeatInterval); state.Elapsed = worldTime.Total - controller.StartTime; + if (state.Elapsed < TimeSpan.Zero && HasComponent(entity)) + GameWorld.RemoveComponent(entity, AsComponentType()); var currentBeats = RhythmEngineUtility.GetActivationBeat(state, settings); if (previousBeats != currentBeats) state.NewBeatTick = (uint) gameTime.Frame; state.CurrentBeat = currentBeats; + + if (!HasComponent(entity)) + { + state.RecoveryActivationBeat = -1; + state.LastPressure = default; + } } foreach (var entity in GameWorld.QueryEntityWith(stackalloc[] diff --git a/PataNext.Simulation.Mixed/GameModes/StartYaridaTrainingGameMode.cs b/PataNext.Simulation.Mixed/GameModes/StartYaridaTrainingGameMode.cs new file mode 100644 index 00000000..c878fabd --- /dev/null +++ b/PataNext.Simulation.Mixed/GameModes/StartYaridaTrainingGameMode.cs @@ -0,0 +1,28 @@ +using GameHost.Core.Ecs; + +namespace PataNext.Module.Simulation.GameModes +{ + public class StartYaridaTrainingGameMode : AppSystem + { + private YaridaTrainingGameMode trainingGameMode; + private int frame; + + private const int targetFrame = 10; + + public StartYaridaTrainingGameMode(WorldCollection collection) : base(collection) + { + DependencyResolver.Add(() => ref trainingGameMode); + } + + protected override void OnUpdate() + { + base.OnUpdate(); + + if (frame >= 0 && frame++ > targetFrame) + { + frame = -1; + trainingGameMode.Start(64); + } + } + } +} \ No newline at end of file diff --git a/PataNext.Simulation.Mixed/GameModes/YaridaTrainingGameMode.cs b/PataNext.Simulation.Mixed/GameModes/YaridaTrainingGameMode.cs new file mode 100644 index 00000000..8c54fa2a --- /dev/null +++ b/PataNext.Simulation.Mixed/GameModes/YaridaTrainingGameMode.cs @@ -0,0 +1,322 @@ +using System; +using System.Collections.Generic; +using System.Numerics; +using BepuUtilities; +using GameHost.Core.Ecs; +using GameHost.Simulation.TabEcs; +using GameHost.Simulation.TabEcs.Interfaces; +using GameHost.Simulation.Utility.Resource; +using GameHost.Worlds.Components; +using PataNext.Module.Simulation.Components; +using PataNext.Module.Simulation.Components.GameModes; +using PataNext.Module.Simulation.Components.GamePlay.Abilities; +using PataNext.Module.Simulation.Components.GamePlay.RhythmEngine; +using PataNext.Module.Simulation.Components.GamePlay.Units; +using PataNext.Module.Simulation.Components.Roles; +using PataNext.Module.Simulation.Components.Units; +using PataNext.Module.Simulation.Game.Providers; +using PataNext.Module.Simulation.Resources; +using PataNext.Module.Simulation.Resources.Keys; +using PataNext.Module.Simulation.Systems; +using PataNext.Simulation.mixed.Components.GamePlay.RhythmEngine; +using StormiumTeam.GameBase.Camera.Components; +using StormiumTeam.GameBase.Roles.Components; +using StormiumTeam.GameBase.Roles.Descriptions; +using StormiumTeam.GameBase.SystemBase; +using MathHelper = StormiumTeam.GameBase.MathHelper; + +namespace PataNext.Module.Simulation.GameModes +{ + public struct ReachScore : IComponentData + { + public float Value; + } + + public class YaridaTrainingGameMode : GameAppSystem + { + private IManagedWorldTime worldTime; + + private PlayableUnitProvider playableUnitProvider; + private AbilityCollectionSystem abilityCollectionSystem; + + public YaridaTrainingGameMode(WorldCollection collection) : base(collection) + { + DependencyResolver.Add(() => ref worldTime); + + DependencyResolver.Add(() => ref playableUnitProvider); + DependencyResolver.Add(() => ref abilityCollectionSystem); + } + + GameResourceDb localKitDb; + GameResourceDb localAttachDb; + GameResourceDb localEquipDb; + + protected override void OnDependenciesResolved(IEnumerable dependencies) + { + base.OnDependenciesResolved(dependencies); + + localKitDb = new GameResourceDb(GameWorld); + localAttachDb = new GameResourceDb(GameWorld); + localEquipDb = new GameResourceDb(GameWorld); + } + + private GameEntity GameMode; + private GameEntity RhythmEngine; + private GameEntity UberHero; + private GameEntity[] Yarida; + + // will be used to check if the player want to forfeit + private GameEntity RetreatAbility; + + public override bool CanUpdate() + { + return GameWorld.Contains(GameMode) && base.CanUpdate(); + } + + private TimeSpan startTime; + protected override void OnUpdate() + { + base.OnUpdate(); + + ref var gmData = ref GetComponentData(GameMode); + ref var uberHeroPosition = ref GetComponentData(UberHero).Value; + + gmData.CurrUberHeroPos = uberHeroPosition.X; + + switch (gmData.Phase) + { + case YaridaTrainingGameModeData.EPhase.Waiting: + { + if (uberHeroPosition.X >= 0) + { + startTime = worldTime.Total; + + gmData.Phase = YaridaTrainingGameModeData.EPhase.March; + gmData.YaridaOvertakeCount = -1; + foreach (var unit in Yarida) + { + GetComponentData(unit).MovementAttackSpeed = 1f; + GetComponentData(unit).Value = 1; + } + } + else + { + foreach (var unit in Yarida) + { + GetComponentData(unit).MovementAttackSpeed = 0; + GetComponentData(unit).Value = new Vector3(10, 0 ,0); + } + } + + break; + } + case YaridaTrainingGameModeData.EPhase.March: + { + // forfeit if true + if (GetComponentData(RetreatAbility).IsActive) + { + GetComponentData(RhythmEngine).StartTime = worldTime.Total.Add(TimeSpan.FromSeconds(2)); + + gmData.Phase = YaridaTrainingGameModeData.EPhase.Waiting; + + uberHeroPosition.X = -10; + GetComponentData(GetComponentData>(UberHero).Target).Value.X = -10; + } + + for (var i = 0; i < Yarida.Length; i++) + { + var unit = Yarida[i]; + var position = GetComponentData(unit).Value; + var target = GetComponentData>(unit); + var targetPos = GetComponentData(target.Target).Value; + if (uberHeroPosition.X >= targetPos.X - 0.33f) + { + gmData.YaridaOvertakeCount = Math.Max(gmData.YaridaOvertakeCount, i); + gmData.LastCheckpointTime = (float) (worldTime.Total - startTime).TotalSeconds; + gmData.LastCheckpointScore = GetComponentData(unit).Value; + } + else if (gmData.YaridaOvertakeCount < i && uberHeroPosition.X > position.X + 0.1f) + { + var checkpointPos = 20 + gmData.YaridaOvertakeCount * 10; + + uberHeroPosition.X = checkpointPos; + GetComponentData(GetComponentData>(UberHero).Target).Value.X = checkpointPos; + } + + ref var reachScore = ref GetComponentData(unit); + if (Math.Abs(position.X - targetPos.X) < 0.2f) + { + reachScore.Value = Math.Max(0, reachScore.Value - 0.1f * (float) worldTime.Delta.TotalSeconds); + } + } + + if (gmData.YaridaOvertakeCount + 1 >= Yarida.Length) + { + GetComponentData(UberHero) = UnitDirection.Left; + gmData.Phase = YaridaTrainingGameModeData.EPhase.Backward; + } + + break; + } + case YaridaTrainingGameModeData.EPhase.Backward: + if (uberHeroPosition.X <= 0) + { + GetComponentData(UberHero) = UnitDirection.Right; + gmData.Phase = YaridaTrainingGameModeData.EPhase.Waiting; + + uberHeroPosition.X = -10; + GetComponentData(GetComponentData>(UberHero).Target).Value.X = -10; + } + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + + public void Start(int yaridaCount) + { + GameMode = GameWorld.CreateEntity(); + GameWorld.AddComponent(GameMode, new YaridaTrainingGameModeData()); + + UberHero = SpawnUberHero(-10); + + Yarida = new GameEntity[yaridaCount]; + for (var i = 0; i != yaridaCount; i++) + { + Yarida[i] = SpawnYarida(10, 10 + i * 10); + } + } + + private GameEntity SpawnUberHero(float positionX) + { + var playerEntity = GameWorld.CreateEntity(); + GameWorld.AddComponent(playerEntity, new PlayerDescription()); + GameWorld.AddComponent(playerEntity, new PlayerInputComponent()); + GameWorld.AddComponent(playerEntity, new PlayerIsLocal()); + + var unitTarget = GameWorld.CreateEntity(); + GameWorld.AddComponent(unitTarget, new UnitTargetDescription()); + GameWorld.AddComponent(unitTarget, new Position()); + GameWorld.AddComponent(unitTarget, new Relative(playerEntity)); + + var rhythmEngine = GameWorld.CreateEntity(); + GameWorld.AddComponent(rhythmEngine, new RhythmEngineDescription()); + GameWorld.AddComponent(rhythmEngine, new RhythmEngineController {State = RhythmEngineState.Playing, StartTime = worldTime.Total.Add(TimeSpan.FromSeconds(2))}); + GameWorld.AddComponent(rhythmEngine, new RhythmEngineSettings {BeatInterval = TimeSpan.FromSeconds(0.5), MaxBeat = 4}); + GameWorld.AddComponent(rhythmEngine, new RhythmEngineLocalState()); + GameWorld.AddComponent(rhythmEngine, new RhythmEngineExecutingCommand()); + GameWorld.AddComponent(rhythmEngine, new Relative(playerEntity)); + GameWorld.AddComponent(rhythmEngine, GameWorld.AsComponentType()); + GameWorld.AddComponent(rhythmEngine, GameWorld.AsComponentType()); + GameWorld.AddComponent(rhythmEngine, new GameCommandState()); + GameWorld.AddComponent(rhythmEngine, new IsSimulationOwned()); + GameCombo.AddToEntity(GameWorld, rhythmEngine); + RhythmSummonEnergy.AddToEntity(GameWorld, rhythmEngine); + + var unit = playableUnitProvider.SpawnEntityWithArguments(new PlayableUnitProvider.Create + { + Statistics = new UnitStatistics + { + BaseWalkSpeed = 2, + FeverWalkSpeed = 2.2f, + MovementAttackSpeed = 3.1f, + Weight = 8.5f, + }, + Direction = UnitDirection.Right + }); + GameWorld.GetComponentData(unit).Value.X = positionX; + GameWorld.GetComponentData(unitTarget).Value.X = positionX; + + GameWorld.AddComponent(unit, new UnitCurrentKit(localKitDb.GetOrCreate(new UnitKitResourceKey("taterazay")))); + GameWorld.AddComponent(unit, new Relative(playerEntity)); + GameWorld.AddComponent(unit, new Relative(unitTarget)); + GameWorld.AddComponent(unit, new UnitEnemySeekingState()); + GameWorld.AddComponent(unit, new UnitTargetOffset()); + GameWorld.AddComponent(unit, new UnitTargetControlTag()); + + var displayedEquip = GameWorld.AddBuffer(unit); + displayedEquip.Add(new UnitDisplayedEquipment + { + Attachment = localAttachDb.GetOrCreate("Mask"), + Resource = localEquipDb.GetOrCreate("Masks/n_kibadda") + }); + displayedEquip.Add(new UnitDisplayedEquipment + { + Attachment = localAttachDb.GetOrCreate("LeftEquipment"), + Resource = localEquipDb.GetOrCreate("Shields/default_shield") + }); + displayedEquip.Add(new UnitDisplayedEquipment + { + Attachment = localAttachDb.GetOrCreate("RightEquipment"), + Resource = localEquipDb.GetOrCreate("Swords/default_sword") + }); + + abilityCollectionSystem.SpawnFor("march", unit); + abilityCollectionSystem.SpawnFor("backward", unit); + RetreatAbility = abilityCollectionSystem.SpawnFor("retreat", unit); + abilityCollectionSystem.SpawnFor("jump", unit); + abilityCollectionSystem.SpawnFor("party", unit); + abilityCollectionSystem.SpawnFor("charge", unit); + abilityCollectionSystem.SpawnFor("CTate.BasicDefendFrontal", unit); + abilityCollectionSystem.SpawnFor("CTate.BasicDefendStay", unit, AbilitySelection.Top); + abilityCollectionSystem.SpawnFor("CTate.EnergyField", unit); + + GameWorld.AddComponent(playerEntity, new ServerCameraState + { + Data = + { + Mode = CameraMode.Forced, + Offset = RigidTransform.Identity, + Target = unit + } + }); + + GameWorld.AddComponent(unit, new Relative(rhythmEngine)); + + RhythmEngine = rhythmEngine; + + return unit; + } + + private GameEntity SpawnYarida(float initialPosX, float positionX) + { + var unit = playableUnitProvider.SpawnEntityWithArguments(new PlayableUnitProvider.Create + { + Statistics = new UnitStatistics + { + BaseWalkSpeed = 0f, + FeverWalkSpeed = 0f, + MovementAttackSpeed = 0f, + Weight = 8.5f, + }, + Direction = UnitDirection.Right + }); + + var tt = GameWorld.CreateEntity(); + GameWorld.AddComponent(tt, new UnitTargetDescription()); + GameWorld.AddComponent(tt, new Position()); + GameWorld.GetComponentData(tt).Value.X = positionX + initialPosX; + GameWorld.GetComponentData(unit).Value.X = initialPosX; + + GameWorld.AddComponent(unit, new UnitCurrentKit(localKitDb.GetOrCreate(new UnitKitResourceKey("yarida")))); + GameWorld.AddComponent(unit, new UnitEnemySeekingState()); + GameWorld.AddComponent(unit, new UnitTargetOffset()); + GameWorld.AddComponent(unit, new ReachScore {Value = 1}); + GameWorld.AddComponent(unit, new Relative(tt)); + + var displayedEquip = GameWorld.AddBuffer(unit); + displayedEquip.Add(new UnitDisplayedEquipment + { + Attachment = localAttachDb.GetOrCreate("Mask"), + Resource = localEquipDb.GetOrCreate("Masks/n_yarida") + }); + displayedEquip.Add(new UnitDisplayedEquipment + { + Attachment = localAttachDb.GetOrCreate("RightEquipment"), + Resource = localEquipDb.GetOrCreate("Spears/default_spear") + }); + + return unit; + } + } +} \ No newline at end of file