96 lines
1.8 KiB
C#
96 lines
1.8 KiB
C#
|
|
using Godot;
|
||
|
|
using System.Collections.Generic;
|
||
|
|
using Rokojori.Extensions;
|
||
|
|
namespace Rokojori;
|
||
|
|
|
||
|
|
[Tool]
|
||
|
|
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Action.svg")]
|
||
|
|
public partial class Receptor:Action
|
||
|
|
{
|
||
|
|
[Export]
|
||
|
|
public SceneCondition sceneCondition;
|
||
|
|
|
||
|
|
[Export( PropertyHint.Range, "0.1,100")]
|
||
|
|
public float receiptionTriggerCoverage = 75f;
|
||
|
|
|
||
|
|
[Export( PropertyHint.Range, "10,2000")]
|
||
|
|
public float receiptionWindowDurationMS = 500f;
|
||
|
|
|
||
|
|
[Export( PropertyHint.Range, "10,1000")]
|
||
|
|
public float tickRateMS = 100f;
|
||
|
|
|
||
|
|
[Export]
|
||
|
|
public Timeline timeline;
|
||
|
|
|
||
|
|
int resultSize => Mathf.CeilToInt( receiptionWindowDurationMS / tickRateMS );
|
||
|
|
|
||
|
|
RingBuffer<bool> _resultsBuffer;
|
||
|
|
|
||
|
|
bool _activated = false;
|
||
|
|
|
||
|
|
public bool activated => _activated;
|
||
|
|
|
||
|
|
bool _active = false;
|
||
|
|
|
||
|
|
public bool active => _active;
|
||
|
|
|
||
|
|
int _eventID = -1;
|
||
|
|
|
||
|
|
public void Start()
|
||
|
|
{
|
||
|
|
if ( _active )
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
_active = true;
|
||
|
|
|
||
|
|
var duration = tickRateMS / 1000f;
|
||
|
|
var tle = TimelineManager.ScheduleLoopEvent( timeline, duration, 0, tle => Sample() );
|
||
|
|
_eventID = tle.id;
|
||
|
|
}
|
||
|
|
|
||
|
|
public void Stop()
|
||
|
|
{
|
||
|
|
if ( ! _active )
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
_active = false;
|
||
|
|
|
||
|
|
TimelineManager.RemoveEvent( timeline, _eventID );
|
||
|
|
_eventID = -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
protected override void _OnTrigger()
|
||
|
|
{
|
||
|
|
Sample();
|
||
|
|
}
|
||
|
|
|
||
|
|
void Sample()
|
||
|
|
{
|
||
|
|
if ( sceneCondition == null )
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( _resultsBuffer == null || _resultsBuffer.capacity != resultSize )
|
||
|
|
{
|
||
|
|
_resultsBuffer = new RingBuffer<bool>( resultSize );
|
||
|
|
}
|
||
|
|
|
||
|
|
_resultsBuffer.Add( sceneCondition.Evaluate() );
|
||
|
|
|
||
|
|
if ( _resultsBuffer.count != resultSize )
|
||
|
|
{
|
||
|
|
_activated = false;
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
var numActive = _resultsBuffer.CountItems( b => b );
|
||
|
|
_activated = numActive / (float) resultSize >= receiptionTriggerCoverage / 100f;
|
||
|
|
|
||
|
|
}
|
||
|
|
}
|