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 the LAST closing brace in the file (Class End) class_end_idx = -1 for i in range(len(lines)-1, 0, -1): if lines[i].strip() == "}": class_end_idx = i break if class_end_idx == -1: print("Error: Class end not found") exit(1) # New Content (With Logs AND robust logic) new_code = """ ensureGlobalConnectivity(spires) { console.log("Ensure Connectivity running..."); if (!spires || spires.length === 0) return; const adj = new Map(); const platById = new Map(); const getPlatId = (sIdx, pIdx) => `${sIdx}:${pIdx}`; let nodeCount = 0; 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); nodeCount++; }); }); console.log(`Adjacency Graph Nodes: ${nodeCount}`); let edgeCount = 0; 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); edgeCount++; } } else { console.log("Bridge missing indices:", b); } }); console.log(`Adjacency Graph Edges: ${edgeCount}`); 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); } } console.log(`Connected Components: ${components.length}`); if (components.length > 1) { 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 { 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); console.log(`Placed Teleporter between (${sA.x},${sA.y},${sA.z}) and (${sB.x},${sB.y},${sB.z})`); } else { console.log("Failed to find spot for Teleporter"); } } } """ # Replace from start_idx to class_end_idx + 1 (since new_code includes }) final_lines = lines[:start_idx] + [new_code] # Note: new_code ends with "}\n". # We dropped `lines[class_end_idx]` (the old closing brace). # We also dropped everything between start_idx and class_end_idx. with open(path, "w", encoding="utf-8") as f: f.writelines(final_lines) print("Cleanup Complete")