mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-11 08:06:33 +01:00
Adds signboards (#95824)
This commit is contained in:
@@ -0,0 +1,213 @@
|
||||
#define INVESTIGATE_SIGNBOARD "signboard"
|
||||
#define SIGNBOARD_WIDTH (ICON_SIZE_X * 3.5)
|
||||
#define SIGNBOARD_HEIGHT (ICON_SIZE_Y * 2.5)
|
||||
#define MAX_SIGN_LEN 106
|
||||
|
||||
/obj/structure/signboard
|
||||
name = "sign"
|
||||
desc = "A foldable sign."
|
||||
icon = 'icons/obj/signboards.dmi'
|
||||
icon_state = "sign"
|
||||
base_icon_state = "sign"
|
||||
density = TRUE
|
||||
anchored = TRUE
|
||||
interaction_flags_atom = INTERACT_ATOM_ATTACK_HAND | INTERACT_ATOM_REQUIRES_DEXTERITY
|
||||
custom_materials = list(/datum/material/wood = SHEET_MATERIAL_AMOUNT * 5)
|
||||
/// The image holding this sign's text
|
||||
var/image/text_image
|
||||
/// The current text written on the sign
|
||||
var/sign_text
|
||||
/// The maximum length of text that can be input onto the sign.
|
||||
var/max_length = MAX_SIGN_LEN
|
||||
/// If true, the text cannot be changed by players.
|
||||
var/locked = FALSE
|
||||
/// If text should be shown while unanchored.
|
||||
var/show_while_unanchored = FALSE
|
||||
/// If TRUE, the sign can be edited without a pen.
|
||||
var/edit_by_hand = FALSE
|
||||
|
||||
/obj/structure/signboard/Initialize(mapload)
|
||||
. = ..()
|
||||
if(sign_text)
|
||||
set_text(sign_text, force = TRUE)
|
||||
investigate_log("had its text set on load to \"[sign_text]\"", INVESTIGATE_SIGNBOARD)
|
||||
update_appearance()
|
||||
register_context()
|
||||
|
||||
/obj/structure/signboard/Destroy(force)
|
||||
QDEL_NULL(text_image)
|
||||
return ..()
|
||||
|
||||
/obj/structure/signboard/add_context(atom/source, list/context, obj/item/held_item, mob/user)
|
||||
. = ..()
|
||||
if(is_locked(user))
|
||||
return
|
||||
if(held_item?.tool_behaviour == TOOL_WRENCH)
|
||||
context[SCREENTIP_CONTEXT_LMB] = anchored ? "Unsecure" : "Secure"
|
||||
return CONTEXTUAL_SCREENTIP_SET
|
||||
if((edit_by_hand || istype(held_item, /obj/item/pen)) && (anchored || show_while_unanchored))
|
||||
context[SCREENTIP_CONTEXT_LMB] = "Set Displayed Text"
|
||||
if(sign_text)
|
||||
context[SCREENTIP_CONTEXT_ALT_RMB] = "Clear Sign"
|
||||
return CONTEXTUAL_SCREENTIP_SET
|
||||
|
||||
/obj/structure/signboard/examine(mob/user)
|
||||
. = ..()
|
||||
if(!edit_by_hand)
|
||||
. += span_notice("You can write on the sign with a <b>pen.</b>")
|
||||
if(anchored)
|
||||
. += span_notice("It's secured to the floor, you could use a <b>wrench</b> to unsecure and move it.")
|
||||
else
|
||||
. += span_notice("It's unsecured, you could use a <b>wrench</b> to secure it in place.")
|
||||
if(sign_text)
|
||||
. += span_boldnotice("\nIt currently displays the following:")
|
||||
. += span_info(html_encode(sign_text))
|
||||
else
|
||||
. += span_notice("\nIt's blank.")
|
||||
|
||||
/obj/structure/signboard/update_icon_state()
|
||||
. = ..()
|
||||
icon_state = "[base_icon_state][sign_text ? "" : "_blank"]"
|
||||
|
||||
/obj/structure/signboard/vv_edit_var(var_name, var_value)
|
||||
if(var_name == NAMEOF(src, sign_text))
|
||||
if(!set_text(var_value, force = TRUE))
|
||||
return FALSE
|
||||
datum_flags |= DF_VAR_EDITED
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
/obj/structure/signboard/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
|
||||
if(!istype(tool, /obj/item/pen))
|
||||
return NONE
|
||||
try_set_text(user)
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
|
||||
/obj/structure/signboard/attack_hand(mob/living/user, list/modifiers)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(!edit_by_hand && !user.is_holding_item_of_type(/obj/item/pen))
|
||||
balloon_alert(user, "need a pen!")
|
||||
return TRUE
|
||||
if(try_set_text(user))
|
||||
return TRUE
|
||||
|
||||
/obj/structure/signboard/proc/try_set_text(mob/living/user)
|
||||
. = FALSE
|
||||
if(!anchored && !show_while_unanchored)
|
||||
return FALSE
|
||||
if(check_locked(user))
|
||||
return FALSE
|
||||
var/new_text = tgui_input_text(
|
||||
user,
|
||||
message = "What would you like to set this sign's text to?",
|
||||
title = full_capitalize(name),
|
||||
default = sign_text,
|
||||
max_length = max_length,
|
||||
multiline = TRUE,
|
||||
encode = FALSE,
|
||||
)
|
||||
if(QDELETED(src) || !new_text || check_locked(user))
|
||||
return FALSE
|
||||
var/list/filter_result = CAN_BYPASS_FILTER(user) ? null : is_ic_filtered(new_text)
|
||||
if(filter_result)
|
||||
REPORT_CHAT_FILTER_TO_USER(user, filter_result)
|
||||
return FALSE
|
||||
var/list/soft_filter_result = CAN_BYPASS_FILTER(user) ? null : is_soft_ic_filtered(new_text)
|
||||
if(soft_filter_result)
|
||||
if(tgui_alert(user, "Your message contains \"[soft_filter_result[CHAT_FILTER_INDEX_WORD]]\". \"[soft_filter_result[CHAT_FILTER_INDEX_REASON]]\", Are you sure you want to say it?", "Soft Blocked Word", list("Yes", "No")) != "Yes")
|
||||
return FALSE
|
||||
message_admins("[ADMIN_LOOKUPFLW(user)] has passed the soft filter for \"[soft_filter_result[CHAT_FILTER_INDEX_WORD]]\" when writing to the sign at [ADMIN_VERBOSEJMP(src)], they may be using a disallowed term. Sign text: \"[html_encode(new_text)]\"")
|
||||
log_admin_private("[key_name(user)] has passed the soft filter for \"[soft_filter_result[CHAT_FILTER_INDEX_WORD]]\" when writing to the sign at [loc_name(src)], they may be using a disallowed term. Sign text: \"[new_text]\"")
|
||||
if(set_text(new_text))
|
||||
balloon_alert(user, "set text")
|
||||
investigate_log("([key_name(user)]) set text to \"[sign_text || "(none)"]\"", INVESTIGATE_SIGNBOARD)
|
||||
return TRUE
|
||||
|
||||
/obj/structure/signboard/click_alt_secondary(mob/user)
|
||||
. = ..()
|
||||
if(!sign_text || !can_interact(user) || !user.can_perform_action(src, NEED_DEXTERITY))
|
||||
return
|
||||
if(!edit_by_hand && !user.is_holding_item_of_type(/obj/item/pen))
|
||||
balloon_alert(user, "need a pen!")
|
||||
return
|
||||
if(check_locked(user))
|
||||
return
|
||||
if(set_text(null))
|
||||
balloon_alert(user, "cleared text")
|
||||
investigate_log("([key_name(user)]) cleared the text", INVESTIGATE_SIGNBOARD)
|
||||
|
||||
/obj/structure/signboard/wrench_act(mob/living/user, obj/item/tool)
|
||||
. = ..()
|
||||
if(!anchored || !check_locked(user))
|
||||
default_unfasten_wrench(user, tool)
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
|
||||
/obj/structure/signboard/on_changed_z_level(turf/old_turf, turf/new_turf, same_z_layer, notify_contents)
|
||||
if(!same_z_layer)
|
||||
SET_PLANE_EXPLICIT(text_image, ABOVE_GAME_PLANE, src)
|
||||
return ..()
|
||||
|
||||
/obj/structure/signboard/set_anchored(anchorvalue)
|
||||
. = ..()
|
||||
update_text()
|
||||
|
||||
/obj/structure/signboard/proc/is_locked(mob/user)
|
||||
if(isAdminGhostAI(user))
|
||||
return FALSE
|
||||
return locked
|
||||
|
||||
/obj/structure/signboard/proc/check_locked(mob/user, silent = FALSE)
|
||||
. = is_locked(user)
|
||||
if(. && !silent)
|
||||
balloon_alert(user, "locked!")
|
||||
|
||||
/obj/structure/signboard/proc/should_display_text()
|
||||
if(QDELETED(src) || !isturf(loc) || !sign_text)
|
||||
return FALSE
|
||||
if(!anchored && !show_while_unanchored)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/structure/signboard/MouseEntered(location, control, params)
|
||||
. = ..()
|
||||
if(QDELETED(src) || !should_display_text())
|
||||
return
|
||||
usr.client.images |= text_image
|
||||
|
||||
/obj/structure/signboard/MouseExited(location, control, params)
|
||||
. = ..()
|
||||
usr.client.images -= text_image
|
||||
|
||||
/// Creates [text_image] if it doesn't exist, and sets its maptext to [sign_text]
|
||||
/obj/structure/signboard/proc/update_text()
|
||||
PROTECTED_PROC(TRUE) // Use set_text instead
|
||||
var/safe_width = src.bound_width || ICON_SIZE_X
|
||||
var/safe_height = src.bound_height || ICON_SIZE_Y
|
||||
var/text_html = MAPTEXT_GRAND9K("<span style='text-align: center; line-height: 1'>[html_encode(sign_text)]</span>")
|
||||
if(!text_image)
|
||||
text_image = new
|
||||
SET_PLANE_EXPLICIT(text_image, ABOVE_GAME_PLANE, src)
|
||||
text_image.alpha = 192
|
||||
text_image.loc = src
|
||||
text_image.maptext_x = (SIGNBOARD_WIDTH - safe_width) * -0.5
|
||||
text_image.maptext_y = safe_height
|
||||
text_image.maptext_width = SIGNBOARD_WIDTH
|
||||
text_image.maptext_height = SIGNBOARD_HEIGHT
|
||||
text_image.maptext = text_html
|
||||
|
||||
/obj/structure/signboard/proc/set_text(new_text, force = FALSE)
|
||||
. = FALSE
|
||||
if(QDELETED(src) || (locked && !force))
|
||||
return
|
||||
if(!istext(new_text) && !isnull(new_text))
|
||||
CRASH("Attempted to set invalid signtext: [new_text]")
|
||||
. = TRUE
|
||||
sign_text = trim(new_text, max_length)
|
||||
update_text()
|
||||
update_appearance()
|
||||
|
||||
#undef MAX_SIGN_LEN
|
||||
#undef SIGNBOARD_HEIGHT
|
||||
#undef SIGNBOARD_WIDTH
|
||||
@@ -0,0 +1,239 @@
|
||||
/obj/structure/signboard/holosign
|
||||
name = "holographic sign"
|
||||
desc = "A holographic signboard, projecting text above it."
|
||||
icon_state = "holographic_sign"
|
||||
base_icon_state = "holographic_sign"
|
||||
layer = ABOVE_MOB_LAYER
|
||||
density = FALSE
|
||||
edit_by_hand = TRUE
|
||||
show_while_unanchored = TRUE
|
||||
light_range = MINIMUM_USEFUL_LIGHT_RANGE
|
||||
light_power = 0.3
|
||||
light_color = COLOR_CARP_TEAL
|
||||
light_on = FALSE
|
||||
custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 5.05, /datum/material/glass = SMALL_MATERIAL_AMOUNT * 0.7)
|
||||
/// If set, only IDs with this name can (un)lock the sign.
|
||||
var/registered_owner
|
||||
/// The current color of the sign.
|
||||
/// The sign will be greyscale if this is set.
|
||||
var/current_color
|
||||
|
||||
/obj/structure/signboard/holosign/Initialize(mapload)
|
||||
. = ..()
|
||||
if(current_color)
|
||||
INVOKE_ASYNC(src, PROC_REF(set_color), current_color)
|
||||
AddComponent(/datum/component/usb_port, list(
|
||||
/obj/item/circuit_component/holo_signboard,
|
||||
))
|
||||
|
||||
/obj/structure/signboard/holosign/add_context(atom/source, list/context, obj/item/held_item, mob/user)
|
||||
. = ..()
|
||||
var/locked = is_locked(user)
|
||||
if(istype(held_item, /obj/item/card/emag))
|
||||
context[SCREENTIP_CONTEXT_LMB] = "Short Out Locking Mechanisms"
|
||||
. = CONTEXTUAL_SCREENTIP_SET
|
||||
else if(!locked && istype(held_item?.GetID(), /obj/item/usb_cable))
|
||||
context[SCREENTIP_CONTEXT_LMB] = "Connect USB Cable"
|
||||
else if(!locked && istype(held_item?.GetID(), /obj/item/card/id))
|
||||
context[SCREENTIP_CONTEXT_LMB] = registered_owner ? "Remove ID Lock" : "Lock To ID"
|
||||
. = CONTEXTUAL_SCREENTIP_SET
|
||||
if(!locked)
|
||||
context[SCREENTIP_CONTEXT_RMB] = "Set Sign Color"
|
||||
. = CONTEXTUAL_SCREENTIP_SET
|
||||
|
||||
/obj/structure/signboard/holosign/update_icon_state()
|
||||
base_icon_state = current_color ? "[initial(base_icon_state)]_greyscale" : initial(base_icon_state)
|
||||
. = ..()
|
||||
if(obj_flags & EMAGGED)
|
||||
icon_state += "_emag"
|
||||
|
||||
/obj/structure/signboard/holosign/examine(mob/user)
|
||||
. = ..()
|
||||
if(obj_flags & EMAGGED)
|
||||
. += span_warning("<br>Its locking mechanisms appear to be shorted out!")
|
||||
else if(registered_owner)
|
||||
. += span_info("<br>It is locked to the ID of [span_name(registered_owner)].")
|
||||
|
||||
/obj/structure/signboard/holosign/update_overlays()
|
||||
. = ..()
|
||||
if(sign_text)
|
||||
. += emissive_appearance(icon, "holographic_sign_e", src)
|
||||
|
||||
/obj/structure/signboard/holosign/vv_edit_var(var_name, var_value)
|
||||
if(var_name == NAMEOF(src, color) || var_name == NAMEOF(src, current_color))
|
||||
INVOKE_ASYNC(src, PROC_REF(set_color), var_value)
|
||||
datum_flags |= DF_VAR_EDITED
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
/obj/structure/signboard/holosign/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
|
||||
var/obj/item/item = astype(tool, /obj/item)
|
||||
var/obj/item/card/id/id = item?.GetID()
|
||||
if(!istype(id) || !can_interact(user) || !user.can_perform_action(src, NEED_DEXTERITY))
|
||||
return NONE
|
||||
|
||||
var/trimmed_id_name = trimtext(id.registered_name)
|
||||
if(!trimmed_id_name)
|
||||
balloon_alert(user, "no name on id!")
|
||||
return ITEM_INTERACT_BLOCKING
|
||||
if(obj_flags & EMAGGED)
|
||||
balloon_alert(user, "lock shorted out!")
|
||||
return ITEM_INTERACT_BLOCKING
|
||||
if(registered_owner)
|
||||
if(!check_locked(user))
|
||||
registered_owner = null
|
||||
balloon_alert(user, "id lock removed")
|
||||
investigate_log("([key_name(user)]) removed id lock", INVESTIGATE_SIGNBOARD)
|
||||
else
|
||||
registered_owner = trimmed_id_name
|
||||
balloon_alert(user, "locked to id")
|
||||
investigate_log("([key_name(user)]) added id lock for \"[registered_owner]\"", INVESTIGATE_SIGNBOARD)
|
||||
update_appearance()
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
|
||||
/obj/structure/signboard/holosign/is_locked(mob/living/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(registered_owner && isliving(user))
|
||||
var/obj/item/card/id/id = user.get_idcard()
|
||||
if(!istype(id) || QDELING(id))
|
||||
return TRUE
|
||||
return !cmptext(trimtext(id.registered_name), registered_owner)
|
||||
|
||||
/obj/structure/signboard/holosign/set_text(new_text, force)
|
||||
. = ..()
|
||||
set_light(l_on = !!sign_text)
|
||||
|
||||
/obj/structure/signboard/holosign/attack_hand_secondary(mob/user, list/modifiers)
|
||||
. = ..()
|
||||
if(. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN)
|
||||
return
|
||||
if(try_set_color(user))
|
||||
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
|
||||
|
||||
/obj/structure/signboard/holosign/proc/try_set_color(mob/user)
|
||||
. = TRUE
|
||||
if(!can_interact(user) || !user.can_perform_action(src, NEED_DEXTERITY))
|
||||
return FALSE
|
||||
if(check_locked(user))
|
||||
return
|
||||
var/new_color = sanitize_color(tgui_color_picker(user, "Set Sign Color", full_capitalize(name), current_color))
|
||||
if(new_color && is_color_dark_with_saturation(new_color, 25))
|
||||
balloon_alert(user, "color too dark!")
|
||||
return
|
||||
if(check_locked(user))
|
||||
return
|
||||
INVOKE_ASYNC(src, PROC_REF(set_color), new_color)
|
||||
if(new_color)
|
||||
balloon_alert(user, "set color to [new_color]")
|
||||
investigate_log("([key_name(user)]) set the color to [new_color || "(none)"]", INVESTIGATE_SIGNBOARD)
|
||||
else
|
||||
balloon_alert(user, "unset color")
|
||||
investigate_log("([key_name(user)]) cleared the color", INVESTIGATE_SIGNBOARD)
|
||||
|
||||
/obj/structure/signboard/holosign/emag_act(mob/user, obj/item/card/emag/emag_card)
|
||||
if(obj_flags & EMAGGED)
|
||||
return FALSE
|
||||
playsound(src, SFX_SPARKS, vol = 100, vary = TRUE, extrarange = SHORT_RANGE_SOUND_EXTRARANGE)
|
||||
do_sparks(3, cardinal_only = FALSE, source = src)
|
||||
balloon_alert(user, "lock broken")
|
||||
investigate_log("was emagged by [key_name(user)] (previous owner: [registered_owner || "(none)"])", INVESTIGATE_SIGNBOARD)
|
||||
registered_owner = null
|
||||
obj_flags |= EMAGGED
|
||||
update_appearance()
|
||||
|
||||
/obj/structure/signboard/holosign/proc/sanitize_color(color)
|
||||
. = sanitize_hexcolor(color)
|
||||
if(!. || . == COLOR_BLACK)
|
||||
return null
|
||||
|
||||
/obj/structure/signboard/holosign/proc/set_color(new_color)
|
||||
new_color = sanitize_color(new_color)
|
||||
if(!new_color)
|
||||
current_color = null
|
||||
remove_atom_colour(FIXED_COLOUR_PRIORITY)
|
||||
else
|
||||
current_color = new_color
|
||||
add_atom_colour(new_color, FIXED_COLOUR_PRIORITY)
|
||||
set_light(l_color = current_color || src::light_color)
|
||||
update_appearance()
|
||||
|
||||
/obj/item/circuit_component/holo_signboard
|
||||
display_name = "Holographic Signboard"
|
||||
desc = "Output text to a signboard, insert <br> in the message field to linebreak. Set the color to 0, 0, 0 to reset to default."
|
||||
circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL
|
||||
|
||||
var/datum/port/input/message
|
||||
var/datum/port/input/clear
|
||||
|
||||
var/datum/port/output/fail_reason
|
||||
var/datum/port/output/on_fail
|
||||
|
||||
var/datum/port/input/red
|
||||
var/datum/port/input/green
|
||||
var/datum/port/input/blue
|
||||
var/datum/port/input/set_color
|
||||
|
||||
var/obj/structure/signboard/holosign/connected_display
|
||||
|
||||
/obj/item/circuit_component/holo_signboard/populate_ports()
|
||||
message = add_input_port("Message", PORT_TYPE_STRING)
|
||||
clear = add_input_port("Clear", PORT_TYPE_SIGNAL, trigger = PROC_REF(clear_received))
|
||||
|
||||
fail_reason = add_output_port("Fail Reason", PORT_TYPE_STRING)
|
||||
on_fail = add_output_port("Failed", PORT_TYPE_SIGNAL)
|
||||
|
||||
red = add_input_port("Red", PORT_TYPE_NUMBER)
|
||||
green = add_input_port("Green", PORT_TYPE_NUMBER)
|
||||
blue = add_input_port("Blue", PORT_TYPE_NUMBER)
|
||||
set_color = add_input_port("Set Color", PORT_TYPE_SIGNAL, trigger = PROC_REF(color_received))
|
||||
|
||||
/obj/item/circuit_component/holo_signboard/register_usb_parent(atom/movable/shell)
|
||||
. = ..()
|
||||
if(istype(shell, /obj/structure/signboard/holosign))
|
||||
connected_display = shell
|
||||
|
||||
/obj/item/circuit_component/holo_signboard/input_received(datum/port/input/port)
|
||||
if(!connected_display)
|
||||
return
|
||||
if(length(message.value) > connected_display.max_length) //5000 is a hell of a lot longer than 144.
|
||||
fail_reason.set_output("Too long ([length(message.value)]/[connected_display.max_length]).")
|
||||
on_fail.set_output(COMPONENT_SIGNAL)
|
||||
return
|
||||
if(is_ic_filtered(message.value))
|
||||
fail_reason.set_output("Prohibited content.")
|
||||
on_fail.set_output(COMPONENT_SIGNAL)
|
||||
return
|
||||
|
||||
var/edited_message = replacetextEx_char(message.value, "<br>", "\n")
|
||||
if(connected_display.set_text(edited_message))
|
||||
investigate_log("Circuit USB ([parent.get_creator()]) set text to \"[connected_display.sign_text || "(none)"]\"", INVESTIGATE_SIGNBOARD)
|
||||
if(is_soft_ic_filtered(message.value))
|
||||
message_admins("A circuit component (by [parent.get_creator_admin()]) added a soft filtered message to a signboard. [ADMIN_COORDJMP(src)]")
|
||||
else
|
||||
fail_reason.set_output("Connection refused by external endpoint.")
|
||||
on_fail.set_output(COMPONENT_SIGNAL)
|
||||
|
||||
/obj/item/circuit_component/holo_signboard/proc/clear_received(datum/port/input/port)
|
||||
if(!connected_display.set_text(null))
|
||||
fail_reason.set_output("Connection refused by external endpoint.")
|
||||
on_fail.set_output(COMPONENT_SIGNAL)
|
||||
|
||||
/obj/item/circuit_component/holo_signboard/proc/color_received(datum/port/input/port)
|
||||
red.set_value(clamp(red.value, 0, 255))
|
||||
blue.set_value(clamp(blue.value, 0, 255))
|
||||
green.set_value(clamp(green.value, 0, 255))
|
||||
var/signboard_color = rgb(red.value, green.value, blue.value)
|
||||
if(signboard_color && signboard_color != rgb(0, 0, 0) && is_color_dark_with_saturation(signboard_color, 25))
|
||||
fail_reason.set_output("Color too dark to display.")
|
||||
on_fail.set_output(COMPONENT_SIGNAL)
|
||||
return
|
||||
connected_display.set_color(signboard_color) //doesnt have a return so no need to check and error
|
||||
investigate_log("Circuit USB ([parent.get_creator()]) set the color to [signboard_color || "(none)"]", INVESTIGATE_SIGNBOARD)
|
||||
|
||||
/// Given a color in the format of "#RRGGBB", will return if the color
|
||||
/// is dark. Value is mixed with Saturation and Brightness from HSV.
|
||||
/proc/is_color_dark_with_saturation(color, threshold = 25)
|
||||
var/hsl = rgb2num(color, COLORSPACE_HSL)
|
||||
return hsl[3] < threshold
|
||||
Reference in New Issue
Block a user