From 3ab98e320a5908951b6217cafb691573fb7347dc Mon Sep 17 00:00:00 2001 From: Nemanja <98561806+EmoGarbage404@users.noreply.github.com> Date: Sun, 30 Oct 2022 03:12:11 -0400 Subject: [PATCH] lathe machine upgrading (#12032) --- Content.Client/Lathe/UI/LatheMenu.xaml.cs | 7 ++-- .../Components/LatheProducingComponent.cs | 10 ++++- Content.Server/Lathe/LatheSystem.cs | 27 ++++++++++--- Content.Shared/Lathe/LatheComponent.cs | 38 +++++++++++++++++++ Content.Shared/Lathe/SharedLatheSystem.cs | 35 ++++++++++++++++- .../Circuitboards/Machine/production.yml | 3 +- .../Entities/Structures/Machines/lathe.yml | 1 + 7 files changed, 107 insertions(+), 14 deletions(-) diff --git a/Content.Client/Lathe/UI/LatheMenu.xaml.cs b/Content.Client/Lathe/UI/LatheMenu.xaml.cs index 5a68494e1f..c5e99e1cb7 100644 --- a/Content.Client/Lathe/UI/LatheMenu.xaml.cs +++ b/Content.Client/Lathe/UI/LatheMenu.xaml.cs @@ -25,7 +25,6 @@ public sealed partial class LatheMenu : DefaultWindow public event Action? RecipeQueueAction; public List Recipes = new(); - private List _oldRecipesToShow = new(); public LatheMenu(LatheBoundUserInterface owner) { @@ -85,6 +84,9 @@ public sealed partial class LatheMenu : DefaultWindow /// public void PopulateRecipes(EntityUid lathe) { + if (!_entityManager.TryGetComponent(lathe, out var component)) + return; + var recipesToShow = new List(); foreach (var recipe in Recipes) { @@ -106,7 +108,6 @@ public sealed partial class LatheMenu : DefaultWindow quantity = 1; RecipeList.Children.Clear(); - _oldRecipesToShow = recipesToShow; foreach (var prototype in recipesToShow) { StringBuilder sb = new(); @@ -121,7 +122,7 @@ public sealed partial class LatheMenu : DefaultWindow else sb.Append('\n'); - sb.Append(amount); + sb.Append((int) (amount * component.MaterialUseMultiplier)); sb.Append(' '); sb.Append(proto.Name); } diff --git a/Content.Server/Lathe/Components/LatheProducingComponent.cs b/Content.Server/Lathe/Components/LatheProducingComponent.cs index bd646e49da..e991dc4248 100644 --- a/Content.Server/Lathe/Components/LatheProducingComponent.cs +++ b/Content.Server/Lathe/Components/LatheProducingComponent.cs @@ -7,9 +7,15 @@ namespace Content.Server.Lathe.Components; public sealed class LatheProducingComponent : Component { /// - /// How much production time has passed, in seconds. + /// The time at which production began /// [ViewVariables(VVAccess.ReadWrite)] - public float AccumulatedTime; + public TimeSpan StartTime; + + /// + /// How long it takes to produce the recipe. + /// + [ViewVariables(VVAccess.ReadWrite)] + public TimeSpan ProductionLength; } diff --git a/Content.Server/Lathe/LatheSystem.cs b/Content.Server/Lathe/LatheSystem.cs index bab1165098..3eff78ca14 100644 --- a/Content.Server/Lathe/LatheSystem.cs +++ b/Content.Server/Lathe/LatheSystem.cs @@ -10,17 +10,20 @@ using Robust.Server.GameObjects; using Robust.Shared.Prototypes; using JetBrains.Annotations; using System.Linq; +using Content.Server.Construction; using Content.Server.Materials; using Content.Server.Power.Components; using Content.Server.Power.EntitySystems; using Content.Server.UserInterface; using Robust.Server.Player; +using Robust.Shared.Timing; namespace Content.Server.Lathe { [UsedImplicitly] public sealed class LatheSystem : SharedLatheSystem { + [Dependency] private readonly IGameTiming _timing = default!; [Dependency] private readonly IPrototypeManager _proto = default!; [Dependency] private readonly SharedAppearanceSystem _appearance = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; @@ -35,6 +38,7 @@ namespace Content.Server.Lathe SubscribeLocalEvent(OnGetWhitelist); SubscribeLocalEvent(OnMapInit); SubscribeLocalEvent(OnPowerChanged); + SubscribeLocalEvent(OnPartsRefresh); SubscribeLocalEvent(OnLatheQueueRecipeMessage); SubscribeLocalEvent(OnLatheSyncRequestMessage); @@ -65,9 +69,7 @@ namespace Content.Server.Lathe if (lathe.CurrentRecipe == null) continue; - comp.AccumulatedTime += frameTime; - - if (comp.AccumulatedTime >= (float) lathe.CurrentRecipe.CompleteTime.TotalSeconds) + if ( _timing.CurTime - comp.StartTime >= comp.ProductionLength) FinishProducing(comp.Owner, lathe); } } @@ -132,7 +134,7 @@ namespace Content.Server.Lathe foreach (var (mat, amount) in recipe.RequiredMaterials) { - _materialStorage.TryChangeMaterialAmount(uid, mat, -amount); + _materialStorage.TryChangeMaterialAmount(uid, mat, (int) (-amount * component.MaterialUseMultiplier)); } component.Queue.Add(recipe); @@ -149,7 +151,9 @@ namespace Content.Server.Lathe var recipe = component.Queue.First(); component.Queue.RemoveAt(0); - EnsureComp(uid); + var lathe = EnsureComp(uid); + lathe.StartTime = _timing.CurTime; + lathe.ProductionLength = recipe.CompleteTime * component.TimeMultiplier; component.CurrentRecipe = recipe; _audio.PlayPvs(component.ProducingSound, component.Owner); @@ -166,7 +170,7 @@ namespace Content.Server.Lathe if (comp.CurrentRecipe != null) Spawn(comp.CurrentRecipe.Result, Transform(uid).Coordinates); comp.CurrentRecipe = null; - prodComp.AccumulatedTime = 0; + prodComp.StartTime = _timing.CurTime; if (!TryStartProducing(uid, comp)) { @@ -257,6 +261,17 @@ namespace Content.Server.Lathe } } + private void OnPartsRefresh(EntityUid uid, LatheComponent component, RefreshPartsEvent args) + { + var printTimeRating = args.PartRatings[component.MachinePartPrintTime]; + var materialUseRating = args.PartRatings[component.MachinePartMaterialUse]; + + component.TimeMultiplier = MathF.Pow(component.PartRatingPrintTimeMultiplier, printTimeRating - 1); + component.MaterialUseMultiplier = MathF.Pow(component.PartRatingMaterialUseMultiplier, materialUseRating - 1); + Dirty(component); + } + + protected override bool HasRecipe(EntityUid uid, LatheRecipePrototype recipe, LatheComponent component) { return GetAvailableRecipes(component).Contains(recipe.ID); diff --git a/Content.Shared/Lathe/LatheComponent.cs b/Content.Shared/Lathe/LatheComponent.cs index 0b070dc0b8..0c3fb5c69f 100644 --- a/Content.Shared/Lathe/LatheComponent.cs +++ b/Content.Shared/Lathe/LatheComponent.cs @@ -1,6 +1,8 @@ +using Content.Shared.Construction.Prototypes; using Content.Shared.Research.Prototypes; using Robust.Shared.Audio; using Robust.Shared.GameStates; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List; namespace Content.Shared.Lathe @@ -56,7 +58,43 @@ namespace Content.Shared.Lathe [ViewVariables] public LatheRecipePrototype? CurrentRecipe; + #region MachineUpgrading + /// + /// A modifier that changes how long it takes to print a recipe + /// + [ViewVariables(VVAccess.ReadWrite)] + public float TimeMultiplier = 1; + /// + /// The machine part that reduces how long it takes to print a recipe. + /// + [DataField("machinePartPrintSpeed", customTypeSerializer: typeof(PrototypeIdSerializer))] + public string MachinePartPrintTime = "Manipulator"; + + /// + /// The value that is used to calculate the modified + /// + [DataField("partRatingPrintTimeMultiplier")] + public float PartRatingPrintTimeMultiplier = 0.5f; + + /// + /// A modifier that changes how much of a material is needed to print a recipe + /// + [ViewVariables(VVAccess.ReadWrite)] + public float MaterialUseMultiplier = 1; + + /// + /// The machine part that reduces how much material it takes to print a recipe. + /// + [DataField("machinePartMaterialUse", customTypeSerializer: typeof(PrototypeIdSerializer))] + public string MachinePartMaterialUse = "MatterBin"; + + /// + /// The value that is used to calculate the modifier + /// + [DataField("partRatingMaterialUseMultiplier")] + public float PartRatingMaterialUseMultiplier = 0.75f; + #endregion } public sealed class LatheGetRecipesEvent : EntityEventArgs diff --git a/Content.Shared/Lathe/SharedLatheSystem.cs b/Content.Shared/Lathe/SharedLatheSystem.cs index 3814299218..f009570fea 100644 --- a/Content.Shared/Lathe/SharedLatheSystem.cs +++ b/Content.Shared/Lathe/SharedLatheSystem.cs @@ -1,7 +1,9 @@ using Content.Shared.Materials; using Content.Shared.Research.Prototypes; using JetBrains.Annotations; +using Robust.Shared.GameStates; using Robust.Shared.Prototypes; +using Robust.Shared.Serialization; namespace Content.Shared.Lathe; @@ -13,6 +15,26 @@ public abstract class SharedLatheSystem : EntitySystem [Dependency] private readonly IPrototypeManager _proto = default!; [Dependency] private readonly SharedMaterialStorageSystem _materialStorage = default!; + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnGetState); + SubscribeLocalEvent(OnHandleState); + } + + private void OnGetState(EntityUid uid, LatheComponent component, ref ComponentGetState args) + { + args.State = new LatheComponentState(component.MaterialUseMultiplier); + } + + private void OnHandleState(EntityUid uid, LatheComponent component, ref ComponentHandleState args) + { + if (args.Current is not LatheComponentState state) + return; + component.MaterialUseMultiplier = state.MaterialUseMultiplier; + } + [PublicAPI] public bool CanProduce(EntityUid uid, string recipe, int amount = 1, LatheComponent? component = null) { @@ -28,7 +50,7 @@ public abstract class SharedLatheSystem : EntitySystem foreach (var (material, needed) in recipe.RequiredMaterials) { - if (_materialStorage.GetMaterialAmount(component.Owner, material) < (amount * needed)) + if (_materialStorage.GetMaterialAmount(component.Owner, material) < amount * needed * component.MaterialUseMultiplier) return false; } return true; @@ -36,3 +58,14 @@ public abstract class SharedLatheSystem : EntitySystem protected abstract bool HasRecipe(EntityUid uid, LatheRecipePrototype recipe, LatheComponent component); } + +[Serializable, NetSerializable] +public sealed class LatheComponentState : ComponentState +{ + public float MaterialUseMultiplier; + + public LatheComponentState(float materialUseMultiplier) + { + MaterialUseMultiplier = materialUseMultiplier; + } +} diff --git a/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml b/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml index c90b978dbd..e2297d924e 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml @@ -94,8 +94,7 @@ prototype: UniformPrinter requirements: MatterBin: 1 - Manipulator: 1 - Laser: 1 + Laser: 2 - type: entity id: VaccinatorMachineCircuitboard diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml index 087c7ed100..173d612841 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml @@ -377,6 +377,7 @@ - type: Lathe idleState: icon runningState: icon + machinePartPrintSpeed: Laser dynamicRecipes: - HandheldHealthAnalyzer - ClothingHandsGlovesLatex