From bbc11882ea65edb00fdde224f112b84c610b06e1 Mon Sep 17 00:00:00 2001 From: Gristlebee <56049844+Gristlebee@users.noreply.github.com> Date: Sat, 31 Aug 2024 21:58:05 -0700 Subject: [PATCH] Destructible Walls (#3145) ## About The Pull Request ### Wall Stuff and Behavior - Moves the damage behavior from concrete walls to base walls. - Basic walls can be repaired with a welder. - Basic walls are still deconstructed with a welder, but it now starts a repeatable do after that reduces the wall's integrity more efficiently than simply attacking. - R-walls integrity is tied to their deconstruction state. Damaging one enough will move it down a state, and can be repaired by following the construction steps. They can still be deconstructed the same as before, or with a plasmacutter. ### Plasmacutters - Plasma cutters are now more of an engineering tool, and acts as an "upgrade" to the welder and deconstructs walls faster, and can repair prosthetic limbs. They can still mine, but lose the additional mining range and has a chance to ruin ores. - Plasmacutters now fit in toolbelts. - Moves plasmacutters and advanced plasmacutters from mining to tech plasma manipulation and adv plasma manipulation tech respectively. - Adds plasmacutters to the Mudskipper, Riggs, Talos, Gecko, Heron, Osprey, Ranger, Hyena, Komodo, Shetland and Twinkleshine - Adds plasmacutters to cargo for 1250 credits ### Misc Code stuff - Cleans up crate/closet deconstruction. It now checks for tool_behavior rather than a specific tool and non-help intent. - Renames concrete_damage.dmi to wall_damage.dmi ## Why It's Good For The Game Rylie asked me to make this. Currently, it's much easier to go through a wall than a door if you want to force entry as it's as simple as having a welder or a jackhammer to take off the wall plating vs having to take the time hack an airlock, which probably isnt great. Also gives some counterplay if you're on the defending side since you have the opportunity to repair compromised walls or go around and attack the breacher. This would add more possible interactions and play around with walls since you no longer need these two specific tools to get through a wall. If you say, have enough ammo you could theoretically just shoot your way in, and they're no longer indestructible pieces of cover. ## Changelog :cl: add: Welders/Plasmacutters now deal damage to wall integrity to decon add: Plasmacutters are now engineering tools and fit in toolbelts. They can damage ores into slag if used to mine. They are now researched with plasma technology and advanced plasma technology. add: Plasmacutters to cargo for 1250 add: Adds plasmacutters to the Mudskipper, Riggs, Talos, Gecko, Heron, Osprey, Ranger, Hyena, Komodo, Shetland and Twinkleshine del: Plasmacutters extra mining range fix: Plasmacutters can repair prosthetic limbs like welders code: Moves damage behavior of concrete walls to normal walls. Basic walls are now repaired with a welder. code: R-walls d-state tied to their integrity. R-walls can be deconstructed with plasmacutters. code: Crate decon checks for tool behavior rather than a istype check /:cl: --- .../RockRuins/rockplanet_harmfactory.dmm | 4 +- .../independent/independent_mudskipper.dmm | 1 + .../independent/independent_rigger.dmm | 1 + .../independent/independent_shetland.dmm | 2 + _maps/shuttles/inteq/inteq_talos.dmm | 4 + .../shuttles/nanotrasen/nanotrasen_gecko.dmm | 2 + .../shuttles/nanotrasen/nanotrasen_heron.dmm | 2 + .../shuttles/nanotrasen/nanotrasen_osprey.dmm | 1 + .../shuttles/nanotrasen/nanotrasen_ranger.dmm | 1 + .../syndicate/syndicate_gorlex_hyena.dmm | 6 +- .../syndicate/syndicate_gorlex_komodo.dmm | 1 + .../syndicate/syndicate_twinkleshine.dmm | 2 + .../mecha/equipment/tools/mining_tools.dm | 14 +- code/game/objects/items.dm | 2 + code/game/objects/items/grenades/plastic.dm | 3 + code/game/objects/items/storage/belt.dm | 3 +- code/game/objects/items/tools/weldingtool.dm | 3 + .../structures/crates_lockers/closets.dm | 32 ++- .../crates_lockers/closets/cardboardbox.dm | 4 +- code/game/objects/structures/girders.dm | 2 +- code/game/turfs/closed/minerals.dm | 11 +- code/game/turfs/closed/wall/conc_walls.dm | 181 +++------------ code/game/turfs/closed/wall/mineral_walls.dm | 30 ++- code/game/turfs/closed/wall/misc_walls.dm | 9 +- code/game/turfs/closed/wall/reinf_walls.dm | 73 +++--- code/game/turfs/closed/walls.dm | 215 +++++++++++++----- code/modules/cargo/packs/tools.dm | 8 +- .../projectiles/guns/energy/special.dm | 21 +- .../projectiles/projectile/special/plasma.dm | 11 +- code/modules/research/techweb/all_nodes.dm | 8 +- .../lavalandruin_code/elephantgraveyard.dm | 6 +- .../{concrete_damage.dmi => wall_damage.dmi} | Bin 32 files changed, 378 insertions(+), 285 deletions(-) rename icons/effects/{concrete_damage.dmi => wall_damage.dmi} (100%) diff --git a/_maps/RandomRuins/RockRuins/rockplanet_harmfactory.dmm b/_maps/RandomRuins/RockRuins/rockplanet_harmfactory.dmm index 8a79949e34b1c..b9c907c5c87e5 100644 --- a/_maps/RandomRuins/RockRuins/rockplanet_harmfactory.dmm +++ b/_maps/RandomRuins/RockRuins/rockplanet_harmfactory.dmm @@ -3367,7 +3367,7 @@ of IA ro ro -hJ +bf Ew LT hi @@ -3446,7 +3446,7 @@ je kC nq qm -hJ +bf tw tC vK diff --git a/_maps/shuttles/independent/independent_mudskipper.dmm b/_maps/shuttles/independent/independent_mudskipper.dmm index d7a3341b89273..618a40d3996fb 100644 --- a/_maps/shuttles/independent/independent_mudskipper.dmm +++ b/_maps/shuttles/independent/independent_mudskipper.dmm @@ -349,6 +349,7 @@ /obj/item/circular_saw, /obj/item/multitool, /obj/item/stack/marker_beacon/thirty, +/obj/item/gun/energy/plasmacutter, /turf/open/floor/plasteel/tech, /area/ship/cargo) "gT" = ( diff --git a/_maps/shuttles/independent/independent_rigger.dmm b/_maps/shuttles/independent/independent_rigger.dmm index 632337fab2636..15265d30016be 100644 --- a/_maps/shuttles/independent/independent_rigger.dmm +++ b/_maps/shuttles/independent/independent_rigger.dmm @@ -4468,6 +4468,7 @@ /obj/item/storage/toolbox/mechanical, /obj/item/storage/belt/utility, /obj/item/clothing/glasses/welding, +/obj/item/gun/energy/plasmacutter, /turf/open/floor/plating, /area/ship/engineering) diff --git a/_maps/shuttles/independent/independent_shetland.dmm b/_maps/shuttles/independent/independent_shetland.dmm index 459bfebcd48fb..0481bd2506fab 100644 --- a/_maps/shuttles/independent/independent_shetland.dmm +++ b/_maps/shuttles/independent/independent_shetland.dmm @@ -4725,6 +4725,8 @@ /obj/item/multitool, /obj/item/clothing/glasses/welding, /obj/item/clothing/glasses/welding, +/obj/item/gun/energy/plasmacutter, +/obj/item/gun/energy/plasmacutter, /turf/open/floor/plasteel/dark, /area/ship/engineering/electrical) "OU" = ( diff --git a/_maps/shuttles/inteq/inteq_talos.dmm b/_maps/shuttles/inteq/inteq_talos.dmm index ddad109a06fb3..38dd26c38305b 100644 --- a/_maps/shuttles/inteq/inteq_talos.dmm +++ b/_maps/shuttles/inteq/inteq_talos.dmm @@ -928,6 +928,7 @@ req_access_txt = "11"; req_one_access = null }, +/obj/item/gun/energy/plasmacutter, /turf/open/floor/plasteel/tech/grid, /area/ship/engineering) "gm" = ( @@ -1348,6 +1349,7 @@ req_access_txt = "11"; req_one_access = null }, +/obj/item/gun/energy/plasmacutter, /turf/open/floor/plasteel/tech/grid, /area/ship/engineering) "iM" = ( @@ -1645,6 +1647,7 @@ pixel_x = 20; pixel_y = 11 }, +/obj/item/gun/energy/plasmacutter, /turf/open/floor/plasteel/tech/grid, /area/ship/engineering) "jZ" = ( @@ -6273,6 +6276,7 @@ name = "honorable artificer's toolbelt" }, /obj/machinery/airalarm/directional/west, +/obj/item/gun/energy/plasmacutter, /turf/open/floor/plasteel/tech/grid, /area/ship/engineering/communications) "Oq" = ( diff --git a/_maps/shuttles/nanotrasen/nanotrasen_gecko.dmm b/_maps/shuttles/nanotrasen/nanotrasen_gecko.dmm index 351f188e33691..2cb4e641cd53c 100644 --- a/_maps/shuttles/nanotrasen/nanotrasen_gecko.dmm +++ b/_maps/shuttles/nanotrasen/nanotrasen_gecko.dmm @@ -383,6 +383,7 @@ /obj/item/clothing/under/rank/cargo/miner, /obj/item/clothing/gloves/color/black, /obj/item/clothing/glasses/meson, +/obj/item/gun/energy/plasmacutter, /turf/open/floor/plasteel/patterned/grid, /area/ship/cargo/port) "dC" = ( @@ -4112,6 +4113,7 @@ /obj/item/clothing/under/rank/cargo/miner, /obj/item/clothing/gloves/color/black, /obj/item/clothing/glasses/meson, +/obj/item/gun/energy/plasmacutter, /turf/open/floor/plasteel/patterned/grid, /area/ship/cargo/starboard) "Qc" = ( diff --git a/_maps/shuttles/nanotrasen/nanotrasen_heron.dmm b/_maps/shuttles/nanotrasen/nanotrasen_heron.dmm index e72766239a4f9..96bd414525c0c 100644 --- a/_maps/shuttles/nanotrasen/nanotrasen_heron.dmm +++ b/_maps/shuttles/nanotrasen/nanotrasen_heron.dmm @@ -1474,6 +1474,7 @@ pixel_y = -11; pixel_x = 9 }, +/obj/item/gun/energy/plasmacutter, /turf/open/floor/plasteel/dark, /area/ship/engineering) "gd" = ( @@ -10650,6 +10651,7 @@ pixel_y = -10; pixel_x = 5 }, +/obj/item/gun/energy/plasmacutter, /turf/open/floor/plasteel/dark, /area/ship/engineering) "NC" = ( diff --git a/_maps/shuttles/nanotrasen/nanotrasen_osprey.dmm b/_maps/shuttles/nanotrasen/nanotrasen_osprey.dmm index 0c860abb9e20c..564cf0733f9fe 100644 --- a/_maps/shuttles/nanotrasen/nanotrasen_osprey.dmm +++ b/_maps/shuttles/nanotrasen/nanotrasen_osprey.dmm @@ -5899,6 +5899,7 @@ }, /obj/item/holosign_creator/engineering, /obj/item/storage/box/metalfoam, +/obj/item/gun/energy/plasmacutter, /turf/open/floor/plasteel/patterned/grid, /area/ship/engineering) "My" = ( diff --git a/_maps/shuttles/nanotrasen/nanotrasen_ranger.dmm b/_maps/shuttles/nanotrasen/nanotrasen_ranger.dmm index 342ffb8fa928b..d2ccfdcfe910b 100644 --- a/_maps/shuttles/nanotrasen/nanotrasen_ranger.dmm +++ b/_maps/shuttles/nanotrasen/nanotrasen_ranger.dmm @@ -1554,6 +1554,7 @@ /obj/item/clothing/glasses/meson/gar{ pixel_y = 8 }, +/obj/item/gun/energy/plasmacutter, /turf/open/floor/plasteel/mono/dark, /area/ship/engineering) "pA" = ( diff --git a/_maps/shuttles/syndicate/syndicate_gorlex_hyena.dmm b/_maps/shuttles/syndicate/syndicate_gorlex_hyena.dmm index ae46dc0286f32..c4fe771bebd0d 100644 --- a/_maps/shuttles/syndicate/syndicate_gorlex_hyena.dmm +++ b/_maps/shuttles/syndicate/syndicate_gorlex_hyena.dmm @@ -899,6 +899,7 @@ /obj/item/clothing/under/syndicate/ngr/jumpsuit, /obj/item/clothing/suit/hazardvest/ngr, /obj/item/clothing/head/hardhat/ngr, +/obj/item/pickaxe/drill, /turf/open/floor/plasteel/tech/grid, /area/ship/storage) "pu" = ( @@ -1152,6 +1153,7 @@ /obj/item/clothing/under/syndicate/ngr/jumpsuit, /obj/item/clothing/suit/hazardvest/ngr, /obj/item/clothing/head/hardhat/ngr, +/obj/item/pickaxe/drill, /turf/open/floor/plasteel/tech/grid, /area/ship/storage) "tI" = ( @@ -3159,10 +3161,10 @@ dir = 4 }, /obj/structure/rack, -/obj/item/pickaxe/drill/jackhammer/old{ +/obj/item/gun/energy/plasmacutter{ pixel_y = 10 }, -/obj/item/pickaxe/drill/jackhammer/old, +/obj/item/gun/energy/plasmacutter, /turf/open/floor/plasteel/tech/grid, /area/ship/storage) "Yv" = ( diff --git a/_maps/shuttles/syndicate/syndicate_gorlex_komodo.dmm b/_maps/shuttles/syndicate/syndicate_gorlex_komodo.dmm index 987b372d217a7..e4efdf5760f4c 100644 --- a/_maps/shuttles/syndicate/syndicate_gorlex_komodo.dmm +++ b/_maps/shuttles/syndicate/syndicate_gorlex_komodo.dmm @@ -1175,6 +1175,7 @@ }, /obj/item/clothing/under/syndicate/hardliners, /obj/item/clothing/suit/hazardvest/hardliners, +/obj/item/gun/energy/plasmacutter, /turf/open/floor/plasteel/tech, /area/ship/engineering) "ls" = ( diff --git a/_maps/shuttles/syndicate/syndicate_twinkleshine.dmm b/_maps/shuttles/syndicate/syndicate_twinkleshine.dmm index 7d738e1057b10..877c571a60a4c 100644 --- a/_maps/shuttles/syndicate/syndicate_twinkleshine.dmm +++ b/_maps/shuttles/syndicate/syndicate_twinkleshine.dmm @@ -4440,6 +4440,7 @@ /obj/item/clothing/head/hardhat/red{ name = "hard hat" }, +/obj/item/gun/energy/plasmacutter, /turf/open/floor/plasteel/dark, /area/ship/engineering) "Af" = ( @@ -8917,6 +8918,7 @@ /obj/item/clothing/head/hardhat/red{ name = "hard hat" }, +/obj/item/gun/energy/plasmacutter, /turf/open/floor/plasteel/dark, /area/ship/engineering) "Zg" = ( diff --git a/code/game/mecha/equipment/tools/mining_tools.dm b/code/game/mecha/equipment/tools/mining_tools.dm index 6283cd2786457..e99d24e3f558f 100644 --- a/code/game/mecha/equipment/tools/mining_tools.dm +++ b/code/game/mecha/equipment/tools/mining_tools.dm @@ -17,6 +17,7 @@ toolspeed = 0.9 var/drill_delay = 7 var/drill_level = DRILL_BASIC + wall_decon_damage = 100 /obj/item/mecha_parts/mecha_equipment/drill/Initialize() . = ..() @@ -62,15 +63,19 @@ return /turf/closed/wall/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill) - if(drill.do_after_mecha(src, 60 / drill.drill_level)) + while(drill.do_after_mecha(src, 15 / drill.drill_level)) drill.log_message("Drilled through [src]", LOG_MECHA) - dismantle_wall(devastated = TRUE) + alter_integrity(-drill.wall_decon_damage) + drill.occupant_message("You drill through some of the outer plating...") + playsound(src,'sound/weapons/drill.ogg',60,TRUE) /turf/closed/wall/r_wall/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill) if(drill.drill_level >= DRILL_HARDENED) - if(drill.do_after_mecha(src, 120 / drill.drill_level)) + while(drill.do_after_mecha(src, 20 / drill.drill_level)) drill.log_message("Drilled through [src]", LOG_MECHA) - dismantle_wall(devastated = TRUE) + alter_integrity(-drill.wall_decon_damage) + drill.occupant_message("You drill through some of the outer plating...") + playsound(src,'sound/weapons/drill.ogg',60,TRUE) else drill.occupant_message("[src] is too durable to drill through.") @@ -150,6 +155,7 @@ drill_level = DRILL_HARDENED force = 15 toolspeed = 0.7 + wall_decon_damage = 300 /obj/item/mecha_parts/mecha_equipment/mining_scanner diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 45d83621b431a..376d1ba16d11a 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -162,6 +162,8 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb var/tool_behaviour = NONE ///How fast does the tool work var/toolspeed = 1 + /// how much damage does this item do when tearing down walls during deconstruction steps? + var/wall_decon_damage = 0 var/block_chance = 0 var/block_cooldown_time = 1 SECONDS diff --git a/code/game/objects/items/grenades/plastic.dm b/code/game/objects/items/grenades/plastic.dm index f3f891bad11d4..c4cafbc8fdb96 100644 --- a/code/game/objects/items/grenades/plastic.dm +++ b/code/game/objects/items/grenades/plastic.dm @@ -52,6 +52,9 @@ target.cut_overlay(plastic_overlay, TRUE) if(!ismob(target) || full_damage_on_mobs) target.ex_act(EXPLODE_HEAVY, target) + if(iswallturf(target)) + var/turf/closed/wall/wall = target + wall.dismantle_wall(TRUE) else location = get_turf(src) if(location) diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm index fbe1bbc73131c..0455a93665576 100644 --- a/code/game/objects/items/storage/belt.dm +++ b/code/game/objects/items/storage/belt.dm @@ -74,7 +74,8 @@ /obj/item/chisel, /obj/item/clothing/glasses/welding, //WS edit: ok mald sure I'll add the welding stuff to the. ok. /obj/item/clothing/mask/gas/welding, - /obj/item/clothing/head/welding //WS end + /obj/item/clothing/head/welding, //WS end + /obj/item/gun/energy/plasmacutter )) /obj/item/storage/belt/utility/chief diff --git a/code/game/objects/items/tools/weldingtool.dm b/code/game/objects/items/tools/weldingtool.dm index c792af38486ab..53f3396f27272 100644 --- a/code/game/objects/items/tools/weldingtool.dm +++ b/code/game/objects/items/tools/weldingtool.dm @@ -39,6 +39,7 @@ var/acti_sound = 'sound/items/welderactivate.ogg' var/deac_sound = 'sound/items/welderdeactivate.ogg' var/start_full = TRUE + wall_decon_damage = 50 /obj/item/weldingtool/empty start_full = FALSE @@ -348,6 +349,7 @@ light_system = NO_LIGHT_SUPPORT light_range = 0 change_icons = 0 + wall_decon_damage = 500 /obj/item/weldingtool/abductor/process() if(get_fuel() <= max_fuel) @@ -378,6 +380,7 @@ can_off_process = 1 light_range = 1 toolspeed = 0.5 + wall_decon_damage = 100 var/last_gen = 0 var/nextrefueltick = 0 diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 714129498e4c4..7731bf48d2ffa 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -27,7 +27,8 @@ var/max_mob_size = MOB_SIZE_HUMAN //Biggest mob_size accepted by the container var/mob_storage_capacity = 3 // how many human sized mob/living can fit together inside a closet. var/storage_capacity = 30 //This is so that someone can't pack hundreds of items in a locker/crate then open it in a populated area to crash clients. - var/cutting_tool = /obj/item/weldingtool + // defaults to welder if null + var/cutting_tool = TOOL_WELDER var/open_sound = 'sound/machines/closet_open.ogg' var/close_sound = 'sound/machines/closet_close.ogg' var/open_sound_volume = 35 @@ -261,27 +262,22 @@ /obj/structure/closet/proc/tool_interact(obj/item/W, mob/user)//returns TRUE if attackBy call shouldnt be continued (because tool was used/closet was of wrong type), FALSE if otherwise . = TRUE if(opened) - if(istype(W, cutting_tool)) - if(W.tool_behaviour == TOOL_WELDER) - if(!W.tool_start_check(user, amount=0)) - return - - to_chat(user, "You begin cutting \the [src] apart...") - if(W.use_tool(src, user, 40, volume=50)) - if(!opened) - return - user.visible_message("[user] slices apart \the [src].", - "You cut \the [src] apart with \the [W].", - "You hear welding.") - deconstruct(TRUE) + if(W.tool_behaviour == cutting_tool && user.a_intent != INTENT_HELP) + if(!W.tool_start_check(user, amount=0)) return - else // for example cardboard box is cut with wirecutters - user.visible_message("[user] cut apart \the [src].", \ - "You cut \the [src] apart with \the [W].") + + to_chat(user, "You begin cutting \the [src] apart...") + if(W.use_tool(src, user, 40, volume=50)) + if(!opened) + return + user.visible_message("[user] slices apart \the [src].", + "You cut \the [src] apart with \the [W].", + "You hear cutting.") deconstruct(TRUE) - return + return if(user.transferItemToLoc(W, drop_location())) // so we put in unlit welder too return + return else if(W.tool_behaviour == TOOL_WELDER && can_weld_shut) if(!W.tool_start_check(user, amount=0)) return diff --git a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm b/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm index a5d7531b0aa8f..7135b3d199a2d 100644 --- a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm +++ b/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm @@ -8,7 +8,7 @@ max_integrity = 70 integrity_failure = 0 can_weld_shut = 0 - cutting_tool = /obj/item/wirecutters + cutting_tool = TOOL_WIRECUTTER material_drop = /obj/item/stack/sheet/cardboard delivery_icon = "deliverybox" anchorable = FALSE @@ -70,7 +70,7 @@ mob_storage_capacity = 5 resistance_flags = NONE move_speed_multiplier = 2 - cutting_tool = /obj/item/weldingtool + cutting_tool = TOOL_WELDER open_sound = 'sound/machines/crate_open.ogg' close_sound = 'sound/machines/crate_close.ogg' open_sound_volume = 35 diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm index 6463282eb6dfd..6a3cae5bbd724 100644 --- a/code/game/objects/structures/girders.dm +++ b/code/game/objects/structures/girders.dm @@ -38,7 +38,7 @@ if(istype(W, /obj/item/gun/energy/plasmacutter)) to_chat(user, "You start slicing apart the girder...") - if(W.use_tool(src, user, 40, volume=100)) + if(W.use_tool(src, user, 10, volume=100)) to_chat(user, "You slice apart the girder.") var/obj/item/stack/sheet/metal/M = new (loc, 2) M.add_fingerprint(user) diff --git a/code/game/turfs/closed/minerals.dm b/code/game/turfs/closed/minerals.dm index 33fcf315fc525..9936053ea3ad5 100644 --- a/code/game/turfs/closed/minerals.dm +++ b/code/game/turfs/closed/minerals.dm @@ -89,10 +89,15 @@ else return attack_hand(user) -/turf/closed/mineral/proc/gets_drilled(user, give_exp = FALSE) +/turf/closed/mineral/proc/gets_drilled(user, give_exp = FALSE, slag_chance = 0) if (mineralType && (mineralAmt > 0)) - new mineralType(src, mineralAmt) - SSblackbox.record_feedback("tally", "ore_mined", mineralAmt, mineralType) + //oops, you ruined the ore + if(prob(slag_chance)) + new /obj/item/stack/ore/slag(src,mineralAmt) + visible_message(span_warning("The ore was completely ruined!")) + else + new mineralType(src, mineralAmt) + SSblackbox.record_feedback("tally", "ore_mined", mineralAmt, mineralType) if(ishuman(user)) var/mob/living/carbon/human/H = user if(give_exp) diff --git a/code/game/turfs/closed/wall/conc_walls.dm b/code/game/turfs/closed/wall/conc_walls.dm index 6f0487ff39b74..aa5845b1144b9 100644 --- a/code/game/turfs/closed/wall/conc_walls.dm +++ b/code/game/turfs/closed/wall/conc_walls.dm @@ -11,34 +11,26 @@ hardness = 30 // doesn't matter much; everything that uses it gets overridden explosion_block = 3 break_sound = 'sound/effects/break_stone.ogg' + attack_hitsound = 'sound/effects/hit_stone.ogg' + hitsound_type = PROJECTILE_HITSOUND_STONE sheet_type = null girder_type = /obj/structure/grille - // The wall will ignore damage from weak items, depending on their - // force, damage type, tool behavior, and sharpness. This is the minimum - // amount of force that a blunt, brute item must have to damage the wall. - var/min_dam = 8 - // This should all be handled by integrity should that ever be expanded to walls. - var/max_health = 650 - var/health - // used to give mining projectiles a bit of an edge against conc walls - var/static/list/extra_dam_proj = typecacheof(list( - /obj/projectile/kinetic, - /obj/projectile/destabilizer, - /obj/projectile/plasma - )) - var/time_to_harden = 30 SECONDS // fraction ranging from 0 to 1 -- 0 is fully soft, 1 is fully hardened // don't change this in subtypes unless you want them to spawn in soft on maps var/harden_lvl = 1 - var/mutable_appearance/crack_overlay + burn_mod = 0.66 + repair_amount = 0 + //mining projectiles do extra damage + extra_dam_proj = list( + /obj/projectile/kinetic, + /obj/projectile/destabilizer, + /obj/projectile/plasma) /turf/closed/wall/concrete/Initialize(mapload, ...) . = ..() - if(health == null) - health = max_health check_harden() update_stats() @@ -46,9 +38,9 @@ . = ..() // by this point it's guaranteed to be a concrete wall var/turf/closed/wall/concrete/conc_wall = T - if(conc_wall.health != health || conc_wall.harden_lvl != harden_lvl) + if(conc_wall.integrity != integrity || conc_wall.harden_lvl != harden_lvl) conc_wall.harden_lvl = harden_lvl - conc_wall.health = health + conc_wall.integrity = integrity // very much not a fan of all the repetition here, // but there's unfortunately no easy way around it conc_wall.check_harden() @@ -68,17 +60,7 @@ add_filter("harden", 1, color_matrix_filter(col_filter, FILTER_COLOR_RGB)) return -/turf/closed/wall/concrete/update_overlays() - . = ..() - var/adj_dam_pct = 1 - (health/(max_health*0.7)) - if(adj_dam_pct <= 0) - return - if(!crack_overlay) - crack_overlay = mutable_appearance('icons/effects/concrete_damage.dmi', "cracks", BULLET_HOLE_LAYER) - crack_overlay.alpha = adj_dam_pct*255 - . += crack_overlay - -// we use this to show health + drying percentage +// we use this to show integrity + drying percentage /turf/closed/wall/concrete/deconstruction_hints(mob/user) . = list() . += "[p_they(TRUE)] look[p_s()] like you could smash [p_them()]." @@ -89,19 +71,12 @@ . += "[p_they(TRUE)] look[p_s()] a little wet." if(0 to 0.4) . += "[p_they(TRUE)] look[p_s()] freshly poured." - switch(health / max_health) - if(0.5 to 0.99) - . += "[p_they(TRUE)] look[p_s()] slightly damaged." - if(0.25 to 0.5) - . += "[p_they(TRUE)] appear[p_s()] heavily damaged." - if(0 to 0.25) - . += "[p_theyre(TRUE)] falling apart!" return /turf/closed/wall/concrete/create_girder() var/obj/girder = ..() - if(health < 0) - girder.take_damage(min(abs(health), 50)) + if(integrity < 0) + girder.take_damage(min(abs(integrity), 50)) return girder /turf/closed/wall/concrete/proc/check_harden() @@ -115,66 +90,16 @@ STOP_PROCESSING(SSobj, src) update_stats() -/turf/closed/wall/concrete/proc/update_stats() +/turf/closed/wall/concrete/update_stats() + .= .. () // explosion block is diminished on a damaged / soft wall - explosion_block = (health / max_health) * harden_lvl * initial(explosion_block) - update_appearance() + explosion_block = (integrity / max_integrity) * harden_lvl * initial(explosion_block) -/turf/closed/wall/concrete/proc/alter_health(delta) +/turf/closed/wall/concrete/alter_integrity(damage) // 8x as vulnerable when unhardened - if(delta < 0) - delta *= 1 + 7*(1-harden_lvl) - health += delta - if(health <= 0) - // if damage put us 50 points or more below 0, we got proper demolished - dismantle_wall(health <= -50 ? TRUE : FALSE) - return FALSE - health = min(health, max_health) - update_stats() - return health - -/turf/closed/wall/concrete/ex_act(severity, target) - if(target == src || !density) - return ..() - switch(severity) - if(EXPLODE_DEVASTATE) - alter_health(-2000) - if(EXPLODE_HEAVY) - alter_health(rand(-500, -800)) - if(EXPLODE_LIGHT) - alter_health(rand(-200, -700)) - -/turf/closed/wall/concrete/bullet_act(obj/projectile/P) - . = ..() - var/dam = get_proj_damage(P) - if(!dam) - return - if(P.suppressed != SUPPRESSED_VERY) - visible_message("[src] is hit by \a [P]!", null, null, COMBAT_MESSAGE_RANGE) - if(!QDELETED(src)) - alter_health(-dam) - -/turf/closed/wall/concrete/attack_animal(mob/living/simple_animal/M) - M.changeNext_move(CLICK_CD_MELEE) - M.do_attack_animation(src) - if((M.environment_smash & ENVIRONMENT_SMASH_WALLS) || (M.environment_smash & ENVIRONMENT_SMASH_RWALLS)) - playsound(src, 'sound/effects/meteorimpact.ogg', 100, TRUE) - alter_health(-400) - return - -/turf/closed/wall/concrete/attack_hulk(mob/living/carbon/user) - SEND_SIGNAL(src, COMSIG_ATOM_HULK_ATTACK, user) - log_combat(user, src, "attacked") - var/obj/item/bodypart/arm = user.hand_bodyparts[user.active_hand_index] - if(!arm || arm.bodypart_disabled) - return FALSE - playsound(src, 'sound/effects/meteorimpact.ogg', 100, TRUE) - user.visible_message("[user] smashes \the [src]!", \ - "You smash \the [src]!", \ - "You hear a booming smash!") - user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ), forced = "hulk") - alter_health(-250) - return TRUE + if(damage < 0) + damage *= 1 + 7*(1-harden_lvl) + .= ..() /turf/closed/wall/concrete/mech_melee_attack(obj/mecha/M) M.do_attack_animation(src) @@ -184,7 +109,7 @@ "You hit [src]!", null, COMBAT_MESSAGE_RANGE) playsound(src, 'sound/weapons/punch4.ogg', 50, TRUE) playsound(src, 'sound/effects/meteorimpact.ogg', 100, TRUE) - alter_health(M.force * -20) + alter_integrity(M.force * -20) if(BURN) playsound(src, 'sound/items/welder.ogg', 100, TRUE) if(TOX) @@ -198,60 +123,14 @@ /turf/closed/wall/concrete/try_decon(obj/item/W, mob/user, turf/T) return null -// catch-all for using most items on the wall -- attempt to smash -/turf/closed/wall/concrete/try_destroy(obj/item/W, mob/user, turf/T) - var/dam = get_item_damage(W) - user.do_attack_animation(src) - if(!dam) - to_chat(user, "[W] isn't strong enough to damage [src]!") - playsound(src, 'sound/weapons/tap.ogg', 50, TRUE) - return TRUE - log_combat(user, src, "attacked", W) - user.visible_message("[user] hits [src] with [W]!", \ - "You hit [src] with [W]!", null, COMBAT_MESSAGE_RANGE) - switch(W.damtype) - if(BRUTE) - playsound(src, 'sound/effects/hit_stone.ogg', 50, TRUE) - if(BURN) - playsound(src, 'sound/items/welder.ogg', 100, TRUE) - alter_health(-dam) - return TRUE +/turf/closed/wall/concrete/get_item_damage(obj/item/I, t_min = min_dam) + t_min = min_dam / (1 + 7*(1-harden_lvl)) // drying walls are more vulnerable + . = .. () -/turf/closed/wall/concrete/proc/get_item_damage(obj/item/I) - var/dam = I.force - if(istype(I, /obj/item/clothing/gloves/gauntlets)) - dam = 20 - else if(I.tool_behaviour == TOOL_MINING) - dam *= (4/3) - else - switch(I.damtype) - if(BRUTE) - if(I.get_sharpness()) - dam *= 2/3 - if(BURN) - dam *= 2/3 - else - return 0 - var/t_min = min_dam / (1 + 7*(1-harden_lvl)) // drying walls are more vulnerable - // if dam is below t_min, then the hit has no effect - return (dam < t_min ? 0 : dam) -/turf/closed/wall/concrete/proc/get_proj_damage(obj/projectile/P) - var/dam = P.damage - // mining projectiles have an edge - if(is_type_in_typecache(P, extra_dam_proj)) - dam = max(dam, 30) - else - switch(P.damage_type) - if(BRUTE) - dam *= 1 - if(BURN) - dam *= 2/3 - else - return 0 - var/t_min = min_dam / (1 + 7*(1-harden_lvl)) // drying walls are more vulnerable - // if dam is below t_min, then the hit has no effect - return (dam < t_min ? 0 : dam) +/turf/closed/wall/concrete/get_proj_damage(obj/projectile/P, t_min = min_dam) + t_min = min_dam / (1 + 7*(1-harden_lvl)) // drying walls are more vulnerable + . = ..() /turf/closed/wall/concrete/reinforced name = "hexacrete wall" @@ -266,7 +145,7 @@ girder_type = /obj/structure/girder min_dam = 13 - max_health = 1300 + max_integrity = 1300 time_to_harden = 60 SECONDS // requires ENVIRONMENT_SMASH_RWALLS for simplemobs to break @@ -276,7 +155,7 @@ if(!M.environment_smash) return if(M.environment_smash & ENVIRONMENT_SMASH_RWALLS) - alter_health(-600) // 3 hits to kill + alter_integrity(-600) // 3 hits to kill playsound(src, 'sound/effects/meteorimpact.ogg', 100, TRUE) else playsound(src, 'sound/effects/bang.ogg', 50, TRUE) diff --git a/code/game/turfs/closed/wall/mineral_walls.dm b/code/game/turfs/closed/wall/mineral_walls.dm index 53dbb9479f3b3..367e488ba868e 100644 --- a/code/game/turfs/closed/wall/mineral_walls.dm +++ b/code/game/turfs/closed/wall/mineral_walls.dm @@ -23,6 +23,8 @@ connector_icon = 'icons/turf/connectors/gold_wall_connector.dmi' connector_icon_state = "gold_wall_connector" no_connector_typecache = list(/turf/closed/wall/mineral/gold, /obj/structure/falsewall/gold) + max_integrity = 150 + brute_mod = 1.5 /turf/closed/wall/mineral/gold/yesdiag icon_state = "gold_wall-255" @@ -41,6 +43,8 @@ connector_icon = 'icons/turf/connectors/silver_wall_connector.dmi' connector_icon_state = "silver_wall_connector" no_connector_typecache = list(/turf/closed/wall/mineral/silver, /obj/structure/falsewall/silver) + max_integrity = 150 + brute_mod = 1.5 /turf/closed/wall/mineral/silver/yesdiag icon_state = "silver_wall-255" @@ -53,7 +57,7 @@ icon_state = "diamond_wall-0" base_icon_state = "diamond_wall" sheet_type = /obj/item/stack/sheet/mineral/diamond - slicing_duration = 200 //diamond wall takes twice as much time to slice + slicing_duration = 50 explosion_block = 3 smoothing_flags = SMOOTH_BITMASK | SMOOTH_CONNECTORS smoothing_groups = list(SMOOTH_GROUP_CLOSED_TURFS, SMOOTH_GROUP_WALLS, SMOOTH_GROUP_DIAMOND_WALLS) @@ -63,6 +67,7 @@ no_connector_typecache = list(/turf/closed/wall/mineral/diamond, /obj/structure/falsewall/diamond) hitsound_type = PROJECTILE_HITSOUND_GLASS + max_integrity = 800 /turf/closed/wall/mineral/diamond/yesdiag icon_state = "diamond_wall-255" @@ -84,6 +89,8 @@ no_connector_typecache = list(/turf/closed/wall/mineral/sandstone, /obj/structure/falsewall/sandstone) hitsound_type = PROJECTILE_HITSOUND_NON_LIVING + max_integrity = 150 + min_dam = 5 /turf/closed/wall/mineral/sandstone/yesdiag icon_state = "sandstone_wall-255" @@ -103,6 +110,7 @@ connector_icon = 'icons/turf/connectors/uranium_wall_connector.dmi' connector_icon_state = "uranium_wall_connector" no_connector_typecache = list(/turf/closed/wall/mineral/uranium, /obj/structure/falsewall/uranium) + max_integrity = 600 /turf/closed/wall/mineral/uranium/yesdiag icon_state = "uranium_wall-255" @@ -170,6 +178,8 @@ no_connector_typecache = list(/turf/closed/wall/mineral/plasma, /obj/structure/falsewall/plasma) hitsound_type = PROJECTILE_HITSOUND_GLASS + max_integrity = 300 + burn_mod = 3 /turf/closed/wall/mineral/plasma/yesdiag icon_state = "plasma_wall-255" @@ -221,6 +231,9 @@ no_connector_typecache = list(/turf/closed/wall/mineral/wood, /obj/structure/falsewall/wood) hitsound_type = PROJECTILE_HITSOUND_WOOD + max_integrity = 75 + burn_mod = 3 + min_dam = 3 /turf/closed/wall/mineral/wood/yesdiag icon_state = "wood_wall-255" @@ -260,6 +273,8 @@ connector_icon_state = "iron_wall_connector" no_connector_typecache = list(/turf/closed/wall/mineral/iron, /obj/structure/falsewall/iron) + max_integrity = 300 + /turf/closed/wall/mineral/iron/yesdiag icon_state = "iron_wall-255" smoothing_flags = SMOOTH_BITMASK | SMOOTH_DIAGONAL_CORNERS @@ -287,6 +302,11 @@ hitsound_type = PROJECTILE_HITSOUND_SNOW + max_integrity = 50 + burn_mod = 3 + brute_mod = 1.5 + min_dam = 1 + /turf/closed/wall/mineral/snow/yesdiag icon_state = "snow_wall-255" smoothing_flags = SMOOTH_BITMASK | SMOOTH_DIAGONAL_CORNERS @@ -298,12 +318,14 @@ icon_state = "abductor_wall-0" base_icon_state = "abductor_wall" sheet_type = /obj/item/stack/sheet/mineral/abductor - slicing_duration = 200 //alien wall takes twice as much time to slice + slicing_duration = 100 //alien wall takes twice as much time to slice explosion_block = 3 smoothing_flags = SMOOTH_BITMASK | SMOOTH_DIAGONAL_CORNERS smoothing_groups = list(SMOOTH_GROUP_CLOSED_TURFS, SMOOTH_GROUP_WALLS, SMOOTH_GROUP_ABDUCTOR_WALLS) canSmoothWith = list(SMOOTH_GROUP_ABDUCTOR_WALLS,SMOOTH_GROUP_AIRLOCK) + max_integrity = 1000 + /////////////////////Titanium walls///////////////////// /turf/closed/wall/mineral/titanium //has to use this path due to how building walls works @@ -322,6 +344,8 @@ hitsound_type = PROJECTILE_HITSOUND_NON_LIVING + max_integrity = 450 + /turf/closed/wall/mineral/titanium/exterior smoothing_groups = list(SMOOTH_GROUP_CLOSED_TURFS, SMOOTH_GROUP_WALLS, SMOOTH_GROUP_TITANIUM_WALLS_EXTERIOR) canSmoothWith = list(SMOOTH_GROUP_TITANIUM_WALLS_EXTERIOR, SMOOTH_GROUP_AIRLOCK, SMOOTH_GROUP_SHUTTLE_PARTS, SMOOTH_GROUP_WALLS, SMOOTH_GROUP_WINDOW_FULLTILE) @@ -400,6 +424,8 @@ hitsound_type = PROJECTILE_HITSOUND_NON_LIVING + max_integrity = 500 + /turf/closed/wall/mineral/plastitanium/nodiagonal icon = 'icons/turf/walls/plastitanium_wall.dmi' icon_state = "map-shuttle_nd" diff --git a/code/game/turfs/closed/wall/misc_walls.dm b/code/game/turfs/closed/wall/misc_walls.dm index 7fbcab55504a7..da4599fc3c1bf 100644 --- a/code/game/turfs/closed/wall/misc_walls.dm +++ b/code/game/turfs/closed/wall/misc_walls.dm @@ -10,6 +10,8 @@ sheet_amount = 1 girder_type = /obj/structure/girder/cult + max_integrity = 600 + /turf/closed/wall/mineral/cult/Initialize(mapload, inherited_virtual_z) new /obj/effect/temp_visual/cult/turf(src) . = ..() @@ -47,8 +49,9 @@ smoothing_flags = SMOOTH_BITMASK canSmoothWith = null hardness = 35 - slicing_duration = 150 //welding through the ice+metal + slicing_duration = 40 bullet_sizzle = TRUE + burn_mod = 2 /turf/closed/wall/rust name = "rusted wall" @@ -58,6 +61,8 @@ base_icon_state = "rusty_wall" smoothing_flags = SMOOTH_BITMASK hardness = 45 + max_integrity = 300 + min_dam = 5 /turf/closed/wall/rust/yesdiag icon_state = "rusty_wall-255" @@ -71,6 +76,8 @@ base_icon_state = "rusty_reinforced_wall" smoothing_flags = SMOOTH_BITMASK hardness = 15 + integrity = 1000 + min_dam = 5 /turf/closed/wall/r_wall/rust/yesdiag icon_state = "rusty_reinforced_wall-255" diff --git a/code/game/turfs/closed/wall/reinf_walls.dm b/code/game/turfs/closed/wall/reinf_walls.dm index 1bd8f6783fd5b..c24565a68f252 100644 --- a/code/game/turfs/closed/wall/reinf_walls.dm +++ b/code/game/turfs/closed/wall/reinf_walls.dm @@ -21,6 +21,8 @@ ///Dismantled state, related to deconstruction. var/d_state = INTACT + max_integrity = 1400 + /turf/closed/wall/r_wall/yesdiag icon_state = "reinforced_wall-255" smoothing_flags = SMOOTH_BITMASK | SMOOTH_DIAGONAL_CORNERS @@ -54,28 +56,37 @@ playsound(src, 'sound/effects/bang.ogg', 50, TRUE) to_chat(M, "This wall is far too strong for you to destroy.") -/turf/closed/wall/r_wall/try_destroy(obj/item/I, mob/user, turf/T) - if(istype(I, /obj/item/pickaxe/drill/jackhammer)) - to_chat(user, "You begin to smash though [src]...") - if(do_after(user, 75, target = src)) - if(!istype(src, /turf/closed/wall/r_wall)) - return TRUE - I.play_tool_sound(src) - visible_message("[user] smashes through [src] with [I]!", "You hear the grinding of metal.") - dismantle_wall() - return TRUE - return FALSE +/turf/closed/wall/r_wall/update_stats() + var/integrity_per_state = max_integrity/7 + d_state = (7 - round(integrity/integrity_per_state)) + .= ..() + +/// Calculate how much integrity the r-wall should have a a given state. +/turf/closed/wall/r_wall/proc/get_state_integrity(state) + if(state > INTACT) + state = INTACT + if(state < SHEATH) + state = SHEATH + return max_integrity - ((max_integrity/7) * state) /turf/closed/wall/r_wall/try_decon(obj/item/W, mob/user, turf/T) //DECONSTRUCTION + if(istype(W,/obj/item/gun/energy/plasmacutter)) + to_chat(user, "You begin slicing through the [src].") + while(W.use_tool(src,user,30,volume = 100)) + to_chat(user, "You slice through some of the outer plating...") + alter_integrity(-(W.wall_decon_damage)) + return 1 + switch(d_state) if(INTACT) if(W.tool_behaviour == TOOL_WIRECUTTER) - W.play_tool_sound(src, 100) - d_state = SUPPORT_LINES - update_appearance() - to_chat(user, "You cut the outer grille.") - return 1 + if(W.use_tool(src, user, 40, volume=100)) + W.play_tool_sound(src, 100) + d_state = SUPPORT_LINES + set_integrity(get_state_integrity(SUPPORT_LINES)) + to_chat(user, "You cut the outer grille.") + return 1 if(SUPPORT_LINES) if(W.tool_behaviour == TOOL_SCREWDRIVER) @@ -84,16 +95,18 @@ if(!istype(src, /turf/closed/wall/r_wall) || d_state != SUPPORT_LINES) return 1 d_state = COVER + set_integrity(get_state_integrity(COVER)) update_appearance() to_chat(user, "You unsecure the support lines.") return 1 else if(W.tool_behaviour == TOOL_WIRECUTTER) - W.play_tool_sound(src, 100) - d_state = INTACT - update_appearance() - to_chat(user, "You repair the outer grille.") - return 1 + if(W.use_tool(src, user, 40, volume=100)) + W.play_tool_sound(src, 100) + d_state = INTACT + set_integrity(get_state_integrity(INTACT)) + to_chat(user, "You repair the outer grille.") + return 1 if(COVER) if(W.tool_behaviour == TOOL_WELDER) @@ -104,7 +117,7 @@ if(!istype(src, /turf/closed/wall/r_wall) || d_state != COVER) return 1 d_state = CUT_COVER - update_appearance() + set_integrity(get_state_integrity(CUT_COVER)) to_chat(user, "You press firmly on the cover, dislodging it.") return 1 @@ -114,7 +127,7 @@ if(!istype(src, /turf/closed/wall/r_wall) || d_state != COVER) return 1 d_state = SUPPORT_LINES - update_appearance() + set_integrity(get_state_integrity(SUPPORT_LINES)) to_chat(user, "The support lines have been secured.") return 1 @@ -125,7 +138,7 @@ if(!istype(src, /turf/closed/wall/r_wall) || d_state != CUT_COVER) return 1 d_state = ANCHOR_BOLTS - update_appearance() + set_integrity(get_state_integrity(ANCHOR_BOLTS)) to_chat(user, "You pry off the cover.") return 1 @@ -137,7 +150,7 @@ if(!istype(src, /turf/closed/wall/r_wall) || d_state != CUT_COVER) return TRUE d_state = COVER - update_appearance() + set_integrity(get_state_integrity(COVER)) to_chat(user, "The metal cover has been welded securely to the frame.") return 1 @@ -148,7 +161,7 @@ if(!istype(src, /turf/closed/wall/r_wall) || d_state != ANCHOR_BOLTS) return 1 d_state = SUPPORT_RODS - update_appearance() + set_integrity(get_state_integrity(SUPPORT_RODS)) to_chat(user, "You remove the bolts anchoring the support rods.") return 1 @@ -158,7 +171,7 @@ if(!istype(src, /turf/closed/wall/r_wall) || d_state != ANCHOR_BOLTS) return 1 d_state = CUT_COVER - update_appearance() + set_integrity(get_state_integrity(CUT_COVER)) to_chat(user, "The metal cover has been pried back into place.") return 1 @@ -171,7 +184,7 @@ if(!istype(src, /turf/closed/wall/r_wall) || d_state != SUPPORT_RODS) return 1 d_state = SHEATH - update_appearance() + set_integrity(get_state_integrity(SHEATH)) to_chat(user, "You slice through the support rods.") return 1 @@ -182,7 +195,7 @@ if(!istype(src, /turf/closed/wall/r_wall) || d_state != SUPPORT_RODS) return 1 d_state = ANCHOR_BOLTS - update_appearance() + set_integrity(get_state_integrity(ANCHOR_BOLTS)) to_chat(user, "You tighten the bolts anchoring the support rods.") return 1 @@ -204,7 +217,7 @@ if(!istype(src, /turf/closed/wall/r_wall) || d_state != SHEATH) return TRUE d_state = SUPPORT_RODS - update_appearance() + set_integrity(get_state_integrity(SUPPORT_RODS)) to_chat(user, "You weld the support rods back together.") return 1 return 0 diff --git a/code/game/turfs/closed/walls.dm b/code/game/turfs/closed/walls.dm index f93faeb8297da..9f0aa58c21800 100644 --- a/code/game/turfs/closed/walls.dm +++ b/code/game/turfs/closed/walls.dm @@ -21,14 +21,31 @@ ///lower numbers are harder. Used to determine the probability of a hulk smashing through. var/hardness = 40 - var/slicing_duration = 100 //default time taken to slice the wall + var/slicing_duration = 25 //default time taken to slice the wall var/sheet_type = /obj/item/stack/sheet/metal var/sheet_amount = 2 var/obj/girder_type = /obj/structure/girder + /// sound when something hits the wall and deals damage + var/attack_hitsound = 'sound/weapons/smash.ogg' var/break_sound = 'sound/items/welder.ogg' + hitsound_type = PROJECTILE_HITSOUND_METAL var/list/dent_decals + // The wall will ignore damage from weak items, depending on their + // force, damage type, tool behavior, and sharpness. This is the minimum + // amount of force that a blunt, brute item must have to damage the wall. + var/min_dam = 8 + var/max_integrity = 400 + var/integrity + var/brute_mod = 1 + var/burn_mod = 1 + var/repair_amount = 50 + // Projectiles that do extra damage to the wall + var/list/extra_dam_proj + + var/mutable_appearance/crack_overlay + /turf/closed/wall/yesdiag icon_state = "wall-255" smoothing_flags = SMOOTH_BITMASK | SMOOTH_DIAGONAL_CORNERS @@ -46,6 +63,9 @@ underlay_appearance.icon_state = fixed_underlay["icon_state"] fixed_underlay = string_assoc_list(fixed_underlay) underlays += underlay_appearance + if(integrity == null) + integrity = max_integrity + /turf/closed/wall/copyTurf(turf/T, copy_air, flags) . = ..() @@ -58,10 +78,29 @@ . = ..() for(var/decal in dent_decals) . += decal + var/adj_dam_pct = 1 - (integrity/(max_integrity)) + if(adj_dam_pct < 0) + adj_dam_pct = 0 + crack_overlay = null + if(!crack_overlay) + crack_overlay = mutable_appearance('icons/effects/wall_damage.dmi', "cracks", BULLET_HOLE_LAYER) + crack_overlay.alpha = adj_dam_pct*255 + . += crack_overlay /turf/closed/wall/examine(mob/user) . += ..() . += deconstruction_hints(user) + . += damage_hints(user) + +/turf/closed/wall/proc/damage_hints(mob/user) + switch(integrity / max_integrity) + if(0.5 to 0.99) + return "[p_they(TRUE)] look[p_s()] slightly damaged." + if(0.25 to 0.5) + return "[p_they(TRUE)] appear[p_s()] heavily damaged." + if(0 to 0.25) + return "[p_theyre(TRUE)] falling apart!" + return /turf/closed/wall/proc/deconstruction_hints(mob/user) return "The outer plating is welded firmly in place." @@ -69,6 +108,99 @@ /turf/closed/wall/attack_tk() return +// negative values reduce integrity, positive values increase integrity +/turf/closed/wall/proc/alter_integrity(damage, devastate = FALSE, safe_decon = FALSE) + integrity += damage + if(integrity >= max_integrity) + integrity = max_integrity + if(integrity <= 0) + if(safe_decon) + dismantle_wall() + return FALSE + // if damage put us 50 points or more below 0, and not safe decon we got proper demolished + if(integrity <= -50) + dismantle_wall(TRUE) + return FALSE + if(devastate) + dismantle_wall(TRUE) + return FALSE + dismantle_wall() + return FALSE + integrity = min(integrity, max_integrity) + update_stats() + return integrity + +/turf/closed/wall/proc/set_integrity(amount,devastate = FALSE) + integrity = amount + update_stats() + if(integrity <= 0) + dismantle_wall(devastate) + +/turf/closed/wall/proc/update_stats() + update_appearance() + +/turf/closed/wall/bullet_act(obj/projectile/P) + . = ..() + var/dam = get_proj_damage(P) + if(!dam) + return + if(P.suppressed != SUPPRESSED_VERY) + visible_message("[src] is hit by \a [P]!", null, null, COMBAT_MESSAGE_RANGE) + if(!QDELETED(src)) + alter_integrity(-dam) + +// catch-all for using most items on the wall -- attempt to smash +/turf/closed/wall/proc/try_destroy(obj/item/W, mob/user, turf/T) + var/dam = get_item_damage(W) + user.do_attack_animation(src) + if(!dam) + to_chat(user, "[W] isn't strong enough to damage [src]!") + playsound(src, 'sound/weapons/tap.ogg', 50, TRUE) + return TRUE + log_combat(user, src, "attacked", W) + user.visible_message("[user] hits [src] with [W]!", \ + "You hit [src] with [W]!", null, COMBAT_MESSAGE_RANGE) + switch(W.damtype) + if(BRUTE) + playsound(src,attack_hitsound, 100, TRUE) + if(BURN) + playsound(src, 'sound/items/welder.ogg', 100, TRUE) + alter_integrity(-dam) + return TRUE + +/turf/closed/wall/proc/get_item_damage(obj/item/I, t_min = min_dam) + var/dam = I.force + if(istype(I, /obj/item/clothing/gloves/gauntlets)) + dam = 20 + else if(I.tool_behaviour == TOOL_MINING) + dam *= (4/3) + else + switch(I.damtype) + if(BRUTE) + if(I.get_sharpness()) + dam *= 2/3 + if(BURN) + dam *= burn_mod + else + return 0 + // if dam is below t_min, then the hit has no effect + return (dam < t_min ? 0 : dam) + +/turf/closed/wall/proc/get_proj_damage(obj/projectile/P, t_min = min_dam) + var/dam = P.damage + if(is_type_in_list(P, extra_dam_proj)) + dam = max(dam, 30) + else + switch(P.damage_type) + if(BRUTE) + dam *= brute_mod + if(BURN) + dam *= burn_mod + else + return 0 + // if dam is below t_min, then the hit has no effect + return (dam < t_min ? 0 : dam) + /turf/closed/wall/proc/dismantle_wall(devastated = FALSE) create_sheets() var/obj/newgirder = create_girder() @@ -97,54 +229,51 @@ return null /turf/closed/wall/ex_act(severity, target) - if(target == src) - dismantle_wall(devastated = TRUE) - return + if(target == src || !density) + return ..() switch(severity) if(EXPLODE_DEVASTATE) - //SN src = null + // SN src = null var/turf/NT = ScrapeAway() NT.contents_explosion(severity, target) return if(EXPLODE_HEAVY) - if (prob(50)) - dismantle_wall(devastated = TRUE) - else - dismantle_wall(devastated = FALSE) + alter_integrity(rand(-500, -800)) if(EXPLODE_LIGHT) - if (prob(hardness)) - dismantle_wall(devastated = FALSE) - if(!density) - ..() + alter_integrity(rand(-200, -700)) /turf/closed/wall/mech_melee_attack(obj/mecha/M) M.do_attack_animation(src) switch(M.damtype) if(BRUTE) playsound(src, 'sound/weapons/punch4.ogg', 50, TRUE) - M.visible_message("[M.name] hits [src]!", \ - "You hit [src]!", null, COMBAT_MESSAGE_RANGE) - if(prob(hardness + M.force) && M.force > 20) - dismantle_wall(devastated = TRUE) - playsound(src, 'sound/effects/meteorimpact.ogg', 100, TRUE) - else - add_dent(WALL_DENT_HIT) if(BURN) playsound(src, 'sound/items/welder.ogg', 100, TRUE) if(TOX) playsound(src, 'sound/effects/spray2.ogg', 100, TRUE) + + if(prob(hardness + M.force) && M.force > 20) + M.visible_message("[M.name] hits [src] with great force!", \ + "You hit [src] with incredible force!", null, COMBAT_MESSAGE_RANGE) + dismantle_wall(devastated = TRUE) + playsound(src, 'sound/effects/meteorimpact.ogg', 100, TRUE) + else + M.visible_message("[M.name] hits [src]!", \ + "You hit [src]!", null, COMBAT_MESSAGE_RANGE) + add_dent(WALL_DENT_HIT) + alter_integrity(M.force * 20) + /turf/closed/wall/attack_paw(mob/living/user) user.changeNext_move(CLICK_CD_MELEE) return attack_hand(user) - /turf/closed/wall/attack_animal(mob/living/simple_animal/M) M.changeNext_move(CLICK_CD_MELEE) M.do_attack_animation(src) if((M.environment_smash & ENVIRONMENT_SMASH_WALLS) || (M.environment_smash & ENVIRONMENT_SMASH_RWALLS)) playsound(src, 'sound/effects/meteorimpact.ogg', 100, TRUE) - dismantle_wall(devastated = TRUE) + alter_integrity(-400) return /turf/closed/wall/attack_hulk(mob/living/carbon/user) @@ -152,16 +281,11 @@ var/obj/item/bodypart/arm = user.hand_bodyparts[user.active_hand_index] if(!arm || arm.bodypart_disabled) return - if(prob(hardness)) - playsound(src, 'sound/effects/meteorimpact.ogg', 100, TRUE) - user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ), forced = "hulk") - dismantle_wall(devastated = TRUE) - else - playsound(src, 'sound/effects/bang.ogg', 50, TRUE) - add_dent(WALL_DENT_HIT) - user.visible_message("[user] smashes \the [src]!", \ - "You smash \the [src]!", \ - "You hear a booming smash!") + alter_integrity(-250) + add_dent(WALL_DENT_HIT) + user.visible_message("[user] smashes \the [src]!", \ + "You smash \the [src]!", \ + "You hear a booming smash!") return TRUE /turf/closed/wall/attack_hand(mob/user) @@ -194,19 +318,20 @@ return ..() /turf/closed/wall/proc/try_clean(obj/item/W, mob/user, turf/T) - if((user.a_intent != INTENT_HELP) || !LAZYLEN(dent_decals)) + if((user.a_intent != INTENT_HELP)) return FALSE if(W.tool_behaviour == TOOL_WELDER) - if(!W.tool_start_check(user, amount=0)) + if(!W.tool_start_check(user, amount=0) || (integrity >= max_integrity)) return FALSE to_chat(user, "You begin fixing dents on the wall...") - if(W.use_tool(src, user, 0, volume=100)) + if(W.use_tool(src, user, slicing_duration, volume=100)) if(iswallturf(src) && LAZYLEN(dent_decals)) to_chat(user, "You fix some dents on the wall.") dent_decals = null update_appearance() + alter_integrity(repair_amount) return TRUE return FALSE @@ -231,25 +356,11 @@ return FALSE to_chat(user, "You begin slicing through the outer plating...") - if(I.use_tool(src, user, slicing_duration, volume=100)) + while(I.use_tool(src, user, slicing_duration, volume=50)) if(iswallturf(src)) - to_chat(user, "You remove the outer plating.") - dismantle_wall() - return TRUE - - return FALSE + to_chat(user, "You slice through some of the outer plating...") + alter_integrity(-(I.wall_decon_damage),FALSE,TRUE) - -/turf/closed/wall/proc/try_destroy(obj/item/I, mob/user, turf/T) - if(istype(I, /obj/item/pickaxe/drill/jackhammer)) - to_chat(user, "You begin to smash though [src]...") - if(do_after(user, 50, target = src)) - if(!iswallturf(src)) - return TRUE - I.play_tool_sound(src) - visible_message("[user] smashes through [src] with [I]!", "You hear the grinding of metal.") - dismantle_wall() - return TRUE return FALSE /turf/closed/wall/singularity_pull(S, current_size) diff --git a/code/modules/cargo/packs/tools.dm b/code/modules/cargo/packs/tools.dm index 6b43448a5d81e..25ed4aaab554f 100644 --- a/code/modules/cargo/packs/tools.dm +++ b/code/modules/cargo/packs/tools.dm @@ -69,11 +69,17 @@ /datum/supply_pack/tools/jackhammer name = "Jackhammer Crate" - desc = "Contains a jackhammer, ideal for breaking rocks and breaking hull." + desc = "Contains a jackhammer, ideal for breaking rocks." cost = 1750 contains = list(/obj/item/pickaxe/drill/jackhammer) crate_name = "jackhammer crate" +/datum/supply_pack/tools/plasmacutter + name = "Plasmacutter Crate" + desc = "Contains a plasmacutter, capable of rapidly breaking down hull." + cost = 1250 + contains = list(/obj/item/gun/energy/plasmacutter) + crate_name = "plasmacutter crate" /datum/supply_pack/tools/metalfoam name = "Metal Foam Grenade Crate" diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index 09de7690b5eaa..c63c8358e2de4 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -110,7 +110,7 @@ /obj/item/gun/energy/plasmacutter name = "plasma cutter" - desc = "A mining tool capable of expelling concentrated plasma bursts. You could use it to cut limbs off xenos! Or, you know, mine stuff." + desc = "An engineering tool capable of expelling concentrated plasma bursts. You could use it to cut limbs off xenos! Or, you know, cut through walls." icon_state = "plasmacutter" item_state = "plasmacutter" ammo_type = list(/obj/item/ammo_casing/energy/plasma) @@ -123,6 +123,7 @@ heat = 3800 usesound = list('sound/items/welder.ogg', 'sound/items/welder2.ogg') tool_behaviour = TOOL_WELDER + wall_decon_damage = 200 toolspeed = 0.7 //plasmacutters can be used as welders, and are faster than standard welders internal_cell = TRUE //so you don't cheese through the need for plasma - WS EDIT var/charge_weld = 25 //amount of charge used up to start action (multiplied by amount) and per progress_flash_divisor ticks of welding @@ -169,6 +170,21 @@ return TRUE +/obj/item/gun/energy/plasmacutter/attack(mob/living/carbon/human/target, mob/user) + if(!istype(target)) + return ..() + var/obj/item/bodypart/attackedLimb = target.get_bodypart(check_zone(user.zone_selected)) + if(!attackedLimb || IS_ORGANIC_LIMB(attackedLimb) || (user.a_intent == INTENT_HARM)) + return ..() + if(!tool_start_check(user, amount = 1)) + return TRUE + user.visible_message("[user] starts to fix some of the dents on [target]'s [parse_zone(attackedLimb.body_zone)].", + "You start fixing some of the dents on [target == user ? "your" : "[target]'s"] [parse_zone(attackedLimb.body_zone)].") + if(!use_tool(target, user, delay = (target == user ? 5 SECONDS : 0.5 SECONDS), amount = 1, volume = 25)) + return TRUE + item_heal_robotic(target, user, brute_heal = 15, burn_heal = 0) + return TRUE + /obj/item/gun/energy/plasmacutter/use(amount) return (!QDELETED(cell) && cell.use(amount ? amount * charge_weld : charge_weld)) @@ -187,6 +203,9 @@ force = 15 ammo_type = list(/obj/item/ammo_casing/energy/plasma/adv) + wall_decon_damage = 200 + toolspeed = 0.4 + /obj/item/gun/energy/wormhole_projector name = "bluespace wormhole projector" desc = "A projector that emits high density quantum-coupled bluespace beams." //WS Edit - Any anomaly core for phazons diff --git a/code/modules/projectiles/projectile/special/plasma.dm b/code/modules/projectiles/projectile/special/plasma.dm index b398731cfd6c3..736b93c85a635 100644 --- a/code/modules/projectiles/projectile/special/plasma.dm +++ b/code/modules/projectiles/projectile/special/plasma.dm @@ -5,8 +5,9 @@ damage = 5 range = 4 dismemberment = 20 + /// chance that the plasmablast ruins the ore + var/slag_chance = 33 impact_effect_type = /obj/effect/temp_visual/impact_effect/purple_laser - var/mine_range = 3 //mines this many additional tiles of rock tracer_type = /obj/effect/projectile/tracer/plasma_cutter muzzle_type = /obj/effect/projectile/muzzle/plasma_cutter impact_type = /obj/effect/projectile/impact/plasma_cutter @@ -15,22 +16,18 @@ . = ..() if(ismineralturf(target)) var/turf/closed/mineral/M = target - M.gets_drilled(firer, FALSE) - if(mine_range) - mine_range-- - range++ + M.gets_drilled(firer, FALSE, slag_chance) if(range > 0) return BULLET_ACT_FORCE_PIERCE /obj/projectile/plasma/adv damage = 7 range = 5 - mine_range = 5 + slag_chance = 20 /obj/projectile/plasma/adv/mech damage = 10 range = 9 - mine_range = 3 /obj/projectile/plasma/turret //Between normal and advanced for damage, made a beam so not the turret does not destroy glass diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index 31a7c508eecd8..ab2cfd3a46813 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -295,7 +295,7 @@ display_name = "Basic Plasma Research" description = "Research into the mysterious and dangerous substance, plasma." prereq_ids = list("engineering") - design_ids = list("mech_generator") + design_ids = list("mech_generator", "plasmacutter") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) export_price = 5000 @@ -304,7 +304,7 @@ display_name = "Advanced Plasma Research" description = "Research on how to fully exploit the power of plasma." prereq_ids = list("basic_plasma") - design_ids = list("mech_plasma_cutter") + design_ids = list("mech_plasma_cutter","plasmacutter_adv") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) export_price = 5000 @@ -550,7 +550,7 @@ display_name = "Mining Technology" description = "Better than Efficiency V." prereq_ids = list("engineering", "basic_plasma") - design_ids = list("drill", "superresonator", "triggermod", "damagemod", "cooldownmod", "rangemod", "ore_redemption", "mining_equipment_vendor", "cargoexpress", "plasmacutter", "mecha_kineticgun", "weatherradio")//e a r l y g a m e) + design_ids = list("drill", "superresonator", "triggermod", "damagemod", "cooldownmod", "rangemod", "ore_redemption", "mining_equipment_vendor", "cargoexpress", "mecha_kineticgun", "weatherradio")//e a r l y g a m e) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) export_price = 5000 @@ -559,7 +559,7 @@ display_name = "Advanced Mining Technology" description = "Efficiency Level 127" //dumb mc references prereq_ids = list("basic_mining", "adv_engi", "adv_power", "adv_plasma") - design_ids = list("drill_diamond", "jackhammer", "hypermod", "plasmacutter_adv") + design_ids = list("drill_diamond", "jackhammer", "hypermod") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) export_price = 5000 // WS Edit Start - Yeet The BSM diff --git a/code/modules/ruins/lavalandruin_code/elephantgraveyard.dm b/code/modules/ruins/lavalandruin_code/elephantgraveyard.dm index 7a26946f0ddc4..e9ca8f3d40939 100644 --- a/code/modules/ruins/lavalandruin_code/elephantgraveyard.dm +++ b/code/modules/ruins/lavalandruin_code/elephantgraveyard.dm @@ -114,7 +114,7 @@ anchored = TRUE locked = TRUE breakout_time = 900 - cutting_tool = /obj/item/shovel + cutting_tool = TOOL_SHOVEL var/lead_tomb = FALSE var/first_open = FALSE @@ -142,7 +142,7 @@ /obj/structure/closet/crate/grave/tool_interact(obj/item/S, mob/living/carbon/user) if(user.a_intent == INTENT_HELP) //checks to attempt to dig the grave, must be done on help intent only. if(!opened) - if(istype(S,cutting_tool) && S.tool_behaviour == TOOL_SHOVEL) + if(S.tool_behaviour == cutting_tool) to_chat(user, "You start start to dig open \the [src] with \the [S]...") if (do_after(user,20, target = src)) opened = TRUE @@ -164,7 +164,7 @@ return 1 else if((user.a_intent != INTENT_HELP) && opened) //checks to attempt to remove the grave entirely. - if(istype(S,cutting_tool) && S.tool_behaviour == TOOL_SHOVEL) + if(S.tool_behaviour == cutting_tool) to_chat(user, "You start to remove \the [src] with \the [S].") if (do_after(user,15, target = src)) to_chat(user, "You remove \the [src] completely.") diff --git a/icons/effects/concrete_damage.dmi b/icons/effects/wall_damage.dmi similarity index 100% rename from icons/effects/concrete_damage.dmi rename to icons/effects/wall_damage.dmi