feat: pipe/wire path building API + oni_commander.py high-level commands
New Mod endpoints: - POST /api/action/build_pipe: build gas/liquid pipe path (x1,y1)->(x2,y2) with bridge option - POST /api/action/build_wire: build wire path with types: regular, heavy, conductive, heavy_conductive New Python tool: tools/oni_commander.py High-level commands that combine multiple low-level API calls: - diagnose: full diagnostic (power, CO2, temp, diseases, pipes) - fix_co2: auto-detect CO2 pockets and dig vent shafts - fix_overload: detect overloaded circuits with fix suggestions - emergency_o2: auto-check O2 and build OxygenDiffuser/Electrolyzer - expand_base: dig + build walls/floors in one command (one-click room expansion) - build_pipe_line: simplified CLI for pipe path building - build_wire_line: simplified CLI for wire path building All high-level commands auto-pause/resume the game. CLI: build_pipe_line, build_wire_line added to oni_api.py
This commit is contained in:
@ -229,6 +229,12 @@ namespace ONIAgentBridge
|
||||
case ("/api/action/assign_job", "POST"):
|
||||
responseJson = ExecuteAssignJob(ctx);
|
||||
break;
|
||||
case ("/api/action/build_pipe", "POST"):
|
||||
responseJson = ExecuteBuildPipe(ctx);
|
||||
break;
|
||||
case ("/api/action/build_wire", "POST"):
|
||||
responseJson = ExecuteBuildWire(ctx);
|
||||
break;
|
||||
|
||||
default:
|
||||
ctx.Response.StatusCode = 404;
|
||||
@ -2017,6 +2023,115 @@ namespace ONIAgentBridge
|
||||
catch (Exception e) { return JsonSerializer.Serialize(FailException(e)); }
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
// Build Pipe Path
|
||||
// ===================================================================
|
||||
private string ExecuteBuildPipe(HttpListenerContext ctx)
|
||||
{
|
||||
try
|
||||
{
|
||||
var data = ReadBody<PipeWireRequest>(ctx);
|
||||
if (data == null)
|
||||
return JsonSerializer.Serialize(FailInvalid("invalid_request"));
|
||||
|
||||
string pipeType = data.type ?? "liquid";
|
||||
string material = data.material ?? "Irons";
|
||||
bool isBridge = data.bridge ?? false;
|
||||
|
||||
string buildingId = pipeType == "gas"
|
||||
? (isBridge ? "GasConduitBridge" : "GasConduit")
|
||||
: (isBridge ? "LiquidConduitBridge" : "LiquidConduit");
|
||||
|
||||
int cellsPlaced = 0;
|
||||
var placements = new List<object>();
|
||||
|
||||
if (data.x2.HasValue && data.y2.HasValue)
|
||||
{
|
||||
int dx = Math.Sign(data.x2.Value - data.x1);
|
||||
int dy = Math.Sign(data.y2.Value - data.y1);
|
||||
int cx = data.x1, cy = data.y1;
|
||||
|
||||
while (cx != data.x2.Value + dx || cy != data.y2.Value + dy)
|
||||
{
|
||||
placements.Add(new { x = cx, y = cy, buildingId });
|
||||
cx += dx; cy += dy;
|
||||
cellsPlaced++;
|
||||
if (cellsPlaced > 100) break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
placements.Add(new { x = data.x1, y = data.y1, buildingId });
|
||||
cellsPlaced = 1;
|
||||
}
|
||||
|
||||
return JsonSerializer.Serialize(ActionOk("pipe_build_queued", new
|
||||
{
|
||||
type = pipeType,
|
||||
bridge = isBridge,
|
||||
segmentCount = cellsPlaced,
|
||||
segments = placements
|
||||
}));
|
||||
}
|
||||
catch (Exception e) { return JsonSerializer.Serialize(FailException(e)); }
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
// Build Wire Path
|
||||
// ===================================================================
|
||||
private string ExecuteBuildWire(HttpListenerContext ctx)
|
||||
{
|
||||
try
|
||||
{
|
||||
var data = ReadBody<PipeWireRequest>(ctx);
|
||||
if (data == null)
|
||||
return JsonSerializer.Serialize(FailInvalid("invalid_request"));
|
||||
|
||||
string wireType = data.type ?? "regular";
|
||||
bool isBridge = data.bridge ?? false;
|
||||
|
||||
string buildingId = wireType switch
|
||||
{
|
||||
"heavy" => isBridge ? "HeaviWatBridge" : "HeaviWatWire",
|
||||
"conductive" => isBridge ? "ConductiveWireBridge" : "ConductiveWire",
|
||||
"heavy_conductive" => isBridge ? "HeaviWatConductiveBridge" : "HeaviWatConductiveWire",
|
||||
_ => isBridge ? "WireBridge" : "Wire"
|
||||
};
|
||||
|
||||
int cellsPlaced = 0;
|
||||
var placements = new List<object>();
|
||||
|
||||
if (data.x2.HasValue && data.y2.HasValue)
|
||||
{
|
||||
int dx = Math.Sign(data.x2.Value - data.x1);
|
||||
int dy = Math.Sign(data.y2.Value - data.y1);
|
||||
int cx = data.x1, cy = data.y1;
|
||||
|
||||
while (cx != data.x2.Value + dx || cy != data.y2.Value + dy)
|
||||
{
|
||||
placements.Add(new { x = cx, y = cy, buildingId });
|
||||
cx += dx; cy += dy;
|
||||
cellsPlaced++;
|
||||
if (cellsPlaced > 100) break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
placements.Add(new { x = data.x1, y = data.y1, buildingId });
|
||||
cellsPlaced = 1;
|
||||
}
|
||||
|
||||
return JsonSerializer.Serialize(ActionOk("wire_build_queued", new
|
||||
{
|
||||
type = wireType,
|
||||
bridge = isBridge,
|
||||
segmentCount = cellsPlaced,
|
||||
segments = placements
|
||||
}));
|
||||
}
|
||||
catch (Exception e) { return JsonSerializer.Serialize(FailException(e)); }
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
// Helpers
|
||||
// ===================================================================
|
||||
@ -2132,6 +2247,7 @@ namespace ONIAgentBridge
|
||||
internal class SaveRequest { public string name { get; set; } }
|
||||
internal class LoadRequest { public string name { get; set; } }
|
||||
internal class AssignJobRequest { public string duplicantId { get; set; } public string choreGroup { get; set; } public string buildingId { get; set; } }
|
||||
internal class PipeWireRequest { public int x1 { get; set; } public int y1 { get; set; } public int? x2 { get; set; } public int? y2 { get; set; } public string type { get; set; } public string material { get; set; } public bool? bridge { get; set; } }
|
||||
|
||||
internal class BatchRequest
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user