Files
Bubberstation/code/modules/holodeck/computer.dm
Vincent faf5ddaceb Holodeck refactor and Enchancements
Moves holodeck code to modules/holodeck.  Repaths holodeck structures a little.  Cleans holodeck code and prepares for additional features (multiple holodecks, etc).  Should fix #4828.

Necessary map bugfixen for Asteroid, Disc, Dream, Meta, and TG.
Adds Lounge, Emergency Medical, pet center, and holdout room to the rec holodeck.

All items spawned by the holodeck will do only stamina damage, except when emagged.  This allows emergency medical to be staffed with scalpels and bonesaws and such.  Emergency medical has some functioning equipment but the only drugs available are in the sleeper.
2015-11-15 20:23:23 -05:00

210 lines
6.4 KiB
Plaintext

/*
Holodeck Update
The on-station holodeck area is of type [holodeck_type].
All subtypes of [program_type] are loaded into the program cache or emag programs list.
If init_program is null, a random program will be loaded on startup.
If you don't wish this, set it to the offline program or another of your choosing.
You can use this to add holodecks with minimal code:
1) Define new areas for the holodeck programs
2) Map them
3) Create a new control console that uses those areas
Non-mapped areas should be skipped but you should probably comment them out anyway.
The base of program_type will always be ignored; only subtypes will be loaded.
*/
/obj/machinery/computer/holodeck
name = "holodeck control console"
desc = "A computer used to control a nearby holodeck."
icon_screen = "holocontrol"
idle_power_usage = 10
active_power_usage = 50
var/area/holodeck/linked
var/area/holodeck/program
var/area/holodeck/last_program
var/area/offline_program = /area/holodeck/rec_center/offline
var/list/program_cache = list()
var/list/emag_programs = list()
// Splitting this up allows two holodecks of the same size
// to use the same source patterns. Y'know, if you want to.
var/holodeck_type = /area/holodeck/rec_center // locate(this) to get the target holodeck
var/program_type = /area/holodeck/rec_center // subtypes of this (but not this itself) are loadable programs
// set this if you want it to start with some particular program.
var/init_program = null
// or this to get anything
var/random_program = 0
var/active = 0
var/damaged = 0
var/list/spawned = list()
var/list/effects = list()
var/last_change = 0
/obj/machinery/computer/holodeck/New()
if(ispath(holodeck_type,/area))
linked = locate(holodeck_type)
if(ispath(offline_program,/area))
offline_program = locate(offline_program)
// the following is necessary for power reasons
var/area/AS = get_area(src)
if(istype(AS,/area/holodeck))
world.log << "### MAPPING ERROR"
world.log << "Holodeck computer cannot be in a holodeck."
world.log << "This would cause circular power dependency."
qdel(src) // todo handle constructed computers
return
else
linked.linked = src // todo detect multiple/constructed computers
if(ticker && ticker.current_state >= GAME_STATE_PLAYING)
initialize()
..()
/obj/machinery/computer/holodeck/initialize()
program_cache = list()
emag_programs = list()
for(var/typekey in typesof(program_type) - program_type)
var/area/holodeck/A = locate(typekey)
if(!A || A == offline_program) continue
if(A.contents.len == 0) continue // not loaded
if(A.restricted)
emag_programs += A
else
program_cache += A
if(typekey == init_program)
load_program(A,force=1)
if(random_program && program_cache.len && init_program == null)
load_program(pick(program_cache),force=1)
else if(!program)
load_program(offline_program)
/obj/machinery/computer/holodeck/power_change()
..()
toggle_power(!stat)
/obj/machinery/computer/holodeck/proc/toggle_power(toggleOn = 0)
if(active == toggleOn) return
if(toggleOn)
if(last_program && last_program != offline_program)
load_program(last_program, delay = 1)
active = 1
else
last_program = program
load_program(offline_program,force=1)
active = 0
/obj/machinery/computer/holodeck/proc/emergency_shutdown()
last_program = program
load_program(offline_program,1)
active = 0
/obj/machinery/computer/holodeck/process()
if(damaged)
if(prob(10))
for(var/turf/simulated/T in linked)
if(prob(5))
var/datum/effect_system/spark_spread/s = new
s.set_up(2, 1, T)
s.start()
return
if(!..() || !active)
return
if(!floorcheck())
emergency_shutdown()
damaged = 1
for(var/mob/M in ultra_range(10,src))
M.show_message("The holodeck overloads!")
for(var/turf/T in linked)
if(prob(30))
var/datum/effect_system/spark_spread/s = new
s.set_up(2, 1, T)
s.start()
T.ex_act(3)
T.hotspot_expose(1000,500,1)
if(!emagged)
for(var/item in spawned)
if(!(get_turf(item) in linked))
derez(item, 0)
for(var/obj/effect/holodeck_effect/HE in effects)
HE.tick()
active_power_usage = 50 + spawned.len * 3 + effects.len * 5
/obj/machinery/computer/holodeck/proc/floorcheck()
for(var/turf/T in linked)
if(!T.intact || istype(T,/turf/space))
return 0
return 1
/obj/machinery/computer/holodeck/Topic(href, list/href_list)
if(..())
return
if(Adjacent(usr) || istype(usr, /mob/living/silicon))
usr.set_machine(src)
src.add_fingerprint(usr)
if(href_list["loadarea"])
var/typepath = text2path(href_list["loadarea"])
if(ispath(typepath,/area))
var/area/target = locate(typepath)
if(istype(target))
load_program(target)
else
world.log << "area not ready: [typepath]"
else
world.log << "bad area argument: [href_list["loadarea"]]"
else if("safety" in href_list)
var/oe = emagged
emagged = !text2num(href_list["safety"])
if(oe == emagged) return
if(program && !stat)
if(!emagged && program.restricted)
load_program(offline_program)
else
nerf(!emagged)
src.updateUsrDialog()
/obj/machinery/computer/holodeck/proc/nerf(active)
for(var/obj/item/I in spawned)
I.damtype = (active? STAMINA : initial(I.damtype) )
for(var/obj/effect/holodeck_effect/HE in effects)
HE.safety(active)
/obj/machinery/computer/holodeck/emag_act(mob/user as mob)
if(!emagged)
if(!emag_programs.len)
user << "[src] does not seem to have a card swipe port. It must be an inferior model."
return
playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1)
emagged = 1
user << "<span class='warning'>You vastly increase projector power and override the safety and security protocols.</span>"
user << "Warning. Automatic shutoff and derezing protocols have been corrupted. Please call Nanotrasen maintenance and do not use the simulator."
log_game("[key_name(user)] emagged the Holodeck Control Console")
src.updateUsrDialog()
nerf(!emagged)
/obj/machinery/computer/holodeck/Destroy()
emergency_shutdown()
..()
/obj/machinery/computer/holodeck/emp_act(severity)
emergency_shutdown()
..()
/obj/machinery/computer/holodeck/ex_act(severity, target)
emergency_shutdown()
..()
/obj/machinery/computer/holodeck/blob_act()
emergency_shutdown()
..()