using Chickensoft.AutoInject; using Chickensoft.Introspection; using Godot; using System.Linq; using Zennysoft.Game.Ma; using Zennysoft.Ma.Adapter; [Meta(typeof(IAutoNode))] public partial class BadEnd : SpecialFloor { public override void _Notification(int what) => this.Notify(what); [Dependency] protected IPlayer _player => this.DependOn(() => GetParent().GetChildren().OfType().Single()); [Dependency] protected IGame _game => this.DependOn(); [Export] public float ShakeAmount = 50; [Export] public int SpawnTimer = 15; [Node] public Node3D EnemySpawnPoints { get; set; } = default!; [Node] public Marker3D PlayerSpawnPoint { get; set; } = default!; [Node] public ShakeCamera Camera3D { get; set; } = default!; private Timer _spawnTimer; public void OnReady() { SpawnEnemies(3); _spawnTimer = new Timer { WaitTime = SpawnTimer }; _spawnTimer.Timeout += SpawnTimer_Timeout; AddChild(_spawnTimer); _spawnTimer.Start(); var tweener = GetTree().CreateTween(); tweener.TweenMethod(Callable.From((float x) => SetShakeValue(x)), ShakeAmount, 1f, 300f).SetDelay(15); } public async void StartEndGameCutscene() { _player.Deactivate(); var enemies = GetTree().GetNodesInGroup("enemy").Cast().ToList(); foreach (var enemy in enemies) enemy.CallDeferred(MethodName.QueueFree); _spawnTimer.Stop(); _player.ShowCamera(false); Camera3D.Current = true; await _game.OnReachBadEnd(); } public void EndGame() { SfxDatabase.Instance.Play(SoundEffect.Death); _game.GameOver(); } private void SetShakeValue(float shakeAmount) { _player.ShakePlayerCamera(shakeAmount, 1f); } public void SpawnEnemies(int numberOfEnemies) { Godot.Collections.Array enemySpawnPoints = [.. EnemySpawnPoints.GetChildren().OfType()]; for (var i = 0; i < numberOfEnemies; i++) { var spawnPoint = enemySpawnPoints.PickRandom(); enemySpawnPoints.Remove(spawnPoint); var instantiatedEnemy = EnemyTypeToEnemyConverter.Convert(EnemyType.Michael); AddChild(instantiatedEnemy); instantiatedEnemy.GlobalPosition = new Vector3(spawnPoint.GlobalPosition.X, 2.4f, spawnPoint.GlobalPosition.Z); ResetPhysicsInterpolation(); var enemyWithFollowBehavior = (IHaveFollowBehavior)instantiatedEnemy; enemyWithFollowBehavior.FollowBehavior.StartFollow(enemyWithFollowBehavior.NavigationAgent); } } private void SpawnTimer_Timeout() => SpawnEnemies(3); public override (Vector3 Rotation, Vector3 Position) GetPlayerSpawnPoint() { return (PlayerSpawnPoint.Rotation, new Vector3(PlayerSpawnPoint.GlobalPosition.X, 2.4f, PlayerSpawnPoint.GlobalPosition.Z)); } public override void _ExitTree() { _spawnTimer.Timeout -= SpawnTimer_Timeout; } }