diff --git a/code/__DEFINES/click.dm b/code/__DEFINES/click.dm index 5900dd54210..d650a32e816 100644 --- a/code/__DEFINES/click.dm +++ b/code/__DEFINES/click.dm @@ -4,5 +4,4 @@ #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 ae06585ae5f..81cdd2c8596 100644 --- a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_mouse.dm +++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_mouse.dm @@ -22,9 +22,10 @@ #define COMSIG_CLICK_CTRL_SHIFT "ctrl_shift_click" ///from base of atom/MouseDrop(): (/atom/over, /mob/user) #define COMSIG_MOUSEDROP_ONTO "mousedrop_onto" - #define COMPONENT_NO_MOUSEDROP (1<<0) -///from base of atom/MouseDrop_T: (/atom/from, /mob/user) + #define COMPONENT_CANCEL_MOUSEDROP_ONTO (1<<0) +///from base of atom/handle_mouse_drop_receive: (/atom/from, /mob/user) #define COMSIG_MOUSEDROPPED_ONTO "mousedropped_onto" + #define COMPONENT_CANCEL_MOUSEDROPPED_ONTO (1<<0) ///from base of mob/MouseWheelOn(): (/atom, delta_x, delta_y, params) #define COMSIG_MOUSE_SCROLL_ON "mousescroll_on" /// From /atom/movable/screen/click(): (atom/target, atom/location, control, params, mob/user) diff --git a/code/__DEFINES/interaction_flags.dm b/code/__DEFINES/interaction_flags.dm index 418466a0eb2..615fe5c4cbd 100644 --- a/code/__DEFINES/interaction_flags.dm +++ b/code/__DEFINES/interaction_flags.dm @@ -20,6 +20,12 @@ #define INTERACT_ATOM_ALLOW_USER_LOCATION (1<<9) /// ignores mobility check #define INTERACT_ATOM_IGNORE_MOBILITY (1<<10) +// Bypass all adjacency checks for mouse drop +#define INTERACT_ATOM_MOUSEDROP_IGNORE_ADJACENT (1<<11) +/// Bypass all can_perform_action checks for mouse drop +#define INTERACT_ATOM_MOUSEDROP_IGNORE_USABILITY (1<<12) +/// Bypass all adjacency and other checks for mouse drop +#define INTERACT_ATOM_MOUSEDROP_IGNORE_CHECKS (INTERACT_ATOM_MOUSEDROP_IGNORE_ADJACENT | INTERACT_ATOM_MOUSEDROP_IGNORE_USABILITY) /// attempt pickup on attack_hand for items #define INTERACT_ITEM_ATTACK_HAND_PICKUP (1<<0) diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 0ca23dcf23a..e8904f0bb1f 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -827,8 +827,10 @@ GLOBAL_LIST_INIT(layers_to_offset, list( #define ALLOW_RESTING (1<<7) /// If this is accessible to creatures with ventcrawl capabilities #define NEED_VENTCRAWL (1<<8) +/// Skips adjacency checks +#define BYPASS_ADJACENCY (1<<9) /// Checks for base adjacency, but silences the error -#define SILENT_ADJACENCY (1<<9) +#define SILENT_ADJACENCY (1<<10) /// 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/drag_drop.dm b/code/_onclick/drag_drop.dm index edecd0ba78f..1bbc20d4913 100644 --- a/code/_onclick/drag_drop.dm +++ b/code/_onclick/drag_drop.dm @@ -6,18 +6,64 @@ almost anything into a trash can. */ /atom/MouseDrop(atom/over, src_location, over_location, src_control, over_control, params) + SHOULD_NOT_OVERRIDE(TRUE) + if(!usr || !over) return - if(SEND_SIGNAL(src, COMSIG_MOUSEDROP_ONTO, over, usr) & COMPONENT_NO_MOUSEDROP) //Whatever is receiving will verify themselves for adjacency. - return + var/proximity_check = usr.client.check_drag_proximity(src, over, src_location, over_location, src_control, over_control, params) if(proximity_check) return proximity_check - if(!Adjacent(usr) || !over.Adjacent(usr)) - return // should stop you from dragging through windows + base_mouse_drop_handler(over, src_location, over_location, params) + +/** + * Called when all sanity checks for mouse dropping have passed. Handles adjacency & other sanity checks before delegating the event + * down to lower level handlers. Do not override unless you are trying to create hud & screen elements which do not require proximity + * or other checks + */ +/atom/proc/base_mouse_drop_handler(atom/over, src_location, over_location, params) + PROTECTED_PROC(TRUE) + SHOULD_NOT_OVERRIDE(TRUE) + + var/mob/user = usr + + if(SEND_SIGNAL(src, COMSIG_MOUSEDROP_ONTO, over, user) & COMPONENT_CANCEL_MOUSEDROP_ONTO) + return + + if(SEND_SIGNAL(over, COMSIG_MOUSEDROPPED_ONTO, src, user, params) & COMPONENT_CANCEL_MOUSEDROPPED_ONTO) + return + + // only if both dragged object & receiver agree to do checks do we proceed + var/combined_atom_flags = interaction_flags_atom | over.interaction_flags_atom + if(!(combined_atom_flags & INTERACT_ATOM_MOUSEDROP_IGNORE_CHECKS)) + if(!(combined_atom_flags & INTERACT_ATOM_MOUSEDROP_IGNORE_ADJACENT)) + if(!Adjacent(user) || !over.Adjacent(user)) + return // should stop you from dragging through windows + + if(!(combined_atom_flags & INTERACT_ATOM_MOUSEDROP_IGNORE_USABILITY)) + var/combined_flags = interaction_flags_mouse_drop | over.interaction_flags_mouse_drop + if(combined_atom_flags & INTERACT_ATOM_MOUSEDROP_IGNORE_ADJACENT) + combined_flags |= BYPASS_ADJACENCY + else + combined_flags |= SILENT_ADJACENCY + if(!user.can_perform_action(src, combined_flags)) + return // is the mob not able to drag the object with both sides conditions applied + + mouse_drop_dragged(over, user, src_location, over_location, params) + + over.mouse_drop_receive(src, user, params) + +/// The proc that should be overridden by subtypes to handle mouse drop. Called on the atom being dragged +/atom/proc/mouse_drop_dragged(atom/over, mob/user, src_location, over_location, params) + PROTECTED_PROC(TRUE) + + return + +/// The proc that should be overridden by subtypes to handle mouse drop. Called on the atom receiving a dragged object +/atom/proc/mouse_drop_receive(atom/dropped, mob/user, params) + PROTECTED_PROC(TRUE) - over.MouseDrop_T(src,usr, params) return /// Handles treating drags as clicks if they're within some conditions @@ -78,11 +124,6 @@ return TRUE -// receive a mousedrop -/atom/proc/MouseDrop_T(atom/dropping, mob/user, params) - SEND_SIGNAL(src, COMSIG_MOUSEDROPPED_ONTO, dropping, user, params) - - /client/MouseDown(datum/object, location, control, params) if(QDELETED(object)) //Yep, you can click on qdeleted things before they have time to nullspace. Fun. return @@ -146,6 +187,8 @@ return ..() /client/MouseDrop(atom/src_object, atom/over_object, atom/src_location, atom/over_location, src_control, over_control, params) + SHOULD_NOT_OVERRIDE(TRUE) + if (IS_WEAKREF_OF(src_object, middle_drag_atom_ref)) middragtime = 0 middle_drag_atom_ref = null diff --git a/code/_onclick/hud/action_button.dm b/code/_onclick/hud/action_button.dm index 9d4343c132e..b2665e1f98e 100644 --- a/code/_onclick/hud/action_button.dm +++ b/code/_onclick/hud/action_button.dm @@ -105,7 +105,7 @@ closeToolTip(usr) return ..() -/atom/movable/screen/movable/action_button/MouseDrop(over_object) +/atom/movable/screen/movable/action_button/mouse_drop_dragged(atom/over_object, mob/user, src_location, over_location, params) last_hovored_ref = null if(!can_use(usr)) return @@ -130,7 +130,6 @@ our_hud.position_action_relative(src, button) save_position() return - . = ..() our_hud.position_action(src, screen_loc) save_position() diff --git a/code/_onclick/hud/movable_screen_objects.dm b/code/_onclick/hud/movable_screen_objects.dm index e0a6c6873bd..7a0937974bd 100644 --- a/code/_onclick/hud/movable_screen_objects.dm +++ b/code/_onclick/hud/movable_screen_objects.dm @@ -20,7 +20,7 @@ /atom/movable/screen/movable/snap snap2grid = TRUE -/atom/movable/screen/movable/MouseDrop(over_object, src_location, over_location, src_control, over_control, params) +/atom/movable/screen/movable/mouse_drop_dragged(atom/over, mob/user, src_location, over_location, params) var/position = mouse_params_to_position(params) if(!position) return diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 6f30f2a5135..2fc1fe644ee 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -15,6 +15,7 @@ animate_movement = SLIDE_STEPS speech_span = SPAN_ROBOT appearance_flags = APPEARANCE_UI + interaction_flags_atom = parent_type::interaction_flags_atom | INTERACT_ATOM_MOUSEDROP_IGNORE_CHECKS /// A reference to the object in the slot. Grabs or items, generally, but any datum will do. var/datum/weakref/master_ref = null /// A reference to the owner HUD, if any. @@ -58,6 +59,10 @@ if(default_click) return ..() +///Screen elements are always on top of the players screen and don't move so yes they are adjacent +/atom/movable/screen/Adjacent(atom/neighbor, atom/target, atom/movable/mover) + return TRUE + /atom/movable/screen/examine(mob/user) return list() @@ -241,6 +246,7 @@ var/mutable_appearance/handcuff_overlay var/static/mutable_appearance/blocked_overlay = mutable_appearance('icons/hud/screen_gen.dmi', "blocked") var/held_index = 0 + interaction_flags_atom = NONE //so dragging objects into hands icon don't skip adjacency & other checks /atom/movable/screen/inventory/hand/update_overlays() . = ..() diff --git a/code/datums/elements/climbable.dm b/code/datums/elements/climbable.dm index 56c16f303c4..004f05dd5f5 100644 --- a/code/datums/elements/climbable.dm +++ b/code/datums/elements/climbable.dm @@ -111,6 +111,8 @@ ///Handles climbing onto the atom when you click-drag /datum/element/climbable/proc/mousedrop_receive(atom/climbed_thing, atom/movable/dropped_atom, mob/user, params) SIGNAL_HANDLER + + . = COMPONENT_CANCEL_MOUSEDROPPED_ONTO if(user != dropped_atom || !isliving(dropped_atom)) return if(!HAS_TRAIT(dropped_atom, TRAIT_FENCE_CLIMBER) && !HAS_TRAIT(dropped_atom, TRAIT_CAN_HOLD_ITEMS)) // If you can hold items you can probably climb a fence diff --git a/code/datums/elements/drag_pickup.dm b/code/datums/elements/drag_pickup.dm index ffce267a895..128ae790996 100644 --- a/code/datums/elements/drag_pickup.dm +++ b/code/datums/elements/drag_pickup.dm @@ -17,8 +17,10 @@ /datum/element/drag_pickup/proc/pick_up(atom/source, atom/over, mob/user) SIGNAL_HANDLER + + . = COMPONENT_CANCEL_MOUSEDROP_ONTO var/mob/living/picker = user - if(!istype(picker) || picker.incapacitated() || !source.Adjacent(picker)) + if(!istype(picker) || !user.can_perform_action(source, FORBID_TELEKINESIS_REACH)) return if(over == picker) diff --git a/code/datums/elements/strippable.dm b/code/datums/elements/strippable.dm index 18dffff6aed..3816d16097d 100644 --- a/code/datums/elements/strippable.dm +++ b/code/datums/elements/strippable.dm @@ -36,11 +36,13 @@ /datum/element/strippable/proc/mouse_drop_onto(datum/source, atom/over, mob/user) SIGNAL_HANDLER + . = COMPONENT_CANCEL_MOUSEDROP_ONTO if (user == source) return - if (over != user) return + if(!user.can_perform_action(source, FORBID_TELEKINESIS_REACH)) + return // Cyborgs buckle people by dragging them onto them, unless in combat mode. if (iscyborg(user)) diff --git a/code/datums/storage/storage.dm b/code/datums/storage/storage.dm index 0a86c9fb545..28ecfcce8dc 100644 --- a/code/datums/storage/storage.dm +++ b/code/datums/storage/storage.dm @@ -714,25 +714,35 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) /datum/storage/proc/on_mousedrop_onto(datum/source, atom/over_object, mob/user) SIGNAL_HANDLER - if(ismecha(user.loc) || user.incapacitated() || !user.canUseStorage()) + . = COMPONENT_CANCEL_MOUSEDROP_ONTO + if(ismecha(user.loc) || !user.canUseStorage()) return - parent.add_fingerprint(user) - if(istype(over_object, /atom/movable/screen/inventory/hand)) - if(real_location.loc != user) + if(real_location.loc != user || !user.can_perform_action(parent, FORBID_TELEKINESIS_REACH | ALLOW_RESTING)) return var/atom/movable/screen/inventory/hand/hand = over_object user.putItemFromInventoryInHandIfPossible(parent, hand.held_index) + parent.add_fingerprint(user) else if(ismob(over_object)) - if(over_object != user) + if(over_object != user || !user.can_perform_action(parent, FORBID_TELEKINESIS_REACH | ALLOW_RESTING)) return + parent.add_fingerprint(user) INVOKE_ASYNC(src, PROC_REF(open_storage), user) else if(!istype(over_object, /atom/movable/screen)) + var/action_status + if(isturf(over_object)) + action_status = user.can_perform_turf_action(over_object) + else + action_status = user.can_perform_action(over_object, FORBID_TELEKINESIS_REACH) + if(!action_status) + return + + parent.add_fingerprint(user) INVOKE_ASYNC(src, PROC_REF(dump_content_at), over_object, user) /** @@ -779,18 +789,17 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) /datum/storage/proc/on_mousedropped_onto(datum/source, obj/item/dropping, mob/user) SIGNAL_HANDLER + . = COMPONENT_CANCEL_MOUSEDROPPED_ONTO if(!istype(dropping)) return if(dropping != user.get_active_held_item()) return + if(!user.can_perform_action(source, FORBID_TELEKINESIS_REACH)) + return if(dropping.atom_storage) // If it has storage it should be trying to dump, not insert. return - if(!iscarbon(user) && !isdrone(user)) return - var/mob/living/user_living = user - if(user_living.incapacitated()) - return attempt_insert(dropping, user) diff --git a/code/game/atom/_atom.dm b/code/game/atom/_atom.dm index f182d14d97e..ab4da3f2f77 100644 --- a/code/game/atom/_atom.dm +++ b/code/game/atom/_atom.dm @@ -138,6 +138,8 @@ /// Flags to check for in can_perform_action. Used in alt-click checks var/interaction_flags_click = NONE + /// Flags to check for in can_perform_action for mouse drag & drop checks. To bypass checks see interaction_flags_atom mouse drop flags + var/interaction_flags_mouse_drop = 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 3ad109b30e5..8af032101ae 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -9,6 +9,7 @@ circuit = /obj/item/circuitboard/machine/autolathe layer = BELOW_OBJ_LAYER processing_flags = NONE + interaction_flags_atom = parent_type::interaction_flags_atom | INTERACT_ATOM_MOUSEDROP_IGNORE_CHECKS ///Is the autolathe hacked via wiring var/hacked = FALSE @@ -380,18 +381,17 @@ busy = FALSE SStgui.update_uis(src) -/obj/machinery/autolathe/MouseDrop(atom/over, src_location, over_location, src_control, over_control, params) - . = ..() - if(!can_interact(usr) || (!HAS_SILICON_ACCESS(usr) && !isAdminGhostAI(usr)) && !Adjacent(usr)) +/obj/machinery/autolathe/mouse_drop_dragged(atom/over, mob/user, src_location, over_location, params) + if(!can_interact(user) || (!HAS_SILICON_ACCESS(user) && !isAdminGhostAI(user)) && !Adjacent(user)) return if(busy) - balloon_alert(usr, "printing started!") + balloon_alert(user, "printing started!") return var/direction = get_dir(src, over_location) if(!direction) return drop_direction = direction - balloon_alert(usr, "dropping [dir2text(drop_direction)]") + balloon_alert(user, "dropping [dir2text(drop_direction)]") /obj/machinery/autolathe/click_alt(mob/user) if(!drop_direction) diff --git a/code/game/machinery/dna_infuser/dna_infuser.dm b/code/game/machinery/dna_infuser/dna_infuser.dm index 7e5c58ef94c..cc2641d3297 100644 --- a/code/game/machinery/dna_infuser/dna_infuser.dm +++ b/code/game/machinery/dna_infuser/dna_infuser.dm @@ -11,7 +11,9 @@ base_icon_state = "infuser" density = TRUE obj_flags = BLOCKS_CONSTRUCTION // Becomes undense when the door is open + interaction_flags_mouse_drop = NEED_HANDS | NEED_DEXTERITY circuit = /obj/item/circuitboard/machine/dna_infuser + /// maximum tier this will infuse var/max_tier_allowed = DNA_MUTANT_TIER_ONE ///currently infusing a vict- subject @@ -199,7 +201,7 @@ infusing_from = target // mostly good for dead mobs like corpses (drag to add). -/obj/machinery/dna_infuser/MouseDrop_T(atom/movable/target, mob/user) +/obj/machinery/dna_infuser/mouse_drop_receive(atom/target, mob/user, params) // if the machine is closed, already has a infusion target, or the target is not valid then no mouse drop. if(!is_valid_infusion(target, user)) return @@ -208,8 +210,6 @@ /// Verify that the given infusion source/mob is a dead creature. /obj/machinery/dna_infuser/proc/is_valid_infusion(atom/movable/target, mob/user) - if(user.stat != CONSCIOUS || HAS_TRAIT(user, TRAIT_UI_BLOCKED) || !Adjacent(user) || !user.Adjacent(target) || !ISADVANCEDTOOLUSER(user)) - return FALSE var/datum/component/edible/food_comp = IS_EDIBLE(target) if(infusing_from) balloon_alert(user, "empty the machine first!") diff --git a/code/game/machinery/dna_scanner.dm b/code/game/machinery/dna_scanner.dm index dbcb36ff3cf..4775642881f 100644 --- a/code/game/machinery/dna_scanner.dm +++ b/code/game/machinery/dna_scanner.dm @@ -6,8 +6,10 @@ base_icon_state = "scanner" density = TRUE obj_flags = BLOCKS_CONSTRUCTION // Becomes undense when the door is open + interaction_flags_mouse_drop = NEED_DEXTERITY occupant_typecache = list(/mob/living, /obj/item/bodypart/head, /obj/item/organ/internal/brain) circuit = /obj/item/circuitboard/machine/dnascanner + var/locked = FALSE var/damage_coeff var/scan_level @@ -140,8 +142,8 @@ /obj/machinery/dna_scannernew/interact(mob/user) toggle_open(user) -/obj/machinery/dna_scannernew/MouseDrop_T(mob/target, mob/user) - if(user.stat != CONSCIOUS || HAS_TRAIT(user, TRAIT_UI_BLOCKED) || !Adjacent(user) || !user.Adjacent(target) || !iscarbon(target) || !ISADVANCEDTOOLUSER(user)) +/obj/machinery/dna_scannernew/mouse_drop_receive(atom/target, mob/user, params) + if(!iscarbon(target)) return close_machine(target) diff --git a/code/game/machinery/hypnochair.dm b/code/game/machinery/hypnochair.dm index 4594e09a9af..f8f3ed49be5 100644 --- a/code/game/machinery/hypnochair.dm +++ b/code/game/machinery/hypnochair.dm @@ -7,13 +7,20 @@ circuit = /obj/item/circuitboard/machine/hypnochair density = TRUE opacity = FALSE + interaction_flags_mouse_drop = NEED_DEXTERITY - var/mob/living/carbon/victim = null ///Keeps track of the victim to apply effects if it teleports away - var/interrogating = FALSE ///Is the device currently interrogating someone? - var/start_time = 0 ///Time when the interrogation was started, to calculate effect in case of interruption - var/trigger_phrase = "" ///Trigger phrase to implant - var/timerid = 0 ///Timer ID for interrogations - var/message_cooldown = 0 ///Cooldown for breakout message + ///Keeps track of the victim to apply effects if it teleports away + var/mob/living/carbon/victim = null + ///Is the device currently interrogating someone? + var/interrogating = FALSE + ///Time when the interrogation was started, to calculate effect in case of interruption + var/start_time = 0 + ///Trigger phrase to implant + var/trigger_phrase = "" + ///Timer ID for interrogations + var/timerid = 0 + ///Cooldown for breakout message + var/message_cooldown = 0 /obj/machinery/hypnochair/Initialize(mapload) . = ..() @@ -194,8 +201,7 @@ to_chat(user, span_warning("[src]'s door won't budge!")) -/obj/machinery/hypnochair/MouseDrop_T(mob/target, mob/user) - if(HAS_TRAIT(user, TRAIT_UI_BLOCKED) || !Adjacent(user) || !user.Adjacent(target) || !isliving(target) || !ISADVANCEDTOOLUSER(user)) +/obj/machinery/hypnochair/mouse_drop_receive(atom/target, mob/user, params) + if(!isliving(target)) return - close_machine(target) diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm index 91104abf681..4ac2a177e76 100644 --- a/code/game/machinery/iv_drip.dm +++ b/code/game/machinery/iv_drip.dm @@ -23,6 +23,7 @@ anchored = FALSE mouse_drag_pointer = MOUSE_ACTIVE_POINTER use_power = NO_POWER_USE + interaction_flags_mouse_drop = NEED_HANDS ///What are we sticking our needle in? var/atom/attached @@ -161,25 +162,22 @@ filling.color = mix_color_from_reagents(container_reagents.reagent_list) . += filling -/obj/machinery/iv_drip/MouseDrop(atom/target) - . = ..() - if(!Adjacent(target) || !usr.can_perform_action(src)) - return - if(!isliving(usr)) - to_chat(usr, span_warning("You can't do that!")) +/obj/machinery/iv_drip/mouse_drop_dragged(atom/target, mob/user) + if(!isliving(user)) + to_chat(user, span_warning("You can't do that!")) return if(!get_reagents()) - to_chat(usr, span_warning("There's nothing attached to the IV drip!")) + to_chat(user, span_warning("There's nothing attached to the IV drip!")) return - if(!target.is_injectable(usr)) - to_chat(usr, span_warning("Can't inject into this!")) + if(!target.is_injectable(user)) + to_chat(user, span_warning("Can't inject into this!")) return if(attached) visible_message(span_warning("[attached] is detached from [src].")) attached = null update_appearance(UPDATE_ICON) - usr.visible_message(span_warning("[usr] attaches [src] to [target]."), span_notice("You attach [src] to [target].")) - attach_iv(target, usr) + user.visible_message(span_warning("[user] attaches [src] to [target]."), span_notice("You attach [src] to [target].")) + attach_iv(target, user) /obj/machinery/iv_drip/attackby(obj/item/W, mob/user, params) if(use_internal_storage) diff --git a/code/game/machinery/launch_pad.dm b/code/game/machinery/launch_pad.dm index 9f889a4193f..f8dc9887758 100644 --- a/code/game/machinery/launch_pad.dm +++ b/code/game/machinery/launch_pad.dm @@ -7,7 +7,9 @@ icon_state = "lpad-idle" active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 2.5 hud_possible = list(DIAG_LAUNCHPAD_HUD) + interaction_flags_mouse_drop = NEED_DEXTERITY | NEED_HANDS circuit = /obj/item/circuitboard/machine/launchpad + /// The beam icon var/icon_teleport = "lpad-beam" /// To prevent briefcase pad deconstruction and such @@ -298,14 +300,13 @@ return FALSE return TRUE -/obj/machinery/launchpad/briefcase/MouseDrop(over_object, src_location, over_location) - . = ..() - if(over_object == usr) - if(!briefcase || !usr.can_perform_action(src, NEED_DEXTERITY|NEED_HANDS)) +/obj/machinery/launchpad/briefcase/mouse_drop_dragged(atom/over_object, mob/user, src_location, over_location, params) + if(over_object == user) + if(!briefcase) return - usr.visible_message(span_notice("[usr] starts closing [src]..."), span_notice("You start closing [src]...")) - if(do_after(usr, 3 SECONDS, target = usr)) - usr.put_in_hands(briefcase) + user.visible_message(span_notice("[usr] starts closing [src]..."), span_notice("You start closing [src]...")) + if(do_after(user, 3 SECONDS, target = user)) + user.put_in_hands(briefcase) moveToNullspace() //hides it from suitcase contents closed = TRUE update_indicator() diff --git a/code/game/machinery/pipe/pipe_dispenser.dm b/code/game/machinery/pipe/pipe_dispenser.dm index d65f33e9587..eb5b499bce7 100644 --- a/code/game/machinery/pipe/pipe_dispenser.dm +++ b/code/game/machinery/pipe/pipe_dispenser.dm @@ -9,6 +9,8 @@ desc = "Dispenses countless types of pipes. Very useful if you need pipes." density = TRUE interaction_flags_machine = INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON | INTERACT_MACHINE_OFFLINE + interaction_flags_mouse_drop = NEED_DEXTERITY + var/wait = 0 var/piping_layer = PIPING_LAYER_DEFAULT ///color of pipe @@ -183,16 +185,12 @@ density = TRUE category = DISPOSAL_PIPEDISPENSER - //Allow you to drag-drop disposal pipes and transit tubes into it -/obj/machinery/pipedispenser/disposal/MouseDrop_T(obj/structure/pipe, mob/usr) - if(!usr.incapacitated()) - return - +/obj/machinery/pipedispenser/disposal/mouse_drop_receive(obj/structure/pipe, mob/user, params) if (!istype(pipe, /obj/structure/disposalconstruct) && !istype(pipe, /obj/structure/c_transit_tube) && !istype(pipe, /obj/structure/c_transit_tube_pod)) return - if (get_dist(usr, src) > 1 || get_dist(src,pipe) > 1 ) + if (get_dist(user, src) > 1 || get_dist(src, pipe) > 1 ) return if (pipe.anchored) @@ -200,7 +198,6 @@ qdel(pipe) - //transit tube dispenser //inherit disposal for the dragging proc /obj/machinery/pipedispenser/disposal/transit_tube diff --git a/code/game/machinery/sleepers.dm b/code/game/machinery/sleepers.dm index 836ea2cf09a..63291035e78 100644 --- a/code/game/machinery/sleepers.dm +++ b/code/game/machinery/sleepers.dm @@ -7,6 +7,7 @@ density = FALSE obj_flags = BLOCKS_CONSTRUCTION state_open = TRUE + interaction_flags_mouse_drop = NEED_DEXTERITY circuit = /obj/item/circuitboard/machine/sleeper payment_department = ACCOUNT_MED @@ -114,9 +115,8 @@ if(is_operational && occupant) open_machine() - -/obj/machinery/sleeper/MouseDrop_T(mob/target, mob/user) - if(HAS_TRAIT(user, TRAIT_UI_BLOCKED) || !Adjacent(user) || !user.Adjacent(target) || !iscarbon(target) || !ISADVANCEDTOOLUSER(user)) +/obj/machinery/sleeper/mouse_drop_receive(atom/target, mob/user, params) + if(!iscarbon(target)) return close_machine(target) diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index a5e301c2168..ce513c4000f 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -9,6 +9,7 @@ power_channel = AREA_USAGE_EQUIP density = TRUE obj_flags = BLOCKS_CONSTRUCTION // Becomes undense when the unit is open + interaction_flags_mouse_drop = NEED_DEXTERITY max_integrity = 250 req_access = list() state_open = FALSE @@ -446,13 +447,9 @@ image.color = COLOR_RED return image -/obj/machinery/suit_storage_unit/MouseDrop_T(atom/A, mob/living/user) - if(!istype(user) || user.stat || !Adjacent(user) || !Adjacent(A) || !isliving(A)) +/obj/machinery/suit_storage_unit/mouse_drop_receive(atom/A, mob/living/user, params) + if(!isliving(A)) return - if(isliving(user)) - var/mob/living/L = user - if(L.body_position == LYING_DOWN) - return var/mob/living/target = A if(!state_open) to_chat(user, span_warning("The unit's doors are shut!")) diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm index e2ad3af956a..fd57b24da09 100644 --- a/code/game/objects/buckling.dm +++ b/code/game/objects/buckling.dm @@ -42,8 +42,7 @@ else return user_unbuckle_mob(buckled_mobs[1], user) -/atom/movable/MouseDrop_T(mob/living/M, mob/living/user) - . = ..() +/atom/movable/mouse_drop_receive(mob/living/M, mob/user, params) return mouse_buckle_handling(M, user) /** diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 12f87382a1c..1e5d8ab4a66 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -1064,8 +1064,11 @@ else apply_outline() //if the player's alive and well we send the command with no color set, so it uses the theme's color -/obj/item/MouseDrop(atom/over, src_location, over_location, src_control, over_control, params) +/obj/item/base_mouse_drop_handler(atom/over, src_location, over_location, params) + SHOULD_NOT_OVERRIDE(TRUE) + . = ..() + remove_filter(HOVER_OUTLINE_FILTER) //get rid of the hover effect in case the mouse exit isn't called if someone drags and drops an item and somthing goes wrong /obj/item/MouseExited() diff --git a/code/game/objects/items/defib.dm b/code/game/objects/items/defib.dm index ac164df007c..cbac185f675 100644 --- a/code/game/objects/items/defib.dm +++ b/code/game/objects/items/defib.dm @@ -136,11 +136,10 @@ ui_action_click() //checks for this are handled in defibrillator.mount.dm return ..() -/obj/item/defibrillator/MouseDrop(obj/over_object) - . = ..() +/obj/item/defibrillator/mouse_drop_dragged(atom/over_object, mob/user, src_location, over_location, params) if(ismob(loc)) var/mob/M = loc - if(!M.incapacitated() && istype(over_object, /atom/movable/screen/inventory/hand)) + if(istype(over_object, /atom/movable/screen/inventory/hand)) var/atom/movable/screen/inventory/hand/H = over_object M.putItemFromInventoryInHandIfPossible(src, H.held_index) diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm index ae806b594e1..1f2cd37a5cc 100644 --- a/code/game/objects/items/devices/radio/headset.dm +++ b/code/game/objects/items/devices/radio/headset.dm @@ -26,7 +26,7 @@ GLOBAL_LIST_INIT(channel_tokens, list( custom_materials = list(/datum/material/iron=SMALL_MATERIAL_AMOUNT * 0.75) subspace_transmission = TRUE canhear_range = 0 // can't hear headsets from very far away - + interaction_flags_mouse_drop = FORBID_TELEKINESIS_REACH slot_flags = ITEM_SLOT_EARS dog_fashion = null var/obj/item/encryptionkey/keyslot2 = null @@ -91,11 +91,9 @@ GLOBAL_LIST_INIT(channel_tokens, list( . = ..() .["headset"] = TRUE -/obj/item/radio/headset/MouseDrop(mob/over, src_location, over_location) - var/mob/headset_user = usr - if((headset_user == over) && headset_user.can_perform_action(src, FORBID_TELEKINESIS_REACH)) - return attack_self(headset_user) - return ..() +/obj/item/radio/headset/mouse_drop_dragged(atom/over, mob/user, src_location, over_location, params) + if(user == over) + return attack_self(user) /// Grants all the languages this headset allows the mob to understand via installed chips. /obj/item/radio/headset/proc/grant_headset_languages(mob/grant_to) diff --git a/code/game/objects/items/implants/implantchair.dm b/code/game/objects/items/implants/implantchair.dm index d76bd363e66..5f833e32648 100644 --- a/code/game/objects/items/implants/implantchair.dm +++ b/code/game/objects/items/implants/implantchair.dm @@ -5,6 +5,7 @@ icon_state = "implantchair" density = TRUE opacity = FALSE + interaction_flags_mouse_drop = NEED_DEXTERITY var/ready = TRUE var/replenishing = FALSE @@ -142,17 +143,11 @@ message_cooldown = world.time + 50 to_chat(user, span_warning("[src]'s door won't budge!")) - -/obj/machinery/implantchair/MouseDrop_T(mob/target, mob/user) - if(user.stat || !Adjacent(user) || !user.Adjacent(target) || !isliving(target) || !ISADVANCEDTOOLUSER(user)) +/obj/machinery/implantchair/mouse_drop_receive(mob/target, mob/user, params) + if(!isliving(target)) return - if(isliving(user)) - var/mob/living/L = user - if(L.body_position == LYING_DOWN) - return close_machine(target) - /obj/machinery/implantchair/close_machine(mob/living/user, density_to_set = TRUE) if((isnull(user) || istype(user)) && state_open) ..(user) diff --git a/code/game/objects/items/pet_carrier.dm b/code/game/objects/items/pet_carrier.dm index e30cdaf39df..2e2e622ff6c 100644 --- a/code/game/objects/items/pet_carrier.dm +++ b/code/game/objects/items/pet_carrier.dm @@ -18,6 +18,8 @@ throw_speed = 2 throw_range = 3 custom_materials = list(/datum/material/iron = HALF_SHEET_MATERIAL_AMOUNT * 7.5, /datum/material/glass = SMALL_MATERIAL_AMOUNT) + interaction_flags_mouse_drop = NEED_DEXTERITY + var/open = TRUE var/locked = FALSE var/list/occupants = list() @@ -153,10 +155,9 @@ if(!open) . += "[base_icon_state]_[locked ? "" : "un"]locked" -/obj/item/pet_carrier/MouseDrop(atom/over_atom) - . = ..() - if(isopenturf(over_atom) && usr.can_perform_action(src, NEED_DEXTERITY) && usr.Adjacent(over_atom) && open && occupants.len) - usr.visible_message(span_notice("[usr] unloads [src]."), \ +/obj/item/pet_carrier/mouse_drop_dragged(atom/over_atom, mob/user, src_location, over_location, params) + if(isopenturf(over_atom) && open && occupants.len) + user.visible_message(span_notice("[user] unloads [src]."), \ span_notice("You unload [src] onto [over_atom].")) for(var/V in occupants) remove_occupant(V, over_atom) diff --git a/code/game/objects/items/tanks/watertank.dm b/code/game/objects/items/tanks/watertank.dm index 4bfcd92c2db..45c20e9908b 100644 --- a/code/game/objects/items/tanks/watertank.dm +++ b/code/game/objects/items/tanks/watertank.dm @@ -14,6 +14,7 @@ max_integrity = 200 armor_type = /datum/armor/item_watertank resistance_flags = FIRE_PROOF + interaction_flags_mouse_drop = ALLOW_RESTING var/obj/item/noz var/volume = 500 @@ -93,12 +94,11 @@ else return ..() -/obj/item/watertank/MouseDrop(obj/over_object) +/obj/item/watertank/mouse_drop_dragged(atom/over_object) var/mob/M = loc if(istype(M) && istype(over_object, /atom/movable/screen/inventory/hand)) var/atom/movable/screen/inventory/hand/H = over_object M.putItemFromInventoryInHandIfPossible(src, H.held_index) - return ..() /obj/item/watertank/attackby(obj/item/attacking_item, mob/user, params) if(attacking_item == noz) diff --git a/code/game/objects/structures/beds_chairs/chair.dm b/code/game/objects/structures/beds_chairs/chair.dm index fbf6a55e207..e8b5ed4c13d 100644 --- a/code/game/objects/structures/beds_chairs/chair.dm +++ b/code/game/objects/structures/beds_chairs/chair.dm @@ -11,6 +11,8 @@ integrity_failure = 0.1 custom_materials = list(/datum/material/iron =SHEET_MATERIAL_AMOUNT) layer = OBJ_LAYER + interaction_flags_mouse_drop = NEED_HANDS | NEED_DEXTERITY + var/buildstacktype = /obj/item/stack/sheet/iron var/buildstackamount = 1 var/item_chair = /obj/item/chair // if null it can't be picked up @@ -261,18 +263,15 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool, 0) /obj/structure/chair/stool/narsie_act() return -/obj/structure/chair/MouseDrop(over_object, src_location, over_location) - . = ..() - if(over_object == usr && Adjacent(usr)) +/obj/structure/chair/mouse_drop_dragged(atom/over_object, mob/user, src_location, over_location, params) + if(over_object == user) if(!item_chair || has_buckled_mobs()) return - if(!usr.can_perform_action(src, NEED_DEXTERITY|NEED_HANDS)) - return - usr.visible_message(span_notice("[usr] grabs \the [src.name]."), span_notice("You grab \the [src.name].")) + user.visible_message(span_notice("[user] grabs \the [src.name]."), span_notice("You grab \the [src.name].")) var/obj/item/C = new item_chair(loc) C.set_custom_materials(custom_materials) TransferComponents(C) - usr.put_in_hands(C) + user.put_in_hands(C) qdel(src) /obj/structure/chair/user_buckle_mob(mob/living/M, mob/user, check_loc = TRUE) diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 61b5d104e55..f98b29e1932 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -911,13 +911,9 @@ GLOBAL_LIST_EMPTY(roundstart_station_closets) /obj/structure/closet/proc/after_weld(weld_state) return -/obj/structure/closet/MouseDrop_T(atom/movable/O, mob/living/user) +/obj/structure/closet/mouse_drop_receive(atom/movable/O, mob/living/user, params) if(!istype(O) || O.anchored || istype(O, /atom/movable/screen)) return - if(!istype(user) || user.incapacitated() || user.body_position == LYING_DOWN) - return - if(!Adjacent(user) || !user.Adjacent(O)) - return if(user == O) //try to climb onto it return ..() if(!opened) @@ -951,7 +947,6 @@ GLOBAL_LIST_EMPTY(roundstart_station_closets) log_combat(user, O, "stuffed", addition = "inside of [src]") else O.forceMove(T) - return 1 /obj/structure/closet/relaymove(mob/living/user, direction) if(user.stat || !isturf(loc)) diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm index d52a4df28cb..9baf7cb14fb 100644 --- a/code/game/objects/structures/morgue.dm +++ b/code/game/objects/structures/morgue.dm @@ -518,6 +518,7 @@ GLOBAL_LIST_EMPTY(crematoriums) density = TRUE anchored = TRUE pass_flags_self = PASSTABLE | LETPASSTHROW + max_integrity = 350 ///The bodycontainer we are a tray to. @@ -558,10 +559,10 @@ GLOBAL_LIST_EMPTY(crematoriums) if(carried_mob == user) //Piggyback user. return user.unbuckle_mob(carried_mob) - MouseDrop_T(carried_mob, user) + mouse_drop_receive(carried_mob, user) -/obj/structure/tray/MouseDrop_T(atom/movable/O as mob|obj, mob/user) - if(!ismovable(O) || O.anchored || !Adjacent(user) || !user.Adjacent(O) || O.loc == user) +/obj/structure/tray/mouse_drop_receive(atom/movable/O as mob|obj, mob/user, params) + if(!ismovable(O) || O.anchored || O.loc == user) return if(!ismob(O)) if(!istype(O, /obj/structure/closet/body_bag)) @@ -570,16 +571,9 @@ GLOBAL_LIST_EMPTY(crematoriums) var/mob/M = O if(M.buckled) return - if(!ismob(user) || user.incapacitated()) - return - if(isliving(user)) - var/mob/living/L = user - if(L.body_position == LYING_DOWN) - return O.forceMove(src.loc) if (user != O) visible_message(span_warning("[user] stuffs [O] into [src].")) - return /* * Crematorium tray diff --git a/code/game/objects/structures/transit_tubes/station.dm b/code/game/objects/structures/transit_tubes/station.dm index 3eeb81cb8ac..8fc1426c5f3 100644 --- a/code/game/objects/structures/transit_tubes/station.dm +++ b/code/game/objects/structures/transit_tubes/station.dm @@ -14,6 +14,7 @@ exit_delay = 1 enter_delay = 2 tube_construction = /obj/structure/c_transit_tube/station + var/open_status = STATION_TUBE_CLOSED var/pod_moving = FALSE var/cooldown_delay = 50 @@ -40,14 +41,9 @@ pod.update_appearance() return - //pod insertion -/obj/structure/transit_tube/station/MouseDrop_T(obj/structure/c_transit_tube_pod/R, mob/user) - if(isliving(user)) - var/mob/living/L = user - if(L.incapacitated()) - return - if (!istype(R) || get_dist(user, src) > 1 || get_dist(src,R) > 1) +/obj/structure/transit_tube/station/mouse_drop_receive(obj/structure/c_transit_tube_pod/R, mob/user, params) + if (!istype(R) || get_dist(user, src) > 1 || get_dist(src, R) > 1) return for(var/obj/structure/transit_tube_pod/pod in loc) return //no fun allowed diff --git a/code/game/turfs/closed/walls.dm b/code/game/turfs/closed/walls.dm index b5829a4364c..4b0f7961d51 100644 --- a/code/game/turfs/closed/walls.dm +++ b/code/game/turfs/closed/walls.dm @@ -34,8 +34,7 @@ var/list/dent_decals -/turf/closed/wall/MouseDrop_T(atom/dropping, mob/user, params) - ..() +/turf/closed/wall/mouse_drop_receive(atom/dropping, mob/user, params) if(dropping != user) return if(!iscarbon(dropping) && !iscyborg(dropping)) diff --git a/code/modules/admin/verbs/light_debug.dm b/code/modules/admin/verbs/light_debug.dm index eac81f6ed29..5738e06eeea 100644 --- a/code/modules/admin/verbs/light_debug.dm +++ b/code/modules/admin/verbs/light_debug.dm @@ -129,8 +129,7 @@ GLOBAL_LIST_EMPTY(light_debugged_atoms) last_hovored_ref = WEAKREF(over_object) over_object.MouseEntered(over_location, over_control, params) -/atom/movable/screen/light_button/MouseDrop(over_object) - . = ..() +/atom/movable/screen/light_button/mouse_drop_dragged(atom/over, mob/user, src_location, over_location, params) last_hovored_ref = null /atom/movable/screen/light_button/MouseEntered(location, control, params) @@ -330,8 +329,7 @@ GLOBAL_LIST_EMPTY(light_debugged_atoms) icon_state = "light_move" mouse_drag_pointer = 'icons/effects/mouse_pointers/light_drag.dmi' -/atom/movable/screen/light_button/move/MouseDrop(over_object) - . = ..() +/atom/movable/screen/light_button/move/mouse_drop_dragged(atom/over_object) if(!ismovable(loc)) return var/atom/movable/movable_owner = loc diff --git a/code/modules/antagonists/abductor/machinery/experiment.dm b/code/modules/antagonists/abductor/machinery/experiment.dm index 711923daa44..a549171b661 100644 --- a/code/modules/antagonists/abductor/machinery/experiment.dm +++ b/code/modules/antagonists/abductor/machinery/experiment.dm @@ -5,6 +5,8 @@ icon_state = "experiment-open" density = FALSE state_open = TRUE + interaction_flags_mouse_drop = NEED_DEXTERITY + var/points = 0 var/credits = 0 var/list/history @@ -21,10 +23,8 @@ console = null return ..() -/obj/machinery/abductor/experiment/MouseDrop_T(mob/target, mob/user) - if(user.stat != CONSCIOUS || HAS_TRAIT(user, TRAIT_UI_BLOCKED) || !Adjacent(user) || !target.Adjacent(user) || !ishuman(target)) - return - if(isabductor(target)) +/obj/machinery/abductor/experiment/mouse_drop_receive(mob/target, mob/user, params) + if(!ishuman(target) || isabductor(target)) return close_machine(target) diff --git a/code/modules/antagonists/fugitive/hunters/hunter_gear.dm b/code/modules/antagonists/fugitive/hunters/hunter_gear.dm index 31f312ae540..2905dff3a0f 100644 --- a/code/modules/antagonists/fugitive/hunters/hunter_gear.dm +++ b/code/modules/antagonists/fugitive/hunters/hunter_gear.dm @@ -7,16 +7,15 @@ icon_state = "bluespace-prison" density = TRUE resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF //ha ha no getting out!! + interaction_flags_mouse_drop = NEED_DEXTERITY /obj/machinery/fugitive_capture/examine(mob/user) . = ..() . += span_notice("Add a prisoner by dragging them into the machine.") -/obj/machinery/fugitive_capture/MouseDrop_T(mob/target, mob/user) +/obj/machinery/fugitive_capture/mouse_drop_receive(mob/target, mob/user, params) var/mob/living/fugitive_hunter = user - if(!isliving(fugitive_hunter)) - return - if(HAS_TRAIT(fugitive_hunter, TRAIT_UI_BLOCKED) || !Adjacent(fugitive_hunter) || !target.Adjacent(fugitive_hunter) || !ishuman(target)) + if(!isliving(fugitive_hunter) || !ishuman(target)) return var/mob/living/carbon/human/fugitive = target var/datum/antagonist/fugitive/fug_antag = fugitive.mind.has_antag_datum(/datum/antagonist/fugitive) diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm index bab9cf52f7c..d81cd2bc537 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm @@ -80,6 +80,7 @@ idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION * 0.75 active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 1.5 flags_1 = PREVENT_CLICK_UNDER_1 + interaction_flags_mouse_drop = NEED_DEXTERITY ///If TRUE will eject the mob once healing is complete var/autoeject = TRUE @@ -641,15 +642,19 @@ return ..() /obj/machinery/cryo_cell/click_alt(mob/user) - if(state_open) + //Required so players don't close the cryo on themselves without a doctor's help + if(get_turf(user) == get_turf(src)) + return CLICK_ACTION_BLOCKING + + if(state_open ) close_machine() else open_machine() balloon_alert(user, "door [state_open ? "opened" : "closed"]") return CLICK_ACTION_SUCCESS -/obj/machinery/cryo_cell/MouseDrop_T(mob/target, mob/user) - if(user.incapacitated() || !Adjacent(user) || !user.Adjacent(target) || !iscarbon(target) || !ISADVANCEDTOOLUSER(user)) +/obj/machinery/cryo_cell/mouse_drop_receive(mob/target, mob/user, params) + if(!iscarbon(target)) return if(isliving(target)) diff --git a/code/modules/bitrunning/objects/netpod.dm b/code/modules/bitrunning/objects/netpod.dm index a1a681cab05..cf8be61f62f 100644 --- a/code/modules/bitrunning/objects/netpod.dm +++ b/code/modules/bitrunning/objects/netpod.dm @@ -11,6 +11,8 @@ max_integrity = 300 obj_flags = BLOCKS_CONSTRUCTION state_open = TRUE + interaction_flags_mouse_drop = NEED_HANDS | NEED_DEXTERITY + /// Whether we have an ongoing connection var/connected = FALSE /// A player selected outfit by clicking the netpod @@ -93,12 +95,10 @@ return ..() -/obj/machinery/netpod/MouseDrop_T(mob/target, mob/user) +/obj/machinery/netpod/mouse_drop_receive(mob/target, mob/user, params) var/mob/living/carbon/player = user - if(!iscarbon(player) || !Adjacent(player) || !ISADVANCEDTOOLUSER(player) || !is_operational || !state_open) - return - if(player.buckled || HAS_TRAIT(player, TRAIT_HANDS_BLOCKED)) + if(!iscarbon(player) || !is_operational || !state_open || player.buckled) return close_machine(target) diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index e9ec547755d..cd32002d043 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -63,17 +63,16 @@ if(!icon_state) item_flags |= ABSTRACT -/obj/item/clothing/MouseDrop(atom/over_object) - . = ..() - var/mob/M = usr +/obj/item/clothing/mouse_drop_dragged(atom/over_object, mob/user, src_location, over_location, params) + var/mob/M = user if(ismecha(M.loc)) // stops inventory actions in a mech return - if(!M.incapacitated() && loc == M && istype(over_object, /atom/movable/screen/inventory/hand)) + if(loc == M && istype(over_object, /atom/movable/screen/inventory/hand)) var/atom/movable/screen/inventory/hand/H = over_object if(M.putItemFromInventoryInHandIfPossible(src, H.held_index)) - add_fingerprint(usr) + add_fingerprint(user) /obj/item/food/clothing name = "temporary moth clothing snack item" diff --git a/code/modules/clothing/head/tinfoilhat.dm b/code/modules/clothing/head/tinfoilhat.dm index 4b265778e23..74ce320a8ab 100644 --- a/code/modules/clothing/head/tinfoilhat.dm +++ b/code/modules/clothing/head/tinfoilhat.dm @@ -8,6 +8,7 @@ clothing_flags = ANTI_TINFOIL_MANEUVER var/datum/brain_trauma/mild/phobia/conspiracies/paranoia var/warped = FALSE + interaction_flags_mouse_drop = NEED_HANDS /datum/armor/costume_foilhat laser = -5 @@ -42,10 +43,10 @@ user.gain_trauma(paranoia, TRAUMA_RESILIENCE_MAGIC) to_chat(user, span_warning("As you don the foiled hat, an entire world of conspiracy theories and seemingly insane ideas suddenly rush into your mind. What you once thought unbelievable suddenly seems.. undeniable. Everything is connected and nothing happens just by accident. You know too much and now they're out to get you. ")) -/obj/item/clothing/head/costume/foilhat/MouseDrop(atom/over_object) +/obj/item/clothing/head/costume/foilhat/mouse_drop_dragged(atom/over_object, mob/user) //God Im sorry - if(!warped && iscarbon(usr)) - var/mob/living/carbon/C = usr + if(!warped && iscarbon(user)) + var/mob/living/carbon/C = user if(src == C.head) to_chat(C, span_userdanger("Why would you want to take this off? Do you want them to get into your mind?!")) return diff --git a/code/modules/clothing/shoes/cowboy.dm b/code/modules/clothing/shoes/cowboy.dm index 73c5a9d0d95..4295b91cad2 100644 --- a/code/modules/clothing/shoes/cowboy.dm +++ b/code/modules/clothing/shoes/cowboy.dm @@ -5,6 +5,8 @@ armor_type = /datum/armor/shoes_cowboy custom_price = PAYCHECK_CREW can_be_tied = FALSE + interaction_flags_mouse_drop = NEED_HANDS | NEED_DEXTERITY + var/max_occupants = 4 /// Do these boots have spur sounds? var/has_spurs = FALSE @@ -52,9 +54,9 @@ user.say(pick("Hot damn!", "Hoo-wee!", "Got-dang!"), spans = list(SPAN_YELL), forced=TRUE) user.client?.give_award(/datum/award/achievement/misc/hot_damn, user) -/obj/item/clothing/shoes/cowboy/MouseDrop_T(mob/living/target, mob/living/user) +/obj/item/clothing/shoes/cowboy/mouse_drop_receive(mob/living/target, mob/living/user, params) . = ..() - if(!(user.mobility_flags & MOBILITY_USE) || user.stat != CONSCIOUS || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !Adjacent(user) || !isliving(target) || !user.Adjacent(target) || target.stat == DEAD) + if(!(user.mobility_flags & MOBILITY_USE) || !isliving(target)) return if(contents.len >= max_occupants) to_chat(user, span_warning("[src] are full!")) diff --git a/code/modules/clothing/shoes/sneakers.dm b/code/modules/clothing/shoes/sneakers.dm index 8d3d9f17645..953d5bd9a1c 100644 --- a/code/modules/clothing/shoes/sneakers.dm +++ b/code/modules/clothing/shoes/sneakers.dm @@ -10,6 +10,7 @@ greyscale_config_inhand_left = /datum/greyscale_config/sneakers/inhand_left greyscale_config_inhand_right = /datum/greyscale_config/sneakers/inhand_right flags_1 = IS_PLAYER_COLORABLE_1 + interaction_flags_mouse_drop = NEED_HANDS /obj/item/clothing/shoes/sneakers/black name = "black shoes" @@ -146,10 +147,9 @@ return FALSE return ..() -/obj/item/clothing/shoes/sneakers/orange/MouseDrop(atom/over) - var/mob/m = usr - if(ishuman(m)) - var/mob/living/carbon/human/c = m +/obj/item/clothing/shoes/sneakers/orange/mouse_drop_dragged(atom/over_object, mob/user) + if(ishuman(user)) + var/mob/living/carbon/human/c = user if(c.shoes == src && attached_cuffs) to_chat(c, span_warning("You need help taking these off!")) return diff --git a/code/modules/food_and_drinks/machinery/monkeyrecycler.dm b/code/modules/food_and_drinks/machinery/monkeyrecycler.dm index d340d4d478d..ca8f6bcafc6 100644 --- a/code/modules/food_and_drinks/machinery/monkeyrecycler.dm +++ b/code/modules/food_and_drinks/machinery/monkeyrecycler.dm @@ -6,8 +6,10 @@ GLOBAL_LIST_EMPTY(monkey_recyclers) icon = 'icons/obj/machines/kitchen.dmi' icon_state = "grinder" layer = BELOW_OBJ_LAYER + interaction_flags_mouse_drop = NEED_DEXTERITY density = TRUE circuit = /obj/item/circuitboard/machine/monkey_recycler + var/stored_matter = 0 var/cube_production = 0.2 var/list/connected = list() //Keeps track of connected xenobio consoles, for deletion in /Destroy() @@ -59,7 +61,7 @@ GLOBAL_LIST_EMPTY(monkey_recyclers) else return ..() -/obj/machinery/monkey_recycler/MouseDrop_T(mob/living/target, mob/living/user) +/obj/machinery/monkey_recycler/mouse_drop_receive(mob/living/target, mob/living/user, params) if(!istype(target)) return if(ismonkey(target)) diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm index 3d10c3f5c47..53fd78cf94d 100644 --- a/code/modules/mining/mine_items.dm +++ b/code/modules/mining/mine_items.dm @@ -160,6 +160,7 @@ close_sound = 'sound/machines/trapdoor/trapdoor_shut.ogg' set_dir_on_move = TRUE can_buckle = TRUE + /// Whether we're on a set of rails or just on the ground var/on_rails = FALSE /// How many turfs we are travelling, also functions as speed (more momentum = faster) @@ -295,17 +296,16 @@ update_rail_state(FALSE) return ..() -/obj/structure/closet/crate/miningcar/MouseDrop(atom/over, src_location, over_location, src_control, over_control, params) - . = ..() - if(!isliving(usr) || !usr.Adjacent(over) || !usr.Adjacent(src)) +/obj/structure/closet/crate/miningcar/mouse_drop_dragged(atom/over, mob/user, src_location, over_location, params) + if(!isliving(user)) return if(on_rails) if(isopenturf(over)) - try_take_off_rails(usr, over) + try_take_off_rails(user, over) return if(istype(over, /obj/structure/minecart_rail) || (isopenturf(over) && (locate(/obj/structure/minecart_rail) in over))) - try_put_on_rails(usr, get_turf(over)) + try_put_on_rails(user, get_turf(over)) return /** diff --git a/code/modules/mob/dead/dead.dm b/code/modules/mob/dead/dead.dm index 30d273db7da..4d74e029860 100644 --- a/code/modules/mob/dead/dead.dm +++ b/code/modules/mob/dead/dead.dm @@ -5,6 +5,7 @@ INITIALIZE_IMMEDIATE(/mob/dead) /mob/dead sight = SEE_TURFS | SEE_MOBS | SEE_OBJS | SEE_SELF move_resist = INFINITY + interaction_flags_atom = parent_type::interaction_flags_atom | INTERACT_ATOM_MOUSEDROP_IGNORE_CHECKS throwforce = 0 /mob/dead/Initialize(mapload) diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 2ef79e5465c..f90cda94563 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -691,15 +691,11 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp GLOB.manifest.ui_interact(src) //this is called when a ghost is drag clicked to something. -/mob/dead/observer/MouseDrop(atom/over) - if(!usr || !over) - return - if (isobserver(usr) && usr.client.holder && (isliving(over) || iscameramob(over)) ) - if (usr.client.holder.cmd_ghost_drag(src,over)) +/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 - return ..() - /mob/dead/observer/Topic(href, href_list) ..() if(usr == src) diff --git a/code/modules/mob/living/basic/slime/slime.dm b/code/modules/mob/living/basic/slime/slime.dm index 63c738b9652..4aa4cf72c4e 100644 --- a/code/modules/mob/living/basic/slime/slime.dm +++ b/code/modules/mob/living/basic/slime/slime.dm @@ -204,12 +204,11 @@ . += "Growth: [amount_grown]/[SLIME_EVOLUTION_THRESHOLD]" . += "Power Level: [powerlevel]/[SLIME_MAX_POWER]" -/mob/living/basic/slime/MouseDrop(atom/movable/target_atom as mob|obj) - if(isliving(target_atom) && target_atom != src && usr == src) +/mob/living/basic/slime/mouse_drop_dragged(atom/target_atom, mob/user) + if(isliving(target_atom) && target_atom != src && user == src) var/mob/living/food = target_atom if(can_feed_on(food)) start_feeding(food) - return ..() ///Slimes can hop off mobs they have latched onto /mob/living/basic/slime/resist_buckle() diff --git a/code/modules/mob/living/carbon/alien/adult/adult.dm b/code/modules/mob/living/carbon/alien/adult/adult.dm index d2ee7432b3c..c15efb77a4a 100644 --- a/code/modules/mob/living/carbon/alien/adult/adult.dm +++ b/code/modules/mob/living/carbon/alien/adult/adult.dm @@ -8,6 +8,7 @@ melee_damage_lower = 20 //Refers to unarmed damage, aliens do unarmed attacks. melee_damage_upper = 20 max_grab = GRAB_AGGRESSIVE + var/caste = "" var/alt_icon = 'icons/mob/nonhuman-player/alienleap.dmi' //used to switch between the two alien icon files. var/leap_on_click = 0 @@ -91,7 +92,7 @@ GLOBAL_LIST_INIT(strippable_alien_humanoid_items, create_strippable_list(list( if(. <= GRAB_AGGRESSIVE) ADD_TRAIT(pulling, TRAIT_FLOORED, CHOKEHOLD_TRAIT) -/mob/living/carbon/alien/adult/MouseDrop_T(atom/dropping, atom/user) +/mob/living/carbon/alien/adult/mouse_drop_receive(atom/dropping, mob/user, params) if(devour_lad(dropping)) return return ..() diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm index 7b61b4cb8ea..44b7db6ee0b 100644 --- a/code/modules/mob/living/carbon/carbon_defines.dm +++ b/code/modules/mob/living/carbon/carbon_defines.dm @@ -121,3 +121,4 @@ var/bodyshape = BODYSHAPE_HUMANOID COOLDOWN_DECLARE(bleeding_message_cd) + diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 40070192b24..b5e538461f2 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1314,6 +1314,21 @@ if(!istype(target)) CRASH("Missing target arg for can_perform_action") + if(!(interaction_flags_atom & INTERACT_ATOM_IGNORE_INCAPACITATED)) + var/ignore_flags = NONE + if(interaction_flags_atom & INTERACT_ATOM_IGNORE_RESTRAINED) + ignore_flags |= IGNORE_RESTRAINTS + if(!(interaction_flags_atom & INTERACT_ATOM_CHECK_GRAB)) + ignore_flags |= IGNORE_GRAB + + if(incapacitated(ignore_flags)) + to_chat(src, span_warning("You are incapacitated at the moment!")) + return FALSE + + if(stat == DEAD || stat != CONSCIOUS) + to_chat(src, span_warning("You are in no physical condition to do this!")) + return FALSE + // If the MOBILITY_UI bitflag is not set it indicates the mob's hands are cutoff, blocked, or handcuffed // Note - AI's and borgs have the MOBILITY_UI bitflag set even though they don't have hands // Also if it is not set, the mob could be incapcitated, knocked out, unconscious, asleep, EMP'd, etc. @@ -1323,11 +1338,14 @@ // NEED_HANDS is already checked by MOBILITY_UI for humans so this is for silicons if((action_bitflags & NEED_HANDS)) + if(HAS_TRAIT(src, TRAIT_HANDS_BLOCKED)) + to_chat(src, span_warning("You can't do that right now!")) + return FALSE if(!can_hold_items(isitem(target) ? target : null)) // almost redundant if it weren't for mobs to_chat(src, span_warning("You don't have the physical ability to do this!")) return FALSE - if(!Adjacent(target) && (target.loc != src) && !recursive_loc_check(src, target)) + if(!(action_bitflags & BYPASS_ADJACENCY) && !Adjacent(target) && (target.loc != src) && !recursive_loc_check(src, 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)) @@ -1335,7 +1353,8 @@ return FALSE else // just a normal carbon mob if((action_bitflags & FORBID_TELEKINESIS_REACH)) - 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 var/datum/dna/mob_DNA = has_dna() @@ -1812,7 +1831,7 @@ GLOBAL_LIST_EMPTY(fire_appearances) ..() update_z(new_turf?.z) -/mob/living/MouseDrop_T(atom/dropping, atom/user) +/mob/living/mouse_drop_receive(atom/dropping, atom/user, params) var/mob/living/U = user if(isliving(dropping)) var/mob/living/M = dropping diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index 9834267047a..acc49dd5721 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -2,7 +2,6 @@ see_invisible = SEE_INVISIBLE_LIVING hud_possible = list(HEALTH_HUD,STATUS_HUD,ANTAG_HUD) pressure_resistance = 10 - hud_type = /datum/hud/living ///Tracks the current size of the mob in relation to its original size. Use update_transform(resize) to change it. diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm index 71292405faa..51b2f395497 100644 --- a/code/modules/mob/living/simple_animal/bot/mulebot.dm +++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm @@ -27,7 +27,6 @@ mob_size = MOB_SIZE_LARGE buckle_prevents_pull = TRUE // No pulling loaded shit bot_mode_flags = ~BOT_MODE_ROUNDSTART_POSSESSION - req_one_access = list(ACCESS_ROBOTICS, ACCESS_CARGO) radio_key = /obj/item/encryptionkey/headset_cargo radio_channel = RADIO_CHANNEL_SUPPLY @@ -378,13 +377,8 @@ // mousedrop a crate to load the bot // can load anything if hacked -/mob/living/simple_animal/bot/mulebot/MouseDrop_T(atom/movable/AM, mob/user) - var/mob/living/L = user - - if (!istype(L)) - return - - if(user.incapacitated() || (istype(L) && L.body_position == LYING_DOWN)) +/mob/living/simple_animal/bot/mulebot/mouse_drop_receive(atom/movable/AM, mob/user, params) + if(!isliving(user)) return if(!istype(AM) || isdead(AM) || iscameramob(AM) || istype(AM, /obj/effect/dummy/phased_mob)) @@ -392,7 +386,6 @@ load(AM) - // called to load a crate /mob/living/simple_animal/bot/mulebot/proc/load(atom/movable/AM) if(load || AM.anchored) @@ -812,8 +805,7 @@ icon_state = "paranormalmulebot0" base_icon = "paranormalmulebot" - -/mob/living/simple_animal/bot/mulebot/paranormal/MouseDrop_T(atom/movable/AM, mob/user) +/mob/living/simple_animal/bot/mulebot/paranormal/mouse_drop_receive(atom/movable/AM, mob/user, params) var/mob/living/L = user if(user.incapacitated() || (istype(L) && L.body_position == LYING_DOWN)) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 4219e8e3c38..ca393cf2566 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -889,20 +889,6 @@ set category = null return -/** - * Controls if a mouse drop succeeds (return null if it doesnt) - */ -/mob/MouseDrop(mob/M) - . = ..() - if(M != usr) - return - if(usr == src) - return - if(!Adjacent(usr)) - return - if(isAI(M)) - return - ///Is the mob muzzled (default false) /mob/proc/is_muzzled() return FALSE @@ -1172,6 +1158,8 @@ * * 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 + * * BYPASS_ADJACENCY - The target does not have to be adjacent + * * SILENT_ADJACENCY - Adjacency is required but errors are not printed * * 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/mod/mod_control.dm b/code/modules/mod/mod_control.dm index 2452d404a93..c386f7f51c6 100644 --- a/code/modules/mod/mod_control.dm +++ b/code/modules/mod/mod_control.dm @@ -13,6 +13,7 @@ base_icon_state = "control" w_class = WEIGHT_CLASS_BULKY slot_flags = ITEM_SLOT_BACK + interaction_flags_mouse_drop = NEED_HANDS strip_delay = 10 SECONDS armor_type = /datum/armor/none actions_types = list( @@ -228,9 +229,9 @@ playsound(src, 'sound/machines/scanbuzz.ogg', 25, FALSE, SILENCED_SOUND_EXTRARANGE) return FALSE -/obj/item/mod/control/MouseDrop(atom/over_object) - if(usr != wearer || !istype(over_object, /atom/movable/screen/inventory/hand)) - return ..() +/obj/item/mod/control/mouse_drop_dragged(atom/over_object, mob/user) + if(user != wearer || !istype(over_object, /atom/movable/screen/inventory/hand)) + return for(var/obj/item/part as anything in get_parts()) if(part.loc != src) balloon_alert(wearer, "retract parts first!") @@ -239,8 +240,7 @@ if(!wearer.incapacitated()) var/atom/movable/screen/inventory/hand/ui_hand = over_object if(wearer.putItemFromInventoryInHandIfPossible(src, ui_hand.held_index)) - add_fingerprint(usr) - return ..() + add_fingerprint(user) /obj/item/mod/control/wrench_act(mob/living/user, obj/item/wrench) if(seconds_electrified && get_charge() && shock(user)) diff --git a/code/modules/modular_computers/computers/item/computer.dm b/code/modules/modular_computers/computers/item/computer.dm index a17a9bb8ed0..a490af9be8d 100644 --- a/code/modules/modular_computers/computers/item/computer.dm +++ b/code/modules/modular_computers/computers/item/computer.dm @@ -12,6 +12,7 @@ max_integrity = 100 armor_type = /datum/armor/item_modular_computer light_system = OVERLAY_LIGHT_DIRECTIONAL + interaction_flags_mouse_drop = NEED_HANDS | ALLOW_RESTING ///The ID currently stored in the computer. var/obj/item/card/id/computer_id_slot @@ -334,11 +335,9 @@ update_appearance() return TRUE -/obj/item/modular_computer/MouseDrop(obj/over_object, src_location, over_location) - var/mob/M = usr - if((!istype(over_object, /atom/movable/screen)) && usr.can_perform_action(src)) - return attack_self(M) - return ..() +/obj/item/modular_computer/mouse_drop_dragged(atom/over_object, mob/user) + if(!istype(over_object, /atom/movable/screen)) + return attack_self(user) /obj/item/modular_computer/attack_ai(mob/user) return attack_self(user) diff --git a/code/modules/modular_computers/computers/item/laptop.dm b/code/modules/modular_computers/computers/item/laptop.dm index 523c241724e..5053b6c6b2c 100644 --- a/code/modules/modular_computers/computers/item/laptop.dm +++ b/code/modules/modular_computers/computers/item/laptop.dm @@ -11,6 +11,8 @@ hardware_flag = PROGRAM_LAPTOP max_idle_programs = 3 w_class = WEIGHT_CLASS_NORMAL + interaction_flags_mouse_drop = NEED_HANDS + // No running around with open laptops in hands. item_flags = SLOWS_WHILE_IN_HAND @@ -58,20 +60,15 @@ try_toggle_open(usr) -/obj/item/modular_computer/laptop/MouseDrop(obj/over_object, src_location, over_location) - . = ..() - if(over_object == usr || over_object == src) - try_toggle_open(usr) +/obj/item/modular_computer/laptop/mouse_drop_dragged(atom/over_object, mob/user, src_location, over_location, params) + if(over_object == user || over_object == src) + try_toggle_open(user) return if(istype(over_object, /atom/movable/screen/inventory/hand)) var/atom/movable/screen/inventory/hand/H = over_object - var/mob/M = usr - - if(M.stat != CONSCIOUS || HAS_TRAIT(M, TRAIT_HANDS_BLOCKED)) + if(!isturf(loc)) return - if(!isturf(loc) || !Adjacent(M)) - return - M.put_in_hand(src, H.held_index) + user.put_in_hand(src, H.held_index) /obj/item/modular_computer/laptop/attack_hand(mob/user, list/modifiers) . = ..() diff --git a/code/modules/paperwork/desk_bell.dm b/code/modules/paperwork/desk_bell.dm index e193bbc98b1..c3964b7292c 100644 --- a/code/modules/paperwork/desk_bell.dm +++ b/code/modules/paperwork/desk_bell.dm @@ -9,6 +9,7 @@ anchored = FALSE pass_flags = PASSTABLE // Able to place on tables max_integrity = 5000 // To make attacking it not instantly break it + /// The amount of times this bell has been rang, used to check the chance it breaks var/times_rang = 0 /// Is this bell broken? @@ -110,17 +111,14 @@ desc = "The cornerstone of any customer service job. This one's been modified for hyper-performance." ring_cooldown_length = 0 -/obj/structure/desk_bell/MouseDrop(obj/over_object, src_location, over_location) +/obj/structure/desk_bell/mouse_drop_dragged(atom/over_object, mob/user) if(!istype(over_object, /obj/vehicle/ridden/wheelchair)) return - if(!Adjacent(over_object) || !Adjacent(usr)) - return var/obj/vehicle/ridden/wheelchair/target = over_object if(target.bell_attached) - usr.balloon_alert(usr, "already has a bell!") + user.balloon_alert(user, "already has a bell!") return - usr.balloon_alert(usr, "attaching bell...") - if(!do_after(usr, 0.5 SECONDS)) + user.balloon_alert(user, "attaching bell...") + if(!do_after(user, 0.5 SECONDS)) return target.attach_bell(src) - return ..() diff --git a/code/modules/paperwork/paper_cutter.dm b/code/modules/paperwork/paper_cutter.dm index 8e4fedf2fda..1315ca3a81d 100644 --- a/code/modules/paperwork/paper_cutter.dm +++ b/code/modules/paperwork/paper_cutter.dm @@ -177,12 +177,7 @@ new /obj/item/paper/paperslip(get_turf(src)) update_appearance() -/obj/item/papercutter/MouseDrop(atom/over_object) - . = ..() - var/mob/user = usr - if(user.incapacitated() || !Adjacent(user)) - return - +/obj/item/papercutter/mouse_drop_dragged(atom/over_object, mob/user) if(over_object == user) user.put_in_hands(src) diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm index 0712e516de4..b7796ad070a 100644 --- a/code/modules/paperwork/photocopier.dm +++ b/code/modules/paperwork/photocopier.dm @@ -66,6 +66,8 @@ GLOBAL_LIST_INIT(paper_blanks, init_paper_blanks()) power_channel = AREA_USAGE_EQUIP max_integrity = 300 integrity_failure = 0.33 + interaction_flags_mouse_drop = NEED_DEXTERITY | ALLOW_RESTING + /// A reference to a mob on top of the photocopier trying to copy their ass. Null if there is no mob. var/mob/living/ass /// A reference to the toner cartridge that's inserted into the copier. Null if there is no cartridge. @@ -87,6 +89,7 @@ GLOBAL_LIST_INIT(paper_blanks, init_paper_blanks()) /// A stack for all the empty paper we have newly inserted (LIFO) var/list/paper_stack = list() + /obj/machinery/photocopier/Initialize(mapload) . = ..() toner_cartridge = new(src) @@ -586,8 +589,8 @@ GLOBAL_LIST_INIT(paper_blanks, init_paper_blanks()) new /obj/effect/decal/cleanable/oil(get_turf(src)) toner_cartridge.charges = 0 -/obj/machinery/photocopier/MouseDrop_T(mob/target, mob/user) - if(!istype(target) || target.anchored || target.buckled || !Adjacent(target) || !user.can_perform_action(src, action_bitflags = ALLOW_RESTING) || target == ass || copier_blocked()) +/obj/machinery/photocopier/mouse_drop_receive(mob/target, mob/user, params) + if(!istype(target) || target.anchored || target.buckled || target == ass || copier_blocked()) return add_fingerprint(user) if(target == user) @@ -626,7 +629,7 @@ GLOBAL_LIST_INIT(paper_blanks, init_paper_blanks()) return TRUE /** - * Checks if the copier is deleted, or has something dense at its location. Called in `MouseDrop_T()` + * Checks if the copier is deleted, or has something dense at its location. Called in `mouse_drop_receive()` */ /obj/machinery/photocopier/proc/copier_blocked() if(QDELETED(src)) diff --git a/code/modules/plumbing/ducts.dm b/code/modules/plumbing/ducts.dm index 87a46107a4b..de4a9005792 100644 --- a/code/modules/plumbing/ducts.dm +++ b/code/modules/plumbing/ducts.dm @@ -295,7 +295,7 @@ All the important duct code: disconnect_duct() return ..() -/obj/machinery/duct/MouseDrop_T(atom/drag_source, mob/living/user) +/obj/machinery/duct/mouse_drop_receive(atom/drag_source, mob/living/user, params) if(!istype(drag_source, /obj/machinery/duct)) return var/obj/machinery/duct/other = drag_source diff --git a/code/modules/projectiles/guns/energy/laser_gatling.dm b/code/modules/projectiles/guns/energy/laser_gatling.dm index a27ee66a1ff..0f5e7d3deac 100644 --- a/code/modules/projectiles/guns/energy/laser_gatling.dm +++ b/code/modules/projectiles/guns/energy/laser_gatling.dm @@ -11,6 +11,7 @@ righthand_file = 'icons/mob/inhands/equipment/backpack_righthand.dmi' slot_flags = ITEM_SLOT_BACK w_class = WEIGHT_CLASS_HUGE + var/obj/item/gun/energy/minigun/gun var/obj/item/stock_parts/cell/minigun/battery var/armed = FALSE //whether the gun is attached, FALSE is attached, TRUE is the gun is wielded. @@ -63,22 +64,14 @@ if(armed) user.dropItemToGround(gun, TRUE) -/obj/item/minigunpack/MouseDrop(atom/over_object) - . = ..() +/obj/item/minigunpack/mouse_drop_dragged(atom/over_object, mob/user) if(armed) return - if(iscarbon(usr)) - var/mob/M = usr - - if(!over_object) - return - - if(!M.incapacitated()) - - if(istype(over_object, /atom/movable/screen/inventory/hand)) - var/atom/movable/screen/inventory/hand/H = over_object - M.putItemFromInventoryInHandIfPossible(src, H.held_index) + if(iscarbon(user)) + if(istype(over_object, /atom/movable/screen/inventory/hand)) + var/atom/movable/screen/inventory/hand/H = over_object + user.putItemFromInventoryInHandIfPossible(src, H.held_index) /obj/item/minigunpack/update_icon_state() icon_state = armed ? "notholstered" : "holstered" diff --git a/code/modules/reagents/chemistry/items.dm b/code/modules/reagents/chemistry/items.dm index 6517cbc4339..d307f96dc26 100644 --- a/code/modules/reagents/chemistry/items.dm +++ b/code/modules/reagents/chemistry/items.dm @@ -14,6 +14,8 @@ item_flags = NOBLUDGEON resistance_flags = FLAMMABLE w_class = WEIGHT_CLASS_TINY + interaction_flags_mouse_drop = NEED_HANDS + ///How many pages the booklet holds var/number_of_pages = 50 @@ -41,11 +43,8 @@ user.put_in_active_hand(src) return ..() -/obj/item/ph_booklet/MouseDrop(atom/over, src_location, over_location, src_control, over_control, params) - var/mob/living/user = usr - if(!isliving(user) || !Adjacent(user)) - return - if(HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) +/obj/item/ph_booklet/mouse_drop_dragged(atom/over, mob/user, src_location, over_location, params) + if(!isliving(user)) return if(!number_of_pages) to_chat(user, span_warning("[src] is empty!")) diff --git a/code/modules/reagents/chemistry/machinery/portable_chem_mixer.dm b/code/modules/reagents/chemistry/machinery/portable_chem_mixer.dm index 25a7eecbd37..5396839e13d 100644 --- a/code/modules/reagents/chemistry/machinery/portable_chem_mixer.dm +++ b/code/modules/reagents/chemistry/machinery/portable_chem_mixer.dm @@ -10,6 +10,7 @@ custom_price = PAYCHECK_CREW * 10 custom_premium_price = PAYCHECK_CREW * 14 interaction_flags_click = FORBID_TELEKINESIS_REACH + interaction_flags_mouse_drop = FORBID_TELEKINESIS_REACH ///Creating an empty slot for a beaker that can be added to dispense into var/obj/item/reagent_containers/beaker @@ -243,11 +244,10 @@ update_appearance() return TRUE -/obj/item/storage/portable_chem_mixer/MouseDrop(obj/over_object) - . = ..() +/obj/item/storage/portable_chem_mixer/mouse_drop_dragged(atom/over_object) if(ismob(loc)) var/mob/M = loc - if(!M.incapacitated() && istype(over_object, /atom/movable/screen/inventory/hand)) + if(istype(over_object, /atom/movable/screen/inventory/hand)) var/atom/movable/screen/inventory/hand/H = over_object M.putItemFromInventoryInHandIfPossible(src, H.held_index) diff --git a/code/modules/recycling/disposal/bin.dm b/code/modules/recycling/disposal/bin.dm index 2771bc1adb2..4b54cf9f4b0 100644 --- a/code/modules/recycling/disposal/bin.dm +++ b/code/modules/recycling/disposal/bin.dm @@ -164,7 +164,7 @@ user.visible_message(span_notice("[user.name] places \the [I] into \the [src]."), span_notice("You place \the [I] into \the [src].")) /// Mouse drop another mob or self -/obj/machinery/disposal/MouseDrop_T(mob/living/target, mob/living/user) +/obj/machinery/disposal/mouse_drop_receive(mob/living/target, mob/living/user, params) if(istype(target)) stuff_mob_in(target, user) diff --git a/code/modules/research/machinery/_production.dm b/code/modules/research/machinery/_production.dm index 16ccedaf778..04c777bb1c0 100644 --- a/code/modules/research/machinery/_production.dm +++ b/code/modules/research/machinery/_production.dm @@ -3,6 +3,7 @@ desc = "Makes researched and prototype items with materials and energy." /// Energy cost per full stack of materials spent. Material insertion is 40% of this. active_power_usage = 0.05 * STANDARD_CELL_RATE + interaction_flags_atom = parent_type::interaction_flags_atom | INTERACT_ATOM_MOUSEDROP_IGNORE_CHECKS /// The efficiency coefficient. Material costs and print times are multiplied by this number; var/efficiency_coeff = 1 @@ -438,18 +439,17 @@ SStgui.update_uis(src) icon_state = initial(icon_state) -/obj/machinery/rnd/production/MouseDrop(atom/over, src_location, over_location, src_control, over_control, params) - . = ..() - if(!can_interact(usr) || (!issilicon(usr) && !isAdminGhostAI(usr)) && !Adjacent(usr)) +/obj/machinery/rnd/production/mouse_drop_dragged(atom/over, mob/user, src_location, over_location, params) + if(!can_interact(user) || (!HAS_SILICON_ACCESS(user) && !isAdminGhostAI(user)) && !Adjacent(user)) return if(busy) - balloon_alert(usr, "busy printing!") + balloon_alert(user, "busy printing!") return var/direction = get_dir(src, over_location) if(!direction) return drop_direction = direction - balloon_alert(usr, "dropping [dir2text(drop_direction)]") + balloon_alert(user, "dropping [dir2text(drop_direction)]") /obj/machinery/rnd/production/click_alt(mob/user) if(drop_direction == 0) diff --git a/code/modules/research/xenobiology/crossbreeding/_clothing.dm b/code/modules/research/xenobiology/crossbreeding/_clothing.dm index 4fb51d223bd..c174856a62a 100644 --- a/code/modules/research/xenobiology/crossbreeding/_clothing.dm +++ b/code/modules/research/xenobiology/crossbreeding/_clothing.dm @@ -16,6 +16,7 @@ Slimecrossing Armor armor_type = /datum/armor/mask_nobreath flags_cover = MASKCOVERSMOUTH resistance_flags = NONE + interaction_flags_mouse_drop = NEED_HANDS /datum/armor/mask_nobreath bio = 50 @@ -125,8 +126,8 @@ Slimecrossing Armor return return ..() -/obj/item/clothing/head/peaceflower/MouseDrop(atom/over, src_location, over_location, src_control, over_control, params) - if(at_peace_check(usr)) +/obj/item/clothing/head/peaceflower/mouse_drop_dragged(atom/over, mob/user, src_location, over_location, params) + if(at_peace_check(user)) return return ..() diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm index fad856df2b5..6740424cf80 100644 --- a/code/modules/shuttle/emergency.dm +++ b/code/modules/shuttle/emergency.dm @@ -805,10 +805,6 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/item/storage/pod, 32) atom_storage?.show_contents(user) return TRUE -/obj/item/storage/pod/MouseDrop(over_object, src_location, over_location) - if(can_interact(usr)) - return ..() - /obj/item/storage/pod/attack_hand_secondary(mob/user, list/modifiers) if(!can_interact(user)) return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN diff --git a/code/modules/vehicles/cars/car.dm b/code/modules/vehicles/cars/car.dm index 46a9c6f7f56..19bf0f20eb2 100644 --- a/code/modules/vehicles/cars/car.dm +++ b/code/modules/vehicles/cars/car.dm @@ -1,6 +1,7 @@ /obj/vehicle/sealed/car layer = ABOVE_MOB_LAYER move_resist = MOVE_FORCE_VERY_STRONG + ///Bitflags for special behavior such as kidnapping var/car_traits = NONE ///Sound file(s) to play when we drive around @@ -21,9 +22,9 @@ if(car_traits & CAN_KIDNAP) initialize_controller_action_type(/datum/action/vehicle/sealed/dump_kidnapped_mobs, VEHICLE_CONTROL_DRIVE) -/obj/vehicle/sealed/car/MouseDrop_T(atom/dropping, mob/M) - if(M.incapacitated() || (HAS_TRAIT(M, TRAIT_HANDS_BLOCKED) && !is_driver(M))) - return FALSE +/obj/vehicle/sealed/car/mouse_drop_receive(atom/dropping, mob/M, params) + if(HAS_TRAIT(M, TRAIT_HANDS_BLOCKED) && !is_driver(M)) + return if((car_traits & CAN_KIDNAP) && isliving(dropping) && M != dropping) var/mob/living/kidnapped = dropping kidnapped.visible_message(span_warning("[M] starts forcing [kidnapped] into [src]!")) diff --git a/code/modules/vehicles/scooter.dm b/code/modules/vehicles/scooter.dm index 0cfde3de8ad..0b842b8ed9c 100644 --- a/code/modules/vehicles/scooter.dm +++ b/code/modules/vehicles/scooter.dm @@ -161,9 +161,8 @@ victim.visible_message(span_danger("[victim] straight up gets grinded into the ground by [skater]'s [src]! Radical!")) addtimer(CALLBACK(src, PROC_REF(grind)), 0.1 SECONDS) -/obj/vehicle/ridden/scooter/skateboard/MouseDrop(atom/over_object) - . = ..() - var/mob/living/carbon/skater = usr +/obj/vehicle/ridden/scooter/skateboard/mouse_drop_dragged(atom/over_object, mob/user) + var/mob/living/carbon/skater = user if(!istype(skater)) return if (over_object == skater) diff --git a/code/modules/vehicles/sealed.dm b/code/modules/vehicles/sealed.dm index 0ecc492f6d5..821a69d8f82 100644 --- a/code/modules/vehicles/sealed.dm +++ b/code/modules/vehicles/sealed.dm @@ -1,5 +1,7 @@ /obj/vehicle/sealed flags_1 = PREVENT_CONTENTS_EXPLOSION_1 + interaction_flags_mouse_drop = NEED_HANDS + var/enter_delay = 2 SECONDS var/mouse_pointer var/headlights_toggle = FALSE @@ -20,7 +22,7 @@ if(istype(E)) E.vehicle_entered_target = src -/obj/vehicle/sealed/MouseDrop_T(atom/dropping, mob/M) +/obj/vehicle/sealed/mouse_drop_receive(atom/dropping, mob/M, params) if(!istype(dropping) || !istype(M)) return ..() if(M == dropping) diff --git a/code/modules/vehicles/wheelchair.dm b/code/modules/vehicles/wheelchair.dm index 92386b0fbc3..b94257bb45f 100644 --- a/code/modules/vehicles/wheelchair.dm +++ b/code/modules/vehicles/wheelchair.dm @@ -6,7 +6,9 @@ layer = OBJ_LAYER max_integrity = 100 armor_type = /datum/armor/ridden_wheelchair - density = FALSE //Thought I couldn't fix this one easily, phew + density = FALSE + interaction_flags_mouse_drop = ALLOW_RESTING + /// Run speed delay is multiplied with this for vehicle move delay. var/delay_multiplier = 6.7 /// This variable is used to specify which overlay icon is used for the wheelchair, ensures wheelchair can cover your legs @@ -122,17 +124,14 @@ fire = 30 acid = 40 -/obj/vehicle/ridden/wheelchair/MouseDrop(over_object, src_location, over_location) //Lets you collapse wheelchair - . = ..() - if(over_object != usr || !Adjacent(usr) || !foldabletype) - return FALSE - if(!ishuman(usr) || !usr.can_perform_action(src, ALLOW_RESTING)) +/obj/vehicle/ridden/wheelchair/mouse_drop_dragged(atom/over_object, mob/user) //Lets you collapse wheelchair + if(over_object != user || !foldabletype || !ishuman(user)) return FALSE if(has_buckled_mobs()) return FALSE - usr.visible_message(span_notice("[usr] collapses [src]."), span_notice("You collapse [src].")) + user.visible_message(span_notice("[user] collapses [src]."), span_notice("You collapse [src].")) var/obj/vehicle/ridden/wheelchair/wheelchair_folded = new foldabletype(get_turf(src)) - usr.put_in_hands(wheelchair_folded) + user.put_in_hands(wheelchair_folded) qdel(src) /obj/item/wheelchair/attack_self(mob/user) //Deploys wheelchair on in-hand use