var/global/list/holodeck_programs = list(
"emptycourt" = /area/holodeck/source_emptycourt, \
"boxingcourt" = /area/holodeck/source_boxingcourt, \
"basketball" = /area/holodeck/source_basketball, \
"thunderdomecourt" = /area/holodeck/source_thunderdomecourt, \
"beach" = /area/holodeck/source_beach, \
"desert" = /area/holodeck/source_desert, \
"space" = /area/holodeck/source_space, \
"picnicarea" = /area/holodeck/source_picnicarea, \
"snowfield" = /area/holodeck/source_snowfield, \
"theatre" = /area/holodeck/source_theatre, \
"meetinghall" = /area/holodeck/source_meetinghall, \
"courtroom" = /area/holodeck/source_courtroom, \
"burntest" = /area/holodeck/source_burntest, \
"wildlifecarp" = /area/holodeck/source_wildlife, \
"turnoff" = /area/holodeck/source_plating \
)
/obj/machinery/computer/HolodeckControl
name = "holodeck control console"
desc = "A computer used to control a nearby holodeck."
icon_state = "holocontrol"
use_power = 1
active_power_usage = 8000 //8kW for the scenery + 500W per holoitem
var/item_power_usage = 500
var/area/linkedholodeck = null
var/area/target = null
var/active = 0
var/list/holographic_items = list()
var/list/holographic_mobs = list()
var/damaged = 0
var/safety_disabled = 0
var/mob/last_to_emag = null
var/last_change = 0
var/last_gravity_change = 0
var/list/supported_programs = list( \
"Empty Court" = "emptycourt", \
"Basketball Court" = "basketball", \
"Thunderdome Court" = "thunderdomecourt", \
"Boxing Ring"="boxingcourt", \
"Beach" = "beach", \
"Desert" = "desert", \
"Space" = "space", \
"Picnic Area" = "picnicarea", \
"Snow Field" = "snowfield", \
"Theatre" = "theatre", \
"Meeting Hall" = "meetinghall", \
"Courtroom" = "courtroom" \
)
var/list/restricted_programs = list("Atmospheric Burn Simulation" = "burntest", "Wildlife Simulation" = "wildlifecarp")
/obj/machinery/computer/HolodeckControl/attack_ai(var/mob/user as mob)
return src.attack_hand(user)
/obj/machinery/computer/HolodeckControl/attack_hand(var/mob/user as mob)
if(..())
return
user.set_machine(src)
var/dat
dat += "Holodeck Control System
"
dat += "
Current Loaded Programs:
"
for(var/prog in supported_programs)
dat += "([prog])
"
dat += "
"
dat += "(Turn Off)
"
dat += "
"
dat += "Please ensure that only holographic weapons are used in the holodeck if a combat simulation has been loaded.
"
if(issilicon(user))
dat += "
"
if(safety_disabled)
if (emagged)
dat += "ERROR: Cannot re-enable Safety Protocols.
"
else
dat += "(Re-Enable Safety Protocols?)
"
else
dat += "(Override Safety Protocols?)
"
dat += "
"
if(safety_disabled)
for(var/prog in restricted_programs)
dat += "(Begin [prog])
"
dat += "Ensure the holodeck is empty before testing.
"
dat += "
"
dat += "Safety Protocols are DISABLED
"
else
dat += "Safety Protocols are ENABLED
"
if(linkedholodeck.has_gravity)
dat += "Gravity is (ON)
"
else
dat += "Gravity is (OFF)
"
user << browse(dat, "window=computer;size=400x500")
onclose(user, "computer")
return
/obj/machinery/computer/HolodeckControl/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"])
var/prog = href_list["program"]
if(prog in holodeck_programs)
target = locate(holodeck_programs[prog])
if(target)
loadProgram(target)
else if(href_list["AIoverride"])
if(!issilicon(usr))
return
if(safety_disabled && emagged)
return //if a traitor has gone through the trouble to emag the thing, let them keep it.
safety_disabled = !safety_disabled
update_projections()
if(safety_disabled)
message_admins("[key_name_admin(usr)] overrode the holodeck's safeties")
log_game("[key_name(usr)] overrided the holodeck's safeties")
else
message_admins("[key_name_admin(usr)] restored the holodeck's safeties")
log_game("[key_name(usr)] restored the holodeck's safeties")
else if(href_list["gravity"])
toggleGravity(linkedholodeck)
src.add_fingerprint(usr)
src.updateUsrDialog()
return
/obj/machinery/computer/HolodeckControl/attackby(var/obj/item/weapon/D as obj, var/mob/user as mob)
if(istype(D, /obj/item/weapon/card/emag))
playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1)
last_to_emag = user //emag again to change the owner
if (!emagged)
emagged = 1
safety_disabled = 1
update_projections()
user << "You vastly increase projector power and override the safety and security protocols."
user << "Warning. Automatic shutoff and derezing protocols have been corrupted. Please call Nanotrasen maintenance and do not use the simulator."
log_game("[key_name(usr)] emagged the Holodeck Control Computer")
src.updateUsrDialog()
return
/obj/machinery/computer/HolodeckControl/proc/update_projections()
if (safety_disabled)
item_power_usage = 2500
for(var/obj/item/weapon/holo/esword/H in linkedholodeck)
H.damtype = BRUTE
else
item_power_usage = initial(item_power_usage)
for(var/obj/item/weapon/holo/esword/H in linkedholodeck)
H.damtype = initial(H.damtype)
for(var/mob/living/simple_animal/hostile/carp/holodeck/C in holographic_mobs)
C.set_safety(!safety_disabled)
if (last_to_emag)
C.friends = list(last_to_emag)
/obj/machinery/computer/HolodeckControl/New()
..()
linkedholodeck = locate(/area/holodeck/alphadeck)
//if(linkedholodeck)
// target = locate(/area/holodeck/source_emptycourt)
// if(target)
// loadProgram(target)
//This could all be done better, but it works for now.
/obj/machinery/computer/HolodeckControl/Del()
emergencyShutdown()
..()
/obj/machinery/computer/HolodeckControl/meteorhit(var/obj/O as obj)
emergencyShutdown()
..()
/obj/machinery/computer/HolodeckControl/emp_act(severity)
emergencyShutdown()
..()
/obj/machinery/computer/HolodeckControl/ex_act(severity)
emergencyShutdown()
..()
/obj/machinery/computer/HolodeckControl/blob_act()
emergencyShutdown()
..()
/obj/machinery/computer/HolodeckControl/power_change()
var/oldstat
..()
if (stat != oldstat && active && (stat & NOPOWER))
emergencyShutdown()
/obj/machinery/computer/HolodeckControl/process()
for(var/item in holographic_items) // do this first, to make sure people don't take items out when power is down.
if(!(get_turf(item) in linkedholodeck))
derez(item, 0)
if (!safety_disabled)
for(var/mob/living/simple_animal/hostile/carp/holodeck/C in holographic_mobs)
if (get_area(C.loc) != linkedholodeck)
holographic_mobs -= C
C.derez()
if(!..())
return
if(active)
use_power(item_power_usage * (holographic_items.len + holographic_mobs.len))
if(!checkInteg(linkedholodeck))
damaged = 1
target = locate(/area/holodeck/source_plating)
if(target)
loadProgram(target)
active = 0
use_power = 1
for(var/mob/M in range(10,src))
M.show_message("The holodeck overloads!")
for(var/turf/T in linkedholodeck)
if(prob(30))
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(2, 1, T)
s.start()
T.ex_act(3)
T.hotspot_expose(1000,500,1)
/obj/machinery/computer/HolodeckControl/proc/derez(var/obj/obj , var/silent = 1)
holographic_items.Remove(obj)
if(obj == null)
return
if(isobj(obj))
var/mob/M = obj.loc
if(ismob(M))
M.u_equip(obj)
M.update_icons() //so their overlays update
if(!silent)
var/obj/oldobj = obj
visible_message("The [oldobj.name] fades away!")
del(obj)
/obj/machinery/computer/HolodeckControl/proc/checkInteg(var/area/A)
for(var/turf/T in A)
if(istype(T, /turf/space))
return 0
return 1
//Why is it called toggle if it doesn't toggle?
/obj/machinery/computer/HolodeckControl/proc/togglePower(var/toggleOn = 0)
if(toggleOn)
var/area/targetsource = locate(/area/holodeck/source_emptycourt)
holographic_items = targetsource.copy_contents_to(linkedholodeck)
spawn(30)
for(var/obj/effect/landmark/L in linkedholodeck)
if(L.name=="Atmospheric Test Start")
spawn(20)
var/turf/T = get_turf(L)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(2, 1, T)
s.start()
if(T)
T.temperature = 5000
T.hotspot_expose(50000,50000,1)
active = 1
use_power = 2
else
for(var/item in holographic_items)
derez(item)
if(!linkedholodeck.has_gravity)
linkedholodeck.gravitychange(1,linkedholodeck)
var/area/targetsource = locate(/area/holodeck/source_plating)
targetsource.copy_contents_to(linkedholodeck , 1)
active = 0
use_power = 1
/obj/machinery/computer/HolodeckControl/proc/loadProgram(var/area/A)
if(world.time < (last_change + 25))
if(world.time < (last_change + 15))//To prevent super-spam clicking, reduced process size and annoyance -Sieve
return
for(var/mob/M in range(3,src))
M.show_message("\b ERROR. Recalibrating projection apparatus.")
last_change = world.time
return
last_change = world.time
active = 1
use_power = 2
for(var/item in holographic_items)
derez(item)
for(var/mob/living/simple_animal/hostile/carp/holodeck/C in holographic_mobs)
holographic_mobs -= C
C.derez()
for(var/obj/effect/decal/cleanable/blood/B in linkedholodeck)
del(B)
holographic_items = A.copy_contents_to(linkedholodeck , 1)
spawn(30)
for(var/obj/effect/landmark/L in linkedholodeck)
if(L.name=="Atmospheric Test Start")
spawn(20)
var/turf/T = get_turf(L)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(2, 1, T)
s.start()
if(T)
T.temperature = 5000
T.hotspot_expose(50000,50000,1)
if(L.name=="Holocarp Spawn")
holographic_mobs += new /mob/living/simple_animal/hostile/carp/holodeck(L.loc)
if(L.name=="Holocarp Spawn Random")
if (prob(4)) //With 4 spawn points, carp should only appear 15% of the time.
holographic_mobs += new /mob/living/simple_animal/hostile/carp/holodeck(L.loc)
update_projections()
/obj/machinery/computer/HolodeckControl/proc/toggleGravity(var/area/A)
if(world.time < (last_gravity_change + 25))
if(world.time < (last_gravity_change + 15))//To prevent super-spam clicking
return
for(var/mob/M in range(3,src))
M.show_message("\b ERROR. Recalibrating gravity field.")
last_change = world.time
return
last_gravity_change = world.time
active = 1
use_power = 1
if(A.has_gravity)
A.gravitychange(0,A)
else
A.gravitychange(1,A)
/obj/machinery/computer/HolodeckControl/proc/emergencyShutdown()
//Get rid of any items
for(var/item in holographic_items)
derez(item)
for(var/mob/living/simple_animal/hostile/carp/holodeck/C in holographic_mobs)
holographic_mobs -= C
C.derez()
//Turn it back to the regular non-holographic room
target = locate(/area/holodeck/source_plating)
if(target)
loadProgram(target)
if(!linkedholodeck.has_gravity)
linkedholodeck.gravitychange(1,linkedholodeck)
var/area/targetsource = locate(/area/holodeck/source_plating)
targetsource.copy_contents_to(linkedholodeck , 1)
active = 0
use_power = 1