Add initial resource and presenter classes for game entities and effects
This commit is contained in:
58
Code/Presenters/CameraPresenterComponent.cs
Normal file
58
Code/Presenters/CameraPresenterComponent.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
using CryptonymThunder.Code.Extensions;
|
||||
using GameCore.ECS;
|
||||
using GameCore.ECS.Interfaces;
|
||||
using GameCore.Input;
|
||||
using GameCore.Movement;
|
||||
using Godot;
|
||||
|
||||
namespace CryptonymThunder.Code.Presenters;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class CameraPresenterComponent : Node3D, IPresenterComponent
|
||||
{
|
||||
private Entity _coreEntity;
|
||||
private World _world;
|
||||
private Camera3D _camera;
|
||||
private RotationComponent _rotationComponent;
|
||||
|
||||
private bool _cursorLocked = true;
|
||||
|
||||
public void Initialize(Entity coreEntity, World world)
|
||||
{
|
||||
_coreEntity = coreEntity;
|
||||
_world = world;
|
||||
_rotationComponent = _world.GetComponent<RotationComponent>(_coreEntity);
|
||||
_camera = GetNode<Camera3D>("Camera3D");
|
||||
|
||||
if (_cursorLocked) Input.MouseMode = Input.MouseModeEnum.Captured;
|
||||
}
|
||||
|
||||
public void SyncToPresentation(float delta)
|
||||
{
|
||||
if (_rotationComponent == null || _camera == null) return;
|
||||
|
||||
var coreRotation = _rotationComponent.Rotation;
|
||||
_camera.Rotation = new Vector3(coreRotation.X, 0f, 0f);
|
||||
}
|
||||
|
||||
public void SyncToCore(float delta)
|
||||
{
|
||||
}
|
||||
|
||||
public override void _Input(InputEvent @event)
|
||||
{
|
||||
if (Input.IsActionJustPressed("ui_cancel"))
|
||||
{
|
||||
if (_cursorLocked)
|
||||
{
|
||||
Input.MouseMode = Input.MouseModeEnum.Visible;
|
||||
_cursorLocked = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Input.MouseMode = Input.MouseModeEnum.Captured;
|
||||
_cursorLocked = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1
Code/Presenters/CameraPresenterComponent.cs.uid
Normal file
1
Code/Presenters/CameraPresenterComponent.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://crx03e8buoni3
|
||||
66
Code/Presenters/CharacterBody3DPresenter.cs
Normal file
66
Code/Presenters/CharacterBody3DPresenter.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
using CryptonymThunder.Code.Extensions;
|
||||
using GameCore.ECS;
|
||||
using GameCore.ECS.Interfaces;
|
||||
using GameCore.Input;
|
||||
using GameCore.Movement;
|
||||
using GameCore.Physics;
|
||||
using Godot;
|
||||
|
||||
namespace CryptonymThunder.Code.Presenters;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class CharacterBody3DPresenter : CharacterBody3D, IEntityPresenter, IPresenterComponent
|
||||
{
|
||||
private World _world;
|
||||
private VelocityComponent _velocity;
|
||||
private PositionComponent _position;
|
||||
private RotationComponent _rotation;
|
||||
private CharacterStateComponent _characterState;
|
||||
private InputStateComponent _inputState;
|
||||
private Camera3D _camera;
|
||||
|
||||
public Entity CoreEntity { get; set; }
|
||||
|
||||
public void Initialize(Entity coreEntity, World world)
|
||||
{
|
||||
CoreEntity = coreEntity;
|
||||
_world = world;
|
||||
_velocity = _world.GetComponent<VelocityComponent>(CoreEntity);
|
||||
_position = _world.GetComponent<PositionComponent>(CoreEntity);
|
||||
_rotation = _world.GetComponent<RotationComponent>(CoreEntity);
|
||||
_inputState = _world.GetComponent<InputStateComponent>(CoreEntity);
|
||||
_characterState = _world.GetComponent<CharacterStateComponent>(CoreEntity);
|
||||
_camera = GetNode<Camera3D>("CameraPivot/Camera3D");
|
||||
}
|
||||
|
||||
public void SyncToPresentation(float delta)
|
||||
{
|
||||
if (_rotation != null)
|
||||
{
|
||||
var coreRotation = _rotation.Rotation;
|
||||
Rotation = new Vector3(Rotation.X, coreRotation.Y, Rotation.Z);
|
||||
}
|
||||
|
||||
if (_velocity == null) return;
|
||||
|
||||
var godotVelocity = Velocity;
|
||||
godotVelocity.X = _velocity.DesiredVelocity.X;
|
||||
godotVelocity.Y = _velocity.DesiredVelocity.Y;
|
||||
godotVelocity.Z = _velocity.DesiredVelocity.Z;
|
||||
|
||||
Velocity = godotVelocity;
|
||||
MoveAndSlide();
|
||||
}
|
||||
|
||||
public void SyncToCore(float delta)
|
||||
{
|
||||
if (_position != null) _position.Position = GlobalPosition.ToGameCore();
|
||||
if (_velocity != null) _velocity.ActualVelocity = Velocity.ToGameCore();
|
||||
if (_characterState != null) _characterState.IsOnFloor = IsOnFloor();
|
||||
if (_inputState != null && _camera != null)
|
||||
{
|
||||
_inputState.MuzzlePosition = _camera.GlobalPosition.ToGameCore();
|
||||
_inputState.MuzzleDirection = (-_camera.GlobalTransform.Basis.Z).ToGameCore();
|
||||
}
|
||||
}
|
||||
}
|
||||
1
Code/Presenters/CharacterBody3DPresenter.cs.uid
Normal file
1
Code/Presenters/CharacterBody3DPresenter.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://hkiny1ftv4r7
|
||||
11
Code/Presenters/EntityPresenter.cs
Normal file
11
Code/Presenters/EntityPresenter.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using GameCore.ECS;
|
||||
using GameCore.ECS.Interfaces;
|
||||
using Godot;
|
||||
|
||||
namespace CryptonymThunder.Code.Presenters;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class EntityPresenter : Node3D, IEntityPresenter
|
||||
{
|
||||
public Entity CoreEntity { get; set; }
|
||||
}
|
||||
1
Code/Presenters/EntityPresenter.cs.uid
Normal file
1
Code/Presenters/EntityPresenter.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cb7vaw6xqjs1i
|
||||
157
Code/Presenters/GamePresenter.cs
Normal file
157
Code/Presenters/GamePresenter.cs
Normal file
@@ -0,0 +1,157 @@
|
||||
using System.Collections.Generic;
|
||||
using CryptonymThunder.Code.Autoloads;
|
||||
using CryptonymThunder.Code.Factories;
|
||||
using CryptonymThunder.Code.Resources;
|
||||
using CryptonymThunder.Code.Services;
|
||||
using GameCore.Attributes;
|
||||
using GameCore.Combat;
|
||||
using GameCore.Config;
|
||||
using GameCore.ECS;
|
||||
using GameCore.ECS.Interfaces;
|
||||
using GameCore.Events;
|
||||
using GameCore.Input;
|
||||
using GameCore.Movement;
|
||||
using Godot;
|
||||
|
||||
namespace CryptonymThunder.Code.Presenters;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class GamePresenter : Node
|
||||
{
|
||||
[Export] private ArchetypeDatabase ArchetypesDatabase { get; set; }
|
||||
[Export] private EntityArchetype PlayerArchetype { get; set; }
|
||||
[Export] private SimulationConfigResource SimulationConfig { get; set; }
|
||||
|
||||
private World _world;
|
||||
private PresenterRegistry _presenterRegistry;
|
||||
private GodotInputService _inputService;
|
||||
private GodotWorldQuery _worldQuery;
|
||||
private PresenterFactory _presenterFactory;
|
||||
|
||||
private readonly Dictionary<int, List<IPresenterComponent>> _presenterComponents = new();
|
||||
private readonly Dictionary<int, IEntityPresenter> _presenters = new();
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_presenterRegistry = GetNode<PresenterRegistry>("/root/PresenterRegistry");
|
||||
_inputService = new GodotInputService();
|
||||
_worldQuery = new GodotWorldQuery(this);
|
||||
|
||||
var simConfig = new SimulationConfig();
|
||||
if (SimulationConfig != null)
|
||||
{
|
||||
simConfig.GravityStrength = SimulationConfig.GravityStrength;
|
||||
}
|
||||
|
||||
_world = new World(_inputService, _worldQuery, simConfig);
|
||||
|
||||
_presenterFactory = new PresenterFactory(_world, new ComponentFactory(), _presenterRegistry, this);
|
||||
|
||||
_world.RegisterSystem(new PlayerInputSystem());
|
||||
_world.RegisterSystem(new RotationSystem());
|
||||
_world.RegisterSystem(new GroundMovementSystem());
|
||||
_world.RegisterSystem(new GravitySystem());
|
||||
_world.RegisterSystem(new JumpSystem());
|
||||
|
||||
_world.RegisterSystem(new AttributeSystem());
|
||||
|
||||
_world.RegisterSystem(new WeaponSystem());
|
||||
_world.RegisterSystem(new ProjectileSystem());
|
||||
_world.RegisterSystem(new ProjectileInitializationSystem(_world));
|
||||
|
||||
_world.RegisterSystem(new DamageSystem(_world));
|
||||
_world.RegisterSystem(new ProjectileCleanupSystem());
|
||||
_world.RegisterSystem(new DestructionSystem());
|
||||
|
||||
_world.Subscribe<EntityDiedEvent>(OnEntityDied);
|
||||
_world.Subscribe<SpawnEntityEvent>(OnSpawnEntity);
|
||||
|
||||
RegisterAllSceneEntities();
|
||||
|
||||
var playerData = _presenterFactory.CreateEntityFromArchetype(PlayerArchetype);
|
||||
_presenters.Add(playerData.Entity.Id, playerData.Presenter);
|
||||
_presenterComponents.Add(playerData.Entity.Id, playerData.Components);
|
||||
}
|
||||
|
||||
public override void _Input(InputEvent @event)
|
||||
{
|
||||
_inputService?.HandleInputEvent(@event);
|
||||
}
|
||||
|
||||
public override void _PhysicsProcess(double delta)
|
||||
{
|
||||
if (_presenters.Count == 0) return;
|
||||
|
||||
_inputService.Update();
|
||||
_world.Update((float)delta);
|
||||
_world.ProcessEvents();
|
||||
|
||||
foreach (var componentList in _presenterComponents.Values)
|
||||
{
|
||||
foreach (var component in componentList)
|
||||
{
|
||||
component.SyncToPresentation((float)delta);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var componentList in _presenterComponents.Values)
|
||||
{
|
||||
foreach (var component in componentList)
|
||||
{
|
||||
component.SyncToCore((float)delta);
|
||||
}
|
||||
}
|
||||
|
||||
_inputService.LateUpdate();
|
||||
}
|
||||
|
||||
private void OnSpawnEntity(SpawnEntityEvent @event)
|
||||
{
|
||||
if (ArchetypesDatabase.Archetypes.TryGetValue(@event.ArchetypeId, out var archetype))
|
||||
{
|
||||
var presenterData = _presenterFactory.CreateEntityFromArchetype(archetype, @event.Position, @event.Rotation, @event.InitialVelocity);
|
||||
_presenters.Add(presenterData.Entity.Id, presenterData.Presenter);
|
||||
_presenterComponents.Add(presenterData.Entity.Id, presenterData.Components);
|
||||
|
||||
_world.PublishEvent(new EntitySpawnedEvent(presenterData.Entity, @event.Owner, @event.ArchetypeId));
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEntityDied(EntityDiedEvent e)
|
||||
{
|
||||
if (_presenters.Remove(e.Entity.Id, out var presenter))
|
||||
{
|
||||
_presenterRegistry.UnregisterPresenter(presenter as Node);
|
||||
_presenterComponents.Remove(e.Entity.Id);
|
||||
(presenter as Node)?.QueueFree();
|
||||
}
|
||||
}
|
||||
|
||||
private void RegisterAllSceneEntities()
|
||||
{
|
||||
var sceneEntities = GetTree().GetNodesInGroup("SceneEntities");
|
||||
foreach (var node in sceneEntities)
|
||||
{
|
||||
if (node is SceneEntity sceneEntity)
|
||||
{
|
||||
var parentNode = sceneEntity.GetParent();
|
||||
if (parentNode != null)
|
||||
{
|
||||
var presenterData = _presenterFactory.RegisterSceneEntity(parentNode, sceneEntity.ComponentResources);
|
||||
_presenters.Add(presenterData.Entity.Id, presenterData.Presenter);
|
||||
_presenterComponents.Add(presenterData.Entity.Id, presenterData.Components);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Node GetPresenterNode(Entity entity)
|
||||
{
|
||||
if (_presenters.TryGetValue(entity.Id, out var presenter))
|
||||
{
|
||||
return presenter as Node;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
1
Code/Presenters/GamePresenter.cs.uid
Normal file
1
Code/Presenters/GamePresenter.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cfpm5p102f65x
|
||||
10
Code/Presenters/SceneEntity.cs
Normal file
10
Code/Presenters/SceneEntity.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using Godot;
|
||||
using Godot.Collections;
|
||||
|
||||
namespace CryptonymThunder.Code.Presenters;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class SceneEntity : Node
|
||||
{
|
||||
[Export] public Array<Resource> ComponentResources { get; set; } = [];
|
||||
}
|
||||
1
Code/Presenters/SceneEntity.cs.uid
Normal file
1
Code/Presenters/SceneEntity.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://b6x8llipvutqs
|
||||
31
Code/Presenters/TransformPresenterComponent.cs
Normal file
31
Code/Presenters/TransformPresenterComponent.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using CryptonymThunder.Code.Extensions;
|
||||
using GameCore.ECS;
|
||||
using GameCore.ECS.Interfaces;
|
||||
using GameCore.Physics;
|
||||
using Godot;
|
||||
|
||||
namespace CryptonymThunder.Code.Presenters;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class TransformPresenterComponent : Node3D, IPresenterComponent, IEntityPresenter
|
||||
{
|
||||
private PositionComponent _position;
|
||||
|
||||
public Entity CoreEntity { get; set; }
|
||||
|
||||
public void Initialize(Entity coreEntity, World world)
|
||||
{
|
||||
CoreEntity = coreEntity;
|
||||
_position = world.GetComponent<PositionComponent>(coreEntity);
|
||||
}
|
||||
|
||||
public void SyncToPresentation(float delta)
|
||||
{
|
||||
if (_position != null) GlobalPosition = _position.Position.ToGodot();
|
||||
}
|
||||
|
||||
public void SyncToCore(float delta)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
1
Code/Presenters/TransformPresenterComponent.cs.uid
Normal file
1
Code/Presenters/TransformPresenterComponent.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://dl2awoy0hyruh
|
||||
Reference in New Issue
Block a user