diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm
index 425b6e7f769..19e5615291a 100644
--- a/code/__defines/mobs.dm
+++ b/code/__defines/mobs.dm
@@ -152,7 +152,7 @@
#define MODIFIER_STACK_EXTEND 2 // Disallows a second instance, but will extend the first instance if possible.
#define MODIFIER_STACK_ALLOWED 3 // Multiple instances are allowed.
-#define MODIFIER_GENETIC 0 // Modifiers with this flag will be copied to mobs who get cloned.
+#define MODIFIER_GENETIC 1 // Modifiers with this flag will be copied to mobs who get cloned.
// Bodyparts and organs.
#define O_MOUTH "mouth"
diff --git a/code/controllers/Processes/planet.dm b/code/controllers/Processes/planet.dm
index 7b446b4d2d5..063d6d3fb9b 100644
--- a/code/controllers/Processes/planet.dm
+++ b/code/controllers/Processes/planet.dm
@@ -20,14 +20,14 @@ var/datum/controller/process/planet/planet_controller = null
for(var/turf/simulated/OT in outdoor_turfs)
for(var/datum/planet/P in planets)
if(OT.z in P.expected_z_levels)
- P.planet_floors += OT
+ P.planet_floors |= OT
break
outdoor_turfs.Cut() //Why were you in there INCORRECTLY?
for(var/turf/unsimulated/wall/planetary/PW in planetary_walls)
for(var/datum/planet/P in planets)
if(PW.type == P.planetary_wall_type)
- P.planet_walls += PW
+ P.planet_walls |= PW
break
planetary_walls.Cut()
diff --git a/code/game/dna/dna_modifier.dm b/code/game/dna/dna_modifier.dm
index af0eccf93cc..e728ab8e50d 100644
--- a/code/game/dna/dna_modifier.dm
+++ b/code/game/dna/dna_modifier.dm
@@ -18,6 +18,7 @@
var/mind=null
var/languages=null
var/list/flavor=null
+ var/list/genetic_modifiers = list() // Modifiers with the MODIFIER_GENETIC flag are saved. Note that only the type is saved, not an instance.
/datum/dna2/record/proc/GetData()
var/list/ser=list("data" = null, "owner" = null, "label" = null, "type" = null, "ue" = 0)
diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm
index cf06523f6e8..b6945b2c07d 100644
--- a/code/game/machinery/cloning.dm
+++ b/code/game/machinery/cloning.dm
@@ -139,6 +139,25 @@
H.set_cloned_appearance()
update_icon()
+ // A modifier is added which makes the new clone be unrobust.
+ var/modifier_lower_bound = 25 MINUTES
+ var/modifier_upper_bound = 40 MINUTES
+
+ // Upgraded cloners can reduce the time of the modifier, up to 80%
+ var/clone_sickness_length = abs(((heal_level - 20) / 100 ) - 1)
+ clone_sickness_length = between(0.2, clone_sickness_length, 1.0) // Caps it off just incase.
+ modifier_lower_bound = round(modifier_lower_bound * clone_sickness_length, 1)
+ modifier_upper_bound = round(modifier_upper_bound * clone_sickness_length, 1)
+
+ H.add_modifier(/datum/modifier/recently_cloned, rand(modifier_lower_bound, modifier_upper_bound))
+
+ // Modifier that doesn't do anything.
+ H.add_modifier(/datum/modifier/cloned)
+
+ // This is really stupid.
+ for(var/modifier_type in R.genetic_modifiers)
+ H.add_modifier(modifier_type)
+
for(var/datum/language/L in R.languages)
H.add_language(L.name)
H.flavor_texts = R.flavor.Copy()
@@ -498,3 +517,31 @@
if(istype(A, /obj/machinery/clonepod))
A:malfunction()
*/
+
+/*
+ * Modifier applied to newly cloned people.
+ */
+
+// Gives rather nasty downsides for awhile, making them less robust.
+/datum/modifier/recently_cloned
+ name = "recently cloned"
+ desc = "You feel rather weak, having been cloned awhile ago."
+
+ on_created_text = "You feel really weak."
+ on_expired_text = "You feel your strength returning to you."
+
+ max_health_percent = 0.6 // -40% max health.
+ incoming_damage_percent = 1.1 // 10% more incoming damage.
+ outgoing_melee_damage_percent = 0.7 // 30% less melee damage.
+ disable_duration_percent = 1.25 // Stuns last 25% longer.
+ slowdown = 1 // Slower.
+ evasion = -1 // 15% easier to hit.
+
+// Does nothing.
+/datum/modifier/cloned
+ name = "cloned"
+ desc = "You died and were cloned, and you can never forget that."
+
+ flags = MODIFIER_GENETIC // So it gets copied if they die and get cloned again.
+ stacks = MODIFIER_STACK_ALLOWED // Two deaths means two instances of this.
+
diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm
index db932f8cd08..668520eee58 100644
--- a/code/game/machinery/computer/cloning.dm
+++ b/code/game/machinery/computer/cloning.dm
@@ -330,6 +330,9 @@
R.types = DNA2_BUF_UI|DNA2_BUF_UE|DNA2_BUF_SE
R.languages = subject.languages
R.flavor = subject.flavor_texts.Copy()
+ for(var/datum/modifier/mod in subject.modifiers)
+ if(mod.flags & MODIFIER_GENETIC)
+ R.genetic_modifiers.Add(mod.type)
//Add an implant if needed
var/obj/item/weapon/implant/health/imp = locate(/obj/item/weapon/implant/health, subject)
diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm
index 830c5f8d6d3..ec0af28d589 100644
--- a/code/game/machinery/spaceheater.dm
+++ b/code/game/machinery/spaceheater.dm
@@ -22,6 +22,10 @@
icon_state = "sheater[on]"
if(panel_open)
overlays += "sheater-open"
+ if(on)
+ set_light(3, 3, "#FFCC00")
+ else
+ set_light(0)
/obj/machinery/space_heater/examine(mob/user)
..(user)
diff --git a/code/game/objects/items/weapons/cards_ids_syndicate.dm b/code/game/objects/items/weapons/cards_ids_syndicate.dm
index 300926d08e7..b5c874868e7 100644
--- a/code/game/objects/items/weapons/cards_ids_syndicate.dm
+++ b/code/game/objects/items/weapons/cards_ids_syndicate.dm
@@ -1,28 +1,21 @@
-var/list/syndicate_ids = list()
-
/obj/item/weapon/card/id/syndicate
name = "agent card"
icon_state = "syndicate"
assignment = "Agent"
origin_tech = list(TECH_ILLEGAL = 3)
var/electronic_warfare = 1
- var/registered_user = null
+ var/mob/registered_user = null
/obj/item/weapon/card/id/syndicate/New(mob/user as mob)
..()
- syndicate_ids += src
access = syndicate_access.Copy()
-/obj/item/weapon/card/id/syndicate/Destroy()
- syndicate_ids -= src
- registered_user = null
- return ..()
+/obj/item/weapon/card/id/syndicate/station_access/New()
+ ..() // Same as the normal Syndicate id, only already has all station access
+ access |= get_all_station_access()
-// On mob destruction, ensure any references are cleared
-/mob/Destroy()
- for(var/obj/item/weapon/card/id/syndicate/SID in syndicate_ids)
- if(SID.registered_user == src)
- SID.registered_user = null
+/obj/item/weapon/card/id/syndicate/Destroy()
+ unset_registered_user(registered_user)
return ..()
/obj/item/weapon/card/id/syndicate/prevent_tracking()
@@ -37,9 +30,8 @@ var/list/syndicate_ids = list()
user << "The microscanner activates as you pass it over the ID, copying its access."
/obj/item/weapon/card/id/syndicate/attack_self(mob/user as mob)
- if(!registered_user)
- registered_user = user
- user.set_id_info(src)
+ // We use the fact that registered_name is not unset should the owner be vaporized, to ensure the id doesn't magically become unlocked.
+ if(!registered_user && register_user(user))
user << "The microscanner marks you as its owner, preventing others from accessing its internals."
if(registered_user == user)
switch(alert("Would you like edit the ID, or show it?","Show or Edit?", "Edit","Show"))
@@ -72,6 +64,21 @@ var/list/syndicate_ids = list()
ui.set_initial_data(data)
ui.open()
+/obj/item/weapon/card/id/syndicate/proc/register_user(var/mob/user)
+ if(!istype(user) || user == registered_user)
+ return FALSE
+ unset_registered_user()
+ registered_user = user
+ user.set_id_info(src)
+ user.register(OBSERVER_EVENT_DESTROY, src, /obj/item/weapon/card/id/syndicate/proc/unset_registered_user)
+ return TRUE
+
+/obj/item/weapon/card/id/syndicate/proc/unset_registered_user(var/mob/user)
+ if(!registered_user || (user && user != registered_user))
+ return
+ registered_user.unregister(OBSERVER_EVENT_DESTROY, src)
+ registered_user = null
+
/obj/item/weapon/card/id/syndicate/CanUseTopic(mob/user)
if(user != registered_user)
return STATUS_CLOSE
@@ -172,7 +179,7 @@ var/list/syndicate_ids = list()
icon_state = initial(icon_state)
name = initial(name)
registered_name = initial(registered_name)
- registered_user = null
+ unset_registered_user()
sex = initial(sex)
user << "All information has been deleted from \the [src]."
. = 1
diff --git a/code/game/objects/items/weapons/material/gravemarker.dm b/code/game/objects/items/weapons/material/gravemarker.dm
index f04e7f5e1be..cd5d3c6079b 100644
--- a/code/game/objects/items/weapons/material/gravemarker.dm
+++ b/code/game/objects/items/weapons/material/gravemarker.dm
@@ -1,7 +1,7 @@
/obj/item/weapon/material/gravemarker
name = "grave marker"
desc = "An object used in marking graves."
- icon_state = "gravestone"
+ icon_state = "gravemarker"
w_class = ITEMSIZE_LARGE
fragile = 1
force_divisor = 0.65
@@ -70,5 +70,6 @@
G.grave_name = grave_name
G.epitaph = epitaph
G.add_fingerprint(usr)
+ G.dir = user.dir
qdel_null(src)
return
\ No newline at end of file
diff --git a/code/game/objects/structures/gravemarker.dm b/code/game/objects/structures/gravemarker.dm
index 117e28898da..0be42fcddb3 100644
--- a/code/game/objects/structures/gravemarker.dm
+++ b/code/game/objects/structures/gravemarker.dm
@@ -1,10 +1,12 @@
/obj/structure/gravemarker
name = "grave marker"
desc = "An object used in marking graves."
- icon_state = "gravestone"
+ icon_state = "gravemarker"
density = 1
anchored = 1
+ throwpass = 1
+ climbable = 1
//Maybe make these calculate based on material?
var/health = 100
@@ -34,6 +36,23 @@
if(epitaph)
to_chat(user, epitaph)
+/obj/structure/gravemarker/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
+ if(!mover)
+ return 1
+ if(istype(mover) && mover.checkpass(PASSTABLE))
+ return 1
+ if(get_dir(loc, target) & dir)
+ return !density
+ else
+ return 1
+
+/obj/structure/gravemarker/CheckExit(atom/movable/O as mob|obj, target as turf)
+ if(istype(O) && O.checkpass(PASSTABLE))
+ return 1
+ if(get_dir(O.loc, target) == dir)
+ return 0
+ return 1
+
/obj/structure/gravemarker/attackby(obj/item/weapon/W, mob/user as mob)
if(istype(W, /obj/item/weapon/screwdriver))
var/carving_1 = sanitizeSafe(input(user, "Who is \the [src.name] for?", "Gravestone Naming", null) as text, MAX_NAME_LEN)
@@ -53,7 +72,7 @@
return
if(istype(W, /obj/item/weapon/wrench))
user.visible_message("[user] starts taking down \the [src.name].", "You start taking down \the [src.name].")
- if(do_after(user, 50 * W.toolspeed))
+ if(do_after(user, material.hardness * W.toolspeed))
user.visible_message("[user] takes down \the [src.name].", "You take down \the [src.name].")
dismantle()
..()
@@ -93,13 +112,13 @@
qdel(src)
return
-/* //Need Directional Sprites
+
/obj/structure/gravemarker/verb/rotate()
set name = "Rotate Grave Marker"
set category = "Object"
set src in oview(1)
- if(dir_locked)
+ if(anchored)
return
if(config.ghost_interaction)
src.set_dir(turn(src.dir, 90))
@@ -114,4 +133,8 @@
src.set_dir(turn(src.dir, 90))
return
-*/
\ No newline at end of file
+
+/obj/structure/gravemarker/gravestone
+ name = "gravestone"
+ desc = "A large stone used in marking graves."
+ icon_state = "gravestone"
\ No newline at end of file
diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm
index 5d371b45554..2f0a032f21d 100644
--- a/code/game/objects/structures/grille.dm
+++ b/code/game/objects/structures/grille.dm
@@ -239,3 +239,14 @@
if(air_group)
return 0 //Make sure air doesn't drain
..()
+
+/obj/structure/grille/broken/cult
+ icon_state = "grillecult-b"
+
+/obj/structure/grille/rustic
+ name = "rustic grille"
+ desc = "A lattice of metal, arranged in an old, rustic fashion."
+ icon_state = "grillerustic"
+
+/obj/structure/grille/broken/rustic
+ icon_state = "grillerustic-b"
diff --git a/code/game/objects/structures/simple_doors.dm b/code/game/objects/structures/simple_doors.dm
index 4e302e0e317..7312c1ebf9b 100644
--- a/code/game/objects/structures/simple_doors.dm
+++ b/code/game/objects/structures/simple_doors.dm
@@ -42,7 +42,7 @@
/obj/structure/simple_door/Destroy()
processing_objects -= src
update_nearby_tiles()
- ..()
+ return ..()
/obj/structure/simple_door/get_material()
return material
@@ -194,5 +194,8 @@
/obj/structure/simple_door/wood/New(var/newloc,var/material_name)
..(newloc, "wood")
+/obj/structure/simple_door/sifwood/New(var/newloc,var/material_name)
+ ..(newloc, "alien wood")
+
/obj/structure/simple_door/resin/New(var/newloc,var/material_name)
..(newloc, "resin")
\ No newline at end of file
diff --git a/code/game/turfs/simulated/outdoors/outdoors.dm b/code/game/turfs/simulated/outdoors/outdoors.dm
index 75c7e680835..e5c64653298 100644
--- a/code/game/turfs/simulated/outdoors/outdoors.dm
+++ b/code/game/turfs/simulated/outdoors/outdoors.dm
@@ -34,6 +34,26 @@ var/list/outdoor_turfs = list()
planet_controller.unallocateTurf(src)
..()
+/turf/simulated/proc/make_outdoors()
+ outdoors = TRUE
+ outdoor_turfs.Add(src)
+
+/turf/simulated/proc/make_indoors()
+ outdoors = FALSE
+ planet_controller.unallocateTurf(src)
+ qdel(weather_overlay)
+ update_icon()
+
+/turf/simulated/post_change()
+ ..()
+ // If it was outdoors and still is, it will not get added twice when the planet controller gets around to putting it in.
+ if(outdoors)
+ make_outdoors()
+ // outdoor_turfs += src
+ else
+ make_indoors()
+ // planet_controller.unallocateTurf(src)
+
/turf/simulated/proc/update_icon_edge()
if(edge_blending_priority)
for(var/checkdir in cardinal)
@@ -55,7 +75,7 @@ var/list/outdoor_turfs = list()
..()
/turf/simulated/floor/outdoors/mud
- name = "grass"
+ name = "mud"
icon_state = "mud_dark"
edge_blending_priority = 3
diff --git a/code/game/turfs/simulated/water.dm b/code/game/turfs/simulated/water.dm
index 781ddeeb7f7..8e32a004d90 100644
--- a/code/game/turfs/simulated/water.dm
+++ b/code/game/turfs/simulated/water.dm
@@ -15,8 +15,12 @@
update_icon()
..()
+/turf/simulated/floor/water/initialize()
+ update_icon()
+
/turf/simulated/floor/water/update_icon()
..() // To get the edges. This also gets rid of other overlays so it needs to go first.
+ overlays.Cut()
icon_state = water_state
var/image/floorbed_sprite = image(icon = 'icons/turf/outdoors.dmi', icon_state = under_state)
underlays.Add(floorbed_sprite)
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index fa0f355bc95..bcc750a13bd 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -658,6 +658,29 @@ var/list/admin_verbs_mentor = list(
log_admin("[key_name(usr)] gave [key_name(T)] a [greater] disease2 with infection chance [D.infectionchance].")
message_admins("[key_name_admin(usr)] gave [key_name(T)] a [greater] disease2 with infection chance [D.infectionchance].", 1)
+/client/proc/admin_give_modifier(var/mob/living/L)
+ set category = "Debug"
+ set name = "Give Modifier"
+ set desc = "Makes a mob weaker or stronger by adding a specific modifier to them."
+
+ if(!L)
+ to_chat(usr, "Looks like you didn't select a mob.")
+ return
+
+ var/list/possible_modifiers = typesof(/datum/modifier) - /datum/modifier
+
+ var/new_modifier_type = input("What modifier should we add to [L]?", "Modifier Type") as null|anything in possible_modifiers
+ if(!new_modifier_type)
+ return
+ var/duration = input("How long should the new modifier last, in seconds. To make it last forever, write '0'.", "Modifier Duration") as num
+ if(duration == 0)
+ duration = null
+ else
+ duration = duration SECONDS
+
+ L.add_modifier(new_modifier_type, duration)
+ log_and_message_admins("has given [key_name(L)] the modifer [new_modifier_type], with a duration of [duration ? "[duration / 600] minutes" : "forever"].")
+
/client/proc/make_sound(var/obj/O in world) // -- TLE
set category = "Special Verbs"
set name = "Make Sound"
diff --git a/code/modules/admin/view_variables/helpers.dm b/code/modules/admin/view_variables/helpers.dm
index c00e598cb37..1e160d253c6 100644
--- a/code/modules/admin/view_variables/helpers.dm
+++ b/code/modules/admin/view_variables/helpers.dm
@@ -34,6 +34,7 @@
return ..() + {"
+
diff --git a/code/modules/admin/view_variables/topic.dm b/code/modules/admin/view_variables/topic.dm
index 7d0966dc592..7c687374904 100644
--- a/code/modules/admin/view_variables/topic.dm
+++ b/code/modules/admin/view_variables/topic.dm
@@ -74,6 +74,18 @@
src.give_spell(M)
href_list["datumrefresh"] = href_list["give_spell"]
+ else if(href_list["give_modifier"])
+ if(!check_rights(R_ADMIN|R_FUN|R_DEBUG))
+ return
+
+ var/mob/living/M = locate(href_list["give_modifier"])
+ if(!istype(M))
+ usr << "This can only be used on instances of type /mob/living"
+ return
+
+ src.admin_give_modifier(M)
+ href_list["datumrefresh"] = href_list["give_modifier"]
+
else if(href_list["give_disease2"])
if(!check_rights(R_ADMIN|R_FUN)) return
diff --git a/code/modules/hydroponics/trays/tray.dm b/code/modules/hydroponics/trays/tray.dm
index 4b26011f6de..4eee4ee91ba 100644
--- a/code/modules/hydroponics/trays/tray.dm
+++ b/code/modules/hydroponics/trays/tray.dm
@@ -174,6 +174,25 @@
connect()
update_icon()
+/obj/machinery/portable_atmospherics/hydroponics/initialize()
+ var/obj/item/seeds/S = locate() in loc
+ if(S)
+ plant_seeds(S)
+
+/obj/machinery/portable_atmospherics/hydroponics/proc/plant_seeds(var/obj/item/seeds/S)
+ lastproduce = 0
+ seed = S.seed //Grab the seed datum.
+ dead = 0
+ age = 1
+ //Snowflakey, maybe move this to the seed datum
+ health = (istype(S, /obj/item/seeds/cutting) ? round(seed.get_trait(TRAIT_ENDURANCE)/rand(2,5)) : seed.get_trait(TRAIT_ENDURANCE))
+ lastcycle = world.time
+
+ qdel(S)
+
+ check_health()
+ update_icon()
+
/obj/machinery/portable_atmospherics/hydroponics/bullet_act(var/obj/item/projectile/Proj)
//Don't act on seeds like dionaea that shouldn't change.
@@ -490,18 +509,7 @@
return
user << "You plant the [S.seed.seed_name] [S.seed.seed_noun]."
- lastproduce = 0
- seed = S.seed //Grab the seed datum.
- dead = 0
- age = 1
- //Snowflakey, maybe move this to the seed datum
- health = (istype(S, /obj/item/seeds/cutting) ? round(seed.get_trait(TRAIT_ENDURANCE)/rand(2,5)) : seed.get_trait(TRAIT_ENDURANCE))
- lastcycle = world.time
-
- qdel(O)
-
- check_health()
- update_icon()
+ plant_seeds(S)
else
user << "\The [src] already has seeds in it!"
diff --git a/code/modules/maps/tg/map_template.dm b/code/modules/maps/tg/map_template.dm
index ae8031638f4..3aaf324463b 100644
--- a/code/modules/maps/tg/map_template.dm
+++ b/code/modules/maps/tg/map_template.dm
@@ -24,7 +24,8 @@ var/list/global/map_templates = list()
if(path)
mappath = path
if(mappath)
- preload_size(mappath)
+ spawn(1)
+ preload_size(mappath)
if(rename)
name = rename
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 3fb8fe8ac9d..194864b7de5 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -258,7 +258,17 @@
"You shake [src] trying to wake [t_him] up!")
else
var/mob/living/carbon/human/hugger = M
- if(istype(hugger))
+ if(M.resting == 1) //Are they resting on the ground?
+ M.visible_message("[M] grabs onto [src] and pulls \himself up", \
+ "You grip onto [src] and pull yourself up off the ground!") //AHHH gender checks are hard, but this should work
+ if(M.fire_stacks >= (src.fire_stacks + 3)) //Fire checks.
+ src.adjust_fire_stacks(1)
+ M.adjust_fire_stacks(-1)
+ if(M.on_fire)
+ src.IgniteMob()
+ if(do_after(M, 0.5 SECONDS)) //.5 second delay. Makes it a bit stronger than just typing rest.
+ M.resting = 0 //Hoist yourself up up off the ground. No para/stunned/weakened removal.
+ else if(istype(hugger))
hugger.species.hug(hugger,src)
else
M.visible_message("[M] hugs [src] to make [t_him] feel better!", \
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index 8ae2ed52bf5..ad3a41fbc86 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -151,15 +151,15 @@ var/list/ai_verbs_hidden = list( // For why this exists, refer to https://xkcd.c
//Languages
add_language("Robot Talk", 1)
add_language(LANGUAGE_GALCOM, 1)
- add_language(LANGUAGE_SOL_COMMON, 0)
- add_language(LANGUAGE_UNATHI, 0)
- add_language(LANGUAGE_SIIK, 0)
- add_language(LANGUAGE_SKRELLIAN, 0)
+ add_language(LANGUAGE_SOL_COMMON, 1)
+ add_language(LANGUAGE_UNATHI, 1)
+ add_language(LANGUAGE_SIIK, 1)
+ add_language(LANGUAGE_SKRELLIAN, 1)
add_language(LANGUAGE_TRADEBAND, 1)
- add_language(LANGUAGE_GUTTER, 0)
+ add_language(LANGUAGE_GUTTER, 1)
add_language(LANGUAGE_EAL, 1)
- add_language(LANGUAGE_SCHECHI, 0)
- add_language(LANGUAGE_SIGN, 0)
+ add_language(LANGUAGE_SCHECHI, 1)
+ add_language(LANGUAGE_SIGN, 1)
if(!safety)//Only used by AIize() to successfully spawn an AI.
if (!B)//If there is no player/brain inside.
diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm
index bd126614378..9d30ef72447 100644
--- a/code/modules/mob/transform_procs.dm
+++ b/code/modules/mob/transform_procs.dm
@@ -77,10 +77,26 @@
else
O.key = key
+ //Languages
+ add_language("Robot Talk", 1)
+ add_language(LANGUAGE_GALCOM, 1)
+ add_language(LANGUAGE_SOL_COMMON, 1)
+ add_language(LANGUAGE_UNATHI, 1)
+ add_language(LANGUAGE_SIIK, 1)
+ add_language(LANGUAGE_SKRELLIAN, 1)
+ add_language(LANGUAGE_TRADEBAND, 1)
+ add_language(LANGUAGE_GUTTER, 1)
+ add_language(LANGUAGE_EAL, 1)
+ add_language(LANGUAGE_SCHECHI, 1)
+ add_language(LANGUAGE_SIGN, 1)
+
+ // Lorefolks say it may be so.
if(O.client && O.client.prefs)
var/datum/preferences/B = O.client.prefs
- for(var/language in B.alternate_languages)
- O.add_language(language)
+ if(LANGUAGE_ROOTGLOBAL in B.alternate_languages)
+ O.add_language(LANGUAGE_ROOTGLOBAL, 1)
+ if(LANGUAGE_ROOTLOCAL in B.alternate_languages)
+ O.add_language(LANGUAGE_ROOTLOCAL, 1)
if(move)
var/obj/loc_landmark
diff --git a/html/changelogs/Woodrat-SyndIDs.yml b/html/changelogs/Woodrat-SyndIDs.yml
new file mode 100644
index 00000000000..fba90ab1fd7
--- /dev/null
+++ b/html/changelogs/Woodrat-SyndIDs.yml
@@ -0,0 +1,37 @@
+################################
+# Example Changelog File
+#
+# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
+#
+# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
+# When it is, any changes listed below will disappear.
+#
+# Valid Prefixes:
+# bugfix
+# wip (For works in progress)
+# tweak
+# soundadd
+# sounddel
+# rscadd (general adding of nice things)
+# rscdel (general deleting of nice things)
+# imageadd
+# imagedel
+# maptweak
+# spellcheck (typo fixes)
+# experiment
+#################################
+
+# Your name.
+author: Woodrat
+
+# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
+delete-after: True
+
+# Any changes you've made. See valid prefix list above.
+# INDENT WITH TWO SPACES. NOT TABS. SPACES.
+# SCREW THIS UP AND IT WON'T WORK.
+# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
+# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
+changes:
+ - rscadd: "Added a Syndicate ID with all access (admin spawn only)."
+ - tweak: "Port of 'Syndicate id cards now listen for owner destruction' from Bay."
diff --git a/icons/obj/structures.dmi b/icons/obj/structures.dmi
index f78d4f8b1f2..f6779fed715 100644
Binary files a/icons/obj/structures.dmi and b/icons/obj/structures.dmi differ
diff --git a/icons/obj/weapons.dmi b/icons/obj/weapons.dmi
index bb782830951..b371d13c0a0 100644
Binary files a/icons/obj/weapons.dmi and b/icons/obj/weapons.dmi differ
diff --git a/icons/turf/areas.dmi b/icons/turf/areas.dmi
index d1bfcbfb013..8ad45585abe 100755
Binary files a/icons/turf/areas.dmi and b/icons/turf/areas.dmi differ
diff --git a/maps/_map_system_readme.dm b/maps/_map_system_readme.dm
new file mode 100644
index 00000000000..95e996907ba
--- /dev/null
+++ b/maps/_map_system_readme.dm
@@ -0,0 +1,18 @@
+/*
+This system is in place to make it easier to seperate data specific to a certain map.
+
+Each map should have their own folder, and contain both the actual map files, and the code files defining their unique
+things, such as areas, elevators, or shuttles. Generally, the layout is that your map folder has,
+
+[map_name] folder
+ [map_name].dm - Containing a lot of #define directives, and is used to automatically load the other files you need.
+ [map_name_defines].dm - This contains the code for the map datum. For more details, read the comments inside ~map_system folder.
+ (optional) [map_name]_areas/structures/whatever.dm - Files for unique things to that map.
+ [map_name]-1.dmm - Your actual map files. Z-levels should be ordered correctly if you seperate your z-levels across map files.
+
+-HOW TO LOAD A SPECIFIC MAP-
+Say you want to load southern_cross,
+First, uncheck your current loaded map, presumably northern_star. Uncheck northern_star.dm inside northern_star folder.
+Then go open southern_cross folder, and check southern_cross.dm, don't check any other folders below, and compile.
+When you finish compiling, you should be able to open the map files for southern_cross.
+*/
\ No newline at end of file
diff --git a/maps/plane/plane-1.dmm b/maps/plane/plane-1.dmm
new file mode 100644
index 00000000000..8017636b44a
--- /dev/null
+++ b/maps/plane/plane-1.dmm
@@ -0,0 +1,71 @@
+"a" = (/turf/unsimulated/wall/planetary/sif,/area/plane_ground)
+"b" = (/turf/simulated/floor/outdoors/dirt,/area/plane_ground)
+"c" = (/obj/effect/landmark/start,/turf/simulated/floor/outdoors/dirt,/area/plane_ground)
+"d" = (/obj/effect/landmark{name = "JoinLate"},/turf/simulated/floor/outdoors/dirt,/area/plane_ground)
+
+(1,1,1) = {"
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbdddbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbdddbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbdddbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+"}
diff --git a/maps/plane/plane-2.dmm b/maps/plane/plane-2.dmm
new file mode 100644
index 00000000000..06144256e95
--- /dev/null
+++ b/maps/plane/plane-2.dmm
@@ -0,0 +1,70 @@
+"a" = (/turf/unsimulated/wall/planetary/sif,/area/plane_sky)
+"b" = (/turf/simulated/open,/area/plane_sky)
+"c" = (/obj/effect/landmark/map_data{height = 2},/turf/simulated/open,/area/plane_sky)
+
+(1,1,1) = {"
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbcbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbba
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+"}
diff --git a/maps/plane/plane.dm b/maps/plane/plane.dm
new file mode 100644
index 00000000000..71ba0072af5
--- /dev/null
+++ b/maps/plane/plane.dm
@@ -0,0 +1,16 @@
+#if !defined(USING_MAP_DATUM)
+
+ #include "plane-1.dmm"
+ #include "plane-2.dmm"
+
+ #include "plane_defines.dm"
+ #include "plane_areas.dm"
+
+
+ #define USING_MAP_DATUM /datum/map/plane
+
+#elif !defined(MAP_OVERRIDE)
+
+ #warn A map has already been included, ignoring Plane
+
+#endif
\ No newline at end of file
diff --git a/maps/plane/plane_areas.dm b/maps/plane/plane_areas.dm
new file mode 100644
index 00000000000..2df2eb91d72
--- /dev/null
+++ b/maps/plane/plane_areas.dm
@@ -0,0 +1,5 @@
+/area/plane_ground
+ name = "flat plane"
+
+/area/plane_sky
+ name = "open sky"
\ No newline at end of file
diff --git a/maps/plane/plane_defines.dm b/maps/plane/plane_defines.dm
new file mode 100644
index 00000000000..8d1e48a5eca
--- /dev/null
+++ b/maps/plane/plane_defines.dm
@@ -0,0 +1,41 @@
+#define Z_LEVEL_FIRST_PLANE 1
+#define Z_LEVEL_SECOND_PLANE 2
+
+/datum/map/plane
+ name = "Another Test Map"
+ full_name = "The Flat Test Map"
+ path = "plane"
+
+ lobby_icon = 'icons/misc/title.dmi'
+ lobby_screens = list("mockingjay00")
+
+ zlevel_datum_type = /datum/map_z_level/plane
+
+ station_name = "The Plain Plane for Air Planes"
+ station_short = "The Plane"
+ dock_name = "the Maximum Fun Chamber"
+ boss_name = "Mister Fun"
+ boss_short = "Mr. Fun"
+ company_name = "Fun Inc."
+ company_short = "FI"
+ starsys_name = "Not Vir"
+
+/datum/map_z_level/plane/first
+ z = Z_LEVEL_FIRST_PLANE
+ name = "The Ground"
+ flags = MAP_LEVEL_STATION|MAP_LEVEL_CONTACT|MAP_LEVEL_PLAYER
+ transit_chance = 50
+ base_turf = /turf/simulated/floor/outdoors/rocks
+
+/datum/map_z_level/plane/second
+ z = Z_LEVEL_SECOND_PLANE
+ name = "The Sky"
+ flags = MAP_LEVEL_STATION|MAP_LEVEL_CONTACT|MAP_LEVEL_PLAYER
+ transit_chance = 50
+ base_turf = /turf/simulated/open
+
+/datum/planet/sif
+ expected_z_levels = list(
+ Z_LEVEL_FIRST_PLANE,
+ Z_LEVEL_SECOND_PLANE
+ )
\ No newline at end of file
diff --git a/maps/submaps/surface_submaps/farm1.dmm b/maps/submaps/surface_submaps/farm1.dmm
new file mode 100644
index 00000000000..a89d481737f
--- /dev/null
+++ b/maps/submaps/surface_submaps/farm1.dmm
@@ -0,0 +1,78 @@
+"a" = (/turf/template_noop,/area/template_noop)
+"b" = (/turf/simulated/floor/outdoors/dirt,/area/submap/farm1)
+"c" = (/obj/structure/railing,/turf/simulated/floor/outdoors/dirt,/area/submap/farm1)
+"d" = (/obj/structure/railing{tag = "icon-railing0 (EAST)"; icon_state = "railing0"; dir = 4},/turf/simulated/floor/outdoors/dirt,/area/submap/farm1)
+"e" = (/turf/simulated/floor/outdoors/grass/sif,/area/submap/farm1)
+"f" = (/obj/structure/railing{tag = "icon-railing0 (WEST)"; icon_state = "railing0"; dir = 8},/turf/simulated/floor/outdoors/dirt,/area/submap/farm1)
+"g" = (/turf/simulated/wall/wood,/area/submap/farm1)
+"h" = (/obj/structure/grille/rustic,/obj/structure/window/reinforced/full,/turf/simulated/floor/plating,/area/submap/farm1)
+"i" = (/obj/structure/closet/secure_closet/freezer/fridge,/turf/simulated/floor/wood,/area/submap/farm1)
+"j" = (/turf/simulated/floor/wood,/area/submap/farm1)
+"k" = (/obj/structure/table/marble,/turf/simulated/floor/wood,/area/submap/farm1)
+"l" = (/obj/structure/table/marble,/obj/item/weapon/material/kitchen/rollingpin,/turf/simulated/floor/wood,/area/submap/farm1)
+"m" = (/obj/machinery/portable_atmospherics/hydroponics/soil,/obj/item/seeds/cornseed,/turf/simulated/floor/outdoors/dirt,/area/submap/farm1)
+"n" = (/obj/item/weapon/material/minihoe,/turf/simulated/floor/outdoors/dirt,/area/submap/farm1)
+"o" = (/obj/structure/table/marble,/obj/item/weapon/material/kitchen/utensil/knife,/turf/simulated/floor/wood,/area/submap/farm1)
+"p" = (/obj/machinery/portable_atmospherics/hydroponics/soil,/obj/item/seeds/bluetomatoseed,/turf/simulated/floor/outdoors/dirt,/area/submap/farm1)
+"q" = (/turf/simulated/floor/outdoors/mud,/area/submap/farm1)
+"r" = (/obj/machinery/portable_atmospherics/hydroponics/soil,/obj/item/seeds/icepepperseed,/turf/simulated/floor/outdoors/dirt,/area/submap/farm1)
+"s" = (/obj/structure/simple_door/wood,/turf/simulated/floor/wood,/area/submap/farm1)
+"t" = (/mob/living/bot/farmbot,/turf/simulated/floor/outdoors/dirt,/area/submap/farm1)
+"u" = (/obj/structure/sink/puddle,/turf/simulated/floor/outdoors/mud,/area/submap/farm1)
+"v" = (/obj/item/weapon/material/hatchet,/turf/simulated/floor/outdoors/mud,/area/submap/farm1)
+"w" = (/obj/structure/table/woodentable,/obj/item/weapon/storage/box/matches,/obj/item/weapon/flame/match,/turf/simulated/floor/wood,/area/submap/farm1)
+"x" = (/obj/structure/table/woodentable,/turf/simulated/floor/wood,/area/submap/farm1)
+"y" = (/obj/item/clothing/shoes/boots/winter/hydro,/obj/item/clothing/suit/storage/hooded/wintercoat/hydro,/turf/simulated/floor/wood,/area/submap/farm1)
+"z" = (/obj/structure/bed/chair/wood{tag = "icon-wooden_chair (WEST)"; icon_state = "wooden_chair"; dir = 8},/turf/simulated/floor/wood,/area/submap/farm1)
+"A" = (/obj/item/weapon/reagent_containers/glass/bucket,/turf/simulated/floor/outdoors/dirt,/area/submap/farm1)
+"B" = (/obj/structure/table/woodentable,/obj/item/weapon/storage/fancy/candle_box,/turf/simulated/floor/wood,/area/submap/farm1)
+"C" = (/obj/machinery/portable_atmospherics/hydroponics/soil,/obj/item/seeds/wheatseed,/turf/simulated/floor/outdoors/dirt,/area/submap/farm1)
+"D" = (/obj/structure/closet/crate/bin,/turf/simulated/floor/wood,/area/submap/farm1)
+"E" = (/obj/machinery/space_heater,/turf/simulated/floor/wood,/area/submap/farm1)
+"F" = (/obj/structure/bookcase,/obj/item/weapon/book/manual/hydroponics_pod_people,/turf/simulated/floor/wood,/area/submap/farm1)
+"G" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/blue,/turf/simulated/floor/wood,/area/submap/farm1)
+"H" = (/obj/structure/table/woodentable,/obj/item/trash/candle,/turf/simulated/floor/wood,/area/submap/farm1)
+"I" = (/turf/simulated/floor/outdoors/rocks,/area/submap/farm1)
+"J" = (/turf/simulated/floor/plating,/area/submap/farm1)
+"K" = (/turf/simulated/floor/water,/area/submap/farm1)
+"L" = (/obj/structure/loot_pile/maint/technical,/turf/simulated/floor/plating,/area/submap/farm1)
+"M" = (/obj/machinery/power/port_gen/pacman,/turf/simulated/floor/plating,/area/submap/farm1)
+"N" = (/obj/structure/closet/crate/hydroponics/prespawned,/turf/simulated/floor/plating,/area/submap/farm1)
+"O" = (/obj/structure/table/steel,/obj/machinery/cell_charger,/turf/simulated/floor/plating,/area/submap/farm1)
+"P" = (/obj/structure/table/steel,/turf/simulated/floor/plating,/area/submap/farm1)
+"Q" = (/obj/structure/railing{tag = "icon-railing0 (NORTH)"; icon_state = "railing0"; dir = 1},/turf/simulated/floor/outdoors/dirt,/area/submap/farm1)
+
+(1,1,1) = {"
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+abccccccccccccccccccccccccbaaaaa
+adeeeeeeeeeeeeeeeeeeeeeeeefaaaaa
+adeeeeeeeeeeeeeeeeeeeeeeeefaaaaa
+adeegghhggeeeeeeeeeeeeeeeefaaaaa
+adeegijklgeeeeemmmmmmmmmeefaaaaa
+adeegjjjkheeeeebnbbbbbbbeefaaaaa
+adeegjjjogebbeepppqqqrrreefaaaaa
+adegggsgggebbbbtbbquvbbbeefaaaaa
+adegwxjygeeebbepppqqqrrreefaaaaa
+adehxzjjgggebeebbAbbbbbbeefaaaaa
+adehBjjjsjsbbeeCCCCCCCCCeefaaaaa
+adegDjjEgggebeeeeeeeeeeeeefaaaaa
+adeggsgggeeebeeeeeeeeeeeeefaaaaa
+adegFjjGgeebbbeeeeebbbbbbbbbbbba
+adegEjjHgeebbbbbbbbbbbbbbbbbbbba
+adeggggggeebeeeeeeebbbbbbbbbbbba
+adeebbbbbbbbeeeeeeebbbeeeefaaaaa
+adebbIIIIIIbbeeegggJJJgggefaaaaa
+adebIIKKKKIIbbeegLJJJJJLgefaaaaa
+adebIKKKKKKIIbbehMJJJJJJhefaaaaa
+adebIIKKKKKKIIbehLJJJJJLhefaaaaa
+adebbIIKKKKKKIbehNJJJJJJhefaaaaa
+adeebbIIKKKKIIbegLJOPPJLgefaaaaa
+adeeebbIIIIIIbbegggggggggefaaaaa
+adeeeebbbbbbbbeeeeeeeeeeeefaaaaa
+adeeeeeeeeeeeeeeeeeeeeeeeefaaaaa
+abQQQQQQQQQQQQQQQQQQQQQQQQbaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+"}
diff --git a/maps/submaps/surface_submaps/forest.dm b/maps/submaps/surface_submaps/forest.dm
index dd02c1b2043..be13e4f9475 100644
--- a/maps/submaps/surface_submaps/forest.dm
+++ b/maps/submaps/surface_submaps/forest.dm
@@ -2,4 +2,9 @@
name = "Surface Content"
desc = "Used to make the surface by 17% less boring."
-// To be added: Templates for surface exploration when they are made.
\ No newline at end of file
+// To be added: Templates for surface exploration when they are made.
+
+/datum/map_template/surface/farm1
+ name = "Farm 1"
+ desc = "A small farm tended by a farmbot."
+ mappath = 'maps/submaps/surface_submaps/farm1.dmm'
\ No newline at end of file
diff --git a/maps/submaps/surface_submaps/forest_areas.dm b/maps/submaps/surface_submaps/forest_areas.dm
new file mode 100644
index 00000000000..f8fe110cb0f
--- /dev/null
+++ b/maps/submaps/surface_submaps/forest_areas.dm
@@ -0,0 +1,6 @@
+/area/submap
+ name = "Submap Area"
+ icon_state = "submap"
+
+/area/submap/farm1
+ name = "farm"
\ No newline at end of file
diff --git a/polaris.dme b/polaris.dme
index efe288ea159..93f75a2b1ab 100644
--- a/polaris.dme
+++ b/polaris.dme
@@ -2273,5 +2273,6 @@
#include "maps\submaps\cave_submaps\cave.dm"
#include "maps\submaps\space_submaps\space.dm"
#include "maps\submaps\surface_submaps\forest.dm"
+#include "maps\submaps\surface_submaps\forest_areas.dm"
#include "maps\~map_system\maps.dm"
// END_INCLUDE