From fd3e4a04d7c8c24bc172397c977ccbb9f363dd75 Mon Sep 17 00:00:00 2001 From: Lucy Date: Mon, 24 Jun 2024 16:57:10 -0400 Subject: [PATCH] [PORT] Various modsuit PRs from /tg/ (#2385) * MOD Complexity rebalance (#76077) Reduced the cost of a lot of MODules. Pathfinder 2 -> 1 Tether 3 -> 1 Temperature Regulator 2 -> 1 DNA lock 2 -> 1 Health analyzer 2 -> 1 Sonar 2 -> 1 Microwave beam 2 -> 1 Drill 2 -> 1 All visors (including NV and thermals) 2 -> 1 Circuit Adapter 2 -> 1 The Mining MODsuit has had its complexity increased to 15 and now starts with the eating apparatus module, with a total base complexity of 10/15 now. The Prototype MODsuit's active slowdown has been decreased from 1.5 (!) to 1. > Reduced the cost of a lot of MODules. There's lots of cute little MODules here, and they are all despite their 'small' cost far too expensive for them to ever be used. The small little cost adds up, when you consider that two 2-complexity modules cost FOUR, which is more than most good modules (that are 3), especially when storage modules take up 3 complexity already. Think about it like genetics, imagine if geladikinesis cost 40 instability. It'd be pointless and just make it not used. > Pathfinder 2 -> 1 Pathfinder is a little buggy, a bit janky, and still just a commodity, so this might let captains keep it for themselves more often when they're kitting out their MOD. > Tether 3 -> 1 Tether costing 3 complexity is ABSURD. That's as much as the actual ion jetpacks, and that's for something which you can replace completely with a fire extinguisher, not even including the tiny 4 tiles tethering range. > Temperature Regulator 2 -> 1 This is vital for spacewalking, I really don't know why it's this expensive. Hell it should be the norm, but whatevs. > DNA lock 2 -> 1 Nobody's ever going to use this if it can just be EMPed and broken... especially when it costs 2 complexity, which is the same cost as defibs, surgical processor, holster, criminal capture.. > Health analyzer 2 -> 1 This is just a health analyzer. A small item that you're paying for the privilege of being able to have it in your janksuit. It really shouldn't cost 2 complexity, nobody ever takes this. > Sonar 2 -> 1 I don't think there's much of a reason for sonar to be 2 complexity. You might think it's nuts, but sonar really isn't that useful as it's a windup with a screen-only range. Making it 1 might let it be seen ingame at some point. > Microwave beam 2 -> 1 Despite the cool name this just fries food. I don't think that should be expensive! > Drill 2 -> 1 The drill module is mostly redundant when by the time you get it, chances are you have a plasma cutter already which is usually better, if not as space-efficient. There's also the dumb issue with drilling into gibtonite which instantly blows it up. > All visors (including NV and thermals) 2 -> 1 Similarly to the health analyzer, chances are if you HAVE the module you don't actually *need* it as you're already.. that job. Additionally, and this is also part of the reason for the NV, thermal, and even the health analyzer modules, is that traitors/nukies now have to balance MOD economy alongside TC count, and I can't tell you just how frustrating it is to buy something and be told I don't have enough complexity to put it into the MODsuit. I already spent the damn TC! > Circuit Adapter 2 -> 1 This thing seems pretty useless. All it can really do is open and close your modsuit, which like, wow okay. No need for it to be expensive. > The Mining MODsuit has had its complexity increased to 15 and now starts with the eating apparatus module, with a total base complexity of 10/13 now. The complexity increase is because for some reason the MODsuit is already filled to the brim by default, which means that actually interacting with robotics in any way is thoroughly disincentivized as you'd need to take so many modules out to do so that it makes the purchase and interaction pointless. Now you CAN go and ask robotics for anything you need, though there isn't much a miner would want and value enough to trek across the station, for now. Also, it starts with the eating apparatus because it really looked like it should! The flavor text even talks about miners, it's strange for that to be there if miners won't use it. It'll also encourage it to actually be bought more by allowing you to eat through it. > The Prototype MODsuit's active slowdown has been decreased from 1.5 (!) to 1. 1.5 is a lot, A LOT, of slowdown. For such an incredibly rare mod, it completely kills the damn thing, even for the charlie station crew! You can't fight xenos with 1.5 slowdown! Having Kinesis isn't enough of a reason to cripple it so thoroughly and pointlessly. It's 0.4 now, which is a nice middleground between 'fast' suits like the medical and security ones, and the 'slow' ones like civilian, engineering, science. :cl: balance: Reduced the complexity cost of a lot of MODules. balance: Pathfinder 2 -> 1 balance: Tether 3 -> 2 balance: Temperature Regulator 2 -> 1 balance: DNA lock 2 -> 1 balance: Health analyzer 2 -> 1 balance: Sonar 2 -> 1 balance: Microwave beam 2 -> 1 balance: Drill 2 -> 1 balance: All visors (including NV and thermals) 2 -> 1 balance: Circuit Adapter 2 -> 1 balance: The Mining MODsuit has had its complexity increased to 13 and now starts with the eating apparatus module, with a total base complexity of 10/13 now. balance: The Prototype MODsuit's active slowdown has been decreased from 1.5 (!) to 1. spellcheck: Fixed a type on the energy net module. /:cl: * Generic Crew-Available Status Readout Module - Continued (#76117) ## About The Pull Request ![image](https://github.com/tgstation/tgstation/assets/31829017/0019591c-a7f5-4315-8ea7-1ebc1ea96206) continues and closes tgstation/tgstation#75708 - adds a generic status readout module that doesn't have a round timer or round ID display - the health analyzer's info display can now be toggled via a setting ![image](https://github.com/tgstation/tgstation/assets/31829017/95dc3c2d-26bf-4747-a5ba-dddc5b2a33d2) - adds the generic status readout module to the advanced medical MODs node ![image](https://github.com/tgstation/tgstation/assets/31829017/8c065c45-692e-4bf9-901f-5c382fb278b6) - it has a death sound now yippee (sound and volume are vareditable. shoutouts to fikou for giving me a sound that was better) - ninjas still get the one with round timer/ID display ## Why It's Good For The Game it's a neat little module that tells you things about your spaceman that you might want to keep track of, like viruses and health and nutritional status ## Changelog :cl: add: A really old data disk with the MOD module designs for the status readout was recovered, and has been haphazardly hotpatched into the research networks. add: Also, the status readout module now plays a sound on death. qol: The MODsuit health analyzer's info tab health readout can now be disabled in its settings. /:cl: --------- Co-authored-by: Hatterhat Co-authored-by: san7890 * Atrocinator flips your chat text around (#76618) ![image](https://github.com/tgstation/tgstation/assets/51863163/fd325eeb-f862-4268-8370-4c13c4701c16) It's funny :cl: Melbert add: The Atrocinator will now flip you even more. /:cl: * Infiltrator MODs don't have a plasma visor anymore (#76164) ## About The Pull Request Disables the plasma stabilizer's visor for any MODsuit that has an infiltrator module ## Why It's Good For The Game It doesn't make sense that a suit designed for concealing your identity gave away your species. This changes that, allowing plasmamen to freely use this MODsuit. ## Changelog :cl: StaringGasMask qol: Now plasmamen can use the infiltrator MODsuit without having their species revealed. The helmet's still not sealed, so remember your mask. /:cl: * Failed MOD auto-storage attempts now tell you that it failed (#76673) ## About The Pull Request title; if you try to retract your suit and it fails to store your suit slot item (tank/gun/etc) into storage, now it tells you with both a balloon alert and chat that you dropped something ![image](https://github.com/tgstation/tgstation/assets/31829017/318b3d19-ba74-46ea-a85b-6f620bcb2e19) ![image](https://github.com/tgstation/tgstation/assets/31829017/602ca3bf-ccb0-4f48-a8a6-9faa0b1c1f6c) ## Why It's Good For The Game "oh shit where'd i put my oxygen tank" (you left it behind 3 Zs ago or something) ## Changelog :cl: qol: When a MOD fails to store something in itself when retracting, you're now notified in both the chat and by a balloon alert. /:cl: Co-authored-by: Hatterhat * Removes the hat whitelist from the hat stabilizer mod (#76962) ## About The Pull Request This PR allows you to use any hat with the hat stabilizer module. Before, it was limited to a pretty small, very arbitrary list of hats (captain's hats, centcom hats, and a few gimmicky hats), making it disappointingly limited to both the captain, and anyone who finds the thing in maints. I'm guessing this limit was put in place to avoid janky looking hats, but plasmamen get the exact same thing without the restriction, and there haven't really been any complaints there. While I did not test this with every single hat, I *did* test it with every hat currently in the autodrobe, and there wasn't any jank there, even with things like wigs, and hats that cover the entire head. There was also a bug/oversight where the MOD eating apparatus module didn't properly disable pepper spray protection like it was supposed to. It was literally just a matter of missing parentheses, so i fixed that too. Not super sure what to mark this change as btw (qol? balance? removal?) so if I should change it, let me know. ## Why It's Good For The Game Allows both the captain and anyone who finds/steals the module to actually wear the hats they want to wear, instead of being limited to a small, mostly arbitrary list of hats, and having less outfit choice that a plasmaman. ## Changelog :cl: qol: You can now use any hat with the hat stabilizer MOD fix: The MOD eating apparatus module now properly disables pepper spray protection /:cl: --------- Co-authored-by: carlarctg <53100513+carlarctg@users.noreply.github.com> Co-authored-by: Hatterhat <31829017+Hatterhat@users.noreply.github.com> Co-authored-by: Hatterhat Co-authored-by: san7890 Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com> Co-authored-by: StaringGasMask <62149527+Exester509@users.noreply.github.com> Co-authored-by: Nick <42454181+Momo8289@users.noreply.github.com> --- code/modules/mod/mod_theme.dm | 8 +- code/modules/mod/mod_types.dm | 3 +- code/modules/mod/modules/module_pathfinder.dm | 2 +- .../mod/modules/modules_engineering.dm | 2 +- code/modules/mod/modules/modules_general.dm | 128 +++++++++----- code/modules/mod/modules/modules_maint.dm | 7 +- code/modules/mod/modules/modules_medical.dm | 25 ++- code/modules/mod/modules/modules_ninja.dm | 54 ++---- code/modules/mod/modules/modules_security.dm | 4 +- code/modules/mod/modules/modules_service.dm | 2 +- code/modules/mod/modules/modules_supply.dm | 2 +- code/modules/mod/modules/modules_visor.dm | 2 +- .../designs/mechfabricator_designs.dm | 13 ++ code/modules/research/techweb/all_nodes.dm | 1 + code/modules/wiremod/shell/module.dm | 2 +- interface/stylesheet.dm | 2 + sound/effects/flatline3.ogg | Bin 0 -> 28813 bytes .../tgui-panel/styles/tgchat/chat-dark.scss | 9 + .../tgui-panel/styles/tgchat/chat-light.scss | 9 + tgui/packages/tgui/interfaces/MODsuit.jsx | 158 ++++++++++-------- 20 files changed, 257 insertions(+), 176 deletions(-) create mode 100644 sound/effects/flatline3.ogg diff --git a/code/modules/mod/mod_theme.dm b/code/modules/mod/mod_theme.dm index e680bb3cc606..f0bcd0be0fbd 100644 --- a/code/modules/mod/mod_theme.dm +++ b/code/modules/mod/mod_theme.dm @@ -317,7 +317,7 @@ resistance_flags = FIRE_PROOF|LAVA_PROOF max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT - complexity_max = DEFAULT_MAX_COMPLEXITY - 5 + complexity_max = DEFAULT_MAX_COMPLEXITY - 2 charge_drain = DEFAULT_CHARGE_DRAIN * 2 allowed_suit_storage = list( /obj/item/resonator, @@ -1293,7 +1293,7 @@ post-void war era modular suit to ever be safely utilized by an operator. This ancient clunker is still functional, \ though it's missing several modern-day luxuries from updated Nakamura Engineering designs. \ Primarily, the suit's myoelectric suit layer is entirely non-existant, and the servos do very little to \ - help distribute the weight evenly across the wearer's body, making it slow and bulky to move in. \ + help distribute the weight evenly across the wearer's body when the suit is deactivated, making it slow and bulky to move in. \ The internal heads-up display is rendered in nearly unreadable cyan, as the visor suggests, \ leaving the user unable to see long distances. However, the way the helmet retracts is pretty cool." default_skin = "prototype" @@ -1302,8 +1302,8 @@ siemens_coefficient = 0 complexity_max = DEFAULT_MAX_COMPLEXITY + 5 charge_drain = DEFAULT_CHARGE_DRAIN * 2 - slowdown_inactive = 2 - slowdown_active = 1.5 + slowdown_inactive = 1.5 + slowdown_active = 1 ui_theme = "hackerman" inbuilt_modules = list(/obj/item/mod/module/anomaly_locked/kinesis/prebuilt/prototype) allowed_suit_storage = list( diff --git a/code/modules/mod/mod_types.dm b/code/modules/mod/mod_types.dm index e33472006c4b..3da0067f0eb6 100644 --- a/code/modules/mod/mod_types.dm +++ b/code/modules/mod/mod_types.dm @@ -106,6 +106,7 @@ /obj/item/mod/module/orebag, /obj/item/mod/module/clamp, /obj/item/mod/module/drill, + /obj/item/mod/module/mouthhole, ) default_pins = list( /obj/item/mod/module/gps, @@ -304,7 +305,7 @@ applied_modules = list( /obj/item/mod/module/storage, /obj/item/mod/module/noslip, - /obj/item/mod/module/status_readout, + /obj/item/mod/module/status_readout/ninja, /obj/item/mod/module/stealth/ninja, /obj/item/mod/module/dispenser/ninja, /obj/item/mod/module/dna_lock/reinforced, diff --git a/code/modules/mod/modules/module_pathfinder.dm b/code/modules/mod/modules/module_pathfinder.dm index 5f40982e9e90..2b4f9c70f5f0 100644 --- a/code/modules/mod/modules/module_pathfinder.dm +++ b/code/modules/mod/modules/module_pathfinder.dm @@ -10,7 +10,7 @@ The implant is stored in the module and needs to be injected in a human to function. \ Nakamura Engineering swears up and down there's airbrakes." icon_state = "pathfinder" - complexity = 2 + complexity = 1 use_power_cost = DEFAULT_CHARGE_DRAIN * 10 incompatible_modules = list(/obj/item/mod/module/pathfinder) /// The pathfinding implant. diff --git a/code/modules/mod/modules/modules_engineering.dm b/code/modules/mod/modules/modules_engineering.dm index e41b35aa51ee..a609236b02fe 100644 --- a/code/modules/mod/modules/modules_engineering.dm +++ b/code/modules/mod/modules/modules_engineering.dm @@ -85,7 +85,7 @@ these are only capable of working in zero-gravity environments, a blessing to some Engineers." icon_state = "tether" module_type = MODULE_ACTIVE - complexity = 3 + complexity = 2 use_power_cost = DEFAULT_CHARGE_DRAIN incompatible_modules = list(/obj/item/mod/module/tether) cooldown_time = 1.5 SECONDS diff --git a/code/modules/mod/modules/modules_general.dm b/code/modules/mod/modules/modules_general.dm index 5ce86023956a..ea8e4409ee1b 100644 --- a/code/modules/mod/modules/modules_general.dm +++ b/code/modules/mod/modules/modules_general.dm @@ -38,9 +38,12 @@ /obj/item/mod/module/storage/proc/on_chestplate_unequip(obj/item/source, force, atom/newloc, no_move, invdrop, silent) if(QDELETED(source) || !mod.wearer || newloc == mod.wearer || !mod.wearer.s_store) return - to_chat(mod.wearer, span_notice("[src] tries to store [mod.wearer.s_store] inside itself.")) - if(atom_storage?.attempt_insert(mod.wearer.s_store, mod.wearer, override = TRUE)) - mod.wearer.temporarilyRemoveItemFromInventory(mod.wearer.s_store) + if(!atom_storage?.attempt_insert(mod.wearer.s_store, mod.wearer, override = TRUE)) + balloon_alert(mod.wearer, "storage failed!") + to_chat(mod.wearer, span_warning("[src] fails to store [mod.wearer.s_store] inside itself!")) + return + to_chat(mod.wearer, span_notice("[src] stores [mod.wearer.s_store] inside itself.")) + mod.wearer.temporarilyRemoveItemFromInventory(mod.wearer.s_store) /obj/item/mod/module/storage/large_capacity name = "MOD expanded storage module" @@ -163,6 +166,68 @@ overlay_state_active = "module_jetpackadv_on" full_speed = TRUE +///Status Readout - Puts a lot of information including health, nutrition, fingerprints, temperature to the suit TGUI. +/obj/item/mod/module/status_readout + name = "MOD status readout module" + desc = "A once-common module, this technology unfortunately went out of fashion in the safer regions of space; \ + and found new life in the research networks of the Periphery. This particular unit hooks into the suit's spine, \ + capable of capturing and displaying all possible biometric data of the wearer; sleep, nutrition, fitness, fingerprints, \ + and even useful information such as their overall health and wellness. The vitals monitor also comes with a speaker, loud enough \ + to alert anyone nearby that someone has, in fact, died." + icon_state = "status" + complexity = 1 + use_power_cost = DEFAULT_CHARGE_DRAIN * 0.1 + incompatible_modules = list(/obj/item/mod/module/status_readout) + tgui_id = "status_readout" + /// Does this show the round ID and shift time? + var/show_time = FALSE + /// Death sound. May or may not be funny. Vareditable at your own risk. + var/death_sound = 'sound/effects/flatline3.ogg' + /// Death sound volume. Please be responsible with this. + var/death_sound_volume = 50 + +/obj/item/mod/module/status_readout/add_ui_data() + . = ..() + .["show_time"] = show_time + .["statustime"] = station_time_timestamp() + .["statusid"] = GLOB.round_id + .["statushealth"] = mod.wearer?.health || 0 + .["statusmaxhealth"] = mod.wearer?.getMaxHealth() || 0 + .["statusbrute"] = mod.wearer?.getBruteLoss() || 0 + .["statusburn"] = mod.wearer?.getFireLoss() || 0 + .["statustoxin"] = mod.wearer?.getToxLoss() || 0 + .["statusoxy"] = mod.wearer?.getOxyLoss() || 0 + .["statustemp"] = mod.wearer?.bodytemperature || 0 + .["statusnutrition"] = mod.wearer?.nutrition || 0 + .["statusfingerprints"] = mod.wearer ? md5(mod.wearer.dna.unique_identity) : null + .["statusdna"] = mod.wearer?.dna.unique_enzymes + .["statusviruses"] = null + if(!length(mod.wearer?.diseases)) + return . + var/list/viruses = list() + for(var/datum/disease/virus as anything in mod.wearer.diseases) + var/list/virus_data = list() + virus_data["name"] = virus.name + virus_data["type"] = virus.spread_text + virus_data["stage"] = virus.stage + virus_data["maxstage"] = virus.max_stages + virus_data["cure"] = virus.cure_text + viruses += list(virus_data) + .["statusviruses"] = viruses + + return . + +/obj/item/mod/module/status_readout/on_suit_activation() + RegisterSignal(mod.wearer, COMSIG_LIVING_DEATH, PROC_REF(death_sound)) + +/obj/item/mod/module/status_readout/on_suit_deactivation(deleting) + UnregisterSignal(mod.wearer, COMSIG_LIVING_DEATH) + +/obj/item/mod/module/status_readout/proc/death_sound(mob/living/carbon/human/wearer) + SIGNAL_HANDLER + if(death_sound && death_sound_volume) + playsound(wearer, death_sound, death_sound_volume, FALSE) + ///Eating Apparatus - Lets the user eat/drink with the suit on. /obj/item/mod/module/mouthhole name = "MOD eating apparatus module" @@ -181,8 +246,8 @@ /obj/item/mod/module/mouthhole/on_install() former_flags = mod.helmet.flags_cover former_visor_flags = mod.helmet.visor_flags_cover - mod.helmet.flags_cover &= ~HEADCOVERSMOUTH|PEPPERPROOF - mod.helmet.visor_flags_cover &= ~HEADCOVERSMOUTH|PEPPERPROOF + mod.helmet.flags_cover &= ~(HEADCOVERSMOUTH|PEPPERPROOF) + mod.helmet.visor_flags_cover &= ~(HEADCOVERSMOUTH|PEPPERPROOF) /obj/item/mod/module/mouthhole/on_uninstall(deleting = FALSE) if(deleting) @@ -358,7 +423,7 @@ ensuring they're comfortable; even if they're some that like it hot." icon_state = "regulator" module_type = MODULE_TOGGLE - complexity = 2 + complexity = 1 active_power_cost = DEFAULT_CHARGE_DRAIN * 0.3 incompatible_modules = list(/obj/item/mod/module/thermal_regulator) cooldown_time = 0.5 SECONDS @@ -389,7 +454,7 @@ however, this incredibly sensitive module is shorted out by EMPs. Luckily, cloning has been outlawed." icon_state = "dnalock" module_type = MODULE_USABLE - complexity = 2 + complexity = 1 use_power_cost = DEFAULT_CHARGE_DRAIN * 3 incompatible_modules = list(/obj/item/mod/module/dna_lock, /obj/item/mod/module/eradication_lock) cooldown_time = 0.5 SECONDS @@ -472,6 +537,11 @@ incompatible_modules = list(/obj/item/mod/module/plasma_stabilizer) overlay_state_inactive = "module_plasma" +/obj/item/mod/module/plasma_stabilizer/generate_worn_overlay() + if(locate(/obj/item/mod/module/infiltrator) in mod.modules) + return list() + return ..() + /obj/item/mod/module/plasma_stabilizer/on_equip() ADD_TRAIT(mod.wearer, TRAIT_NOSELFIGNITION_HEAD_ONLY, MOD_TRAIT) @@ -484,7 +554,7 @@ /obj/item/mod/module/hat_stabilizer name = "MOD hat stabilizer module" desc = "A simple set of deployable stands, directly atop one's head; \ - these will deploy under a select few hats to keep them from falling off, allowing them to be worn atop the sealed helmet. \ + these will deploy under a hat to keep it from falling off, allowing them to be worn atop the sealed helmet. \ You still need to take the hat off your head while the helmet deploys, though. \ This is a must-have for Nanotrasen Captains, enabling them to show off their authoritative hat even while in their MODsuit." icon_state = "hat_holder" @@ -493,36 +563,9 @@ even though it comes inbuilt into the Magnate/Corporate MODS and spawns in maints, I like the idea of stealing them*/ /// Currently "stored" hat. No armor or function will be inherited, ONLY the icon. var/obj/item/clothing/head/attached_hat - /// Whitelist of attachable hats, read note in Initialize() below this line - var/static/list/attachable_hats_list - -/obj/item/mod/module/hat_stabilizer/Initialize(mapload) - . = ..() - attachable_hats_list = typecacheof( - //List of attachable hats. Make sure these and their subtypes are all tested, so they dont appear janky. - //This list should also be gimmicky, so captains can have fun. I.E. the Santahat, Pirate hat, Tophat, Chefhat... - //Yes, I said it, the captain should have fun. - list( - /obj/item/clothing/head/hats/caphat, - /obj/item/clothing/head/costume/crown, - /obj/item/clothing/head/hats/centhat, - /obj/item/clothing/head/hats/centcom_cap, - /obj/item/clothing/head/costume/pirate, - /obj/item/clothing/head/costume/santa, - /obj/item/clothing/head/utility/hardhat/reindeer, - /obj/item/clothing/head/costume/sombrero/green, - /obj/item/clothing/head/costume/kitty, - /obj/item/clothing/head/costume/rabbitears, - /obj/item/clothing/head/costume/festive, - /obj/item/clothing/head/costume/powdered_wig, - /obj/item/clothing/head/costume/weddingveil, - /obj/item/clothing/head/hats/tophat, - /obj/item/clothing/head/costume/nursehat, - /obj/item/clothing/head/utility/chefhat, - /obj/item/clothing/head/costume/papersack, - /obj/item/clothing/head/caphat/beret, - /obj/item/clothing/head/helmet/space/beret, - )) + /// Original cover flags for the MOD helmet, before a hat is placed + var/former_flags + var/former_visor_flags /obj/item/mod/module/hat_stabilizer/on_suit_activation() RegisterSignal(mod.helmet, COMSIG_ATOM_EXAMINE, PROC_REF(add_examine)) @@ -552,14 +595,15 @@ if(!mod.active) balloon_alert(user, "suit must be active!") return - if(!is_type_in_typecache(hitting_item, attachable_hats_list)) - balloon_alert(user, "this hat won't fit!") - return if(attached_hat) balloon_alert(user, "hat already attached!") return if(mod.wearer.transferItemToLoc(hitting_item, src, force = FALSE, silent = TRUE)) attached_hat = hitting_item + former_flags = mod.helmet.flags_cover + former_visor_flags = mod.helmet.visor_flags_cover + mod.helmet.flags_cover |= attached_hat.flags_cover + mod.helmet.visor_flags_cover |= attached_hat.visor_flags_cover balloon_alert(user, "hat attached, right-click to remove") mod.wearer.update_clothing(mod.slot_flags) @@ -579,6 +623,8 @@ else balloon_alert_to_viewers("the hat falls to the floor!") attached_hat = null + mod.helmet.flags_cover = former_flags + mod.helmet.visor_flags_cover = former_visor_flags mod.wearer.update_clothing(mod.slot_flags) ///Sign Language Translator - allows people to sign over comms using the modsuit's gloves. diff --git a/code/modules/mod/modules/modules_maint.dm b/code/modules/mod/modules/modules_maint.dm index 9829321f6400..d3eb905a2068 100644 --- a/code/modules/mod/modules/modules_maint.dm +++ b/code/modules/mod/modules/modules_maint.dm @@ -287,6 +287,7 @@ playsound(src, 'sound/effects/curseattack.ogg', 50) mod.wearer.AddElement(/datum/element/forced_gravity, NEGATIVE_GRAVITY) RegisterSignal(mod.wearer, COMSIG_MOVABLE_MOVED, PROC_REF(check_upstairs)) + RegisterSignal(mod.wearer, COMSIG_MOB_SAY, PROC_REF(on_talk)) ADD_TRAIT(mod.wearer, TRAIT_SILENT_FOOTSTEPS, MOD_TRAIT) check_upstairs() //todo at some point flip your screen around @@ -300,7 +301,7 @@ if(deleting) playsound(src, 'sound/effects/curseattack.ogg', 50) qdel(mod.wearer.RemoveElement(/datum/element/forced_gravity, NEGATIVE_GRAVITY)) - UnregisterSignal(mod.wearer, COMSIG_MOVABLE_MOVED) + UnregisterSignal(mod.wearer, list(COMSIG_MOVABLE_MOVED, COMSIG_MOB_SAY)) step_count = 0 REMOVE_TRAIT(mod.wearer, TRAIT_SILENT_FOOTSTEPS, MOD_TRAIT) var/turf/open/openspace/current_turf = get_turf(mod.wearer) @@ -334,3 +335,7 @@ QDEL_IN(mod.wearer, FLY_TIME) #undef FLY_TIME + +/obj/item/mod/module/atrocinator/proc/on_talk(datum/source, list/speech_args) + SIGNAL_HANDLER + speech_args[SPEECH_SPANS] |= "upside_down" diff --git a/code/modules/mod/modules/modules_medical.dm b/code/modules/mod/modules/modules_medical.dm index 46f698e0d5fb..10d3be3b0f41 100644 --- a/code/modules/mod/modules/modules_medical.dm +++ b/code/modules/mod/modules/modules_medical.dm @@ -13,24 +13,30 @@ but it's up to you to do something with it." icon_state = "health" module_type = MODULE_ACTIVE - complexity = 2 + complexity = 1 use_power_cost = DEFAULT_CHARGE_DRAIN incompatible_modules = list(/obj/item/mod/module/health_analyzer) cooldown_time = 0.5 SECONDS tgui_id = "health_analyzer" /// Scanning mode, changes how we scan something. var/mode = HEALTH_SCAN + /// Do we relay the wearer's health data to the info tab? Mainly useful for turning off if you also have a status readout. + var/show_vitals = TRUE /// List of all scanning modes. var/static/list/modes = list(HEALTH_SCAN, WOUND_SCAN, CHEM_SCAN) /obj/item/mod/module/health_analyzer/add_ui_data() . = ..() - .["userhealth"] = mod.wearer?.health || 0 - .["usermaxhealth"] = mod.wearer?.getMaxHealth() || 0 - .["userbrute"] = mod.wearer?.getBruteLoss() || 0 - .["userburn"] = mod.wearer?.getFireLoss() || 0 - .["usertoxin"] = mod.wearer?.getToxLoss() || 0 - .["useroxy"] = mod.wearer?.getOxyLoss() || 0 + .["show_vitals"] = show_vitals + if(show_vitals) + .["userhealth"] = mod.wearer?.health || 0 + .["usermaxhealth"] = mod.wearer?.getMaxHealth() || 0 + .["userbrute"] = mod.wearer?.getBruteLoss() || 0 + .["userburn"] = mod.wearer?.getFireLoss() || 0 + .["usertoxin"] = mod.wearer?.getToxLoss() || 0 + .["useroxy"] = mod.wearer?.getOxyLoss() || 0 + + return . /obj/item/mod/module/health_analyzer/on_select_use(atom/target) . = ..() @@ -50,11 +56,16 @@ /obj/item/mod/module/health_analyzer/get_configuration() . = ..() .["mode"] = add_ui_configuration("Scan Mode", "list", mode, modes) + .["show_vitals"] = add_ui_configuration("Self Vitals Display", "bool", show_vitals) + + return . /obj/item/mod/module/health_analyzer/configure_edit(key, value) switch(key) if("mode") mode = value + if("show_vitals") + show_vitals = value #undef HEALTH_SCAN #undef WOUND_SCAN diff --git a/code/modules/mod/modules/modules_ninja.dm b/code/modules/mod/modules/modules_ninja.dm index 64613a4bcec8..02bcc706c5ed 100644 --- a/code/modules/mod/modules/modules_ninja.dm +++ b/code/modules/mod/modules/modules_ninja.dm @@ -287,52 +287,24 @@ empulse(src, heavy_range = 4, light_range = 6) drain_power(use_power_cost) -///Status Readout - Puts a lot of information including health, nutrition, fingerprints, temperature to the suit TGUI. -/obj/item/mod/module/status_readout - name = "MOD status readout module" - desc = "A once-common module, this technology went unfortunately out of fashion; \ - and right into the arachnid grip of the Spider Clan. This hooks into the suit's spine, \ - capable of capturing and displaying all possible biometric data of the wearer; sleep, nutrition, fitness, fingerprints, \ - and even useful information such as their overall health and wellness." - icon_state = "status" - complexity = 1 - use_power_cost = DEFAULT_CHARGE_DRAIN * 0.1 - incompatible_modules = list(/obj/item/mod/module/status_readout) - tgui_id = "status_readout" - -/obj/item/mod/module/status_readout/add_ui_data() - . = ..() - .["statustime"] = station_time_timestamp() - .["statusid"] = GLOB.round_id - .["statushealth"] = mod.wearer?.health || 0 - .["statusmaxhealth"] = mod.wearer?.getMaxHealth() || 0 - .["statusbrute"] = mod.wearer?.getBruteLoss() || 0 - .["statusburn"] = mod.wearer?.getFireLoss() || 0 - .["statustoxin"] = mod.wearer?.getToxLoss() || 0 - .["statusoxy"] = mod.wearer?.getOxyLoss() || 0 - .["statustemp"] = mod.wearer?.bodytemperature || 0 - .["statusnutrition"] = mod.wearer?.nutrition || 0 - .["statusfingerprints"] = mod.wearer ? md5(mod.wearer.dna.unique_identity) : null - .["statusdna"] = mod.wearer?.dna.unique_enzymes - .["statusviruses"] = null - if(!length(mod.wearer?.diseases)) - return - var/list/viruses = list() - for(var/datum/disease/virus as anything in mod.wearer.diseases) - var/list/virus_data = list() - virus_data["name"] = virus.name - virus_data["type"] = virus.spread_text - virus_data["stage"] = virus.stage - virus_data["maxstage"] = virus.max_stages - virus_data["cure"] = virus.cure_text - viruses += list(virus_data) - .["statusviruses"] = viruses +/// Ninja Status Readout - Like the normal status display (see the base type), but with a clock. +/obj/item/mod/module/status_readout/ninja + name = "MOD Spider Clan status readout module" + desc = "A once-common module, this technology unfortunately went out of fashion in the safer regions of space; \ + and, according to the extra markings on this particular unit's casing, right into the arachnid grip of the Spider Clan. \ + Like other similar units, this one hooks into the suit's spine, and is capable of capturing and displaying \ + all possible biometric data of the wearer; sleep, nutrition, fitness, fingerprints, \ + and even useful information such as their overall health and wellness. This one comes with a clock that calibrates to the \ + local system time, and an operational ID number display. The vital monitor's speaker has been removed." + show_time = TRUE + death_sound = null + death_sound_volume = null ///Energy Net - Ensnares enemies in a net that prevents movement. /obj/item/mod/module/energy_net name = "MOD energy net module" desc = "A custom-built net-thrower. While conventional implementations of this capturing device \ - tilize monomolecular fibers or cutting razorwire, this uses hardlight technology to deploy a \ + utilize monomolecular fibers or cutting razorwire, this uses hardlight technology to deploy a \ trapping field capable of immobilizing even the strongest opponents." icon_state = "energy_net" removable = FALSE diff --git a/code/modules/mod/modules/modules_security.dm b/code/modules/mod/modules/modules_security.dm index 8669e7debe8d..d943c2c7d99b 100644 --- a/code/modules/mod/modules/modules_security.dm +++ b/code/modules/mod/modules/modules_security.dm @@ -364,8 +364,8 @@ Its loud ping is much harder to hide in an indoor station than in the outdoor operations it was designed for." icon_state = "active_sonar" module_type = MODULE_USABLE - use_power_cost = DEFAULT_CHARGE_DRAIN * 5 - complexity = 3 + use_power_cost = DEFAULT_CHARGE_DRAIN * 4 + complexity = 2 incompatible_modules = list(/obj/item/mod/module/active_sonar) cooldown_time = 25 SECONDS diff --git a/code/modules/mod/modules/modules_service.dm b/code/modules/mod/modules/modules_service.dm index 061c81313225..5381a26e88bd 100644 --- a/code/modules/mod/modules/modules_service.dm +++ b/code/modules/mod/modules/modules_service.dm @@ -27,7 +27,7 @@ allowing them to cook food from a distance, with the greatest of ease. Not recommended for use against grapes." icon_state = "microwave_beam" module_type = MODULE_ACTIVE - complexity = 2 + complexity = 1 use_power_cost = DEFAULT_CHARGE_DRAIN * 5 incompatible_modules = list(/obj/item/mod/module/microwave_beam, /obj/item/mod/module/organ_thrower) cooldown_time = 10 SECONDS diff --git a/code/modules/mod/modules/modules_supply.dm b/code/modules/mod/modules/modules_supply.dm index f5cd29622911..70e57e685b01 100644 --- a/code/modules/mod/modules/modules_supply.dm +++ b/code/modules/mod/modules/modules_supply.dm @@ -118,7 +118,7 @@ your drill is surely the one that both pierces and creates the heavens." icon_state = "drill" module_type = MODULE_ACTIVE - complexity = 2 + complexity = 1 use_power_cost = DEFAULT_CHARGE_DRAIN incompatible_modules = list(/obj/item/mod/module/drill) cooldown_time = 0.5 SECONDS diff --git a/code/modules/mod/modules/modules_visor.dm b/code/modules/mod/modules/modules_visor.dm index 33ee50a7ed0e..e8656fe92331 100644 --- a/code/modules/mod/modules/modules_visor.dm +++ b/code/modules/mod/modules/modules_visor.dm @@ -5,7 +5,7 @@ name = "MOD visor module" desc = "A heads-up display installed into the visor of the suit. They say these also let you see behind you." module_type = MODULE_TOGGLE - complexity = 2 + complexity = 1 active_power_cost = DEFAULT_CHARGE_DRAIN * 0.3 incompatible_modules = list(/obj/item/mod/module/visor) cooldown_time = 0.5 SECONDS diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm index ec29ee5f36b0..d6849f41c04e 100644 --- a/code/modules/research/designs/mechfabricator_designs.dm +++ b/code/modules/research/designs/mechfabricator_designs.dm @@ -1893,6 +1893,19 @@ ) departmental_flags = DEPARTMENT_BITFLAG_MEDICAL +/datum/design/module/statusreadout + name = "Status Readout Module" + id = "mod_statusreadout" + materials = list( + /datum/material/iron = HALF_SHEET_MATERIAL_AMOUNT * 3, + /datum/material/glass = HALF_SHEET_MATERIAL_AMOUNT, + /datum/material/titanium = SMALL_MATERIAL_AMOUNT * 2, + ) + build_path = /obj/item/mod/module/status_readout + category = list( + RND_CATEGORY_MODSUIT_MODULES + RND_SUBCATEGORY_MODSUIT_MODULES_MEDICAL + ) + /datum/design/module/patienttransport name = "Patient Transport Module" id = "mod_patienttransport" diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index 35de515ceee6..feab11b01e32 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -1757,6 +1757,7 @@ "mod_defib", "mod_threadripper", "mod_surgicalprocessor", + "mod_statusreadout", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3500) diff --git a/code/modules/wiremod/shell/module.dm b/code/modules/wiremod/shell/module.dm index 5c269e8c7e8d..bffff02e5fbc 100644 --- a/code/modules/wiremod/shell/module.dm +++ b/code/modules/wiremod/shell/module.dm @@ -2,7 +2,7 @@ name = "MOD circuit adapter module" desc = "A module shell that allows a circuit to be inserted into, and interface with, a MODsuit." module_type = MODULE_USABLE - complexity = 3 + complexity = 1 idle_power_cost = DEFAULT_CHARGE_DRAIN * 0.5 incompatible_modules = list(/obj/item/mod/module/circuit) cooldown_time = 0.5 SECONDS diff --git a/interface/stylesheet.dm b/interface/stylesheet.dm index 6b1a5788e639..a247d3ad9c83 100644 --- a/interface/stylesheet.dm +++ b/interface/stylesheet.dm @@ -172,6 +172,8 @@ h1.alert, h2.alert {color: #000000;} .swarmer {color: #2C75FF;} .resonate {color: #298F85;} +.upside_down {display: inline; -moz-transform: scale(-1, -1); -webkit-transform: scale(-1, -1); -o-transform: scale(-1, -1); -ms-transform: scale(-1, -1); transform: scale(-1, -1);} + //MONKESTATION ADDITION START .brass { color: #BE8700; diff --git a/sound/effects/flatline3.ogg b/sound/effects/flatline3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..1430ee7429b847fb2602e025c8434d7b9f31a27a GIT binary patch literal 28813 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 JZS!N|{{T;h!o2_h literal 0 HcmV?d00001 diff --git a/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss b/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss index 0a8bfe7cfd81..031d987925af 100644 --- a/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss +++ b/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss @@ -895,6 +895,15 @@ em { color: #298f85; } +.upside_down { + display: inline; + -moz-transform: scale(-1, -1); + -webkit-transform: scale(-1, -1); + -o-transform: scale(-1, -1); + -ms-transform: scale(-1, -1); + transform: scale(-1, -1); +} + .connectionClosed, .fatalError { background: red; diff --git a/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss b/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss index edd742a00a78..ba3df2116007 100644 --- a/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss +++ b/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss @@ -925,6 +925,15 @@ h2.alert { color: #298f85; } +.upside_down { + display: inline; + -moz-transform: scale(-1, -1); + -webkit-transform: scale(-1, -1); + -o-transform: scale(-1, -1); + -ms-transform: scale(-1, -1); + transform: scale(-1, -1); +} + .connectionClosed, .fatalError { background: red; diff --git a/tgui/packages/tgui/interfaces/MODsuit.jsx b/tgui/packages/tgui/interfaces/MODsuit.jsx index 488622c830de..97ed019d93a7 100644 --- a/tgui/packages/tgui/interfaces/MODsuit.jsx +++ b/tgui/packages/tgui/interfaces/MODsuit.jsx @@ -132,6 +132,7 @@ const RadCounter = (props) => { const HealthAnalyzer = (props) => { const { active, + show_vitals, userhealth, usermaxhealth, userbrute, @@ -140,79 +141,88 @@ const HealthAnalyzer = (props) => { useroxy, } = props; return ( - <> -
- - - -
- - -
- - - -
-
- -
- - - -
-
- -
- - - -
-
- -
+
+ {show_vitals ? ( + <> +
- +
- - - + + +
+ + + +
+
+ +
+ + + +
+
+ +
+ + + +
+
+ +
+ + + +
+
+
+ + ) : ( +
+ {'Health Analyzer Vitals Readout Disabled In Settings'} +
+ )} +
); }; const StatusReadout = (props) => { const { active, + show_time, statustime, statusid, statushealth, @@ -229,18 +239,20 @@ const StatusReadout = (props) => { } = props; return ( <> - - -
- {active ? statustime : '00:00:00'} -
-
- -
- {active ? statusid || '0' : '???'} -
-
-
+ {!!show_time && ( + + +
+ {active ? statustime : '00:00:00'} +
+
+ +
+ {active ? statusid : '???'} +
+
+
+ )}