Files
wwdpublic/Content.Server/_Goobstation/Clothing/Systems/PoweredSealableClothingSystem.cs
Eris d6f3265e83 MODsuits (Port From Goob #1242) (#1640)
# Description

Ports MODsuits from Goobstation PR
https://github.com/Goob-Station/Goob-Station/pull/1242. The PR author
has confirmed that he is okay with me doing this.

---

# TODO

- [X] Port in sprites
- [x] Port in YMLs
- [X] Port code
- [x] Port code PATCHES
- [x] Update EE with required fixes

---

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

## Modsuit crafting

https://github.com/user-attachments/assets/8ff03d3a-0fc1-4818-b710-bfc43f0e2a68

## Modsuit sealing

https://github.com/user-attachments/assets/6671459a-7767-499b-8678-062fc1db7134

</p>
</details>

---

# Changelog

🆑
- add: Modsuits have been ported from Goobstation!

---------

Signed-off-by: Eris <erisfiregamer1@gmail.com>
Co-authored-by: DEATHB4DEFEAT <77995199+DEATHB4DEFEAT@users.noreply.github.com>
Co-authored-by: VMSolidus <evilexecutive@gmail.com>

(cherry picked from commit cb06c41fc07275e1f15af916babb44368c0c26c2)
2025-01-29 20:09:26 +03:00

113 lines
4.5 KiB
C#

using Content.Server.Power.EntitySystems;
using Content.Server.PowerCell;
using Content.Shared._Goobstation.Clothing.Components;
using Content.Shared._Goobstation.Clothing.Systems;
using Content.Shared.Alert;
using Content.Shared.Inventory;
using Content.Shared.Movement.Systems;
using Content.Shared.PowerCell;
using Content.Shared.PowerCell.Components;
using Content.Shared.Rounding;
namespace Content.Server._Goobstation.Clothing.Systems;
public sealed partial class PoweredSealableClothingSystem : SharedPoweredSealableClothingSystem
{
[Dependency] private readonly AlertsSystem _alertsSystem = default!;
[Dependency] private readonly PowerCellSystem _powerCellSystem = default!;
[Dependency] private readonly MovementSpeedModifierSystem _movementSpeed = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<SealableClothingRequiresPowerComponent, InventoryRelayedEvent<RefreshMovementSpeedModifiersEvent>>(OnMovementSpeedChange);
SubscribeLocalEvent<SealableClothingRequiresPowerComponent, PowerCellChangedEvent>(OnPowerCellChanged);
SubscribeLocalEvent<SealableClothingRequiresPowerComponent, PowerCellSlotEmptyEvent>(OnPowerCellEmpty);
SubscribeLocalEvent<SealableClothingRequiresPowerComponent, ClothingControlSealCompleteEvent>(OnRequiresPowerSealCompleteEvent);
SubscribeLocalEvent<SealableClothingRequiresPowerComponent, InventoryRelayedEvent<FindInventoryBatteryEvent>>(OnFindInventoryBatteryEvent);
}
private void OnPowerCellChanged(Entity<SealableClothingRequiresPowerComponent> entity, ref PowerCellChangedEvent args)
{
if (!entity.Comp.IsPowered && _powerCellSystem.HasDrawCharge(entity))
{
entity.Comp.IsPowered = true;
Dirty(entity);
ModifySpeed(entity);
}
UpdateClothingPowerAlert(entity);
}
private void OnPowerCellEmpty(Entity<SealableClothingRequiresPowerComponent> entity, ref PowerCellSlotEmptyEvent args)
{
entity.Comp.IsPowered = false;
Dirty(entity);
ModifySpeed(entity);
}
/// Enables or disables power cell draw on seal/unseal complete
private void OnRequiresPowerSealCompleteEvent(Entity<SealableClothingRequiresPowerComponent> entity, ref ClothingControlSealCompleteEvent args)
{
if (!TryComp(entity, out PowerCellDrawComponent? drawComp))
return;
_powerCellSystem.SetDrawEnabled((entity.Owner, drawComp), args.IsSealed);
UpdateClothingPowerAlert(entity);
ModifySpeed(entity);
}
private void OnMovementSpeedChange(Entity<SealableClothingRequiresPowerComponent> entity, ref InventoryRelayedEvent<RefreshMovementSpeedModifiersEvent> args)
{
if (!TryComp(entity, out SealableClothingControlComponent? controlComp))
return;
// If suit is unsealed - don't care about penalty
if (!controlComp.IsCurrentlySealed)
return;
if (!entity.Comp.IsPowered)
args.Args.ModifySpeed(entity.Comp.MovementSpeedPenalty);
}
private void ModifySpeed(EntityUid uid)
{
if (!TryComp(uid, out SealableClothingControlComponent? controlComp) || controlComp.WearerEntity == null)
return;
_movementSpeed.RefreshMovementSpeedModifiers(controlComp.WearerEntity.Value);
}
/// Sets power alert to wearer when clothing is sealed
private void UpdateClothingPowerAlert(Entity<SealableClothingRequiresPowerComponent> entity)
{
var (uid, comp) = entity;
if (!TryComp<SealableClothingControlComponent>(uid, out var controlComp) || controlComp.WearerEntity == null)
return;
if (!_powerCellSystem.TryGetBatteryFromSlot(entity, out var battery) || !controlComp.IsCurrentlySealed)
{
_alertsSystem.ClearAlert(controlComp.WearerEntity.Value, comp.SuitPowerAlert);
return;
}
var severity = ContentHelpers.RoundToLevels(MathF.Max(0f, battery.CurrentCharge), battery.MaxCharge, 6);
_alertsSystem.ShowAlert(controlComp.WearerEntity.Value, comp.SuitPowerAlert, (short) severity);
}
/// Tries to find battery for charger
private void OnFindInventoryBatteryEvent(Entity<SealableClothingRequiresPowerComponent> entity, ref InventoryRelayedEvent<FindInventoryBatteryEvent> args)
{
if (args.Args.FoundBattery != null)
return;
if (_powerCellSystem.TryGetBatteryFromSlot(entity, out var batteryEnt, out var battery))
args.Args.FoundBattery = (batteryEnt.Value, battery);
}
}