Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
MosleyTheMalO committed Aug 13, 2024
2 parents 6ab0655 + 461804a commit 91a0b89
Show file tree
Hide file tree
Showing 12 changed files with 264 additions and 229 deletions.
44 changes: 33 additions & 11 deletions code/_onclick/hud/action_button.dm
Original file line number Diff line number Diff line change
Expand Up @@ -29,31 +29,37 @@
return ..()

/atom/movable/screen/movable/action_button/proc/can_use(mob/user)
if (linked_action)
if(isobserver(user))
var/mob/dead/observer/dead_mob = user
if(dead_mob.observetarget) // Observers can only click on action buttons if they're not observing something
return FALSE

if(linked_action)
if(linked_action.viewers[user.hud_used])
return TRUE
return FALSE
else if (isobserver(user))
var/mob/dead/observer/O = user
return !O.observetarget
else
return TRUE

return TRUE

/atom/movable/screen/movable/action_button/Click(location,control,params)
if (!can_use(usr))
return

var/list/modifiers = params2list(params)
if(modifiers["shift"])
if(LAZYACCESS(modifiers, SHIFT_CLICK))
var/datum/hud/our_hud = usr.hud_used
our_hud.position_action(src, SCRN_OBJ_DEFAULT)
return TRUE
var/mob/clicker = usr
if(!clicker.CheckActionCooldown())
return
clicker.DelayNextAction(1)
linked_action.Trigger()
return TRUE

// Entered and Exited won't fire while you're dragging something, because you're still "holding" it
// Very much byond logic, but I want nice behavior, so we fake it with drag
/atom/movable/screen/movable/action_button/MouseDrag(atom/over_object, src_location, over_location, src_control, over_control, params)
/atom/movable/screen/movable/action_button/MouseDrag(atom/over_object, atom/src_location, atom/over_location, src_control, over_control, params)
. = ..()
if(!can_use(usr))
return
Expand All @@ -70,6 +76,9 @@
if(old_object)
old_object.MouseExited(over_location, over_control, params)

if(QDELETED(over_location))
last_hovored_ref = null
return
last_hovored_ref = WEAKREF(over_object)
over_object.MouseEntered(over_location, over_control, params)

Expand All @@ -82,7 +91,7 @@
closeToolTip(usr)
return ..()

/atom/movable/screen/movable/action_button/MouseDrop(over_object)
/atom/movable/screen/movable/action_button/MouseDrop(atom/over_object, mob/user, src_location, over_location, params)
last_hovored_ref = null
if(!can_use(usr))
return
Expand Down Expand Up @@ -141,6 +150,12 @@
user.client.prefs.action_buttons_screen_locs -= "[name]_[id]"
user.client.prefs.queue_save_pref(1 SECONDS, TRUE)

/**
* This is a silly proc used in hud code code to determine what icon and icon state we should be using
* for hud elements (such as action buttons) that don't have their own icon and icon state set.
*
* It returns a list, which is pretty much just a struct of info
*/
/datum/hud/proc/get_action_buttons_icons()
. = list()
.["bg_icon"] = ui_style
Expand All @@ -153,8 +168,15 @@
var/datum/action/A = X
A.UpdateButtons(status_only)

//This is the proc used to update all the action buttons.
/mob/proc/update_action_buttons(reload_screen)
/**
* This proc handles adding all of the mob's actions to their screen
*
* If you just need to update existing buttons, use [/mob/proc/update_mob_action_buttons]!
*
* Arguments:
* * update_flags - reload_screen - bool, if TRUE, this proc will add the button to the screen of the passed mob as well
*/
/mob/proc/update_action_buttons(reload_screen = FALSE)
if(!hud_used || !client)
return

Expand Down
160 changes: 100 additions & 60 deletions code/datums/action.dm
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,50 @@
#define AB_CHECK_ALIVE 16

/datum/action
/// The name of the action
var/name = "Generic Action"
/// The description of what the action does, shown in button tooltips
var/desc = null
var/atom/target = null
var/check_flags = 0
var/required_mobility_flags = MOBILITY_USE
var/processing = FALSE
var/buttontooltipstyle = ""
var/transparent_when_unavailable = TRUE
/// The target the action is attached to. If the target datum is deleted, the action is as well.
/// Set in New() via the proc link_to(). PLEASE set a target if you're making an action
var/datum/target = null
/// Where any buttons we create should be by default. Accepts screen_loc and location defines
var/default_button_position = SCRN_OBJ_IN_LIST

var/button_icon = 'icons/mob/actions/backgrounds.dmi' //This is the file for the BACKGROUND icon
var/background_icon_state = ACTION_BUTTON_DEFAULT_BACKGROUND //And this is the state for the background icon

var/icon_icon = 'icons/mob/actions.dmi' //This is the file for the ACTION icon
var/button_icon_state = "default" //And this is the state for the action icon
/// This is who currently owns the action, and most often, this is who is using the action if it is triggered
/// This can be the same as "target" but is not ALWAYS the same - this is set and unset with Grant() and Remove()
var/mob/owner
/// Flags that will determine of the owner / user of the action can... use the action
var/check_flags = NONE
var/required_mobility_flags = MOBILITY_USE
var/processing = FALSE
/// Whether the button becomes transparent when it can't be used, or just reddened
var/transparent_when_unavailable = TRUE
///List of all mobs that are viewing our action button -> A unique movable for them to view.
var/list/viewers = list()

/// The style the button's tooltips appear to be
var/buttontooltipstyle = ""

/// This is the file for the BACKGROUND underlay icon of the button
var/button_icon = 'icons/mob/actions/backgrounds.dmi'
/// This is the icon state state for the BACKGROUND underlay icon of the button
/// (If set to ACTION_BUTTON_DEFAULT_BACKGROUND, uses the hud's default background)
var/background_icon_state = ACTION_BUTTON_DEFAULT_BACKGROUND

/// This is the file for the icon that appears on the button
var/icon_icon = 'icons/mob/actions.dmi'
/// This is the icon state for the icon that appears on the button
var/button_icon_state = "default"

/datum/action/New(Target)
link_to(Target)

/datum/action/proc/link_to(Target)
target = Target
RegisterSignal(Target, COMSIG_ATOM_UPDATED_ICON, PROC_REF(OnUpdatedIcon))
RegisterSignal(Target, COMSIG_PARENT_QDELETING, PROC_REF(clear_ref), override = TRUE)

if(isatom(Target))
RegisterSignal(Target, COMSIG_ATOM_UPDATED_ICON, PROC_REF(OnUpdatedIcon))

/datum/action/Destroy()
if(owner)
Expand All @@ -39,48 +57,60 @@
QDEL_LIST_ASSOC_VAL(viewers) // Qdel the buttons in the viewers list **NOT THE HUDS**
return ..()

/datum/action/proc/Grant(mob/M)
if(!M)
/// Signal proc that clears any references based on the owner or target deleting
/// If the owner's deleted, we will simply remove from them, but if the target's deleted, we will self-delete
/datum/action/proc/clear_ref(datum/ref)
SIGNAL_HANDLER
if(ref == owner)
Remove(owner)
return
if(owner)
if(owner == M)
return
if(ref == target)
qdel(src)

/datum/action/proc/Grant(mob/grant_to)
if(isnull(grant_to))
Remove(owner)
owner = M
return
if(grant_to == owner)
return // We already have it
var/mob/previous_owner = owner
owner = grant_to
if(!isnull(previous_owner))
Remove(previous_owner)
RegisterSignal(owner, COMSIG_PARENT_QDELETING, PROC_REF(clear_ref), override = TRUE)

// Register some signals based on our check_flags
// so that our button icon updates when relevant
if(check_flags & AB_CHECK_CONSCIOUS)
RegisterSignal(owner, COMSIG_MOB_STATCHANGE, PROC_REF(update_status_on_signal))

GiveAction(M)
GiveAction(grant_to)

/datum/action/proc/clear_ref(datum/ref)
SIGNAL_HANDLER
if(ref == owner)
Remove(owner)
if(ref == target)
qdel(src)
/datum/action/proc/Remove(mob/remove_from)
SHOULD_CALL_PARENT(TRUE)

/datum/action/proc/Remove(mob/M)
for(var/datum/hud/hud in viewers)
if(!hud.mymob)
continue
HideFrom(hud.mymob)
if(M)
LAZYREMOVE(M.actions, src) // We aren't always properly inserted into the viewers list, gotta make sure that action's cleared
LAZYREMOVE(remove_from.actions, src) // We aren't always properly inserted into the viewers list, gotta make sure that action's cleared
viewers = list()

if(owner)
UnregisterSignal(owner, list(
COMSIG_PARENT_QDELETING,
COMSIG_MOB_STATCHANGE
))
if(target == owner)
RegisterSignal(target, COMSIG_PARENT_QDELETING, PROC_REF(clear_ref))
if(isnull(owner))
return
UnregisterSignal(owner, COMSIG_PARENT_QDELETING)

// Clean up our check_flag signals
UnregisterSignal(owner, list(
COMSIG_MOB_STATCHANGE
))

if(target == owner)
RegisterSignal(target, COMSIG_PARENT_QDELETING, PROC_REF(clear_ref))
if(owner == remove_from)
owner = null

/// Actually triggers the effects of the action.
/// Called when the on-screen button is clicked, for example.
/datum/action/proc/Trigger()
if(!IsAvailable())
return FALSE
Expand All @@ -91,6 +121,10 @@
/datum/action/proc/Process()
return

/**
* Whether our action is currently available to use or not
* * silent - If false this is being called to check if we have any messages to show to the owner
*/
/datum/action/proc/IsAvailable(silent = FALSE)
if(!owner)
return FALSE
Expand All @@ -105,9 +139,13 @@
return FALSE
if(check_flags & AB_CHECK_LYING)
if(istype(L) && !CHECK_MOBILITY(L, MOBILITY_STAND))
if (!silent)
owner.balloon_alert(owner, "must stand up!")
return FALSE
if(check_flags & AB_CHECK_CONSCIOUS)
if(owner.stat)
if (!silent)
owner.balloon_alert(owner, "unconscious!")
return FALSE
if(check_flags & AB_CHECK_ALIVE)
if(owner.stat == DEAD)
Expand Down Expand Up @@ -167,7 +205,8 @@
SIGNAL_HANDLER
UpdateButtons(force = TRUE)

//Give our action button to the player
/// Gives our action to the passed viewer.
/// Puts our action in their actions list and shows them the button.
/datum/action/proc/GiveAction(mob/viewer)
var/datum/hud/our_hud = viewer.hud_used
if(viewers[our_hud]) // Already have a copy of us? go away
Expand All @@ -176,7 +215,7 @@
LAZYOR(viewer.actions, src) // Move this in
ShowTo(viewer)

//Adds our action button to the screen of a player
/// Adds our action button to the screen of the passed viewer.
/datum/action/proc/ShowTo(mob/viewer)
var/datum/hud/our_hud = viewer.hud_used
if(!our_hud || viewers[our_hud]) // There's no point in this if you have no hud in the first place
Expand All @@ -193,7 +232,7 @@
button.load_position(viewer)
viewer.update_action_buttons()

//Removes our action button from the screen of a player
/// Removes our action from the passed viewer.
/datum/action/proc/HideFrom(mob/viewer)
var/datum/hud/our_hud = viewer.hud_used
var/atom/movable/screen/movable/action_button/button = viewers[our_hud]
Expand Down Expand Up @@ -446,7 +485,8 @@

/datum/action/item_action/toggle/New(Target)
..()
name = "Toggle [target.name]"
var/obj/item/item_target = target
name = "Toggle [item_target.name]"

/datum/action/item_action/halt
name = "HALT!"
Expand Down Expand Up @@ -474,7 +514,9 @@

/datum/action/item_action/adjust/New(Target)
..()
name = "Adjust [target.name]"
var/obj/item/item_target = target
name = "Adjust [item_target.name]"


/datum/action/item_action/switch_hud
name = "Switch HUD"
Expand Down Expand Up @@ -549,21 +591,31 @@
return ..()

/datum/action/item_action/organ_action
name = "Organ Action"
check_flags = AB_CHECK_CONSCIOUS

/datum/action/item_action/organ_action/IsAvailable(silent = FALSE)
var/obj/item/organ/I = target
if(!I.owner)
var/obj/item/organ/attached_organ = target
if(!attached_organ.owner)
return FALSE
return ..()

/datum/action/item_action/organ_action/toggle
name = "Toggle Organ"

/datum/action/item_action/organ_action/toggle/New(Target)
..()
name = "Toggle [target.name]"
var/obj/item/organ/organ_target = target
name = "Toggle [organ_target.name]"

/datum/action/item_action/organ_action/use
name = "Use Organ"

/datum/action/item_action/organ_action/use/New(Target)
..()
name = "Use [target.name]"
var/obj/item/organ/organ_target = target
name = "Use [organ_target.name]"


/datum/action/item_action/cult_dagger
name = "Draw Blood Rune"
Expand Down Expand Up @@ -958,20 +1010,8 @@
/datum/action/item_action/storage_gather_mode
name = "Switch gathering mode"
desc = "Switches the gathering mode of a storage object."
icon_icon = 'icons/mob/actions/actions_items.dmi'
button_icon_state = "storage_gather_switch"

/datum/action/item_action/storage_gather_mode/ApplyIcon(atom/movable/screen/movable/action_button/current_button)
. = ..()
var/old_layer = target.layer
var/old_plane = target.plane
target.layer = FLOAT_LAYER //AAAH
target.plane = FLOAT_PLANE //^ what that guy said
current_button.cut_overlays()
current_button.add_overlay(target)
target.layer = old_layer
target.plane = old_plane
current_button.appearance_cache = target.appearance
button_icon = 'icons/mob/actions/actions_items.dmi'
background_icon_state = "storage_gather_switch"

/proc/get_action_of_type(mob/M, action_type)
if(!M.actions || !ispath(action_type, /datum/action))
Expand Down
8 changes: 5 additions & 3 deletions code/datums/elements/polychromic.dm
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,9 @@
check_flags = NONE

/datum/action/item_action/polychromic/ApplyIcon(atom/movable/screen/movable/action_button/current_button, force)
var/matrix/save_matrix = target.transform
target.transform = matrix(0.8, 0, 0, 0, 0.8, 0)
var/atom/polychromic_thing = target

var/matrix/save_matrix = polychromic_thing.transform
polychromic_thing.transform = matrix(0.8, 0, 0, 0, 0.8, 0)
. = ..()
target.transform = save_matrix
polychromic_thing.transform = save_matrix
Loading

0 comments on commit 91a0b89

Please sign in to comment.