mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-02 13:02:38 +00:00
* HARK! THERE ARE SOME MAIDENS THAT NEED SAVING! * claymores, chairs * mapmerge, price increase, no losing the flag, no teleporting in, other small stuff * oldworld language, medieval mutation, reviews * see desc for full changelog huge improvements to how medieval speech feels, CTF now fully lit, json beautified, bugs squashed and more NOTELEPORT exploits also quashed. (I NEED TO UNDO THIS FOR ATOMIZATION) * removes my fixes? also bugfixes and CTF separation * dumb json mistake, starting work on reality simulators * BOWS ARE BROOOOOOOOOOOOOOOOOKEN * br * getting closer to working * well, mostly everything now. * finally ready * removes languages stuff as it is buggy and does not work, fixes more bugs, fixes more bugs, fixes more bugs * conflict fix * linting * more lint * bow buff, speech fix, TON of ctf fixes * oh fuck year * NO MORE INSTA DELETING CREW * whoops * review handled * pooosh * conflict fix
317 lines
9.3 KiB
Plaintext
317 lines
9.3 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.
|
|
*/
|
|
|
|
#define HOLODECK_CD 25
|
|
#define HOLODECK_DMG_CD 500
|
|
|
|
/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
|
|
var/list/emag_programs
|
|
|
|
// 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
|
|
|
|
var/active = FALSE
|
|
var/damaged = FALSE
|
|
var/list/spawned = list()
|
|
var/list/effects = list()
|
|
var/current_cd = 0
|
|
|
|
/obj/machinery/computer/holodeck/Initialize(mapload)
|
|
..()
|
|
return INITIALIZE_HINT_LATELOAD
|
|
|
|
/obj/machinery/computer/holodeck/LateInitialize()
|
|
if(ispath(holodeck_type, /area))
|
|
linked = pop(get_areas(holodeck_type, FALSE))
|
|
if(ispath(offline_program, /area))
|
|
offline_program = pop(get_areas(offline_program), FALSE)
|
|
// the following is necessary for power reasons
|
|
if(!linked || !offline_program)
|
|
log_world("No matching holodeck area found")
|
|
qdel(src)
|
|
return
|
|
var/area/AS = get_area(src)
|
|
if(istype(AS, /area/holodeck))
|
|
log_mapping("Holodeck computer cannot be in a holodeck, This would cause circular power dependency.")
|
|
qdel(src)
|
|
return
|
|
else
|
|
linked.linked = src
|
|
var/area/my_area = get_area(src)
|
|
if(my_area)
|
|
linked.power_usage = my_area.power_usage
|
|
else
|
|
linked.power_usage = new /list(AREA_USAGE_LEN)
|
|
|
|
generate_program_list()
|
|
load_program(offline_program, FALSE, FALSE)
|
|
|
|
/obj/machinery/computer/holodeck/Destroy()
|
|
emergency_shutdown()
|
|
if(linked)
|
|
linked.linked = null
|
|
linked.power_usage = new /list(AREA_USAGE_LEN)
|
|
return ..()
|
|
|
|
/obj/machinery/computer/holodeck/power_change()
|
|
. = ..()
|
|
toggle_power(!machine_stat)
|
|
|
|
/obj/machinery/computer/holodeck/ui_interact(mob/user, datum/tgui/ui)
|
|
ui = SStgui.try_update_ui(user, src, ui)
|
|
if(!ui)
|
|
ui = new(user, src, "Holodeck", name)
|
|
ui.open()
|
|
|
|
/obj/machinery/computer/holodeck/ui_data(mob/user)
|
|
var/list/data = list()
|
|
|
|
data["default_programs"] = program_cache
|
|
if(obj_flags & EMAGGED)
|
|
data["emagged"] = TRUE
|
|
data["emag_programs"] = emag_programs
|
|
data["program"] = program
|
|
data["can_toggle_safety"] = issilicon(user) || isAdminGhostAI(user)
|
|
|
|
return data
|
|
|
|
/obj/machinery/computer/holodeck/ui_act(action, params)
|
|
. = ..()
|
|
if(.)
|
|
return
|
|
. = TRUE
|
|
switch(action)
|
|
if("load_program")
|
|
var/program_to_load = text2path(params["type"])
|
|
if(!ispath(program_to_load))
|
|
return FALSE
|
|
var/valid = FALSE
|
|
var/list/checked = program_cache.Copy()
|
|
if(obj_flags & EMAGGED)
|
|
checked |= emag_programs
|
|
for(var/prog in checked)
|
|
var/list/P = prog
|
|
if(P["type"] == program_to_load)
|
|
valid = TRUE
|
|
break
|
|
if(!valid)
|
|
return FALSE
|
|
|
|
var/area/A = locate(program_to_load) in GLOB.sortedAreas
|
|
if(A)
|
|
load_program(A)
|
|
if("safety")
|
|
if((obj_flags & EMAGGED) && program)
|
|
emergency_shutdown()
|
|
nerf(obj_flags & EMAGGED)
|
|
obj_flags ^= EMAGGED
|
|
say("Safeties restored. Restarting...")
|
|
|
|
/obj/machinery/computer/holodeck/process(delta_time)
|
|
if(damaged && DT_PROB(5, delta_time))
|
|
for(var/turf/T in linked)
|
|
if(DT_PROB(2.5, delta_time))
|
|
do_sparks(2, 1, T)
|
|
return
|
|
|
|
if(!..() || !active)
|
|
return
|
|
|
|
if(!floorcheck())
|
|
emergency_shutdown()
|
|
damaged = TRUE
|
|
for(var/mob/M in urange(10,src))
|
|
M.show_message("The holodeck overloads!")
|
|
|
|
for(var/turf/T in linked)
|
|
if(prob(30))
|
|
do_sparks(2, 1, T)
|
|
SSexplosions.lowturf += T
|
|
T.hotspot_expose(1000,500,1)
|
|
|
|
if(!(obj_flags & EMAGGED))
|
|
for(var/item in spawned)
|
|
if(!(get_turf(item) in linked))
|
|
derez(item, 0)
|
|
for(var/e in effects)
|
|
var/obj/effect/holodeck_effect/HE = e
|
|
HE.tick()
|
|
|
|
active_power_usage = 50 + spawned.len * 3 + effects.len * 5
|
|
|
|
/obj/machinery/computer/holodeck/emag_act(mob/user)
|
|
if(obj_flags & EMAGGED)
|
|
return
|
|
if(!LAZYLEN(emag_programs))
|
|
to_chat(user, "[src] does not seem to have a card swipe port. It must be an inferior model.")
|
|
return
|
|
playsound(src, "sparks", 75, TRUE)
|
|
obj_flags |= EMAGGED
|
|
to_chat(user, "<span class='warning'>You vastly increase projector power and override the safety and security protocols.</span>")
|
|
say("Warning. Automatic shutoff and derezzing protocols have been corrupted. Please call Nanotrasen maintenance and do not use the simulator.")
|
|
log_game("[key_name(user)] emagged the Holodeck Control Console")
|
|
nerf(!(obj_flags & EMAGGED))
|
|
|
|
/obj/machinery/computer/holodeck/emp_act(severity)
|
|
. = ..()
|
|
if(. & EMP_PROTECT_SELF)
|
|
return
|
|
emergency_shutdown()
|
|
|
|
/obj/machinery/computer/holodeck/ex_act(severity, target)
|
|
emergency_shutdown()
|
|
return ..()
|
|
|
|
/obj/machinery/computer/holodeck/blob_act(obj/structure/blob/B)
|
|
emergency_shutdown()
|
|
return ..()
|
|
|
|
/obj/machinery/computer/holodeck/proc/generate_program_list()
|
|
for(var/typekey in subtypesof(program_type))
|
|
var/area/holodeck/A = GLOB.areas_by_type[typekey]
|
|
if(!A || !A.contents.len)
|
|
continue
|
|
var/list/info_this = list()
|
|
info_this["name"] = A.name
|
|
info_this["type"] = A.type
|
|
if(A.restricted)
|
|
LAZYADD(emag_programs, list(info_this))
|
|
else
|
|
LAZYADD(program_cache, list(info_this))
|
|
|
|
/obj/machinery/computer/holodeck/proc/toggle_power(toggleOn = FALSE)
|
|
if(active == toggleOn)
|
|
return
|
|
|
|
if(toggleOn)
|
|
if(last_program && last_program != offline_program)
|
|
addtimer(CALLBACK(src, .proc/load_program, last_program, TRUE), 25)
|
|
active = TRUE
|
|
else
|
|
last_program = program
|
|
load_program(offline_program, TRUE)
|
|
active = FALSE
|
|
|
|
/obj/machinery/computer/holodeck/proc/emergency_shutdown()
|
|
last_program = program
|
|
load_program(offline_program, TRUE)
|
|
active = FALSE
|
|
|
|
/obj/machinery/computer/holodeck/proc/floorcheck()
|
|
for(var/turf/T in linked)
|
|
if(!T.intact || isspaceturf(T))
|
|
return FALSE
|
|
return TRUE
|
|
|
|
/obj/machinery/computer/holodeck/proc/nerf(active)
|
|
for(var/obj/item/I in spawned)
|
|
I.damtype = active ? STAMINA : initial(I.damtype)
|
|
for(var/e in effects)
|
|
var/obj/effect/holodeck_effect/HE = e
|
|
HE.safety(active)
|
|
|
|
/obj/machinery/computer/holodeck/proc/load_program(area/A, force = FALSE, add_delay = TRUE)
|
|
if(!is_operational)
|
|
A = offline_program
|
|
force = TRUE
|
|
|
|
if(program == A)
|
|
return
|
|
if(current_cd > world.time && !force)
|
|
say("ERROR. Recalibrating projection apparatus.")
|
|
return
|
|
if(add_delay)
|
|
current_cd = world.time + HOLODECK_CD
|
|
if(damaged)
|
|
current_cd += HOLODECK_DMG_CD
|
|
active = (A != offline_program)
|
|
use_power = active + IDLE_POWER_USE
|
|
|
|
for(var/e in effects)
|
|
var/obj/effect/holodeck_effect/HE = e
|
|
HE.deactivate(src)
|
|
|
|
for(var/item in spawned)
|
|
derez(item, !force)
|
|
|
|
program = A
|
|
// note nerfing does not yet work on guns, should
|
|
// should also remove/limit/filter reagents?
|
|
// this is an exercise left to others I'm afraid. -Sayu
|
|
spawned = A.copy_contents_to(linked, 1, nerf_weapons = !(obj_flags & EMAGGED))
|
|
for(var/obj/machinery/M in spawned)
|
|
M.flags_1 |= NODECONSTRUCT_1
|
|
for(var/obj/structure/S in spawned)
|
|
S.flags_1 |= NODECONSTRUCT_1
|
|
effects = list()
|
|
|
|
addtimer(CALLBACK(src, .proc/finish_spawn), 30)
|
|
|
|
/obj/machinery/computer/holodeck/proc/finish_spawn()
|
|
var/list/added = list()
|
|
for(var/obj/effect/holodeck_effect/HE in spawned)
|
|
effects += HE
|
|
spawned -= HE
|
|
var/atom/x = HE.activate(src)
|
|
if(istype(x) || islist(x))
|
|
spawned += x // holocarp are not forever
|
|
added += x
|
|
for(var/obj/machinery/M in added)
|
|
M.flags_1 |= NODECONSTRUCT_1
|
|
for(var/obj/structure/S in added)
|
|
S.flags_1 |= NODECONSTRUCT_1
|
|
if(istype(program, /area/holodeck/rec_center/thunderdome1218) && !SSshuttle.shuttle_purchase_requirements_met[SHUTTLE_UNLOCK_MEDISIM])
|
|
say("Special note from \"1218 AD\" developer: I see you too are interested in the REAL dark ages of humanity! I've made this program also unlock some interesting shuttle designs on any communication console around. Have fun!")
|
|
SSshuttle.shuttle_purchase_requirements_met[SHUTTLE_UNLOCK_MEDISIM] = TRUE
|
|
|
|
/obj/machinery/computer/holodeck/proc/derez(obj/O, silent = TRUE, forced = FALSE)
|
|
// Emagging a machine creates an anomaly in the derez systems.
|
|
if(O && (obj_flags & EMAGGED) && !machine_stat && !forced)
|
|
if((ismob(O) || ismob(O.loc)) && prob(50))
|
|
addtimer(CALLBACK(src, .proc/derez, O, silent), 50) // may last a disturbingly long time
|
|
return
|
|
|
|
spawned -= O
|
|
if(!O)
|
|
return
|
|
var/turf/T = get_turf(O)
|
|
for(var/atom/movable/AM in O) // these should be derezed if they were generated
|
|
AM.forceMove(T)
|
|
if(ismob(AM))
|
|
silent = FALSE // otherwise make sure they are dropped
|
|
|
|
if(!silent)
|
|
visible_message("<span class='notice'>[O] fades away!</span>")
|
|
qdel(O)
|
|
|
|
#undef HOLODECK_CD
|
|
#undef HOLODECK_DMG_CD
|