Port And Update Cybersun Stealth Hardsuit (#866) (#1807)

# Description

Ports the Cybersun Stealthsuit by popular demand. I've made a few
changes to it for this codebase to better accomodate for some of our MRP
standards, including making sure that it correctly modifies the sound
emitter that all hardsuits share. Rather than deleting the sound
effects, it modifies them to be significantly quieter, with harsher
falloff such that it can only be heard to a maximum distance of 5 tiles.
Its stats and costs are rebalanced around being weaker for fighting, but
it by extension a lot cheaper than it is on LRP.

I spent more time trying to figure out how to fix the stealth movement
balance to something I was satisfied with, than I did porting the suit.

It also got a new name to match the naming scheme of the other Cybersun
suits. For EE's code, it's balanced a lot differently than it is on Goob
LRP. It's cheaper here than it is there, and more strongly favors the
"Stealth" side of balance than it does combat. If you move sufficiently
slowly, you can remain in stealth. It makes noise like a "Light"
hardsuit, but is significantly muffled. It offers less protection than
the Security tacsuits. It's really not for direct combat, and is
*strongly* meant to play to the metal gear 4 fantasy.

<details><summary><h1>Media</h1></summary>
<p>

![image](https://github.com/user-attachments/assets/db30c1a5-af8e-4748-bc52-4dcc61833eaf)

</p>
</details>

# Changelog

🆑
- add: Ported the Cybersun Stealthsuit from Goobstation, with some
updates for the EE Codebase.

---------

Co-authored-by: starch <starchpersonal@gmail.com>
(cherry picked from commit 93eba0855fad629981732005e0c3b4bb2973b8ff)
This commit is contained in:
VMSolidus
2025-02-19 22:41:28 -05:00
committed by Spatison
parent 3a9a3a82ad
commit efdb28c42a
20 changed files with 274 additions and 0 deletions

View File

@@ -0,0 +1,6 @@
using Robust.Shared.GameStates;
namespace Content.Shared.Stealth.Components;
[RegisterComponent, NetworkedComponent]
public sealed partial class BreakStealthOnAttackComponent : Component { }

View File

@@ -1,7 +1,10 @@
using Content.Shared.Examine;
using Content.Shared.Interaction.Events;
using Content.Shared.Mobs;
using Content.Shared.Mobs.Systems;
using Content.Shared.Stealth.Components;
using Content.Shared.Throwing;
using Content.Shared.Weapons.Ranged.Events;
using Robust.Shared.GameStates;
using Robust.Shared.Timing;
@@ -25,6 +28,9 @@ public abstract class SharedStealthSystem : EntitySystem
SubscribeLocalEvent<StealthComponent, ExamineAttemptEvent>(OnExamineAttempt);
SubscribeLocalEvent<StealthComponent, ExaminedEvent>(OnExamined);
SubscribeLocalEvent<StealthComponent, MobStateChangedEvent>(OnMobStateChanged);
SubscribeLocalEvent<BreakStealthOnAttackComponent, BeforeThrowEvent>(OnThrow);
SubscribeLocalEvent<BreakStealthOnAttackComponent, AttackAttemptEvent>(OnAttack);
SubscribeLocalEvent<BreakStealthOnAttackComponent, ShotAttemptedEvent>(OnShoot);
}
private void OnExamineAttempt(EntityUid uid, StealthComponent component, ExamineAttemptEvent args)
@@ -188,6 +194,19 @@ public abstract class SharedStealthSystem : EntitySystem
return Math.Clamp(component.LastVisibility + ev.FlatModifier, component.MinVisibility, component.MaxVisibility);
}
private void OnThrow(EntityUid uid, BreakStealthOnAttackComponent stealth, BeforeThrowEvent args) => BreakStealth(uid);
private void OnAttack(EntityUid uid, BreakStealthOnAttackComponent stealth, AttackAttemptEvent args) => BreakStealth(uid);
private void OnShoot(EntityUid uid, BreakStealthOnAttackComponent stealth, ShotAttemptedEvent args) => BreakStealth(uid);
public void BreakStealth(EntityUid uid)
{
if (!TryComp(uid, out StealthComponent? stealth))
return;
BreakStealth(uid, stealth);
}
public void BreakStealth(EntityUid uid, StealthComponent stealth) => ModifyVisibility(uid, stealth.MaxVisibility, stealth);
/// <summary>
/// Used to run through any stealth effecting components on the entity.
/// </summary>

View File

@@ -5,3 +5,6 @@ uplink-mech-teleporter-heavy-desc = Contains a heavily armored Cybersun mech wit
uplink-mech-teleporter-assault-name = Assault Mech teleporter
uplink-mech-teleporter-assault-desc = Contains a lightly armored Cybersun mech with an integrated chainsword, LBX AC 10 "Scattershot", SRM-8 Light Missile Rack and P-X Tesla Cannon.
uplink-hardsuit-cybersun-stealth-name = CSA-91x "Èguǐ" tacsuit
uplink-hardsuit-cybersun-stealth-desc = A rare prototype tacsuit that features metamaterial plating which warps light around it to produce an "Invisibility cloak" effect.

View File

@@ -75,6 +75,8 @@ ent-ClothingHeadHelmetHardsuitCybersun = CSA-80UA helmet
.desc = An incredibly sturdy looking helmet designed for the Guan Yu tacsuit.
ent-ClothingHeadHelmetHardsuitJuggernautReverseEngineered = CSA-80UA helmet
.desc = An incredibly sturdy looking helmet designed for the Guan Yu tacsuit. This one has been painted blue.
ent-ClothingHeadHelmetHardsuitCybersunStealth = CSA-91x helmet
.desc = A moderately protective sealed helmet designed for the èguǐ tacsuit. It features "Cloaking" metamaterials.
ent-ClothingHeadHelmetHardsuitWizard = WZD-84 helmet
.desc = A bizarre, gem-encrusted helmet from unknown origins. It provides some protection to its wearer without restricting their movements.
ent-ClothingHeadHelmetHardsuitLing = organic space helmet

View File

@@ -102,6 +102,9 @@ ent-ClothingOuterHardsuitJuggernaut = CSA-80UA - "Guan Yu" tacsuit
ent-ClothingOuterHardsuitJuggernautReverseEngineered = CSA-80UA - "Guan Yu" tacsuit
.desc = The pride and joy of the Cybersun-Armaments Corporation, named after an ancient Sol' War God. Commonly known throughout the galaxy as a "Juggernaut".
Matching its bulky appearance, it protects against all forms of damage. It feels VERY heavy.
ent-ClothingOuterHardsuitCybersunStealth = CSA-91x "Èguǐ" tacsuit
.desc = A rare prototype tacsuit that features metamaterial plating which warps light around it to produce an "Invisibility cloak" effect.
Unfortunately, it accomplishes this by trading a lot of protections that one would normally expect from a typical tacsuit.
ent-ClothingOuterHardsuitWizard = WZD-84 - "Mana" tacsuit
.desc = A bizarre gem-encrusted hardsuit. Famously used by members of the Wizard Federation in their operations.
Contrary to it's appearance, it can protect its wearer from space and considerable amounts of physical trauma, it feels somewhat light.

View File

@@ -0,0 +1,13 @@
- type: entity
parent: ClothingBackpackDuffelSyndicateBundle
id: ClothingBackpackDuffelSyndicateStealthHardsuitBundle
name: cybersun stealthsuit bundle
description: "An advanced cybersun stealth tacsuit bundle."
components:
- type: StorageFill
contents:
- id: ClothingOuterHardsuitCybersunStealth
- id: ClothingMaskGasSyndicate
- id: ClothingHandsGlovesCombat
- id: DoubleEmergencyOxygenTankFilled
- id: DoubleEmergencyNitrogenTankFilled

View File

@@ -36,3 +36,17 @@
whitelist:
tags:
- NukeOpsUplink
- type: listing
id: UplinkHardsuitCybersunStealth
name: uplink-hardsuit-cybersun-stealth-name
description: uplink-hardsuit-cybersun-stealth-desc
icon: { sprite: /Textures/_Goobstation/Clothing/OuterClothing/Hardsuits/cybersunstealth.rsi, state: icon }
productEntity: ClothingBackpackDuffelSyndicateStealthHardsuitBundle
discountCategory: rareDiscounts
discountDownTo:
Telecrystal: 35
cost:
Telecrystal: 55
categories:
- UplinkWearables

View File

@@ -21,3 +21,32 @@
Slash: 0.9
Piercing: 0.9
Heat: 0.9
# cybersun stealth
- type: entity
parent: ClothingHeadHardsuitWithLightBase
id: ClothingHeadHelmetHardsuitCybersunStealth
suffix: stealth
name: cybersun stealth hardsuit helmet
description: A helmet with plating for stealth operations.
components:
- type: Sprite
sprite: _Goobstation/Clothing/Head/Hardsuits/cybersunstealth.rsi
- type: Clothing
sprite: _Goobstation/Clothing/Head/Hardsuits/cybersunstealth.rsi
- type: PointLight
color: green
- type: PressureProtection
highPressureMultiplier: 0.08
lowPressureMultiplier: 1000
- type: Armor
modifiers:
coefficients:
Blunt: 0.95
Slash: 0.95
Piercing: 0.95
Heat: 0.95
- type: ClothingGrantComponent
component:
- type: Stealth

View File

@@ -29,3 +29,67 @@
clothingPrototype: ClothingHeadHelmetHardsuitBlueshield
- type: StaminaDamageResistance
coefficient: 0.5 # 50%
# cybersun stealth
- type: entity
parent: ClothingOuterHardsuitBase
id: ClothingOuterHardsuitCybersunStealth
suffix: stealth
name: cybersun stealth hardsuit
description: A hardsuit with stealth plating for operations, the shielding doesn't work while you're moving though! Needs the helmet on to finish the stealth field.
components:
- type: Sprite
sprite: _Goobstation/Clothing/OuterClothing/Hardsuits/cybersunstealth.rsi
- type: Item
size: Huge
- type: Clothing
sprite: _Goobstation/Clothing/OuterClothing/Hardsuits/cybersunstealth.rsi
onEquipFunctions:
- !type:TraitAddComponent
components:
- type: BreakStealthOnAttack
onUnequipFunctions:
- !type:TraitRemoveComponent
components:
- type: BreakStealthOnAttack
- type: PressureProtection
highPressureMultiplier: 0.05
lowPressureMultiplier: 1000
- type: ExplosionResistance
damageCoefficient: 0.75
- type: Armor
modifiers:
coefficients:
Blunt: 0.85 # Metamaterials are quite brittle
Slash: 0.75
Piercing: 0.70 # But at least it can have steel plates underneath.
Heat: 0.75
Radiation: 0.85
Caustic: 0.85
- type: ClothingSpeedModifier
walkModifier: 0.8
sprintModifier: 0.85
- type: HeldSpeedModifier
- type: ToggleableClothing
clothingPrototype: ClothingHeadHelmetHardsuitCybersunStealth
- type: Tag
tags:
- Hardsuit
- WhitelistChameleon
- type: ClothingGrantComponent
component:
- type: StealthOnMove
passiveVisibilityRate: -0.65
movementVisibilityRate: 0.575
- type: EmitsSoundOnMove
soundCollection:
collection: FootstepHardsuitLight
params:
volume: -12
maxDistance: 5
rolloffFactor: 1.2
# SIGNIFICANTLY Quieter than a normal hardsuit, but not perfectly stealthy. If you move while people are close enough, they can still hear it.
- type: StaminaDamageResistance
coefficient: 0.85 # 15%. Substantially lower than a normal hardsuit.

View File

@@ -0,0 +1,70 @@
- type: entity
parent: ClothingOuterHardsuitBase
id: ClothingOuterHardsuitSyndieStealthDebug
suffix: DEBUG, DO NOT MAP, stealth
name: syndicate stealth hardsuit
description: A hardsuit with stealth plating for operations, the shielding doesn't work while you're moving though! Needs the helmet on to finish the stealth field.
components:
- type: Sprite
sprite: Clothing/OuterClothing/Hardsuits/syndicate.rsi
- type: Item
size: Huge
- type: Clothing
sprite: Clothing/OuterClothing/Hardsuits/syndicate.rsi
- type: PressureProtection
highPressureMultiplier: 0.05
lowPressureMultiplier: 1000
- type: ExplosionResistance
damageCoefficient: 0.5
- type: Armor
modifiers:
coefficients:
Blunt: 0.65
Slash: 0.65
Piercing: 0.65
Heat: 0.7
Radiation: 0.55
Caustic: 0.7
- type: ClothingSpeedModifier
walkModifier: 0.95
sprintModifier: 0.95
- type: HeldSpeedModifier
- type: ToggleableClothing
clothingPrototype: ClothingHeadHelmetHardsuitSyndieStealthDebug
- type: Tag
tags:
- Hardsuit
- WhitelistChameleon
- type: ClothingGrantComponent
component:
- type: StealthOnMove
passiveVisibilityRate: -0.5
movementVisibilityRate: 0.4
- type: entity
parent: ClothingHeadHardsuitWithLightBase
id: ClothingHeadHelmetHardsuitSyndieStealthDebug
suffix: DEBUG, DO NOT MAP, stealth
name: syndicate stealth hardsuit helmet
description: A helmet with plating for stealth operations.
components:
- type: Sprite
sprite: Clothing/Head/Hardsuits/syndicate.rsi
- type: Clothing
sprite: Clothing/Head/Hardsuits/syndicate.rsi
- type: PointLight
color: green
- type: PressureProtection
highPressureMultiplier: 0.08
lowPressureMultiplier: 1000
- type: Armor
modifiers:
coefficients:
Blunt: 0.9
Slash: 0.9
Piercing: 0.9
Heat: 0.9
- type: ClothingGrantComponent # this is horrible shitcode i have to do because clothinggrantcomponent only works with 1 comp per clothing item
component:
- type: Stealth

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 444 B

View File

@@ -0,0 +1,25 @@
{
"version": 1,
"license": "CC-BY-SA-3.0",
"copyright": "Sprites made by InfinityPandaRed for Goobstation",
"size": {
"x": 32,
"y": 32
},
"states": [
{
"name": "icon"
},
{
"name": "icon-flash"
},
{
"name": "off-equipped-HELMET",
"directions": 4
},
{
"name": "on-equipped-HELMET",
"directions": 4
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 706 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 510 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 551 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 557 B

View File

@@ -0,0 +1,26 @@
{
"version": 1,
"license": "CC-BY-SA-3.0",
"copyright": "made by InfinityPandaRed for goob station",
"size": {
"x": 32,
"y": 32
},
"states": [
{
"name": "icon"
},
{
"name": "equipped-OUTERCLOTHING",
"directions": 4
},
{
"name": "inhand-left",
"directions": 4
},
{
"name": "inhand-right",
"directions": 4
}
]
}