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).GridEntityId); var targetGrid = grid.GridTileToLocal(targetNode.TileRef.GridIndices); return targetGrid; } } }