Signalizes an AI card thing (#76869)

## About The Pull Request

Changes this code to be signalized on AI cards


https://github.com/tgstation/tgstation/blob/76bddbd90306829291896e9b90e6e8071933e6fa/code/modules/mob/living/silicon/ai/death.dm#L44-L49

Minor code improvements as well (Moving the sleep out from flushing into
its own async proc)

## Why It's Good For The Game

Cringe code

## Changelog

🆑 Melbert
code: AI cards should react more snap-ily to having their occupant
perish
/🆑
This commit is contained in:
MrMelbert
2023-07-16 21:38:42 +02:00
committed by GitHub
parent a4927595c9
commit dc83eff4ef
4 changed files with 82 additions and 47 deletions
+66 -28
View File
@@ -3,6 +3,7 @@
desc = "A storage device for AIs. Patent pending."
icon = 'icons/obj/aicards.dmi'
icon_state = "aicard" // aicard-full
base_icon_state = "aicard"
inhand_icon_state = "electronic"
worn_icon_state = "electronic"
lefthand_file = 'icons/mob/inhands/items/devices_lefthand.dmi'
@@ -15,7 +16,6 @@
/obj/item/aicard/Destroy(force)
if(AI)
AI.death()
AI.ghostize(can_reenter_corpse = FALSE)
QDEL_NULL(AI)
@@ -25,47 +25,80 @@
name = "intelliTater"
desc = "A stylish upgrade (?) to the intelliCard."
icon_state = "aitater"
base_icon_state = "aitater"
/obj/item/aicard/aispook
name = "intelliLantern"
desc = "A spoOoOoky upgrade to the intelliCard."
icon_state = "aispook"
base_icon_state = "aispook"
/obj/item/aicard/suicide_act(mob/living/user)
user.visible_message(span_suicide("[user] is trying to upload [user.p_them()]self into [src]! That's not going to work out well!"))
return BRUTELOSS
/obj/item/aicard/pre_attack(atom/target, mob/living/user, params)
if(AI) //AI is on the card, implies user wants to upload it.
var/our_ai = AI
target.transfer_ai(AI_TRANS_FROM_CARD, user, AI, src)
if(!AI)
log_combat(user, our_ai, "uploaded", src, "to [target].")
update_appearance()
. = ..()
if(.)
return
if(AI)
if(upload_ai(target, user))
return TRUE
else //No AI on the card, therefore the user wants to download one.
target.transfer_ai(AI_TRANS_TO_CARD, user, null, src)
if(AI)
log_silicon("[key_name(user)] carded [key_name(AI)]", src)
update_appearance()
else
if(capture_ai(target, user))
return TRUE
return ..()
/// Tries to get an AI from the atom clicked
/obj/item/aicard/proc/capture_ai(atom/from_what, mob/living/user)
from_what.transfer_ai(AI_TRANS_TO_CARD, user, null, src)
if(isnull(AI))
return FALSE
log_silicon("[key_name(user)] carded [key_name(AI)]", src)
update_appearance()
AI.cancel_camera()
RegisterSignal(AI, COMSIG_MOB_STATCHANGE, PROC_REF(on_ai_stat_change))
return TRUE
/// Tries to upload the AI we have captured to the atom clicked
/obj/item/aicard/proc/upload_ai(atom/to_what, mob/living/user)
var/mob/living/silicon/ai/old_ai = AI
to_what.transfer_ai(AI_TRANS_FROM_CARD, user, AI, src)
if(!isnull(AI))
return FALSE
log_combat(user, old_ai, "uploaded", src, "to [to_what].")
update_appearance()
old_ai.cancel_camera()
UnregisterSignal(old_ai, COMSIG_MOB_STATCHANGE)
return TRUE
/obj/item/aicard/proc/on_ai_stat_change(datum/source, new_stat, old_stat)
SIGNAL_HANDLER
if(new_stat == DEAD || old_stat == DEAD)
update_appearance()
/obj/item/aicard/update_name(updates)
. = ..()
if(AI)
name = "[initial(name)] - [AI.name]"
else
name = initial(name)
/obj/item/aicard/update_icon_state()
if(!AI)
name = initial(name)
icon_state = initial(icon_state)
return ..()
name = "[initial(name)] - [AI.name]"
icon_state = "[initial(icon_state)][AI.stat == DEAD ? "-404" : "-full"]"
AI.cancel_camera()
if(AI)
icon_state = "[base_icon_state][AI.stat == DEAD ? "-404" : "-full"]"
else
icon_state = base_icon_state
return ..()
/obj/item/aicard/update_overlays()
. = ..()
if(!AI?.control_disabled)
return
. += "[initial(icon_state)]-on"
. += "[base_icon_state]-on"
/obj/item/aicard/ui_state(mob/user)
return GLOB.hands_state
@@ -101,13 +134,7 @@
var/confirm = tgui_alert(usr, "Are you sure you want to wipe this card's memory?", name, list("Yes", "No"))
if(confirm == "Yes" && !..())
flush = TRUE
if(AI && AI.loc == src)
to_chat(AI, span_userdanger("Your core files are being wiped!"))
while(AI.stat != DEAD && flush)
AI.adjustOxyLoss(5)
AI.updatehealth()
sleep(0.5 SECONDS)
flush = FALSE
wipe_ai()
. = TRUE
if("wireless")
AI.control_disabled = !AI.control_disabled
@@ -122,3 +149,14 @@
to_chat(AI, span_warning("Your Subspace Transceiver has been [AI.radio_enabled ? "enabled" : "disabled"]!"))
. = TRUE
update_appearance()
/obj/item/aicard/proc/wipe_ai()
set waitfor = FALSE
if(AI && AI.loc == src)
to_chat(AI, span_userdanger("Your core files are being wiped!"))
while(AI.stat != DEAD && flush)
AI.adjustOxyLoss(5)
AI.updatehealth()
sleep(0.5 SECONDS)
flush = FALSE
+1
View File
@@ -409,6 +409,7 @@ That prevents a few funky behaviors.
/atom/proc/transfer_ai(interaction, mob/user, mob/living/silicon/ai/AI, obj/item/aicard/card)
SHOULD_CALL_PARENT(TRUE)
if(istype(card))
if(card.flush)
to_chat(user, span_alert("ERROR: AI flush is in progress, cannot execute transfer protocol."))
@@ -41,13 +41,6 @@
if(explosive)
addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(explosion), loc, 3, 6, 12, null, 15), 1 SECONDS)
if(istype(loc, /obj/item/aicard/aitater))
loc.icon_state = "aitater-404"
else if(istype(loc, /obj/item/aicard/aispook))
loc.icon_state = "aispook-404"
else if(istype(loc, /obj/item/aicard))
loc.icon_state = "aicard-404"
/mob/living/silicon/ai/proc/ShutOffDoomsdayDevice()
if(nuking)
nuking = FALSE
+15 -12
View File
@@ -77,26 +77,29 @@
disk_pinpointers.alert = FALSE
/obj/machinery/power/apc/transfer_ai(interaction, mob/user, mob/living/silicon/ai/AI, obj/item/aicard/card)
. = ..()
if(!.)
return
if(card.AI)
to_chat(user, span_warning("[card] is already occupied!"))
return
return FALSE
if(!occupier)
to_chat(user, span_warning("There's nothing in [src] to transfer!"))
return
return FALSE
if(!occupier.mind || !occupier.client)
to_chat(user, span_warning("[occupier] is either inactive or destroyed!"))
return
return FALSE
if(!occupier.parent.stat)
to_chat(user, span_warning("[occupier] is refusing all attempts at transfer!") )
return
return FALSE
if(transfer_in_progress)
to_chat(user, span_warning("There's already a transfer in progress!"))
return
return FALSE
if(interaction != AI_TRANS_TO_CARD || occupier.stat)
return
return FALSE
var/turf/user_turf = get_turf(user)
if(!user_turf)
return
return FALSE
transfer_in_progress = TRUE
user.visible_message(span_notice("[user] slots [card] into [src]..."), span_notice("Transfer process initiated. Sending request for AI approval..."))
playsound(src, 'sound/machines/click.ogg', 50, TRUE)
@@ -105,21 +108,21 @@
to_chat(user, span_danger("AI denied transfer request. Process terminated."))
playsound(src, 'sound/machines/buzz-sigh.ogg', 50, TRUE)
transfer_in_progress = FALSE
return
return FALSE
if(user.loc != user_turf)
to_chat(user, span_danger("Location changed. Process terminated."))
to_chat(occupier, span_warning("[user] moved away! Transfer canceled."))
transfer_in_progress = FALSE
return
return FALSE
to_chat(user, span_notice("AI accepted request. Transferring stored intelligence to [card]..."))
to_chat(occupier, span_notice("Transfer starting. You will be moved to [card] shortly."))
if(!do_after(user, 50, target = src))
to_chat(occupier, span_warning("[user] was interrupted! Transfer canceled."))
transfer_in_progress = FALSE
return
return FALSE
if(!occupier || !card)
transfer_in_progress = FALSE
return
return FALSE
user.visible_message(span_notice("[user] transfers [occupier] to [card]!"), span_notice("Transfer complete! [occupier] is now stored in [card]."))
to_chat(occupier, span_notice("Transfer complete! You've been stored in [user]'s [card.name]."))
occupier.forceMove(card)
@@ -128,4 +131,4 @@
occupier.cancel_camera()
occupier = null
transfer_in_progress = FALSE
return
return TRUE