manually ports last upstream PRs (#9286)

This commit is contained in:
Kashargul
2024-10-24 00:37:53 +02:00
committed by GitHub
parent efa98f8e47
commit 3becf31cf4
15 changed files with 314 additions and 92 deletions

View File

@@ -241,3 +241,5 @@
// Just used downstream
#define span_wingdings(str) ("<span class='wingdings'>" + str + "</span>")
#define span_maptext(str) ("<span class='maptext'>" + str + "</span>")

View File

@@ -16,6 +16,7 @@
if(owner)
my_mob = owner
update_abilities(0, owner)
overlays.Add(closed_state)
else
message_admins("ERROR: ability_master's New() was not given an owner argument. This is a bug.")

View File

@@ -1,19 +1,36 @@
/datum/action
var/name = "Generic Action"
var/desc = null
var/atom/movable/target = null
var/check_flags = 0
var/processing = 0
var/check_flags = NONE
var/processing = FALSE
var/obj/screen/movable/action_button/button = null
var/button_icon = 'icons/mob/actions.dmi'
var/button_icon_state = "default"
var/background_icon_state = "bg_default"
var/mob/living/owner
var/buttontooltipstyle = ""
var/transparent_when_unavailable = TRUE
var/icon_icon = 'icons/mob/actions.dmi'
var/button_icon_state = "default"
var/mob/owner
/datum/action/New(Target)
target = 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
RegisterSignal(Target, COMSIG_ATOM_UPDATED_ICON, .proc/OnUpdatedIcon)
/datum/action/Destroy()
if(owner)
@@ -22,84 +39,128 @@
QDEL_NULL(button)
return ..()
/datum/action/proc/Grant(mob/living/L)
/datum/action/proc/Grant(mob/M)
if(M)
if(owner)
if(owner == L)
if(owner == M)
return
Remove(owner)
owner = L
L.actions += src
if(L.client)
L.client.screen += button
L.update_action_buttons(TRUE)
owner = M
/datum/action/proc/Remove(mob/living/L)
if(L.client)
L.client.screen -= button
// button id generation
var/counter = 0
var/bitfield = 0
for(var/datum/action/A as anything 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
LAZYADD(M.actions, src)
if(M.client)
M.client.screen += button
button.locked = /* M.client.prefs.buttons_locked || */ button.id ? LAZYACCESS(M.client.prefs.action_button_screen_locs, "[name]_[button.id]") : FALSE //even if its not defaultly locked we should remember we locked it before
button.moved = button.id ? LAZYACCESS(M.client.prefs.action_button_screen_locs, "[name]_[button.id]") : FALSE
M.update_action_buttons(TRUE)
else
Remove(owner)
/datum/action/proc/Remove(mob/M)
if(M)
if(M.client)
M.client.screen -= button
button.moved = FALSE
L.actions -= src
L.update_action_buttons(TRUE)
LAZYREMOVE(M.actions, src)
M.update_action_buttons(TRUE)
owner = null
button.moved = FALSE //so the button appears in its normal position when given to another owner.
button.locked = FALSE
button.id = null
/datum/action/proc/Trigger()
if(!IsAvailable())
return 0
return 1
/datum/action/process()
return
return FALSE
if(SEND_SIGNAL(src, COMSIG_ACTION_TRIGGER, src) & COMPONENT_ACTION_BLOCK_TRIGGER)
return FALSE
return TRUE
/datum/action/proc/IsAvailable()
if(!owner)
return 0
return FALSE
if(check_flags & AB_CHECK_RESTRAINED)
if(owner.restrained())
return 0
return FALSE
if(check_flags & AB_CHECK_STUNNED)
if(owner.stunned)
return 0
return FALSE
if(check_flags & AB_CHECK_LYING)
if(owner.lying)
return 0
return FALSE
if(check_flags & AB_CHECK_CONSCIOUS)
if(owner.stat)
return 0
return 1
return FALSE
return TRUE
/datum/action/proc/UpdateButtonIcon()
/datum/action/proc/UpdateButtonIcon(status_only = FALSE, force = FALSE)
if(button)
if(!status_only)
button.name = name
button.desc = desc
// if(owner && 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"]
// if(button.icon_state != settings["bg_state"])
// button.icon_state = settings["bg_state"]
// else
if(button.icon != button_icon)
button.icon = button_icon
if(button.icon_state != background_icon_state)
button.icon_state = background_icon_state
ApplyIcon(button)
ApplyIcon(button, force)
if(!IsAvailable())
button.color = rgb(128, 0, 0, 128)
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(obj/screen/movable/action_button/current_button)
current_button.cut_overlays()
if(button_icon && button_icon_state)
var/image/img
img = image(button_icon, current_button, button_icon_state)
img.pixel_x = 0
img.pixel_y = 0
current_button.add_overlay(img)
/datum/action/proc/ApplyIcon(obj/screen/movable/action_button/current_button, force = FALSE)
if(icon_icon && button_icon_state && ((current_button.button_icon_state != button_icon_state) || force))
current_button.cut_overlays(TRUE)
current_button.add_overlay(mutable_appearance(icon_icon, button_icon_state))
current_button.button_icon_state = button_icon_state
// Currently never triggered
/datum/action/proc/OnUpdatedIcon()
SIGNAL_HANDLER
UpdateButtonIcon()
//Presets for item actions
/datum/action/item_action
check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUNNED|AB_CHECK_LYING|AB_CHECK_CONSCIOUS
button_icon_state = null
// If you want to override the normal icon being the item
// then change this to an icon state
/datum/action/item_action/New(Target)
. = ..()
var/obj/item/I = target
I.actions += src
LAZYADD(I.actions, src)
/datum/action/item_action/Destroy()
var/obj/item/I = target
I.actions -= src
LAZYREMOVE(I.actions, src)
return ..()
/datum/action/item_action/Trigger()
@@ -110,22 +171,28 @@
I.ui_action_click(owner, src.type)
return 1
/datum/action/item_action/ApplyIcon(obj/screen/movable/action_button/current_button)
current_button.cut_overlays()
if(target)
/datum/action/item_action/ApplyIcon(obj/screen/movable/action_button/current_button, force)
if(button_icon && button_icon_state)
// If set, use the custom icon that we set instead
// of the item appearence
return ..()
else if(target && ((current_button.appearance_cache != target.appearance) || force))
var/mutable_appearance/ma = new(target.appearance)
ma.plane = FLOAT_PLANE
ma.layer = FLOAT_LAYER
ma.pixel_x = 0
ma.pixel_y = 0
current_button.cut_overlays()
current_button.add_overlay(ma)
current_button.appearance_cache = target.appearance
/datum/action/item_action/hands_free
check_flags = AB_CHECK_CONSCIOUS
/datum/action/innate
check_flags = 0
check_flags = NONE
var/active = 0
/datum/action/innate/Trigger()
@@ -143,14 +210,45 @@
/datum/action/innate/proc/Deactivate()
return
//Preset for action that call specific procs (consider innate).
/datum/action/generic
check_flags = 0
var/procname
//Preset for an action with a cooldown
/datum/action/cooldown
check_flags = NONE
transparent_when_unavailable = FALSE
var/cooldown_time = 0
var/next_use_time = 0
/datum/action/generic/Trigger()
if(!..())
return 0
if(target && procname)
call(target, procname)(usr)
return 1
/datum/action/cooldown/New()
..()
button.maptext = ""
button.maptext_x = 8
button.maptext_y = 0
button.maptext_width = 24
button.maptext_height = 12
/datum/action/cooldown/IsAvailable()
return next_use_time <= world.time
/datum/action/cooldown/proc/StartCooldown()
next_use_time = world.time + cooldown_time
button.maptext = span_maptext(span_bold("[round(cooldown_time/10, 0.1)]"))
UpdateButtonIcon()
START_PROCESSING(SSfastprocess, src)
/datum/action/cooldown/process()
if(!owner)
button.maptext = ""
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 = span_maptext(span_bold("[round(timeleft/10, 0.1)]"))
/datum/action/cooldown/Grant(mob/M)
..()
if(owner)
UpdateButtonIcon()
if(next_use_time > world.time)
START_PROCESSING(SSfastprocess, src)

View File

@@ -1,26 +1,107 @@
/obj/screen/movable/action_button
var/datum/action/linked_action
var/actiontooltipstyle = ""
screen_loc = null
var/button_icon_state
var/appearance_cache
var/id
/obj/screen/movable/action_button/proc/can_use(mob/user)
if(linked_action)
return linked_action.owner == user
else if(isobserver(user))
// var/mob/dead/observer/O = user
// return !O.observetarget
return TRUE
else
return TRUE
/obj/screen/movable/action_button/MouseDrop(over_object)
if(!can_use(usr))
return
if((istype(over_object, /obj/screen/movable/action_button) && !istype(over_object, /obj/screen/movable/action_button/hide_toggle)))
if(locked)
to_chat(usr, span_warning("Action button \"[name]\" is locked, unlock it first."))
return
var/obj/screen/movable/action_button/B = over_object
var/list/actions = usr.actions
actions.Swap(actions.Find(src.linked_action), actions.Find(B.linked_action))
moved = FALSE
B.moved = FALSE
usr.update_action_buttons()
else
return ..()
/obj/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))
if(locked)
to_chat(usr, span_warning("Action button \"[name]\" is locked, unlock it first."))
return TRUE
moved = FALSE
usr.update_action_buttons()
return 1
return TRUE
if(LAZYACCESS(modifiers, CTRL_CLICK))
locked = !locked
to_chat(usr, span_notice("Action button \"[name]\" [locked ? "" : "un"]locked."))
if(id && usr?.client?.prefs) // try to (un)remember position
LAZYSET(usr.client.prefs.action_button_screen_locs, "[name]_[id]", locked ? moved : null)
return TRUE
if(!usr.checkClickCooldown())
return
usr.setClickCooldown(1)
linked_action.Trigger()
return 1
return TRUE
//Hide/Show Action Buttons ... Button
/obj/screen/movable/action_button/hide_toggle
name = "Hide Buttons"
desc = "Shift-click any button to reset its position, and Control-click it to lock it in place. Alt-click this button reset all buttons to their default positions."
icon = 'icons/mob/actions.dmi'
icon_state = "bg_default"
var/hidden = 0
var/hidden = FALSE
// /obj/screen/movable/action_button/hide_toggle/Initialize()
// . = ..()
// var/static/list/icon_cache = list()
// var/cache_key = "[hide_icon][hide_state]"
// hide_appearance = icon_cache[cache_key]
// if(!hide_appearance)
// hide_appearance = icon_cache[cache_key] = mutable_appearance(hide_icon, hide_state)
// cache_key = "[hide_icon][show_state]"
// show_appearance = icon_cache[cache_key]
// if(!show_appearance)
// show_appearance = icon_cache[cache_key] = mutable_appearance(hide_icon, show_state)
/obj/screen/movable/action_button/hide_toggle/Click(location, control, params)
if(!can_use(usr))
return FALSE
var/list/modifiers = params2list(params)
if(LAZYACCESS(modifiers, SHIFT_CLICK))
if(locked)
to_chat(usr, span_warning("Action button \"[name]\" is locked, unlock it first."))
return TRUE
moved = FALSE
usr.update_action_buttons(TRUE)
return TRUE
if(LAZYACCESS(modifiers, CTRL_CLICK))
locked = !locked
to_chat(usr, span_notice("Action button \"[name]\" [locked ? "" : "un"]locked."))
if(id && usr?.client?.prefs) // try to (un)remember position
LAZYSET(usr.client.prefs.action_button_screen_locs, "[name]_[id]", locked ? moved : null)
return TRUE
if(LAZYACCESS(modifiers, ALT_CLICK))
AltClick(usr)
return TRUE
/obj/screen/movable/action_button/hide_toggle/Click()
usr.hud_used.action_buttons_hidden = !usr.hud_used.action_buttons_hidden
hidden = usr.hud_used.action_buttons_hidden
@@ -28,41 +109,67 @@
name = "Show Buttons"
else
name = "Hide Buttons"
UpdateIcon()
update_icon()
usr.update_action_buttons()
/obj/screen/movable/action_button/hide_toggle/proc/InitialiseIcon(var/mob/living/user)
/obj/screen/movable/action_button/hide_toggle/AltClick(mob/user)
for(var/datum/action/A as anything in user.actions)
var/obj/screen/movable/action_button/B = A.button
B.moved = FALSE
if(B.id && usr?.client?.prefs)
LAZYSET(usr.client.prefs.action_button_screen_locs, "[name]_[B.id]", null)
// B.locked = usr.client.prefs.buttons_locked
// locked = usr.client.prefs.buttons_locked
if(id && usr?.client?.prefs)
LAZYSET(usr.client.prefs.action_button_screen_locs, "[name]_[id]", null)
moved = FALSE
user.update_action_buttons(TRUE)
to_chat(user, span_notice("Action button positions have been reset."))
/obj/screen/movable/action_button/hide_toggle/proc/InitialiseIcon(mob/user)
// var/settings = owner_hud.get_action_buttons_icons()
// icon = settings["bg_icon"]
// icon_state = settings["bg_state"]
// hide_icon = settings["toggle_icon"]
// hide_state = settings["toggle_hide"]
// show_state = settings["toggle_show"]
if(isalien(user))
icon_state = "bg_alien"
else
icon_state = "bg_default"
UpdateIcon()
update_icon()
/obj/screen/movable/action_button/hide_toggle/proc/UpdateIcon()
/obj/screen/movable/action_button/hide_toggle/update_icon()
cut_overlays()
var/image/img = image(icon, src, hidden ? "show" : "hide")
add_overlay(img)
add_overlay(mutable_appearance(icon, hidden ? "show" : "hide"))
// add_overlay(mutable_appearance(hide_icon, hidden ? show_state : hide_state))
/obj/screen/movable/action_button/MouseEntered(location, control, params)
openToolTip(usr, src, params, title = name, content = desc)
. = ..()
if(!QDELETED(src))
openToolTip(usr, src, params, title = name, content = desc, theme = actiontooltipstyle)
/obj/screen/movable/action_button/MouseExited(location, control, params)
closeToolTip(usr)
//used to update the buttons icon.
/mob/proc/update_action_buttons_icon()
return
// /datum/hud/proc/get_action_buttons_icons()
// . = list()
// .["bg_icon"] = ui_style_icon
// .["bg_state"] = "template"
/mob/living/update_action_buttons_icon()
// //TODO : Make these fit theme
// .["toggle_icon"] = 'icons/mob/actions.dmi'
// .["toggle_hide"] = "hide"
// .["toggle_show"] = "show"
//used to update the buttons icon.
/mob/proc/update_action_buttons_icon(status_only = FALSE)
for(var/X in actions)
var/datum/action/A = X
A.UpdateButtonIcon()
A.UpdateButtonIcon(status_only)
//This is the proc used to update all the action buttons. Properly defined in /mob/living/
//This is the proc used to update all the action buttons.
/mob/proc/update_action_buttons(reload_screen)
return
/mob/living/update_action_buttons(reload_screen)
if(!hud_used || !client)
return

View File

@@ -325,6 +325,8 @@ var/list/global_huds = list(
mymob.create_mob_hud(src)
hide_actions_toggle = new()
hide_actions_toggle.InitialiseIcon(mymob)
// if(mymob.client)
// hide_actions_toggle.locked = mymob.client.prefs.buttons_locked
persistant_inventory_update()
mymob.reload_fullscreen() // Reload any fullscreen overlays this mob has.

View File

@@ -12,6 +12,7 @@
mouse_drag_pointer = 'icons/effects/mouse_pointers/screen_drag.dmi'
var/snap2grid = FALSE
var/moved = FALSE
var/locked = FALSE
var/x_off = -16
var/y_off = -16
@@ -23,6 +24,8 @@
/obj/screen/movable/MouseDrop(over_object, src_location, over_location, src_control, over_control, params)
if(locked) // no! i am locked! begone!
return
var/position = mouse_params_to_position(params)
if(!position)
return
@@ -78,6 +81,8 @@
. = num+1
else if(findtext(X,"CENTER"))
. = view_dist+1
else
. = text2num(X)
/obj/screen/movable/proc/encode_screen_Y(Y)
var/view_dist = world.view
@@ -106,6 +111,8 @@
. = num+1
else if(findtext(Y,"CENTER"))
. = view_dist+1
else
. = text2num(Y)
//Debug procs
/client/proc/test_movable_UI()

View File

@@ -33,7 +33,7 @@ SUBSYSTEM_DEF(statpanels)
//"Next Map: -- Not Available --",
"Round ID: [GLOB.round_id ? GLOB.round_id : "NULL"]", // CHOMPEdit
"Server Time: [time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]",
"Round Time: [ROUND_TIME()]",
"Round Time: [roundduration2text()]",
"Station Date: [stationdate2text()], [capitalize(GLOB.world_time_season)]", // CHOMPEdit
"Station Time: [stationtime2text()]",
"Time Dilation: [round(SStime_track.time_dilation_current,1)]% AVG:([round(SStime_track.time_dilation_avg_fast,1)]%, [round(SStime_track.time_dilation_avg,1)]%, [round(SStime_track.time_dilation_avg_slow,1)]%)"

View File

@@ -35,8 +35,8 @@
var/max_pressure_protection // Set this variable if the item protects its wearer against high pressures below an upper bound. Keep at null to disable protection.
var/min_pressure_protection // Set this variable if the item protects its wearer against low pressures above a lower bound. Keep at null to disable protection. 0 represents protection against hard vacuum.
var/list/actions = list() //list of /datum/action's that this item has.
var/list/actions_types = list() //list of paths of action datums to give to the item on New().
var/list/actions //list of /datum/action's that this item has.
var/list/actions_types //list of paths of action datums to give to the item on New().
//This flag is used to determine when items in someone's inventory cover others. IE helmets making it so you can't see glasses, etc.
//It should be used purely for appearance. For gameplay effects caused by items covering body parts, use body_parts_covered.
@@ -338,8 +338,7 @@
if(zoom)
zoom() //binoculars, scope, etc
appearance_flags &= ~NO_CLIENT_COLOR
for(var/X in actions)
var/datum/action/A = X
for(var/datum/action/A as anything in actions)
A.Remove(user)
// called just as an item is picked up (loc is not yet changed)

View File

@@ -70,7 +70,7 @@
prob(2);/obj/item/gun/projectile/automatic/l6_saw,\
prob(2);/obj/item/gun/energy/gun/burst,\
prob(2);/obj/item/storage/box/frags,\
prob(2);/obj/item/twohanded/fireaxe,\
prob(2);/obj/item/material/twohanded/fireaxe,\
prob(2);/obj/item/gun/projectile/luger/brown,\
prob(2);/obj/item/gun/launcher/crossbow,\
prob(2);/obj/item/melee/shock_maul,\

View File

@@ -135,7 +135,7 @@
prob(9);/obj/item/gun/projectile/automatic/mini_uzi,\
prob(9);/obj/item/gun/projectile/pistol,\
prob(9);/obj/item/gun/projectile/shotgun/pump/combat,\
prob(9);/obj/item/twohanded/fireaxe,\
prob(9);/obj/item/material/twohanded/fireaxe,\
prob(9);/obj/item/cane/concealed,\
prob(9);/obj/item/gun/energy/gun,\
prob(8);/obj/item/gun/energy/ionrifle,\

View File

@@ -173,6 +173,10 @@ var/list/preferences_datums = list()
var/examine_text_mode = 0 // Just examine text, include usage (description_info), switch to examine panel.
var/multilingual_mode = 0 // Default behaviour, delimiter-key-space, delimiter-key-delimiter, off
// THIS IS NOT SAVED
// WE JUST HAVE NOWHERE ELSE TO STORE IT
var/list/action_button_screen_locs
var/list/volume_channels = list()
///If they are currently in the process of swapping slots, don't let them open 999 windows for it and get confused

View File

@@ -1041,6 +1041,7 @@
if(lying != lying_prev)
lying_prev = lying
update_transform()
update_action_buttons_icon(status_only = TRUE)
//VOREStation Add
if(lying && LAZYLEN(buckled_mobs))
for(var/mob/living/L as anything in buckled_mobs)

View File

@@ -39,7 +39,6 @@
var/mob_always_swap = 0
var/mob/living/cameraFollow = null
var/list/datum/action/actions = list()
var/tod = null // Time of death
var/update_slimes = 1

View File

@@ -240,4 +240,6 @@
/// dict of custom stat tabs with data
var/list/list/misc_tabs = list()
var/list/datum/action/actions
var/custom_footstep = FOOTSTEP_MOB_SHOE // CHOMPEdit

View File

@@ -221,7 +221,7 @@
// speak_chance = 1
a_intent = "harm"
var/corpse = /obj/effect/landmark/mobcorpse/tunnelclown
var/weapon1 = /obj/item/twohanded/fireaxe
var/weapon1 = /obj/item/material/twohanded/fireaxe
stop_when_pulled = 0
maxHealth = 100
health = 100