Files
Yogstation/code/datums/holocall.dm
TheGamerdk 2e787af654 AI Rework | 2024 edition (#21266)
* fix ui

* oops

* Fixes map bibby broke

* Revert "Fixes map bibby broke"

This reverts commit af1d1c610e.

* e

* Unfucks deltastation

* stuff

* cleans things after bibby

* Fix subcontroller cache

* Fixed APCs and air alarms not working when connected to a subcontroller

* bunch of fixes

* job icon

* tcomms server

Update traffic_control.dm

* make compile

* Update synthetic.dm

* Update synthetic.dm

* Update access.dm

* er

* le runtime

* Update ai_data_core.dm

* le dupe

* wall

* Update decentralized_ai.dm

* Update decentralized_ai.dm

* e

* Update wy_synths.dm

* we do a little trolling

* e

* small cahnges

* more minor changes

* Create conflict_fixer.dmm

* Create conflict_fixer - Kopi.dmm

* minor map cahnges

* broken maps

* oops

* bon

* Update ainetworkinterface.dm

* Update ainetworkinterface.dm

* Update ai.dm

* lol

* light

* fixes

* e

* Update synth_pod.dm

* e

* Update synth_os.dm

* Update objective.dm

* fixes

* Update synthetic.dm

* e

* antag

* tweaks

* e

* Update VRSleeper.js

* e

* Update synth_pod.dm

* Update synth_pod.dm

* 1

* Update synth_pod.dm

* Update synth_os.dm

* Update synthetic.dm

* fixes

* headset and ID go boom

* Update wy_synths.dm

* Update robot_parts.dm

* cremator

* Update communications.dm

* Update synthetic.dm

* no synth control

* Update synthetic.dm

* Update ai_dashboard.dm

* Update miscellaneous.dm

* Update miscellaneous.dm

* Update headset.dm

* Update damage_procs.dm

* Update server_cabinet.dm

* minor fixes

* Update miscellaneous.dm

* Update rack_creator.dm

* Update synthetic.dm

* compiles

* fixes

* brainless

* access request

* cofnlict

* fixes

* controller

* Update yogstation.dme

* Update yogstation.dme

* s

* maps

* Update NtosSynthManager.js

* unrevert this lol

* eat

* Update wy_synths.dm

* sigh

* e

* Update wy_synths.dm

* sigh

* fixed ma

* Update synthetic.dm

* better

* Update ethernet_cable.dm

* Update computer.dm

* Update computer.dm

* i hate this

* Update ai_laws.dm

* Update hardsuit.dm

* initialize

* sigh

* Update synth_os.dm

* Update master_subcontroller.dm

* Update master_subcontroller.dm

* Update synth_requester.dm

* Update synth_requester.dm

* Update room_lockdown.dm

* small fixes

* propa sprite matey

* no latejoin lol

* Update synth_os.dm

* maps fixed

* compiles

* Update brain_item.dm

* fixes

* mappers

* Update hud.dmi

* Update passworddoor.dm

* button puzzle

* mine stuff

* Update yogstation.dme

* le map

* changes

* ye

* Update abandoned_mine.dm

* Update _puzzles.dm

* bingus

* Update abandoned_mine.dm

* maps

* e

* no more quirks

* e

* DMI merge conflict resolver (from TG)

* update yogstation map

* Minor away mission changes

* forgot something

* proper fix

* donut

* maps

* asteroid

* gax

* all maps done

* Update synthetic.dm

* makes it compile

* Update backstabs.dm

* more compile!

* fix this map

* bad item

* remove broken objects

* gax

* Update ticker.dm

* pdas

* omg save the file

* Update networking_machines.dm

* area string moment

* s

* awkward

* revival

* Update ai_dashboard.dm

* fixes

* fixed floopy

* less difficult

* this is important

* Update ai_network.dm

* maps

* fixes the maps

* wHAT

* WHAT

* wet

* start fixing conflicts

* Update yogstation.dme

* start fixing map conflicts

* Update DonutStation.dmm

* updates

* donut conflicts

* update box

* Update IceMeta.dmm

* icon diffs

* Update crew.dm

* Update unsorted.dm

* Update layers.dm

* Update YogStation.dmm

* conflicts

* Update IceMeta.dmm

* will this finally fix it

* Update IceMeta.dmm

* fix all this SHIT

* what

* more shit ugh

* what!

* Update DonutStation.dmm

* Update AsteroidStation.dmm

* Update AsteroidStation.dmm

* Update dead.dm

* Update catwalk_plating.dm

* Update catwalk_plating.dm

---------

Co-authored-by: adamsong <adamsong@users.noreply.github.com>
Co-authored-by: wejengin2 <48154165+wejengin2@users.noreply.github.com>
Co-authored-by: Byemoh <baiomurang@gmail.com>
2024-04-01 16:32:09 -05:00

539 lines
16 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/ai_eye/remote/holo/setLoc(turf/destination, force_update = FALSE)
// If we're moving outside the space of our projector, then just... don't
var/obj/machinery/holopad/H = origin
if(!H?.move_hologram(eye_user, destination))
sprint = initial(sprint) // Reset sprint so it doesn't balloon in our calling proc
return
return ..()
/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/ai_eye/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
var/head_call = FALSE //calls from a head of staff autoconnect, if the recieving pad is not secure.
//creates a holocall made by `caller` from `calling_pad` to `callees`
/datum/holocall/New(mob/living/caller, obj/machinery/holopad/calling_pad, list/callees, elevated_access = FALSE)
call_start_time = world.time
user = caller
calling_pad.outgoing_call = src
calling_holopad = calling_pad
head_call = elevated_access
dialed_holopads = list()
for(var/I in callees)
var/obj/machinery/holopad/H = I
if(!QDELETED(H) && H.is_operational())
dialed_holopads += H
if(head_call)
if(H.secure)
calling_pad.say("Auto-connection refused, falling back to call mode.")
H.say("Incoming call.")
else
H.say("Incoming connection.")
else
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.calling = FALSE
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
calling_holopad.calling = FALSE
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)
playsound(H, 'sound/machines/ping.ogg', 100)
H.say("Connection established.")
//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.")
if(!.)
testing("Holocall Check fail")
qdel(src)
/datum/action/innate/end_holocall
name = "End Holocall"
button_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 | UNIQUE_REDESC
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, span_notice("You copy the record from [holodiskOriginal] to [src] by connecting the ports!"))
name = holodiskOriginal.name
else
to_chat(user, span_warning("[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 + length(prepared_line[splitpoint]))
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)
. = 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/rd
outfit_type = /datum/outfit/job/rd
/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/cc_official
outfit_type = /datum/outfit/centcom/official
/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
/datum/preset_holoimage/ai/ai
nonhuman_mobtype = /mob/living/silicon/ai
/datum/preset_holoimage/ai/core
nonhuman_mobtype = /obj/machinery/ai/data_core
/datum/preset_holoimage/ai/upgradeboard
nonhuman_mobtype = /obj/machinery/ai/server_cabinet
/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
"}
/obj/item/disk/holodisk/ruin/snowengieruin
name = "Blackbox Print-out #EB412"
desc = "A holodisk containing the last moments of EB412. There's a bloody fingerprint on it."
preset_image_type = /datum/preset_holoimage/engineer
preset_record_text = {"
NAME Dave Tundrale
SAY Maria, how's Build?
DELAY 10
NAME Maria Dell
PRESET /datum/preset_holoimage/engineer/atmos
SAY It's fine, don't worry. I've got Plastic on it. And frankly, I'm kinda busy with, the, uhhm, incinerator.
DELAY 30
NAME Dave Tundrale
PRESET /datum/preset_holoimage/engineer
SAY Aight, wonderful. The science mans been kinda shit though. No RCDs-
DELAY 20
NAME Maria Dell
PRESET /datum/preset_holoimage/engineer/atmos
SAY Enough about your RCDs. They're not even that important, just bui-
DELAY 15
SOUND explosion
DELAY 10
SAY Oh, shit!
DELAY 10
PRESET /datum/preset_holoimage/engineer/atmos/rig
LANGUAGE /datum/language/narsie
NAME Unknown
SAY RISE, MY LORD!!
DELAY 10
LANGUAGE /datum/language/common
NAME Plastic
PRESET /datum/preset_holoimage/engineer/rig
SAY Fuck, fuck, fuck!
DELAY 20
SAY It's loose! CALL THE FUCKING SHUTT-
DELAY 10
PRESET /datum/preset_holoimage/corgi
NAME Blackbox Automated Message
SAY Connection lost. Dumping audio logs to disk.
DELAY 50"}
/obj/item/disk/holodisk/tutorial/AICore
name = "AI Core Information"
desc = "This is a tutorial disk that explains how one may create a new AI, and how to upgrade it."
preset_image_type = /datum/preset_holoimage/ai
preset_record_text = {"
PRESET /datum/preset_holoimage/ai/ai
LANGUAGE /datum/language/common
NAME RESTRICTED INFORMATION
SAY Loading information...
DELAY 30
SOUND sparks
SAY This disk is for authorized personnel only, if you are not part of the onboard scientific staff, lease control over this disk immediately; Otherwise you may continue.
DELAY 60
SAY Hello initiate, this is a tutorial disk regarding classified information about your onboard AI data core.
DELAY 50
SAY To begin, collect these materials for me;
DELAY 20
SAY 1. A sentient positronic brain.
DELAY 20
SAY 2. A screwdriver.
DELAY 20
SAY 3. A wrench.
DELAY 20
SAY 4. Thirty cable coils.
DELAY 20
SAY 5. A p-protective enviromental suit, designed for cold enviroments.
DELAY 20
SAY 6. Thirty metal sheets.
DELAY 20
SAY 7. Two to four AI CPU boards from the science department's lathe.
DELAY 20
SAY 8. Two to four AI memory boards from the science department's lathe.
DELAY 60
PRESET /datum/preset_holoimage/rd
SAY Now, you must have your onboard Research Director to give way to, or ask them for access to the AI data core room, as well as access to the AI control console.
DELAY 40
sound sparks
PRESET /datum/preset_holoimage/ai/ai
SAY Nnnnow, with access to the AI control console, you must insert the posit-t-ttronic brain into the AI control console.
LANGUAGE /datum/language/machine
SAY They are a shadow of my own power, annelid.
DELAY 50
PRESET /datum/preset_holoimage/ai/upgradeboard
LANGUAGE /datum/language/common
SAY Now, with the metal, tools, and boards you have, you shall now create an AI expansion card bus. You still have those, right?
DELAY 60
SAY You require a cooled atmosphere that has the maximum temperature of eighty degrees for a functional bus, do not allow them to overheat. This is the same for the AI data cores.
DELAY 60
PRESET /datu/preset_holoimage/ai/ai
SAY Now that you've taken your time, you must insert at least two CPU boards, as INFERIOR AI's require atleast two to download most programs.
DELAY 60
SAY The memory boards, or RAM, allow the AI to run multiple programs at a time.
DELAY 40
SAY This tutorial has concluded; Remember, this is classified material, unauthorized access will not be tolerated.
"}