diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm index b7bcd047fdf..1b304283d63 100644 --- a/code/__DEFINES/components.dm +++ b/code/__DEFINES/components.dm @@ -198,6 +198,8 @@ #define COMSIG_LIVING_STATUS_UNCONSCIOUS "living_unconscious" //from base of mob/living/Unconscious() (amount, update, ignore) #define COMSIG_LIVING_STATUS_SLEEP "living_sleeping" //from base of mob/living/Sleeping() (amount, update, ignore) #define COMPONENT_NO_STUN 1 //For all of them +#define COMSIG_LIVING_CAN_TRACK "mob_cantrack" //from base of /mob/living/can_track(): (mob/user) + #define COMPONENT_CANT_TRACK "mob_cant_track" // /mob/living/carbon signals #define COMSIG_CARBON_SOUNDBANG "carbon_soundbang" //from base of mob/living/carbon/soundbang_act(): (list(intensity)) diff --git a/code/datums/elements/digitalcamo.dm b/code/datums/elements/digitalcamo.dm new file mode 100644 index 00000000000..ebb51ec8a55 --- /dev/null +++ b/code/datums/elements/digitalcamo.dm @@ -0,0 +1,35 @@ +/datum/element/digitalcamo + element_flags = ELEMENT_DETACH + var/list/attached_mobs = list() + +/datum/element/digitalcamo/New() + . = ..() + START_PROCESSING(SSdcs, src) + +/datum/element/digitalcamo/Attach(datum/target) + . = ..() + if(!isliving(target) || target in attached_mobs) + return ELEMENT_INCOMPATIBLE + RegisterSignal(target, COMSIG_PARENT_EXAMINE, .proc/on_examine) + RegisterSignal(target, COMSIG_LIVING_CAN_TRACK, .proc/can_track) + var/image/img = image(loc = target) + img.override = TRUE + attached_mobs[target] = img + +/datum/element/digitalcamo/Detach(datum/target) + . = ..() + UnregisterSignal(target, list(COMSIG_PARENT_EXAMINE, COMSIG_LIVING_CAN_TRACK)) + for(var/mob/living/silicon/ai/AI in GLOB.player_list) + AI.client.images -= attached_mobs[target] + attached_mobs -= target + +/datum/element/digitalcamo/proc/on_examine(datum/source, mob/M) + to_chat(M, "[source.p_their()] skin seems to be shifting and morphing like is moving around below it.") + +/datum/element/digitalcamo/proc/can_track(datum/source) + return COMPONENT_CANT_TRACK + +/datum/element/digitalcamo/process() + for(var/mob/living/silicon/ai/AI in GLOB.player_list) + for(var/mob in attached_mobs) + AI.client.images |= attached_mobs[mob] diff --git a/code/modules/antagonists/changeling/powers/digitalcamo.dm b/code/modules/antagonists/changeling/powers/digitalcamo.dm index f193ceb105d..028f85b83e8 100644 --- a/code/modules/antagonists/changeling/powers/digitalcamo.dm +++ b/code/modules/antagonists/changeling/powers/digitalcamo.dm @@ -4,21 +4,20 @@ helptext = "We cannot be tracked by camera or seen by AI units while using this skill. However, humans looking at us will find us... uncanny." button_icon_state = "digital_camo" dna_cost = 1 + active = FALSE //Prevents AIs tracking you but makes you easily detectable to the human-eye. /datum/action/changeling/digitalcamo/sting_action(mob/user) ..() - if(user.digitalcamo) + if(active) to_chat(user, "We return to normal.") - user.digitalinvis = 0 - user.digitalcamo = 0 + user.RemoveElement(/datum/element/digitalcamo) else to_chat(user, "We distort our form to hide from the AI.") - user.digitalcamo = 1 - user.digitalinvis = 1 + user.AddElement(/datum/element/digitalcamo) + active = !active return TRUE /datum/action/changeling/digitalcamo/Remove(mob/user) - user.digitalcamo = FALSE - user.digitalinvis = FALSE + user.RemoveElement(/datum/element/digitalcamo) ..() diff --git a/code/modules/mob/living/carbon/examine.dm b/code/modules/mob/living/carbon/examine.dm index 93a7ed02e8e..bbd797608bc 100644 --- a/code/modules/mob/living/carbon/examine.dm +++ b/code/modules/mob/living/carbon/examine.dm @@ -89,9 +89,6 @@ else if(InCritical()) . += "[t_His] breathing is shallow and labored." - if(digitalcamo) - . += "[t_He] [t_is] moving [t_his] body in an unnatural and blatantly unsimian manner." - var/trait_exam = common_trait_examine() if (!isnull(trait_exam)) . += trait_exam diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index e8e7c37e162..b69eeae5afc 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -291,9 +291,6 @@ else if(!client) msg += "[t_He] [t_has] a blank, absent-minded stare and appears completely unresponsive to anything. [t_He] may snap out of it soon.\n" - if(digitalcamo) - msg += "[t_He] [t_is] moving [t_his] body in an unnatural and blatantly inhuman manner.\n" - if (length(msg)) . += "[msg.Join("")]" diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index 0d40c75d80b..8db38369dad 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -2,9 +2,6 @@ set waitfor = FALSE set invisibility = 0 - if(digitalinvis) - handle_diginvis() //AI becomes unable to see mob - if((movement_type & FLYING) && !(movement_type & FLOATING)) //TODO: Better floating float(on = TRUE) @@ -83,14 +80,6 @@ /mob/living/proc/handle_diseases() return -/mob/living/proc/handle_diginvis() - if(!digitaldisguise) - src.digitaldisguise = image(loc = src) - src.digitaldisguise.override = 1 - for(var/mob/living/silicon/ai/AI in GLOB.player_list) - AI.client.images |= src.digitaldisguise - - /mob/living/proc/handle_random_events() return diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index af3d29544b8..91b170a090c 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -878,25 +878,23 @@ /mob/living/proc/can_track(mob/living/user) //basic fast checks go first. When overriding this proc, I recommend calling ..() at the end. + if(SEND_SIGNAL(src, COMSIG_LIVING_CAN_TRACK, args) & COMPONENT_CANT_TRACK) + return FALSE var/turf/T = get_turf(src) if(!T) - return 0 + return FALSE if(is_centcom_level(T.z)) //dont detect mobs on centcom - return 0 + return FALSE if(is_away_level(T.z)) - return 0 + return FALSE if(user != null && src == user) - return 0 + return FALSE if(invisibility || alpha == 0)//cloaked - return 0 - if(digitalcamo || digitalinvis) - return 0 - + return FALSE // Now, are they viewable by a camera? (This is last because it's the most intensive check) if(!near_camera(src)) - return 0 - - return 1 + return FALSE + return TRUE //used in datum/reagents/reaction() proc /mob/living/proc/get_permeability_protection(list/target_zones) diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index fa7b062f068..845cb8dd411 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -54,7 +54,7 @@ /** * Magic var that stops you moving and interacting with anything - * + * * Set when you're being turned into something else and also used in a bunch of places * it probably shouldn't really be */ @@ -72,7 +72,7 @@ /** * back up of the real name during admin possession - * + * * If an admin possesses an object it's real name is set to the admin name and this * stores whatever the real name was previously. When possession ends, the real name * is reset to this value @@ -115,12 +115,12 @@ var/active_hand_index = 1 /** * list of items held in hands - * + * * len = number of hands, eg: 2 nulls is 2 empty hands, 1 item and 1 null is 1 full hand * and 1 empty hand. - * + * * NB: contains nulls! - * + * * held_items[active_hand_index] is the actively held item, but please use * get_active_held_item() instead, because OOP */ @@ -158,17 +158,10 @@ */ var/list/mob_spell_list = list() - + /// bitflags defining which status effects can be inflicted (replaces canknockdown, canstun, etc) var/status_flags = CANSTUN|CANKNOCKDOWN|CANUNCONSCIOUS|CANPUSH - /// Can they be tracked by the AI? - var/digitalcamo = 0 - ///Are they ivisible to the AI? - var/digitalinvis = 0 - ///what does the AI see instead of them? - var/image/digitaldisguise = null - /// Can they interact with station electronics var/has_unlimited_silicon_privilege = 0 @@ -199,5 +192,5 @@ ///THe z level this mob is currently registered in var/registered_z = null - + var/memory_throttle_time = 0 diff --git a/tgstation.dme b/tgstation.dme index 0e80db2c934..5e16b98e399 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -488,6 +488,7 @@ #include "code\datums\diseases\advance\symptoms\youth.dm" #include "code\datums\elements\_element.dm" #include "code\datums\elements\cleaning.dm" +#include "code\datums\elements\digitalcamo.dm" #include "code\datums\elements\earhealing.dm" #include "code\datums\elements\firestacker.dm" #include "code\datums\elements\snail_crawl.dm"