using Content.Server.AI.Operators;
using Content.Server.AI.Operators.Generic;
using Content.Server.AI.Operators.Movement;
using Content.Server.AI.Pathfinding;
using Content.Server.AI.Pathfinding.Accessible;
using Content.Server.AI.Utility.Considerations;
using Content.Server.AI.Utility.Considerations.ActionBlocker;
using Content.Server.AI.WorldState;
using Robust.Shared.Map;
using Robust.Shared.Random;
namespace Content.Server.AI.Utility.Actions.Idle
{
///
/// Will move to a random spot close by
///
public sealed class WanderAndWait : UtilityAction
{
public override bool CanOverride => false;
public override float Bonus => 1.0f;
public override void SetupOperators(Blackboard context)
{
var robustRandom = IoCManager.Resolve();
var randomGrid = FindRandomGrid(robustRandom);
float waitTime;
if (randomGrid != EntityCoordinates.Invalid)
{
waitTime = robustRandom.Next(3, 8);
}
else
{
waitTime = 0.0f;
}
ActionOperators = new Queue(new AiOperator[]
{
new MoveToGridOperator(Owner, randomGrid),
new WaitOperator(waitTime),
});
}
protected override IReadOnlyCollection> GetConsiderations(Blackboard context)
{
var considerationsManager = IoCManager.Resolve();
return new[]
{
considerationsManager.Get()
.BoolCurve(context),
};
}
private EntityCoordinates FindRandomGrid(IRobustRandom robustRandom)
{
// Very inefficient (should weight each region by its node count) but better than the old system
var reachableSystem = EntitySystem.Get();
var reachableArgs = ReachableArgs.GetArgs(Owner);
var entityRegion = reachableSystem.GetRegion(Owner);
var reachableRegions = reachableSystem.GetReachableRegions(reachableArgs, entityRegion);
// TODO: When SetupOperators can fail this should be null and fail the setup.
if (reachableRegions.Count == 0)
{
return default;
}
var reachableNodes = new List();
foreach (var region in reachableRegions)
{
foreach (var node in region.Nodes)
{
reachableNodes.Add(node);
}
}
var targetNode = robustRandom.Pick(reachableNodes);
var mapManager = IoCManager.Resolve();
var grid = mapManager.GetGrid(IoCManager.Resolve().GetComponent(Owner).GridID);
var targetGrid = grid.GridTileToLocal(targetNode.TileRef.GridIndices);
return targetGrid;
}
}
}