Files
Bubberstation/code/datums/mapgen/CaveGenerator.dm
Watermelon914 375a20e49b Refactors most spans into span procs (#59645)
Converts most spans into span procs. Mostly used regex for this and sorted out any compile time errors afterwards so there could be some bugs.
Was initially going to do defines, but ninja said to make it into a proc, and if there's any overhead, they can easily be changed to defines.

Makes it easier to control the formatting and prevents typos when creating spans as it'll runtime if you misspell instead of silently failing.
Reduces the code you need to write when writing spans, as you don't need to close the span as that's automatically handled by the proc.

(Note from Lemon: This should be converted to defines once we update the minimum version to 514. Didn't do it now because byond pain and such)
2021-06-14 13:03:53 -07:00

145 lines
5.8 KiB
Plaintext

/datum/map_generator/cave_generator
var/name = "Cave Generator"
///Weighted list of the types that spawns if the turf is open
var/open_turf_types = list(/turf/open/floor/plating/asteroid/airless = 1)
///Weighted list of the types that spawns if the turf is closed
var/closed_turf_types = list(/turf/closed/mineral/random = 1)
///Weighted list of mobs that can spawn in the area.
var/list/mob_spawn_list
// Weighted list of Megafauna that can spawn in the caves
var/list/megafauna_spawn_list
///Weighted list of flora that can spawn in the area.
var/list/flora_spawn_list
///Weighted list of extra features that can spawn in the area, such as geysers.
var/list/feature_spawn_list
///Base chance of spawning a mob
var/mob_spawn_chance = 6
///Base chance of spawning flora
var/flora_spawn_chance = 2
///Base chance of spawning features
var/feature_spawn_chance = 0.1
///Unique ID for this spawner
var/string_gen
///Chance of cells starting closed
var/initial_closed_chance = 45
///Amount of smoothing iterations
var/smoothing_iterations = 20
///How much neighbours does a dead cell need to become alive
var/birth_limit = 4
///How little neighbours does a alive cell need to die
var/death_limit = 3
/datum/map_generator/cave_generator/New()
. = ..()
if(!mob_spawn_list)
mob_spawn_list = list(/mob/living/simple_animal/hostile/asteroid/goldgrub = 1, /mob/living/simple_animal/hostile/asteroid/goliath = 5, /mob/living/simple_animal/hostile/asteroid/basilisk = 4, /mob/living/simple_animal/hostile/asteroid/hivelord = 3)
if(!megafauna_spawn_list)
megafauna_spawn_list = GLOB.megafauna_spawn_list
if(!flora_spawn_list)
flora_spawn_list = list(/obj/structure/flora/ash/leaf_shroom = 2 , /obj/structure/flora/ash/cap_shroom = 2 , /obj/structure/flora/ash/stem_shroom = 2 , /obj/structure/flora/ash/cacti = 1, /obj/structure/flora/ash/tall_shroom = 2, /obj/structure/flora/ash/seraka = 2)
if(!feature_spawn_list)
feature_spawn_list = list(/obj/structure/geyser/random = 1)
/datum/map_generator/cave_generator/generate_terrain(list/turfs)
. = ..()
var/start_time = REALTIMEOFDAY
string_gen = rustg_cnoise_generate("[initial_closed_chance]", "[smoothing_iterations]", "[birth_limit]", "[death_limit]", "[world.maxx]", "[world.maxy]") //Generate the raw CA data
for(var/i in turfs) //Go through all the turfs and generate them
var/turf/gen_turf = i
var/area/A = gen_turf.loc
if(!(A.area_flags & CAVES_ALLOWED))
continue
var/closed = text2num(string_gen[world.maxx * (gen_turf.y - 1) + gen_turf.x])
var/stored_flags
if(gen_turf.turf_flags & NO_RUINS)
stored_flags |= NO_RUINS
var/turf/new_turf = pickweight(closed ? closed_turf_types : open_turf_types)
new_turf = gen_turf.ChangeTurf(new_turf, initial(new_turf.baseturfs), CHANGETURF_DEFER_CHANGE)
new_turf.flags_1 |= stored_flags
if(!closed)//Open turfs have some special behavior related to spawning flora and mobs.
var/turf/open/new_open_turf = new_turf
///Spawning isn't done in procs to save on overhead on the 60k turfs we're going through.
//FLORA SPAWNING HERE
var/atom/spawned_flora
if(flora_spawn_list && prob(flora_spawn_chance))
var/can_spawn = TRUE
if(!(A.area_flags & FLORA_ALLOWED))
can_spawn = FALSE
if(can_spawn)
spawned_flora = pickweight(flora_spawn_list)
spawned_flora = new spawned_flora(new_open_turf)
//FEATURE SPAWNING HERE
var/atom/spawned_feature
if(feature_spawn_list && prob(feature_spawn_chance))
var/can_spawn = TRUE
if(!(A.area_flags & FLORA_ALLOWED)) //checks the same flag because lol dunno
can_spawn = FALSE
var/atom/picked_feature = pickweight(feature_spawn_list)
for(var/obj/structure/F in range(7, new_open_turf))
if(istype(F, picked_feature))
can_spawn = FALSE
if(can_spawn)
spawned_feature = new picked_feature(new_open_turf)
//MOB SPAWNING HERE
if(mob_spawn_list && !spawned_flora && !spawned_feature && prob(mob_spawn_chance))
var/can_spawn = TRUE
if(!(A.area_flags & MOB_SPAWN_ALLOWED))
can_spawn = FALSE
var/atom/picked_mob = pickweight(mob_spawn_list)
if(picked_mob == SPAWN_MEGAFAUNA) //
if((A.area_flags & MEGAFAUNA_SPAWN_ALLOWED) && megafauna_spawn_list?.len) //this is danger. it's boss time.
picked_mob = pickweight(megafauna_spawn_list)
else //this is not danger, don't spawn a boss, spawn something else
picked_mob = pickweight(mob_spawn_list - SPAWN_MEGAFAUNA) //What if we used 100% of the brain...and did something (slightly) less shit than a while loop?
for(var/thing in urange(12, new_open_turf)) //prevents mob clumps
if(!ishostile(thing) && !istype(thing, /obj/structure/spawner))
continue
if((ispath(picked_mob, /mob/living/simple_animal/hostile/megafauna) || ismegafauna(thing)) && get_dist(new_open_turf, thing) <= 7)
can_spawn = FALSE //if there's a megafauna within standard view don't spawn anything at all
break
if(ispath(picked_mob, /mob/living/simple_animal/hostile/asteroid) || istype(thing, /mob/living/simple_animal/hostile/asteroid))
can_spawn = FALSE //if the random is a standard mob, avoid spawning if there's another one within 12 tiles
break
if((ispath(picked_mob, /obj/structure/spawner/lavaland) || istype(thing, /obj/structure/spawner/lavaland)) && get_dist(new_open_turf, thing) <= 2)
can_spawn = FALSE //prevents tendrils spawning in each other's collapse range
break
if(can_spawn)
if(ispath(picked_mob, /mob/living/simple_animal/hostile/megafauna/bubblegum)) //there can be only one bubblegum, so don't waste spawns on it
megafauna_spawn_list.Remove(picked_mob)
new picked_mob(new_open_turf)
CHECK_TICK
var/message = "[name] finished in [(REALTIMEOFDAY - start_time)/10]s!"
to_chat(world, span_boldannounce("[message]"))
log_world(message)