diff --git a/_maps/RandomRuins/SpaceRuins/way_home.dmm b/_maps/RandomRuins/SpaceRuins/way_home.dmm
new file mode 100644
index 00000000000..f5a194b42e1
--- /dev/null
+++ b/_maps/RandomRuins/SpaceRuins/way_home.dmm
@@ -0,0 +1,37 @@
+"a" = (/turf/space,/area/space)
+"b" = (/turf/simulated/mineral/random,/area/ruin/unpowered/no_grav/way_home)
+"c" = (/turf/simulated/floor/plating/asteroid/airless,/area/ruin/unpowered/no_grav/way_home)
+"d" = (/obj/structure/signpost{name = "salvation"},/turf/simulated/floor/plating/asteroid/airless,/area/ruin/unpowered/no_grav/way_home)
+
+(1,1,1) = {"
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaabaaaaaaaaaaaaaaa
+aaaaaaaaaaaaabbbaaaaaaaaaaaaaa
+aaaaaaaaaabbbbbbbbbaaaaaaaaaaa
+aaaaaaaaaaabbbbbbbbaaaaaaaaaaa
+aaaaaaaaaabbbbbbbbaaaaaaaaaaaa
+aaaaaaaaabbbbbbbbbaaaaaaaaaaaa
+aaaaaaaaabbbbbbbbbbaaaaaaaaaaa
+aaaaaaaabbbbbbbbbbbbaaaaaaaaaa
+aaaaaaabbbbbbbbcbbbaaaaaaaaaaa
+aaaaaaabbbbbbbcccaaaaaaaaaaaaa
+aaaaaabbbbbbbbccaaaaaaaaaaaaaa
+aaaaaabbbbbbcccaaaaaaaaaaaaaaa
+aaaaaaabbbcccccaaaaaaaaaaaaaaa
+aaaaaaabbaacccccaaaaaaaaaaaaaa
+aaaaaaaaaaaaaccccaaaaaaaaaaaaa
+aaaaaaaaaaaaaccdccaaaaaaaaaaaa
+aaaaaaaaaaaaaccccccaaaaaaaaaaa
+aaaaaaaaaaaaaaccccccaaaaaaaaaa
+aaaaaaaaaaaaaacccbccaaaaaaaaaa
+aaaaaaaaaaaaaaaccbbccaaaaaaaaa
+aaaaaaaaaaaaaaacbbbbbaaaaaaaaa
+aaaaaaaaaaaaaaacbbbbbbaaaaaaaa
+aabbaaaaaaaaaaaabbbbbbbaaaaaaa
+aabbbaaaaaaaaaabbbbbbbbbaaaaaa
+aaabaaaaaaaaaabbaaabbbabaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+"}
diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index b56e973631e..22b489e9cd7 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -178,6 +178,7 @@
#define ZLEVEL_SPACEMAX 7
#define ZLEVEL_MINING 5
#define ZLEVEL_SPACEMIN 3
+#define ZLEVEL_DEEPSPACE 6
#define ZLEVEL_ABANDONNEDTSAT 3
#define ZLEVEL_CENTCOM 2
#define ZLEVEL_STATION 1
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index 8e6afc688e3..1653d780ab0 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -797,8 +797,9 @@ Turf and target are seperate in case you want to teleport some distance from a t
//Takes: Area type as text string or as typepath OR an instance of the area.
//Returns: A list of all turfs in areas of that type of that type in the world.
-/proc/get_area_turfs(areatype)
- if(!areatype) return null
+/proc/get_area_turfs(areatype, target_z = 0)
+ if(!areatype)
+ return null
if(istext(areatype)) areatype = text2path(areatype)
if(isarea(areatype))
var/area/areatemp = areatype
@@ -807,7 +808,9 @@ Turf and target are seperate in case you want to teleport some distance from a t
var/list/turfs = new/list()
for(var/area/N in world)
if(istype(N, areatype))
- for(var/turf/T in N) turfs += T
+ for(var/turf/T in N)
+ if(target_z == T.z || target_z == 0)
+ turfs += T
return turfs
//Takes: Area type as text string or as typepath OR an instance of the area.
diff --git a/code/controllers/master.dm b/code/controllers/master.dm
index 7b711c76125..07fd30d3e40 100644
--- a/code/controllers/master.dm
+++ b/code/controllers/master.dm
@@ -8,6 +8,8 @@
* All core systems are subsystems.
* They are process()'d by this Master Controller.
**/
+#define SPACE_LEVELS_TO_SEED 2
+#define RUINS_PER_LEVEL 3
var/global/datum/controller/master/Master = new()
@@ -72,6 +74,14 @@ var/global/datum/controller/master/Master = new()
return
world << "Initializing subsystems..."
+ //Seed ruins in space
+ /*
+ var/space_to_seed = SPACE_LEVELS_TO_SEED //Maybe this should be a config option?
+ while(space_to_seed)
+ var/target_z = pick(ZLEVEL_SPACEMAX, ZLEVEL_ABANDONNEDTSAT, ZLEVEL_STATION, ZLEVEL_DEEPSPACE)
+ seedRuins(RUINS_PER_LEVEL, target_z) //As well as this
+ space_to_seed--
+ */
// Pick a random away mission.
createRandomZlevel()
// Generate asteroid.
@@ -196,3 +206,7 @@ var/global/datum/controller/master/Master = new()
statclick = new/obj/effect/statclick/debug("Initializing...", src)
stat("Master Controller:", statclick.update("[round(Master.cost, 0.001)]ds (Interval: [Master.processing_interval] | Iteration:[Master.iteration])"))
+
+
+#undef SPACE_LEVELS_TO_SEED
+#undef RUINS_PER_LEVEL
\ No newline at end of file
diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm
index bf87018e786..e39dcaa34e6 100644
--- a/code/modules/awaymissions/corpse.dm
+++ b/code/modules/awaymissions/corpse.dm
@@ -343,3 +343,11 @@
icon = 'icons/effects/blood.dmi'
icon_state = "remains"
flavour_text = "By unknown powers, your rotting remains have been resurrected! Walk this mortal plain and terrorize all living adventurers who dare cross your path."
+
+
+/obj/effect/landmark/corpse/abductor
+ name = "abductor"
+ mobname = "???"
+ mob_species = /datum/species/abductor
+ corpseuniform = /obj/item/clothing/under/color/grey
+ corpseshoes = /obj/item/clothing/shoes/combat
\ No newline at end of file
diff --git a/code/modules/awaymissions/zlevel.dm b/code/modules/awaymissions/zlevel.dm
index 807c8f1a291..c81cacb8c01 100644
--- a/code/modules/awaymissions/zlevel.dm
+++ b/code/modules/awaymissions/zlevel.dm
@@ -1,37 +1,20 @@
+#define RANDOM_UPPER_X 220
+#define RANDOM_UPPER_Y 220
+
+#define RANDOM_LOWER_X 30
+#define RANDOM_LOWER_Y 30
+
+
+var/global/list/potentialRandomZlevels = generateMapList(filename = "config/awaymissionconfig.txt")
+
+var/global/list/potentialLavaRuins = generateMapList(filename = "config/lavaRuinConfig.txt")
+
+var/global/list/potentialSpaceRuins = generateMapList(filename = "config/spaceRuinConfig.txt")
+
/proc/createRandomZlevel()
if(awaydestinations.len) //crude, but it saves another var!
return
- var/list/potentialRandomZlevels = list()
- world << "Searching for away missions..."
- var/list/Lines = file2list("config/awaymissionconfig.txt")
- if(!Lines.len) return
- for (var/t in Lines)
- if (!t)
- continue
-
- t = trim(t)
- if (length(t) == 0)
- continue
- else if (copytext(t, 1, 2) == "#")
- continue
-
- var/pos = findtext(t, " ")
- var/name = null
- // var/value = null
-
- if (pos)
- name = lowertext(copytext(t, 1, pos))
- // value = copytext(t, pos + 1)
- else
- name = lowertext(t)
-
- if (!name)
- continue
-
- potentialRandomZlevels.Add(t)
-
-
if(potentialRandomZlevels.len)
world << "Loading away mission..."
@@ -39,7 +22,6 @@
var/file = file(map)
if(isfile(file))
maploader.load_map(file)
- smooth_zlevel(world.maxz)
world.log << "away mission loaded: [map]"
map_transition_config.Add(AWAY_MISSION_LIST)
@@ -53,4 +35,104 @@
else
world << "No away missions found."
- return
\ No newline at end of file
+ return
+
+
+/proc/generateMapList(filename)
+ var/list/potentialMaps = list()
+ var/list/Lines = file2list(filename)
+ if(!Lines.len) return
+ for (var/t in Lines)
+ if (!t)
+ continue
+
+ t = trim(t)
+ if (length(t) == 0)
+ continue
+ else if (copytext(t, 1, 2) == "#")
+ continue
+
+ var/pos = findtext(t, " ")
+ var/name = null
+
+ if (pos)
+ name = lowertext(copytext(t, 1, pos))
+
+ else
+ name = lowertext(t)
+
+ if (!name)
+ continue
+
+ potentialMaps.Add(t)
+
+ return potentialMaps
+
+
+/proc/seedRuins(z_level = 1, ruin_number = 0, whitelist = /area/space, list/potentialRuins = potentialSpaceRuins)
+// var/list/turfs = get_area_turfs(whitelist, z_level)
+
+/* if(!turfs.len)
+ return
+*/
+ if(ruin_number > potentialRuins.len)
+ ruin_number = potentialRuins.len //To avoid someone doing something dumb and entering an infinite loop
+
+ while(ruin_number)
+ var/sanity = 0
+ var/valid = FALSE
+ while(!valid)
+ valid = TRUE
+ sanity++
+ if(sanity > 100)
+ ruin_number--
+ break
+ var/turf/T = locate(rand(RANDOM_LOWER_X, RANDOM_UPPER_X), rand(RANDOM_LOWER_Y, RANDOM_UPPER_Y), z_level)
+
+ for(var/turf/check in range(T, 15))
+ var/area/new_area = get_area(check)
+ if(!(istype(new_area, whitelist)))
+ valid = FALSE
+ break
+
+
+ if(valid)
+ world.log << "Ruins marker placed at [T.x][T.y][T.z]"
+ var/obj/effect/ruin_loader/R = new /obj/effect/ruin_loader(T)
+ R.Load(potentialRuins, -15, -15)
+ ruin_number --
+
+ return
+
+
+/obj/effect/ruin_loader
+ name = "random ruin"
+ icon = 'icons/obj/weapons.dmi'
+ icon_state = "syndballoon"
+ invisibility = 0
+
+/obj/effect/ruin_loader/proc/Load(list/potentialRuins = potentialSpaceRuins, x_offset = 0, y_offset = 0)
+ if(potentialRuins.len)
+ world << "Loading ruins..."
+
+ var/map = pick(potentialRuins)
+ var/file = file(map)
+ if(isfile(file))
+ maploader.load_map(file, src.x + x_offset, src.y + y_offset, src.z)
+ world.log << "[map] loaded at at [src.x + x_offset],[src.y + y_offset],[src.z]"
+ potentialRuins -= map //Don't want to load the same one twice
+ world << "Ruins loaded."
+
+ else
+ world << "No ruins found."
+ return
+
+ qdel(src)
+
+
+
+#undef RANDOM_UPPER_X
+#undef RANDOM_UPPER_Y
+
+#undef RANDOM_LOWER_X
+#undef RANDOM_LOWER_Y
\ No newline at end of file
diff --git a/code/modules/ruins/ruin_areas.dm b/code/modules/ruins/ruin_areas.dm
new file mode 100644
index 00000000000..f0c8cade312
--- /dev/null
+++ b/code/modules/ruins/ruin_areas.dm
@@ -0,0 +1,23 @@
+//Parent types
+
+/area/ruin/
+ name = "\improper Unexplored Location"
+ icon_state = "away"
+
+
+/area/ruin/unpowered
+ always_unpowered = 0
+
+/area/ruin/unpowered/no_grav
+ has_gravity = 0
+
+/area/ruin/powered
+ requires_power = 0
+
+
+
+//Areas
+
+/area/ruin/unpowered/no_grav/way_home
+ name = "\improper Salvation"
+ icon_state = "away"
\ No newline at end of file
diff --git a/config/lavaRuinConfig.txt b/config/lavaRuinConfig.txt
new file mode 100644
index 00000000000..c677f1e344a
--- /dev/null
+++ b/config/lavaRuinConfig.txt
@@ -0,0 +1,4 @@
+#List the potential random ruins here. This file is for small things that would appear in lavaland, such as hidden temples or labs.
+#Maps must be the full path to them
+#Ruins should be 30x30 at max. Anymore than that will break the game.
+#SPECIFYING AN INVALID MAP WILL RESULT IN RUNTIMES ON GAME START
\ No newline at end of file
diff --git a/config/spaceRuinConfig.txt b/config/spaceRuinConfig.txt
new file mode 100644
index 00000000000..a0de267df38
--- /dev/null
+++ b/config/spaceRuinConfig.txt
@@ -0,0 +1,6 @@
+#List the potential random ruins here. This file is for small things that would appear in space, like an asteroid or broken escape pod.
+#Maps must be the full path to them
+#Ruins should be 40x40 at max. Anymore than that will break the game.
+#SPECIFYING AN INVALID MAP WILL RESULT IN RUNTIMES ON GAME START
+
+#_maps/RandomRuins/SpaceRuins/way_home.dmm
\ No newline at end of file
diff --git a/tgstation.dme b/tgstation.dme
index e5a9aa6781f..57e55748e30 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -1556,6 +1556,7 @@
#include "code\modules\research\designs\weapon_designs.dm"
#include "code\modules\research\xenobiology\xenobio_camera.dm"
#include "code\modules\research\xenobiology\xenobiology.dm"
+#include "code\modules\ruins\ruin_areas.dm"
#include "code\modules\security levels\keycard authentication.dm"
#include "code\modules\security levels\security levels.dm"
#include "code\modules\shuttle\shuttle.dm"