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