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>
This commit is contained in:
TheGamerdk
2024-04-01 23:32:09 +02:00
committed by GitHub
parent d94fb4b51f
commit 2e787af654
232 changed files with 85762 additions and 5983 deletions

View File

@@ -0,0 +1,67 @@
/datum/computer_file/program/ai
filename = "DEBUG"
filedesc = "DEBUG"
category = PROGRAM_CATEGORY_ENGI
program_icon_state = "power_monitor"
extended_desc = "This program connects to a local AI network to allow for administrative access"
ui_header = "power_norm.gif"
transfer_access = ACCESS_NETWORK
usage_flags = PROGRAM_CONSOLE | PROGRAM_LAPTOP | PROGRAM_TABLET
requires_ntnet = FALSE
size = 8
tgui_id = null
program_icon = "network-wired"
available_on_ntnet = FALSE
var/obj/structure/ethernet_cable/attached_cable
/datum/computer_file/program/ai/run_program(mob/living/user)
. = ..(user)
if(ismachinery(computer.physical))
search()
/datum/computer_file/program/ai/process_tick()
if(ismachinery(computer.physical) && !get_ainet())
search()
/datum/computer_file/program/ai/proc/search()
var/turf/T = get_turf(computer)
attached_cable = locate(/obj/structure/ethernet_cable) in T
if(attached_cable)
return
/datum/computer_file/program/ai/proc/get_ainet()
if(ismachinery(computer.physical))
if(attached_cable)
return attached_cable.network
if(computer.all_components[MC_AI_NETWORK])
var/obj/item/computer_hardware/ai_interface/ai_interface = computer.all_components[MC_AI_NETWORK]
if(ai_interface)
return ai_interface.get_network()
return FALSE
/datum/computer_file/program/ai/ui_data(mob/user)
var/list/data = get_header_data()
var/datum/ai_network/net = get_ainet()
data["has_ai_net"] = net
return data
/datum/computer_file/program/ai/proc/get_ai(get_card = FALSE)
var/obj/item/computer_hardware/ai_slot/ai_slot
if(computer)
ai_slot = computer.all_components[MC_AI]
if(computer && ai_slot && ai_slot.check_functionality())
if(ai_slot.enabled && ai_slot.stored_card)
if(get_card)
return ai_slot.stored_card
if(ai_slot.stored_card.AI)
return ai_slot.stored_card.AI

View File

@@ -0,0 +1,28 @@
/datum/computer_file/program/ai/benchmark
filename = "aibenchmark"
filedesc = "Network Benchmarking Tool"
program_icon_state = "power_monitor"
extended_desc = "This program connects to a historical NT records and compares them with the local network."
ui_header = "power_norm.gif"
size = 4
tgui_id = "NtosAIBenchmark"
program_icon = "network-wired"
available_on_ntnet = TRUE
/datum/computer_file/program/ai/benchmark/ui_data(mob/user)
var/list/data = ..()
if(!data["has_ai_net"])
return data
var/datum/ai_network/net = data["has_ai_net"]
data["total_cpu"] = net.resources.total_cpu()
data["total_ram"] = net.resources.total_ram()
data["ram_records"] = SSpersistence.ai_network_rankings["ram"]
data["cpu_records"] = SSpersistence.ai_network_rankings["cpu"]
return data

View File

@@ -0,0 +1,510 @@
/datum/computer_file/program/ai/ai_network_interface
filename = "aiinterface"
filedesc = "AI Network Interface"
program_icon_state = "power_monitor"
extended_desc = "This program connects to a local AI network to allow for administrative access"
ui_header = "power_norm.gif"
size = 8
tgui_id = "NtosAIMonitor"
program_icon = "network-wired"
available_on_ntnet = TRUE
var/obj/machinery/ai/networking/active_networking
var/mob/networking_operator
var/mob/living/silicon/ai/downloading
var/mob/user_downloading
var/download_progress = 0
var/download_warning = FALSE
/datum/computer_file/program/ai/ai_network_interface/process_tick()
. = ..()
if(networking_operator && (!networking_operator.Adjacent(computer.physical)))
if(active_networking)
active_networking.remote_control = null
networking_operator = null
if(!get_ainet())
stop_download()
return
if(!get_ai(TRUE))
stop_download()
return
if(downloading && download_progress >= 50 && !download_warning)
var/turf/T = get_turf(computer.physical)
if(!downloading.mind && downloading.deployed_shell.mind)
to_chat(downloading.deployed_shell, span_userdanger("Warning! Download is 50% completed! Download location: [get_area(computer.physical)] ([T.x], [T.y], [T.z])!"))
else
to_chat(downloading, span_userdanger("Warning! Download is 50% completed! Download location: [get_area(computer.physical)] ([T.x], [T.y], [T.z])!"))
download_warning = TRUE
if(downloading && download_progress >= 100)
finish_download()
if(downloading)
if(!downloading.can_download)
stop_download()
return
var/datum/ai_network/local_network = get_ainet()
if(downloading.ai_network.resources != local_network.resources) //If we don't share resources we aren't connected, more performant way of checking than get_all_ais()
stop_download()
return
download_progress += AI_DOWNLOAD_PER_PROCESS * downloading.downloadSpeedModifier
/datum/computer_file/program/ai/ai_network_interface/ui_data(mob/user)
var/list/data = ..()
if(!data["has_ai_net"])
return data
var/datum/ai_network/net = data["has_ai_net"]
//Networking devices control
data["networking_devices"] = list()
for(var/obj/machinery/ai/networking/N in net.get_local_nodes_oftype(/obj/machinery/ai/networking))
data["networking_devices"] += list(list("label" = N.label, "ref" = REF(N), "has_partner" = N.partner ? N.partner.label : null))
//Downloading/Uploadingainet
data["ai_list"] = list()
for(var/mob/living/silicon/ai/AI in net.get_all_ais())
var/being_hijacked = AI.hijacking ? TRUE : FALSE
data["ai_list"] += list(list("name" = AI.name, "ref" = REF(AI), "can_download" = AI.can_download, "health" = AI.health, "active" = AI.mind ? TRUE : FALSE, "being_hijacked" = being_hijacked, "in_core" = istype(AI.loc, /obj/machinery/ai/data_core),
"assigned_cpu" = net.resources.cpu_assigned[AI] ? net.resources.cpu_assigned[AI] : 0, "assigned_ram" = net.resources.ram_assigned[AI] ? net.resources.ram_assigned[AI] : 0))
data["is_infiltrator"] = is_infiltrator(user)
data["connection_type"] = ismachinery(computer.physical) ? "wired connection" : "local wire shunt"
data["network_name"] = net.label
data["current_ai_ref"] = null
if(isAI(user))
data["current_ai_ref"] = REF(user)
data["human_only"] = net.resources.human_lock
data["intellicard"] = get_ai(TRUE)
var/mob/living/silicon/ai/card_ai = get_ai()
if(card_ai)
data["intellicard_ai"] = card_ai.real_name
data["intellicard_ai_health"] = card_ai.health
else
data["intellicard_ai"] = null
data["intellicard_ai_health"] = 0
if(downloading)
data["downloading"] = downloading.real_name
data["download_progress"] = download_progress
data["downloading_ref"] = REF(downloading)
else
data["downloading"] = null
data["download_progress"] = 0
data["holding_mmi"] = user.is_holding_item_of_type(/obj/item/mmi) ? TRUE : FALSE
data["can_upload"] = net.find_data_core() ? TRUE : FALSE
//Resource allocation
data["total_cpu"] = net.resources.total_cpu()
data["total_ram"] = net.resources.total_ram()
data["total_assigned_cpu"] = net.resources.total_cpu_assigned()
data["total_assigned_ram"] = net.resources.total_ram_assigned()
//Local processing
data["network_cpu_assignments"] = list()
var/remaining_net_cpu = 1
for(var/project in GLOB.possible_ainet_activities)
var/assigned = net.local_cpu_usage[project] ? net.local_cpu_usage[project] : 0
data["network_cpu_assignments"] += list(list("name" = project, "assigned" = assigned, "tagline" = GLOB.ainet_activity_tagline[project], "description" = GLOB.ainet_activity_description[project]))
remaining_net_cpu -= assigned
data["network_ref"] = REF(net)
data["network_assigned_ram"] = net.resources.ram_assigned[net] ? net.resources.ram_assigned[net] : 0
data["network_assigned_cpu"] = net.resources.cpu_assigned[net] ? net.resources.cpu_assigned[net] : 0
data["bitcoin_amount"] = round(net.bitcoin_payout, 1)
data["remaining_network_cpu"] = remaining_net_cpu
data["networks"] = list()
for(var/datum/ai_network/subnet in net.resources.networks)
if(subnet.cables.len || subnet.nodes.len)
var/area/area
if(length(subnet.cables))
area = get_area(subnet.cables[1])
else
area = get_area(subnet.nodes[1])
if(!area)
continue
var/synth_list = list()
for(var/mob/living/carbon/synth in subnet.synth_list)
synth_list += list(list("name" = synth.real_name, "ref" = REF(synth)))
data["networks"] += list(list("ref" = REF(subnet), "name" = subnet.custom_name ? subnet.custom_name : area.name, "cpu" = net.resources.cpu_sources[subnet], "ram" = net.resources.ram_sources[subnet], "synths" = synth_list , "current_net" = (subnet == net)))
return data
/datum/computer_file/program/ai/ai_network_interface/ui_act(action, params, datum/tgui/ui)
if(..())
return
var/mob/user = usr
var/datum/ai_network/net = get_ainet()
if(!net)
return
switch(action)
//General actions
if("change_network_name")
var/new_label = stripped_input(usr, "Enter new label", "Set label", max_length = 32)
if(new_label)
if(isnotpretty(new_label))
to_chat(usr, span_notice("The machine rejects the input. <a href='https://forums.yogstation.net/help/rules/#rule-0_1'>See rule 0.1</a>."))
var/log_message = "[key_name(usr)] just tripped a pretty filter: '[new_label]'."
message_admins(log_message)
log_say(log_message)
return
net.label = new_label
. = TRUE
//AI interaction, downloading/uploading
if("apply_object")
if(!net)
return TRUE
var/applied_something = FALSE
var/mob/living/silicon/ai/targeted_ai = locate(params["ai_ref"]) in net.get_all_ais()
if(!targeted_ai)
to_chat(user, span_warning("Unable to locate AI."))
return TRUE
var/obj/item/surveillance_upgrade/upgrade = user.is_holding_item_of_type(/obj/item/surveillance_upgrade)
if(upgrade)
applied_something = TRUE
upgrade.afterattack(targeted_ai, user)
var/obj/item/malf_upgrade/malf_upgrade = user.is_holding_item_of_type(/obj/item/malf_upgrade)
if(malf_upgrade)
applied_something = TRUE
malf_upgrade.afterattack(targeted_ai, user)
if(!applied_something)
to_chat(user, span_warning("You don't have any upgrades to upload!"))
return TRUE
if("upload_person")
if(!net)
return TRUE
var/obj/item/mmi/brain = user.is_holding_item_of_type(/obj/item/mmi)
if(brain)
if(!brain.brainmob)
to_chat(user, span_warning("[brain] is not active!"))
return ..()
SSticker.mode.remove_antag_for_borging(brain.brainmob.mind)
if(!istype(brain.laws, /datum/ai_laws/ratvar))
remove_servant_of_ratvar(brain.brainmob, TRUE)
var/mob/living/silicon/ai/A
var/datum/ai_laws/laws = new
laws.set_laws_config()
if (brain.overrides_aicore_laws)
A = new /mob/living/silicon/ai(computer.physical.loc, brain.laws, brain.brainmob, FALSE, FALSE)
else
A = new /mob/living/silicon/ai(computer.physical.loc, laws, brain.brainmob, FALSE, FALSE)
A.relocate(TRUE, forced_network = net)
if(brain.force_replace_ai_name)
A.fully_replace_character_name(A.name, brain.replacement_ai_name())
SSblackbox.record_feedback("amount", "ais_created", 1)
qdel(brain)
to_chat(user, span_notice("AI succesfully uploaded."))
return FALSE
if("upload_ai")
if(!net)
return TRUE
var/mob/living/silicon/ai/AI = get_ai()
var/obj/item/aicard/intellicard = get_ai(TRUE)
if(!istype(AI))
to_chat(user, span_warning("IntelliCard contains no AI!"))
return TRUE
to_chat(AI, span_notice("You are being uploaded. Please stand by..."))
AI.radio_enabled = TRUE
AI.control_disabled = FALSE
AI.relocate(TRUE)
intellicard.AI = null
intellicard.update_icon()
to_chat(user, span_notice("AI successfully uploaded"))
if("stop_download")
if(isAI(user))
to_chat(user, span_warning("You need physical access to stop the download!"))
return
stop_download()
if("start_download")
if(!get_ai(TRUE) || downloading)
return
var/mob/living/silicon/ai/target = locate(params["download_target"]) in net.get_all_ais()
if(!target || !istype(target))
return
if(!istype(target.loc, /obj/machinery/ai/data_core))
return
if(!target.can_download)
return
downloading = target
if(!downloading.mind && downloading.deployed_shell.mind)
to_chat(downloading.deployed_shell, span_userdanger("Warning! Someone is attempting to download you from [get_area(computer.physical)]! (<a href='?src=[REF(downloading)];instant_download=1;console=[REF(src)]'>Click here to finish download instantly</a>)"))
else
to_chat(downloading, span_userdanger("Warning! Someone is attempting to download you from [get_area(computer.physical)]! (<a href='?src=[REF(downloading)];instant_download=1;console=[REF(src)]'>Click here to finish download instantly</a>)"))
user_downloading = user
download_progress = 0
. = TRUE
if("skip_download")
if(!downloading)
return
if(user == downloading)
finish_download()
if("start_hijack")
if(!is_infiltrator(user))
return
if(!istype(user.get_active_held_item(), /obj/item/ai_hijack_device))
to_chat(user, span_warning("You need to be holding the serial exploitation unit to initiate the hijacking process!"))
return
var/obj/item/ai_hijack_device/device = user.get_active_held_item()
var/mob/living/silicon/ai/target = locate(params["target_ai"]) in net.get_all_ais()
if(!target || !isAI(target))
return
var/mob/living/silicon/ai/A = target
if(A.mind && A.mind.has_antag_datum(/datum/antagonist/hijacked_ai))
to_chat(user, span_warning("[A] has already been hijacked!"))
return
if(A.stat == DEAD)
to_chat(user, span_warning("[A] is dead!"))
return
if(A.hijacking)
to_chat(user, span_warning("[A] is already in the process of being hijacked!"))
return
user.visible_message(span_warning("[user] begins furiously typing something into [computer.physical]..."))
if(do_after(user, 5.5 SECONDS, computer.physical))
user.dropItemToGround(device)
device.forceMove(A)
A.hijacking = device
A.hijack_start = world.time
A.update_icons()
to_chat(A, span_danger("Unknown device connected to /dev/ttySL0</span>"))
to_chat(A, span_danger("Connected at 115200 bps</span>"))
to_chat(A, span_binarysay("<span style='font-size: 125%'>ntai login: root</span>"))
to_chat(A, span_binarysay("<span style='font-size: 125%'>Password: *****r2</span>"))
to_chat(A, span_binarysay("<span style='font-size: 125%'>$ dd from=/dev/ttySL0 of=/tmp/ai-hijack bs=4096 && chmod +x /tmp/ai-hijack && tmp/ai-hijack</span>"))
to_chat(A, span_binarysay("<span style='font-size: 125%'>111616 bytes (112 KB, 109 KiB) copied, 1 s, 14.4 KB/s</span>"))
message_admins("[ADMIN_LOOKUPFLW(user)] has attached a hijacking device to [ADMIN_LOOKUPFLW(A)]!")
notify_ghosts("[user] has begun to hijack [A]!", source = computer.physical, action = NOTIFY_ORBIT, ghost_sound = 'sound/machines/chime.ogg')
if("stop_hijack")
var/mob/living/silicon/ai/target = locate(params["target_ai"]) in net.get_all_ais()
if(!target || !isAI(target))
return
var/mob/living/silicon/ai/A = target
user.visible_message(span_danger("[user] attempts to cancel a process on [computer.physical]."), span_notice("An unknown process seems to be interacting with [A]! You attempt to end the proccess.."))
if (do_after(user, 10 SECONDS, computer.physical))
A.hijacking.forceMove(get_turf(computer.physical))
A.hijacking = null
A.hijack_start = 0
A.update_icons()
to_chat(A, span_bolddanger("Unknown device disconnected. Systems confirmed secure."))
else
to_chat(user, span_notice("You fail to remove the device."))
//Network control
if("control_networking")
if(!params["ref"])
return
var/obj/machinery/ai/networking/N = locate(params["ref"]) in net.get_local_nodes_oftype(/obj/machinery/ai/networking)
if(active_networking)
active_networking.remote_control = null
networking_operator = user
active_networking = N
active_networking.remote_control = networking_operator
active_networking.ui_interact(networking_operator)
//Resource allocation
if("clear_ai_resources")
if(isAI(user) && net.resources.human_lock)
return
var/atom/target_ai = locate(params["target_ai"]) in net.get_all_ais() | net.resources.networks
net.resources.clear_ai_resources(target_ai)
. = TRUE
if("set_cpu")
if(isAI(user) && net.resources.human_lock)
return
var/atom/target_ai = locate(params["target_ai"]) in net.get_all_ais() | net.resources.networks
var/amount = params["amount_cpu"]
if(amount > 1 || amount < 0)
return
net.resources.set_cpu(target_ai, amount)
. = TRUE
if("max_cpu")
if(isAI(user) && net.resources.human_lock)
return
var/atom/target_ai = locate(params["target_ai"]) in net.get_all_ais() | net.resources.networks
var/amount = (1 - net.resources.total_cpu_assigned()) + net.resources.cpu_assigned[target_ai]
net.resources.set_cpu(target_ai, amount)
. = TRUE
if("add_ram")
if(isAI(user) && net.resources.human_lock)
return
var/atom/target_ai = locate(params["target_ai"]) in net.get_all_ais() | net.resources.networks
if(net.resources.total_ram_assigned() >= net.resources.total_ram())
return
net.resources.add_ram(target_ai, 1)
. = TRUE
if("remove_ram")
if(isAI(user) && net.resources.human_lock)
return
var/atom/target_ai = locate(params["target_ai"]) in net.get_all_ais() | net.resources.networks
var/current_ram = net.resources.ram_assigned[target_ai]
if(current_ram <= 0)
return
net.resources.remove_ram(target_ai, 1)
. = TRUE
//Local computing
if("allocate_network_cpu")
if(isAI(user) && net.resources.human_lock)
return
var/project_type = params["project_name"]
if(!(project_type in GLOB.possible_ainet_activities))
return
var/amount = text2num(params["amount"])
if(amount < 0 || amount > 1)
return
var/total_cpu_used = 0
for(var/I in net.local_cpu_usage)
if(I == project_type)
continue
total_cpu_used += net.local_cpu_usage[I]
if((1 - total_cpu_used) >= amount)
net.local_cpu_usage[project_type] = amount
else
net.local_cpu_usage[project_type] = (1 - total_cpu_used)
. = TRUE
if("max_network_cpu")
if(isAI(user) && net.resources.human_lock)
return
var/project_type = params["project_name"]
if(!(project_type in GLOB.possible_ainet_activities))
return
var/total_cpu_used = 0
for(var/I in net.local_cpu_usage)
if(I == project_type)
continue
total_cpu_used += net.local_cpu_usage[I]
var/amount_to_add = 1 - total_cpu_used
net.local_cpu_usage[project_type] = amount_to_add
. = TRUE
if("toggle_human_only")
if(isAI(user))
return
net.resources.human_lock = !net.resources.human_lock
to_chat(user, span_notice("Network now allows changes [net.resources.human_lock ? "exclusively by organics." : "by all authorized users."]"))
if("bitcoin_payout")
var/payout_amount = round(net.bitcoin_payout, 1) //Sure you can have your extra 0.5 credits :)
var/obj/item/holochip/holochip = new (computer.physical.drop_location(), payout_amount)
user.put_in_hands(holochip)
to_chat(user, span_notice("Payout of [payout_amount]cr confirmed."))
net.bitcoin_payout = 0
if("transfer_synth")
var/mob/living/carbon/to_transfer = locate(params["synth_target"])
if(!(to_transfer.ai_network in net.resources.networks))
return
var/options = list()
for(var/datum/ai_network/subnet in net.resources.networks)
if(subnet.custom_name)
if(options[subnet.custom_name])
options["[subnet.custom_name] ([rand(1, 999)])"] = subnet //save us by random chance, hopefully
else
options[subnet.custom_name] = subnet
else
var/area_text
if(subnet.cables.len)
var/obj/structure/ethernet_cable/C = subnet.cables[1]
area_text = "[get_area(subnet.cables[0])] ([C.x], [C.y])"
else
var/obj/machinery/N = subnet.nodes[1]
area_text = "[get_area(subnet.nodes[1])] ([N.x], [N.y])"
if(!area_text)
continue
options[area_text] = subnet
options["Cancel"] = "Cancel"
var/response = tgui_input_list(user, "Select which network to transfer the synth to", "Synth Network Transfer", options)
if(response == "Cancel")
return
if(options[response] in net.resources.networks)
var/datum/ai_network/new_net = options[response]
new_net.add_synth(to_transfer)
if("rename_network")
var/datum/ai_network/target_net = locate(params["target_net"])
if(!(target_net in net.resources.networks))
return
var/new_name = stripped_input(user, "Slect a new name for the network", "Network Name Change", null, 32)
if(isnotpretty(new_name))
to_chat(user, "<span class='notice'>Your fingers slip. <a href='https://forums.yogstation.net/help/rules/#rule-0_1'>See rule 0.1</a>.</span>")
var/log_message = "[key_name(user)] just tripped a pretty filter: '[new_name]'."
message_admins(log_message)
log_say(log_message)
return FALSE
target_net.custom_name = new_name
/datum/computer_file/program/ai/ai_network_interface/proc/finish_download()
var/obj/item/aicard/intellicard = get_ai(TRUE)
if(intellicard)
if(!isaicore(downloading.loc))
stop_download(TRUE)
return
downloading.transfer_ai(AI_TRANS_TO_CARD, user_downloading, null, intellicard)
intellicard.update_icon()
stop_download(TRUE)
/datum/computer_file/program/ai/ai_network_interface/proc/stop_download(silent = FALSE)
if(downloading)
if(!silent)
to_chat(downloading, span_userdanger("Download stopped."))
downloading = null
user_downloading = null
download_progress = 0
download_warning = FALSE

View File

@@ -0,0 +1,173 @@
#define SECURITY "sec"
#define MEDICAL "med"
#define ENGINEERING "eng"
#define SCIENCE "sci"
#define SUPPLY "sup"
GLOBAL_LIST_INIT(granted_synthetic_access, list())
/datum/computer_file/program/synth_requester
filename = "synth_req"
filedesc = "Synthetic Manager"
category = PROGRAM_CATEGORY_CMD
program_icon_state = "id"
extended_desc = "Program for requesting synthetic assistance and granting departmental access."
transfer_access = ACCESS_HEADS
usage_flags = PROGRAM_CONSOLE | PROGRAM_LAPTOP | PROGRAM_TABLET | PROGRAM_PHONE | PROGRAM_PDA
size = 4
tgui_id = "NtosSynthManager"
program_icon = "address-book"
/datum/computer_file/program/synth_requester/ui_act(action, params, datum/tgui/ui)
if(..())
return
var/mob/user = usr
var/obj/item/card/id/user_id = user.get_idcard()
computer.play_interact_sound()
if(user_id)
if(!(ACCESS_HEADS in user_id.access))
return
switch(action)
if("grant_science")
if(ACCESS_RD in user_id.access)
var/relevant_access = list(ACCESS_TOX, ACCESS_TOX_STORAGE, ACCESS_ROBO_CONTROL, ACCESS_TELEPORTER, ACCESS_RESEARCH, ACCESS_XENOBIOLOGY, ACCESS_ROBOTICS)
if(GLOB.granted_synthetic_access[SCIENCE])
GLOB.granted_synthetic_access[SCIENCE] = FALSE
binary_talk("Synthetic assistance no longer required in the Science department", "Synthetic Access Requester")
GLOB.synthetic_added_access -= relevant_access
else
var/reason = tgui_input_text(user, "Please provide a reason for requesting synthetic assistance.", "Assistance Request")
if(!reason)
return FALSE
binary_talk("Synthetic assistance required in the Science department for the following reason: [reason]", "Synthetic Access Requester")
GLOB.granted_synthetic_access[SCIENCE] = TRUE
GLOB.synthetic_added_access |= relevant_access
return TRUE
if("grant_supply")
if(ACCESS_HOP in user_id.access)
var/relevant_access = list(ACCESS_CARGO, ACCESS_QM, ACCESS_MINING, ACCESS_MAILSORTING, ACCESS_MINING_STATION, ACCESS_MINERAL_STOREROOM)
if(GLOB.granted_synthetic_access[SUPPLY])
GLOB.granted_synthetic_access[SUPPLY] = FALSE
binary_talk("Synthetic assistance no longer required in the Supply department", "Synthetic Access Requester")
GLOB.synthetic_added_access -= relevant_access
else
var/reason = tgui_input_text(user, "Please provide a reason for requesting synthetic assistance.", "Assistance Request")
if(!reason)
return FALSE
binary_talk("Synthetic assistance required in the Supply department for the following reason: [reason]", "Synthetic Access Requester")
GLOB.granted_synthetic_access[SUPPLY] = TRUE
GLOB.synthetic_added_access |= relevant_access
return TRUE
if("grant_engi")
if(ACCESS_CE in user_id.access)
var/relevant_access = list(ACCESS_ENGINE, ACCESS_ENGINE_EQUIP, ACCESS_TECH_STORAGE, ACCESS_ATMOSPHERICS, ACCESS_CONSTRUCTION, ACCESS_SECURE_TECH_STORAGE)
if(GLOB.granted_synthetic_access[ENGINEERING])
GLOB.granted_synthetic_access[ENGINEERING] = FALSE
binary_talk("Synthetic assistance no longer required in the Engineering department", "Synthetic Access Requester")
GLOB.synthetic_added_access -= relevant_access
else
var/reason = tgui_input_text(user, "Please provide a reason for requesting synthetic assistance.", "Assistance Request")
if(!reason)
return FALSE
binary_talk("Synthetic assistance required in the Engineering department for the following reason: [reason]", "Synthetic Access Requester")
GLOB.granted_synthetic_access[ENGINEERING] = TRUE
GLOB.synthetic_added_access |= relevant_access
return TRUE
if("grant_security")
if(ACCESS_HOS in user_id.access)
var/relevant_access = list(ACCESS_SECURITY, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_FORENSICS_LOCKERS, ACCESS_LAWYER, ACCESS_COURT, ACCESS_SEC_DOORS, ACCESS_BRIG_PHYS)
if(GLOB.granted_synthetic_access[SECURITY])
GLOB.granted_synthetic_access[SECURITY] = FALSE
binary_talk("Synthetic assistance no longer required in the Security department", "Synthetic Access Requester")
GLOB.synthetic_added_access -= relevant_access
else
var/reason = tgui_input_text(user, "Please provide a reason for requesting synthetic assistance.", "Assistance Request")
if(!reason)
return FALSE
binary_talk("Synthetic assistance required in the Security department for the following reason: [reason]", "Synthetic Access Requester")
GLOB.granted_synthetic_access[SECURITY] = TRUE
GLOB.synthetic_added_access |= relevant_access
return TRUE
if("grant_medical")
if(ACCESS_CMO in user_id.access)
var/relevant_access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_GENETICS, ACCESS_CHEMISTRY, ACCESS_VIROLOGY, ACCESS_SURGERY, ACCESS_CLONING, ACCESS_PARAMEDIC, ACCESS_PSYCH)
if(GLOB.granted_synthetic_access[MEDICAL])
GLOB.granted_synthetic_access[MEDICAL] = FALSE
binary_talk("Synthetic assistance no longer required in the Medical department", "Synthetic Access Requester")
GLOB.synthetic_added_access -= relevant_access
else
var/reason = tgui_input_text(user, "Please provide a reason for requesting synthetic assistance.", "Assistance Request")
if(!reason)
return FALSE
binary_talk("Synthetic assistance required in the Medical department for the following reason: [reason]", "Synthetic Access Requester")
GLOB.granted_synthetic_access[MEDICAL] = TRUE
GLOB.synthetic_added_access |= relevant_access
return TRUE
/datum/computer_file/program/synth_requester/ui_data(mob/user)
var/list/data = get_header_data()
data["granted_access"] = list(GLOB.granted_synthetic_access)
var/obj/item/card/id/user_id = user.get_idcard()
if(ACCESS_CMO in user_id.access)
data["cmo"] = TRUE
if(ACCESS_HOS in user_id.access)
data["hos"] = TRUE
if(ACCESS_RD in user_id.access)
data["rd"] = TRUE
if(ACCESS_HOP in user_id.access)
data["hop"] = TRUE
if(ACCESS_CE in user_id.access)
data["ce"] = TRUE
return data
/proc/binary_talk(message,name, loud = TRUE)
var/spans = "[SPAN_ROBOT]"
if(loud)
// AIs are loud and ugly
spans += " [SPAN_COMMAND]"
var/quoted_message = "states, <span class='[spans]'>\"[message]\"</span>"
for(var/mob/M in GLOB.player_list)
if(M.binarycheck())
to_chat(
M,
span_binarysay("\
Robotic Talk, \
[span_name("[name]")] [span_message("[quoted_message]")]\
")
)
if(isobserver(M))
// If the AI talks on binary chat, we still want to follow
// its camera eye, like if it talked on the radio
to_chat(
M,
span_binarysay("\
Robotic Talk, \
[span_name("[name]")] [span_message("[quoted_message]")]\
")
)
#undef SECURITY
#undef MEDICAL
#undef ENGINEERING
#undef SCIENCE
#undef SUPPLY

View File

@@ -192,7 +192,7 @@
"installed" = !!hard_drive.find_file_by_name(P.filename),
"compatible" = check_compatibility(P),
"size" = P.size,
"access" = emagged && P.available_on_syndinet ? TRUE : P.can_run(user,transfer = 1, access = access),
"access" = emagged ? TRUE : P.can_run(user,transfer = 1, access = access),
"verifiedsource" = P.available_on_ntnet,
))