99 lines
3.6 KiB
C#
99 lines
3.6 KiB
C#
using System.Collections.Generic;
|
|
using CryptonymThunder.Code.Autoloads;
|
|
using CryptonymThunder.Code.Resources;
|
|
using GameCore.ECS;
|
|
using GameCore.ECS.Interfaces;
|
|
using GameCore.Movement;
|
|
using GameCore.Physics;
|
|
using Godot;
|
|
using Godot.Collections;
|
|
|
|
namespace CryptonymThunder.Code.Factories;
|
|
|
|
public class PresenterFactory(
|
|
World world,
|
|
ComponentFactory componentFactory,
|
|
PresenterRegistry presenterRegistry,
|
|
Node sceneRoot)
|
|
{
|
|
private readonly World _world = world;
|
|
private readonly ComponentFactory _componentFactory = componentFactory;
|
|
private PresenterRegistry _presenterRegistry = presenterRegistry;
|
|
private readonly Node _sceneRoot = sceneRoot;
|
|
|
|
public PresenterData CreateEntityFromArchetype(EntityArchetype archetype, GameCore.Math.Vector3? position = null,
|
|
GameCore.Math.Vector3? rotation = null, GameCore.Math.Vector3? initialVelocity = null)
|
|
{
|
|
var entity = _world.CreateEntity();
|
|
|
|
foreach (var resource in archetype.ComponentResources)
|
|
{
|
|
var component = _componentFactory.Create(resource);
|
|
if (component != null) _world.AddComponent(entity, component);
|
|
}
|
|
|
|
var presenterNode = archetype.Scene.Instantiate<Node>();
|
|
if (presenterNode is not IEntityPresenter presenter)
|
|
{
|
|
GD.PrintErr($"Archetype scene '{archetype.ResourcePath}' root does not implement IEntityPresenter!");
|
|
presenterNode.QueueFree();
|
|
return default;
|
|
}
|
|
|
|
presenter.CoreEntity = entity;
|
|
|
|
var components = InitializePresenterComponents(presenterNode, entity);
|
|
|
|
if (position.HasValue && _world.GetComponent<PositionComponent>(entity) is { } posComp)
|
|
posComp.Position = position.Value;
|
|
if (rotation.HasValue && _world.GetComponent<RotationComponent>(entity) is { } rotComp)
|
|
rotComp.Rotation = rotation.Value;
|
|
if (initialVelocity.HasValue && _world.GetComponent<VelocityComponent>(entity) is { } velComp)
|
|
velComp.DesiredVelocity = initialVelocity.Value;
|
|
|
|
_sceneRoot.AddChild(presenterNode);
|
|
return new PresenterData(entity, presenter, components);
|
|
}
|
|
|
|
public PresenterData RegisterSceneEntity(Node presenterNode, Array<Resource> componentResources)
|
|
{
|
|
var entity = _world.CreateEntity();
|
|
|
|
foreach (var resource in componentResources)
|
|
{
|
|
var component = _componentFactory.Create(resource);
|
|
if (component != null) _world.AddComponent(entity, component);
|
|
}
|
|
|
|
if (presenterNode is not IEntityPresenter presenter)
|
|
{
|
|
GD.PrintErr($"Scene node '{presenterNode.Name}' does not implement IEntityPresenter!");
|
|
return default;
|
|
}
|
|
|
|
presenter.CoreEntity = entity;
|
|
var components = InitializePresenterComponents(presenterNode, entity);
|
|
return new PresenterData(entity, presenter, components);
|
|
}
|
|
|
|
private List<IPresenterComponent> InitializePresenterComponents(Node presenterNode, Entity entity)
|
|
{
|
|
_presenterRegistry.RegisterPresenter(presenterNode, entity);
|
|
|
|
var components = new List<IPresenterComponent>();
|
|
foreach (var child in presenterNode.GetChildren(true))
|
|
{
|
|
if (child is IPresenterComponent pComponent)
|
|
{
|
|
pComponent.Initialize(entity, _world);
|
|
components.Add(pComponent);
|
|
}
|
|
}
|
|
if (presenterNode is IPresenterComponent rootComponent)
|
|
{
|
|
rootComponent.Initialize(entity, _world);
|
|
components.Add(rootComponent);
|
|
}
|
|
return components;
|
|
}
|
|
} |