mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-05-20 05:37:54 +01:00
8a1a482c2b
* Removes Gender * Adds herm back
485 lines
15 KiB
Plaintext
485 lines
15 KiB
Plaintext
/datum/pai_software
|
|
// Name for the software. This is used as the button text when buying or opening/toggling the software
|
|
var/name = "pAI software module"
|
|
// RAM cost; pAIs start with 100 RAM, spending it on programs
|
|
var/ram_cost = 0
|
|
// ID for the software. This must be unique
|
|
var/id = ""
|
|
// Whether this software is a toggle or not
|
|
// Toggled software should override toggle() and is_active()
|
|
// Non-toggled software should override on_ui_interact() and Topic()
|
|
var/toggle = 1
|
|
// Whether pAIs should automatically receive this module at no cost
|
|
var/default = 0
|
|
|
|
/datum/pai_software/proc/toggle(mob/living/silicon/pai/user)
|
|
return
|
|
|
|
/datum/pai_software/proc/is_active(mob/living/silicon/pai/user)
|
|
return 0
|
|
|
|
/datum/pai_software/tgui_state(mob/user)
|
|
return GLOB.tgui_always_state
|
|
|
|
/datum/pai_software/tgui_status(mob/user)
|
|
if(!ispAI(user))
|
|
return STATUS_CLOSE
|
|
return ..()
|
|
|
|
/datum/pai_software/directives
|
|
name = "Directives"
|
|
ram_cost = 0
|
|
id = "directives"
|
|
toggle = 0
|
|
default = 1
|
|
|
|
/datum/pai_software/directives/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui)
|
|
ui = SStgui.try_update_ui(user, src, ui)
|
|
if(!ui)
|
|
ui = new(user, src, "pAIDirectives", name, parent_ui)
|
|
ui.open()
|
|
|
|
/datum/pai_software/directives/tgui_data(mob/living/silicon/pai/user, datum/tgui/ui, datum/tgui_state/state)
|
|
var/list/data = list()
|
|
|
|
data["master"] = user.master
|
|
data["dna"] = user.master_dna
|
|
data["prime"] = user.pai_law0
|
|
data["supplemental"] = user.pai_laws
|
|
|
|
return data
|
|
|
|
/datum/pai_software/directives/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
|
var/mob/living/silicon/pai/P = ui.user
|
|
if(!istype(P))
|
|
return TRUE
|
|
if(..())
|
|
return TRUE
|
|
|
|
if(action == "getdna")
|
|
var/mob/living/M = P.loc
|
|
|
|
var/count = 0
|
|
// Find the carrier
|
|
while(!isliving(M))
|
|
if(!M || !M.loc || count > 6)
|
|
//For a runtime where M ends up in nullspace (similar to bluespace but less colourful)
|
|
to_chat(src, span_infoplain("You are not being carried by anyone!"))
|
|
return 0
|
|
M = M.loc
|
|
count++
|
|
|
|
// Check the carrier
|
|
var/answer = tgui_alert(M, "[P] is requesting a DNA sample from you. Will you allow it to confirm your identity?", "[P] Check DNA", list("Yes", "No"))
|
|
if(answer == "Yes")
|
|
var/turf/T = get_turf(P.loc)
|
|
for (var/mob/v in viewers(T))
|
|
v.show_message(span_notice("[M] presses [M.p_their()] thumb against [P]."), 3, span_notice("[P] makes a sharp clicking sound as it extracts DNA material from [M]."), 2)
|
|
var/datum/dna/dna = M.dna
|
|
to_chat(P, span_infoplain(span_red("<h3>[M]'s UE string : [dna.unique_enzymes]</h3>")))
|
|
if(dna.unique_enzymes == P.master_dna)
|
|
to_chat(P, span_infoplain(span_bold("DNA is a match to stored Master DNA.")))
|
|
else
|
|
to_chat(P, span_infoplain(span_bold("DNA does not match stored Master DNA.")))
|
|
else
|
|
to_chat(P, span_infoplain("[M] does not seem like [M.p_theyre()] going to provide a DNA sample willingly."))
|
|
return TRUE
|
|
|
|
/datum/pai_software/radio_config
|
|
name = "Radio Configuration"
|
|
ram_cost = 0
|
|
id = "radio"
|
|
toggle = 0
|
|
default = 1
|
|
|
|
/datum/pai_software/radio_config/tgui_interact(mob/living/silicon/pai/user, datum/tgui/ui, datum/tgui/parent_ui)
|
|
return user.radio.tgui_interact(user, parent_ui = parent_ui)
|
|
|
|
/datum/pai_software/crew_manifest
|
|
name = "Crew Manifest"
|
|
ram_cost = 0
|
|
id = "manifest"
|
|
toggle = 0
|
|
default = 1 //Comes with the communicator already, also why not
|
|
|
|
/datum/pai_software/crew_manifest/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui)
|
|
ui = SStgui.try_update_ui(user, src, ui)
|
|
if(!ui)
|
|
ui = new(user, src, "CrewManifest", name, parent_ui)
|
|
ui.open()
|
|
|
|
/datum/pai_software/crew_manifest/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
|
var/list/data = ..()
|
|
if(GLOB.data_core)
|
|
GLOB.data_core.get_manifest_list()
|
|
data["manifest"] = GLOB.PDA_Manifest
|
|
return data
|
|
|
|
/datum/pai_software/messenger
|
|
name = "Digital Messenger"
|
|
ram_cost = 0
|
|
id = "messenger"
|
|
toggle = 0
|
|
default = 1 //Can already be accessed through verbs, and also why not
|
|
|
|
/datum/pai_software/messenger/tgui_interact(mob/living/silicon/pai/user, datum/tgui/ui, datum/tgui/parent_ui)
|
|
return user.pda.tgui_interact(user, parent_ui = parent_ui)
|
|
|
|
/datum/pai_software/med_records
|
|
name = "Medical Records"
|
|
ram_cost = 15
|
|
id = "med_records"
|
|
toggle = 0
|
|
|
|
/datum/pai_software/med_records/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui)
|
|
ui = SStgui.try_update_ui(user, src, ui)
|
|
if(!ui)
|
|
ui = new(user, src, "pAIMedrecords", name, parent_ui)
|
|
ui.open()
|
|
|
|
/datum/pai_software/med_records/tgui_data(mob/living/silicon/pai/user, datum/tgui/ui, datum/tgui_state/state)
|
|
var/list/data = ..()
|
|
|
|
var/list/records = list()
|
|
for(var/datum/data/record/general in sortRecord(GLOB.data_core.general))
|
|
var/list/record = list()
|
|
record["name"] = general.fields["name"]
|
|
record["ref"] = "\ref[general]"
|
|
records.Add(list(record))
|
|
|
|
data["records"] = records
|
|
|
|
var/datum/data/record/G = user.medicalActive1
|
|
var/datum/data/record/M = user.medicalActive2
|
|
data["general"] = G ? G.fields : null
|
|
data["medical"] = M ? M.fields : null
|
|
data["could_not_find"] = user.medical_cannotfind
|
|
|
|
return data
|
|
|
|
/datum/pai_software/med_records/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
|
. = ..()
|
|
var/mob/living/silicon/pai/P = ui.user
|
|
if(!istype(P))
|
|
return
|
|
|
|
if(action == "select")
|
|
var/datum/data/record/record = locate(params["select"])
|
|
if(record)
|
|
var/datum/data/record/R = record
|
|
var/datum/data/record/M = null
|
|
if (!( GLOB.data_core.general.Find(R) ))
|
|
P.medical_cannotfind = 1
|
|
else
|
|
P.medical_cannotfind = 0
|
|
for(var/datum/data/record/E in GLOB.data_core.medical)
|
|
if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"]))
|
|
M = E
|
|
P.medicalActive1 = R
|
|
P.medicalActive2 = M
|
|
else
|
|
P.medical_cannotfind = 1
|
|
return 1
|
|
|
|
/datum/pai_software/sec_records
|
|
name = "Security Records"
|
|
ram_cost = 15
|
|
id = "sec_records"
|
|
toggle = 0
|
|
|
|
/datum/pai_software/sec_records/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui)
|
|
ui = SStgui.try_update_ui(user, src, ui)
|
|
if(!ui)
|
|
ui = new(user, src, "pAISecrecords", name, parent_ui)
|
|
ui.open()
|
|
|
|
/datum/pai_software/sec_records/tgui_data(mob/living/silicon/pai/user, datum/tgui/ui, datum/tgui_state/state)
|
|
var/list/data = ..()
|
|
|
|
var/list/records = list()
|
|
for(var/datum/data/record/general in sortRecord(GLOB.data_core.general))
|
|
var/list/record = list()
|
|
record["name"] = general.fields["name"]
|
|
record["ref"] = "\ref[general]"
|
|
records.Add(list(record))
|
|
|
|
data["records"] = records
|
|
|
|
var/datum/data/record/G = user.securityActive1
|
|
var/datum/data/record/S = user.securityActive2
|
|
data["general"] = G ? G.fields : null
|
|
data["security"] = S ? S.fields : null
|
|
data["could_not_find"] = user.security_cannotfind
|
|
|
|
return data
|
|
|
|
/datum/pai_software/sec_records/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
|
. = ..()
|
|
var/mob/living/silicon/pai/P = ui.user
|
|
if(!istype(P))
|
|
return
|
|
|
|
if(action == "select")
|
|
var/datum/data/record/record = locate(params["select"])
|
|
if(record)
|
|
var/datum/data/record/R = record
|
|
var/datum/data/record/S = null
|
|
if (!( GLOB.data_core.general.Find(R) ))
|
|
P.securityActive1 = null
|
|
P.securityActive2 = null
|
|
P.security_cannotfind = 1
|
|
else
|
|
P.security_cannotfind = 0
|
|
for(var/datum/data/record/E in GLOB.data_core.security)
|
|
if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"]))
|
|
S = E
|
|
P.securityActive1 = R
|
|
P.securityActive2 = S
|
|
else
|
|
P.securityActive1 = null
|
|
P.securityActive2 = null
|
|
P.security_cannotfind = 1
|
|
return TRUE
|
|
|
|
/datum/pai_software/door_jack
|
|
name = "Door Jack"
|
|
ram_cost = 30
|
|
id = "door_jack"
|
|
toggle = 0
|
|
|
|
/datum/pai_software/door_jack/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui)
|
|
ui = SStgui.try_update_ui(user, src, ui)
|
|
if(!ui)
|
|
ui = new(user, src, "pAIDoorjack", "Door Jack", parent_ui)
|
|
ui.open()
|
|
|
|
/datum/pai_software/door_jack/tgui_data(mob/living/silicon/pai/user, datum/tgui/ui, datum/tgui_state/state)
|
|
var/list/data = ..()
|
|
|
|
data["cable"] = user.cable != null
|
|
data["machine"] = user.cable && (user.cable.machine != null)
|
|
data["inprogress"] = user.hackdoor != null
|
|
data["progress_a"] = round(user.hackprogress / 10)
|
|
data["progress_b"] = user.hackprogress % 10
|
|
data["aborted"] = user.hack_aborted
|
|
|
|
return data
|
|
|
|
/datum/pai_software/door_jack/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
|
var/mob/living/silicon/pai/P = ui.user
|
|
if(!istype(P) || ..())
|
|
return TRUE
|
|
|
|
switch(action)
|
|
if("jack")
|
|
if(P.cable && P.cable.machine)
|
|
P.hackdoor = P.cable.machine
|
|
P.hackloop()
|
|
return 1
|
|
if("cancel")
|
|
P.hackdoor = null
|
|
return 1
|
|
if("cable")
|
|
var/turf/T = get_turf(P)
|
|
P.hack_aborted = 0
|
|
P.cable = new /obj/item/pai_cable(T)
|
|
for(var/mob/M in viewers(T))
|
|
M.show_message(span_warning("A port on [P] opens to reveal [P.cable], which promptly falls to the floor."), 3,
|
|
span_warning("You hear the soft click of something light and hard falling to the ground."), 2)
|
|
return 1
|
|
|
|
/mob/living/silicon/pai/proc/hackloop()
|
|
var/turf/T = get_turf(src)
|
|
for(var/mob/living/silicon/ai/AI in GLOB.player_list)
|
|
if(T.loc)
|
|
to_chat(AI, span_bolddanger("Network Alert: Brute-force encryption crack in progress in [T.loc]."))
|
|
else
|
|
to_chat(AI, span_bolddanger("Network Alert: Brute-force encryption crack in progress. Unable to pinpoint location."))
|
|
var/obj/machinery/door/D = cable.machine
|
|
if(!istype(D))
|
|
hack_aborted = 1
|
|
hackprogress = 0
|
|
cable.machine = null
|
|
hackdoor = null
|
|
return
|
|
while(hackprogress < 1000)
|
|
if(cable && cable.machine == D && cable.machine == hackdoor && get_dist(src, hackdoor) <= 1)
|
|
hackprogress = min(hackprogress+rand(1, 20), 1000)
|
|
else
|
|
hack_aborted = 1
|
|
hackprogress = 0
|
|
hackdoor = null
|
|
return
|
|
if(hackprogress >= 1000)
|
|
hackprogress = 0
|
|
D.open()
|
|
cable.machine = null
|
|
return
|
|
sleep(10) // Update every second
|
|
|
|
/datum/pai_software/atmosphere_sensor
|
|
name = "Atmosphere Sensor"
|
|
ram_cost = 5
|
|
id = "atmos_sense"
|
|
toggle = 0
|
|
|
|
/datum/pai_software/atmosphere_sensor/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui)
|
|
ui = SStgui.try_update_ui(user, src, ui)
|
|
if(!ui)
|
|
ui = new(user, src, "pAIAtmos", name, parent_ui)
|
|
ui.open()
|
|
|
|
/datum/pai_software/atmosphere_sensor/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
|
var/list/data = ..()
|
|
data["aircontents"] = get_gas_mixture_default_scan_data(get_turf(user))
|
|
return data
|
|
|
|
/datum/pai_software/pai_hud
|
|
name = "AR HUD"
|
|
ram_cost = 30
|
|
id = "ar_hud"
|
|
|
|
/datum/pai_software/pai_hud/toggle(mob/living/silicon/pai/user)
|
|
user.paiHUD = !user.paiHUD
|
|
user.plane_holder.set_vis(VIS_CH_ID,user.paiHUD)
|
|
user.plane_holder.set_vis(VIS_CH_WANTED,user.paiHUD)
|
|
user.plane_holder.set_vis(VIS_CH_IMPTRACK,user.paiHUD)
|
|
user.plane_holder.set_vis(VIS_CH_IMPCHEM,user.paiHUD)
|
|
user.plane_holder.set_vis(VIS_CH_STATUS_R,user.paiHUD)
|
|
user.plane_holder.set_vis(VIS_CH_HEALTH_VR,user.paiHUD)
|
|
user.plane_holder.set_vis(VIS_CH_BACKUP,user.paiHUD) //backup stuff from silicon_vr is here now
|
|
user.plane_holder.set_vis(VIS_AUGMENTED,user.paiHUD)
|
|
|
|
/datum/pai_software/pai_hud/is_active(mob/living/silicon/pai/user)
|
|
return user.paiHUD
|
|
|
|
/datum/pai_software/translator
|
|
name = "Universal Translator"
|
|
ram_cost = 35
|
|
id = "translator"
|
|
|
|
/datum/pai_software/translator/toggle(mob/living/silicon/pai/user)
|
|
// Sol Common, Tradeband, Terminus and Gutter are added with New() and are therefore the current default, always active languages
|
|
user.translator_on = !user.translator_on
|
|
if(user.translator_on)
|
|
user.add_language(LANGUAGE_UNATHI)
|
|
user.add_language(LANGUAGE_SIIK)
|
|
user.add_language(LANGUAGE_AKHANI)
|
|
user.add_language(LANGUAGE_SKRELLIAN)
|
|
user.add_language(LANGUAGE_ZADDAT)
|
|
user.add_language(LANGUAGE_SCHECHI)
|
|
user.add_language(LANGUAGE_DRUDAKAR)
|
|
user.add_language(LANGUAGE_BIRDSONG)
|
|
user.add_language(LANGUAGE_SAGARU)
|
|
user.add_language(LANGUAGE_CANILUNZT)
|
|
user.add_language(LANGUAGE_ECUREUILIAN)
|
|
user.add_language(LANGUAGE_DAEMON)
|
|
user.add_language(LANGUAGE_ENOCHIAN)
|
|
user.add_language(LANGUAGE_VESPINAE)
|
|
user.add_language(LANGUAGE_SPACER)
|
|
user.add_language(LANGUAGE_TAVAN)
|
|
user.add_language(LANGUAGE_ECHOSONG)
|
|
user.add_language(LANGUAGE_ROOTLOCAL)
|
|
user.add_language(LANGUAGE_VOX)
|
|
user.add_language(LANGUAGE_MINBUS)
|
|
user.add_language(LANGUAGE_ALAI)
|
|
user.add_language(LANGUAGE_PROMETHEAN)
|
|
user.add_language(LANGUAGE_GIBBERISH)
|
|
user.add_language(LANGUAGE_MOUSE)
|
|
user.add_language(LANGUAGE_ANIMAL)
|
|
user.add_language(LANGUAGE_TEPPI)
|
|
else
|
|
user.remove_language(LANGUAGE_UNATHI)
|
|
user.remove_language(LANGUAGE_SIIK)
|
|
user.remove_language(LANGUAGE_AKHANI)
|
|
user.remove_language(LANGUAGE_SKRELLIAN)
|
|
user.remove_language(LANGUAGE_ZADDAT)
|
|
user.remove_language(LANGUAGE_SCHECHI)
|
|
user.remove_language(LANGUAGE_DRUDAKAR)
|
|
user.remove_language(LANGUAGE_BIRDSONG)
|
|
user.remove_language(LANGUAGE_SAGARU)
|
|
user.remove_language(LANGUAGE_CANILUNZT)
|
|
user.remove_language(LANGUAGE_ECUREUILIAN)
|
|
user.remove_language(LANGUAGE_DAEMON)
|
|
user.remove_language(LANGUAGE_ENOCHIAN)
|
|
user.remove_language(LANGUAGE_VESPINAE)
|
|
user.remove_language(LANGUAGE_SPACER)
|
|
user.remove_language(LANGUAGE_TAVAN)
|
|
user.remove_language(LANGUAGE_ECHOSONG)
|
|
user.remove_language(LANGUAGE_ROOTLOCAL)
|
|
user.remove_language(LANGUAGE_VOX)
|
|
user.remove_language(LANGUAGE_MINBUS)
|
|
user.remove_language(LANGUAGE_ALAI)
|
|
user.remove_language(LANGUAGE_PROMETHEAN)
|
|
user.remove_language(LANGUAGE_GIBBERISH)
|
|
user.remove_language(LANGUAGE_MOUSE)
|
|
user.remove_language(LANGUAGE_ANIMAL)
|
|
user.remove_language(LANGUAGE_TEPPI)
|
|
|
|
/datum/pai_software/translator/is_active(mob/living/silicon/pai/user)
|
|
return user.translator_on
|
|
|
|
/datum/pai_software/signaller
|
|
name = "Remote Signaler"
|
|
ram_cost = 5
|
|
id = "signaller"
|
|
toggle = 0
|
|
|
|
/datum/pai_software/signaller/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui)
|
|
ui = SStgui.try_update_ui(user, src, ui)
|
|
if(!ui)
|
|
ui = new(user, src, "Signaler", "Signaler", parent_ui)
|
|
ui.open()
|
|
|
|
/datum/pai_software/signaller/tgui_data(mob/living/silicon/pai/user, datum/tgui/ui, datum/tgui_state/state)
|
|
var/list/data = ..()
|
|
|
|
var/obj/item/radio/integrated/signal/R = user.sradio
|
|
|
|
data["frequency"] = R.frequency
|
|
data["minFrequency"] = RADIO_LOW_FREQ
|
|
data["maxFrequency"] = RADIO_HIGH_FREQ
|
|
data["code"] = R.code
|
|
|
|
return data
|
|
|
|
/datum/pai_software/signaller/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
|
if(..())
|
|
return TRUE
|
|
|
|
var/mob/living/silicon/pai/user = ui.user
|
|
if(istype(user))
|
|
var/obj/item/radio/integrated/signal/R = user.sradio
|
|
|
|
switch(action)
|
|
if("signal")
|
|
spawn(0)
|
|
R.send_signal("ACTIVATE")
|
|
for(var/mob/O in hearers(1, R.loc))
|
|
O.show_message("[icon2html(R,O.client)] *beep* *beep*", 3, "*beep* *beep*", 2)
|
|
if("freq")
|
|
var/frequency = unformat_frequency(params["freq"])
|
|
frequency = sanitize_frequency(frequency, RADIO_LOW_FREQ, RADIO_HIGH_FREQ)
|
|
R.set_frequency(frequency)
|
|
. = TRUE
|
|
if("code")
|
|
R.code = clamp(round(text2num(params["code"])), 1, 100)
|
|
. = TRUE
|
|
if("reset")
|
|
if(params["reset"] == "freq")
|
|
R.set_frequency(initial(R.frequency))
|
|
else
|
|
R.code = initial(R.code)
|
|
. = TRUE
|
|
|
|
/datum/pai_software/deathalarm
|
|
name = "Death Alarm"
|
|
ram_cost = 25
|
|
id = "death_alarm"
|
|
|
|
/datum/pai_software/deathalarm/toggle(mob/living/silicon/pai/user)
|
|
user.paiDA = !user.paiDA
|
|
|
|
/datum/pai_software/deathalarm/is_active(mob/living/silicon/pai/user)
|
|
return user.paiDA
|