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