Files
cryptonhym-thunder/Code/Presenters/GamePresenter.cs

161 lines
5.6 KiB
C#

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.Inventory;
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 PickupSystem());
_world.RegisterSystem(new InventorySystem(_world));
_world.RegisterSystem(new ItemAcquisitionSystem(_world));
_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;
}
}