From 8e3f635b9884fc207971b2e8139a56bcd891ef34 Mon Sep 17 00:00:00 2001 From: Jeremiah <42397676+jlsnow301@users.noreply.github.com> Date: Tue, 16 Apr 2024 16:48:03 -0700 Subject: [PATCH] Alt click refactor (#82656) ## About The Pull Request Rewrites how alt click works. Based heavily on #82625. What a cool concept, it flows nicely with #82533. Fixes #81242 (tm bugs fixed) Fixes #82668
More info for devs Handy regex used for alt click s&r: `AltClick\((.*).*\)(\n\t.*\.\.\(\))?` `click_alt($1)` (yes I am aware this only copies the first arg. there are no other args!) ### Obj reskins No reason for obj reskin to check on every single alt click for every object. It applies to only a few items. - Moved to obj/item - Made into signal - Added screentips ### Ventcrawling Every single atmospherics machine checked for ventcrawling capability on alt click despite only 3 objects needing that functionality. This has been moved down to those individual items.
## Why It's Good For The Game For players: - Alt clicking should work more logically, not causing double actions like eject disk and open item window - Added context menus for reskinnable items - Removed adjacency restriction on loot panel For devs: - Makes alt click interactions easier to work with, no more click chain nonsense and redundant guard clauses. - OOP hell reduced - Pascal Case reduced - Glorious snake case ## Changelog :cl: add: The lootpanel now works at range. add: Screentips for reskinnable items. fix: Alt click interactions have been refactored, which may lead to unintentional changes to gameplay. Report any issues, please. /:cl: --- code/__DEFINES/click.dm | 8 +++ .../signals_atom/signals_atom_mouse.dm | 1 - code/__DEFINES/mobs.dm | 4 ++ code/__DEFINES/traits/declarations.dm | 3 - code/_globalvars/traits/_traits.dm | 1 - code/_onclick/ai.dm | 15 ++--- code/_onclick/click.dm | 46 +------------ code/_onclick/click_alt.dm | 66 +++++++++++++++++++ code/_onclick/cyborg.dm | 22 +++---- code/_onclick/observer.dm | 2 +- code/_onclick/overmind.dm | 4 +- code/datums/ai/oldhostile/hostile_tameable.dm | 2 +- code/datums/components/gps.dm | 6 +- .../components/pet_commands/obeys_commands.dm | 1 + code/datums/components/rotation.dm | 5 +- code/datums/components/style/style_meter.dm | 13 ++-- code/datums/components/toggle_suit.dm | 9 +-- code/datums/storage/storage.dm | 3 +- code/game/atom/_atom.dm | 3 + code/game/machinery/autolathe.dm | 10 +-- code/game/machinery/civilian_bounties.dm | 6 +- code/game/machinery/computer/_computer.dm | 6 -- code/game/machinery/computer/dna_console.dm | 12 +--- .../machinery/computer/prisoner/_prisoner.dm | 8 +-- code/game/machinery/defibrillator_mount.dm | 9 ++- code/game/machinery/deployable.dm | 5 +- code/game/machinery/dish_drive.dm | 7 +- .../game/machinery/dna_infuser/dna_infuser.dm | 8 +-- code/game/machinery/fat_sucker.dm | 9 ++- code/game/machinery/harvester.dm | 18 ++--- code/game/machinery/iv_drip.dm | 9 +-- code/game/machinery/pipe/construction.dm | 2 - code/game/machinery/sleepers.dm | 6 +- code/game/machinery/spaceheater.dm | 8 +-- code/game/machinery/stasis.dm | 26 ++++---- code/game/objects/items.dm | 24 +++++++ code/game/objects/items/airlock_painter.dm | 18 ++--- code/game/objects/items/cards_ids.dm | 26 ++++---- .../machines/machine_circuitboards.dm | 5 +- code/game/objects/items/cosmetics.dm | 13 ++-- code/game/objects/items/crayons.dm | 8 ++- code/game/objects/items/credit_holochip.dm | 18 ++--- .../objects/items/devices/desynchronizer.dm | 18 +++-- .../objects/items/devices/geiger_counter.dm | 7 +- .../objects/items/devices/quantum_keycard.dm | 7 +- .../objects/items/devices/radio/headset.dm | 12 ++-- .../items/devices/scanners/gas_analyzer.dm | 26 ++++---- .../items/devices/scanners/health_analyzer.dm | 14 ++-- code/game/objects/items/devices/swapper.dm | 12 ++-- .../objects/items/devices/taperecorder.dm | 6 +- code/game/objects/items/etherealdiscoball.dm | 4 +- code/game/objects/items/extinguisher.dm | 8 +-- code/game/objects/items/flamethrower.dm | 16 +++-- code/game/objects/items/grenades/_grenade.dm | 1 - .../game/objects/items/implants/implantpad.dm | 7 +- code/game/objects/items/inspector.dm | 9 +-- code/game/objects/items/machine_wand.dm | 7 +- code/game/objects/items/pet_carrier.dm | 7 +- code/game/objects/items/pillow.dm | 12 ++-- code/game/objects/items/rcd/RPLD.dm | 3 +- code/game/objects/items/rcd/RWD.dm | 6 +- code/game/objects/items/robot/items/hypo.dm | 6 +- .../game/objects/items/robot/items/storage.dm | 23 +++---- code/game/objects/items/spear.dm | 13 ++-- code/game/objects/items/stacks/medical.dm | 6 +- code/game/objects/items/stacks/wrap.dm | 9 +-- code/game/objects/items/storage/belt.dm | 6 +- code/game/objects/items/storage/fancy.dm | 4 +- code/game/objects/items/storage/lockbox.dm | 6 +- code/game/objects/items/tanks/tank_types.dm | 10 +-- code/game/objects/items_reskin.dm | 57 ++++++++++++++++ code/game/objects/objs.dm | 52 --------------- .../objects/structures/beds_chairs/bed.dm | 9 +-- .../objects/structures/beds_chairs/chair.dm | 9 ++- code/game/objects/structures/bedsheet_bin.dm | 7 +- code/game/objects/structures/divine.dm | 10 ++- .../objects/structures/lavaland/geyser.dm | 8 +-- code/game/objects/structures/morgue.dm | 7 +- code/game/objects/structures/railings.dm | 2 - code/game/objects/structures/shower.dm | 2 - .../objects/structures/training_machine.dm | 19 +++--- .../transit_tube_construction.dm | 2 - .../objects/structures/windoor_assembly.dm | 2 - code/game/objects/structures/window.dm | 2 - code/modules/admin/sound_emitter.dm | 11 ++-- .../abductor/equipment/gear/abductor_items.dm | 4 +- code/modules/art/paintings.dm | 10 +-- code/modules/art/statues.dm | 2 - code/modules/assembly/health.dm | 6 +- code/modules/assembly/holder.dm | 2 - code/modules/assembly/infrared.dm | 2 - .../atmospherics/machinery/atmosmachinery.dm | 5 -- .../components/binary_devices/passive_gate.dm | 17 ++--- .../binary_devices/pressure_valve.dm | 17 ++--- .../components/binary_devices/pump.dm | 17 ++--- .../binary_devices/temperature_gate.dm | 17 ++--- .../binary_devices/temperature_pump.dm | 17 ++--- .../components/binary_devices/volume_pump.dm | 17 ++--- .../components/electrolyzer/electrolyzer.dm | 8 +-- .../components/trinary_devices/filter.dm | 16 +++-- .../components/trinary_devices/mixer.dm | 16 +++-- .../components/unary_devices/cryo.dm | 15 ++--- .../unary_devices/outlet_injector.dm | 16 +++-- .../components/unary_devices/passive_vent.dm | 2 + .../components/unary_devices/thermomachine.dm | 7 +- .../components/unary_devices/unary_devices.dm | 6 ++ .../components/unary_devices/vent_pump.dm | 1 + .../components/unary_devices/vent_scrubber.dm | 1 + .../portable/portable_atmospherics.dm | 9 ++- code/modules/cards/deck/deck.dm | 15 +++-- code/modules/cards/singlecard.dm | 8 +-- code/modules/cargo/supplypod_beacon.dm | 16 +++-- code/modules/cargo/universal_scanner.dm | 6 +- code/modules/clothing/glasses/_glasses.dm | 50 +++++++------- code/modules/clothing/head/jobs.dm | 30 ++++----- code/modules/clothing/head/soft_caps.dm | 12 ++-- code/modules/clothing/masks/animal_masks.dm | 11 ++-- code/modules/clothing/masks/bandana.dm | 66 ++++++++++--------- code/modules/clothing/masks/breath.dm | 8 +-- code/modules/clothing/masks/costume.dm | 8 --- code/modules/clothing/neck/_neck.dm | 10 +-- .../clothing/spacesuits/_spacesuits.dm | 21 +++--- code/modules/clothing/spacesuits/plasmamen.dm | 6 +- code/modules/clothing/suits/wintercoats.dm | 8 +-- code/modules/clothing/under/_under.dm | 33 +++++----- code/modules/clothing/under/costume.dm | 1 + code/modules/detectivework/scanner.dm | 18 ++--- .../experiment/handlers/experiment_handler.dm | 1 + code/modules/fishing/aquarium/aquarium.dm | 6 +- .../food_and_drinks/machinery/icecream_vat.dm | 13 ++-- .../food_and_drinks/machinery/microwave.dm | 19 +++--- code/modules/hydroponics/biogenerator.dm | 8 +-- code/modules/hydroponics/hydroponics.dm | 2 - code/modules/lootpanel/_lootpanel.dm | 3 - code/modules/lootpanel/ui.dm | 4 -- .../ruins/spaceruin_code/hilbertshotel.dm | 17 +++-- code/modules/mining/abandoned_crates.dm | 7 +- .../modules/mining/equipment/explorer_gear.dm | 37 ++++++----- .../mining/equipment/marker_beacons.dm | 23 +++---- code/modules/mining/machine_redemption.dm | 22 +++---- code/modules/mob/living/basic/bots/_bots.dm | 9 +-- .../mob/living/basic/minebots/minebot.dm | 6 +- .../basic/space_fauna/revenant/_revenant.dm | 2 +- code/modules/mob/living/brain/posibrain.dm | 9 ++- code/modules/mob/living/living.dm | 9 ++- .../mob/living/simple_animal/bot/bot.dm | 9 +-- code/modules/mob/mob.dm | 4 ++ .../computers/item/computer.dm | 13 ++-- .../computers/item/laptop.dm | 13 ++-- .../modular_computers/computers/item/pda.dm | 6 -- .../computers/machinery/modular_computer.dm | 8 +-- code/modules/paperwork/carbonpaper.dm | 6 +- code/modules/paperwork/clipboard.dm | 17 +++-- code/modules/paperwork/paper.dm | 17 ++--- code/modules/paperwork/paper_cutter.dm | 6 +- code/modules/paperwork/pen.dm | 1 + code/modules/photography/camera/camera.dm | 5 +- .../plumbing/plumbers/_plumb_machinery.dm | 2 - code/modules/plumbing/plumbers/iv_drip.dm | 2 - code/modules/power/pipecleaners.dm | 5 +- code/modules/power/singularity/emitter.dm | 2 - code/modules/projectiles/guns/ballistic.dm | 22 +++---- .../projectiles/guns/ballistic/automatic.dm | 5 +- .../projectiles/guns/ballistic/bows/_bow.dm | 5 +- .../projectiles/guns/ballistic/revolver.dm | 4 +- .../projectiles/guns/ballistic/shotgun.dm | 10 +-- .../chemistry/machinery/chem_dispenser.dm | 2 - .../chemistry/machinery/chem_mass_spec.dm | 8 +-- .../machinery/portable_chem_mixer.dm | 8 +-- .../reagents/reagent_containers/chem_pack.dm | 32 +++++---- .../reagents/reagent_containers/cups/_cup.dm | 12 ++-- .../reagent_containers/cups/bottle.dm | 4 +- .../reagent_containers/cups/drinks.dm | 28 ++++---- .../reagents/reagent_containers/medigel.dm | 1 + .../reagents/reagent_containers/spray.dm | 11 +++- code/modules/reagents/reagent_dispenser.dm | 2 - .../recycling/disposal/construction.dm | 2 - code/modules/recycling/sortingmachinery.dm | 4 +- code/modules/research/destructive_analyzer.dm | 4 +- .../modules/research/machinery/_production.dm | 10 +-- .../research/ordnance/doppler_array.dm | 2 - .../research/xenobiology/xenobio_camera.dm | 4 +- .../research/xenobiology/xenobiology.dm | 5 +- code/modules/shuttle/emergency.dm | 14 ++-- code/modules/transport/tram/tram_remote.dm | 7 +- code/modules/transport/tram/tram_signals.dm | 12 ++-- .../modules/vehicles/mecha/mech_fabricator.dm | 14 ++-- code/modules/vehicles/mecha/mecha_actions.dm | 9 +-- code/modules/vehicles/ridden.dm | 10 +-- code/modules/vehicles/wheelchair.dm | 2 - code/modules/wiremod/shell/controller.dm | 4 +- tgstation.dme | 3 + 192 files changed, 1031 insertions(+), 1038 deletions(-) create mode 100644 code/__DEFINES/click.dm create mode 100644 code/_onclick/click_alt.dm create mode 100644 code/game/objects/items_reskin.dm diff --git a/code/__DEFINES/click.dm b/code/__DEFINES/click.dm new file mode 100644 index 00000000000..5900dd54210 --- /dev/null +++ b/code/__DEFINES/click.dm @@ -0,0 +1,8 @@ +/// Action has succeeded, preventing further alt click interaction +#define CLICK_ACTION_SUCCESS (1<<0) +/// Action failed, preventing further alt click interaction +#define CLICK_ACTION_BLOCKING (1<<1) +/// Either return state +#define CLICK_ACTION_ANY (CLICK_ACTION_SUCCESS | CLICK_ACTION_BLOCKING) + +/// Use NONE for continue interaction diff --git a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_mouse.dm b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_mouse.dm index 3ff131d9a39..2ea2e4d5fe3 100644 --- a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_mouse.dm +++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_mouse.dm @@ -13,7 +13,6 @@ #define COMSIG_CLICK_CTRL "ctrl_click" ///from base of atom/AltClick(): (/mob) #define COMSIG_CLICK_ALT "alt_click" - #define COMPONENT_CANCEL_CLICK_ALT (1<<0) ///from base of atom/alt_click_secondary(): (/mob) #define COMSIG_CLICK_ALT_SECONDARY "alt_click_secondary" #define COMPONENT_CANCEL_CLICK_ALT_SECONDARY (1<<0) diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 91955b496ca..195dd3f53aa 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -823,6 +823,10 @@ GLOBAL_LIST_INIT(layers_to_offset, list( #define ALLOW_SILICON_REACH (1<<6) /// If resting on the floor is allowed to perform action (pAIs can play music while resting) #define ALLOW_RESTING (1<<7) +/// If this is accessible to creatures with ventcrawl capabilities +#define NEED_VENTCRAWL (1<<8) +/// Checks for base adjacency, but silences the error +#define SILENT_ADJACENCY (1<<9) /// The default mob sprite size (used for shrinking or enlarging the mob sprite to regular size) #define RESIZE_DEFAULT_SIZE 1 diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index c01d663e0e3..f5ad67a8c94 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -1114,7 +1114,4 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai /// Trait applied to objects and mobs that can attack a boulder and break it down. (See /obj/item/boulder/manual_process()) #define TRAIT_BOULDER_BREAKER "boulder_breaker" -/// Prevents the affected object from opening a loot window via alt click. See atom/AltClick() -#define TRAIT_ALT_CLICK_BLOCKER "no_alt_click" - // END TRAIT DEFINES diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index 1595e23a77d..9ee26893b5f 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -8,7 +8,6 @@ GLOBAL_LIST_INIT(traits_by_type, list( /atom = list( "TRAIT_AI_PAUSED" = TRAIT_AI_PAUSED, - "TRAIT_ALT_CLICK_BLOCKER" = TRAIT_ALT_CLICK_BLOCKER, "TRAIT_BANNED_FROM_CARGO_SHUTTLE" = TRAIT_BANNED_FROM_CARGO_SHUTTLE, "TRAIT_BEING_SHOCKED" = TRAIT_BEING_SHOCKED, "TRAIT_COMMISSIONED" = TRAIT_COMMISSIONED, diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm index 8f95bdadda9..f45c1c7c82d 100644 --- a/code/_onclick/ai.dm +++ b/code/_onclick/ai.dm @@ -55,7 +55,7 @@ ShiftClickOn(A) return if(LAZYACCESS(modifiers, ALT_CLICK)) // alt and alt-gr (rightalt) - AltClickOn(A) + A.ai_click_alt(src) return if(LAZYACCESS(modifiers, CTRL_CLICK)) CtrlClickOn(A) @@ -120,8 +120,6 @@ /mob/living/silicon/ai/CtrlClickOn(atom/target) target.AICtrlClick(src) -/mob/living/silicon/ai/AltClickOn(atom/target) - target.AIAltClick(src) /* The following criminally helpful code is just the previous code cleaned up; @@ -133,8 +131,7 @@ /atom/proc/AICtrlClick(mob/living/silicon/ai/user) return -/atom/proc/AIAltClick(mob/living/silicon/ai/user) - AltClick(user) +/atom/proc/ai_click_alt(mob/living/silicon/ai/user) return /atom/proc/AIShiftClick(mob/living/silicon/ai/user) @@ -151,7 +148,7 @@ toggle_bolt(user) add_hiddenprint(user) -/obj/machinery/door/airlock/AIAltClick(mob/living/silicon/ai/user) // Eletrifies doors. +/obj/machinery/door/airlock/ai_click_alt(mob/living/silicon/ai/user) if(obj_flags & EMAGGED) return @@ -220,7 +217,7 @@ update() /// Toggle APC equipment settings -/obj/machinery/power/apc/AIAltClick(mob/living/silicon/ai/user) +/obj/machinery/power/apc/ai_click_alt(mob/living/silicon/ai/user) if(!can_use(user, loud = TRUE)) return @@ -244,7 +241,7 @@ return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN /* AI Turrets */ -/obj/machinery/turretid/AIAltClick(mob/living/silicon/ai/user) //toggles lethal on turrets +/obj/machinery/turretid/ai_click_alt(mob/living/silicon/ai/user) //toggles lethal on turrets if(ailock) return toggle_lethal(user) @@ -255,7 +252,7 @@ toggle_on(user) /* Holopads */ -/obj/machinery/holopad/AIAltClick(mob/living/silicon/ai/user) +/obj/machinery/holopad/ai_click_alt(mob/living/silicon/ai/user) if (user) balloon_alert(user, "disrupted all active calls") add_hiddenprint(user) diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index b96b8241b12..eecad5c7522 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -96,7 +96,7 @@ if(LAZYACCESS(modifiers, RIGHT_CLICK)) alt_click_on_secondary(A) else - AltClickOn(A) + base_click_alt(A) return if(LAZYACCESS(modifiers, CTRL_CLICK)) CtrlClickOn(A) @@ -385,50 +385,6 @@ A.CtrlClick(src) return -/** - * Alt click - * Unused except for AI - */ -/mob/proc/AltClickOn(atom/A) - . = SEND_SIGNAL(src, COMSIG_MOB_ALTCLICKON, A) - if(. & COMSIG_MOB_CANCEL_CLICKON) - return - A.AltClick(src) - -/** - * Alt click on an atom. - * Performs alt-click actions before attempting to open a loot window. - * Returns TRUE if successful, FALSE if not. - */ -/atom/proc/AltClick(mob/user) - if(!user.can_interact_with(src)) - return FALSE - - if(SEND_SIGNAL(src, COMSIG_CLICK_ALT, user) & COMPONENT_CANCEL_CLICK_ALT) - return TRUE - - if(HAS_TRAIT(src, TRAIT_ALT_CLICK_BLOCKER) && !isobserver(user)) - return TRUE - - var/turf/tile = get_turf(src) - if(isnull(tile)) - return FALSE - - if(!isturf(loc) && !isturf(src)) - return FALSE - - if(!user.TurfAdjacent(tile)) - return FALSE - - if(HAS_TRAIT(user, TRAIT_MOVE_VENTCRAWLING)) - return FALSE - - var/datum/lootpanel/panel = user.client?.loot_panel - if(isnull(panel)) - return FALSE - - panel.open(tile) - return TRUE ///The base proc of when something is right clicked on when alt is held - generally use alt_click_secondary instead /atom/proc/alt_click_on_secondary(atom/A) diff --git a/code/_onclick/click_alt.dm b/code/_onclick/click_alt.dm new file mode 100644 index 00000000000..16c8e843995 --- /dev/null +++ b/code/_onclick/click_alt.dm @@ -0,0 +1,66 @@ +/** + * ### Base proc for alt click interaction. + * + * If you wish to add custom `click_alt` behavior for a single type, use that proc. + */ +/mob/proc/base_click_alt(atom/target) + SHOULD_NOT_OVERRIDE(TRUE) + + var/turf/tile = isturf(target) ? target : get_turf(target) + + if(isobserver(src) || isrevenant(src)) + open_lootpanel(tile) + return + + if(!isturf(target) && can_perform_action(target, (target.interaction_flags_click | SILENT_ADJACENCY))) + if(SEND_SIGNAL(target, COMSIG_CLICK_ALT, src) & CLICK_ACTION_ANY) + return + + if(target.click_alt(src) & CLICK_ACTION_ANY) + return + + open_lootpanel(tile) + + +/// Helper for opening the lootpanel +/mob/proc/open_lootpanel(turf/target) + if(HAS_TRAIT(src, TRAIT_MOVE_VENTCRAWLING)) + return + + var/datum/lootpanel/panel = client?.loot_panel + if(isnull(panel)) + return + + panel.open(target) + + +/** + * ## Custom alt click interaction + * Override this to change default alt click behavior. Return `CLICK_ACTION_SUCCESS`, `CLICK_ACTION_BLOCKING` or `NONE`. + * + * ### Guard clauses + * Consider adding `interaction_flags_click` before adding unique guard clauses. + * + * ### Return flags + * Forgetting your return will cause the default alt click behavior to occur thereafter. + * + * The difference between NONE and BLOCKING can get hazy, but I like to keep NONE limited to guard clauses and "never" cases. + * + * A good usage for BLOCKING over NONE is when it's situational for the item and there's some feedback indicating this. + * + * ### Examples: + * User is a ghost, alt clicks on item with special disk eject: NONE + * + * Machine broken, no feedback: NONE + * + * Alt click a pipe to max output but its already max: BLOCKING + * + * Alt click a gun that normally works, but is out of ammo: BLOCKING + * + * User unauthorized, machine beeps: BLOCKING + * + * @param {mob} user - The person doing the alt clicking. + */ +/atom/proc/click_alt(mob/user) + SHOULD_CALL_PARENT(FALSE) + return NONE diff --git a/code/_onclick/cyborg.dm b/code/_onclick/cyborg.dm index b1b27c3400f..b16d74550a9 100644 --- a/code/_onclick/cyborg.dm +++ b/code/_onclick/cyborg.dm @@ -31,7 +31,7 @@ MiddleClickOn(A, params) return if(LAZYACCESS(modifiers, ALT_CLICK)) // alt and alt-gr (rightalt) - AltClickOn(A) + A.borg_click_alt(src) return if(LAZYACCESS(modifiers, CTRL_CLICK)) CtrlClickOn(A) @@ -89,7 +89,7 @@ if(after_attack_secondary_result == SECONDARY_ATTACK_CALL_NORMAL) W.afterattack(A, src, FALSE, params) - else + else W.afterattack(A, src, FALSE, params) //Give cyborgs hotkey clicks without breaking existing uses of hotkey clicks @@ -103,8 +103,6 @@ /mob/living/silicon/robot/CtrlClickOn(atom/target) target.BorgCtrlClick(src) -/mob/living/silicon/robot/AltClickOn(atom/target) - target.BorgAltClick(src) /atom/proc/BorgCtrlShiftClick(mob/living/silicon/robot/user) //forward to human click if not overridden CtrlShiftClick(user) @@ -152,9 +150,9 @@ else ..() -/obj/machinery/power/apc/BorgAltClick(mob/living/silicon/robot/user) +/obj/machinery/power/apc/borg_click_alt(mob/living/silicon/robot/user) if(get_dist(src, user) <= user.interaction_range && !(user.control_disabled)) - AIAltClick(user) + ai_click_alt(user) else ..() @@ -171,19 +169,19 @@ else ..() -/atom/proc/BorgAltClick(mob/living/silicon/robot/user) - AltClick(user) +/atom/proc/borg_click_alt(mob/living/silicon/robot/user) + user.base_click_alt(src) return -/obj/machinery/door/airlock/BorgAltClick(mob/living/silicon/robot/user) // Eletrifies doors. Forwards to AI code. +/obj/machinery/door/airlock/borg_click_alt(mob/living/silicon/robot/user) // Eletrifies doors. Forwards to AI code. if(get_dist(src, user) <= user.interaction_range && !(user.control_disabled)) - AIAltClick(user) + ai_click_alt(user) else ..() -/obj/machinery/turretid/BorgAltClick(mob/living/silicon/robot/user) //turret lethal on/off. Forwards to AI code. +/obj/machinery/turretid/borg_click_alt(mob/living/silicon/robot/user) //turret lethal on/off. Forwards to AI code. if(get_dist(src, user) <= user.interaction_range && !(user.control_disabled)) - AIAltClick(user) + ai_click_alt(user) else ..() diff --git a/code/_onclick/observer.dm b/code/_onclick/observer.dm index 65fccef85b9..ae2ebd97632 100644 --- a/code/_onclick/observer.dm +++ b/code/_onclick/observer.dm @@ -31,7 +31,7 @@ MiddleClickOn(A, params) return if(LAZYACCESS(modifiers, ALT_CLICK)) - A.AltClick(src) + base_click_alt(A) return if(LAZYACCESS(modifiers, CTRL_CLICK)) CtrlClickOn(A) diff --git a/code/_onclick/overmind.dm b/code/_onclick/overmind.dm index d6b8994f82f..900ad59bde2 100644 --- a/code/_onclick/overmind.dm +++ b/code/_onclick/overmind.dm @@ -10,7 +10,7 @@ ShiftClickOn(A) return if(LAZYACCESS(modifiers, ALT_CLICK)) - AltClickOn(A) + blob_click_alt(A) return if(LAZYACCESS(modifiers, CTRL_CLICK)) CtrlClickOn(A) @@ -30,7 +30,7 @@ if(T) create_shield(T) -/mob/camera/blob/AltClickOn(atom/A) //Remove a blob +/mob/camera/blob/proc/blob_click_alt(atom/A) //Remove a blob var/turf/T = get_turf(A) if(T) remove_blob(T) diff --git a/code/datums/ai/oldhostile/hostile_tameable.dm b/code/datums/ai/oldhostile/hostile_tameable.dm index 5c96eca17da..d76ffb8a282 100644 --- a/code/datums/ai/oldhostile/hostile_tameable.dm +++ b/code/datums/ai/oldhostile/hostile_tameable.dm @@ -108,7 +108,7 @@ return if(!istype(clicker) || blackboard[BB_HOSTILE_FRIEND] != clicker) return - . = COMPONENT_CANCEL_CLICK_ALT + . = CLICK_ACTION_BLOCKING INVOKE_ASYNC(src, PROC_REF(command_radial), clicker) /// Show the command radial menu diff --git a/code/datums/components/gps.dm b/code/datums/components/gps.dm index a84bc1e7595..7e52f00def7 100644 --- a/code/datums/components/gps.dm +++ b/code/datums/components/gps.dm @@ -50,7 +50,7 @@ GLOBAL_LIST_EMPTY(GPS_list) if(!emp_proof) RegisterSignal(parent, COMSIG_ATOM_EMP_ACT, PROC_REF(on_emp_act)) RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) - RegisterSignal(parent, COMSIG_CLICK_ALT, PROC_REF(on_AltClick)) + RegisterSignal(parent, COMSIG_CLICK_ALT, PROC_REF(on_click_alt)) ///Called on COMSIG_ITEM_ATTACK_SELF /datum/component/gps/item/proc/interact(datum/source, mob/user) @@ -85,11 +85,11 @@ GLOBAL_LIST_EMPTY(GPS_list) A.add_overlay("working") ///Calls toggletracking -/datum/component/gps/item/proc/on_AltClick(datum/source, mob/user) +/datum/component/gps/item/proc/on_click_alt(datum/source, mob/user) SIGNAL_HANDLER toggletracking(user) - return COMPONENT_CANCEL_CLICK_ALT + return CLICK_ACTION_SUCCESS ///Toggles the tracking for the gps /datum/component/gps/item/proc/toggletracking(mob/user) diff --git a/code/datums/components/pet_commands/obeys_commands.dm b/code/datums/components/pet_commands/obeys_commands.dm index 2fceaa2b337..ec3a04c940a 100644 --- a/code/datums/components/pet_commands/obeys_commands.dm +++ b/code/datums/components/pet_commands/obeys_commands.dm @@ -72,6 +72,7 @@ return // Not our friend, can't boss us around INVOKE_ASYNC(src, PROC_REF(display_radial_menu), clicker) + return CLICK_ACTION_SUCCESS /// Actually display the radial menu and then do something with the result /datum/component/obeys_commands/proc/display_radial_menu(mob/living/clicker) diff --git a/code/datums/components/rotation.dm b/code/datums/components/rotation.dm index 160cc3b7629..f872c6bfd69 100644 --- a/code/datums/components/rotation.dm +++ b/code/datums/components/rotation.dm @@ -26,8 +26,6 @@ RegisterSignal(parent, COMSIG_CLICK_ALT_SECONDARY, PROC_REF(rotate_right)) RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(ExamineMessage)) RegisterSignal(parent, COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM, PROC_REF(on_requesting_context_from_item)) - - ADD_TRAIT(parent, TRAIT_ALT_CLICK_BLOCKER, REF(src)) return ..() /datum/component/simple_rotation/PostTransfer() @@ -43,8 +41,6 @@ COMSIG_ATOM_EXAMINE, COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM, )) - - REMOVE_TRAIT(parent, TRAIT_ALT_CLICK_BLOCKER, REF(src)) return ..() /datum/component/simple_rotation/Destroy() @@ -63,6 +59,7 @@ /datum/component/simple_rotation/proc/rotate_left(datum/source, mob/user) SIGNAL_HANDLER rotate(user, ROTATION_COUNTERCLOCKWISE) + return CLICK_ACTION_SUCCESS /datum/component/simple_rotation/proc/rotate(mob/user, degrees) if(QDELETED(user)) diff --git a/code/datums/components/style/style_meter.dm b/code/datums/components/style/style_meter.dm index 72688f41c52..b5aabd72f62 100644 --- a/code/datums/components/style/style_meter.dm +++ b/code/datums/components/style/style_meter.dm @@ -38,7 +38,7 @@ RegisterSignal(interacting_with, COMSIG_ITEM_EQUIPPED, PROC_REF(check_wearing)) RegisterSignal(interacting_with, COMSIG_ITEM_DROPPED, PROC_REF(on_drop)) RegisterSignal(interacting_with, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) - RegisterSignal(interacting_with, COMSIG_CLICK_ALT, PROC_REF(on_altclick)) + RegisterSignal(interacting_with, COMSIG_CLICK_ALT, PROC_REF(on_click_alt)) RegisterSignal(interacting_with, COMSIG_ATOM_TOOL_ACT(TOOL_MULTITOOL), PROC_REF(redirect_multitool)) balloon_alert(user, "style meter attached") playsound(src, 'sound/machines/click.ogg', 30, TRUE) @@ -90,14 +90,15 @@ /// Signal proc to remove from glasses -/obj/item/style_meter/proc/on_altclick(datum/source, mob/user) +/obj/item/style_meter/proc/on_click_alt(datum/source, mob/user) SIGNAL_HANDLER - if(istype(loc, /obj/item/clothing/glasses)) - clean_up() - forceMove(get_turf(src)) + if(!istype(loc, /obj/item/clothing/glasses)) + return CLICK_ACTION_BLOCKING - return COMPONENT_CANCEL_CLICK_ALT + clean_up() + forceMove(get_turf(src)) + return CLICK_ACTION_SUCCESS /obj/item/style_meter/multitool_act(mob/living/user, obj/item/tool) multitooled = !multitooled diff --git a/code/datums/components/toggle_suit.dm b/code/datums/components/toggle_suit.dm index 596bf3b3252..c4a378a16de 100644 --- a/code/datums/components/toggle_suit.dm +++ b/code/datums/components/toggle_suit.dm @@ -20,7 +20,7 @@ src.base_icon_state = atom_parent.base_icon_state || atom_parent.icon_state /datum/component/toggle_icon/RegisterWithParent() - RegisterSignal(parent, COMSIG_CLICK_ALT, PROC_REF(on_alt_click)) + RegisterSignal(parent, COMSIG_CLICK_ALT, PROC_REF(on_click_alt)) RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) /datum/component/toggle_icon/UnregisterFromParent() @@ -34,7 +34,7 @@ * source - the atom being clicked on * user - the mob doing the click */ -/datum/component/toggle_icon/proc/on_alt_click(atom/source, mob/user) +/datum/component/toggle_icon/proc/on_click_alt(atom/source, mob/user) SIGNAL_HANDLER if(!isliving(user)) @@ -47,13 +47,14 @@ if(living_user.incapacitated()) source.balloon_alert(user, "you're incapacitated!") - return + return CLICK_ACTION_BLOCKING if(living_user.usable_hands <= 0) source.balloon_alert(user, "you don't have hands!") - return + return CLICK_ACTION_BLOCKING do_icon_toggle(source, living_user) + return CLICK_ACTION_SUCCESS /* * Signal proc for COMSIG_ATOM_EXAMINE. diff --git a/code/datums/storage/storage.dm b/code/datums/storage/storage.dm index 87398f52555..b1bacfbceab 100644 --- a/code/datums/storage/storage.dm +++ b/code/datums/storage/storage.dm @@ -916,7 +916,8 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) SIGNAL_HANDLER INVOKE_ASYNC(src, PROC_REF(open_storage), to_show) - return COMPONENT_NO_AFTERATTACK + if(display_contents) + return COMPONENT_NO_AFTERATTACK /// Opens the storage to the mob, showing them the contents to their UI. /datum/storage/proc/open_storage(mob/to_show) diff --git a/code/game/atom/_atom.dm b/code/game/atom/_atom.dm index 976e2e0e005..46b4a1c391f 100644 --- a/code/game/atom/_atom.dm +++ b/code/game/atom/_atom.dm @@ -136,6 +136,9 @@ ///whether ghosts can see screentips on it var/ghost_screentips = FALSE + /// Flags to check for in can_perform_action. Used in alt-click checks + var/interaction_flags_click = NONE + /** * Top level of the destroy chain for most atoms * diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index 4fbfe2d37bf..1bdcba84967 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -388,15 +388,15 @@ drop_direction = direction balloon_alert(usr, "dropping [dir2text(drop_direction)]") -/obj/machinery/autolathe/AltClick(mob/user) - . = ..() - if(!drop_direction || !can_interact(user)) - return +/obj/machinery/autolathe/click_alt(mob/user) + if(!drop_direction) + return CLICK_ACTION_BLOCKING if(busy) balloon_alert(user, "busy printing!") - return + return CLICK_ACTION_SUCCESS balloon_alert(user, "drop direction reset") drop_direction = 0 + return CLICK_ACTION_SUCCESS /obj/machinery/autolathe/attackby(obj/item/attacking_item, mob/living/user, params) if(user.combat_mode) //so we can hit the machine diff --git a/code/game/machinery/civilian_bounties.dm b/code/game/machinery/civilian_bounties.dm index d2a584a1675..1cb7ee1477e 100644 --- a/code/game/machinery/civilian_bounties.dm +++ b/code/game/machinery/civilian_bounties.dm @@ -163,11 +163,9 @@ inserted_scan_id.registered_account.bounties = null return inserted_scan_id.registered_account.civilian_bounty -/obj/machinery/computer/piratepad_control/civilian/AltClick(mob/user) - . = ..() - if(!Adjacent(user)) - return FALSE +/obj/machinery/computer/piratepad_control/civilian/click_alt(mob/user) id_eject(user, inserted_scan_id) + return CLICK_ACTION_SUCCESS /obj/machinery/computer/piratepad_control/civilian/ui_data(mob/user) var/list/data = list() diff --git a/code/game/machinery/computer/_computer.dm b/code/game/machinery/computer/_computer.dm index 1592bb010c3..9d746bfa32c 100644 --- a/code/game/machinery/computer/_computer.dm +++ b/code/game/machinery/computer/_computer.dm @@ -128,12 +128,6 @@ new_frame.state = FRAME_COMPUTER_STATE_GLASSED new_frame.update_appearance(UPDATE_ICON_STATE) -/obj/machinery/computer/AltClick(mob/user) - . = ..() - if(!can_interact(user)) - return - if(!user.can_perform_action(src, ALLOW_SILICON_REACH) || !is_operational) - return /obj/machinery/computer/ui_interact(mob/user, datum/tgui/ui) SHOULD_CALL_PARENT(TRUE) diff --git a/code/game/machinery/computer/dna_console.dm b/code/game/machinery/computer/dna_console.dm index f37c7a8478a..f0d7b2e30eb 100644 --- a/code/game/machinery/computer/dna_console.dm +++ b/code/game/machinery/computer/dna_console.dm @@ -54,7 +54,7 @@ icon_keyboard = "med_key" density = TRUE circuit = /obj/item/circuitboard/computer/scan_consolenew - + interaction_flags_click = ALLOW_SILICON_REACH light_color = LIGHT_COLOR_BLUE /// Link to the techweb's stored research. Used to retrieve stored mutations @@ -210,15 +210,9 @@ stored_research = tool.buffer return TRUE -/obj/machinery/computer/scan_consolenew/AltClick(mob/user) - // Make sure the user can interact with the machine. - . = ..() - if(!can_interact(user)) - return - if(!user.can_perform_action(src, ALLOW_SILICON_REACH)) - return - +/obj/machinery/computer/scan_consolenew/click_alt(mob/user) eject_disk(user) + return CLICK_ACTION_SUCCESS /obj/machinery/computer/scan_consolenew/Initialize(mapload) . = ..() diff --git a/code/game/machinery/computer/prisoner/_prisoner.dm b/code/game/machinery/computer/prisoner/_prisoner.dm index f1ce2555936..9777c1b209c 100644 --- a/code/game/machinery/computer/prisoner/_prisoner.dm +++ b/code/game/machinery/computer/prisoner/_prisoner.dm @@ -2,6 +2,7 @@ interaction_flags_machine = INTERACT_MACHINE_ALLOW_SILICON|INTERACT_MACHINE_REQUIRES_LITERACY /// ID card currently inserted into the computer. VAR_FINAL/obj/item/card/id/advanced/prisoner/contained_id + interaction_flags_click = ALLOW_SILICON_REACH /obj/machinery/computer/prisoner/on_deconstruction(disassembled) contained_id?.forceMove(drop_location()) @@ -20,10 +21,9 @@ if(contained_id) . += span_notice("Alt-click to eject the ID card.") -/obj/machinery/computer/prisoner/AltClick(mob/user) - . = ..() - if(user.can_perform_action(src, ALLOW_SILICON_REACH)) - id_eject(user) +/obj/machinery/computer/prisoner/click_alt(mob/user) + id_eject(user) + return CLICK_ACTION_SUCCESS /obj/machinery/computer/prisoner/proc/id_insert(mob/user, obj/item/card/id/advanced/prisoner/new_id) if(!istype(new_id)) diff --git a/code/game/machinery/defibrillator_mount.dm b/code/game/machinery/defibrillator_mount.dm index c067fcfef0b..207a3f753ef 100644 --- a/code/game/machinery/defibrillator_mount.dm +++ b/code/game/machinery/defibrillator_mount.dm @@ -157,15 +157,13 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/defibrillator_mount, 28) to_chat(user, span_notice("You remove [src] from the wall.")) return TRUE -/obj/machinery/defibrillator_mount/AltClick(mob/living/carbon/user) - if(!istype(user) || !user.can_perform_action(src)) - return +/obj/machinery/defibrillator_mount/click_alt(mob/living/carbon/user) if(!defib) to_chat(user, span_warning("It'd be hard to remove a defib unit from a mount that has none.")) - return + return CLICK_ACTION_BLOCKING if(clamps_locked) to_chat(user, span_warning("You try to tug out [defib], but the mount's clamps are locked tight!")) - return + return CLICK_ACTION_BLOCKING if(!user.put_in_hands(defib)) to_chat(user, span_warning("You need a free hand!")) user.visible_message(span_notice("[user] unhooks [defib] from [src], dropping it on the floor."), \ @@ -174,6 +172,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/defibrillator_mount, 28) user.visible_message(span_notice("[user] unhooks [defib] from [src]."), \ span_notice("You slide out [defib] from [src] and unhook the charging cables.")) playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE) + return CLICK_ACTION_SUCCESS /obj/machinery/defibrillator_mount/charging name = "PENLITE defibrillator mount" diff --git a/code/game/machinery/deployable.dm b/code/game/machinery/deployable.dm index 04b4db6f72d..4f78fbf3a52 100644 --- a/code/game/machinery/deployable.dm +++ b/code/game/machinery/deployable.dm @@ -180,10 +180,9 @@ . = ..() . += span_notice("Alt-click to toggle modes.") -/obj/item/grenade/barrier/AltClick(mob/living/carbon/user) - if(!istype(user) || !user.can_perform_action(src)) - return +/obj/item/grenade/barrier/click_alt(mob/living/carbon/user) toggle_mode(user) + return CLICK_ACTION_SUCCESS /obj/item/grenade/barrier/proc/toggle_mode(mob/user) switch(mode) diff --git a/code/game/machinery/dish_drive.dm b/code/game/machinery/dish_drive.dm index 1b21d812dc0..b386ebb376f 100644 --- a/code/game/machinery/dish_drive.dm +++ b/code/game/machinery/dish_drive.dm @@ -9,6 +9,7 @@ density = FALSE circuit = /obj/item/circuitboard/machine/dish_drive pass_flags = PASSTABLE + interaction_flags_click = ALLOW_SILICON_REACH /// List of dishes the drive can hold var/static/list/collectable_items = list( /obj/item/trash/waffles, @@ -141,9 +142,9 @@ balloon_alert(user, "disposal signal sent") do_the_dishes(TRUE) -/obj/machinery/dish_drive/AltClick(mob/living/user) - if(user.can_perform_action(src, ALLOW_SILICON_REACH)) - do_the_dishes(TRUE) +/obj/machinery/dish_drive/click_alt(mob/living/user) + do_the_dishes(TRUE) + return CLICK_ACTION_SUCCESS /obj/machinery/dish_drive/proc/do_the_dishes(manual) if(!LAZYLEN(dish_drive_contents)) diff --git a/code/game/machinery/dna_infuser/dna_infuser.dm b/code/game/machinery/dna_infuser/dna_infuser.dm index 8275eb1e948..6c239089f5d 100644 --- a/code/game/machinery/dna_infuser/dna_infuser.dm +++ b/code/game/machinery/dna_infuser/dna_infuser.dm @@ -288,17 +288,17 @@ return FALSE return TRUE -/obj/machinery/dna_infuser/AltClick(mob/user) - . = ..() +/obj/machinery/dna_infuser/click_alt(mob/user) if(infusing) balloon_alert(user, "not while it's on!") - return + return CLICK_ACTION_BLOCKING if(!infusing_from) balloon_alert(user, "no sample to eject!") - return + return CLICK_ACTION_BLOCKING balloon_alert(user, "ejected sample") infusing_from.forceMove(get_turf(src)) infusing_from = null + return CLICK_ACTION_SUCCESS #undef INFUSING_TIME #undef SCREAM_TIME diff --git a/code/game/machinery/fat_sucker.dm b/code/game/machinery/fat_sucker.dm index 4567959b844..c93a0e4f7ea 100644 --- a/code/game/machinery/fat_sucker.dm +++ b/code/game/machinery/fat_sucker.dm @@ -98,17 +98,16 @@ else to_chat(user, span_warning("The safety hatch has been disabled!")) -/obj/machinery/fat_sucker/AltClick(mob/living/user) - if(!user.can_perform_action(src)) - return +/obj/machinery/fat_sucker/click_alt(mob/living/user) if(user == occupant) to_chat(user, span_warning("You can't reach the controls from inside!")) - return + return CLICK_ACTION_BLOCKING if(!(obj_flags & EMAGGED) && !allowed(user)) to_chat(user, span_warning("You lack the required access.")) - return + return CLICK_ACTION_BLOCKING free_exit = !free_exit to_chat(user, span_notice("Safety hatch [free_exit ? "unlocked" : "locked"].")) + return CLICK_ACTION_SUCCESS /obj/machinery/fat_sucker/update_overlays() . = ..() diff --git a/code/game/machinery/harvester.dm b/code/game/machinery/harvester.dm index 09599b0cbff..5fa999a690e 100644 --- a/code/game/machinery/harvester.dm +++ b/code/game/machinery/harvester.dm @@ -57,20 +57,16 @@ else if(!harvesting) open_machine() -/obj/machinery/harvester/AltClick(mob/user) - . = ..() - if(!user.can_perform_action(src)) - return +/obj/machinery/harvester/click_alt(mob/user) if(panel_open) output_dir = turn(output_dir, -90) to_chat(user, span_notice("You change [src]'s output settings, setting the output to [dir2text(output_dir)].")) - return - if(!can_interact(user)) - return - if(harvesting || !user || !isliving(user) || state_open) - return - if(can_harvest()) - start_harvest() + return CLICK_ACTION_SUCCESS + if(harvesting || state_open || !can_harvest()) + return CLICK_ACTION_BLOCKING + + start_harvest() + return CLICK_ACTION_SUCCESS /obj/machinery/harvester/proc/can_harvest() if(!powered() || state_open || !occupant || !iscarbon(occupant)) diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm index 6244dcdd2db..91104abf681 100644 --- a/code/game/machinery/iv_drip.dm +++ b/code/game/machinery/iv_drip.dm @@ -207,15 +207,10 @@ else return ..() -/// Checks whether the IV drip transfer rate can be modified with AltClick -/obj/machinery/iv_drip/proc/can_use_alt_click(mob/user) - if(!can_interact(user)) - return FALSE -/obj/machinery/iv_drip/AltClick(mob/user) - if(!can_use_alt_click(user)) - return ..() +/obj/machinery/iv_drip/click_alt(mob/user) set_transfer_rate(transfer_rate > MIN_IV_TRANSFER_RATE ? MIN_IV_TRANSFER_RATE : MAX_IV_TRANSFER_RATE) + return CLICK_ACTION_SUCCESS /obj/machinery/iv_drip/on_deconstruction(disassembled = TRUE) new /obj/item/stack/sheet/iron(loc) diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm index d9e3787fd9e..9e926d9a841 100644 --- a/code/game/machinery/pipe/construction.dm +++ b/code/game/machinery/pipe/construction.dm @@ -394,8 +394,6 @@ Buildable meters balloon_alert(user, "pipe layer set to [piping_layer]") return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN -/obj/item/pipe/AltClick(mob/user) - return ..() // This hotkey is BLACKLISTED since it's used by /datum/component/simple_rotation /obj/item/pipe/trinary/flippable/examine(mob/user) . = ..() diff --git a/code/game/machinery/sleepers.dm b/code/game/machinery/sleepers.dm index f768381548a..33e255badb2 100644 --- a/code/game/machinery/sleepers.dm +++ b/code/game/machinery/sleepers.dm @@ -164,14 +164,12 @@ ui = new(user, src, "Sleeper", name) ui.open() -/obj/machinery/sleeper/AltClick(mob/user) - . = ..() - if(!user.can_perform_action(src, ALLOW_SILICON_REACH)) - return +/obj/machinery/sleeper/click_alt(mob/user) if(state_open) close_machine() else open_machine() + return CLICK_ACTION_SUCCESS /obj/machinery/sleeper/examine(mob/user) . = ..() diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm index 58ef3d8bbef..0ddebbf3ee3 100644 --- a/code/game/machinery/spaceheater.dm +++ b/code/game/machinery/spaceheater.dm @@ -16,6 +16,7 @@ max_integrity = 250 armor_type = /datum/armor/machinery_space_heater circuit = /obj/item/circuitboard/machine/space_heater + interaction_flags_click = ALLOW_SILICON_REACH //We don't use area power, we always use the cell use_power = NO_POWER_USE ///The cell we spawn with @@ -308,6 +309,7 @@ panel_open = TRUE //This is always open - since we've injected wires in the panel //We inherit the cell from the heater prior cell = null + interaction_flags_click = FORBID_TELEKINESIS_REACH ///The beaker within the heater var/obj/item/reagent_containers/beaker = null ///How powerful the heating is, upgrades with parts. (ala chem_heater.dm's method, basically the same level of heating, but this is restricted) @@ -440,11 +442,9 @@ update_appearance() return TRUE -/obj/machinery/space_heater/improvised_chem_heater/AltClick(mob/living/user) - . = ..() - if(!can_interact(user) || !user.can_perform_action(src, FORBID_TELEKINESIS_REACH)) - return +/obj/machinery/space_heater/improvised_chem_heater/click_alt(mob/living/user) replace_beaker(user) + return CLICK_ACTION_SUCCESS /obj/machinery/space_heater/improvised_chem_heater/update_icon_state() . = ..() diff --git a/code/game/machinery/stasis.dm b/code/game/machinery/stasis.dm index a8d4d62544b..9ef3d8e3a99 100644 --- a/code/game/machinery/stasis.dm +++ b/code/game/machinery/stasis.dm @@ -12,6 +12,7 @@ circuit = /obj/item/circuitboard/machine/stasis fair_market_price = 10 payment_department = ACCOUNT_MED + interaction_flags_click = ALLOW_SILICON_REACH var/stasis_enabled = TRUE var/last_stasis_sound = FALSE var/stasis_can_toggle = 0 @@ -36,19 +37,18 @@ playsound(src, 'sound/machines/synth_no.ogg', 50, TRUE, frequency = sound_freq) last_stasis_sound = _running -/obj/machinery/stasis/AltClick(mob/user) - . = ..() - if(!can_interact(user)) - return - if(world.time >= stasis_can_toggle && user.can_perform_action(src, ALLOW_SILICON_REACH)) - stasis_enabled = !stasis_enabled - stasis_can_toggle = world.time + STASIS_TOGGLE_COOLDOWN - playsound(src, 'sound/machines/click.ogg', 60, TRUE) - user.visible_message(span_notice("\The [src] [stasis_enabled ? "powers on" : "shuts down"]."), \ - span_notice("You [stasis_enabled ? "power on" : "shut down"] \the [src]."), \ - span_hear("You hear a nearby machine [stasis_enabled ? "power on" : "shut down"].")) - play_power_sound() - update_appearance() +/obj/machinery/stasis/click_alt(mob/user) + if(world.time < stasis_can_toggle) + return CLICK_ACTION_BLOCKING + stasis_enabled = !stasis_enabled + stasis_can_toggle = world.time + STASIS_TOGGLE_COOLDOWN + playsound(src, 'sound/machines/click.ogg', 60, TRUE) + user.visible_message(span_notice("\The [src] [stasis_enabled ? "powers on" : "shuts down"]."), \ + span_notice("You [stasis_enabled ? "power on" : "shut down"] \the [src]."), \ + span_hear("You hear a nearby machine [stasis_enabled ? "power on" : "shut down"].")) + play_power_sound() + update_appearance() + return CLICK_ACTION_SUCCESS /obj/machinery/stasis/Exited(atom/movable/gone, direction) if(gone == occupant) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 0abe9312a5f..af6b2fe48b7 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -221,6 +221,11 @@ /// A lazylist used for applying fantasy values, contains the actual modification applied to a variable. var/list/fantasy_modifications = null + /// Has the item been reskinned? + var/current_skin + ///// List of options to reskin. + var/list/unique_reskin + /obj/item/Initialize(mapload) if(attack_verb_continuous) attack_verb_continuous = string_list(attack_verb_continuous) @@ -257,6 +262,11 @@ if(LAZYLEN(embedding)) updateEmbedding() + if(unique_reskin) + RegisterSignal(src, COMSIG_CLICK_ALT, PROC_REF(on_click_alt_reskin)) + register_context() + + /obj/item/Destroy(force) // This var exists as a weird proxy "owner" ref // It's used in a few places. Stop using it, and optimially replace all uses please @@ -271,6 +281,20 @@ return ..() + +/obj/item/add_context(atom/source, list/context, obj/item/held_item, mob/user) + . = ..() + + if(!unique_reskin) + return + + if(current_skin && !(item_flags & INFINITE_RESKIN)) + return + + context[SCREENTIP_CONTEXT_ALT_LMB] = "Reskin" + return CONTEXTUAL_SCREENTIP_SET + + /// Called when an action associated with our item is deleted /obj/item/proc/on_action_deleted(datum/source) SIGNAL_HANDLER diff --git a/code/game/objects/items/airlock_painter.dm b/code/game/objects/items/airlock_painter.dm index 6a6fc5fc51c..6d5a8340a3f 100644 --- a/code/game/objects/items/airlock_painter.dm +++ b/code/game/objects/items/airlock_painter.dm @@ -147,14 +147,16 @@ else return ..() -/obj/item/airlock_painter/AltClick(mob/user) - . = ..() - if(ink && user.can_perform_action(src)) - playsound(src.loc, 'sound/machines/click.ogg', 50, TRUE) - ink.forceMove(user.drop_location()) - user.put_in_hands(ink) - to_chat(user, span_notice("You remove [ink] from [src].")) - ink = null +/obj/item/airlock_painter/click_alt(mob/user) + if(!ink) + return CLICK_ACTION_BLOCKING + + playsound(src.loc, 'sound/machines/click.ogg', 50, TRUE) + ink.forceMove(user.drop_location()) + user.put_in_hands(ink) + to_chat(user, span_notice("You remove [ink] from [src].")) + ink = null + return CLICK_ACTION_SUCCESS /obj/item/airlock_painter/decal name = "decal painter" diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm index b0502c34144..c3621cd3329 100644 --- a/code/game/objects/items/cards_ids.dm +++ b/code/game/objects/items/cards_ids.dm @@ -666,44 +666,45 @@ to_chat(user, span_notice("The provided account has been linked to this ID card. It contains [account.account_balance] credits.")) return TRUE -/obj/item/card/id/AltClick(mob/living/user) +/obj/item/card/id/click_alt(mob/living/user) if(!alt_click_can_use_id(user)) - return + return NONE if(registered_account.account_debt) var/choice = tgui_alert(user, "Choose An Action", "Bank Account", list("Withdraw", "Pay Debt")) if(!choice || QDELETED(user) || QDELETED(src) || !alt_click_can_use_id(user) || loc != user) - return + return CLICK_ACTION_BLOCKING if(choice == "Pay Debt") pay_debt(user) - return + return CLICK_ACTION_SUCCESS if (registered_account.being_dumped) registered_account.bank_card_talk(span_warning("内部服务器错误"), TRUE) - return + return CLICK_ACTION_SUCCESS if(loc != user) to_chat(user, span_warning("You must be holding the ID to continue!")) - return + return CLICK_ACTION_BLOCKING if(registered_account.replaceable && !registered_account.account_balance) var/choice = tgui_alert(user, "This card's account is unassigned. Would you like to link a bank account?", "Bank Account", list("Link Account", "Leave Unassigned")) if(!choice || QDELETED(user) || QDELETED(src) || !alt_click_can_use_id(user) || loc != user) - return + return CLICK_ACTION_BLOCKING if(choice == "Link Account") set_new_account(user) - return + return CLICK_ACTION_SUCCESS var/amount_to_remove = tgui_input_number(user, "How much do you want to withdraw? (Max: [registered_account.account_balance] cr)", "Withdraw Funds", max_value = registered_account.account_balance) if(!amount_to_remove || QDELETED(user) || QDELETED(src) || issilicon(user) || loc != user) - return + return CLICK_ACTION_BLOCKING if(!alt_click_can_use_id(user)) - return + return CLICK_ACTION_BLOCKING if(registered_account.adjust_money(-amount_to_remove, "System: Withdrawal")) var/obj/item/holochip/holochip = new (user.drop_location(), amount_to_remove) user.put_in_hands(holochip) to_chat(user, span_notice("You withdraw [amount_to_remove] credits into a holochip.")) SSblackbox.record_feedback("amount", "credits_removed", amount_to_remove) log_econ("[amount_to_remove] credits were removed from [src] owned by [src.registered_name]") - return + return CLICK_ACTION_SUCCESS else var/difference = amount_to_remove - registered_account.account_balance registered_account.bank_card_talk(span_warning("ERROR: The linked account requires [difference] more credit\s to perform that withdrawal."), TRUE) + return CLICK_ACTION_BLOCKING /obj/item/card/id/alt_click_secondary(mob/user) . = ..() @@ -918,8 +919,9 @@ department_name = ACCOUNT_CAR_NAME icon_state = "car_budget" //saving up for a new tesla -/obj/item/card/id/departmental_budget/AltClick(mob/living/user) +/obj/item/card/id/departmental_budget/click_alt(mob/living/user) registered_account.bank_card_talk(span_warning("Withdrawing is not compatible with this card design."), TRUE) //prevents the vault bank machine being useless and putting money from the budget to your card to go over personal crates + return CLICK_ACTION_BLOCKING /obj/item/card/id/advanced name = "identification card" diff --git a/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm index addfbc233ef..ace68943246 100644 --- a/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm +++ b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm @@ -1227,11 +1227,10 @@ suction = !suction to_chat(user, span_notice("You [suction ? "enable" : "disable"] the board's suction function.")) -/obj/item/circuitboard/machine/dish_drive/AltClick(mob/living/user) - if(!user.Adjacent(src)) - return +/obj/item/circuitboard/machine/dish_drive/click_alt(mob/living/user) transmit = !transmit to_chat(user, span_notice("You [transmit ? "enable" : "disable"] the board's automatic disposal transmission.")) + return CLICK_ACTION_SUCCESS /obj/item/circuitboard/machine/gibber name = "Gibber" diff --git a/code/game/objects/items/cosmetics.dm b/code/game/objects/items/cosmetics.dm index 12d71db1d5a..a78d9d4fbf0 100644 --- a/code/game/objects/items/cosmetics.dm +++ b/code/game/objects/items/cosmetics.dm @@ -10,6 +10,7 @@ icon_state = "lipstick" inhand_icon_state = "lipstick" w_class = WEIGHT_CLASS_TINY + interaction_flags_click = NEED_DEXTERITY|NEED_HANDS|ALLOW_RESTING var/open = FALSE /// Actual color of the lipstick, also gets applied to the human var/lipstick_color = COLOR_RED @@ -45,15 +46,9 @@ colored_overlay.color = lipstick_color . += colored_overlay -/obj/item/lipstick/AltClick(mob/user) - . = ..() - if(.) - return TRUE - - if(!user.can_perform_action(src, NEED_DEXTERITY|NEED_HANDS|ALLOW_RESTING)) - return FALSE - - return display_radial_menu(user) +/obj/item/lipstick/click_alt(mob/user) + display_radial_menu(user) + return CLICK_ACTION_SUCCESS /obj/item/lipstick/proc/display_radial_menu(mob/living/carbon/human/user) var/style_options = list( diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm index ae0dca8d195..4cb077808a8 100644 --- a/code/game/objects/items/crayons.dm +++ b/code/game/objects/items/crayons.dm @@ -759,6 +759,7 @@ pre_noise = TRUE post_noise = FALSE + interaction_flags_click = NEED_DEXTERITY|NEED_HANDS /obj/item/toy/crayon/spraycan/Initialize(mapload) . = ..() @@ -960,12 +961,13 @@ return SECONDARY_ATTACK_CONTINUE_CHAIN -/obj/item/toy/crayon/spraycan/AltClick(mob/user) - if(!has_cap || !user.can_perform_action(src, NEED_DEXTERITY|NEED_HANDS)) - return +/obj/item/toy/crayon/spraycan/click_alt(mob/user) + if(!has_cap) + return CLICK_ACTION_BLOCKING is_capped = !is_capped balloon_alert(user, is_capped ? "capped" : "cap removed") update_appearance() + return CLICK_ACTION_SUCCESS /obj/item/toy/crayon/spraycan/attackby_storage_insert(datum/storage, atom/storage_holder, mob/user) return is_capped diff --git a/code/game/objects/items/credit_holochip.dm b/code/game/objects/items/credit_holochip.dm index 83e6165b91d..c9b6fe4a134 100644 --- a/code/game/objects/items/credit_holochip.dm +++ b/code/game/objects/items/credit_holochip.dm @@ -7,6 +7,8 @@ throwforce = 0 force = 0 w_class = WEIGHT_CLASS_TINY + interaction_flags_click = NEED_DEXTERITY|FORBID_TELEKINESIS_REACH + /// Amount on money on the card var/credits = 0 /obj/item/holochip/Initialize(mapload, amount = 1) @@ -101,23 +103,21 @@ update_appearance() qdel(H) -/obj/item/holochip/AltClick(mob/user) - if(!user.can_perform_action(src, NEED_DEXTERITY|FORBID_TELEKINESIS_REACH)) - return +/obj/item/holochip/click_alt(mob/user) if(loc != user) to_chat(user, span_warning("You must be holding the holochip to continue!")) - return FALSE + return CLICK_ACTION_BLOCKING var/split_amount = tgui_input_number(user, "How many credits do you want to extract from the holochip? (Max: [credits] cr)", "Holochip", max_value = credits) if(!split_amount || QDELETED(user) || QDELETED(src) || issilicon(user) || !usr.can_perform_action(src, NEED_DEXTERITY|FORBID_TELEKINESIS_REACH) || loc != user) - return + return CLICK_ACTION_BLOCKING var/new_credits = spend(split_amount, TRUE) - var/obj/item/holochip/H = new(user ? user : drop_location(), new_credits) + var/obj/item/holochip/chip = new(user ? user : drop_location(), new_credits) if(user) - if(!user.put_in_hands(H)) - H.forceMove(user.drop_location()) + if(!user.put_in_hands(chip)) + chip.forceMove(user.drop_location()) add_fingerprint(user) - H.add_fingerprint(user) to_chat(user, span_notice("You extract [split_amount] credits into a new holochip.")) + return CLICK_ACTION_SUCCESS /obj/item/holochip/emp_act(severity) . = ..() diff --git a/code/game/objects/items/devices/desynchronizer.dm b/code/game/objects/items/devices/desynchronizer.dm index 0d9791c890a..c3e69a0103c 100644 --- a/code/game/objects/items/devices/desynchronizer.dm +++ b/code/game/objects/items/devices/desynchronizer.dm @@ -9,11 +9,18 @@ lefthand_file = 'icons/mob/inhands/items/devices_lefthand.dmi' righthand_file = 'icons/mob/inhands/items/devices_righthand.dmi' custom_materials = list(/datum/material/iron= SMALL_MATERIAL_AMOUNT * 2.5, /datum/material/glass= SMALL_MATERIAL_AMOUNT * 5) - var/max_duration = 3000 - var/duration = 300 + interaction_flags_click = NEED_DEXTERITY + /// Max time this can be set + var/max_duration = 300 SECONDS + /// Currently set time + var/duration = 30 SECONDS + /// Last world time var/last_use = 0 + /// world.time + (world.time - last_use) var/next_use = 0 + /// The current space time rift var/obj/effect/abstract/sync_holder/sync_holder + /// Timer obj for calling resync var/resync_timer /obj/item/desynchronizer/attack_self(mob/living/user) @@ -32,14 +39,13 @@ . += span_notice("Alt-click to customize the duration. Current duration: [DisplayTimeText(duration)].") . += span_notice("Can be used again to interrupt the effect early. The recharge time is the same as the time spent in desync.") -/obj/item/desynchronizer/AltClick(mob/living/user) - if(!user.can_perform_action(src, NEED_DEXTERITY)) - return +/obj/item/desynchronizer/click_alt(mob/living/user) var/new_duration = tgui_input_number(user, "Set the duration", "Desynchronizer", duration / 10, max_duration, 5) if(!new_duration || QDELETED(user) || QDELETED(src) || !usr.can_perform_action(src, NEED_DEXTERITY)) - return + return CLICK_ACTION_BLOCKING duration = new_duration to_chat(user, span_notice("You set the duration to [DisplayTimeText(duration)].")) + return CLICK_ACTION_SUCCESS /obj/item/desynchronizer/proc/desync(mob/living/user) if(sync_holder) diff --git a/code/game/objects/items/devices/geiger_counter.dm b/code/game/objects/items/devices/geiger_counter.dm index 6e152c33661..db2d0d820ba 100644 --- a/code/game/objects/items/devices/geiger_counter.dm +++ b/code/game/objects/items/devices/geiger_counter.dm @@ -110,12 +110,11 @@ to_chat(user, span_notice("[icon2html(src, user)] [isliving(target) ? "Subject" : "Target"] is free of radioactive contamination.")) -/obj/item/geiger_counter/AltClick(mob/living/user) - if(!istype(user) || !user.can_perform_action(src)) - return ..() +/obj/item/geiger_counter/click_alt(mob/living/user) if(!scanning) to_chat(usr, span_warning("[src] must be on to reset its radiation level!")) - return + return CLICK_ACTION_BLOCKING to_chat(usr, span_notice("You flush [src]'s radiation counts, resetting it to normal.")) last_perceived_radiation_danger = null update_appearance(UPDATE_ICON) + return CLICK_ACTION_SUCCESS diff --git a/code/game/objects/items/devices/quantum_keycard.dm b/code/game/objects/items/devices/quantum_keycard.dm index abffdcca4d5..34b83a62092 100644 --- a/code/game/objects/items/devices/quantum_keycard.dm +++ b/code/game/objects/items/devices/quantum_keycard.dm @@ -10,6 +10,8 @@ righthand_file = 'icons/mob/inhands/equipment/idcards_righthand.dmi' w_class = WEIGHT_CLASS_TINY obj_flags = UNIQUE_RENAME + interaction_flags_click = NEED_DEXTERITY + /// The linked quantum pad var/obj/machinery/quantumpad/qpad /// where the pad is located and what color the card will become @@ -40,13 +42,12 @@ else . += span_notice("Insert [src] into an active quantum pad to link it.") -/obj/item/quantum_keycard/AltClick(mob/living/user) - if(!istype(user) || !user.can_perform_action(src, NEED_DEXTERITY)) - return +/obj/item/quantum_keycard/click_alt(mob/living/user) to_chat(user, span_notice("You start pressing [src]'s unlink button...")) if(do_after(user, 4 SECONDS, target = src)) to_chat(user, span_notice("The keycard beeps twice and disconnects the quantum link.")) set_pad() + return CLICK_ACTION_SUCCESS /obj/item/quantum_keycard/proc/set_pad(obj/machinery/quantumpad/new_pad) qpad = new_pad diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm index 310df72dbda..ae806b594e1 100644 --- a/code/game/objects/items/devices/radio/headset.dm +++ b/code/game/objects/items/devices/radio/headset.dm @@ -447,9 +447,9 @@ GLOBAL_LIST_INIT(channel_tokens, list( // And grant all the languages we definitely should know now grant_headset_languages(mob_loc) -/obj/item/radio/headset/AltClick(mob/living/user) - if(!istype(user) || !Adjacent(user) || user.incapacitated()) - return - if (command) - use_command = !use_command - to_chat(user, span_notice("You toggle high-volume mode [use_command ? "on" : "off"].")) +/obj/item/radio/headset/click_alt(mob/living/user) + if (!command) + return CLICK_ACTION_BLOCKING + use_command = !use_command + to_chat(user, span_notice("You toggle high-volume mode [use_command ? "on" : "off"].")) + return CLICK_ACTION_SUCCESS diff --git a/code/game/objects/items/devices/scanners/gas_analyzer.dm b/code/game/objects/items/devices/scanners/gas_analyzer.dm index cd57bd24a7e..ba4fc6c145f 100644 --- a/code/game/objects/items/devices/scanners/gas_analyzer.dm +++ b/code/game/objects/items/devices/scanners/gas_analyzer.dm @@ -17,10 +17,16 @@ tool_behaviour = TOOL_ANALYZER custom_materials = list(/datum/material/iron=SMALL_MATERIAL_AMOUNT * 0.3, /datum/material/glass=SMALL_MATERIAL_AMOUNT * 0.2) grind_results = list(/datum/reagent/mercury = 5, /datum/reagent/iron = 5, /datum/reagent/silicon = 5) + interaction_flags_click = NEED_LITERACY|NEED_LIGHT + /// Boolean whether this has a CD var/cooldown = FALSE - var/cooldown_time = 250 - var/barometer_accuracy // 0 is the best accuracy. + /// The time in deciseconds + var/cooldown_time = 25 SECONDS + /// 0 is best accuracy + var/barometer_accuracy + /// Cached gasmix data from ui_interact var/list/last_gasmix_data + /// Max scan distance var/ranged_scan_distance = 1 /obj/item/analyzer/Initialize(mapload) @@ -53,19 +59,14 @@ user.visible_message(span_suicide("[user] begins to analyze [user.p_them()]self with [src]! The display shows that [user.p_theyre()] dead!")) return BRUTELOSS -/obj/item/analyzer/AltClick(mob/user) //Barometer output for measuring when the next storm happens - ..() - - if(!user.can_perform_action(src, NEED_LITERACY|NEED_LIGHT)) - return - +/obj/item/analyzer/click_alt(mob/user) //Barometer output for measuring when the next storm happens if(cooldown) to_chat(user, span_warning("[src]'s barometer function is preparing itself.")) - return + return CLICK_ACTION_BLOCKING var/turf/T = get_turf(user) if(!T) - return + return CLICK_ACTION_BLOCKING playsound(src, 'sound/effects/pop.ogg', 100) var/area/user_area = T.loc @@ -73,7 +74,7 @@ if(!user_area.outdoors) to_chat(user, span_warning("[src]'s barometer function won't work indoors!")) - return + return CLICK_ACTION_BLOCKING for(var/V in SSweather.processing) var/datum/weather/W = V @@ -84,7 +85,7 @@ if(ongoing_weather) if((ongoing_weather.stage == MAIN_STAGE) || (ongoing_weather.stage == WIND_DOWN_STAGE)) to_chat(user, span_warning("[src]'s barometer function can't trace anything while the storm is [ongoing_weather.stage == MAIN_STAGE ? "already here!" : "winding down."]")) - return + return CLICK_ACTION_BLOCKING to_chat(user, span_notice("The next [ongoing_weather] will hit in [butchertime(ongoing_weather.next_hit_time - world.time)].")) if(ongoing_weather.aesthetic) @@ -98,6 +99,7 @@ to_chat(user, span_warning("[src]'s barometer function says a storm will land in approximately [butchertime(fixed)].")) cooldown = TRUE addtimer(CALLBACK(src, TYPE_PROC_REF(/obj/item/analyzer, ping)), cooldown_time) + return CLICK_ACTION_SUCCESS /obj/item/analyzer/proc/ping() if(isliving(loc)) diff --git a/code/game/objects/items/devices/scanners/health_analyzer.dm b/code/game/objects/items/devices/scanners/health_analyzer.dm index 83ea668a9fb..bd0b94a1aff 100644 --- a/code/game/objects/items/devices/scanners/health_analyzer.dm +++ b/code/game/objects/items/devices/scanners/health_analyzer.dm @@ -20,8 +20,12 @@ throw_speed = 3 throw_range = 7 custom_materials = list(/datum/material/iron=SMALL_MATERIAL_AMOUNT *2) + interaction_flags_click = NEED_LITERACY|NEED_LIGHT + /// Verbose/condensed var/mode = SCANNER_VERBOSE + /// HEALTH/WOUND var/scanmode = SCANMODE_HEALTH + /// Advanced health analyzer var/advanced = FALSE custom_price = PAYCHECK_COMMAND /// If this analyzer will give a bonus to wound treatments apon woundscan. @@ -469,17 +473,13 @@ // we handled the last
so we don't need handholding to_chat(user, examine_block(jointext(render_list, "")), trailing_newline = FALSE, type = MESSAGE_TYPE_INFO) -/obj/item/healthanalyzer/AltClick(mob/user) - ..() - - if(!user.can_perform_action(src, NEED_LITERACY|NEED_LIGHT) || user.is_blind()) - return - +/obj/item/healthanalyzer/click_alt(mob/user) if(mode == SCANNER_NO_MODE) - return + return CLICK_ACTION_BLOCKING mode = !mode to_chat(user, mode == SCANNER_VERBOSE ? "The scanner now shows specific limb damage." : "The scanner no longer shows limb damage.") + return CLICK_ACTION_SUCCESS /obj/item/healthanalyzer/advanced name = "advanced health analyzer" diff --git a/code/game/objects/items/devices/swapper.dm b/code/game/objects/items/devices/swapper.dm index ea7d06f9596..e006ffb93c0 100644 --- a/code/game/objects/items/devices/swapper.dm +++ b/code/game/objects/items/devices/swapper.dm @@ -8,9 +8,12 @@ item_flags = NOBLUDGEON lefthand_file = 'icons/mob/inhands/items/devices_lefthand.dmi' righthand_file = 'icons/mob/inhands/items/devices_righthand.dmi' - - var/cooldown = 300 + interaction_flags_click = NEED_DEXTERITY + /// Cooldown for usage + var/cooldown = 30 SECONDS + /// Next available time var/next_use = 0 + /// Swapper linked to this obj var/obj/item/swapper/linked_swapper /obj/item/swapper/Destroy() @@ -66,15 +69,14 @@ else . += span_notice("Not Linked. Use on another quantum spin inverter to establish a quantum link.") -/obj/item/swapper/AltClick(mob/living/user) - if(!user.can_perform_action(src, NEED_DEXTERITY)) - return +/obj/item/swapper/click_alt(mob/living/user) to_chat(user, span_notice("You break the current quantum link.")) if(!QDELETED(linked_swapper)) linked_swapper.linked_swapper = null linked_swapper.update_appearance() linked_swapper = null update_appearance() + return CLICK_ACTION_SUCCESS //Gets the topmost teleportable container /obj/item/swapper/proc/get_teleportable_container() diff --git a/code/game/objects/items/devices/taperecorder.dm b/code/game/objects/items/devices/taperecorder.dm index c686eeb04a7..d30f379197e 100644 --- a/code/game/objects/items/devices/taperecorder.dm +++ b/code/game/objects/items/devices/taperecorder.dm @@ -61,11 +61,9 @@ . += span_notice("The wire panel is [open_panel ? "opened" : "closed"]. The display reads:") . += "[readout()]" -/obj/item/taperecorder/AltClick(mob/user) - . = ..() - if(!can_interact(user)) - return +/obj/item/taperecorder/click_alt(mob/user) play() + return CLICK_ACTION_SUCCESS /obj/item/taperecorder/proc/update_available_icons() icons_available = list() diff --git a/code/game/objects/items/etherealdiscoball.dm b/code/game/objects/items/etherealdiscoball.dm index 0a95e4bbc73..fe066bd1bf5 100644 --- a/code/game/objects/items/etherealdiscoball.dm +++ b/code/game/objects/items/etherealdiscoball.dm @@ -41,10 +41,10 @@ TurnOn() to_chat(user, span_notice("You turn the disco ball on!")) -/obj/structure/etherealball/AltClick(mob/living/carbon/human/user) - . = ..() +/obj/structure/etherealball/click_alt(mob/living/carbon/human/user) set_anchored(!anchored) to_chat(user, span_notice("You [anchored ? null : "un"]lock the disco ball.")) + return CLICK_ACTION_SUCCESS /obj/structure/etherealball/proc/TurnOn() TurnedOn = TRUE //Same diff --git a/code/game/objects/items/extinguisher.dm b/code/game/objects/items/extinguisher.dm index ca9c16ccc64..b3fe0572f9c 100644 --- a/code/game/objects/items/extinguisher.dm +++ b/code/game/objects/items/extinguisher.dm @@ -18,6 +18,7 @@ attack_verb_simple = list("slam", "whack", "bash", "thunk", "batter", "bludgeon", "thrash") dog_fashion = /datum/dog_fashion/back resistance_flags = FIRE_PROOF + interaction_flags_click = NEED_DEXTERITY|NEED_HANDS /// The max amount of water this extinguisher can hold. var/max_water = 50 /// Does the welder extinguisher start with water. @@ -270,13 +271,12 @@ if(1 to 3) source.delay = 3 -/obj/item/extinguisher/AltClick(mob/user) - if(!user.can_perform_action(src, NEED_DEXTERITY|NEED_HANDS)) - return +/obj/item/extinguisher/click_alt(mob/user) if(!user.is_holding(src)) to_chat(user, span_notice("You must be holding the [src] in your hands do this!")) - return + return CLICK_ACTION_BLOCKING EmptyExtinguisher(user) + return CLICK_ACTION_SUCCESS /obj/item/extinguisher/proc/EmptyExtinguisher(mob/user) if(loc == user && reagents.total_volume) diff --git a/code/game/objects/items/flamethrower.dm b/code/game/objects/items/flamethrower.dm index 587c172e2c0..d2f4b0cfc71 100644 --- a/code/game/objects/items/flamethrower.dm +++ b/code/game/objects/items/flamethrower.dm @@ -20,6 +20,7 @@ light_range = 2 light_power = 2 light_on = FALSE + interaction_flags_click = NEED_DEXTERITY|NEED_HANDS var/status = FALSE var/lit = FALSE //on or off var/operating = FALSE//cooldown @@ -158,12 +159,15 @@ /obj/item/flamethrower/attack_self(mob/user) toggle_igniter(user) -/obj/item/flamethrower/AltClick(mob/user) - if(ptank && isliving(user) && user.can_perform_action(src, NEED_DEXTERITY|NEED_HANDS)) - user.put_in_hands(ptank) - ptank = null - to_chat(user, span_notice("You remove the plasma tank from [src]!")) - update_appearance() +/obj/item/flamethrower/click_alt(mob/user) + if(isnull(ptank)) + return NONE + + user.put_in_hands(ptank) + ptank = null + to_chat(user, span_notice("You remove the plasma tank from [src]!")) + update_appearance() + return CLICK_ACTION_SUCCESS /obj/item/flamethrower/examine(mob/user) . = ..() diff --git a/code/game/objects/items/grenades/_grenade.dm b/code/game/objects/items/grenades/_grenade.dm index 86bb062b651..4c737ed53f3 100644 --- a/code/game/objects/items/grenades/_grenade.dm +++ b/code/game/objects/items/grenades/_grenade.dm @@ -53,7 +53,6 @@ /obj/item/grenade/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_ODD_CUSTOMIZABLE_FOOD_INGREDIENT, type) - ADD_TRAIT(src, TRAIT_ALT_CLICK_BLOCKER, REF(src)) RegisterSignal(src, COMSIG_ITEM_USED_AS_INGREDIENT, PROC_REF(on_used_as_ingredient)) /obj/item/grenade/suicide_act(mob/living/carbon/user) diff --git a/code/game/objects/items/implants/implantpad.dm b/code/game/objects/items/implants/implantpad.dm index ae09f8675b6..222bc1f6d4e 100644 --- a/code/game/objects/items/implants/implantpad.dm +++ b/code/game/objects/items/implants/implantpad.dm @@ -10,6 +10,7 @@ throw_speed = 3 throw_range = 5 w_class = WEIGHT_CLASS_SMALL + interaction_flags_click = FORBID_TELEKINESIS_REACH ///The implant case currently inserted into the pad. var/obj/item/implantcase/inserted_case @@ -46,11 +47,9 @@ update_static_data_for_all_viewers() update_appearance(UPDATE_ICON) -/obj/item/implantpad/AltClick(mob/user) - . = ..() - if(!user.can_perform_action(src, FORBID_TELEKINESIS_REACH)) - return +/obj/item/implantpad/click_alt(mob/user) remove_implant(user) + return CLICK_ACTION_SUCCESS /obj/item/implantpad/ui_interact(mob/user, datum/tgui/ui) ui = SStgui.try_update_ui(user, src, ui) diff --git a/code/game/objects/items/inspector.dm b/code/game/objects/items/inspector.dm index 2f25e53c1fb..f96c1beb573 100644 --- a/code/game/objects/items/inspector.dm +++ b/code/game/objects/items/inspector.dm @@ -372,15 +372,16 @@ */ /obj/item/paper/fake_report/water grind_results = list(/datum/reagent/water = 5) + interaction_flags_click = NEED_DEXTERITY|NEED_HANDS -/obj/item/paper/fake_report/water/AltClick(mob/living/user, obj/item/I) - if(!user.can_perform_action(src, NEED_DEXTERITY|NEED_HANDS)) - return +/obj/item/paper/fake_report/water/click_alt(mob/living/user) var/datum/action/innate/origami/origami_action = locate() in user.actions if(origami_action?.active) //Origami masters can fold water - make_plane(user, I, /obj/item/paperplane/syndicate) + make_plane(user, /obj/item/paperplane/syndicate) else if(do_after(user, 1 SECONDS, target = src, progress=TRUE)) var/turf/open/target = get_turf(src) target.MakeSlippery(TURF_WET_WATER, min_wet_time = 10 SECONDS, wet_time_to_add = 5 SECONDS) to_chat(user, span_notice("As you try to fold [src] into the shape of a plane, it disintegrates into water!")) qdel(src) + + return CLICK_ACTION_SUCCESS diff --git a/code/game/objects/items/machine_wand.dm b/code/game/objects/items/machine_wand.dm index 71ea2fae1b6..c1dd0bf382d 100644 --- a/code/game/objects/items/machine_wand.dm +++ b/code/game/objects/items/machine_wand.dm @@ -63,14 +63,15 @@ if(controlling_machine_or_bot) return controlling_machine_or_bot.ui_act(action, params, ui, state) -/obj/item/machine_remote/AltClick(mob/user) - . = ..() +/obj/item/machine_remote/click_alt(mob/user) if(moving_bug) //we have a bug in transit, so let's kill it. QDEL_NULL(moving_bug) + return CLICK_ACTION_BLOCKING if(!controlling_machine_or_bot) - return + return CLICK_ACTION_BLOCKING say("Remote control over [controlling_machine_or_bot] stopped.") remove_old_machine() + return CLICK_ACTION_SUCCESS /obj/item/machine_remote/afterattack(atom/target, mob/user, proximity_flag, click_parameters) . = ..() diff --git a/code/game/objects/items/pet_carrier.dm b/code/game/objects/items/pet_carrier.dm index 61c1a892c47..e30cdaf39df 100644 --- a/code/game/objects/items/pet_carrier.dm +++ b/code/game/objects/items/pet_carrier.dm @@ -66,9 +66,9 @@ open = TRUE update_appearance() -/obj/item/pet_carrier/AltClick(mob/living/user) - if(open || !user.can_perform_action(src)) - return +/obj/item/pet_carrier/click_alt(mob/living/user) + if(open) + return CLICK_ACTION_BLOCKING locked = !locked to_chat(user, span_notice("You flip the lock switch [locked ? "down" : "up"].")) if(locked) @@ -76,6 +76,7 @@ else playsound(user, 'sound/machines/boltsup.ogg', 30, TRUE) update_appearance() + return CLICK_ACTION_SUCCESS /obj/item/pet_carrier/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers) if(user.combat_mode || !isliving(interacting_with)) diff --git a/code/game/objects/items/pillow.dm b/code/game/objects/items/pillow.dm index 1dad0a7fba5..659cc38f58b 100644 --- a/code/game/objects/items/pillow.dm +++ b/code/game/objects/items/pillow.dm @@ -102,16 +102,15 @@ if(pillow_trophy) . += span_notice("Alt-click to remove the tag!") -/obj/item/pillow/AltClick(mob/user) - . = ..() - if(!can_interact(user) || !user.can_hold_items(src)) - return +/obj/item/pillow/click_alt(mob/user) + if(!user.can_hold_items(src)) + return CLICK_ACTION_BLOCKING if(!pillow_trophy) balloon_alert(user, "no tag!") - return + return CLICK_ACTION_BLOCKING balloon_alert(user, "removing tag...") if(!do_after(user, 2 SECONDS, src)) - return + return CLICK_ACTION_BLOCKING if(last_fighter) pillow_trophy.desc = "A pillow tag taken from [last_fighter] after a gruesome pillow fight." user.put_in_hands(pillow_trophy) @@ -119,6 +118,7 @@ balloon_alert(user, "tag removed") playsound(user,'sound/items/poster_ripped.ogg', 50) update_appearance() + return CLICK_ACTION_SUCCESS /obj/item/pillow/update_appearance(updates) . = ..() diff --git a/code/game/objects/items/rcd/RPLD.dm b/code/game/objects/items/rcd/RPLD.dm index de7e80cf190..192875694c1 100644 --- a/code/game/objects/items/rcd/RPLD.dm +++ b/code/game/objects/items/rcd/RPLD.dm @@ -275,8 +275,9 @@ create_machine(target, user) -/obj/item/construction/plumbing/AltClick(mob/user) +/obj/item/construction/plumbing/click_alt(mob/user) ui_interact(user) + return CLICK_ACTION_SUCCESS /obj/item/construction/plumbing/proc/mouse_wheeled(mob/source, atom/A, delta_x, delta_y, params) SIGNAL_HANDLER diff --git a/code/game/objects/items/rcd/RWD.dm b/code/game/objects/items/rcd/RWD.dm index a20946e322f..0ee29e87a35 100644 --- a/code/game/objects/items/rcd/RWD.dm +++ b/code/game/objects/items/rcd/RWD.dm @@ -125,8 +125,7 @@ add_cable(user, cable) return TRUE -/obj/item/rwd/AltClick(mob/user) - . = ..() +/obj/item/rwd/click_alt(mob/user) if(!radial_menu) radial_menu = list( "Layer 1" = image(icon = 'icons/hud/radial.dmi', icon_state = "coil-red"), @@ -136,7 +135,7 @@ var/layer_result = show_radial_menu(user, src, radial_menu, custom_check = CALLBACK(src, PROC_REF(check_menu), user), require_near = TRUE, tooltips = TRUE) if(!check_menu(user)) - return + return CLICK_ACTION_BLOCKING switch(layer_result) if("Layer 1") cable_layer = CABLE_LAYER_1 @@ -145,6 +144,7 @@ if("Layer 3") cable_layer = CABLE_LAYER_3 update_appearance(UPDATE_ICON_STATE) + return CLICK_ACTION_SUCCESS /obj/item/rwd/proc/check_menu(mob/living/user) if(!istype(user)) diff --git a/code/game/objects/items/robot/items/hypo.dm b/code/game/objects/items/robot/items/hypo.dm index f2383b799f2..052a6aa71e3 100644 --- a/code/game/objects/items/robot/items/hypo.dm +++ b/code/game/objects/items/robot/items/hypo.dm @@ -244,11 +244,9 @@ . += "Currently loaded: [selected_reagent ? "[selected_reagent]. [selected_reagent.description]" : "nothing."]" . += span_notice("Alt+Click to change transfer amount. Currently set to [amount_per_transfer_from_this]u.") -/obj/item/reagent_containers/borghypo/AltClick(mob/living/user) - . = ..() - if(user.stat == DEAD || user != loc) - return //IF YOU CAN HEAR ME SET MY TRANSFER AMOUNT TO 1 +/obj/item/reagent_containers/borghypo/click_alt(mob/living/user) change_transfer_amount(user) + return CLICK_ACTION_SUCCESS /// Default Medborg Hypospray /obj/item/reagent_containers/borghypo/medical diff --git a/code/game/objects/items/robot/items/storage.dm b/code/game/objects/items/robot/items/storage.dm index 01541df5a9c..2d91128adb6 100644 --- a/code/game/objects/items/robot/items/storage.dm +++ b/code/game/objects/items/robot/items/storage.dm @@ -50,10 +50,11 @@ stored.attack_self(user) //Alt click drops the stored item. -/obj/item/borg/apparatus/AltClick(mob/living/silicon/robot/user) +/obj/item/borg/apparatus/click_alt(mob/living/silicon/robot/user) if(!stored || !issilicon(user)) - return ..() + return CLICK_ACTION_BLOCKING stored.forceMove(user.drop_location()) + return CLICK_ACTION_SUCCESS /obj/item/borg/apparatus/pre_attack(atom/atom, mob/living/user, params) if(stored) @@ -244,16 +245,16 @@ bag = mutable_appearance(icon, icon_state = "evidenceobj") // empty bag . += bag -/obj/item/borg/apparatus/organ_storage/AltClick(mob/living/silicon/robot/user) - . = ..() - if(stored) - var/obj/item/organ = stored - user.visible_message(span_notice("[user] dumps [organ] from [src]."), span_notice("You dump [organ] from [src].")) - cut_overlays() - organ.forceMove(get_turf(src)) - else +/obj/item/borg/apparatus/organ_storage/click_alt(mob/living/silicon/robot/user) + if(!stored) to_chat(user, span_notice("[src] is empty.")) - return + return CLICK_ACTION_BLOCKING + + var/obj/item/organ = stored + user.visible_message(span_notice("[user] dumps [organ] from [src]."), span_notice("You dump [organ] from [src].")) + cut_overlays() + organ.forceMove(get_turf(src)) + return CLICK_ACTION_SUCCESS ///Apparatus to allow Engineering/Sabo borgs to manipulate any material sheets. /obj/item/borg/apparatus/sheet_manipulator diff --git a/code/game/objects/items/spear.dm b/code/game/objects/items/spear.dm index 5590bfd3c2f..401ffd46934 100644 --- a/code/game/objects/items/spear.dm +++ b/code/game/objects/items/spear.dm @@ -160,13 +160,12 @@ . = ..() . += span_notice("Alt-click to set your war cry.") -/obj/item/spear/explosive/AltClick(mob/user) - if(user.can_perform_action(src)) - ..() - if(istype(user) && loc == user) - var/input = tgui_input_text(user, "What do you want your war cry to be? You will shout it when you hit someone in melee.", "War Cry", max_length = 50) - if(input) - src.war_cry = input +/obj/item/spear/explosive/click_alt(mob/user) + var/input = tgui_input_text(user, "What do you want your war cry to be? You will shout it when you hit someone in melee.", "War Cry", max_length = 50) + if(input) + war_cry = input + return CLICK_ACTION_SUCCESS + /obj/item/spear/explosive/afterattack(atom/movable/AM, mob/user, proximity) . = ..() diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index 1f33384b393..e8e31ef9054 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -419,11 +419,11 @@ return return ..() -/obj/item/stack/medical/mesh/AltClick(mob/living/user) +/obj/item/stack/medical/mesh/click_alt(mob/living/user) if(!is_open) balloon_alert(user, "open it first!") - return - return ..() + return CLICK_ACTION_BLOCKING + return CLICK_ACTION_SUCCESS /obj/item/stack/medical/mesh/attack_hand(mob/user, list/modifiers) if(!is_open && user.get_inactive_held_item() == src) diff --git a/code/game/objects/items/stacks/wrap.dm b/code/game/objects/items/stacks/wrap.dm index 71483d46833..5097234b47c 100644 --- a/code/game/objects/items/stacks/wrap.dm +++ b/code/game/objects/items/stacks/wrap.dm @@ -36,13 +36,14 @@ //Set layers to these colors, base then ribbon set_greyscale(colors = list(generated_base_color, generated_ribbon_color)) -/obj/item/stack/wrapping_paper/AltClick(mob/user, modifiers) +/obj/item/stack/wrapping_paper/click_alt(mob/user) var/new_base = input(user, "", "Select a base color", color) as color var/new_ribbon = input(user, "", "Select a ribbon color", color) as color - if(!user.can_perform_action(src)) - return + if(!new_base || !new_ribbon) + return CLICK_ACTION_BLOCKING + set_greyscale(colors = list(new_base, new_ribbon)) - return TRUE + return CLICK_ACTION_SUCCESS //preset wrapping paper meant to fill the original color configuration /obj/item/stack/wrapping_paper/xmas diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm index 6f3d058cf7e..4df20fd0e11 100644 --- a/code/game/objects/items/storage/belt.dm +++ b/code/game/objects/items/storage/belt.dm @@ -811,6 +811,7 @@ inhand_icon_state = "sheath" worn_icon_state = "sheath" w_class = WEIGHT_CLASS_BULKY + interaction_flags_click = NEED_DEXTERITY|NEED_HANDS /obj/item/storage/belt/sabre/Initialize(mapload) . = ..() @@ -826,9 +827,7 @@ if(length(contents)) . += span_notice("Alt-click it to quickly draw the blade.") -/obj/item/storage/belt/sabre/AltClick(mob/user) - if(!user.can_perform_action(src, NEED_DEXTERITY|NEED_HANDS)) - return +/obj/item/storage/belt/sabre/click_alt(mob/user) if(length(contents)) var/obj/item/I = contents[1] user.visible_message(span_notice("[user] takes [I] out of [src]."), span_notice("You take [I] out of [src].")) @@ -836,6 +835,7 @@ update_appearance() else balloon_alert(user, "it's empty!") + return CLICK_ACTION_SUCCESS /obj/item/storage/belt/sabre/update_icon_state() icon_state = initial(inhand_icon_state) diff --git a/code/game/objects/items/storage/fancy.dm b/code/game/objects/items/storage/fancy.dm index 95eb304509f..1e6cd6432ca 100644 --- a/code/game/objects/items/storage/fancy.dm +++ b/code/game/objects/items/storage/fancy.dm @@ -240,13 +240,13 @@ . = ..() quick_remove_item(/obj/item/clothing/mask/cigarette, user) -/obj/item/storage/fancy/cigarettes/AltClick(mob/user) - . = ..() +/obj/item/storage/fancy/cigarettes/click_alt(mob/user) var/obj/item/lighter = locate(/obj/item/lighter) in contents if(lighter) quick_remove_item(lighter, user) else quick_remove_item(/obj/item/clothing/mask/cigarette, user) + return CLICK_ACTION_SUCCESS /// Removes an item from the packet if there is one /obj/item/storage/fancy/cigarettes/proc/quick_remove_item(obj/item/grabbies, mob/user) diff --git a/code/game/objects/items/storage/lockbox.dm b/code/game/objects/items/storage/lockbox.dm index 3e7b73c93f3..87a7e4928da 100644 --- a/code/game/objects/items/storage/lockbox.dm +++ b/code/game/objects/items/storage/lockbox.dm @@ -120,13 +120,11 @@ if(!atom_storage.locked) . += span_notice("Alt-click to [open ? "close":"open"] it.") -/obj/item/storage/lockbox/medal/AltClick(mob/user) - if(!user.can_perform_action(src)) - return +/obj/item/storage/lockbox/medal/click_alt(mob/user) if(!atom_storage.locked) open = (open ? FALSE : TRUE) update_appearance() - ..() + return CLICK_ACTION_SUCCESS /obj/item/storage/lockbox/medal/PopulateContents() new /obj/item/clothing/accessory/medal/gold/captain(src) diff --git a/code/game/objects/items/tanks/tank_types.dm b/code/game/objects/items/tanks/tank_types.dm index 064a749521e..b21deb35581 100644 --- a/code/game/objects/items/tanks/tank_types.dm +++ b/code/game/objects/items/tanks/tank_types.dm @@ -7,12 +7,14 @@ * Emergency Oxygen * Generic */ +/obj/item/tank/internals + interaction_flags_click = FORBID_TELEKINESIS_REACH|NEED_HANDS + /// Allows carbon to toggle internals via AltClick of the equipped tank. -/obj/item/tank/internals/AltClick(mob/user) - ..() - if((loc == user) && user.can_perform_action(src, FORBID_TELEKINESIS_REACH|NEED_HANDS)) - toggle_internals(user) +/obj/item/tank/internals/click_alt(mob/user) + toggle_internals(user) + return CLICK_ACTION_SUCCESS /obj/item/tank/internals/examine(mob/user) . = ..() diff --git a/code/game/objects/items_reskin.dm b/code/game/objects/items_reskin.dm new file mode 100644 index 00000000000..1a7c27e098d --- /dev/null +++ b/code/game/objects/items_reskin.dm @@ -0,0 +1,57 @@ +/// Called when alt clicked and the item has unique reskin options +/obj/item/proc/on_click_alt_reskin(datum/source, mob/user) + SIGNAL_HANDLER + + if(!user.can_perform_action(src, NEED_DEXTERITY)) + return NONE + + if(!(obj_flags & INFINITE_RESKIN) && current_skin) + return NONE + + INVOKE_ASYNC(src, PROC_REF(reskin_obj), user) + return CLICK_ACTION_SUCCESS + + +/** + * Reskins object based on a user's choice + * + * Arguments: + * * M The mob choosing a reskin option + */ +/obj/item/proc/reskin_obj(mob/user) + if(!LAZYLEN(unique_reskin)) + return + + var/list/items = list() + for(var/reskin_option in unique_reskin) + var/image/item_image = image(icon = src.icon, icon_state = unique_reskin[reskin_option]) + items += list("[reskin_option]" = item_image) + sort_list(items) + + var/pick = show_radial_menu(user, src, items, custom_check = CALLBACK(src, PROC_REF(check_reskin_menu), user), radius = 38, require_near = TRUE) + if(!pick) + return + if(!unique_reskin[pick]) + return + current_skin = pick + icon_state = unique_reskin[pick] + to_chat(user, "[src] is now skinned as '[pick].'") + SEND_SIGNAL(src, COMSIG_OBJ_RESKIN, user, pick) + + +/** + * Checks if we are allowed to interact with a radial menu for reskins + * + * Arguments: + * * user The mob interacting with the menu + */ +/obj/item/proc/check_reskin_menu(mob/user) + if(QDELETED(src)) + return FALSE + if(!(obj_flags & INFINITE_RESKIN) && current_skin) + return FALSE + if(!istype(user)) + return FALSE + if(user.incapacitated()) + return FALSE + return TRUE diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index b6946dffc9a..bfdd0f71426 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -27,9 +27,6 @@ /// A multiplier to an objecet's force when used against a stucture, vechicle, machine, or robot. var/demolition_mod = 1 - var/current_skin //Has the item been reskinned? - var/list/unique_reskin //List of options to reskin. - /// Custom fire overlay icon, will just use the default overlay if this is null var/custom_fire_overlay /// Particles this obj uses when burning, if any @@ -192,56 +189,7 @@ GLOBAL_LIST_EMPTY(objects_by_id_tag) . += span_notice(desc_controls) if(obj_flags & UNIQUE_RENAME) . += span_notice("Use a pen on it to rename it or change its description.") - if(unique_reskin && (!current_skin || (obj_flags & INFINITE_RESKIN))) - . += span_notice("Alt-click it to reskin it.") -/obj/AltClick(mob/user) - . = ..() - if(unique_reskin && (!current_skin || (obj_flags & INFINITE_RESKIN)) && user.can_perform_action(src, NEED_DEXTERITY)) - reskin_obj(user) - -/** - * Reskins object based on a user's choice - * - * Arguments: - * * M The mob choosing a reskin option - */ -/obj/proc/reskin_obj(mob/user) - if(!LAZYLEN(unique_reskin)) - return - - var/list/items = list() - for(var/reskin_option in unique_reskin) - var/image/item_image = image(icon = src.icon, icon_state = unique_reskin[reskin_option]) - items += list("[reskin_option]" = item_image) - sort_list(items) - - var/pick = show_radial_menu(user, src, items, custom_check = CALLBACK(src, PROC_REF(check_reskin_menu), user), radius = 38, require_near = TRUE) - if(!pick) - return - if(!unique_reskin[pick]) - return - current_skin = pick - icon_state = unique_reskin[pick] - to_chat(user, "[src] is now skinned as '[pick].'") - SEND_SIGNAL(src, COMSIG_OBJ_RESKIN, user, pick) - -/** - * Checks if we are allowed to interact with a radial menu for reskins - * - * Arguments: - * * user The mob interacting with the menu - */ -/obj/proc/check_reskin_menu(mob/user) - if(QDELETED(src)) - return FALSE - if(!(obj_flags & INFINITE_RESKIN) && current_skin) - return FALSE - if(!istype(user)) - return FALSE - if(user.incapacitated()) - return FALSE - return TRUE /obj/analyzer_act(mob/living/user, obj/item/analyzer/tool) if(atmos_scan(user=user, target=src, silent=FALSE)) diff --git a/code/game/objects/structures/beds_chairs/bed.dm b/code/game/objects/structures/beds_chairs/bed.dm index 5c5fac60eaa..0e3845d2efa 100644 --- a/code/game/objects/structures/beds_chairs/bed.dm +++ b/code/game/objects/structures/beds_chairs/bed.dm @@ -110,17 +110,14 @@ if(!isnull(foldable_type)) . += span_notice("You can fold it up with a Right-click.") -/obj/structure/bed/medical/AltClick(mob/user) - . = ..() - if(!can_interact(user)) - return - +/obj/structure/bed/medical/click_alt(mob/user) if(has_buckled_mobs() && (user in buckled_mobs)) - return + return CLICK_ACTION_BLOCKING anchored = !anchored balloon_alert(user, "brakes [anchored ? "applied" : "released"]") update_appearance() + return CLICK_ACTION_SUCCESS /obj/structure/bed/medical/post_buckle_mob(mob/living/buckled) . = ..() diff --git a/code/game/objects/structures/beds_chairs/chair.dm b/code/game/objects/structures/beds_chairs/chair.dm index af4bb3084cd..4e86db31427 100644 --- a/code/game/objects/structures/beds_chairs/chair.dm +++ b/code/game/objects/structures/beds_chairs/chair.dm @@ -57,8 +57,6 @@ return . = ..() -/obj/structure/chair/AltClick(mob/user) - return ..() // This hotkey is BLACKLISTED since it's used by /datum/component/simple_rotation ///allows each chair to request the electrified_buckle component with overlays that dont look ridiculous /obj/structure/chair/proc/electrify_self(obj/item/assembly/shock_kit/input_shock_kit, mob/user, list/overlays_from_child_procs) @@ -442,6 +440,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool/bar, 0) buildstacktype = /obj/item/stack/sheet/bronze buildstackamount = 1 item_chair = null + interaction_flags_click = NEED_DEXTERITY + /// Total rotations made var/turns = 0 /obj/structure/chair/bronze/Initialize(mapload) @@ -459,10 +459,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool/bar, 0) if(turns >= 8) STOP_PROCESSING(SSfastprocess, src) -/obj/structure/chair/bronze/AltClick(mob/user) +/obj/structure/chair/bronze/click_alt(mob/user) turns = 0 - if(!user.can_perform_action(src, NEED_DEXTERITY)) - return if(!(datum_flags & DF_ISPROCESSING)) user.visible_message(span_notice("[user] spins [src] around, and the last vestiges of Ratvarian technology keeps it spinning FOREVER."), \ span_notice("Automated spinny chairs. The pinnacle of ancient Ratvarian technology.")) @@ -471,6 +469,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool/bar, 0) user.visible_message(span_notice("[user] stops [src]'s uncontrollable spinning."), \ span_notice("You grab [src] and stop its wild spinning.")) STOP_PROCESSING(SSfastprocess, src) + return CLICK_ACTION_SUCCESS /obj/structure/chair/mime name = "invisible chair" diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm index 108ca3fe9b8..8b4fef65293 100644 --- a/code/game/objects/structures/bedsheet_bin.dm +++ b/code/game/objects/structures/bedsheet_bin.dm @@ -20,6 +20,7 @@ LINEN BINS w_class = WEIGHT_CLASS_TINY resistance_flags = FLAMMABLE dying_key = DYE_REGISTRY_BEDSHEET + interaction_flags_click = NEED_DEXTERITY dog_fashion = /datum/dog_fashion/head/ghost /// Custom nouns to act as the subject of dreams @@ -133,11 +134,9 @@ LINEN BINS else return ..() -/obj/item/bedsheet/AltClick(mob/living/user) - // double check the canUseTopic args to make sure it's correct - if(!istype(user) || !user.can_perform_action(src, NEED_DEXTERITY)) - return +/obj/item/bedsheet/click_alt(mob/living/user) dir = REVERSE_DIR(dir) + return CLICK_ACTION_SUCCESS /obj/item/bedsheet/blue icon_state = "sheetblue" diff --git a/code/game/objects/structures/divine.dm b/code/game/objects/structures/divine.dm index ef9f650e42a..6114a20158c 100644 --- a/code/game/objects/structures/divine.dm +++ b/code/game/objects/structures/divine.dm @@ -7,19 +7,17 @@ density = FALSE can_buckle = 1 -/obj/structure/sacrificealtar/AltClick(mob/living/user) - ..() - if(!istype(user) || !user.can_perform_action(src)) - return +/obj/structure/sacrificealtar/click_alt(mob/living/user) if(!has_buckled_mobs()) - return + return CLICK_ACTION_BLOCKING var/mob/living/L = locate() in buckled_mobs if(!L) - return + return CLICK_ACTION_BLOCKING to_chat(user, span_notice("Invoking the sacred ritual, you sacrifice [L].")) L.investigate_log("has been sacrificially gibbed on an altar.", INVESTIGATE_DEATHS) L.gib(DROP_ALL_REMAINS) message_admins("[ADMIN_LOOKUPFLW(user)] has sacrificed [key_name_admin(L)] on the sacrificial altar at [AREACOORD(src)].") + return CLICK_ACTION_SUCCESS /obj/structure/healingfountain name = "healing fountain" diff --git a/code/game/objects/structures/lavaland/geyser.dm b/code/game/objects/structures/lavaland/geyser.dm index a2f0412f1da..7ef40423e0d 100644 --- a/code/game/objects/structures/lavaland/geyser.dm +++ b/code/game/objects/structures/lavaland/geyser.dm @@ -167,14 +167,12 @@ playsound(src, 'sound/machines/click.ogg', 10, TRUE) -/obj/item/plunger/AltClick(mob/user) - if(!istype(user) || !user.can_perform_action(src)) - return - +/obj/item/plunger/click_alt(mob/user) var/new_layer = tgui_input_list(user, "Select a layer", "Layer", GLOB.plumbing_layers) if(isnull(new_layer) || !user.can_perform_action(src)) - return + return CLICK_ACTION_BLOCKING target_layer = GLOB.plumbing_layers[new_layer] + return CLICK_ACTION_SUCCESS ///A faster reinforced plunger /obj/item/plunger/reinforced diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm index bbdf209148c..4ac1a62a63f 100644 --- a/code/game/objects/structures/morgue.dm +++ b/code/game/objects/structures/morgue.dm @@ -170,6 +170,7 @@ GLOBAL_LIST_EMPTY(bodycontainers) //Let them act as spawnpoints for revenants an icon_state = "morgue1" base_icon_state = "morgue" dir = EAST + interaction_flags_click = ALLOW_SILICON_REACH|ALLOW_RESTING connected = /obj/structure/tray/m_tray @@ -298,12 +299,10 @@ GLOBAL_LIST_EMPTY(bodycontainers) //Let them act as spawnpoints for revenants an . = ..() . += span_notice("The speaker is [beeper ? "enabled" : "disabled"]. Alt-click to toggle it.") -/obj/structure/bodycontainer/morgue/AltClick(mob/user) - ..() - if(!user.can_perform_action(src, (ALLOW_SILICON_REACH|ALLOW_RESTING))) - return +/obj/structure/bodycontainer/morgue/click_alt(mob/user) beeper = !beeper to_chat(user, span_notice("You turn the speaker function [beeper ? "on" : "off"].")) + return CLICK_ACTION_SUCCESS /obj/structure/bodycontainer/morgue/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) diff --git a/code/game/objects/structures/railings.dm b/code/game/objects/structures/railings.dm index 95cf4fc58e5..2651684e39b 100644 --- a/code/game/objects/structures/railings.dm +++ b/code/game/objects/structures/railings.dm @@ -88,8 +88,6 @@ to_chat(user, span_warning("[src] is already in good condition!")) return -/obj/structure/railing/AltClick(mob/user) - return ..() // This hotkey is BLACKLISTED since it's used by /datum/component/simple_rotation /obj/structure/railing/wirecutter_act(mob/living/user, obj/item/I) . = ..() diff --git a/code/game/objects/structures/shower.dm b/code/game/objects/structures/shower.dm index 48fa379b416..350adcb11f1 100644 --- a/code/game/objects/structures/shower.dm +++ b/code/game/objects/structures/shower.dm @@ -366,8 +366,6 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/shower, (-16)) deconstruct() return TRUE -/obj/structure/showerframe/AltClick(mob/user) - return ..() // This hotkey is BLACKLISTED since it's used by /datum/component/simple_rotation /obj/effect/mist name = "mist" diff --git a/code/game/objects/structures/training_machine.dm b/code/game/objects/structures/training_machine.dm index fd0d8bb0c8f..c2f4d3a18ae 100644 --- a/code/game/objects/structures/training_machine.dm +++ b/code/game/objects/structures/training_machine.dm @@ -20,6 +20,7 @@ can_buckle = TRUE buckle_lying = 0 max_integrity = 200 + interaction_flags_click = NEED_DEXTERITY|FORBID_TELEKINESIS_REACH|ALLOW_RESTING ///Is the machine moving? Setting this to FALSE will automatically call stop_moving() var/moving = FALSE ///The distance the machine is allowed to roam from its starting point @@ -174,21 +175,19 @@ attached_item.throw_at(destination, 4, 1) on_attached_delete() -/obj/structure/training_machine/AltClick(mob/user) - . = ..() - if(!user.can_perform_action(src, NEED_DEXTERITY|FORBID_TELEKINESIS_REACH|ALLOW_RESTING)) - return +/obj/structure/training_machine/click_alt(mob/user) if(has_buckled_mobs()) user_unbuckle_mob(buckled_mobs[1], user) - return + return CLICK_ACTION_SUCCESS if (!attached_item) - return + return NONE if (obj_flags & EMAGGED) to_chat(user, span_warning("The toolbox is somehow stuck on! It won't budge!")) - return + return CLICK_ACTION_BLOCKING to_chat(user, span_notice("You remove \the [attached_item] from the training device.")) remove_attached_item(user) playsound(src, SFX_RUSTLE, 50, TRUE) + return CLICK_ACTION_SUCCESS /** * Toggle the machine's movement @@ -396,12 +395,10 @@ if (!.) check_hit(hit_atom) -/obj/item/training_toolbox/AltClick(mob/user) - . = ..() - if(!can_interact(user)) - return +/obj/item/training_toolbox/click_alt(mob/user) to_chat(user, span_notice("You push the 'Lap' button on the toolbox's display.")) lap_hits = initial(lap_hits) + return CLICK_ACTION_SUCCESS /obj/item/training_toolbox/examine(mob/user) . = ..() diff --git a/code/game/objects/structures/transit_tubes/transit_tube_construction.dm b/code/game/objects/structures/transit_tubes/transit_tube_construction.dm index 44952801ec7..e6b0f30225c 100644 --- a/code/game/objects/structures/transit_tubes/transit_tube_construction.dm +++ b/code/game/objects/structures/transit_tubes/transit_tube_construction.dm @@ -51,8 +51,6 @@ qdel(src) return TRUE -/obj/structure/c_transit_tube/AltClick(mob/user) - return ..() // This hotkey is BLACKLISTED since it's used by /datum/component/simple_rotation // transit tube station /obj/structure/c_transit_tube/station diff --git a/code/game/objects/structures/windoor_assembly.dm b/code/game/objects/structures/windoor_assembly.dm index 0a56c6add69..3437e2a5ae0 100644 --- a/code/game/objects/structures/windoor_assembly.dm +++ b/code/game/objects/structures/windoor_assembly.dm @@ -327,8 +327,6 @@ qdel(src) -/obj/structure/windoor_assembly/AltClick(mob/user) - return ..() // This hotkey is BLACKLISTED since it's used by /datum/component/simple_rotation //Flips the windoor assembly, determines whather the door opens to the left or the right /obj/structure/windoor_assembly/verb/flip() diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index d9bf9004436..09464888db7 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -277,8 +277,6 @@ add_fingerprint(user) return ..() -/obj/structure/window/AltClick(mob/user) - return ..() // This hotkey is BLACKLISTED since it's used by /datum/component/simple_rotation /obj/structure/window/set_anchored(anchorvalue) ..() diff --git a/code/modules/admin/sound_emitter.dm b/code/modules/admin/sound_emitter.dm index 4786e0ad7c1..d697537c6df 100644 --- a/code/modules/admin/sound_emitter.dm +++ b/code/modules/admin/sound_emitter.dm @@ -51,10 +51,13 @@ return edit_emitter(user) -/obj/effect/sound_emitter/AltClick(mob/user) - if(check_rights_for(user.client, R_SOUND)) - activate(user) - to_chat(user, span_notice("Sound emitter activated."), confidential = TRUE) +/obj/effect/sound_emitter/click_alt(mob/user) + if(!check_rights_for(user.client, R_SOUND)) + return CLICK_ACTION_BLOCKING + + activate(user) + to_chat(user, span_notice("Sound emitter activated."), confidential = TRUE) + return CLICK_ACTION_SUCCESS /obj/effect/sound_emitter/proc/edit_emitter(mob/user) var/dat = "" diff --git a/code/modules/antagonists/abductor/equipment/gear/abductor_items.dm b/code/modules/antagonists/abductor/equipment/gear/abductor_items.dm index 07e8dad2aa6..a7d60e40bef 100644 --- a/code/modules/antagonists/abductor/equipment/gear/abductor_items.dm +++ b/code/modules/antagonists/abductor/equipment/gear/abductor_items.dm @@ -285,8 +285,8 @@
Congratulations! You are now trained for invasive xenobiology research!"} -/obj/item/paper/guides/antag/abductor/AltClick() - return //otherwise it would fold into a paperplane. +/obj/item/paper/guides/antag/abductor/click_alt() + return CLICK_ACTION_BLOCKING //otherwise it would fold into a paperplane. /obj/item/melee/baton/abductor name = "advanced baton" diff --git a/code/modules/art/paintings.dm b/code/modules/art/paintings.dm index a4758eb9e11..f050528bd3b 100644 --- a/code/modules/art/paintings.dm +++ b/code/modules/art/paintings.dm @@ -569,10 +569,12 @@ current_canvas = null update_appearance() -/obj/structure/sign/painting/AltClick(mob/user) - . = ..() - if(current_canvas?.can_select_frame(user)) - INVOKE_ASYNC(current_canvas, TYPE_PROC_REF(/obj/item/canvas, select_new_frame), user) +/obj/structure/sign/painting/click_alt(mob/user) + if(!current_canvas?.can_select_frame(user)) + return CLICK_ACTION_BLOCKING + + INVOKE_ASYNC(current_canvas, TYPE_PROC_REF(/obj/item/canvas, select_new_frame), user) + return CLICK_ACTION_SUCCESS /obj/structure/sign/painting/proc/frame_canvas(mob/user, obj/item/canvas/new_canvas) if(!(new_canvas.type in accepted_canvas_types)) diff --git a/code/modules/art/statues.dm b/code/modules/art/statues.dm index 428bb5d8e06..8ed46a5bf81 100644 --- a/code/modules/art/statues.dm +++ b/code/modules/art/statues.dm @@ -44,8 +44,6 @@ return return ..() -/obj/structure/statue/AltClick(mob/user) - return ..() // This hotkey is BLACKLISTED since it's used by /datum/component/simple_rotation /obj/structure/statue/atom_deconstruct(disassembled = TRUE) var/amount_mod = disassembled ? 0 : -2 diff --git a/code/modules/assembly/health.dm b/code/modules/assembly/health.dm index 23c329894e7..28ab16f63d7 100644 --- a/code/modules/assembly/health.dm +++ b/code/modules/assembly/health.dm @@ -37,16 +37,14 @@ update_appearance() return secured -/obj/item/assembly/health/AltClick(mob/living/user) - if(!can_interact(user)) - return - +/obj/item/assembly/health/click_alt(mob/living/user) if(alarm_health == HEALTH_THRESHOLD_CRIT) alarm_health = HEALTH_THRESHOLD_DEAD to_chat(user, span_notice("You toggle [src] to \"detect death\" mode.")) else alarm_health = HEALTH_THRESHOLD_CRIT to_chat(user, span_notice("You toggle [src] to \"detect critical state\" mode.")) + return CLICK_ACTION_SUCCESS /obj/item/assembly/health/process() //not ready yet diff --git a/code/modules/assembly/holder.dm b/code/modules/assembly/holder.dm index 70f116b3e3e..5f50618e77d 100644 --- a/code/modules/assembly/holder.dm +++ b/code/modules/assembly/holder.dm @@ -141,8 +141,6 @@ return ..() -/obj/item/assembly_holder/AltClick(mob/user) - return ..() // This hotkey is BLACKLISTED since it's used by /datum/component/simple_rotation /obj/item/assembly_holder/screwdriver_act(mob/user, obj/item/tool) if(..()) diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm index b5c847a78ab..8dd4573fcfd 100644 --- a/code/modules/assembly/infrared.dm +++ b/code/modules/assembly/infrared.dm @@ -35,8 +35,6 @@ buffer_turf = null return ..() -/obj/item/assembly/infra/AltClick(mob/user) - return ..() // This hotkey is BLACKLISTED since it's used by /datum/component/simple_rotation /obj/item/assembly/infra/examine(mob/user) . = ..() diff --git a/code/modules/atmospherics/machinery/atmosmachinery.dm b/code/modules/atmospherics/machinery/atmosmachinery.dm index d8d0ed3b47e..d152cf09e71 100644 --- a/code/modules/atmospherics/machinery/atmosmachinery.dm +++ b/code/modules/atmospherics/machinery/atmosmachinery.dm @@ -607,11 +607,6 @@ animate(our_client, pixel_x = 0, pixel_y = 0, time = 0.05 SECONDS) our_client.move_delay = world.time + 0.05 SECONDS -/obj/machinery/atmospherics/AltClick(mob/living/L) - if(vent_movement & VENTCRAWL_ALLOWED && istype(L)) - L.handle_ventcrawl(src) - return - return ..() /** * Getter of a list of pipenets diff --git a/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm b/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm index 69b54a01a8c..fe6f9423b43 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm @@ -22,7 +22,6 @@ Passive gate is similar to the regular pump except: /obj/machinery/atmospherics/components/binary/passive_gate/Initialize(mapload) . = ..() - ADD_TRAIT(src, TRAIT_ALT_CLICK_BLOCKER, REF(src)) register_context() /obj/machinery/atmospherics/components/binary/passive_gate/add_context(atom/source, list/context, obj/item/held_item, mob/user) @@ -39,13 +38,15 @@ Passive gate is similar to the regular pump except: update_appearance() return ..() -/obj/machinery/atmospherics/components/binary/passive_gate/AltClick(mob/user) - if(can_interact(user)) - target_pressure = MAX_OUTPUT_PRESSURE - investigate_log("was set to [target_pressure] kPa by [key_name(user)]", INVESTIGATE_ATMOS) - balloon_alert(user, "pressure output set to [target_pressure] kPa") - update_appearance() - return ..() +/obj/machinery/atmospherics/components/binary/passive_gate/click_alt(mob/user) + if(target_pressure == MAX_OUTPUT_PRESSURE) + return CLICK_ACTION_BLOCKING + + target_pressure = MAX_OUTPUT_PRESSURE + investigate_log("was set to [target_pressure] kPa by [key_name(user)]", INVESTIGATE_ATMOS) + balloon_alert(user, "pressure output set to [target_pressure] kPa") + update_appearance() + return CLICK_ACTION_SUCCESS /obj/machinery/atmospherics/components/binary/passive_gate/update_icon_nopipes() cut_overlays() diff --git a/code/modules/atmospherics/machinery/components/binary_devices/pressure_valve.dm b/code/modules/atmospherics/machinery/components/binary_devices/pressure_valve.dm index 72dd3c7f2f6..c3313322135 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/pressure_valve.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/pressure_valve.dm @@ -14,7 +14,6 @@ /obj/machinery/atmospherics/components/binary/pressure_valve/Initialize(mapload) . = ..() - ADD_TRAIT(src, TRAIT_ALT_CLICK_BLOCKER, REF(src)) register_context() /obj/machinery/atmospherics/components/binary/pressure_valve/add_context(atom/source, list/context, obj/item/held_item, mob/user) @@ -31,13 +30,15 @@ update_appearance() return ..() -/obj/machinery/atmospherics/components/binary/pressure_valve/AltClick(mob/user) - if(can_interact(user)) - target_pressure = MAX_OUTPUT_PRESSURE - investigate_log("was set to [target_pressure] kPa by [key_name(user)]", INVESTIGATE_ATMOS) - balloon_alert(user, "target pressure set to [target_pressure] kPa") - update_appearance() - return ..() +/obj/machinery/atmospherics/components/binary/pressure_valve/click_alt(mob/user) + if(target_pressure == MAX_OUTPUT_PRESSURE) + return CLICK_ACTION_BLOCKING + + target_pressure = MAX_OUTPUT_PRESSURE + investigate_log("was set to [target_pressure] kPa by [key_name(user)]", INVESTIGATE_ATMOS) + balloon_alert(user, "target pressure set to [target_pressure] kPa") + update_appearance() + return CLICK_ACTION_SUCCESS /obj/machinery/atmospherics/components/binary/pressure_valve/update_icon_nopipes() if(on && is_operational && is_gas_flowing) diff --git a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm index 50d86992d74..035f3a0f996 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm @@ -27,7 +27,6 @@ AddComponent(/datum/component/usb_port, list( /obj/item/circuit_component/atmos_pump, )) - ADD_TRAIT(src, TRAIT_ALT_CLICK_BLOCKER, REF(src)) register_context() /obj/machinery/atmospherics/components/binary/pump/add_context(atom/source, list/context, obj/item/held_item, mob/user) @@ -44,13 +43,15 @@ update_appearance() return ..() -/obj/machinery/atmospherics/components/binary/pump/AltClick(mob/user) - if(can_interact(user)) - target_pressure = MAX_OUTPUT_PRESSURE - investigate_log("was set to [target_pressure] kPa by [key_name(user)]", INVESTIGATE_ATMOS) - balloon_alert(user, "pressure output set to [target_pressure] kPa") - update_appearance() - return ..() +/obj/machinery/atmospherics/components/binary/pump/click_alt(mob/user) + if(target_pressure == MAX_OUTPUT_PRESSURE) + return CLICK_ACTION_BLOCKING + + target_pressure = MAX_OUTPUT_PRESSURE + investigate_log("was set to [target_pressure] kPa by [key_name(user)]", INVESTIGATE_ATMOS) + balloon_alert(user, "pressure output set to [target_pressure] kPa") + update_appearance() + return CLICK_ACTION_SUCCESS /obj/machinery/atmospherics/components/binary/pump/update_icon_nopipes() icon_state = (on && is_operational) ? "pump_on-[set_overlay_offset(piping_layer)]" : "pump_off-[set_overlay_offset(piping_layer)]" diff --git a/code/modules/atmospherics/machinery/components/binary_devices/temperature_gate.dm b/code/modules/atmospherics/machinery/components/binary_devices/temperature_gate.dm index 567759a3829..d1202dbec94 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/temperature_gate.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/temperature_gate.dm @@ -19,7 +19,6 @@ /obj/machinery/atmospherics/components/binary/temperature_gate/Initialize(mapload) . = ..() - ADD_TRAIT(src, TRAIT_ALT_CLICK_BLOCKER, REF(src)) register_context() /obj/machinery/atmospherics/components/binary/temperature_gate/add_context(atom/source, list/context, obj/item/held_item, mob/user) @@ -36,13 +35,15 @@ update_appearance() return ..() -/obj/machinery/atmospherics/components/binary/temperature_gate/AltClick(mob/user) - if(can_interact(user)) - target_temperature = max_temperature - investigate_log("was set to [target_temperature] K by [key_name(user)]", INVESTIGATE_ATMOS) - balloon_alert(user, "target temperature set to [target_temperature] K") - update_appearance() - return ..() +/obj/machinery/atmospherics/components/binary/temperature_gate/click_alt(mob/user) + if(target_temperature == max_temperature) + return CLICK_ACTION_BLOCKING + + target_temperature = max_temperature + investigate_log("was set to [target_temperature] K by [key_name(user)]", INVESTIGATE_ATMOS) + balloon_alert(user, "target temperature set to [target_temperature] K") + update_appearance() + return CLICK_ACTION_SUCCESS /obj/machinery/atmospherics/components/binary/temperature_gate/examine(mob/user) diff --git a/code/modules/atmospherics/machinery/components/binary_devices/temperature_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/temperature_pump.dm index 54f277c25b1..2615b964ed8 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/temperature_pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/temperature_pump.dm @@ -14,7 +14,6 @@ /obj/machinery/atmospherics/components/binary/temperature_pump/Initialize(mapload) . = ..() - ADD_TRAIT(src, TRAIT_ALT_CLICK_BLOCKER, REF(src)) register_context() /obj/machinery/atmospherics/components/binary/temperature_pump/add_context(atom/source, list/context, obj/item/held_item, mob/user) @@ -31,13 +30,15 @@ update_appearance() return ..() -/obj/machinery/atmospherics/components/binary/temperature_pump/AltClick(mob/user) - if(can_interact(user) && !(heat_transfer_rate == max_heat_transfer_rate)) - heat_transfer_rate = max_heat_transfer_rate - investigate_log("was set to [heat_transfer_rate]% by [key_name(user)]", INVESTIGATE_ATMOS) - balloon_alert(user, "transfer rate set to [heat_transfer_rate]%") - update_appearance() - return ..() +/obj/machinery/atmospherics/components/binary/temperature_pump/click_alt(mob/user) + if(heat_transfer_rate == max_heat_transfer_rate) + return CLICK_ACTION_BLOCKING + + heat_transfer_rate = max_heat_transfer_rate + investigate_log("was set to [heat_transfer_rate]% by [key_name(user)]", INVESTIGATE_ATMOS) + balloon_alert(user, "transfer rate set to [heat_transfer_rate]%") + update_appearance() + return CLICK_ACTION_SUCCESS /obj/machinery/atmospherics/components/binary/temperature_pump/update_icon_nopipes() icon_state = "tpump_[on && is_operational ? "on" : "off"]-[set_overlay_offset(piping_layer)]" diff --git a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm index e190bb47d30..41dc549b858 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm @@ -31,7 +31,6 @@ AddComponent(/datum/component/usb_port, list( /obj/item/circuit_component/atmos_volume_pump, )) - ADD_TRAIT(src, TRAIT_ALT_CLICK_BLOCKER, REF(src)) register_context() /obj/machinery/atmospherics/components/binary/volume_pump/CtrlClick(mob/user) @@ -42,13 +41,15 @@ update_appearance() return ..() -/obj/machinery/atmospherics/components/binary/volume_pump/AltClick(mob/user) - if(can_interact(user)) - transfer_rate = MAX_TRANSFER_RATE - investigate_log("was set to [transfer_rate] L/s by [key_name(user)]", INVESTIGATE_ATMOS) - balloon_alert(user, "volume output set to [transfer_rate] L/s") - update_appearance() - return ..() +/obj/machinery/atmospherics/components/binary/volume_pump/click_alt(mob/user) + if(transfer_rate == MAX_TRANSFER_RATE) + return CLICK_ACTION_BLOCKING + + transfer_rate = MAX_TRANSFER_RATE + investigate_log("was set to [transfer_rate] L/s by [key_name(user)]", INVESTIGATE_ATMOS) + balloon_alert(user, "volume output set to [transfer_rate] L/s") + update_appearance() + return CLICK_ACTION_SUCCESS /obj/machinery/atmospherics/components/binary/volume_pump/update_icon_nopipes() icon_state = on && is_operational ? "volpump_on-[set_overlay_offset(piping_layer)]" : "volpump_off-[set_overlay_offset(piping_layer)]" diff --git a/code/modules/atmospherics/machinery/components/electrolyzer/electrolyzer.dm b/code/modules/atmospherics/machinery/components/electrolyzer/electrolyzer.dm index 0ab8427c0ae..56ee3c6039d 100644 --- a/code/modules/atmospherics/machinery/components/electrolyzer/electrolyzer.dm +++ b/code/modules/atmospherics/machinery/components/electrolyzer/electrolyzer.dm @@ -187,14 +187,12 @@ return return ..() -/obj/machinery/electrolyzer/AltClick(mob/user) - . = ..() +/obj/machinery/electrolyzer/click_alt(mob/user) if(panel_open) balloon_alert(user, "close panel!") - return - if(!can_interact(user)) - return + return CLICK_ACTION_BLOCKING toggle_power(user) + return CLICK_ACTION_SUCCESS /obj/machinery/electrolyzer/proc/toggle_power(mob/user) if(!anchored && !cell) diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm index 1727d4877b5..c6b4bd43be4 100644 --- a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm +++ b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm @@ -32,13 +32,15 @@ update_appearance() return ..() -/obj/machinery/atmospherics/components/trinary/filter/AltClick(mob/user) - if(can_interact(user)) - transfer_rate = MAX_TRANSFER_RATE - investigate_log("was set to [transfer_rate] L/s by [key_name(user)]", INVESTIGATE_ATMOS) - balloon_alert(user, "volume output set to [transfer_rate] L/s") - update_appearance() - return ..() +/obj/machinery/atmospherics/components/trinary/filter/click_alt(mob/user) + if(transfer_rate == MAX_TRANSFER_RATE) + return CLICK_ACTION_BLOCKING + + transfer_rate = MAX_TRANSFER_RATE + investigate_log("was set to [transfer_rate] L/s by [key_name(user)]", INVESTIGATE_ATMOS) + balloon_alert(user, "volume output set to [transfer_rate] L/s") + update_appearance() + return CLICK_ACTION_SUCCESS /obj/machinery/atmospherics/components/trinary/filter/update_overlays() . = ..() diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm index 862fbc65c89..f832adcb4ea 100644 --- a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm +++ b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm @@ -35,13 +35,15 @@ update_appearance() return ..() -/obj/machinery/atmospherics/components/trinary/mixer/AltClick(mob/user) - if(can_interact(user)) - target_pressure = MAX_OUTPUT_PRESSURE - investigate_log("was set to [target_pressure] kPa by [key_name(user)]", INVESTIGATE_ATMOS) - balloon_alert(user, "pressure output on set to [target_pressure] kPa") - update_appearance() - return ..() +/obj/machinery/atmospherics/components/trinary/mixer/click_alt(mob/user) + if(target_pressure == MAX_OUTPUT_PRESSURE) + return CLICK_ACTION_BLOCKING + + target_pressure = MAX_OUTPUT_PRESSURE + investigate_log("was set to [target_pressure] kPa by [key_name(user)]", INVESTIGATE_ATMOS) + balloon_alert(user, "pressure output on set to [target_pressure] kPa") + update_appearance() + return CLICK_ACTION_SUCCESS /obj/machinery/atmospherics/components/trinary/mixer/update_overlays() . = ..() diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm index 4d35875f1d7..232c047a2b2 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm @@ -644,14 +644,13 @@ balloon_alert(user, "turned [on ? "on" : "off"]") return ..() -/obj/machinery/cryo_cell/AltClick(mob/user) - if(can_interact(user)) - if(state_open) - close_machine() - else - open_machine() - balloon_alert(user, "door [state_open ? "opened" : "closed"]") - return ..() +/obj/machinery/cryo_cell/click_alt(mob/user) + if(state_open) + close_machine() + else + open_machine() + balloon_alert(user, "door [state_open ? "opened" : "closed"]") + return CLICK_ACTION_SUCCESS /obj/machinery/cryo_cell/get_remote_view_fullscreens(mob/user) user.overlay_fullscreen("remote_view", /atom/movable/screen/fullscreen/impaired, 1) diff --git a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm index 4161a30ed7d..771301b60e4 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm @@ -62,13 +62,15 @@ update_appearance() return ..() -/obj/machinery/atmospherics/components/unary/outlet_injector/AltClick(mob/user) - if(can_interact(user)) - volume_rate = MAX_TRANSFER_RATE - investigate_log("was set to [volume_rate] L/s by [key_name(user)]", INVESTIGATE_ATMOS) - balloon_alert(user, "volume output set to [volume_rate] L/s") - update_appearance() - return ..() +/obj/machinery/atmospherics/components/unary/outlet_injector/click_alt(mob/user) + if(volume_rate == MAX_TRANSFER_RATE) + return CLICK_ACTION_BLOCKING + + volume_rate = MAX_TRANSFER_RATE + investigate_log("was set to [volume_rate] L/s by [key_name(user)]", INVESTIGATE_ATMOS) + balloon_alert(user, "volume output set to [volume_rate] L/s") + update_appearance() + return CLICK_ACTION_SUCCESS /obj/machinery/atmospherics/components/unary/outlet_injector/update_icon_nopipes() cut_overlays() diff --git a/code/modules/atmospherics/machinery/components/unary_devices/passive_vent.dm b/code/modules/atmospherics/machinery/components/unary_devices/passive_vent.dm index 17f6c761f12..4ac0e959e40 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/passive_vent.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/passive_vent.dm @@ -12,6 +12,8 @@ pipe_state = "pvent" has_cap_visuals = TRUE vent_movement = VENTCRAWL_ALLOWED | VENTCRAWL_CAN_SEE | VENTCRAWL_ENTRANCE_ALLOWED + interaction_flags_click = NEED_VENTCRAWL + /obj/machinery/atmospherics/components/unary/passive_vent/update_icon_nopipes() cut_overlays() diff --git a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm index 0af962ac0f3..01def672bf7 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm @@ -144,12 +144,10 @@ . += span_notice("Heat capacity at [heat_capacity] Joules per Kelvin.") . += span_notice("Temperature range [min_temperature]K - [max_temperature]K ([(T0C-min_temperature)*-1]C - [(T0C-max_temperature)*-1]C).") -/obj/machinery/atmospherics/components/unary/thermomachine/AltClick(mob/living/user) +/obj/machinery/atmospherics/components/unary/thermomachine/click_alt(mob/living/user) if(panel_open) balloon_alert(user, "close panel!") - return - if(!can_interact(user)) - return + return CLICK_ACTION_BLOCKING if(target_temperature == T20C) target_temperature = max_temperature @@ -161,6 +159,7 @@ investigate_log("was set to [target_temperature] K by [key_name(user)]", INVESTIGATE_ATMOS) balloon_alert(user, "temperature reset to [target_temperature] K") update_appearance() + return CLICK_ACTION_SUCCESS /// Performs heat calculation for the freezer. /// We just equalize the gasmix with an object at temp = var/target_temperature and heat cap = var/heat_capacity diff --git a/code/modules/atmospherics/machinery/components/unary_devices/unary_devices.dm b/code/modules/atmospherics/machinery/components/unary_devices/unary_devices.dm index 4d876fd4586..c8bfd8628e9 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/unary_devices.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/unary_devices.dm @@ -17,6 +17,12 @@ ..() update_appearance() + +/obj/machinery/atmospherics/components/unary/click_alt(mob/living/beno) + beno.handle_ventcrawl(src) + return CLICK_ACTION_SUCCESS + + /obj/machinery/atmospherics/components/unary/proc/assign_uid_vents() uid = num2text(gl_uid++) return uid diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm index 2220f640541..02f0d203544 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm @@ -18,6 +18,7 @@ vent_movement = VENTCRAWL_ALLOWED | VENTCRAWL_CAN_SEE | VENTCRAWL_ENTRANCE_ALLOWED // vents are more complex machinery and so are less resistant to damage max_integrity = 100 + interaction_flags_click = NEED_VENTCRAWL ///Direction of pumping the gas (ATMOS_DIRECTION_RELEASING or ATMOS_DIRECTION_SIPHONING) var/pump_direction = ATMOS_DIRECTION_RELEASING diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm index 86cbc07a94f..20a0b86b41c 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm @@ -15,6 +15,7 @@ has_cap_visuals = TRUE vent_movement = VENTCRAWL_ALLOWED | VENTCRAWL_CAN_SEE | VENTCRAWL_ENTRANCE_ALLOWED processing_flags = NONE + interaction_flags_click = NEED_VENTCRAWL ///The mode of the scrubber (ATMOS_DIRECTION_SCRUBBING or ATMOS_DIRECTION_SIPHONING) var/scrubbing = ATMOS_DIRECTION_SCRUBBING diff --git a/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm b/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm index 3d4e2b02e1f..3713958fbaa 100644 --- a/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm +++ b/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm @@ -8,6 +8,7 @@ armor_type = /datum/armor/machinery_portable_atmospherics anchored = FALSE layer = ABOVE_OBJ_LAYER + interaction_flags_click = NEED_DEXTERITY ///Stores the gas mixture of the portable component. Don't access this directly, use return_air() so you support the temporary processing it provides var/datum/gas_mixture/air_contents @@ -162,14 +163,12 @@ update_appearance() return TRUE -/obj/machinery/portable_atmospherics/AltClick(mob/living/user) - . = ..() - if(!istype(user) || !user.can_perform_action(src, NEED_DEXTERITY) || !can_interact(user)) - return +/obj/machinery/portable_atmospherics/click_alt(mob/living/user) if(!holding) - return + return CLICK_ACTION_BLOCKING to_chat(user, span_notice("You remove [holding] from [src].")) replace_tank(user, TRUE) + return CLICK_ACTION_SUCCESS /obj/machinery/portable_atmospherics/examine(mob/user) . = ..() diff --git a/code/modules/cards/deck/deck.dm b/code/modules/cards/deck/deck.dm index 6a199bec4d7..d142692776c 100644 --- a/code/modules/cards/deck/deck.dm +++ b/code/modules/cards/deck/deck.dm @@ -11,6 +11,7 @@ hitsound = null attack_verb_continuous = list("attacks") attack_verb_simple = list("attack") + interaction_flags_click = NEED_DEXTERITY|FORBID_TELEKINESIS_REACH /// The amount of time it takes to shuffle var/shuffle_time = DECK_SHUFFLE_TIME /// Deck shuffling cooldown. @@ -143,13 +144,13 @@ attack_hand(user, modifiers, flip_card = TRUE) return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN -/obj/item/toy/cards/deck/AltClick(mob/living/user) - if(user.can_perform_action(src, NEED_DEXTERITY|FORBID_TELEKINESIS_REACH)) - if(HAS_TRAIT(src, TRAIT_WIELDED)) - shuffle_cards(user) - else - to_chat(user, span_notice("You must hold the [src] with both hands to shuffle.")) - return ..() +/obj/item/toy/cards/deck/click_alt(mob/living/user) + if(!HAS_TRAIT(src, TRAIT_WIELDED)) + to_chat(user, span_notice("You must hold the [src] with both hands to shuffle.")) + return CLICK_ACTION_BLOCKING + + shuffle_cards(user) + return CLICK_ACTION_SUCCESS /obj/item/toy/cards/deck/update_icon_state() switch(count_cards()) diff --git a/code/modules/cards/singlecard.dm b/code/modules/cards/singlecard.dm index 169715c51d9..e03c5800346 100644 --- a/code/modules/cards/singlecard.dm +++ b/code/modules/cards/singlecard.dm @@ -14,6 +14,7 @@ throw_range = 7 attack_verb_continuous = list("attacks") attack_verb_simple = list("attack") + interaction_flags_click = NEED_DEXTERITY|FORBID_TELEKINESIS_REACH /// Artistic style of the deck var/deckstyle = "nanotrasen" /// If the cards in the deck have different icon states (blank and CAS decks do not) @@ -237,8 +238,7 @@ if(isturf(src.loc)) // only display tihs message when flipping in a visible spot like on a table user.balloon_alert_to_viewers("flips a card") -/obj/item/toy/singlecard/AltClick(mob/living/carbon/human/user) - if(user.can_perform_action(src, NEED_DEXTERITY|FORBID_TELEKINESIS_REACH)) - transform = turn(transform, 90) +/obj/item/toy/singlecard/click_alt(mob/living/carbon/human/user) + transform = turn(transform, 90) // use the simple_rotation component to make this turn with Alt+RMB & Alt+LMB at some point in the future - TimT - return ..() + return CLICK_ACTION_SUCCESS diff --git a/code/modules/cargo/supplypod_beacon.dm b/code/modules/cargo/supplypod_beacon.dm index 999e7d76eec..8f1166002de 100644 --- a/code/modules/cargo/supplypod_beacon.dm +++ b/code/modules/cargo/supplypod_beacon.dm @@ -9,9 +9,14 @@ w_class = WEIGHT_CLASS_SMALL armor_type = /datum/armor/supplypod_beacon resistance_flags = FIRE_PROOF + interaction_flags_click = ALLOW_SILICON_REACH + /// The linked console var/obj/machinery/computer/cargo/express/express_console + /// If linked var/linked = FALSE + /// If this is ready to launch var/ready = FALSE + /// If it's been launched var/launched = FALSE /datum/armor/supplypod_beacon @@ -90,13 +95,12 @@ update_status(SP_READY) to_chat(user, span_notice("[src] linked to [C].")) -/obj/item/supplypod_beacon/AltClick(mob/user) - if (!user.can_perform_action(src, ALLOW_SILICON_REACH)) - return - if (express_console) - unlink_console() - else +/obj/item/supplypod_beacon/click_alt(mob/user) + if(!express_console) to_chat(user, span_alert("There is no linked console.")) + return CLICK_ACTION_BLOCKING + unlink_console() + return CLICK_ACTION_SUCCESS /obj/item/supplypod_beacon/attackby(obj/item/W, mob/user) if(!istype(W, /obj/item/pen)) //give a tag that is visible from the linked express console diff --git a/code/modules/cargo/universal_scanner.dm b/code/modules/cargo/universal_scanner.dm index 68fe533959a..80a821a1f5e 100644 --- a/code/modules/cargo/universal_scanner.dm +++ b/code/modules/cargo/universal_scanner.dm @@ -129,15 +129,15 @@ payments_acc = null to_chat(user, span_notice("You clear the registered account.")) -/obj/item/universal_scanner/AltClick(mob/user) - . = ..() +/obj/item/universal_scanner/click_alt(mob/user) if(!scanning_mode == SCAN_SALES_TAG) - return + return CLICK_ACTION_BLOCKING var/potential_cut = input("How much would you like to pay out to the registered card?","Percentage Profit ([round(cut_min*100)]% - [round(cut_max*100)]%)") as num|null if(!potential_cut) cut_multiplier = initial(cut_multiplier) cut_multiplier = clamp(round(potential_cut/100, cut_min), cut_min, cut_max) to_chat(user, span_notice("[round(cut_multiplier*100)]% profit will be received if a package with a barcode is sold.")) + return CLICK_ACTION_SUCCESS /obj/item/universal_scanner/examine(mob/user) . = ..() diff --git a/code/modules/clothing/glasses/_glasses.dm b/code/modules/clothing/glasses/_glasses.dm index 9fe43df5856..1bcdc21f166 100644 --- a/code/modules/clothing/glasses/_glasses.dm +++ b/code/modules/clothing/glasses/_glasses.dm @@ -65,22 +65,19 @@ H.set_eye_blur_if_lower(10 SECONDS) eyes.apply_organ_damage(5) -/obj/item/clothing/glasses/AltClick(mob/user) - if(glass_colour_type && !forced_glass_color && ishuman(user)) - var/mob/living/carbon/human/human_user = user +/obj/item/clothing/glasses/click_alt(mob/user) + if(isnull(glass_colour_type) || forced_glass_color || !ishuman(user)) + return NONE + var/mob/living/carbon/human/human_user = user - if (human_user.glasses != src) - return ..() - - if (HAS_TRAIT_FROM(human_user, TRAIT_SEE_GLASS_COLORS, GLASSES_TRAIT)) - REMOVE_TRAIT(human_user, TRAIT_SEE_GLASS_COLORS, GLASSES_TRAIT) - to_chat(human_user, span_notice("You will no longer see glasses colors.")) - else - ADD_TRAIT(human_user, TRAIT_SEE_GLASS_COLORS, GLASSES_TRAIT) - to_chat(human_user, span_notice("You will now see glasses colors.")) - human_user.update_glasses_color(src, TRUE) + if (HAS_TRAIT_FROM(human_user, TRAIT_SEE_GLASS_COLORS, GLASSES_TRAIT)) + REMOVE_TRAIT(human_user, TRAIT_SEE_GLASS_COLORS, GLASSES_TRAIT) + to_chat(human_user, span_notice("You will no longer see glasses colors.")) else - return ..() + ADD_TRAIT(human_user, TRAIT_SEE_GLASS_COLORS, GLASSES_TRAIT) + to_chat(human_user, span_notice("You will now see glasses colors.")) + human_user.update_glasses_color(src, TRUE) + return CLICK_ACTION_SUCCESS /obj/item/clothing/glasses/proc/change_glass_color(mob/living/carbon/human/H, datum/client_colour/glass_colour/new_color_type) var/old_colour_type = glass_colour_type @@ -656,18 +653,19 @@ var/datum/atom_hud/our_hud = GLOB.huds[hud] our_hud.hide_from(user) -/obj/item/clothing/glasses/debug/AltClick(mob/user) - . = ..() - if(ishuman(user)) - if(xray) - vision_flags &= ~SEE_MOBS|SEE_OBJS - REMOVE_TRAIT(user, TRAIT_XRAY_VISION, GLASSES_TRAIT) - else - vision_flags |= SEE_MOBS|SEE_OBJS - ADD_TRAIT(user, TRAIT_XRAY_VISION, GLASSES_TRAIT) - xray = !xray - var/mob/living/carbon/human/human_user = user - human_user.update_sight() +/obj/item/clothing/glasses/debug/click_alt(mob/user) + if(!ishuman(user)) + return CLICK_ACTION_BLOCKING + if(xray) + vision_flags &= ~SEE_MOBS|SEE_OBJS + REMOVE_TRAIT(user, TRAIT_XRAY_VISION, GLASSES_TRAIT) + else + vision_flags |= SEE_MOBS|SEE_OBJS + ADD_TRAIT(user, TRAIT_XRAY_VISION, GLASSES_TRAIT) + xray = !xray + var/mob/living/carbon/human/human_user = user + human_user.update_sight() + return CLICK_ACTION_SUCCESS /obj/item/clothing/glasses/regular/kim name = "binoclard lenses" diff --git a/code/modules/clothing/head/jobs.dm b/code/modules/clothing/head/jobs.dm index f68523fcdae..b300ff99179 100644 --- a/code/modules/clothing/head/jobs.dm +++ b/code/modules/clothing/head/jobs.dm @@ -173,6 +173,8 @@ armor_type = /datum/armor/fedora_det_hat icon_state = "detective" inhand_icon_state = "det_hat" + interaction_flags_click = NEED_DEXTERITY|NEED_HANDS + /// Cooldown for retrieving precious candy corn on alt click var/candy_cooldown = 0 dog_fashion = /datum/dog_fashion/head/detective ///Path for the flask that spawns inside their hat roundstart @@ -198,17 +200,16 @@ . = ..() . += span_notice("Alt-click to take a candy corn.") -/obj/item/clothing/head/fedora/det_hat/AltClick(mob/user) - . = ..() - if(loc != user || !user.can_perform_action(src, NEED_DEXTERITY|NEED_HANDS)) - return - if(candy_cooldown < world.time) - var/obj/item/food/candy_corn/CC = new /obj/item/food/candy_corn(src) - user.put_in_hands(CC) - to_chat(user, span_notice("You slip a candy corn from your hat.")) - candy_cooldown = world.time+1200 - else +/obj/item/clothing/head/fedora/det_hat/click_alt(mob/user) + if(candy_cooldown >= world.time) to_chat(user, span_warning("You just took a candy corn! You should wait a couple minutes, lest you burn through your stash.")) + return CLICK_ACTION_BLOCKING + + var/obj/item/food/candy_corn/CC = new /obj/item/food/candy_corn(src) + user.put_in_hands(CC) + to_chat(user, span_notice("You slip a candy corn from your hat.")) + candy_cooldown = world.time+1200 + return CLICK_ACTION_SUCCESS /obj/item/clothing/head/fedora/det_hat/minor flask_path = /obj/item/reagent_containers/cup/glass/flask/det/minor @@ -221,6 +222,7 @@ icon_state = "detective" inhand_icon_state = "det_hat" dog_fashion = /datum/dog_fashion/head/detective + interaction_flags_click = FORBID_TELEKINESIS_REACH ///prefix our phrases must begin with var/prefix = "go go gadget" ///an assoc list of phrase = item (like gun = revolver) @@ -297,14 +299,12 @@ return user.put_in_inactive_hand(items_by_phrase[phrase]) -/obj/item/clothing/head/fedora/inspector_hat/AltClick(mob/user) - . = ..() - if(!user.can_perform_action(src, FORBID_TELEKINESIS_REACH)) - return +/obj/item/clothing/head/fedora/inspector_hat/click_alt(mob/user) var/new_prefix = tgui_input_text(user, "What should be the new prefix?", "Activation prefix", prefix, max_length = 24) if(!new_prefix || !user.can_perform_action(src, FORBID_TELEKINESIS_REACH)) - return + return CLICK_ACTION_BLOCKING prefix = new_prefix + return CLICK_ACTION_SUCCESS /obj/item/clothing/head/fedora/inspector_hat/Exited(atom/movable/gone, direction) . = ..() diff --git a/code/modules/clothing/head/soft_caps.dm b/code/modules/clothing/head/soft_caps.dm index 0b0a6fb4d50..92517d4a7dd 100644 --- a/code/modules/clothing/head/soft_caps.dm +++ b/code/modules/clothing/head/soft_caps.dm @@ -5,11 +5,14 @@ worn_icon = 'icons/mob/clothing/head/hats.dmi' icon_state = "cargosoft" inhand_icon_state = "greyscale_softcap" //todo wip + interaction_flags_click = NEED_DEXTERITY + /// For setting icon archetype var/soft_type = "cargo" + /// If there is a suffix to append var/soft_suffix = "soft" dog_fashion = /datum/dog_fashion/head/cargo_tech - + /// Whether this is on backwards... Woah, cool var/flipped = FALSE /obj/item/clothing/head/soft/dropped() @@ -24,10 +27,9 @@ flip(usr) -/obj/item/clothing/head/soft/AltClick(mob/user) - ..() - if(user.can_perform_action(src, NEED_DEXTERITY)) - flip(user) +/obj/item/clothing/head/soft/click_alt(mob/user) + flip(user) + return CLICK_ACTION_SUCCESS /obj/item/clothing/head/soft/proc/flip(mob/user) diff --git a/code/modules/clothing/masks/animal_masks.dm b/code/modules/clothing/masks/animal_masks.dm index c2013b99177..5df5c6738d8 100644 --- a/code/modules/clothing/masks/animal_masks.dm +++ b/code/modules/clothing/masks/animal_masks.dm @@ -46,11 +46,12 @@ GLOBAL_LIST_INIT(cursed_animal_masks, list( if(clothing_flags & VOICEBOX_TOGGLABLE) . += span_notice("Its voicebox is currently [clothing_flags & VOICEBOX_DISABLED ? "disabled" : "enabled"]. Alt-click to toggle it.") -/obj/item/clothing/mask/animal/AltClick(mob/user) - . = ..() - if(clothing_flags & VOICEBOX_TOGGLABLE) - clothing_flags ^= VOICEBOX_DISABLED - to_chat(user, span_notice("You [clothing_flags & VOICEBOX_DISABLED ? "disabled" : "enabled"] [src]'s voicebox.")) +/obj/item/clothing/mask/animal/click_alt(mob/user) + if(!(clothing_flags & VOICEBOX_TOGGLABLE)) + return NONE + clothing_flags ^= VOICEBOX_DISABLED + to_chat(user, span_notice("You [clothing_flags & VOICEBOX_DISABLED ? "disabled" : "enabled"] [src]'s voicebox.")) + return CLICK_ACTION_SUCCESS /obj/item/clothing/mask/animal/proc/make_cursed() //apply cursed effects. ADD_TRAIT(src, TRAIT_NODROP, CURSED_MASK_TRAIT) diff --git a/code/modules/clothing/masks/bandana.dm b/code/modules/clothing/masks/bandana.dm index 70f7d2ef537..6f03ba178ea 100644 --- a/code/modules/clothing/masks/bandana.dm +++ b/code/modules/clothing/masks/bandana.dm @@ -46,34 +46,36 @@ worn_icon_state = initial(worn_icon_state) undyeable = initial(undyeable) -/obj/item/clothing/mask/bandana/AltClick(mob/user) - . = ..() - if(iscarbon(user)) - var/mob/living/carbon/char = user - var/matrix/widen = matrix() - if((char.get_item_by_slot(ITEM_SLOT_NECK) == src) || (char.get_item_by_slot(ITEM_SLOT_MASK) == src) || (char.get_item_by_slot(ITEM_SLOT_HEAD) == src)) - to_chat(user, span_warning("You can't tie [src] while wearing it!")) - return - else if(slot_flags & ITEM_SLOT_HEAD) - to_chat(user, span_warning("You must undo [src] before you can tie it into a neckerchief!")) - return - else if(!user.is_holding(src)) - to_chat(user, span_warning("You must be holding [src] in order to tie it!")) - return +/obj/item/clothing/mask/bandana/click_alt(mob/user) + if(!iscarbon(user)) + return NONE - if(slot_flags & ITEM_SLOT_MASK) - undyeable = TRUE - slot_flags = ITEM_SLOT_NECK - worn_y_offset = -3 - widen.Scale(1.25, 1) - transform = widen - user.visible_message(span_notice("[user] ties [src] up like a neckerchief."), span_notice("You tie [src] up like a neckerchief.")) - else - undyeable = initial(undyeable) - slot_flags = initial(slot_flags) - worn_y_offset = initial(worn_y_offset) - transform = initial(transform) - user.visible_message(span_notice("[user] unties the neckercheif."), span_notice("You untie the neckercheif.")) + var/mob/living/carbon/char = user + var/matrix/widen = matrix() + if((char.get_item_by_slot(ITEM_SLOT_NECK) == src) || (char.get_item_by_slot(ITEM_SLOT_MASK) == src) || (char.get_item_by_slot(ITEM_SLOT_HEAD) == src)) + to_chat(user, span_warning("You can't tie [src] while wearing it!")) + return CLICK_ACTION_BLOCKING + else if(slot_flags & ITEM_SLOT_HEAD) + to_chat(user, span_warning("You must undo [src] before you can tie it into a neckerchief!")) + return CLICK_ACTION_BLOCKING + else if(!user.is_holding(src)) + to_chat(user, span_warning("You must be holding [src] in order to tie it!")) + return CLICK_ACTION_BLOCKING + + if(slot_flags & ITEM_SLOT_MASK) + undyeable = TRUE + slot_flags = ITEM_SLOT_NECK + worn_y_offset = -3 + widen.Scale(1.25, 1) + transform = widen + user.visible_message(span_notice("[user] ties [src] up like a neckerchief."), span_notice("You tie [src] up like a neckerchief.")) + else + undyeable = initial(undyeable) + slot_flags = initial(slot_flags) + worn_y_offset = initial(worn_y_offset) + transform = initial(transform) + user.visible_message(span_notice("[user] unties the neckercheif."), span_notice("You untie the neckercheif.")) + return CLICK_ACTION_SUCCESS /obj/item/clothing/mask/bandana/red name = "red bandana" @@ -222,14 +224,16 @@ greyscale_config_inhand_left = /datum/greyscale_config/facescarf/inhands_left greyscale_config_inhand_right = /datum/greyscale_config/facescarf/inhands_right flags_1 = IS_PLAYER_COLORABLE_1 + interaction_flags_click = NEED_DEXTERITY /obj/item/clothing/mask/facescarf/attack_self(mob/user) adjustmask(user) -/obj/item/clothing/mask/facescarf/AltClick(mob/user) - ..() - if(user.can_perform_action(src, NEED_DEXTERITY)) - adjustmask(user) + +/obj/item/clothing/mask/facescarf/click_alt(mob/user) + adjustmask(user) + return CLICK_ACTION_SUCCESS + /obj/item/clothing/mask/facescarf/examine(mob/user) . = ..() diff --git a/code/modules/clothing/masks/breath.dm b/code/modules/clothing/masks/breath.dm index 8ba15fe521d..0249f0b1321 100644 --- a/code/modules/clothing/masks/breath.dm +++ b/code/modules/clothing/masks/breath.dm @@ -12,6 +12,7 @@ flags_cover = MASKCOVERSMOUTH visor_flags_cover = MASKCOVERSMOUTH resistance_flags = NONE + interaction_flags_click = NEED_DEXTERITY /datum/armor/mask_breath bio = 50 @@ -23,10 +24,9 @@ /obj/item/clothing/mask/breath/attack_self(mob/user) adjustmask(user) -/obj/item/clothing/mask/breath/AltClick(mob/user) - ..() - if(user.can_perform_action(src, NEED_DEXTERITY)) - adjustmask(user) +/obj/item/clothing/mask/breath/click_alt(mob/user) + adjustmask(user) + return CLICK_ACTION_SUCCESS /obj/item/clothing/mask/breath/examine(mob/user) . = ..() diff --git a/code/modules/clothing/masks/costume.dm b/code/modules/clothing/masks/costume.dm index 893455dcdd0..626d8ce4a65 100644 --- a/code/modules/clothing/masks/costume.dm +++ b/code/modules/clothing/masks/costume.dm @@ -12,14 +12,6 @@ "Pleading" = "pleading" ) -/obj/item/clothing/mask/joy/Initialize(mapload) - . = ..() - register_context() - -/obj/item/clothing/mask/joy/add_context(atom/source, list/context, obj/item/held_item, mob/user) - . = ..() - context[SCREENTIP_CONTEXT_ALT_LMB] = "Change Emotion" - return CONTEXTUAL_SCREENTIP_SET /obj/item/clothing/mask/joy/reskin_obj(mob/user) . = ..() diff --git a/code/modules/clothing/neck/_neck.dm b/code/modules/clothing/neck/_neck.dm index d2e019d0c44..a41442c0fb9 100644 --- a/code/modules/clothing/neck/_neck.dm +++ b/code/modules/clothing/neck/_neck.dm @@ -73,10 +73,9 @@ else . += span_notice("The tie can be untied with Alt-Click.") -/obj/item/clothing/neck/tie/AltClick(mob/user) - . = ..() +/obj/item/clothing/neck/tie/click_alt(mob/user) if(clip_on) - return + return NONE to_chat(user, span_notice("You concentrate as you begin [is_tied ? "untying" : "tying"] [src]...")) var/tie_timer_actual = tie_timer // Mirrors give you a boost to your tying speed. I realize this stacks and I think that's hilarious. @@ -88,11 +87,11 @@ // Tie/Untie our tie if(!do_after(user, tie_timer_actual)) to_chat(user, span_notice("Your fingers fumble away from [src] as your concentration breaks.")) - return + return CLICK_ACTION_BLOCKING // Clumsy & Dumb people have trouble tying their ties. if((HAS_TRAIT(user, TRAIT_CLUMSY) || HAS_TRAIT(user, TRAIT_DUMB)) && prob(50)) to_chat(user, span_notice("You just can't seem to get a proper grip on [src]!")) - return + return CLICK_ACTION_BLOCKING // Success! is_tied = !is_tied user.visible_message( @@ -101,6 +100,7 @@ ) update_appearance(UPDATE_ICON) user.update_clothing(ITEM_SLOT_NECK) + return CLICK_ACTION_SUCCESS /obj/item/clothing/neck/tie/update_icon() . = ..() diff --git a/code/modules/clothing/spacesuits/_spacesuits.dm b/code/modules/clothing/spacesuits/_spacesuits.dm index b145516fdd9..74741513d70 100644 --- a/code/modules/clothing/spacesuits/_spacesuits.dm +++ b/code/modules/clothing/spacesuits/_spacesuits.dm @@ -58,11 +58,17 @@ equip_delay_other = 80 resistance_flags = NONE actions_types = list(/datum/action/item_action/toggle_spacesuit) - var/temperature_setting = BODYTEMP_NORMAL /// The default temperature setting - var/obj/item/stock_parts/cell/cell = /obj/item/stock_parts/cell/high /// If this is a path, this gets created as an object in Initialize. - var/cell_cover_open = FALSE /// Status of the cell cover on the suit - var/thermal_on = FALSE /// Status of the thermal regulator - var/show_hud = TRUE /// If this is FALSE the batery status UI will be disabled. This is used for suits that don't use bateries like the changeling's flesh suit mutation. + interaction_flags_click = NEED_DEXTERITY + /// The default temperature setting + var/temperature_setting = BODYTEMP_NORMAL + /// If this is a path, this gets created as an object in Initialize. + var/obj/item/stock_parts/cell/cell = /obj/item/stock_parts/cell/high + /// Status of the cell cover on the suit + var/cell_cover_open = FALSE + /// Status of the thermal regulator + var/thermal_on = FALSE + /// If this is FALSE the batery status UI will be disabled. This is used for suits that don't use bateries like the changeling's flesh suit mutation. + var/show_hud = TRUE /datum/armor/suit_space bio = 100 @@ -190,10 +196,9 @@ return /// Open the cell cover when ALT+Click on the suit -/obj/item/clothing/suit/space/AltClick(mob/living/user) - if(!user.can_perform_action(src, NEED_DEXTERITY)) - return ..() +/obj/item/clothing/suit/space/click_alt(mob/living/user) toggle_spacesuit_cell(user) + return CLICK_ACTION_SUCCESS /// Remove the cell whent he cover is open on CTRL+Click /obj/item/clothing/suit/space/CtrlClick(mob/living/user) diff --git a/code/modules/clothing/spacesuits/plasmamen.dm b/code/modules/clothing/spacesuits/plasmamen.dm index ce21351c885..02a54f194ea 100644 --- a/code/modules/clothing/spacesuits/plasmamen.dm +++ b/code/modules/clothing/spacesuits/plasmamen.dm @@ -87,9 +87,9 @@ else . += span_notice("There's nothing placed on the helmet.") -/obj/item/clothing/head/helmet/space/plasmaman/AltClick(mob/user) - if(user.can_perform_action(src)) - toggle_welding_screen(user) +/obj/item/clothing/head/helmet/space/plasmaman/click_alt(mob/user) + toggle_welding_screen(user) + return CLICK_ACTION_SUCCESS /obj/item/clothing/head/helmet/space/plasmaman/ui_action_click(mob/user, action) if(istype(action, /datum/action/item_action/toggle_welding_screen)) diff --git a/code/modules/clothing/suits/wintercoats.dm b/code/modules/clothing/suits/wintercoats.dm index a5a1fef7903..7c26a238354 100644 --- a/code/modules/clothing/suits/wintercoats.dm +++ b/code/modules/clothing/suits/wintercoats.dm @@ -47,12 +47,7 @@ . += span_notice("Alt-click to [zipped ? "un" : ""]zip.") -/obj/item/clothing/suit/hooded/wintercoat/AltClick(mob/user) - . = ..() - - if (. == FALSE) // Direct check for FALSE, because that's the specific case we want to propagate, not just null. - return FALSE - +/obj/item/clothing/suit/hooded/wintercoat/click_alt(mob/user) zipped = !zipped worn_icon_state = "[initial(icon_state)][zipped ? "_t" : ""]" balloon_alert(user, "[zipped ? "" : "un"]zipped") @@ -60,6 +55,7 @@ if(ishuman(loc)) var/mob/living/carbon/human/wearer = loc wearer.update_worn_oversuit() + return CLICK_ACTION_SUCCESS /obj/item/clothing/head/hooded/winterhood name = "winter hood" diff --git a/code/modules/clothing/under/_under.dm b/code/modules/clothing/under/_under.dm index 20a117e112e..e91da4305a6 100644 --- a/code/modules/clothing/under/_under.dm +++ b/code/modules/clothing/under/_under.dm @@ -51,33 +51,37 @@ if(random_sensor) //make the sensor mode favor higher levels, except coords. sensor_mode = pick(SENSOR_VITALS, SENSOR_VITALS, SENSOR_VITALS, SENSOR_LIVING, SENSOR_LIVING, SENSOR_COORDS, SENSOR_COORDS, SENSOR_OFF) - register_context() + if(!unique_reskin) // Already registered via unique reskin + register_context() AddElement(/datum/element/update_icon_updates_onmob, flags = ITEM_SLOT_ICLOTHING|ITEM_SLOT_OCLOTHING, body = TRUE) -/obj/item/clothing/under/add_context(atom/source, list/context, obj/item/held_item, mob/living/user) - . = NONE +/obj/item/clothing/under/add_context(atom/source, list/context, obj/item/held_item, mob/living/user) + . = ..() + + var/changed = FALSE if(isnull(held_item) && has_sensor == HAS_SENSORS) context[SCREENTIP_CONTEXT_RMB] = "Toggle suit sensors" - . = CONTEXTUAL_SCREENTIP_SET + changed = TRUE if(istype(held_item, /obj/item/clothing/accessory) && length(attached_accessories) < max_number_of_accessories) context[SCREENTIP_CONTEXT_LMB] = "Attach accessory" - . = CONTEXTUAL_SCREENTIP_SET + changed = TRUE if(LAZYLEN(attached_accessories)) context[SCREENTIP_CONTEXT_ALT_RMB] = "Remove accessory" - . = CONTEXTUAL_SCREENTIP_SET + changed = TRUE if(istype(held_item, /obj/item/stack/cable_coil) && has_sensor == BROKEN_SENSORS) context[SCREENTIP_CONTEXT_LMB] = "Repair suit sensors" - . = CONTEXTUAL_SCREENTIP_SET + changed = TRUE if(can_adjust && adjusted != DIGITIGRADE_STYLE) context[SCREENTIP_CONTEXT_ALT_LMB] = "Wear [adjusted == ALT_STYLE ? "normally" : "casually"]" - . = CONTEXTUAL_SCREENTIP_SET + changed = TRUE + + return changed ? CONTEXTUAL_SCREENTIP_SET : NONE - return . /obj/item/clothing/under/worn_overlays(mutable_appearance/standing, isinhands = FALSE) . = ..() @@ -347,17 +351,14 @@ return TRUE -/obj/item/clothing/under/AltClick(mob/user) - . = ..() - if(.) - return - +/obj/item/clothing/under/click_alt(mob/user) if(!can_adjust) balloon_alert(user, "can't be adjusted!") - return + return CLICK_ACTION_BLOCKING if(!can_use(user)) - return + return NONE rolldown() + return CLICK_ACTION_SUCCESS /obj/item/clothing/under/alt_click_secondary(mob/user) . = ..() diff --git a/code/modules/clothing/under/costume.dm b/code/modules/clothing/under/costume.dm index e2ecb135720..9259bc78c96 100644 --- a/code/modules/clothing/under/costume.dm +++ b/code/modules/clothing/under/costume.dm @@ -239,6 +239,7 @@ "Black" = "black_mech_suit", ) + /obj/item/clothing/under/costume/russian_officer name = "\improper Russian officer's uniform" desc = "The latest in fashionable russian outfits." diff --git a/code/modules/detectivework/scanner.dm b/code/modules/detectivework/scanner.dm index 6ce6b0e67a6..82c77839da7 100644 --- a/code/modules/detectivework/scanner.dm +++ b/code/modules/detectivework/scanner.dm @@ -218,20 +218,20 @@ /proc/get_timestamp() return time2text(world.time + 432000, ":ss") -/obj/item/detective_scanner/AltClick(mob/living/user) - // Best way for checking if a player can use while not incapacitated, etc - if(!user.can_perform_action(src)) - return +/obj/item/detective_scanner/click_alt(mob/living/user) if(!LAZYLEN(log)) balloon_alert(user, "no logs!") - return + return CLICK_ACTION_BLOCKING if(scanner_busy) balloon_alert(user, "scanner busy!") - return + return CLICK_ACTION_BLOCKING balloon_alert(user, "deleting logs...") - if(do_after(user, 3 SECONDS, target = src)) - balloon_alert(user, "logs cleared") - log = list() + if(!do_after(user, 3 SECONDS, target = src)) + return CLICK_ACTION_BLOCKING + balloon_alert(user, "logs cleared") + log = list() + return CLICK_ACTION_SUCCESS + /obj/item/detective_scanner/examine(mob/user) . = ..() diff --git a/code/modules/experisci/experiment/handlers/experiment_handler.dm b/code/modules/experisci/experiment/handlers/experiment_handler.dm index 389140bff1c..d1482c61c98 100644 --- a/code/modules/experisci/experiment/handlers/experiment_handler.dm +++ b/code/modules/experisci/experiment/handlers/experiment_handler.dm @@ -236,6 +236,7 @@ /datum/component/experiment_handler/proc/configure_experiment(datum/source, mob/user) SIGNAL_HANDLER INVOKE_ASYNC(src, PROC_REF(ui_interact), user) + return CLICK_ACTION_SUCCESS /** * Attempts to show the user the experiment configuration panel diff --git a/code/modules/fishing/aquarium/aquarium.dm b/code/modules/fishing/aquarium/aquarium.dm index fe281d7e511..8a719c16f70 100644 --- a/code/modules/fishing/aquarium/aquarium.dm +++ b/code/modules/fishing/aquarium/aquarium.dm @@ -159,10 +159,7 @@ if(panel_open && reagents.total_volume) . += span_notice("You can use a plunger to empty the feed storage.") -/obj/structure/aquarium/AltClick(mob/living/user) - . = ..() - if(!user.can_perform_action(src)) - return +/obj/structure/aquarium/click_alt(mob/living/user) panel_open = !panel_open balloon_alert(user, "panel [panel_open ? "open" : "closed"]") if(panel_open) @@ -170,6 +167,7 @@ else reagents.flags &= ~(TRANSPARENT|REFILLABLE) update_appearance() + return CLICK_ACTION_SUCCESS /obj/structure/aquarium/wrench_act(mob/living/user, obj/item/tool) . = ..() diff --git a/code/modules/food_and_drinks/machinery/icecream_vat.dm b/code/modules/food_and_drinks/machinery/icecream_vat.dm index d4de5991995..cae1b260249 100644 --- a/code/modules/food_and_drinks/machinery/icecream_vat.dm +++ b/code/modules/food_and_drinks/machinery/icecream_vat.dm @@ -154,13 +154,12 @@ return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN return ..() -/obj/machinery/icecream_vat/AltClick(mob/user) - if(!user.can_interact_with(src)) - return FALSE - if(custom_ice_cream_beaker) - balloon_alert(user, "removed beaker") - try_put_in_hand(custom_ice_cream_beaker, user) - return ..() +/obj/machinery/icecream_vat/click_alt(mob/user) + if(!custom_ice_cream_beaker) + return CLICK_ACTION_BLOCKING + balloon_alert(user, "removed beaker") + try_put_in_hand(custom_ice_cream_beaker, user) + return CLICK_ACTION_SUCCESS /obj/machinery/icecream_vat/interact(mob/living/user) . = ..() diff --git a/code/modules/food_and_drinks/machinery/microwave.dm b/code/modules/food_and_drinks/machinery/microwave.dm index dfb6ac9b2de..ea4d12749e6 100644 --- a/code/modules/food_and_drinks/machinery/microwave.dm +++ b/code/modules/food_and_drinks/machinery/microwave.dm @@ -31,6 +31,7 @@ light_color = LIGHT_COLOR_DIM_YELLOW light_power = 3 anchored_tabletop_offset = 6 + interaction_flags_click = ALLOW_SILICON_REACH /// Is its function wire cut? var/wire_disabled = FALSE /// Wire cut to run mode backwards @@ -473,16 +474,16 @@ return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN -/obj/machinery/microwave/AltClick(mob/user, list/modifiers) - if(user.can_perform_action(src, ALLOW_SILICON_REACH)) - if(!vampire_charging_capable) - return +/obj/machinery/microwave/click_alt(mob/user, list/modifiers) + if(!vampire_charging_capable) + return NONE - vampire_charging_enabled = !vampire_charging_enabled - balloon_alert(user, "set to [vampire_charging_enabled ? "charge" : "cook"]") - playsound(src, 'sound/machines/twobeep_high.ogg', 50, FALSE) - if(HAS_SILICON_ACCESS(user)) - visible_message(span_notice("[user] sets \the [src] to [vampire_charging_enabled ? "charge" : "cook"]."), blind_message = span_notice("You hear \the [src] make an informative beep!")) + vampire_charging_enabled = !vampire_charging_enabled + balloon_alert(user, "set to [vampire_charging_enabled ? "charge" : "cook"]") + playsound(src, 'sound/machines/twobeep_high.ogg', 50, FALSE) + if(HAS_SILICON_ACCESS(user)) + visible_message(span_notice("[user] sets \the [src] to [vampire_charging_enabled ? "charge" : "cook"]."), blind_message = span_notice("You hear \the [src] make an informative beep!")) + return CLICK_ACTION_SUCCESS /obj/machinery/microwave/CtrlClick(mob/user) . = ..() diff --git a/code/modules/hydroponics/biogenerator.dm b/code/modules/hydroponics/biogenerator.dm index 260c4042a0a..35bf611b506 100644 --- a/code/modules/hydroponics/biogenerator.dm +++ b/code/modules/hydroponics/biogenerator.dm @@ -13,6 +13,7 @@ density = TRUE circuit = /obj/item/circuitboard/machine/biogenerator processing_flags = START_PROCESSING_MANUALLY + interaction_flags_click = FORBID_TELEKINESIS_REACH /// Whether the biogenerator is currently processing biomass or not. var/processing = FALSE /// The reagent container that is currently inside of the biomass generator. Can be null. @@ -272,10 +273,9 @@ to_chat(user, span_warning("You cannot put \the [attacking_item] in \the [src]!")) -/obj/machinery/biogenerator/AltClick(mob/living/user) - . = ..() - if(user.can_perform_action(src, FORBID_TELEKINESIS_REACH) && can_interact(user)) - eject_beaker(user) +/obj/machinery/biogenerator/click_alt(mob/living/user) + eject_beaker(user) + return CLICK_ACTION_SUCCESS /// Activates biomass processing and converts all inserted food products into biomass diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm index 669b22ed0ac..9b23f0b25b0 100644 --- a/code/modules/hydroponics/hydroponics.dm +++ b/code/modules/hydroponics/hydroponics.dm @@ -1099,8 +1099,6 @@ set_self_sustaining(!self_sustaining) to_chat(user, span_notice("You [self_sustaining ? "activate" : "deactivated"] [src]'s autogrow function[self_sustaining ? ", maintaining the tray's health while using high amounts of power" : ""].")) -/obj/machinery/hydroponics/AltClick(mob/user) - return ..() // This hotkey is BLACKLISTED since it's used by /datum/component/simple_rotation /obj/machinery/hydroponics/attack_hand_secondary(mob/user, list/modifiers) . = ..() diff --git a/code/modules/lootpanel/_lootpanel.dm b/code/modules/lootpanel/_lootpanel.dm index 86a94cc9957..339a79d77fa 100644 --- a/code/modules/lootpanel/_lootpanel.dm +++ b/code/modules/lootpanel/_lootpanel.dm @@ -55,9 +55,6 @@ /datum/lootpanel/ui_status(mob/user, datum/ui_state/state) - if(!source_turf.Adjacent(user)) - return UI_CLOSE - if(user.incapacitated()) return UI_DISABLED diff --git a/code/modules/lootpanel/ui.dm b/code/modules/lootpanel/ui.dm index 3c829871c60..c7f0cf2358d 100644 --- a/code/modules/lootpanel/ui.dm +++ b/code/modules/lootpanel/ui.dm @@ -20,10 +20,6 @@ if(isnull(ref)) return FALSE - if(!source_turf.Adjacent(user)) // Source tile is no longer valid - reset_contents() - return FALSE - var/datum/search_object/index = locate(ref) in contents var/atom/thing = index?.item if(QDELETED(index) || QDELETED(thing)) // Obj is gone diff --git a/code/modules/mapfluff/ruins/spaceruin_code/hilbertshotel.dm b/code/modules/mapfluff/ruins/spaceruin_code/hilbertshotel.dm index a8fac3da76c..8906a6d2555 100644 --- a/code/modules/mapfluff/ruins/spaceruin_code/hilbertshotel.dm +++ b/code/modules/mapfluff/ruins/spaceruin_code/hilbertshotel.dm @@ -344,15 +344,14 @@ GLOBAL_VAR_INIT(hhMysteryRoomNumber, rand(1, 999999)) if(get_dist(get_turf(src), get_turf(user)) <= 1) promptExit(user) -/turf/closed/indestructible/hoteldoor/AltClick(mob/user) - . = ..() - if(get_dist(get_turf(src), get_turf(user)) <= 1) - to_chat(user, span_notice("You peak through the door's bluespace peephole...")) - user.reset_perspective(parentSphere) - var/datum/action/peephole_cancel/PHC = new - user.overlay_fullscreen("remote_view", /atom/movable/screen/fullscreen/impaired, 1) - PHC.Grant(user) - RegisterSignal(user, COMSIG_MOVABLE_MOVED, PROC_REF(check_eye)) +/turf/closed/indestructible/hoteldoor/click_alt(mob/user) + to_chat(user, span_notice("You peak through the door's bluespace peephole...")) + user.reset_perspective(parentSphere) + var/datum/action/peephole_cancel/PHC = new + user.overlay_fullscreen("remote_view", /atom/movable/screen/fullscreen/impaired, 1) + PHC.Grant(user) + RegisterSignal(user, COMSIG_MOVABLE_MOVED, PROC_REF(check_eye)) + return CLICK_ACTION_SUCCESS /turf/closed/indestructible/hoteldoor/proc/check_eye(mob/user, atom/oldloc, direction) SIGNAL_HANDLER diff --git a/code/modules/mining/abandoned_crates.dm b/code/modules/mining/abandoned_crates.dm index 5022dac212c..0b029bc3b63 100644 --- a/code/modules/mining/abandoned_crates.dm +++ b/code/modules/mining/abandoned_crates.dm @@ -60,10 +60,9 @@ return ..() -/obj/structure/closet/crate/secure/loot/AltClick(mob/living/user) - if(!user.can_perform_action(src)) - return - return attack_hand(user) //this helps you not blow up so easily by overriding unlocking which results in an immediate boom. +/obj/structure/closet/crate/secure/loot/click_alt(mob/living/user) + attack_hand(user) //this helps you not blow up so easily by overriding unlocking which results in an immediate boom. + return CLICK_ACTION_SUCCESS /obj/structure/closet/crate/secure/loot/attackby(obj/item/W, mob/user) if(locked) diff --git a/code/modules/mining/equipment/explorer_gear.dm b/code/modules/mining/equipment/explorer_gear.dm index 10ba871176f..4845b0f9c00 100644 --- a/code/modules/mining/equipment/explorer_gear.dm +++ b/code/modules/mining/equipment/explorer_gear.dm @@ -131,24 +131,25 @@ hoodtype = /obj/item/clothing/head/hooded/cloakhood/goliath body_parts_covered = CHEST|GROIN|ARMS -/obj/item/clothing/suit/hooded/cloak/goliath/AltClick(mob/user) - . = ..() - if(iscarbon(user)) - var/mob/living/carbon/char = user - if((char.get_item_by_slot(ITEM_SLOT_NECK) == src) || (char.get_item_by_slot(ITEM_SLOT_OCLOTHING) == src)) - to_chat(user, span_warning("You can't adjust [src] while wearing it!")) - return - if(!user.is_holding(src)) - to_chat(user, span_warning("You must be holding [src] in order to adjust it!")) - return - if(slot_flags & ITEM_SLOT_OCLOTHING) - slot_flags = ITEM_SLOT_NECK - set_armor(/datum/armor/none) - user.visible_message(span_notice("[user] adjusts their [src] for ceremonial use."), span_notice("You adjust your [src] for ceremonial use.")) - else - slot_flags = initial(slot_flags) - set_armor(initial(armor_type)) - user.visible_message(span_notice("[user] adjusts their [src] for defensive use."), span_notice("You adjust your [src] for defensive use.")) +/obj/item/clothing/suit/hooded/cloak/goliath/click_alt(mob/user) + if(!iscarbon(user)) + return NONE + var/mob/living/carbon/char = user + if((char.get_item_by_slot(ITEM_SLOT_NECK) == src) || (char.get_item_by_slot(ITEM_SLOT_OCLOTHING) == src)) + to_chat(user, span_warning("You can't adjust [src] while wearing it!")) + return CLICK_ACTION_BLOCKING + if(!user.is_holding(src)) + to_chat(user, span_warning("You must be holding [src] in order to adjust it!")) + return CLICK_ACTION_BLOCKING + if(slot_flags & ITEM_SLOT_OCLOTHING) + slot_flags = ITEM_SLOT_NECK + set_armor(/datum/armor/none) + user.visible_message(span_notice("[user] adjusts their [src] for ceremonial use."), span_notice("You adjust your [src] for ceremonial use.")) + else + slot_flags = initial(slot_flags) + set_armor(initial(armor_type)) + user.visible_message(span_notice("[user] adjusts their [src] for defensive use."), span_notice("You adjust your [src] for defensive use.")) + return CLICK_ACTION_SUCCESS /datum/armor/cloak_goliath melee = 35 diff --git a/code/modules/mining/equipment/marker_beacons.dm b/code/modules/mining/equipment/marker_beacons.dm index 9a7913278e8..c33181dd806 100644 --- a/code/modules/mining/equipment/marker_beacons.dm +++ b/code/modules/mining/equipment/marker_beacons.dm @@ -59,16 +59,15 @@ GLOBAL_LIST_INIT(marker_beacon_colors, sort_list(list( var/obj/structure/marker_beacon/M = new(user.loc, picked_color) transfer_fingerprints_to(M) -/obj/item/stack/marker_beacon/AltClick(mob/living/user) - if(!istype(user) || !user.can_perform_action(src)) - return +/obj/item/stack/marker_beacon/click_alt(mob/living/user) var/input_color = tgui_input_list(user, "Choose a color", "Beacon Color", GLOB.marker_beacon_colors) if(isnull(input_color)) - return - if(!istype(user) || !user.can_perform_action(src)) - return + return CLICK_ACTION_BLOCKING + if(!user.can_perform_action(src)) + return CLICK_ACTION_BLOCKING picked_color = input_color update_appearance() + return CLICK_ACTION_SUCCESS /obj/structure/marker_beacon name = "marker beacon" @@ -154,17 +153,15 @@ GLOBAL_LIST_INIT(marker_beacon_colors, sort_list(list( return return ..() -/obj/structure/marker_beacon/AltClick(mob/living/user) - ..() - if(!istype(user) || !user.can_perform_action(src)) - return +/obj/structure/marker_beacon/click_alt(mob/living/user) var/input_color = tgui_input_list(user, "Choose a color", "Beacon Color", GLOB.marker_beacon_colors) if(isnull(input_color)) - return - if(!istype(user) || !user.can_perform_action(src)) - return + return CLICK_ACTION_BLOCKING + if(!user.can_perform_action(src)) + return NONE picked_color = input_color update_appearance() + return CLICK_ACTION_SUCCESS /* Preset marker beacon types, for mapping */ diff --git a/code/modules/mining/machine_redemption.dm b/code/modules/mining/machine_redemption.dm index 0b9b7895c6b..14460cffb1b 100644 --- a/code/modules/mining/machine_redemption.dm +++ b/code/modules/mining/machine_redemption.dm @@ -203,18 +203,16 @@ default_unfasten_wrench(user, tool) return ITEM_INTERACT_SUCCESS -/obj/machinery/mineral/ore_redemption/AltClick(mob/living/user) - . = ..() - if(!user.can_perform_action(src)) - return - if(panel_open) - input_dir = turn(input_dir, -90) - output_dir = turn(output_dir, -90) - to_chat(user, span_notice("You change [src]'s I/O settings, setting the input to [dir2text(input_dir)] and the output to [dir2text(output_dir)].")) - unregister_input_turf() // someone just rotated the input and output directions, unregister the old turf - register_input_turf() // register the new one - update_appearance(UPDATE_OVERLAYS) - return TRUE +/obj/machinery/mineral/ore_redemption/click_alt(mob/living/user) + if(!panel_open) + return CLICK_ACTION_BLOCKING + input_dir = turn(input_dir, -90) + output_dir = turn(output_dir, -90) + to_chat(user, span_notice("You change [src]'s I/O settings, setting the input to [dir2text(input_dir)] and the output to [dir2text(output_dir)].")) + unregister_input_turf() // someone just rotated the input and output directions, unregister the old turf + register_input_turf() // register the new one + update_appearance(UPDATE_OVERLAYS) + return CLICK_ACTION_SUCCESS /obj/machinery/mineral/ore_redemption/ui_interact(mob/user, datum/tgui/ui) ui = SStgui.try_update_ui(user, src, ui) diff --git a/code/modules/mob/living/basic/bots/_bots.dm b/code/modules/mob/living/basic/bots/_bots.dm index c86160db025..ccd4b0d617f 100644 --- a/code/modules/mob/living/basic/bots/_bots.dm +++ b/code/modules/mob/living/basic/bots/_bots.dm @@ -41,6 +41,7 @@ GLOBAL_LIST_INIT(command_strings, list( light_power = 0.6 speed = 3 req_one_access = list(ACCESS_ROBOTICS) + interaction_flags_click = ALLOW_SILICON_REACH ///The Robot arm attached to this robot - has a 50% chance to drop on death. var/robot_arm = /obj/item/bodypart/arm/right/robot ///The inserted (if any) pAI in this bot. @@ -362,13 +363,9 @@ GLOBAL_LIST_INIT(command_strings, list( ui = new(user, src, "SimpleBot", name) ui.open() -/mob/living/basic/bot/AltClick(mob/user) - . = ..() - if(!can_interact(user)) - return - if(!user.can_perform_action(src, ALLOW_SILICON_REACH)) - return +/mob/living/basic/bot/click_alt(mob/user) unlock_with_id(user) + return CLICK_ACTION_SUCCESS /mob/living/basic/bot/proc/unlock_with_id(mob/living/user) if(bot_access_flags & BOT_COVER_EMAGGED) diff --git a/code/modules/mob/living/basic/minebots/minebot.dm b/code/modules/mob/living/basic/minebots/minebot.dm index 26e549cbcf9..3361330915f 100644 --- a/code/modules/mob/living/basic/minebots/minebot.dm +++ b/code/modules/mob/living/basic/minebots/minebot.dm @@ -203,12 +203,12 @@ combat_overlay.color = selected_color update_appearance() -/mob/living/basic/mining_drone/AltClick(mob/living/user) - . = ..() +/mob/living/basic/mining_drone/click_alt(mob/living/user) if(user.combat_mode) - return + return CLICK_ACTION_BLOCKING set_combat_mode(!combat_mode) balloon_alert(user, "now [combat_mode ? "attacking wildlife" : "collecting loose ore"]") + return CLICK_ACTION_SUCCESS /mob/living/basic/mining_drone/RangedAttack(atom/target) if(!combat_mode) diff --git a/code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm b/code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm index c7ceb73e3c8..21943d39d3d 100644 --- a/code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm +++ b/code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm @@ -204,7 +204,7 @@ ShiftClickOn(A) return if(LAZYACCESS(modifiers, ALT_CLICK)) - A.AltClick(src) + base_click_alt(A) return if(LAZYACCESS(modifiers, RIGHT_CLICK)) ranged_secondary_attack(A, modifiers) diff --git a/code/modules/mob/living/brain/posibrain.dm b/code/modules/mob/living/brain/posibrain.dm index a59e5021948..9df1697e400 100644 --- a/code/modules/mob/living/brain/posibrain.dm +++ b/code/modules/mob/living/brain/posibrain.dm @@ -75,17 +75,16 @@ GLOBAL_VAR(posibrain_notify_cooldown) update_appearance() addtimer(CALLBACK(src, PROC_REF(check_success)), ask_delay) -/obj/item/mmi/posibrain/AltClick(mob/living/user) - if(!istype(user) || !user.can_perform_action(src)) - return +/obj/item/mmi/posibrain/click_alt(mob/living/user) var/input_seed = tgui_input_text(user, "Enter a personality seed", "Enter seed", ask_role, MAX_NAME_LEN) if(isnull(input_seed)) - return - if(!istype(user) || !user.can_perform_action(src)) + return CLICK_ACTION_BLOCKING + if(!user.can_perform_action(src)) return to_chat(user, span_notice("You set the personality seed to \"[input_seed]\".")) ask_role = input_seed update_appearance() + return CLICK_ACTION_SUCCESS /obj/item/mmi/posibrain/proc/check_success() searching = FALSE diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 46d65b376bd..70663c7acda 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1330,9 +1330,14 @@ var/datum/dna/mob_DNA = has_dna() if(!mob_DNA || !mob_DNA.check_mutation(/datum/mutation/human/telekinesis) || !tkMaxRangeCheck(src, target)) - to_chat(src, span_warning("You are too far away!")) + if(!(action_bitflags & SILENT_ADJACENCY)) + to_chat(src, span_warning("You are too far away!")) return FALSE + if((action_bitflags & NEED_VENTCRAWL) && !HAS_TRAIT(src, TRAIT_VENTCRAWLER_NUDE) && !HAS_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS)) + to_chat(src, span_warning("You wouldn't fit!")) + return FALSE + if((action_bitflags & NEED_DEXTERITY) && !ISADVANCEDTOOLUSER(src)) to_chat(src, span_warning("You don't have the dexterity to do this!")) return FALSE @@ -1777,7 +1782,7 @@ GLOBAL_LIST_EMPTY(fire_appearances) if(registered_z && old_level_new_clients == 0) for(var/datum/ai_controller/controller as anything in SSai_controllers.ai_controllers_by_zlevel[registered_z]) controller.set_ai_status(AI_STATUS_OFF) - + //Check the amount of clients exists on the Z level we're moving towards, excluding ourselves. var/new_level_old_clients = SSmobs.clients_by_zlevel[new_z].len diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm index 27bbec88292..ec204dbc82b 100644 --- a/code/modules/mob/living/simple_animal/bot/bot.dm +++ b/code/modules/mob/living/simple_animal/bot/bot.dm @@ -29,6 +29,7 @@ light_power = 0.6 del_on_death = TRUE req_one_access = list(ACCESS_ROBOTICS) + interaction_flags_click = ALLOW_SILICON_REACH ///Cooldown between salutations for commissioned bots COOLDOWN_DECLARE(next_salute_check) @@ -411,13 +412,9 @@ ui = new(user, src, "SimpleBot", name) ui.open() -/mob/living/simple_animal/bot/AltClick(mob/user) - . = ..() - if(!can_interact(user)) - return - if(!user.can_perform_action(src, ALLOW_SILICON_REACH)) - return +/mob/living/simple_animal/bot/click_alt(mob/user) unlock_with_id(user) + return CLICK_ACTION_SUCCESS /mob/living/simple_animal/bot/proc/unlock_with_id(mob/user) if(bot_cover_flags & BOT_COVER_EMAGGED) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 7577563c6df..43cd9b752ea 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1142,6 +1142,10 @@ * * FORBID_TELEKINESIS_REACH - If telekinesis is forbidden to perform action from a distance (ex. canisters are blacklisted from telekinesis manipulation) * * ALLOW_SILICON_REACH - If silicons are allowed to perform action from a distance (silicons can operate airlocks from far away) * * ALLOW_RESTING - If resting on the floor is allowed to perform action () + * * ALLOW_VENTCRAWL - Mobs with ventcrawl traits can alt-click this to vent + * + * silence_adjacency: Sometimes we want to use this proc to check interaction without allowing it to throw errors for base case adjacency + * Alt click uses this, as otherwise you can detect what is interactable from a distance via the error message **/ /mob/proc/can_perform_action(atom/movable/target, action_bitflags) return diff --git a/code/modules/modular_computers/computers/item/computer.dm b/code/modules/modular_computers/computers/item/computer.dm index f47210901df..ba295d45093 100644 --- a/code/modules/modular_computers/computers/item/computer.dm +++ b/code/modules/modular_computers/computers/item/computer.dm @@ -223,19 +223,18 @@ /obj/item/modular_computer/get_cell() return internal_cell -/obj/item/modular_computer/AltClick(mob/user) - . = ..() +/obj/item/modular_computer/click_alt(mob/user) if(issilicon(user)) - return FALSE - if(!user.can_perform_action(src)) - return FALSE + return NONE if(RemoveID(user)) - return TRUE + return CLICK_ACTION_SUCCESS if(istype(inserted_pai)) // Remove pAI remove_pai(user) - return TRUE + return CLICK_ACTION_SUCCESS + + return CLICK_ACTION_BLOCKING // Gets IDs/access levels from card slot. Would be useful when/if PDAs would become modular PCs. //guess what /obj/item/modular_computer/GetAccess() diff --git a/code/modules/modular_computers/computers/item/laptop.dm b/code/modules/modular_computers/computers/item/laptop.dm index 3bf46f16d1b..b55fb6d2ee6 100644 --- a/code/modules/modular_computers/computers/item/laptop.dm +++ b/code/modules/modular_computers/computers/item/laptop.dm @@ -91,14 +91,11 @@ toggle_open(user) -/obj/item/modular_computer/laptop/AltClick(mob/user) - . = ..() - if(!can_interact(user)) - return - if(screen_on) // Close it. - try_toggle_open(user) - else - return ..() +/obj/item/modular_computer/laptop/click_alt(mob/user) + if(!screen_on) + return CLICK_ACTION_BLOCKING + try_toggle_open(user) // Close it. + return CLICK_ACTION_SUCCESS /obj/item/modular_computer/laptop/proc/toggle_open(mob/living/user=null) if(screen_on) diff --git a/code/modules/modular_computers/computers/item/pda.dm b/code/modules/modular_computers/computers/item/pda.dm index 674520f1fb2..cbed5bef57f 100644 --- a/code/modules/modular_computers/computers/item/pda.dm +++ b/code/modules/modular_computers/computers/item/pda.dm @@ -157,12 +157,6 @@ inserted_item = attacking_item playsound(src, 'sound/machines/pda_button1.ogg', 50, TRUE) -/obj/item/modular_computer/pda/AltClick(mob/user) - . = ..() - if(.) - return - - remove_pen(user) /obj/item/modular_computer/pda/CtrlClick(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 0e17f012453..6f0050534cc 100644 --- a/code/modules/modular_computers/computers/machinery/modular_computer.dm +++ b/code/modules/modular_computers/computers/machinery/modular_computer.dm @@ -116,11 +116,11 @@ SIGNAL_HANDLER return update_icon(updates) -/obj/machinery/modular_computer/AltClick(mob/user) - . = ..() +/obj/machinery/modular_computer/click_alt(mob/user) if(CPU_INTERACTABLE(user) || !can_interact(user)) - return - cpu.AltClick(user) + return NONE + cpu.click_alt(user) + return CLICK_ACTION_SUCCESS //ATTACK HAND IGNORING PARENT RETURN VALUE // On-click handling. Turns on the computer if it's off and opens the GUI. diff --git a/code/modules/paperwork/carbonpaper.dm b/code/modules/paperwork/carbonpaper.dm index 1dfe4ea7821..9c8ec0b8640 100644 --- a/code/modules/paperwork/carbonpaper.dm +++ b/code/modules/paperwork/carbonpaper.dm @@ -20,11 +20,11 @@ return . += span_notice("Right-click to tear off the carbon-copy (you must use both hands).") -/obj/item/paper/carbon/AltClick(mob/living/user) +/obj/item/paper/carbon/click_alt(mob/living/user) if(!copied) to_chat(user, span_notice("Take off the carbon copy first.")) - return - return ..() + return CLICK_ACTION_BLOCKING + return CLICK_ACTION_SUCCESS /obj/item/paper/carbon/proc/removecopy(mob/living/user) if(copied) diff --git a/code/modules/paperwork/clipboard.dm b/code/modules/paperwork/clipboard.dm index ffcaba5a02d..f4e6c712246 100644 --- a/code/modules/paperwork/clipboard.dm +++ b/code/modules/paperwork/clipboard.dm @@ -71,13 +71,16 @@ pen = null update_icon() -/obj/item/clipboard/AltClick(mob/user) - ..() - if(pen) - if(integrated_pen) - to_chat(user, span_warning("You can't seem to find a way to remove [src]'s [pen].")) - else - remove_pen(user) +/obj/item/clipboard/click_alt(mob/user) + if(isnull(pen)) + return CLICK_ACTION_BLOCKING + + if(integrated_pen) + to_chat(user, span_warning("You can't seem to find a way to remove [src]'s [pen].")) + return CLICK_ACTION_BLOCKING + + remove_pen(user) + return CLICK_ACTION_SUCCESS /obj/item/clipboard/update_overlays() . = ..() diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index 5aac6d93bc3..e1bddd6feff 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -30,6 +30,7 @@ grind_results = list(/datum/reagent/cellulose = 3) color = COLOR_WHITE item_flags = SKIP_FANTASY_ON_SPAWN + interaction_flags_click = NEED_DEXTERITY|NEED_HANDS /// Lazylist of raw, unsanitised, unparsed text inputs that have been made to the paper. var/list/datum/paper_input/raw_text_inputs @@ -359,13 +360,13 @@ return TRUE return ..() -/obj/item/paper/AltClick(mob/living/user) - . = ..() - if(!user.can_perform_action(src, NEED_DEXTERITY|NEED_HANDS)) - return +/obj/item/paper/click_alt(mob/living/user) if(HAS_TRAIT(user, TRAIT_PAPER_MASTER)) - return make_plane(user, /obj/item/paperplane/syndicate) - return make_plane(user, /obj/item/paperplane) + make_plane(user, /obj/item/paperplane/syndicate) + return CLICK_ACTION_SUCCESS + make_plane(user, /obj/item/paperplane) + return CLICK_ACTION_SUCCESS + /** @@ -374,9 +375,9 @@ * * Arguments: * * mob/living/user - who's folding - * * obj/item/paperplane/plane_type - what it will be folded into (path) + * * plane_type - what it will be folded into (path) */ -/obj/item/paper/proc/make_plane(mob/living/user, obj/item/paperplane/plane_type = /obj/item/paperplane) +/obj/item/paper/proc/make_plane(mob/living/user, plane_type = /obj/item/paperplane) balloon_alert(user, "folded into a plane") user.temporarilyRemoveItemFromInventory(src) var/obj/item/paperplane/new_plane = new plane_type(loc, src) diff --git a/code/modules/paperwork/paper_cutter.dm b/code/modules/paperwork/paper_cutter.dm index ae93a1daad8..8e4fedf2fda 100644 --- a/code/modules/paperwork/paper_cutter.dm +++ b/code/modules/paperwork/paper_cutter.dm @@ -141,16 +141,14 @@ return ..() -/obj/item/papercutter/AltClick(mob/user) - if(!user.Adjacent(src)) - return ..() - +/obj/item/papercutter/click_alt(mob/user) // can only remove one at a time; paper goes first, as its most likely what players will want to be taking out if(!isnull(stored_paper)) user.put_in_hands(stored_paper) else if(!isnull(stored_blade) && !blade_secured) user.put_in_hands(stored_blade) update_appearance() + return CLICK_ACTION_SUCCESS /obj/item/papercutter/attack_hand_secondary(mob/user, list/modifiers) if(!stored_blade) diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm index 5a167df49f7..ec71eda2e46 100644 --- a/code/modules/paperwork/pen.dm +++ b/code/modules/paperwork/pen.dm @@ -180,6 +180,7 @@ if(current_skin) desc = "It's an expensive [current_skin] fountain pen. The nib is quite sharp." + /obj/item/pen/fountain/captain/proc/reskin_dart_insert(datum/component/dart_insert/insert_comp) if(!istype(insert_comp)) //You really shouldn't be sending this signal from anything other than a dart_insert component return diff --git a/code/modules/photography/camera/camera.dm b/code/modules/photography/camera/camera.dm index bde6003ef09..35462a24d86 100644 --- a/code/modules/photography/camera/camera.dm +++ b/code/modules/photography/camera/camera.dm @@ -72,10 +72,9 @@ picture_size_y = min(clamp(desired_y, picture_size_y_min, picture_size_y_max), CAMERA_PICTURE_SIZE_HARD_LIMIT) return TRUE -/obj/item/camera/AltClick(mob/user) - if(!user.can_perform_action(src)) - return +/obj/item/camera/click_alt(mob/user) adjust_zoom(user) + return CLICK_ACTION_SUCCESS /obj/item/camera/attack(mob/living/carbon/human/M, mob/user) return diff --git a/code/modules/plumbing/plumbers/_plumb_machinery.dm b/code/modules/plumbing/plumbers/_plumb_machinery.dm index 132d882dbee..8baf59508b8 100644 --- a/code/modules/plumbing/plumbers/_plumb_machinery.dm +++ b/code/modules/plumbing/plumbers/_plumb_machinery.dm @@ -26,8 +26,6 @@ . = ..() . += span_notice("The maximum volume display reads: [reagents.maximum_volume] units.") -/obj/machinery/plumbing/AltClick(mob/user) - return ..() // This hotkey is BLACKLISTED since it's used by /datum/component/simple_rotation /obj/machinery/plumbing/wrench_act(mob/living/user, obj/item/tool) . = ..() diff --git a/code/modules/plumbing/plumbers/iv_drip.dm b/code/modules/plumbing/plumbers/iv_drip.dm index 7ed187929df..f9a5ae47598 100644 --- a/code/modules/plumbing/plumbers/iv_drip.dm +++ b/code/modules/plumbing/plumbers/iv_drip.dm @@ -29,8 +29,6 @@ reagents.expose(get_turf(src), TOUCH) //splash on the floor reagents.clear_reagents() -/obj/machinery/iv_drip/plumbing/can_use_alt_click(mob/user) - return FALSE //Alt click is used for rotation /obj/machinery/iv_drip/plumbing/wrench_act(mob/living/user, obj/item/tool) if(default_unfasten_wrench(user, tool) == SUCCESSFUL_UNFASTEN) diff --git a/code/modules/power/pipecleaners.dm b/code/modules/power/pipecleaners.dm index 2a41c70bdfe..7f1ef8fc2e3 100644 --- a/code/modules/power/pipecleaners.dm +++ b/code/modules/power/pipecleaners.dm @@ -163,10 +163,9 @@ By design, d1 is the smallest direction and d2 is the highest stored.color = colorC stored.update_appearance() -/obj/structure/pipe_cleaner/AltClick(mob/living/user) - if(!user.can_perform_action(src)) - return +/obj/structure/pipe_cleaner/click_alt(mob/living/user) cut_pipe_cleaner(user) + return CLICK_ACTION_SUCCESS /////////////////////////////////////////////// // The pipe cleaner coil object, used for laying pipe cleaner diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm index 084f74d50ec..c4be44ed367 100644 --- a/code/modules/power/singularity/emitter.dm +++ b/code/modules/power/singularity/emitter.dm @@ -346,8 +346,6 @@ return return ..() -/obj/machinery/power/emitter/AltClick(mob/user) - return ..() // This hotkey is BLACKLISTED since it's used by /datum/component/simple_rotation /obj/machinery/power/emitter/proc/integrate(obj/item/gun/energy/energy_gun, mob/user) if(!istype(energy_gun, /obj/item/gun/energy)) diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm index c9a142c999d..71a69c02d99 100644 --- a/code/modules/projectiles/guns/ballistic.dm +++ b/code/modules/projectiles/guns/ballistic.dm @@ -490,18 +490,16 @@ update_weight_class(w_class - I.w_class) return ..() -/obj/item/gun/ballistic/AltClick(mob/user) - if (unique_reskin && !current_skin && user.can_perform_action(src, NEED_DEXTERITY)) - reskin_obj(user) - return - if(loc == user) - if(suppressed && can_unsuppress) - var/obj/item/suppressor/S = suppressed - if(!user.is_holding(src)) - return ..() - balloon_alert(user, "[S.name] removed") - user.put_in_hands(S) - clear_suppressor() +/obj/item/gun/ballistic/click_alt(mob/user) + if(!suppressed || !can_unsuppress) + return CLICK_ACTION_BLOCKING + var/obj/item/suppressor/S = suppressed + if(!user.is_holding(src)) + return CLICK_ACTION_BLOCKING + balloon_alert(user, "[S.name] removed") + user.put_in_hands(S) + clear_suppressor() + return CLICK_ACTION_SUCCESS ///Prefire empty checks for the bolt drop /obj/item/gun/ballistic/proc/prefire_empty_checks() diff --git a/code/modules/projectiles/guns/ballistic/automatic.dm b/code/modules/projectiles/guns/ballistic/automatic.dm index 3d6940692d8..8c6e2ae7cbd 100644 --- a/code/modules/projectiles/guns/ballistic/automatic.dm +++ b/code/modules/projectiles/guns/ballistic/automatic.dm @@ -260,13 +260,12 @@ . += span_notice("It seems like you could use an empty hand to remove the magazine.") -/obj/item/gun/ballistic/automatic/l6_saw/AltClick(mob/user) - if(!user.can_perform_action(src)) - return +/obj/item/gun/ballistic/automatic/l6_saw/click_alt(mob/user) cover_open = !cover_open balloon_alert(user, "cover [cover_open ? "opened" : "closed"]") playsound(src, 'sound/weapons/gun/l6/l6_door.ogg', 60, TRUE) update_appearance() + return CLICK_ACTION_SUCCESS /obj/item/gun/ballistic/automatic/l6_saw/update_icon_state() . = ..() diff --git a/code/modules/projectiles/guns/ballistic/bows/_bow.dm b/code/modules/projectiles/guns/ballistic/bows/_bow.dm index c356d5b266c..86094d0fe17 100644 --- a/code/modules/projectiles/guns/ballistic/bows/_bow.dm +++ b/code/modules/projectiles/guns/ballistic/bows/_bow.dm @@ -29,13 +29,14 @@ . = ..() icon_state = chambered ? "[base_icon_state]_[drawn ? "drawn" : "nocked"]" : "[base_icon_state]" -/obj/item/gun/ballistic/bow/AltClick(mob/user) +/obj/item/gun/ballistic/bow/click_alt(mob/user) if(isnull(chambered)) - return ..() + return CLICK_ACTION_BLOCKING user.put_in_hands(chambered) chambered = magazine.get_round() update_appearance() + return CLICK_ACTION_SUCCESS /obj/item/gun/ballistic/bow/proc/drop_arrow() chambered.forceMove(drop_location()) diff --git a/code/modules/projectiles/guns/ballistic/revolver.dm b/code/modules/projectiles/guns/ballistic/revolver.dm index 373607e53dd..e142616cbd4 100644 --- a/code/modules/projectiles/guns/ballistic/revolver.dm +++ b/code/modules/projectiles/guns/ballistic/revolver.dm @@ -37,9 +37,9 @@ ..() chamber_round() -/obj/item/gun/ballistic/revolver/AltClick(mob/user) - ..() +/obj/item/gun/ballistic/revolver/click_alt(mob/user) spin() + return CLICK_ACTION_SUCCESS /obj/item/gun/ballistic/revolver/fire_sounds() var/frequency_to_use = sin((90/magazine?.max_ammo) * get_ammo(TRUE, FALSE)) // fucking REVOLVERS diff --git a/code/modules/projectiles/guns/ballistic/shotgun.dm b/code/modules/projectiles/guns/ballistic/shotgun.dm index a45511193b7..1b9f6809c6d 100644 --- a/code/modules/projectiles/guns/ballistic/shotgun.dm +++ b/code/modules/projectiles/guns/ballistic/shotgun.dm @@ -85,6 +85,7 @@ w_class = WEIGHT_CLASS_HUGE semi_auto = TRUE accepted_magazine_type = /obj/item/ammo_box/magazine/internal/shot/tube + interaction_flags_click = NEED_DEXTERITY|NEED_HANDS /// If defined, the secondary tube is this type, if you want different shell loads var/alt_mag_type /// If TRUE, we're drawing from the alternate_magazine @@ -131,10 +132,9 @@ else balloon_alert(user, "switched to tube A") -/obj/item/gun/ballistic/shotgun/automatic/dual_tube/AltClick(mob/living/user) - if(!user.can_perform_action(src, NEED_DEXTERITY|NEED_HANDS)) - return +/obj/item/gun/ballistic/shotgun/automatic/dual_tube/click_alt(mob/living/user) rack() + return CLICK_ACTION_SUCCESS // Bulldog shotgun // @@ -288,10 +288,6 @@ can_be_sawn_off = TRUE pb_knockback = 3 // it's a super shotgun! -/obj/item/gun/ballistic/shotgun/doublebarrel/AltClick(mob/user) - . = ..() - if(unique_reskin && !current_skin && user.can_perform_action(src, NEED_DEXTERITY)) - reskin_obj(user) /obj/item/gun/ballistic/shotgun/doublebarrel/sawoff(mob/user) . = ..() diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm index d406e9f489f..50198147fb8 100644 --- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm +++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm @@ -481,8 +481,6 @@ /obj/machinery/chem_dispenser/attack_ai_secondary(mob/user, list/modifiers) return attack_hand_secondary(user, modifiers) -/obj/machinery/chem_dispenser/AltClick(mob/user) - return ..() // This hotkey is BLACKLISTED since it's used by /datum/component/simple_rotation /obj/machinery/chem_dispenser/drinks name = "soda dispenser" diff --git a/code/modules/reagents/chemistry/machinery/chem_mass_spec.dm b/code/modules/reagents/chemistry/machinery/chem_mass_spec.dm index 298fe259814..60490e42cf1 100644 --- a/code/modules/reagents/chemistry/machinery/chem_mass_spec.dm +++ b/code/modules/reagents/chemistry/machinery/chem_mass_spec.dm @@ -433,14 +433,12 @@ replace_beaker(ui.user, FALSE) return TRUE -/obj/machinery/chem_mass_spec/AltClick(mob/living/user) - . = ..() - if(!can_interact(user)) - return +/obj/machinery/chem_mass_spec/click_alt(mob/living/user) if(processing_reagents) balloon_alert(user, "still processing!") - return ..() + return CLICK_ACTION_BLOCKING replace_beaker(user, TRUE) + return CLICK_ACTION_SUCCESS /obj/machinery/chem_mass_spec/alt_click_secondary(mob/living/user) . = ..() diff --git a/code/modules/reagents/chemistry/machinery/portable_chem_mixer.dm b/code/modules/reagents/chemistry/machinery/portable_chem_mixer.dm index a6113d2f0c6..4983040ee22 100644 --- a/code/modules/reagents/chemistry/machinery/portable_chem_mixer.dm +++ b/code/modules/reagents/chemistry/machinery/portable_chem_mixer.dm @@ -9,6 +9,7 @@ slot_flags = ITEM_SLOT_BELT custom_price = PAYCHECK_CREW * 10 custom_premium_price = PAYCHECK_CREW * 14 + interaction_flags_click = FORBID_TELEKINESIS_REACH ///Creating an empty slot for a beaker that can be added to dispense into var/obj/item/reagent_containers/beaker @@ -250,15 +251,14 @@ var/atom/movable/screen/inventory/hand/H = over_object M.putItemFromInventoryInHandIfPossible(src, H.held_index) -/obj/item/storage/portable_chem_mixer/AltClick(mob/living/user) +/obj/item/storage/portable_chem_mixer/click_alt(mob/living/user) if(!atom_storage.locked) balloon_alert(user, "lock first to use alt eject!") - return ..() - if(!can_interact(user) || !user.can_perform_action(src, FORBID_TELEKINESIS_REACH)) - return + return CLICK_ACTION_BLOCKING replace_beaker(user) update_appearance() + return CLICK_ACTION_SUCCESS /obj/item/storage/portable_chem_mixer/CtrlClick(mob/living/user) if(atom_storage.locked == STORAGE_FULLY_LOCKED) diff --git a/code/modules/reagents/reagent_containers/chem_pack.dm b/code/modules/reagents/reagent_containers/chem_pack.dm index 3345f1e99ef..98ffa2e596e 100644 --- a/code/modules/reagents/reagent_containers/chem_pack.dm +++ b/code/modules/reagents/reagent_containers/chem_pack.dm @@ -8,23 +8,29 @@ spillable = TRUE obj_flags = UNIQUE_RENAME resistance_flags = ACID_PROOF - var/sealed = FALSE fill_icon_thresholds = list(10, 20, 30, 40, 50, 60, 70, 80, 90, 100) has_variable_transfer_amount = FALSE + interaction_flags_click = NEED_DEXTERITY + /// Whether this has been sealed shut + var/sealed = FALSE -/obj/item/reagent_containers/chem_pack/AltClick(mob/living/user) - if(user.can_perform_action(src, NEED_DEXTERITY) && !sealed) - if(iscarbon(user) && (HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))) - to_chat(user, span_warning("Uh... whoops! You accidentally spill the content of the bag onto yourself.")) - SplashReagents(user) - return +/obj/item/reagent_containers/chem_pack/click_alt(mob/living/user) + if(sealed) + balloon_alert(user, "sealed!") + return CLICK_ACTION_BLOCKING - reagents.flags = NONE - reagent_flags = DRAWABLE | INJECTABLE //To allow for sabotage or ghetto use. - reagents.flags = reagent_flags - spillable = FALSE - sealed = TRUE - to_chat(user, span_notice("You seal the bag.")) + if(iscarbon(user) && (HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))) + to_chat(user, span_warning("Uh... whoops! You accidentally spill the content of the bag onto yourself.")) + SplashReagents(user) + return CLICK_ACTION_BLOCKING + + reagents.flags = NONE + reagent_flags = DRAWABLE | INJECTABLE //To allow for sabotage or ghetto use. + reagents.flags = reagent_flags + spillable = FALSE + sealed = TRUE + balloon_alert(user, "sealed") + return CLICK_ACTION_SUCCESS /obj/item/reagent_containers/chem_pack/examine() . = ..() diff --git a/code/modules/reagents/reagent_containers/cups/_cup.dm b/code/modules/reagents/reagent_containers/cups/_cup.dm index 9aaafda4ead..41542ea105e 100644 --- a/code/modules/reagents/reagent_containers/cups/_cup.dm +++ b/code/modules/reagents/reagent_containers/cups/_cup.dm @@ -453,11 +453,13 @@ spillable = TRUE var/obj/item/grinded -/obj/item/reagent_containers/cup/mortar/AltClick(mob/user) - if(grinded) - grinded.forceMove(drop_location()) - grinded = null - to_chat(user, span_notice("You eject the item inside.")) +/obj/item/reagent_containers/cup/mortar/click_alt(mob/user) + if(!grinded) + return CLICK_ACTION_BLOCKING + grinded.forceMove(drop_location()) + grinded = null + balloon_alert(user, "ejected") + return CLICK_ACTION_SUCCESS /obj/item/reagent_containers/cup/mortar/attackby(obj/item/I, mob/living/carbon/human/user) ..() diff --git a/code/modules/reagents/reagent_containers/cups/bottle.dm b/code/modules/reagents/reagent_containers/cups/bottle.dm index 1e4466da8c3..75bc79c5a6a 100644 --- a/code/modules/reagents/reagent_containers/cups/bottle.dm +++ b/code/modules/reagents/reagent_containers/cups/bottle.dm @@ -513,7 +513,7 @@ return TRUE -/obj/item/reagent_containers/cup/bottle/syrup_bottle/AltClick(mob/user) +/obj/item/reagent_containers/cup/bottle/syrup_bottle/click_alt(mob/user) cap_on = !cap_on if(!cap_on) icon_state = "syrup_open" @@ -522,7 +522,7 @@ icon_state = "syrup" balloon_alert(user, "put pump cap on") update_icon_state() - return ..() + return CLICK_ACTION_SUCCESS /obj/item/reagent_containers/cup/bottle/syrup_bottle/proc/rename(mob/user, obj/item/writing_instrument) if(!user.can_write(writing_instrument)) diff --git a/code/modules/reagents/reagent_containers/cups/drinks.dm b/code/modules/reagents/reagent_containers/cups/drinks.dm index cba2f937da4..5a3ed446f60 100644 --- a/code/modules/reagents/reagent_containers/cups/drinks.dm +++ b/code/modules/reagents/reagent_containers/cups/drinks.dm @@ -122,10 +122,10 @@ . += span_notice("Alt-click to toggle cup lid.") return -/obj/item/reagent_containers/cup/glass/coffee/AltClick(mob/user) +/obj/item/reagent_containers/cup/glass/coffee/click_alt(mob/user) lid_open = !lid_open update_icon_state() - return ..() + return CLICK_ACTION_SUCCESS /obj/item/reagent_containers/cup/glass/coffee/update_icon_state() if(lid_open) @@ -248,11 +248,10 @@ else . += span_notice("The cap has been taken off. Alt-click to put a cap on.") -/obj/item/reagent_containers/cup/glass/waterbottle/AltClick(mob/user) - . = ..() +/obj/item/reagent_containers/cup/glass/waterbottle/click_alt(mob/user) if(cap_lost) to_chat(user, span_warning("The cap seems to be missing! Where did it go?")) - return + return CLICK_ACTION_BLOCKING var/fumbled = HAS_TRAIT(user, TRAIT_CLUMSY) && prob(5) if(cap_on || fumbled) @@ -270,6 +269,7 @@ spillable = FALSE to_chat(user, span_notice("You put the cap on [src].")) update_appearance() + return CLICK_ACTION_SUCCESS /obj/item/reagent_containers/cup/glass/waterbottle/is_refillable() if(cap_on) @@ -436,6 +436,7 @@ amount_per_transfer_from_this = 10 volume = 100 isGlass = FALSE + interaction_flags_click = NEED_HANDS|FORBID_TELEKINESIS_REACH /// Whether or not poured drinks should use custom names and descriptions var/using_custom_drinks = FALSE /// Name custom drinks will have @@ -463,34 +464,30 @@ . += span_notice("Drinks poured from this shaker will have the following name: [custom_drink_name]") . += span_notice("Drinks poured from this shaker will have the following description: [custom_drink_desc]") -/obj/item/reagent_containers/cup/glass/shaker/AltClick(mob/user) - . = ..() - if(!user.can_perform_action(src, NEED_HANDS|FORBID_TELEKINESIS_REACH)) - return - +/obj/item/reagent_containers/cup/glass/shaker/click_alt(mob/user) if(using_custom_drinks) using_custom_drinks = FALSE disable_custom_drinks() balloon_alert(user, "custom drinks disabled") - return + return CLICK_ACTION_BLOCKING var/new_name = reject_bad_text(tgui_input_text(user, "Drink name", "Set drink name", custom_drink_name, 45, FALSE), 64) if(!new_name) balloon_alert(user, "invalid drink name!") using_custom_drinks = FALSE - return + return CLICK_ACTION_BLOCKING if(!user.can_perform_action(src, NEED_HANDS|FORBID_TELEKINESIS_REACH)) - return + return CLICK_ACTION_BLOCKING var/new_desc = reject_bad_text(tgui_input_text(user, "Drink description", "Set drink description", custom_drink_desc, 64, TRUE), 128) if(!new_desc) balloon_alert(user, "invalid drink description!") using_custom_drinks = FALSE - return + return CLICK_ACTION_BLOCKING if(!user.can_perform_action(src, NEED_HANDS|FORBID_TELEKINESIS_REACH)) - return + return CLICK_ACTION_BLOCKING using_custom_drinks = TRUE custom_drink_name = new_name @@ -498,6 +495,7 @@ enable_custom_drinks() balloon_alert(user, "now pouring custom drinks") + return CLICK_ACTION_SUCCESS /obj/item/reagent_containers/cup/glass/shaker/proc/enable_custom_drinks() RegisterSignal(src, COMSIG_REAGENTS_CUP_TRANSFER_TO, PROC_REF(handle_transfer)) diff --git a/code/modules/reagents/reagent_containers/medigel.dm b/code/modules/reagents/reagent_containers/medigel.dm index e6836c7a4c2..f6d7b116eff 100644 --- a/code/modules/reagents/reagent_containers/medigel.dm +++ b/code/modules/reagents/reagent_containers/medigel.dm @@ -32,6 +32,7 @@ "Purple" = "medigel_purple" ) + /obj/item/reagent_containers/medigel/mode_change_message(mob/user) var/squirt_mode = amount_per_transfer_from_this == initial(amount_per_transfer_from_this) to_chat(user, span_notice("You will now apply the medigel's contents in [squirt_mode ? "extended sprays":"short bursts"]. You'll now use [amount_per_transfer_from_this] units per use.")) diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index 52968cac22f..077c53246de 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -438,9 +438,14 @@ "Yellow" = "sprayer_med_yellow", "Blue" = "sprayer_med_blue") -/obj/item/reagent_containers/spray/medical/AltClick(mob/user) - if(unique_reskin && !current_skin && user.can_perform_action(src, NEED_DEXTERITY)) - reskin_obj(user) + +/obj/item/reagent_containers/spray/medical/add_context(atom/source, list/context, obj/item/held_item, mob/user) + . = ..() + + if(!current_skin) + context[SCREENTIP_CONTEXT_ALT_LMB] = "Reskin" + return CONTEXTUAL_SCREENTIP_SET + /obj/item/reagent_containers/spray/medical/reskin_obj(mob/M) ..() diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm index b3238f73493..b8b3576aa4b 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/reagent_dispenser.dm @@ -435,8 +435,6 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/reagent_dispensers/wall/virusfood, 30 . = ..() AddComponent(/datum/component/simple_rotation) -/obj/structure/reagent_dispensers/plumbed/storage/AltClick(mob/user) - return ..() // This hotkey is BLACKLISTED since it's used by /datum/component/simple_rotation /obj/structure/reagent_dispensers/plumbed/storage/update_overlays() . = ..() diff --git a/code/modules/recycling/disposal/construction.dm b/code/modules/recycling/disposal/construction.dm index 4b8fef12924..903a59a9305 100644 --- a/code/modules/recycling/disposal/construction.dm +++ b/code/modules/recycling/disposal/construction.dm @@ -95,8 +95,6 @@ pipe_type = initial(temp.flip_type) update_appearance() -/obj/structure/disposalconstruct/AltClick(mob/user) - return ..() // This hotkey is BLACKLISTED since it's used by /datum/component/simple_rotation // construction/deconstruction // wrench: (un)anchor diff --git a/code/modules/recycling/sortingmachinery.dm b/code/modules/recycling/sortingmachinery.dm index 47352fc6240..8c46de58a98 100644 --- a/code/modules/recycling/sortingmachinery.dm +++ b/code/modules/recycling/sortingmachinery.dm @@ -400,10 +400,10 @@ payments_acc = null to_chat(user, span_notice("You clear the registered account.")) -/obj/item/sales_tagger/AltClick(mob/user) - . = ..() +/obj/item/sales_tagger/click_alt(mob/user) var/potential_cut = input("How much would you like to pay out to the registered card?","Percentage Profit ([round(cut_min*100)]% - [round(cut_max*100)]%)") as num|null if(!potential_cut) cut_multiplier = initial(cut_multiplier) cut_multiplier = clamp(round(potential_cut/100, cut_min), cut_min, cut_max) to_chat(user, span_notice("[round(cut_multiplier*100)]% profit will be received if a package with a barcode is sold.")) + return CLICK_ACTION_SUCCESS diff --git a/code/modules/research/destructive_analyzer.dm b/code/modules/research/destructive_analyzer.dm index 03fffcec8ca..590511a8348 100644 --- a/code/modules/research/destructive_analyzer.dm +++ b/code/modules/research/destructive_analyzer.dm @@ -53,9 +53,9 @@ addtimer(CALLBACK(src, PROC_REF(finish_loading)), 1 SECONDS) return TRUE -/obj/machinery/rnd/destructive_analyzer/AltClick(mob/user) - . = ..() +/obj/machinery/rnd/destructive_analyzer/click_alt(mob/user) unload_item() + return CLICK_ACTION_SUCCESS /obj/machinery/rnd/destructive_analyzer/update_icon_state() icon_state = "[base_icon_state][loaded_item ? "_l" : null]" diff --git a/code/modules/research/machinery/_production.dm b/code/modules/research/machinery/_production.dm index d0c2473f449..96e1387e2cc 100644 --- a/code/modules/research/machinery/_production.dm +++ b/code/modules/research/machinery/_production.dm @@ -448,12 +448,12 @@ drop_direction = direction balloon_alert(usr, "dropping [dir2text(drop_direction)]") -/obj/machinery/rnd/production/AltClick(mob/user) - . = ..() - if(!drop_direction || !can_interact(user)) - return +/obj/machinery/rnd/production/click_alt(mob/user) + if(drop_direction == 0) + return CLICK_ACTION_BLOCKING if(busy) balloon_alert(user, "busy printing!") - return + return CLICK_ACTION_BLOCKING balloon_alert(user, "drop direction reset") drop_direction = 0 + return CLICK_ACTION_SUCCESS diff --git a/code/modules/research/ordnance/doppler_array.dm b/code/modules/research/ordnance/doppler_array.dm index 7afe201f360..5e44c2dc703 100644 --- a/code/modules/research/ordnance/doppler_array.dm +++ b/code/modules/research/ordnance/doppler_array.dm @@ -250,8 +250,6 @@ SIGNAL_HANDLER set_light_on(!(machine_stat & NOPOWER)) -/obj/machinery/doppler_array/AltClick(mob/user) - return ..() // This hotkey is BLACKLISTED since it's used by /datum/component/simple_rotation /obj/machinery/doppler_array/ui_interact(mob/user, datum/tgui/ui) ui = SStgui.try_update_ui(user, src, ui) diff --git a/code/modules/research/xenobiology/xenobio_camera.dm b/code/modules/research/xenobiology/xenobio_camera.dm index 172959153aa..9724bd776d8 100644 --- a/code/modules/research/xenobiology/xenobio_camera.dm +++ b/code/modules/research/xenobiology/xenobio_camera.dm @@ -360,9 +360,9 @@ Due to keyboard shortcuts, the second one is not necessarily the remote eye's lo // Alternate clicks for slime, monkey and open turf if using a xenobio console -/mob/living/basic/slime/AltClick(mob/user) +/mob/living/basic/slime/click_alt(mob/user) SEND_SIGNAL(user, COMSIG_XENO_SLIME_CLICK_ALT, src) - ..() + return CLICK_ACTION_SUCCESS /mob/living/basic/slime/ShiftClick(mob/user) SEND_SIGNAL(user, COMSIG_XENO_SLIME_CLICK_SHIFT, src) diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index 3d4d9bc4b45..7f87a08b85b 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -705,10 +705,9 @@ context[SCREENTIP_CONTEXT_ALT_LMB] = "Set potion offer reason" return CONTEXTUAL_SCREENTIP_SET -/obj/item/slimepotion/slime/sentience/AltClick(mob/living/user) - if(!can_interact(user)) - return +/obj/item/slimepotion/slime/sentience/click_alt(mob/living/user) potion_reason = tgui_input_text(user, "Enter reason for offering potion", "Intelligence Potion", potion_reason, multiline = TRUE) + return CLICK_ACTION_SUCCESS /obj/item/slimepotion/slime/sentience/attack(mob/living/dumb_mob, mob/user) if(being_used || !isliving(dumb_mob)) diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm index c93bd5e8c14..62e13ecb7f9 100644 --- a/code/modules/shuttle/emergency.dm +++ b/code/modules/shuttle/emergency.dm @@ -201,9 +201,11 @@ shuttle.setTimer(shuttle.timeLeft(1) + hijack_flight_time_increase) //give the guy more time to hijack if it's already in flight. return shuttle.hijack_status -/obj/machinery/computer/emergency_shuttle/AltClick(user) - if(isliving(user)) - attempt_hijack_stage(user) +/obj/machinery/computer/emergency_shuttle/click_alt(mob/living/user) + if(!isliving(user)) + return NONE + attempt_hijack_stage(user) + return CLICK_ACTION_SUCCESS /obj/machinery/computer/emergency_shuttle/proc/attempt_hijack_stage(mob/living/user) if(!user.CanReach(src)) @@ -819,10 +821,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/item/storage/pod, 32) return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN return ..() -/obj/item/storage/pod/AltClick(mob/user) - if(!can_interact(user)) - return - return ..() +/obj/item/storage/pod/click_alt(mob/user) + return CLICK_ACTION_SUCCESS /obj/item/storage/pod/can_interact(mob/user) if(!..()) diff --git a/code/modules/transport/tram/tram_remote.dm b/code/modules/transport/tram/tram_remote.dm index 4176117d8b2..3a45ec4e665 100644 --- a/code/modules/transport/tram/tram_remote.dm +++ b/code/modules/transport/tram/tram_remote.dm @@ -107,12 +107,9 @@ SEND_SIGNAL(src, COMSIG_TRANSPORT_REQUEST, specific_transport_id, destination, options) -/obj/item/assembly/control/transport/remote/AltClick(mob/user) - . = ..() - if(!can_interact(user)) - return - +/obj/item/assembly/control/transport/remote/click_alt(mob/user) link_tram(user) + return CLICK_ACTION_SUCCESS /obj/item/assembly/control/transport/remote/proc/link_tram(mob/user) specific_transport_id = null diff --git a/code/modules/transport/tram/tram_signals.dm b/code/modules/transport/tram/tram_signals.dm index 88f18d2cb7d..eb648666030 100644 --- a/code/modules/transport/tram/tram_signals.dm +++ b/code/modules/transport/tram/tram_signals.dm @@ -169,20 +169,16 @@ obj_flags |= EMAGGED return TRUE -/obj/machinery/transport/crossing_signal/AltClick(mob/living/user) - . = ..() - if(!can_interact(user)) - return - +/obj/machinery/transport/crossing_signal/click_alt(mob/living/user) var/obj/item/tool = user.get_active_held_item() if(!panel_open || tool?.tool_behaviour != TOOL_WRENCH) - return FALSE + return CLICK_ACTION_BLOCKING tool.play_tool_sound(src, 50) setDir(turn(dir,-90)) - to_chat(user, span_notice("You rotate [src].")) + balloon_alert(user, "rotated") find_uplink() - return TRUE + return CLICK_ACTION_SUCCESS /obj/machinery/transport/crossing_signal/attackby_secondary(obj/item/weapon, mob/user, params) . = ..() diff --git a/code/modules/vehicles/mecha/mech_fabricator.dm b/code/modules/vehicles/mecha/mech_fabricator.dm index 9fea0ebe82f..2dce26624ad 100644 --- a/code/modules/vehicles/mecha/mech_fabricator.dm +++ b/code/modules/vehicles/mecha/mech_fabricator.dm @@ -127,14 +127,12 @@ if(panel_open) . += span_notice("Alt-click to rotate the output direction.") -/obj/machinery/mecha_part_fabricator/AltClick(mob/user) - . = ..() - if(!user.can_perform_action(src)) - return - if(panel_open) - dir = turn(dir, -90) - balloon_alert(user, "rotated to [dir2text(dir)].") - return TRUE +/obj/machinery/mecha_part_fabricator/click_alt(mob/user) + if(!panel_open) + return CLICK_ACTION_BLOCKING + dir = turn(dir, -90) + balloon_alert(user, "rotated to [dir2text(dir)].") + return CLICK_ACTION_SUCCESS /** * Updates the `final_sets` and `buildable_parts` for the current mecha fabricator. diff --git a/code/modules/vehicles/mecha/mecha_actions.dm b/code/modules/vehicles/mecha/mecha_actions.dm index 2b410bd60c7..d544c829667 100644 --- a/code/modules/vehicles/mecha/mecha_actions.dm +++ b/code/modules/vehicles/mecha/mecha_actions.dm @@ -91,14 +91,15 @@ chassis.toggle_strafe() -/obj/vehicle/sealed/mecha/AltClick(mob/living/user) - if(!(user in occupants) || !user.can_perform_action(src)) - return +/obj/vehicle/sealed/mecha/click_alt(mob/living/user) + if(!(user in occupants)) + return CLICK_ACTION_BLOCKING if(!(user in return_controllers_with_flag(VEHICLE_CONTROL_DRIVE))) to_chat(user, span_warning("You're in the wrong seat to control movement.")) - return + return CLICK_ACTION_BLOCKING toggle_strafe() + return CLICK_ACTION_SUCCESS /obj/vehicle/sealed/mecha/proc/toggle_strafe() if(!(mecha_flags & CAN_STRAFE)) diff --git a/code/modules/vehicles/ridden.dm b/code/modules/vehicles/ridden.dm index 33f81184e9a..52c7924d72f 100644 --- a/code/modules/vehicles/ridden.dm +++ b/code/modules/vehicles/ridden.dm @@ -5,6 +5,7 @@ buckle_lying = 0 pass_flags_self = PASSTABLE COOLDOWN_DECLARE(message_cooldown) + interaction_flags_click = NEED_DEXTERITY /obj/vehicle/ridden/examine(mob/user) . = ..() @@ -39,16 +40,17 @@ inserted_key.forceMove(drop_location()) inserted_key = I -/obj/vehicle/ridden/AltClick(mob/user) - if(!inserted_key || !user.can_perform_action(src, NEED_DEXTERITY)) - return ..() +/obj/vehicle/ridden/click_alt(mob/user) + if(!inserted_key) + return CLICK_ACTION_BLOCKING if(!is_occupant(user)) to_chat(user, span_warning("You must be riding the [src] to remove [src]'s key!")) - return + return CLICK_ACTION_BLOCKING to_chat(user, span_notice("You remove \the [inserted_key] from \the [src].")) inserted_key.forceMove(drop_location()) user.put_in_hands(inserted_key) inserted_key = null + return CLICK_ACTION_SUCCESS /obj/vehicle/ridden/user_buckle_mob(mob/living/M, mob/user, check_loc = TRUE) if(!in_range(user, src) || !in_range(M, src)) diff --git a/code/modules/vehicles/wheelchair.dm b/code/modules/vehicles/wheelchair.dm index e7b3d9b3a56..92fcb995f76 100644 --- a/code/modules/vehicles/wheelchair.dm +++ b/code/modules/vehicles/wheelchair.dm @@ -63,8 +63,6 @@ qdel(src) return ITEM_INTERACT_SUCCESS -/obj/vehicle/ridden/wheelchair/AltClick(mob/user) - return ..() // This hotkey is BLACKLISTED since it's used by /datum/component/simple_rotation /obj/vehicle/ridden/wheelchair/update_overlays() . = ..() diff --git a/code/modules/wiremod/shell/controller.dm b/code/modules/wiremod/shell/controller.dm index ad03867b89b..b46dad3673f 100644 --- a/code/modules/wiremod/shell/controller.dm +++ b/code/modules/wiremod/shell/controller.dm @@ -71,9 +71,9 @@ */ /obj/item/circuit_component/controller/proc/send_alternate_signal(atom/source, mob/user) SIGNAL_HANDLER - if(!user.Adjacent(source)) - return + handle_trigger(source, user, "alternate", alt) + return CLICK_ACTION_SUCCESS /** diff --git a/tgstation.dme b/tgstation.dme index ac9d29c1d1b..f3dac6384a9 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -63,6 +63,7 @@ #include "code\__DEFINES\chat.dm" #include "code\__DEFINES\chat_filter.dm" #include "code\__DEFINES\cleaning.dm" +#include "code\__DEFINES\click.dm" #include "code\__DEFINES\client.dm" #include "code\__DEFINES\clothing.dm" #include "code\__DEFINES\colors.dm" @@ -554,6 +555,7 @@ #include "code\_onclick\adjacent.dm" #include "code\_onclick\ai.dm" #include "code\_onclick\click.dm" +#include "code\_onclick\click_alt.dm" #include "code\_onclick\cyborg.dm" #include "code\_onclick\drag_drop.dm" #include "code\_onclick\item_attack.dm" @@ -2130,6 +2132,7 @@ #include "code\game\objects\buckling.dm" #include "code\game\objects\empulse.dm" #include "code\game\objects\items.dm" +#include "code\game\objects\items_reskin.dm" #include "code\game\objects\obj_defense.dm" #include "code\game\objects\objs.dm" #include "code\game\objects\structures.dm"