mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-01-01 13:12:23 +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.
123 lines
3.1 KiB
Plaintext
123 lines
3.1 KiB
Plaintext
|
|
/datum/mapGenerator
|
|
|
|
//Map information
|
|
var/list/map = list()
|
|
var/turf/bottomLeft = null
|
|
var/turf/topRight = null
|
|
|
|
//mapGeneratorModule information
|
|
var/list/modules = list()
|
|
|
|
/datum/mapGenerator/New()
|
|
..()
|
|
initialiseModules()
|
|
|
|
//Defines the region the map represents, sets map, bottomLeft, topRight
|
|
//Returns the map
|
|
/datum/mapGenerator/proc/defineRegion(var/turf/Start, var/turf/End)
|
|
if(!checkRegion(Start, End))
|
|
return 0
|
|
|
|
if(!Start || !End)
|
|
return 0
|
|
bottomLeft = Start
|
|
topRight = End
|
|
|
|
map = block(bottomLeft,topRight)
|
|
return map
|
|
|
|
|
|
//Checks for and Rejects bad region coordinates
|
|
//Returns 1/0
|
|
/datum/mapGenerator/proc/checkRegion(var/turf/Start, var/turf/End)
|
|
. = 1
|
|
|
|
if(!Start || !End)
|
|
return 0 //Just bail
|
|
|
|
if(Start.x > world.maxx || End.x > world.maxx)
|
|
. = 0
|
|
if(Start.y > world.maxy || End.y > world.maxy)
|
|
. = 0
|
|
if(Start.z > world.maxz || End.z > world.maxz)
|
|
. = 0
|
|
|
|
|
|
//Requests the mapGeneratorModule(s) to (re)generate
|
|
/datum/mapGenerator/proc/generate()
|
|
set background = 1 //this can get beefy
|
|
|
|
syncModules()
|
|
if(!modules || !modules.len)
|
|
return
|
|
for(var/datum/mapGeneratorModule/mod in modules)
|
|
mod.generate()
|
|
|
|
|
|
//Requests the mapGeneratorModule(s) to (re)generate this one turf
|
|
/datum/mapGenerator/proc/generateOneTurf(var/turf/T)
|
|
if(!T)
|
|
return
|
|
syncModules()
|
|
if(!modules || !modules.len)
|
|
return
|
|
for(var/datum/mapGeneratorModule/mod in modules)
|
|
mod.place(T)
|
|
|
|
|
|
//Replaces all paths in the module list with actual module datums
|
|
/datum/mapGenerator/proc/initialiseModules()
|
|
for(var/path in modules)
|
|
if(ispath(path))
|
|
modules.Remove(path)
|
|
modules |= new path
|
|
syncModules()
|
|
|
|
|
|
//Sync mapGeneratorModule(s) to mapGenerator
|
|
/datum/mapGenerator/proc/syncModules()
|
|
for(var/datum/mapGeneratorModule/mod in modules)
|
|
mod.sync(src)
|
|
|
|
|
|
|
|
///////////////////////////
|
|
// HERE BE DEBUG DRAGONS //
|
|
///////////////////////////
|
|
|
|
/client/proc/debugNatureMapGenerator()
|
|
set name = "Test Nature Map Generator"
|
|
set category = "Debug"
|
|
|
|
var/datum/mapGenerator/nature/N = new()
|
|
var/startInput = input(usr,"Start turf of Map, (X;Y;Z)", "Map Gen Settings", "1;1;1") as text
|
|
var/endInput = input(usr,"End turf of Map (X;Y;Z)", "Map Gen Settings", "[world.maxx];[world.maxy];[mob ? mob.z : 1]") as text
|
|
//maxx maxy and current z so that if you fuck up, you only fuck up one entire z level instead of the entire universe
|
|
if(!startInput || !endInput)
|
|
src << "Missing Input"
|
|
return
|
|
|
|
var/list/startCoords = text2list(startInput, ";")
|
|
var/list/endCoords = text2list(endInput, ";")
|
|
if(!startCoords || !endCoords)
|
|
src << "Invalid Coords"
|
|
src << "Start Input: [startInput]"
|
|
src << "End Input: [endInput]"
|
|
return
|
|
|
|
var/turf/Start = locate(text2num(startCoords[1]),text2num(startCoords[2]),text2num(startCoords[3]))
|
|
var/turf/End = locate(text2num(endCoords[1]),text2num(endCoords[2]),text2num(endCoords[3]))
|
|
if(!Start || !End)
|
|
src << "Invalid Turfs"
|
|
src << "Start Coords: [startCoords[1]] - [startCoords[2]] - [startCoords[3]]"
|
|
src << "End Coords: [endCoords[1]] - [endCoords[2]] - [endCoords[3]]"
|
|
return
|
|
|
|
src << "Defining Region"
|
|
N.defineRegion(Start, End)
|
|
src << "Region Defined"
|
|
src << "Generating Region"
|
|
N.generate()
|
|
src << "Generated Region"
|