Skip to content

Instantly share code, notes, and snippets.

@LemonInTheDark
Last active December 2, 2024 08:55
Show Gist options
  • Select an option

  • Save LemonInTheDark/06677d4cf05803c4526721f09d8068f7 to your computer and use it in GitHub Desktop.

Select an option

Save LemonInTheDark/06677d4cf05803c4526721f09d8068f7 to your computer and use it in GitHub Desktop.
Sample code to recursively apply a color filter to an appearance, respecting appearance flags/rendering rules
/*
Problem statment:
We want to apply color filters AS IF they were a color var
this means they need to be recursively applied
fortunately KEEP_TOGETHER removes the need to apply a filter and thus modify the appearance,
UP UNTIL we hit something that cannot be KEPT_TOGETHER (KEEP_APART, on a different plane, etc)
if this happens we need to recursively modify up the list. life is pain
*/
/// recursively applies a color filter to a passed in mutable appearance/atom, returns the modified appearance
/proc/color_filter_appearance_recursive(mutable_appearance/filter, filter_to_apply, mutable_appearance/parent)
var/parent_keep_together = parent.appearance_flags & KEEP_TOGETHER
if((filter.appearance_flags & RESET_COLOR) && (!parent_keep_together || filter.appearance_flags & KEEP_APART))
return filter
return _color_filter_appearance_recursive(filter.appearance, filter_to_apply, parent_keep_together, parent.plane)
/proc/_color_filter_appearance_recursive(mutable_appearance/filter, filter_to_apply, parent_keep_together, parent_plane)
var/drawing_keep_together = parent_keep_together
var/drawing_plane = parent_plane
var/draw_filter = !parent_keep_together
// if the planes are different then we revoke keep_together
// and start tracking the new plane
if(filter.plane != drawing_plane && filter.plane != FLOAT_PLANE)
drawing_plane = filter.plane
drawing_keep_together = FALSE
draw_filter = TRUE
// If KEEP_APART is on we don't want to draw with our parent
if(drawing_keep_together && filter.appearance_flags & KEEP_APART)
drawing_keep_together = FALSE
draw_filter = TRUE
// If KEEP_TOGETHER is on our children should draw with us
if(!drawing_keep_together && filter.appearance_flags & KEEP_TOGETHER)
drawing_keep_together = TRUE
// copy overlays list so we can modify it
var/list/overlays_to_modify = filter.overlays.Copy()
// iterate overlays to apply to children
for(var/overlay_index in 1 to length(overlays_to_modify))
// reminder this is still fake and actually a static appearance
var/mutable_appearance/child_appearance = overlays_to_modify[overlay_index]
// if we want to reset color and doing so is valid stop looking and ignore us
if((child_appearance.appearance_flags & RESET_COLOR) && (!drawing_keep_together || child_appearance.appearance_flags & KEEP_APART))
continue
overlays_to_modify[overlay_index] = _color_filter_appearance_recursive(child_appearance, filter_to_apply, drawing_keep_together, drawing_plane)
// same for underlays
var/something_changed = FALSE
if(!(overlays_to_modify ~= filter.overlays))
something_changed = TRUE
// Same for underlays
// is THIS APPEARANCE drawing apart from its parent? (is keep_together inactive, are we drawing with KEEP_APART, is our plane different)
if(draw_filter)
something_changed = TRUE
if(!something_changed)
return filter
// copy passed appearance to a mutable one (the typing is a lie, sorry)
var/mutable_appearance/modify = new(filter)
if(draw_filter)
// Insert our new filter FIRST (we want to behave like the color var)
var/list/existing_filters = modify.filters.Copy()
modify.filters = list(filter_to_apply) + existing_filters
modify.overlays = overlays_to_modify // should be basically free no reason to guard check
// same for underlays
return modify
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment