Skip to content

Commit

Permalink
Merge branch 'Citadel-Station-13:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
LordPapalus authored Aug 2, 2023
2 parents 442eed3 + e9add0b commit 40b899f
Show file tree
Hide file tree
Showing 689 changed files with 23,177 additions and 21,903 deletions.
174 changes: 96 additions & 78 deletions citadel.dme

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions code/__DEFINES/_cooldowns.dm
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
#define COMSIG_CD_STOP(cd_index) "cooldown_[cd_index]"
#define COMSIG_CD_RESET(cd_index) "cd_reset_[cd_index]"

#define TIMER_COOLDOWN_START(cd_source, cd_index, cd_time) LAZYSET(cd_source.cooldowns, cd_index, addtimer(CALLBACK(GLOBAL_PROC, /proc/end_cooldown, cd_source, cd_index), cd_time))
#define TIMER_COOLDOWN_START(cd_source, cd_index, cd_time) LAZYSET(cd_source.cooldowns, cd_index, addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(end_cooldown), cd_source, cd_index), cd_time))

#define TIMER_COOLDOWN_CHECK(cd_source, cd_index) LAZYACCESS(cd_source.cooldowns, cd_index)

Expand All @@ -38,7 +38,7 @@
* A bit more expensive than the regular timers, but can be reset before they end and the time left can be checked.
*/

#define S_TIMER_COOLDOWN_START(cd_source, cd_index, cd_time) LAZYSET(cd_source.cooldowns, cd_index, addtimer(CALLBACK(GLOBAL_PROC, /proc/end_cooldown, cd_source, cd_index), cd_time, TIMER_STOPPABLE))
#define S_TIMER_COOLDOWN_START(cd_source, cd_index, cd_time) LAZYSET(cd_source.cooldowns, cd_index, addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(end_cooldown), cd_source, cd_index), cd_time, TIMER_STOPPABLE))

#define S_TIMER_COOLDOWN_RESET(cd_source, cd_index) reset_cooldown(cd_source, cd_index)

Expand Down
4 changes: 3 additions & 1 deletion code/__DEFINES/_lists.dm
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
/// Picks from the list, with some safeties, and returns the "default" arg if it fails
#define DEFAULTPICK(L, default) ((istype(L, /list) && L:len) ? pick(L) : default)
/// Ensures L is initailized after this point
#define LAZYINITLIST(L) if (!L) L = list()
#define LAZYINITLIST(L) if (isnull(L)) L = list()
/// Ensures L is initialized and uses it as a rvalue
#define LAZYGETLIST(L) (isnull(L)? (L = list()) : L)
/// Sets a L back to null iff it is empty
#define UNSETEMPTY(L) if (L && !length(L)) L = null
/// Removes I from list L, and sets I to null if it is now empty
Expand Down
7 changes: 6 additions & 1 deletion code/__DEFINES/access.dm
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ STANDARD_ACCESS_DATUM(ACCESS_SECURITY_HOS, station/security/hos, "Head of Securi
STANDARD_ACCESS_DATUM(ACCESS_SECURITY_GENPOP_ENTER, station/security/genpop_enter, "Genpop - Enter")

#define ACCESS_SECURITY_GENPOP_EXIT 112
STANDARD_ACCESS_DATUM(ACCESS_SECURITY_GENPOP_EXIT, station/security/genpop_exit, "Genpop - Enter")
STANDARD_ACCESS_DATUM(ACCESS_SECURITY_GENPOP_EXIT, station/security/genpop_exit, "Genpop - Exit")


#define ACCESS_SECURITY_EDIT 306
Expand Down Expand Up @@ -431,3 +431,8 @@ STANDARD_ACCESS_DATUM(ACCESS_MISC_CASHCRATE, misc/cashcrate, "Cash Crates")

#define ACCESS_SPECIAL_SILICONS 199
STANDARD_ACCESS_DATUM(ACCESS_SPECIAL_SILICONS, special/silicons, "Synthetic")

// Network

#define ACCESS_NETWORK 404
STANDARD_ACCESS_DATUM(ACCESS_NETWORK, misc/network, "Network")
11 changes: 6 additions & 5 deletions code/__DEFINES/callbacks.dm
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,15 @@
} \
else { \
ASYNC { \
call(proc_owner, proc_path)(##proc_arguments); \
/* Written with `0 ||` to avoid the compiler seeing call("string"), and thinking it's a deprecated DLL */ \
call(0 || proc_owner, proc_path)(##proc_arguments); \
}; \
}

/// Varset callback for a list
#define VARSET_LIST_CALLBACK(target, var_name, var_value) CALLBACK(GLOBAL_PROC, /proc/___callbackvarset, ##target, ##var_name, ##var_value)
#define VARSET_LIST_CALLBACK(target, var_name, var_value) CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(___callbackvarset), ##target, ##var_name, ##var_value)
/// Varset callback for a datum
#define VARSET_CALLBACK(datum, var, var_value) CALLBACK(GLOBAL_PROC, /proc/___callbackvarset, ##datum, NAMEOF(##datum, ##var), ##var_value)
#define VARSET_CALLBACK(datum, var, var_value) CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(___callbackvarset), ##datum, NAMEOF(##datum, ##var), ##var_value)
/// Create a varset timer
#define VARSET_IN(datum, var, var_value, time) addtimer(VARSET_CALLBACK(datum, var, var_value), time)

Expand All @@ -37,9 +38,9 @@
datum.vars[var_name] = var_value

/// flick() callback
#define FLICK_CALLBACK(state, target) CALLBACK(GLOBAL_PROC, /proc/___callbackflick, target, state)
#define FLICK_CALLBACK(state, target) CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(___callbackflick), target, state)
/// flick() using timer
#define FLICK_IN(state, target, time) addtimer(CALLBACK(GLOBAL_PROC, /proc/___callbackflick, target, state), time)
#define FLICK_IN(state, target, time) addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(___callbackflick), target, state), time)

/proc/___callbackflick(target, state)
flick(target, state)
30 changes: 30 additions & 0 deletions code/__DEFINES/loadout.dm
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,33 @@
#define LOADOUT_CATEGORY_UNIFORMS "Uniforms and Casual Dress"
#define LOADOUT_CATEGORY_UTILITY "Utility"
#define LOADOUT_CATEGORY_XENOWEAR "Xenowear"

/// allow customizing name
#define LOADOUT_CUSTOMIZE_NAME (1<<0)
/// allow customizing desc
#define LOADOUT_CUSTOMIZE_DESC (1<<1)
/// allow customizing color
#define LOADOUT_CUSTOMIZE_COLOR (1<<2)

DEFINE_BITFIELD(loadout_customize_flags, list(
BITFIELD(LOADOUT_CUSTOMIZE_NAME),
BITFIELD(LOADOUT_CUSTOMIZE_DESC),
BITFIELD(LOADOUT_CUSTOMIZE_COLOR),
))

// *DO NOT RAISE THIS. This is for performance reasons.* //
#define LOADOUT_MAX_SLOTS 10
#define LOADOUT_SLOT_NAME_LENGTH 32
#define LOADOUT_MAX_ITEMS 30
/// Used in chargen for accessory loadout limit.
#define LOADOUT_MAX_COST 20
/// Used in chargen for accessory loadout limit on holidays.
#define LOADOUT_MAX_COST_HOLIDAY_SPAM 30

#define LOADOUT_SLOTDATA_NAME "name"
#define LOADOUT_SLOTDATA_ENTRIES "entries"

#define LOADOUT_ENTRYDATA_RENAME "rename"
#define LOADOUT_ENTRYDATA_REDESC "redesc"
#define LOADOUT_ENTRYDATA_RECOLOR "recolor"
#define LOADOUT_ENTRYDATA_TWEAKS "tweaks"
8 changes: 4 additions & 4 deletions code/__DEFINES/misc.dm
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,6 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s
// Some arbitrary defines to be used by self-pruning global lists. (see master_controller)
/// Used to trigger removal from a processing list.
#define PROCESS_KILL 26
/// Used in chargen for accessory loadout limit.
#define MAX_GEAR_COST 20
/// Used in chargen for accessory loadout limit on holidays.
#define MAX_GEAR_COST_HOLIDAY_SPAM 30

// Shuttles.

Expand Down Expand Up @@ -171,6 +167,10 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s
#define MAX_NTNET_LOGS 500
#define MIN_NTNET_LOGS 10

#define NTOS_EMAIL_NONEWMESSAGES 0
#define NTOS_EMAIL_NOTIFALREADY 1
#define NTOS_EMAIL_NEWMESSAGE 2


// Special return values from bullet_act(). Positive return values are already used to indicate the blocked level of the projectile.
/// If the projectile should continue flying after calling bullet_act()
Expand Down
4 changes: 4 additions & 0 deletions code/__DEFINES/preferences/data_keys_character.dm
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
#define CHARACTER_DATA_CULTURE "lore_culture"
#define CHARACTER_DATA_LANGUAGES "languages"

//? Loadouts
#define CHARACTER_DATA_LOADOUT "loadout"
#define CHARACTER_DATA_LOADOUT_SLOT "loadout_slot"

//? Species
#define CHARACTER_DATA_REAL_SPECIES "real_species"
#define CHARACTER_DATA_CHAR_SPECIES "char_species"
Expand Down
13 changes: 11 additions & 2 deletions code/__DEFINES/preferences/procs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,21 @@
#define PREF_COPY_TO_FOR_RENDER (1<<3)
/// ignore species checks; you should check the species yourself!
#define PREF_COPY_TO_NO_CHECK_SPECIES (1<<4)
/// ignore most loadout restrictions, and spawn loadout. do not use in spawn procs, SSjob/SSticker will do it instead!
#define PREF_COPY_TO_UNRESTRICTED_LOADOUT (1<<5)
/// ignore loadout role checks
#define PREF_COPY_TO_LOADOUT_IGNORE_ROLE (1<<5)
/// ignore all other loadout checks but whitelists
#define PREF_COPY_TO_LOADOUT_IGNORE_CHECKS (1<<6)
/// ignore loadout whitelist checks
#define PREF_COPY_TO_LOADOUT_IGNORE_WHITELIST (1<<7)
/// avoid making messages like "equipping x to you in loadout"
#define PREF_COPY_TO_SILENT (1<<8)

/// DO NOT update icons
#define PREF_COPY_TO_DO_NOT_RENDER (1<<23)

/// ignore most loadout restrictions, and spawn loadout. do not use in spawn procs, SSjob/SSticker will do it instead!
#define PREF_COPY_TO_UNRESTRICTED_LOADOUT (PREF_COPY_TO_LOADOUT_IGNORE_ROLE | PREF_COPY_TO_LOADOUT_IGNORE_CHECKS | PREF_COPY_TO_LOADOUT_IGNORE_WHITELIST)

/// helper
#define PREF_COPYING_TO_CHECK_IS_SPAWNING(flags) (flags & (PREF_COPY_TO_FOR_ROUNDSTART | PREF_COPY_TO_FOR_LATEJOIN | PREF_COPY_TO_FOR_GHOSTROLE))

2 changes: 1 addition & 1 deletion code/__DEFINES/preferences/savefiles.dm
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@
//* no reason to need it for global loading, and global migrations
//* should be low level anyways
#define CHARACTER_VERSION_MIN -1
#define CHARACTER_VERSION_MAX 4
#define CHARACTER_VERSION_MAX 5
/// what nulled version fields are considered; this basically makes them go through all migrations
#define CHARACTER_VERSION_LEGACY 0
6 changes: 3 additions & 3 deletions code/__DEFINES/qdel.dm
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@
#define QDESTROYING(X) (!X || X.gc_destroyed == GC_CURRENTLY_BEING_QDELETED)

//Qdel helper macros.
#define QDEL_IN(item, time) addtimer(CALLBACK(GLOBAL_PROC, .proc/qdel, item), time, TIMER_STOPPABLE)
#define QDEL_IN_CLIENT_TIME(item, time) addtimer(CALLBACK(GLOBAL_PROC, .proc/qdel, item), time, TIMER_STOPPABLE | TIMER_CLIENT_TIME)
#define QDEL_IN(item, time) addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(qdel), item), time, TIMER_STOPPABLE)
#define QDEL_IN_CLIENT_TIME(item, time) addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(qdel), item), time, TIMER_STOPPABLE | TIMER_CLIENT_TIME)
#define QDEL_NULL(item) qdel(item); item = null
#define QDEL_NULL_LIST QDEL_LIST_NULL
#define QDEL_LIST_NULL(x) if(x) { for(var/y in x) { qdel(y) } ; x = null }
#define QDEL_LIST(L) if(L) { for(var/I in L) qdel(I); L.Cut(); }
#define QDEL_LIST_IN(L, time) addtimer(CALLBACK(GLOBAL_PROC, .proc/______qdel_list_wrapper, L), time, TIMER_STOPPABLE)
#define QDEL_LIST_IN(L, time) addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(______qdel_list_wrapper), L), time, TIMER_STOPPABLE)
#define QDEL_LIST_ASSOC(L) if(L) { for(var/I in L) { qdel(L[I]); qdel(I); } L.Cut(); }
#define QDEL_LIST_ASSOC_VAL(L) if(L) { for(var/I in L) qdel(L[I]); L.Cut(); }

Expand Down
2 changes: 1 addition & 1 deletion code/__DEFINES/rendering/zmimic.dm
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#define TURF_IS_MIMICKING(T) (isturf(T) && (T:mz_flags & MZ_MIMIC_BELOW))
#define CHECK_OO_EXISTENCE(OO) if (OO && !MOVABLE_IS_ON_ZTURF(OO) && !OO.destruction_timer) { OO.destruction_timer = addtimer(CALLBACK(OO, /datum/.proc/qdel_self), 10 SECONDS, TIMER_STOPPABLE); }
#define CHECK_OO_EXISTENCE(OO) if (OO && !MOVABLE_IS_ON_ZTURF(OO) && !OO.destruction_timer) { OO.destruction_timer = addtimer(CALLBACK(OO, TYPE_PROC_REF(/datum, qdel_self)), 10 SECONDS, TIMER_STOPPABLE); }
#define UPDATE_OO_IF_PRESENT CHECK_OO_EXISTENCE(bound_overlay); if (bound_overlay) { update_above(); }

// I do not apologize.
Expand Down
File renamed without changes.
1 change: 1 addition & 0 deletions code/__DEFINES/spans.dm
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@
#define SPAN_SUPPRADIO(str) ("<span class='suppradio'>[str]</span>")
#define SPAN_SYNDRADIO(str) ("<span class='syndradio'>[str]</span>")
#define SPAN_TAPE_RECORDER(str) ("<span class='tape_recorder'>[str]</span>")
#define SPAN_TINY(str) ("<span class='tiny'>[str]</span>")
#define SPAN_TINYNOTICE(str) ("<span class='tinynotice'>[str]</span>")
#define SPAN_TINYNOTICEITAL(str) ("<span class='tinynoticeital'>[str]</span>")
#define SPAN_UNCONSCIOUS(str) ("<span class='unconscious'>[str]</span>")
Expand Down
4 changes: 2 additions & 2 deletions code/__HELPERS/_global_objects.dm
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
var/datum/gear_tweak/color/gear_tweak_free_color_choice = new()
var/datum/loadout_tweak/color/gear_tweak_free_color_choice = new()

var/datum/gear_tweak/collar_tag/gear_tweak_collar_tag = new()
var/datum/loadout_tweak/collar_tag/gear_tweak_collar_tag = new()
2 changes: 1 addition & 1 deletion code/__HELPERS/_lists_tg.dm
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ This actually tests if they have the same entries and values.
return tim_sort(L, order >= 0 ? /proc/cmp_records_asc : /proc/cmp_records_dsc)

//any value in a list
/proc/sortList(list/L, cmp=/proc/cmp_text_asc)
/proc/sortList(list/L, cmp= GLOBAL_PROC_REF(cmp_text_asc))
return tim_sort(L.Copy(), cmp)

//uses sortList() but uses the var's name specifically. This should probably be using mergeAtom() instead
Expand Down
4 changes: 4 additions & 0 deletions code/__HELPERS/_logging.dm
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,10 @@ GLOBAL_LIST_INIT(testing_global_profiler, list("_PROFILE_NAME" = "Global"))
if (config_legacy.log_emote)
WRITE_LOG(GLOB.world_game_log, "SUBTLER: [speaker.simple_info_line()]: [html_decode(text)]")

/proc/log_subtle_vore(text, mob/speaker)
if (config_legacy.log_emote)
WRITE_LOG(GLOB.world_game_log, "SUBTLE_VORE: [speaker.simple_info_line()]: [html_decode(text)]")

/proc/log_aooc(text, client/user)
if (config_legacy.log_ooc)
WRITE_LOG(GLOB.world_game_log, "AOOC: [user.simple_info_line()]: [html_decode(text)]")
Expand Down
4 changes: 2 additions & 2 deletions code/__HELPERS/animations.dm
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

/proc/fade_out(image/I, list/show_to)
animate(I, alpha = 0, time = 0.5 SECONDS, easing = EASE_IN)
addtimer(CALLBACK(GLOBAL_PROC, .proc/remove_image_from_clients, I, show_to), 0.5 SECONDS)
addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(remove_image_from_clients), I, show_to), 0.5 SECONDS)

/proc/animate_speech_bubble(image/I, list/show_to, duration)
var/matrix/M = matrix()
Expand All @@ -11,7 +11,7 @@
for(var/client/C in show_to)
C.images += I
animate(I, transform = 0, alpha = 255, time = 0.2 SECONDS, easing = EASE_IN)
addtimer(CALLBACK(GLOBAL_PROC, .proc/fade_out, I, show_to), (duration - 0.5 SECONDS))
addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(fade_out), I, show_to), (duration - 0.5 SECONDS))

/proc/animate_receive_damage(atom/A)
var/pixel_x_diff = rand(-2,2)
Expand Down
4 changes: 2 additions & 2 deletions code/__HELPERS/areas.dm
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
for(var/area/A in world)
GLOB.sortedAreas.Add(A)

tim_sort(GLOB.sortedAreas, /proc/cmp_name_asc)
tim_sort(GLOB.sortedAreas, GLOBAL_PROC_REF(cmp_name_asc))
setupTeleportLocs() // shitcode patch to make vorecode work until we get rid of this shit meme or refactor it entirely

/area/proc/addSorted()
GLOB.sortedAreas.Add(src)
tim_sort(GLOB.sortedAreas, /proc/cmp_name_asc)
tim_sort(GLOB.sortedAreas, GLOBAL_PROC_REF(cmp_name_asc))

//Takes: Area type as a text string from a variable.
//Returns: Instance for the area in the world.
Expand Down
2 changes: 1 addition & 1 deletion code/__HELPERS/files/client_io.dm
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ GLOBAL_VAR_INIT(fileaccess_timer, 0)
var/list/choices = flist(path)
if(path != root)
choices.Insert(1,"/")
tim_sort(choices, /proc/cmp_text_asc)
tim_sort(choices, GLOBAL_PROC_REF(cmp_text_asc))

var/choice = input(src,"Choose a file to access:","Download",null) as null|anything in choices
switch(choice)
Expand Down
2 changes: 1 addition & 1 deletion code/__HELPERS/lists/asset_sorted.dm
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/// Runtimes if the passed in list is not sorted.
/proc/assert_sorted(list/list, name, cmp = /proc/cmp_numeric_asc)
/proc/assert_sorted(list/list, name, cmp = GLOBAL_PROC_REF(cmp_numeric_asc))
var/last_value = list[1]

for (var/index in 2 to list.len)
Expand Down
4 changes: 2 additions & 2 deletions code/__HELPERS/misc/sonar.dm
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@
C.images += images
for(var/image/I as anything in images)
animate(I, alpha = 255, time = fadein, easing = SINE_EASING)
addtimer(CALLBACK(src, .proc/remove_sonar_images, images, clients, fadeout), sustain, TIMER_CLIENT_TIME)
addtimer(CALLBACK(src, PROC_REF(remove_sonar_images), images, clients, fadeout), sustain, TIMER_CLIENT_TIME)
/datum/controller/subsystem/sonar/proc/remove_sonar_images(list/image/images, list/client/clients, time)
for(var/image/I as anything in images)
animate(I, alpha = 0, time = time, easing = SINE_EASING)
addtimer(CALLBACK(src, .proc/dispose_sonar_images, images, clients), time, TIMER_CLIENT_TIME)
addtimer(CALLBACK(src, PROC_REF(dispose_sonar_images), images, clients), time, TIMER_CLIENT_TIME)
/datum/controller/subsystem/sonar/proc/dispose_sonar_images(list/image/images, list/client/clients)
for(var/client/C in clients)
Expand Down
2 changes: 1 addition & 1 deletion code/__HELPERS/path.dm
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@
/datum/pathfind/New(atom/movable/caller, atom/goal, id, max_distance, mintargetdist, simulated_only, avoid)
src.caller = caller
end = get_turf(goal)
open = new /datum/heap(/proc/HeapPathWeightCompare)
open = new /datum/heap(GLOBAL_PROC_REF(HeapPathWeightCompare))
sources = new()
src.id = id
src.max_distance = max_distance
Expand Down
4 changes: 2 additions & 2 deletions code/__HELPERS/piping_colors_lists.dm
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ GLOBAL_LIST_INIT(pipe_colors_ordered, tim_sort(list(
PIPE_COLOR_PURPLE = 2,
PIPE_COLOR_RED = 3,
PIPE_COLOR_YELLOW = 4
), /proc/cmp_text_asc))
), GLOBAL_PROC_REF(cmp_text_asc)))

///Names shown in the examine for every colored atmos component
GLOBAL_LIST_INIT(pipe_color_name, tim_sort(list(
Expand All @@ -51,4 +51,4 @@ GLOBAL_LIST_INIT(pipe_color_name, tim_sort(list(
PIPE_COLOR_YELLOW = "yellow",
PIPE_COLOR_BROWN = "brown",
PIPE_COLOR_PURPLE = "purple"
), /proc/cmp_text_asc))
), GLOBAL_PROC_REF(cmp_text_asc)))
48 changes: 48 additions & 0 deletions code/__HELPERS/sanitize/color.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
* probably, because the matrix isn't sanitized for numbers, just that it's the right length of list.
*/
/proc/sanitize_probably_a_byond_color(what, default = "#ffffff")
if(istext(what))
return sanitize_hexcolor(what, 6, 1, default)
if(islist(what))
var/list/cmatrix = what
switch(length(cmatrix))
if(9, 12, 16, 20)
return cmatrix
return default
return default

/proc/sanitize_hexcolor(color, desired_format=3, include_crunch=0, default)
var/crunch = include_crunch ? "#" : ""
if(!istext(color))
color = ""

var/start = 1 + (text2ascii(color, 1) == 35)
var/len = length(color)
var/char = ""
// RRGGBB -> RGB but awful
var/convert_to_shorthand = desired_format == 3 && length_char(color) > 3

. = ""
var/i = start
while(i <= len)
char = color[i]
switch(text2ascii(char))
if(48 to 57) //numbers 0 to 9
. += char
if(97 to 102) //letters a to f
. += char
if(65 to 70) //letters A to F
. += lowertext(char)
else
break
i += length(char)
if(convert_to_shorthand && i <= len) //skip next one
i += length(color[i])

if(length_char(.) != desired_format)
if(default)
return default
return crunch + repeat_string(desired_format, "0")

return crunch + .
Loading

0 comments on commit 40b899f

Please sign in to comment.