Code/BehaviorTree/Decorator/TimeMin.cs
using Sandbox.Diagnostics;
namespace NPBehave
{
public class TimeMin : Decorator
{
private float _limit = 0.0f;
private float _randomVariation;
private bool _waitOnFailure = false;
private bool _isLimitReached = false;
private bool _isDecorateeDone = false;
private bool _isDecorateeSuccess = false;
public TimeMin(float limit, Node decoratee) : base("TimeMin", decoratee)
{
_limit = limit;
_randomVariation = _limit * 0.05f;
_waitOnFailure = false;
Assert.True(limit > 0f, "limit has to be set");
}
public TimeMin(float limit, bool waitOnFailure, Node decoratee) : base("TimeMin", decoratee)
{
_limit = limit;
_randomVariation = _limit * 0.05f;
_waitOnFailure = waitOnFailure;
Assert.True(limit > 0f, "limit has to be set");
}
public TimeMin(float limit, float randomVariation, bool waitOnFailure, Node decoratee) : base("TimeMin", decoratee)
{
_limit = limit;
_randomVariation = randomVariation;
_waitOnFailure = waitOnFailure;
Assert.True(limit > 0f, "limit has to be set");
}
protected override void DoStart()
{
_isDecorateeDone = false;
_isDecorateeSuccess = false;
_isLimitReached = false;
Clock.AddTimer(_limit, _randomVariation, 0, TimeoutReached);
Decoratee.Start();
}
protected override void DoStop()
{
if (Decoratee.IsActive)
{
Clock.RemoveTimer(TimeoutReached);
_isLimitReached = true;
Decoratee.Stop();
}
else
{
Clock.RemoveTimer(TimeoutReached);
Stopped(false);
}
}
protected override void DoChildStopped(Node child, bool result)
{
_isDecorateeDone = true;
_isDecorateeSuccess = result;
if (_isLimitReached || (!result && !_waitOnFailure))
{
Clock.RemoveTimer(TimeoutReached);
Stopped(_isDecorateeSuccess);
}
else
{
Assert.True(Clock.HasTimer(TimeoutReached));
}
}
private void TimeoutReached()
{
_isLimitReached = true;
if (_isDecorateeDone)
{
Stopped(_isDecorateeSuccess);
}
else
{
Assert.True(Decoratee.IsActive);
}
}
}
}