using System; using System.Collections.Generic; using Robust.Shared.Interfaces.GameObjects; namespace Content.Server.AI.WorldState { /// /// Basic StateDate, no frills /// public interface IAiState { void Setup(IEntity owner); } public interface IPlanningState { void Reset(); } public interface ICachedState { void CheckCache(); } /// /// The default class for state values. Also see CachedStateData and PlanningStateData /// /// public abstract class StateData : IAiState { public abstract string Name { get; } protected IEntity Owner { get; private set; } public void Setup(IEntity owner) { Owner = owner; } public abstract T GetValue(); } /// /// For when we want to set StateData but not reset it when re-planning actions /// Useful for group blackboard sharing or to avoid repeating the same action (e.g. bark phrases). /// /// public abstract class StoredStateData : IAiState { // Probably not the best class name but couldn't think of anything better public abstract string Name { get; } private IEntity Owner { get; set; } private T _value; public void Setup(IEntity owner) { Owner = owner; } public virtual void SetValue(T value) { _value = value; } public T GetValue() { return _value; } } /// /// This is state data that is transient and forgotten every time we re-plan /// e.g. "Current Target" gets updated for every action we consider /// /// public abstract class PlanningStateData : IAiState, IPlanningState { public abstract string Name { get; } protected IEntity Owner { get; private set; } protected T Value; public void Setup(IEntity owner) { Owner = owner; } public abstract void Reset(); public T GetValue() { return Value; } public virtual void SetValue(T value) { Value = value; } } /// /// This is state data that is cached for n seconds before being discarded. /// Mostly useful to get nearby components and store the value. /// /// public abstract class CachedStateData : IAiState, ICachedState { public abstract string Name { get; } protected IEntity Owner { get; private set; } private bool _cached; protected T Value; private DateTime _lastCache = DateTime.Now; /// /// How long something stays in the cache before new values are retrieved /// protected float CacheTime { get; set; } = 2.0f; public void Setup(IEntity owner) { Owner = owner; } public void CheckCache() { if (!_cached || (DateTime.Now - _lastCache).TotalSeconds >= CacheTime) { _cached = false; return; } _cached = true; } /// /// When the cache is stale we'll retrieve the actual value and store it again /// protected abstract T GetTrueValue(); public T GetValue() { CheckCache(); if (!_cached) { Value = GetTrueValue(); _cached = true; _lastCache = DateTime.Now; } return Value; } } }