mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2025-12-31 12:41:46 +00:00
This commit adds a Procedural map generating system for code and admins to use ingame. The system is modular, which means that it is fairly easy to make new generating systems. Currently, only the 'nature' unsimulated system is implemented, as a testing verb for admins to use. Admins can define the starting XYZ and ending XYZ of the generated system. Players - This means you may see content that is truely random, in the future. Coders - This system allows you to randomize map elements. Writing new modules is documented at code/modules/procedural-mapping/mapGeneratorReadme.dm Detailed information about how the system works, and how it can be integrated is also avalible there. Admins - This system will allow you to, at the touch of a button, create very complex structures and turfs that would otherwise require being spawned in manually, one by one. The nature button is a fairly good example of this, with it's randomized grass textures, randomly placed trees, and randomly placed rocks. This would normally take a good 5 minutes to do, spawning the trees and rocks and turfs, but it takes about 20 seconds to enter the coordinates and have it be completely random.
101 lines
3.2 KiB
Plaintext
101 lines
3.2 KiB
Plaintext
|
|
#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
|
|
|
|
|
|
//Syncs the module up with it's mother
|
|
/datum/mapGeneratorModule/proc/sync(var/datum/mapGenerator/mum)
|
|
mother = null
|
|
if(mum)
|
|
mother = mum
|
|
|
|
|
|
//Generates it's spawnable atoms and turfs
|
|
/datum/mapGeneratorModule/proc/generate()
|
|
if(!mother)
|
|
return
|
|
var/list/map = mother.map
|
|
for(var/turf/T in map)
|
|
place(T)
|
|
|
|
|
|
//Place a spawnable atom or turf on this turf
|
|
/datum/mapGeneratorModule/proc/place(var/turf/T)
|
|
if(!T)
|
|
return 0
|
|
|
|
var/clustering = 0
|
|
|
|
//Turfs don't care whether atoms can be placed here
|
|
for(var/turfPath in spawnableTurfs)
|
|
if(clusterCheckFlags & CLUSTER_CHECK_TURFS)
|
|
if(clusterMax && clusterMin)
|
|
clustering = rand(clusterMin,clusterMax)
|
|
if(locate(/atom/movable) in range(clustering, T))
|
|
continue
|
|
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))
|
|
continue
|
|
if(prob(spawnableAtoms[atomPath]))
|
|
new atomPath (T)
|
|
|
|
. = 1
|
|
|
|
|
|
//Checks and Rejects dense turfs
|
|
/datum/mapGeneratorModule/proc/checkPlaceAtom(var/turf/T)
|
|
. = 1
|
|
if(!T)
|
|
return 0
|
|
if(T.density)
|
|
. = 0
|
|
for(var/atom/A in T)
|
|
if(A.density)
|
|
. = 0
|
|
break
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// PREMADE BASE TEMPLATES //
|
|
// Appropriate settings for usable types //
|
|
// Not usable types themselves, use them as parent types //
|
|
// Seriously, don't use these on their own, just parents //
|
|
///////////////////////////////////////////////////////////
|
|
//The /atom and /turf examples are just so these compile, replace those with your typepaths in your subtypes.
|
|
|
|
//Settings appropriate for a turf that covers the entire map region, eg a fill colour on a bottom layer in a graphics program.
|
|
//Should only have one of these in your mapGenerator unless you want to waste CPU
|
|
/datum/mapGeneratorModule/bottomLayer
|
|
clusterCheckFlags = CLUSTER_CHECK_NONE
|
|
spawnableAtoms = list()//Recommended: No atoms.
|
|
spawnableTurfs = list(/turf = 100)
|
|
|
|
//Settings appropriate for turfs/atoms that cover SOME of the map region, sometimes referred to as a splatter layer.
|
|
/datum/mapGeneratorModule/splatterLayer
|
|
clusterCheckFlags = CLUSTER_CHECK_ALL
|
|
spawnableAtoms = list(/atom = 30)
|
|
spawnableTurfs = list(/turf = 30)
|
|
|
|
//Settings appropriate for turfs/atoms that cover a lot of the map region, eg a dense forest.
|
|
/datum/mapGeneratorModule/denseLayer
|
|
clusterCheckFlags = CLUSTER_CHECK_NONE
|
|
spawnableAtoms = list(/atom = 75)
|
|
spawnableTurfs = list(/turf = 75) |