From 599f645ccb11ea4407267a6cc11b36171d6a9f36 Mon Sep 17 00:00:00 2001 From: GDN <96800819+GDNgit@users.noreply.github.com> Date: Wed, 21 Feb 2024 16:49:28 -0600 Subject: [PATCH] adds the ability to keybind click() triggers (#23395) * adds the ability to keybind click() triggers * Update code/datums/keybindings/click_keybindings.dm Co-authored-by: Ryan <80364400+Sirryan2002@users.noreply.github.com> * Update code/_onclick/click.dm * final fixes * runtime fix --------- Co-authored-by: Ryan <80364400+Sirryan2002@users.noreply.github.com> --- code/__DEFINES/keybindings_defines.dm | 3 +- code/_globalvars/lists/keybindings_lists.dm | 1 + code/_onclick/ai_onclick.dm | 59 +++++++++------ code/_onclick/click.dm | 4 + code/_onclick/cyborg.dm | 3 + code/_onclick/observer_onclick.dm | 15 ++++ code/_onclick/other_mobs.dm | 3 + code/_onclick/overmind_onclick.dm | 12 +++ code/datums/keybindings/click_keybindings.dm | 77 ++++++++++++++++++++ code/game/atoms_movable.dm | 2 + code/modules/client/client_defines.dm | 2 + paradise.dme | 1 + 12 files changed, 158 insertions(+), 24 deletions(-) create mode 100644 code/datums/keybindings/click_keybindings.dm diff --git a/code/__DEFINES/keybindings_defines.dm b/code/__DEFINES/keybindings_defines.dm index 04debd1a2447..6568d8a45094 100644 --- a/code/__DEFINES/keybindings_defines.dm +++ b/code/__DEFINES/keybindings_defines.dm @@ -14,7 +14,8 @@ #define KB_CATEGORY_EMOTE_SILICON 14 #define KB_CATEGORY_EMOTE_ANIMAL 15 #define KB_CATEGORY_EMOTE_CUSTOM 16 -#define KB_CATEGORY_COMMUNICATION 17 +#define KB_CATEGORY_CLICK 17 +#define KB_CATEGORY_COMMUNICATION 18 #define KB_CATEGORY_UNSORTED 1000 ///Max length of a keypress command before it's considered to be a forged packet/bogus command diff --git a/code/_globalvars/lists/keybindings_lists.dm b/code/_globalvars/lists/keybindings_lists.dm index 836c1a0cbb5d..72e001c87e41 100644 --- a/code/_globalvars/lists/keybindings_lists.dm +++ b/code/_globalvars/lists/keybindings_lists.dm @@ -16,6 +16,7 @@ GLOBAL_LIST_INIT(keybindings_groups, list( "Animal Emote" = KB_CATEGORY_EMOTE_ANIMAL, "Brain Emote" = KB_CATEGORY_EMOTE_BRAIN, "Alien Emote" = KB_CATEGORY_EMOTE_ALIEN, + "Click Keybinds" = KB_CATEGORY_CLICK, "Admin" = KB_CATEGORY_ADMIN, "Other" = KB_CATEGORY_UNSORTED, "Custom Emotes (Character-based)" = KB_CATEGORY_EMOTE_CUSTOM, diff --git a/code/_onclick/ai_onclick.dm b/code/_onclick/ai_onclick.dm index 093d9408014f..b821e3591dcd 100644 --- a/code/_onclick/ai_onclick.dm +++ b/code/_onclick/ai_onclick.dm @@ -35,30 +35,8 @@ if(control_disabled || stat) return - var/turf/pixel_turf = isturf(A) ? A : get_turf_pixel(A) - if(isnull(pixel_turf)) + if(!can_click_on_turf(A)) return - if(!can_see(A)) - if(isturf(A)) //On unmodified clients clicking the static overlay clicks the turf underneath - return // So there's no point messaging admins - add_attack_logs(src, src, "[key_name_admin(src)] might be running a modified client! (failed can_see on AI click of [A]([ADMIN_COORDJMP(pixel_turf)]))", ATKLOG_ALL) - var/message = "[key_name(src)] might be running a modified client! (failed can_see on AI click of [A]([COORD(pixel_turf)]))" - log_admin(message) - GLOB.discord_manager.send2discord_simple_noadmins("**\[Warning]** [key_name(src)] might be running a modified client! (failed checkTurfVis on AI click of [A]([COORD(pixel_turf)]))") - - - var/turf_visible - if(pixel_turf) - turf_visible = GLOB.cameranet.checkTurfVis(pixel_turf) - if(!turf_visible) - if(istype(loc, /obj/item/aicard) && (pixel_turf in view(client.view, loc))) - turf_visible = TRUE - else - if(pixel_turf.obscured) - log_admin("[key_name_admin(src)] might be running a modified client! (failed checkTurfVis on AI click of [A]([COORD(pixel_turf)])") - add_attack_logs(src, src, "[key_name_admin(src)] might be running a modified client! (failed checkTurfVis on AI click of [A]([ADMIN_COORDJMP(pixel_turf)]))", ATKLOG_ALL) - GLOB.discord_manager.send2discord_simple_noadmins("**\[Warning]** [key_name(src)] might be running a modified client! (failed checkTurfVis on AI click of [A]([COORD(pixel_turf)]))") - return var/list/modifiers = params2list(params) if(modifiers["shift"] && modifiers["ctrl"]) @@ -106,6 +84,41 @@ A.add_hiddenprint(src) A.attack_ai(src) +/mob/living/silicon/ai/MiddleShiftControlClickOn(atom/A) + return + +/mob/living/silicon/ai/can_use_clickbinds() + var/atom/atom_targeted = locateUID(client.moused_over) + if(atom_targeted) + return can_click_on_turf(atom_targeted) + +/mob/living/silicon/ai/proc/can_click_on_turf(atom/A) + var/turf/pixel_turf = isturf(A) ? A : get_turf_pixel(A) + if(isnull(pixel_turf)) + return + if(!can_see(A)) + if(isturf(A)) //On unmodified clients clicking the static overlay clicks the turf underneath + return // So there's no point messaging admins + add_attack_logs(src, src, "[key_name_admin(src)] might be running a modified client! (failed can_see on AI click of [A]([ADMIN_COORDJMP(pixel_turf)]))", ATKLOG_ALL) + var/message = "[key_name(src)] might be running a modified client! (failed can_see on AI click of [A]([COORD(pixel_turf)]))" + log_admin(message) + GLOB.discord_manager.send2discord_simple_noadmins("**\[Warning]** [key_name(src)] might be running a modified client! (failed checkTurfVis on AI click of [A]([COORD(pixel_turf)]))") + return FALSE + + var/turf_visible + if(pixel_turf) + turf_visible = GLOB.cameranet.checkTurfVis(pixel_turf) + if(!turf_visible) + if(istype(loc, /obj/item/aicard) && (pixel_turf in view(client.view, loc))) + turf_visible = TRUE + else + if(pixel_turf.obscured) + log_admin("[key_name_admin(src)] might be running a modified client! (failed checkTurfVis on AI click of [A]([COORD(pixel_turf)])") + add_attack_logs(src, src, "[key_name_admin(src)] might be running a modified client! (failed checkTurfVis on AI click of [A]([ADMIN_COORDJMP(pixel_turf)]))", ATKLOG_ALL) + GLOB.discord_manager.send2discord_simple_noadmins("**\[Warning]** [key_name(src)] might be running a modified client! (failed checkTurfVis on AI click of [A]([COORD(pixel_turf)]))") + return FALSE + return TRUE + /* AI has no need for the UnarmedAttack() and RangedAttack() procs, because the AI code is not generic; attack_ai() is used instead. diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index ecf3793c777a..9c783730317a 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -164,6 +164,10 @@ return +/// Can this mob use keybinded click actions? (Altclick, Ctrlclick, ect) +/mob/proc/can_use_clickbinds() + return TRUE + //Is the atom obscured by a PREVENT_CLICK_UNDER_1 object above it /atom/proc/IsObscured() if(!isturf(loc)) //This only makes sense for things directly on turfs for now diff --git a/code/_onclick/cyborg.dm b/code/_onclick/cyborg.dm index 86949ea31c7a..f5c0cd7784ea 100644 --- a/code/_onclick/cyborg.dm +++ b/code/_onclick/cyborg.dm @@ -104,6 +104,9 @@ return return +/mob/living/silicon/robot/MiddleShiftControlClickOn(atom/A) + return + //Ctrl+Middle click cycles through modules /mob/living/silicon/robot/proc/CtrlMiddleClickOn(atom/A) cycle_modules() diff --git a/code/_onclick/observer_onclick.dm b/code/_onclick/observer_onclick.dm index 028419a79abd..c36c8f07a3de 100644 --- a/code/_onclick/observer_onclick.dm +++ b/code/_onclick/observer_onclick.dm @@ -62,6 +62,21 @@ /mob/dead/observer/ShiftClickOn(atom/A) examinate(A) +/mob/dead/observer/AltClickOn(atom/A) + AltClickNoInteract(src, A) + +/mob/dead/observer/AltShiftClickOn(atom/A) + return + +/mob/dead/observer/CtrlShiftClickOn(atom/A) + return + +/mob/dead/observer/MiddleShiftClickOn(atom/A) + return + +/mob/dead/observer/MiddleShiftControlClickOn(atom/A) + return + /atom/proc/attack_ghost(mob/user) if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_GHOST, user) & COMPONENT_CANCEL_ATTACK_CHAIN) return TRUE diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm index f8193e8d4c1c..f8b8d2f535c8 100644 --- a/code/_onclick/other_mobs.dm +++ b/code/_onclick/other_mobs.dm @@ -112,6 +112,9 @@ /mob/new_player/ClickOn() return +/mob/new_player/can_use_clickbinds() + return FALSE + // pAIs are not intended to interact with anything in the world /mob/living/silicon/pai/UnarmedAttack(atom/A) return diff --git a/code/_onclick/overmind_onclick.dm b/code/_onclick/overmind_onclick.dm index 40c60b992686..ed9f06b63fc0 100644 --- a/code/_onclick/overmind_onclick.dm +++ b/code/_onclick/overmind_onclick.dm @@ -33,3 +33,15 @@ var/turf/T = get_turf(A) if(T) remove_blob(T) + +/mob/camera/blob/AltShiftClickOn(atom/A) + return AltClickOn(A) + +/mob/camera/blob/CtrlShiftClickOn(atom/A) + return CtrlClickOn(A) + +/mob/camera/blob/MiddleShiftClickOn(atom/A) + return MiddleClickOn(A) + +/mob/camera/blob/MiddleShiftControlClickOn(atom/A) + return MiddleClickOn(A) diff --git a/code/datums/keybindings/click_keybindings.dm b/code/datums/keybindings/click_keybindings.dm new file mode 100644 index 000000000000..45835029acd5 --- /dev/null +++ b/code/datums/keybindings/click_keybindings.dm @@ -0,0 +1,77 @@ +/datum/keybinding/clickbind + category = KB_CATEGORY_CLICK + +/datum/keybinding/clickbind/can_use(client/C, mob/M) + return istype(M) && M.can_use_clickbinds() && ..() + +/datum/keybinding/clickbind/down(client/C) + ..() + if(C.mob.next_click > world.time) + return + C.mob.changeNext_click(1) + return locateUID(C.moused_over) + +/datum/keybinding/clickbind/alt_click + name = "Alt-Click" + +/datum/keybinding/clickbind/alt_click/down(client/C) + . = ..() + if(.) + C.mob.AltClickOn(.) + +/datum/keybinding/clickbind/ctrl_click + name = "Ctrl-Click" + +/datum/keybinding/clickbind/ctrl_click/down(client/C) + . = ..() + if(.) + C.mob.CtrlClickOn(.) + +/datum/keybinding/clickbind/shift_click + name = "Shift-Click" + +/datum/keybinding/clickbind/shift_click/down(client/C) + . = ..() + if(.) + C.mob.ShiftClickOn(.) + +/datum/keybinding/clickbind/middle_click + name = "Middle-Click" + +/datum/keybinding/clickbind/middle_click/down(client/C) + . = ..() + if(.) + C.mob.MiddleClickOn(.) + +/datum/keybinding/clickbind/alt_shift_click + name = "Alt-Shift-Click" + +/datum/keybinding/clickbind/alt_shift_click/down(client/C) + . = ..() + if(.) + C.mob.AltShiftClickOn(.) + +/datum/keybinding/clickbind/ctrl_shift_click + name = "Ctrl-Shift-Click" + +/datum/keybinding/clickbind/ctrl_shift_click/down(client/C) + . = ..() + if(.) + C.mob.CtrlShiftClickOn(.) + +/datum/keybinding/clickbind/middle_shift_click + name = "Middle-Shift-Click" + +/datum/keybinding/clickbind/middle_shift_click/down(client/C) + . = ..() + if(.) + C.mob.MiddleShiftClickOn(.) + +/datum/keybinding/clickbind/middle_shift_ctrl_click + name = "Middle-Shift-Ctrl-Click" + +/datum/keybinding/clickbind/middle_shift_ctrl_click/down(client/C) + . = ..() + if(.) + C.mob.MiddleShiftControlClickOn(.) + diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 724b25acdb50..98c6784021b5 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -682,9 +682,11 @@ return //We inline a MAPTEXT() here, because there's no good way to statically add to a string like this active_hud.screentip_text.maptext = "[name]" + usr.client.moused_over = UID() /atom/movable/MouseExited(location, control, params) usr.hud_used.screentip_text.maptext = "" + usr.client.moused_over = null /atom/movable/proc/choose_crush_crit(mob/living/carbon/victim) if(!length(GLOB.tilt_crits)) diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm index c647cfef350b..390f425611c9 100644 --- a/code/modules/client/client_defines.dm +++ b/code/modules/client/client_defines.dm @@ -123,6 +123,8 @@ var/list/active_keybindings = list() /// The client's movement keybindings to directions, which work regardless of modifiers. var/list/movement_kb_dirs = list() + /// The client's currently moused over datum, limited to movable and stored as UID + var/atom/movable/moused_over /// A lazy list of atoms we've examined in the last RECENT_EXAMINE_MAX_WINDOW (default 2) seconds, so that we will call [/atom/proc/examine_more] instead of [/atom/proc/examine] on them when examining var/list/recent_examines diff --git a/paradise.dme b/paradise.dme index 1791ca678fd8..ef10a3ef4d10 100644 --- a/paradise.dme +++ b/paradise.dme @@ -478,6 +478,7 @@ #include "code\datums\keybindings\admin_keybinds.dm" #include "code\datums\keybindings\ai_keybinds.dm" #include "code\datums\keybindings\carbon_keybinds.dm" +#include "code\datums\keybindings\click_keybindings.dm" #include "code\datums\keybindings\client.dm" #include "code\datums\keybindings\communication_keybinds.dm" #include "code\datums\keybindings\emote_keybinds.dm"