From 90d3abd83f704cfd28421bf2c4783ff7f3ff4be4 Mon Sep 17 00:00:00 2001 From: Gabriel Kaszewski Date: Thu, 30 Oct 2025 03:24:51 +0100 Subject: [PATCH] Add audio and particle services, update GamePresenter for game state management --- Code/Presenters/GamePresenter.cs | 13 +++++++- Code/Services/GodotAudioService.cs | 16 ++++++++++ Code/Services/GodotParticleService.cs | 15 ++++++++++ Code/Services/GodotWorldQuery.cs | 43 +++++++++++++++++++++++++++ 4 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 Code/Services/GodotAudioService.cs create mode 100644 Code/Services/GodotParticleService.cs diff --git a/Code/Presenters/GamePresenter.cs b/Code/Presenters/GamePresenter.cs index 4d47873..00130a5 100644 --- a/Code/Presenters/GamePresenter.cs +++ b/Code/Presenters/GamePresenter.cs @@ -18,6 +18,7 @@ using GameCore.Logging.Interfaces; using GameCore.Logic; using GameCore.Movement; using GameCore.Player; +using GameCore.State; using Godot; namespace CryptonymThunder.Code.Presenters; @@ -36,6 +37,8 @@ public partial class GamePresenter : Node private GodotInputService _inputService; private GodotWorldQuery _worldQuery; private PresenterFactory _presenterFactory; + private GodotAudioService _audioService; + private GodotParticleService _particleService; private ILogger _logger = new NullLogger(); private readonly Dictionary> _presenterComponents = new(); @@ -46,6 +49,8 @@ public partial class GamePresenter : Node _presenterRegistry = GetNode("/root/PresenterRegistry"); _inputService = new GodotInputService(); _worldQuery = new GodotWorldQuery(this); + _audioService = new GodotAudioService(); + _particleService = new GodotParticleService(); var simConfig = new SimulationConfig(); if (SimulationConfig != null) @@ -61,7 +66,7 @@ public partial class GamePresenter : Node } } - _world = new World(_inputService, _worldQuery, simConfig, _logger); + _world = new World(_inputService, _worldQuery, simConfig, _logger, _audioService, _particleService); var effectFactory = new EffectFactory(); var requirementFactory = new InteractionRequirementFactory(); @@ -116,6 +121,7 @@ public partial class GamePresenter : Node public override void _PhysicsProcess(double delta) { + if (_world.GameState.CurrentStatus != GameStatus.InGame) return; if (_presenters.Count == 0) return; _inputService.Update(); @@ -198,4 +204,9 @@ public partial class GamePresenter : Node disposableLogger.Dispose(); } } + + public void OnPauseButtonPressed() + { + _world.GameState.SetStatus(GameStatus.Paused); + } } \ No newline at end of file diff --git a/Code/Services/GodotAudioService.cs b/Code/Services/GodotAudioService.cs new file mode 100644 index 0000000..1357ff4 --- /dev/null +++ b/Code/Services/GodotAudioService.cs @@ -0,0 +1,16 @@ +using GameCore.Math; +using GameCore.Services; + +namespace CryptonymThunder.Code.Services; + +public class GodotAudioService : IAudioService +{ + public void Play(string soundId) + { + + } + + public void PlayAtPoint(string soundId, Vector3 position) + { + } +} \ No newline at end of file diff --git a/Code/Services/GodotParticleService.cs b/Code/Services/GodotParticleService.cs new file mode 100644 index 0000000..bf54800 --- /dev/null +++ b/Code/Services/GodotParticleService.cs @@ -0,0 +1,15 @@ +using GameCore.Math; +using GameCore.Services; + +namespace CryptonymThunder.Code.Services; + +public class GodotParticleService : IParticleService +{ + public void Trigger(string particleId, Vector3 position) + { + } + + public void Trigger(string particleId, Vector3 position, Vector3 normal) + { + } +} \ No newline at end of file diff --git a/Code/Services/GodotWorldQuery.cs b/Code/Services/GodotWorldQuery.cs index ae5541a..f074db3 100644 --- a/Code/Services/GodotWorldQuery.cs +++ b/Code/Services/GodotWorldQuery.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using CryptonymThunder.Code.Autoloads; using CryptonymThunder.Code.Extensions; using CryptonymThunder.Code.Presenters; @@ -58,4 +59,46 @@ public class GodotWorldQuery(GamePresenter ownerNode) : IWorldQuery var rotatedZ = -vector.X * (float)Math.Sin(yawRadians) + vector.Z * (float)Math.Cos(yawRadians); return new Vector3(rotatedX, vector.Y, rotatedZ); } + + public IEnumerable OverlapSphere(Vector3 position, float radius, Entity? ownerToExclude = null) + { + var spaceState = _godotWorld.DirectSpaceState; + var query = new PhysicsShapeQueryParameters3D(); + + var sphere = new SphereShape3D(); + sphere.Radius = radius; + query.Shape = sphere; + + query.Transform = new Transform3D(Basis.Identity, position.ToGodot()); + + query.CollisionMask = 1; + query.CollideWithBodies = true; + query.CollideWithAreas = false; + + if (ownerToExclude.HasValue) + { + var ownerPresenter = ownerNode.GetPresenterNode(ownerToExclude.Value); + if (ownerPresenter != null) + { + query.Exclude = [((PhysicsBody3D)ownerPresenter).GetRid()]; + } + } + + var results = spaceState.IntersectShape(query); + if (results.Count == 0) + { + yield break; + } + + foreach (var result in results) + { + if (result["collider"].Obj is Node3D collider) + { + if (_presenterRegistry.TryGetEntity(collider.GetInstanceId(), out var hitEntity)) + { + yield return hitEntity; + } + } + } + } } \ No newline at end of file