diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm index 47467165b94..a22b1475ad8 100644 --- a/code/game/objects/structures.dm +++ b/code/game/objects/structures.dm @@ -7,7 +7,6 @@ var/breakable var/parts var/list/climbers = list() - var/block_turf_edges = FALSE // If true, turf edge icons will not be made on the turf this occupies. var/list/connections var/list/other_connections diff --git a/code/game/objects/structures/cliff.dm b/code/game/objects/structures/cliff.dm index c12cbef0c3d..95e37b68ce3 100644 --- a/code/game/objects/structures/cliff.dm +++ b/code/game/objects/structures/cliff.dm @@ -33,7 +33,8 @@ two tiles on initialization, and which way a cliff is facing may change during m opacity = FALSE climbable = TRUE climb_delay = 10 SECONDS - block_turf_edges = TRUE // Don't want turf edges popping up from the cliff edge. + // TODO: IMPLEMENT THIS AGAIN, this was done in a horrifically slow and stupid way + // block_turf_edges = TRUE // Don't want turf edges popping up from the cliff edge. register_as_dangerous_object = TRUE var/icon_variant = null // Used to make cliffs less repeative by having a selection of sprites to display. diff --git a/code/game/turfs/simulated.dm b/code/game/turfs/simulated.dm index 2f6bbc08f5c..b4cde1a4027 100644 --- a/code/game/turfs/simulated.dm +++ b/code/game/turfs/simulated.dm @@ -1,6 +1,5 @@ /turf/simulated name = "station" - smoothing_flags = SMOOTH_CUSTOM var/wet = 0 var/image/wet_overlay = null diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm index 68f1b4cc28f..c03bc398a2a 100644 --- a/code/game/turfs/simulated/floor.dm +++ b/code/game/turfs/simulated/floor.dm @@ -3,6 +3,10 @@ desc = "Unfinished flooring." icon = 'icons/turf/flooring/plating_vr.dmi' icon_state = "plating" + smoothing_flags = SMOOTH_CUSTOM + base_icon_state = "plating" + thermal_conductivity = 0.040 + heat_capacity = 10000 // Damage to flooring. var/broken @@ -12,7 +16,6 @@ var/base_name = "plating" var/base_desc = "The naked hull." var/base_icon = 'icons/turf/flooring/plating_vr.dmi' - base_icon_state = "plating" var/static/list/base_footstep_sounds = list("human" = list( 'sound/effects/footstep/plating1.ogg', 'sound/effects/footstep/plating2.ogg', @@ -28,8 +31,13 @@ var/decl/flooring/flooring var/mineral = MAT_STEEL - thermal_conductivity = 0.040 - heat_capacity = 10000 + // If greater than 0, this turf will apply edge overlays on top of other turfs cardinally adjacent to it, if those adjacent turfs are of a different icon_state, + // and if those adjacent turfs have a lower edge_blending_priority. + var/edge_blending_priority = 0 + /// edge icon state, overrides icon_state if set + var/edge_icon_state + // Outdoors var determines if the game should consider the turf to be 'outdoors', which controls certain things such as weather effects. + var/outdoors = FALSE /turf/simulated/floor/is_plating() return !flooring @@ -56,7 +64,7 @@ old_decals = decals decals = overfloor_decals // VOREStation Edit End - update_icon(1) + QUEUE_SMOOTH_NEIGHBORS(src) levelupdate() //This proc will set floor_type to null and the update_icon() proc will then change the icon_state of the turf @@ -92,7 +100,7 @@ levelupdate() if(!defer_icon_update) - update_icon(1) + QUEUE_SMOOTH_NEIGHBORS(src) /turf/simulated/floor/levelupdate() for(var/obj/O in src) diff --git a/code/game/turfs/simulated/floor_damage.dm b/code/game/turfs/simulated/floor_damage.dm index 255333fa409..85bb1a5c808 100644 --- a/code/game/turfs/simulated/floor_damage.dm +++ b/code/game/turfs/simulated/floor_damage.dm @@ -13,7 +13,7 @@ broken = rand(0,flooring.has_damage_range) else broken = 0 - update_icon() + update_appearance() /turf/simulated/floor/proc/burn_tile(var/exposed_temperature) if(!flooring || !(flooring.flags & TURF_CAN_BURN) || !isnull(burnt)) @@ -22,4 +22,4 @@ burnt = rand(0,flooring.has_burn_range) else burnt = 0 - update_icon() + update_appearance() diff --git a/code/game/turfs/simulated/floor_icon.dm b/code/game/turfs/simulated/floor_icon.dm index f575d1c56bd..6d45601e995 100644 --- a/code/game/turfs/simulated/floor_icon.dm +++ b/code/game/turfs/simulated/floor_icon.dm @@ -1,16 +1,23 @@ +GLOBAL_DATUM_INIT(no_ceiling_image, /image, generate_no_ceiling_image()) + +/proc/generate_no_ceiling_image() + var/image/I = image(icon = 'icons/turf/open_space.dmi', icon_state = "no_ceiling") + I.plane = PLANE_MESONS + return I + +/turf/simulated/floor/custom_smooth() + update_icon() + update_border_spillover() + +/turf/simulated/floor/calculate_adjacencies() + return NONE + +GLOBAL_LIST_EMPTY(turf_edge_cache) + var/list/flooring_cache = list() -var/image/no_ceiling_image = null - -/hook/startup/proc/setup_no_ceiling_image() - cache_no_ceiling_image() - return TRUE - -/proc/cache_no_ceiling_image() - no_ceiling_image = image(icon = 'icons/turf/open_space.dmi', icon_state = "no_ceiling") - no_ceiling_image.plane = PLANE_MESONS - -/turf/simulated/floor/update_icon(var/update_neighbors) +/turf/simulated/floor/update_icon() + . = ..() cut_overlays() if(flooring) @@ -28,8 +35,8 @@ var/image/no_ceiling_image = null flooring_override = icon_state // Apply edges, corners, and inner corners. - var/has_border = 0 if(flooring.flags & TURF_HAS_EDGES) + var/has_border = 0 for(var/step_dir in GLOB.cardinal) var/turf/simulated/floor/T = get_step(src, step_dir) if(!flooring.test_link(src, T)) @@ -65,67 +72,61 @@ var/image/no_ceiling_image = null var/turf/simulated/floor/T = get_step(src, SOUTHWEST) if(!flooring.test_link(src, T)) add_overlay(flooring.get_flooring_overlay("[flooring.icon_base]-corner-[SOUTHWEST]", "[flooring.icon_base]_corners", SOUTHWEST)) + if(!isnull(broken) && (flooring.flags & TURF_CAN_BREAK)) + add_overlay(flooring.get_flooring_overlay("[flooring.icon_base]-broken-[broken]","broken[broken]")) + if(!isnull(burnt) && (flooring.flags & TURF_CAN_BURN)) + add_overlay(flooring.get_flooring_overlay("[flooring.icon_base]-burned-[burnt]","burned[burnt]")) + else + // no flooring - just handle plating stuff + if(is_plating() && !(isnull(broken) && isnull(burnt))) //temp, todo + icon = 'icons/turf/flooring/plating.dmi' + icon_state = "dmg[rand(1,4)]" // Re-apply floor decals if(LAZYLEN(decals)) add_overlay(decals) - if(is_plating() && !(isnull(broken) && isnull(burnt))) //temp, todo - icon = 'icons/turf/flooring/plating.dmi' - icon_state = "dmg[rand(1,4)]" - else if(flooring) - if(!isnull(broken) && (flooring.flags & TURF_CAN_BREAK)) - add_overlay(flooring.get_flooring_overlay("[flooring.icon_base]-broken-[broken]","broken[broken]")) - if(!isnull(burnt) && (flooring.flags & TURF_CAN_BURN)) - add_overlay(flooring.get_flooring_overlay("[flooring.icon_base]-burned-[burnt]","burned[burnt]")) - - if(update_neighbors) - for(var/turf/simulated/floor/F in range(src, 1)) - if(F == src) - continue - F.update_icon() - // Show 'ceilingless' overlay. - var/turf/above = GetAbove(src) - if(above && isopenturf(above) && !istype(src, /turf/simulated/floor/outdoors)) // This won't apply to outdoor turfs since its assumed they don't have a ceiling anyways. - add_overlay(no_ceiling_image) + var/turf/above = Above(src) + if(isopenturf(above) && !istype(src, /turf/simulated/floor/outdoors)) // This won't apply to outdoor turfs since its assumed they don't have a ceiling anyways. + add_overlay(GLOB.no_ceiling_image) - // Update our 'them-to-us' edges, aka edges from external turfs we feel should spill onto us - if(edge_blending_priority) - update_icon_edge() +/** + * welcome to the less modular but more sensical and efficient way to do icon edges + * instead of having every turf check, we only have turfs tha can spill onto others check, and apply their edges to other turfs + * now only on /turf/simulated/floor, because let's be honest, + * 1. no one used borders on walls + * 2. if you want a floor to spill onto a wall, go ahead and reconsider your life/design choices + * 3. i can think of a reason but honestly performance is better than some niche case of floor resin creeping onto walls or something, use objs for that. + */ +/turf/simulated/floor/proc/update_border_spillover() + if(!edge_blending_priority) + return // not us + for(var/d in GLOB.cardinal) + var/turf/simulated/floor/F = get_step(src, d) + if(!istype(F)) + continue + // check that their priority is lower than ours, and we don't have the same icon state + if(F.edge_blending_priority < edge_blending_priority && icon_state != F.icon_state) + var/key = "[F.icon_state || F.edge_icon_state]-[d]" + add_overlay(GLOB.turf_edge_cache[key] || generate_border_cache_for(F.icon_state || F.edge_icon_state, d)) -// This updates an edge from an adjacent turf onto us, not our own 'internal' edges. -// For e.g. we might be outdoor metal plating, and we want to find sand next to us to have it 'spill onto' our turf with an overlay. -/turf/simulated/proc/update_icon_edge() - for(var/checkdir in GLOB.cardinal) // Check every direction - var/turf/simulated/T = get_step(src, checkdir) // Get the turf in that direction - // Our conditions: - // Has to be a /turf/simulated - // Has to have it's own edge_blending_priority - // Has to have a higher priority than us - // Their icon_state is not our icon_state - // They don't forbid_turf_edge - if(istype(T) && T.edge_blending_priority && edge_blending_priority < T.edge_blending_priority && icon_state != T.icon_state) - var/cache_key = "[T.get_edge_icon_state()]-[checkdir]" // Usually [icon_state]-[dirnum] - if(!turf_edge_cache[cache_key]) - var/image/I = image(icon = 'icons/turf/outdoors_edge.dmi', icon_state = "[T.get_edge_icon_state()]-edge", dir = checkdir, layer = ABOVE_TURF_LAYER) // Icon should be abstracted out - I.plane = TURF_PLANE - turf_edge_cache[cache_key] = I - add_overlay(turf_edge_cache[cache_key]) +/proc/generate_border_cache_for(state, dir) + // make it + var/image/I = image(icon = 'icons/turf/oudoors_edge.dmi', icon_State = "[F.icon_state || F.edge_icon_state]-edge", dir = turn(d, 180), layer = ABOVE_TURF_LAYER) + I.plane = TURF_PLANE + switch(dir) + if(NORTH) + I.pixel_y = 32 + if(SOUTH) + I.pixel_y = -32 + if(EAST) + I.pixel_x = 32 + if(WEST) + I.pixel_x = -32 + GLOB.turf_edge_cache[key] = I + return I -// We will take this state and use it for a cache key, and append '-edge' to it to get the edge overlay (edges *from other turfs*, not our own internal edges) -/turf/simulated/proc/get_edge_icon_state() - return icon_state - -// Tests if we shouldn't apply a turf edge. -// Returns the blocker if one exists. -/* -/turf/simulated/proc/forbid_turf_edge() - for(var/obj/structure/S in contents) - if(S.block_turf_edges) - return S - return null -*/ // wip - turf icon stuff needs to be refactored //Tests whether this flooring will smooth with the specified turf diff --git a/code/game/turfs/simulated/floors/lava.dm b/code/game/turfs/simulated/floors/lava.dm index 7ffc5a29d1c..b0f0937efea 100644 --- a/code/game/turfs/simulated/floors/lava.dm +++ b/code/game/turfs/simulated/floors/lava.dm @@ -21,7 +21,6 @@ /turf/simulated/floor/outdoors/lava/Initialize(mapload) if(!outdoors) name = "magma" - update_icon() return ..() /turf/simulated/floor/outdoors/lava/make_outdoors() diff --git a/code/game/turfs/simulated/floors/outdoors.dm b/code/game/turfs/simulated/floors/outdoors.dm index 66c492d0281..48466b9a99b 100644 --- a/code/game/turfs/simulated/floors/outdoors.dm +++ b/code/game/turfs/simulated/floors/outdoors.dm @@ -1,12 +1,3 @@ -var/list/turf_edge_cache = list() - -/turf/ - // If greater than 0, this turf will apply edge overlays on top of other turfs cardinally adjacent to it, if those adjacent turfs are of a different icon_state, - // and if those adjacent turfs have a lower edge_blending_priority. - var/edge_blending_priority = 0 - // Outdoors var determines if the game should consider the turf to be 'outdoors', which controls certain things such as weather effects. - var/outdoors = FALSE - /turf/simulated/floor/outdoors name = "generic ground" desc = "Rather boring." @@ -19,7 +10,7 @@ var/list/turf_edge_cache = list() baseturfs = /turf/simulated/floor/outdoors/rocks /turf/simulated/floor/outdoors/Initialize(mapload) - update_icon() + QUEUE_SMOOTH(src) . = ..() /turf/simulated/floor/Initialize(mapload) diff --git a/code/game/turfs/simulated/floors/water.dm b/code/game/turfs/simulated/floors/water.dm index 3825963d258..5c66023d46b 100644 --- a/code/game/turfs/simulated/floors/water.dm +++ b/code/game/turfs/simulated/floors/water.dm @@ -7,6 +7,7 @@ var/water_state = "water_shallow" var/under_state = "rock" edge_blending_priority = -1 + edge_icon_state = "water_shallow" movement_cost = 4 outdoors = TRUE @@ -32,9 +33,6 @@ var/image/water_sprite = image(icon = 'icons/turf/outdoors.dmi', icon_state = water_state, layer = WATER_LAYER) add_overlay(water_sprite) -/turf/simulated/floor/water/get_edge_icon_state() - return "water_shallow" - /turf/simulated/floor/water/attackby(obj/item/O as obj, mob/user as mob) var/obj/item/reagent_containers/RG = O if (istype(RG) && RG.is_open_container()) @@ -226,9 +224,6 @@ turf/simulated/floor/water/contaminated/Entered(atom/movable/AM, atom/oldloc) var/image/acid_sprite = image(icon = 'icons/turf/outdoors.dmi', icon_state = acid_state, layer = WATER_LAYER) add_overlay(acid_sprite) -/turf/simulated/floor/water/acid/get_edge_icon_state() - return "acid_shallow" - /turf/simulated/floor/water/acid/return_air_for_internal_lifeform(var/mob/living/L) if(L && L.lying) if(L.can_breathe_water()) // For squid. @@ -340,9 +335,6 @@ turf/simulated/floor/water/contaminated/Entered(atom/movable/AM, atom/oldloc) var/image/blood_sprite = image(icon = 'icons/turf/outdoors.dmi', icon_state = blood_state, layer = WATER_LAYER) add_overlay(blood_sprite) -/turf/simulated/floor/water/blood/get_edge_icon_state() - return "acidb_shallow" - /turf/simulated/floor/water/blood/return_air_for_internal_lifeform(var/mob/living/L) if(L && L.lying) if(L.can_breathe_water()) // For squid. diff --git a/code/game/turfs/simulated/misc/fancy_shuttles.dm b/code/game/turfs/simulated/misc/fancy_shuttles.dm index a7f74361660..6a0c0d44d70 100644 --- a/code/game/turfs/simulated/misc/fancy_shuttles.dm +++ b/code/game/turfs/simulated/misc/fancy_shuttles.dm @@ -128,7 +128,7 @@ GLOBAL_LIST_EMPTY(fancy_shuttles) // Trust me, this is WAY faster than the normal wall overlays shenanigans, don't worry about performance /turf/simulated/wall/fancy_shuttle/update_icon() if(!damage_overlays[1]) - generate_overlays() + generate_damage_overlays() cut_overlays() if(fancy_shuttle_tag) // after a shuttle jump it won't be set anymore, but the shuttle jump proc will set our icon and state diff --git a/code/game/turfs/simulated/wall.dm b/code/game/turfs/simulated/wall.dm index 7ab7bfb611c..799b9db8465 100644 --- a/code/game/turfs/simulated/wall.dm +++ b/code/game/turfs/simulated/wall.dm @@ -15,6 +15,7 @@ thermal_conductivity = WALL_HEAT_TRANSFER_COEFFICIENT heat_capacity = 312500 //a little over 5 cm thick , 312500 for 1 m by 2.5 m by 0.25 m plasteel wall baseturfs = /turf/simulated/floor/plating + smoothing_flags = SMOOTH_CUSTOM var/icon/wall_masks = 'icons/turf/wall_masks.dmi' var/damage = 0 diff --git a/code/game/turfs/simulated/wall_icon.dm b/code/game/turfs/simulated/wall_icon.dm index c02deff96e7..f23589c6eb5 100644 --- a/code/game/turfs/simulated/wall_icon.dm +++ b/code/game/turfs/simulated/wall_icon.dm @@ -6,10 +6,10 @@ var/amt = 16 var/alpha_inc = 256 / 16 var/list/generated = list() - generated.len = mat + generated.len = amt . = generated for(var/i in 1 to 16) - var/image/I = imiage(icon = 'icons/turf/wall/damage_masks.dmi') + var/image/I = image(icon = 'icons/turf/wall/damage_masks.dmi', icon_state = "overlay_damage") I.blend_mode = BLEND_MULTIPLY I.alpha = (i * alpha_inc) - 1 damage_overlays[i] = I diff --git a/code/game/turfs/simulated/walls/dungeon.dm b/code/game/turfs/simulated/walls/dungeon.dm index 362889c13a5..f798fc90cfc 100644 --- a/code/game/turfs/simulated/walls/dungeon.dm +++ b/code/game/turfs/simulated/walls/dungeon.dm @@ -35,7 +35,6 @@ /turf/simulated/wall/solidrock/Initialize(mapload) . = ..() icon_state = base_state - update_icon(1) // TODO: /tg/ icon smoothing /turf/simulated/wall/solidrock/attackby() return diff --git a/code/modules/multiz/basic.dm b/code/modules/multiz/basic.dm index 6854792eefb..d7f752e1441 100644 --- a/code/modules/multiz/basic.dm +++ b/code/modules/multiz/basic.dm @@ -36,6 +36,12 @@ var/list/z_levels = list()// Each bit re... haha just kidding this is a list of return null return HasBelow(turf.z) ? get_step(turf, DOWN) : null +/turf/proc/Above() + return HasAbove(z)? get_step(src, UP) : null + +/turf/proc/Below() + return HasBelow(z)? get_step(src, DOWN) : null + /proc/GetConnectedZlevels(z) . = list(z) for(var/level = z, HasBelow(level), level--)