diff --git a/code/__DEFINES/dcs/signals/signals_xeno_control.dm b/code/__DEFINES/dcs/signals/signals_xeno_control.dm index c67756a64f3..660dc9ce446 100644 --- a/code/__DEFINES/dcs/signals/signals_xeno_control.dm +++ b/code/__DEFINES/dcs/signals/signals_xeno_control.dm @@ -1,7 +1,5 @@ //Xenobio hotkeys -///from slime AltClickOn(): (/mob) -#define COMSIG_XENO_SLIME_CLICK_ALT "xeno_slime_click_alt" ///from slime ShiftClickOn(): (/mob) #define COMSIG_XENO_SLIME_CLICK_SHIFT "xeno_slime_click_shift" ///from turf ShiftClickOn(): (/mob) diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index f1a48df79fa..f22e4d9c723 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -837,8 +837,10 @@ GLOBAL_LIST_INIT(layers_to_offset, list( #define NEED_VENTCRAWL (1<<8) /// Skips adjacency checks #define BYPASS_ADJACENCY (1<<9) +/// Skips reccursive loc checks +#define NOT_INSIDE_TARGET (1<<10) /// Checks for base adjacency, but silences the error -#define SILENT_ADJACENCY (1<<10) +#define SILENT_ADJACENCY (1<<11) /// 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/_onclick/click.dm b/code/_onclick/click.dm index 4dde5a7f04a..cd8563d849f 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -93,9 +93,9 @@ return if(LAZYACCESS(modifiers, ALT_CLICK)) // alt and alt-gr (rightalt) if(LAZYACCESS(modifiers, RIGHT_CLICK)) - base_click_alt_secondary(A) + AltClickSecondaryOn(A) else - base_click_alt(A) + AltClickOn(A) return if(LAZYACCESS(modifiers, CTRL_CLICK)) CtrlClickOn(A) diff --git a/code/_onclick/click_alt.dm b/code/_onclick/click_alt.dm index 51c58408e25..28801b9816d 100644 --- a/code/_onclick/click_alt.dm +++ b/code/_onclick/click_alt.dm @@ -1,5 +1,9 @@ +///Main proc for primary alt click +/mob/proc/AltClickOn(atom/target) + base_click_alt(target) + /** - * ### Base proc for alt click interaction left click. + * ### Base proc for alt click interaction left click. Returns if the click was intercepted & handled * * If you wish to add custom `click_alt` behavior for a single type, use that proc. */ @@ -8,43 +12,36 @@ // Check if they've hooked in to prevent src from alt clicking anything if(SEND_SIGNAL(src, COMSIG_MOB_ALTCLICKON, target) & COMSIG_MOB_CANCEL_CLICKON) - return + return TRUE - // Is it visible (and we're not wearing it (our clothes are invisible))? - if(!CAN_I_SEE(target)) - return - - if(is_blind() && !IN_GIVEN_RANGE(src, target, 1)) - return - - var/turf/tile = get_turf(target) - - // Ghosties just see loot - if(isobserver(src) || isrevenant(src)) - client.loot_panel.open(tile) - return + // If it has a signal handler that returns a click action, done. + if(SEND_SIGNAL(target, COMSIG_CLICK_ALT, src) & CLICK_ACTION_ANY) + return TRUE + // If it has a custom click_alt that returns success/block, done. if(can_perform_action(target, (target.interaction_flags_click | SILENT_ADJACENCY))) - // If it has a signal handler that returns a click action, done. - if(SEND_SIGNAL(target, COMSIG_CLICK_ALT, src) & CLICK_ACTION_ANY) - return + return target.click_alt(src) & CLICK_ACTION_ANY - // If it has a custom click_alt that returns success/block, done. - if(target.click_alt(src) & CLICK_ACTION_ANY) - return + return FALSE + +/mob/living/base_click_alt(atom/target) + SHOULD_NOT_OVERRIDE(TRUE) + + . = ..() + if(. || !CAN_I_SEE(target) || (is_blind() && !IN_GIVEN_RANGE(src, target, 1))) + return // No alt clicking to view turf from beneath if(HAS_TRAIT(src, TRAIT_MOVE_VENTCRAWLING)) return /// No loot panel if it's on our person - if(isobj(target) && isliving(src)) - var/mob/living/user = src - if(target in user.get_all_gear()) - to_chat(user, span_warning("You can't search for this item, it's already in your inventory! Take it off first.")) - return + if(isobj(target) && (target in get_all_gear())) + to_chat(src, span_warning("You can't search for this item, it's already in your inventory! Take it off first.")) + return - client.loot_panel.open(tile) + client.loot_panel.open(get_turf(target)) + return TRUE /** * ## Custom alt click interaction @@ -78,6 +75,10 @@ return NONE +///Main proc for secondary alt click +/mob/proc/AltClickSecondaryOn(atom/target) + base_click_alt_secondary(target) + /** * ### Base proc for alt click interaction right click. * @@ -90,17 +91,13 @@ if(SEND_SIGNAL(src, COMSIG_MOB_ALTCLICKON_SECONDARY, target) & COMSIG_MOB_CANCEL_CLICKON) return - if(!can_perform_action(target, target.interaction_flags_click | SILENT_ADJACENCY)) - return - //Hook on the atom to intercept the click if(SEND_SIGNAL(target, COMSIG_CLICK_ALT_SECONDARY, src) & COMPONENT_CANCEL_CLICK_ALT_SECONDARY) return - if(isobserver(src) && client && check_rights_for(client, R_DEBUG)) - client.toggle_tag_datum(src) - return - target.click_alt_secondary(src) + // If it has a custom click_alt_secondary then do that + if(can_perform_action(target, target.interaction_flags_click | SILENT_ADJACENCY)) + target.click_alt_secondary(src) /** * ## Custom alt click secondary interaction diff --git a/code/_onclick/click_ctrl.dm b/code/_onclick/click_ctrl.dm index 2e80f017816..72f67b4271e 100644 --- a/code/_onclick/click_ctrl.dm +++ b/code/_onclick/click_ctrl.dm @@ -20,12 +20,11 @@ if(SEND_SIGNAL(target, COMSIG_CLICK_CTRL, src) & CLICK_ACTION_ANY) return TRUE - // This means the action has been processed even though nothing happened - if(!can_perform_action(target, target.interaction_flags_click | SILENT_ADJACENCY)) - return TRUE - // If it has a custom click_alt that returns success/block, done. - return target.click_ctrl(src) & CLICK_ACTION_ANY + if(can_perform_action(target, target.interaction_flags_click | SILENT_ADJACENCY)) + return target.click_ctrl(src) & CLICK_ACTION_ANY + + return FALSE /** * Ctrl click @@ -35,7 +34,7 @@ SHOULD_NOT_OVERRIDE(TRUE) . = ..() - if(. || world.time < next_move || !CanReach(target)) + if(. || world.time < next_move || !can_perform_action(target, NOT_INSIDE_TARGET | SILENT_ADJACENCY)) return . = TRUE diff --git a/code/datums/ai/oldhostile/hostile_tameable.dm b/code/datums/ai/oldhostile/hostile_tameable.dm index d76ffb8a282..1c30cb95487 100644 --- a/code/datums/ai/oldhostile/hostile_tameable.dm +++ b/code/datums/ai/oldhostile/hostile_tameable.dm @@ -106,10 +106,11 @@ if(!COOLDOWN_FINISHED(src, command_cooldown)) return - if(!istype(clicker) || blackboard[BB_HOSTILE_FRIEND] != clicker) + if(!istype(clicker) || blackboard[BB_HOSTILE_FRIEND] != clicker || !clicker.can_perform_action(source)) return - . = CLICK_ACTION_BLOCKING + INVOKE_ASYNC(src, PROC_REF(command_radial), clicker) + return CLICK_ACTION_BLOCKING /// Show the command radial menu /datum/ai_controller/hostile_friend/proc/command_radial(mob/living/clicker) diff --git a/code/datums/components/pet_commands/obeys_commands.dm b/code/datums/components/pet_commands/obeys_commands.dm index ec3a04c940a..8aaa7e71792 100644 --- a/code/datums/components/pet_commands/obeys_commands.dm +++ b/code/datums/components/pet_commands/obeys_commands.dm @@ -66,7 +66,7 @@ SIGNAL_HANDLER var/mob/living/living_parent = parent - if (IS_DEAD_OR_INCAP(living_parent)) + if (IS_DEAD_OR_INCAP(living_parent) || !clicker.can_perform_action(living_parent)) return if (!(clicker in living_parent.ai_controller?.blackboard[BB_FRIENDS_LIST])) return // Not our friend, can't boss us around diff --git a/code/datums/components/rotation.dm b/code/datums/components/rotation.dm index f872c6bfd69..6ff8197e093 100644 --- a/code/datums/components/rotation.dm +++ b/code/datums/components/rotation.dm @@ -55,6 +55,7 @@ /datum/component/simple_rotation/proc/rotate_right(datum/source, mob/user) SIGNAL_HANDLER rotate(user, ROTATION_CLOCKWISE) + return CLICK_ACTION_SUCCESS /datum/component/simple_rotation/proc/rotate_left(datum/source, mob/user) SIGNAL_HANDLER diff --git a/code/datums/components/style/style_meter.dm b/code/datums/components/style/style_meter.dm index c06fc35aca3..94263700dda 100644 --- a/code/datums/components/style/style_meter.dm +++ b/code/datums/components/style/style_meter.dm @@ -93,10 +93,10 @@ /obj/item/style_meter/proc/on_click_alt(datum/source, mob/user) SIGNAL_HANDLER - if(!istype(loc, /obj/item/clothing/glasses)) + if(!istype(loc, /obj/item/clothing/glasses) || !user.can_perform_action(source)) return CLICK_ACTION_BLOCKING - clean_up() + clean_up(loc) forceMove(get_turf(src)) return CLICK_ACTION_SUCCESS diff --git a/code/datums/components/toggle_suit.dm b/code/datums/components/toggle_suit.dm index aee7522745e..022fc37c07a 100644 --- a/code/datums/components/toggle_suit.dm +++ b/code/datums/components/toggle_suit.dm @@ -36,24 +36,15 @@ * source - the atom being clicked on * user - the mob doing the click */ -/datum/component/toggle_icon/proc/on_click_alt(atom/source, mob/user) +/datum/component/toggle_icon/proc/on_click_alt(atom/source, mob/living/living_user) SIGNAL_HANDLER - if(!isliving(user)) + if(!isliving(living_user) || !living_user.can_perform_action(source)) return - var/mob/living/living_user = user - - if(!living_user.Adjacent(source)) - return - - if(living_user.incapacitated()) - source.balloon_alert(user, "you're incapacitated!") - return CLICK_ACTION_BLOCKING - if(living_user.usable_hands <= 0) - source.balloon_alert(user, "you don't have hands!") - return CLICK_ACTION_BLOCKING + source.balloon_alert(living_user, "you don't have hands!") + return do_icon_toggle(source, living_user) return CLICK_ACTION_SUCCESS diff --git a/code/datums/storage/storage.dm b/code/datums/storage/storage.dm index 2a5bd2a98fd..38c39300d54 100644 --- a/code/datums/storage/storage.dm +++ b/code/datums/storage/storage.dm @@ -954,8 +954,7 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) if(!click_alt_open) return - return open_storage_on_signal(source, user) - + return open_storage_on_signal(source, user) ? CLICK_ACTION_SUCCESS : NONE /// Opens the storage to the mob, showing them the contents to their UI. /datum/storage/proc/open_storage(mob/to_show) @@ -963,11 +962,7 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) show_contents(to_show) return FALSE - if(!to_show.CanReach(parent)) - parent.balloon_alert(to_show, "can't reach!") - return FALSE - - if(!isliving(to_show) || to_show.incapacitated()) + if(!isliving(to_show) || !to_show.can_perform_action(parent)) return FALSE if(locked) diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 3c02de47073..1a7b362ec2e 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -693,8 +693,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp //this is called when a ghost is drag clicked to something. /mob/dead/observer/mouse_drop_dragged(atom/over, mob/user) if (isobserver(user) && user.client.holder && (isliving(over) || iscameramob(over))) - if (user.client.holder.cmd_ghost_drag(src,over)) - return + user.client.holder.cmd_ghost_drag(src, over) /mob/dead/observer/Topic(href, href_list) ..() @@ -983,6 +982,13 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp game = create_mafia_game() game.ui_interact(usr) +/mob/dead/observer/AltClickOn(atom/target) + client.loot_panel.open(get_turf(target)) + +/mob/dead/observer/AltClickSecondaryOn(atom/target) + if(client && check_rights_for(client, R_DEBUG)) + client.toggle_tag_datum(src) + /mob/dead/observer/CtrlShiftClickOn(atom/target) if(isobserver(target) && check_rights(R_SPAWN)) var/mob/dead/observer/target_ghost = target diff --git a/code/modules/mob/living/basic/guardian/guardian_types/support.dm b/code/modules/mob/living/basic/guardian/guardian_types/support.dm index 3b5574db7f3..8ab24b7e9b7 100644 --- a/code/modules/mob/living/basic/guardian/guardian_types/support.dm +++ b/code/modules/mob/living/basic/guardian/guardian_types/support.dm @@ -103,10 +103,12 @@ /// Try and teleport something to our beacon /datum/action/cooldown/mob_cooldown/guardian_bluespace_beacon/proc/try_teleporting(mob/living/source, atom/target) SIGNAL_HANDLER + if (!can_teleport(source, target)) return + INVOKE_ASYNC(src, PROC_REF(perform_teleport), source, target) - return COMPONENT_CANCEL_ATTACK_CHAIN + return COMSIG_MOB_CANCEL_CLICKON /// Validate whether we can teleport this object /datum/action/cooldown/mob_cooldown/guardian_bluespace_beacon/proc/can_teleport(mob/living/source, atom/movable/target) @@ -118,7 +120,7 @@ if (!guardian_mob.is_deployed()) source.balloon_alert(source, "manifest yourself!") return FALSE - if (!source.Adjacent(target)) + if (!source.can_perform_action(target)) target.balloon_alert(source, "too far!") return FALSE if (target.anchored) 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 4ba903d9928..a154ba9da0c 100644 --- a/code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm +++ b/code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm @@ -150,6 +150,10 @@ update_appearance(UPDATE_ICON) update_health_hud() +/mob/living/basic/revenant/AltClickOn(atom/target) + if(CAN_I_SEE(target)) + client.loot_panel.open(get_turf(target)) + /mob/living/basic/revenant/get_status_tab_items() . = ..() . += "Current Essence: [essence >= max_essence ? essence : "[essence] / [max_essence]"] E" diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 54fce885a80..a03d00648c6 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1345,7 +1345,7 @@ to_chat(src, span_warning("You don't have the hands for this action!")) return FALSE - if(!(action_bitflags & BYPASS_ADJACENCY) && !recursive_loc_check(src, target) && !CanReach(target)) + if(!(action_bitflags & BYPASS_ADJACENCY) && ((action_bitflags & NOT_INSIDE_TARGET) || !recursive_loc_check(src, target)) && !CanReach(target)) if(HAS_SILICON_ACCESS(src) && !ispAI(src)) if(!(action_bitflags & ALLOW_SILICON_REACH)) // silicons can ignore range checks (except pAIs) if(!(action_bitflags & SILENT_ADJACENCY)) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 7dd1cf0d288..f24f5a58c0d 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1160,6 +1160,7 @@ * * ALLOW_VENTCRAWL - Mobs with ventcrawl traits can alt-click this to vent * * BYPASS_ADJACENCY - The target does not have to be adjacent * * SILENT_ADJACENCY - Adjacency is required but errors are not printed + * * NOT_INSIDE_TARGET - The target maybe adjacent but the mob should not be inside the target * * 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 diff --git a/code/modules/research/xenobiology/xenobio_camera.dm b/code/modules/research/xenobiology/xenobio_camera.dm index 5dbe284026d..68ffe5e9248 100644 --- a/code/modules/research/xenobiology/xenobio_camera.dm +++ b/code/modules/research/xenobiology/xenobio_camera.dm @@ -91,18 +91,20 @@ eyeobj.icon_state = "generic_camera" /obj/machinery/computer/camera_advanced/xenobio/GrantActions(mob/living/user) - ..() + . = ..() RegisterSignal(user, COMSIG_MOB_CTRL_CLICKED, PROC_REF(XenoClickCtrl)) - RegisterSignal(user, COMSIG_XENO_SLIME_CLICK_ALT, PROC_REF(XenoSlimeClickAlt)) + RegisterSignal(user, COMSIG_MOB_ALTCLICKON, PROC_REF(XenoSlimeClickAlt)) RegisterSignal(user, COMSIG_XENO_SLIME_CLICK_SHIFT, PROC_REF(XenoSlimeClickShift)) RegisterSignal(user, COMSIG_XENO_TURF_CLICK_SHIFT, PROC_REF(XenoTurfClickShift)) /obj/machinery/computer/camera_advanced/xenobio/remove_eye_control(mob/living/user) - UnregisterSignal(user, COMSIG_MOB_CTRL_CLICKED) - UnregisterSignal(user, COMSIG_XENO_SLIME_CLICK_ALT) - UnregisterSignal(user, COMSIG_XENO_SLIME_CLICK_SHIFT) - UnregisterSignal(user, COMSIG_XENO_TURF_CLICK_SHIFT) - ..() + UnregisterSignal(user, list( + COMSIG_MOB_CTRL_CLICKED, + COMSIG_MOB_ALTCLICKON, + COMSIG_XENO_SLIME_CLICK_SHIFT, + COMSIG_XENO_TURF_CLICK_SHIFT, + )) + return ..() /obj/machinery/computer/camera_advanced/xenobio/attackby(obj/item/used_item, mob/user, params) if(istype(used_item, /obj/item/food/monkeycube)) @@ -355,11 +357,6 @@ 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/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) ..() @@ -372,6 +369,10 @@ Due to keyboard shortcuts, the second one is not necessarily the remote eye's lo /obj/machinery/computer/camera_advanced/xenobio/proc/XenoSlimeClickAlt(mob/living/user, mob/living/basic/slime/target_slime) SIGNAL_HANDLER + . = COMSIG_MOB_CANCEL_CLICKON + if(!isslime(target_slime)) + return + var/mob/camera/ai_eye/remote/xenobio/remote_eye = user.remote_control var/obj/machinery/computer/camera_advanced/xenobio/xeno_console = remote_eye.origin diff --git a/code/modules/wiremod/shell/controller.dm b/code/modules/wiremod/shell/controller.dm index 9afe0303be8..126cc889436 100644 --- a/code/modules/wiremod/shell/controller.dm +++ b/code/modules/wiremod/shell/controller.dm @@ -81,6 +81,9 @@ */ /obj/item/circuit_component/controller/proc/send_right_signal(atom/source, mob/user) SIGNAL_HANDLER - if(!user.Adjacent(source)) + + if(!user.can_perform_action(source)) return + handle_trigger(source, user, "extra", right) + return CLICK_ACTION_SUCCESS