Files
Paradise/code/modules/procedural mapping/mapGenerator.dm
Remie Richards 0f7b09ef07 Procedural Map Generator System
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.
2015-04-11 05:28:10 -07:00

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"