diff --git a/code/modules/procedural mapping/mapGenerator.dm b/code/modules/procedural mapping/mapGenerator.dm index 9a304e5c57a..887ddfc40a4 100644 --- a/code/modules/procedural mapping/mapGenerator.dm +++ b/code/modules/procedural mapping/mapGenerator.dm @@ -1,10 +1,27 @@ +//clusterCheckFlags defines +//All based on clusterMin and clusterMax as guides + +//Individual defines +#define CLUSTER_CHECK_NONE 0 //No checks are done, cluster as much as possible +#define CLUSTER_CHECK_DIFFERENT_TURFS 2 //Don't let turfs of DIFFERENT types cluster +#define CLUSTER_CHECK_DIFFERENT_ATOMS 4 //Don't let atoms of DIFFERENT types cluster +#define CLUSTER_CHECK_SAME_TURFS 8 //Don't let turfs of the SAME type cluster +#define CLUSTER_CHECK_SAME_ATOMS 16 //Don't let atoms of the SAME type cluster + +//Combined defines +#define CLUSTER_CHECK_SAMES 24 //Don't let any of the same type cluster +#define CLUSTER_CHECK_DIFFERENTS 6 //Don't let any of different types cluster +#define CLUSTER_CHECK_ALL_TURFS 10 //Don't let ANY turfs cluster same and different types +#define CLUSTER_CHECK_ALL_ATOMS 20 //Don't let ANY atoms cluster same and different types + +//All +#define CLUSTER_CHECK_ALL 30 //Don't let anything cluster, like, at all + /datum/mapGenerator //Map information var/list/map = list() - var/turf/bottomLeft = null - var/turf/topRight = null //mapGeneratorModule information var/list/modules = list() @@ -13,21 +30,62 @@ ..() initialiseModules() -//Defines the region the map represents, sets map, bottomLeft, topRight +//Defines the region the map represents, sets map //Returns the map -/datum/mapGenerator/proc/defineRegion(var/turf/Start, var/turf/End) +/datum/mapGenerator/proc/defineRegion(var/turf/Start, var/turf/End, var/replace = 0) if(!checkRegion(Start, End)) return 0 - if(!Start || !End) - return 0 - bottomLeft = Start - topRight = End + if(replace) + undefineRegion() - map = block(bottomLeft,topRight) + map |= block(Start,End) return map +//Defines the region the map represents, as a CIRCLE!, sets map +//Returns the map +/datum/mapGenerator/proc/defineCircularRegion(var/turf/Start, var/turf/End, var/replace = 0) + if(!checkRegion(Start, End)) + return 0 + + var/centerX = abs(max(End.x-Start.x,1)) + var/centerY = abs(max(End.y-Start.y,1)) + + + var/lilZ = min(Start.z,End.z) + var/bigZ = max(Start.z,End.z) + + var/centerZ = max(abs(bigZ-(lilZ/2)),1) //Spherical maps! woo! + + var/radius = abs(max(centerX,centerY)) //take the biggest displacement as the radius + + if(replace) + undefineRegion() + + //Sphere mode engage + var/evenCheckZ = 0 + if(max(bigZ,lilZ) % 2 == 0) + evenCheckZ = centerZ+1 + + for(var/i = lilZ, i <= bigZ, i++) + var/theRadius = radius + if(i != centerZ) + if(i != evenCheckZ) + theRadius = max(radius/max((2*abs(centerZ-i)),1),1) + + + map |= circlerange(locate(centerX,centerY,i),theRadius) + + + return map + + +//Empties the map list, he's dead jim. +/datum/mapGenerator/proc/undefineRegion() + map = list() //bai bai + + //Checks for and Rejects bad region coordinates //Returns 1/0 /datum/mapGenerator/proc/checkRegion(var/turf/Start, var/turf/End) @@ -52,7 +110,8 @@ if(!modules || !modules.len) return for(var/datum/mapGeneratorModule/mod in modules) - mod.generate() + spawn(0) + mod.generate() //Requests the mapGeneratorModule(s) to (re)generate this one turf @@ -63,7 +122,8 @@ if(!modules || !modules.len) return for(var/datum/mapGeneratorModule/mod in modules) - mod.place(T) + spawn(0) + mod.place(T) //Replaces all paths in the module list with actual module datums @@ -114,6 +174,27 @@ src << "End Coords: [endCoords[1]] - [endCoords[2]] - [endCoords[3]]" return + var/list/clusters = list("None"=CLUSTER_CHECK_NONE,"All"=CLUSTER_CHECK_ALL,"Sames"=CLUSTER_CHECK_SAMES,"Differents"=CLUSTER_CHECK_DIFFERENTS, \ + "Same turfs"=CLUSTER_CHECK_SAME_TURFS, "Same atoms"=CLUSTER_CHECK_SAME_ATOMS, "Different turfs"=CLUSTER_CHECK_DIFFERENT_TURFS, \ + "Different atoms"=CLUSTER_CHECK_DIFFERENT_ATOMS, "All turfs"=CLUSTER_CHECK_ALL_TURFS,"All atoms"=CLUSTER_CHECK_ALL_ATOMS) + + var/moduleClusters = input("Cluster Flags (Cancel to leave unchanged from defaults)","Map Gen Settings") as null|anything in clusters + //null for default + + var/theCluster = 0 + if(moduleClusters != "None") + if(!clusters[moduleClusters]) + src << "Invalid Cluster Flags" + return + theCluster = clusters[moduleClusters] + else + theCluster = CLUSTER_CHECK_NONE + + if(theCluster) + for(var/datum/mapGeneratorModule/M in N.modules) + M.clusterCheckFlags = theCluster + + src << "Defining Region" N.defineRegion(Start, End) src << "Region Defined" diff --git a/code/modules/procedural mapping/mapGeneratorModule.dm b/code/modules/procedural mapping/mapGeneratorModule.dm index 458f11cd969..da08a540ef3 100644 --- a/code/modules/procedural mapping/mapGeneratorModule.dm +++ b/code/modules/procedural mapping/mapGeneratorModule.dm @@ -1,16 +1,12 @@ -#define CLUSTER_CHECK_NONE 0 //No checks are done, cluster as much as possible -#define CLUSTER_CHECK_ATOMS 2 //Don't let atoms cluster, based on clusterMin and clusterMax as guides -#define CLUSTER_CHECK_TURFS 4 //Don't let turfs cluster, based on clusterMin and clusterMax as guides -#define CLUSTER_CHECK_ALL 6 //Don't let anything cluster, based on clusterMind and clusterMax as guides - /datum/mapGeneratorModule var/datum/mapGenerator/mother = null var/list/spawnableAtoms = list() var/list/spawnableTurfs = list() var/clusterMax = 5 var/clusterMin = 1 - var/clusterCheckFlags = CLUSTER_CHECK_ALL + var/clusterCheckFlags = CLUSTER_CHECK_SAME_ATOMS + var/allowAtomsOnSpace = FALSE //Syncs the module up with it's mother @@ -35,27 +31,74 @@ return 0 var/clustering = 0 + var/skipLoopIteration = FALSE //Turfs don't care whether atoms can be placed here for(var/turfPath in spawnableTurfs) - if(clusterCheckFlags & CLUSTER_CHECK_TURFS) - if(clusterMax && clusterMin) + + //Clustering! + if(clusterMax && clusterMin) + + //You're the same as me? I hate you I'm going home + if(clusterCheckFlags & CLUSTER_CHECK_SAME_TURFS) clustering = rand(clusterMin,clusterMax) - if(locate(/atom/movable) in range(clustering, T)) + for(var/turf/F in trange(clustering,T)) + if(istype(F,turfPath)) + skipLoopIteration = TRUE + break + if(skipLoopIteration) + skipLoopIteration = FALSE continue + + //You're DIFFERENT to me? I hate you I'm going home + if(clusterCheckFlags & CLUSTER_CHECK_DIFFERENT_TURFS) + clustering = rand(clusterMin,clusterMax) + for(var/turf/F in trange(clustering,T)) + if(!(istype(F,turfPath))) + skipLoopIteration = TRUE + break + if(skipLoopIteration) + skipLoopIteration = FALSE + continue + + //Success! if(prob(spawnableTurfs[turfPath])) T.ChangeTurf(turfPath) + //Atoms DO care whether atoms can be placed here if(checkPlaceAtom(T)) + for(var/atomPath in spawnableAtoms) - if(clusterCheckFlags & CLUSTER_CHECK_ATOMS) - if(clusterMax && clusterMin) - clustering = rand(clusterMin,clusterMax) - if(locate(/atom/movable) in range(clustering, T)) + + //Clustering! + if(clusterMax && clusterMin) + + //You're the same as me? I hate you I'm going home + if(clusterCheckFlags & CLUSTER_CHECK_SAME_ATOMS) + clustering = rand(clusterMin, clusterMax) + for(var/atom/movable/M in range(clustering,T)) + if(istype(M,atomPath)) + skipLoopIteration = TRUE + break + if(skipLoopIteration) + skipLoopIteration = FALSE continue + + //You're DIFFERENT from me? I hate you I'm going home + if(clusterCheckFlags & CLUSTER_CHECK_DIFFERENT_ATOMS) + clustering = rand(clusterMin, clusterMax) + for(var/atom/movable/M in range(clustering,T)) + if(!(istype(M,atomPath))) + skipLoopIteration = TRUE + break + if(skipLoopIteration) + skipLoopIteration = FALSE + continue + + //Success! if(prob(spawnableAtoms[atomPath])) - new atomPath (T) + new atomPath(T) . = 1 @@ -71,6 +114,8 @@ if(A.density) . = 0 break + if(!allowAtomsOnSpace && (istype(T,/turf/space))) + . = 0 /////////////////////////////////////////////////////////// diff --git a/code/modules/procedural mapping/mapGeneratorModules/nature.dm b/code/modules/procedural mapping/mapGeneratorModules/nature.dm index 742141f6fdf..09ca84574b1 100644 --- a/code/modules/procedural mapping/mapGeneratorModules/nature.dm +++ b/code/modules/procedural mapping/mapGeneratorModules/nature.dm @@ -34,4 +34,4 @@ //Grass tufts with a high spawn chance /datum/mapGeneratorModule/denseLayer/grassTufts spawnableTurfs = list() - spawnableAtoms = list(/obj/structure/flora/ausbushes/grassybush = 75) \ No newline at end of file + spawnableAtoms = list(/obj/structure/flora/ausbushes/grassybush = 75) diff --git a/code/modules/procedural mapping/mapGeneratorReadme.dm b/code/modules/procedural mapping/mapGeneratorReadme.dm index 95fa449624e..ae656b5b30b 100644 --- a/code/modules/procedural mapping/mapGeneratorReadme.dm +++ b/code/modules/procedural mapping/mapGeneratorReadme.dm @@ -11,14 +11,22 @@ mapGenerator: Desc: a mapGenerator is a master datum that collects and syncs all mapGeneratorModules in it's modules list - defineRegion(var/list/startList, var/list/endList) - Example: defineRegion(locate(1,1,1),locate(5,5,5)) + defineRegion(var/turf/Start, var/turf/End, var/replace = 0) + Example: defineRegion(locate(1,1,1),locate(5,5,5),0) Desc: Sets the bounds of the mapGenerator's "map" + defineCircularRegion(var/turf/Start, var/turf/End, var/replace = 0) + Example: defineCircularRegion(locate(1,1,1),locate(5,5,5),0) + Desc: Sets the mapGenerator's "map" as a circle, with center in the middle of Start and End's X,Y,Z coordinates + + undefineRegion() + Example: undefineRegion() + Desc: Empties the map generator list + checkRegion(var/turf/Start, var/turf/End) Example: checkRegion(locate(1,1,1), locate(5,5,5)) Desc: Checks if a rectangle between Start's coords and End's coords is valid - Existing Calls: mapGenerator/defineRegion() + Existing Calls: mapGenerator/defineRegion(), mapGenerator/defineCircularRegion() generate() Example: generate() @@ -108,8 +116,6 @@ Variable Breakdown (For Mappers): mapGenerator map - INTERNAL, do not touch - bottomLeft - INTERNAL, do not touch - topRight - INTERNAL, do not touch modules - A list of typepaths of mapGeneratorModules mapGeneratorModule @@ -118,13 +124,23 @@ Variable Breakdown (For Mappers): spawnableTurfs - A list of typepaths and their probability to spawn, eg: spawnableTurfs = list(/turf/unsimulated/floor/grass = 100) clusterMax - The max range to check for something being "too close" for this atom/turf to spawn, the true value is random between clusterMin and clusterMax clusterMin - The min range to check for something being "too close" for this atom/turf to spawn, the true value is random between clusterMin and clusterMax - clusterCheckFlags - A Bitfield that controls how the cluster checks work. + clusterCheckFlags - A Bitfield that controls how the cluster checks work, All based on clusterMin and clusterMax guides + allowAtomsOnSpace - A Boolean for if we allow atoms to spawn on space tiles clusterCheckFlags flags: - CLUSTER_CHECK_NONE 0 //No checks are done, cluster as much as possible - CLUSTER_CHECK_ATOMS 2 //Don't let atoms cluster, based on clusterMin and clusterMax as guides - CLUSTER_CHECK_TURFS 4 //Don't let turfs cluster, based on clusterMin and clusterMax as guides - CLUSTER_CHECK_ALL 6 //Don't let anything cluster, based on clusterMind and clusterMax as guides + CLUSTER_CHECK_NONE 0 //No checks are done, cluster as much as possible + CLUSTER_CHECK_DIFFERENT_TURFS 2 //Don't let turfs of DIFFERENT types cluster + CLUSTER_CHECK_DIFFERENT_ATOMS 4 //Don't let atoms of DIFFERENT types cluster + CLUSTER_CHECK_SAME_TURFS 8 //Don't let turfs of the SAME type cluster + CLUSTER_CHECK_SAME_ATOMS 16 //Don't let atoms of the SAME type cluster + + CLUSTER_CHECK_SAMES 24 //Don't let any of the same type cluster + CLUSTER_CHECK_DIFFERENTS 6 //Don't let any different types cluster + CLUSTER_CHECK_ALL_TURFS 10 //Don't let ANY turfs cluster same and different types + CLUSTER_CHECK_ALL_ATOMS 20 //Don't let ANY atoms cluster same and different types + + CLUSTER_CHECK_ALL 30 //Don't let anything cluster, like, at all + */ \ No newline at end of file diff --git a/code/modules/procedural mapping/mapGenerators/nature.dm b/code/modules/procedural mapping/mapGenerators/nature.dm index 0300de38211..7254e576ba4 100644 --- a/code/modules/procedural mapping/mapGenerators/nature.dm +++ b/code/modules/procedural mapping/mapGenerators/nature.dm @@ -2,9 +2,9 @@ //Exists primarily as a test type. /datum/mapGenerator/nature - modules = list(/datum/mapGeneratorModule/pineTrees, \ + modules = list(/datum/mapGeneratorModule/bottomLayer/grassTurfs, \ + /datum/mapGeneratorModule/pineTrees, \ /datum/mapGeneratorModule/deadTrees, \ /datum/mapGeneratorModule/randBushes, \ /datum/mapGeneratorModule/randRocks, \ - /datum/mapGeneratorModule/bottomLayer/grassTurfs, \ /datum/mapGeneratorModule/denseLayer/grassTufts)