Skip to content

Commit

Permalink
Reimplement Part Upgrading (#917)
Browse files Browse the repository at this point in the history
# Description

By extremely popular demand(Both internally, and from our downstreams),
this PR reimplements Part Upgrading. Since some of the systems that this
PR touches were substantially changed since the removal of Parts, I had
to do a lot of very in depth by-hand edits of individual systems.
Shockingly, the only one that really proved any trouble was Cloning
System, so I'm genuinely surprised wizden didn't substantially touch any
of these codes since removing parts..

# Changelog

:cl:
- add: Part Upgrading has returned!

---------

Signed-off-by: VMSolidus <[email protected]>
Co-authored-by: DEATHB4DEFEAT <[email protected]>
  • Loading branch information
VMSolidus and DEATHB4DEFEAT committed Sep 21, 2024
1 parent 0e187aa commit 49d128c
Show file tree
Hide file tree
Showing 86 changed files with 1,704 additions and 220 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,3 @@ public async Task ChangeMachine()
AssertPrototype("Autolathe");
}
}

Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

namespace Content.IntegrationTests.Tests.Interaction;

// This partial class contains various constant prototype IDs common to interaction tests.
Expand Down Expand Up @@ -27,8 +28,6 @@ public abstract partial class InteractionTest

// Parts
protected const string Bin1 = "MatterBinStockPart";
protected const string Cap1 = "CapacitorStockPart";
protected const string Manipulator1 = "MicroManipulatorStockPart";
protected const string Battery1 = "PowerCellSmall";
protected const string Battery4 = "PowerCellHyper";
}

7 changes: 7 additions & 0 deletions Content.Server/Anomaly/AnomalySystem.Vessel.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Content.Server.Anomaly.Components;
using Content.Server.Construction;
using Content.Server.Power.EntitySystems;
using Content.Shared.Anomaly;
using Content.Shared.Anomaly.Components;
Expand All @@ -20,6 +21,7 @@ private void InitializeVessel()
{
SubscribeLocalEvent<AnomalyVesselComponent, ComponentShutdown>(OnVesselShutdown);
SubscribeLocalEvent<AnomalyVesselComponent, MapInitEvent>(OnVesselMapInit);
SubscribeLocalEvent<AnomalyVesselComponent, UpgradeExamineEvent>(OnUpgradeExamine);
SubscribeLocalEvent<AnomalyVesselComponent, InteractUsingEvent>(OnVesselInteractUsing);
SubscribeLocalEvent<AnomalyVesselComponent, ExaminedEvent>(OnExamined);
SubscribeLocalEvent<AnomalyVesselComponent, ResearchServerGetPointsPerSecondEvent>(OnVesselGetPointsPerSecond);
Expand Down Expand Up @@ -65,6 +67,11 @@ private void OnVesselMapInit(EntityUid uid, AnomalyVesselComponent component, Ma
UpdateVesselAppearance(uid, component);
}

private void OnUpgradeExamine(EntityUid uid, AnomalyVesselComponent component, UpgradeExamineEvent args)
{
args.AddPercentageUpgrade("anomaly-vessel-component-upgrade-output", component.PointMultiplier);
}

private void OnVesselInteractUsing(EntityUid uid, AnomalyVesselComponent component, InteractUsingEvent args)
{
if (component.Anomaly != null ||
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
using Content.Shared.Atmos;
using Content.Shared.Construction.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;

namespace Content.Server.Atmos.Piping.Binary.Components
{
[RegisterComponent]
public sealed partial class GasRecyclerComponent : Component
{
[ViewVariables(VVAccess.ReadOnly)]
[DataField("reacting")]
public Boolean Reacting { get; set; } = false;

Expand All @@ -17,10 +18,28 @@ public sealed partial class GasRecyclerComponent : Component
[DataField("outlet")]
public string OutletName { get; set; } = "outlet";

[DataField, ViewVariables(VVAccess.ReadWrite)]
[DataField]
public float MinTemp = 300 + Atmospherics.T0C;

[DataField, ViewVariables(VVAccess.ReadWrite)]
[DataField]
public float BaseMinTemp = 300 + Atmospherics.T0C;

[DataField(customTypeSerializer: typeof(PrototypeIdSerializer<MachinePartPrototype>))]
public string MachinePartMinTemp = "Capacitor";

[DataField]
public float PartRatingMinTempMultiplier = 0.95f;

[ViewVariables(VVAccess.ReadWrite)]
public float MinPressure = 30 * Atmospherics.OneAtmosphere;

[DataField]
public float BaseMinPressure = 30 * Atmospherics.OneAtmosphere;

[DataField(customTypeSerializer: typeof(PrototypeIdSerializer<MachinePartPrototype>))]
public string MachinePartMinPressure = "Manipulator";

[DataField]
public float PartRatingMinPressureMultiplier = 0.8f;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Content.Server.Atmos.EntitySystems;
using Content.Server.Atmos.Piping.Binary.Components;
using Content.Server.Atmos.Piping.Components;
using Content.Server.Construction;
using Content.Server.NodeContainer;
using Content.Server.NodeContainer.EntitySystems;
using Content.Server.NodeContainer.Nodes;
Expand Down Expand Up @@ -28,6 +29,8 @@ public override void Initialize()
SubscribeLocalEvent<GasRecyclerComponent, AtmosDeviceUpdateEvent>(OnUpdate);
SubscribeLocalEvent<GasRecyclerComponent, AtmosDeviceDisabledEvent>(OnDisabled);
SubscribeLocalEvent<GasRecyclerComponent, ExaminedEvent>(OnExamined);
SubscribeLocalEvent<GasRecyclerComponent, RefreshPartsEvent>(OnRefreshParts);
SubscribeLocalEvent<GasRecyclerComponent, UpgradeExamineEvent>(OnUpgradeExamine);
}

private void OnEnabled(EntityUid uid, GasRecyclerComponent comp, ref AtmosDeviceEnabledEvent args)
Expand Down Expand Up @@ -116,5 +119,20 @@ private void UpdateAppearance(EntityUid uid, GasRecyclerComponent? comp = null)

_appearance.SetData(uid, PumpVisuals.Enabled, comp.Reacting);
}

private void OnRefreshParts(EntityUid uid, GasRecyclerComponent component, RefreshPartsEvent args)
{
var ratingTemp = args.PartRatings[component.MachinePartMinTemp];
var ratingPressure = args.PartRatings[component.MachinePartMinPressure];

component.MinTemp = component.BaseMinTemp * MathF.Pow(component.PartRatingMinTempMultiplier, ratingTemp - 1);
component.MinPressure = component.BaseMinPressure * MathF.Pow(component.PartRatingMinPressureMultiplier, ratingPressure - 1);
}

private void OnUpgradeExamine(EntityUid uid, GasRecyclerComponent component, UpgradeExamineEvent args)
{
args.AddPercentageUpgrade("gas-recycler-upgrade-min-temp", component.MinTemp / component.BaseMinTemp);
args.AddPercentageUpgrade("gas-recycler-upgrade-min-pressure", component.MinPressure / component.BaseMinPressure);
}
}
}
46 changes: 43 additions & 3 deletions Content.Server/Atmos/Portable/PortableScrubberComponent.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using Content.Shared.Atmos;
using Content.Shared.Construction.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;

namespace Content.Server.Atmos.Portable
{
Expand Down Expand Up @@ -37,13 +39,51 @@ public sealed partial class PortableScrubberComponent : Component
/// <summary>
/// Maximum internal pressure before it refuses to take more.
/// </summary>
[DataField, ViewVariables(VVAccess.ReadWrite)]
[DataField]
public float MaxPressure = 2500;

/// <summary>
/// The speed at which gas is scrubbed from the environment.
/// The base amount of maximum internal pressure
/// </summary>
[DataField, ViewVariables(VVAccess.ReadWrite)]
[DataField]
public float BaseMaxPressure = 2500;

/// <summary>
/// The machine part that modifies the maximum internal pressure
/// </summary>
[DataField(customTypeSerializer: typeof(PrototypeIdSerializer<MachinePartPrototype>))]
public string MachinePartMaxPressure = "MatterBin";

/// <summary>
/// How much the <see cref="MachinePartMaxPressure"/> will affect the pressure.
/// The value will be multiplied by this amount for each increasing part tier.
/// </summary>
[DataField]
public float PartRatingMaxPressureModifier = 1.5f;

/// <summary>
/// The speed at which gas is scrubbed from the environment.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
public float TransferRate = 800;

/// <summary>
/// The base speed at which gas is scrubbed from the environment.
/// </summary>
[DataField]
public float BaseTransferRate = 800;

/// <summary>
/// The machine part which modifies the speed of <see cref="TransferRate"/>
/// </summary>
[DataField(customTypeSerializer: typeof(PrototypeIdSerializer<MachinePartPrototype>))]
public string MachinePartTransferRate = "Manipulator";

/// <summary>
/// How much the <see cref="MachinePartTransferRate"/> will modify the rate.
/// The value will be multiplied by this amount for each increasing part tier.
/// </summary>
[DataField]
public float PartRatingTransferRateModifier = 1.4f;
}
}
18 changes: 18 additions & 0 deletions Content.Server/Atmos/Portable/PortableScrubberSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using Content.Server.NodeContainer.NodeGroups;
using Content.Server.Audio;
using Content.Server.Administration.Logs;
using Content.Server.Construction;
using Content.Server.NodeContainer.EntitySystems;
using Content.Shared.Database;

Expand All @@ -38,6 +39,8 @@ public override void Initialize()
SubscribeLocalEvent<PortableScrubberComponent, ExaminedEvent>(OnExamined);
SubscribeLocalEvent<PortableScrubberComponent, DestructionEventArgs>(OnDestroyed);
SubscribeLocalEvent<PortableScrubberComponent, GasAnalyzerScanEvent>(OnScrubberAnalyzed);
SubscribeLocalEvent<PortableScrubberComponent, RefreshPartsEvent>(OnRefreshParts);
SubscribeLocalEvent<PortableScrubberComponent, UpgradeExamineEvent>(OnUpgradeExamine);
}

private bool IsFull(PortableScrubberComponent component)
Expand Down Expand Up @@ -156,5 +159,20 @@ private void OnScrubberAnalyzed(EntityUid uid, PortableScrubberComponent compone
if (_nodeContainer.TryGetNode(uid, component.PortName, out PipeNode? port))
args.GasMixtures.Add(component.PortName, port.Air);
}

private void OnRefreshParts(EntityUid uid, PortableScrubberComponent component, RefreshPartsEvent args)
{
var pressureRating = args.PartRatings[component.MachinePartMaxPressure];
var transferRating = args.PartRatings[component.MachinePartTransferRate];

component.MaxPressure = component.BaseMaxPressure * MathF.Pow(component.PartRatingMaxPressureModifier, pressureRating - 1);
component.TransferRate = component.BaseTransferRate * MathF.Pow(component.PartRatingTransferRateModifier, transferRating - 1);
}

private void OnUpgradeExamine(EntityUid uid, PortableScrubberComponent component, UpgradeExamineEvent args)
{
args.AddPercentageUpgrade("portable-scrubber-component-upgrade-max-pressure", component.MaxPressure / component.BaseMaxPressure);
args.AddPercentageUpgrade("portable-scrubber-component-upgrade-transfer-rate", component.TransferRate / component.BaseTransferRate);
}
}
}
19 changes: 18 additions & 1 deletion Content.Server/Bed/BedSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@
using Content.Server.Bed.Components;
using Content.Server.Bed.Sleep;
using Content.Server.Body.Systems;
using Content.Server.Construction;
using Content.Server.Power.Components;
using Content.Server.Power.EntitySystems;
using Content.Shared.Bed;
using Content.Shared.Bed.Sleep;
using Content.Shared.Body.Components;
using Content.Shared.Buckle.Components;
using Content.Shared.Damage;
using Content.Shared.Emag.Components;
using Content.Shared.Emag.Systems;
using Content.Shared.Mobs.Systems;
using Robust.Shared.Timing;
Expand All @@ -32,6 +34,8 @@ public override void Initialize()
SubscribeLocalEvent<StasisBedComponent, BuckleChangeEvent>(OnBuckleChange);
SubscribeLocalEvent<StasisBedComponent, PowerChangedEvent>(OnPowerChanged);
SubscribeLocalEvent<StasisBedComponent, GotEmaggedEvent>(OnEmagged);
SubscribeLocalEvent<StasisBedComponent, RefreshPartsEvent>(OnRefreshParts);
SubscribeLocalEvent<StasisBedComponent, UpgradeExamineEvent>(OnUpgradeExamine);
}

private void ManageUpdateList(EntityUid uid, HealOnBuckleComponent component, ref BuckleChangeEvent args)
Expand Down Expand Up @@ -66,7 +70,7 @@ public override void Update(float frameTime)

foreach (var healedEntity in strapComponent.BuckledEntities)
{
if (_mobStateSystem.IsDead(healedEntity)
if (_mobStateSystem.IsDead(healedEntity)
|| HasComp<SiliconComponent>(healedEntity))
continue;

Expand Down Expand Up @@ -126,5 +130,18 @@ private void UpdateMetabolisms(EntityUid uid, StasisBedComponent component, bool
RaiseLocalEvent(buckledEntity, ref metabolicEvent);
}
}

private void OnRefreshParts(EntityUid uid, StasisBedComponent component, RefreshPartsEvent args)
{
var metabolismRating = args.PartRatings[component.MachinePartMetabolismModifier];
component.Multiplier = component.BaseMultiplier * metabolismRating; // Linear scaling so it's not OP
if (HasComp<EmaggedComponent>(uid))
component.Multiplier = 1f / component.Multiplier;
}

private void OnUpgradeExamine(EntityUid uid, StasisBedComponent component, UpgradeExamineEvent args)
{
args.AddPercentageUpgrade("stasis-bed-component-upgrade-stasis", component.Multiplier / component.BaseMultiplier);
}
}
}
11 changes: 10 additions & 1 deletion Content.Server/Bed/Components/StasisBedComponent.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
using Content.Shared.Construction.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;

namespace Content.Server.Bed.Components
{
[RegisterComponent]
public sealed partial class StasisBedComponent : Component
{
[DataField]
public float BaseMultiplier = 10f;

/// <summary>
/// What the metabolic update rate will be multiplied by (higher = slower metabolism)
/// What the metabolic update rate will be multiplied by (higher = slower metabolism)
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
public float Multiplier = 10f;

[DataField(customTypeSerializer: typeof(PrototypeIdSerializer<MachinePartPrototype>))]
public string MachinePartMetabolismModifier = "Capacitor";
}
}
30 changes: 26 additions & 4 deletions Content.Server/Botany/Components/SeedExtractorComponent.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
using Content.Server.Botany.Systems;
using Content.Server.Construction;
using Content.Shared.Construction.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;

namespace Content.Server.Botany.Components;

Expand All @@ -7,14 +10,33 @@ namespace Content.Server.Botany.Components;
public sealed partial class SeedExtractorComponent : Component
{
/// <summary>
/// The minimum amount of seed packets dropped.
/// The minimum amount of seed packets dropped with no machine upgrades.
/// </summary>
[DataField("baseMinSeeds"), ViewVariables(VVAccess.ReadWrite)]
[DataField]
public int BaseMinSeeds = 1;

/// <summary>
/// The maximum amount of seed packets dropped.
/// The maximum amount of seed packets dropped with no machine upgrades.
/// </summary>
[DataField("baseMaxSeeds"), ViewVariables(VVAccess.ReadWrite)]
[DataField]
public int BaseMaxSeeds = 3;

/// <summary>
/// Modifier to the amount of seeds outputted, set on <see cref="RefreshPartsEvent"/>.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
public float SeedAmountMultiplier;

/// <summary>
/// Machine part whose rating modifies the amount of seed packets dropped.
/// </summary>
[DataField(customTypeSerializer: typeof(PrototypeIdSerializer<MachinePartPrototype>))]
public string MachinePartSeedAmount = "Manipulator";

/// <summary>
/// How much the machine part quality affects the amount of seeds outputted.
/// Going up a tier will multiply the seed output by this amount.
/// </summary>
[DataField]
public float PartRatingSeedAmountMultiplier = 1.5f;
}
Loading

0 comments on commit 49d128c

Please sign in to comment.