diff --git a/code/__HELPERS/cmp.dm b/code/__HELPERS/cmp.dm index 5fb86f94603..e03f33bb8ec 100644 --- a/code/__HELPERS/cmp.dm +++ b/code/__HELPERS/cmp.dm @@ -55,8 +55,5 @@ if (!.) . = B.qdels - A.qdels -/proc/cmp_ruincost_priority(datum/map_template/ruin/A, datum/map_template/ruin/B) - return initial(A.cost) - initial(B.cost) - /proc/cmp_timer(datum/timedevent/a, datum/timedevent/b) return a.timeToRun - b.timeToRun \ No newline at end of file diff --git a/code/_global_vars/mapping.dm b/code/_global_vars/mapping.dm index 911c465c2bd..675565b6097 100644 --- a/code/_global_vars/mapping.dm +++ b/code/_global_vars/mapping.dm @@ -1,2 +1,4 @@ // AREA LIST // -GLOBAL_LIST_EMPTY(map_areas) \ No newline at end of file +GLOBAL_LIST_EMPTY(map_areas) + +GLOBAL_LIST_EMPTY(stationroom_landmarks) //List of all spawns for maints rooms \ No newline at end of file diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index 841e2dbac18..cc5da9bad5b 100755 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -173,6 +173,7 @@ GLOBAL_LIST_EMPTY(storyteller_cache) var/python_path = "" //Path to the python executable. Defaults to "python" on windows and "/usr/bin/env python2" on unix var/use_lib_nudge = 0 //Use the C library nudge instead of the python nudge. var/use_overmap = 0 + var/generate_maint_ruins = 0 // Event settings var/expected_round_length = 3 * 60 * 60 * 10 // 3 hours @@ -238,6 +239,7 @@ GLOBAL_LIST_EMPTY(storyteller_cache) var/cache_assets = FALSE var/smart_cache_assets = FALSE + var/directory = "config" /datum/configuration/New() fill_storyevents_list() @@ -674,6 +676,9 @@ GLOBAL_LIST_EMPTY(storyteller_cache) if("use_overmap") config.use_overmap = 1 + if("generate_maints_ruins") //Soj add + config.generate_maint_ruins = 1 + if("expected_round_length") config.expected_round_length = MinutesToTicks(text2num(value)) diff --git a/code/controllers/subsystems/mapping.dm b/code/controllers/subsystems/mapping.dm index 6ffcdc5da5b..a1ff1fc0c30 100644 --- a/code/controllers/subsystems/mapping.dm +++ b/code/controllers/subsystems/mapping.dm @@ -4,6 +4,7 @@ SUBSYSTEM_DEF(mapping) flags = SS_NO_FIRE var/list/map_templates = list() + var/list/ruins_templates = list() var/dmm_suite/maploader = null var/list/teleportlocs = list() var/list/ghostteleportlocs = list() @@ -36,6 +37,10 @@ SUBSYSTEM_DEF(mapping) maploader = new() load_map_templates() +// Generates the random maint ruin templates. +#ifndef LOWMEMORYMODE + SSmapping.seedStation() +#endif // Generate cache of all areas in world. This cache allows world areas to be looked up on a list instead of being searched for EACH time for(var/area/A in world) GLOB.map_areas += A @@ -91,6 +96,8 @@ SUBSYSTEM_DEF(mapping) return TRUE /datum/controller/subsystem/mapping/proc/load_map_templates() + //Can also add other templates in the future. For now, maint ruins. + preloadTemplates() for(var/T in subtypesof(/datum/map_template)) var/datum/map_template/template = T if(!(initial(template.mappath))) // If it's missing the actual path its probably a base type or being used for inheritence. @@ -98,3 +105,53 @@ SUBSYSTEM_DEF(mapping) template = new T() map_templates[template.name] = template return TRUE + + +/datum/controller/subsystem/mapping/proc/seedStation() + for(var/V in GLOB.stationroom_landmarks) + var/obj/effect/landmark/stationroom/LM = V + LM.load() + if(GLOB.stationroom_landmarks.len) + seedStation() //I'm sure we can trust everyone not to insert a 1x1 rooms which loads a landmark which loads a landmark which loads a la... + + +/proc/cmp_ruincost_priority(datum/map_template/ruin/A, datum/map_template/ruin/B) + return initial(A.cost) - initial(B.cost) + +/datum/controller/subsystem/mapping/proc/preloadRuinTemplates() + // Still supporting bans by filename + var/list/banned = generateMapList("[global.config.directory]/lavaruinblacklist.txt") + banned += generateMapList("[global.config.directory]/spaceruinblacklist.txt") + banned += generateMapList("[global.config.directory]/iceruinblacklist.txt") + banned += generateMapList("[global.config.directory]/stationruinblacklist.txt") + + for(var/item in sort_list(subtypesof(/datum/map_template/ruin), GLOBAL_PROC_REF(cmp_ruincost_priority))) + var/datum/map_template/ruin/ruin_type = item + // screen out the abstract subtypes + if(!initial(ruin_type.id)) + continue + var/datum/map_template/ruin/R = new ruin_type() + + if(banned.Find(R.mappath)) + continue + + map_templates[R.name] = R + ruins_templates[R.name] = R + + //We have to be specific here. + if(istype(R, /datum/map_template/ruin/station)) + station_room_templates[R.name] = R + + +/datum/controller/subsystem/mapping/proc/preloadTemplates(path = "_maps/templates/") //see master controller setup + var/list/filelist = flist(path) + for(var/map in filelist) + var/datum/map_template/T = new(path = "[path][map]", rename = "[map]") + map_templates[T.name] = T + + preloadRuinTemplates() + + + // Station Ruins, Maints Rooms, Random shit! +/datum/controller/subsystem/mapping + var/list/station_room_templates = list() \ No newline at end of file diff --git a/code/datums/ruins.dm b/code/datums/ruins.dm new file mode 100644 index 00000000000..6f3dff6ece7 --- /dev/null +++ b/code/datums/ruins.dm @@ -0,0 +1,19 @@ +/datum/map_template/ruin + name = null + var/description = "Unset Desc" + + var/unpickable = FALSE //If TRUE these won't be placed automatically (can still be forced or loaded with another ruin) + var/always_place = FALSE //Will skip the whole weighting process and just plop this down, ideally you want the ruins of this kind to have no cost. + var/placement_weight = 1 //How often should this ruin appear + var/list/always_spawn_with = null //These ruin types will be spawned along with it (where dependent on the flag) eg list(/datum/map_template/ruin/space/teleporter_space = SPACERUIN_Z) + var/list/never_spawn_with = null //If this ruin is spawned these will not eg list(/datum/map_template/ruin/base_alternate) + + var/prefix = null + var/suffix = null + +/datum/map_template/ruin/New() + if(!name && id) + name = id + + mappath = prefix + suffix + ..(path = mappath) \ No newline at end of file diff --git a/code/datums/ruins/maints.dm b/code/datums/ruins/maints.dm new file mode 100644 index 00000000000..a7192c6ded8 --- /dev/null +++ b/code/datums/ruins/maints.dm @@ -0,0 +1,46 @@ +//YOU MUST UPDATE MAINTS_RUINS.DM! Otherwise, your maps will NOT load! BE SURE you use the NAME variable! +// EXAMPLE: + +// NAME = "Maint Oldstorage" + +// In the list, you use the name VARIABLE Maint Oldstorage, NOT the datum path name, and NOT its ID. + +///Base for all station ruins. +/datum/map_template/ruin/station/maint + prefix = "maps/MaintsRuins/" + +///Base for the 3x3 rooms. +/datum/map_template/ruin/station/maint/threexthree + prefix = "maps/MaintsRuins/3x3/" + +/* Examples / not ported +/datum/map_template/ruin/station/maint/threexthree/oldstorage + id = "OldStorage" + suffix = "3x3_OldStorage.dmm" + name = "Maint OldStorage" + +/datum/map_template/ruin/station/maint/threexthree/oldstorage1 + id = "OldStorage1" + suffix = "3x3_OldStorage1.dmm" + name = "Maint OldStorage1" + +/datum/map_template/ruin/station/maint/threexthree/oldstorage2 + id = "OldStorage2" + suffix = "3x3_OldStorage2.dmm" + name = "Maint OldStorage2" + +/datum/map_template/ruin/station/maint/threexthree/oldstorage3 + id = "OldStorage3" + suffix = "3x3_OldStorage3.dmm" + name = "Maint OldStorage3" + +/datum/map_template/ruin/station/maint/threexthree/oldstorage4 + id = "OldStorage4" + suffix = "3x3_OldStorage4.dmm" + name = "Maint OldStorage4" + +/datum/map_template/ruin/station/maint/threexthree/oldstorage5 + id = "OldStorage5" + suffix = "3x3_OldStorage5.dmm" + name = "Maint OldStorage5" +*/ \ No newline at end of file diff --git a/code/game/objects/landmarks/maints_ruins.dm b/code/game/objects/landmarks/maints_ruins.dm new file mode 100644 index 00000000000..ddabec4da64 --- /dev/null +++ b/code/game/objects/landmarks/maints_ruins.dm @@ -0,0 +1,83 @@ +GLOBAL_LIST_EMPTY(chosen_station_templates) + +/obj/effect/landmark/stationroom + var/list/template_names = list() + /// Whether or not we can choose templates that have already been chosen + var/unique = FALSE + +/obj/effect/landmark/stationroom/New() + ..() + GLOB.stationroom_landmarks += src + +/obj/effect/landmark/stationroom/Destroy() + if(src in GLOB.stationroom_landmarks) + GLOB.stationroom_landmarks -= src + return ..() + +/obj/effect/landmark/stationroom/proc/load(template_name) + var/turf/T = get_turf(src) + if(!T) + return FALSE + if(!template_name) + for(var/t in template_names) + if(!SSmapping.station_room_templates[t]) + stack_trace("Station room spawner placed at ([T.x], [T.y], [T.z]) has invalid ruin name of \"[t]\" in its list") + template_names -= t + template_name = choose() + if(!template_name) + GLOB.stationroom_landmarks -= src + qdel(src) + return FALSE + GLOB.chosen_station_templates += template_name + var/datum/map_template/template = SSmapping.station_room_templates[template_name] + if(!template) + return FALSE + testing("Ruin \"[template_name]\" placed at ([T.x], [T.y], [T.z])") + template.load(T, centered = FALSE) + template.loaded++ + GLOB.stationroom_landmarks -= src + qdel(src) + return TRUE + +// Proc to allow you to add conditions for choosing templates, instead of just randomly picking from the template list. +// Examples where this would be useful, would be choosing certain templates depending on conditions such as holidays, +// Or co-dependent templates, such as having a template for the core and one for the satelite, and swapping AI and comms.git +/obj/effect/landmark/stationroom/proc/choose() + if(unique) + var/list/current_templates = template_names + for(var/i in GLOB.chosen_station_templates) + template_names -= i + if(!template_names.len) + stack_trace("Station room spawner (type: [type]) has run out of ruins, unique will be ignored") + template_names = current_templates + return pickweight(template_names) + +/* Examples +/obj/effect/landmark/stationroom/maint/threexthree + template_names = list("Maint OldStorage", "Maint OldStorage1", "Maint OldStorage2") + +(untested example) - this maybe makes them more or less rare +/obj/effect/landmark/stationroom/maint/threexthree + template_names = list("Common OldStorage" = 12, "Rare OldStorage" = 4, "Super Rare OldStorage" = 2) +*/ + +/obj/effect/landmark/stationroom/maint/ + unique = TRUE + +/obj/effect/landmark/stationroom/maint/threexthree + template_names = list() + +/obj/effect/landmark/stationroom/maint/threexfive + template_names = list() + +/obj/effect/landmark/stationroom/maint/fivexthree + template_names = list() + +/obj/effect/landmark/stationroom/maint/fivexfour + template_names = list() + +/obj/effect/landmark/stationroom/maint/tenxfive + template_names = list() + +/obj/effect/landmark/stationroom/maint/tenxten + template_names = list() \ No newline at end of file diff --git a/code/modules/maps/tg/map_template.dm b/code/modules/maps/tg/map_template.dm index 236f4efc8e1..8b1a29a4fe3 100644 --- a/code/modules/maps/tg/map_template.dm +++ b/code/modules/maps/tg/map_template.dm @@ -307,4 +307,27 @@ admin_notice("Submap loader gave up with [budget] left to spend.", R_DEBUG) else admin_notice("Submaps loaded.", R_DEBUG) - admin_notice("Loaded: [english_list(pretty_submap_list)]", R_DEBUG) */ \ No newline at end of file + admin_notice("Loaded: [english_list(pretty_submap_list)]", R_DEBUG) */ + +/proc/generateMapList(filename) + . = list() + var/list/Lines = world.file2list(filename) + if(!Lines.len) + return + for (var/t in Lines) + if (!t) + continue + t = trim(t) + if (length(t) == 0) + continue + else if (t[1] == "#") + continue + var/pos = findtext(t, " ") + var/name = null + if (pos) + name = lowertext(copytext(t, 1, pos)) + else + name = lowertext(t) + if (!name) + continue + . += t \ No newline at end of file diff --git a/sojourn-station.dme b/sojourn-station.dme index 835cbb8c3d8..8c6c70ae93b 100644 --- a/sojourn-station.dme +++ b/sojourn-station.dme @@ -332,6 +332,7 @@ #include "code\datums\progressbar.dm" #include "code\datums\recipe.dm" #include "code\datums\recoil.dm" +#include "code\datums\ruins.dm" #include "code\datums\security_state.dm" #include "code\datums\sound_player.dm" #include "code\datums\verb_callbacks.dm" @@ -527,6 +528,7 @@ #include "code\datums\repositories\crew\tracking.dm" #include "code\datums\repositories\crew\vital.dm" #include "code\datums\repositories\crew\~defines.dm" +#include "code\datums\ruins\maints.dm" #include "code\datums\setup_option\background.dm" #include "code\datums\setup_option\core_implant.dm" #include "code\datums\setup_option\core_implants.dm" @@ -1365,6 +1367,7 @@ #include "code\game\objects\landmarks\join.dm" #include "code\game\objects\landmarks\landmark.dm" #include "code\game\objects\landmarks\machinery.dm" +#include "code\game\objects\landmarks\maints_ruins.dm" #include "code\game\objects\landmarks\mob.dm" #include "code\game\objects\landmarks\storyevent.dm" #include "code\game\objects\random\ameridian.dm"