diff --git a/Content.Server/Lathe/LatheSystem.cs b/Content.Server/Lathe/LatheSystem.cs index 2b3b810fba..7448a9b84d 100644 --- a/Content.Server/Lathe/LatheSystem.cs +++ b/Content.Server/Lathe/LatheSystem.cs @@ -14,6 +14,7 @@ using Content.Shared.Database; using Content.Shared.Emag.Components; using Content.Shared.Lathe; using Content.Shared.Materials; +using Content.Shared.ReagentSpeed; using Content.Shared.Research.Components; using Content.Shared.Research.Prototypes; using JetBrains.Annotations; @@ -35,6 +36,7 @@ namespace Content.Server.Lathe [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly UserInterfaceSystem _uiSys = default!; [Dependency] private readonly MaterialStorageSystem _materialStorage = default!; + [Dependency] private readonly ReagentSpeedSystem _reagentSpeed = default!; [Dependency] private readonly StackSystem _stack = default!; [Dependency] private readonly TransformSystem _transform = default!; @@ -186,9 +188,11 @@ namespace Content.Server.Lathe var recipe = component.Queue.First(); component.Queue.RemoveAt(0); + var time = _reagentSpeed.ApplySpeed(uid, recipe.CompleteTime); + var lathe = EnsureComp(uid); lathe.StartTime = _timing.CurTime; - lathe.ProductionLength = recipe.CompleteTime * component.TimeMultiplier; + lathe.ProductionLength = time * component.TimeMultiplier; component.CurrentRecipe = recipe; var ev = new LatheStartPrintingEvent(recipe); diff --git a/Content.Shared/ReagentSpeed/ReagentSpeedComponent.cs b/Content.Shared/ReagentSpeed/ReagentSpeedComponent.cs new file mode 100644 index 0000000000..d233cad2a0 --- /dev/null +++ b/Content.Shared/ReagentSpeed/ReagentSpeedComponent.cs @@ -0,0 +1,34 @@ +using Content.Shared.Chemistry.Reagent; +using Content.Shared.FixedPoint; +using Robust.Shared.Prototypes; + +namespace Content.Shared.ReagentSpeed; + +/// +/// Makes a device work faster by consuming reagents on each use. +/// Other systems must use for this to do anything. +/// +[RegisterComponent, Access(typeof(ReagentSpeedSystem))] +public sealed partial class ReagentSpeedComponent : Component +{ + /// + /// Solution that will be checked. + /// Anything that isn't in Modifiers is left alone. + /// + [DataField(required: true)] + public string Solution = string.Empty; + + /// + /// How much reagent from the solution to use up for each use. + /// This is per-modifier-reagent and not shared between them. + /// + [DataField] + public FixedPoint2 Cost = 5; + + /// + /// Reagents and how much they modify speed at full purity. + /// Small number means faster large number means slower. + /// + [DataField(required: true)] + public Dictionary, float> Modifiers = new(); +} diff --git a/Content.Shared/ReagentSpeed/ReagentSpeedSystem.cs b/Content.Shared/ReagentSpeed/ReagentSpeedSystem.cs new file mode 100644 index 0000000000..8561c7b12a --- /dev/null +++ b/Content.Shared/ReagentSpeed/ReagentSpeedSystem.cs @@ -0,0 +1,33 @@ +using Content.Shared.Chemistry.EntitySystems; + +namespace Content.Shared.ReagentSpeed; + +public sealed class ReagentSpeedSystem : EntitySystem +{ + [Dependency] private readonly SharedSolutionContainerSystem _solution = default!; + + /// + /// Consumes reagents and modifies the duration. + /// This can be production time firing delay etc. + /// + public TimeSpan ApplySpeed(Entity ent, TimeSpan time) + { + if (!Resolve(ent, ref ent.Comp, false)) + return time; + + if (!_solution.TryGetSolution(ent.Owner, ent.Comp.Solution, out _, out var solution)) + return time; + + foreach (var (reagent, fullModifier) in ent.Comp.Modifiers) + { + var used = solution.RemoveReagent(reagent, ent.Comp.Cost); + var efficiency = (used / ent.Comp.Cost).Float(); + // scale the speed modifier so microdosing has less effect + var reduction = (1f - fullModifier) * efficiency; + var modifier = 1f - reduction; + time *= modifier; + } + + return time; + } +} diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml index e4ae1c42e8..294a974184 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml @@ -50,9 +50,44 @@ - type: ResearchClient - type: TechnologyDatabase +# a lathe that can be sped up with space lube / slowed down with glue +- type: entity + abstract: true + parent: BaseLathe + id: BaseLatheLube + components: + - type: ReagentSpeed + solution: lube + modifiers: + SpaceLube: 0.25 + SpaceGlue: 5 + - type: SolutionContainerManager + solutions: + lube: + maxVol: 250 + - type: Spillable + solution: lube + - type: RefillableSolution + solution: lube + - type: ExaminableSolution + solution: lube + +- type: entity + abstract: true + id: BaseHyperlathe + components: + - type: Lathe + materialUseMultiplier: 0.5 + timeMultiplier: 1.5 + - type: LatheHeatProducing + - type: ReagentSpeed + modifiers: + SpaceLube: 0.8 # being faster means less heat so lube needs to be nerfed + SpaceGlue: 5 # no change from normal lathe, overheat!!! + - type: entity id: Autolathe - parent: BaseLathe + parent: BaseLatheLube name: autolathe description: It produces items using metal and glass. components: @@ -215,22 +250,18 @@ - type: entity id: AutolatheHyperConvection - parent: Autolathe + parent: [Autolathe, BaseHyperlathe] name: hyper convection autolathe description: A highly-experimental autolathe that harnesses the power of extreme heat to slowly create objects more cost-effectively. components: - type: Sprite sprite: Structures/Machines/autolathe_hypercon.rsi - - type: Lathe - materialUseMultiplier: 0.5 - timeMultiplier: 1.5 - - type: LatheHeatProducing - type: Machine board: AutolatheHyperConvectionMachineCircuitboard - type: entity id: Protolathe - parent: BaseLathe + parent: BaseLatheLube name: protolathe description: Converts raw materials into useful objects. components: @@ -334,22 +365,18 @@ - type: entity id: ProtolatheHyperConvection - parent: Protolathe + parent: [Protolathe, BaseHyperlathe] name: hyper convection protolathe description: A highly-experimental protolathe that harnesses the power of extreme heat to slowly create objects more cost-effectively. components: - type: Sprite sprite: Structures/Machines/protolathe_hypercon.rsi - - type: Lathe - materialUseMultiplier: 0.5 - timeMultiplier: 1.5 - - type: LatheHeatProducing - type: Machine board: ProtolatheHyperConvectionMachineCircuitboard - type: entity id: CircuitImprinter - parent: BaseLathe + parent: BaseLatheLube name: circuit imprinter description: Prints circuit boards for machines. components: @@ -485,7 +512,7 @@ - type: entity id: ExosuitFabricator - parent: BaseLathe + parent: BaseLatheLube name: exosuit fabricator description: Creates parts for robotics and other mechanical needs components: @@ -643,7 +670,7 @@ - type: entity id: SecurityTechFab - parent: BaseLathe + parent: BaseLatheLube name: security techfab description: Prints equipment for use by security crew. components: @@ -764,7 +791,7 @@ - type: entity id: AmmoTechFab - parent: BaseLathe + parent: BaseLatheLube name: ammo techfab description: Prints the bare minimum of bullets that any budget military or armory could need. Nothing fancy. components: @@ -815,7 +842,7 @@ - type: entity id: MedicalTechFab - parent: BaseLathe + parent: BaseLatheLube name: medical techfab description: Prints equipment for use by the medbay. components: