#define ISDISTEDGE(A, D) (((A.x > (world.maxx - D) || A.x <= D)||(A.y > (world.maxy - D) || A.y <= D))?1:0) //1 if A is within D tiles range from edge of the map. #define SPAWN(TYPE,LOC,NUM) for(var/i=0, i= 1 && currentY+yy <= world.maxy && currentY+yy >= 1) count += L[currentX+xx][currentY+yy] else //OOB, count as wall. count += default var/count2 = 0 if(fillLarge) for(var/xx=-passTwoRange, xx<=passTwoRange, xx++) for(var/yy=-passTwoRange, yy<=passTwoRange, yy++) if(abs(xx)==passTwoRange && abs(yy)==passTwoRange) continue //Skip diagonals for this one. Better results if(currentX+xx <= world.maxx && currentX+xx >= 1 && currentY+yy <= world.maxy && currentY+yy >= 1) count2 += L[currentX+xx][currentY+yy] else //OOB, count as wall. count2 += default return (count >= minSolid + ((generation==4||generation==3) ? endFill : 0 ) || (count2<=(generation==4?1:2) && fillLarge && (generation==3 || generation==4)) ) //Remove ((generation==4||generation==3)?-1:0) for larger corridors /datum/mapGenerator/seaCaverns //Cellular automata based generator. Produces cavern-like maps. Empty space is filled with asteroid floor. generate(var/list/miningZ) var/map[world.maxx][world.maxy] for(var/x=1,x<=world.maxx,x++) for(var/y=1,y<=world.maxy,y++) map[x][y] = pick(90;1,100;0) //Initialize randomly. for(var/i=0, i<5, i++) //5 Passes to smooth it out. var/mapnew[world.maxx][world.maxy] for(var/x=1,x<=world.maxx,x++) for(var/y=1,y<=world.maxy,y++) mapnew[x][y] = CAGetSolid(map, x, y, i) LAGCHECK(LAG_REALTIME) map = mapnew for(var/x=1,x<=world.maxx,x++) for(var/y=1,y<=world.maxy,y++) var/turf/T = locate(x,y,AST_ZLEVEL) if(map[x][y] && !ISDISTEDGE(T, 3) && T.loc && ((T.loc.type == /area) || istype(T.loc , /area/allowGenerate)) ) var/turf/simulated/wall/asteroid/N = new/turf/simulated/wall/asteroid(T) N.quality = rand(-101,101) generated.Add(N) if(T.loc.type == /area || istype(T.loc, /area/allowGenerate)) new/area/allowGenerate/trench(T) LAGCHECK(LAG_REALTIME) var/list/used = list() for(var/s=0, s<20, s++) var/turf/TU = pick(generated - used) var/list/L = list() for(var/turf/simulated/wall/asteroid/A in orange(5,TU)) L.Add(A) seeds.Add(TU) seeds[TU] = L used.Add(L) used.Add(TU) var/list/holeList = list() for(var/k=0, k 9) seeds.Add(X) seeds[X] = placed var/list/holeList = list() for(var/k=0, kSkipping Mining Generation!") return else boutput(world, "Generating Mining Level ...") for(var/turf/T) if(T.z == AST_ZLEVEL) miningZ.Add(T) var/extra = rand(0,AST_NUMPREFABSEXTRA) for(var/n=0, n= 33) logTheThing("debug", null, null, "Prefab placement #[n] [M.type] failed due to maximum tries [maxTries][M.required?" WARNING: REQUIRED FAILED":""]. [target] @ [showCoords(target.x, target.y, target.z)]") else break var/datum/mapGenerator/D if(map_currently_underwater) D = new/datum/mapGenerator/seaCaverns() else D = new/datum/mapGenerator/asteroidsDistance() miningZ = D.generate(miningZ) boutput(world, "Generated Mining Level in [((world.timeofday - startTime)/10)] seconds!") if (map_currently_underwater) hotspot_controller.generate_map() /proc/pickPrefab() var/list/eligible = list() var/list/required = list() for(var/datum/generatorPrefab/M in miningModifiers) if(M.underwater != map_currently_underwater) continue if(M.type in miningModifiersUsed) if(M.required) continue if(M.maxNum != -1) if(miningModifiersUsed[M.type] >= M.maxNum) continue else eligible.Add(M) eligible[M] = M.probability else eligible.Add(M) eligible[M] = M.probability else eligible.Add(M) eligible[M] = M.probability if(M.required) required.Add(M) if(required.len) var/datum/generatorPrefab/P = required[1] miningModifiersUsed.Add(P.type) miningModifiersUsed[P.type] = 1 return P else if(eligible.len) var/datum/generatorPrefab/P = pickweight(eligible) if(P.type in miningModifiersUsed) miningModifiersUsed[P.type] = (miningModifiersUsed[P.type] + 1) else miningModifiersUsed.Add(P.type) miningModifiersUsed[P.type] = 1 return P else return null /datum/generatorPrefab var/probability = 0 var/maxNum = 0 var/prefabPath = "" var/prefabSizeX = 5 var/prefabSizeY = 5 var/underwater = 0 //prefab will only be used if this matches map_currently_underwater. I.e. if this is 1 and map_currently_underwater is 1 then the prefab may be used. var/required = 0 //If 1 we will try to always place thing thing no matter what. Required prefabs will only ever be placed once. proc/applyTo(var/turf/target) var/adjustX = target.x var/adjustY = target.y //Move prefabs backwards if they would end up outside the map. if((adjustX + prefabSizeX) > (world.maxx - AST_MAPBORDER)) adjustX -= ((adjustX + prefabSizeX) - (world.maxx - AST_MAPBORDER)) if((adjustY + prefabSizeY) > (world.maxy - AST_MAPBORDER)) adjustY -= ((adjustY + prefabSizeY) - (world.maxy - AST_MAPBORDER)) var/turf/T = locate(adjustX, adjustY, target.z) for(var/x=0, x