201 lines
7.2 KiB
C#
201 lines
7.2 KiB
C#
using System;
|
|
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.Interaction;
|
|
using GameCore.Inventory;
|
|
using GameCore.Logging;
|
|
using GameCore.Logging.Interfaces;
|
|
using GameCore.Logic;
|
|
using GameCore.Movement;
|
|
using GameCore.Player;
|
|
using Godot;
|
|
|
|
namespace CryptonymThunder.Code.Presenters;
|
|
|
|
[GlobalClass]
|
|
public partial class GamePresenter : Node
|
|
{
|
|
[Export] private ArchetypeDatabase ArchetypesDatabase { get; set; }
|
|
[Export] private WeaponDatabase WeaponDatabase { get; set; }
|
|
[Export] private EntityArchetype PlayerArchetype { get; set; }
|
|
[Export] private SimulationConfigResource SimulationConfig { get; set; }
|
|
[Export(PropertyHint.Range, "1.0, 10.0, 0.1")] private float InteractionRange { get; set; } = 3.0f;
|
|
|
|
private World _world;
|
|
private PresenterRegistry _presenterRegistry;
|
|
private GodotInputService _inputService;
|
|
private GodotWorldQuery _worldQuery;
|
|
private PresenterFactory _presenterFactory;
|
|
private ILogger _logger = new NullLogger();
|
|
|
|
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;
|
|
|
|
if (simConfig.LoggingEnabled)
|
|
{
|
|
_logger = new CompositeLogger(
|
|
new GodotLogger(),
|
|
new FileLogger("game_log.txt", LogLevel.Info)
|
|
);
|
|
}
|
|
}
|
|
|
|
_world = new World(_inputService, _worldQuery, simConfig, _logger);
|
|
|
|
var effectFactory = new EffectFactory();
|
|
var requirementFactory = new InteractionRequirementFactory();
|
|
var triggerActionFactory = new TriggerActionFactory();
|
|
var componentFactory = new ComponentFactory(effectFactory, requirementFactory, triggerActionFactory);
|
|
var weaponDataService = new GodotWeaponDataService(WeaponDatabase, effectFactory);
|
|
|
|
_presenterFactory = new PresenterFactory(_world, 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 WeaponAcquisitionSystem(_world));
|
|
_world.RegisterSystem(new WeaponSwapSystem());
|
|
_world.RegisterSystem(new EquipmentSystem(_world, weaponDataService));
|
|
|
|
_world.RegisterSystem(new InteractionSystem(InteractionRange));
|
|
_world.RegisterSystem(new DoorSystem());
|
|
_world.RegisterSystem(new LogicSequenceSystem(_world));
|
|
|
|
_world.RegisterSystem(new WeaponSystem());
|
|
_world.RegisterSystem(new ProjectileSystem());
|
|
_world.RegisterSystem(new ProjectileInitializationSystem(_world));
|
|
|
|
|
|
_world.RegisterSystem(new HealingSystem(_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;
|
|
}
|
|
|
|
public override void _ExitTree()
|
|
{
|
|
if (_logger is IDisposable disposableLogger)
|
|
{
|
|
disposableLogger.Dispose();
|
|
}
|
|
}
|
|
} |