Event System

This commit is contained in:
Marco 2025-02-13 16:10:22 +01:00
commit f379eac5c3
10 changed files with 336 additions and 10 deletions

View file

@ -0,0 +1,62 @@
using System;
using Cirno.Scripts.Resources.Events;
using Godot;
using Godot.Collections;
namespace Cirno.Scripts.Activables;
public partial class ScriptableBase : Node2D
{
[Export] public Array<EventResource> Events;
private EventResource CurrentEvent => Events[_currentEventIndex];
private int _currentEventIndex = 0;
private bool _started = false;
public override void _Ready()
{
}
public void Start()
{
_started = true;
StartEvent(CurrentEvent);
}
private void StartEvent(EventResource eventResource)
{
eventResource.Start(this);
}
public override void _Process(double delta)
{
if (!_started) return;
CurrentEvent.UpdateEvent(delta);
if (!CurrentEvent.WaitForCompletion || CurrentEvent.IsComplete())
{
// This loops
//_currentEventIndex = (_currentEventIndex + 1) % Events.Count;
_currentEventIndex++;
if (_currentEventIndex >= Events.Count)
{
// It's over
_started = false;
_currentEventIndex = 0;
return;
}
CurrentEvent.Start(this);
}
// if (_currentHealth <= CurrentPhase.Threshold && currentPhaseIndex + 1 < Phases.Count)
// {
// currentPhaseIndex++;
// _bossHud.SpellCardName = CurrentPhase.PhaseName;
// StartPhase(CurrentPhase);
// }
}
}

View file

@ -46,17 +46,36 @@ public partial class Door : Activable
public override void Activate(ActivationType activationType = ActivationType.Toggle)
{
switch (State)
switch (activationType)
{
case DoorState.Closed:
case ActivationType.Toggle:
switch (State)
{
case DoorState.Closed:
Open();
break;
case DoorState.Open:
Close();
break;
default:
throw new ArgumentOutOfRangeException();
}
break;
case ActivationType.Enable:
Open();
break;
case DoorState.Open:
case ActivationType.Disable:
Close();
break;
case ActivationType.Use:
break;
case ActivationType.Destroy:
break;
default:
throw new ArgumentOutOfRangeException();
throw new ArgumentOutOfRangeException(nameof(activationType), activationType, null);
}
}
private void SetState(DoorState state)

View file

@ -0,0 +1,6 @@
namespace Cirno.Scripts.Interactables;
public partial class AreaEventTrigger
{
}

View file

@ -12,6 +12,9 @@ public partial class AreaTrigger : Area2D
[Export] public bool DoNotActivateOnFirst { get; set; }
private int _activations = 0;
[Signal]
public delegate void ActivatedEventHandler();
public bool Activate(InteractionController player)
{
@ -23,12 +26,17 @@ public partial class AreaTrigger : Area2D
if (OneTime && _activations > 0) return false;
if (Target is not IActivable target)
if (Target != null)
{
GD.PrintErr($"Target {Target.Name} is not activable");
return false;
if (Target is not IActivable target)
{
GD.PrintErr($"Target {Target.Name} is not activable");
return false;
}
target.Activate();
}
target.Activate();
EmitSignal(nameof(Activated));
_activations++;

View file

@ -0,0 +1,56 @@
using Godot;
using Godot.Collections;
namespace Cirno.Scripts.Resources.Events;
[GlobalClass]
public partial class ActivateEvent : EventResource
{
[Export] public ActivationType ActivationType = ActivationType.Toggle;
[Export] public Array<NodePath> Targets;
private Node2D _parent;
private bool _isComplete = false;
protected void ActivateTargets()
{
foreach (var activationTarget in Targets)
{
ActivateTarget(_parent.GetNode<Node2D>(activationTarget));
}
}
private bool ActivateTarget(Node2D activationTarget)
{
if (activationTarget is not IActivable target)
{
GD.PrintErr($"Target {activationTarget.Name} is not activable");
return false;
}
target?.Activate(ActivationType);
GD.Print($"{activationTarget.Name} activated");
return true;
}
public override void Start(Node2D parent)
{
_parent = parent;
ActivateTargets();
_isComplete = true;
}
public override void UpdateEvent(double delta)
{
}
public override bool IsComplete()
{
return _isComplete;
}
}

View file

@ -0,0 +1,52 @@
using Godot;
namespace Cirno.Scripts.Resources.Events;
[GlobalClass]
public partial class DialogueStartEvent : EventResource
{
[Export] public string TimelineName = "timeline";
private Node _dialogic;
private GameManager _gameManager;
private bool _isComplete = false;
public override void Start(Node2D parent)
{
_gameManager = parent.GetGameManager();
_dialogic = parent.GetNode("/root/Dialogic");
_gameManager.ChangeState(GameState.Dialogue);
_dialogic.Connect("timeline_ended", Callable.From(OnTimelineEnded));
_dialogic.Call("start", TimelineName);
}
private void OnTimelineEnded()
{
if (_dialogic.IsConnected("timeline_ended", Callable.From(OnTimelineEnded)))
{
_dialogic.Disconnect("timeline_ended", Callable.From(OnTimelineEnded));
}
DialogueEndAction();
}
private void DialogueEndAction()
{
_gameManager.ChangeState(GameState.Playing);
_isComplete = true;
}
public override void UpdateEvent(double delta)
{
}
public override bool IsComplete()
{
return _isComplete;
}
}

View file

@ -0,0 +1,12 @@
using Godot;
namespace Cirno.Scripts.Resources.Events;
[GlobalClass]
public abstract partial class EventResource : Resource
{
[Export] public bool WaitForCompletion = true;
public abstract void Start(Node2D parent);
public abstract void UpdateEvent(double delta);
public abstract bool IsComplete();
}

View file

@ -0,0 +1,56 @@
using System.Threading.Tasks;
using Godot;
namespace Cirno.Scripts.Resources.Events;
[GlobalClass]
public partial class MovePlayerEvent : EventResource
{
[Export]
public Vector2 RelativeTargetPosition = Vector2.Zero;
[Export]
public float MovementTime = 1f;
[Export]
public Tween.EaseType EaseType = Tween.EaseType.InOut;
[Export]
public Tween.TransitionType TransitionType = Tween.TransitionType.Linear;
private bool _isComplete = false;
private GameManager _gameManager;
public override void Start(Node2D parentNode)
{
_gameManager = parentNode.GetGameManager();
_isComplete = false;
_ = MovePlayer();
}
protected async Task MovePlayer()
{
_gameManager.Player.RequestMovementDisable(true);
Tween tween = _gameManager.GetTree().CreateTween();
tween.SetEase(EaseType);
tween.SetTrans(TransitionType);
tween.TweenProperty(_gameManager.Player, "global_position", _gameManager.Player.GlobalPosition + RelativeTargetPosition, MovementTime);
// Wait for the tween to finish
await ToSignal(tween, "finished");
_gameManager.Player.RequestMovementDisable(false);
_isComplete = true;
}
public override void UpdateEvent(double delta) { }
public override bool IsComplete()
{
return _isComplete;
}
}