mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-01-29 02:31:49 +00:00
Refactored mousedrag procs, added signals, some safeguards, did some cleanups around, renamed them to make a little more sense. Mostly put in line with TG's code. Fast clicking and releasing with a drag, depending on the grace period and how fast it is done, can be counted as clicks, to aid in combat scenarios where you spamclick.
129 lines
5.5 KiB
Plaintext
129 lines
5.5 KiB
Plaintext
/*
|
|
MouseDrop:
|
|
|
|
Called on the atom you're dragging. In a lot of circumstances we want to use the
|
|
receiving object instead, so that's the default action. This allows you to drag
|
|
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
|
|
|
|
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
|
|
|
|
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))
|
|
//Check for adjacency
|
|
// In TG it's `if(!(combined_atom_flags & INTERACT_ATOM_MOUSEDROP_IGNORE_ADJACENT) && (!CanReach(user) || !over.CanReach(user)))` but i'm not recreating those procs now
|
|
if(!(combined_atom_flags & INTERACT_ATOM_MOUSEDROP_IGNORE_ADJACENT) && (!Adjacent(user) || !over.Adjacent(user)))
|
|
return // should stop you from dragging through windows
|
|
|
|
// NOT IMPLEMENTED IN AURORA
|
|
// if(!(combined_atom_flags & INTERACT_ATOM_MOUSEDROP_IGNORE_USABILITY))
|
|
// //Bypass adjacency cause we already checked for it above
|
|
// if(!user.can_perform_action(src, interaction_flags_mouse_drop | over.interaction_flags_mouse_drop | BYPASS_ADJACENCY))
|
|
// 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)
|
|
|
|
return
|
|
|
|
/// Handles treating drags as clicks if they're within some conditions
|
|
/// Does some other stuff adjacent to trying to figure out what the user actually "wanted" to click
|
|
/// Returns TRUE if it caused a click, FALSE otherwise
|
|
/client/proc/check_drag_proximity(atom/dragging, atom/over, src_location, over_location, src_control, over_control, params)
|
|
// We will swap which thing we're trying to check for clickability based off the type
|
|
// Assertion is if you drag a turf to anything else, you really just wanted to click the anything else
|
|
// And slightly misseed. I'm not interested in making this game pixel percise, so if it fits our other requirements
|
|
// Lets just let that through yeah?
|
|
var/atom/attempt_click = dragging
|
|
var/atom/click_from = over
|
|
var/location_to_use = src_location
|
|
var/control_to_use = src_control
|
|
if(isturf(attempt_click) && !isturf(over))
|
|
// swapppp
|
|
attempt_click = over
|
|
click_from = dragging
|
|
location_to_use = over_location
|
|
control_to_use = over_control
|
|
|
|
if(is_drag_clickable(attempt_click, click_from, params))
|
|
Click(attempt_click, location_to_use, control_to_use, params)
|
|
return TRUE
|
|
return FALSE
|
|
|
|
/// Distance in pixels that we consider "acceptable" from the initial click to the release
|
|
/// Note: this does not account for the position of the object, just where it is on the screen
|
|
#define LENIENCY_DISTANCE 16
|
|
/// Accepted time in seconds between the initial click and drag release
|
|
/// Go higher then this and we just don't care anymore
|
|
#define LENIENCY_TIME (0.1 SECONDS)
|
|
|
|
/// Does the logic for checking if a drag counts as a click or not
|
|
/// Returns true if it does, false otherwise
|
|
/client/proc/is_drag_clickable(atom/dragging, atom/over, params)
|
|
if(dragging == over)
|
|
return TRUE
|
|
if(world.time - drag_start > LENIENCY_TIME) // Time's up bestie
|
|
return FALSE
|
|
if(!get_turf(dragging)) // If it isn't in the world, drop it. This is for things that can move, and we assume hud elements will not have this problem
|
|
return FALSE
|
|
// Basically, are you trying to buckle someone down, or drag them onto you?
|
|
// If so, we know you must be right about what you want
|
|
if(ismovable(over))
|
|
var/atom/movable/over_movable = over
|
|
// The buckle bit will cover most mobs, for stupid reasons. still useful here tho
|
|
if(over_movable.can_be_buckled || over_movable == eye)
|
|
return FALSE
|
|
|
|
var/list/modifiers = params2list(params)
|
|
var/list/old_offsets = screen_loc_to_offset(LAZYACCESS(drag_details, SCREEN_LOC), view)
|
|
var/list/new_offsets = screen_loc_to_offset(LAZYACCESS(modifiers, SCREEN_LOC), view)
|
|
|
|
var/distance = sqrt(((old_offsets[1] - new_offsets[1]) ** 2) + ((old_offsets[2] - new_offsets[2]) ** 2))
|
|
if(distance > LENIENCY_DISTANCE)
|
|
return FALSE
|
|
|
|
return TRUE
|
|
|
|
|
|
/*
|
|
MOUSE UP AND MOUSE DOWN AREN'T HERE BUT IN code\modules\client\client_procs.dm
|
|
*/
|