Skip to content

Commit

Permalink
refactor: LootPanel И большой рефактор Альт Клика (ss220-space#6598)
Browse files Browse the repository at this point in the history
* a

* bugfix: LootPanel И большой рефактор Альт Клика

* fixes
  • Loading branch information
BeebBeebBoob authored Feb 24, 2025
1 parent 4297798 commit c11e2e1
Show file tree
Hide file tree
Showing 136 changed files with 874 additions and 794 deletions.
8 changes: 8 additions & 0 deletions code/__DEFINES/click.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/// Action has succeeded, preventing further alt click interaction
#define CLICK_ACTION_SUCCESS (1<<0)
/// Action failed, preventing further alt click interaction
#define CLICK_ACTION_BLOCKING (1<<1)
/// Either return state
#define CLICK_ACTION_ANY (CLICK_ACTION_SUCCESS | CLICK_ACTION_BLOCKING)

/// Use NONE for continue interaction
2 changes: 1 addition & 1 deletion code/__DEFINES/dcs/signals.dm
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@
#define COMPONENT_ALLOW_EXAMINATE (1<<0) //Allows the user to examinate regardless of client.eye.
///from base of atom/CtrlClickOn(): (/mob)
#define COMSIG_CLICK_CTRL "ctrl_click"
///from base of atom/AltClick(): (/mob)
///from base of atom/base_click_alt(): (/mob)
#define COMSIG_CLICK_ALT "alt_click"
///from base of atom/CtrlShiftClick(/mob)
#define COMSIG_CLICK_CTRL_SHIFT "ctrl_shift_click"
Expand Down
5 changes: 0 additions & 5 deletions code/__DEFINES/flags.dm
Original file line number Diff line number Diff line change
Expand Up @@ -237,9 +237,4 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
#define DEFAULT_DOAFTER_IGNORE (DA_IGNORE_LYING|DA_IGNORE_RESTRAINED)


//Incapacitated ignore flags for [/proc/incapacitated()]
/// If the incapacitated will ignore a mob in restraints
#define INC_IGNORE_RESTRAINED (1<<0)
/// If the incapacitated will ignore a mob being agressively grabbed
#define INC_IGNORE_GRABBED (1<<1)

6 changes: 6 additions & 0 deletions code/__DEFINES/is_helpers.dm
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
// simple is_type and similar inline helpers
#define in_range(source, user) (get_dist(source, user) <= 1 && (get_step(source, 0)?:z) == (get_step(user, 0)?:z))

/// Within given range, but not counting z-levels
#define IN_GIVEN_RANGE(source, other, given_range) (get_dist(source, other) <= given_range && (get_step(source, 0)?:z) == (get_step(other, 0)?:z))

// Atoms
#define isatom(A) (isloc(A))

Expand Down
2 changes: 0 additions & 2 deletions code/__DEFINES/misc.dm
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,6 @@
#define STAGE_FIVE 9
#define STAGE_SIX 11 //From supermatter shard

#define in_range(source, user) (get_dist(source, user) <= 1)

#define FOR_DVIEW(type, range, center, invis_flags) \
GLOB.dview_mob.loc = center; \
GLOB.dview_mob.set_invis_see(invis_flags); \
Expand Down
32 changes: 32 additions & 0 deletions code/__DEFINES/mobs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -467,3 +467,35 @@

/// Eyes examine time mod
#define EXAMINE_INSTANT 0 // 0 seconds

//Incapacitated ignore flags for [/proc/incapacitated()].
// They also used at interaction_flags_c var.
/// If the incapacitated will ignore a mob in restraints
#define INC_IGNORE_RESTRAINED (1<<0)
/// If the incapacitated will ignore a mob being agressively grabbed
#define INC_IGNORE_GRABBED (1<<1)

/// If reading is required to perform action (can't read a book if you are illiterate)
#define NEED_LITERACY (1<<0)
/// If incapacitated doesn't needed to be checked.
#define BYPASS_INCAPACITATED (1<<1)
/// If other mobs (monkeys, aliens, etc) can perform action (can't use computers if you are a monkey)
#define NEED_DEXTERITY (1<<2)
/// If hands are required to perform action (can't use objects that require hands if you are a cyborg)
#define NEED_HANDS (1<<3)
/// If telekinesis is forbidden to perform action from a distance (ex. canisters are blacklisted from telekinesis manipulation)
#define FORBID_TELEKINESIS_REACH (1<<4)
/// If silicons are allowed to perform action from a distance (silicons can operate airlocks from far away)
#define ALLOW_SILICON_REACH (1<<5)
/// If resting on the floor is allowed to perform action (pAIs can play music while resting)
#define ALLOW_RESTING (1<<6)
/// If this is accessible to creatures with ventcrawl capabilities
#define NEED_VENTCRAWL (1<<7)
/// Skips adjacency checks
#define BYPASS_ADJACENCY (1<<8)
/// Skips recursive loc checks
#define NOT_INSIDE_TARGET (1<<9)
/// Checks for base adjacency, but silences the error
#define SILENT_ADJACENCY (1<<10)
/// Allows pAIs to perform an action
#define ALLOW_PAI (1<<11)
3 changes: 0 additions & 3 deletions code/__DEFINES/traits/declarations.dm
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,3 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define TRAIT_BLOB_ZOMBIFIED "blob_zombified"

#define TRAIT_BEING_OFFERED "offered"

/// Prevents the affected object from opening a loot window via alt click. See atom/AltClick()
#define TRAIT_ALT_CLICK_BLOCKER "no_alt_click"
3 changes: 3 additions & 0 deletions code/__HELPERS/view.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#define DEFAULT_SIGHT_DISTANCE 7
/// Basic check to see if the src object can see the target object.
#define CAN_I_SEE(target) ((src in viewers(DEFAULT_SIGHT_DISTANCE, target)) || in_range(target, src))
1 change: 0 additions & 1 deletion code/_globalvars/traits.dm
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
GLOBAL_LIST_INIT(traits_by_type, list(
/atom = list(
"TRAIT_AI_PAUSED" = TRAIT_AI_PAUSED,
"TRAIT_ALT_CLICK_BLOCKER" = TRAIT_ALT_CLICK_BLOCKER,
"TRAIT_BEING_SHOCKED" = TRAIT_BEING_SHOCKED,
"TRAIT_BLOCK_RADIATION" = TRAIT_BLOCK_RADIATION,
"TRAIT_CMAGGED" = TRAIT_CMAGGED,
Expand Down
32 changes: 24 additions & 8 deletions code/_onclick/ai.dm
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
ShiftClickOn(A)
return
if(modifiers["alt"]) // alt and alt-gr (rightalt)
AltClickOn(A)
ai_base_click_alt(A)
return
if(modifiers["ctrl"])
CtrlClickOn(A)
Expand Down Expand Up @@ -126,8 +126,6 @@
A.AIShiftClick(src)
/mob/living/silicon/ai/CtrlClickOn(atom/A)
A.AICtrlClick(src)
/mob/living/silicon/ai/AltClickOn(atom/A)
A.AIAltClick(src)
/mob/living/silicon/ai/MiddleClickOn(atom/A)
A.AIMiddleClick(src)
/mob/living/silicon/ai/MiddleShiftClickOn(atom/A)
Expand All @@ -151,8 +149,26 @@
/atom/proc/AICtrlClick(mob/living/silicon/user)
return

/atom/proc/AIAltClick(atom/A)
AltClick(A)
/// Reimplementation of base_click_alt for AI
/mob/living/silicon/ai/proc/ai_base_click_alt(atom/target)
// If for some reason we can't alt click
if(SEND_SIGNAL(src, COMSIG_MOB_ALTCLICKON, target) & COMSIG_MOB_CANCEL_CLICKON)
return

if(!isturf(target) && can_perform_action(target, (target.interaction_flags_click | SILENT_ADJACENCY)))
// Signal intercept
if(SEND_SIGNAL(target, COMSIG_CLICK_ALT, src) & CLICK_ACTION_ANY)
return

// AI alt click interaction succeeds
if(target.ai_click_alt(src) & CLICK_ACTION_ANY)
return

client.loot_panel.open(get_turf(target))

/atom/proc/ai_click_alt(mob/living/silicon/ai/user)
return


/atom/proc/AIMiddleClick(mob/living/user)
return
Expand All @@ -179,7 +195,7 @@
enabled = !enabled
updateTurrets()

/obj/machinery/turretid/AIAltClick() //toggles lethal on turrets
/obj/machinery/turretid/ai_click_alt(mob/living/silicon/ai/user) //toggles lethal on turrets
if(lethal_is_configurable)
lethal = !lethal
updateTurrets()
Expand All @@ -201,7 +217,7 @@
return
toggle_bolt(user)

/obj/machinery/door/airlock/AIAltClick(mob/living/silicon/user) // Electrifies doors.
/obj/machinery/door/airlock/ai_click_alt(mob/living/silicon/ai/user) // Electrifies doors.
if(!ai_control_check(user))
return
if(wires.is_cut(WIRE_ELECTRIFY))
Expand All @@ -222,5 +238,5 @@
/obj/machinery/ai_slipper/AICtrlClick(mob/living/silicon/ai/user) //Turns liquid dispenser on or off
ToggleOn()

/obj/machinery/ai_slipper/AIAltClick() //Dispenses liquid if on
/obj/machinery/ai_slipper/ai_click_alt(mob/living/silicon/ai/user) //Dispenses liquid if on
Activate()
64 changes: 10 additions & 54 deletions code/_onclick/click.dm
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@
return FALSE

// Default behavior: ignore double clicks, consider them normal clicks instead
/mob/proc/DblClickOn(var/atom/A, var/params)
/mob/proc/DblClickOn(atom/A, params)
return

/*
Expand Down Expand Up @@ -252,14 +252,14 @@
Used when you are handcuffed and click things.
Not currently used by anything but could easily be.
*/
/mob/proc/RestrainedClickOn(var/atom/A)
/mob/proc/RestrainedClickOn(atom/A)
return

/*
Middle click
Only used for swapping hands
*/
/mob/proc/MiddleClickOn(var/atom/A)
/mob/proc/MiddleClickOn(atom/A)
pointed(A)
return

Expand Down Expand Up @@ -313,10 +313,10 @@
For most mobs, examine.
This is overridden in ai.dm
*/
/mob/proc/ShiftClickOn(var/atom/A)
/mob/proc/ShiftClickOn(atom/A)
A.ShiftClick(src)
return
/atom/proc/ShiftClick(var/mob/user)
/atom/proc/ShiftClick(mob/user)
if(user.client && get_turf(user.client.eye) == get_turf(user))
user.examinate(src)
return
Expand All @@ -325,7 +325,7 @@
Ctrl click
For most objects, pull
*/
/mob/proc/CtrlClickOn(var/atom/A)
/mob/proc/CtrlClickOn(atom/A)
A.CtrlClick(src)
return

Expand All @@ -350,50 +350,6 @@
return ..()


/*
Alt click
Unused except for AI
*/
/mob/proc/AltClickOn(var/atom/A)
A.AltClick(src)
return

// See click_override.dm
/mob/living/AltClickOn(atom/A)
if(middleClickOverride)
middleClickOverride.onClick(A, src)
else
..()

/**
* Alt click on an atom.
* Performs alt-click actions before attempting to open a loot window.
* Returns TRUE if successful, FALSE if not.
*/
/atom/proc/AltClick(mob/user)
if(HAS_TRAIT(src, TRAIT_ALT_CLICK_BLOCKER) && !isobserver(user))
return TRUE

var/turf/T = get_turf(src)
if(isnull(T))
return FALSE

if(!isturf(loc) && !isturf(src))
return FALSE

if(!user.TurfAdjacent(T))
return FALSE

if(HAS_TRAIT(user, TRAIT_MOVE_VENTCRAWLING))
return FALSE

var/datum/lootpanel/panel = user.client?.loot_panel
if(isnull(panel))
return FALSE

panel.open(T)
return TRUE


/mob/proc/TurfAdjacent(turf/T)
return T.Adjacent(src)
Expand All @@ -402,18 +358,18 @@
Control+Shift/Alt+Shift click
Unused except for AI
*/
/mob/proc/CtrlShiftClickOn(var/atom/A)
/mob/proc/CtrlShiftClickOn(atom/A)
A.CtrlShiftClick(src)
return

/atom/proc/CtrlShiftClick(var/mob/user)
/atom/proc/CtrlShiftClick(mob/user)
return

/mob/proc/AltShiftClickOn(var/atom/A)
/mob/proc/AltShiftClickOn(atom/A)
A.AltShiftClick(src)
return

/atom/proc/AltShiftClick(var/mob/user)
/atom/proc/AltShiftClick(mob/user)
return


Expand Down
88 changes: 88 additions & 0 deletions code/_onclick/click_alt.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
///Main proc for primary alt click
/mob/proc/AltClickOn(atom/target)
base_click_alt(target)

/**
* ### Base proc for alt click interaction. Returns if the click was intercepted & handled
*
* If you wish to add custom `click_alt` behavior for a single type, use that proc.
*/
/mob/proc/base_click_alt(atom/target)
SHOULD_NOT_OVERRIDE(TRUE)

// Check if they've hooked in to prevent src from alt clicking anything
//if(SEND_SIGNAL(src, COMSIG_MOB_ALTCLICKON, target) & COMSIG_MOB_CANCEL_CLICKON)
// return TRUE

// Ghosties just see loot
if(isobserver(src))
client.loot_panel.open(get_turf(target))
return

// If it has a signal handler that returns a click action, done.
if(SEND_SIGNAL(target, COMSIG_CLICK_ALT, src) & CLICK_ACTION_ANY)
return TRUE

// If it has a custom click_alt that returns success/block, done.
if(can_perform_action(target, (target.interaction_flags_click | SILENT_ADJACENCY)))
return target.click_alt(src) & CLICK_ACTION_ANY

// No alt clicking to view turf from beneath
if(HAS_TRAIT(src, TRAIT_MOVE_VENTCRAWLING))
return

client.loot_panel.open(get_turf(target))

return FALSE

/mob/living/base_click_alt(atom/target)
SHOULD_NOT_OVERRIDE(TRUE)

if(..())
return
if(!CAN_I_SEE(target) || (!has_vision() && !IN_GIVEN_RANGE(src, target, 1)))
return

// No alt clicking to view turf from beneath
if(HAS_TRAIT(src, TRAIT_MOVE_VENTCRAWLING))
return

/// No loot panel if it's on our person
if(isobj(target) && (target in get_all_gear()))
to_chat(src, span_warning("You can't search for this item, it's already in your inventory! Take it off first."))
return

client.loot_panel.open(get_turf(target))
return TRUE


/**
* ## Custom alt click interaction
* Override this to change default alt click behavior. Return `CLICK_ACTION_SUCCESS`, `CLICK_ACTION_BLOCKING` or `NONE`.
*
* ### Guard clauses
* Consider adding `interaction_flags_click` before adding unique guard clauses.
*
* ### Return flags
* Forgetting your return will cause the default alt click behavior to occur thereafter.
*
* The difference between NONE and BLOCKING can get hazy, but I like to keep NONE limited to guard clauses and "never" cases.
*
* A good usage for BLOCKING over NONE is when it's situational for the item and there's some feedback indicating this.
*
* ### Examples:
* User is a ghost, alt clicks on item with special disk eject: NONE
*
* Machine broken, no feedback: NONE
*
* Alt click a pipe to max output but its already max: BLOCKING
*
* Alt click a gun that normally works, but is out of ammo: BLOCKING
*
* User unauthorized, machine beeps: BLOCKING
*
* @param {mob} user - The person doing the alt clicking.
*/
/atom/proc/click_alt(mob/user)
SHOULD_CALL_PARENT(FALSE)
return NONE
2 changes: 1 addition & 1 deletion code/_onclick/cogscarab.dm
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@
return

/mob/living/silicon/robot/cogscarab/AltClickOn(atom/A)
A.AltClick(src)
base_click_alt(A)
return

/mob/living/silicon/robot/cogscarab/CtrlShiftClickOn(atom/A)
Expand Down
Loading

0 comments on commit c11e2e1

Please sign in to comment.