Last active
December 2, 2024 08:55
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| 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