mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-15 18:14:22 +01:00
Adds AI Integrity restorer to program datums, various modular computer improvements (#21546)
* Ports AI restorer to modular computars * mostly done. working on qdel improvments * undoes testing flag * undoes gc stuff * Fixes id card module name * memes
This commit is contained in:
@@ -62,6 +62,7 @@
|
||||
for(var/H in all_components)
|
||||
var/obj/item/weapon/computer_hardware/CH = all_components[H]
|
||||
if(CH.holder == src)
|
||||
CH.on_remove(src)
|
||||
CH.holder = null
|
||||
qdel(CH)
|
||||
return ..()
|
||||
@@ -73,6 +74,8 @@
|
||||
verbs += /obj/item/device/modular_computer/proc/eject_id
|
||||
if(MC_SDD)
|
||||
verbs += /obj/item/device/modular_computer/proc/eject_disk
|
||||
if(MC_AI)
|
||||
verbs += /obj/item/device/modular_computer/proc/eject_card
|
||||
|
||||
/obj/item/device/modular_computer/proc/remove_verb(path)
|
||||
switch(path)
|
||||
@@ -80,6 +83,8 @@
|
||||
verbs -= /obj/item/device/modular_computer/proc/eject_id
|
||||
if(MC_SDD)
|
||||
verbs -= /obj/item/device/modular_computer/proc/eject_disk
|
||||
if(MC_AI)
|
||||
verbs -= /obj/item/device/modular_computer/proc/eject_card
|
||||
|
||||
// Eject ID card from computer, if it has ID slot with card inside.
|
||||
/obj/item/device/modular_computer/proc/eject_id()
|
||||
@@ -91,13 +96,24 @@
|
||||
return
|
||||
var/obj/item/weapon/computer_hardware/card_slot/card_slot = all_components[MC_CARD]
|
||||
if(usr.canUseTopic(src))
|
||||
card_slot.try_eject(, usr)
|
||||
card_slot.try_eject(null, usr)
|
||||
|
||||
// Eject ID card from computer, if it has ID slot with card inside.
|
||||
/obj/item/device/modular_computer/proc/eject_card()
|
||||
set name = "Eject Intellicard"
|
||||
set category = "Object"
|
||||
|
||||
if(issilicon(usr))
|
||||
return
|
||||
var/obj/item/weapon/computer_hardware/ai_slot/ai_slot = all_components[MC_AI]
|
||||
if(usr.canUseTopic(src))
|
||||
ai_slot.try_eject(null, usr,1)
|
||||
|
||||
|
||||
// Eject ID card from computer, if it has ID slot with card inside.
|
||||
/obj/item/device/modular_computer/proc/eject_disk()
|
||||
set name = "Eject Data Disk"
|
||||
set category = "Object"
|
||||
set src in view(1)
|
||||
|
||||
if(issilicon(usr))
|
||||
return
|
||||
@@ -114,12 +130,16 @@
|
||||
|
||||
if(user.canUseTopic(src))
|
||||
var/obj/item/weapon/computer_hardware/card_slot/card_slot = all_components[MC_CARD]
|
||||
var/obj/item/weapon/computer_hardware/ai_slot/ai_slot = all_components[MC_AI]
|
||||
var/obj/item/weapon/computer_hardware/hard_drive/portable/portable_drive = all_components[MC_SDD]
|
||||
if(portable_drive)
|
||||
if(uninstall_component(portable_drive, user))
|
||||
portable_drive.verb_pickup()
|
||||
else if(card_slot)
|
||||
card_slot.try_eject(, user)
|
||||
else
|
||||
if(card_slot && card_slot.try_eject(null, user))
|
||||
return
|
||||
if(ai_slot)
|
||||
ai_slot.try_eject(null, user)
|
||||
|
||||
|
||||
// Gets IDs/access levels from card slot. Would be useful when/if PDAs would become modular PCs.
|
||||
|
||||
@@ -63,10 +63,14 @@
|
||||
machinery_computer.verbs += /obj/machinery/modular_computer/proc/eject_id
|
||||
if(MC_SDD)
|
||||
machinery_computer.verbs += /obj/machinery/modular_computer/proc/eject_disk
|
||||
if(MC_AI)
|
||||
machinery_computer.verbs += /obj/machinery/modular_computer/proc/eject_card
|
||||
|
||||
/obj/item/device/modular_computer/processor/remove_verb(path)
|
||||
switch(path)
|
||||
if(MC_CARD)
|
||||
machinery_computer.verbs -= /obj/machinery/modular_computer/proc/eject_id
|
||||
if(MC_SDD)
|
||||
machinery_computer.verbs -= /obj/machinery/modular_computer/proc/eject_disk
|
||||
machinery_computer.verbs -= /obj/machinery/modular_computer/proc/eject_disk
|
||||
if(MC_AI)
|
||||
machinery_computer.verbs -= /obj/machinery/modular_computer/proc/eject_card
|
||||
@@ -3,6 +3,7 @@
|
||||
var/_has_id_slot = 0
|
||||
var/_has_printer = 0
|
||||
var/_has_battery = 0
|
||||
var/_has_ai = 0
|
||||
|
||||
/obj/machinery/modular_computer/console/preset/New()
|
||||
. = ..()
|
||||
@@ -16,6 +17,8 @@
|
||||
cpu.install_component(new /obj/item/weapon/computer_hardware/printer)
|
||||
if(_has_battery)
|
||||
cpu.install_component(new /obj/item/weapon/computer_hardware/battery(cpu, /obj/item/weapon/stock_parts/cell/computer/super))
|
||||
if(_has_ai)
|
||||
cpu.install_component(new /obj/item/weapon/computer_hardware/ai_slot)
|
||||
install_programs()
|
||||
|
||||
// Override in child types to install preset-specific programs.
|
||||
@@ -38,12 +41,14 @@
|
||||
/obj/machinery/modular_computer/console/preset/research
|
||||
console_department = "Research"
|
||||
desc = "A stationary computer. This one comes preloaded with research programs."
|
||||
_has_ai = 1
|
||||
|
||||
/obj/machinery/modular_computer/console/preset/research/install_programs()
|
||||
var/obj/item/weapon/computer_hardware/hard_drive/hard_drive = cpu.all_components[MC_HDD]
|
||||
hard_drive.store_file(new/datum/computer_file/program/ntnetmonitor())
|
||||
hard_drive.store_file(new/datum/computer_file/program/nttransfer())
|
||||
hard_drive.store_file(new/datum/computer_file/program/chatclient())
|
||||
hard_drive.store_file(new/datum/computer_file/program/aidiag())
|
||||
|
||||
|
||||
// ===== COMMAND CONSOLE =====
|
||||
|
||||
@@ -74,7 +74,6 @@ var/list/global_modular_computers = list()
|
||||
/obj/machinery/modular_computer/proc/eject_id()
|
||||
set name = "Eject ID"
|
||||
set category = "Object"
|
||||
set src in view(1)
|
||||
|
||||
if(cpu)
|
||||
cpu.eject_id()
|
||||
@@ -83,11 +82,18 @@ var/list/global_modular_computers = list()
|
||||
/obj/machinery/modular_computer/proc/eject_disk()
|
||||
set name = "Eject Data Disk"
|
||||
set category = "Object"
|
||||
set src in view(1)
|
||||
|
||||
if(cpu)
|
||||
cpu.eject_disk()
|
||||
|
||||
/obj/machinery/modular_computer/proc/eject_card()
|
||||
set name = "Eject Intellicard"
|
||||
set category = "Object"
|
||||
set src in view(1)
|
||||
|
||||
if(cpu)
|
||||
cpu.eject_card()
|
||||
|
||||
/obj/machinery/modular_computer/AltClick(mob/user)
|
||||
if(cpu)
|
||||
cpu.AltClick(user)
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
|
||||
|
||||
/datum/computer_file/program/aidiag
|
||||
filename = "aidiag"
|
||||
filedesc = "AI Maintenance Utility"
|
||||
program_icon_state = "generic"
|
||||
extended_desc = "This program is capable of reconstructing damaged AI systems. Requires direct AI connection via intellicard slot."
|
||||
size = 12
|
||||
requires_ntnet = 0
|
||||
usage_flags = PROGRAM_CONSOLE
|
||||
transfer_access = access_heads
|
||||
available_on_ntnet = 1
|
||||
var/restoring = FALSE
|
||||
|
||||
/datum/computer_file/program/aidiag/proc/get_ai()
|
||||
|
||||
var/obj/item/weapon/computer_hardware/ai_slot/ai_slot
|
||||
|
||||
if(computer)
|
||||
ai_slot = computer.all_components[MC_AI]
|
||||
|
||||
if(computer && ai_slot && ai_slot.check_functionality() && ai_slot.enabled && ai_slot.stored_card && ai_slot.stored_card.AI)
|
||||
return ai_slot.stored_card.AI
|
||||
return null
|
||||
|
||||
/datum/computer_file/program/aidiag/ui_act(action, params)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
var/mob/living/silicon/ai/A = get_ai()
|
||||
if(!A)
|
||||
restoring = FALSE
|
||||
return FALSE
|
||||
|
||||
switch("action")
|
||||
if("PRG_beginReconstruction")
|
||||
if(A.health < 100)
|
||||
restoring = TRUE
|
||||
return TRUE
|
||||
|
||||
/datum/computer_file/program/aidiag/process_tick()
|
||||
..()
|
||||
if(!restoring) //Put the check here so we don't check for an ai all the time
|
||||
return
|
||||
|
||||
var/mob/living/silicon/ai/A = get_ai()
|
||||
if(!A)
|
||||
restoring = FALSE // If the AI was removed, stop the restoration sequence.
|
||||
return
|
||||
var/obj/item/device/aicard/cardhold = A.loc
|
||||
if(cardhold.flush)
|
||||
restoring = FALSE
|
||||
return
|
||||
A.adjustOxyLoss(-1, 0)
|
||||
A.adjustFireLoss(-1, 0)
|
||||
A.adjustToxLoss(-1, 0)
|
||||
A.adjustBruteLoss(-1, 0)
|
||||
A.updatehealth()
|
||||
if(A.health >= 0 && A.stat == DEAD)
|
||||
A.revive()
|
||||
// Finished restoring
|
||||
if(A.health >= 100)
|
||||
restoring = FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
|
||||
/datum/computer_file/program/aidiag/ui_data(mob/user)
|
||||
var/list/data = get_header_data()
|
||||
var/mob/living/silicon/ai/AI
|
||||
// A shortcut for getting the AI stored inside the computer. The program already does necessary checks.
|
||||
AI = get_ai()
|
||||
|
||||
if(!AI)
|
||||
data["error"] = "No AI located"
|
||||
else
|
||||
var/obj/item/device/aicard/cardhold = AI.loc
|
||||
if(cardhold.flush)
|
||||
data["error"] = "Flush in progress"
|
||||
else
|
||||
data["name"] = AI.name
|
||||
data["restoring"] = restoring
|
||||
data["laws"] = AI.laws.get_law_list(include_zeroth = 1)
|
||||
data["health"] = (AI.health + 100) / 2
|
||||
data["isDead"] = AI.stat == DEAD
|
||||
data["ai_laws"] = AI.laws.get_law_list(include_zeroth = 1)
|
||||
|
||||
return data
|
||||
|
||||
/datum/computer_file/program/aidiag/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "ai_restorer", "Integrity Restorer", 600, 400, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
datum/computer_file/program/aidiag/kill_program(forced)
|
||||
restoring = FALSE
|
||||
return ..(forced)
|
||||
@@ -12,6 +12,7 @@
|
||||
size = 5
|
||||
var/has_alert = 0
|
||||
var/alarms = list("Fire" = list(), "Atmosphere" = list(), "Power" = list())
|
||||
var/alarm_z = list(ZLEVEL_STATION,ZLEVEL_LAVALAND)
|
||||
|
||||
/datum/computer_file/program/alarm_monitor/process_tick()
|
||||
..()
|
||||
@@ -49,6 +50,9 @@
|
||||
|
||||
/datum/computer_file/program/alarm_monitor/proc/triggerAlarm(class, area/A, O, obj/source)
|
||||
|
||||
if(!(source.z in alarm_z))
|
||||
return
|
||||
|
||||
var/list/L = alarms[class]
|
||||
for(var/I in L)
|
||||
if (I == A.name)
|
||||
|
||||
@@ -145,6 +145,7 @@
|
||||
"filename" = P.filename,
|
||||
"filedesc" = P.filedesc,
|
||||
"fileinfo" = P.extended_desc,
|
||||
"compatibility" = check_compatibility(P),
|
||||
"size" = P.size
|
||||
)))
|
||||
data["hackedavailable"] = 0
|
||||
@@ -165,6 +166,13 @@
|
||||
|
||||
return data
|
||||
|
||||
/datum/computer_file/program/ntnetdownload/proc/check_compatibility(datum/computer_file/program/P)
|
||||
var/hardflag = computer.hardware_flag
|
||||
|
||||
if(P && P.is_supported_by_hardware(hardflag,0))
|
||||
return "Compatible"
|
||||
return "Incompatible!"
|
||||
|
||||
/datum/computer_file/program/ntnetdownload/kill_program(forced)
|
||||
abort_file_download()
|
||||
return ..(forced)
|
||||
@@ -92,12 +92,12 @@
|
||||
|
||||
// Called when component is removed from PC.
|
||||
/obj/item/weapon/computer_hardware/proc/on_remove(obj/item/device/modular_computer/M, mob/living/user = null)
|
||||
try_eject()
|
||||
try_eject(forced = 1)
|
||||
|
||||
// Called when someone tries to insert something in it - paper in printer, card in card reader, etc.
|
||||
/obj/item/weapon/computer_hardware/proc/try_insert(obj/item/I, mob/living/user = null)
|
||||
return FALSE
|
||||
|
||||
// Called when someone tries to eject something from it - card from card reader, etc.
|
||||
/obj/item/weapon/computer_hardware/proc/try_eject(slot=0, mob/living/user = null)
|
||||
/obj/item/weapon/computer_hardware/proc/try_eject(slot=0, mob/living/user = null, forced = 0)
|
||||
return FALSE
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
/obj/item/weapon/computer_hardware/ai_slot
|
||||
name = "intelliCard interface slot"
|
||||
desc = "A module allowing this computer to interface with most common intelliCard modules. Necessary for some programs to run properly."
|
||||
power_usage = 100 //W
|
||||
icon_state = "card_mini"
|
||||
w_class = 2
|
||||
origin_tech = "programming=2"
|
||||
device_type = MC_AI
|
||||
|
||||
var/obj/item/device/aicard/stored_card = null
|
||||
var/locked = FALSE
|
||||
|
||||
|
||||
obj/item/weapon/computer_hardware/ai_slot/examine(mob/user)
|
||||
..()
|
||||
if(stored_card)
|
||||
user << "There appears to be an intelliCard loaded."
|
||||
|
||||
/obj/item/weapon/computer_hardware/ai_slot/on_install(obj/item/device/modular_computer/M, mob/living/user = null)
|
||||
M.add_verb(device_type)
|
||||
|
||||
/obj/item/weapon/computer_hardware/ai_slot/on_remove(obj/item/device/modular_computer/M, mob/living/user = null)
|
||||
M.remove_verb(device_type)
|
||||
|
||||
/obj/item/weapon/computer_hardware/ai_slot/try_insert(obj/item/I, mob/living/user = null)
|
||||
if(!holder)
|
||||
return FALSE
|
||||
|
||||
if(!istype(I, /obj/item/device/aicard))
|
||||
return FALSE
|
||||
|
||||
if(stored_card)
|
||||
user << "<span class='warning'>You try to insert \the [I] into \the [src], but the slot is occupied.</span>"
|
||||
return FALSE
|
||||
if(user && !user.unEquip(I))
|
||||
return FALSE
|
||||
|
||||
|
||||
stored_card = I
|
||||
|
||||
I.forceMove(src)
|
||||
user << "<span class='notice'>You insert \the [I] into \the [src].</span>"
|
||||
|
||||
return TRUE
|
||||
|
||||
|
||||
/obj/item/weapon/computer_hardware/ai_slot/try_eject(forced = 0,mob/living/user = null)
|
||||
if(!stored_card)
|
||||
user << "<span class='warning'>There is no card in \the [src].</span>"
|
||||
return FALSE
|
||||
|
||||
if(locked && !forced)
|
||||
user << "<span class='warning'>Safeties prevent you from removing the card while reconstruction is in progress...</span>"
|
||||
return FALSE
|
||||
|
||||
if(stored_card)
|
||||
stored_card.forceMove(get_turf(src))
|
||||
locked = FALSE
|
||||
stored_card.verb_pickup()
|
||||
stored_card = null
|
||||
|
||||
user << "<span class='notice'>You remove the card from \the [src].</span>"
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/weapon/computer_hardware/ai_slot/attackby(obj/item/I, mob/living/user)
|
||||
if(..())
|
||||
return
|
||||
if(istype(I, /obj/item/weapon/screwdriver))
|
||||
user << "<span class='notice'>You press down on the manual eject button with \the [I].</span>"
|
||||
try_eject(,user,1)
|
||||
return
|
||||
@@ -38,7 +38,7 @@
|
||||
return TRUE
|
||||
|
||||
|
||||
/obj/item/weapon/computer_hardware/battery/try_eject(slot=0, mob/living/user = null)
|
||||
/obj/item/weapon/computer_hardware/battery/try_eject(slot=0, mob/living/user = null, forced = 0)
|
||||
if(!battery)
|
||||
user << "<span class='warning'>There is no power cell connected to \the [src].</span>"
|
||||
return FALSE
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/obj/item/weapon/computer_hardware/card_slot
|
||||
name = "\improper ID authentication module"
|
||||
name = "identification card authentication module" // \improper breaks the find_hardware_by_name proc
|
||||
desc = "A module allowing this computer to read or write data on ID cards. Necessary for some programs to run properly."
|
||||
power_usage = 10 //W
|
||||
icon_state = "card_mini"
|
||||
@@ -59,7 +59,7 @@
|
||||
return TRUE
|
||||
|
||||
|
||||
/obj/item/weapon/computer_hardware/card_slot/try_eject(slot=0, mob/living/user = null)
|
||||
/obj/item/weapon/computer_hardware/card_slot/try_eject(slot=0, mob/living/user = null, forced = 0)
|
||||
if(!stored_card && !stored_card2)
|
||||
user << "<span class='warning'>There are no cards in \the [src].</span>"
|
||||
return FALSE
|
||||
@@ -89,3 +89,16 @@
|
||||
user << "<span class='notice'>You remove the card[ejected>1 ? "s" : ""] from \the [src].</span>"
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/weapon/computer_hardware/card_slot/attackby(obj/item/I, mob/living/user)
|
||||
if(..())
|
||||
return
|
||||
if(istype(I, /obj/item/weapon/screwdriver))
|
||||
user << "<span class='notice'>You press down on the manual eject button with \the [I].</span>"
|
||||
try_eject(0,user)
|
||||
return
|
||||
|
||||
/obj/item/weapon/computer_hardware/card_slot/examine(mob/user)
|
||||
..()
|
||||
if(stored_card || stored_card2)
|
||||
user << "There appears to be something loaded in the card slots."
|
||||
Reference in New Issue
Block a user