diff --git a/code/__HELPERS/icon_smoothing.dm b/code/__HELPERS/icon_smoothing.dm index e001e4c30b7..cbe3fc8ca6a 100644 --- a/code/__HELPERS/icon_smoothing.dm +++ b/code/__HELPERS/icon_smoothing.dm @@ -54,45 +54,6 @@ DEFINE_BITFIELD(smoothing_junction, list( #define DEFAULT_UNDERLAY_ICON_STATE "plating" -#define SET_ADJ_IN_DIR(source, junction, direction, direction_flag) \ - do { \ - var/turf/neighbor = get_step(source, direction); \ - if(!neighbor) { \ - if(source.smoothing_flags & SMOOTH_BORDER) { \ - junction |= direction_flag; \ - }; \ - }; \ - else { \ - if(!isnull(neighbor.smoothing_groups)) { \ - for(var/target in source.canSmoothWith) { \ - if(!(source.canSmoothWith[target] & neighbor.smoothing_groups[target])) { \ - continue; \ - }; \ - junction |= direction_flag; \ - break; \ - }; \ - }; \ - if(!(junction & direction_flag) && source.smoothing_flags & SMOOTH_OBJ) { \ - for(var/obj/thing in neighbor) { \ - if(!thing.anchored || isnull(thing.smoothing_groups)) { \ - continue; \ - }; \ - for(var/target in source.canSmoothWith) { \ - if(!(source.canSmoothWith[target] & thing.smoothing_groups[target])) { \ - continue; \ - }; \ - junction |= direction_flag; \ - break; \ - }; \ - if(junction & direction_flag) { \ - break; \ - }; \ - }; \ - }; \ - }; \ - } while(FALSE) - - ///Scans all adjacent turfs to find targets to smooth with. /atom/proc/calculate_adjacencies() . = NONE @@ -165,8 +126,6 @@ DEFINE_BITFIELD(smoothing_junction, list( else CRASH("smooth_icon called for [src] with smoothing_flags == [smoothing_flags]") SEND_SIGNAL(src, COMSIG_ATOM_SMOOTHED_ICON) - update_appearance(~UPDATE_SMOOTHING) - /atom/proc/corners_diagonal_smooth(adjacencies) switch(adjacencies) @@ -319,7 +278,6 @@ DEFINE_BITFIELD(smoothing_junction, list( return NO_ADJ_FOUND - /** * Basic smoothing proc. The atom checks for adjacent directions to smooth with and changes the icon_state based on that. * @@ -329,8 +287,48 @@ DEFINE_BITFIELD(smoothing_junction, list( /atom/proc/bitmask_smooth() var/new_junction = NONE + // cache for sanic speed + var/canSmoothWith = src.canSmoothWith + + var/smooth_border = (smoothing_flags & SMOOTH_BORDER) + var/smooth_obj = (smoothing_flags & SMOOTH_OBJ) + + #define SET_ADJ_IN_DIR(direction, direction_flag) \ + set_adj_in_dir: { \ + do { \ + var/turf/neighbor = get_step(src, direction); \ + if(neighbor) { \ + var/neighbor_smoothing_groups = neighbor.smoothing_groups; \ + if(neighbor_smoothing_groups) { \ + for(var/target in canSmoothWith) { \ + if(canSmoothWith[target] & neighbor_smoothing_groups[target]) { \ + new_junction |= direction_flag; \ + break set_adj_in_dir; \ + }; \ + }; \ + }; \ + if(smooth_obj) { \ + for(var/atom/movable/thing as anything in neighbor) { \ + var/thing_smoothing_groups = thing.smoothing_groups; \ + if(!thing.anchored || isnull(thing_smoothing_groups)) { \ + continue; \ + }; \ + for(var/target in canSmoothWith) { \ + if(canSmoothWith[target] & thing_smoothing_groups[target]) { \ + new_junction |= direction_flag; \ + break set_adj_in_dir; \ + }; \ + }; \ + }; \ + }; \ + } else if (smooth_border) { \ + new_junction |= direction_flag; \ + }; \ + } while(FALSE) \ + } + for(var/direction in GLOB.cardinals) //Cardinal case first. - SET_ADJ_IN_DIR(src, new_junction, direction, direction) + SET_ADJ_IN_DIR(direction, direction) if(!(new_junction & (NORTH|SOUTH)) || !(new_junction & (EAST|WEST))) set_smoothed_icon_state(new_junction) @@ -338,20 +336,22 @@ DEFINE_BITFIELD(smoothing_junction, list( if(new_junction & NORTH_JUNCTION) if(new_junction & WEST_JUNCTION) - SET_ADJ_IN_DIR(src, new_junction, NORTHWEST, NORTHWEST_JUNCTION) + SET_ADJ_IN_DIR(NORTHWEST, NORTHWEST_JUNCTION) if(new_junction & EAST_JUNCTION) - SET_ADJ_IN_DIR(src, new_junction, NORTHEAST, NORTHEAST_JUNCTION) + SET_ADJ_IN_DIR(NORTHEAST, NORTHEAST_JUNCTION) if(new_junction & SOUTH_JUNCTION) if(new_junction & WEST_JUNCTION) - SET_ADJ_IN_DIR(src, new_junction, SOUTHWEST, SOUTHWEST_JUNCTION) + SET_ADJ_IN_DIR(SOUTHWEST, SOUTHWEST_JUNCTION) if(new_junction & EAST_JUNCTION) - SET_ADJ_IN_DIR(src, new_junction, SOUTHEAST, SOUTHEAST_JUNCTION) + SET_ADJ_IN_DIR(SOUTHEAST, SOUTHEAST_JUNCTION) set_smoothed_icon_state(new_junction) + #undef SET_ADJ_IN_DIR + ///Changes the icon state based on the new junction bitmask. Returns the old junction value. /atom/proc/set_smoothed_icon_state(new_junction) @@ -361,36 +361,46 @@ DEFINE_BITFIELD(smoothing_junction, list( /turf/closed/set_smoothed_icon_state(new_junction) - . = ..() - if(smoothing_flags & SMOOTH_DIAGONAL_CORNERS) - switch(new_junction) - if( - NORTH_JUNCTION|WEST_JUNCTION, - NORTH_JUNCTION|EAST_JUNCTION, - SOUTH_JUNCTION|WEST_JUNCTION, - SOUTH_JUNCTION|EAST_JUNCTION, - NORTH_JUNCTION|WEST_JUNCTION|NORTHWEST_JUNCTION, - NORTH_JUNCTION|EAST_JUNCTION|NORTHEAST_JUNCTION, - SOUTH_JUNCTION|WEST_JUNCTION|SOUTHWEST_JUNCTION, - SOUTH_JUNCTION|EAST_JUNCTION|SOUTHEAST_JUNCTION - ) - icon_state = "[base_icon_state]-[smoothing_junction]-d" - if(!fixed_underlay && new_junction != .) // Mutable underlays? - var/junction_dir = reverse_ndir(smoothing_junction) - var/turned_adjacency = REVERSE_DIR(junction_dir) - var/turf/neighbor_turf = get_step(src, turned_adjacency & (NORTH|SOUTH)) - var/mutable_appearance/underlay_appearance = mutable_appearance(layer = TURF_LAYER, offset_spokesman = src, plane = FLOOR_PLANE) + // Avoid calling ..() here to avoid setting icon_state twice, which is expensive given how hot this proc is + . = smoothing_junction + smoothing_junction = new_junction + + if (!(smoothing_flags & SMOOTH_DIAGONAL_CORNERS)) + icon_state = "[base_icon_state]-[smoothing_junction]" + return . + + switch(new_junction) + if( + NORTH_JUNCTION|WEST_JUNCTION, + NORTH_JUNCTION|EAST_JUNCTION, + SOUTH_JUNCTION|WEST_JUNCTION, + SOUTH_JUNCTION|EAST_JUNCTION, + NORTH_JUNCTION|WEST_JUNCTION|NORTHWEST_JUNCTION, + NORTH_JUNCTION|EAST_JUNCTION|NORTHEAST_JUNCTION, + SOUTH_JUNCTION|WEST_JUNCTION|SOUTHWEST_JUNCTION, + SOUTH_JUNCTION|EAST_JUNCTION|SOUTHEAST_JUNCTION, + ) + icon_state = "[base_icon_state]-[smoothing_junction]-d" + if(new_junction == . || fixed_underlay) // Mutable underlays? + return . + + var/junction_dir = reverse_ndir(smoothing_junction) + var/turned_adjacency = REVERSE_DIR(junction_dir) + var/turf/neighbor_turf = get_step(src, turned_adjacency & (NORTH|SOUTH)) + var/mutable_appearance/underlay_appearance = mutable_appearance(layer = TURF_LAYER, offset_spokesman = src, plane = FLOOR_PLANE) + if(!neighbor_turf.get_smooth_underlay_icon(underlay_appearance, src, turned_adjacency)) + neighbor_turf = get_step(src, turned_adjacency & (EAST|WEST)) + + if(!neighbor_turf.get_smooth_underlay_icon(underlay_appearance, src, turned_adjacency)) + neighbor_turf = get_step(src, turned_adjacency) + if(!neighbor_turf.get_smooth_underlay_icon(underlay_appearance, src, turned_adjacency)) - neighbor_turf = get_step(src, turned_adjacency & (EAST|WEST)) - - if(!neighbor_turf.get_smooth_underlay_icon(underlay_appearance, src, turned_adjacency)) - neighbor_turf = get_step(src, turned_adjacency) - - if(!neighbor_turf.get_smooth_underlay_icon(underlay_appearance, src, turned_adjacency)) - if(!get_smooth_underlay_icon(underlay_appearance, src, turned_adjacency)) //if all else fails, ask our own turf - underlay_appearance.icon = DEFAULT_UNDERLAY_ICON - underlay_appearance.icon_state = DEFAULT_UNDERLAY_ICON_STATE - underlays += underlay_appearance + if(!get_smooth_underlay_icon(underlay_appearance, src, turned_adjacency)) //if all else fails, ask our own turf + underlay_appearance.icon = DEFAULT_UNDERLAY_ICON + underlay_appearance.icon_state = DEFAULT_UNDERLAY_ICON_STATE + underlays += underlay_appearance + else + icon_state = "[base_icon_state]-[smoothing_junction]" /turf/open/floor/set_smoothed_icon_state(new_junction) if(broken || burnt) @@ -521,5 +531,3 @@ DEFINE_BITFIELD(smoothing_junction, list( #undef DEFAULT_UNDERLAY_ICON #undef DEFAULT_UNDERLAY_ICON_STATE - -#undef SET_ADJ_IN_DIR diff --git a/code/controllers/subsystem/icon_smooth.dm b/code/controllers/subsystem/icon_smooth.dm index f53d945c422..d19c7f6dad7 100644 --- a/code/controllers/subsystem/icon_smooth.dm +++ b/code/controllers/subsystem/icon_smooth.dm @@ -32,16 +32,13 @@ SUBSYSTEM_DEF(icon_smooth) can_fire = FALSE /datum/controller/subsystem/icon_smooth/Initialize() - smooth_zlevel(1, TRUE) - smooth_zlevel(2, TRUE) - var/list/queue = smooth_queue smooth_queue = list() while(length(queue)) var/atom/smoothing_atom = queue[length(queue)] queue.len-- - if(QDELETED(smoothing_atom) || !(smoothing_atom.smoothing_flags & SMOOTH_QUEUED) || smoothing_atom.z <= 2) + if(QDELETED(smoothing_atom) || !(smoothing_atom.smoothing_flags & SMOOTH_QUEUED) || !smoothing_atom.z) continue smoothing_atom.smooth_icon() CHECK_TICK