From 1216f976635fd81ebdd6f83da931e032ef413dcb Mon Sep 17 00:00:00 2001 From: Atermonera Date: Sat, 14 Jul 2018 12:24:18 -0700 Subject: [PATCH] Adds roofing tiles (#5409) * Adds roofing tiles They're used to place plating overhead without going up a floor And to remove weather effects Changing a turf will correctly inherit the old outdoors variable, so that roofing tiles can check it when deciding whether to roof an area * Adds roofing tiles They're used to place plating overhead without going up a floor And to remove weather effects Changing a turf will correctly inherit the old outdoors variable, so that roofing tiles can check it when deciding whether to roof an area --- .../objects/items/stacks/tiles/tile_types.dm | 6 ++ code/game/turfs/simulated/floor_attackby.dm | 45 +++++++++ code/game/turfs/simulated/wall_attacks.dm | 94 ++++++++++++------- code/game/turfs/space/space.dm | 36 ++++++- code/game/turfs/turf_changing.dm | 2 + code/modules/materials/material_recipes.dm | 1 + html/changelogs/Atermonera - Ceilings.yml | 7 ++ 7 files changed, 154 insertions(+), 37 deletions(-) create mode 100644 html/changelogs/Atermonera - Ceilings.yml diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm index bc93d20bb5..17f4121a76 100644 --- a/code/game/objects/items/stacks/tiles/tile_types.dm +++ b/code/game/objects/items/stacks/tiles/tile_types.dm @@ -198,3 +198,9 @@ throw_range = 20 flags = 0 no_variants = FALSE + +/obj/item/stack/tile/roofing + name = "roofing" + singular_name = "roofing" + desc = "A section of roofing material. You can use it to repair the ceiling, or expand it." + icon_state = "techtile_grid" \ No newline at end of file diff --git a/code/game/turfs/simulated/floor_attackby.dm b/code/game/turfs/simulated/floor_attackby.dm index 91371e7beb..940e2df548 100644 --- a/code/game/turfs/simulated/floor_attackby.dm +++ b/code/game/turfs/simulated/floor_attackby.dm @@ -9,6 +9,51 @@ attack_tile(C, L) // Be on help intent if you want to decon something. return + if(istype(C, /obj/item/stack/tile/roofing)) + var/expended_tile = FALSE // To track the case. If a ceiling is built in a multiz zlevel, it also necessarily roofs it against weather + var/turf/T = GetAbove(src) + var/obj/item/stack/tile/roofing/R = C + + // Patch holes in the ceiling + if(T) + if(istype(T, /turf/simulated/open) || istype(T, /turf/space)) + // Must be build adjacent to an existing floor/wall, no floating floors + var/list/cardinalTurfs = list() // Up a Z level + for(var/dir in cardinal) + var/turf/B = get_step(T, dir) + if(B) + cardinalTurfs += B + + var/turf/simulated/A = locate(/turf/simulated/floor) in cardinalTurfs + if(!A) + A = locate(/turf/simulated/wall) in cardinalTurfs + if(!A) + to_chat(user, "There's nothing to attach the ceiling to!") + return + + if(R.use(1)) // Cost of roofing tiles is 1:1 with cost to place lattice and plating + T.ReplaceWithLattice() + T.ChangeTurf(/turf/simulated/floor) + playsound(src, 'sound/weapons/Genhit.ogg', 50, 1) + user.visible_message("[user] patches a hole in the ceiling.", "You patch a hole in the ceiling.") + expended_tile = TRUE + else + to_chat(user, "There aren't any holes in the ceiling to patch here.") + return + + // Create a ceiling to shield from the weather + if(src.outdoors) + for(var/dir in cardinal) + var/turf/A = get_step(src, dir) + if(A && !A.outdoors) + if(expended_tile || R.use(1)) + src.outdoors = FALSE + SSplanets.unallocateTurf(src) + playsound(src, 'sound/weapons/Genhit.ogg', 50, 1) + user.visible_message("[user] roofs a tile, shielding it from the elements.", "You roof this tile, shielding it from the elements.") + break + return + if(flooring) if(istype(C, /obj/item/weapon)) try_deconstruct_tile(C, user) diff --git a/code/game/turfs/simulated/wall_attacks.dm b/code/game/turfs/simulated/wall_attacks.dm index 1eaca16e76..4d87e2e87e 100644 --- a/code/game/turfs/simulated/wall_attacks.dm +++ b/code/game/turfs/simulated/wall_attacks.dm @@ -84,16 +84,16 @@ if(rotting) if(reinf_material) - user << "\The [reinf_material.display_name] feels porous and crumbly." + to_chat(user, "\The [reinf_material.display_name] feels porous and crumbly.") else - user << "\The [material.display_name] crumbles under your touch!" + to_chat(user, "\The [material.display_name] crumbles under your touch!") dismantle_wall() return 1 if(..()) return 1 if(!can_open) - user << "You push the wall, but nothing happens." + to_chat(user, "You push the wall, but nothing happens.") playsound(src, 'sound/weapons/Genhit.ogg', 25, 1) else toggle_open(user) @@ -138,28 +138,58 @@ user.setClickCooldown(user.get_attack_speed(W)) if (!user.) - user << "You don't have the dexterity to do this!" + to_chat(user, "You don't have the dexterity to do this!") return //get the user's location - if(!istype(user.loc, /turf)) return //can't do this stuff whilst inside objects and such + if(!istype(user.loc, /turf)) + return //can't do this stuff whilst inside objects and such if(W) radiate() if(is_hot(W)) burn(is_hot(W)) + if(istype(W, /obj/item/stack/tile/roofing)) + var/expended_tile = FALSE // To track the case. If a ceiling is built in a multiz zlevel, it also necessarily roofs it against weather + var/turf/T = GetAbove(src) + var/obj/item/stack/tile/roofing/R = W + + // Place plating over a wall + if(T) + if(istype(T, /turf/simulated/open) || istype(T, /turf/space)) + if(R.use(1)) // Cost of roofing tiles is 1:1 with cost to place lattice and plating + T.ReplaceWithLattice() + T.ChangeTurf(/turf/simulated/floor) + playsound(src, 'sound/weapons/Genhit.ogg', 50, 1) + user.visible_message("[user] patches a hole in the ceiling.", "You patch a hole in the ceiling.") + expended_tile = TRUE + else + to_chat(user, "There aren't any holes in the ceiling to patch here.") + return + + // Create a ceiling to shield from the weather + if(outdoors) + if(expended_tile || R.use(1)) // Don't need to check adjacent turfs for a wall, we're building on one + outdoors = FALSE + SSplanets.unallocateTurf(src) + if(!expended_tile) // Would've already played a sound + playsound(src, 'sound/weapons/Genhit.ogg', 50, 1) + user.visible_message("[user] roofs \the [src], shielding it from the elements.", "You roof \the [src] tile, shielding it from the elements.") + return + + if(locate(/obj/effect/overlay/wallrot) in src) if(istype(W, /obj/item/weapon/weldingtool) ) var/obj/item/weapon/weldingtool/WT = W if( WT.remove_fuel(0,user) ) - user << "You burn away the fungi with \the [WT]." + to_chat(user, "You burn away the fungi with \the [WT].") playsound(src, WT.usesound, 10, 1) for(var/obj/effect/overlay/wallrot/WR in src) qdel(WR) return else if(!is_sharp(W) && W.force >= 10 || W.force >= 20) - user << "\The [src] crumbles away under the force of your [W.name]." + to_chat(user, "\The [src] crumbles away under the force of your [W.name].") src.dismantle_wall(1) return @@ -179,7 +209,7 @@ var/obj/item/weapon/melee/energy/blade/EB = W EB.spark_system.start() - user << "You slash \the [src] with \the [EB]; the thermite ignites!" + to_chat(user, "You slash \the [src] with \the [EB]; the thermite ignites!") playsound(src, "sparks", 50, 1) playsound(src, 'sound/weapons/blade1.ogg', 50, 1) @@ -196,13 +226,13 @@ return if(WT.remove_fuel(0,user)) - user << "You start repairing the damage to [src]." + to_chat(user, "You start repairing the damage to [src].") playsound(src.loc, WT.usesound, 100, 1) if(do_after(user, max(5, damage / 5) * WT.toolspeed) && WT && WT.isOn()) - user << "You finish repairing the damage to [src]." + to_chat(user, "You finish repairing the damage to [src].") take_damage(-damage) else - user << "You need more welding fuel to complete this task." + to_chat(user, "You need more welding fuel to complete this task.") return user.update_examine_panel(src) return @@ -219,7 +249,7 @@ if(!WT.isOn()) return if(!WT.remove_fuel(0,user)) - user << "You need more welding fuel to complete this task." + to_chat(user, "You need more welding fuel to complete this task.") return dismantle_verb = "cutting" dismantle_sound = W.usesound @@ -236,7 +266,7 @@ if(dismantle_verb) - user << "You begin [dismantle_verb] through the outer plating." + to_chat(user, "You begin [dismantle_verb] through the outer plating.") if(dismantle_sound) playsound(src, dismantle_sound, 100, 1) @@ -246,7 +276,7 @@ if(!do_after(user,cut_delay * W.toolspeed)) return - user << "You remove the outer plating." + to_chat(user, "You remove the outer plating.") dismantle_wall() user.visible_message("The wall was torn open by [user]!") return @@ -259,24 +289,24 @@ playsound(src, W.usesound, 100, 1) construction_stage = 5 user.update_examine_panel(src) - user << "You cut through the outer grille." + to_chat(user, "You cut through the outer grille.") update_icon() return if(5) if (istype(W, /obj/item/weapon/screwdriver)) - user << "You begin removing the support lines." + to_chat(user, "You begin removing the support lines.") playsound(src, W.usesound, 100, 1) if(!do_after(user,40 * W.toolspeed) || !istype(src, /turf/simulated/wall) || construction_stage != 5) return construction_stage = 4 user.update_examine_panel(src) update_icon() - user << "You unscrew the support lines." + to_chat(user, "You unscrew the support lines.") return else if (istype(W, /obj/item/weapon/wirecutters)) construction_stage = 6 user.update_examine_panel(src) - user << "You mend the outer grille." + to_chat(user, "You mend the outer grille.") playsound(src, W.usesound, 100, 1) update_icon() return @@ -289,51 +319,51 @@ if(WT.remove_fuel(0,user)) cut_cover=1 else - user << "You need more welding fuel to complete this task." + to_chat(user, "You need more welding fuel to complete this task.") return else if (istype(W, /obj/item/weapon/pickaxe/plasmacutter)) cut_cover = 1 if(cut_cover) - user << "You begin slicing through the metal cover." + to_chat(user, "You begin slicing through the metal cover.") playsound(src, W.usesound, 100, 1) if(!do_after(user, 60 * W.toolspeed) || !istype(src, /turf/simulated/wall) || construction_stage != 4) return construction_stage = 3 user.update_examine_panel(src) update_icon() - user << "You press firmly on the cover, dislodging it." + to_chat(user, "You press firmly on the cover, dislodging it.") return else if (istype(W, /obj/item/weapon/screwdriver)) - user << "You begin screwing down the support lines." + to_chat(user, "You begin screwing down the support lines.") playsound(src, W.usesound, 100, 1) if(!do_after(user,40 * W.toolspeed) || !istype(src, /turf/simulated/wall) || construction_stage != 4) return construction_stage = 5 user.update_examine_panel(src) update_icon() - user << "You screw down the support lines." + to_chat(user, "You screw down the support lines.") return if(3) if (istype(W, /obj/item/weapon/crowbar)) - user << "You struggle to pry off the cover." + to_chat(user, "You struggle to pry off the cover.") playsound(src, W.usesound, 100, 1) if(!do_after(user,100 * W.toolspeed) || !istype(src, /turf/simulated/wall) || construction_stage != 3) return construction_stage = 2 user.update_examine_panel(src) update_icon() - user << "You pry off the cover." + to_chat(user, "You pry off the cover.") return if(2) if (istype(W, /obj/item/weapon/wrench)) - user << "You start loosening the anchoring bolts which secure the support rods to their frame." + to_chat(user, "You start loosening the anchoring bolts which secure the support rods to their frame.") playsound(src, W.usesound, 100, 1) if(!do_after(user,40 * W.toolspeed) || !istype(src, /turf/simulated/wall) || construction_stage != 2) return construction_stage = 1 user.update_examine_panel(src) update_icon() - user << "You remove the bolts anchoring the support rods." + to_chat(user, "You remove the bolts anchoring the support rods.") return if(1) var/cut_cover @@ -342,28 +372,28 @@ if( WT.remove_fuel(0,user) ) cut_cover=1 else - user << "You need more welding fuel to complete this task." + to_chat(user, "You need more welding fuel to complete this task.") return else if(istype(W, /obj/item/weapon/pickaxe/plasmacutter)) cut_cover = 1 if(cut_cover) - user << "You begin slicing through the support rods." + to_chat(user, "You begin slicing through the support rods.") playsound(src, W.usesound, 100, 1) if(!do_after(user,70 * W.toolspeed) || !istype(src, /turf/simulated/wall) || construction_stage != 1) return construction_stage = 0 user.update_examine_panel(src) update_icon() - user << "The slice through the support rods." + to_chat(user, "The slice through the support rods.") return if(0) if(istype(W, /obj/item/weapon/crowbar)) - user << "You struggle to pry off the outer sheath." + to_chat(user, "You struggle to pry off the outer sheath.") playsound(src, W.usesound, 100, 1) if(!do_after(user,100 * W.toolspeed) || !istype(src, /turf/simulated/wall) || !user || !W || !T ) return if(user.loc == T && user.get_active_hand() == W ) - user << "You pry off the outer sheath." + to_chat(user, "You pry off the outer sheath.") dismantle_wall() return diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index 13368bb7ed..1c700eec85 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -33,18 +33,18 @@ /turf/space/attackby(obj/item/C as obj, mob/user as mob) - if (istype(C, /obj/item/stack/rods)) + if(istype(C, /obj/item/stack/rods)) var/obj/structure/lattice/L = locate(/obj/structure/lattice, src) if(L) return var/obj/item/stack/rods/R = C if (R.use(1)) - user << "Constructing support lattice ..." + to_chat(user, "Constructing support lattice ...") playsound(src, 'sound/weapons/Genhit.ogg', 50, 1) ReplaceWithLattice() return - if (istype(C, /obj/item/stack/tile/floor)) + if(istype(C, /obj/item/stack/tile/floor)) var/obj/structure/lattice/L = locate(/obj/structure/lattice, src) if(L) var/obj/item/stack/tile/floor/S = C @@ -56,7 +56,33 @@ ChangeTurf(/turf/simulated/floor/airless) return else - user << "The plating is going to need some support." + to_chat(user, "The plating is going to need some support.") + + if(istype(C, /obj/item/stack/tile/roofing)) + var/turf/T = GetAbove(src) + var/obj/item/stack/tile/roofing/R = C + + // Patch holes in the ceiling + if(T) + if(istype(T, /turf/simulated/open) || istype(T, /turf/space)) + // Must be build adjacent to an existing floor/wall, no floating floors + var/turf/simulated/A = locate(/turf/simulated/floor) in T.CardinalTurfs() + if(!A) + A = locate(/turf/simulated/wall) in T.CardinalTurfs() + if(!A) + to_chat(user, "There's nothing to attach the ceiling to!") + return + + if(R.use(1)) // Cost of roofing tiles is 1:1 with cost to place lattice and plating + T.ReplaceWithLattice() + T.ChangeTurf(/turf/simulated/floor) + playsound(src, 'sound/weapons/Genhit.ogg', 50, 1) + user.visible_message("[user] expands the ceiling.", "You expand the ceiling.") + else + to_chat(user, "There aren't any holes in the ceiling to patch here.") + return + // Space shouldn't have weather of the sort planets with atmospheres do. + // If that's changed, then you'll want to swipe the rest of the roofing code from code/game/turfs/simulated/floor_attackby.dm return @@ -64,7 +90,7 @@ /turf/space/Entered(atom/movable/A as mob|obj) if(movement_disabled) - usr << "Movement is admin-disabled." //This is to identify lag problems + to_chat(usr, "Movement is admin-disabled.") //This is to identify lag problems return ..() if ((!(A) || src != A.loc)) return diff --git a/code/game/turfs/turf_changing.dm b/code/game/turfs/turf_changing.dm index b355ec6328..1d77686661 100644 --- a/code/game/turfs/turf_changing.dm +++ b/code/game/turfs/turf_changing.dm @@ -40,6 +40,7 @@ var/old_affecting_lights = affecting_lights var/old_lighting_overlay = lighting_overlay var/old_corners = corners + var/old_outdoors = outdoors //world << "Replacing [src.type] with [N]" @@ -108,3 +109,4 @@ lighting_build_overlay() else lighting_clear_overlay() + outdoors = old_outdoors \ No newline at end of file diff --git a/code/modules/materials/material_recipes.dm b/code/modules/materials/material_recipes.dm index 6e75d97a0d..232ef46e3e 100644 --- a/code/modules/materials/material_recipes.dm +++ b/code/modules/materials/material_recipes.dm @@ -53,6 +53,7 @@ recipes += new/datum/stack_recipe("canister", /obj/machinery/portable_atmospherics/canister, 10, time = 15, one_per_turf = 1, on_floor = 1) recipes += new/datum/stack_recipe("cannon frame", /obj/item/weapon/cannonframe, 10, time = 15, one_per_turf = 0, on_floor = 0) recipes += new/datum/stack_recipe("regular floor tile", /obj/item/stack/tile/floor, 1, 4, 20) + recipes += new/datum/stack_recipe("roofing tile", /obj/item/stack/tile/roofing, 3, 4, 20) recipes += new/datum/stack_recipe("metal rod", /obj/item/stack/rods, 1, 2, 60) recipes += new/datum/stack_recipe("frame", /obj/item/frame, 5, time = 25, one_per_turf = 1, on_floor = 1) recipes += new/datum/stack_recipe("mirror frame", /obj/item/frame/mirror, 1, time = 5, one_per_turf = 0, on_floor = 1) diff --git a/html/changelogs/Atermonera - Ceilings.yml b/html/changelogs/Atermonera - Ceilings.yml new file mode 100644 index 0000000000..760df592f5 --- /dev/null +++ b/html/changelogs/Atermonera - Ceilings.yml @@ -0,0 +1,7 @@ +author: Atermonera +delete-after: True +changes: + - rscadd: "Steel sheets can be used to construct Roofing Tiles" + - rscadd: "Roofing tiles can be used on tiles under open spaces or space tiles in multiZ maps to place a lattice and plating on the space above" + - rscadd: "Roofing tiles can be used on outdoor turfs to make them indoors" + - rscadd: "Both functions work together on multiZ maps with outdoor turfs, only one roofing tile is used per tile roofed."