using SpaceGame.Api.Simulation.Engine; using SpaceGame.Api.Simulation.Model; namespace SpaceGame.Api.Simulation.AI; internal sealed class IdleShipBehaviorState : IShipBehaviorState { public string Kind => "idle"; public void Plan(SimulationEngine engine, ShipRuntime ship, SimulationWorld world) { ship.ControllerTask = new ControllerTaskRuntime { Kind = ControllerTaskKind.Idle, Threshold = world.Balance.ArrivalThreshold, Status = WorkStatus.Pending, }; } public void ApplyEvent(SimulationEngine engine, ShipRuntime ship, SimulationWorld world, string controllerEvent) { } } internal sealed class PatrolShipBehaviorState : IShipBehaviorState { public string Kind => "patrol"; public void Plan(SimulationEngine engine, ShipRuntime ship, SimulationWorld world) { if (ship.DefaultBehavior.PatrolPoints.Count == 0) { ship.DefaultBehavior.Kind = "idle"; ship.ControllerTask = new ControllerTaskRuntime { Kind = ControllerTaskKind.Idle, Threshold = world.Balance.ArrivalThreshold, Status = WorkStatus.Pending, }; return; } ship.ControllerTask = new ControllerTaskRuntime { Kind = ControllerTaskKind.Travel, TargetPosition = ship.DefaultBehavior.PatrolPoints[ship.DefaultBehavior.PatrolIndex], TargetSystemId = ship.SystemId, Threshold = 18f, }; } public void ApplyEvent(SimulationEngine engine, ShipRuntime ship, SimulationWorld world, string controllerEvent) { if (controllerEvent == "arrived" && ship.DefaultBehavior.PatrolPoints.Count > 0) { ship.DefaultBehavior.PatrolIndex = (ship.DefaultBehavior.PatrolIndex + 1) % ship.DefaultBehavior.PatrolPoints.Count; } } } internal sealed class ResourceHarvestShipBehaviorState : IShipBehaviorState { private readonly string resourceItemId; private readonly string requiredModule; public ResourceHarvestShipBehaviorState(string kind, string resourceItemId, string requiredModule) { Kind = kind; this.resourceItemId = resourceItemId; this.requiredModule = requiredModule; } public string Kind { get; } public void Plan(SimulationEngine engine, ShipRuntime ship, SimulationWorld world) => engine.PlanResourceHarvest(ship, world, resourceItemId, requiredModule); public void ApplyEvent(SimulationEngine engine, ShipRuntime ship, SimulationWorld world, string controllerEvent) { switch (ship.DefaultBehavior.Phase, controllerEvent) { case ("travel-to-node", "arrived"): ship.DefaultBehavior.Phase = SimulationEngine.GetShipCargoAmount(ship) >= ship.Definition.CargoCapacity ? "travel-to-station" : "extract"; break; case ("extract", "cargo-full"): ship.DefaultBehavior.Phase = "travel-to-station"; break; case ("extract", "node-depleted"): ship.DefaultBehavior.Phase = "travel-to-node"; ship.DefaultBehavior.NodeId = null; break; case ("travel-to-station", "arrived"): ship.DefaultBehavior.Phase = "dock"; break; case ("dock", "docked"): ship.DefaultBehavior.Phase = "unload"; break; case ("undock", "undocked"): ship.DefaultBehavior.Phase = "travel-to-node"; ship.DefaultBehavior.NodeId = null; break; } } } internal sealed class ConstructStationShipBehaviorState : IShipBehaviorState { public string Kind => "construct-station"; public void Plan(SimulationEngine engine, ShipRuntime ship, SimulationWorld world) => engine.PlanStationConstruction(ship, world); public void ApplyEvent(SimulationEngine engine, ShipRuntime ship, SimulationWorld world, string controllerEvent) { switch (ship.DefaultBehavior.Phase, controllerEvent) { case ("travel-to-station", "arrived"): ship.DefaultBehavior.Phase = "deliver-to-site"; break; case ("deliver-to-site", "construction-delivered"): ship.DefaultBehavior.Phase = "build-site"; break; case ("construct-module", "module-constructed"): case ("build-site", "site-constructed"): ship.DefaultBehavior.Phase = "travel-to-station"; ship.DefaultBehavior.ModuleId = null; break; } } }