diff --git a/code/_helpers/icon_smoothing.dm b/code/_helpers/icon_smoothing.dm index 41c0af5881b..de17f6c276e 100644 --- a/code/_helpers/icon_smoothing.dm +++ b/code/_helpers/icon_smoothing.dm @@ -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) diff --git a/code/game/turfs/simulated/wall_icon.dm b/code/game/turfs/simulated/wall_icon.dm index 7852ebef3e3..9b5ece8e412 100644 --- a/code/game/turfs/simulated/wall_icon.dm +++ b/code/game/turfs/simulated/wall_icon.dm @@ -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 = . diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index e8b3fb10e34..33754cc3909 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -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) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 95af62a6f50..e8254f76df2 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -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 diff --git a/code/modules/materials/materials.dm b/code/modules/materials/materials.dm index 5c478e799ea..6b241044ae9 100644 --- a/code/modules/materials/materials.dm +++ b/code/modules/materials/materials.dm @@ -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 diff --git a/code/modules/mining/mine_turfs.dm b/code/modules/mining/mine_turfs.dm index 2a870820cf9..20732bb630c 100644 --- a/code/modules/mining/mine_turfs.dm +++ b/code/modules/mining/mine_turfs.dm @@ -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 diff --git a/code/modules/multiz/turf.dm b/code/modules/multiz/turf.dm index 14c376e8969..1dcec55faca 100644 --- a/code/modules/multiz/turf.dm +++ b/code/modules/multiz/turf.dm @@ -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 diff --git a/icons/turf/smooth/composite_metal.dmi b/icons/turf/smooth/composite_metal.dmi new file mode 100644 index 00000000000..790dc927ea1 Binary files /dev/null and b/icons/turf/smooth/composite_metal.dmi differ diff --git a/icons/turf/smooth/composite_solid.dmi b/icons/turf/smooth/composite_solid.dmi new file mode 100644 index 00000000000..1b6543b0a0d Binary files /dev/null and b/icons/turf/smooth/composite_solid.dmi differ diff --git a/icons/turf/smooth/composite_stone.dmi b/icons/turf/smooth/composite_stone.dmi new file mode 100644 index 00000000000..f28713ddf6b Binary files /dev/null and b/icons/turf/smooth/composite_stone.dmi differ diff --git a/icons/turf/smooth/composite_stone_reinf.dmi b/icons/turf/smooth/composite_stone_reinf.dmi new file mode 100644 index 00000000000..3130586fae7 Binary files /dev/null and b/icons/turf/smooth/composite_stone_reinf.dmi differ diff --git a/icons/turf/smooth/rusty_wall.dmi b/icons/turf/smooth/rusty_wall.dmi new file mode 100644 index 00000000000..5db142a83b9 Binary files /dev/null and b/icons/turf/smooth/rusty_wall.dmi differ