aether-shards/update_connectivity.py
2026-01-14 11:11:38 -08:00

134 lines
4.1 KiB
Python

import os
path = "src/generation/CrystalSpiresGenerator.js"
with open(path, "r", encoding="utf-8") as f:
lines = f.readlines()
start_idx = -1
for i, line in enumerate(lines):
if "ensureGlobalConnectivity(spires) {" in line:
start_idx = i
break
if start_idx == -1:
print("Error: ensureGlobalConnectivity not found")
exit(1)
# Find end of method. It's likely the second to last closing brace, or indented " }".
# The previous `view_file` showed it ending at line 1212/1213.
# We will scan for " }" starting from start_idx.
end_idx = -1
for i in range(start_idx + 1, len(lines)):
if lines[i].rstrip() == " }":
end_idx = i
break
if end_idx == -1:
print("Error: Closing brace not found")
exit(1)
# New Content
new_code = """ ensureGlobalConnectivity(spires) {
if (!spires || spires.length === 0) return;
// 1. Build Adjacency Graph
// Map platform ID "sIdx:pIdx" -> {id, p, neighbors: Set<id>}
const adj = new Map();
const platById = new Map();
const getPlatId = (sIdx, pIdx) => `${sIdx}:${pIdx}`;
spires.forEach((s, sIdx) => {
s.platforms.forEach((p, pIdx) => {
const id = getPlatId(sIdx, pIdx);
adj.set(id, {id, p, neighbors: new Set()});
platById.set(id, p);
});
});
// Populate Neighbors from Bridges
this.generatedAssets.bridges.forEach(b => {
if (b.fromPlatIdx !== undefined && b.toPlatIdx !== undefined) {
const idA = getPlatId(b.fromSpire, b.fromPlatIdx);
const idB = getPlatId(b.toSpire, b.toPlatIdx);
if(adj.has(idA) && adj.has(idB)) {
adj.get(idA).neighbors.add(idB);
adj.get(idB).neighbors.add(idA);
}
}
});
// 2. Find Connected Components (BFS)
const visited = new Set();
const components = [];
for(const [id, node] of adj) {
if(!visited.has(id)) {
const comp = [];
const q = [id];
visited.add(id);
while(q.length > 0) {
const curr = q.shift();
comp.push(curr);
adj.get(curr).neighbors.forEach(nId => {
if(!visited.has(nId)) {
visited.add(nId);
q.push(nId);
}
});
}
components.push(comp);
}
}
// 3. Link Components
if (components.length > 1) {
// Identify Main Component (Largest)
components.sort((a,b) => b.length - a.length);
const targetComp = components[0];
const targetNodeId = targetComp[0];
const targetPlat = platById.get(targetNodeId);
for(let i=1; i<components.length; i++) {
const orphanComp = components[i];
const orphanNodeId = orphanComp[0];
const orphanPlat = platById.get(orphanNodeId);
this.placeTeleporter(targetPlat, orphanPlat);
}
}
}
placeTeleporter(pA, pB) {
const findSpot = (p) => {
const r = p.radius - 1;
for(let x=Math.round(p.x-r); x<=Math.round(p.x+r); x++) {
for(let z=Math.round(p.z-r); z<=Math.round(p.z+r); z++) {
const y = Math.round(p.y);
const floor = this.grid.getCell(x, y, z);
const air = this.grid.getCell(x, y+1, z);
if (floor !== 0 && air === 0) {
return {x, y: y+1, z};
}
}
}
return null;
};
const sA = findSpot(pA);
const sB = findSpot(pB);
if(sA && sB) {
this.grid.setCell(sA.x, sA.y, sA.z, 22);
this.grid.setCell(sB.x, sB.y, sB.z, 22);
}
}
"""
# Replace
final_lines = lines[:start_idx] + [new_code] + lines[end_idx+1:]
with open(path, "w", encoding="utf-8") as f:
f.writelines(final_lines)
print("Update Complete")