mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-10 17:52:36 +00:00
## About The Pull Request This PR tackles our piss-poor item action handling. Currently in order to make an item only have actions when its equipped to a certain slot you need to override a proc, which I've changed by introducing an action_slots variable. I've also cleaned up a ton of action code, and most importantly moved a lot of Trigger effects on items to do_effect, which allows actions to not call ui_action_click or attack_self on an item without bypassing IsAvailible and comsigs that parent Trigger has. This resolves issues like jump boots being usable from your hands, HUDs being toggleable out of your pockets, etc. Also moved a few actions from relying on attack_self to individual handling on their side. This also stops welding masks/hardhats from showing their action while you hold them, this part of the change is just something I thought didn't make much sense - you can use their action by using them in-hand, and flickering on your action bar can be annoying when reshuffling your backpack. Closes #89653 ## Why It's Good For The Game Makes action handling significantly less ass, allows us to avoid code like this ```js /obj/item/clothing/mask/gas/sechailer/ui_action_click(mob/user, action) if(istype(action, /datum/action/item_action/halt)) halt() else adjust_visor(user) ```
214 lines
6.3 KiB
Plaintext
214 lines
6.3 KiB
Plaintext
/datum/action/item_action/mod
|
|
background_icon_state = "bg_mod"
|
|
overlay_icon_state = "bg_mod_border"
|
|
button_icon = 'icons/mob/actions/actions_mod.dmi'
|
|
check_flags = AB_CHECK_CONSCIOUS
|
|
/// Whether this action is intended for the AI. Stuff breaks a lot if this is done differently.
|
|
var/ai_action = FALSE
|
|
|
|
/datum/action/item_action/mod/New(Target)
|
|
..()
|
|
if(!istype(Target, /obj/item/mod/control))
|
|
qdel(src)
|
|
return
|
|
if(ai_action)
|
|
background_icon_state = ACTION_BUTTON_DEFAULT_BACKGROUND
|
|
|
|
/datum/action/item_action/mod/Grant(mob/user)
|
|
var/obj/item/mod/control/mod = target
|
|
if(ai_action && user != mod.ai_assistant)
|
|
return
|
|
else if(!ai_action && user == mod.ai_assistant)
|
|
return
|
|
return ..()
|
|
|
|
/datum/action/item_action/mod/Remove(mob/user)
|
|
var/obj/item/mod/control/mod = target
|
|
if(ai_action && user != mod.ai_assistant)
|
|
return
|
|
else if(!ai_action && user == mod.ai_assistant)
|
|
return
|
|
return ..()
|
|
|
|
/datum/action/item_action/mod/do_effect(trigger_flags)
|
|
var/obj/item/mod/control/mod = target
|
|
if(mod.malfunctioning && prob(75))
|
|
mod.balloon_alert(usr, "button malfunctions!")
|
|
return FALSE
|
|
return TRUE
|
|
|
|
/datum/action/item_action/mod/deploy
|
|
name = "Deploy MODsuit"
|
|
desc = "LMB: Deploy/Undeploy part. RMB: Deploy/Undeploy full suit."
|
|
button_icon_state = "deploy"
|
|
|
|
/datum/action/item_action/mod/deploy/do_effect(trigger_flags)
|
|
. = ..()
|
|
if(!.)
|
|
return
|
|
var/obj/item/mod/control/mod = target
|
|
if(trigger_flags & TRIGGER_SECONDARY_ACTION)
|
|
mod.quick_deploy(usr)
|
|
else
|
|
mod.choose_deploy(usr)
|
|
|
|
/datum/action/item_action/mod/deploy/ai
|
|
ai_action = TRUE
|
|
|
|
/datum/action/item_action/mod/activate
|
|
name = "Activate MODsuit"
|
|
desc = "LMB: Activate/Deactivate suit with prompt. RMB: Activate/Deactivate suit skipping prompt."
|
|
button_icon_state = "activate"
|
|
/// First time clicking this will set it to TRUE, second time will activate it.
|
|
var/ready = FALSE
|
|
|
|
/datum/action/item_action/mod/activate/do_effect(trigger_flags)
|
|
. = ..()
|
|
if(!.)
|
|
return
|
|
if(!(trigger_flags & TRIGGER_SECONDARY_ACTION) && !ready)
|
|
ready = TRUE
|
|
button_icon_state = "activate-ready"
|
|
build_all_button_icons()
|
|
addtimer(CALLBACK(src, PROC_REF(reset_ready)), 3 SECONDS)
|
|
return
|
|
var/obj/item/mod/control/mod = target
|
|
reset_ready()
|
|
mod.toggle_activate(usr)
|
|
|
|
/// Resets the state requiring to be doubleclicked again.
|
|
/datum/action/item_action/mod/activate/proc/reset_ready()
|
|
ready = FALSE
|
|
button_icon_state = initial(button_icon_state)
|
|
build_all_button_icons()
|
|
|
|
/datum/action/item_action/mod/activate/ai
|
|
ai_action = TRUE
|
|
|
|
/datum/action/item_action/mod/module
|
|
name = "Toggle Module"
|
|
desc = "Toggle a MODsuit module."
|
|
button_icon_state = "module"
|
|
|
|
/datum/action/item_action/mod/module/do_effect(trigger_flags)
|
|
. = ..()
|
|
if(!.)
|
|
return
|
|
var/obj/item/mod/control/mod = target
|
|
mod.quick_module(usr)
|
|
|
|
/datum/action/item_action/mod/module/ai
|
|
ai_action = TRUE
|
|
|
|
/datum/action/item_action/mod/panel
|
|
name = "MODsuit Panel"
|
|
desc = "Open the MODsuit's panel."
|
|
button_icon_state = "panel"
|
|
|
|
/datum/action/item_action/mod/panel/do_effect(trigger_flags)
|
|
. = ..()
|
|
if(!.)
|
|
return
|
|
var/obj/item/mod/control/mod = target
|
|
mod.ui_interact(usr)
|
|
|
|
/datum/action/item_action/mod/panel/ai
|
|
ai_action = TRUE
|
|
|
|
/datum/action/item_action/mod/pinnable
|
|
/// A reference to the mob we are pinned to.
|
|
var/mob/pinner
|
|
|
|
/datum/action/item_action/mod/pinnable/New(Target, mob/user)
|
|
. = ..()
|
|
var/obj/item/mod/control/mod = Target
|
|
if(user == mod.ai_assistant)
|
|
ai_action = TRUE
|
|
pinner = user
|
|
RegisterSignal(user, COMSIG_QDELETING, PROC_REF(pinner_deleted))
|
|
|
|
/datum/action/item_action/mod/pinnable/Grant(mob/user)
|
|
if(pinner != user)
|
|
return
|
|
return ..()
|
|
|
|
/// If the guy whose UI we are pinned to got deleted
|
|
/datum/action/item_action/mod/pinnable/proc/pinner_deleted()
|
|
SIGNAL_HANDLER
|
|
pinner = null
|
|
qdel(src)
|
|
|
|
/datum/action/item_action/mod/pinnable/module
|
|
desc = "Activate the module."
|
|
/// Overrides the icon applications.
|
|
var/override = FALSE
|
|
/// Module we are linked to.
|
|
var/obj/item/mod/module/module
|
|
/// Timer until we remove our cooldown overlay
|
|
var/cooldown_timer
|
|
|
|
/datum/action/item_action/mod/pinnable/module/New(Target, mob/user, obj/item/mod/module/linked_module)
|
|
button_icon = linked_module.icon
|
|
button_icon_state = linked_module.icon_state
|
|
. = ..()
|
|
module = linked_module
|
|
module.pinned_to[REF(user)] = src
|
|
if(linked_module.allow_flags & MODULE_ALLOW_INCAPACITATED)
|
|
// clears check hands and check conscious
|
|
check_flags = NONE
|
|
name = "Activate [capitalize(linked_module.name)]"
|
|
desc = "Quickly activate [linked_module]."
|
|
RegisterSignals(linked_module, list(
|
|
COMSIG_MODULE_ACTIVATED,
|
|
COMSIG_MODULE_DEACTIVATED,
|
|
COMSIG_MODULE_USED,
|
|
), PROC_REF(module_interacted_with))
|
|
RegisterSignal(linked_module, COMSIG_MODULE_COOLDOWN_STARTED, PROC_REF(cooldown_started))
|
|
|
|
/datum/action/item_action/mod/pinnable/module/Destroy()
|
|
deltimer(cooldown_timer)
|
|
UnregisterSignal(module, list(
|
|
COMSIG_MODULE_ACTIVATED,
|
|
COMSIG_MODULE_DEACTIVATED,
|
|
COMSIG_MODULE_COOLDOWN_STARTED,
|
|
COMSIG_MODULE_USED,
|
|
))
|
|
module.pinned_to -= REF(pinner)
|
|
module = null
|
|
pinner = null
|
|
return ..()
|
|
|
|
/datum/action/item_action/mod/pinnable/module/do_effect(trigger_flags)
|
|
. = ..()
|
|
if(!.)
|
|
return
|
|
module.on_select()
|
|
|
|
/datum/action/item_action/mod/pinnable/module/apply_button_overlay(atom/movable/screen/movable/action_button/current_button, force)
|
|
current_button.cut_overlays()
|
|
if(override)
|
|
return ..()
|
|
|
|
var/obj/item/mod/control/mod = target
|
|
if(module == mod.selected_module)
|
|
current_button.add_overlay(image(icon = 'icons/hud/radial.dmi', icon_state = "module_selected", layer = FLOAT_LAYER-0.1))
|
|
else if(module.active)
|
|
current_button.add_overlay(image(icon = 'icons/hud/radial.dmi', icon_state = "module_active", layer = FLOAT_LAYER-0.1))
|
|
if(!COOLDOWN_FINISHED(module, cooldown_timer))
|
|
current_button.add_overlay(image(icon = 'icons/hud/radial.dmi', icon_state = "module_cooldown"))
|
|
return ..()
|
|
|
|
/datum/action/item_action/mod/pinnable/module/proc/module_interacted_with(datum/source)
|
|
SIGNAL_HANDLER
|
|
|
|
build_all_button_icons(UPDATE_BUTTON_OVERLAY|UPDATE_BUTTON_STATUS)
|
|
|
|
/datum/action/item_action/mod/pinnable/module/proc/cooldown_started(datum/source, cooldown_time)
|
|
SIGNAL_HANDLER
|
|
|
|
deltimer(cooldown_timer)
|
|
build_all_button_icons(UPDATE_BUTTON_OVERLAY)
|
|
if (cooldown_time == 0)
|
|
return
|
|
cooldown_timer = addtimer(CALLBACK(src, PROC_REF(build_all_button_icons), UPDATE_BUTTON_OVERLAY), cooldown_time + 1, TIMER_STOPPABLE)
|