|
|
|
|
@@ -11,9 +11,11 @@
|
|
|
|
|
var/check_flags = 0
|
|
|
|
|
var/required_mobility_flags = MOBILITY_USE
|
|
|
|
|
var/processing = FALSE
|
|
|
|
|
var/atom/movable/screen/movable/action_button/button = null
|
|
|
|
|
var/buttontooltipstyle = ""
|
|
|
|
|
var/transparent_when_unavailable = TRUE
|
|
|
|
|
/// Where any buttons we create should be by default. Accepts screen_loc and location defines
|
|
|
|
|
var/default_button_position = SCRN_OBJ_IN_LIST
|
|
|
|
|
|
|
|
|
|
var/use_target_appearance = FALSE
|
|
|
|
|
var/list/target_appearance_matrix //if set, will be used to transform the target button appearance as an arglist.
|
|
|
|
|
|
|
|
|
|
@@ -28,12 +30,6 @@
|
|
|
|
|
|
|
|
|
|
/datum/action/New(Target)
|
|
|
|
|
link_to(Target)
|
|
|
|
|
button = new
|
|
|
|
|
button.linked_action = src
|
|
|
|
|
button.name = name
|
|
|
|
|
button.actiontooltipstyle = buttontooltipstyle
|
|
|
|
|
if(desc)
|
|
|
|
|
button.desc = desc
|
|
|
|
|
|
|
|
|
|
/datum/action/proc/link_to(Target)
|
|
|
|
|
target = Target
|
|
|
|
|
@@ -43,51 +39,42 @@
|
|
|
|
|
if(owner)
|
|
|
|
|
Remove(owner)
|
|
|
|
|
target = null
|
|
|
|
|
QDEL_NULL(button)
|
|
|
|
|
QDEL_LIST_ASSOC_VAL(viewers) // Qdel the buttons in the viewers list **NOT THE HUDS**
|
|
|
|
|
return ..()
|
|
|
|
|
|
|
|
|
|
/datum/action/proc/Grant(mob/M)
|
|
|
|
|
if(M)
|
|
|
|
|
if(owner)
|
|
|
|
|
if(owner == M)
|
|
|
|
|
return
|
|
|
|
|
Remove(owner)
|
|
|
|
|
owner = M
|
|
|
|
|
|
|
|
|
|
//button id generation
|
|
|
|
|
var/counter = 0
|
|
|
|
|
var/bitfield = 0
|
|
|
|
|
for(var/datum/action/A in M.actions)
|
|
|
|
|
if(A.name == name && A.button.id)
|
|
|
|
|
counter += 1
|
|
|
|
|
bitfield |= A.button.id
|
|
|
|
|
bitfield = ~bitfield
|
|
|
|
|
var/bitflag = 1
|
|
|
|
|
for(var/i in 1 to (counter + 1))
|
|
|
|
|
if(bitfield & bitflag)
|
|
|
|
|
button.id = bitflag
|
|
|
|
|
break
|
|
|
|
|
bitflag *= 2
|
|
|
|
|
|
|
|
|
|
M.actions += src
|
|
|
|
|
if(M.client)
|
|
|
|
|
M.client.screen += button
|
|
|
|
|
button.locked = M.client.prefs.buttons_locked || button.id ? M.client.prefs.action_buttons_screen_locs["[name]_[button.id]"] : FALSE //even if it's not defaultly locked we should remember we locked it before
|
|
|
|
|
button.moved = button.id ? M.client.prefs.action_buttons_screen_locs["[name]_[button.id]"] : FALSE
|
|
|
|
|
M.update_action_buttons()
|
|
|
|
|
else
|
|
|
|
|
if(!M)
|
|
|
|
|
Remove(owner)
|
|
|
|
|
return
|
|
|
|
|
if(owner)
|
|
|
|
|
if(owner == M)
|
|
|
|
|
return
|
|
|
|
|
Remove(owner)
|
|
|
|
|
owner = M
|
|
|
|
|
RegisterSignal(owner, COMSIG_PARENT_QDELETING, .proc/clear_ref, override = TRUE)
|
|
|
|
|
|
|
|
|
|
GiveAction(M)
|
|
|
|
|
|
|
|
|
|
/datum/action/proc/clear_ref(datum/ref)
|
|
|
|
|
SIGNAL_HANDLER
|
|
|
|
|
if(ref == owner)
|
|
|
|
|
Remove(owner)
|
|
|
|
|
if(ref == target)
|
|
|
|
|
qdel(src)
|
|
|
|
|
|
|
|
|
|
/datum/action/proc/Remove(mob/M)
|
|
|
|
|
if(M)
|
|
|
|
|
if(M.client)
|
|
|
|
|
M.client.screen -= button
|
|
|
|
|
M.actions -= src
|
|
|
|
|
M.update_action_buttons()
|
|
|
|
|
owner = null
|
|
|
|
|
button.moved = FALSE //so the button appears in its normal position when given to another owner.
|
|
|
|
|
button.locked = FALSE
|
|
|
|
|
button.id = null
|
|
|
|
|
for(var/datum/hud/hud in viewers)
|
|
|
|
|
if(!hud.mymob)
|
|
|
|
|
continue
|
|
|
|
|
HideFrom(hud.mymob)
|
|
|
|
|
LAZYREMOVE(M.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, COMSIG_PARENT_QDELETING)
|
|
|
|
|
if(target == owner)
|
|
|
|
|
RegisterSignal(target, COMSIG_PARENT_QDELETING, .proc/clear_ref)
|
|
|
|
|
owner = null
|
|
|
|
|
|
|
|
|
|
/datum/action/proc/Trigger()
|
|
|
|
|
if(!IsAvailable())
|
|
|
|
|
@@ -125,15 +112,15 @@
|
|
|
|
|
/datum/action/proc/UpdateButtons(status_only, force)
|
|
|
|
|
for(var/datum/hud/hud in viewers)
|
|
|
|
|
var/atom/movable/screen/movable/button = viewers[hud]
|
|
|
|
|
UpdateButtonIcon(button, status_only, force)
|
|
|
|
|
UpdateButton(button, status_only, force)
|
|
|
|
|
|
|
|
|
|
/datum/action/proc/UpdateButtonIcon(status_only = FALSE, force = FALSE)
|
|
|
|
|
/datum/action/proc/UpdateButton(atom/movable/screen/movable/action_button/button, status_only = FALSE, force = FALSE)
|
|
|
|
|
if(!button)
|
|
|
|
|
return
|
|
|
|
|
if(!status_only)
|
|
|
|
|
button.name = name
|
|
|
|
|
button.desc = desc
|
|
|
|
|
if(owner && owner.hud_used && background_icon_state == ACTION_BUTTON_DEFAULT_BACKGROUND)
|
|
|
|
|
if(owner?.hud_used && background_icon_state == ACTION_BUTTON_DEFAULT_BACKGROUND)
|
|
|
|
|
var/list/settings = owner.hud_used.get_action_buttons_icons()
|
|
|
|
|
if(button.icon != settings["bg_icon"])
|
|
|
|
|
button.icon = settings["bg_icon"]
|
|
|
|
|
@@ -145,25 +132,13 @@
|
|
|
|
|
if(button.icon_state != background_icon_state)
|
|
|
|
|
button.icon_state = background_icon_state
|
|
|
|
|
|
|
|
|
|
if(!use_target_appearance)
|
|
|
|
|
ApplyIcon(button, force)
|
|
|
|
|
ApplyIcon(button, force)
|
|
|
|
|
|
|
|
|
|
else if(target && button.appearance_cache != target.appearance) //replace with /ref comparison if this is not valid.
|
|
|
|
|
var/mutable_appearance/M = new(target)
|
|
|
|
|
M.layer = FLOAT_LAYER
|
|
|
|
|
M.plane = FLOAT_PLANE
|
|
|
|
|
if(target_appearance_matrix)
|
|
|
|
|
var/list/L = target_appearance_matrix
|
|
|
|
|
M.transform = matrix(L[1], L[2], L[3], L[4], L[5], L[6])
|
|
|
|
|
button.cut_overlays()
|
|
|
|
|
button.add_overlay(M)
|
|
|
|
|
button.appearance_cache = target.appearance
|
|
|
|
|
|
|
|
|
|
if(!IsAvailable(TRUE))
|
|
|
|
|
if(!IsAvailable())
|
|
|
|
|
button.color = transparent_when_unavailable ? rgb(128,0,0,128) : rgb(128,0,0)
|
|
|
|
|
else
|
|
|
|
|
button.color = rgb(255,255,255,255)
|
|
|
|
|
return 1
|
|
|
|
|
return TRUE
|
|
|
|
|
|
|
|
|
|
/datum/action/proc/ApplyIcon(atom/movable/screen/movable/action_button/current_button, force = FALSE)
|
|
|
|
|
if(icon_icon && button_icon_state && ((current_button.button_icon_state != button_icon_state) || force))
|
|
|
|
|
@@ -184,7 +159,67 @@
|
|
|
|
|
M.ghostize(can_reenter_corpse = TRUE, voluntary = TRUE)
|
|
|
|
|
|
|
|
|
|
/datum/action/proc/OnUpdatedIcon()
|
|
|
|
|
addtimer(CALLBACK(src, .proc/UpdateButtonIcon), 1) //Hopefully runs after new icon overlays have been compiled.
|
|
|
|
|
SIGNAL_HANDLER
|
|
|
|
|
UpdateButtons()
|
|
|
|
|
|
|
|
|
|
//Give our action button to the player
|
|
|
|
|
/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
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
LAZYOR(viewer.actions, src) // Move this in
|
|
|
|
|
ShowTo(viewer)
|
|
|
|
|
|
|
|
|
|
//Adds our action button to the screen of a player
|
|
|
|
|
/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
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
var/atom/movable/screen/movable/action_button/button = CreateButton()
|
|
|
|
|
SetId(button, viewer)
|
|
|
|
|
|
|
|
|
|
button.our_hud = our_hud
|
|
|
|
|
viewers[our_hud] = button
|
|
|
|
|
if(viewer.client)
|
|
|
|
|
viewer.client.screen += button
|
|
|
|
|
|
|
|
|
|
button.load_position(viewer)
|
|
|
|
|
viewer.update_action_buttons()
|
|
|
|
|
|
|
|
|
|
//Removes our action button from the screen of a player
|
|
|
|
|
/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]
|
|
|
|
|
LAZYREMOVE(viewer.actions, src)
|
|
|
|
|
if(button)
|
|
|
|
|
qdel(button)
|
|
|
|
|
|
|
|
|
|
/datum/action/proc/CreateButton()
|
|
|
|
|
var/atom/movable/screen/movable/action_button/button = new()
|
|
|
|
|
button.linked_action = src
|
|
|
|
|
button.actiontooltipstyle = buttontooltipstyle
|
|
|
|
|
if(desc)
|
|
|
|
|
button.desc = desc
|
|
|
|
|
return button
|
|
|
|
|
|
|
|
|
|
/datum/action/proc/SetId(atom/movable/screen/movable/action_button/our_button, mob/owner)
|
|
|
|
|
//button id generation
|
|
|
|
|
var/bitfield = 0
|
|
|
|
|
for(var/datum/action/action in owner.actions)
|
|
|
|
|
if(action == src) // This could be us, which is dumb
|
|
|
|
|
continue
|
|
|
|
|
var/atom/movable/screen/movable/action_button/button = action.viewers[owner.hud_used]
|
|
|
|
|
if(action.name == name && button.id)
|
|
|
|
|
bitfield |= button.id
|
|
|
|
|
|
|
|
|
|
bitfield = ~bitfield // Flip our possible ids, so we can check if we've found a unique one
|
|
|
|
|
for(var/i in 0 to 23) // We get 24 possible bitflags in dm
|
|
|
|
|
var/bitflag = 1 << i // Shift us over one
|
|
|
|
|
if(bitfield & bitflag)
|
|
|
|
|
our_button.id = bitflag
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
//Presets for item actions
|
|
|
|
|
/datum/action/item_action
|
|
|
|
|
@@ -258,12 +293,14 @@
|
|
|
|
|
/datum/action/item_action/set_internals
|
|
|
|
|
name = "Set Internals"
|
|
|
|
|
|
|
|
|
|
/datum/action/item_action/set_internals/UpdateButtonIcon(status_only = FALSE, force)
|
|
|
|
|
if(..()) //button available
|
|
|
|
|
if(iscarbon(owner))
|
|
|
|
|
var/mob/living/carbon/C = owner
|
|
|
|
|
if(target == C.internal)
|
|
|
|
|
button.icon_state = "template_active"
|
|
|
|
|
/datum/action/item_action/set_internals/UpdateButton(atom/movable/screen/movable/action_button/button, status_only = FALSE, force)
|
|
|
|
|
if(!..()) // no button available
|
|
|
|
|
return
|
|
|
|
|
if(!iscarbon(owner))
|
|
|
|
|
return
|
|
|
|
|
var/mob/living/carbon/C = owner
|
|
|
|
|
if(target == C.internal)
|
|
|
|
|
button.icon_state = "template_active"
|
|
|
|
|
|
|
|
|
|
/datum/action/item_action/pick_color
|
|
|
|
|
name = "Choose A Color"
|
|
|
|
|
@@ -309,9 +346,9 @@
|
|
|
|
|
|
|
|
|
|
/datum/action/item_action/toggle_unfriendly_fire/Trigger()
|
|
|
|
|
if(..())
|
|
|
|
|
UpdateButtonIcon()
|
|
|
|
|
UpdateButtons()
|
|
|
|
|
|
|
|
|
|
/datum/action/item_action/toggle_unfriendly_fire/UpdateButtonIcon(status_only = FALSE, force)
|
|
|
|
|
/datum/action/item_action/toggle_unfriendly_fire/UpdateButton(atom/movable/screen/movable/action_button/button, status_only = FALSE, force)
|
|
|
|
|
if(istype(target, /obj/item/hierophant_club))
|
|
|
|
|
var/obj/item/hierophant_club/H = target
|
|
|
|
|
if(H.friendly_fire_check)
|
|
|
|
|
@@ -380,7 +417,6 @@
|
|
|
|
|
/datum/action/item_action/toggle/New(Target)
|
|
|
|
|
..()
|
|
|
|
|
name = "Toggle [target.name]"
|
|
|
|
|
button.name = name
|
|
|
|
|
|
|
|
|
|
/datum/action/item_action/halt
|
|
|
|
|
name = "HALT!"
|
|
|
|
|
@@ -409,7 +445,6 @@
|
|
|
|
|
/datum/action/item_action/adjust/New(Target)
|
|
|
|
|
..()
|
|
|
|
|
name = "Adjust [target.name]"
|
|
|
|
|
button.name = name
|
|
|
|
|
|
|
|
|
|
/datum/action/item_action/switch_hud
|
|
|
|
|
name = "Switch HUD"
|
|
|
|
|
@@ -495,12 +530,10 @@
|
|
|
|
|
/datum/action/item_action/organ_action/toggle/New(Target)
|
|
|
|
|
..()
|
|
|
|
|
name = "Toggle [target.name]"
|
|
|
|
|
button.name = name
|
|
|
|
|
|
|
|
|
|
/datum/action/item_action/organ_action/use/New(Target)
|
|
|
|
|
..()
|
|
|
|
|
name = "Use [target.name]"
|
|
|
|
|
button.name = name
|
|
|
|
|
|
|
|
|
|
/datum/action/item_action/cult_dagger
|
|
|
|
|
name = "Draw Blood Rune"
|
|
|
|
|
@@ -509,14 +542,13 @@
|
|
|
|
|
button_icon_state = "draw"
|
|
|
|
|
buttontooltipstyle = "cult"
|
|
|
|
|
background_icon_state = "bg_demon"
|
|
|
|
|
default_button_position = "6:157,4:-2"
|
|
|
|
|
|
|
|
|
|
/datum/action/item_action/cult_dagger/Grant(mob/M)
|
|
|
|
|
if(iscultist(M))
|
|
|
|
|
..()
|
|
|
|
|
button.screen_loc = "6:157,4:-2"
|
|
|
|
|
button.moved = "6:157,4:-2"
|
|
|
|
|
else
|
|
|
|
|
if(!iscultist(M))
|
|
|
|
|
Remove(owner)
|
|
|
|
|
return
|
|
|
|
|
return ..()
|
|
|
|
|
|
|
|
|
|
/datum/action/item_action/cult_dagger/Trigger()
|
|
|
|
|
for(var/obj/item/H in owner.held_items) //In case we were already holding another dagger
|
|
|
|
|
@@ -643,7 +675,6 @@
|
|
|
|
|
icon_icon = S.action_icon
|
|
|
|
|
button_icon_state = S.action_icon_state
|
|
|
|
|
background_icon_state = S.action_background_icon_state
|
|
|
|
|
button.name = name
|
|
|
|
|
|
|
|
|
|
/datum/action/spell_action/Destroy()
|
|
|
|
|
var/obj/effect/proc_holder/S = target
|
|
|
|
|
@@ -711,44 +742,114 @@
|
|
|
|
|
/datum/action/cooldown
|
|
|
|
|
check_flags = 0
|
|
|
|
|
transparent_when_unavailable = FALSE
|
|
|
|
|
// The default cooldown applied when StartCooldown() is called
|
|
|
|
|
var/cooldown_time = 0
|
|
|
|
|
// The actual next time this ability can be used
|
|
|
|
|
var/next_use_time = 0
|
|
|
|
|
// Whether or not you want the cooldown for the ability to display in text form
|
|
|
|
|
var/text_cooldown = TRUE
|
|
|
|
|
// Setting for intercepting clicks before activating the ability
|
|
|
|
|
var/click_to_activate = FALSE
|
|
|
|
|
// Shares cooldowns with other cooldown abilities of the same value, not active if null
|
|
|
|
|
var/shared_cooldown
|
|
|
|
|
|
|
|
|
|
/datum/action/cooldown/New()
|
|
|
|
|
..()
|
|
|
|
|
/datum/action/cooldown/CreateButton()
|
|
|
|
|
var/atom/movable/screen/movable/action_button/button = ..()
|
|
|
|
|
button.maptext = ""
|
|
|
|
|
button.maptext_x = 8
|
|
|
|
|
button.maptext_y = 0
|
|
|
|
|
button.maptext_width = 24
|
|
|
|
|
button.maptext_height = 12
|
|
|
|
|
return button
|
|
|
|
|
|
|
|
|
|
/datum/action/cooldown/IsAvailable(silent = FALSE)
|
|
|
|
|
return next_use_time <= world.time
|
|
|
|
|
/datum/action/cooldown/IsAvailable()
|
|
|
|
|
return ..() && (next_use_time <= world.time)
|
|
|
|
|
|
|
|
|
|
/datum/action/cooldown/proc/StartCooldown()
|
|
|
|
|
next_use_time = world.time + cooldown_time
|
|
|
|
|
button.maptext = MAPTEXT_TINY_UNICODE("[round(cooldown_time/10, 0.1)]")
|
|
|
|
|
UpdateButtonIcon()
|
|
|
|
|
/// Starts a cooldown time to be shared with similar abilities, will use default cooldown time if an override is not specified
|
|
|
|
|
/datum/action/cooldown/proc/StartCooldown(override_cooldown_time)
|
|
|
|
|
if(shared_cooldown)
|
|
|
|
|
for(var/datum/action/cooldown/shared_ability in owner.actions - src)
|
|
|
|
|
if(shared_cooldown == shared_ability.shared_cooldown)
|
|
|
|
|
if(isnum(override_cooldown_time))
|
|
|
|
|
shared_ability.StartCooldownSelf(override_cooldown_time)
|
|
|
|
|
else
|
|
|
|
|
shared_ability.StartCooldownSelf(cooldown_time)
|
|
|
|
|
StartCooldownSelf(override_cooldown_time)
|
|
|
|
|
|
|
|
|
|
/// Starts a cooldown time for this ability only, will use default cooldown time if an override is not specified
|
|
|
|
|
/datum/action/cooldown/proc/StartCooldownSelf(override_cooldown_time)
|
|
|
|
|
if(isnum(override_cooldown_time))
|
|
|
|
|
next_use_time = world.time + override_cooldown_time
|
|
|
|
|
else
|
|
|
|
|
next_use_time = world.time + cooldown_time
|
|
|
|
|
UpdateButtons()
|
|
|
|
|
START_PROCESSING(SSfastprocess, src)
|
|
|
|
|
|
|
|
|
|
/datum/action/cooldown/process()
|
|
|
|
|
/datum/action/cooldown/Trigger(trigger_flags, atom/target)
|
|
|
|
|
. = ..()
|
|
|
|
|
if(!.)
|
|
|
|
|
return
|
|
|
|
|
if(!owner)
|
|
|
|
|
return FALSE
|
|
|
|
|
if(click_to_activate)
|
|
|
|
|
if(target)
|
|
|
|
|
// For automatic / mob handling
|
|
|
|
|
return InterceptClickOn(owner, null, target)
|
|
|
|
|
if(owner.click_intercept == src)
|
|
|
|
|
owner.click_intercept = null
|
|
|
|
|
else
|
|
|
|
|
owner.click_intercept = src
|
|
|
|
|
for(var/datum/action/cooldown/ability in owner.actions)
|
|
|
|
|
ability.UpdateButtons()
|
|
|
|
|
return TRUE
|
|
|
|
|
return PreActivate(owner)
|
|
|
|
|
|
|
|
|
|
/// Intercepts client owner clicks to activate the ability
|
|
|
|
|
/datum/action/cooldown/proc/InterceptClickOn(mob/living/caller, params, atom/target)
|
|
|
|
|
if(!IsAvailable())
|
|
|
|
|
return FALSE
|
|
|
|
|
if(!target)
|
|
|
|
|
return FALSE
|
|
|
|
|
PreActivate(target)
|
|
|
|
|
caller.click_intercept = null
|
|
|
|
|
return TRUE
|
|
|
|
|
|
|
|
|
|
/// For signal calling
|
|
|
|
|
/datum/action/cooldown/proc/PreActivate(atom/target)
|
|
|
|
|
if(SEND_SIGNAL(owner, COMSIG_MOB_ABILITY_STARTED, src) & COMPONENT_BLOCK_ABILITY_START)
|
|
|
|
|
return
|
|
|
|
|
. = Activate(target)
|
|
|
|
|
SEND_SIGNAL(owner, COMSIG_MOB_ABILITY_FINISHED, src)
|
|
|
|
|
|
|
|
|
|
/// To be implemented by subtypes
|
|
|
|
|
/datum/action/cooldown/proc/Activate(atom/target)
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
/datum/action/cooldown/UpdateButton(atom/movable/screen/movable/action_button/button, status_only = FALSE, force = FALSE)
|
|
|
|
|
. = ..()
|
|
|
|
|
if(!button)
|
|
|
|
|
return
|
|
|
|
|
var/time_left = max(next_use_time - world.time, 0)
|
|
|
|
|
if(text_cooldown)
|
|
|
|
|
button.maptext = MAPTEXT("<b>[round(time_left/10, 0.1)]</b>")
|
|
|
|
|
if(!owner || time_left == 0)
|
|
|
|
|
button.maptext = ""
|
|
|
|
|
if(IsAvailable() && owner.click_intercept == src)
|
|
|
|
|
button.color = COLOR_GREEN
|
|
|
|
|
|
|
|
|
|
/datum/action/cooldown/process()
|
|
|
|
|
var/time_left = max(next_use_time - world.time, 0)
|
|
|
|
|
if(!owner || time_left == 0)
|
|
|
|
|
STOP_PROCESSING(SSfastprocess, src)
|
|
|
|
|
var/timeleft = max(next_use_time - world.time, 0)
|
|
|
|
|
if(timeleft == 0)
|
|
|
|
|
button.maptext = ""
|
|
|
|
|
UpdateButtonIcon()
|
|
|
|
|
STOP_PROCESSING(SSfastprocess, src)
|
|
|
|
|
else
|
|
|
|
|
button.maptext = MAPTEXT_TINY_UNICODE("[round(cooldown_time/10, 0.1)]")
|
|
|
|
|
UpdateButtons()
|
|
|
|
|
|
|
|
|
|
/datum/action/cooldown/Grant(mob/M)
|
|
|
|
|
..()
|
|
|
|
|
if(owner)
|
|
|
|
|
UpdateButtonIcon()
|
|
|
|
|
if(next_use_time > world.time)
|
|
|
|
|
START_PROCESSING(SSfastprocess, src)
|
|
|
|
|
if(!owner)
|
|
|
|
|
return
|
|
|
|
|
UpdateButtons()
|
|
|
|
|
if(next_use_time > world.time)
|
|
|
|
|
START_PROCESSING(SSfastprocess, src)
|
|
|
|
|
|
|
|
|
|
//surf_ss13
|
|
|
|
|
/datum/action/item_action/bhop
|
|
|
|
|
|