diff --git a/code/_helpers/unsorted.dm b/code/_helpers/unsorted.dm index c4c2c7ba15e..6a722bf7e30 100644 --- a/code/_helpers/unsorted.dm +++ b/code/_helpers/unsorted.dm @@ -1206,6 +1206,9 @@ proc/is_hot(obj/item/W as obj) istype(W, /obj/item/weapon/bonesetter) ) +/proc/is_borg_item(obj/item/W as obj) + return W && W.loc && isrobot(W.loc) + //check if mob is lying down on something we can operate him on. /proc/can_operate(mob/living/carbon/M) return (M.lying && \ diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 954aa20bd5e..24faa63f439 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -580,6 +580,7 @@ var/global/list/default_medbay_channels = list( icon_state = "radio" canhear_range = 0 subspace_transmission = 1 + name = "integrated radio" /obj/item/device/radio/borg/Destroy() myborg = null diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm index 5fbd5ae86ae..2de4593ee15 100644 --- a/code/game/objects/items/weapons/tools.dm +++ b/code/game/objects/items/weapons/tools.dm @@ -235,14 +235,17 @@ /obj/item/weapon/weldingtool/attackby(obj/item/W as obj, mob/user as mob) if(istype(W,/obj/item/weapon/screwdriver)) + if (isrobot(loc)) + user << span("alert", "You cannot modify your own welder!") + return if(welding) - user << "Stop welding first!" + user << span("danger", "Stop welding first!") return status = !status if(status) - user << "You secure the welder." + user << span("notice", "You secure the welder.") else - user << "The welder can now be attached and modified." + user << span("notice", "The welder can now be attached and modified.") src.add_fingerprint(user) return @@ -346,7 +349,7 @@ return message_admins("[key_name_admin(user)] triggered a fueltank explosion.") log_game("[key_name(user)] triggered a fueltank explosion with a welding tool.") - user << "\red That was stupid of you." + user << span("alert", "That was stupid of you.") tank.explode() return else @@ -385,7 +388,7 @@ return 1 else if(M) - M << "You need more welding fuel to complete this task." + M << span("notice", "You need more welding fuel to complete this task.") return 0 //Returns whether or not the welding tool is currently on. diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 5fd17409f76..feed407bed1 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -97,7 +97,8 @@ var/list/admin_verbs_admin = list( /client/proc/cmd_dev_say, /client/proc/view_duty_log, /client/proc/cmd_dev_bst, - /client/proc/clear_toxins + /client/proc/clear_toxins, + /client/proc/wipe_ai // allow admins to force-wipe AIs ) var/list/admin_verbs_ban = list( /client/proc/unban_panel, @@ -1017,3 +1018,20 @@ var/list/admin_verbs_cciaa = list( log_and_message_admins("has toggled explosions to be [config.use_recursive_explosions ? "recursive" : "non-recursive"].") feedback_add_details("admin_verb", "TRE") + +/client/proc/wipe_ai() + set category = "Admin" + set name = "Wipe AI" + set desc = "Forces an AI to wipe its own core, ghosting them and freeing their job slot." + + if (!check_rights(R_ADMIN)) + return + + var/mob/living/silicon/ai/target = input("Choose the AI to force-wipe:", "AI Termination") as null|anything in ai_list + + if (alert("Are you sure you want to wipe [target.name]? They will be ghosted and their job slot freed.", "Confirm AI Termination", "No", "No", "Yes") != "Yes") + return + + log_and_message_admins("admin-wiped [key_name_admin(target)]'s core.") + target.do_wipe_core() + \ No newline at end of file diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 902b10b3583..31a06e91394 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -313,6 +313,9 @@ var/list/ai_verbs_default = list( if(powered_ai.anchored) use_power = 2 +/mob/living/silicon/ai/rejuvenate() + return // TODO: Implement AI rejuvination + /mob/living/silicon/ai/proc/pick_icon() set category = "AI Commands" set name = "Set AI Core Display" @@ -435,6 +438,7 @@ var/list/ai_verbs_default = list( /mob/living/silicon/ai/emp_act(severity) if (prob(30)) view_core() + icon_state = "ai-fuzz" ..() /mob/living/silicon/ai/Topic(href, href_list) diff --git a/code/modules/mob/living/silicon/ai/icons.dm b/code/modules/mob/living/silicon/ai/icons.dm index 83689c9dd4d..3130a4ac3d9 100644 --- a/code/modules/mob/living/silicon/ai/icons.dm +++ b/code/modules/mob/living/silicon/ai/icons.dm @@ -28,11 +28,13 @@ var/list/datum/ai_icon/ai_icons name = "Red" alive_icon = "ai-red" alive_light = "#F04848" + dead_icon = "ai-red_dead" /datum/ai_icon/green name = "Green" alive_icon = "ai-wierd" alive_light = "#00FF99" + dead_icon = "ai-weird_dead" /datum/ai_icon/blue name = "Blue" @@ -57,6 +59,7 @@ var/list/datum/ai_icon/ai_icons /datum/ai_icon/database name = "Database" alive_icon = "ai-database" + dead_icon = "ai-database_dead" /datum/ai_icon/dorf name = "Dorf" @@ -75,11 +78,13 @@ var/list/datum/ai_icon/ai_icons /datum/ai_icon/glitchman name = "Glitchman" alive_icon = "ai-glitchman" + dead_icon = "ai-glitchman_dead" /datum/ai_icon/goon name = "Goon" alive_icon = "ai-goon" alive_light = "#3E5C80" + dead_icon = "ai-goon_dead" /datum/ai_icon/heartline name = "Heartline" @@ -100,6 +105,7 @@ var/list/datum/ai_icon/ai_icons name = "Lonestar" alive_icon = "ai-lonestar" alive_light = "#58751C" + dead_icon = "ai-lonestar_dead" /datum/ai_icon/matrix name = "Matrix" @@ -110,6 +116,7 @@ var/list/datum/ai_icon/ai_icons name = "Monochrome" alive_icon = "ai-mono" alive_light = "#585858" + dead_icon = "ai-mono_dead" /datum/ai_icon/nanotrasen name = "Nanotrasen" @@ -120,6 +127,7 @@ var/list/datum/ai_icon/ai_icons name = "Rainbow" alive_icon = "ai-clown" alive_light = "#E50213" + dead_icon = "ai-clown_dead" /datum/ai_icon/smiley name = "Smiley" @@ -130,11 +138,13 @@ var/list/datum/ai_icon/ai_icons name = "Soviet" alive_icon = "ai-redoctober" alive_light = "#FF4307" + dead_icon = "ai-redoctober_dead" /datum/ai_icon/Static name = "Static" alive_icon = "ai-static" alive_light = "#4784C1" + dead_icon = "ai-static_dead" /datum/ai_icon/text name = "Text" @@ -143,6 +153,7 @@ var/list/datum/ai_icon/ai_icons /datum/ai_icon/trapped name = "Trapped" alive_icon = "ai-hades" + dead_icon = "ai-hades_dead" /datum/ai_icon/triumvirate_static name = "Triumvirate" @@ -151,5 +162,5 @@ var/list/datum/ai_icon/ai_icons /datum/ai_icon/triumvirate_static name = "Triumvirate Static" - alive_icon = "ai-static" + alive_icon = "ai-triumvirate-malf" alive_light = "#020B2B" diff --git a/code/modules/mob/living/silicon/ai/latejoin.dm b/code/modules/mob/living/silicon/ai/latejoin.dm index 0ea59bb7347..1ad63b22ea6 100644 --- a/code/modules/mob/living/silicon/ai/latejoin.dm +++ b/code/modules/mob/living/silicon/ai/latejoin.dm @@ -12,21 +12,7 @@ var/global/list/empty_playable_ai_cores = list() return 1 -/mob/living/silicon/ai/verb/wipe_core() - set name = "Wipe Core" - set category = "OOC" - set desc = "Wipe your core. This is functionally equivalent to cryo or robotic storage, freeing up your job slot." - - if(ticker && ticker.mode && ticker.mode.name == "AI malfunction") - usr << "You cannot use this verb in malfunction. If you need to leave, please adminhelp." - return - - // Guard against misclicks, this isn't the sort of thing we want happening accidentally - if(alert("WARNING: This will immediately wipe your core and ghost you, removing your character from the round permanently (similar to cryo and robotic storage). Are you entirely sure you want to do this?", - "Wipe Core", "No", "No", "Yes") != "Yes") - return - - // We warned you. +/mob/living/silicon/ai/proc/do_wipe_core() empty_playable_ai_cores += new /obj/structure/AIcore/deactivated(loc) global_announcer.autosay("[src] has been moved to intelligence storage.", "Artificial Intelligence Oversight") @@ -43,3 +29,20 @@ var/global/list/empty_playable_ai_cores = list() ghostize(0) qdel(src) + +/mob/living/silicon/ai/verb/wipe_core() + set name = "Wipe Core" + set category = "OOC" + set desc = "Wipe your core. This is functionally equivalent to cryo or robotic storage, freeing up your job slot." + + if(ticker && ticker.mode && ticker.mode.name == "AI malfunction") + usr << "You cannot use this verb in malfunction. If you need to leave, please adminhelp." + return + + // Guard against misclicks, this isn't the sort of thing we want happening accidentally + if(alert("WARNING: This will immediately wipe your core and ghost you, removing your character from the round permanently (similar to cryo and robotic storage). Are you entirely sure you want to do this?", + "Wipe Core", "No", "No", "Yes") != "Yes") + return + + // We warned you. + do_wipe_core() diff --git a/html/changelogs/Lohikar-SynthChanges.yml b/html/changelogs/Lohikar-SynthChanges.yml new file mode 100644 index 00000000000..6567d326487 --- /dev/null +++ b/html/changelogs/Lohikar-SynthChanges.yml @@ -0,0 +1,6 @@ +author: Lohikar +delete-after: True +changes: + - imageadd: "Some AI displays now have special icons used when the AI is dead." + - rscadd: "Added an admin verb that allows force-storaging of SSD AIs." + - imageadd: "The AI's icon now changes when it is EMPed." diff --git a/icons/mob/AI.dmi b/icons/mob/AI.dmi index f074231afba..f364c4ddbd7 100644 Binary files a/icons/mob/AI.dmi and b/icons/mob/AI.dmi differ