diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm index 29b7d89ab79..a3ff9ac9afd 100644 --- a/code/game/objects/structures/girders.dm +++ b/code/game/objects/structures/girders.dm @@ -6,9 +6,65 @@ w_class = ITEMSIZE_HUGE var/state = 0 var/health = 200 + var/max_health = 200 + var/displaced_health = 50 + var/current_damage = 0 var/cover = 50 //how much cover the girder provides against projectiles. + var/default_material = DEFAULT_WALL_MATERIAL + var/material/girder_material var/material/reinf_material var/reinforcing = 0 + var/applies_material_colour = 1 + +/obj/structure/girder/New(var/newloc, var/material_key) + ..(newloc) + if(!material_key) + material_key = default_material + set_material(material_key) + update_icon() + +/obj/structure/girder/Destroy() + if(girder_material.products_need_process()) + processing_objects -= src + . = ..() + +/obj/structure/girder/process() + if(!radiate()) + processing_objects -= src + return + +/obj/structure/girder/proc/radiate() + var/total_radiation = girder_material.radioactivity + (reinf_material ? reinf_material.radioactivity / 2 : 0) + if(!total_radiation) + return + + radiation_repository.radiate(src, total_radiation) + return total_radiation + + +/obj/structure/girder/proc/set_material(var/new_material) + girder_material = get_material_by_name(new_material) + if(!girder_material) + qdel(src) + name = "[girder_material.display_name] [initial(name)]" + max_health = round(girder_material.integrity) //Should be 150 with default integrity (steel). Weaker than ye-olden Girders now. + health = max_health + displaced_health = round(max_health/4) + if(applies_material_colour) + color = girder_material.icon_colour + if(girder_material.products_need_process()) //Am I radioactive or some other? Process me! + processing_objects |= src + else if(src in processing_objects) //If I happened to be radioactive or s.o. previously, and am not now, stop processing. + processing_objects -= src + +/obj/structure/girder/get_material() + return girder_material + +/obj/structure/girder/update_icon() + if(anchored) + icon_state = "girder" + else + icon_state = "displaced" /obj/structure/girder/displaced icon_state = "displaced" @@ -16,6 +72,17 @@ health = 50 cover = 25 +/obj/structure/girder/displaced/New(var/newloc, var/material_key) + ..(newloc, material_key) + displace() + +/obj/structure/girder/proc/displace() + name = "displaced [girder_material.display_name] [initial(name)]" + icon_state = "displaced" + anchored = 0 + health = (displaced_health - round(current_damage / 4)) + cover = 25 + /obj/structure/girder/attack_generic(var/mob/user, var/damage, var/attack_message = "smashes apart", var/wallbreaker) if(!damage || !wallbreaker) return 0 @@ -36,6 +103,25 @@ if(!istype(Proj, /obj/item/projectile/beam)) damage *= 0.4 //non beams do reduced damage + else if(girder_material && girder_material.reflectivity >= 0.5) // Reflect lasers. + var/new_damage = damage * girder_material.reflectivity + var/outgoing_damage = damage - new_damage + damage = round(new_damage) + Proj.damage = outgoing_damage + + visible_message("\The [src] reflects \the [Proj]!") + + // Find a turf near or on the original location to bounce to + var/new_x = Proj.starting.x + pick(0, 0, 0, -1, 1, -2, 2) + var/new_y = Proj.starting.y + pick(0, 0, 0, -1, 1, -2, 2) + //var/turf/curloc = get_turf(src) + var/turf/curloc = get_step(src, get_dir(src, Proj.starting)) + + Proj.penetrating += 1 // Needed for the beam to get out of the girder. + + // redirect the projectile + Proj.redirect(new_x, new_y, curloc, null) + health -= damage ..() if(health <= 0) @@ -47,9 +133,10 @@ dismantle() /obj/structure/girder/proc/reset_girder() + name = "[girder_material.display_name] [initial(name)]" anchored = 1 cover = initial(cover) - health = min(health,initial(health)) + health = min(max_health - current_damage,max_health) state = 0 icon_state = initial(icon_state) reinforcing = 0 @@ -60,62 +147,59 @@ if(istype(W, /obj/item/weapon/wrench) && state == 0) if(anchored && !reinf_material) playsound(src, W.usesound, 100, 1) - user << "Now disassembling the girder..." - if(do_after(user,40 * W.toolspeed)) + to_chat(user, "Now disassembling the girder...") + if(do_after(user,(35 + round(max_health/50)) * W.toolspeed)) if(!src) return - user << "You dissasembled the girder!" + to_chat(user, "You dissasembled the girder!") dismantle() else if(!anchored) playsound(src, W.usesound, 100, 1) - user << "Now securing the girder..." + to_chat(user, "Now securing the girder...") if(do_after(user, 40 * W.toolspeed, src)) - user << "You secured the girder!" + to_chat(user, "You secured the girder!") reset_girder() else if(istype(W, /obj/item/weapon/pickaxe/plasmacutter)) - user << "Now slicing apart the girder..." + to_chat(user, "Now slicing apart the girder...") if(do_after(user,30 * W.toolspeed)) if(!src) return - user << "You slice apart the girder!" + to_chat(user, "You slice apart the girder!") dismantle() else if(istype(W, /obj/item/weapon/pickaxe/diamonddrill)) - user << "You drill through the girder!" + to_chat(user, "You drill through the girder!") dismantle() else if(istype(W, /obj/item/weapon/screwdriver)) if(state == 2) playsound(src, W.usesound, 100, 1) - user << "Now unsecuring support struts..." + to_chat(user, "Now unsecuring support struts...") if(do_after(user,40 * W.toolspeed)) if(!src) return - user << "You unsecured the support struts!" + to_chat(user, "You unsecured the support struts!") state = 1 else if(anchored && !reinf_material) playsound(src, W.usesound, 100, 1) reinforcing = !reinforcing - user << "\The [src] can now be [reinforcing? "reinforced" : "constructed"]!" + to_chat(user, "\The [src] can now be [reinforcing? "reinforced" : "constructed"]!") else if(istype(W, /obj/item/weapon/wirecutters) && state == 1) playsound(src, W.usesound, 100, 1) - user << "Now removing support struts..." + to_chat(user, "Now removing support struts...") if(do_after(user,40 * W.toolspeed)) if(!src) return - user << "You removed the support struts!" + to_chat(user, "You removed the support struts!") reinf_material.place_dismantled_product(get_turf(src)) reinf_material = null reset_girder() else if(istype(W, /obj/item/weapon/crowbar) && state == 0 && anchored) playsound(src, W.usesound, 100, 1) - user << "Now dislodging the girder..." + to_chat(user, "Now dislodging the girder...") if(do_after(user, 40 * W.toolspeed)) if(!src) return - user << "You dislodged the girder!" - icon_state = "displaced" - anchored = 0 - health = 50 - cover = 25 + to_chat(user, "You dislodged the girder!") + displace() else if(istype(W, /obj/item/stack/material)) if(reinforcing && !reinf_material) @@ -130,14 +214,16 @@ /obj/structure/girder/proc/take_damage(var/damage) health -= damage - if(health <= 0) dismantle() + else + current_damage = current_damage + damage //Rather than calculate this every time we need to use it, just calculate it here and save it. + /obj/structure/girder/proc/construct_wall(obj/item/stack/material/S, mob/user) var/amount_to_use = reinf_material ? 1 : 2 if(S.get_amount() < amount_to_use) - user << "There isn't enough material here to construct a wall." + to_chat(user, "There isn't enough material here to construct a wall.") return 0 var/material/M = name_to_material[S.default_type] @@ -148,24 +234,24 @@ add_hiddenprint(usr) if(M.integrity < 50) - user << "This material is too soft for use in wall construction." + to_chat(user, "This material is too soft for use in wall construction.") return 0 - user << "You begin adding the plating..." + to_chat(user, "You begin adding the plating...") if(!do_after(user,40) || !S.use(amount_to_use)) return 1 //once we've gotten this far don't call parent attackby() if(anchored) - user << "You added the plating!" + to_chat(user, "You added the plating!") else - user << "You create a false wall! Push on it to open or close the passage." + to_chat(user, "You create a false wall! Push on it to open or close the passage.") wall_fake = 1 var/turf/Tsrc = get_turf(src) Tsrc.ChangeTurf(/turf/simulated/wall) var/turf/simulated/wall/T = get_turf(src) - T.set_material(M, reinf_material) + T.set_material(M, reinf_material, girder_material) if(wall_fake) T.can_open = 1 T.add_hiddenprint(usr) @@ -174,22 +260,22 @@ /obj/structure/girder/proc/reinforce_with_material(obj/item/stack/material/S, mob/user) //if the verb is removed this can be renamed. if(reinf_material) - user << "\The [src] is already reinforced." + to_chat(user, "\The [src] is already reinforced.") return 0 if(S.get_amount() < 1) - user << "There isn't enough material here to reinforce the girder." + to_chat(user, "There isn't enough material here to reinforce the girder.") return 0 var/material/M = name_to_material[S.default_type] if(!istype(M) || M.integrity < 50) - user << "You cannot reinforce \the [src] with that; it is too soft." + to_chat(user, "You cannot reinforce \the [src] with that; it is too soft.") return 0 - user << "Now reinforcing..." + to_chat(user, "Now reinforcing...") if (!do_after(user,40) || !S.use(1)) return 1 //don't call parent attackby() past this point - user << "You added reinforcement!" + to_chat(user, "You added reinforcement!") reinf_material = M reinforce_girder() @@ -197,13 +283,13 @@ /obj/structure/girder/proc/reinforce_girder() cover = reinf_material.hardness - health = 500 + health = health + round(reinf_material.integrity/2) state = 2 icon_state = "reinforced" reinforcing = 0 /obj/structure/girder/proc/dismantle() - new /obj/item/stack/material/steel(get_turf(src)) + girder_material.place_dismantled_product(get_turf(src)) qdel(src) /obj/structure/girder/attack_hand(mob/user as mob) @@ -235,6 +321,8 @@ icon_state= "cultgirder" health = 250 cover = 70 + girder_material = DEFAULT_WALL_MATERIAL + applies_material_colour = 0 /obj/structure/girder/cult/dismantle() new /obj/effect/decal/remains/human(get_turf(src)) @@ -243,18 +331,18 @@ /obj/structure/girder/cult/attackby(obj/item/W as obj, mob/user as mob) if(istype(W, /obj/item/weapon/wrench)) playsound(src, W.usesound, 100, 1) - user << "Now disassembling the girder..." + to_chat(user, "Now disassembling the girder...") if(do_after(user,40 * W.toolspeed)) - user << "You dissasembled the girder!" + to_chat(user, "You dissasembled the girder!") dismantle() else if(istype(W, /obj/item/weapon/pickaxe/plasmacutter)) - user << "Now slicing apart the girder..." + to_chat(user, "Now slicing apart the girder...") if(do_after(user,30 * W.toolspeed)) - user << "You slice apart the girder!" + to_chat(user, "You slice apart the girder!") dismantle() else if(istype(W, /obj/item/weapon/pickaxe/diamonddrill)) - user << "You drill through the girder!" + to_chat(user, "You drill through the girder!") new /obj/effect/decal/remains/human(get_turf(src)) dismantle() diff --git a/code/game/turfs/simulated/wall_icon.dm b/code/game/turfs/simulated/wall_icon.dm index eab99bfba72..2dac063723b 100644 --- a/code/game/turfs/simulated/wall_icon.dm +++ b/code/game/turfs/simulated/wall_icon.dm @@ -31,9 +31,13 @@ update_icon() -/turf/simulated/wall/proc/set_material(var/material/newmaterial, var/material/newrmaterial) +/turf/simulated/wall/proc/set_material(var/material/newmaterial, var/material/newrmaterial, var/material/newgmaterial) material = newmaterial reinf_material = newrmaterial + if(!newgmaterial) + girder_material = DEFAULT_WALL_MATERIAL + else + girder_material = newgmaterial update_material() /turf/simulated/wall/update_icon() diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index fcd0a31479b..21fd9492f09 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -14,6 +14,7 @@ var/global/damage_overlays[16] var/active var/can_open = 0 + var/material/girder_material var/material/material var/material/reinf_material var/last_state @@ -26,12 +27,15 @@ for(var/obj/O in src) O.hide(1) -/turf/simulated/wall/New(var/newloc, var/materialtype, var/rmaterialtype) +/turf/simulated/wall/New(var/newloc, var/materialtype, var/rmaterialtype, var/girdertype) ..(newloc) icon_state = "blank" if(!materialtype) materialtype = DEFAULT_WALL_MATERIAL material = get_material_by_name(materialtype) + if(!girdertype) + girdertype = DEFAULT_WALL_MATERIAL + girder_material = get_material_by_name(girdertype) if(!isnull(rmaterialtype)) reinf_material = get_material_by_name(rmaterialtype) update_material() @@ -120,18 +124,18 @@ . = ..(user) if(!damage) - user << "It looks fully intact." + to_chat(user, "It looks fully intact.") else var/dam = damage / material.integrity if(dam <= 0.3) - user << "It looks slightly damaged." + to_chat(user, "It looks slightly damaged.") else if(dam <= 0.6) - user << "It looks moderately damaged." + to_chat(user, "It looks moderately damaged.") else - user << "It looks heavily damaged." + to_chat(user, "It looks heavily damaged.") if(locate(/obj/effect/overlay/wallrot) in src) - user << "There is fungus growing on [src]." + to_chat(user, "There is fungus growing on [src].") //Damage @@ -186,9 +190,9 @@ playsound(src, 'sound/items/Welder.ogg', 100, 1) if(!no_product) if(reinf_material) - reinf_material.place_dismantled_girder(src, reinf_material) + reinf_material.place_dismantled_girder(src, reinf_material, girder_material) else - material.place_dismantled_girder(src) + material.place_dismantled_girder(src, null, girder_material) if(!devastated) material.place_dismantled_product(src) if (!reinf_material) @@ -204,6 +208,7 @@ clear_plants() material = get_material_by_name("placeholder") reinf_material = null + girder_material = null update_connections(1) ChangeTurf(/turf/simulated/floor/plating) @@ -211,6 +216,8 @@ /turf/simulated/wall/ex_act(severity) switch(severity) if(1.0) + if(girder_material.explosion_resistance >= 25 && prob(girder_material.explosion_resistance)) + new /obj/structure/girder/displaced(src, girder_material.name) src.ChangeTurf(get_base_turf_by_area(src)) if(2.0) if(prob(75)) @@ -247,12 +254,15 @@ O.density = 1 O.layer = 5 - src.ChangeTurf(/turf/simulated/floor/plating) + if(girder_material.integrity >= 150 && !girder_material.is_brittle()) //Strong girders will remain in place when a wall is melted. + dismantle_wall(1,1) + else + src.ChangeTurf(/turf/simulated/floor/plating) var/turf/simulated/floor/F = src F.burn_tile() - F.icon_state = "wall_thermite" - user << "The thermite starts melting through the wall." + F.icon_state = "dmg[rand(1,4)]" + to_chat(user, "The thermite starts melting through the wall.") spawn(100) if(O) @@ -261,7 +271,7 @@ return /turf/simulated/wall/proc/radiate() - var/total_radiation = material.radioactivity + (reinf_material ? reinf_material.radioactivity / 2 : 0) + var/total_radiation = material.radioactivity + (reinf_material ? reinf_material.radioactivity / 2 : 0) + (girder_material ? girder_material.radioactivity / 2 : 0) if(!total_radiation) return @@ -271,7 +281,7 @@ /turf/simulated/wall/proc/burn(temperature) if(material.combustion_effect(src, temperature, 0.7)) spawn(2) - new /obj/structure/girder(src) + new /obj/structure/girder(src, girder_material.name) src.ChangeTurf(/turf/simulated/floor) for(var/turf/simulated/wall/W in range(3,src)) W.burn((temperature/4)) diff --git a/code/modules/materials/material_recipes.dm b/code/modules/materials/material_recipes.dm index a52d66a0fa4..6a10383f76b 100644 --- a/code/modules/materials/material_recipes.dm +++ b/code/modules/materials/material_recipes.dm @@ -22,6 +22,7 @@ recipes += new/datum/stack_recipe("[display_name] chair", /obj/structure/bed/chair, one_per_turf = 1, on_floor = 1, supplied_material = "[name]") recipes += new/datum/stack_recipe("[display_name] bed", /obj/structure/bed, 2, one_per_turf = 1, on_floor = 1, supplied_material = "[name]") recipes += new/datum/stack_recipe("[display_name] double bed", /obj/structure/bed/double, 4, one_per_turf = 1, on_floor = 1, supplied_material = "[name]") + recipes += new/datum/stack_recipe("[display_name] wall girders", /obj/structure/girder, 2, time = 50, one_per_turf = 1, on_floor = 1, supplied_material = "[name]") if(hardness>50) recipes += new/datum/stack_recipe("[display_name] fork", /obj/item/weapon/material/kitchen/utensil/fork/plastic, 1, on_floor = 1, supplied_material = "[name]") @@ -57,7 +58,6 @@ recipes += new/datum/stack_recipe("mirror frame", /obj/item/frame/mirror, 1, time = 5, one_per_turf = 0, on_floor = 1) recipes += new/datum/stack_recipe("fire extinguisher cabinet frame", /obj/item/frame/extinguisher_cabinet, 4, time = 5, one_per_turf = 0, on_floor = 1) //recipes += new/datum/stack_recipe("fire axe cabinet frame", /obj/item/frame/fireaxe_cabinet, 4, time = 5, one_per_turf = 0, on_floor = 1) - recipes += new/datum/stack_recipe("wall girders", /obj/structure/girder, 2, time = 50, one_per_turf = 1, on_floor = 1) recipes += new/datum/stack_recipe("railing", /obj/structure/railing, 2, time = 50, one_per_turf = 0, on_floor = 1) recipes += new/datum/stack_recipe("turret frame", /obj/machinery/porta_turret_construct, 5, time = 25, one_per_turf = 1, on_floor = 1) recipes += new/datum/stack_recipe_list("airlock assemblies", list( \ diff --git a/code/modules/materials/materials.dm b/code/modules/materials/materials.dm index 54a890074ac..af5e1b74750 100644 --- a/code/modules/materials/materials.dm +++ b/code/modules/materials/materials.dm @@ -192,11 +192,16 @@ var/list/name_to_material name = "placeholder" // Places a girder object when a wall is dismantled, also applies reinforced material. -/material/proc/place_dismantled_girder(var/turf/target, var/material/reinf_material) +/material/proc/place_dismantled_girder(var/turf/target, var/material/reinf_material, var/material/girder_material) var/obj/structure/girder/G = new(target) if(reinf_material) G.reinf_material = reinf_material G.reinforce_girder() + if(girder_material) + if(istype(girder_material, /material)) + girder_material = girder_material.name + G.set_material(girder_material) + // General wall debris product placement. // Not particularly necessary aside from snowflakey cult girders. diff --git a/html/changelogs/Mechoid-Material Girders.yml b/html/changelogs/Mechoid-Material Girders.yml new file mode 100644 index 00000000000..6b23ebc6dcf --- /dev/null +++ b/html/changelogs/Mechoid-Material Girders.yml @@ -0,0 +1,11 @@ + +author: Mechoid + +delete-after: True + +changes: + - rscadd: "Adds material girders." + - tweak: "Girder decon time is now partially dependant on material. Stronger girders take slightly longer." + - tweak: "Wall girders are now under the integrity-based construction listing. Material-Name Wall Girder." + - rscadd: "Explosive-resistant girders in walls have a chance to survive as an unanchored girder, if their wall is destroyed." + - rscadd: "Radioactive girders affect the completed wall's radioactivity."