import os path = "src/generation/CrystalSpiresGenerator.js" with open(path, "r", encoding="utf-8") as f: lines = f.readlines() # Line numbers (1-based) to 0-based indices # remove 780-944, 1070-1170, 1172-1234, 1345-1450 # Note: Python slices are [start:end] where start is inclusive, end is exclusive. # Line N -> Index N-1. # Block 1: 1 to 779 (Index 0 to 779) chunk1 = lines[:779] # Block 2: Skip 780-944 (Index 779-944) # Keep 945-1069 (Index 944-1069) chunk2 = lines[944:1069] # Block 3: Skip 1070-1170 (Index 1069-1170) # Keep 1171 (Index 1170) chunk3 = lines[1170:1171] # Block 4: Skip 1172-1234 (Index 1171-1234) # Keep 1235-1344 (Index 1234-1344) chunk4 = lines[1234:1344] # Block 5: Skip 1345-1450 (Index 1344-1450) # Keep 1451-End (Index 1450:) chunk5 = lines[1450:] # New Content Strings new_buildBridge = """ buildBridge(start, end, fromCenter = null, minDist = 2.0) { // Wrapper for generateBezierBridge // Simple Bezier logic for compatibility check const p0 = start; const p2 = end; const midX = (p0.x + p2.x) / 2; const midZ = (p0.z + p2.z) / 2; const midY = (p0.y + p2.y) / 2; const dx = p2.x - p0.x; const dz = p2.z - p0.z; const dist = Math.sqrt(dx*dx + dz*dz); const nx = dx / dist; const nz = dz / dist; const arcFactor = dist < 5.0 ? 0.5 : (dist / 8.0); const archHeight = 3.0 * arcFactor; // Simplified random const curveMag = 0; // Straight arch for simple builds (or random if rng available?) // We don't have RNG access easily here unless we use this.rng // Assume this.rng exists. if (this.rng) { const cm = this.rng.range(-dist/4, dist/4); const ah = this.rng.range(1, 4) * arcFactor; // Recalc } // Re-use generateBezierBridge logic? // "generateBezierBridge" requires pA, pB (Platforms). // Here we have points. // We'll duplicate logic briefly to ensure it works. const p1 = {x: midX, y: midY + archHeight, z: midZ}; const steps = Math.ceil(dist * 2.5); const pathVoxels = []; const visited = new Set(); for(let i=0; i<=steps; i++) { const t = i / steps; const invT = 1 - t; const x = invT*invT*p0.x + 2*invT*t*p1.x + t*t*p2.x; const y = invT*invT*p0.y + 2*invT*t*p1.y + t*t*p2.y; const z = invT*invT*p0.z + 2*invT*t*p1.z + t*t*p2.z; const ix = Math.round(x); const iy = Math.round(y); const iz = Math.round(z); const key = `${ix},${iy},${iz}`; if (!visited.has(key)) { visited.add(key); pathVoxels.push({x: ix, y: iy, z: iz}); } } // VALIDATION for (let i=0; i 4 && dEnd > 4) return false; } const h1 = this.grid.getCell(v.x, v.y+1, v.z); const h2 = this.grid.getCell(v.x, v.y+2, v.z); if (h1 !== 0 || h2 !== 0) return false; if (i > 0) { if (Math.abs(v.y - pathVoxels[i-1].y) > 1) return false; } } // PLACEMENT for (const v of pathVoxels) { if (this.grid.getCell(v.x, v.y, v.z) === 0) { this.grid.setCell(v.x, v.y, v.z, 20); } } return true; }\n\n""" new_connectivity = """ /** * Ensure Connectivity via Flood Fill & Teleporters. */ ensureGlobalConnectivity(spires) { if (!spires || spires.length === 0) return; let startPt = {x: spires[0].x, y: spires[0].platforms[0].y + 1, z: spires[0].z}; const visited = new Set(); const q = [{x: Math.round(startPt.x), y: Math.round(startPt.y), z: Math.round(startPt.z)}]; visited.add(`${q[0].x},${q[0].y},${q[0].z}`); const MAX_ITER = 50000; let iter = 0; // Flood Fill while(q.length > 0 && iter < MAX_ITER) { iter++; const curr = q.shift(); const dirs = [{x:1,z:0},{x:-1,z:0},{x:0,z:1},{x:0,z:-1}]; for(const d of dirs) { const nx = curr.x+d.x; const nz = curr.z+d.z; // Y-scan const candidates = [curr.y, curr.y+1, curr.y-1]; for(const ny of candidates) { if (this.grid.isValidBounds(nx, ny, nz)) { const floor = this.grid.getCell(nx, ny-1, nz); const feet = this.grid.getCell(nx, ny, nz); const h1 = this.grid.getCell(nx, ny+1, nz); const h2 = this.grid.getCell(nx, ny+2, nz); const pass = (floor!==0 && (feet===0||feet===20||feet===22) && h1===0 && h2===0); if(pass) { const key = `${nx},${ny},${nz}`; if(!visited.has(key)) { visited.add(key); q.push({x:nx, y:ny, z:nz}); } } } } } } // Identify Orphans const orphans = []; spires.forEach(s => { s.platforms.forEach(p => { // Check if any point on/near platform is visited let connected = false; const r = p.radius - 1; for(let x=p.x-r; x<=p.x+r; x++) { for(let z=p.z-r; z<=p.z+r; z++) { const key = `${Math.round(x)},${Math.round(p.y+1)},${Math.round(z)}`; if(visited.has(key)) { connected = true; break; } } if(connected) break; } if (!connected) orphans.push(p); }); }); // Fix Orphans with Teleporters orphans.forEach(orp => { const ox = Math.round(orp.x); const oz = Math.round(orp.z); const oy = Math.round(orp.y + 1); // Stand on top // Find target (Spawn/Spire 0) const target = spires[0].platforms[0]; const tx = Math.round(target.x); const tz = Math.round(target.z); const ty = Math.round(target.y + 1); if(this.grid.isValidBounds(ox, oy, oz) && this.grid.isValidBounds(tx, ty, tz)) { this.grid.setCell(ox, oy, oz, 22); // Teleporter this.grid.setCell(tx, ty, tz, 22); // Teleporter // Logic linkage would be separate asset, but visual ID 22 is enough for now. // console.log("Teleporter Placed"); } }); }\n\n""" # Assemble final_content = ( chunk1 + [" // A* Removed\n"] + chunk2 + [new_buildBridge] + chunk3 + [" // Legacy Removed\n"] + chunk4 + [new_connectivity] + chunk5 ) # Write back with open(path, "w", encoding="utf-8") as f: f.writelines(final_content) print("Refactor Complete")