mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-10 00:43:14 +00:00
removes materials list from items, uses custom_materials instead. This might introduce some bugs so we should testmerge this for a while (and Ill test stuff locally as much as I can) this also adds material crafting to sheets. Test case being chairs. In the future we can add stuff like tables, walls, doors etc. also applies materials to everything, with fixes, which can close #46299
414 lines
12 KiB
Plaintext
414 lines
12 KiB
Plaintext
#define HOLOPAD_MAX_DIAL_TIME 200
|
|
|
|
#define HOLORECORD_DELAY "delay"
|
|
#define HOLORECORD_SAY "say"
|
|
#define HOLORECORD_SOUND "sound"
|
|
#define HOLORECORD_LANGUAGE "lang"
|
|
#define HOLORECORD_PRESET "preset"
|
|
#define HOLORECORD_RENAME "rename"
|
|
|
|
#define HOLORECORD_MAX_LENGTH 200
|
|
|
|
/mob/camera/aiEye/remote/holo/setLoc()
|
|
. = ..()
|
|
var/obj/machinery/holopad/H = origin
|
|
H?.move_hologram(eye_user, loc)
|
|
|
|
/obj/machinery/holopad/remove_eye_control(mob/living/user)
|
|
if(user.client)
|
|
user.reset_perspective(null)
|
|
user.remote_control = null
|
|
|
|
//this datum manages it's own references
|
|
|
|
/datum/holocall
|
|
var/mob/living/user //the one that called
|
|
var/obj/machinery/holopad/calling_holopad //the one that sent the call
|
|
var/obj/machinery/holopad/connected_holopad //the one that answered the call (may be null)
|
|
var/list/dialed_holopads //all things called, will be cleared out to just connected_holopad once answered
|
|
|
|
var/mob/camera/aiEye/remote/holo/eye //user's eye, once connected
|
|
var/obj/effect/overlay/holo_pad_hologram/hologram //user's hologram, once connected
|
|
var/datum/action/innate/end_holocall/hangup //hangup action
|
|
|
|
var/call_start_time
|
|
|
|
//creates a holocall made by `caller` from `calling_pad` to `callees`
|
|
/datum/holocall/New(mob/living/caller, obj/machinery/holopad/calling_pad, list/callees)
|
|
call_start_time = world.time
|
|
user = caller
|
|
calling_pad.outgoing_call = src
|
|
calling_holopad = calling_pad
|
|
dialed_holopads = list()
|
|
|
|
for(var/I in callees)
|
|
var/obj/machinery/holopad/H = I
|
|
if(!QDELETED(H) && H.is_operational())
|
|
dialed_holopads += H
|
|
H.say("Incoming call.")
|
|
LAZYADD(H.holo_calls, src)
|
|
|
|
if(!dialed_holopads.len)
|
|
calling_pad.say("Connection failure.")
|
|
qdel(src)
|
|
return
|
|
|
|
testing("Holocall started")
|
|
|
|
//cleans up ALL references :)
|
|
/datum/holocall/Destroy()
|
|
QDEL_NULL(hangup)
|
|
|
|
if(!QDELETED(eye))
|
|
QDEL_NULL(eye)
|
|
|
|
if(connected_holopad && !QDELETED(hologram))
|
|
hologram = null
|
|
connected_holopad.clear_holo(user)
|
|
|
|
user = null
|
|
|
|
//Hologram survived holopad destro
|
|
if(!QDELETED(hologram))
|
|
hologram.HC = null
|
|
QDEL_NULL(hologram)
|
|
|
|
for(var/I in dialed_holopads)
|
|
var/obj/machinery/holopad/H = I
|
|
LAZYREMOVE(H.holo_calls, src)
|
|
dialed_holopads.Cut()
|
|
|
|
if(calling_holopad)
|
|
calling_holopad.outgoing_call = null
|
|
calling_holopad.SetLightsAndPower()
|
|
calling_holopad = null
|
|
if(connected_holopad)
|
|
connected_holopad.SetLightsAndPower()
|
|
connected_holopad = null
|
|
|
|
testing("Holocall destroyed")
|
|
|
|
return ..()
|
|
|
|
//Gracefully disconnects a holopad `H` from a call. Pads not in the call are ignored. Notifies participants of the disconnection
|
|
/datum/holocall/proc/Disconnect(obj/machinery/holopad/H)
|
|
testing("Holocall disconnect")
|
|
if(H == connected_holopad)
|
|
var/area/A = get_area(connected_holopad)
|
|
calling_holopad.say("[A] holopad disconnected.")
|
|
else if(H == calling_holopad && connected_holopad)
|
|
connected_holopad.say("[user] disconnected.")
|
|
|
|
ConnectionFailure(H, TRUE)
|
|
|
|
//Forcefully disconnects a holopad `H` from a call. Pads not in the call are ignored.
|
|
/datum/holocall/proc/ConnectionFailure(obj/machinery/holopad/H, graceful = FALSE)
|
|
testing("Holocall connection failure: graceful [graceful]")
|
|
if(H == connected_holopad || H == calling_holopad)
|
|
if(!graceful && H != calling_holopad)
|
|
calling_holopad.say("Connection failure.")
|
|
qdel(src)
|
|
return
|
|
|
|
LAZYREMOVE(H.holo_calls, src)
|
|
dialed_holopads -= H
|
|
if(!dialed_holopads.len)
|
|
if(graceful)
|
|
calling_holopad.say("Call rejected.")
|
|
testing("No recipients, terminating")
|
|
qdel(src)
|
|
|
|
//Answers a call made to a holopad `H` which cannot be the calling holopad. Pads not in the call are ignored
|
|
/datum/holocall/proc/Answer(obj/machinery/holopad/H)
|
|
testing("Holocall answer")
|
|
if(H == calling_holopad)
|
|
CRASH("How cute, a holopad tried to answer itself.")
|
|
|
|
if(!(H in dialed_holopads))
|
|
return
|
|
|
|
if(connected_holopad)
|
|
CRASH("Multi-connection holocall")
|
|
|
|
for(var/I in dialed_holopads)
|
|
if(I == H)
|
|
continue
|
|
Disconnect(I)
|
|
|
|
for(var/I in H.holo_calls)
|
|
var/datum/holocall/HC = I
|
|
if(HC != src)
|
|
HC.Disconnect(H)
|
|
|
|
connected_holopad = H
|
|
|
|
if(!Check())
|
|
return
|
|
|
|
hologram = H.activate_holo(user)
|
|
hologram.HC = src
|
|
|
|
//eyeobj code is horrid, this is the best copypasta I could make
|
|
eye = new
|
|
eye.origin = H
|
|
eye.eye_initialized = TRUE
|
|
eye.eye_user = user
|
|
eye.name = "Camera Eye ([user.name])"
|
|
user.remote_control = eye
|
|
user.reset_perspective(eye)
|
|
eye.setLoc(H.loc)
|
|
|
|
hangup = new(eye, src)
|
|
hangup.Grant(user)
|
|
|
|
//Checks the validity of a holocall and qdels itself if it's not. Returns TRUE if valid, FALSE otherwise
|
|
/datum/holocall/proc/Check()
|
|
for(var/I in dialed_holopads)
|
|
var/obj/machinery/holopad/H = I
|
|
if(!H.is_operational())
|
|
ConnectionFailure(H)
|
|
|
|
if(QDELETED(src))
|
|
return FALSE
|
|
|
|
. = !QDELETED(user) && !user.incapacitated() && !QDELETED(calling_holopad) && calling_holopad.is_operational() && user.loc == calling_holopad.loc
|
|
|
|
if(.)
|
|
if(!connected_holopad)
|
|
. = world.time < (call_start_time + HOLOPAD_MAX_DIAL_TIME)
|
|
if(!.)
|
|
calling_holopad.say("No answer received.")
|
|
calling_holopad.temp = ""
|
|
|
|
if(!.)
|
|
testing("Holocall Check fail")
|
|
qdel(src)
|
|
|
|
/datum/action/innate/end_holocall
|
|
name = "End Holocall"
|
|
icon_icon = 'icons/mob/actions/actions_silicon.dmi'
|
|
button_icon_state = "camera_off"
|
|
var/datum/holocall/hcall
|
|
|
|
/datum/action/innate/end_holocall/New(Target, datum/holocall/HC)
|
|
..()
|
|
hcall = HC
|
|
|
|
/datum/action/innate/end_holocall/Activate()
|
|
hcall.Disconnect(hcall.calling_holopad)
|
|
|
|
|
|
//RECORDS
|
|
/datum/holorecord
|
|
var/caller_name = "Unknown" //Caller name
|
|
var/image/caller_image
|
|
var/list/entries = list()
|
|
var/language = /datum/language/common //Initial language, can be changed by HOLORECORD_LANGUAGE entries
|
|
|
|
/datum/holorecord/proc/set_caller_image(mob/user)
|
|
var/olddir = user.dir
|
|
user.setDir(SOUTH)
|
|
caller_image = image(user)
|
|
user.setDir(olddir)
|
|
|
|
/obj/item/disk/holodisk
|
|
name = "holorecord disk"
|
|
desc = "Stores recorder holocalls."
|
|
icon_state = "holodisk"
|
|
obj_flags = UNIQUE_RENAME
|
|
custom_materials = list(/datum/material/iron = 100, /datum/material/glass = 100)
|
|
var/datum/holorecord/record
|
|
//Preset variables
|
|
var/preset_image_type
|
|
var/preset_record_text
|
|
|
|
/obj/item/disk/holodisk/Initialize(mapload)
|
|
. = ..()
|
|
if(preset_record_text)
|
|
build_record()
|
|
|
|
/obj/item/disk/holodisk/Destroy()
|
|
QDEL_NULL(record)
|
|
return ..()
|
|
|
|
/obj/item/disk/holodisk/attackby(obj/item/W, mob/user, params)
|
|
if(istype(W, /obj/item/disk/holodisk))
|
|
var/obj/item/disk/holodisk/holodiskOriginal = W
|
|
if (holodiskOriginal.record)
|
|
if (!record)
|
|
record = new
|
|
record.caller_name = holodiskOriginal.record.caller_name
|
|
record.caller_image = holodiskOriginal.record.caller_image
|
|
record.entries = holodiskOriginal.record.entries.Copy()
|
|
record.language = holodiskOriginal.record.language
|
|
to_chat(user, "You copy the record from [holodiskOriginal] to [src] by connecting the ports!")
|
|
name = holodiskOriginal.name
|
|
else
|
|
to_chat(user, "[holodiskOriginal] has no record on it!")
|
|
..()
|
|
|
|
/obj/item/disk/holodisk/proc/build_record()
|
|
record = new
|
|
var/list/lines = splittext(preset_record_text,"\n")
|
|
for(var/line in lines)
|
|
var/prepared_line = trim(line)
|
|
if(!length(prepared_line))
|
|
continue
|
|
var/splitpoint = findtext(prepared_line," ")
|
|
if(!splitpoint)
|
|
continue
|
|
var/command = copytext(prepared_line,1,splitpoint)
|
|
var/value = copytext(prepared_line,splitpoint+1)
|
|
switch(command)
|
|
if("DELAY")
|
|
var/delay_value = text2num(value)
|
|
if(!delay_value)
|
|
continue
|
|
record.entries += list(list(HOLORECORD_DELAY,delay_value))
|
|
if("NAME")
|
|
if(!record.caller_name)
|
|
record.caller_name = value
|
|
else
|
|
record.entries += list(list(HOLORECORD_RENAME,value))
|
|
if("SAY")
|
|
record.entries += list(list(HOLORECORD_SAY,value))
|
|
if("SOUND")
|
|
record.entries += list(list(HOLORECORD_SOUND,value))
|
|
if("LANGUAGE")
|
|
var/lang_type = text2path(value)
|
|
if(ispath(lang_type,/datum/language))
|
|
record.entries += list(list(HOLORECORD_LANGUAGE,lang_type))
|
|
if("PRESET")
|
|
var/preset_type = text2path(value)
|
|
if(ispath(preset_type,/datum/preset_holoimage))
|
|
record.entries += list(list(HOLORECORD_PRESET,preset_type))
|
|
if(!preset_image_type)
|
|
record.caller_image = image('icons/mob/animal.dmi',"old")
|
|
else
|
|
var/datum/preset_holoimage/H = new preset_image_type
|
|
record.caller_image = H.build_image()
|
|
|
|
//These build caller image from outfit and some additional data, for use by mappers for ruin holorecords
|
|
/datum/preset_holoimage
|
|
var/nonhuman_mobtype //Fill this if you just want something nonhuman
|
|
var/outfit_type
|
|
var/species_type = /datum/species/human
|
|
|
|
/datum/preset_holoimage/proc/build_image()
|
|
if(nonhuman_mobtype)
|
|
var/mob/living/L = nonhuman_mobtype
|
|
. = image(initial(L.icon),initial(L.icon_state))
|
|
else
|
|
var/mob/living/carbon/human/dummy/mannequin = generate_or_wait_for_human_dummy("HOLODISK_PRESET")
|
|
if(species_type)
|
|
mannequin.set_species(species_type)
|
|
if(outfit_type)
|
|
mannequin.equipOutfit(outfit_type,TRUE)
|
|
mannequin.setDir(SOUTH)
|
|
COMPILE_OVERLAYS(mannequin)
|
|
. = image(mannequin)
|
|
unset_busy_human_dummy("HOLODISK_PRESET")
|
|
|
|
/obj/item/disk/holodisk/example
|
|
preset_image_type = /datum/preset_holoimage/clown
|
|
preset_record_text = {"
|
|
NAME Clown
|
|
DELAY 10
|
|
SAY Why did the chaplain cross the maint ?
|
|
DELAY 20
|
|
SAY He wanted to get to the other side!
|
|
SOUND clownstep
|
|
DELAY 30
|
|
LANGUAGE /datum/language/narsie
|
|
SAY Helped him get there!
|
|
DELAY 10
|
|
SAY ALSO IM SECRETLY A GORILLA
|
|
DELAY 10
|
|
PRESET /datum/preset_holoimage/gorilla
|
|
NAME Gorilla
|
|
LANGUAGE /datum/language/common
|
|
SAY OOGA
|
|
DELAY 20"}
|
|
|
|
/datum/preset_holoimage/engineer
|
|
outfit_type = /datum/outfit/job/engineer
|
|
|
|
/datum/preset_holoimage/engineer/rig
|
|
outfit_type = /datum/outfit/job/engineer/gloved/rig
|
|
|
|
/datum/preset_holoimage/engineer/ce
|
|
outfit_type = /datum/outfit/job/ce
|
|
|
|
/datum/preset_holoimage/engineer/ce/rig
|
|
outfit_type = /datum/outfit/job/engineer/gloved/rig
|
|
|
|
/datum/preset_holoimage/engineer/atmos
|
|
outfit_type = /datum/outfit/job/atmos
|
|
|
|
/datum/preset_holoimage/engineer/atmos/rig
|
|
outfit_type = /datum/outfit/job/engineer/gloved/rig
|
|
|
|
/datum/preset_holoimage/researcher
|
|
outfit_type = /datum/outfit/job/scientist
|
|
|
|
/datum/preset_holoimage/captain
|
|
outfit_type = /datum/outfit/job/captain
|
|
|
|
/datum/preset_holoimage/nanotrasenprivatesecurity
|
|
outfit_type = /datum/outfit/nanotrasensoldiercorpse2
|
|
|
|
/datum/preset_holoimage/gorilla
|
|
nonhuman_mobtype = /mob/living/simple_animal/hostile/gorilla
|
|
|
|
/datum/preset_holoimage/corgi
|
|
nonhuman_mobtype = /mob/living/simple_animal/pet/dog/corgi
|
|
|
|
/datum/preset_holoimage/clown
|
|
outfit_type = /datum/outfit/job/clown
|
|
|
|
/obj/item/disk/holodisk/donutstation/whiteship
|
|
name = "Blackbox Print-out #DS024"
|
|
desc = "A holodisk containing the last viable recording of DS024's blackbox."
|
|
preset_image_type = /datum/preset_holoimage/engineer/ce
|
|
preset_record_text = {"
|
|
NAME Geysr Shorthalt
|
|
SAY Engine renovations complete and the ships been loaded. We all ready?
|
|
DELAY 25
|
|
PRESET /datum/preset_holoimage/engineer
|
|
NAME Jacob Ullman
|
|
SAY Lets blow this popsicle stand of a station.
|
|
DELAY 20
|
|
PRESET /datum/preset_holoimage/engineer/atmos
|
|
NAME Lindsey Cuffler
|
|
SAY Uh, sir? Shouldn't we call for a secondary shuttle? The bluespace drive on this thing made an awfully weird noise when we jumped here..
|
|
DELAY 30
|
|
PRESET /datum/preset_holoimage/engineer/ce
|
|
NAME Geysr Shorthalt
|
|
SAY Pah! Ship techie at the dock said to give it a good few kicks if it started acting up, let me just..
|
|
DELAY 25
|
|
SOUND punch
|
|
SOUND sparks
|
|
DELAY 10
|
|
SOUND punch
|
|
SOUND sparks
|
|
DELAY 10
|
|
SOUND punch
|
|
SOUND sparks
|
|
SOUND warpspeed
|
|
DELAY 15
|
|
PRESET /datum/preset_holoimage/engineer/atmos
|
|
NAME Lindsey Cuffler
|
|
SAY Uhh.. is it supposed to be doing that??
|
|
DELAY 15
|
|
PRESET /datum/preset_holoimage/engineer/ce
|
|
NAME Geysr Shorthalt
|
|
SAY See? Working as intended. Now, are we all ready?
|
|
DELAY 10
|
|
PRESET /datum/preset_holoimage/engineer
|
|
NAME Jacob Ullman
|
|
SAY Is it supposed to be glowing like that?
|
|
DELAY 20
|
|
SOUND explosion
|
|
|
|
"}
|