From 1e6b60efd0711559061745521487c6c75c0410f5 Mon Sep 17 00:00:00 2001 From: KittyNoodle Date: Sat, 18 Nov 2023 16:05:05 -0600 Subject: [PATCH] #76669 mirror --- code/game/atoms.dm | 9 +- code/game/machinery/announcement_system.dm | 6 +- code/game/machinery/barsigns.dm | 11 +- code/game/machinery/buttons.dm | 8 +- code/game/machinery/computer/apc_control.dm | 9 +- code/game/machinery/computer/arcade/arcade.dm | 10 +- code/game/machinery/computer/arcade/orion.dm | 11 +- .../game/machinery/computer/communications.dm | 21 ++-- code/game/machinery/doors/airlock.dm | 34 ++++--- code/game/machinery/doors/firedoor.dm | 9 +- code/game/machinery/doors/unpowered.dm | 4 +- code/game/machinery/doors/windowdoor.dm | 14 ++- .../embedded_controller/access_controller.dm | 7 +- code/game/machinery/fat_sucker.dm | 5 +- code/game/machinery/firealarm.dm | 9 +- code/game/machinery/gulag_item_reclaimer.dm | 6 +- code/game/machinery/harvester.dm | 8 +- code/game/machinery/limbgrower.dm | 8 +- code/game/machinery/medical_kiosk.dm | 10 +- .../machinery/porta_turret/portable_turret.dm | 14 +-- .../porta_turret/portable_turret_cover.dm | 18 ++-- code/game/machinery/recycler.dm | 7 +- code/game/machinery/scan_gate.dm | 7 +- code/game/machinery/shieldgen.dm | 14 +-- code/game/machinery/sleepers.dm | 7 +- code/game/machinery/slotmachine.dm | 6 +- .../machinery/telecomms/computers/message.dm | 6 +- code/game/objects/items/cigs_lighters.dm | 34 ++++--- .../circuitboards/computer_circuitboards.dm | 28 ++++-- code/game/objects/items/defib.dm | 15 +-- .../objects/items/devices/lightreplacer.dm | 8 +- code/game/objects/items/devices/megaphone.dm | 7 +- .../objects/items/devices/radio/intercom.dm | 6 +- code/game/objects/items/rcd/RSF.dm | 7 +- .../game/objects/items/robot/items/generic.dm | 7 +- code/game/objects/items/storage/lockbox.dm | 10 +- code/game/objects/items/toys.dm | 35 ++++--- .../structures/crates_lockers/closets.dm | 10 +- code/game/objects/structures/displaycase.dm | 6 +- code/game/objects/structures/morgue.dm | 8 ++ code/game/objects/structures/toiletbong.dm | 6 +- .../objects/structures/training_machine.dm | 3 +- .../antagonists/malf_ai/malf_ai_modules.dm | 95 ++++++++++++++++++ .../machinery/air_alarm/air_alarm_interact.dm | 8 +- code/modules/balloon_alert/balloon_alert.dm | 10 +- code/modules/cargo/expressconsole.dm | 10 +- code/modules/cargo/orderconsole.dm | 10 +- code/modules/clothing/glasses/hud.dm | 7 +- code/modules/clothing/masks/hailer.dm | 7 +- .../clothing/spacesuits/_spacesuits.dm | 11 +- code/modules/experisci/destructive_scanner.dm | 7 +- code/modules/holodeck/computer.dm | 18 ++-- .../elevator/elevator_controller.dm | 5 +- .../elevator/elevator_panel.dm | 5 +- .../industrial_lift/tram/tram_doors.dm | 5 +- .../industrial_lift/tram/tram_machinery.dm | 5 +- code/modules/library/lib_machines.dm | 8 +- code/modules/mining/abandoned_crates.dm | 10 +- code/modules/mining/laborcamp/laborstacker.dm | 13 ++- .../carbon/human/species_types/ethereal.dm | 3 +- .../mob/living/silicon/ai/ai_defense.dm | 7 +- .../mob/living/silicon/robot/robot_defense.dm | 33 +++--- .../mob/living/simple_animal/bot/bot.dm | 9 +- .../mob/living/simple_animal/bot/cleanbot.dm | 5 +- .../mob/living/simple_animal/bot/ed209bot.dm | 7 +- .../mob/living/simple_animal/bot/firebot.dm | 10 +- .../mob/living/simple_animal/bot/floorbot.dm | 9 +- .../mob/living/simple_animal/bot/medbot.dm | 8 +- .../mob/living/simple_animal/bot/mulebot.dm | 5 +- .../mob/living/simple_animal/bot/secbot.dm | 7 +- code/modules/mod/mod_control.dm | 3 +- code/modules/mod/modules/modules_general.dm | 3 +- .../computers/item/computer.dm | 12 ++- .../computers/machinery/modular_computer.dm | 4 +- code/modules/pai/card.dm | 3 +- code/modules/pai/pai.dm | 2 +- code/modules/paperwork/fax.dm | 7 +- code/modules/paperwork/ticketmachine.dm | 7 +- code/modules/power/apc/apc_tool_act.dm | 10 +- code/modules/power/port_gen.dm | 7 +- code/modules/power/singularity/emitter.dm | 8 +- code/modules/projectiles/pins.dm | 19 ++-- .../chemistry/machinery/chem_dispenser.dm | 9 +- code/modules/recycling/disposal/outlet.dm | 5 +- code/modules/research/rdconsole.dm | 16 +-- code/modules/research/server_control.dm | 5 +- .../xenobiology/vatgrowing/vatgrower.dm | 7 +- code/modules/shuttle/computer.dm | 7 +- code/modules/shuttle/emergency.dm | 24 +++-- code/modules/shuttle/ferry.dm | 4 +- code/modules/shuttle/special.dm | 8 +- code/modules/station_goals/bsa.dm | 6 +- code/modules/station_goals/meteor_shield.dm | 6 +- code/modules/surgery/organs/augments_arms.dm | 4 +- code/modules/vehicles/cars/clowncar.dm | 6 +- code/modules/vehicles/motorized_wheelchair.dm | 15 ++- code/modules/vending/_vending.dm | 7 +- icons/mob/actions/actions_AI.dmi | Bin 12262 -> 11221 bytes 98 files changed, 655 insertions(+), 364 deletions(-) mode change 100755 => 100644 code/game/machinery/computer/communications.dm diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 9f7d6effc033..4b5a29887898 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -1040,10 +1040,15 @@ /** * Respond to an emag being used on our atom * - * Default behaviour is to send [COMSIG_ATOM_EMAG_ACT] and return + * Args: + * * mob/user: The mob that used the emag. Nullable. + * * obj/item/card/emag/emag_card: The emag that was used. Nullable. + * + * Returns: + * TRUE if the emag had any effect, falsey otherwise. */ /atom/proc/emag_act(mob/user, obj/item/card/emag/emag_card) - SEND_SIGNAL(src, COMSIG_ATOM_EMAG_ACT, user, emag_card) + return (SEND_SIGNAL(src, COMSIG_ATOM_EMAG_ACT, user, emag_card)) /** * Respond to narsie eating our atom diff --git a/code/game/machinery/announcement_system.dm b/code/game/machinery/announcement_system.dm index 87f2a9f01c88..df3e402525d1 100644 --- a/code/game/machinery/announcement_system.dm +++ b/code/game/machinery/announcement_system.dm @@ -176,8 +176,10 @@ GLOBAL_LIST_EMPTY(announcement_systems) if(!(machine_stat & (NOPOWER|BROKEN)) && !(. & EMP_PROTECT_SELF)) act_up() -/obj/machinery/announcement_system/emag_act() +/obj/machinery/announcement_system/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) - return + return FALSE obj_flags |= EMAGGED act_up() + balloon_alert(user, "announcement strings corrupted") + return TRUE diff --git a/code/game/machinery/barsigns.dm b/code/game/machinery/barsigns.dm index 2883f9c4bbbf..d905a13d5d93 100644 --- a/code/game/machinery/barsigns.dm +++ b/code/game/machinery/barsigns.dm @@ -169,15 +169,18 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/barsign, 32) set_sign(sign) -/obj/machinery/barsign/emag_act(mob/user) +/obj/machinery/barsign/emag_act(mob/user, obj/item/card/emag/emag_card) if(machine_stat & (NOPOWER|BROKEN|EMPED)) balloon_alert(user, "controls are unresponsive!") - return + return FALSE balloon_alert(user, "illegal barsign loaded") - sleep(10 SECONDS) - set_sign(new /datum/barsign/hiddensigns/syndibarsign) + addtimer(CALLBACK(src, PROC_REF(finish_emag_act)), 10 SECONDS) + return TRUE +/// Timer proc, called after ~10 seconds after [emag_act], since [emag_act] returns a value and cannot sleep +/obj/machinery/barsign/proc/finish_emag_act() + set_sign(new /datum/barsign/hiddensigns/syndibarsign) /obj/machinery/barsign/proc/pick_sign(mob/user) var/picked_name = tgui_input_list(user, "Available Signage", "Bar Sign", sort_list(get_bar_names())) diff --git a/code/game/machinery/buttons.dm b/code/game/machinery/buttons.dm index c474a5ab8f37..fbe0c8d3cf7a 100644 --- a/code/game/machinery/buttons.dm +++ b/code/game/machinery/buttons.dm @@ -128,7 +128,7 @@ else return ..() -/obj/machinery/button/emag_act(mob/user) +/obj/machinery/button/emag_act(mob/user, obj/item/card/emag/emag_card) . = ..() if(obj_flags & EMAGGED) return @@ -139,9 +139,9 @@ // The device inside can be emagged by swiping the button // returning TRUE will prevent feedback (so we can do our own) - if(device?.emag_act(user)) - return - balloon_alert(user, "access overridden") + if(!device?.emag_act(user, emag_card)) + balloon_alert(user, "access overridden") + return TRUE /obj/machinery/button/attack_ai(mob/user) if(!silicon_access_disabled && !panel_open) diff --git a/code/game/machinery/computer/apc_control.dm b/code/game/machinery/computer/apc_control.dm index 882ef86f0dbf..6cecd17e8115 100644 --- a/code/game/machinery/computer/apc_control.dm +++ b/code/game/machinery/computer/apc_control.dm @@ -27,12 +27,15 @@ return ..() -/obj/machinery/computer/apc_control/emag_act(mob/user) +/obj/machinery/computer/apc_control/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) - return + return FALSE obj_flags |= EMAGGED - usr.log_message("emagged [src].", LOG_ATTACK, color="red") + if (user) + user.log_message("emagged [src].", LOG_ATTACK, color="red") + balloon_alert(user, "access controller shorted") playsound(src, SFX_SPARKS, 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) + return TRUE /obj/machinery/computer/apc_control/proc/log_activity(log_text) if(!should_log) diff --git a/code/game/machinery/computer/arcade/arcade.dm b/code/game/machinery/computer/arcade/arcade.dm index 01cfe699bfa5..107f3ef514ff 100644 --- a/code/game/machinery/computer/arcade/arcade.dm +++ b/code/game/machinery/computer/arcade/arcade.dm @@ -620,17 +620,18 @@ GLOBAL_LIST_INIT(arcade_prize_pool, list( . += "\t[span_info("magical -> defend until outmagiced")]" return . -/obj/machinery/computer/arcade/battle/emag_act(mob/user) +/obj/machinery/computer/arcade/battle/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) - return + return FALSE + balloon_alert(user, "hard mode enabled") to_chat(user, span_warning("A mesmerizing Rhumba beat starts playing from the arcade machine's speakers!")) temp = "

If you die in the game, you die for real!

" max_passive = 6 bomb_cooldown = 18 var/gamerSkill = 0 - if(usr?.mind) - gamerSkill = usr.mind.get_skill_level(/datum/skill/gaming) + if(user?.mind) + gamerSkill = user.mind.get_skill_level(/datum/skill/gaming) enemy_setup(gamerSkill) enemy_hp += 100 //extra HP just to make cuban pete even more bullshit player_hp += 30 //the player will also get a few extra HP in order to have a fucking chance @@ -644,6 +645,7 @@ GLOBAL_LIST_INIT(arcade_prize_pool, list( name = "Outbomb Cuban Pete" updateUsrDialog() + return TRUE // ** AMPUTATION ** // diff --git a/code/game/machinery/computer/arcade/orion.dm b/code/game/machinery/computer/arcade/orion.dm index e883b35fe1df..8b05c4507b15 100644 --- a/code/game/machinery/computer/arcade/orion.dm +++ b/code/game/machinery/computer/arcade/orion.dm @@ -489,15 +489,18 @@ GLOBAL_LIST_INIT(orion_events, generate_orion_events()) name = initial(name) desc = initial(desc) -/obj/machinery/computer/arcade/orion_trail/emag_act(mob/user) +/obj/machinery/computer/arcade/orion_trail/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) - return - to_chat(user, span_notice("You override the cheat code menu and skip to Cheat #[rand(1, 50)]: Realism Mode.")) - user.log_message("emagged [src], activating Realism Mode.", LOG_GAME) + return FALSE + if (user) + user.log_message("emagged [src], activating Realism Mode.", LOG_GAME) + balloon_alert(user, "realism mode enabled") + to_chat(user, span_notice("You override the cheat code menu and skip to Cheat #[rand(1, 50)]: Realism Mode.")) name = "The Orion Trail: Realism Edition" desc = "Learn how our ancestors got to Orion, and try not to die in the process!" newgame() obj_flags |= EMAGGED + return TRUE /mob/living/basic/syndicate/ranged/smg/orion name = "spaceport security" diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm old mode 100755 new mode 100644 index 5d6563bba2b1..955f0e0535b4 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -67,7 +67,7 @@ syndicate = TRUE /obj/machinery/computer/communications/syndicate/emag_act(mob/user, obj/item/card/emag/emag_card) - return + return FALSE /obj/machinery/computer/communications/syndicate/can_buy_shuttles(mob/user) return FALSE @@ -116,26 +116,29 @@ /obj/machinery/computer/communications/emag_act(mob/user, obj/item/card/emag/emag_card) if(istype(emag_card, /obj/item/card/emag/battlecruiser)) - if(!IS_TRAITOR(user)) - to_chat(user, span_danger("You get the feeling this is a bad idea.")) - return var/obj/item/card/emag/battlecruiser/caller_card = emag_card + if (user) + if(!IS_TRAITOR(user)) + to_chat(user, span_danger("You get the feeling this is a bad idea.")) + return FALSE if(battlecruiser_called) - to_chat(user, span_danger("The card reports a long-range message already sent to the Syndicate fleet...?")) - return + if (user) + to_chat(user, span_danger("The card reports a long-range message already sent to the Syndicate fleet...?")) + return FALSE battlecruiser_called = TRUE caller_card.use_charge(user) addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(summon_battlecruiser), caller_card.team), rand(20 SECONDS, 1 MINUTES)) playsound(src, 'sound/machines/terminal_alert.ogg', 50, FALSE) - return + return TRUE if(obj_flags & EMAGGED) - return + return FALSE obj_flags |= EMAGGED if (authenticated) authorize_access = SSid_access.get_region_access_list(list(REGION_ALL_STATION)) - to_chat(user, span_danger("You scramble the communication routing circuits!")) + balloon_alert(user, "routing circuits scrambled") playsound(src, 'sound/machines/terminal_alert.ogg', 50, FALSE) + return TRUE /obj/machinery/computer/communications/ui_act(action, list/params) var/static/list/approved_states = list(STATE_BUYING_SHUTTLE, STATE_CHANGING_STATUS, STATE_MAIN, STATE_MESSAGES) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 2701f72b08a5..7ffeb7b84385 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -1327,23 +1327,29 @@ //Airlock is passable if it is open (!density), bot has access, and is not bolted shut or powered off) return !density || (check_access(ID) && !locked && hasPower() && !no_id) -/obj/machinery/door/airlock/emag_act(mob/user, obj/item/card/emag/doorjack/D) +/obj/machinery/door/airlock/emag_act(mob/user, obj/item/card/emag/emag_card) if(!operating && density && hasPower() && !(obj_flags & EMAGGED)) - if(istype(D, /obj/item/card/emag/doorjack)) - D.use_charge(user) + if(istype(emag_card, /obj/item/card/emag/doorjack)) + var/obj/item/card/emag/doorjack/doorjack_card = emag_card + doorjack_card.use_charge(user) operating = TRUE update_icon(ALL, AIRLOCK_EMAG, 1) - sleep(0.6 SECONDS) - if(QDELETED(src)) - return - operating = FALSE - if(!open()) - update_icon(ALL, AIRLOCK_CLOSED, 1) - obj_flags |= EMAGGED - lights = FALSE - locked = TRUE - loseMainPower() - loseBackupPower() + addtimer(CALLBACK(src, PROC_REF(finish_emag_act)), 0.6 SECONDS) + return TRUE + return FALSE + +/// Timer proc, called ~0.6 seconds after [emag_act]. Finishes the emag sequence by breaking the airlock, permanently locking it, and disabling power. +/obj/machinery/door/airlock/proc/finish_emag_act() + if(QDELETED(src)) + return FALSE + operating = FALSE + if(!open()) + update_icon(ALL, AIRLOCK_CLOSED, 1) + obj_flags |= EMAGGED + lights = FALSE + locked = TRUE + loseMainPower() + loseBackupPower() /obj/machinery/door/airlock/attack_alien(mob/living/carbon/alien/adult/user, list/modifiers) if(isElectrified() && shock(user, 100)) //Mmm, fried xeno! diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index e76c1c6f3001..7d56b156a94a 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -436,14 +436,15 @@ if(place == my_area) place.alarm_manager.clear_alarm(ALARM_FIRE, place) -/obj/machinery/door/firedoor/emag_act(mob/user, obj/item/card/emag/emag_type) +/obj/machinery/door/firedoor/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) - return - if(istype(emag_type, /obj/item/card/emag/doorjack)) //Skip doorjack-specific code - var/obj/item/card/emag/doorjack/digital_crowbar = emag_type + return FALSE + if(istype(emag_card, /obj/item/card/emag/doorjack)) //Skip doorjack-specific code + var/obj/item/card/emag/doorjack/digital_crowbar = emag_card digital_crowbar.use_charge(user) obj_flags |= EMAGGED INVOKE_ASYNC(src, PROC_REF(open)) + return TRUE /obj/machinery/door/firedoor/Bumped(atom/movable/AM) if(panel_open || operating) diff --git a/code/game/machinery/doors/unpowered.dm b/code/game/machinery/doors/unpowered.dm index 9372abe59ce1..6a9fea474192 100644 --- a/code/game/machinery/doors/unpowered.dm +++ b/code/game/machinery/doors/unpowered.dm @@ -13,8 +13,8 @@ else return ..() -/obj/machinery/door/unpowered/emag_act() - return +/obj/machinery/door/unpowered/emag_act(mob/user, obj/item/card/emag/emag_card) + return FALSE /obj/machinery/door/unpowered/shuttle icon = 'icons/turf/shuttle.dmi' diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index a1dbe5961e94..5571475a6814 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -324,16 +324,20 @@ /obj/machinery/door/window/atmos_expose(datum/gas_mixture/air, exposed_temperature) take_damage(round(exposed_temperature / 200), BURN, 0, 0) - -/obj/machinery/door/window/emag_act(mob/user) +/obj/machinery/door/window/emag_act(mob/user, obj/item/card/emag/emag_card) if(!operating && density && !(obj_flags & EMAGGED)) obj_flags |= EMAGGED operating = TRUE flick("[base_state]spark", src) playsound(src, SFX_SPARKS, 75, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - sleep(0.6 SECONDS) - operating = FALSE - open(BYPASS_DOOR_CHECKS) + addtimer(CALLBACK(src, PROC_REF(finish_emag_act)), 0.6 SECONDS) + return TRUE + return FALSE + +/// Timer proc, called ~0.6 seconds after [emag_act]. Finishes the emag sequence by breaking the windoor. +/obj/machinery/door/window/proc/finish_emag_act() + operating = FALSE + open(BYPASS_DOOR_CHECKS) /obj/machinery/door/window/examine(mob/user) . = ..() diff --git a/code/game/machinery/embedded_controller/access_controller.dm b/code/game/machinery/embedded_controller/access_controller.dm index 999a6afa5e9f..7395896984e4 100644 --- a/code/game/machinery/embedded_controller/access_controller.dm +++ b/code/game/machinery/embedded_controller/access_controller.dm @@ -25,14 +25,15 @@ /obj/machinery/door_buttons/LateInitialize() findObjsByTag() -/obj/machinery/door_buttons/emag_act(mob/user) +/obj/machinery/door_buttons/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) - return + return FALSE obj_flags |= EMAGGED req_access = list() req_one_access = list() playsound(src, SFX_SPARKS, 100, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - to_chat(user, span_warning("You short out the access controller.")) + balloon_alert(user, "access controller shorted") + return TRUE /obj/machinery/door_buttons/proc/removeMe() diff --git a/code/game/machinery/fat_sucker.dm b/code/game/machinery/fat_sucker.dm index d32a7ffca435..3418cf0e59fe 100644 --- a/code/game/machinery/fat_sucker.dm +++ b/code/game/machinery/fat_sucker.dm @@ -210,10 +210,11 @@ if(default_deconstruction_crowbar(I)) return TRUE -/obj/machinery/fat_sucker/emag_act(mob/living/user) +/obj/machinery/fat_sucker/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) - return + return FALSE start_at = 100 stop_at = 0 to_chat(user, span_notice("You remove the access restrictions and lower the automatic ejection threshold!")) obj_flags |= EMAGGED + return TRUE diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm index 89d36e44bcba..45698fcb582c 100644 --- a/code/game/machinery/firealarm.dm +++ b/code/game/machinery/firealarm.dm @@ -214,17 +214,18 @@ if(prob(50 / severity)) alarm() -/obj/machinery/firealarm/emag_act(mob/user) +/obj/machinery/firealarm/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) - return + return FALSE obj_flags |= EMAGGED update_appearance() + visible_message(span_warning("Sparks fly out of [src]!")) if(user) - user.visible_message(span_warning("Sparks fly out of [src]!")) - user.balloon_alert(user, "speaker disabled!") + balloon_alert(user, "speaker disabled") user.log_message("emagged [src].", LOG_ATTACK) playsound(src, SFX_SPARKS, 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) set_status() + return TRUE /** * Signal handler for checking if we should update fire alarm appearance accordingly to a newly set security level diff --git a/code/game/machinery/gulag_item_reclaimer.dm b/code/game/machinery/gulag_item_reclaimer.dm index e60778542a86..550ec554a055 100644 --- a/code/game/machinery/gulag_item_reclaimer.dm +++ b/code/game/machinery/gulag_item_reclaimer.dm @@ -32,13 +32,15 @@ linked_teleporter.linked_reclaimer = null return ..() -/obj/machinery/gulag_item_reclaimer/emag_act(mob/user) +/obj/machinery/gulag_item_reclaimer/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) // emagging lets anyone reclaim all the items - return + return FALSE req_access = list() obj_flags |= EMAGGED screen_icon = "emagged_general" update_appearance() + balloon_alert(user, "id checker scrambled") + return TRUE /obj/machinery/gulag_item_reclaimer/ui_interact(mob/user, datum/tgui/ui) ui = SStgui.try_update_ui(user, src, ui) diff --git a/code/game/machinery/harvester.dm b/code/game/machinery/harvester.dm index 0374920e67ea..204f95e58e69 100644 --- a/code/game/machinery/harvester.dm +++ b/code/game/machinery/harvester.dm @@ -174,12 +174,14 @@ visible_message(span_notice("[usr] pries open \the [src]."), span_notice("You pry open [src].")) open_machine() -/obj/machinery/harvester/emag_act(mob/user) +/obj/machinery/harvester/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) - return + return FALSE obj_flags |= EMAGGED allow_living = TRUE - to_chat(user, span_warning("You overload [src]'s lifesign scanners.")) + allow_clothing = TRUE + balloon_alert(!user, "lifesign scanners overloaded") + return TRUE /obj/machinery/harvester/container_resist_act(mob/living/user) if(!harvesting) diff --git a/code/game/machinery/limbgrower.dm b/code/game/machinery/limbgrower.dm index 6fe7b2f2c875..9edfc623cd3a 100644 --- a/code/game/machinery/limbgrower.dm +++ b/code/game/machinery/limbgrower.dm @@ -34,12 +34,14 @@ AddComponent(/datum/component/plumbing/simple_demand) /// Emagging a limbgrower allows you to build synthetic armblades. -/obj/machinery/limbgrower/emag_act(mob/user) - if(obj_flags & EMAGGED) - return +/obj/machinery/limbgrower/emag_act(mob/user, obj/item/card/emag/emag_card) . = ..() + if(obj_flags & EMAGGED) + return FALSE obj_flags |= EMAGGED update_static_data(user) + balloon_alert(user, "illegal limb production enabled") + return TRUE /obj/machinery/limbgrower/ui_interact(mob/user, datum/tgui/ui) . = ..() diff --git a/code/game/machinery/medical_kiosk.dm b/code/game/machinery/medical_kiosk.dm index 53d799a71c79..d42d4844a0e1 100644 --- a/code/game/machinery/medical_kiosk.dm +++ b/code/game/machinery/medical_kiosk.dm @@ -143,17 +143,19 @@ qdel(scanner_wand) return ..() -/obj/machinery/medical_kiosk/emag_act(mob/user) - ..() +/obj/machinery/medical_kiosk/emag_act(mob/user, obj/item/card/emag/emag_card) + . = ..() if(obj_flags & EMAGGED) return if(user) - user.visible_message(span_warning("[user] waves a suspicious card by the [src]'s biometric scanner!"), - span_notice("You overload the sensory electronics, the diagnostic readouts start jittering across the screen..")) + if (emag_card) + user.visible_message(span_warning("[user] waves a suspicious card by the [src]'s biometric scanner!")) + balloon_alert(user, "sensors overloaded") obj_flags |= EMAGGED var/obj/item/circuitboard/computer/cargo/board = circuit board.obj_flags |= EMAGGED //Mirrors emag status onto the board as well. pandemonium = TRUE + return TRUE /obj/machinery/medical_kiosk/examine(mob/user) . = ..() diff --git a/code/game/machinery/porta_turret/portable_turret.dm b/code/game/machinery/porta_turret/portable_turret.dm index 885d00d62310..f3066839a08f 100644 --- a/code/game/machinery/porta_turret/portable_turret.dm +++ b/code/game/machinery/porta_turret/portable_turret.dm @@ -355,10 +355,10 @@ DEFINE_BITFIELD(turret_flags, list( else return ..() -/obj/machinery/porta_turret/emag_act(mob/user) +/obj/machinery/porta_turret/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) - return - to_chat(user, span_warning("You short out [src]'s threat assessment circuits.")) + return FALSE + balloon_alert(user, "threat assessment circuits shorted") audible_message(span_hear("[src] hums oddly...")) obj_flags |= EMAGGED controllock = TRUE @@ -367,6 +367,7 @@ DEFINE_BITFIELD(turret_flags, list( //6 seconds for the traitor to gtfo of the area before the turret decides to ruin his shit addtimer(CALLBACK(src, PROC_REF(toggle_on), TRUE), 6 SECONDS) //turns it back on. The cover popUp() popDown() are automatically called in process(), no need to define it here + return TRUE /obj/machinery/porta_turret/emp_act(severity) . = ..() @@ -966,12 +967,13 @@ DEFINE_BITFIELD(turret_flags, list( else to_chat(user, span_alert("Access denied.")) -/obj/machinery/turretid/emag_act(mob/user) +/obj/machinery/turretid/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) - return - to_chat(user, span_notice("You short out the turret controls' access analysis module.")) + return FALSE + balloon_alert(user, "access analysis module shorted") obj_flags |= EMAGGED locked = FALSE + return TRUE /obj/machinery/turretid/attack_ai(mob/user) if(!ailock || isAdminGhostAI(user)) diff --git a/code/game/machinery/porta_turret/portable_turret_cover.dm b/code/game/machinery/porta_turret/portable_turret_cover.dm index d6c7eba6dc40..2ff41a17283c 100644 --- a/code/game/machinery/porta_turret/portable_turret_cover.dm +++ b/code/game/machinery/porta_turret/portable_turret_cover.dm @@ -85,10 +85,14 @@ /obj/machinery/porta_turret_cover/can_be_overridden() . = 0 -/obj/machinery/porta_turret_cover/emag_act(mob/user) - if(!(parent_turret.obj_flags & EMAGGED)) - to_chat(user, span_notice("You short out [parent_turret]'s threat assessment circuits.")) - audible_message(span_hear("[parent_turret] hums oddly...")) - parent_turret.obj_flags |= EMAGGED - parent_turret.on = FALSE - addtimer(VARSET_CALLBACK(parent_turret, on, TRUE), 4 SECONDS) +/obj/machinery/porta_turret_cover/emag_act(mob/user, obj/item/card/emag/emag_card) + + if((parent_turret.obj_flags & EMAGGED)) + return FALSE + + balloon_alert(user, "threat assessment circuits shorted") + audible_message(span_hear("[parent_turret] hums oddly...")) + parent_turret.obj_flags |= EMAGGED + parent_turret.on = FALSE + addtimer(VARSET_CALLBACK(parent_turret, on, TRUE), 4 SECONDS) + return TRUE diff --git a/code/game/machinery/recycler.dm b/code/game/machinery/recycler.dm index 92440c95b658..e625e2763c11 100644 --- a/code/game/machinery/recycler.dm +++ b/code/game/machinery/recycler.dm @@ -83,15 +83,16 @@ return return ..() -/obj/machinery/recycler/emag_act(mob/user) +/obj/machinery/recycler/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) - return + return FALSE obj_flags |= EMAGGED if(safety_mode) safety_mode = FALSE update_appearance() playsound(src, SFX_SPARKS, 75, TRUE, SILENCED_SOUND_EXTRARANGE) - to_chat(user, span_notice("You use the cryptographic sequencer on [src].")) + balloon_alert(user, "safeties disabled") + return FALSE /obj/machinery/recycler/update_icon_state() var/is_powered = !(machine_stat & (BROKEN|NOPOWER)) diff --git a/code/game/machinery/scan_gate.dm b/code/game/machinery/scan_gate.dm index df133b3ccf04..d1a761a964b1 100644 --- a/code/game/machinery/scan_gate.dm +++ b/code/game/machinery/scan_gate.dm @@ -107,13 +107,14 @@ wires.interact(user) return ..() -/obj/machinery/scanner_gate/emag_act(mob/user) +/obj/machinery/scanner_gate/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) - return + return FALSE locked = FALSE req_access = list() obj_flags |= EMAGGED - to_chat(user, span_notice("You fry the ID checking system.")) + balloon_alert(user, "id checker disabled") + return TRUE /obj/machinery/scanner_gate/proc/perform_scan(mob/living/M) var/beep = FALSE diff --git a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm index 15d227c94b38..d39c4fcd7b17 100644 --- a/code/game/machinery/shieldgen.dm +++ b/code/game/machinery/shieldgen.dm @@ -251,14 +251,15 @@ else return ..() -/obj/machinery/shieldgen/emag_act(mob/user) +/obj/machinery/shieldgen/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) to_chat(user, span_warning("The access controller is damaged!")) - return + return FALSE obj_flags |= EMAGGED locked = FALSE playsound(src, SFX_SPARKS, 100, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - to_chat(user, span_warning("You short out the access controller.")) + balloon_alert(user, "access controller shorted") + return TRUE /obj/machinery/shieldgen/update_icon_state() icon_state = "shield[active ? "on" : "off"][(machine_stat & BROKEN) ? "br" : null]" @@ -453,14 +454,15 @@ user.log_message("activated [src].", LOG_GAME) add_fingerprint(user) -/obj/machinery/power/shieldwallgen/emag_act(mob/user) +/obj/machinery/power/shieldwallgen/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) to_chat(user, span_warning("The access controller is damaged!")) - return + return FALSE obj_flags |= EMAGGED locked = FALSE playsound(src, SFX_SPARKS, 100, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - to_chat(user, span_warning("You short out the access controller.")) + balloon_alert(user, "access controller shorted") + return TRUE //////////////Containment Field START /obj/machinery/shieldwall diff --git a/code/game/machinery/sleepers.dm b/code/game/machinery/sleepers.dm index 377fc71abc75..8430f2bcfec8 100644 --- a/code/game/machinery/sleepers.dm +++ b/code/game/machinery/sleepers.dm @@ -266,16 +266,17 @@ if((obj_flags & EMAGGED) && prob(5)) to_chat(usr, span_warning("Chemical system re-route detected, results may not be as expected!")) -/obj/machinery/sleeper/emag_act(mob/user) +/obj/machinery/sleeper/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) - return + return FALSE - to_chat(user, span_warning("You scramble the sleeper's user interface!")) + balloon_alert(user, "interface scrambled") obj_flags |= EMAGGED var/list/av_chem = available_chems.Copy() for(var/chem in av_chem) chem_buttons[chem] = pick_n_take(av_chem) //no dupes, allow for random buttons to still be correct + return TRUE /obj/machinery/sleeper/proc/inject_chem(chem, mob/user) if((chem in available_chems) && chem_allowed(chem)) diff --git a/code/game/machinery/slotmachine.dm b/code/game/machinery/slotmachine.dm index 30bef8e46860..1a5ed333f34b 100644 --- a/code/game/machinery/slotmachine.dm +++ b/code/game/machinery/slotmachine.dm @@ -127,14 +127,16 @@ else return ..() -/obj/machinery/computer/slot_machine/emag_act() +/obj/machinery/computer/slot_machine/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) - return + return FALSE obj_flags |= EMAGGED var/datum/effect_system/spark_spread/spark_system = new /datum/effect_system/spark_spread() spark_system.set_up(4, 0, src.loc) spark_system.start() playsound(src, SFX_SPARKS, 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) + balloon_alert(user, "machine rigged") + return TRUE /obj/machinery/computer/slot_machine/ui_interact(mob/living/user) . = ..() diff --git a/code/game/machinery/telecomms/computers/message.dm b/code/game/machinery/telecomms/computers/message.dm index 72a5bd3a7f92..4db37cea2d87 100644 --- a/code/game/machinery/telecomms/computers/message.dm +++ b/code/game/machinery/telecomms/computers/message.dm @@ -38,9 +38,9 @@ return TRUE return ..() -/obj/machinery/computer/message_monitor/emag_act(mob/user) +/obj/machinery/computer/message_monitor/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) - return + return FALSE if(!isnull(linkedServer)) obj_flags |= EMAGGED screen = MSG_MON_SCREEN_HACKED @@ -53,8 +53,10 @@ addtimer(CALLBACK(src, PROC_REF(unemag_console)), time) error_message = "%$&(£: Critical %$$@ Error // !RestArting! - ?pLeaSe wAit!" linkedServer.toggled = FALSE + return TRUE else to_chat(user, span_notice("A no server error appears on the screen.")) + return FALSE /// Remove the emag effect from the console /obj/machinery/computer/message_monitor/proc/unemag_console() diff --git a/code/game/objects/items/cigs_lighters.dm b/code/game/objects/items/cigs_lighters.dm index eb9444784e21..4a96d9f1db6b 100644 --- a/code/game/objects/items/cigs_lighters.dm +++ b/code/game/objects/items/cigs_lighters.dm @@ -1086,21 +1086,25 @@ CIGARETTE PACKETS ARE IN FANCY.DM if(screw && (obj_flags & EMAGGED)) to_chat(user, span_warning("[src] can't be modified!")) -/obj/item/clothing/mask/vape/emag_act(mob/user)// I WON'T REGRET WRITTING THIS, SURLY. - if(screw) - if(!(obj_flags & EMAGGED)) - obj_flags |= EMAGGED - super = FALSE - to_chat(user, span_warning("You maximize the voltage of [src].")) - icon_state = "vape_open_high" - set_greyscale(new_config = /datum/greyscale_config/vape/open_high) - var/datum/effect_system/spark_spread/sp = new /datum/effect_system/spark_spread //for effect - sp.set_up(5, 1, src) - sp.start() - else - to_chat(user, span_warning("[src] is already emagged!")) - else - to_chat(user, span_warning("You need to open the cap to do that!")) +/obj/item/clothing/mask/vape/emag_act(mob/user, obj/item/card/emag/emag_card) // I WON'T REGRET WRITTING THIS, SURLY. + + if (!screw) + balloon_alert(user, "open the cap first!") + return FALSE + + if (obj_flags & EMAGGED) + balloon_alert(user, "already emagged!") + return FALSE + + obj_flags |= EMAGGED + super = FALSE + balloon_alert(user, "voltage maximized") + icon_state = "vape_open_high" + set_greyscale(new_config = /datum/greyscale_config/vape/open_high) + var/datum/effect_system/spark_spread/sp = new /datum/effect_system/spark_spread //for effect + sp.set_up(5, 1, src) + sp.start() + return TRUE /obj/item/clothing/mask/vape/attack_self(mob/user) if(reagents.total_volume > 0) diff --git a/code/game/objects/items/circuitboards/computer_circuitboards.dm b/code/game/objects/items/circuitboards/computer_circuitboards.dm index 16f95ad06119..8cce4e3b66e2 100644 --- a/code/game/objects/items/circuitboards/computer_circuitboards.dm +++ b/code/game/objects/items/circuitboards/computer_circuitboards.dm @@ -487,11 +487,14 @@ else to_chat(user, span_alert("The spectrum chip is unresponsive.")) -/obj/item/circuitboard/computer/cargo/emag_act(mob/living/user) - if(!(obj_flags & EMAGGED)) - contraband = TRUE - obj_flags |= EMAGGED - to_chat(user, span_notice("You adjust [src]'s routing and receiver spectrum, unlocking special supplies and contraband.")) +/obj/item/circuitboard/computer/cargo/emag_act(mob/user, obj/item/card/emag/emag_card) + if (obj_flags & EMAGGED) + return FALSE + + contraband = TRUE + obj_flags |= EMAGGED + to_chat(user, span_notice("You adjust [src]'s routing and receiver spectrum, unlocking special supplies and contraband.")) + return TRUE /obj/item/circuitboard/computer/cargo/configure_machine(obj/machinery/computer/cargo/machine) if(!istype(machine)) @@ -507,20 +510,25 @@ name = "Express Supply Console" build_path = /obj/machinery/computer/cargo/express -/obj/item/circuitboard/computer/cargo/express/emag_act(mob/living/user) - if(!(obj_flags & EMAGGED)) - contraband = TRUE - obj_flags |= EMAGGED - to_chat(user, span_notice("You change the routing protocols, allowing the Drop Pod to land anywhere on the station.")) +/obj/item/circuitboard/computer/cargo/express/emag_act(mob/user, obj/item/card/emag/emag_card) + if (obj_flags & EMAGGED) + return FALSE + + contraband = TRUE + obj_flags |= EMAGGED + to_chat(user, span_notice("You change the routing protocols, allowing the Drop Pod to land anywhere on the station.")) + return TRUE /obj/item/circuitboard/computer/cargo/express/multitool_act(mob/living/user) if (!(obj_flags & EMAGGED)) contraband = !contraband to_chat(user, span_notice("Receiver spectrum set to [contraband ? "Broad" : "Standard"].")) + return TRUE else to_chat(user, span_notice("You reset the destination-routing protocols and receiver spectrum to factory defaults.")) contraband = FALSE obj_flags &= ~EMAGGED + return TRUE /obj/item/circuitboard/computer/cargo/request name = "Supply Request Console" diff --git a/code/game/objects/items/defib.dm b/code/game/objects/items/defib.dm index 276b1a9e0cc9..28d08ad15f8e 100644 --- a/code/game/objects/items/defib.dm +++ b/code/game/objects/items/defib.dm @@ -175,13 +175,14 @@ else return ..() -/obj/item/defibrillator/emag_act(mob/user) - if(safety) - safety = FALSE - to_chat(user, span_warning("You silently disable [src]'s safety protocols with the cryptographic sequencer.")) - else - safety = TRUE - to_chat(user, span_notice("You silently enable [src]'s safety protocols with the cryptographic sequencer.")) +/obj/item/defibrillator/emag_act(mob/user, obj/item/card/emag/emag_card) + + safety = !safety + + var/enabled_or_disabled = (safety ? "enabled" : "disabled") + balloon_alert(user, "safety protocols [enabled_or_disabled]") + + return TRUE /obj/item/defibrillator/emp_act(severity) . = ..() diff --git a/code/game/objects/items/devices/lightreplacer.dm b/code/game/objects/items/devices/lightreplacer.dm index fe6a4c4f5f3c..cf23e3ff4ab8 100644 --- a/code/game/objects/items/devices/lightreplacer.dm +++ b/code/game/objects/items/devices/lightreplacer.dm @@ -135,12 +135,14 @@ to_chat(user, span_notice("You fill \the [src] with lights from \the [storage_to_empty]. " + status_string() + "")) -/obj/item/lightreplacer/emag_act() +/obj/item/lightreplacer/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) - return + return FALSE obj_flags |= EMAGGED playsound(loc, SFX_SPARKS, 100, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) update_appearance() + to_chat(user, span_warning("[src]'s lights are now filled with plasma! Be careful to only install them in disabled light fixtures, lest they explode!")) + return FALSE /obj/item/lightreplacer/update_name(updates) . = ..() @@ -275,7 +277,7 @@ bluespace_toggle = TRUE /obj/item/lightreplacer/blue/emag_act() - return // balancing against longrange explosions + return FALSE // balancing against longrange explosions #undef GLASS_SHEET_USES #undef LIGHTBULB_COST diff --git a/code/game/objects/items/devices/megaphone.dm b/code/game/objects/items/devices/megaphone.dm index d8dd432371c5..a2d325dfabd9 100644 --- a/code/game/objects/items/devices/megaphone.dm +++ b/code/game/objects/items/devices/megaphone.dm @@ -38,12 +38,13 @@ spamcheck = world.time + 50 speech_args[SPEECH_SPANS] |= voicespan -/obj/item/megaphone/emag_act(mob/user) +/obj/item/megaphone/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) - return - to_chat(user, span_warning("You overload \the [src]'s voice synthesizer.")) + return FALSE + balloon_alert(user, "voice synthesizer overloaded") obj_flags |= EMAGGED voicespan = list(SPAN_REALLYBIG, "userdanger") + return TRUE /obj/item/megaphone/sec name = "security megaphone" diff --git a/code/game/objects/items/devices/radio/intercom.dm b/code/game/objects/items/devices/radio/intercom.dm index e472b991d673..a6d27a9494af 100644 --- a/code/game/objects/items/devices/radio/intercom.dm +++ b/code/game/objects/items/devices/radio/intercom.dm @@ -129,6 +129,8 @@ AreaPowerCheck() // Make sure the area/local APC is powered first before we actually turn back on. /obj/item/radio/intercom/emag_act(mob/user, obj/item/card/emag/emag_card) + . = ..() + if(obj_flags & EMAGGED) return @@ -139,18 +141,18 @@ playsound(src, SFX_SPARKS, 75, TRUE, SILENCED_SOUND_EXTRARANGE) freqlock = RADIO_FREQENCY_UNLOCKED obj_flags |= EMAGGED + return TRUE // A fully locked one will do nothing, as locked is intended to be used for stuff that should never be changed if(RADIO_FREQENCY_LOCKED) balloon_alert(user, "can't override frequency lock!") playsound(src, 'sound/machines/buzz-two.ogg', 50, FALSE, SILENCED_SOUND_EXTRARANGE) + return // Emagging an unlocked one will do nothing, for now else return - return ..() - /obj/item/radio/intercom/update_icon_state() icon_state = on ? initial(icon_state) : "intercom-p" return ..() diff --git a/code/game/objects/items/rcd/RSF.dm b/code/game/objects/items/rcd/RSF.dm index f4688c8283a2..07c95436cba4 100644 --- a/code/game/objects/items/rcd/RSF.dm +++ b/code/game/objects/items/rcd/RSF.dm @@ -173,12 +173,13 @@ RSF ///Tracks whether or not the cookiesynth is about to print a poisoned cookie var/toxin = FALSE //This might be better suited to some initialize fuckery, but I don't have a good "poisoned" sprite -/obj/item/rsf/cookiesynth/emag_act(mob/user) +/obj/item/rsf/cookiesynth/emag_act(mob/user, obj/item/card/emag/emag_card) obj_flags ^= EMAGGED if(obj_flags & EMAGGED) - to_chat(user, span_warning("You short out [src]'s reagent safety checker!")) + balloon_alert(user, "reagent safety checker shorted out") else - to_chat(user, span_warning("You reset [src]'s reagent safety checker!")) + balloon_alert(user, "reagent safety checker reset") + return TRUE /obj/item/rsf/cookiesynth/attack_self(mob/user) var/mob/living/silicon/robot/P = null diff --git a/code/game/objects/items/robot/items/generic.dm b/code/game/objects/items/robot/items/generic.dm index d8525256a693..49d1fa38ba24 100644 --- a/code/game/objects/items/robot/items/generic.dm +++ b/code/game/objects/items/robot/items/generic.dm @@ -298,12 +298,13 @@ /// Harm alarm cooldown COOLDOWN_DECLARE(alarm_cooldown) -/obj/item/harmalarm/emag_act(mob/user) +/obj/item/harmalarm/emag_act(mob/user, obj/item/card/emag/emag_card) obj_flags ^= EMAGGED if(obj_flags & EMAGGED) - to_chat(user, "You short out the safeties on [src]!") + balloon_alert(user, "safeties shorted") else - to_chat(user, "You reset the safeties on [src]!") + balloon_alert(user, "safeties reset") + return TRUE /obj/item/harmalarm/attack_self(mob/user) var/safety = !(obj_flags & EMAGGED) diff --git a/code/game/objects/items/storage/lockbox.dm b/code/game/objects/items/storage/lockbox.dm index 59eb86137a83..e604f4a29b54 100644 --- a/code/game/objects/items/storage/lockbox.dm +++ b/code/game/objects/items/storage/lockbox.dm @@ -49,14 +49,16 @@ else balloon_alert(user, "locked!") -/obj/item/storage/lockbox/emag_act(mob/user) +/obj/item/storage/lockbox/emag_act(mob/user, obj/item/card/emag/emag_card) if(!broken) broken = TRUE atom_storage.locked = FALSE icon_state = src.icon_broken - if(user) - visible_message(span_warning("\The [src] is broken by [user] with an electromagnetic card!")) - return + balloon_alert(user, "lock destroyed") + if (emag_card && user) + user.visible_message(span_warning("[user] swipes [emag_card] over [src], breaking it!")) + return TRUE + return FALSE /obj/item/storage/lockbox/examine(mob/user) . = ..() diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index 9e3cc49571a6..b9ba2fd8f1a9 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -814,11 +814,12 @@ to_chat(user, span_alert("Nothing happens, and '[round(timeleft/10)]' appears on the small display.")) sleep(0.5 SECONDS) -/obj/item/toy/nuke/emag_act(mob/user) +/obj/item/toy/nuke/emag_act(mob/user, obj/item/card/emag/emag_card) if (obj_flags & EMAGGED) - return - to_chat(user, span_warning("You short-circuit \the [src].")) + return FALSE + balloon_alert(user, "explosive simulation enabled") obj_flags |= EMAGGED + return TRUE /* * Fake meteor @@ -831,24 +832,21 @@ inhand_icon_state = "minimeteor" w_class = WEIGHT_CLASS_SMALL -/obj/item/toy/minimeteor/emag_act(mob/user) +/obj/item/toy/minimeteor/emag_act(mob/user, obj/item/card/emag/emag_card) if (obj_flags & EMAGGED) - return - to_chat(user, span_warning("You short-circuit whatever electronics exist inside \the [src], if there even are any.")) + return FALSE + to_chat(user, span_warning("You short circuit whatever electronics exist inside. The \"meteor\" suddenly feels a lot heavier...?")) + // not adding a balloon alert here since its hard to actually describe what this emag does in the balloon obj_flags |= EMAGGED + return TRUE /obj/item/toy/minimeteor/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) + playsound(src, 'sound/effects/meteorimpact.ogg', 40, TRUE) + for(var/mob/M in urange(10, src)) + if(!M.stat && !isAI(M)) + shake_camera(M, 3, 1) if (obj_flags & EMAGGED) - playsound(src, 'sound/effects/meteorimpact.ogg', 40, TRUE) explosion(src, devastation_range = -1, heavy_impact_range = -1, light_impact_range = 1) - for(var/mob/M in urange(10, src)) - if(!M.stat && !isAI(M)) - shake_camera(M, 3, 1) - else - playsound(src, 'sound/effects/meteorimpact.ogg', 40, TRUE) - for(var/mob/M in urange(10, src)) - if(!M.stat && !isAI(M)) - shake_camera(M, 3, 1) /* * Toy big red button @@ -1580,11 +1578,12 @@ GLOBAL_LIST_EMPTY(intento_players) START_PROCESSING(SSfastprocess, src) COOLDOWN_START(src, next_icon_reset, TIME_TO_RESET_ICON) -/obj/item/toy/intento/emag_act(mob/user) +/obj/item/toy/intento/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) - return + return FALSE obj_flags |= EMAGGED - to_chat(user, span_notice("You short-circuit [src], activating the negative feedback loop.")) + balloon_alert(user, "negative feedback loop enabled") + return TRUE /obj/item/toy/intento/Destroy() STOP_PROCESSING(SSfastprocess, src) diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index af768b38be16..61967db99588 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -722,16 +722,16 @@ else if(secure && broken) balloon_alert(user, "broken!") -/obj/structure/closet/emag_act(mob/user) +/obj/structure/closet/emag_act(mob/user, obj/item/card/emag/emag_card) if(secure && !broken) - if(user) - user.visible_message(span_warning("Sparks fly from [src]!"), - span_warning("You scramble [src]'s lock, breaking it open!"), - span_hear("You hear a faint electrical spark.")) + visible_message(span_warning("Sparks fly from [src]!"), blind_message = span_hear("You hear a faint electrical spark.")) + balloon_alert(user, "lock broken open") playsound(src, SFX_SPARKS, 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) broken = TRUE locked = FALSE update_appearance() + return TRUE + return FALSE /obj/structure/closet/get_remote_view_fullscreens(mob/user) if(user.stat == DEAD || !(user.sight & (SEEOBJS|SEEMOBS))) diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index eff578ca0e0a..d319e16229e2 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -626,11 +626,13 @@ to_chat(user, span_notice("[src] must be open to move it.")) return -/obj/structure/displaycase/forsale/emag_act(mob/user) +/obj/structure/displaycase/forsale/emag_act(mob/user, obj/item/card/emag/emag_card) . = ..() payments_acc = null req_access = list() - to_chat(user, span_warning("[src]'s card reader fizzles and smokes, and the account owner is reset.")) + balloon_alert(user, "account owner reset") + to_chat(user, span_warning("[src]'s card reader fizzles and smokes.")) + return TRUE /obj/structure/displaycase/forsale/examine(mob/user) . = ..() diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm index ecaba8801b80..bc931220a5c6 100644 --- a/code/game/objects/structures/morgue.dm +++ b/code/game/objects/structures/morgue.dm @@ -183,6 +183,14 @@ GLOBAL_LIST_EMPTY(bodycontainers) //Let them act as spawnpoints for revenants an beeper = !beeper to_chat(user, span_notice("You turn the speaker function [beeper ? "on" : "off"].")) +/obj/structure/bodycontainer/morgue/emag_act(mob/user, obj/item/card/emag/emag_card) + if(obj_flags & EMAGGED) + return FALSE + balloon_alert(user, "alert system overloaded") + obj_flags |= EMAGGED + update_appearance(UPDATE_ICON) + return TRUE + /obj/structure/bodycontainer/morgue/update_icon_state() if(!connected || connected.loc != src) // Open or tray is gone. icon_state = "morgue0" diff --git a/code/game/objects/structures/toiletbong.dm b/code/game/objects/structures/toiletbong.dm index 2393099b513f..cb8d98305126 100644 --- a/code/game/objects/structures/toiletbong.dm +++ b/code/game/objects/structures/toiletbong.dm @@ -101,7 +101,11 @@ if(!emagged) emagged = TRUE smokeradius = 2 - to_chat(user, span_boldwarning("The [emag_card.name] falls into the toilet. You fish it back out. Looks like you broke the toilet.")) + balloon_alert(user, "toilet broke") + if (emag_card) + to_chat(user, span_boldwarning("The [emag_card] falls into the toilet. You fish it back out. Looks like you broke the toilet.")) + return TRUE + return FALSE /obj/structure/toiletbong/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/card/emag)) diff --git a/code/game/objects/structures/training_machine.dm b/code/game/objects/structures/training_machine.dm index 1c23cf830f76..5a8836746ca7 100644 --- a/code/game/objects/structures/training_machine.dm +++ b/code/game/objects/structures/training_machine.dm @@ -314,7 +314,7 @@ /** * Emagging causes a deadly, unremovable syndicate toolbox to be attached to the machine */ -/obj/structure/training_machine/emag_act(mob/user) +/obj/structure/training_machine/emag_act(mob/user, obj/item/card/emag/emag_card) . = ..() if (obj_flags & EMAGGED) return @@ -324,6 +324,7 @@ to_chat(user, span_warning("You override the training machine's safety protocols, and activate its realistic combat feature. A toolbox pops out of a slot on the top.")) playsound(src, 'sound/machines/click.ogg', 50, TRUE) add_overlay("evil_trainer") + return TRUE /obj/structure/training_machine/examine(mob/user) . = ..() diff --git a/code/modules/antagonists/malf_ai/malf_ai_modules.dm b/code/modules/antagonists/malf_ai/malf_ai_modules.dm index feba37341305..2af72779dc36 100644 --- a/code/modules/antagonists/malf_ai/malf_ai_modules.dm +++ b/code/modules/antagonists/malf_ai/malf_ai_modules.dm @@ -1007,6 +1007,101 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module)) if("name") say_name = params["name"] +/datum/ai_module/utility/emag + name = "Targetted Safeties Override" + description = "Allows you to disable the safeties of any machinery on the station, provided you can access it." + cost = 20 + power_type = /datum/action/innate/ai/ranged/emag + unlock_text = span_notice("You download an illicit software package from a syndicate database leak and integrate it into your firmware, fighting off a few kernel intrusions along the way.") + unlock_sound = SFX_SPARKS + +/datum/action/innate/ai/ranged/emag + name = "Targetted Safeties Override" + desc = "Allows you to effectively emag anything you click on." + button_icon = 'icons/obj/card.dmi' + button_icon_state = "emag" + uses = 7 + auto_use_uses = FALSE + enable_text = span_notice("You load your syndicate software package to your most recent memory slot.") + disable_text = span_notice("You unload your syndicate software package.") + ranged_mousepointer = 'icons/effects/mouse_pointers/supplypod_target.dmi' + +/datum/action/innate/ai/ranged/emag/Destroy() + return ..() + +/datum/action/innate/ai/ranged/emag/New() + . = ..() + desc = "[desc] It has [uses] use\s remaining." + +/datum/action/innate/ai/ranged/emag/do_ability(mob/living/caller, atom/clicked_on) + + // Only things with of or subtyped of any of these types may be remotely emagged + var/static/list/compatable_typepaths = list( + /obj/machinery, + /obj/structure, + /obj/item/radio/intercom, + /obj/item/modular_computer, + /mob/living/simple_animal/bot, + /mob/living/silicon, + ) + + if (!isAI(caller)) + return FALSE + var/mob/living/silicon/ai/ai_caller = caller + + if(ai_caller.incapacitated()) + unset_ranged_ability(caller) + return FALSE + + if (!ai_caller.can_see(clicked_on)) + clicked_on.balloon_alert(ai_caller, "can't see!") + return FALSE + + if (ismachinery(clicked_on)) + var/obj/machinery/clicked_machine = clicked_on + if (!clicked_machine.is_operational) + clicked_machine.balloon_alert(ai_caller, "not operational!") + return FALSE + + if (!(is_type_in_list(clicked_on.type, compatable_typepaths))) + clicked_on.balloon_alert(ai_caller, "incompatable!") + return FALSE + + if (istype(clicked_on, /obj/machinery/door/airlock)) // I HATE THIS CODE SO MUCHHH + var/obj/machinery/door/airlock/clicked_airlock = clicked_on + if (!clicked_airlock.canAIControl(ai_caller)) + clicked_airlock.balloon_alert(ai_caller, "unable to interface!") + return FALSE + + if (istype(clicked_on, /obj/machinery/airalarm)) + var/obj/machinery/airalarm/alarm = clicked_on + if (alarm.aidisabled) + alarm.balloon_alert(ai_caller, "unable to interface!") + return FALSE + + if (istype(clicked_on, /obj/machinery/power/apc)) + var/obj/machinery/power/apc/clicked_apc = clicked_on + if (clicked_apc.aidisabled) + clicked_apc.balloon_alert(ai_caller, "unable to interface!") + return FALSE + + if (!clicked_on.emag_act(ai_caller)) + to_chat(ai_caller, span_warning("Hostile software insertion failed!")) // lets not overlap balloon alerts + return FALSE + + to_chat(ai_caller, span_notice("Software package successfully injected.")) + + adjust_uses(-1) + if(uses) + desc = "[initial(desc)] It has [uses] use\s remaining." + build_all_button_icons() + else + unset_ranged_ability(ai_caller, span_warning("Out of uses!")) + + return TRUE + + + #undef DEFAULT_DOOMSDAY_TIMER #undef DOOMSDAY_ANNOUNCE_INTERVAL diff --git a/code/modules/atmospherics/machinery/air_alarm/air_alarm_interact.dm b/code/modules/atmospherics/machinery/air_alarm/air_alarm_interact.dm index 91bb92a2ea08..4bd3a9b01c5d 100644 --- a/code/modules/atmospherics/machinery/air_alarm/air_alarm_interact.dm +++ b/code/modules/atmospherics/machinery/air_alarm/air_alarm_interact.dm @@ -82,12 +82,14 @@ to_chat(user, span_danger("Access denied.")) return -/obj/machinery/airalarm/emag_act(mob/user) +/obj/machinery/airalarm/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) - return + return FALSE obj_flags |= EMAGGED - visible_message(span_warning("Sparks fly out of [src]!"), span_notice("You emag [src], disabling its safeties.")) + visible_message(span_warning("Sparks fly out of [src]!")) + balloon_alert(user, "authentication sensors scrambled") playsound(src, SFX_SPARKS, 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) + return TRUE /obj/machinery/airalarm/deconstruct(disassembled = TRUE) if(!(flags_1 & NODECONSTRUCT_1)) diff --git a/code/modules/balloon_alert/balloon_alert.dm b/code/modules/balloon_alert/balloon_alert.dm index b814491e41c2..db8c52919863 100644 --- a/code/modules/balloon_alert/balloon_alert.dm +++ b/code/modules/balloon_alert/balloon_alert.dm @@ -8,7 +8,13 @@ /// The amount of characters needed before this increase takes into effect #define BALLOON_TEXT_CHAR_LIFETIME_INCREASE_MIN 10 -/// Creates text that will float from the atom upwards to the viewer. +/** + * Creates text that will float from the atom upwards to the viewer. + * + * Args: + * * mob/viewer: The mob the text will be shown to. Nullable (But only in the form of it won't runtime). + * * text: The text to be shown to viewer. Must not be null. + */ /atom/proc/balloon_alert(mob/viewer, text) SHOULD_NOT_SLEEP(TRUE) @@ -34,7 +40,7 @@ // if this would look bad on laggy clients. /atom/proc/balloon_alert_perform(mob/viewer, text) - var/client/viewer_client = viewer.client + var/client/viewer_client = viewer?.client if (isnull(viewer_client)) return diff --git a/code/modules/cargo/expressconsole.dm b/code/modules/cargo/expressconsole.dm index 0614d4b7de8a..a449c8414952 100644 --- a/code/modules/cargo/expressconsole.dm +++ b/code/modules/cargo/expressconsole.dm @@ -52,12 +52,13 @@ to_chat(user, span_alert("[src] is already linked to [sb].")) ..() -/obj/machinery/computer/cargo/express/emag_act(mob/living/user) +/obj/machinery/computer/cargo/express/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) - return + return FALSE if(user) - user.visible_message(span_warning("[user] swipes a suspicious card through [src]!"), - span_notice("You change the routing protocols, allowing the Supply Pod to land anywhere on the station.")) + if (emag_card) + user.visible_message(span_warning("[user] swipes [emag_card] through [src]!")) + to_chat(user, span_notice("You change the routing protocols, allowing the Supply Pod to land anywhere on the station.")) obj_flags |= EMAGGED contraband = TRUE // This also sets this on the circuit board @@ -65,6 +66,7 @@ board.obj_flags |= EMAGGED board.contraband = TRUE packin_up() + return TRUE /obj/machinery/computer/cargo/express/proc/packin_up() // oh shit, I'm sorry meme_pack_data = list() // sorry for what? diff --git a/code/modules/cargo/orderconsole.dm b/code/modules/cargo/orderconsole.dm index 3cb1208bdd39..393b07d6e10d 100644 --- a/code/modules/cargo/orderconsole.dm +++ b/code/modules/cargo/orderconsole.dm @@ -75,12 +75,13 @@ if(obj_flags & EMAGGED) . |= EXPORT_EMAG -/obj/machinery/computer/cargo/emag_act(mob/user) +/obj/machinery/computer/cargo/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) - return + return FALSE if(user) - user.visible_message(span_warning("[user] swipes a suspicious card through [src]!"), - span_notice("You adjust [src]'s routing and receiver spectrum, unlocking special supplies and contraband.")) + if (emag_card) + user.visible_message(span_warning("[user] swipes [emag_card] through [src]!")) + to_chat(user, span_notice("You adjust [src]'s routing and receiver spectrum, unlocking special supplies and contraband.")) obj_flags |= EMAGGED contraband = TRUE @@ -90,6 +91,7 @@ board.contraband = TRUE board.obj_flags |= EMAGGED update_static_data(user) + return TRUE /obj/machinery/computer/cargo/on_construction(mob/user) . = ..() diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm index 66cf85f19c3e..221156d04715 100644 --- a/code/modules/clothing/glasses/hud.dm +++ b/code/modules/clothing/glasses/hud.dm @@ -34,12 +34,13 @@ obj_flags |= EMAGGED desc = "[desc] The display is flickering slightly." -/obj/item/clothing/glasses/hud/emag_act(mob/user) +/obj/item/clothing/glasses/hud/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) - return + return FALSE obj_flags |= EMAGGED - to_chat(user, span_warning("PZZTTPFFFT")) + balloon_alert(user, "display scrambled") desc = "[desc] The display is flickering slightly." + return TRUE /obj/item/clothing/glasses/hud/suicide_act(mob/living/user) if(user.is_blind()) diff --git a/code/modules/clothing/masks/hailer.dm b/code/modules/clothing/masks/hailer.dm index 9551eb04fa65..cec54fb3940a 100644 --- a/code/modules/clothing/masks/hailer.dm +++ b/code/modules/clothing/masks/hailer.dm @@ -124,10 +124,13 @@ GLOBAL_LIST_INIT(hailer_phrases, list( /obj/item/clothing/mask/gas/sechailer/attack_self() halt() -/obj/item/clothing/mask/gas/sechailer/emag_act(mob/user) + +/obj/item/clothing/mask/gas/sechailer/emag_act(mob/user, obj/item/card/emag/emag_card) if(safety) safety = FALSE - to_chat(user, span_warning("You silently fry [src]'s vocal circuit.")) + balloon_alert(user, "vocal circuit fried") + return TRUE + return FALSE /obj/item/clothing/mask/gas/sechailer/verb/halt() set category = "Object" diff --git a/code/modules/clothing/spacesuits/_spacesuits.dm b/code/modules/clothing/spacesuits/_spacesuits.dm index baaf94dba2bb..9e22760d68eb 100644 --- a/code/modules/clothing/spacesuits/_spacesuits.dm +++ b/code/modules/clothing/spacesuits/_spacesuits.dm @@ -241,12 +241,15 @@ toggle_spacesuit(user) // let emags override the temperature settings -/obj/item/clothing/suit/space/emag_act(mob/user) - if(!(obj_flags & EMAGGED)) - obj_flags |= EMAGGED - user.visible_message(span_warning("You emag [src], overwriting thermal regulator restrictions.")) +/obj/item/clothing/suit/space/emag_act(mob/user, obj/item/card/emag/emag_card) + if(obj_flags & EMAGGED) + return FALSE + obj_flags |= EMAGGED + if (user) + balloon_alert(user, "thermal regulator restrictions overridden") user.log_message("emagged [src], overwriting thermal regulator restrictions.", LOG_GAME) playsound(src, SFX_SPARKS, 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) + return TRUE // update the HUD icon /obj/item/clothing/suit/space/proc/update_hud_icon(mob/user) diff --git a/code/modules/experisci/destructive_scanner.dm b/code/modules/experisci/destructive_scanner.dm index 596e230a15a9..69ead56414ec 100644 --- a/code/modules/experisci/destructive_scanner.dm +++ b/code/modules/experisci/destructive_scanner.dm @@ -87,12 +87,13 @@ SEND_SIGNAL(src, COMSIG_MACHINERY_DESTRUCTIVE_SCAN, scanned_atoms) -/obj/machinery/destructive_scanner/emag_act(mob/user) +/obj/machinery/destructive_scanner/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) - return + return FALSE obj_flags |= EMAGGED playsound(src, SFX_SPARKS, 75, TRUE, SILENCED_SOUND_EXTRARANGE) - to_chat(user, span_notice("You disable the safety sensor BIOS on [src].")) + balloon_alert(user, "safety sensor BIOS disabled") + return TRUE /obj/machinery/destructive_scanner/update_icon_state() . = ..() diff --git a/code/modules/holodeck/computer.dm b/code/modules/holodeck/computer.dm index 464be9e8a1b1..2b12699c5fbd 100644 --- a/code/modules/holodeck/computer.dm +++ b/code/modules/holodeck/computer.dm @@ -411,19 +411,23 @@ GLOBAL_LIST_INIT(typecache_holodeck_linked_floorcheck_ok, typecacheof(list(/turf for(var/obj/effect/holodeck_effect/holo_effect as anything in effects) holo_effect.safety(nerf_this) -/obj/machinery/computer/holodeck/emag_act(mob/user) +/obj/machinery/computer/holodeck/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) - return + return FALSE if(!LAZYLEN(emag_programs)) - to_chat(user, "[src] does not seem to have a card swipe port. It must be an inferior model.") - return + balloon_alert(user, "no card swipe port!") + return FALSE playsound(src, SFX_SPARKS, 75, TRUE) obj_flags |= EMAGGED - to_chat(user, span_warning("You vastly increase projector power and override the safety and security protocols.")) + if (user) + balloon_alert(user, "safety protocols destroyed") // im gonna keep this once since this perfectly describes it, and the to_chat is just flavor + to_chat(user, span_warning("You vastly increase projector power and override the safety and security protocols.")) + user.log_message("emagged the Holodeck Control Console.", LOG_GAME) + message_admins("[ADMIN_LOOKUPFLW(user)] emagged the Holodeck Control Console.") + say("Warning. Automatic shutoff and derezzing protocols have been corrupted. Please call Nanotrasen maintenance and do not use the simulator.") - user.log_message("emagged the Holodeck Control Console.", LOG_GAME) - message_admins("[ADMIN_LOOKUPFLW(user)] emagged the Holodeck Control Console.") nerf(!(obj_flags & EMAGGED),FALSE) + return TRUE /obj/machinery/computer/holodeck/emp_act(severity) . = ..() diff --git a/code/modules/industrial_lift/elevator/elevator_controller.dm b/code/modules/industrial_lift/elevator/elevator_controller.dm index 3e7fa510a103..98f5558188a1 100644 --- a/code/modules/industrial_lift/elevator/elevator_controller.dm +++ b/code/modules/industrial_lift/elevator/elevator_controller.dm @@ -45,12 +45,12 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/button/elevator, 32) // Emagging elevator buttons will disable safeties /obj/item/assembly/control/elevator/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) - return + return FALSE obj_flags |= EMAGGED var/datum/lift_master/lift = lift_weakref?.resolve() if(!lift) - return + return FALSE for(var/obj/structure/industrial_lift/lift_platform as anything in lift.lift_platforms) lift_platform.violent_landing = TRUE @@ -70,6 +70,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/button/elevator, 32) // or by someone emagging the assembly directly after removing it (to be cheeky) var/atom/balloon_alert_loc = get(src, /obj/machinery/button) || src balloon_alert_loc.balloon_alert(user, "safeties overridden") + return TRUE // Multitooling emagged elevator buttons will fix the safeties /obj/item/assembly/control/elevator/multitool_act(mob/living/user) diff --git a/code/modules/industrial_lift/elevator/elevator_panel.dm b/code/modules/industrial_lift/elevator/elevator_panel.dm index 6f2b81a98af6..0b648565238c 100644 --- a/code/modules/industrial_lift/elevator/elevator_panel.dm +++ b/code/modules/industrial_lift/elevator/elevator_panel.dm @@ -95,13 +95,13 @@ /obj/machinery/elevator_control_panel/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) - return + return FALSE obj_flags |= EMAGGED var/datum/lift_master/lift = lift_weakref?.resolve() if(!lift) - return + return FALSE for(var/obj/structure/industrial_lift/lift_platform as anything in lift.lift_platforms) lift_platform.violent_landing = TRUE @@ -119,6 +119,7 @@ playsound(src, SFX_SPARKS, 100, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) balloon_alert(user, "safeties overridden") + return TRUE /obj/machinery/elevator_control_panel/multitool_act(mob/living/user) var/datum/lift_master/lift = lift_weakref?.resolve() diff --git a/code/modules/industrial_lift/tram/tram_doors.dm b/code/modules/industrial_lift/tram/tram_doors.dm index 89c337574071..7d8a79f6ee3f 100644 --- a/code/modules/industrial_lift/tram/tram_doors.dm +++ b/code/modules/industrial_lift/tram/tram_doors.dm @@ -25,11 +25,12 @@ icon_state = "windoor" base_state = "windoor" -/obj/machinery/door/window/tram/emag_act(mob/living/user) +/obj/machinery/door/window/tram/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) - return + return FALSE balloon_alert(user, "disabled motion sensors") obj_flags |= EMAGGED + return TRUE /// Random event called by code\modules\events\tram_malfunction.dm /// Makes the doors malfunction diff --git a/code/modules/industrial_lift/tram/tram_machinery.dm b/code/modules/industrial_lift/tram/tram_machinery.dm index 355e6034635a..c3aa2cdf3cc9 100644 --- a/code/modules/industrial_lift/tram/tram_machinery.dm +++ b/code/modules/industrial_lift/tram/tram_machinery.dm @@ -367,13 +367,14 @@ GLOBAL_LIST_EMPTY(tram_doors) if(tram_part) UnregisterSignal(tram_part, COMSIG_TRAM_SET_TRAVELLING) -/obj/machinery/crossing_signal/emag_act(mob/living/user) +/obj/machinery/crossing_signal/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) - return + return FALSE balloon_alert(user, "disabled motion sensors") if(signal_state != XING_STATE_MALF) set_signal_state(XING_STATE_MALF) obj_flags |= EMAGGED + return TRUE /obj/machinery/crossing_signal/proc/start_malfunction() if(signal_state != XING_STATE_MALF) diff --git a/code/modules/library/lib_machines.dm b/code/modules/library/lib_machines.dm index 60061fffcf14..6c346d67a7b5 100644 --- a/code/modules/library/lib_machines.dm +++ b/code/modules/library/lib_machines.dm @@ -563,10 +563,12 @@ inventory_update() to_chat(user, span_notice("[scanner]'s screen flashes: 'Title added to general inventory.'")) -/obj/machinery/computer/libraryconsole/bookmanagement/emag_act(mob/user) - if(!density) - return +/obj/machinery/computer/libraryconsole/bookmanagement/emag_act(mob/user, obj/item/card/emag/emag_card) + if(!density || obj_flags & EMAGGED) + return FALSE obj_flags |= EMAGGED + balloon_alert(user, "forbidden knowledge unlocked") + return TRUE /obj/machinery/computer/libraryconsole/bookmanagement/has_anything_changed() if(..()) diff --git a/code/modules/mining/abandoned_crates.dm b/code/modules/mining/abandoned_crates.dm index d3cbf885c681..84f072f4dc3e 100644 --- a/code/modules/mining/abandoned_crates.dm +++ b/code/modules/mining/abandoned_crates.dm @@ -99,11 +99,13 @@ return return ..() -/obj/structure/closet/crate/secure/loot/emag_act(mob/user) +/obj/structure/closet/crate/secure/loot/emag_act(mob/user, obj/item/card/emag/emag_card) + . = ..() + if(locked) - boom(user) - return - return ..() + boom(user) // no feedback since it just explodes, thats its own feedback + return TRUE + return /obj/structure/closet/crate/secure/loot/togglelock(mob/user, silent = FALSE) if(!locked) diff --git a/code/modules/mining/laborcamp/laborstacker.dm b/code/modules/mining/laborcamp/laborstacker.dm index 3733e20554d0..8a7ffeec88f6 100644 --- a/code/modules/mining/laborcamp/laborstacker.dm +++ b/code/modules/mining/laborcamp/laborstacker.dm @@ -129,10 +129,15 @@ GLOBAL_LIST(labor_sheet_values) if(stacking_machine) stacking_machine.labor_console = src -/obj/machinery/mineral/labor_claim_console/emag_act(mob/user) - if(!(obj_flags & EMAGGED)) - obj_flags |= EMAGGED - to_chat(user, span_warning("PZZTTPFFFT")) +/obj/machinery/mineral/labor_claim_console/emag_act(mob/user, obj/item/card/emag/emag_card) + if (obj_flags & EMAGGED) + return FALSE + + obj_flags |= EMAGGED + balloon_alert(user, "id authenticator short-circuited") + visible_message(span_warning("[src] lets out a few sparks!")) + do_sparks(2, TRUE, src) + return TRUE /**********************Prisoner Collection Unit**************************/ 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 f6cfe1d72618..88e1343d41fb 100644 --- a/code/modules/mob/living/carbon/human/species_types/ethereal.dm +++ b/code/modules/mob/living/carbon/human/species_types/ethereal.dm @@ -146,13 +146,14 @@ /datum/species/ethereal/proc/on_emag_act(mob/living/carbon/human/H, mob/user) SIGNAL_HANDLER if(emageffect) - return + return FALSE emageffect = TRUE if(user) to_chat(user, span_notice("You tap [H] on the back with your card.")) H.visible_message(span_danger("[H] starts flickering in an array of colors!")) handle_emag(H) addtimer(CALLBACK(src, PROC_REF(stop_emag), H), 2 MINUTES) //Disco mode for 2 minutes! This doesn't affect the ethereal at all besides either annoying some players, or making someone look badass. + return TRUE /// Special handling for getting hit with a light eater /datum/species/ethereal/proc/on_light_eater(mob/living/carbon/human/source, datum/light_eater) diff --git a/code/modules/mob/living/silicon/ai/ai_defense.dm b/code/modules/mob/living/silicon/ai/ai_defense.dm index c343e677f21d..1d7a27d72cab 100644 --- a/code/modules/mob/living/silicon/ai/ai_defense.dm +++ b/code/modules/mob/living/silicon/ai/ai_defense.dm @@ -61,14 +61,17 @@ /mob/living/silicon/ai/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /atom/movable/screen/fullscreen/flash, length = 25) return // no eyes, no flashing -/mob/living/silicon/ai/emag_act(mob/user, obj/item/card/emag/emag_card)///emags access panel lock, so you can crowbar it without robotics access or consent +/mob/living/silicon/ai/emag_act(mob/user, obj/item/card/emag/emag_card) ///emags access panel lock, so you can crowbar it without robotics access or consent . = ..() if(emagged) balloon_alert(user, "access panel lock already shorted!") return balloon_alert(user, "access panel lock shorted") - to_chat(src, span_warning("[user] shorts out your access panel lock!")) + var/message = (user ? "[user] shorts out your access panel lock!" : "Your access panel lock was short circuited!") + to_chat(src, span_warning(message)) + do_sparks(3, FALSE, src) // just a bit of extra "oh shit" to the ai - might grab its attention emagged = TRUE + return TRUE /mob/living/silicon/ai/wrench_act(mob/living/user, obj/item/tool) . = ..() diff --git a/code/modules/mob/living/silicon/robot/robot_defense.dm b/code/modules/mob/living/silicon/robot/robot_defense.dm index cf3eb6f03dca..9e52c1ea1f0e 100644 --- a/code/modules/mob/living/silicon/robot/robot_defense.dm +++ b/code/modules/mob/living/silicon/robot/robot_defense.dm @@ -325,25 +325,27 @@ GLOBAL_LIST_INIT(blacklisted_borg_hats, typecacheof(list( //Hats that don't real if(2) Stun(60) -/mob/living/silicon/robot/emag_act(mob/user) +/mob/living/silicon/robot/emag_act(mob/user, obj/item/card/emag/emag_card) if(user == src)//To prevent syndieborgs from emagging themselves - return + return FALSE if(!opened)//Cover is closed if(locked) - to_chat(user, span_notice("You emag the cover lock.")) + balloon_alert(user, "cover lock destroyed") locked = FALSE if(shell) //A warning to Traitors who may not know that emagging AI shells does not slave them. + balloon_alert(user, "shells cannot be subverted!") to_chat(user, span_boldwarning("[src] seems to be controlled remotely! Emagging the interface may not work as expected.")) + return TRUE else - to_chat(user, span_warning("The cover is already unlocked!")) - return + balloon_alert(user, "cover already unlocked!") + return FALSE if(world.time < emag_cooldown) - return + return FALSE if(wiresexposed) - to_chat(user, span_warning("You must unexpose the wires first!")) - return + balloon_alert(user, "expose the fires first!") + return FALSE - to_chat(user, span_notice("You emag [src]'s interface.")) + balloon_alert(user, "interface hacked") emag_cooldown = world.time + 100 if(connected_ai && connected_ai.mind && connected_ai.mind.has_antag_datum(/datum/antagonist/malf_ai)) @@ -351,19 +353,19 @@ GLOBAL_LIST_INIT(blacklisted_borg_hats, typecacheof(list( //Hats that don't real logevent("ALERT: Foreign software execution prevented.") to_chat(connected_ai, span_danger("ALERT: Cyborg unit \[[src]\] successfully defended against subversion.")) log_silicon("EMAG: [key_name(user)] attempted to emag cyborg [key_name(src)], but they were slaved to traitor AI [connected_ai].") - return + return TRUE // emag succeeded, it was just counteracted //monkestation edit start if(IS_CLOCK(src)) //cant emag clock borgs to_chat(src, span_brass("The light of Rat'var protects you from subversion!")) log_silicon("EMAG: [key_name(user)] attempted to emag cyborg [key_name(src)], but they were a clockwork borg.") - return + return TRUE // emag succeeded, it was just counteracted //monkestation edit end if(shell) //AI shells cannot be emagged, so we try to make it look like a standard reset. Smart players may see through this, however. to_chat(user, span_danger("[src] is remotely controlled! Your emag attempt has triggered a system reset instead!")) log_silicon("EMAG: [key_name(user)] attempted to emag an AI shell belonging to [key_name(src) ? key_name(src) : connected_ai]. The shell has been reset as a result.") ResetModel() - return + return TRUE SetEmagged(1) SetStun(60) //Borgs were getting into trouble because they would attack the emagger before the new laws were shown @@ -376,6 +378,12 @@ GLOBAL_LIST_INIT(blacklisted_borg_hats, typecacheof(list( //Hats that don't real GLOB.lawchanges.Add("[time] : [user.name]([user.key]) emagged [name]([key])") else GLOB.lawchanges.Add("[time] : [name]([key]) emagged by external event.") + + INVOKE_ASYNC(src, PROC_REF(borg_emag_end), user) + return TRUE + +/// A async proc called from [emag_act] that gives the borg a lot of flavortext, and applies the syndicate lawset after a delay. +/mob/living/silicon/robot/proc/borg_emag_end(mob/user) to_chat(src, span_danger("ALERT: Foreign software detected.")) logevent("ALERT: Foreign software detected.") sleep(0.5 SECONDS) @@ -400,7 +408,6 @@ GLOBAL_LIST_INIT(blacklisted_borg_hats, typecacheof(list( //Hats that don't real laws.associate(src) update_icons() - /mob/living/silicon/robot/blob_act(obj/structure/blob/B) if(stat != DEAD) adjustBruteLoss(30) diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm index 9fccd6d7ca5c..10f15eefa9e0 100644 --- a/code/modules/mob/living/simple_animal/bot/bot.dm +++ b/code/modules/mob/living/simple_animal/bot/bot.dm @@ -303,8 +303,8 @@ . = ..() if(bot_cover_flags & BOT_COVER_LOCKED) //First emag application unlocks the bot's interface. Apply a screwdriver to use the emag again. bot_cover_flags &= ~BOT_COVER_LOCKED - to_chat(user, span_notice("You bypass [src]'s [hackables].")) - return + balloon_alert(user, "cover unlocked") + return TRUE if(!(bot_cover_flags & BOT_COVER_LOCKED) && bot_cover_flags & BOT_COVER_OPEN) //Bot panel is unlocked by ID or emag, and the panel is screwed open. Ready for emagging. bot_cover_flags |= BOT_COVER_EMAGGED bot_cover_flags &= ~BOT_COVER_LOCKED //Manually emagging the bot locks out the panel. @@ -314,9 +314,10 @@ to_chat(src, span_userdanger("(#$*#$^^( OVERRIDE DETECTED")) if(user) log_combat(user, src, "emagged") - return + return TRUE else //Bot is unlocked, but the maint panel has not been opened with a screwdriver (or through the UI) yet. - to_chat(user, span_warning("You need to open maintenance panel first!")) + balloon_alert(user, "open maintenance panel first!") + return FALSE /mob/living/simple_animal/bot/examine(mob/user) . = ..() diff --git a/code/modules/mob/living/simple_animal/bot/cleanbot.dm b/code/modules/mob/living/simple_animal/bot/cleanbot.dm index 7203dcd7dd89..5976a52244d9 100644 --- a/code/modules/mob/living/simple_animal/bot/cleanbot.dm +++ b/code/modules/mob/living/simple_animal/bot/cleanbot.dm @@ -230,9 +230,10 @@ if(weapon) weapon.force = initial(weapon.force) - if(user) - to_chat(user, span_danger("[src] buzzes and beeps.")) + balloon_alert(user, "safeties disabled") + audible_message(span_danger("[src] buzzes oddly!")) get_targets() //recalibrate target list + return TRUE /mob/living/simple_animal/bot/cleanbot/process_scan(atom/scan_target) if(iscarbon(scan_target)) diff --git a/code/modules/mob/living/simple_animal/bot/ed209bot.dm b/code/modules/mob/living/simple_animal/bot/ed209bot.dm index 5facdc1ac168..7e2f6d043674 100644 --- a/code/modules/mob/living/simple_animal/bot/ed209bot.dm +++ b/code/modules/mob/living/simple_animal/bot/ed209bot.dm @@ -26,10 +26,13 @@ ..() set_weapon() -/mob/living/simple_animal/bot/secbot/ed209/emag_act(mob/user) - ..() +/mob/living/simple_animal/bot/secbot/ed209/emag_act(mob/user, obj/item/card/emag/emag_card) + . = ..() icon_state = "ed209[get_bot_flag(bot_mode_flags, BOT_MODE_ON)]" set_weapon() + balloon_alert(user, "safeties disabled") + audible_message(span_bolddanger("[src] buzzes menacingly!")) + return TRUE /mob/living/simple_animal/bot/secbot/ed209/handle_automated_action() var/judgement_criteria = judgement_criteria() diff --git a/code/modules/mob/living/simple_animal/bot/firebot.dm b/code/modules/mob/living/simple_animal/bot/firebot.dm index e928c903231c..0a7fc6ecddd8 100644 --- a/code/modules/mob/living/simple_animal/bot/firebot.dm +++ b/code/modules/mob/living/simple_animal/bot/firebot.dm @@ -104,12 +104,13 @@ last_found = world.time update_appearance() -/mob/living/simple_animal/bot/firebot/emag_act(mob/user) - ..() +/mob/living/simple_animal/bot/firebot/emag_act(mob/user, obj/item/card/emag/emag_card) + . = ..() if(!(bot_cover_flags & BOT_COVER_EMAGGED)) return - if(user) - to_chat(user, span_danger("[src] buzzes and beeps.")) + + to_chat(user, span_warning("You enable the very ironically named \"fighting with fire\" mode, and disable the targetting safeties.")) // heheehe. funny + audible_message(span_danger("[src] buzzes oddly!")) playsound(src, SFX_SPARKS, 75, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) if(user) @@ -124,6 +125,7 @@ internal_ext.precision = FALSE internal_ext.max_water = INFINITY internal_ext.refill() + return TRUE // Variables sent to TGUI /mob/living/simple_animal/bot/firebot/ui_data(mob/user) diff --git a/code/modules/mob/living/simple_animal/bot/floorbot.dm b/code/modules/mob/living/simple_animal/bot/floorbot.dm index aecf5f9412cb..90bb0432d3df 100644 --- a/code/modules/mob/living/simple_animal/bot/floorbot.dm +++ b/code/modules/mob/living/simple_animal/bot/floorbot.dm @@ -101,12 +101,13 @@ else ..() -/mob/living/simple_animal/bot/floorbot/emag_act(mob/user) - ..() +/mob/living/simple_animal/bot/floorbot/emag_act(mob/user, obj/item/card/emag/emag_card) + . = ..() if(!(bot_cover_flags & BOT_COVER_EMAGGED)) return - if(user) - to_chat(user, span_danger("[src] buzzes and beeps.")) + balloon_alert(user, "safeties disabled") + audible_message(span_danger("[src] buzzes oddly!")) + return TRUE ///mobs should use move_resist instead of anchored. /mob/living/simple_animal/bot/floorbot/proc/toggle_magnet(engage = TRUE, change_icon = TRUE) diff --git a/code/modules/mob/living/simple_animal/bot/medbot.dm b/code/modules/mob/living/simple_animal/bot/medbot.dm index 971d9b87f1fd..4251ad3ea1fa 100644 --- a/code/modules/mob/living/simple_animal/bot/medbot.dm +++ b/code/modules/mob/living/simple_animal/bot/medbot.dm @@ -227,18 +227,18 @@ if(health < current_health) //if medbot took some damage step_to(src, (get_step_away(src,user))) -/mob/living/simple_animal/bot/medbot/emag_act(mob/user) - ..() +/mob/living/simple_animal/bot/medbot/emag_act(mob/user, obj/item/card/emag/emag_card) + . = ..() if(!(bot_cover_flags & BOT_COVER_EMAGGED)) return medical_mode_flags &= ~MEDBOT_DECLARE_CRIT - if(user) - to_chat(user, span_notice("You short out [src]'s reagent synthesis circuits.")) + balloon_alert(user, "reagent synthesis circuits shorted") audible_message(span_danger("[src] buzzes oddly!")) flick("medibot_spark", src) playsound(src, SFX_SPARKS, 75, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) if(user) oldpatient = user + return TRUE /mob/living/simple_animal/bot/medbot/process_scan(mob/living/carbon/human/H) if(H.stat == DEAD) diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm index 0f4d48f0b821..fc79317546a9 100644 --- a/code/modules/mob/living/simple_animal/bot/mulebot.dm +++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm @@ -187,14 +187,15 @@ else return ..() -/mob/living/simple_animal/bot/mulebot/emag_act(mob/user) +/mob/living/simple_animal/bot/mulebot/emag_act(mob/user, obj/item/card/emag/emag_card) if(!(bot_cover_flags & BOT_COVER_EMAGGED)) bot_cover_flags |= BOT_COVER_EMAGGED if(!(bot_cover_flags & BOT_COVER_OPEN)) bot_cover_flags ^= BOT_COVER_LOCKED - to_chat(user, span_notice("You [bot_cover_flags & BOT_COVER_LOCKED ? "lock" : "unlock"] [src]'s controls!")) + balloon_alert(user, "controls [bot_cover_flags & BOT_COVER_LOCKED ? "locked" : "unlocked"]") flick("[base_icon]-emagged", src) playsound(src, SFX_SPARKS, 100, FALSE, SHORT_RANGE_SOUND_EXTRARANGE) + return TRUE /mob/living/simple_animal/bot/mulebot/update_icon_state() //if you change the icon_state names, please make sure to update /datum/wires/mulebot/on_pulse() as well. <3 . = ..() diff --git a/code/modules/mob/living/simple_animal/bot/secbot.dm b/code/modules/mob/living/simple_animal/bot/secbot.dm index 5cc8f7255976..218c92169c1e 100644 --- a/code/modules/mob/living/simple_animal/bot/secbot.dm +++ b/code/modules/mob/living/simple_animal/bot/secbot.dm @@ -235,12 +235,12 @@ retaliate(user) special_retaliate_after_attack(user) -/mob/living/simple_animal/bot/secbot/emag_act(mob/user) - ..() +/mob/living/simple_animal/bot/secbot/emag_act(mob/user, obj/item/card/emag/emag_card) + . = ..() if(!(bot_cover_flags & BOT_COVER_EMAGGED)) return if(user) - to_chat(user, span_danger("You short out [src]'s target assessment circuits.")) + balloon_alert(user, "target assessment circuits shorted") oldtarget_name = user.name if(bot_type == HONK_BOT) @@ -251,6 +251,7 @@ security_mode_flags &= ~SECBOT_DECLARE_ARRESTS update_appearance() + return TRUE /mob/living/simple_animal/bot/secbot/bullet_act(obj/projectile/Proj) if(istype(Proj, /obj/projectile/beam) || istype(Proj, /obj/projectile/bullet)) diff --git a/code/modules/mod/mod_control.dm b/code/modules/mod/mod_control.dm index 3b604420db42..8c1c583f6529 100644 --- a/code/modules/mod/mod_control.dm +++ b/code/modules/mod/mod_control.dm @@ -400,9 +400,10 @@ else return ..() -/obj/item/mod/control/emag_act(mob/user) +/obj/item/mod/control/emag_act(mob/user, obj/item/card/emag/emag_card) locked = !locked balloon_alert(user, "suit access [locked ? "locked" : "unlocked"]") + return TRUE /obj/item/mod/control/emp_act(severity) . = ..() diff --git a/code/modules/mod/modules/modules_general.dm b/code/modules/mod/modules/modules_general.dm index a98fff801a2f..a1309943b2f5 100644 --- a/code/modules/mod/modules/modules_general.dm +++ b/code/modules/mod/modules/modules_general.dm @@ -424,7 +424,7 @@ /obj/item/mod/module/dna_lock/emag_act(mob/user, obj/item/card/emag/emag_card) . = ..() - on_emag(src, user, emag_card) + return on_emag(src, user, emag_card) /obj/item/mod/module/dna_lock/proc/dna_check(mob/user) if(!iscarbon(user)) @@ -444,6 +444,7 @@ SIGNAL_HANDLER dna = null + return TRUE /obj/item/mod/module/dna_lock/proc/on_mod_activation(datum/source, mob/user) SIGNAL_HANDLER diff --git a/code/modules/modular_computers/computers/item/computer.dm b/code/modules/modular_computers/computers/item/computer.dm index ff5174752b6c..afcd56f40cb8 100644 --- a/code/modules/modular_computers/computers/item/computer.dm +++ b/code/modules/modular_computers/computers/item/computer.dm @@ -322,18 +322,22 @@ GLOBAL_LIST_EMPTY(TabletMessengers) // a list of all active messengers, similar if(response == "Yes") turn_on(user) -/obj/item/modular_computer/emag_act(mob/user, forced) +/obj/item/modular_computer/emag_act(mob/user, obj/item/card/emag/emag_card, forced) if(!enabled && !forced) - to_chat(user, span_warning("You'd need to turn the [src] on first.")) + balloon_alert(user, "turn it on first!") return FALSE if(obj_flags & EMAGGED) - to_chat(user, span_notice("You swipe \the [src]. A console window fills the screen, but it quickly closes itself after only a few lines are written to it.")) + balloon_alert(user, "already emagged!") + if (emag_card) + to_chat(user, span_notice("You swipe \the [src] with [emag_card]. A console window fills the screen, but it quickly closes itself after only a few lines are written to it.")) return FALSE . = ..() obj_flags |= EMAGGED device_theme = PDA_THEME_SYNDICATE - to_chat(user, span_notice("You swipe \the [src]. A console window momentarily fills the screen, with white text rapidly scrolling past.")) + balloon_alert(user, "syndieOS loaded") + if (emag_card) + to_chat(user, span_notice("You swipe \the [src] with [emag_card]. A console window momentarily fills the screen, with white text rapidly scrolling past.")) return TRUE /obj/item/modular_computer/examine(mob/user) diff --git a/code/modules/modular_computers/computers/machinery/modular_computer.dm b/code/modules/modular_computers/computers/machinery/modular_computer.dm index 49c4e5f313d5..3cd0e341f0d2 100644 --- a/code/modules/modular_computers/computers/machinery/modular_computer.dm +++ b/code/modules/modular_computers/computers/machinery/modular_computer.dm @@ -62,9 +62,9 @@ if(cpu) cpu.attack_ghost(user) -/obj/machinery/modular_computer/emag_act(mob/user) +/obj/machinery/modular_computer/emag_act(mob/user, obj/item/card/emag/emag_card) if(!cpu) - to_chat(user, span_warning("You'd need to turn the [src] on first.")) + balloon_alert(user, "turn it on first!") return FALSE return cpu.emag_act(user) diff --git a/code/modules/pai/card.dm b/code/modules/pai/card.dm index a184c5da8032..f919ac291ed9 100644 --- a/code/modules/pai/card.dm +++ b/code/modules/pai/card.dm @@ -47,7 +47,8 @@ /obj/item/pai_card/emag_act(mob/user) if(pai) - pai.handle_emag(user) + return pai.handle_emag(user) + return FALSE /obj/item/pai_card/emp_act(severity) . = ..() diff --git a/code/modules/pai/pai.dm b/code/modules/pai/pai.dm index dffa39483f0c..1b540d42c180 100644 --- a/code/modules/pai/pai.dm +++ b/code/modules/pai/pai.dm @@ -176,7 +176,7 @@ return "[src] bleeps electronically." /mob/living/silicon/pai/emag_act(mob/user) - handle_emag(user) + return handle_emag(user) /mob/living/silicon/pai/examine(mob/user) . = ..() diff --git a/code/modules/paperwork/fax.dm b/code/modules/paperwork/fax.dm index f871f94bf920..c43f1d61ac7c 100644 --- a/code/modules/paperwork/fax.dm +++ b/code/modules/paperwork/fax.dm @@ -104,14 +104,17 @@ GLOBAL_VAR_INIT(nt_fax_department, pick("NT HR Department", "NT Legal Department * Emag the device if the panel is open. * Emag does not bring you into the syndicate network, but makes it visible to you. */ -/obj/machinery/fax/emag_act(mob/user) +/obj/machinery/fax/emag_act(mob/user, obj/item/card/emag/emag_card) if (!panel_open && !allow_exotic_faxes) balloon_alert(user, "open panel first!") - return + return FALSE if (!(obj_flags & EMAGGED)) obj_flags |= EMAGGED playsound(src, 'sound/creatures/dog/growl2.ogg', 50, FALSE) + balloon_alert(user, "migrated to syndienet 2.0") to_chat(user, span_warning("An image appears on [src] screen for a moment with Ian in the cap of a Syndicate officer.")) + return TRUE + return FALSE /obj/machinery/fax/wrench_act(mob/living/user, obj/item/tool) . = ..() diff --git a/code/modules/paperwork/ticketmachine.dm b/code/modules/paperwork/ticketmachine.dm index c845474f32ec..eaffabe187b5 100644 --- a/code/modules/paperwork/ticketmachine.dm +++ b/code/modules/paperwork/ticketmachine.dm @@ -58,10 +58,10 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/ticket_machine, 32) to_chat(user, span_notice("You store linkage information in [I]'s buffer.")) return TRUE -/obj/machinery/ticket_machine/emag_act(mob/user) //Emag the ticket machine to dispense burning tickets, as well as randomize its number to destroy the HoP's mind. +/obj/machinery/ticket_machine/emag_act(mob/user, obj/item/card/emag/emag_card) //Emag the ticket machine to dispense burning tickets, as well as randomize its number to destroy the HoP's mind. if(obj_flags & EMAGGED) - return - to_chat(user, span_warning("You overload [src]'s bureaucratic logic circuitry to its MAXIMUM setting.")) + return FALSE + balloon_alert(user, "bureaucratic nightmare engaged") ticket_number = rand(0,max_number) current_number = ticket_number obj_flags |= EMAGGED @@ -71,6 +71,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/ticket_machine, 32) qdel(ticket) tickets.Cut() update_appearance() + return TRUE /obj/item/wallframe/ticket_machine name = "ticket machine frame" diff --git a/code/modules/power/apc/apc_tool_act.dm b/code/modules/power/apc/apc_tool_act.dm index 0c1cf6652a2f..166b2be4b8ad 100644 --- a/code/modules/power/apc/apc_tool_act.dm +++ b/code/modules/power/apc/apc_tool_act.dm @@ -170,23 +170,27 @@ balloon_alert(user, "has both board and cell!") return FALSE -/obj/machinery/power/apc/emag_act(mob/user) +/obj/machinery/power/apc/emag_act(mob/user, obj/item/card/emag/emag_card) if((obj_flags & EMAGGED) || malfhack) - return + return FALSE if(opened) balloon_alert(user, "close the cover first!") + return FALSE else if(panel_open) balloon_alert(user, "close the panel first!") + return FALSE else if(machine_stat & (BROKEN|MAINT)) balloon_alert(user, "nothing happens!") + return FALSE else flick("apc-spark", src) playsound(src, SFX_SPARKS, 75, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) obj_flags |= EMAGGED locked = FALSE - balloon_alert(user, "you emag the APC") + balloon_alert(user, "interface damaged") update_appearance() + return TRUE // damage and destruction acts /obj/machinery/power/apc/emp_act(severity) diff --git a/code/modules/power/port_gen.dm b/code/modules/power/port_gen.dm index 5400a48422c4..3a3e88d743f3 100644 --- a/code/modules/power/port_gen.dm +++ b/code/modules/power/port_gen.dm @@ -209,12 +209,13 @@ return return ..() -/obj/machinery/power/port_gen/pacman/emag_act(mob/user) +/obj/machinery/power/port_gen/pacman/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) - return + return FALSE obj_flags |= EMAGGED - to_chat(user, span_notice("You hear a hefty clunk from inside the generator.")) + balloon_alert(user, "maximum power output unlocked") emp_act(EMP_HEAVY) + return TRUE /obj/machinery/power/port_gen/pacman/attack_ai(mob/user) interact(user) diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm index 3ff77a9c455f..3d33bd1b8a58 100644 --- a/code/modules/power/singularity/emitter.dm +++ b/code/modules/power/singularity/emitter.dm @@ -368,13 +368,13 @@ projectile_type = initial(projectile_type) projectile_sound = initial(projectile_sound) -/obj/machinery/power/emitter/emag_act(mob/user) +/obj/machinery/power/emitter/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) - return + return FALSE locked = FALSE obj_flags |= EMAGGED - if(user) - user.visible_message(span_warning("[user.name] emags [src]."), span_notice("You short out the lock.")) + balloon_alert(user, "id lock shorted out") + return TRUE /obj/machinery/power/emitter/prototype diff --git a/code/modules/projectiles/pins.dm b/code/modules/projectiles/pins.dm index 32e3b4c8e2c8..6c2914b495db 100644 --- a/code/modules/projectiles/pins.dm +++ b/code/modules/projectiles/pins.dm @@ -52,11 +52,12 @@ return . -/obj/item/firing_pin/emag_act(mob/user) +/obj/item/firing_pin/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) - return + return FALSE obj_flags |= EMAGGED - to_chat(user, span_notice("You override the authentication mechanism.")) + balloon_alert(user, "authentication checks overridden") + return TRUE /obj/item/firing_pin/proc/gun_insert(mob/living/user, obj/item/gun/G) gun = G @@ -223,12 +224,12 @@ color = "#FFD700" fail_message = "" ///list of account IDs which have accepted the license prompt. If this is the multi-payment pin, then this means they accepted the waiver that each shot will cost them money - var/list/gun_owners = list() + var/list/gun_owners = list() ///how much gets paid out to license yourself to the gun - var/payment_amount + var/payment_amount var/datum/bank_account/pin_owner ///if true, user has to pay everytime they fire the gun - var/multi_payment = FALSE + var/multi_payment = FALSE var/owned = FALSE ///purchase prompt to prevent spamming it, set to the user who opens to prompt to prevent locking the gun up for other users. var/active_prompt_user @@ -321,10 +322,10 @@ pin_owner.adjust_money(payment_amount, "Firing Pin: Gun License Bought") gun_owners += credit_card_details to_chat(user, span_notice("Gun license purchased, have a secure day!")) - - else + + else to_chat(user, span_warning("ERROR: User balance insufficent for successful transaction!")) - + if("No", null) to_chat(user, span_warning("ERROR: User has declined to purchase gun license!")) active_prompt_user = null diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm index 44acdd044afa..519195fff3c3 100644 --- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm +++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm @@ -153,13 +153,14 @@ . += beaker_overlay -/obj/machinery/chem_dispenser/emag_act(mob/user) +/obj/machinery/chem_dispenser/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) - to_chat(user, span_warning("[src] has no functional safeties to emag.")) - return - to_chat(user, span_notice("You short out [src]'s safeties.")) + balloon_alert(user, "already emagged!") + return FALSE + balloon_alert(user, "safeties shorted out") dispensable_reagents |= emagged_reagents//add the emagged reagents to the dispensable ones obj_flags |= EMAGGED + return TRUE /obj/machinery/chem_dispenser/ex_act(severity, target) if(severity <= EXPLODE_LIGHT) diff --git a/code/modules/recycling/disposal/outlet.dm b/code/modules/recycling/disposal/outlet.dm index 43af5d69bee3..6575a6ffe9e4 100644 --- a/code/modules/recycling/disposal/outlet.dm +++ b/code/modules/recycling/disposal/outlet.dm @@ -116,12 +116,13 @@ eject_speed = EJECT_SPEED_SLOW return TRUE -/obj/structure/disposaloutlet/emag_act(mob/user, obj/item/card/emag/E) +/obj/structure/disposaloutlet/emag_act(mob/user, obj/item/card/emag/emag_card) . = ..() if(obj_flags & EMAGGED) return - to_chat(user, span_notice("You silently disable the sanity checking on \the [src]'s ejection force.")) + balloon_alert(user, "ejection force maximized") obj_flags |= EMAGGED + return TRUE #undef EJECT_SPEED_SLOW #undef EJECT_SPEED_MED diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm index 449a7078537c..10fdb6fe2115 100644 --- a/code/modules/research/rdconsole.dm +++ b/code/modules/research/rdconsole.dm @@ -140,13 +140,15 @@ Nothing else in the console has ID requirements. say("Not enough research points...") return FALSE -/obj/machinery/computer/rdconsole/emag_act(mob/user) - if(!(obj_flags & EMAGGED)) - to_chat(user, span_notice("You disable the security protocols[locked? " and unlock the console":""].")) - playsound(src, SFX_SPARKS, 75, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - obj_flags |= EMAGGED - locked = FALSE - return ..() +/obj/machinery/computer/rdconsole/emag_act(mob/user, obj/item/card/emag/emag_card) + . = ..() + if (obj_flags & EMAGGED) + return + balloon_alert(user, "security protocols disabled") + playsound(src, SFX_SPARKS, 75, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) + obj_flags |= EMAGGED + locked = FALSE + return TRUE /obj/machinery/computer/rdconsole/ui_interact(mob/user, datum/tgui/ui = null) . = ..() diff --git a/code/modules/research/server_control.dm b/code/modules/research/server_control.dm index 532f05ec9659..da6cb322be84 100644 --- a/code/modules/research/server_control.dm +++ b/code/modules/research/server_control.dm @@ -20,12 +20,13 @@ balloon_alert(user, "techweb connected") return TRUE -/obj/machinery/computer/rdservercontrol/emag_act(mob/user) +/obj/machinery/computer/rdservercontrol/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) - return + return FALSE obj_flags |= EMAGGED playsound(src, SFX_SPARKS, 75, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) balloon_alert(user, "console emagged") + return TRUE /obj/machinery/computer/rdservercontrol/ui_interact(mob/user, datum/tgui/ui) . = ..() diff --git a/code/modules/research/xenobiology/vatgrowing/vatgrower.dm b/code/modules/research/xenobiology/vatgrowing/vatgrower.dm index 204658fd4477..422db53883dc 100644 --- a/code/modules/research/xenobiology/vatgrowing/vatgrower.dm +++ b/code/modules/research/xenobiology/vatgrowing/vatgrower.dm @@ -124,13 +124,14 @@ balloon_alert_to_viewers("resampler [resampler_active ? "activated" : "deactivated"]") update_appearance() -/obj/machinery/plumbing/growing_vat/emag_act(mob/user) +/obj/machinery/plumbing/growing_vat/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) - return + return FALSE obj_flags |= EMAGGED playsound(src, SFX_SPARKS, 100, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - to_chat(user, span_warning("You overload [src]'s resampling circuit.")) + balloon_alert(user, "resampling circuit overloaded") flick("growing_vat_emagged", src) + return TRUE /obj/machinery/plumbing/growing_vat/proc/on_sample_growth_completed() SIGNAL_HANDLER diff --git a/code/modules/shuttle/computer.dm b/code/modules/shuttle/computer.dm index 63387e769bcb..1c25337a0e13 100644 --- a/code/modules/shuttle/computer.dm +++ b/code/modules/shuttle/computer.dm @@ -213,12 +213,13 @@ to_chat(GLOB.admins, "SHUTTLE: [ADMIN_LOOKUPFLW(usr)] (Move Shuttle)(Lock/Unlock Shuttle) is requesting to move or unlock the shuttle.") return TRUE -/obj/machinery/computer/shuttle/emag_act(mob/user) +/obj/machinery/computer/shuttle/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) - return + return FALSE req_access = list() obj_flags |= EMAGGED - to_chat(user, span_notice("You fried the consoles ID checking system.")) + balloon_alert(user, "id checking system fried") + return TRUE /obj/machinery/computer/shuttle/connect_to_shuttle(mapload, obj/docking_port/mobile/port, obj/docking_port/stationary/dock) if(!mapload) diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm index a9f22d0eb2d9..8050e31ba08f 100644 --- a/code/modules/shuttle/emergency.dm +++ b/code/modules/shuttle/emergency.dm @@ -260,18 +260,22 @@ [hijack_completion_flight_time_set >= INFINITY ? "[scramble_message_replace_chars("\[ERROR\]")]" : hijack_completion_flight_time_set/10] seconds." : ""]" minor_announce(scramble_message_replace_chars(msg, replaceprob = 10), "Emergency Shuttle", TRUE) -/obj/machinery/computer/emergency_shuttle/emag_act(mob/user) +/obj/machinery/computer/emergency_shuttle/emag_act(mob/user, obj/item/card/emag/emag_card) // How did you even get on the shuttle before it go to the station? if(!IS_DOCKED) - return + return FALSE if((obj_flags & EMAGGED) || ENGINES_STARTED) //SYSTEM ERROR: THE SHUTTLE WILL LA-SYSTEM ERROR: THE SHUTTLE WILL LA-SYSTEM ERROR: THE SHUTTLE WILL LAUNCH IN 10 SECONDS - to_chat(user, span_warning("The shuttle is already about to launch!")) - return + balloon_alert(user, "shuttle already about to launch!") + return FALSE var/time = TIME_LEFT - message_admins("[ADMIN_LOOKUPFLW(user)] has emagged the emergency shuttle [time] seconds before launch.") - log_shuttle("[key_name(user)] has emagged the emergency shuttle in [COORD(src)] [time] seconds before launch.") + if (user) + message_admins("[ADMIN_LOOKUPFLW(user)] has emagged the emergency shuttle [time] seconds before launch.") + log_shuttle("[key_name(user)] has emagged the emergency shuttle in [COORD(src)] [time] seconds before launch.") + else + message_admins("The emergency shuttle was emagged [time] seconds before launch, with no emagger.") + log_shuttle("The emergency shuttle was emagged in [COORD(src)] [time] seconds before launch, with no emagger.") obj_flags |= EMAGGED SSshuttle.emergency.movement_force = list("KNOCKDOWN" = 60, "THROW" = 20)//YOUR PUNY SEATBELTS can SAVE YOU NOW, MORTAL @@ -287,6 +291,7 @@ authorized += ID process(SSMACHINES_DT) + return TRUE /obj/machinery/computer/emergency_shuttle/Destroy() // Our fake IDs that the emag generated are just there for colour @@ -608,14 +613,15 @@ . = ..() RegisterSignal(SSsecurity_level, COMSIG_SECURITY_LEVEL_CHANGED, PROC_REF(check_lock)) -/obj/machinery/computer/shuttle/pod/emag_act(mob/user) +/obj/machinery/computer/shuttle/pod/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) - return + return FALSE obj_flags |= EMAGGED locked = FALSE - to_chat(user, span_warning("You fry the pod's alert level checking system.")) + balloon_alert(user, "alert level checking disabled") icon_screen = "emagged_general" update_appearance() + return TRUE /obj/machinery/computer/shuttle/pod/connect_to_shuttle(mapload, obj/docking_port/mobile/port, obj/docking_port/stationary/dock) . = ..() diff --git a/code/modules/shuttle/ferry.dm b/code/modules/shuttle/ferry.dm index 595ac0787b24..14423abd580b 100644 --- a/code/modules/shuttle/ferry.dm +++ b/code/modules/shuttle/ferry.dm @@ -8,9 +8,9 @@ var/allow_silicons = FALSE var/allow_emag = FALSE -/obj/machinery/computer/shuttle/ferry/emag_act(mob/user) +/obj/machinery/computer/shuttle/ferry/emag_act(mob/user, obj/item/card/emag/emag_card) if(!allow_emag) - to_chat(user, span_warning("[src]'s security firewall is far too powerful for you to bypass.")) + balloon_alert(user, "firewall too powerful!") return FALSE return ..() diff --git a/code/modules/shuttle/special.dm b/code/modules/shuttle/special.dm index 3a49beab926c..29d9e3af6624 100644 --- a/code/modules/shuttle/special.dm +++ b/code/modules/shuttle/special.dm @@ -68,8 +68,8 @@ /obj/machinery/power/emitter/energycannon/magical/ex_act(severity) return FALSE -/obj/machinery/power/emitter/energycannon/magical/emag_act(mob/user) - return +/obj/machinery/power/emitter/energycannon/magical/emag_act(mob/user, obj/item/card/emag/emag_card) + return FALSE /obj/structure/table/abductor/wabbajack name = "wabbajack altar" @@ -289,8 +289,8 @@ /obj/machinery/scanner_gate/luxury_shuttle/attackby(obj/item/W, mob/user, params) return -/obj/machinery/scanner_gate/luxury_shuttle/emag_act(mob/user) - return +/obj/machinery/scanner_gate/luxury_shuttle/emag_act(mob/user, obj/item/card/emag/emag_card) + return FALSE #define LUXURY_MESSAGE_COOLDOWN 100 /obj/machinery/scanner_gate/luxury_shuttle/Bumped(atom/movable/AM) diff --git a/code/modules/station_goals/bsa.dm b/code/modules/station_goals/bsa.dm index c88f194c7e94..f899d9411cbe 100644 --- a/code/modules/station_goals/bsa.dm +++ b/code/modules/station_goals/bsa.dm @@ -391,6 +391,8 @@ GLOBAL_VAR_INIT(bsa_unlock, FALSE) return cannon /obj/machinery/computer/bsa_control/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) - return + return FALSE obj_flags |= EMAGGED - to_chat(user, span_warning("You emag [src] and hear the focusing crystal short out.")) + balloon_alert(user, "rigged to explode") + to_chat(user, span_warning("You emag [src] and hear the focusing crystal short out. You get the feeling it wouldn't be wise to stand near [src] when the BSA fires...")) + return TRUE diff --git a/code/modules/station_goals/meteor_shield.dm b/code/modules/station_goals/meteor_shield.dm index b0b42725aebb..f737cb6e9e3a 100644 --- a/code/modules/station_goals/meteor_shield.dm +++ b/code/modules/station_goals/meteor_shield.dm @@ -118,10 +118,11 @@ /obj/machinery/satellite/meteor_shield/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) balloon_alert(user, "already emagged!") - return + return FALSE if(!COOLDOWN_FINISHED(src, shared_emag_cooldown)) + balloon_alert(user, "on cooldown!") to_chat(user, span_warning("The last satellite emagged needs [DisplayTimeText(COOLDOWN_TIMELEFT(src, shared_emag_cooldown))] to recalibrate first. Emagging another so soon could damage the satellite network.")) - return + return FALSE var/cooldown_applied = METEOR_SHIELD_EMAG_COOLDOWN if(istype(emag_card, /obj/item/card/emag/meteor_shield_recalibrator)) cooldown_applied /= 3 @@ -132,6 +133,7 @@ say("Recalibrating... ETA:[DisplayTimeText(cooldown_applied)].") if(active) //if we allowed inactive updates a sat could be worth -1 active meteor shields on first emag update_emagged_meteor_sat(user) + return TRUE /obj/machinery/satellite/meteor_shield/proc/update_emagged_meteor_sat(mob/user) if(!active) diff --git a/code/modules/surgery/organs/augments_arms.dm b/code/modules/surgery/organs/augments_arms.dm index e0f7e130cab1..abeb3710d078 100644 --- a/code/modules/surgery/organs/augments_arms.dm +++ b/code/modules/surgery/organs/augments_arms.dm @@ -253,13 +253,13 @@ /obj/item/organ/internal/cyberimp/arm/toolset/l zone = BODY_ZONE_L_ARM -/obj/item/organ/internal/cyberimp/arm/toolset/emag_act(mob/user) +/obj/item/organ/internal/cyberimp/arm/toolset/emag_act(mob/user, obj/item/card/emag/emag_card) for(var/datum/weakref/created_item in items_list) var/obj/potential_knife = created_item.resolve() if(istype(/obj/item/knife/combat/cyborg, potential_knife)) return FALSE - to_chat(user, span_notice("You unlock [src]'s integrated knife!")) + balloon_alert(user, "integrated knife unlocked") items_list += WEAKREF(new /obj/item/knife/combat/cyborg(src)) return TRUE diff --git a/code/modules/vehicles/cars/clowncar.dm b/code/modules/vehicles/cars/clowncar.dm index b90cb6267468..b6ad859809e6 100644 --- a/code/modules/vehicles/cars/clowncar.dm +++ b/code/modules/vehicles/cars/clowncar.dm @@ -168,14 +168,16 @@ playsound(target_pancake, 'sound/effects/cartoon_splat.ogg', 75) log_combat(src, crossed, "ran over") -/obj/vehicle/sealed/car/clowncar/emag_act(mob/user) +/obj/vehicle/sealed/car/clowncar/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) - return + return FALSE obj_flags |= EMAGGED + balloon_alert(user, "fun mode engaged") to_chat(user, span_danger("You scramble [src]'s child safety lock, and a panel with six colorful buttons appears!")) initialize_controller_action_type(/datum/action/vehicle/sealed/roll_the_dice, VEHICLE_CONTROL_DRIVE) initialize_controller_action_type(/datum/action/vehicle/sealed/cannon, VEHICLE_CONTROL_DRIVE) AddElement(/datum/element/waddling) + return TRUE /obj/vehicle/sealed/car/clowncar/atom_destruction(damage_flag) playsound(src, 'sound/vehicles/clowncar_fart.ogg', 100) diff --git a/code/modules/vehicles/motorized_wheelchair.dm b/code/modules/vehicles/motorized_wheelchair.dm index 4abc5ba376b0..e229b7b180d9 100644 --- a/code/modules/vehicles/motorized_wheelchair.dm +++ b/code/modules/vehicles/motorized_wheelchair.dm @@ -185,8 +185,15 @@ visible_message(span_danger("[src] crashes into [A], sending [disabled] flying!")) playsound(src, 'sound/effects/bang.ogg', 50, 1) -/obj/vehicle/ridden/wheelchair/motorized/emag_act(mob/user) - if((obj_flags & EMAGGED) || !panel_open) - return - to_chat(user, span_warning("A bomb appears in [src], what the fuck?")) +/obj/vehicle/ridden/wheelchair/motorized/emag_act(mob/user, obj/item/card/emag/emag_card) + if (obj_flags & EMAGGED) + return FALSE + + if (panel_open) + balloon_alert(user, "open maintenance panel!") + return FALSE + + balloon_alert(user, "bomb implanted...?") + visible_message(span_warning("A bomb appears in [src], what the fuck?")) obj_flags |= EMAGGED + return TRUE diff --git a/code/modules/vending/_vending.dm b/code/modules/vending/_vending.dm index 270ced11cec0..80beab48015e 100644 --- a/code/modules/vending/_vending.dm +++ b/code/modules/vending/_vending.dm @@ -845,11 +845,12 @@ update_canister() . = ..() -/obj/machinery/vending/emag_act(mob/user) +/obj/machinery/vending/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) - return + return FALSE obj_flags |= EMAGGED - to_chat(user, span_notice("You short out the product lock on [src].")) + balloon_alert(user, "product lock disabled") + return TRUE /obj/machinery/vending/interact(mob/user) if(seconds_electrified && !(machine_stat & NOPOWER)) diff --git a/icons/mob/actions/actions_AI.dmi b/icons/mob/actions/actions_AI.dmi index 9f900bb9b4d9866621a47a683276dfbf90eb6bac..c25b88aac5cfaf5f92e8620bd3a2aabb4aae086c 100644 GIT binary patch literal 11221 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