diff --git a/code/__HELPERS/icon_smoothing.dm b/code/__HELPERS/icon_smoothing.dm
index 27ec6e7202f..2db8621195d 100644
--- a/code/__HELPERS/icon_smoothing.dm
+++ b/code/__HELPERS/icon_smoothing.dm
@@ -108,11 +108,19 @@
return adjacencies
+//do not use, use queue_smooth(atom)
/proc/smooth_icon(atom/A)
+ if(!A || !A.smooth || !A.z)
+ return
if(QDELETED(A))
return
- if(A && (A.smooth & SMOOTH_TRUE) || (A.smooth & SMOOTH_MORE))
+ if((A.smooth & SMOOTH_TRUE) || (A.smooth & SMOOTH_MORE))
var/adjacencies = calculate_adjacencies(A)
+
+ if(A.smooth & SMOOTH_DIAGONAL)
+ A.diagonal_smooth(adjacencies)
+ else
+ cardinal_smooth(A, adjacencies)
if(A.smooth & SMOOTH_DIAGONAL)
A.diagonal_smooth(adjacencies)
else
@@ -149,12 +157,12 @@
/turf/simulated/wall/diagonal_smooth(adjacencies)
adjacencies = reverse_ndir(..())
if(adjacencies)
- underlays.Cut()
+ var/list/U = list()
if(fixed_underlay)
if(fixed_underlay["space"])
- underlays += image('icons/turf/space.dmi', SPACE_ICON_STATE, layer=TURF_LAYER)
+ U += image('icons/turf/space.dmi', SPACE_ICON_STATE, layer=TURF_LAYER)
else
- underlays += image(fixed_underlay["icon"], fixed_underlay["icon_state"], layer=TURF_LAYER)
+ U += image(fixed_underlay["icon"], fixed_underlay["icon_state"], layer=TURF_LAYER)
else
var/turf/T = get_step(src, turn(adjacencies, 180))
if(T && (T.density || T.smooth))
@@ -163,13 +171,14 @@
T = get_step(src, turn(adjacencies, 225))
if(istype(T, /turf/space) && !istype(T, /turf/space/transit))
- underlays += image('icons/turf/space.dmi', SPACE_ICON_STATE, layer=TURF_LAYER)
+ U += image('icons/turf/space.dmi', SPACE_ICON_STATE, layer=TURF_LAYER)
else if(T && !T.density && !T.smooth)
- underlays += T
+ U += T
else if(baseturf && !initial(baseturf.density) && !initial(baseturf.smooth))
- underlays += image(initial(baseturf.icon), initial(baseturf.icon_state), layer=TURF_LAYER)
+ U += image(initial(baseturf.icon), initial(baseturf.icon_state), layer=TURF_LAYER)
else
- underlays += DEFAULT_UNDERLAY_IMAGE
+ U += DEFAULT_UNDERLAY_IMAGE
+ underlays = U
/proc/cardinal_smooth(atom/A, adjacencies)
//NW CORNER
@@ -224,43 +233,36 @@
else if(adjacencies & N_EAST)
se = "4-e"
+ var/list/New = list()
+
if(A.top_left_corner != nw)
A.overlays -= A.top_left_corner
A.top_left_corner = nw
- A.overlays += nw
+ New += nw
if(A.top_right_corner != ne)
A.overlays -= A.top_right_corner
A.top_right_corner = ne
- A.overlays += ne
+ New += ne
if(A.bottom_right_corner != sw)
A.overlays -= A.bottom_right_corner
A.bottom_right_corner = sw
- A.overlays += sw
+ New += sw
if(A.bottom_left_corner != se)
A.overlays -= A.bottom_left_corner
A.bottom_left_corner = se
- A.overlays += se
+ New += se
-/proc/find_type_in_direction(atom/source, direction, range=1)
- var/x_offset = 0
- var/y_offset = 0
+ if(New.len)
+ A.overlays.Add(New)
- if(direction & NORTH)
- y_offset = range
- else if(direction & SOUTH)
- y_offset -= range
-
- if(direction & EAST)
- x_offset = range
- else if(direction & WEST)
- x_offset -= range
-
- var/turf/target_turf = locate(source.x + x_offset, source.y + y_offset, source.z)
+/proc/find_type_in_direction(atom/source, direction)
+ var/turf/target_turf = get_step(source, direction)
if(!target_turf)
return NULLTURF_BORDER
+
if(source.canSmoothWith)
var/atom/A
if(source.smooth & SMOOTH_MORE)
@@ -287,22 +289,22 @@
//Icon smoothing helpers
-/proc/smooth_icon_neighbors(atom/A)
- for(var/V in orange(1,A))
- var/atom/T = V
- if(T.smooth)
- smooth_icon(T)
-
-/proc/smooth_zlevel(var/zlevel)
+/proc/smooth_zlevel(var/zlevel, now = FALSE)
var/list/away_turfs = block(locate(1, 1, zlevel), locate(world.maxx, world.maxy, zlevel))
for(var/V in away_turfs)
var/turf/T = V
if(T.smooth)
- smooth_icon(T)
+ if(now)
+ smooth_icon(T)
+ else
+ queue_smooth(T)
for(var/R in T)
var/atom/A = R
if(A.smooth)
- smooth_icon(A)
+ if(now)
+ smooth_icon(A)
+ else
+ queue_smooth(A)
/atom/proc/clear_smooth_overlays()
overlays -= top_left_corner
@@ -316,14 +318,16 @@
/atom/proc/replace_smooth_overlays(nw, ne, sw, se)
clear_smooth_overlays()
+ var/list/O = list()
top_left_corner = nw
- overlays += nw
+ O += nw
top_right_corner = ne
- overlays += ne
+ O += ne
bottom_left_corner = sw
- overlays += sw
+ O += sw
bottom_right_corner = se
- overlays += se
+ O += se
+ overlays.Add(O)
/proc/reverse_ndir(ndir)
switch(ndir)
@@ -362,6 +366,21 @@
else
return 0
+//SSicon_smooth
+/proc/queue_smooth_neighbors(atom/A)
+ for(var/V in orange(1,A))
+ var/atom/T = V
+ if(T.smooth)
+ queue_smooth(T)
+
+//SSicon_smooth
+/proc/queue_smooth(atom/A)
+ if(SSicon_smooth)
+ SSicon_smooth.smooth_queue[A] = A
+ SSicon_smooth.can_fire = 1
+ else
+ smooth_icon(A)
+
//Example smooth wall
/turf/simulated/wall/smooth
name = "smooth wall"
diff --git a/code/controllers/subsystem/icon_smooth.dm b/code/controllers/subsystem/icon_smooth.dm
new file mode 100644
index 00000000000..65260e5af55
--- /dev/null
+++ b/code/controllers/subsystem/icon_smooth.dm
@@ -0,0 +1,32 @@
+SUBSYSTEM_DEF(icon_smooth)
+ name = "Icon Smoothing"
+ init_order = INIT_ORDER_ICON_SMOOTHING
+ wait = 1
+ priority = FIRE_PRIOTITY_SMOOTHING
+ flags = SS_TICKER
+
+ var/list/smooth_queue = list()
+
+/datum/controller/subsystem/icon_smooth/fire()
+ while(smooth_queue.len)
+ var/atom/A = smooth_queue[smooth_queue.len]
+ smooth_queue.len--
+ smooth_icon(A)
+ if(MC_TICK_CHECK)
+ return
+ if(!smooth_queue.len)
+ can_fire = 0
+
+/datum/controller/subsystem/icon_smooth/Initialize()
+ smooth_zlevel(1,TRUE)
+ smooth_zlevel(2,TRUE)
+ var/queue = smooth_queue
+ smooth_queue = list()
+ for(var/V in queue)
+ var/atom/A = V
+ if(!A || A.z <= 2)
+ continue
+ smooth_icon(A)
+ CHECK_TICK
+
+ ..()
diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm
index 9dc62b3551e..130a50cac89 100644
--- a/code/game/objects/effects/decals/cleanable.dm
+++ b/code/game/objects/effects/decals/cleanable.dm
@@ -12,13 +12,13 @@
src.icon_state = pick(src.random_icon_states)
create_reagents(100)
if(smooth)
- smooth_icon(src)
- smooth_icon_neighbors(src)
+ queue_smooth(src)
+ queue_smooth_neighbors(src)
..()
/obj/effect/decal/cleanable/Destroy()
if(smooth)
- smooth_icon_neighbors(src)
+ queue_smooth_neighbors(src)
return ..()
/obj/effect/decal/cleanable/attackby(obj/item/W as obj, mob/user as mob,)
diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm
index f74a3b542ca..e38350a0136 100644
--- a/code/game/objects/structures.dm
+++ b/code/game/objects/structures.dm
@@ -32,8 +32,8 @@
..()
if(smooth)
if(ticker && ticker.current_state == GAME_STATE_PLAYING)
- smooth_icon(src)
- smooth_icon_neighbors(src)
+ queue_smooth(src)
+ queue_smooth_neighbors(src)
icon_state = ""
if(climbable)
verbs += /obj/structure/proc/climb_on
@@ -46,7 +46,7 @@
if(smooth)
var/turf/T = get_turf(src)
spawn(0)
- smooth_icon_neighbors(T)
+ queue_smooth_neighbors(T)
return ..()
/obj/structure/proc/climb_on()
diff --git a/code/game/objects/structures/false_walls.dm b/code/game/objects/structures/false_walls.dm
index 31239a5ecb4..98d17d71be9 100644
--- a/code/game/objects/structures/false_walls.dm
+++ b/code/game/objects/structures/false_walls.dm
@@ -82,7 +82,7 @@
if(density)
icon_state = initial(icon_state)
smooth = SMOOTH_TRUE
- smooth_icon(src)
+ queue_smooth(src)
else
icon_state = "fwall_open"
@@ -322,4 +322,4 @@
mineral = /obj/item/stack/sheet/mineral/plastitanium
walltype = /turf/simulated/wall/mineral/plastitanium
smooth = SMOOTH_MORE
- canSmoothWith = list(/turf/simulated/wall/mineral/plastitanium, /obj/machinery/door/airlock/shuttle, /obj/machinery/door/airlock, /obj/structure/window/full/shuttle, /obj/structure/shuttle/engine/heater)
\ No newline at end of file
+ canSmoothWith = list(/turf/simulated/wall/mineral/plastitanium, /obj/machinery/door/airlock/shuttle, /obj/machinery/door/airlock, /obj/structure/window/full/shuttle, /obj/structure/shuttle/engine/heater)
diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm
index 91f348d0106..7554b7ae194 100644
--- a/code/game/objects/structures/tables_racks.dm
+++ b/code/game/objects/structures/tables_racks.dm
@@ -50,8 +50,8 @@
/obj/structure/table/update_icon()
if(smooth && !flipped)
icon_state = ""
- smooth_icon(src)
- smooth_icon_neighbors(src)
+ queue_smooth(src)
+ queue_smooth_neighbors(src)
if(flipped)
clear_smooth_overlays()
diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm
index c1e58f89848..a33e4176599 100644
--- a/code/game/objects/structures/window.dm
+++ b/code/game/objects/structures/window.dm
@@ -444,7 +444,7 @@ var/global/wcCommon = pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", "#8f
/obj/structure/window/proc/update_nearby_icons()
update_icon()
if(smooth)
- smooth_icon_neighbors(src)
+ queue_smooth_neighbors(src)
/obj/structure/window/update_icon()
if(!QDELETED(src))
@@ -453,7 +453,7 @@ var/global/wcCommon = pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", "#8f
var/ratio = obj_integrity / max_integrity
ratio = CEILING(ratio*4, 1) * 25
if(smooth)
- smooth_icon(src)
+ queue_smooth(src)
overlays -= crack_overlay
if(ratio > 75)
return
@@ -733,4 +733,4 @@ obj/structure/window/full/reinforced/ice
dir = FULLTILE_WINDOW_DIR
max_integrity = 120
level = 3
- glass_amount = 2
\ No newline at end of file
+ glass_amount = 2
diff --git a/code/game/turfs/simulated.dm b/code/game/turfs/simulated.dm
index fedbfaa5929..21dbdb9e024 100644
--- a/code/game/turfs/simulated.dm
+++ b/code/game/turfs/simulated.dm
@@ -85,6 +85,6 @@
/turf/simulated/ChangeTurf(var/path)
. = ..()
- smooth_icon_neighbors(src)
+ queue_smooth_neighbors(src)
/turf/simulated/proc/is_shielded()
diff --git a/code/game/turfs/simulated/floor/fancy_floor.dm b/code/game/turfs/simulated/floor/fancy_floor.dm
index 96f10a832b5..e9f8d96e70f 100644
--- a/code/game/turfs/simulated/floor/fancy_floor.dm
+++ b/code/game/turfs/simulated/floor/fancy_floor.dm
@@ -128,11 +128,11 @@
return 0
if(!broken && !burnt)
if(smooth)
- smooth_icon(src)
+ queue_smooth(src)
else
make_plating()
if(smooth)
- smooth_icon_neighbors(src)
+ queue_smooth_neighbors(src)
/turf/simulated/floor/carpet/break_tile()
broken = 1
diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm
index c22c7530505..6008b093c5a 100644
--- a/code/game/turfs/simulated/walls.dm
+++ b/code/game/turfs/simulated/walls.dm
@@ -72,7 +72,7 @@
if(!damage_overlays[1]) //list hasn't been populated
generate_overlays()
- smooth_icon(src)
+ queue_smooth(src)
if(!damage)
if(damage_overlay)
overlays -= damage_overlays[damage_overlay]
diff --git a/code/game/turfs/simulated/walls_reinforced.dm b/code/game/turfs/simulated/walls_reinforced.dm
index eb054ba19ed..f1837173d6d 100644
--- a/code/game/turfs/simulated/walls_reinforced.dm
+++ b/code/game/turfs/simulated/walls_reinforced.dm
@@ -65,7 +65,7 @@
d_state = RWALL_INTACT
update_icon()
- smooth_icon_neighbors(src)
+ queue_smooth_neighbors(src)
to_chat(user, "You repair the last of the damage.")
return TRUE
@@ -84,7 +84,7 @@
to_chat(user, "You add an additional layer of coating to the wall.")
ChangeTurf(/turf/simulated/wall/r_wall/coated)
update_icon()
- smooth_icon_neighbors(src)
+ queue_smooth_neighbors(src)
can_be_reinforced = FALSE
return TRUE
return FALSE
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
index 4d6974f702f..d7ed44c3c9a 100644
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -39,18 +39,18 @@
for(var/atom/movable/AM in src)
Entered(AM)
if(smooth && ticker && ticker.current_state == GAME_STATE_PLAYING)
- smooth_icon(src)
+ queue_smooth(src)
/hook/startup/proc/smooth_world()
var/watch = start_watch()
log_startup_progress("Smoothing atoms...")
for(var/turf/T in world)
if(T.smooth)
- smooth_icon(T)
+ queue_smooth(T)
for(var/A in T)
var/atom/AA = A
if(AA.smooth)
- smooth_icon(AA)
+ queue_smooth(AA)
log_startup_progress(" Smoothed atoms in [stop_watch(watch)]s.")
return 1
diff --git a/code/modules/awaymissions/zlevel.dm b/code/modules/awaymissions/zlevel.dm
index c617b90030f..36a4eeda829 100644
--- a/code/modules/awaymissions/zlevel.dm
+++ b/code/modules/awaymissions/zlevel.dm
@@ -17,11 +17,11 @@ var/global/list/potentialRandomZlevels = generateMapList(filename = "config/away
log_debug("Smoothing tiles")
for(var/turf/T in smoothTurfs)
if(T.smooth)
- smooth_icon(T)
+ queue_smooth(T)
for(var/R in T)
var/atom/A = R
if(A.smooth)
- smooth_icon(A)
+ queue_smooth(A)
if(istype(T, /turf/simulated/mineral)) // For the listening post, among other maps
var/turf/simulated/mineral/MT = T
MT.add_edges()
diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm
index 88551f49096..4a587ac1253 100644
--- a/code/modules/shuttle/on_move.dm
+++ b/code/modules/shuttle/on_move.dm
@@ -52,7 +52,7 @@
// After docking //
/atom/proc/postDock(obj/docking_port/S1)
if(smooth)
- smooth_icon(src)
+ queue_smooth(src)
/obj/machinery/door/airlock/postDock(obj/docking_port/stationary/S1)
. = ..()
diff --git a/code/modules/shuttle/ripple.dm b/code/modules/shuttle/ripple.dm
index ef3b18d2e39..3d3b52d9023 100644
--- a/code/modules/shuttle/ripple.dm
+++ b/code/modules/shuttle/ripple.dm
@@ -15,5 +15,5 @@
/obj/effect/temp_visual/ripple/New()
. = ..()
- smooth_icon(src)
+ queue_smooth(src)
animate(src, alpha=255, time=SHUTTLE_RIPPLE_TIME)
diff --git a/paradise.dme b/paradise.dme
index a20b8d43042..d35fedc2589 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -203,6 +203,7 @@
#include "code\controllers\subsystem\atoms.dm"
#include "code\controllers\subsystem\fires.dm"
#include "code\controllers\subsystem\garbage.dm"
+#include "code\controllers\subsystem\icon_smooth.dm"
#include "code\controllers\subsystem\machinery.dm"
#include "code\controllers\subsystem\mobs.dm"
#include "code\controllers\subsystem\nano_mob_hunter.dm"