From 377f473cedf947c170a2946dc86dd99c073fedfe Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Fri, 24 Mar 2023 15:27:55 +1100 Subject: [PATCH] Change pricingsystem a bit (#14470) --- .../Cargo/Systems/PriceGunSystem.cs | 5 +- Content.Server/Cargo/Systems/PricingSystem.cs | 232 +++++++++++++----- .../UserInterface/StatValuesCommand.cs | 3 +- .../VendingMachines/VendingMachineSystem.cs | 3 +- 4 files changed, 172 insertions(+), 71 deletions(-) diff --git a/Content.Server/Cargo/Systems/PriceGunSystem.cs b/Content.Server/Cargo/Systems/PriceGunSystem.cs index 39d836b791..23bded1d42 100644 --- a/Content.Server/Cargo/Systems/PriceGunSystem.cs +++ b/Content.Server/Cargo/Systems/PriceGunSystem.cs @@ -27,7 +27,7 @@ public sealed class PriceGunSystem : EntitySystem private void OnUtilityVerb(EntityUid uid, PriceGunComponent component, GetVerbsEvent args) { - if (!args.CanAccess || !args.CanInteract || args.Target == null) + if (!args.CanAccess || !args.CanInteract) return; if (TryComp(args.Using, out UseDelayComponent? useDelay) && useDelay.ActiveDelay) @@ -50,7 +50,7 @@ public sealed class PriceGunSystem : EntitySystem } private void OnAfterInteract(EntityUid uid, PriceGunComponent component, AfterInteractEvent args) { - if (!args.CanReach || args.Target == null) + if (!args.CanReach || args.Target == null || args.Handled) return; if (TryComp(args.Used, out UseDelayComponent? useDelay) && useDelay.ActiveDelay) @@ -60,5 +60,6 @@ public sealed class PriceGunSystem : EntitySystem _popupSystem.PopupEntity(Loc.GetString("price-gun-pricing-result", ("object", Identity.Entity(args.Target.Value, EntityManager)), ("price", $"{price:F2}")), args.User, args.User); _useDelay.BeginDelay(uid, useDelay); + args.Handled = true; } } diff --git a/Content.Server/Cargo/Systems/PricingSystem.cs b/Content.Server/Cargo/Systems/PricingSystem.cs index 56f8e2ffd1..17ab0bf376 100644 --- a/Content.Server/Cargo/Systems/PricingSystem.cs +++ b/Content.Server/Cargo/Systems/PricingSystem.cs @@ -23,20 +23,17 @@ namespace Content.Server.Cargo.Systems; /// public sealed class PricingSystem : EntitySystem { + [Dependency] private readonly IComponentFactory _factory = default!; [Dependency] private readonly IConsoleHost _consoleHost = default!; [Dependency] private readonly IMapManager _mapManager = default!; - [Dependency] private readonly MobStateSystem _mobStateSystem = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - [Dependency] private readonly BodySystem _bodySystem = default!; + [Dependency] private readonly MobStateSystem _mobStateSystem = default!; /// public override void Initialize() { - SubscribeLocalEvent(CalculateStaticPrice); - SubscribeLocalEvent(CalculateStackPrice); SubscribeLocalEvent(CalculateMobPrice); - SubscribeLocalEvent(CalculateSolutionPrice); _consoleHost.RegisterCommand("appraisegrid", "Calculates the total value of the given grids.", @@ -87,6 +84,7 @@ public sealed class PricingSystem : EntitySystem private void CalculateMobPrice(EntityUid uid, MobPriceComponent component, ref PriceCalculationEvent args) { + // TODO: Estimated pricing. if (args.Handled) return; @@ -106,26 +104,9 @@ public sealed class PricingSystem : EntitySystem args.Price += (component.Price - partPenalty) * (_mobStateSystem.IsAlive(uid, state) ? 1.0 : component.DeathPenalty); } - private void CalculateStackPrice(EntityUid uid, StackPriceComponent component, ref PriceCalculationEvent args) + private double GetSolutionPrice(SolutionContainerManagerComponent component) { - if (args.Handled) - return; - - if (!TryComp(uid, out var stack)) - { - Logger.ErrorS("pricing", $"Tried to get the stack price of {ToPrettyString(uid)}, which has no {nameof(StackComponent)}."); - return; - } - - args.Price += stack.Count * component.Price; - } - - private void CalculateSolutionPrice(EntityUid uid, SolutionContainerManagerComponent component, ref PriceCalculationEvent args) - { - if (args.Handled) - return; - - var price = 0f; + var price = 0.0; foreach (var solution in component.Solutions.Values) { @@ -136,51 +117,43 @@ public sealed class PricingSystem : EntitySystem price += (float) reagent.Quantity * reagentProto.PricePerUnit; } } - args.Price += price; + + return price; } - private void CalculateStaticPrice(EntityUid uid, StaticPriceComponent component, ref PriceCalculationEvent args) + private double GetMaterialPrice(MaterialComponent component) { - if (args.Handled) - return; - - args.Price += component.Price; + double price = 0; + foreach (var (id, quantity) in component.Materials) + { + price += _prototypeManager.Index(id).Price * quantity; + } + return price; } /// /// Get a rough price for an entityprototype. Does not consider contained entities. /// - public double GetEstimatedPrice(EntityPrototype prototype, IComponentFactory? factory = null) + public double GetEstimatedPrice(EntityPrototype prototype) { - IoCManager.Resolve(ref factory); - var price = 0.0; - - if (prototype.Components.TryGetValue(factory.GetComponentName(typeof(StaticPriceComponent)), - out var staticPriceProto)) + var ev = new EstimatedPriceCalculationEvent() { - var staticComp = (StaticPriceComponent) staticPriceProto.Component; + Prototype = prototype, + }; - price += staticComp.Price; - } + RaiseLocalEvent(ref ev); - if (prototype.Components.TryGetValue(factory.GetComponentName(typeof(StackPriceComponent)), out var stackpriceProto) && - prototype.Components.TryGetValue(factory.GetComponentName(typeof(StackComponent)), out var stackProto)) - { - var stackPrice = (StackPriceComponent) stackpriceProto.Component; - var stack = (StackComponent) stackProto.Component; - price += stack.Count * stackPrice.Price; - } + if (ev.Handled) + return ev.Price; - return price; - } + var price = ev.Price; + price += GetMaterialsPrice(prototype); + price += GetSolutionsPrice(prototype); + price += GetStackPrice(prototype); + price += GetStaticPrice(prototype); + + // TODO: Proper container support. - public double GetMaterialPrice(MaterialComponent component) - { - double price = 0; - foreach (var (id, quantity) in component.Materials) - { - price += _prototypeManager.Index(id).Price * quantity; - } return price; } @@ -201,7 +174,31 @@ public sealed class PricingSystem : EntitySystem if (ev.Handled) return ev.Price; + var price = ev.Price; //TODO: Add an OpaqueToAppraisal component or similar for blocking the recursive descent into containers, or preventing material pricing. + // DO NOT FORGET TO UPDATE ESTIMATED PRICING + price += GetMaterialsPrice(uid); + price += GetSolutionsPrice(uid); + price += GetStackPrice(uid); + price += GetStaticPrice(uid); + + if (TryComp(uid, out var containers)) + { + foreach (var container in containers.Containers.Values) + { + foreach (var ent in container.ContainedEntities) + { + price += GetPrice(ent); + } + } + } + + return price; + } + + private double GetMaterialsPrice(EntityUid uid) + { + double price = 0; if (TryComp(uid, out var material) && !HasComp(uid)) { @@ -209,21 +206,109 @@ public sealed class PricingSystem : EntitySystem if (TryComp(uid, out var stack)) matPrice *= stack.Count; - ev.Price += matPrice; + price += matPrice; } - if (TryComp(uid, out var containers)) + return price; + } + + private double GetMaterialsPrice(EntityPrototype prototype) + { + double price = 0; + + if (prototype.Components.TryGetValue(_factory.GetComponentName(typeof(MaterialComponent)), out var materials) && + !prototype.Components.ContainsKey(_factory.GetComponentName(typeof(StackPriceComponent)))) { - foreach (var container in containers.Containers) + var materialsComp = (MaterialComponent) materials.Component; + var matPrice = GetMaterialPrice(materialsComp); + + if (prototype.Components.TryGetValue(_factory.GetComponentName(typeof(StackComponent)), out var stackProto)) { - foreach (var ent in container.Value.ContainedEntities) - { - ev.Price += GetPrice(ent); - } + matPrice *= ((StackComponent) stackProto.Component).Count; } + + price += matPrice; + } + + return price; + } + + private double GetSolutionsPrice(EntityUid uid) + { + var price = 0.0; + + if (TryComp(uid, out var solComp)) + { + price += GetSolutionPrice(solComp); } - return ev.Price; + return price; + } + + private double GetSolutionsPrice(EntityPrototype prototype) + { + var price = 0.0; + + if (prototype.Components.TryGetValue(_factory.GetComponentName(typeof(SolutionContainerManagerComponent)), out var solManager)) + { + var solComp = (SolutionContainerManagerComponent) solManager.Component; + price += GetSolutionPrice(solComp); + } + + return price; + } + + private double GetStackPrice(EntityUid uid) + { + var price = 0.0; + + if (TryComp(uid, out var stackPrice) && + TryComp(uid, out var stack)) + { + price += stack.Count * stackPrice.Price; + } + + return price; + } + + private double GetStackPrice(EntityPrototype prototype) + { + var price = 0.0; + + if (prototype.Components.TryGetValue(_factory.GetComponentName(typeof(StackPriceComponent)), out var stackpriceProto) && + prototype.Components.TryGetValue(_factory.GetComponentName(typeof(StackComponent)), out var stackProto)) + { + var stackPrice = (StackPriceComponent) stackpriceProto.Component; + var stack = (StackComponent) stackProto.Component; + price += stack.Count * stackPrice.Price; + } + + return price; + } + + private double GetStaticPrice(EntityUid uid) + { + var price = 0.0; + + if (TryComp(uid, out var staticPrice)) + { + price += staticPrice.Price; + } + + return price; + } + + private double GetStaticPrice(EntityPrototype prototype) + { + var price = 0.0; + + if (prototype.Components.TryGetValue(_factory.GetComponentName(typeof(StaticPriceComponent)), out var staticProto)) + { + var staticPrice = (StaticPriceComponent) staticProto.Component; + price += staticPrice.Price; + } + + return price; } /// @@ -256,7 +341,7 @@ public sealed class PricingSystem : EntitySystem /// A directed by-ref event fired on an entity when something needs to know it's price. This value is not cached. /// [ByRefEvent] -public struct PriceCalculationEvent +public record struct PriceCalculationEvent() { /// /// The total price of the entity. @@ -267,6 +352,23 @@ public struct PriceCalculationEvent /// Whether this event was already handled. /// public bool Handled = false; +} + +/// +/// Raised broadcast for an entity prototype to determine its estimated price. +/// +[ByRefEvent] +public record struct EstimatedPriceCalculationEvent() +{ + public EntityPrototype Prototype; - public PriceCalculationEvent() { } + /// + /// The total price of the entity. + /// + public double Price = 0; + + /// + /// Whether this event was already handled. + /// + public bool Handled = false; } diff --git a/Content.Server/UserInterface/StatValuesCommand.cs b/Content.Server/UserInterface/StatValuesCommand.cs index 07f5a275e8..7ca39fce26 100644 --- a/Content.Server/UserInterface/StatValuesCommand.cs +++ b/Content.Server/UserInterface/StatValuesCommand.cs @@ -154,7 +154,6 @@ public sealed class StatValuesCommand : IConsoleCommand { var values = new List(); var protoManager = IoCManager.Resolve(); - var factory = IoCManager.Resolve(); var priceSystem = IoCManager.Resolve().GetEntitySystem(); foreach (var proto in protoManager.EnumeratePrototypes()) @@ -167,7 +166,7 @@ public sealed class StatValuesCommand : IConsoleCommand cost += materialPrice * count; } - var sell = priceSystem.GetEstimatedPrice(protoManager.Index(proto.Result), factory); + var sell = priceSystem.GetEstimatedPrice(protoManager.Index(proto.Result)); values.Add(new[] { diff --git a/Content.Server/VendingMachines/VendingMachineSystem.cs b/Content.Server/VendingMachines/VendingMachineSystem.cs index 57355afcce..8072027f78 100644 --- a/Content.Server/VendingMachines/VendingMachineSystem.cs +++ b/Content.Server/VendingMachines/VendingMachineSystem.cs @@ -25,7 +25,6 @@ namespace Content.Server.VendingMachines { public sealed class VendingMachineSystem : SharedVendingMachineSystem { - [Dependency] private readonly IComponentFactory _factory = default!; [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly AccessReaderSystem _accessReader = default!; @@ -71,7 +70,7 @@ namespace Content.Server.VendingMachines continue; } - price += entry.Amount * _pricing.GetEstimatedPrice(proto, _factory); + price += entry.Amount * _pricing.GetEstimatedPrice(proto); } args.Price += price; -- 2.51.2