Add door interaction system with requirements and HUD integration
This commit is contained in:
54
Code/Presenters/DoorPresenter.cs
Normal file
54
Code/Presenters/DoorPresenter.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using GameCore.ECS;
|
||||
using GameCore.ECS.Interfaces;
|
||||
using GameCore.Interaction;
|
||||
using Godot;
|
||||
|
||||
namespace CryptonymThunder.Code.Presenters;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class DoorPresenter : AnimatableBody3D, IEntityPresenter, IPresenterComponent
|
||||
{
|
||||
[Export] private AnimationPlayer _animationPlayer;
|
||||
[Export] private string _openAnimationName = "Open";
|
||||
|
||||
private DoorComponent _doorComponent;
|
||||
private Animation _openAnimation;
|
||||
|
||||
public Entity CoreEntity { get; set; }
|
||||
|
||||
public void Initialize(Entity coreEntity, World world)
|
||||
{
|
||||
CoreEntity = coreEntity;
|
||||
_doorComponent = world.GetComponent<DoorComponent>(CoreEntity);
|
||||
|
||||
if (_animationPlayer == null)
|
||||
{
|
||||
world.Logger.Error($"DoorPresenter '{Name}' is missing an AnimationPlayer!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_animationPlayer.HasAnimation(_openAnimationName))
|
||||
{
|
||||
world.Logger.Error($"DoorPresenter '{Name}' AnimationPlayer is missing animation: '{_openAnimationName}'");
|
||||
return;
|
||||
}
|
||||
|
||||
_openAnimation = _animationPlayer.GetAnimation(_openAnimationName);
|
||||
_animationPlayer.Play(_openAnimationName);
|
||||
_animationPlayer.Pause();
|
||||
SyncToPresentation(0f);
|
||||
}
|
||||
|
||||
public void SyncToPresentation(float delta)
|
||||
{
|
||||
if (_doorComponent == null || _openAnimation == null) return;
|
||||
|
||||
var targetTime = _doorComponent.OpenProgress * _openAnimation.Length;
|
||||
|
||||
_animationPlayer.Seek(targetTime, true);
|
||||
}
|
||||
|
||||
public void SyncToCore(float delta)
|
||||
{
|
||||
}
|
||||
}
|
||||
1
Code/Presenters/DoorPresenter.cs.uid
Normal file
1
Code/Presenters/DoorPresenter.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bxqite0b1di2b
|
||||
@@ -11,6 +11,7 @@ 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;
|
||||
@@ -27,6 +28,7 @@ public partial class GamePresenter : Node
|
||||
[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;
|
||||
@@ -61,7 +63,8 @@ public partial class GamePresenter : Node
|
||||
_world = new World(_inputService, _worldQuery, simConfig, _logger);
|
||||
|
||||
var effectFactory = new EffectFactory();
|
||||
var componentFactory = new ComponentFactory(effectFactory);
|
||||
var requirementFactory = new InteractionRequirementFactory();
|
||||
var componentFactory = new ComponentFactory(effectFactory, requirementFactory);
|
||||
var weaponDataService = new GodotWeaponDataService(WeaponDatabase, effectFactory);
|
||||
|
||||
_presenterFactory = new PresenterFactory(_world, componentFactory, _presenterRegistry, this);
|
||||
@@ -80,10 +83,14 @@ public partial class GamePresenter : Node
|
||||
_world.RegisterSystem(new WeaponSwapSystem());
|
||||
_world.RegisterSystem(new EquipmentSystem(_world, weaponDataService));
|
||||
|
||||
_world.RegisterSystem(new InteractionSystem(InteractionRange));
|
||||
_world.RegisterSystem(new DoorSystem());
|
||||
|
||||
_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());
|
||||
|
||||
@@ -5,6 +5,7 @@ using GameCore.Combat.Effects;
|
||||
using GameCore.ECS;
|
||||
using GameCore.ECS.Interfaces;
|
||||
using GameCore.Events;
|
||||
using GameCore.Interaction;
|
||||
using GameCore.Inventory;
|
||||
using GameCore.Player;
|
||||
using Godot;
|
||||
@@ -23,6 +24,7 @@ public partial class HudPresenterComponent : Control, IPresenterComponent
|
||||
[Export] private Label _healthLabel;
|
||||
[Export] private Label _ammoLabel;
|
||||
[Export] private Label _weaponLabel;
|
||||
[Export] private Label _interactLabel;
|
||||
|
||||
private string _currentAmmoId;
|
||||
|
||||
@@ -45,6 +47,11 @@ public partial class HudPresenterComponent : Control, IPresenterComponent
|
||||
_world.Subscribe<EntityHealedEvent>(OnEntityHealed);
|
||||
_world.Subscribe<InventoryItemChangedEvent>(OnInventoryChanged);
|
||||
_world.Subscribe<WeaponEquippedEvent>(OnWeaponEquipped);
|
||||
|
||||
if (_interactLabel != null)
|
||||
{
|
||||
_interactLabel.Visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnWeaponEquipped(WeaponEquippedEvent e)
|
||||
@@ -113,6 +120,34 @@ public partial class HudPresenterComponent : Control, IPresenterComponent
|
||||
|
||||
public void SyncToPresentation(float delta)
|
||||
{
|
||||
if (_interactLabel != null)
|
||||
{
|
||||
var lookingAt = _world.GetComponent<IsLookingAtInteractableComponent>(_playerEntity);
|
||||
if (lookingAt != null)
|
||||
{
|
||||
var door = _world.GetComponent<DoorComponent>(lookingAt.Target);
|
||||
if (door != null)
|
||||
{
|
||||
var interactKey = "F";
|
||||
_interactLabel.Text = door.CurrentState switch
|
||||
{
|
||||
DoorComponent.DoorState.Locked => $"[{interactKey}] Interact (Locked)",
|
||||
DoorComponent.DoorState.Closed => $"[{interactKey}] Open Door",
|
||||
DoorComponent.DoorState.Open => $"[{interactKey}] Close Door",
|
||||
_ => ""
|
||||
};
|
||||
_interactLabel.Visible = !string.IsNullOrEmpty(_interactLabel.Text);
|
||||
}
|
||||
else
|
||||
{
|
||||
_interactLabel.Visible = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_interactLabel.Visible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SyncToCore(float delta)
|
||||
|
||||
Reference in New Issue
Block a user