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);
|
HitResult Raycast(Vector3 from, Vector3 to, Entity? ownerToExclude = null);
|
||||||
Vector3 RotateVectorByYaw(Vector3 vector, float yawRadians);
|
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.Input.Interfaces;
|
||||||
using GameCore.Interaction;
|
using GameCore.Interaction;
|
||||||
using GameCore.Logging.Interfaces;
|
using GameCore.Logging.Interfaces;
|
||||||
|
using GameCore.Services;
|
||||||
|
using GameCore.State;
|
||||||
|
|
||||||
namespace GameCore.ECS;
|
namespace GameCore.ECS;
|
||||||
|
|
||||||
@@ -13,18 +15,37 @@ namespace GameCore.ECS;
|
|||||||
/// It manages all entities, components, and systems, and orchestrates the main game loop.
|
/// 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.
|
/// This class is the primary point of interaction for the Engine/Presentation layer.
|
||||||
/// </summary>
|
/// </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 Dictionary<int, List<IComponent>> _componentsByEntityId = new();
|
||||||
private readonly EventBus _eventBus = new();
|
private readonly EventBus _eventBus = new();
|
||||||
private readonly List<ISystem> _systems = [];
|
private readonly List<ISystem> _systems = [];
|
||||||
|
public readonly IAudioService AudioService;
|
||||||
|
|
||||||
public readonly SimulationConfig Config = config;
|
public readonly SimulationConfig Config;
|
||||||
public readonly IInputService InputService = inputService;
|
public readonly IGameStateService GameState;
|
||||||
public readonly ILogger Logger = logger;
|
public readonly IInputService InputService;
|
||||||
public readonly IWorldQuery WorldQuery = worldQuery;
|
public readonly ILogger Logger;
|
||||||
|
public readonly IParticleService ParticleService;
|
||||||
|
public readonly IWorldQuery WorldQuery;
|
||||||
private int _nextEntityId;
|
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>
|
/// <summary>
|
||||||
/// Creates a new, unique entity.
|
/// Creates a new, unique entity.
|
||||||
/// </summary>
|
/// </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