From d738cbb296a43285e6e0e66267f6228bf5228e88 Mon Sep 17 00:00:00 2001 From: EnterTheJake <102721711+EnterTheJake@users.noreply.github.com> Date: Sat, 19 Jul 2025 06:14:58 +0200 Subject: [PATCH] Several balance changes to Combat MODsuits (#91944) ## About The Pull Request atomization of https://github.com/tgstation/tgstation/pull/91702 with a few changes. - armor booster module has been removed, nukie suits are now always fully armored and EVA proof. - Jetpack modules have had their power drain reduced considerably. - Cap,Hos and Sec MODs armor values have been bumped up (similar to the old hardsuit values). - Sec armor plates are now a cargo import. The nf suit now comes with the Shock absorber pre-installed. - Fixes Nukie suits not having T4 flash protection. - All combat modsuits now have ear protection by default when the suit active (Cap,Sec,Hos,Syndie,ERT, Death Squad, Ninja and RD.) - Night visor module now comes preinstalled in the syndie mods and doesn't conflict with other vision modules, nor it costs complexity, power drain reduced, the module itself has been removed from the uplink. - Increases the complexity on the nukie suits by 2 points. - all traitor modules now cost 1 less TC. ## Why It's Good For The Game **armor booster removal** I really dislike how this module works, it's a constant hassle having to manually swap mode depending on the pressure, it's just an annoyng memory check that punishes you with chip damage when not respected. The choice of wheter wearing a mod or not doesn't really apply to nuclear operatives since they wear these things all the time and losing half of your armor in space never really made a ton of sense to begin with. **Jetpack power drain buff** The drain on this thing is absolute fucking nuts, it eats high capacity cells in a matter of minutes, power should be a limiting factor to using these things but it shouldn't tank your battery health this quickly. **Cap,Sec,Hos MODs buffs** Back when Fikou introduced MODsuits, one point he clarified in the design doc is that "Combat stuff usually leads to uninteresting design, it makes the suits do everything for everyone" I don't want to diss on the dude (Love you bud), but I don't think his point makes a ton of sense. Combat stuff, on this case Combat mods should be built with Combat in mind. In all fairness he then has a paragraph addressing why the crew based combat suits should have low armor, but it still rings hollow to me. Armored or not, being slower than your average spessman is enough to make you an easy target or to never be able to chase anyone on foot, even with their armor increased I don't see players having them constantly on all the time, the slowdown is a hard enough disincentive. The Magnate and HoS mods specifically are unique pieces of gear, and they are usually assigned to 2 of the most important (and prone to assassination) roles on the station. There's also a weird paradox with some of the modules they come equipped with the sec MODs, the pepper spray and the projectile dampener are built around getting hit, which is a hard sell when your armor is so low you might as well just die straight up. Out of respect to Fikou's will of not wanting to grant the crew the ability to mass produce combat MODs, I removed the sec modplates from the techweb and moved em as a cargo import. **Uplink MODules Price reduction** These were originally priced with progression in mind, traitor specifically has become considerably weaker since they lost access to avenues to generate extra TCs. It's hard to justify getting a suit when most weapons in the uplink cost more than half of your budget, let alone the modules. **Shock absorption into the inf suit** This module is pretty much already mandatory if you don't want to lose fights in one hit, wearing a syndie modsuit makes you giga valid to everyone on station and any traitor worth their salt will buy this module regardless anyway; it just punishes new players who don't know better. **Night Visor MOD changes** This module is completely useless, nobody ever uses it, because it conflicts with other vision modules, and it's completely redundant since Thermal vision already comes packed with NV on their own. **Complexity increase on the Nukie suits + T4 flashing protection added** The nukie suits have honestly quite limited complexity for the role they are supposed to fill , the T4 flash protection missing from the suit is unintended as we made any other MODsuit have T4 protection already, Moth Nukies rejoice. **Ear Protection on combat MODs (oh boy)** Listen, as of right now we have a total of 2 counters for flashbangs, a Bowman or being deaf. A sealed, airtight suit shouldn't offer less protection against loud noises than a mere headset. baddies that usually pack these suits usually have a Bowman anyway, Nukies have it, ninja can easily teleport into a sec outpost and get it, it's a bit more tricky for traitor since they usually have to invest in an emag to quickly take the set or kill a security officer. At least now if you see a baddie roll up in a suit you no longer have to play hypotheticals wheter your flashbang will work properly or not. I also gave the ear protection to the RD mod despite it not being a combat MOD, because frankly it made sense, it's a bomb proof armor, It should also protect you from loud noises. ## Changelog :cl: removal: Armor booster module has been removed. balance: Jetpack module energy drain has been massively reduced. balance: armor on the Magnate,Safegaurd and sec modsuits has been considerably increased. balance: Sec MOD plates have been transferred from RnD to Cargo. balance The Infiltrator MOD now comes with the shock absorption module pre-installed. balance: Nukie MODsuits hav a bit more complexity. fix: Nukie MODs now have the same flash protection as the other suits with welding protection. balance: night visor module comes pre-installed in the syndie mods, no longer consumes complexity,drains less power and doesn't conflict with the other visor MODules. removal: Nightvision MODule removed from the uplink. balance: Combat MODs and RDs now grant earing protection when the suit is active. /:cl: --------- Co-authored-by: Xander3359 <66163761+Xander3359@users.noreply.github.com> --- code/modules/antagonists/clown_ops/clownop.dm | 8 -- code/modules/antagonists/nukeop/outfits.dm | 6 - code/modules/cargo/packs/security.dm | 8 ++ code/modules/mod/mod_theme.dm | 85 ++++++------ code/modules/mod/mod_types.dm | 8 +- code/modules/mod/modules/modules_antag.dm | 121 +----------------- .../mod/modules/modules_engineering.dm | 16 ++- code/modules/mod/modules/modules_general.dm | 24 +++- code/modules/mod/modules/modules_visor.dm | 23 ++++ .../designs/mechfabricator_designs.dm | 13 -- .../research/techweb/nodes/modsuit_nodes.dm | 1 - .../cardboard_cutouts_nukie_cutout.png | Bin 588 -> 584 bytes ...dynamic_human_icons_syndicate_commando.png | Bin 1039 -> 1040 bytes code/modules/uplink/uplink_items/suits.dm | 20 ++- 14 files changed, 127 insertions(+), 206 deletions(-) diff --git a/code/modules/antagonists/clown_ops/clownop.dm b/code/modules/antagonists/clown_ops/clownop.dm index 1b64eeab7ba..da4d6d41ec0 100644 --- a/code/modules/antagonists/clown_ops/clownop.dm +++ b/code/modules/antagonists/clown_ops/clownop.dm @@ -75,16 +75,8 @@ back = /obj/item/mod/control/pre_equipped/empty/syndicate/honkerative uniform = /obj/item/clothing/under/syndicate -/datum/outfit/clown_operative/post_equip(mob/living/carbon/human/H, visuals_only) - var/obj/item/mod/module/armor_booster/booster = locate() in H.back - booster.activate() - /datum/outfit/clown_operative_elite name = "Clown Operative (Elite, Preview only)" back = /obj/item/mod/control/pre_equipped/empty/syndicate/honkerative uniform = /obj/item/clothing/under/syndicate - -/datum/outfit/clown_operative_elite/post_equip(mob/living/carbon/human/H, visuals_only) - var/obj/item/mod/module/armor_booster/booster = locate() in H.back - booster.activate() diff --git a/code/modules/antagonists/nukeop/outfits.dm b/code/modules/antagonists/nukeop/outfits.dm index 7546893b82f..5be8f13f2fc 100644 --- a/code/modules/antagonists/nukeop/outfits.dm +++ b/code/modules/antagonists/nukeop/outfits.dm @@ -186,10 +186,6 @@ back = /obj/item/mod/control/pre_equipped/empty/syndicate uniform = /obj/item/clothing/under/syndicate -/datum/outfit/nuclear_operative/post_equip(mob/living/carbon/human/H, visuals_only) - var/obj/item/mod/module/armor_booster/booster = locate() in H.back - booster.activate() - /datum/outfit/nuclear_operative_elite name = "Nuclear Operative (Elite, Preview only)" @@ -199,8 +195,6 @@ r_hand = /obj/item/shield/energy /datum/outfit/nuclear_operative_elite/post_equip(mob/living/carbon/human/H, visuals_only) - var/obj/item/mod/module/armor_booster/booster = locate() in H.back - booster.activate() var/obj/item/shield/energy/shield = locate() in H.held_items shield.icon_state = "[shield.base_icon_state]1" H.update_held_items() diff --git a/code/modules/cargo/packs/security.dm b/code/modules/cargo/packs/security.dm index 5374bb1f384..b97c7cd68bf 100644 --- a/code/modules/cargo/packs/security.dm +++ b/code/modules/cargo/packs/security.dm @@ -25,6 +25,14 @@ contains = list(/obj/item/clothing/suit/armor/vest = 3) crate_name = "armor crate" +/datum/supply_pack/security/modsuit_plating + name = "Security MOD plating" + desc = "A single security MOD suit plating" + cost = CARGO_CRATE_VALUE + access_view = ACCESS_SECURITY + contains = list(/obj/item/mod/construction/plating/security) + crate_name = "MOD plating crate" + /datum/supply_pack/security/disabler name = "Disabler Crate" desc = "Three stamina-draining disabler weapons." diff --git a/code/modules/mod/mod_theme.dm b/code/modules/mod/mod_theme.dm index d1890885425..8bd6f1bb7fc 100644 --- a/code/modules/mod/mod_theme.dm +++ b/code/modules/mod/mod_theme.dm @@ -819,7 +819,7 @@ max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT complexity_max = DEFAULT_MAX_COMPLEXITY + 5 slowdown_deployed = 1.25 - inbuilt_modules = list(/obj/item/mod/module/reagent_scanner/advanced) + inbuilt_modules = list(/obj/item/mod/module/reagent_scanner/advanced, /obj/item/mod/module/hearing_protection) allowed_suit_storage = list( /obj/item/analyzer, /obj/item/dnainjector, @@ -886,6 +886,7 @@ armor_type = /datum/armor/mod_theme_security complexity_max = DEFAULT_MAX_COMPLEXITY - 2 slowdown_deployed = 0.5 + inbuilt_modules = list(/obj/item/mod/module/hearing_protection) allowed_suit_storage = list( /obj/item/reagent_containers/spray/pepper, /obj/item/restraints/handcuffs, @@ -929,15 +930,15 @@ ) /datum/armor/mod_theme_security - melee = 15 + melee = 35 bullet = 15 - laser = 15 - energy = 15 + laser = 30 + energy = 40 bomb = 25 bio = 100 - fire = 75 + fire = 100 acid = 75 - wound = 15 + wound = 20 /datum/mod_theme/safeguard name = "safeguard" @@ -952,7 +953,7 @@ armor_type = /datum/armor/mod_theme_safeguard resistance_flags = FIRE_PROOF max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT - inbuilt_modules = list(/obj/item/mod/module/shove_blocker/locked) + inbuilt_modules = list(/obj/item/mod/module/shove_blocker/locked, /obj/item/mod/module/hearing_protection) slowdown_deployed = 0.25 allowed_suit_storage = list( /obj/item/reagent_containers/spray/pepper, @@ -995,15 +996,15 @@ ) /datum/armor/mod_theme_safeguard - melee = 15 - bullet = 15 - laser = 15 - energy = 15 + melee = 45 + bullet = 25 + laser = 30 + energy = 40 bomb = 40 bio = 100 fire = 100 - acid = 95 - wound = 15 + acid = 100 + wound = 25 /datum/mod_theme/magnate name = "magnate" @@ -1025,6 +1026,7 @@ siemens_coefficient = 0 complexity_max = DEFAULT_MAX_COMPLEXITY + 5 slowdown_deployed = 0.25 + inbuilt_modules = list(/obj/item/mod/module/hearing_protection) allowed_suit_storage = list( /obj/item/restraints/handcuffs, /obj/item/assembly/flash, @@ -1067,10 +1069,10 @@ ) /datum/armor/mod_theme_magnate - melee = 20 - bullet = 15 - laser = 15 - energy = 15 + melee = 40 + bullet = 50 + laser = 50 + energy = 60 bomb = 50 bio = 100 fire = 100 @@ -1157,13 +1159,13 @@ default_skin = "syndicate" armor_type = /datum/armor/mod_theme_syndicate atom_flags = PREVENT_CONTENTS_EXPLOSION_1 - complexity_max = DEFAULT_MAX_COMPLEXITY + 3 + complexity_max = DEFAULT_MAX_COMPLEXITY + 5 max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT siemens_coefficient = 0 slowdown_deployed = 0 ui_theme = "syndicate" resistance_flags = FIRE_PROOF - inbuilt_modules = list(/obj/item/mod/module/armor_booster) + inbuilt_modules = list(/obj/item/mod/module/welding/syndicate, /obj/item/mod/module/night, /obj/item/mod/module/hearing_protection) allowed_suit_storage = list( /obj/item/restraints/handcuffs, /obj/item/assembly/flash, @@ -1241,10 +1243,10 @@ ) /datum/armor/mod_theme_syndicate - melee = 15 - bullet = 20 - laser = 15 - energy = 15 + melee = 40 + bullet = 50 + laser = 30 + energy = 30 bomb = 35 bio = 100 fire = 50 @@ -1265,11 +1267,11 @@ resistance_flags = FIRE_PROOF|ACID_PROOF atom_flags = PREVENT_CONTENTS_EXPLOSION_1 max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT - complexity_max = DEFAULT_MAX_COMPLEXITY + 3 + complexity_max = DEFAULT_MAX_COMPLEXITY + 4 siemens_coefficient = 0 slowdown_deployed = 0 ui_theme = "syndicate" - inbuilt_modules = list(/obj/item/mod/module/armor_booster) + inbuilt_modules = list(/obj/item/mod/module/welding/syndicate, /obj/item/mod/module/night, /obj/item/mod/module/hearing_protection) allowed_suit_storage = list( /obj/item/restraints/handcuffs, /obj/item/assembly/flash, @@ -1313,10 +1315,10 @@ ) /datum/armor/mod_theme_elite - melee = 35 - bullet = 30 - laser = 35 - energy = 35 + melee = 60 + bullet = 60 + laser = 50 + energy = 50 bomb = 55 bio = 100 fire = 100 @@ -1343,7 +1345,7 @@ activation_step_time = MOD_ACTIVATION_STEP_TIME * 0.5 ui_theme = "syndicate" slot_flags = ITEM_SLOT_BELT - inbuilt_modules = list(/obj/item/mod/module/infiltrator, /obj/item/mod/module/storage/belt, /obj/item/mod/module/demoralizer) + inbuilt_modules = list(/obj/item/mod/module/infiltrator, /obj/item/mod/module/storage/belt, /obj/item/mod/module/demoralizer, /obj/item/mod/module/hearing_protection, /obj/item/mod/module/night) allowed_suit_storage = list( /obj/item/restraints/handcuffs, /obj/item/assembly/flash, @@ -1412,7 +1414,7 @@ max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT charge_drain = DEFAULT_CHARGE_DRAIN * 2 slowdown_deployed = -0.5 - inbuilt_modules = list(/obj/item/mod/module/quick_carry/advanced) + inbuilt_modules = list(/obj/item/mod/module/quick_carry/advanced, /obj/item/mod/module/hearing_protection) allowed_suit_storage = list( /obj/item/assembly/flash, /obj/item/healthanalyzer, @@ -1499,7 +1501,7 @@ complexity_max = DEFAULT_MAX_COMPLEXITY slowdown_deployed = 0 ui_theme = "wizard" - inbuilt_modules = list(/obj/item/mod/module/anti_magic/wizard) + inbuilt_modules = list(/obj/item/mod/module/anti_magic/wizard, /obj/item/mod/module/hearing_protection) allowed_suit_storage = list( /obj/item/teleportation_scroll, /obj/item/highfrequencyblade/wizard, @@ -1566,7 +1568,7 @@ siemens_coefficient = 0 slowdown_deployed = 0 ui_theme = "hackerman" - inbuilt_modules = list(/obj/item/mod/module/welding/camera_vision, /obj/item/mod/module/hacker, /obj/item/mod/module/weapon_recall, /obj/item/mod/module/adrenaline_boost, /obj/item/mod/module/energy_net) + inbuilt_modules = list(/obj/item/mod/module/welding/camera_vision, /obj/item/mod/module/hacker, /obj/item/mod/module/weapon_recall, /obj/item/mod/module/adrenaline_boost, /obj/item/mod/module/energy_net, /obj/item/mod/module/hearing_protection) allowed_suit_storage = list( /obj/item/gun, /obj/item/melee/baton, @@ -1702,7 +1704,7 @@ siemens_coefficient = 0 slowdown_deployed = 0 ui_theme = "ntos_terminal" - inbuilt_modules = list(/obj/item/mod/module/armor_booster) + inbuilt_modules = list(/obj/item/mod/module/welding/syndicate, /obj/item/mod/module/hearing_protection) allowed_suit_storage = list( /obj/item/ammo_box, /obj/item/ammo_casing, @@ -1745,9 +1747,10 @@ ) /datum/armor/mod_theme_glitch - melee = 15 - bullet = 20 - laser = 35 + melee = 40 + bullet = 50 + laser = 50 + energy = 15 bomb = 65 bio = 100 fire = 100 @@ -1769,6 +1772,7 @@ max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT siemens_coefficient = 0 slowdown_deployed = 0 + inbuilt_modules = list(/obj/item/mod/module/hearing_protection) allowed_suit_storage = list( /obj/item/restraints/handcuffs, /obj/item/assembly/flash, @@ -1863,7 +1867,7 @@ armor_type = /datum/armor/mod_theme_elite resistance_flags = FIRE_PROOF|ACID_PROOF complexity_max = DEFAULT_MAX_COMPLEXITY + 5 - inbuilt_modules = list(/obj/item/mod/module/armor_booster/no_speedbost) + inbuilt_modules = list(/obj/item/mod/module/welding/syndicate) /datum/mod_theme/apocryphal name = "apocryphal" @@ -1881,6 +1885,7 @@ max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT siemens_coefficient = 0 complexity_max = DEFAULT_MAX_COMPLEXITY + 10 + inbuilt_modules = list(/obj/item/mod/module/hearing_protection) allowed_suit_storage = list( /obj/item/restraints/handcuffs, /obj/item/assembly/flash, @@ -1951,6 +1956,7 @@ max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT siemens_coefficient = 0 slowdown_deployed = 0 + inbuilt_modules = list(/obj/item/mod/module/hearing_protection) allowed_suit_storage = list( /obj/item/restraints/handcuffs, /obj/item/assembly/flash, @@ -2015,6 +2021,7 @@ max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT complexity_max = DEFAULT_MAX_COMPLEXITY - 10 slowdown_deployed = 0 + inbuilt_modules = list(/obj/item/mod/module/hearing_protection) allowed_suit_storage = list( /obj/item/restraints/handcuffs, ) @@ -2080,6 +2087,7 @@ siemens_coefficient = 0 slowdown_deployed = 0 activation_step_time = MOD_ACTIVATION_STEP_TIME * 0.2 + inbuilt_modules = list(/obj/item/mod/module/hearing_protection) allowed_suit_storage = list( /obj/item/gun, ) @@ -2146,6 +2154,7 @@ siemens_coefficient = 0 slowdown_deployed = 0 activation_step_time = MOD_ACTIVATION_STEP_TIME * 0.01 + inbuilt_modules = list(/obj/item/mod/module/hearing_protection) allowed_suit_storage = list( /obj/item/gun, ) diff --git a/code/modules/mod/mod_types.dm b/code/modules/mod/mod_types.dm index 49d54d2372b..03cd746045c 100644 --- a/code/modules/mod/mod_types.dm +++ b/code/modules/mod/mod_types.dm @@ -247,7 +247,6 @@ /obj/item/mod/module/quick_cuff, ) default_pins = list( - /obj/item/mod/module/armor_booster, /obj/item/mod/module/jetpack, ) @@ -268,7 +267,6 @@ /obj/item/mod/module/quick_cuff, ) default_pins = list( - /obj/item/mod/module/armor_booster, /obj/item/mod/module/jetpack/advanced, /obj/item/mod/module/jump_jet, ) @@ -290,7 +288,6 @@ /obj/item/mod/module/quick_cuff, ) default_pins = list( - /obj/item/mod/module/armor_booster, /obj/item/mod/module/jetpack/advanced, /obj/item/mod/module/jump_jet, ) @@ -327,7 +324,6 @@ /obj/item/mod/module/quick_cuff, ) default_pins = list( - /obj/item/mod/module/armor_booster, /obj/item/mod/module/jetpack/advanced, /obj/item/mod/module/jump_jet, ) @@ -347,7 +343,6 @@ /obj/item/mod/module/quick_cuff, ) default_pins = list( - /obj/item/mod/module/armor_booster, /obj/item/mod/module/jetpack/advanced, /obj/item/mod/module/jump_jet, /obj/item/mod/module/flamethrower, @@ -358,6 +353,7 @@ starting_frequency = MODLINK_FREQ_SYNDICATE applied_cell = /obj/item/stock_parts/power_store/cell/super applied_modules = list( + /obj/item/mod/module/shock_absorber, /obj/item/mod/module/emp_shield, /obj/item/mod/module/magnetic_harness, /obj/item/mod/module/quick_carry, @@ -453,7 +449,6 @@ /obj/item/mod/module/flashlight, ) default_pins = list( - /obj/item/mod/module/armor_booster, /obj/item/mod/module/jetpack/advanced, /obj/item/mod/module/jump_jet, ) @@ -538,7 +533,6 @@ /obj/item/mod/module/flashlight/darkness, /obj/item/mod/module/dna_lock, /obj/item/mod/module/quick_cuff, - /obj/item/mod/module/visor/night, /obj/item/mod/module/shove_blocker, /obj/item/mod/module/noslip, ) diff --git a/code/modules/mod/modules/modules_antag.dm b/code/modules/mod/modules/modules_antag.dm index 27393e06961..2c8e2e7e008 100644 --- a/code/modules/mod/modules/modules_antag.dm +++ b/code/modules/mod/modules/modules_antag.dm @@ -1,122 +1,5 @@ //Antag modules for MODsuits -///Armor Booster - Grants your suit more armor and speed in exchange for EVA protection. Also acts as a welding screen. -/obj/item/mod/module/armor_booster - name = "MOD armor booster module" - desc = "A retrofitted series of retractable armor plates, allowing the suit to function as essentially power armor, \ - giving the user incredible protection against conventional firearms, or everyday attacks in close-quarters. \ - However, the additional plating cannot deploy alongside parts of the suit used for vacuum sealing, \ - so this extra armor provides zero ability for extravehicular activity while deployed." - icon_state = "armor_booster" - module_type = MODULE_TOGGLE - active_power_cost = DEFAULT_CHARGE_DRAIN * 0.3 - removable = FALSE - incompatible_modules = list(/obj/item/mod/module/armor_booster, /obj/item/mod/module/welding, /obj/item/mod/module/headprotector) - overlay_state_inactive = "module_armorbooster_off" - overlay_state_active = "module_armorbooster_on" - use_mod_colors = TRUE - mask_worn_overlay = TRUE - /// Whether or not this module removes pressure protection. - var/remove_pressure_protection = TRUE - /// Slowdown added to the control unit while this module is disabled - var/space_slowdown = 0.5 - /// Armor values added to the suit parts. - var/datum/armor/armor_mod = /datum/armor/mod_module_armor_boost - /// List of parts of the suit that are spaceproofed, for giving them back the pressure protection. - var/list/spaceproofed = list() - -/obj/item/mod/module/armor_booster/no_speedbost - space_slowdown = 0 - -/datum/armor/mod_module_armor_boost - melee = 25 - bullet = 30 - laser = 15 - energy = 15 - -/obj/item/mod/module/armor_booster/on_part_activation() - RegisterSignal(mod, COMSIG_MOD_UPDATE_SPEED, PROC_REF(on_update_speed)) - var/obj/item/clothing/head_cover = mod.get_part_from_slot(ITEM_SLOT_HEAD) || mod.get_part_from_slot(ITEM_SLOT_MASK) || mod.get_part_from_slot(ITEM_SLOT_EYES) - if(istype(head_cover)) - head_cover.flash_protect = FLASH_PROTECTION_WELDER - mod.update_speed() - -/obj/item/mod/module/armor_booster/on_part_deactivation(deleting = FALSE) - if(deleting) - return - UnregisterSignal(mod, COMSIG_MOD_UPDATE_SPEED) - var/obj/item/clothing/head_cover = mod.get_part_from_slot(ITEM_SLOT_HEAD) || mod.get_part_from_slot(ITEM_SLOT_MASK) || mod.get_part_from_slot(ITEM_SLOT_EYES) - if(istype(head_cover)) - head_cover.flash_protect = initial(head_cover.flash_protect) - mod.update_speed() - -/obj/item/mod/module/armor_booster/on_activation() - playsound(src, 'sound/vehicles/mecha/mechmove03.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - balloon_alert(mod.wearer, "armor boosted, EVA lost") - var/datum/mod_part/head_cover = mod.get_part_datum_from_slot(ITEM_SLOT_HEAD) || mod.get_part_datum_from_slot(ITEM_SLOT_MASK) || mod.get_part_datum_from_slot(ITEM_SLOT_EYES) - if(head_cover) - RegisterSignal(mod, COMSIG_MOD_PART_SEALED, PROC_REF(seal_helmet)) - seal_helmet(mod, head_cover) - for(var/obj/item/part as anything in mod.get_parts(all = TRUE)) - part.set_armor(part.get_armor().add_other_armor(armor_mod)) - if(!remove_pressure_protection || !isclothing(part)) - continue - var/obj/item/clothing/clothing_part = part - if(clothing_part.clothing_flags & STOPSPRESSUREDAMAGE) - clothing_part.clothing_flags &= ~STOPSPRESSUREDAMAGE - spaceproofed[clothing_part] = TRUE - mod.update_speed() - -/obj/item/mod/module/armor_booster/on_deactivation(display_message = TRUE, deleting = FALSE) - if(!deleting) - playsound(src, 'sound/vehicles/mecha/mechmove03.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - balloon_alert(mod.wearer, "armor retracts, EVA ready") - var/datum/mod_part/head_cover = mod.get_part_datum_from_slot(ITEM_SLOT_HEAD) || mod.get_part_datum_from_slot(ITEM_SLOT_MASK) || mod.get_part_datum_from_slot(ITEM_SLOT_EYES) - if(head_cover) - UnregisterSignal(mod, COMSIG_MOD_PART_SEALED) - REMOVE_TRAIT(mod.wearer, TRAIT_HEAD_INJURY_BLOCKED, REF(src)) - for(var/obj/item/part as anything in mod.get_parts(all = TRUE)) - part.set_armor(part.get_armor().subtract_other_armor(armor_mod)) - if(!remove_pressure_protection || !isclothing(part)) - continue - var/obj/item/clothing/clothing_part = part - if(spaceproofed[clothing_part]) - clothing_part.clothing_flags |= STOPSPRESSUREDAMAGE - mod.update_speed() - spaceproofed = list() - -/obj/item/mod/module/armor_booster/proc/on_update_speed(datum/source, list/module_slowdowns, prevent_slowdown) - SIGNAL_HANDLER - if (!active) - module_slowdowns += space_slowdown - -/obj/item/mod/module/armor_booster/generate_worn_overlay(obj/item/source, mutable_appearance/standing) - overlay_state_inactive = "[initial(overlay_state_inactive)]-[mod.skin]" - overlay_state_active = "[initial(overlay_state_active)]-[mod.skin]" - return ..() - -/obj/item/mod/module/armor_booster/proc/seal_helmet(datum/source, datum/mod_part/part) - var/datum/mod_part/head_cover = mod.get_part_datum_from_slot(ITEM_SLOT_HEAD) || mod.get_part_datum_from_slot(ITEM_SLOT_MASK) || mod.get_part_datum_from_slot(ITEM_SLOT_EYES) - if(part != head_cover) - return - if(part.sealed) - ADD_TRAIT(mod.wearer, TRAIT_HEAD_INJURY_BLOCKED, REF(src)) - else - REMOVE_TRAIT(mod.wearer, TRAIT_HEAD_INJURY_BLOCKED, REF(src)) - -/obj/item/mod/module/armor_booster/on_install() - . = ..() - RegisterSignal(mod, COMSIG_MOD_GET_VISOR_OVERLAY, PROC_REF(on_visor_overlay)) - -/obj/item/mod/module/armor_booster/on_uninstall(deleting = FALSE) - . = ..() - UnregisterSignal(mod, COMSIG_MOD_GET_VISOR_OVERLAY) - -/obj/item/mod/module/armor_booster/proc/on_visor_overlay(datum/source, mutable_appearance/standing, list/overrides) - SIGNAL_HANDLER - if (active) - overrides += mutable_appearance(overlay_icon_file, "module_armorbooster_visor-[mod.skin]", layer = standing.layer + 0.1) - ///Energy Shield - Gives you a rechargeable energy shield that nullifies attacks. /obj/item/mod/module/energy_shield name = "MOD energy shield module" @@ -531,7 +414,7 @@ complexity = 0 removable = FALSE idle_power_cost = DEFAULT_CHARGE_DRAIN * 0 - incompatible_modules = list(/obj/item/mod/module/infiltrator, /obj/item/mod/module/armor_booster, /obj/item/mod/module/welding, /obj/item/mod/module/headprotector) + incompatible_modules = list(/obj/item/mod/module/infiltrator, /obj/item/mod/module/welding/syndicate, /obj/item/mod/module/welding, /obj/item/mod/module/headprotector) required_slots = list(ITEM_SLOT_FEET, ITEM_SLOT_HEAD, ITEM_SLOT_OCLOTHING) /// List of traits added when the suit is activated var/list/traits_to_add = list(TRAIT_SILENT_FOOTSTEPS, TRAIT_UNKNOWN, TRAIT_HEAD_INJURY_BLOCKED) @@ -595,7 +478,7 @@ stealth_alpha = 30 module_type = MODULE_ACTIVE cooldown_time = 2 SECONDS - incompatible_modules = list(/obj/item/mod/module/stealth, /obj/item/mod/module/armor_booster) + incompatible_modules = list(/obj/item/mod/module/stealth, /obj/item/mod/module/welding/syndicate) /// How much time before we are able to cloak again after the cloak is broken (not disabled) COOLDOWN_DECLARE(recloak_timer) /// If the stealth portion of the module is active diff --git a/code/modules/mod/modules/modules_engineering.dm b/code/modules/mod/modules/modules_engineering.dm index 018d6d35275..fa28e7aaee6 100644 --- a/code/modules/mod/modules/modules_engineering.dm +++ b/code/modules/mod/modules/modules_engineering.dm @@ -8,7 +8,7 @@ immunity against extremities such as spot and arc welding, solar eclipses, and handheld flashlights." icon_state = "welding" complexity = 1 - incompatible_modules = list(/obj/item/mod/module/welding, /obj/item/mod/module/armor_booster) + incompatible_modules = list(/obj/item/mod/module/welding) overlay_state_inactive = "module_welding" required_slots = list(ITEM_SLOT_HEAD|ITEM_SLOT_EYES|ITEM_SLOT_MASK) @@ -25,6 +25,18 @@ if(istype(head_cover)) head_cover.flash_protect = initial(head_cover.flash_protect) +/obj/item/mod/module/welding/syndicate + complexity = 0 + removable = FALSE + incompatible_modules = list(/obj/item/mod/module/welding, /obj/item/mod/module/welding/syndicate, /obj/item/mod/module/stealth/wraith) + overlay_state_inactive = "module_armorbooster_on" + use_mod_colors = TRUE + mask_worn_overlay = TRUE + +/obj/item/mod/module/welding/syndicate/generate_worn_overlay(obj/item/source, mutable_appearance/standing) + overlay_state_inactive = "[initial(overlay_state_inactive)]-[mod.skin]" + return ..() + ///T-Ray Scan - Scans the terrain for undertile objects. /obj/item/mod/module/t_ray name = "MOD t-ray scan module" @@ -396,7 +408,7 @@ relatively easy to install into most other suits." icon_state = "welding" complexity = 1 - incompatible_modules = list(/obj/item/mod/module/armor_booster, /obj/item/mod/module/infiltrator) + incompatible_modules = list(/obj/item/mod/module/welding/syndicate, /obj/item/mod/module/infiltrator) required_slots = list(ITEM_SLOT_HEAD) /obj/item/mod/module/headprotector/on_part_activation() diff --git a/code/modules/mod/modules/modules_general.dm b/code/modules/mod/modules/modules_general.dm index 85f9d23e432..7ff12b07398 100644 --- a/code/modules/mod/modules/modules_general.dm +++ b/code/modules/mod/modules/modules_general.dm @@ -103,7 +103,7 @@ icon_state = "jetpack" module_type = MODULE_TOGGLE complexity = 3 - active_power_cost = DEFAULT_CHARGE_DRAIN * 0.5 + active_power_cost = DEFAULT_CHARGE_DRAIN * 0.05 use_energy_cost = DEFAULT_CHARGE_DRAIN incompatible_modules = list(/obj/item/mod/module/jetpack) overlay_state_inactive = "module_jetpack" @@ -1045,3 +1045,25 @@ var/datum/effect_system/lightning_spread/sparks = new /datum/effect_system/lightning_spread sparks.set_up(number = 5, cardinals_only = TRUE, location = mod.wearer.loc) sparks.start() + +/obj/item/mod/module/hearing_protection + name = "MOD hearing protection module" + desc = "A module that protects the users ears from loud sounds" + complexity = 0 + removable = FALSE + incompatible_modules = list(/obj/item/mod/module/hearing_protection) + required_slots = list(ITEM_SLOT_HEAD) + +/obj/item/mod/module/hearing_protection/on_part_activation() + var/obj/item/clothing/head_cover = mod.get_part_from_slot(ITEM_SLOT_HEAD) || mod.get_part_from_slot(ITEM_SLOT_MASK) || mod.get_part_from_slot(ITEM_SLOT_EYES) + if(istype(head_cover)) + head_cover.AddComponent(/datum/component/wearertargeting/earprotection, list(ITEM_SLOT_HEAD)) + var/datum/component/wearertargeting/earprotection/protection = head_cover.GetComponent(/datum/component/wearertargeting/earprotection) + protection.on_equip(src, mod.wearer, ITEM_SLOT_HEAD) + +/obj/item/mod/module/hearing_protection/on_part_deactivation(deleting = FALSE) + if(deleting) + return + var/obj/item/clothing/head_cover = mod.get_part_from_slot(ITEM_SLOT_HEAD) || mod.get_part_from_slot(ITEM_SLOT_MASK) || mod.get_part_from_slot(ITEM_SLOT_EYES) + if(istype(head_cover)) + qdel(head_cover.GetComponent(/datum/component/wearertargeting/earprotection)) diff --git a/code/modules/mod/modules/modules_visor.dm b/code/modules/mod/modules/modules_visor.dm index 64ddc69d2ed..57209462732 100644 --- a/code/modules/mod/modules/modules_visor.dm +++ b/code/modules/mod/modules/modules_visor.dm @@ -74,4 +74,27 @@ this allows the user to perceive their surroundings while in complete darkness, enhancing the view by tenfold; \ yet brightening everything into a spooky green glow. They say these also let you see behind you." icon_state = "night_visor" + incompatible_modules = list(/obj/item/mod/module/visor, /obj/item/mod/module/night) visor_traits = list(TRAIT_TRUE_NIGHT_VISION) + +/obj/item/mod/module/night // Not Visor type so that it remains compatible with other visors + name = "MOD night vision module" + desc = "A heads-up display installed into the visor of the suit. Typical for both civilian and military applications, \ + this allows the user to perceive their surroundings while in complete darkness, enhancing the view by tenfold; \ + yet brightening everything into a spooky green glow. They say these also let you see behind you. \ + These ones are a special version which remain compatible with the other visor modules." + icon_state = "night_visor" + active_power_cost = DEFAULT_CHARGE_DRAIN * 0.1 + complexity = 0 + removable = FALSE + module_type = MODULE_TOGGLE + incompatible_modules = list(/obj/item/mod/module/night, /obj/item/mod/module/visor/night) + required_slots = list(ITEM_SLOT_HEAD|ITEM_SLOT_EYES|ITEM_SLOT_MASK) + +/obj/item/mod/module/night/on_activation() + mod.wearer.add_traits(TRAIT_TRUE_NIGHT_VISION, REF(src)) + mod.wearer.update_sight() + +/obj/item/mod/module/night/on_deactivation(display_message = TRUE, deleting = FALSE) + mod.wearer.remove_traits(TRAIT_TRUE_NIGHT_VISION, REF(src)) + mod.wearer.update_sight() diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm index e2564ec2da4..fb45c44d7fc 100644 --- a/code/modules/research/designs/mechfabricator_designs.dm +++ b/code/modules/research/designs/mechfabricator_designs.dm @@ -2097,19 +2097,6 @@ departmental_flags = DEPARTMENT_BITFLAG_MEDICAL research_icon_state = "medical-plating" -/datum/design/mod_plating/security - name = "MOD Security Plating" - id = "mod_plating_security" - build_path = /obj/item/mod/construction/plating/security - materials = list( - /datum/material/iron =SHEET_MATERIAL_AMOUNT*3, - /datum/material/uranium =SHEET_MATERIAL_AMOUNT, - /datum/material/glass =HALF_SHEET_MATERIAL_AMOUNT, - /datum/material/plasma =HALF_SHEET_MATERIAL_AMOUNT, - ) - departmental_flags = DEPARTMENT_BITFLAG_SECURITY - research_icon_state = "security-plating" - /datum/design/mod_plating/cosmohonk name = "MOD Cosmohonk Plating" id = "mod_plating_cosmohonk" diff --git a/code/modules/research/techweb/nodes/modsuit_nodes.dm b/code/modules/research/techweb/nodes/modsuit_nodes.dm index 0ce6eb4b229..63cc115125d 100644 --- a/code/modules/research/techweb/nodes/modsuit_nodes.dm +++ b/code/modules/research/techweb/nodes/modsuit_nodes.dm @@ -90,7 +90,6 @@ prereq_ids = list(TECHWEB_NODE_MOD_EQUIP) design_ids = list( "mod_mirage_grenade", - "mod_plating_security", "mod_stealth", "mod_mag_harness", "mod_pathfinder", diff --git a/code/modules/unit_tests/screenshots/cardboard_cutouts_nukie_cutout.png b/code/modules/unit_tests/screenshots/cardboard_cutouts_nukie_cutout.png index 47061552e62a8d709def742f6c1a5e86d9847a4c..4a80c31646bb2a8fde1138fcbaf2215c72cd7da8 100644 GIT binary patch delta 355 zcmV-p0i6EK1jq!CBmq&8B_feZGX!RgMY)lIfPXbfL_t(IjeU~~a>F1DL=lcHk$}L3 zGqgim#HF@_6X?no)OEKwqjuTysv_ zo0j}U(yFJlDdOp07H(3FnAqBbju|A&HEgOg`2`l}xh$EuWDEj{Y4O`Xl=gmJjAmRD z0PjZu-9R@Qlao7iw_T~1ZcGY6;4XM<9ZXEdJrNSbW9Pku!?;(%du$uy-0L9P$+bVY zM0e*b`T**!2iu^wu(e6&-yRJEHHZ46XV4tB7C+Gw5-UMb=`R2P002ovPDHLkV1n4o BrEmZM delta 360 zcmV-u0hj*B1k41GBmq>BB_aa^T|bdWGX!Blj#`m^fPXegL_t(IjeU~~a>F1DL=lcH zkrV_jq^W!Vdv+mi8-J)YgEO;dAgx3}BXNe}SBqXwKkfPHiD+ye}gwU+w2OpHG8)T=>6CuW{h&IuPpHO8na!JPpi z_ykp>`hO5kbP}&|t`Xn8oOGLVNqD>FooNqz7?;Z<&D!#QsN%Ear92+`wPw^^70{RJ z5Z9d3_NFC2k+kY5ZHjpMmxY^DBPO=?pkoHfat)j6On!j{dM-;QE*XPBVp{z252d}I z7o!>11i<@IKsV5h#^mG<-ECLuM>i&gAaEBvwoMKuG4?p^Zk!gW{ z5lKWrR9Jfl-G)+2RKjft?>#g3_rKQ|d)ly!p8+?Fg z$`wx3lovI(z%=6xE~?Tp4heVCkn4zlx7kgcQy-XfOL^-voHX|qOEhb4VM{bDy@--b3E%v|iS!wvf{@%&buVv9`2*Z7I2)Q6`nGO7CW7PB>A>= z7}&Qh;M^j{9*KN;-6XkueZzw9F9~?5RfT`zPp$Qp^XsQQJN{kZtUws)9R7AvK*OM+ zb3RRdRZy^V-Iw>b6IXnzJWBDm6X$4+BAQ$U=UgG@%K{C`kB>MH7r8?D@ezkWGvsW< zbEaU-k@F1MO!54X7mp7{%!izR!Ne0f#lR2WPcVpqeTXMi22otQShYM@GCobm3U~=Q zL$ELmL+%C~D}+lR&=0PO2`-hF-v1KtbnpiOR<0Uv@DP}4&3x$d+ukA!7C?82+-*~;?U$_s7CXx>bo#=TZnceDq27uMk7#s;9)`w8xK zAEkMe^Dv)B#YW+50UA7>f%P=!v3FthZs-Qj7QllDBwry*{Oo=(9f2f4Rzlxlz6Hy# z8`khGz=|N&7GE5RH_eHEOq%9GE$Xt+UeE_o>Hf7qsi8@j*_VFQcB~W6S1;jg0m42H zm7jAx(vlr`AhHR1MtvSM=+U2K7935C#`EEY<1!5H!fs$%+gSVCSb+;<+=F!){2V}S zU(!JLVfjV)Ss~3wyMi|4Zw1s_fIkTMDGU{i0@Zn%5RVnShZra6u2#*MmMG)UVS5k!gW{ z5J^NqR9JfkKZ_f zh)fksIe_$~%S3_nKH=@{BGN@JZ#AcalDErMmu1oGIaa?Yv9!?GZkDYzfC1dgCc`X!Fy5Ns@2d zfPrJ%63#7R?2*Wq=S`B!$0scK{E&pV-c|S~@zma*Ilun$uYvy%I4clFI!C;n6woke z7@SX2pA|IhT=(VU?Zg$|Dvwg)?Zi3ED5Awx2+kF1zOK-q{CJ7;aFHvNA1`qTm?LK+ zo+|}&j-2PnW{T&FyhVI4VqWBb3?`n?DF(jzeu7C1>_Z}QuyXZ$gNMM!LT z%hhlQ#X%z{i(M~>=t=={=2!Wa^~7 z5i4*HfwGJ1k=v#2AoLK(Rj@}yw(|P6@91nWBaIe^-} zmVq9_>x=NcLYa?t1vcfs3TU(de-MaMm@1eBYVa~49xFr-F;O5Z(;r>G@}oJJ#KGP} iOe_?gEfI12