mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-25 22:19:30 +01:00
Adds a color matrix layer to GAGS (#63957)
* Adds a color matrix layer to GAGS * Fixes default row value * Passes along the last viable icon for color matrix use * Removes stray nocache reference
This commit is contained in:
@@ -231,20 +231,20 @@
|
||||
fcopy(icon_output, "tmp/gags_debug_output.dmi")
|
||||
|
||||
/// Actually create the icon and color it in, handles caching
|
||||
/datum/greyscale_config/proc/Generate(color_string)
|
||||
/datum/greyscale_config/proc/Generate(color_string, icon/last_external_icon)
|
||||
var/key = color_string
|
||||
var/icon/new_icon = icon_cache[key]
|
||||
if(new_icon)
|
||||
return icon(new_icon)
|
||||
|
||||
var/icon/icon_bundle = GenerateBundle(color_string)
|
||||
var/icon/icon_bundle = GenerateBundle(color_string, last_external_icon=last_external_icon)
|
||||
icon_bundle = fcopy_rsc(icon_bundle)
|
||||
icon_cache[key] = icon_bundle
|
||||
var/icon/output = icon(icon_bundle)
|
||||
return output
|
||||
|
||||
/// Handles the actual icon manipulation to create the spritesheet
|
||||
/datum/greyscale_config/proc/GenerateBundle(list/colors, list/render_steps)
|
||||
/datum/greyscale_config/proc/GenerateBundle(list/colors, list/render_steps, icon/last_external_icon)
|
||||
if(!istype(colors))
|
||||
colors = SSgreyscale.ParseColorString(colors)
|
||||
if(length(colors) != expected_colors)
|
||||
@@ -255,7 +255,7 @@
|
||||
var/list/icon_state_steps
|
||||
if(render_steps)
|
||||
icon_state_steps = render_steps[icon_state] = list()
|
||||
var/icon/generated_icon = GenerateLayerGroup(colors, icon_states[icon_state], icon_state_steps)
|
||||
var/icon/generated_icon = GenerateLayerGroup(colors, icon_states[icon_state], icon_state_steps, last_external_icon)
|
||||
// We read a pixel to force the icon to be fully generated before we let it loose into the world
|
||||
// I hate this
|
||||
generated_icon.GetPixel(1, 1)
|
||||
@@ -271,15 +271,15 @@
|
||||
return icon_bundle
|
||||
|
||||
/// Internal recursive proc to handle nested layer groups
|
||||
/datum/greyscale_config/proc/GenerateLayerGroup(list/colors, list/group, list/render_steps)
|
||||
/datum/greyscale_config/proc/GenerateLayerGroup(list/colors, list/group, list/render_steps, icon/last_external_icon)
|
||||
var/icon/new_icon
|
||||
for(var/datum/greyscale_layer/layer as anything in group)
|
||||
var/icon/layer_icon
|
||||
if(islist(layer))
|
||||
layer_icon = GenerateLayerGroup(colors, layer, render_steps)
|
||||
layer_icon = GenerateLayerGroup(colors, layer, render_steps, new_icon || last_external_icon)
|
||||
layer = layer[1] // When there are multiple layers in a group like this we use the first one's blend mode
|
||||
else
|
||||
layer_icon = layer.Generate(colors, render_steps)
|
||||
layer_icon = layer.Generate(colors, render_steps, new_icon || last_external_icon)
|
||||
|
||||
if(!new_icon)
|
||||
new_icon = layer_icon
|
||||
|
||||
@@ -31,6 +31,27 @@
|
||||
new_values += new_value
|
||||
return new_values
|
||||
|
||||
/datum/json_reader/color_matrix/ReadJson(list/value)
|
||||
if(!istype(value))
|
||||
CRASH("Expected a list but got [value]")
|
||||
if(length(value) > 5 || length(value) < 4)
|
||||
CRASH("Color matrix must contain 4 or 5 rows")
|
||||
var/list/new_values = list()
|
||||
for(var/list/row in value)
|
||||
var/list/interpreted_row = list()
|
||||
if(!istype(row) || length(row) != 4)
|
||||
stack_trace("Expected list to contain further row lists with exactly 4 entries")
|
||||
interpreted_row = list(0, 0, 0, 0)
|
||||
continue
|
||||
for(var/number in row)
|
||||
if(!isnum(number))
|
||||
stack_trace("Each color matrix row must only contain numbers")
|
||||
interpreted_row += 0
|
||||
else
|
||||
interpreted_row += number
|
||||
new_values += interpreted_row
|
||||
return new_values
|
||||
|
||||
/datum/json_reader/blend_mode
|
||||
var/static/list/blend_modes = list(
|
||||
"add" = ICON_ADD,
|
||||
|
||||
@@ -66,18 +66,19 @@
|
||||
|
||||
/// Used to actualy create the layer using the given colors
|
||||
/// Do not override, use InternalGenerate instead
|
||||
/datum/greyscale_layer/proc/Generate(list/colors, list/render_steps)
|
||||
/datum/greyscale_layer/proc/Generate(list/colors, list/render_steps, icon/new_icon)
|
||||
var/list/processed_colors = list()
|
||||
for(var/i in color_ids)
|
||||
if(isnum(i))
|
||||
processed_colors += colors[i]
|
||||
else
|
||||
processed_colors += i
|
||||
return InternalGenerate(processed_colors, render_steps)
|
||||
var/icon/copy_of_new_icon = icon(new_icon) // Layers shouldn't be modifying it directly, this is just for them to reference
|
||||
return InternalGenerate(processed_colors, render_steps, copy_of_new_icon)
|
||||
|
||||
/// Override this to implement layers.
|
||||
/// The colors var will only contain colors that this layer is configured to use.
|
||||
/datum/greyscale_layer/proc/InternalGenerate(list/colors, list/render_steps)
|
||||
/datum/greyscale_layer/proc/InternalGenerate(list/colors, list/render_steps, icon/new_icon)
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
// Subtypes
|
||||
@@ -103,11 +104,25 @@
|
||||
. = ..()
|
||||
required_values[NAMEOF(src, icon_state)] = /datum/json_reader/text
|
||||
|
||||
/datum/greyscale_layer/icon_state/InternalGenerate(list/colors, list/render_steps)
|
||||
/datum/greyscale_layer/icon_state/InternalGenerate(list/colors, list/render_steps, icon/new_icon)
|
||||
. = ..()
|
||||
var/icon/new_icon = icon(icon)
|
||||
var/icon/generated_icon = icon(icon)
|
||||
if(length(colors))
|
||||
new_icon.Blend(colors[1], ICON_MULTIPLY)
|
||||
generated_icon.Blend(colors[1], ICON_MULTIPLY)
|
||||
return generated_icon
|
||||
|
||||
/// A layer to modify the previous layer's colors with a color matrix
|
||||
/datum/greyscale_layer/color_matrix
|
||||
layer_type = "color_matrix"
|
||||
var/list/color_matrix
|
||||
|
||||
/datum/greyscale_layer/color_matrix/GetExpectedValues(list/required_values, list/optional_values)
|
||||
. = ..()
|
||||
required_values[NAMEOF(src, color_matrix)] = /datum/json_reader/color_matrix
|
||||
|
||||
/datum/greyscale_layer/color_matrix/InternalGenerate(list/colors, list/render_steps, icon/new_icon)
|
||||
. = ..()
|
||||
new_icon.MapColors(arglist(color_matrix))
|
||||
return new_icon
|
||||
|
||||
/// A layer created by using another greyscale icon's configuration
|
||||
@@ -130,12 +145,12 @@
|
||||
if(!reference_type.icon_states[icon_state])
|
||||
CRASH("[src] expects icon_state '[icon_state]' but referenced configuration '[reference_type]' does not have it.")
|
||||
|
||||
/datum/greyscale_layer/reference/InternalGenerate(list/colors, list/render_steps)
|
||||
/datum/greyscale_layer/reference/InternalGenerate(list/colors, list/render_steps, icon/new_icon)
|
||||
var/icon/generated_icon
|
||||
if(render_steps)
|
||||
var/list/reference_data = list()
|
||||
generated_icon = reference_type.GenerateBundle(colors, reference_data)
|
||||
generated_icon = reference_type.GenerateBundle(colors, reference_data, new_icon)
|
||||
render_steps += reference_data[icon_state]
|
||||
else
|
||||
generated_icon = reference_type.Generate(colors.Join())
|
||||
generated_icon = reference_type.Generate(colors.Join(), new_icon)
|
||||
return icon(generated_icon, icon_state)
|
||||
|
||||
Reference in New Issue
Block a user