diff --git a/aurorastation.dme b/aurorastation.dme index 63af9a19cf0..843cc4747af 100644 --- a/aurorastation.dme +++ b/aurorastation.dme @@ -166,6 +166,7 @@ #include "code\controllers\master\failsafe.dm" #include "code\controllers\master\master.dm" #include "code\controllers\master\subsystem.dm" +#include "code\controllers\subsystems\ai_obfuscation.dm" #include "code\controllers\subsystems\air.dm" #include "code\controllers\subsystems\alarm.dm" #include "code\controllers\subsystems\ao.dm" diff --git a/code/controllers/subsystems/ai_obfuscation.dm b/code/controllers/subsystems/ai_obfuscation.dm new file mode 100644 index 00000000000..c6c0f67215c --- /dev/null +++ b/code/controllers/subsystems/ai_obfuscation.dm @@ -0,0 +1,33 @@ +var/global/datum/controller/subsystem/ai_obfuscation/SSai_obfuscation + +/datum/controller/subsystem/ai_obfuscation + name = "AI Obfuscation" + flags = SS_NO_FIRE + + var/list/image/obfuscation_images = list() + +/datum/controller/subsystem/ai_obfuscation/New() + NEW_SS_GLOBAL(SSai_obfuscation) + +/datum/controller/subsystem/ai_obfuscation/proc/add_obfuscation_image(var/image/added_image) + if(!istype(added_image)) + return + obfuscation_images += added_image + + for(var/ai in ai_list) + var/mob/living/silicon/ai/A = ai + if(A.client) + A.client.images += added_image + +/datum/controller/subsystem/ai_obfuscation/proc/remove_obfuscation_image(var/image/removed_image) + if(!istype(removed_image)) + return + obfuscation_images -= removed_image + + for(var/ai in ai_list) + var/mob/living/silicon/ai/A = ai + if(A.client) + A.client.images -= removed_image + +/datum/controller/subsystem/ai_obfuscation/proc/get_obfuscation_images() + return obfuscation_images \ No newline at end of file diff --git a/code/datums/uplink/stealth and camouflage items.dm b/code/datums/uplink/stealth and camouflage items.dm index 06de7b73f9e..b4058b157da 100644 --- a/code/datums/uplink/stealth and camouflage items.dm +++ b/code/datums/uplink/stealth and camouflage items.dm @@ -16,7 +16,7 @@ /datum/uplink_item/item/stealth_items/id name = "Agent ID card" - item_cost = 3 + item_cost = 4 path = /obj/item/card/id/syndicate /datum/uplink_item/item/stealth_items/chameleon_kit diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 3dfae529431..9e3c92439e6 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -466,6 +466,10 @@ var/list/global/slot_flags_enumeration = list( return 0 return 1 +// override for give shenanigans +/obj/item/proc/on_give(var/mob/giver, var/mob/receiver) + return + /* /obj/item/verb/verb_pickup() set src in oview(1) diff --git a/code/game/objects/items/weapons/cards_ids_syndicate.dm b/code/game/objects/items/weapons/cards_ids_syndicate.dm index 732c2d9abc7..820b812557e 100644 --- a/code/game/objects/items/weapons/cards_ids_syndicate.dm +++ b/code/game/objects/items/weapons/cards_ids_syndicate.dm @@ -2,17 +2,38 @@ name = "agent card" assignment = "Agent" origin_tech = list(TECH_ILLEGAL = 3) - var/electronic_warfare = 1 + var/charge = 10000 + var/electronic_warfare = FALSE + var/image/obfuscation_image var/mob/registered_user = null /obj/item/card/id/syndicate/New(mob/user as mob) ..() access = syndicate_access.Copy() + START_PROCESSING(SSprocessing, src) /obj/item/card/id/syndicate/Destroy() + STOP_PROCESSING(SSprocessing, src) unset_registered_user(registered_user) return ..() +/obj/item/card/id/syndicate/examine(mob/user) + ..() + if(Adjacent(user)) + if(user == registered_user) + to_chat(user, FONT_SMALL(SPAN_NOTICE("It is at [charge]/[initial(charge)] charge."))) + +/obj/item/card/id/syndicate/process() + if(electronic_warfare) + charge = max(0, charge - 50) + if(charge <= 0) + if(ismob(loc)) + to_chat(loc, SPAN_WARNING("\The [src] runs out of power and deactivates.")) + electronic_warfare = FALSE + check_obfuscation() + else if(charge != initial(charge)) + charge = min(initial(charge), charge + 100) + /obj/item/card/id/syndicate/prevent_tracking() return electronic_warfare @@ -79,6 +100,42 @@ return STATUS_CLOSE return ..() + +/obj/item/card/id/syndicate/throw_at() + ..() + electronic_warfare = FALSE + check_obfuscation() + +/obj/item/card/id/syndicate/dropped() + ..() + electronic_warfare = FALSE + check_obfuscation() + +/obj/item/card/id/syndicate/on_give() + check_obfuscation() + +/obj/item/card/id/syndicate/update_icon() + cut_overlays() + if(electronic_warfare) + var/mutable_appearance/electro_overlay = mutable_appearance(icon, "electronic_warfare") + add_overlay(electro_overlay) + +/obj/item/card/id/syndicate/proc/check_obfuscation() + if(electronic_warfare) + if(ismob(loc)) + obfuscation_image = image("loc" = loc) + obfuscation_image.override = TRUE + SSai_obfuscation.add_obfuscation_image(obfuscation_image) + else if(obfuscation_image) + electronic_warfare = FALSE + SSai_obfuscation.remove_obfuscation_image(obfuscation_image) + QDEL_NULL(obfuscation_image) + else + if(obfuscation_image) + SSai_obfuscation.remove_obfuscation_image(obfuscation_image) + QDEL_NULL(obfuscation_image) + update_icon() + /obj/item/card/id/syndicate/Topic(href, href_list, var/datum/topic_state/state) if(..()) return 1 @@ -86,7 +143,8 @@ var/user = usr if(href_list["electronic_warfare"]) electronic_warfare = text2num(href_list["electronic_warfare"]) - to_chat(user, "Electronic warfare [electronic_warfare ? "enabled" : "disabled"].") + to_chat(user, SPAN_NOTICE("Electronic warfare [electronic_warfare ? "enabled" : "disabled"].")) + check_obfuscation() else if(href_list["set"]) switch(href_list["set"]) if("Age") diff --git a/code/modules/mob/living/carbon/give.dm b/code/modules/mob/living/carbon/give.dm index 75b614b009e..0d1cf4af905 100644 --- a/code/modules/mob/living/carbon/give.dm +++ b/code/modules/mob/living/carbon/give.dm @@ -38,6 +38,7 @@ return if(usr.unEquip(I)) - target.put_in_hands(I) // If this fails it will just end up on the floor, but that's fitting for things like dionaea. - usr.visible_message(span("notice", "\The [usr] handed \the [I] to \the [target]."), span("notice", "You give \the [I] to \the [target].")) - + I.on_give(usr, target) + if(!QDELETED(I)) // if on_give deletes the item, we don't want runtimes below + target.put_in_hands(I) // If this fails it will just end up on the floor, but that's fitting for things like dionaea. + usr.visible_message(span("notice", "\The [usr] handed \the [I] to \the [target]."), span("notice", "You give \the [I] to \the [target].")) diff --git a/code/modules/mob/living/silicon/ai/login.dm b/code/modules/mob/living/silicon/ai/login.dm index 3c4352c5c65..8e08082b28b 100644 --- a/code/modules/mob/living/silicon/ai/login.dm +++ b/code/modules/mob/living/silicon/ai/login.dm @@ -14,6 +14,9 @@ blind.invisibility = 101 client.screen.Add( blind, flash ) + for(var/image/obfuscation_image in SSai_obfuscation.get_obfuscation_images()) + client.images += obfuscation_image + if(stat != DEAD) for(var/obj/machinery/ai_status_display/O in SSmachinery.all_status_displays) //change status O.mode = 1 diff --git a/html/changelogs/geeves-ai_visibility_nerf.yml b/html/changelogs/geeves-ai_visibility_nerf.yml new file mode 100644 index 00000000000..a455406d65d --- /dev/null +++ b/html/changelogs/geeves-ai_visibility_nerf.yml @@ -0,0 +1,7 @@ +author: Geeves + +delete-after: True +changes: + - rscadd: "The agent ID card now makes you invisible to the AI when electronic warfare is enabled." + - tweak: "The price of the agent ID card have been upped to 4, from 3." + - tweak: "Agent IDs now have a charge, which lasts for a few minutes. When the charge runs out, electronic warfare is disabled." \ No newline at end of file diff --git a/icons/obj/card.dmi b/icons/obj/card.dmi index 1685be026a0..d1b01b20a2a 100644 Binary files a/icons/obj/card.dmi and b/icons/obj/card.dmi differ