diff --git a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_x_act.dm b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_x_act.dm index 6448be3fecb..a33c4951384 100644 --- a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_x_act.dm +++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_x_act.dm @@ -93,3 +93,7 @@ /// Args: (obj/item/inserting, mob/living/user) #define COMSIG_ATOM_STORAGE_ITEM_INTERACT_INSERT "atom_storage_item_interact_insert" #define BLOCK_STORAGE_INSERT (1<<0) + +/// from /obj/projectile/energy/fisher/on_hit() or /obj/item/gun/energy/recharge/fisher when striking a target +#define COMSIG_ATOM_SABOTEUR_ACT "hit_by_saboteur" + #define COMSIG_SABOTEUR_SUCCESS 1 diff --git a/code/__DEFINES/dcs/signals/signals_object.dm b/code/__DEFINES/dcs/signals/signals_object.dm index 797256017d4..651f630db09 100644 --- a/code/__DEFINES/dcs/signals/signals_object.dm +++ b/code/__DEFINES/dcs/signals/signals_object.dm @@ -416,10 +416,6 @@ ///sent to the projectile when spawning the item (shrapnel) that may be embedded: (new_item) #define COMSIG_PROJECTILE_ON_SPAWN_EMBEDDED "projectile_on_spawn_embedded" -/// from /obj/projectile/energy/fisher/on_hit() or /obj/item/gun/energy/recharge/fisher when striking a target -#define COMSIG_HIT_BY_SABOTEUR "hit_by_saboteur" - #define COMSIG_SABOTEUR_SUCCESS (1<<0) - // /obj/vehicle/sealed/car/vim signals ///from /datum/action/vehicle/sealed/noise/chime/Trigger(): () diff --git a/code/datums/components/seclight_attachable.dm b/code/datums/components/seclight_attachable.dm index b1d4aebc93f..6b3991c9c5e 100644 --- a/code/datums/components/seclight_attachable.dm +++ b/code/datums/components/seclight_attachable.dm @@ -97,8 +97,8 @@ RegisterSignal(parent, COMSIG_ITEM_UI_ACTION_CLICK, PROC_REF(on_action_click)) RegisterSignal(parent, COMSIG_ATOM_ATTACKBY, PROC_REF(on_attackby)) RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) + RegisterSignal(parent, COMSIG_ATOM_SABOTEUR_ACT, PROC_REF(on_hit_by_saboteur)) RegisterSignal(parent, COMSIG_QDELETING, PROC_REF(on_parent_deleted)) - RegisterSignal(parent, COMSIG_HIT_BY_SABOTEUR, PROC_REF(on_saboteur)) /datum/component/seclite_attachable/UnregisterFromParent() UnregisterSignal(parent, list( @@ -110,6 +110,7 @@ COMSIG_ITEM_UI_ACTION_CLICK, COMSIG_ATOM_ATTACKBY, COMSIG_ATOM_EXAMINE, + COMSIG_ATOM_SABOTEUR_ACT, COMSIG_QDELETING, )) @@ -296,8 +297,8 @@ // but that's the downside of using icon states over overlays. source.icon_state = base_state -/// Signal proc for [COMSIG_HIT_BY_SABOTEUR] that turns the light off for a few seconds. -/datum/component/seclite_attachable/proc/on_saboteur(datum/source, disrupt_duration) - SIGNAL_HANDLER +//turns the light off for a few seconds. +/datum/component/seclite_attachable/proc/on_hit_by_saboteur(datum/source, disrupt_duration) . = light.on_saboteur(source, disrupt_duration) update_light() + return . diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 6f21e9303fc..e2f5d16cc57 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -133,8 +133,6 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/camera/xray, 0) find_and_hang_on_wall(directional = TRUE, \ custom_drop_callback = CALLBACK(src, PROC_REF(deconstruct), FALSE)) - RegisterSignal(src, COMSIG_HIT_BY_SABOTEUR, PROC_REF(on_saboteur)) - /obj/machinery/camera/Destroy(force) if(can_use()) toggle_cam(null, 0) //kick anyone viewing out and remove from the camera chunks @@ -235,11 +233,11 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/camera/xray, 0) M.reset_perspective(null) to_chat(M, span_warning("The screen bursts into static!")) -/obj/machinery/camera/proc/on_saboteur(datum/source, disrupt_duration) - SIGNAL_HANDLER +/obj/machinery/camera/on_saboteur(datum/source, disrupt_duration) + . = ..() //lasts twice as much so we don't have to constantly shoot cameras just to be S T E A L T H Y emp_act(EMP_LIGHT, reset_time = disrupt_duration * 2) - return COMSIG_SABOTEUR_SUCCESS + return TRUE /obj/machinery/camera/proc/post_emp_reset(thisemp, previous_network) if(QDELETED(src)) diff --git a/code/game/machinery/porta_turret/portable_turret.dm b/code/game/machinery/porta_turret/portable_turret.dm index af27a5411cd..df4e4555d7e 100644 --- a/code/game/machinery/porta_turret/portable_turret.dm +++ b/code/game/machinery/porta_turret/portable_turret.dm @@ -135,8 +135,6 @@ DEFINE_BITFIELD(turret_flags, list( if(!has_cover) INVOKE_ASYNC(src, PROC_REF(popUp)) - RegisterSignal(src, COMSIG_HIT_BY_SABOTEUR, PROC_REF(on_saboteur)) - AddElement(/datum/element/hostile_machine) ///Toggles the turret on or off depending on the value of the turn_on arg. @@ -157,10 +155,10 @@ DEFINE_BITFIELD(turret_flags, list( addtimer(CALLBACK(src, PROC_REF(toggle_on), TRUE), duration + 1) //the cooldown isn't over until the tick after its end. toggle_on(FALSE) -/obj/machinery/porta_turret/proc/on_saboteur(datum/source, disrupt_duration) - SIGNAL_HANDLER +/obj/machinery/porta_turret/on_saboteur(datum/source, disrupt_duration) + . = ..() INVOKE_ASYNC(src, PROC_REF(set_disabled), disrupt_duration) - return COMSIG_SABOTEUR_SUCCESS + return TRUE /obj/machinery/porta_turret/proc/check_should_process() if (datum_flags & DF_ISPROCESSING) diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index 8db7652d5a0..e8242f2817f 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -41,8 +41,6 @@ set_light_on(TRUE) update_brightness() register_context() - if(toggle_context) - RegisterSignal(src, COMSIG_HIT_BY_SABOTEUR, PROC_REF(on_saboteur)) var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/flashlight_eyes) @@ -286,12 +284,12 @@ setDir(user.dir) /// when hit by a light disruptor - turns the light off, forces the light to be disabled for a few seconds -/obj/item/flashlight/proc/on_saboteur(datum/source, disrupt_duration) - SIGNAL_HANDLER +/obj/item/flashlight/on_saboteur(datum/source, disrupt_duration) + . = ..() if(light_on) toggle_light() COOLDOWN_START(src, disabled_time, disrupt_duration) - return COMSIG_SABOTEUR_SUCCESS + return TRUE /obj/item/flashlight/pen name = "penlight" diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 2b7a9bad760..7303eaf8738 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -121,19 +121,17 @@ return AddElement(/datum/element/slapcrafting, string_list(list(/datum/crafting_recipe/improv_explosive))) - RegisterSignal(src, COMSIG_HIT_BY_SABOTEUR, PROC_REF(on_saboteur)) - /obj/item/radio/Destroy() remove_radio_all(src) //Just to be sure if(istype(keyslot)) QDEL_NULL(keyslot) return ..() -/obj/item/radio/proc/on_saboteur(datum/source, disrupt_duration) - SIGNAL_HANDLER +/obj/item/radio/on_saboteur(datum/source, disrupt_duration) + . = ..() if(broadcasting) //no broadcasting but it can still be used to send radio messages. set_broadcasting(FALSE) - return COMSIG_SABOTEUR_SUCCESS + return TRUE /obj/item/radio/proc/set_frequency(new_frequency) SEND_SIGNAL(src, COMSIG_RADIO_NEW_FREQUENCY, args) diff --git a/code/game/objects/items/melee/baton.dm b/code/game/objects/items/melee/baton.dm index 8c1ae33c4c7..0fd63321519 100644 --- a/code/game/objects/items/melee/baton.dm +++ b/code/game/objects/items/melee/baton.dm @@ -479,7 +479,6 @@ else cell = new preload_cell_type(src) RegisterSignal(src, COMSIG_ATOM_ATTACKBY, PROC_REF(convert)) - RegisterSignal(src, COMSIG_HIT_BY_SABOTEUR, PROC_REF(on_saboteur)) update_appearance() /obj/item/melee/baton/security/get_cell() @@ -514,13 +513,14 @@ qdel(item) qdel(src) -/obj/item/melee/baton/security/proc/on_saboteur(datum/source, disrupt_duration) - SIGNAL_HANDLER +/obj/item/melee/baton/security/on_saboteur(datum/source, disrupt_duration) + . = ..() if(!active) return turn_off() update_appearance() - return COMSIG_SABOTEUR_SUCCESS + return TRUE + /obj/item/melee/baton/security/Exited(atom/movable/mov_content) . = ..() if(mov_content == cell) diff --git a/code/modules/clothing/head/hardhat.dm b/code/modules/clothing/head/hardhat.dm index fc56f833423..1ea0e7dc825 100644 --- a/code/modules/clothing/head/hardhat.dm +++ b/code/modules/clothing/head/hardhat.dm @@ -40,7 +40,6 @@ /obj/item/clothing/head/utility/hardhat/Initialize(mapload) . = ..() AddElement(/datum/element/update_icon_updates_onmob) - RegisterSignal(src, COMSIG_HIT_BY_SABOTEUR, PROC_REF(on_saboteur)) /obj/item/clothing/head/utility/hardhat/proc/toggle_helmet_light(mob/living/user) on = !on @@ -60,11 +59,11 @@ /obj/item/clothing/head/utility/hardhat/proc/turn_off(mob/user) set_light_on(FALSE) -/obj/item/clothing/head/utility/hardhat/proc/on_saboteur(datum/source, disrupt_duration) - SIGNAL_HANDLER +/obj/item/clothing/head/utility/hardhat/on_saboteur(datum/source, disrupt_duration) + . = ..() if(on) toggle_helmet_light() - return COMSIG_SABOTEUR_SUCCESS + return TRUE /obj/item/clothing/head/utility/hardhat/attack_self(mob/living/user) toggle_helmet_light(user) diff --git a/code/modules/clothing/spacesuits/plasmamen.dm b/code/modules/clothing/spacesuits/plasmamen.dm index 380cd0cf3fb..09c8f5e7d08 100644 --- a/code/modules/clothing/spacesuits/plasmamen.dm +++ b/code/modules/clothing/spacesuits/plasmamen.dm @@ -78,7 +78,6 @@ . = ..() visor_toggling() update_appearance() - RegisterSignal(src, COMSIG_HIT_BY_SABOTEUR, PROC_REF(on_saboteur)) /obj/item/clothing/head/helmet/space/plasmaman/examine() . = ..() @@ -194,13 +193,13 @@ update_item_action_buttons() -/obj/item/clothing/head/helmet/space/plasmaman/proc/on_saboteur(datum/source, disrupt_duration) - SIGNAL_HANDLER +/obj/item/clothing/head/helmet/space/plasmaman/on_saboteur(datum/source, disrupt_duration) + . = ..() if(!helmet_on) - return + return FALSE helmet_on = FALSE update_appearance() - return COMSIG_SABOTEUR_SUCCESS + return TRUE /obj/item/clothing/head/helmet/space/plasmaman/attack_hand_secondary(mob/user) ..() diff --git a/code/modules/mining/equipment/kinetic_crusher.dm b/code/modules/mining/equipment/kinetic_crusher.dm index 6a276e83072..1da0a7db6a3 100644 --- a/code/modules/mining/equipment/kinetic_crusher.dm +++ b/code/modules/mining/equipment/kinetic_crusher.dm @@ -49,7 +49,6 @@ ) //technically it's huge and bulky, but this provides an incentive to use it AddComponent(/datum/component/two_handed, force_unwielded=0, force_wielded=20) - RegisterSignal(src, COMSIG_HIT_BY_SABOTEUR, PROC_REF(on_saboteur)) /obj/item/kinetic_crusher/Destroy() QDEL_LIST(trophies) @@ -175,10 +174,11 @@ playsound(user, 'sound/weapons/empty.ogg', 100, TRUE) update_appearance() -/obj/item/kinetic_crusher/proc/on_saboteur(datum/source, disrupt_duration) +/obj/item/kinetic_crusher/on_saboteur(datum/source, disrupt_duration) + . = ..() set_light_on(FALSE) playsound(src, 'sound/weapons/empty.ogg', 100, TRUE) - return COMSIG_SABOTEUR_SUCCESS + return TRUE /obj/item/kinetic_crusher/update_icon_state() inhand_icon_state = "crusher[HAS_TRAIT(src, TRAIT_WIELDED)]" // this is not icon_state and not supported by 2hcomponent diff --git a/code/modules/mob/living/carbon/human/species_types/ethereal.dm b/code/modules/mob/living/carbon/human/species_types/ethereal.dm index 669b4f6b18d..0f27f0e47e6 100644 --- a/code/modules/mob/living/carbon/human/species_types/ethereal.dm +++ b/code/modules/mob/living/carbon/human/species_types/ethereal.dm @@ -54,7 +54,7 @@ default_color = new_ethereal.dna.features["ethcolor"] RegisterSignal(new_ethereal, COMSIG_ATOM_EMAG_ACT, PROC_REF(on_emag_act)) RegisterSignal(new_ethereal, COMSIG_ATOM_EMP_ACT, PROC_REF(on_emp_act)) - RegisterSignal(new_ethereal, COMSIG_HIT_BY_SABOTEUR, PROC_REF(on_saboteur)) + RegisterSignal(new_ethereal, COMSIG_ATOM_SABOTEUR_ACT, PROC_REF(hit_by_saboteur)) RegisterSignal(new_ethereal, COMSIG_LIGHT_EATER_ACT, PROC_REF(on_light_eater)) RegisterSignal(new_ethereal, COMSIG_LIVING_HEALTH_UPDATE, PROC_REF(refresh_light_color)) ethereal_light = new_ethereal.mob_light(light_type = /obj/effect/dummy/lighting_obj/moblight/species) @@ -71,7 +71,7 @@ UnregisterSignal(former_ethereal, list( COMSIG_ATOM_EMAG_ACT, COMSIG_ATOM_EMP_ACT, - COMSIG_HIT_BY_SABOTEUR, + COMSIG_ATOM_SABOTEUR_ACT, COMSIG_LIGHT_EATER_ACT, COMSIG_LIVING_HEALTH_UPDATE, )) @@ -124,14 +124,13 @@ if(EMP_HEAVY) addtimer(CALLBACK(src, PROC_REF(stop_emp), source), 20 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE) //We're out for 20 seconds -/datum/species/ethereal/proc/on_saboteur(mob/living/carbon/human/source, disrupt_duration) - SIGNAL_HANDLER +/datum/species/ethereal/proc/hit_by_saboteur(mob/living/carbon/human/source, disrupt_duration) EMPeffect = TRUE refresh_light_color(source) to_chat(source, span_warning("Something inside of you crackles in a bad way.")) source.take_bodypart_damage(burn = 3, wound_bonus = CANT_WOUND) addtimer(CALLBACK(src, PROC_REF(stop_emp), source), disrupt_duration, TIMER_UNIQUE|TIMER_OVERRIDE) - return COMSIG_SABOTEUR_SUCCESS + return TRUE /datum/species/ethereal/proc/on_emag_act(mob/living/carbon/human/source, mob/user) SIGNAL_HANDLER diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 2f670c5fbe2..dc6f449bdb4 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -19,7 +19,6 @@ AddElement(/datum/element/ridable, /datum/component/riding/creature/cyborg) RegisterSignal(src, COMSIG_PROCESS_BORGCHARGER_OCCUPANT, PROC_REF(charge)) RegisterSignal(src, COMSIG_LIGHT_EATER_ACT, PROC_REF(on_light_eater)) - RegisterSignal(src, COMSIG_HIT_BY_SABOTEUR, PROC_REF(on_saboteur)) robot_modules_background = new() robot_modules_background.icon_state = "block" @@ -452,12 +451,13 @@ return COMPONENT_BLOCK_LIGHT_EATER /// special handling for getting shot with a light disruptor/saboteur e.g. the fisher -/mob/living/silicon/robot/proc/on_saboteur(datum/source, disrupt_duration) - SIGNAL_HANDLER +/mob/living/silicon/robot/on_saboteur(datum/source, disrupt_duration) + . = ..() if(lamp_enabled) toggle_headlamp(TRUE) balloon_alert(src, "headlamp off!") - return COMSIG_SABOTEUR_SUCCESS + COOLDOWN_START(src, disabled_time, disrupt_duration) + return TRUE /** * Handles headlamp smashing @@ -489,6 +489,9 @@ */ /mob/living/silicon/robot/proc/toggle_headlamp(turn_off = FALSE, update_color = FALSE) //if both lamp is enabled AND the update_color flag is on, keep the lamp on. Otherwise, if anything listed is true, disable the lamp. + if(!COOLDOWN_FINISHED(src, disabled_time)) + balloon_alert(src, "disrupted!") + return FALSE if(!(update_color && lamp_enabled) && (turn_off || lamp_enabled || update_color || !lamp_functional || stat || low_power_mode)) set_light_on(lamp_functional && stat != DEAD && lamp_doom) //If the lamp isn't broken and borg isn't dead, doomsday borgs cannot disable their light fully. set_light_color(COLOR_RED) //This should only matter for doomsday borgs, as any other time the lamp will be off and the color not seen diff --git a/code/modules/mob/living/silicon/robot/robot_defines.dm b/code/modules/mob/living/silicon/robot/robot_defines.dm index e6af597bc60..e85dba4a134 100644 --- a/code/modules/mob/living/silicon/robot/robot_defines.dm +++ b/code/modules/mob/living/silicon/robot/robot_defines.dm @@ -42,6 +42,8 @@ ///If this is a path, this gets created as an object in Initialize. var/obj/item/stock_parts/power_store/cell = /obj/item/stock_parts/power_store/cell/high + ///If we've been forcibly disabled for a temporary amount of time. + COOLDOWN_DECLARE(disabled_time) ///If the lamp isn't broken. var/lamp_functional = TRUE ///If the lamp is turned on diff --git a/code/modules/mob/living/simple_animal/bot/secbot.dm b/code/modules/mob/living/simple_animal/bot/secbot.dm index ea094416872..d946367f6c3 100644 --- a/code/modules/mob/living/simple_animal/bot/secbot.dm +++ b/code/modules/mob/living/simple_animal/bot/secbot.dm @@ -143,7 +143,6 @@ ) AddElement(/datum/element/connect_loc, loc_connections) AddComponent(/datum/component/security_vision, judgement_criteria = NONE, update_judgement_criteria = CALLBACK(src, PROC_REF(judgement_criteria))) - RegisterSignal(src, COMSIG_HIT_BY_SABOTEUR, PROC_REF(on_saboteur)) /mob/living/simple_animal/bot/secbot/Destroy() QDEL_NULL(weapon) @@ -167,12 +166,12 @@ GLOB.move_manager.stop_looping(src) last_found = world.time -/mob/living/simple_animal/bot/secbot/proc/on_saboteur(datum/source, disrupt_duration) - SIGNAL_HANDLER +/mob/living/simple_animal/bot/secbot/on_saboteur(datum/source, disrupt_duration) + . = ..() if(!(security_mode_flags & SECBOT_SABOTEUR_AFFECTED)) security_mode_flags |= SECBOT_SABOTEUR_AFFECTED addtimer(CALLBACK(src, PROC_REF(remove_saboteur_effect)), disrupt_duration) - return COMSIG_SABOTEUR_SUCCESS + return TRUE /mob/living/simple_animal/bot/secbot/proc/remove_saboteur_effect() security_mode_flags &= ~SECBOT_SABOTEUR_AFFECTED diff --git a/code/modules/mod/modules/modules_antag.dm b/code/modules/mod/modules/modules_antag.dm index 4a63c66085a..c67fd7755d8 100644 --- a/code/modules/mod/modules/modules_antag.dm +++ b/code/modules/mod/modules/modules_antag.dm @@ -558,3 +558,63 @@ /obj/item/gun/medbeam/mod name = "MOD medbeam" + +/obj/item/mod/module/stealth/wraith + name = "MOD Wraith Cloaking Module" + desc = "A more destructive adaptation of the stealth module." + icon_state = "cloak_traitor" + stealth_alpha = 30 + module_type = MODULE_ACTIVE + cooldown_time = 2 SECONDS + +/obj/item/mod/module/stealth/wraith/on_select_use(atom/target) + . = ..() + if(!. || target == mod.wearer) + return + if(get_dist(mod.wearer, target) > 6) + balloon_alert(mod.wearer, "can't reach that!") + return + if(istype(target, /obj/machinery/power/apc)) //Bit too strong for a module so this is blacklisted + balloon_alert(mod.wearer, "cant disable apc!") + return + + var/list/things_to_disrupt = list(target) + if(isliving(target)) + var/mob/living/live_target = target + things_to_disrupt += live_target.get_all_gear() + + for(var/atom/disrupted as anything in things_to_disrupt) + if(disrupted.on_saboteur(src, 1 MINUTES)) + mod.add_charge(DEFAULT_CHARGE_DRAIN * 250) + +/obj/item/mod/module/stealth/wraith/on_suit_activation() + if(bumpoff) + RegisterSignal(mod.wearer, COMSIG_LIVING_MOB_BUMP, PROC_REF(unstealth)) + RegisterSignal(mod.wearer, COMSIG_LIVING_UNARMED_ATTACK, PROC_REF(on_unarmed_attack)) + RegisterSignal(mod.wearer, COMSIG_ATOM_BULLET_ACT, PROC_REF(on_bullet_act)) + RegisterSignals(mod.wearer, list(COMSIG_MOB_ITEM_ATTACK, COMSIG_ATOM_ATTACKBY, COMSIG_ATOM_ATTACK_HAND, COMSIG_ATOM_HITBY, COMSIG_ATOM_HULK_ATTACK, COMSIG_ATOM_ATTACK_PAW, COMSIG_CARBON_CUFF_ATTEMPTED), PROC_REF(unstealth)) + animate(mod.wearer, alpha = stealth_alpha, time = 1.5 SECONDS) + drain_power(use_energy_cost) + +/obj/item/mod/module/stealth/wraith/on_suit_deactivation(deleting) + if(bumpoff) + UnregisterSignal(mod.wearer, COMSIG_LIVING_MOB_BUMP) + UnregisterSignal(mod.wearer, list(COMSIG_LIVING_UNARMED_ATTACK, COMSIG_MOB_ITEM_ATTACK, COMSIG_ATOM_ATTACKBY, COMSIG_ATOM_ATTACK_HAND, COMSIG_ATOM_BULLET_ACT, COMSIG_ATOM_HITBY, COMSIG_ATOM_HULK_ATTACK, COMSIG_ATOM_ATTACK_PAW, COMSIG_CARBON_CUFF_ATTEMPTED)) + animate(mod.wearer, alpha = 255, time = 1.5 SECONDS) + +/obj/item/mod/module/stealth/wraith/unstealth(datum/source) + . = ..() + if(mod.active) + addtimer(CALLBACK(src, PROC_REF(on_suit_activation)), 5 SECONDS) + +/obj/item/mod/module/stealth/wraith/examine_more(mob/user) + . = ..() + . += span_info( \ + "The Wraith Module does not simply bend light around the user to obscure their visual pattern, \ + but actively attacks and overloads surrounding light emitting objects, repurposing this energy to power the suit. \ + It is possible that this technology has its origins in Spider Clan advancements, \ + but the exact source of the Wraith Module is highly disputed. \ + No group has stepped forward to claim it as their handiwork due to the political consequences of having stolen Spider Clan tech and their inevitable retaliation for such transgressions. \ + Most point fingers at Cybersun Industries, but murmurs suggest it could even be even more clandestine organizations amongst the Syndicate branches. \ + Whatever the case, if you are looking at one of these right now, don't show it to a space ninja." \ + ) diff --git a/code/modules/mod/modules/modules_general.dm b/code/modules/mod/modules/modules_general.dm index 3b7803a517a..34f3de0cfa0 100644 --- a/code/modules/mod/modules/modules_general.dm +++ b/code/modules/mod/modules/modules_general.dm @@ -388,12 +388,6 @@ /// Maximum range we can set. var/max_range = 5 -/obj/item/mod/module/flashlight/on_suit_activation() - RegisterSignal(mod.wearer, COMSIG_HIT_BY_SABOTEUR, PROC_REF(on_saboteur)) - -/obj/item/mod/module/flashlight/on_suit_deactivation(deleting = FALSE) - UnregisterSignal(mod.wearer, COMSIG_HIT_BY_SABOTEUR) - /obj/item/mod/module/flashlight/on_activation() set_light_flags(light_flags | LIGHT_ATTACHED) set_light_on(active) @@ -403,11 +397,11 @@ set_light_flags(light_flags & ~LIGHT_ATTACHED) set_light_on(active) -/obj/item/mod/module/flashlight/proc/on_saboteur(datum/source, disrupt_duration) - SIGNAL_HANDLER +/obj/item/mod/module/flashlight/on_saboteur(datum/source, disrupt_duration) + . = ..() if(active) on_deactivation() - return COMSIG_SABOTEUR_SUCCESS + return TRUE /obj/item/mod/module/flashlight/on_process(seconds_per_tick) active_power_cost = base_power * light_range diff --git a/code/modules/modular_computers/computers/item/computer.dm b/code/modules/modular_computers/computers/item/computer.dm index 4f4a8fcc170..d8e41c67cb5 100644 --- a/code/modules/modular_computers/computers/item/computer.dm +++ b/code/modules/modular_computers/computers/item/computer.dm @@ -139,7 +139,6 @@ UpdateDisplay() if(has_light) add_item_action(/datum/action/item_action/toggle_computer_light) - RegisterSignal(src, COMSIG_HIT_BY_SABOTEUR, PROC_REF(on_saboteur)) if(inserted_disk) inserted_disk = new inserted_disk(src) if(internal_cell) @@ -753,20 +752,16 @@ update_item_action_buttons(force = TRUE) //force it because we added an overlay, not changed its icon return TRUE -/** - * Disables the computer's flashlight/LED light, if it has one, for a given disrupt_duration. - * - * Called when sent COMSIG_HIT_BY_SABOTEUR. - */ -/obj/item/modular_computer/proc/on_saboteur(datum/source, disrupt_duration) - SIGNAL_HANDLER +//Disables the computer's flashlight/LED light, if it has one, for a given disrupt_duration. +/obj/item/modular_computer/on_saboteur(datum/source, disrupt_duration) + . = ..() if(!has_light) return set_light_on(FALSE) update_appearance() update_item_action_buttons(force = TRUE) //force it because we added an overlay, not changed its icon COOLDOWN_START(src, disabled_time, disrupt_duration) - return COMSIG_SABOTEUR_SUCCESS + return TRUE /** * Sets the computer's light color, if it has a light. diff --git a/code/modules/pai/card.dm b/code/modules/pai/card.dm index ccf0bae5f04..35d707ec0f2 100644 --- a/code/modules/pai/card.dm +++ b/code/modules/pai/card.dm @@ -27,7 +27,6 @@ update_appearance() SSpai.pai_card_list += src ADD_TRAIT(src, TRAIT_CASTABLE_LOC, INNATE_TRAIT) - RegisterSignal(src, COMSIG_HIT_BY_SABOTEUR, PROC_REF(on_saboteur)) /obj/item/pai_card/attackby(obj/item/used, mob/user, params) if(pai && istype(used, /obj/item/encryptionkey)) @@ -71,8 +70,8 @@ emotion_icon = initial(emotion_icon) update_appearance() -/obj/item/pai_card/proc/on_saboteur(datum/source, disrupt_duration) - SIGNAL_HANDLER +/obj/item/pai_card/on_saboteur(datum/source, disrupt_duration) + . = ..() if(pai) return pai.on_saboteur(source, disrupt_duration) diff --git a/code/modules/pai/pai.dm b/code/modules/pai/pai.dm index 4268c040e2b..5792fef8e6a 100644 --- a/code/modules/pai/pai.dm +++ b/code/modules/pai/pai.dm @@ -239,7 +239,6 @@ RegisterSignal(src, COMSIG_LIVING_CULT_SACRIFICED, PROC_REF(on_cult_sacrificed)) RegisterSignals(src, list(COMSIG_LIVING_ADJUST_BRUTE_DAMAGE, COMSIG_LIVING_ADJUST_BURN_DAMAGE), PROC_REF(on_shell_damaged)) RegisterSignal(src, COMSIG_LIVING_ADJUST_STAMINA_DAMAGE, PROC_REF(on_shell_weakened)) - RegisterSignal(src, COMSIG_HIT_BY_SABOTEUR, PROC_REF(on_saboteur)) /mob/living/silicon/pai/make_laws() laws = new /datum/ai_laws/pai() @@ -353,11 +352,11 @@ to_chat(src, span_danger("WARN: Holochasis range restrictions disabled.")) return TRUE -/mob/living/silicon/pai/proc/on_saboteur(datum/source, disrupt_duration) - SIGNAL_HANDLER +/mob/living/silicon/pai/on_saboteur(datum/source, disrupt_duration) + . = ..() set_silence_if_lower(disrupt_duration) balloon_alert(src, "muted!") - return COMSIG_SABOTEUR_SUCCESS + return TRUE /** * Resets the pAI and any emagged status. diff --git a/code/modules/power/apc/apc_main.dm b/code/modules/power/apc/apc_main.dm index b0c5035a1f8..9a4443abe62 100644 --- a/code/modules/power/apc/apc_main.dm +++ b/code/modules/power/apc/apc_main.dm @@ -223,7 +223,6 @@ register_context() addtimer(CALLBACK(src, PROC_REF(update)), 0.5 SECONDS) RegisterSignal(SSdcs, COMSIG_GLOB_GREY_TIDE, PROC_REF(grey_tide)) - RegisterSignal(src, COMSIG_HIT_BY_SABOTEUR, PROC_REF(on_saboteur)) update_appearance() var/static/list/hovering_mob_typechecks = list( @@ -255,12 +254,11 @@ disconnect_terminal() return ..() -/obj/machinery/power/apc/proc/on_saboteur(datum/source, disrupt_duration) - SIGNAL_HANDLER - +/obj/machinery/power/apc/on_saboteur(datum/source, disrupt_duration) + . = ..() disrupt_duration *= 0.1 // so, turns out, failure timer is in seconds, not deciseconds; without this, disruptions last 10 times as long as they probably should energy_fail(disrupt_duration) - return COMSIG_SABOTEUR_SUCCESS + return TRUE /obj/machinery/power/apc/on_set_is_operational(old_value) update_area_power_usage(!old_value) diff --git a/code/modules/power/floodlight.dm b/code/modules/power/floodlight.dm index 38354241f9a..ce7e662f1b6 100644 --- a/code/modules/power/floodlight.dm +++ b/code/modules/power/floodlight.dm @@ -150,7 +150,6 @@ /obj/machinery/power/floodlight/Initialize(mapload) . = ..() RegisterSignal(src, COMSIG_OBJ_PAINTED, TYPE_PROC_REF(/obj/machinery/power/floodlight, on_color_change)) //update light color when color changes - RegisterSignal(src, COMSIG_HIT_BY_SABOTEUR, PROC_REF(on_saboteur)) register_context() /obj/machinery/power/floodlight/proc/on_color_change(obj/machinery/power/flood_light, mob/user, obj/item/toy/crayon/spraycan/spraycan, is_dark_color) @@ -296,10 +295,10 @@ /obj/machinery/power/floodlight/attack_ai(mob/user) return attack_hand(user) -/obj/machinery/power/floodlight/proc/on_saboteur(datum/source, disrupt_duration) - SIGNAL_HANDLER +/obj/machinery/power/floodlight/on_saboteur(datum/source, disrupt_duration) + . = ..() atom_break(ENERGY) // technically, - return COMSIG_SABOTEUR_SUCCESS + return TRUE /obj/machinery/power/floodlight/atom_break(damage_flag) . = ..() diff --git a/code/modules/power/lighting/light.dm b/code/modules/power/lighting/light.dm index 889ca7244e8..431f2095b0a 100644 --- a/code/modules/power/lighting/light.dm +++ b/code/modules/power/lighting/light.dm @@ -116,7 +116,6 @@ // Light projects out backwards from the dir of the light set_light(l_dir = REVERSE_DIR(dir)) RegisterSignal(src, COMSIG_LIGHT_EATER_ACT, PROC_REF(on_light_eater)) - RegisterSignal(src, COMSIG_HIT_BY_SABOTEUR, PROC_REF(on_saboteur)) AddElement(/datum/element/atmos_sensitive, mapload) AddElement(/datum/element/contextual_screentip_bare_hands, rmb_text = "Remove bulb") if(break_if_moved) @@ -688,10 +687,10 @@ tube?.burn() return -/obj/machinery/light/proc/on_saboteur(datum/source, disrupt_duration) - SIGNAL_HANDLER +/obj/machinery/light/on_saboteur(datum/source, disrupt_duration) + . = ..() break_light_tube() - return COMSIG_SABOTEUR_SUCCESS + return TRUE /obj/machinery/light/proc/grey_tide(datum/source, list/grey_tide_areas) SIGNAL_HANDLER diff --git a/code/modules/projectiles/projectile/special/saboteur.dm b/code/modules/projectiles/projectile/special/saboteur.dm index 46fcc136c09..5e7249b7d54 100644 --- a/code/modules/projectiles/projectile/special/saboteur.dm +++ b/code/modules/projectiles/projectile/special/saboteur.dm @@ -1,3 +1,9 @@ +///Override on subtype to add behaviour. Whatever happens when we are sabotaged +/atom/proc/on_saboteur(datum/source, disrupt_duration) + SHOULD_CALL_PARENT(TRUE) + if(SEND_SIGNAL(src, COMSIG_ATOM_SABOTEUR_ACT, disrupt_duration) & COMSIG_SABOTEUR_SUCCESS) //Signal handles datums for the most part + return TRUE + /obj/projectile/energy/fisher name = "attenuated kinetic force" alpha = 0 @@ -19,7 +25,7 @@ var/success = FALSE for(var/atom/disrupted as anything in things_to_disrupt) - if(SEND_SIGNAL(disrupted, COMSIG_HIT_BY_SABOTEUR, disrupt_duration) & COMSIG_SABOTEUR_SUCCESS) + if(disrupted.on_saboteur(src, disrupt_duration)) success = TRUE if(success && ismob(firer)) diff --git a/code/modules/uplink/uplink_items/suits.dm b/code/modules/uplink/uplink_items/suits.dm index b66cce4eaec..2839a6d2d1e 100644 --- a/code/modules/uplink/uplink_items/suits.dm +++ b/code/modules/uplink/uplink_items/suits.dm @@ -80,3 +80,9 @@ progression_minimum = 90 MINUTES cost = 16 cant_discount = TRUE + +/datum/uplink_item/suits/modsuit/Wraith + name = "MODsuit wraith cloaking module" + desc = "A MODsuit module that grants to the user Optical camouflage and the ability to overload light sources to recharge suit power." + item = /obj/item/mod/module/stealth/wraith + cost = 3 diff --git a/code/modules/vehicles/mecha/_mecha.dm b/code/modules/vehicles/mecha/_mecha.dm index 3eb64658ccc..4755631dfeb 100644 --- a/code/modules/vehicles/mecha/_mecha.dm +++ b/code/modules/vehicles/mecha/_mecha.dm @@ -229,7 +229,6 @@ ui_view.generate_view("mech_view_[REF(src)]") RegisterSignal(src, COMSIG_MOVABLE_MOVED, PROC_REF(on_move)) RegisterSignal(src, COMSIG_LIGHT_EATER_ACT, PROC_REF(on_light_eater)) - RegisterSignal(src, COMSIG_HIT_BY_SABOTEUR, PROC_REF(on_saboteur)) spark_system = new spark_system.set_up(2, 0, src) @@ -833,11 +832,11 @@ remove_action_type_from_mob(/datum/action/vehicle/sealed/mecha/mech_toggle_lights, occupant) return COMPONENT_BLOCK_LIGHT_EATER -/obj/vehicle/sealed/mecha/proc/on_saboteur(datum/source, disrupt_duration) - SIGNAL_HANDLER +/obj/vehicle/sealed/mecha/on_saboteur(datum/source, disrupt_duration) + . = ..() if(mecha_flags &= HAS_LIGHTS && light_on) set_light_on(FALSE) - return COMSIG_SABOTEUR_SUCCESS + return TRUE /// Apply corresponding accesses /obj/vehicle/sealed/mecha/proc/update_access() diff --git a/icons/obj/clothing/modsuit/mod_modules.dmi b/icons/obj/clothing/modsuit/mod_modules.dmi index 5cab83c56d5..9d5600dab80 100644 Binary files a/icons/obj/clothing/modsuit/mod_modules.dmi and b/icons/obj/clothing/modsuit/mod_modules.dmi differ