Port Cybersun Stealth Hardsuit (#4341)

* copy paste ops

* no attribution allowed here no siree

* lgtm

* direction didnt mention caustic get 1984'd

* Update uplink_catalog.yml

* ftlops
This commit is contained in:
KOTOB 2025-10-04 15:51:39 -07:00 committed by GitHub
parent cc8a70c324
commit b4f824f7af
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 293 additions and 0 deletions

View File

@ -0,0 +1,15 @@
using Robust.Shared.Prototypes;
namespace Content.Shared._Goobstation.Clothing.Components
{
[RegisterComponent]
public sealed partial class ClothingGrantComponentComponent : Component
{
[DataField("component", required: true)]
[AlwaysPushInheritance]
public ComponentRegistry Components { get; private set; } = new();
[ViewVariables(VVAccess.ReadWrite)]
public Dictionary<string, bool> Active = new(); // Goobstation
}
}

View File

@ -0,0 +1,14 @@
using Content.Shared.Tag; // harmony
using Robust.Shared.Prototypes; // harmony
namespace Content.Shared._Goobstation.Clothing.Components;
[RegisterComponent]
public sealed partial class ClothingGrantTagComponent : Component
{
[DataField("tag", required: true), ViewVariables(VVAccess.ReadWrite)]
public ProtoId<TagPrototype> Tag = ""; // Harmony - change to protoid
[ViewVariables(VVAccess.ReadWrite)]
public bool IsActive = false;
}

View File

@ -0,0 +1,100 @@
using Content.Shared.Clothing.Components;
using Content.Shared.Inventory.Events;
using Content.Shared.Tag;
using Robust.Shared.Serialization.Manager;
namespace Content.Shared._Goobstation.Clothing.Systems;
public sealed class ClothingGrantingSystem : EntitySystem
{
[Dependency] private readonly IComponentFactory _componentFactory = default!;
[Dependency] private readonly ISerializationManager _serializationManager = default!;
[Dependency] private readonly TagSystem _tagSystem = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<Content.Shared._Goobstation.Clothing.Components.ClothingGrantComponentComponent, GotEquippedEvent>(OnCompEquip);
SubscribeLocalEvent<Content.Shared._Goobstation.Clothing.Components.ClothingGrantComponentComponent, GotUnequippedEvent>(OnCompUnequip);
SubscribeLocalEvent<Content.Shared._Goobstation.Clothing.Components.ClothingGrantTagComponent, GotEquippedEvent>(OnTagEquip);
SubscribeLocalEvent<Content.Shared._Goobstation.Clothing.Components.ClothingGrantTagComponent, GotUnequippedEvent>(OnTagUnequip);
}
private void OnCompEquip(EntityUid uid, Content.Shared._Goobstation.Clothing.Components.ClothingGrantComponentComponent component, GotEquippedEvent args)
{
if (!TryComp<ClothingComponent>(uid, out var clothing)) return;
if (!clothing.Slots.HasFlag(args.SlotFlags)) return;
// Goobstation
//if (component.Components.Count > 1)
//{
// Logger.Error("Although a component registry supports multiple components, we cannot bookkeep more than 1 component for ClothingGrantComponent at this time.");
// return;
//}
foreach (var (name, data) in component.Components)
{
var newComp = (Component) _componentFactory.GetComponent(name);
if (HasComp(args.Equipee, newComp.GetType()))
continue;
newComp.Owner = args.Equipee;
var temp = (object) newComp;
_serializationManager.CopyTo(data.Component, ref temp);
EntityManager.AddComponent(args.Equipee, (Component)temp!);
component.Active[name] = true; // Goobstation
}
}
private void OnCompUnequip(EntityUid uid, Content.Shared._Goobstation.Clothing.Components.ClothingGrantComponentComponent component, GotUnequippedEvent args)
{
// Goobstation
//if (!component.IsActive) return;
foreach (var (name, data) in component.Components)
{
// Goobstation
if (!component.Active.ContainsKey(name) || !component.Active[name])
continue;
var newComp = (Component) _componentFactory.GetComponent(name);
RemComp(args.Equipee, newComp.GetType());
component.Active[name] = false; // Goobstation
}
// Goobstation
//component.IsActive = false;
}
private void OnTagEquip(EntityUid uid, Content.Shared._Goobstation.Clothing.Components.ClothingGrantTagComponent component, GotEquippedEvent args)
{
if (!TryComp<ClothingComponent>(uid, out var clothing))
return;
if (!clothing.Slots.HasFlag(args.SlotFlags))
return;
EnsureComp<TagComponent>(args.Equipee);
_tagSystem.AddTag(args.Equipee, component.Tag);
component.IsActive = true;
}
private void OnTagUnequip(EntityUid uid, Content.Shared._Goobstation.Clothing.Components.ClothingGrantTagComponent component, GotUnequippedEvent args)
{
if (!component.IsActive)
return;
_tagSystem.RemoveTag(args.Equipee, component.Tag);
component.IsActive = false;
}
}

View File

@ -0,0 +1,4 @@
uplink-hardsuit-cybersun-stealth-name = Cybersun Stealth Hardsuit
uplink-hardsuit-cybersun-stealth-desc = Reversed engineered from Spider Clan technology, this hardsuit has stealth plating in it for those special ops. Faster, but less armored than the default hardsuits.
## Harmony - Fixed typo
## DeltaV - no slowdown

View File

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

View File

@ -0,0 +1,19 @@
- 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
cost:
Telecrystal: 15 # Harmony - modified since goob has different TC ratio.
categories:
- UplinkWearables
# begin Harmony change - yeah let's not give this to syndies
# Begin DeltaV additions - we ARE giving this to syndies
#conditions:
#- !type:StoreWhitelistCondition
# whitelist:
# tags:
# - NukeOpsUplink
# End DeltaV additions - we ARE giving this to syndies
# end Harmony change

View File

@ -0,0 +1,31 @@
- type: entity
parent: [ ClothingHeadHardsuitBase, ClothingHeadSuitWithLightBase ] # Harmony - Changed parent to upstream convention
id: ClothingHeadHelmetHardsuitCybersunStealth
# suffix: stealth - Harmony change
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
# Harmony start
- type: StealthOnMove
passiveVisibilityRate: -0.5
movementVisibilityRate: 0.45 # DeltaV - was 0.6
# Harmony end

View File

@ -0,0 +1,46 @@
- type: entity
parent: [ ClothingOuterHardsuitBase, BaseSyndicateContraband ]
id: ClothingOuterHardsuitCybersunStealth
# suffix: stealth - Harmony change
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
- type: PressureProtection
highPressureMultiplier: 0.05
lowPressureMultiplier: 1000
- type: ExplosionResistance
damageCoefficient: 0.8 # DeltaV - was 0.65
- type: Armor
modifiers:
coefficients:
Blunt: 0.7 # DeltaV - was 0.65
Slash: 0.7 # DeltaV - was 0.65
Piercing: 0.6
Heat: 0.8 # DeltaV - was 0.6
Radiation: 0.8 # DeltaV - was 0.55
#Caustic: 0.7 # DeltaV
- type: StaminaResistance # DeltaV
damageCoefficient: 0.7
- type: ClothingSpeedModifier
walkModifier: 1.0 # DeltaV - was 0.8
sprintModifier: 1.0 # DeltaV - was 0.85
- type: HeldSpeedModifier
- type: ToggleableClothing
clothingPrototype: ClothingHeadHelmetHardsuitCybersunStealth
- type: Tag
tags:
- Hardsuit
- WhitelistChameleon
# Harmony start
# - type: ClothingGrantComponent
# component:
# - type: StealthOnMove
# passiveVisibilityRate: -0.5
# movementVisibilityRate: 0.6
# Harmony end

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
}
]
}