Story/ActionTrigger.cs
namespace Opium;
public interface ITriggerable
{
public void Trigger();
}
[EditorHandle( "ui/gizmos/action.png" )]
public partial class ActionTrigger : Component, Component.ITriggerListener
{
/// <summary>
/// A list of triggers that need to be activated before this one can be.
/// </summary>
[Property] public List<ActionTrigger> RequiredTriggers { get; set; }
/// <summary>
/// A list of important markers that we'll pass to ActionGraph.
/// </summary>
public IEnumerable<ObjectMarker> Markers => Components.GetAll<ObjectMarker>( FindMode.EverythingInSelfAndDescendants );
[Property, ReadOnly] public bool Activated { get; set; }
[Property] public Action<IEnumerable<ObjectMarker>> OnActivate { get; set; }
[Property] public List<GameObject> Triggerables { get; set; } = new();
/// <summary>
/// An actor if we found one.
/// </summary>
public Actor Actor { get; set; }
public void OnTriggerEnter( Collider other )
{
if ( Activated ) return;
var actor = other.Components.Get<Actor>( FindMode.EverythingInSelfAndAncestors );
// If we don't have any requirements, or we match ALL of them.
if ( actor is not null && ( RequiredTriggers.Count < 1 || RequiredTriggers.All( x => x.Activated ) ) )
{
Actor = actor;
Activate();
}
}
protected override void DrawGizmos()
{
Gizmo.Transform = new();
var baseColor = Activated ? Color.Red : Color.Cyan;
foreach ( var obj in Components.GetAll<Collider>() )
{
foreach ( var shape in obj.KeyframeBody.Shapes )
{
var body = shape.Body;
var bounds = body.GetBounds();
Gizmo.Draw.Color = baseColor.WithAlpha( 0.8f );
Gizmo.Draw.LineBBox( bounds.Grow( 1f ) );
Gizmo.Draw.Color = baseColor.WithAlpha( 0.2f );
Gizmo.Draw.SolidBox( bounds );
Gizmo.Hitbox.BBox( bounds );
}
}
foreach ( var child in GameObject.Children )
{
Gizmo.Draw.Color = baseColor.WithAlpha( 0.8f );
Gizmo.Draw.Line( GameObject.Transform.Position + Vector3.Up * 2f, child.Transform.Position );
}
}
void Triggers()
{
foreach ( var go in Triggerables )
{
var triggerable = go?.Components.Get<ITriggerable>();
if ( triggerable is not null ) triggerable.Trigger();
}
}
protected virtual void Activate()
{
Triggers();
OnActivate?.Invoke( Markers );
Activated = true;
}
public void OnTriggerExit( Collider other )
{
}
}