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)