mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-08-28 06:28:01 +01:00
Looking Glass Holodecks
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
/area/looking_glass
|
||||
name = "make a subtype"
|
||||
|
||||
var/obj/effect/landmark/looking_glass/our_landmark
|
||||
var/list/our_turfs = list()
|
||||
var/list/our_optional_turfs = list()
|
||||
|
||||
var/lg_id
|
||||
|
||||
var/active = FALSE
|
||||
|
||||
/area/looking_glass/Initialize()
|
||||
. = ..()
|
||||
our_landmark = locate() in src
|
||||
if(!our_landmark)
|
||||
testing("Looking glass area [name] couldn't find a landmark")
|
||||
for(var/turf/simulated/floor/looking_glass/lgt in src)
|
||||
our_turfs += lgt
|
||||
if(lgt.optional)
|
||||
our_optional_turfs += lgt
|
||||
|
||||
/area/looking_glass/Destroy()
|
||||
our_landmark = null
|
||||
our_turfs.Cut()
|
||||
return ..()
|
||||
|
||||
/area/looking_glass/Entered(var/atom/movable/AM)
|
||||
if(isliving(AM))
|
||||
var/mob/living/L = AM
|
||||
if(L.client)
|
||||
our_landmark?.gain_viewer(L.client)
|
||||
|
||||
/area/looking_glass/Exited(var/atom/movable/AM)
|
||||
if(isliving(AM))
|
||||
var/mob/living/L = AM
|
||||
if(L.client)
|
||||
our_landmark?.lose_viewer(L.client)
|
||||
|
||||
/area/looking_glass/proc/begin_program(var/image/newimage)
|
||||
if(!active)
|
||||
for(var/trf in our_turfs)
|
||||
var/turf/simulated/floor/looking_glass/lgt = trf
|
||||
lgt.activate()
|
||||
|
||||
our_landmark.take_image(newimage)
|
||||
active = TRUE
|
||||
|
||||
/area/looking_glass/proc/end_program()
|
||||
if(active)
|
||||
for(var/trf in our_turfs)
|
||||
var/turf/simulated/floor/looking_glass/lgt = trf
|
||||
lgt.deactivate()
|
||||
|
||||
active = FALSE
|
||||
|
||||
spawn(2 SECONDS)
|
||||
our_landmark.drop_image()
|
||||
|
||||
/area/looking_glass/proc/toggle_optional(var/transparent)
|
||||
for(var/trf in our_optional_turfs)
|
||||
var/turf/simulated/floor/looking_glass/lgt = trf
|
||||
lgt.center = !transparent
|
||||
if(active)
|
||||
lgt.deactivate()
|
||||
spawn(3 SECONDS)
|
||||
lgt.activate()
|
||||
|
||||
/area/looking_glass/lg_1
|
||||
name = "looking glass one"
|
||||
lg_id = "one"
|
||||
|
||||
/area/looking_glass/lg_2
|
||||
name = "looking glass two"
|
||||
lg_id = "two"
|
||||
|
||||
/area/looking_glass/lg_3
|
||||
name = "looking glass three"
|
||||
lg_id = "three"
|
||||
@@ -0,0 +1,162 @@
|
||||
/obj/machinery/computer/looking_glass
|
||||
name = "looking glass control"
|
||||
desc = "Controls the looking glass displays in this room. Provided courtesy of KHI."
|
||||
|
||||
icon_keyboard = "tech_key"
|
||||
icon_screen = "holocontrol"
|
||||
|
||||
var/static/list/supported_programs = list()
|
||||
var/static/list/secret_programs = list()
|
||||
|
||||
use_power = USE_POWER_IDLE
|
||||
active_power_usage = 8000
|
||||
|
||||
var/current_program = "Off"
|
||||
var/area/looking_glass/my_area
|
||||
var/last_gravity_change = 0
|
||||
var/ready = TRUE
|
||||
var/immersion = FALSE
|
||||
|
||||
var/lg_id = "change_me"
|
||||
|
||||
/obj/machinery/computer/looking_glass/Initialize()
|
||||
. = ..()
|
||||
for(var/area/looking_glass/lga in world)
|
||||
if(lga.lg_id == lg_id)
|
||||
my_area = lga
|
||||
break
|
||||
if(!istype(my_area))
|
||||
testing("Looking glass console [x],[y],[x] not in a looking glass area.")
|
||||
if(!supported_programs.len)
|
||||
supported_programs["Off"] = null
|
||||
supported_programs["Diagnostics"] = image(icon = 'icons/skybox/skybox.dmi', icon_state = "diagnostic")
|
||||
supported_programs["Space 1"] = image(icon = 'icons/skybox/skybox.dmi', icon_state = "space1")
|
||||
supported_programs["Space 2"] = image(icon = 'icons/skybox/skybox.dmi', icon_state = "space2")
|
||||
supported_programs["Space 3"] = image(icon = 'icons/skybox/skybox.dmi', icon_state = "space3")
|
||||
supported_programs["Space 4"] = image(icon = 'icons/skybox/skybox.dmi', icon_state = "space4")
|
||||
supported_programs["Space 5"] = image(icon = 'icons/skybox/skybox.dmi', icon_state = "space5")
|
||||
supported_programs["Space 6"] = image(icon = 'icons/skybox/skybox.dmi', icon_state = "space6")
|
||||
|
||||
/obj/machinery/computer/looking_glass/Destroy()
|
||||
my_area = null
|
||||
return ..()
|
||||
|
||||
/obj/machinery/computer/looking_glass/attack_ai(var/mob/user as mob)
|
||||
return src.attack_hand(user)
|
||||
|
||||
/obj/machinery/computer/looking_glass/attack_hand(var/mob/user as mob)
|
||||
if(..())
|
||||
return
|
||||
user.set_machine(src)
|
||||
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/computer/looking_glass/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
user.set_machine(src)
|
||||
|
||||
var/list/data = list()
|
||||
var/program_list[0]
|
||||
|
||||
for(var/P in supported_programs)
|
||||
program_list[++program_list.len] = P
|
||||
|
||||
if(emagged)
|
||||
for(var/P in secret_programs)
|
||||
program_list[++program_list.len] = P
|
||||
|
||||
data["supportedPrograms"] = program_list
|
||||
data["currentProgram"] = current_program
|
||||
data["immersion"] = immersion
|
||||
if(my_area?.has_gravity)
|
||||
data["gravity"] = 1
|
||||
else
|
||||
data["gravity"] = null
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "lookingglass.tmpl", src.name, 400, 550)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(20)
|
||||
|
||||
/obj/machinery/computer/looking_glass/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
if((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon)))
|
||||
usr.set_machine(src)
|
||||
|
||||
if(href_list["program"])
|
||||
if(ready)
|
||||
var/prog = href_list["program"]
|
||||
if(prog == "Off")
|
||||
current_program = "Off"
|
||||
unload_program()
|
||||
else if((prog in supported_programs) || (emagged && (prog in secret_programs)))
|
||||
current_program = prog
|
||||
load_program(prog)
|
||||
else
|
||||
visible_message("<span class='warning'>ERROR. Recalibrating displays.</span>")
|
||||
|
||||
else if(href_list["gravity"])
|
||||
toggle_gravity(my_area)
|
||||
|
||||
else if(href_list["immersion"])
|
||||
immersion = !immersion
|
||||
my_area.toggle_optional(immersion)
|
||||
|
||||
src.add_fingerprint(usr)
|
||||
|
||||
SSnanoui.update_uis(src)
|
||||
|
||||
/obj/machinery/computer/looking_glass/emag_act(var/remaining_charges, var/mob/user as mob)
|
||||
if (!emagged)
|
||||
playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1)
|
||||
emagged = 1
|
||||
to_chat(user, "<span class='notice'>You unlock several programs that were hidden somewhere in memory.</span>")
|
||||
log_game("[key_name(usr)] emagged the [name]")
|
||||
return 1
|
||||
return
|
||||
|
||||
/obj/machinery/computer/looking_glass/proc/load_program(var/prog_name)
|
||||
ready = FALSE
|
||||
VARSET_IN(src, ready, TRUE, 10 SECONDS)
|
||||
|
||||
if(prog_name in supported_programs)
|
||||
my_area.begin_program(supported_programs[prog_name])
|
||||
else if(prog_name in secret_programs)
|
||||
my_area.begin_program(secret_programs[prog_name])
|
||||
|
||||
/obj/machinery/computer/looking_glass/proc/unload_program()
|
||||
ready = FALSE
|
||||
VARSET_IN(src, ready, TRUE, 10 SECONDS)
|
||||
|
||||
my_area.end_program()
|
||||
|
||||
/obj/machinery/computer/looking_glass/proc/toggle_gravity(var/area/A)
|
||||
if(world.time < (last_gravity_change + 3 SECONDS))
|
||||
if(world.time < (last_gravity_change + 1 SECOND))
|
||||
return
|
||||
visible_message("<span class='warning'>ERROR. Recalibrating gravity field.</b>")
|
||||
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()
|
||||
@@ -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
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user