ERROR. Recalibrating gravity field.")
+ return
+
+ last_gravity_change = world.time
+
+ if(A.has_gravity)
+ A.gravitychange(0)
+ else
+ A.gravitychange(1)
+
+//This could all be done better, but it works for now.
+/obj/machinery/computer/looking_glass/Destroy()
+ unload_program()
+ ..()
+
+/obj/machinery/computer/looking_glass/ex_act(severity)
+ unload_program()
+ ..()
+
+/obj/machinery/computer/looking_glass/power_change()
+ var/oldstat = stat
+ ..()
+ if (stat != oldstat && (stat & NOPOWER))
+ unload_program()
\ No newline at end of file
diff --git a/code/modules/looking_glass/lg_imageholder.dm b/code/modules/looking_glass/lg_imageholder.dm
new file mode 100644
index 00000000000..0d4cf5b157b
--- /dev/null
+++ b/code/modules/looking_glass/lg_imageholder.dm
@@ -0,0 +1,66 @@
+#define LG_IMAGE_SIZE 736
+
+/obj/effect/landmark/looking_glass
+ var/image/holding
+
+ var/list/viewers
+
+ var/lg_id //Area sets this for you
+
+ mouse_opacity = 0
+
+/obj/effect/landmark/looking_glass/Initialize()
+ . = ..()
+ viewers = list()
+
+/obj/effect/landmark/looking_glass/proc/gain_viewer(var/client/C)
+ if(C in viewers)
+ testing("Looking Glass [x],[y],[z] tried to add a duplicate viewer.")
+ viewers |= C
+ if(holding)
+ show_to(C)
+
+/obj/effect/landmark/looking_glass/proc/lose_viewer(var/client/C)
+ if(!(C in viewers))
+ testing("Looking Glass [x],[y],[z] tried to remove a viewer it didn't have")
+ viewers -= C
+ if(holding)
+ unshow_to(C)
+
+/obj/effect/landmark/looking_glass/proc/show_to(var/client/C)
+ C.images |= holding
+
+/obj/effect/landmark/looking_glass/proc/unshow_to(var/client/C)
+ C.images -= holding
+
+/obj/effect/landmark/looking_glass/proc/take_image(var/image/newimage)
+ if(!istype(newimage))
+ return
+
+ if(holding)
+ for(var/client in viewers)
+ unshow_to(client)
+
+ holding = newimage
+ newimage.plane = PLANE_LOOKINGGLASS_IMG
+ newimage.blend_mode = BLEND_MULTIPLY
+ newimage.appearance_flags = RESET_TRANSFORM
+ newimage.mouse_opacity = 0
+ newimage.pixel_y = newimage.pixel_x = (LG_IMAGE_SIZE/-2) + 16
+ newimage.loc = src
+
+ for(var/client in viewers)
+ show_to(client)
+
+/obj/effect/landmark/looking_glass/proc/drop_image()
+ if(!holding)
+ return
+
+ for(var/client in viewers)
+ unshow_to(client)
+
+ holding.loc = null
+ holding = null
+
+
+#undef LG_IMAGE_SIZE
\ No newline at end of file
diff --git a/code/modules/looking_glass/lg_turfs.dm b/code/modules/looking_glass/lg_turfs.dm
new file mode 100644
index 00000000000..189790335d8
--- /dev/null
+++ b/code/modules/looking_glass/lg_turfs.dm
@@ -0,0 +1,88 @@
+/decl/flooring/looking_glass
+ name = "looking glass surface"
+ desc = "Too expensive to replace. Don't break it!"
+ icon = 'icons/turf/flooring/lg_origin.dmi'
+ icon_base = "origin"
+ build_type = null
+ damage_temperature = T0C+200
+
+
+/turf/simulated/floor/looking_glass
+ name = "looking glass surface"
+ icon = 'icons/turf/flooring/lg_origin.dmi'
+ icon_state = "origin_arrow"
+ initial_flooring = /decl/flooring/looking_glass
+ appearance_flags = TILE_BOUND
+ dynamic_lighting = FALSE
+
+ var/center = FALSE
+ var/optional = FALSE
+
+/turf/simulated/floor/looking_glass/center
+ center = TRUE
+ icon_state = "origin_center"
+
+/turf/simulated/floor/looking_glass/optional
+ center = TRUE
+ optional = TRUE
+ icon_state = "origin_optional_arrow"
+
+/turf/simulated/floor/looking_glass/proc/activate()
+ set waitfor = FALSE
+
+ icon_state = "origin_switching"
+
+ animate(src, color = "#000000", time = 3 SECONDS)
+
+ sleep(3 SECONDS)
+
+ var/new_x = 0
+ var/new_y = 0
+
+ if(dir & NORTH)
+ new_y = 112
+ else if(dir & SOUTH)
+ new_y = -112
+
+ if(dir & EAST)
+ new_x = 112
+ else if(dir & WEST)
+ new_x = -112
+
+ var/matrix/M = matrix()
+ var/mutable_appearance/MA = new (src)
+
+ if(!center)
+ var/horizontal = (dir & (WEST|EAST))
+ var/vertical = (dir & (NORTH|SOUTH))
+ M.Scale(horizontal ? 8 : 1, vertical ? 8 : 1)
+ M.Translate(new_x, new_y)
+ MA.opacity = 1
+ if(!optional)
+ MA.density = 1
+
+ MA.icon_state = "origin_active"
+ MA.plane = PLANE_LOOKINGGLASS
+ MA.layer = 0
+ appearance = MA
+
+ animate(src, color = "#FFFFFF", transform = M, time = 3 SECONDS)
+
+/turf/simulated/floor/looking_glass/proc/deactivate()
+ set waitfor = FALSE
+
+ animate(src, color = "#000000", transform = matrix(), time = 3 SECONDS)
+
+ sleep(3 SECONDS)
+ var/mutable_appearance/MA = new (src)
+ MA.opacity = 0
+ MA.density = 0
+ MA.icon_state = "origin_switching"
+ MA.plane = initial(plane)
+ MA.layer = initial(layer)
+ appearance = MA
+
+ animate(src, color = null, time = 3 SECONDS)
+ sleep(3 SECONDS)
+ icon_state = "origin"
+
diff --git a/icons/turf/flooring/lg_origin.dmi b/icons/turf/flooring/lg_origin.dmi
new file mode 100644
index 00000000000..d455723fd08
Binary files /dev/null and b/icons/turf/flooring/lg_origin.dmi differ
diff --git a/nano/templates/lookingglass.tmpl b/nano/templates/lookingglass.tmpl
new file mode 100644
index 00000000000..8f117e6f66f
--- /dev/null
+++ b/nano/templates/lookingglass.tmpl
@@ -0,0 +1,14 @@
+Current Loaded Programs:
+{{for data.supportedPrograms}}
+ {{:helper.link(value, data.currentProgram == value ? 'check' : 'close', {'program' : value}, null, data.currentProgram == value ? 'linkOn' : null)}}
+{{/for}}
+
+
+
Area Gravity:
+ {{:helper.link(data.gravity ? 'On ' : 'Off', data.gravity ? 'check' : 'close', {'gravity' : 1}, null, data.gravity ? 'linkOn' : 'redButton')}}
+
+
+
+
Full Immersion:
+ {{:helper.link(data.immersion ? 'On ' : 'Off', data.immersion ? 'check' : 'close', {'immersion' : 1}, null, data.immersion ? 'linkOn' : 'redButton')}}
+
\ No newline at end of file