Files
Bubberstation/code/modules/modular_computers/file_system/programs/airestorer.dm
SkyratBot 434c1bea7a [MIRROR] Refactor modular computer (and application) attackby into item_interaction (#28360)
* Refactor modular computer (and application) attackby into item_interaction (#84245)

## About The Pull Request

Sooooooooo I was recently notified of an issue (#84185) that popped up
from me replacing the `attackby(...)` chain on id cards, where it's no
longer possible to put money into IDs inside of PDAs by slapping it
against the PDA.
As I expected, this is because modular computers both still use
`attackby(...)`, and would call `attackby(...)` on the ID they contained
if hit with cash.

24a23009e8/code/modules/modular_computers/computers/item/computer.dm (L799)
Now this could've been an easy one line no-gbp fix where I just replace
it with a direct call to `insert_money(...)` on the ID and call it a
day!
But hey. Might as well get rid of the `attackby(...)` altogether while
we're at it.

First off, because the `attackby(...)` proc was getting quite bloated,
we split off all the specific item behaviours into `[X]_act(...)` type
procs to clean it up.
We then make those return item interaction flags, so we can call them on
`item_interaction(...)` after the right typecheck passes and immediately
return their results.
This also involves replacing the `application_attackby(...)` on
applications with an `application_item_interaction(...)`, and making it
return the item interaction flags too.

The code of each subsection isn't significantly different, though
reorganized a bit in some cases.
Like inserting a computer disks now tries to move it into the computer
_first_ before swapping out whichever disk is already in there, so it
doesn't swap out the disk if putting the new one in fails.
## Why It's Good For The Game

Fixes #84185.
Having more stuff be updated to the proper `item_interaction(...)`
system is cool and good.

* Refactor modular computer (and application) attackby into item_interaction

---------

Co-authored-by: _0Steven <42909981+00-Steven@users.noreply.github.com>
2024-06-25 16:19:55 +05:30

136 lines
4.3 KiB
Plaintext

/datum/computer_file/program/ai_restorer
filename = "ai_restore"
filedesc = "AI Manager & Restorer"
downloader_category = PROGRAM_CATEGORY_SCIENCE
program_open_overlay = "generic"
extended_desc = "Firmware Restoration Kit, capable of reconstructing damaged AI systems. Requires direct AI connection via intellicard slot."
size = 12
can_run_on_flags = PROGRAM_CONSOLE | PROGRAM_LAPTOP
download_access = list(ACCESS_RD)
tgui_id = "NtosAiRestorer"
program_icon = "laptop-code"
/// The AI stored in the program
var/obj/item/aicard/stored_card
/// Variable dictating if we are in the process of restoring the AI in the inserted intellicard
var/restoring = FALSE
/datum/computer_file/program/ai_restorer/on_examine(obj/item/modular_computer/source, mob/user)
var/list/examine_text = list()
if(!stored_card)
examine_text += "It has a slot installed for an intelliCard."
return examine_text
if(computer.Adjacent(user))
examine_text += "It has a slot installed for an intelliCard which contains: [stored_card.name]"
else
examine_text += "It has a slot installed for an intelliCard, which appears to be occupied."
examine_text += span_info("Alt-click to eject the intelliCard.")
return examine_text
/datum/computer_file/program/ai_restorer/kill_program(mob/user)
try_eject(forced = TRUE)
return ..()
/datum/computer_file/program/ai_restorer/process_tick(seconds_per_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 = stored_card.AI
if(stored_card.flush)
restoring = FALSE
return
A.adjustOxyLoss(-5, FALSE)
A.adjustFireLoss(-5, FALSE)
A.adjustBruteLoss(-5, FALSE)
// Please don't forget to update health, otherwise the below if statements will probably always fail.
A.updatehealth()
if(A.health >= 0 && A.stat == DEAD)
A.revive()
stored_card.update_appearance()
// Finished restoring
if(A.health >= 100)
restoring = FALSE
return TRUE
/datum/computer_file/program/ai_restorer/application_item_interaction(mob/living/user, obj/item/tool, list/modifiers)
if(istype(tool, /obj/item/aicard))
return aicard_act(user, tool)
/datum/computer_file/program/ai_restorer/proc/aicard_act(mob/living/user, obj/item/aicard/used_aicard)
if(!computer)
return NONE
if(stored_card)
to_chat(user, span_warning("You try to insert \the [used_aicard] into \the [computer.name], but the slot is occupied."))
return ITEM_INTERACT_BLOCKING
if(!user.transferItemToLoc(used_aicard, computer))
return ITEM_INTERACT_BLOCKING
stored_card = used_aicard
to_chat(user, span_notice("You insert \the [used_aicard] into \the [computer.name]."))
return ITEM_INTERACT_SUCCESS
/datum/computer_file/program/ai_restorer/try_eject(mob/living/user, forced = FALSE)
if(!stored_card)
if(user)
to_chat(user, span_warning("There is no card in \the [computer.name]."))
return FALSE
if(restoring && !forced)
if(user)
to_chat(user, span_warning("Safeties prevent you from removing the card until reconstruction is complete..."))
return FALSE
if(user && computer.Adjacent(user))
to_chat(user, span_notice("You remove [stored_card] from [computer.name]."))
user.put_in_hands(stored_card)
else
stored_card.forceMove(computer.drop_location())
stored_card = null
restoring = FALSE
return TRUE
/datum/computer_file/program/ai_restorer/ui_act(action, params, datum/tgui/ui, datum/ui_state/state)
. = ..()
switch(action)
if("PRG_beginReconstruction")
if(!stored_card || !stored_card.AI)
return FALSE
var/mob/living/silicon/ai/A = stored_card.AI
if(A && A.health < 100)
restoring = TRUE
A.notify_revival("Your core files are being restored!", source = computer)
return TRUE
if("PRG_eject")
if(stored_card)
try_eject(usr)
return TRUE
/datum/computer_file/program/ai_restorer/ui_data(mob/user)
var/list/data = list()
data["ejectable"] = TRUE
data["AI_present"] = !!stored_card?.AI
data["error"] = null
if(!stored_card)
data["error"] = "Please insert an intelliCard."
else if(!stored_card.AI)
data["error"] = "No AI located..."
else if(stored_card.flush)
data["error"] = "Flush in progress!"
else
data["name"] = stored_card.AI.name
data["restoring"] = restoring
data["health"] = (stored_card.AI.health + 100) / 2
data["isDead"] = stored_card.AI.stat == DEAD
data["laws"] = stored_card.AI.laws.get_law_list(include_zeroth = TRUE, render_html = FALSE)
return data