improvement on gm windows, ai

This commit is contained in:
2026-03-20 12:40:26 -04:00
parent ff078fe939
commit 3b56785f9a
39 changed files with 2594 additions and 358 deletions

View File

@@ -21,7 +21,7 @@ internal sealed class ShipBehaviorStateMachine
new PatrolShipBehaviorState(),
new AttackTargetShipBehaviorState(),
new TradeHaulShipBehaviorState(),
new ResourceHarvestShipBehaviorState("auto-mine", "ore", "mining"),
new ResourceHarvestShipBehaviorState("auto-mine", null, "mining"),
new ConstructStationShipBehaviorState(),
};

View File

@@ -58,10 +58,10 @@ internal sealed class PatrolShipBehaviorState : IShipBehaviorState
internal sealed class ResourceHarvestShipBehaviorState : IShipBehaviorState
{
private readonly string resourceItemId;
private readonly string? resourceItemId;
private readonly string requiredModule;
public ResourceHarvestShipBehaviorState(string kind, string resourceItemId, string requiredModule)
public ResourceHarvestShipBehaviorState(string kind, string? resourceItemId, string requiredModule)
{
Kind = kind;
this.resourceItemId = resourceItemId;

View File

@@ -291,11 +291,18 @@ internal sealed class ShipControlService
};
}
internal void PlanResourceHarvest(ShipRuntime ship, SimulationWorld world, string resourceItemId, string requiredModule)
internal void PlanResourceHarvest(ShipRuntime ship, SimulationWorld world, string? resourceItemId, string requiredModule)
{
var behavior = ship.DefaultBehavior;
var cargoItemId = ship.Inventory.Keys.FirstOrDefault();
var targetResourceItemId = SelectMiningResourceItem(world, ship, cargoItemId ?? behavior.ItemId ?? resourceItemId);
if (string.IsNullOrWhiteSpace(targetResourceItemId))
{
behavior.Phase = null;
ship.ControllerTask = CreateIdleTask(world.Balance.ArrivalThreshold);
return;
}
if (!string.Equals(behavior.ItemId, targetResourceItemId, StringComparison.Ordinal))
{
behavior.ItemId = targetResourceItemId;
@@ -426,22 +433,22 @@ internal sealed class ShipControlService
}
}
private static string SelectMiningResourceItem(SimulationWorld world, ShipRuntime ship, string fallbackItemId)
private static string? SelectMiningResourceItem(SimulationWorld world, ShipRuntime ship, string? fallbackItemId)
{
var candidateItemId = world.MarketOrders
.Where(order =>
string.Equals(order.FactionId, ship.FactionId, StringComparison.Ordinal)
&& order.Kind == MarketOrderKinds.Buy
&& order.ConstructionSiteId is null
&& order.State != MarketOrderStateKinds.Cancelled
&& order.RemainingAmount > 0.01f)
.SelectMany(order => FactionIndustryPlanner.ResolveRootResourceItems(world, order.ItemId)
.Select(itemId => new
{
ItemId = itemId,
Score = order.RemainingAmount * MathF.Max(0.25f, order.Valuation),
}))
.Where(entry =>
CanShipMineItem(world, ship, entry.ItemId)
&& world.Nodes.Any(node => string.Equals(node.ItemId, entry.ItemId, StringComparison.Ordinal) && node.OreRemaining > 0.01f))
.Select(order => new
{
ItemId = order.ItemId,
Score = order.RemainingAmount * MathF.Max(0.25f, order.Valuation),
})
.Where(entry => CanShipMineItem(world, ship, entry.ItemId))
.Where(entry => world.Nodes.Any(node => string.Equals(node.ItemId, entry.ItemId, StringComparison.Ordinal) && node.OreRemaining > 0.01f))
.GroupBy(entry => entry.ItemId, StringComparer.Ordinal)
.Select(group => new
{
@@ -457,7 +464,8 @@ internal sealed class ShipControlService
return candidateItemId;
}
if (CanShipMineItem(world, ship, fallbackItemId)
if (!string.IsNullOrWhiteSpace(fallbackItemId)
&& CanShipMineItem(world, ship, fallbackItemId)
&& world.Nodes.Any(node => string.Equals(node.ItemId, fallbackItemId, StringComparison.Ordinal) && node.OreRemaining > 0.01f))
{
return fallbackItemId;

View File

@@ -1,5 +1,6 @@
using static SpaceGame.Api.Stations.Simulation.InfrastructureSimulationService;
using static SpaceGame.Api.Shared.Runtime.SimulationRuntimeSupport;
using static SpaceGame.Api.Stations.Simulation.StationSimulationService;
namespace SpaceGame.Api.Ships.Simulation;
@@ -331,7 +332,8 @@ internal sealed partial class ShipTaskExecutionService
}
var moved = MathF.Min(remaining, world.Balance.TransferRate * deltaSeconds);
moved = MathF.Min(moved, GetInventoryAmount(station.Inventory, required.Key));
var available = MathF.Max(0f, GetInventoryAmount(station.Inventory, required.Key) - GetStationReserveFloor(world, station, required.Key));
moved = MathF.Min(moved, available);
if (moved <= 0.01f)
{
continue;
@@ -356,7 +358,8 @@ internal sealed partial class ShipTaskExecutionService
}
var moved = MathF.Min(remaining, world.Balance.TransferRate * deltaSeconds);
moved = MathF.Min(moved, GetInventoryAmount(station.Inventory, required.Key));
var available = MathF.Max(0f, GetInventoryAmount(station.Inventory, required.Key) - GetStationReserveFloor(world, station, required.Key));
moved = MathF.Min(moved, available);
if (moved <= 0.01f)
{
continue;