diff --git a/Content.Server/Power/Components/UpgradePowerDrawComponent.cs b/Content.Server/Power/Components/UpgradePowerDrawComponent.cs new file mode 100644 index 0000000000..6fbd1e97f1 --- /dev/null +++ b/Content.Server/Power/Components/UpgradePowerDrawComponent.cs @@ -0,0 +1,47 @@ +using Content.Shared.Construction.Prototypes; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; + +namespace Content.Server.Power.Components; + +/// +/// This is used for machines whose power draw +/// can be decreased through machine part upgrades. +/// +[RegisterComponent] +public sealed class UpgradePowerDrawComponent : Component +{ + /// + /// The base power draw of the machine. + /// Prioritizes hv/mv draw over lv draw. + /// Value is initializezd on map init from + /// + [ViewVariables(VVAccess.ReadWrite)] + public float BaseLoad; + + /// + /// The machine part that affects the power draw. + /// + [DataField("machinePartPowerDraw", customTypeSerializer: typeof(PrototypeIdSerializer)), ViewVariables(VVAccess.ReadWrite)] + public string MachinePartPowerDraw = "Capacitor"; + + /// + /// The multiplier used for scaling the power draw. + /// + [DataField("powerDrawMultiplier", required: true), ViewVariables(VVAccess.ReadWrite)] + public float PowerDrawMultiplier = 1f; + + /// + /// What type of scaling is being used? + /// + [DataField("scaling", required: true), ViewVariables(VVAccess.ReadWrite)] + public PowerDrawScalingType Scaling; +} + +/// +/// The different types of scaling that are available +/// +public enum PowerDrawScalingType : byte +{ + Linear, + Exponential +} diff --git a/Content.Server/Power/EntitySystems/UpgradePowerDrawSystem.cs b/Content.Server/Power/EntitySystems/UpgradePowerDrawSystem.cs new file mode 100644 index 0000000000..62aa508059 --- /dev/null +++ b/Content.Server/Power/EntitySystems/UpgradePowerDrawSystem.cs @@ -0,0 +1,49 @@ +using Content.Server.Construction; +using Content.Server.Power.Components; + +namespace Content.Server.Power.EntitySystems; + +/// +/// This handles using upgraded machine parts +/// to modify the power load of a machine. +/// +public sealed class UpgradePowerDrawSystem : EntitySystem +{ + /// + public override void Initialize() + { + SubscribeLocalEvent(OnMapInit); + SubscribeLocalEvent(OnRefreshParts); + } + + private void OnMapInit(EntityUid uid, UpgradePowerDrawComponent component, MapInitEvent args) + { + if (TryComp(uid, out var powa)) + component.BaseLoad = powa.DrawRate; + else if (TryComp(uid, out var powa2)) + component.BaseLoad = powa2.Load; + } + + private void OnRefreshParts(EntityUid uid, UpgradePowerDrawComponent component, RefreshPartsEvent args) + { + var load = component.BaseLoad; + var rating = args.PartRatings[component.MachinePartPowerDraw]; + switch (component.Scaling) + { + case PowerDrawScalingType.Linear: + load += component.PowerDrawMultiplier * (rating - 1); + break; + case PowerDrawScalingType.Exponential: + load *= MathF.Pow(component.PowerDrawMultiplier, rating - 1); + break; + default: + Logger.Error($"invalid power scaling type for {ToPrettyString(uid)}."); + load = 0; + break; + } + if (TryComp(uid, out var powa)) + powa.Load = load; + if (TryComp(uid, out var powa2)) + powa2.DrawRate = load; + } +} diff --git a/Resources/Prototypes/Entities/Structures/Dispensers/chem.yml b/Resources/Prototypes/Entities/Structures/Dispensers/chem.yml index 8cef071ec2..9d36ded332 100644 --- a/Resources/Prototypes/Entities/Structures/Dispensers/chem.yml +++ b/Resources/Prototypes/Entities/Structures/Dispensers/chem.yml @@ -30,3 +30,6 @@ - type: Wires BoardName: "chem_dispenser" LayoutId: chem_dispenser + - type: UpgradePowerDraw + powerDrawMultiplier: 0.75 + scaling: Exponential diff --git a/Resources/Prototypes/Entities/Structures/Machines/stasisbed.yml b/Resources/Prototypes/Entities/Structures/Machines/stasisbed.yml index f39e17cc6a..52d01484dd 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/stasisbed.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/stasisbed.yml @@ -19,6 +19,9 @@ - type: Appearance - type: ApcPowerReceiver powerLoad: 1000 + - type: UpgradePowerDraw + powerDrawMultiplier: 0.75 + scaling: Exponential - type: ExtensionCableReceiver - type: Damageable damageContainer: Inorganic