diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index dcb78253f35..e1a9f895ea5 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -16,11 +16,9 @@ var/obj/item/airlock_electronics/electronics var/base_state = "left" var/reinf = 0 - var/cancolor = TRUE var/shards = 2 var/rods = 2 var/cable = 1 - var/list/debris = list() /obj/machinery/door/window/New(loc, set_dir) ..() @@ -29,18 +27,9 @@ if(req_access && req_access.len) icon_state = "[icon_state]" base_state = icon_state - if(!color && cancolor) - color = color_windows(src) - for(var/i in 1 to shards) - debris += new /obj/item/shard(src) - if(rods) - debris += new /obj/item/stack/rods(src, rods) - if(cable) - debris += new /obj/item/stack/cable_coil(src, cable) /obj/machinery/door/window/Destroy() density = FALSE - QDEL_LIST(debris) if(obj_integrity == 0) playsound(src, "shatter", 70, 1) QDEL_NULL(electronics) @@ -190,12 +179,19 @@ /obj/machinery/door/window/deconstruct(disassembled = TRUE) if(!(flags & NODECONSTRUCT) && !disassembled) - for(var/obj/fragment in debris) - fragment.forceMove(get_turf(src)) - transfer_fingerprints_to(fragment) - debris -= fragment + for(var/obj/item/shard/debris in spawnDebris(drop_location())) + transfer_fingerprints_to(debris) // transfer fingerprints to shards only qdel(src) +/obj/machinery/door/window/proc/spawnDebris(location) + . = list() + for(var/i in 1 to shards) + . += new /obj/item/shard(location) + if(rods) + . += new /obj/item/stack/rods(location, rods) + if(cable) + . += new /obj/item/stack/cable_coil(location, cable) + /obj/machinery/door/window/narsie_act() color = NARSIE_WINDOW_COLOUR @@ -349,12 +345,11 @@ shards = 0 rods = 0 resistance_flags = ACID_PROOF | FIRE_PROOF - cancolor = FALSE var/made_glow = FALSE -/obj/machinery/door/window/clockwork/New(loc, set_dir) - ..() - debris += new/obj/item/stack/tile/brass(src, 2) +/obj/machinery/door/window/clockwork/spawnDebris(location) + . = ..() + . = new /obj/item/stack/tile/brass(location, 2) /obj/machinery/door/window/clockwork/setDir(direct) if(!made_glow) diff --git a/code/game/objects/effects/decals/Cleanable/misc.dm b/code/game/objects/effects/decals/Cleanable/misc.dm index a8510ddc102..721b28d09fd 100644 --- a/code/game/objects/effects/decals/Cleanable/misc.dm +++ b/code/game/objects/effects/decals/Cleanable/misc.dm @@ -18,6 +18,22 @@ scoop_reagents = list("ash" = 10) mergeable_decal = FALSE +/obj/effect/decal/cleanable/glass + name = "tiny shards" + desc = "Back to sand." + icon = 'icons/obj/shards.dmi' + icon_state = "tiny" + +/obj/effect/decal/cleanable/glass/Initialize(mapload) + . = ..() + setDir(pick(GLOB.cardinal)) + +/obj/effect/decal/cleanable/glass/ex_act() + qdel(src) + +/obj/effect/decal/cleanable/glass/plasma + icon_state = "plasmatiny" + /obj/effect/decal/cleanable/dirt name = "dirt" desc = "Someone should clean that up." diff --git a/code/game/objects/effects/spawners/windowspawner.dm b/code/game/objects/effects/spawners/windowspawner.dm index cf29d86a450..1e81177c53f 100644 --- a/code/game/objects/effects/spawners/windowspawner.dm +++ b/code/game/objects/effects/spawners/windowspawner.dm @@ -2,12 +2,13 @@ name = "window spawner" icon = 'icons/obj/structures.dmi' icon_state = "window_spawner" - var/useFull = 0 - var/useGrille = 1 - var/windowtospawn = /obj/structure/window/basic - anchored = 1 // No sliding out while you prime + var/useFull = TRUE + var/useGrille = TRUE + var/window_to_spawn_regular = /obj/structure/window/basic + var/window_to_spawn_full = /obj/structure/window/full/basic + anchored = TRUE // No sliding out while you prime -/obj/effect/spawner/window/Initialize() +/obj/effect/spawner/window/Initialize(mapload) . = ..() var/turf/T = get_turf(src) for(var/obj/structure/grille/G in get_turf(src)) @@ -20,35 +21,33 @@ for(var/obj/effect/spawner/window/WS in get_step(src,cdir)) cdir = null break - if(!cdir) continue - var/obj/structure/window/WI = new windowtospawn(get_turf(src)) + if(!cdir) + continue + var/obj/structure/window/WI = new window_to_spawn_regular(get_turf(src)) WI.dir = cdir else - var/obj/structure/window/W = new windowtospawn(get_turf(src)) - W.dir = SOUTHWEST + new window_to_spawn_full(get_turf(src)) if(useGrille) new /obj/structure/grille(get_turf(src)) - src.air_update_turf(1) //atmos can pass otherwise - // Give some time for nearby window spawners to initialize - spawn(10) - qdel(src) - // why is this line a no-op - // QDEL_IN(src, 10) + air_update_turf(TRUE) //atmos can pass otherwise + return INITIALIZE_HINT_QDEL /obj/effect/spawner/window/reinforced name = "reinforced window spawner" icon_state = "rwindow_spawner" - windowtospawn = /obj/structure/window/reinforced + window_to_spawn_regular = /obj/structure/window/reinforced + window_to_spawn_full = /obj/structure/window/full/reinforced /obj/effect/spawner/window/reinforced/plasma name = "reinforced plasma window spawner" icon_state = "pwindow_spawner" - windowtospawn = /obj/structure/window/plasmareinforced + window_to_spawn_regular = /obj/structure/window/plasmareinforced + window_to_spawn_full = /obj/structure/window/full/plasmareinforced /obj/effect/spawner/window/shuttle name = "shuttle window spawner" icon_state = "swindow_spawner" - windowtospawn = /obj/structure/window/shuttle + window_to_spawn_full = /obj/structure/window/shuttle diff --git a/code/game/objects/items/weapons/RCD.dm b/code/game/objects/items/weapons/RCD.dm index c65410b5129..92d13337766 100644 --- a/code/game/objects/items/weapons/RCD.dm +++ b/code/game/objects/items/weapons/RCD.dm @@ -492,17 +492,6 @@ QDEL_NULL(A) for(var/obj/structure/window/W in T1.contents) qdel(W) - for(var/cdir in GLOB.cardinal) - var/turf/T2 = get_step(T1, cdir) - if(locate(/obj/structure/window/full/shuttle) in T2) - continue // Shuttle windows? Nah. We don't need extra windows there. - if(!(locate(/obj/structure/grille) in T2)) - continue - for(var/obj/structure/window/W in T2) - if(W.dir == turn(cdir, 180)) - qdel(W) - var/obj/structure/window/reinforced/W = new(T2) - W.dir = turn(cdir, 180) return TRUE return FALSE @@ -535,15 +524,7 @@ new /obj/structure/grille(A) for(var/obj/structure/window/W in A) qdel(W) - for(var/cdir in GLOB.cardinal) - var/turf/T = get_step(A, cdir) - if(locate(/obj/structure/grille) in T) - for(var/obj/structure/window/W in T) - if(W.dir == turn(cdir, 180)) - qdel(W) - else // Build a window! - var/obj/structure/window/reinforced/W = new(A) - W.dir = cdir + new /obj/structure/window/full/reinforced(A) var/turf/AT = A AT.ChangeTurf(/turf/simulated/floor/plating) // Platings go under windows. return TRUE diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index b4747d1c67f..3e2a96ff75a 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -160,54 +160,37 @@ "You [anchored ? "fasten [src] to" : "unfasten [src] from"] the floor.") /obj/structure/grille/proc/build_window(obj/item/stack/sheet/S, mob/user) - var/dir_to_set = NORTH + var/dir_to_set = SOUTHWEST if(!istype(S) || !user) return if(broken) to_chat(user, "You must repair or replace [src] first!") return - if(S.get_amount() < 1) - to_chat(user, "You need at least one sheet of glass for that!") + if(S.get_amount() < 2) + to_chat(user, "You need at least two sheets of glass for that!") return if(!anchored) to_chat(user, "[src] needs to be fastened to the floor first!") return - if(!getRelativeDirection(src, user) && (user.loc != loc)) //essentially a cardinal direction adjacent or sharing same loc check - to_chat(user, "You can't reach.") - return - if(loc == user.loc) - dir_to_set = user.dir - else - if(x == user.x) - if(y > user.y) - dir_to_set = SOUTH - else - dir_to_set = NORTH - else if(y == user.y) - if(x > user.x) - dir_to_set = WEST - else - dir_to_set = EAST for(var/obj/structure/window/WINDOW in loc) - if(WINDOW.dir == dir_to_set) - to_chat(user, "There is already a window facing this way there.") - return + to_chat(user, "There is already a window there!") + return to_chat(user, "You start placing the window...") if(do_after(user, 20, target = src)) if(!loc || !anchored) //Grille destroyed or unanchored while waiting return - for(var/obj/structure/window/WINDOW in loc) - if(WINDOW.dir == dir_to_set)//checking this for a 2nd time to check if a window was made while we were waiting. - to_chat(user, "There is already a window facing this way there.") - return - var/obj/structure/window/W = new S.created_window(get_turf(src)) - S.use(1) + for(var/obj/structure/window/WINDOW in loc) //checking this for a 2nd time to check if a window was made while we were waiting. + to_chat(user, "There is already a window there!") + return + var/obj/structure/window/W = new S.full_window(drop_location()) W.setDir(dir_to_set) W.ini_dir = dir_to_set W.anchored = FALSE - W.state = WINDOW_OUT_OF_FRAME - to_chat(user, "You place the [W] on [src].") + air_update_turf(TRUE) W.update_nearby_icons() + W.state = WINDOW_OUT_OF_FRAME + S.use(2) + to_chat(user, "You place the [W] on [src].") /obj/structure/grille/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 2382688232b..afdfdfbd6ef 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -1,26 +1,3 @@ -GLOBAL_LIST_INIT(wcBar, pick(list("#0d8395", "#58b5c3", "#58c366", "#90d79a", "#ffffff"))) -GLOBAL_LIST_INIT(wcBrig, pick(list("#aa0808", "#7f0606", "#ff0000"))) -GLOBAL_LIST_INIT(wcCommon, pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", "#8fcf44", "#ffffff"))) - -/obj/proc/color_windows(obj/W) - var/list/wcBarAreas = list(/area/crew_quarters/bar) - var/list/wcBrigAreas = list(/area/security, /area/shuttle/gamma) - - var/newcolor - var/turf/T = get_turf(W) - if(!istype(T)) - return - var/area/A = T.loc - - if(is_type_in_list(A,wcBarAreas)) - newcolor = GLOB.wcBar - else if(is_type_in_list(A,wcBrigAreas)) - newcolor = GLOB.wcBrig - else - newcolor = GLOB.wcCommon - - return newcolor - /obj/structure/window name = "window" desc = "A window." @@ -43,11 +20,10 @@ GLOBAL_LIST_INIT(wcCommon, pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", var/decon_speed = null var/fulltile = FALSE var/shardtype = /obj/item/shard + var/glass_decal = /obj/effect/decal/cleanable/glass var/glass_type = /obj/item/stack/sheet/glass var/glass_amount = 1 - var/cancolor = FALSE - var/image/crack_overlay - var/list/debris = list() + var/mutable_appearance/crack_overlay var/real_explosion_block //ignore this, just use explosion_block var/breaksound = "shatter" var/hitsound = 'sound/effects/Glasshit.ogg' @@ -81,30 +57,12 @@ GLOBAL_LIST_INIT(wcCommon, pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", ini_dir = dir - if(!color && cancolor) - color = color_windows(src) - - // Precreate our own debris - - var/shards = 1 if(fulltile) - shards++ setDir() if(decon_speed == null && fulltile) decon_speed = 2 SECONDS - var/rods = 0 - if(reinf) - rods++ - if(fulltile) - rods++ - - for(var/i in 1 to shards) - debris += new shardtype(src) - if(rods) - debris += new /obj/item/stack/rods(src, rods) - //windows only block while reinforced and fulltile, so we'll use the proc real_explosion_block = explosion_block explosion_block = EXPLOSION_BLOCK_PROC @@ -113,8 +71,6 @@ GLOBAL_LIST_INIT(wcCommon, pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", /obj/structure/window/narsie_act() color = NARSIE_WINDOW_COLOUR - for(var/obj/item/shard/shard in debris) - shard.color = NARSIE_WINDOW_COLOUR /obj/structure/window/ratvar_act() if(!fulltile) @@ -324,6 +280,7 @@ GLOBAL_LIST_INIT(wcCommon, pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", WELDER_ATTEMPT_REPAIR_MESSAGE if(I.use_tool(src, user, 40, volume = I.tool_volume)) obj_integrity = max_integrity + update_nearby_icons() WELDER_REPAIR_SUCCESS_MESSAGE /obj/structure/window/proc/check_state(checked_state) @@ -371,13 +328,20 @@ GLOBAL_LIST_INIT(wcCommon, pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", if(!disassembled) playsound(src, breaksound, 70, 1) if(!(flags & NODECONSTRUCT)) - for(var/i in debris) - var/obj/item/I = i - I.forceMove(loc) - transfer_fingerprints_to(I) + for(var/obj/item/shard/debris in spawnDebris(drop_location())) + transfer_fingerprints_to(debris) // transfer fingerprints to shards only qdel(src) update_nearby_icons() +/obj/structure/window/proc/spawnDebris(location) + . = list() + . += new shardtype(location) + . += new glass_decal(location) + if(reinf) + . += new /obj/item/stack/rods(location, (fulltile ? 2 : 1)) + if(fulltile) + . += new shardtype(location) + /obj/structure/window/verb/rotate() set name = "Rotate Window Counter-Clockwise" set category = "Object" @@ -479,14 +443,16 @@ GLOBAL_LIST_INIT(wcCommon, pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", if(!fulltile) return var/ratio = obj_integrity / max_integrity - ratio = CEILING(ratio*4, 1) * 25 + ratio = CEILING(ratio * 4, 1) * 25 + if(smooth) queue_smooth(src) - overlays -= crack_overlay + + cut_overlay(crack_overlay) if(ratio > 75) return - crack_overlay = image('icons/obj/structures.dmi',"damage[ratio]",-(layer+0.1)) - overlays += crack_overlay + crack_overlay = mutable_appearance('icons/obj/structures.dmi', "damage[ratio]", -(layer+0.1)) + add_overlay(crack_overlay) /obj/structure/window/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) ..() @@ -504,7 +470,6 @@ GLOBAL_LIST_INIT(wcCommon, pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", desc = "It looks rather strong. Might take a few good hits to shatter it." icon_state = "rwindow" reinf = TRUE - cancolor = TRUE heat_resistance = 1600 armor = list("melee" = 50, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 25, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 100) rad_insulation = RAD_HEAVY_INSULATION @@ -576,6 +541,7 @@ GLOBAL_LIST_INIT(wcCommon, pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", name = "plasma window" desc = "A window made out of a plasma-silicate alloy. It looks insanely tough to break and burn through." icon_state = "plasmawindow" + glass_decal = /obj/effect/decal/cleanable/glass/plasma shardtype = /obj/item/shard/plasma glass_type = /obj/item/stack/sheet/plasmaglass heat_resistance = 32000 @@ -591,6 +557,7 @@ GLOBAL_LIST_INIT(wcCommon, pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", name = "reinforced plasma window" desc = "A plasma-glass alloy window, with rods supporting it. It looks hopelessly tough to break. It also looks completely fireproof, considering how basic plasma windows are insanely fireproof." icon_state = "plasmarwindow" + glass_decal = /obj/effect/decal/cleanable/glass/plasma shardtype = /obj/item/shard/plasma glass_type = /obj/item/stack/sheet/plasmarglass reinf = TRUE @@ -619,7 +586,6 @@ GLOBAL_LIST_INIT(wcCommon, pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", icon_state = "window" max_integrity = 50 smooth = SMOOTH_TRUE - cancolor = TRUE canSmoothWith = list(/obj/structure/window/full/basic, /obj/structure/window/full/reinforced, /obj/structure/window/full/reinforced/tinted, /obj/structure/window/full/plasmabasic, /obj/structure/window/full/plasmareinforced) /obj/structure/window/full/plasmabasic @@ -627,6 +593,7 @@ GLOBAL_LIST_INIT(wcCommon, pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", desc = "A plasma-glass alloy window. It looks insanely tough to break. It appears it's also insanely tough to burn through." icon = 'icons/obj/smooth_structures/plasma_window.dmi' icon_state = "plasmawindow" + glass_decal = /obj/effect/decal/cleanable/glass/plasma shardtype = /obj/item/shard/plasma glass_type = /obj/item/stack/sheet/plasmaglass heat_resistance = 32000 @@ -642,6 +609,7 @@ GLOBAL_LIST_INIT(wcCommon, pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", desc = "A plasma-glass alloy window, with rods supporting it. It looks hopelessly tough to break. It also looks completely fireproof, considering how basic plasma windows are insanely fireproof." icon = 'icons/obj/smooth_structures/rplasma_window.dmi' icon_state = "rplasmawindow" + glass_decal = /obj/effect/decal/cleanable/glass/plasma shardtype = /obj/item/shard/plasma glass_type = /obj/item/stack/sheet/plasmarglass smooth = SMOOTH_TRUE @@ -668,7 +636,6 @@ GLOBAL_LIST_INIT(wcCommon, pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", rad_insulation = RAD_HEAVY_INSULATION explosion_block = 1 glass_type = /obj/item/stack/sheet/rglass - cancolor = TRUE /obj/structure/window/full/reinforced/tinted name = "tinted window" @@ -681,7 +648,6 @@ GLOBAL_LIST_INIT(wcCommon, pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", icon = 'icons/obj/smooth_structures/rice_window.dmi' icon_state = "ice_window" max_integrity = 150 - cancolor = FALSE /obj/structure/window/full/shuttle name = "shuttle window" @@ -734,19 +700,18 @@ GLOBAL_LIST_INIT(wcCommon, pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", explosion_block = 2 //fancy AND hard to destroy. the most useful combination. glass_type = /obj/item/stack/tile/brass reinf = FALSE - cancolor = FALSE var/made_glow = FALSE /obj/structure/window/reinforced/clockwork/Initialize(mapload, direct) . = ..() if(fulltile) made_glow = TRUE - QDEL_LIST(debris) if(fulltile) new /obj/effect/temp_visual/ratvar/window(get_turf(src)) - debris += new/obj/item/stack/tile/brass(src, 2) - else - debris += new/obj/item/stack/tile/brass(src, 1) + +/obj/structure/window/reinforced/clockwork/spawnDebris(location) + . = list() + . += new /obj/item/stack/tile/brass(location, (fulltile ? 2 : 1)) /obj/structure/window/reinforced/clockwork/setDir(direct) if(!made_glow) @@ -757,7 +722,7 @@ GLOBAL_LIST_INIT(wcCommon, pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", /obj/structure/window/reinforced/clockwork/ratvar_act() obj_integrity = max_integrity - update_icon() + update_nearby_icons() /obj/structure/window/reinforced/clockwork/narsie_act() take_damage(rand(25, 75), BRUTE) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 52125e9fd41..8eaadf52ab3 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -154,10 +154,16 @@ return FALSE //Finally, check objects/mobs to block entry that are not on the border + var/atom/movable/tompost_bump + var/top_layer = FALSE for(var/atom/movable/obstacle in large_dense) if(!obstacle.CanPass(mover, mover.loc, 1) && (forget != obstacle)) - mover.Bump(obstacle, TRUE) - return FALSE + if(obstacle.layer > top_layer) + tompost_bump = obstacle + top_layer = obstacle.layer + if(tompost_bump) + mover.Bump(tompost_bump, TRUE) + return FALSE return TRUE //Nothing found to block so return success! /turf/Entered(atom/movable/M, atom/OL, ignoreRest = FALSE) diff --git a/icons/obj/shards.dmi b/icons/obj/shards.dmi index 20927b8dd79..b136530df63 100644 Binary files a/icons/obj/shards.dmi and b/icons/obj/shards.dmi differ diff --git a/icons/obj/smooth_structures/plasma_window.dmi b/icons/obj/smooth_structures/plasma_window.dmi index 3d57d156f01..b5249e13a8a 100644 Binary files a/icons/obj/smooth_structures/plasma_window.dmi and b/icons/obj/smooth_structures/plasma_window.dmi differ diff --git a/icons/obj/smooth_structures/reinforced_window.dmi b/icons/obj/smooth_structures/reinforced_window.dmi index ed9a2a143e6..7c846fa4eee 100644 Binary files a/icons/obj/smooth_structures/reinforced_window.dmi and b/icons/obj/smooth_structures/reinforced_window.dmi differ diff --git a/icons/obj/smooth_structures/rplasma_window.dmi b/icons/obj/smooth_structures/rplasma_window.dmi index c64f42c7f5a..9da045e0350 100644 Binary files a/icons/obj/smooth_structures/rplasma_window.dmi and b/icons/obj/smooth_structures/rplasma_window.dmi differ diff --git a/icons/obj/smooth_structures/window.dmi b/icons/obj/smooth_structures/window.dmi index 670713bcfe0..a0d424f1957 100644 Binary files a/icons/obj/smooth_structures/window.dmi and b/icons/obj/smooth_structures/window.dmi differ diff --git a/icons/obj/structures.dmi b/icons/obj/structures.dmi index d1b6b267f8a..9bdcb4c3f7a 100644 Binary files a/icons/obj/structures.dmi and b/icons/obj/structures.dmi differ