Add MeleeEffect and related services for combat interactions
This commit is contained in:
29
GameCore/Combat/Effects/MeleeEffect.cs
Normal file
29
GameCore/Combat/Effects/MeleeEffect.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using GameCore.Combat.Interfaces;
|
||||
using GameCore.Input;
|
||||
|
||||
namespace GameCore.Combat.Effects;
|
||||
|
||||
public class MeleeEffect(float range, float radius) : IEffect
|
||||
{
|
||||
public void Execute(EffectContext context)
|
||||
{
|
||||
var input = context.World.GetComponent<InputStateComponent>(context.Owner);
|
||||
var weapon = context.World.GetComponent<WeaponComponent>(context.Owner);
|
||||
if (input == null || weapon == null) return;
|
||||
|
||||
var checkPosition = input.MuzzlePosition + input.MuzzleDirection * range;
|
||||
var hits = context.World.WorldQuery.OverlapSphere(checkPosition, radius, context.Owner);
|
||||
|
||||
foreach (var hitEntity in hits)
|
||||
{
|
||||
var hitContext = new EffectContext
|
||||
{
|
||||
World = context.World,
|
||||
Owner = context.Owner,
|
||||
Target = hitEntity
|
||||
};
|
||||
|
||||
foreach (var effect in weapon.OnHitEffects) effect.Execute(hitContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,4 +6,5 @@ public interface IWorldQuery
|
||||
{
|
||||
HitResult Raycast(Vector3 from, Vector3 to, Entity? ownerToExclude = null);
|
||||
Vector3 RotateVectorByYaw(Vector3 vector, float yawRadians);
|
||||
IEnumerable<Entity> OverlapSphere(Vector3 position, float radius, Entity? ownerToExclude = null);
|
||||
}
|
||||
@@ -5,6 +5,8 @@ using GameCore.Events.Interfaces;
|
||||
using GameCore.Input.Interfaces;
|
||||
using GameCore.Interaction;
|
||||
using GameCore.Logging.Interfaces;
|
||||
using GameCore.Services;
|
||||
using GameCore.State;
|
||||
|
||||
namespace GameCore.ECS;
|
||||
|
||||
@@ -13,18 +15,37 @@ namespace GameCore.ECS;
|
||||
/// It manages all entities, components, and systems, and orchestrates the main game loop.
|
||||
/// This class is the primary point of interaction for the Engine/Presentation layer.
|
||||
/// </summary>
|
||||
public class World(IInputService inputService, IWorldQuery worldQuery, SimulationConfig config, ILogger logger)
|
||||
public class World
|
||||
{
|
||||
private readonly Dictionary<int, List<IComponent>> _componentsByEntityId = new();
|
||||
private readonly EventBus _eventBus = new();
|
||||
private readonly List<ISystem> _systems = [];
|
||||
public readonly IAudioService AudioService;
|
||||
|
||||
public readonly SimulationConfig Config = config;
|
||||
public readonly IInputService InputService = inputService;
|
||||
public readonly ILogger Logger = logger;
|
||||
public readonly IWorldQuery WorldQuery = worldQuery;
|
||||
public readonly SimulationConfig Config;
|
||||
public readonly IGameStateService GameState;
|
||||
public readonly IInputService InputService;
|
||||
public readonly ILogger Logger;
|
||||
public readonly IParticleService ParticleService;
|
||||
public readonly IWorldQuery WorldQuery;
|
||||
private int _nextEntityId;
|
||||
|
||||
public World(IInputService inputService,
|
||||
IWorldQuery worldQuery,
|
||||
SimulationConfig config,
|
||||
ILogger logger,
|
||||
IAudioService audioService,
|
||||
IParticleService particleService)
|
||||
{
|
||||
AudioService = audioService;
|
||||
Config = config;
|
||||
InputService = inputService;
|
||||
Logger = logger;
|
||||
ParticleService = particleService;
|
||||
WorldQuery = worldQuery;
|
||||
GameState = new GameStateService(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new, unique entity.
|
||||
/// </summary>
|
||||
|
||||
9
GameCore/Events/GameStatusChangedEvent.cs
Normal file
9
GameCore/Events/GameStatusChangedEvent.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using GameCore.Events.Interfaces;
|
||||
using GameCore.State;
|
||||
|
||||
namespace GameCore.Events;
|
||||
|
||||
public readonly struct GameStatusChangedEvent(GameStatus newStatus) : IEvent
|
||||
{
|
||||
public readonly GameStatus NewStatus = newStatus;
|
||||
}
|
||||
9
GameCore/Services/IAudioService.cs
Normal file
9
GameCore/Services/IAudioService.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using GameCore.Math;
|
||||
|
||||
namespace GameCore.Services;
|
||||
|
||||
public interface IAudioService
|
||||
{
|
||||
void Play(string soundId);
|
||||
void PlayAtPoint(string soundId, Vector3 position);
|
||||
}
|
||||
9
GameCore/Services/IParticleService.cs
Normal file
9
GameCore/Services/IParticleService.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using GameCore.Math;
|
||||
|
||||
namespace GameCore.Services;
|
||||
|
||||
public interface IParticleService
|
||||
{
|
||||
void Trigger(string particleId, Vector3 position);
|
||||
void Trigger(string particleId, Vector3 position, Vector3 normal);
|
||||
}
|
||||
40
GameCore/State/GameStateService.cs
Normal file
40
GameCore/State/GameStateService.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using GameCore.ECS;
|
||||
using GameCore.Events;
|
||||
|
||||
namespace GameCore.State;
|
||||
|
||||
public class GameStateService(World world) : IGameStateService
|
||||
{
|
||||
private readonly HashSet<string> _unlockedLevelIds = [];
|
||||
private readonly World _world = world;
|
||||
public GameStatus CurrentStatus { get; private set; } = GameStatus.InMainMenu;
|
||||
public string CurrentLevelId { get; private set; }
|
||||
public IReadOnlyCollection<string> UnlockedLevelIds => _unlockedLevelIds;
|
||||
|
||||
public void SetStatus(GameStatus newStatus)
|
||||
{
|
||||
if (CurrentStatus == newStatus) return;
|
||||
|
||||
CurrentStatus = newStatus;
|
||||
_world.PublishEvent(new GameStatusChangedEvent(newStatus));
|
||||
}
|
||||
|
||||
public void StartGame(string startingLevelId)
|
||||
{
|
||||
CurrentLevelId = startingLevelId;
|
||||
_unlockedLevelIds.Add(startingLevelId);
|
||||
SetStatus(GameStatus.InGame);
|
||||
}
|
||||
|
||||
public void UnlockLevel(string levelId)
|
||||
{
|
||||
_unlockedLevelIds.Add(levelId);
|
||||
}
|
||||
|
||||
public void ResetProgress()
|
||||
{
|
||||
_unlockedLevelIds.Clear();
|
||||
CurrentLevelId = null!;
|
||||
SetStatus(GameStatus.InMainMenu);
|
||||
}
|
||||
}
|
||||
9
GameCore/State/GameStatus.cs
Normal file
9
GameCore/State/GameStatus.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace GameCore.State;
|
||||
|
||||
public enum GameStatus
|
||||
{
|
||||
InMainMenu,
|
||||
InGame,
|
||||
Paused,
|
||||
GameOver
|
||||
}
|
||||
13
GameCore/State/IGameStateService.cs
Normal file
13
GameCore/State/IGameStateService.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
namespace GameCore.State;
|
||||
|
||||
public interface IGameStateService
|
||||
{
|
||||
GameStatus CurrentStatus { get; }
|
||||
string CurrentLevelId { get; }
|
||||
IReadOnlyCollection<string> UnlockedLevelIds { get; }
|
||||
|
||||
void SetStatus(GameStatus newStatus);
|
||||
void StartGame(string startingLevelId);
|
||||
void UnlockLevel(string levelId);
|
||||
void ResetProgress();
|
||||
}
|
||||
Reference in New Issue
Block a user