mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-18 02:24:11 +01:00
ac5add482f
* List Input refresh * Modal Alerts * Text Input * Number Input * Split Button * Renaming * Alert converts * Text Input Conversion (Part 1) And TextArea Autofocus + maxLength * Text Input Conversion (Part 2) * AAAAAAAAAAAAAAAAAAAA * I'm FUCKED * @GDNgit review changes * "'" fixes * Revert TGUI Alert from admin delete * NumberInput Window size * CRASH if empty list * Update code/modules/tgui/tgui_input/list_input.dm * TGUI Rebuild * TGUI Rebuild * Update code/modules/paperwork/faxmachine.dm * _char * compile * Rebuild --------- Co-authored-by: Aylong <69762909+Aylong220@users.noreply.github.com> Co-authored-by: S34N <12197162+S34NW@users.noreply.github.com>
430 lines
12 KiB
Plaintext
430 lines
12 KiB
Plaintext
// Main Menu //
|
|
/datum/pai_software/main_menu
|
|
name = "Main Menu"
|
|
id = "mainmenu"
|
|
default = TRUE
|
|
template_file = "pai_main_menu"
|
|
ui_icon = "home"
|
|
|
|
/datum/pai_software/main_menu/get_app_data(mob/living/silicon/pai/user)
|
|
var/list/data = list()
|
|
data["available_ram"] = user.ram
|
|
|
|
// Emotions
|
|
var/list/emotions = list()
|
|
for(var/name in GLOB.pai_emotions)
|
|
var/list/emote = list()
|
|
emote["name"] = name
|
|
emote["id"] = GLOB.pai_emotions[name]
|
|
emotions[++emotions.len] = emote
|
|
|
|
data["emotions"] = emotions
|
|
data["current_emotion"] = user.card.current_emotion
|
|
|
|
var/list/speech_types = list()
|
|
for(var/name in user.possible_say_verbs)
|
|
var/list/speech = list()
|
|
speech["name"] = name
|
|
speech["id"] = length(speech_types)
|
|
speech_types[++speech_types.len] = speech
|
|
|
|
data["current_speech_verb"] = user.speech_state
|
|
data["speech_verbs"] = speech_types
|
|
|
|
var/list/chassis_choices = list()
|
|
var/list/chassises_to_add = list()
|
|
|
|
chassis_choices = user.possible_chassis.Copy()
|
|
if(user.custom_sprite)
|
|
chassis_choices["Custom"] = "[user.ckey]-pai"
|
|
for(var/name in chassis_choices)
|
|
var/list/chassis_to_update_with = list()
|
|
chassis_to_update_with["name"] = name
|
|
chassis_to_update_with["icon"] = chassis_choices[name]
|
|
chassis_to_update_with["id"] = length(chassis_to_update_with)
|
|
chassises_to_add[++chassises_to_add.len] = chassis_to_update_with
|
|
|
|
data["available_chassises"] = chassises_to_add
|
|
data["current_chassis"] = user.chassis
|
|
|
|
var/list/available_s = list()
|
|
for(var/s in GLOB.pai_software_by_key)
|
|
var/datum/pai_software/PS = GLOB.pai_software_by_key[s]
|
|
available_s += list(list("name" = PS.name, "key" = PS.id, "icon" = PS.ui_icon, "cost" = PS.ram_cost))
|
|
|
|
// Split to installed software and toggles for the UI
|
|
var/list/installed_s = list()
|
|
var/list/installed_t = list()
|
|
for(var/s in pai_holder.installed_software)
|
|
var/datum/pai_software/PS = pai_holder.installed_software[s]
|
|
if(PS.toggle_software)
|
|
installed_t += list(list("name" = PS.name, "key" = PS.id, "icon" = PS.ui_icon, "active" = PS.is_active(user)))
|
|
else
|
|
installed_s += list(list("name" = PS.name, "key" = PS.id, "icon" = PS.ui_icon))
|
|
|
|
data["available_software"] = available_s
|
|
data["installed_software"] = installed_s
|
|
data["installed_toggles"] = installed_t
|
|
|
|
return data
|
|
|
|
/datum/pai_software/main_menu/ui_act(action, list/params)
|
|
if(..())
|
|
return
|
|
|
|
switch(action)
|
|
if("purchaseSoftware")
|
|
var/datum/pai_software/S = GLOB.pai_software_by_key[params["key"]]
|
|
if(S && (pai_holder.ram >= S.ram_cost))
|
|
var/datum/pai_software/newPS = new S.type(pai_holder)
|
|
pai_holder.ram -= newPS.ram_cost
|
|
pai_holder.installed_software[newPS.id] = newPS
|
|
if("setEmotion")
|
|
var/emotion = clamp(text2num(params["emotion"]), 1, 9)
|
|
pai_holder.card.setEmotion(emotion)
|
|
if("startSoftware")
|
|
var/software_key = params["software_key"]
|
|
if(pai_holder.installed_software[software_key])
|
|
pai_holder.active_software = pai_holder.installed_software[software_key]
|
|
if("setToggle")
|
|
var/toggle_key = params["toggle_key"]
|
|
if(pai_holder.installed_software[toggle_key])
|
|
pai_holder.installed_software[toggle_key].toggle(pai_holder)
|
|
if("setSpeechStyle")
|
|
pai_holder.speech_state = params["speech_state"]
|
|
var/list/sayverbs = pai_holder.possible_say_verbs[pai_holder.speech_state]
|
|
pai_holder.speak_statement = sayverbs[1]
|
|
pai_holder.speak_exclamation = sayverbs[length(sayverbs) > 1 ? 2 : length(sayverbs)]
|
|
pai_holder.speak_query = sayverbs[length(sayverbs) > 2 ? 3 : length(sayverbs)]
|
|
if("setChassis")
|
|
pai_holder.chassis = params["chassis_to_change"]
|
|
pai_holder.icon_state = pai_holder.chassis
|
|
if(pai_holder.icon_state == "[pai_holder.ckey]-pai")
|
|
pai_holder.icon = 'icons/mob/custom_synthetic/custom-synthetic.dmi'
|
|
else
|
|
pai_holder.icon = 'icons/mob/pai.dmi'
|
|
|
|
|
|
// Directives //
|
|
/datum/pai_software/directives
|
|
name = "Directives"
|
|
id = "directives"
|
|
default = TRUE
|
|
template_file = "pai_directives"
|
|
ui_icon = "clipboard-list"
|
|
|
|
/datum/pai_software/directives/get_app_data(mob/living/silicon/pai/user)
|
|
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/ui_act(action, list/params)
|
|
if(..())
|
|
return
|
|
|
|
. = TRUE
|
|
|
|
switch(action)
|
|
if("getdna")
|
|
var/mob/living/M = get_holding_mob()
|
|
if(!istype(M))
|
|
return
|
|
|
|
// Check the carrier
|
|
var/answer = tgui_alert(M, "[pai_holder] is requesting a DNA sample from you. Will you allow it to confirm your identity?", "[pai_holder] Check DNA", list("Yes", "No"))
|
|
if(answer == "Yes")
|
|
M.visible_message("<span class='notice'>[M] presses [M.p_their()] thumb against [pai_holder].</span>", "<span class='notice'>You press your thumb against [pai_holder].</span>")
|
|
var/datum/dna/dna = M.dna
|
|
to_chat(usr, "<span class='notice'>[M]'s UE string: [dna.unique_enzymes]</span>")
|
|
if(dna.unique_enzymes == pai_holder.master_dna)
|
|
to_chat(usr, "<span class='notice'>DNA is a match to stored Master DNA.</span>")
|
|
else
|
|
to_chat(usr, "<span class='warning'>DNA does not match stored Master DNA.</span>")
|
|
else
|
|
to_chat(usr, "<span class='warning'>[M] does not seem like [M.p_they()] [M.p_are()] going to provide a DNA sample willingly.</span>")
|
|
|
|
// Crew Manifest //
|
|
/datum/pai_software/crew_manifest
|
|
name = "Crew Manifest"
|
|
id = "manifest"
|
|
default = TRUE
|
|
template_file = "pai_manifest"
|
|
ui_icon = "users"
|
|
|
|
/datum/pai_software/crew_manifest/get_app_data(mob/living/silicon/pai/user)
|
|
var/list/data = list()
|
|
|
|
GLOB.data_core.get_manifest_json()
|
|
data["manifest"] = GLOB.PDA_Manifest
|
|
|
|
return data
|
|
|
|
// Med Records //
|
|
/datum/pai_software/med_records
|
|
name = "Medical Records"
|
|
ram_cost = 15
|
|
id = "med_records"
|
|
template_file = "pai_medrecords"
|
|
ui_icon = "heartbeat"
|
|
/// Integrated medical records module to reduce duplicated code
|
|
var/datum/data/pda/app/crew_records/medical/integrated_records = new
|
|
|
|
/datum/pai_software/med_records/get_app_data(mob/living/silicon/pai/user)
|
|
var/list/data = list()
|
|
// Just grab the stuff internally
|
|
integrated_records.update_ui(user, data)
|
|
return data
|
|
|
|
/datum/pai_software/med_records/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
|
|
if(..())
|
|
return
|
|
// Double proxy here
|
|
integrated_records.ui_act(action, params, ui, state)
|
|
|
|
// Sec Records //
|
|
/datum/pai_software/sec_records
|
|
name = "Security Records"
|
|
ram_cost = 15
|
|
id = "sec_records"
|
|
template_file = "pai_secrecords"
|
|
ui_icon = "id-badge"
|
|
/// Integrated security records module to reduce duplicated code
|
|
var/datum/data/pda/app/crew_records/security/integrated_records = new
|
|
|
|
/datum/pai_software/sec_records/get_app_data(mob/living/silicon/pai/user)
|
|
var/list/data = list()
|
|
// Just grab the stuff internally
|
|
integrated_records.update_ui(user, data)
|
|
return data
|
|
|
|
/datum/pai_software/sec_records/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
|
|
if(..())
|
|
return
|
|
// Double proxy here
|
|
integrated_records.ui_act(action, params, ui, state)
|
|
|
|
// Atmos Scan //
|
|
/datum/pai_software/atmosphere_sensor
|
|
name = "Atmosphere Sensor"
|
|
ram_cost = 5
|
|
id = "atmos_sense"
|
|
template_file = "pai_atmosphere"
|
|
ui_icon = "fire"
|
|
/// Integrated PDA atmos scan module to reduce duplicated code
|
|
var/datum/data/pda/app/atmos_scanner/scanner = new
|
|
|
|
/datum/pai_software/atmosphere_sensor/get_app_data(mob/living/silicon/pai/user)
|
|
var/list/data = list()
|
|
// Just grab the stuff internally
|
|
scanner.update_ui(user, data)
|
|
return data
|
|
|
|
// Messenger //
|
|
/datum/pai_software/messenger
|
|
name = "Digital Messenger"
|
|
id = "messenger"
|
|
default = TRUE
|
|
template_file = "pai_messenger"
|
|
ui_icon = "envelope"
|
|
|
|
/datum/pai_software/messenger/get_app_data(mob/living/silicon/pai/user)
|
|
var/list/data = list()
|
|
|
|
// Some safety checks
|
|
if(!user.pda)
|
|
CRASH("pAI found without PDA.")
|
|
|
|
var/datum/data/pda/app/messenger/PM = user.pda.find_program(/datum/data/pda/app/messenger)
|
|
if(!PM)
|
|
CRASH("pAI PDA lacks a messenger program")
|
|
|
|
// Grab the internal data
|
|
PM.update_ui(user, data)
|
|
|
|
return data
|
|
|
|
/datum/pai_software/messenger/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
|
|
if(..())
|
|
return
|
|
|
|
// Grab their messenger
|
|
var/datum/data/pda/app/messenger/PM = pai_holder.pda.find_program(/datum/data/pda/app/messenger)
|
|
// Double proxy here
|
|
PM.ui_act(action, params, ui, state)
|
|
|
|
// Radio
|
|
/datum/pai_software/radio_config
|
|
name = "Radio Configuration"
|
|
id = "radio"
|
|
default = TRUE
|
|
template_file = "pai_radio"
|
|
ui_icon = "broadcast-tower"
|
|
|
|
/datum/pai_software/radio_config/get_app_data(mob/living/silicon/pai/user)
|
|
var/list/data = list()
|
|
data["frequency"] = user.radio.frequency
|
|
data["minFrequency"] = PUBLIC_LOW_FREQ
|
|
data["maxFrequency"] = PUBLIC_HIGH_FREQ
|
|
data["broadcasting"] = user.radio.broadcasting
|
|
return data
|
|
|
|
/datum/pai_software/radio_config/ui_act(action, list/params)
|
|
if(..())
|
|
return
|
|
|
|
switch(action)
|
|
if("toggleBroadcast")
|
|
// Just toggle it
|
|
pai_holder.radio.broadcasting = !pai_holder.radio.broadcasting
|
|
|
|
if("freq")
|
|
var/new_frequency = sanitize_frequency(text2num(params["freq"]) * 10)
|
|
pai_holder.radio.set_frequency(new_frequency)
|
|
|
|
// Signaler //
|
|
/datum/pai_software/signaler
|
|
name = "Remote Signaler"
|
|
ram_cost = 5
|
|
id = "signaler"
|
|
template_file = "pai_signaler"
|
|
ui_icon = "rss"
|
|
|
|
/datum/pai_software/signaler/get_app_data(mob/living/silicon/pai/user)
|
|
var/list/data = list()
|
|
|
|
data["frequency"] = user.integ_signaler.frequency
|
|
data["code"] = user.integ_signaler.code
|
|
data["minFrequency"] = PUBLIC_LOW_FREQ
|
|
data["maxFrequency"] = PUBLIC_HIGH_FREQ
|
|
|
|
return data
|
|
|
|
/datum/pai_software/signaler/ui_act(action, list/params)
|
|
if(..())
|
|
return
|
|
|
|
switch(action)
|
|
if("signal")
|
|
|
|
pai_holder.integ_signaler.activate()
|
|
|
|
if("freq")
|
|
pai_holder.integ_signaler.frequency = sanitize_frequency(text2num(params["freq"]) * 10)
|
|
|
|
if("code")
|
|
pai_holder.integ_signaler.code = clamp(text2num(params["code"]), 1, 100)
|
|
|
|
// Door Jack //
|
|
/datum/pai_software/door_jack
|
|
name = "Door Jack"
|
|
ram_cost = 30
|
|
id = "door_jack"
|
|
template_file = "pai_doorjack"
|
|
ui_icon = "door-open"
|
|
/// Progress on hacking the door
|
|
var/progress = 0
|
|
/// Are we hacking?
|
|
var/hacking = FALSE
|
|
/// The cable being plugged into a door
|
|
var/obj/item/pai_cable/cable
|
|
/// The door being hacked
|
|
var/obj/machinery/door/hackdoor
|
|
|
|
/datum/pai_software/door_jack/get_app_data(mob/living/silicon/pai/user)
|
|
var/list/data = list()
|
|
|
|
data["cable"] = (cable != null)
|
|
data["machine"] = (cable?.machine != null)
|
|
data["inprogress"] = (hackdoor != null)
|
|
data["progress"] = progress
|
|
|
|
return data
|
|
|
|
/datum/pai_software/door_jack/ui_act(action, list/params)
|
|
if(..())
|
|
return
|
|
|
|
switch(action)
|
|
if("jack")
|
|
if(cable && cable.machine)
|
|
hackdoor = cable.machine
|
|
if(hacking)
|
|
to_chat(usr, "<span class='warning'>You are already hacking that door!</span>")
|
|
else
|
|
hacking = TRUE
|
|
INVOKE_ASYNC(src, PROC_REF(hackloop))
|
|
if("cancel")
|
|
hackdoor = null
|
|
if("cable")
|
|
playsound(pai_holder, 'sound/mecha/mechmove03.ogg', 25, TRUE)
|
|
if(cable) // Retracting
|
|
pai_holder.visible_message("<span class='warning'>[cable] is pulled back into [pai_holder] with a quick snap.</span>")
|
|
QDEL_NULL(cable)
|
|
else // Extending
|
|
cable = new /obj/item/pai_cable(get_turf(pai_holder))
|
|
pai_holder.visible_message("<span class='warning'>A port on [pai_holder] opens to reveal [cable], which promptly falls to the floor.</span>")
|
|
|
|
/**
|
|
* Door jack hack loop
|
|
*
|
|
* Self-contained proc for handling the hacking of a door.
|
|
* Invoked asyncly, but will only allow one instance at a time
|
|
*/
|
|
/datum/pai_software/door_jack/proc/hackloop()
|
|
var/obj/machinery/door/D = cable.machine
|
|
if(!istype(D))
|
|
cleanup_hack()
|
|
return
|
|
while(progress < 100)
|
|
if(cable && cable.machine == D && cable.machine == hackdoor && get_dist(pai_holder, hackdoor) <= 1)
|
|
progress = min(progress + rand(1, 20), 100)
|
|
else
|
|
cleanup_hack()
|
|
return
|
|
if(progress >= 100)
|
|
D.open()
|
|
cleanup_hack()
|
|
return
|
|
sleep(1 SECONDS) // Update every second
|
|
|
|
/**
|
|
* Door jack cleanup proc
|
|
*
|
|
* Self-contained proc for cleaning up failed hack attempts
|
|
*/
|
|
/datum/pai_software/door_jack/proc/cleanup_hack()
|
|
progress = 0
|
|
hackdoor = null
|
|
cable.machine = null
|
|
QDEL_NULL(cable)
|
|
hacking = FALSE
|
|
|
|
// Host Bioscan //
|
|
/datum/pai_software/host_scan
|
|
name = "Host Bioscan"
|
|
ram_cost = 5
|
|
id = "bioscan"
|
|
template_file = "pai_bioscan"
|
|
ui_icon = "heartbeat"
|
|
|
|
/datum/pai_software/host_scan/get_app_data(mob/living/silicon/pai/user)
|
|
var/list/data = list()
|
|
|
|
var/mob/living/held = get_holding_mob(FALSE)
|
|
|
|
if(isliving(held))
|
|
data["holder"] = held.name
|
|
data["dead"] = (held.stat > UNCONSCIOUS)
|
|
data["health"] = held.health
|
|
data["brute"] = held.getBruteLoss()
|
|
data["oxy"] = held.getOxyLoss()
|
|
data["tox"] = held.getToxLoss()
|
|
data["burn"] = held.getFireLoss()
|
|
|
|
return data
|