mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2025-12-20 15:12:19 +00:00
Wall Icon Refactor (#3023)
changes: Atom types can now define custom adjacency code for the smoothing system. Walls now draw using the generic icon smoothing system. Walls now pre-bake colors into their icons instead of doing it client-side with the color var. Walls can now use the SSoverlay appearance cache; wall icon updates should be faster. The "rusty" wall type now actually works. Smoothing now uses mutable_appearance instead of image in some places. Should be a bit easier on clients, though I haven't done profiling. This PR breaks 510 compatibility.
This commit is contained in:
@@ -69,60 +69,62 @@
|
||||
/turf/unsimulated/wall
|
||||
smooth_underlays = TRUE
|
||||
|
||||
/proc/calculate_adjacencies(atom/A)
|
||||
if(!A.loc)
|
||||
/atom/proc/calculate_adjacencies()
|
||||
if (!loc)
|
||||
return 0
|
||||
|
||||
var/adjacencies = 0
|
||||
|
||||
var/atom/movable/AM
|
||||
if(istype(A, /atom/movable))
|
||||
AM = A
|
||||
if(AM.can_be_unanchored && !AM.anchored)
|
||||
return 0
|
||||
|
||||
for(var/direction in cardinal)
|
||||
AM = find_type_in_direction(A, direction)
|
||||
AM = find_type_in_direction(src, direction)
|
||||
if(AM == NULLTURF_BORDER)
|
||||
if((A.smooth & SMOOTH_BORDER))
|
||||
if((smooth & SMOOTH_BORDER))
|
||||
adjacencies |= 1 << direction
|
||||
else if( (AM && !istype(AM)) || (istype(AM) && AM.anchored) )
|
||||
adjacencies |= 1 << direction
|
||||
|
||||
if(adjacencies & N_NORTH)
|
||||
if(adjacencies & N_WEST)
|
||||
AM = find_type_in_direction(A, NORTHWEST)
|
||||
AM = find_type_in_direction(src, NORTHWEST)
|
||||
if(AM == NULLTURF_BORDER)
|
||||
if((A.smooth & SMOOTH_BORDER))
|
||||
if((smooth & SMOOTH_BORDER))
|
||||
adjacencies |= N_NORTHWEST
|
||||
else if( (AM && !istype(AM)) || (istype(AM) && AM.anchored) )
|
||||
adjacencies |= N_NORTHWEST
|
||||
if(adjacencies & N_EAST)
|
||||
AM = find_type_in_direction(A, NORTHEAST)
|
||||
AM = find_type_in_direction(src, NORTHEAST)
|
||||
if(AM == NULLTURF_BORDER)
|
||||
if((A.smooth & SMOOTH_BORDER))
|
||||
if((smooth & SMOOTH_BORDER))
|
||||
adjacencies |= N_NORTHEAST
|
||||
else if( (AM && !istype(AM)) || (istype(AM) && AM.anchored) )
|
||||
adjacencies |= N_NORTHEAST
|
||||
|
||||
if(adjacencies & N_SOUTH)
|
||||
if(adjacencies & N_WEST)
|
||||
AM = find_type_in_direction(A, SOUTHWEST)
|
||||
AM = find_type_in_direction(src, SOUTHWEST)
|
||||
if(AM == NULLTURF_BORDER)
|
||||
if((A.smooth & SMOOTH_BORDER))
|
||||
if((smooth & SMOOTH_BORDER))
|
||||
adjacencies |= N_SOUTHWEST
|
||||
else if( (AM && !istype(AM)) || (istype(AM) && AM.anchored) )
|
||||
adjacencies |= N_SOUTHWEST
|
||||
if(adjacencies & N_EAST)
|
||||
AM = find_type_in_direction(A, SOUTHEAST)
|
||||
AM = find_type_in_direction(src, SOUTHEAST)
|
||||
if(AM == NULLTURF_BORDER)
|
||||
if((A.smooth & SMOOTH_BORDER))
|
||||
if((smooth & SMOOTH_BORDER))
|
||||
adjacencies |= N_SOUTHEAST
|
||||
else if( (AM && !istype(AM)) || (istype(AM) && AM.anchored) )
|
||||
adjacencies |= N_SOUTHEAST
|
||||
|
||||
return adjacencies
|
||||
|
||||
/atom/movable/calculate_adjacencies()
|
||||
if (can_be_unanchored && !anchored)
|
||||
return 0
|
||||
|
||||
return ..()
|
||||
|
||||
//do not use, use queue_smooth(atom)
|
||||
/proc/smooth_icon(atom/A)
|
||||
if(!A || !A.smooth)
|
||||
@@ -133,7 +135,7 @@
|
||||
if(QDELETED(A))
|
||||
return
|
||||
if((A.smooth & SMOOTH_TRUE) || (A.smooth & SMOOTH_MORE))
|
||||
var/adjacencies = calculate_adjacencies(A)
|
||||
var/adjacencies = A.calculate_adjacencies()
|
||||
|
||||
if(A.smooth & SMOOTH_DIAGONAL)
|
||||
A.diagonal_smooth(adjacencies)
|
||||
@@ -172,7 +174,7 @@
|
||||
if (smooth_underlays && adjacencies)
|
||||
// This should be a mutable_appearance, but we're still on 510.
|
||||
// Alas.
|
||||
var/image/underlay_appearance = image(layer = TURF_LAYER)
|
||||
var/mutable_appearance/underlay_appearance = new(layer = TURF_LAYER)
|
||||
var/list/U = list(underlay_appearance)
|
||||
if(fixed_underlay)
|
||||
if(fixed_underlay["space"])
|
||||
@@ -257,33 +259,103 @@
|
||||
se = "4-e"
|
||||
|
||||
var/list/New
|
||||
var/list/Old
|
||||
|
||||
if(A.top_left_corner != nw)
|
||||
A.cut_overlay(A.top_left_corner)
|
||||
if (A.top_left_corner)
|
||||
LAZYADD(Old, A.top_left_corner)
|
||||
A.top_left_corner = nw
|
||||
LAZYADD(New, nw)
|
||||
|
||||
if(A.top_right_corner != ne)
|
||||
A.cut_overlay(A.top_right_corner)
|
||||
if (A.top_right_corner)
|
||||
LAZYADD(Old, A.top_right_corner)
|
||||
A.top_right_corner = ne
|
||||
LAZYADD(New, ne)
|
||||
|
||||
if(A.bottom_right_corner != sw)
|
||||
A.cut_overlay(A.bottom_right_corner)
|
||||
if (A.bottom_right_corner)
|
||||
LAZYADD(Old, A.bottom_right_corner)
|
||||
A.bottom_right_corner = sw
|
||||
LAZYADD(New, sw)
|
||||
|
||||
if(A.bottom_left_corner != se)
|
||||
A.cut_overlay(A.bottom_left_corner)
|
||||
if (A.bottom_left_corner)
|
||||
LAZYADD(Old, A.bottom_left_corner)
|
||||
A.bottom_left_corner = se
|
||||
LAZYADD(New, se)
|
||||
|
||||
if(Old)
|
||||
A.cut_overlay(Old)
|
||||
|
||||
if(New)
|
||||
A.add_overlay(New)
|
||||
|
||||
if (A.icon_state && !(A.smooth & SMOOTH_NO_CLEAR_ICON))
|
||||
A.icon_state = null
|
||||
|
||||
// A more stripped down version of the above, meant for using images to apply multiple smooth overlays
|
||||
// at once.
|
||||
/proc/cardinal_smooth_fromicon(icon/I, adjacencies)
|
||||
//NW CORNER
|
||||
var/nw = "1-i"
|
||||
if((adjacencies & N_NORTH) && (adjacencies & N_WEST))
|
||||
if(adjacencies & N_NORTHWEST)
|
||||
nw = "1-f"
|
||||
else
|
||||
nw = "1-nw"
|
||||
else
|
||||
if(adjacencies & N_NORTH)
|
||||
nw = "1-n"
|
||||
else if(adjacencies & N_WEST)
|
||||
nw = "1-w"
|
||||
|
||||
//NE CORNER
|
||||
var/ne = "2-i"
|
||||
if((adjacencies & N_NORTH) && (adjacencies & N_EAST))
|
||||
if(adjacencies & N_NORTHEAST)
|
||||
ne = "2-f"
|
||||
else
|
||||
ne = "2-ne"
|
||||
else
|
||||
if(adjacencies & N_NORTH)
|
||||
ne = "2-n"
|
||||
else if(adjacencies & N_EAST)
|
||||
ne = "2-e"
|
||||
|
||||
//SW CORNER
|
||||
var/sw = "3-i"
|
||||
if((adjacencies & N_SOUTH) && (adjacencies & N_WEST))
|
||||
if(adjacencies & N_SOUTHWEST)
|
||||
sw = "3-f"
|
||||
else
|
||||
sw = "3-sw"
|
||||
else
|
||||
if(adjacencies & N_SOUTH)
|
||||
sw = "3-s"
|
||||
else if(adjacencies & N_WEST)
|
||||
sw = "3-w"
|
||||
|
||||
//SE CORNER
|
||||
var/se = "4-i"
|
||||
if((adjacencies & N_SOUTH) && (adjacencies & N_EAST))
|
||||
if(adjacencies & N_SOUTHEAST)
|
||||
se = "4-f"
|
||||
else
|
||||
se = "4-se"
|
||||
else
|
||||
if(adjacencies & N_SOUTH)
|
||||
se = "4-s"
|
||||
else if(adjacencies & N_EAST)
|
||||
se = "4-e"
|
||||
|
||||
var/image/nw_i = image(I, nw)
|
||||
var/image/ne_i = image(I, ne)
|
||||
var/image/sw_i = image(I, sw)
|
||||
var/image/se_i = image(I, se)
|
||||
|
||||
return list(nw_i, ne_i, sw_i, se_i)
|
||||
|
||||
/proc/find_type_in_direction(atom/source, direction)
|
||||
var/turf/target_turf = get_step(source, direction)
|
||||
if(!target_turf)
|
||||
@@ -332,13 +404,10 @@
|
||||
queue_smooth(A)
|
||||
|
||||
/atom/proc/clear_smooth_overlays()
|
||||
cut_overlay(top_left_corner)
|
||||
cut_overlay(list(top_left_corner, top_right_corner, bottom_left_corner, bottom_right_corner))
|
||||
top_left_corner = null
|
||||
cut_overlay(top_right_corner)
|
||||
top_right_corner = null
|
||||
cut_overlay(bottom_right_corner)
|
||||
bottom_right_corner = null
|
||||
cut_overlay(bottom_left_corner)
|
||||
bottom_left_corner = null
|
||||
|
||||
/atom/proc/replace_smooth_overlays(nw, ne, sw, se)
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
material = get_material_by_name(DEFAULT_WALL_MATERIAL)
|
||||
if(material)
|
||||
explosion_resistance = material.explosion_resistance
|
||||
if (material.wall_icon)
|
||||
icon = material.wall_icon
|
||||
|
||||
if(reinf_material && reinf_material.explosion_resistance > explosion_resistance)
|
||||
explosion_resistance = reinf_material.explosion_resistance
|
||||
|
||||
@@ -26,10 +29,8 @@
|
||||
else if(material.opacity < 0.5 && opacity)
|
||||
set_light(0)
|
||||
|
||||
update_connections(1)
|
||||
update_icon()
|
||||
|
||||
|
||||
/turf/simulated/wall/proc/set_material(var/material/newmaterial, var/material/newrmaterial)
|
||||
material = newmaterial
|
||||
reinf_material = newrmaterial
|
||||
@@ -42,37 +43,43 @@
|
||||
if(!damage_overlays[1]) //list hasn't been populated
|
||||
generate_overlays()
|
||||
|
||||
cut_overlays()
|
||||
var/list/cutlist = (reinforcement_images||list()) + damage_image
|
||||
cut_overlay(cutlist, TRUE)
|
||||
LAZYCLEARLIST(reinforcement_images)
|
||||
damage_image = null
|
||||
|
||||
var/list/overlays_to_add = list()
|
||||
var/image/I
|
||||
|
||||
if(!density)
|
||||
I = image('icons/turf/wall_masks.dmi', "[material.icon_base]fwall_open")
|
||||
I.color = material.icon_colour
|
||||
add_overlay(I)
|
||||
if (!density) // We're a fake and we're open.
|
||||
clear_smooth_overlays()
|
||||
fake_wall_image = image('icons/turf/wall_masks.dmi', "[material.icon_base]fwall_open")
|
||||
fake_wall_image.color = material.icon_colour
|
||||
add_overlay(fake_wall_image)
|
||||
smooth = SMOOTH_FALSE
|
||||
return
|
||||
else if (fake_wall_image)
|
||||
cut_overlay(fake_wall_image)
|
||||
fake_wall_image = null
|
||||
smooth = initial(smooth)
|
||||
|
||||
for(var/i = 1 to 4)
|
||||
I = image('icons/turf/wall_masks.dmi', "[material.icon_base][wall_connections[i]]", dir = 1<<(i-1))
|
||||
I.color = material.icon_colour
|
||||
overlays_to_add += I
|
||||
calculate_adjacencies() // Update cached_adjacency
|
||||
|
||||
if(reinf_material)
|
||||
var/image/I
|
||||
if(construction_stage != null && construction_stage < 6)
|
||||
I = image('icons/turf/wall_masks.dmi', "reinf_construct-[construction_stage]")
|
||||
I.color = reinf_material.icon_colour
|
||||
overlays_to_add += I
|
||||
LAZYADD(reinforcement_images, I)
|
||||
else
|
||||
if("[reinf_material.icon_reinf]0" in icon_states('icons/turf/wall_masks.dmi'))
|
||||
// Directional icon
|
||||
for(var/i = 1 to 4)
|
||||
I = image('icons/turf/wall_masks.dmi', "[reinf_material.icon_reinf][wall_connections[i]]", dir = 1<<(i-1))
|
||||
I.color = reinf_material.icon_colour
|
||||
overlays_to_add += I
|
||||
if (reinf_material.multipart_reinf_icon)
|
||||
LAZYADD(reinforcement_images, cardinal_smooth_fromicon(reinf_material.multipart_reinf_icon, cached_adjacency))
|
||||
else
|
||||
I = image('icons/turf/wall_masks.dmi', reinf_material.icon_reinf)
|
||||
I.color = reinf_material.icon_colour
|
||||
overlays_to_add += I
|
||||
LAZYADD(reinforcement_images, I)
|
||||
|
||||
if (reinforcement_images)
|
||||
overlays_to_add += reinforcement_images
|
||||
|
||||
if(damage != 0)
|
||||
var/integrity = material.integrity
|
||||
@@ -83,9 +90,12 @@
|
||||
if(overlay > damage_overlays.len)
|
||||
overlay = damage_overlays.len
|
||||
|
||||
overlays_to_add += damage_overlays[overlay]
|
||||
damage_image = damage_overlays[overlay]
|
||||
overlays_to_add += damage_image
|
||||
|
||||
add_overlay(overlays_to_add)
|
||||
add_overlay(overlays_to_add, TRUE)
|
||||
UNSETEMPTY(reinforcement_images)
|
||||
queue_smooth(src)
|
||||
|
||||
/turf/simulated/wall/proc/generate_overlays()
|
||||
var/alpha_inc = 256 / damage_overlays.len
|
||||
@@ -96,23 +106,50 @@
|
||||
img.alpha = (i * alpha_inc) - 1
|
||||
damage_overlays[i] = img
|
||||
|
||||
|
||||
/turf/simulated/wall/proc/update_connections(propagate = 0)
|
||||
if(!material)
|
||||
/turf/simulated/wall/calculate_adjacencies()
|
||||
. = 0
|
||||
if (!loc || !material)
|
||||
return
|
||||
var/list/dirs = list()
|
||||
for(var/turf/simulated/wall/W in orange(src, 1))
|
||||
if(!W.material)
|
||||
continue
|
||||
if(propagate)
|
||||
W.update_connections()
|
||||
W.update_icon()
|
||||
if(can_join_with(W))
|
||||
dirs += get_dir(src, W)
|
||||
|
||||
wall_connections = dirs_to_corner_states(dirs)
|
||||
var/turf/simulated/wall/W
|
||||
var/material/M
|
||||
var/our_icon_base = material.icon_base
|
||||
|
||||
/turf/simulated/wall/proc/can_join_with(var/turf/simulated/wall/W)
|
||||
if(material && W.material && material.icon_base == W.material.icon_base)
|
||||
return 1
|
||||
return 0
|
||||
for (var/dir in cardinal)
|
||||
W = get_step(src, dir)
|
||||
if (istype(W) && (W.smooth || !W.density))
|
||||
M = W.material
|
||||
if (M && M.icon_base == our_icon_base)
|
||||
. |= 1 << dir
|
||||
|
||||
if (. & N_NORTH)
|
||||
if (. & N_WEST)
|
||||
W = get_step(src, NORTHWEST)
|
||||
if (istype(W) && (W.smooth || !W.density))
|
||||
M = W.material
|
||||
if (M && M.icon_base == our_icon_base)
|
||||
. |= N_NORTHWEST
|
||||
|
||||
if (. & N_EAST)
|
||||
W = get_step(src, NORTHEAST)
|
||||
if (istype(W) && (W.smooth || !W.density))
|
||||
M = W.material
|
||||
if (M && M.icon_base == our_icon_base)
|
||||
. |= N_NORTHEAST
|
||||
|
||||
if (. & N_SOUTH)
|
||||
if (. & N_WEST)
|
||||
W = get_step(src, SOUTHWEST)
|
||||
if (istype(W) && (W.smooth || !W.density))
|
||||
M = W.material
|
||||
if (M && M.icon_base == our_icon_base)
|
||||
. |= N_SOUTHWEST
|
||||
|
||||
if (. & N_EAST)
|
||||
W = get_step(src, SOUTHEAST)
|
||||
if (istype(W) && (W.smooth || !W.density))
|
||||
M = W.material
|
||||
if (M && M.icon_base == our_icon_base)
|
||||
. |= N_SOUTHEAST
|
||||
|
||||
cached_adjacency = .
|
||||
|
||||
@@ -19,7 +19,12 @@
|
||||
var/last_state
|
||||
var/construction_stage
|
||||
|
||||
var/list/wall_connections = list("0", "0", "0", "0")
|
||||
var/tmp/list/image/reinforcement_images
|
||||
var/tmp/image/damage_image
|
||||
var/tmp/image/fake_wall_image
|
||||
var/tmp/cached_adjacency
|
||||
|
||||
smooth = SMOOTH_TRUE | SMOOTH_NO_CLEAR_ICON
|
||||
|
||||
// Walls always hide the stuff below them.
|
||||
/turf/simulated/wall/levelupdate(mapload)
|
||||
@@ -178,7 +183,6 @@
|
||||
clear_plants()
|
||||
material = get_material_by_name("placeholder")
|
||||
reinf_material = null
|
||||
update_connections(1)
|
||||
|
||||
if (!no_change)
|
||||
ChangeTurf(/turf/simulated/floor/plating)
|
||||
|
||||
@@ -81,9 +81,7 @@
|
||||
..()
|
||||
return QDEL_HINT_IWILLGC
|
||||
|
||||
// This should be using mutable_appearance, but 510. Woe.
|
||||
// Update this & all overrides if/when we move to 511.
|
||||
/turf/proc/get_smooth_underlay_icon(image/underlay_appearance, turf/asking_turf, adjacency_dir)
|
||||
/turf/proc/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir)
|
||||
underlay_appearance.icon = icon
|
||||
underlay_appearance.icon_state = icon_state
|
||||
underlay_appearance.dir = adjacency_dir
|
||||
|
||||
@@ -83,6 +83,8 @@ var/list/name_to_material
|
||||
var/door_icon_base = "metal" // Door base icon tag. See header.
|
||||
var/icon_reinf = "reinf_metal" // Overlay used
|
||||
var/list/stack_origin_tech = list(TECH_MATERIAL = 1) // Research level for stacks.
|
||||
var/icon/wall_icon
|
||||
var/icon/multipart_reinf_icon
|
||||
|
||||
// Attributes
|
||||
var/cut_delay = 0 // Delay in ticks when cutting through this wall.
|
||||
@@ -153,6 +155,31 @@ var/list/name_to_material
|
||||
if(!shard_icon)
|
||||
shard_icon = shard_type
|
||||
|
||||
var/skip_blend = FALSE
|
||||
switch (icon_base)
|
||||
if ("solid")
|
||||
wall_icon = 'icons/turf/smooth/composite_solid.dmi'
|
||||
if ("stone")
|
||||
wall_icon = 'icons/turf/smooth/composite_stone.dmi'
|
||||
multipart_reinf_icon = 'icons/turf/smooth/composite_stone_reinf.dmi'
|
||||
if ("metal")
|
||||
wall_icon = 'icons/turf/smooth/composite_metal.dmi'
|
||||
if ("cult")
|
||||
wall_icon = 'icons/turf/smooth/cult_wall.dmi'
|
||||
skip_blend = TRUE
|
||||
if ("arust")
|
||||
wall_icon = 'icons/turf/smooth/rusty_wall.dmi'
|
||||
skip_blend = TRUE
|
||||
else
|
||||
world.log << "materials: [src] has unknown icon_base [icon_base]."
|
||||
|
||||
if (wall_icon && icon_colour && !skip_blend)
|
||||
wall_icon = new(wall_icon)
|
||||
wall_icon.Blend(icon_colour, ICON_MULTIPLY)
|
||||
if (multipart_reinf_icon)
|
||||
multipart_reinf_icon = new(multipart_reinf_icon)
|
||||
multipart_reinf_icon.Blend(icon_colour, ICON_MULTIPLY)
|
||||
|
||||
// This is a placeholder for proper integration of windows/windoors into the system.
|
||||
/material/proc/build_windows(var/mob/living/user, var/obj/item/stack/used_stack)
|
||||
return 0
|
||||
@@ -599,6 +626,7 @@ var/list/name_to_material
|
||||
stack_type = null
|
||||
icon_colour = "#B7410E"
|
||||
icon_base = "arust"
|
||||
icon_reinf = "reinf_over"
|
||||
integrity = 250
|
||||
explosion_resistance = 8
|
||||
hardness = 15
|
||||
|
||||
@@ -541,7 +541,7 @@
|
||||
|
||||
return INITIALIZE_HINT_NORMAL
|
||||
|
||||
/turf/simulated/floor/asteroid/get_smooth_underlay_icon(image/underlay_appearance, turf/asking_turf, adjacency_dir)
|
||||
/turf/simulated/floor/asteroid/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir)
|
||||
. = ..()
|
||||
underlay_appearance.pixel_x = pixel_x
|
||||
underlay_appearance.pixel_y = pixel_y
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
|
||||
return ..()
|
||||
|
||||
/turf/simulated/open/get_smooth_underlay_icon(image/underlay_appearance, turf/asking_turf, adjacency_dir)
|
||||
/turf/simulated/open/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir)
|
||||
underlay_appearance.appearance = src
|
||||
return TRUE
|
||||
|
||||
|
||||
BIN
icons/turf/smooth/composite_metal.dmi
Normal file
BIN
icons/turf/smooth/composite_metal.dmi
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.0 KiB |
BIN
icons/turf/smooth/composite_solid.dmi
Normal file
BIN
icons/turf/smooth/composite_solid.dmi
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.0 KiB |
BIN
icons/turf/smooth/composite_stone.dmi
Normal file
BIN
icons/turf/smooth/composite_stone.dmi
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.1 KiB |
BIN
icons/turf/smooth/composite_stone_reinf.dmi
Normal file
BIN
icons/turf/smooth/composite_stone_reinf.dmi
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.9 KiB |
BIN
icons/turf/smooth/rusty_wall.dmi
Normal file
BIN
icons/turf/smooth/rusty_wall.dmi
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
Reference in New Issue
Block a user