From 6e89dcfebeb0f54f0626ebbdbbeb653cecb022e6 Mon Sep 17 00:00:00 2001
From: Apogee-dev <60533805+Apogee-dev@users.noreply.github.com>
Date: Fri, 15 Nov 2024 07:21:18 -0800
Subject: [PATCH] Massively rebalances combat exosuit durability (#3351)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## About The Pull Request
Numbers are very, VERY subject to change as this gets tested. In fact,
they’re almost guaranteed to need tuning.
### Combat exos have dramatically buffed armor across the board.
Gygax now has armor equivalent to a bulletproof vest; Durand has armor
comparable to a marine vest.
In general, this means that weapons with neutral or higher AP are
necessary to deal more than chip damage to either exosuit, especially
the Durand, but high-penetrating weapons such as DMRs or hard counters
like EMPs and explosions are still just as effective as before.
### To compensate, repairs are now less efficient and slower.
Repairs for all exosuits, when using a welder, now take a short do_after
to complete, meaning you can't mash LMB to repair. Combat exos
additionally have a repair multiplier that means repairs of all sorts
heal less damage while still consuming the same amount of fuel or
battery and time. Gygaxes have a 25% penalty to repair value and Durands
have a 50% penalty.
### Civilian exo durability is unchanged.
Outside of the slower welder repairs, civilian exos haven't been
touched; Combat Ripleys are just as useful as before, they just
shouldn't feel more durable than a Gygax anymore.
Also I gave the Paladin higher melee armor and lower bullet armor so it
isn't just a palette-swapped Durand.
## Why It's Good For The Game
The fact that the most efficient way to kill combat exos is buckshot is
just plain silly; Exosuits aren't tanks, but they're still supposed to
be heavily armored and require bigger guns to crack. This change
hopefully makes that the case without making exos too much harder to
kill when you have the right tools. Pretty much everybody has access to
a decent anti-exo weapon at low cost in the form of the Illestren, and
bomb damage such as that dealt by a KA is still as efficient as it used
to be, so even the poorest crews shouldn't be completely bereft of tools
to deal with them.
## Changelog
:cl:
balance: Massively buffed combat exosuit armor
balance: Made repairing exosuits with a welder a do_after
balance: Combat exosuits get less healing from repairs
balance: The Paladin now has higher melee armor and lower bullet armor
than the Durand
/:cl:
---------
Co-authored-by: Sun-Soaked <45698967+Sun-Soaked@users.noreply.github.com>
---
code/game/mecha/combat/combat.dm | 3 ++-
code/game/mecha/combat/durand.dm | 14 +++++++-----
code/game/mecha/combat/gygax.dm | 16 +++-----------
code/game/mecha/combat/marauder.dm | 10 ++++-----
.../game/mecha/equipment/tools/other_tools.dm | 22 ++++++++++++++-----
code/game/mecha/mecha.dm | 1 +
code/game/mecha/mecha_defense.dm | 12 +++++-----
7 files changed, 43 insertions(+), 35 deletions(-)
diff --git a/code/game/mecha/combat/combat.dm b/code/game/mecha/combat/combat.dm
index 0ebc11b39558..04f3272cce1b 100644
--- a/code/game/mecha/combat/combat.dm
+++ b/code/game/mecha/combat/combat.dm
@@ -2,10 +2,11 @@
force = 30
internals_req_access = list(ACCESS_MECH_SCIENCE, ACCESS_MECH_SECURITY)
internal_damage_threshold = 50
- armor = list("melee" = 30, "bullet" = 30, "laser" = 15, "energy" = 20, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
+ armor = list("melee" = 40, "bullet" = 50, "laser" = 30, "energy" = 20, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
mouse_pointer = 'icons/effects/mouse_pointers/mecha_mouse.dmi'
destruction_sleep_duration = 40
exit_delay = 40
+ repair_multiplier = 0.75
/obj/mecha/combat/restore_equipment()
mouse_pointer = 'icons/effects/mouse_pointers/mecha_mouse.dmi'
diff --git a/code/game/mecha/combat/durand.dm b/code/game/mecha/combat/durand.dm
index a42e1e29f7ee..3e47ebe80e7c 100644
--- a/code/game/mecha/combat/durand.dm
+++ b/code/game/mecha/combat/durand.dm
@@ -1,12 +1,13 @@
/obj/mecha/combat/durand
- desc = "An aging combat exosuit utilized by the Nanotrasen corporation. Originally developed to combat hostile alien lifeforms."
+ desc = "An aging and extremely well-armored combat exosuit utilized by the Nanotrasen corporation. Originally developed to combat hostile alien lifeforms."
name = "\improper Durand"
icon_state = "durand"
step_in = 4
dir_in = 1 //Facing North.
- max_integrity = 400
- deflect_chance = 20
- armor = list("melee" = 40, "bullet" = 35, "laser" = 15, "energy" = 10, "bomb" = 20, "bio" = 0, "rad" = 50, "fire" = 100, "acid" = 100)
+ max_integrity = 300
+ deflect_chance = 15
+ repair_multiplier = 0.5
+ armor = list("melee" = 50, "bullet" = 75, "laser" = 50, "energy" = 10, "bomb" = 20, "bio" = 0, "rad" = 50, "fire" = 100, "acid" = 100)
max_temperature = 30000
infra_luminosity = 8
force = 40
@@ -18,11 +19,12 @@
/obj/mecha/combat/durand/clip
- desc = "An aging combat exosuit appropriated from abandoned Nanotrasen facilities, now supplied to the CMM-BARD anti-xenofauna division. The defence grid has been modified to disperse controlled electric shocks on contact, at the cost of its ability to block ranged projectiles."
+ desc = "An aging combat exosuit specially modified for the CMM-BARD anti-xenofauna division. Features improved close-combat armor and a modified defence grid able to electrocute melee attackers, at the cost of its ability to block projectiles."
name = "\improper Paladin"
icon_state = "clipdurand"
+ armor = list("melee" = 75, "bullet" = 50, "laser" = 50, "energy" = 10, "bomb" = 20, "bio" = 0, "rad" = 50, "fire" = 100, "acid" = 100)
+ deflect_chance = 20
wreckage = /obj/structure/mecha_wreckage/durand/clip
- armor = list("melee" = 40, "bullet" = 35, "laser" = 15, "energy" = 10, "bomb" = 20, "bio" = 0, "rad" = 50, "fire" = 100, "acid" = 100)
shield_passive_drain = 0
shield_type = /obj/durand_shield/clip
diff --git a/code/game/mecha/combat/gygax.dm b/code/game/mecha/combat/gygax.dm
index 02f66b54236a..a22a8dd4706d 100644
--- a/code/game/mecha/combat/gygax.dm
+++ b/code/game/mecha/combat/gygax.dm
@@ -4,9 +4,9 @@
icon_state = "gygax"
step_in = 3
dir_in = 1 //Facing North.
- max_integrity = 250
+ max_integrity = 300
deflect_chance = 5
- armor = list("melee" = 25, "bullet" = 20, "laser" = 30, "energy" = 15, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
+ armor = list("melee" = 40, "bullet" = 60, "laser" = 40, "energy" = 15, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
max_temperature = 25000
leg_overload_coeff = 80
infra_luminosity = 6
@@ -22,20 +22,10 @@
mechstep(direction) //agile mechs get to move and turn in the same step
/obj/mecha/combat/gygax/dark
- desc = "A lightweight exosuit, painted in a dark scheme. This model appears to have some modifications."
+ desc = "A lightweight exosuit, painted in a dark scheme."
name = "\improper Dark Gygax"
icon_state = "darkgygax"
- max_integrity = 300
- deflect_chance = 20
- armor = list("melee" = 40, "bullet" = 40, "laser" = 50, "energy" = 35, "bomb" = 20, "bio" = 0, "rad" =20, "fire" = 100, "acid" = 100)
- max_temperature = 35000
- leg_overload_coeff = 70
- force = 30
- operation_req_access = list(ACCESS_SYNDICATE)
- internals_req_access = list(ACCESS_SYNDICATE)
wreckage = /obj/structure/mecha_wreckage/gygax/dark
- max_equip = 5
- destruction_sleep_duration = 20
/obj/mecha/combat/gygax/dark/loaded/Initialize()
. = ..()
diff --git a/code/game/mecha/combat/marauder.dm b/code/game/mecha/combat/marauder.dm
index 825d5e24a1b8..b35cc1e370ff 100644
--- a/code/game/mecha/combat/marauder.dm
+++ b/code/game/mecha/combat/marauder.dm
@@ -1,11 +1,11 @@
/obj/mecha/combat/marauder
- desc = "Heavy-duty, combat exosuit, developed after the Durand model. Rarely found among civilian populations."
+ desc = "A heavy-duty combat exosuit that improves on the Durand model in nearly every way. Rarely found among civilian populations."
name = "\improper Marauder"
icon_state = "marauder"
step_in = 5
- max_integrity = 500
- deflect_chance = 25
- armor = list("melee" = 50, "bullet" = 55, "laser" = 40, "energy" = 30, "bomb" = 30, "bio" = 0, "rad" = 60, "fire" = 100, "acid" = 100)
+ max_integrity = 400
+ deflect_chance = 20
+ armor = list("melee" = 50, "bullet" = 75, "laser" = 50, "energy" = 30, "bomb" = 30, "bio" = 0, "rad" = 60, "fire" = 100, "acid" = 100)
max_temperature = 60000
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
infra_luminosity = 3
@@ -43,7 +43,7 @@
max_ammo()
/obj/mecha/combat/marauder/seraph
- desc = "Heavy-duty, command-type exosuit. This is a custom model, utilized only by high-ranking military personnel."
+ desc = "A heavy-duty command-type exosuit. This is a custom model, utilized only by high-ranking military personnel."
name = "\improper Seraph"
icon_state = "seraph"
operation_req_access = list(ACCESS_CENT_SPECOPS)
diff --git a/code/game/mecha/equipment/tools/other_tools.dm b/code/game/mecha/equipment/tools/other_tools.dm
index 1b33de31b54e..d7cc256302bc 100644
--- a/code/game/mecha/equipment/tools/other_tools.dm
+++ b/code/game/mecha/equipment/tools/other_tools.dm
@@ -151,8 +151,8 @@
/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster //what is that noise? A BAWWW from TK mutants.
- name = "armor booster module (Close Combat Weaponry)"
- desc = "Boosts exosuit armor against armed melee attacks. Requires energy to operate."
+ name = "applique armor (Close Combat Weaponry)"
+ desc = "Applique armor to protect civilian exosuits against armed melee attacks. Requires energy to operate. Cannot equip to combat mechs."
icon_state = "mecha_abooster_ccw"
equip_cooldown = 10
energy_drain = 50
@@ -166,11 +166,17 @@
start_cooldown()
return 1
+/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster/can_attach(obj/mecha/M)
+ if(!..())
+ return FALSE
+ if(istype(M, /obj/mecha/working))
+ return TRUE
+ return FALSE
/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster
- name = "armor booster module (Ranged Weaponry)"
- desc = "Boosts exosuit armor against ranged attacks. Completely blocks taser shots. Requires energy to operate."
+ name = "applique armor (Ranged Weaponry)"
+ desc = "Applique armor to protect civilian exosuits against ranged attacks. Completely blocks taser shots. Requires energy to operate. Cannot equip to combat mechs."
icon_state = "mecha_abooster_proj"
equip_cooldown = 10
energy_drain = 50
@@ -184,6 +190,12 @@
start_cooldown()
return 1
+/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster/can_attach(obj/mecha/M)
+ if(!..())
+ return FALSE
+ if(istype(M, /obj/mecha/working))
+ return TRUE
+ return FALSE
////////////////////////////////// REPAIR DROID //////////////////////////////////////////////////
@@ -244,7 +256,7 @@
STOP_PROCESSING(SSobj, src)
set_ready_state(1)
return
- var/h_boost = health_boost
+ var/h_boost = health_boost * chassis.repair_multiplier
var/repaired = 0
if(chassis.internal_damage & MECHA_INT_SHORT_CIRCUIT)
h_boost *= -2
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index eba4801ba56d..11c8003de4ae 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -13,6 +13,7 @@
light_power = 0.8
light_range = 6
light_on = FALSE
+ var/repair_multiplier = 1 //multiply incoming repairs by this value. used to make some mechs less efficient and slower to repair.
var/ruin_mecha = FALSE //if the mecha starts on a ruin, don't automatically give it a tracking beacon to prevent metagaming.
var/can_move = 0 //time of next allowed movement
var/stopped = FALSE
diff --git a/code/game/mecha/mecha_defense.dm b/code/game/mecha/mecha_defense.dm
index b6c72134456d..dd65c6c499ca 100644
--- a/code/game/mecha/mecha_defense.dm
+++ b/code/game/mecha/mecha_defense.dm
@@ -298,17 +298,19 @@
if(!W.use_tool(src, user, 0, volume=50, amount=1))
return
clearInternalDamage(MECHA_INT_TANK_BREACH)
- to_chat(user, "You repair the damaged gas tank.")
+ to_chat(user, span_notice("You repair the damaged gas tank."))
return
if(obj_integrity < max_integrity)
+ if(!do_after(user, 20, target= src))
+ return
if(!W.use_tool(src, user, 0, volume=50, amount=1))
return
- user.visible_message("[user] repairs some damage to [name].", "You repair some damage to [src].")
- obj_integrity += min(10, max_integrity-obj_integrity)
+ user.visible_message(span_notice("[user] repairs some damage to [name]."), span_notice("You repair some damage to [src]."))
+ obj_integrity += min(10 * repair_multiplier, max_integrity-obj_integrity)
if(obj_integrity == max_integrity)
- to_chat(user, "It looks to be fully repaired now.")
+ to_chat(user, span_notice("It looks to be fully repaired now."))
return
- to_chat(user, "The [name] is at full integrity!")
+ to_chat(user, span_warning("The [name] is at full integrity!"))
/obj/mecha/proc/mech_toxin_damage(mob/living/target)
playsound(src, 'sound/effects/spray2.ogg', 50, TRUE)