diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm index 3e571009d27..f89aa2edc91 100644 --- a/code/game/objects/structures.dm +++ b/code/game/objects/structures.dm @@ -8,11 +8,21 @@ 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 = list("0", "0", "0", "0") + var/list/other_connections = list("0", "0", "0", "0") + var/list/blend_objects = newlist() // Objects which to blend with + var/list/noblend_objects = newlist() //Objects to avoid blending with (such as children of listed blend objects. + +/obj/structure/Initialize() + . = ..() + if(climbable) + verbs += /obj/structure/proc/climb_on /obj/structure/Destroy() if(parts) new parts(loc) - . = ..() + return ..() /obj/structure/attack_hand(mob/user) if(breakable) @@ -46,13 +56,7 @@ if(3.0) return -/obj/structure/New() - ..() - if(climbable) - verbs += /obj/structure/proc/climb_on - /obj/structure/proc/climb_on() - set name = "Climb structure" set desc = "Climbs onto a structure." set category = "Object" @@ -61,7 +65,6 @@ do_climb(usr) /obj/structure/MouseDrop_T(mob/target, mob/user) - var/mob/living/H = user if(istype(H) && can_climb(H) && target == user) do_climb(target) @@ -185,3 +188,72 @@ user.do_attack_animation(src) spawn(1) qdel(src) return 1 + +/obj/structure/proc/can_visually_connect() + return anchored + +/obj/structure/proc/can_visually_connect_to(var/obj/structure/S) + return istype(S, src) + +/obj/structure/proc/update_connections(propagate = 0) + var/list/dirs = list() + var/list/other_dirs = list() + + for(var/obj/structure/S in orange(src, 1)) + if(can_visually_connect_to(S)) + if(S.can_visually_connect()) + if(propagate) + //S.update_connections() //Not here + S.update_icon() + dirs += get_dir(src, S) + + if(!can_visually_connect()) + connections = list("0", "0", "0", "0") + other_connections = list("0", "0", "0", "0") + return FALSE + + for(var/direction in cardinal) + var/turf/T = get_step(src, direction) + var/success = 0 + for(var/b_type in blend_objects) + if(istype(T, b_type)) + success = 1 + if(propagate) + var/turf/simulated/wall/W = T + if(istype(W)) + W.update_connections(1) + if(success) + break + if(success) + break + if(!success) + for(var/obj/O in T) + for(var/b_type in blend_objects) + if(istype(O, b_type)) + success = 1 + for(var/obj/structure/S in T) + if(istype(S, src)) + success = 0 + for(var/nb_type in noblend_objects) + if(istype(O, nb_type)) + success = 0 + + if(success) + break + if(success) + break + + if(success) + dirs += get_dir(src, T) + other_dirs += get_dir(src, T) + + refresh_neighbors() + + connections = dirs_to_corner_states(dirs) + other_connections = dirs_to_corner_states(other_dirs) + return TRUE + +/obj/structure/proc/refresh_neighbors() + for(var/thing in RANGE_TURFS(1, src)) + var/turf/T = thing + T.update_icon() diff --git a/code/game/objects/structures/catwalk.dm b/code/game/objects/structures/catwalk.dm index 26e040c7e9e..325cfff923b 100644 --- a/code/game/objects/structures/catwalk.dm +++ b/code/game/objects/structures/catwalk.dm @@ -1,102 +1,111 @@ -// Based on catwalk.dm from https://github.com/Endless-Horizon/CEV-Eris /obj/structure/catwalk name = "catwalk" desc = "Cats really don't like these things." - plane = DECAL_PLANE - layer = ABOVE_UTILITY icon = 'icons/turf/catwalks.dmi' icon_state = "catwalk" + plane = DECAL_PLANE + layer = ABOVE_UTILITY density = 0 + anchored = 1.0 + var/hatch_open = FALSE + var/plating_color = null + var/obj/item/stack/tile/plated_tile = null + var/static/plating_colors = list( + /obj/item/stack/tile/floor = "#858a8f", + /obj/item/stack/tile/floor/dark = "#4f4f4f", + /obj/item/stack/tile/floor/white = "#e8e8e8") var/health = 100 var/maxhealth = 100 - anchored = 1.0 /obj/structure/catwalk/Initialize() . = ..() - for(var/obj/structure/catwalk/O in range(1)) - O.update_icon() for(var/obj/structure/catwalk/C in get_turf(src)) if(C != src) - warning("Duplicate [type] in [loc] ([x], [y], [z])") - return INITIALIZE_HINT_QDEL + qdel(C) + update_connections(1) update_icon() + /obj/structure/catwalk/Destroy() - var/turf/location = loc - . = ..() - location.alpha = initial(location.alpha) - for(var/obj/structure/catwalk/L in orange(location, 1)) - L.update_icon() + redraw_nearby_catwalks() + return ..() + +/obj/structure/catwalk/proc/redraw_nearby_catwalks() + for(var/direction in alldirs) + var/obj/structure/catwalk/L = locate() in get_step(src, direction) + if(L) + L.update_connections() + L.update_icon() //so siding get updated properly + /obj/structure/catwalk/update_icon() - var/connectdir = 0 - for(var/direction in cardinal) - if(locate(/obj/structure/catwalk, get_step(src, direction))) - connectdir |= direction - - //Check the diagonal connections for corners, where you have, for example, connections both north and east. In this case it checks for a north-east connection to determine whether to add a corner marker or not. - var/diagonalconnect = 0 //1 = NE; 2 = SE; 4 = NW; 8 = SW - //NORTHEAST - if(connectdir & NORTH && connectdir & EAST) - if(locate(/obj/structure/catwalk, get_step(src, NORTHEAST))) - diagonalconnect |= 1 - //SOUTHEAST - if(connectdir & SOUTH && connectdir & EAST) - if(locate(/obj/structure/catwalk, get_step(src, SOUTHEAST))) - diagonalconnect |= 2 - //NORTHWEST - if(connectdir & NORTH && connectdir & WEST) - if(locate(/obj/structure/catwalk, get_step(src, NORTHWEST))) - diagonalconnect |= 4 - //SOUTHWEST - if(connectdir & SOUTH && connectdir & WEST) - if(locate(/obj/structure/catwalk, get_step(src, SOUTHWEST))) - diagonalconnect |= 8 - - icon_state = "catwalk[connectdir]-[diagonalconnect]" - + update_connections() + cut_overlays() + icon_state = "" + var/image/I + if(!hatch_open) + for(var/i = 1 to 4) + I = image(icon, "catwalk[connections[i]]", dir = 1<<(i-1)) + add_overlay(I) + if(plating_color) + I = image(icon, "plated") + I.color = plating_color + add_overlay(I) /obj/structure/catwalk/ex_act(severity) switch(severity) - if(1.0) + if(1) + new /obj/item/stack/rods(src.loc) qdel(src) - if(2.0) + if(2) + new /obj/item/stack/rods(src.loc) qdel(src) - if(3.0) - qdel(src) - return + +/obj/structure/catwalk/attack_robot(var/mob/user) + if(Adjacent(user)) + attack_hand(user) + +/obj/structure/catwalk/proc/deconstruct(mob/user) + playsound(src, 'sound/items/Welder.ogg', 100, 1) + to_chat(user, "Slicing \the [src] joints ...") + new /obj/item/stack/rods(src.loc) + new /obj/item/stack/rods(src.loc) + //Lattice would delete itself, but let's save ourselves a new obj + if(istype(src.loc, /turf/space) || istype(src.loc, /turf/simulated/open)) + new /obj/structure/lattice/(src.loc) + if(plated_tile) + new plated_tile(src.loc) + qdel(src) /obj/structure/catwalk/attackby(obj/item/C as obj, mob/user as mob) - if(istype(C, /obj/item/weapon/weldingtool)) - var/obj/item/weapon/weldingtool/WT = C - if(WT.isOn()) - if(WT.remove_fuel(0, user)) - to_chat(user, "Slicing lattice joints ...") - new /obj/item/stack/rods(src.loc) - new /obj/item/stack/rods(src.loc) - new /obj/structure/lattice(src.loc) - qdel(src) - if(C.is_screwdriver()) - if(health < maxhealth) - to_chat(user, "You begin repairing \the [src.name] with \the [C.name].") - if(do_after(user, 20, src)) - health = maxhealth - else - take_damage(C.force) - user.setClickCooldown(user.get_attack_speed(C)) - return ..() + if(C.is_crowbar() && plated_tile) + hatch_open = !hatch_open + if(hatch_open) + playsound(src, 'sound/items/Crowbar.ogg', 100, 2) + to_chat(user, "You pry open \the [src]'s maintenance hatch.") + else + playsound(src, 'sound/items/Deconstruct.ogg', 100, 2) + to_chat(user, "You shut \the [src]'s maintenance hatch.") + update_icon() + return + if(istype(C, /obj/item/stack/tile/floor) && !plated_tile) + var/obj/item/stack/tile/floor/ST = C + to_chat(user, "Placing tile...") + if (!do_after(user, 10)) + return + if(!ST.use(1)) + return + to_chat(user, "You plate \the [src]") + name = "plated catwalk" + plated_tile = C.type + src.add_fingerprint(user) + for(var/tiletype in plating_colors) + if(istype(ST, tiletype)) + plating_color = plating_colors[tiletype] + update_icon() -/obj/structure/catwalk/Crossed() - . = ..() - if(isliving(usr) && !usr.is_incorporeal()) - playsound(src, pick('sound/effects/footstep/catwalk1.ogg', 'sound/effects/footstep/catwalk2.ogg', 'sound/effects/footstep/catwalk3.ogg', 'sound/effects/footstep/catwalk4.ogg', 'sound/effects/footstep/catwalk5.ogg'), 25, 1) - -/obj/structure/catwalk/CheckExit(atom/movable/O, turf/target) - if(O.checkpass(PASSGRILLE)) - return 1 - if(target && target.z < src.z) - return 0 - return 1 +/obj/structure/catwalk/refresh_neighbors() + return /obj/structure/catwalk/take_damage(amount) health -= amount @@ -104,4 +113,67 @@ visible_message("\The [src] breaks down!") playsound(loc, 'sound/effects/grillehit.ogg', 50, 1) new /obj/item/stack/rods(get_turf(src)) - Destroy() \ No newline at end of file + Destroy() + +/obj/structure/catwalk/Crossed() + . = ..() + if(isliving(usr) && !usr.is_incorporeal()) + playsound(src, pick('sound/effects/footstep/catwalk1.ogg', 'sound/effects/footstep/catwalk2.ogg', 'sound/effects/footstep/catwalk3.ogg', 'sound/effects/footstep/catwalk4.ogg', 'sound/effects/footstep/catwalk5.ogg'), 25, 1) + +/obj/effect/catwalk_plated + name = "plated catwalk spawner" + icon = 'icons/turf/catwalks.dmi' + icon_state = "catwalk_plated" + density = 1 + anchored = 1.0 + var/activated = FALSE + plane = DECAL_PLANE + layer = ABOVE_UTILITY + var/tile = /obj/item/stack/tile/floor + var/platecolor = "#858a8f" + +/obj/effect/catwalk_plated/Initialize(mapload) + . = ..() + if(SSticker?.current_state < GAME_STATE_PLAYING) + activate() + +/obj/effect/catwalk_plated/CanPass() + return 0 + +/obj/effect/catwalk_plated/attack_hand() + attack_generic() + +/obj/effect/catwalk_plated/attack_ghost() + attack_generic() + +/obj/effect/catwalk_plated/attack_generic() + activate() + +/obj/effect/catwalk_plated/proc/activate() + if(activated) return + + if(locate(/obj/structure/catwalk) in loc) + warning("Frame Spawner: A catwalk already exists at [loc.x]-[loc.y]-[loc.z]") + else + var/obj/structure/catwalk/C = new /obj/structure/catwalk(loc) + C.plated_tile = tile + C.plating_color = platecolor + C.name = "plated catwalk" + C.update_icon() + activated = 1 + /* We don't have wallframes - yet + for(var/turf/T in orange(src, 1)) + for(var/obj/effect/wallframe_spawn/other in T) + if(!other.activated) other.activate() + */ + qdel(src) + +/obj/effect/catwalk_plated/dark + icon_state = "catwalk_plateddark" + tile = /obj/item/stack/tile/floor/dark + platecolor = "#4f4f4f" + +/obj/effect/catwalk_plated/white + icon_state = "catwalk_platedwhite" + tile = /obj/item/stack/tile/floor/white + platecolor = "#e8e8e8" diff --git a/code/modules/tables/tables.dm b/code/modules/tables/tables.dm index 31b112e9bdf..f853e224fcb 100644 --- a/code/modules/tables/tables.dm +++ b/code/modules/tables/tables.dm @@ -28,8 +28,6 @@ var/list/table_icon_cache = list() var/carpeted = 0 var/carpeted_type = /obj/item/stack/tile/carpet - var/list/connections = list("nw0", "ne0", "sw0", "se0") - var/item_place = 1 //allows items to be placed on the table, but not on benches. /obj/structure/table/proc/update_material() @@ -402,60 +400,6 @@ var/list/table_icon_cache = list() if(carpeted) overlays += "carpet_flip[type]" -// set propagate if you're updating a table that should update tables around it too, for example if it's a new table or something important has changed (like material). -/obj/structure/table/proc/update_connections(propagate=0) - if(!material) - connections = list("0", "0", "0", "0") - - if(propagate) - for(var/obj/structure/table/T in oview(src, 1)) - T.update_connections() - return - - var/list/blocked_dirs = list() - for(var/obj/structure/window/W in get_turf(src)) - if(W.is_fulltile()) - connections = list("0", "0", "0", "0") - return - blocked_dirs |= W.dir - - for(var/D in list(NORTH, SOUTH, EAST, WEST) - blocked_dirs) - var/turf/T = get_step(src, D) - for(var/obj/structure/window/W in T) - if(W.is_fulltile() || W.dir == reverse_dir[D]) - blocked_dirs |= D - break - else - if(W.dir != D) // it's off to the side - blocked_dirs |= W.dir|D // blocks the diagonal - - for(var/D in list(NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST) - blocked_dirs) - var/turf/T = get_step(src, D) - - for(var/obj/structure/window/W in T) - if(W.is_fulltile() || W.dir & reverse_dir[D]) - blocked_dirs |= D - break - - // Blocked cardinals block the adjacent diagonals too. Prevents weirdness with tables. - for(var/x in list(NORTH, SOUTH)) - for(var/y in list(EAST, WEST)) - if((x in blocked_dirs) || (y in blocked_dirs)) - blocked_dirs |= x|y - - var/list/connection_dirs = list() - - for(var/obj/structure/table/T in orange(src, 1)) - var/T_dir = get_dir(src, T) - if(T_dir in blocked_dirs) continue - if(material && T.material && material.name == T.material.name && flipped == T.flipped) - connection_dirs |= T_dir - if(propagate) - spawn(0) - T.update_connections() - T.update_icon() - - connections = dirs_to_corner_states(connection_dirs) #define CORNER_NONE 0 #define CORNER_COUNTERCLOCKWISE 1 diff --git a/icons/turf/catwalks.dmi b/icons/turf/catwalks.dmi index 9e3d3d977ca..20c5e1f4d98 100644 Binary files a/icons/turf/catwalks.dmi and b/icons/turf/catwalks.dmi differ