Change pricingsystem a bit (#14470)

This commit is contained in:
metalgearsloth
2023-03-24 15:27:55 +11:00
committed by GitHub
parent 303506fc38
commit 377f473ced
4 changed files with 177 additions and 76 deletions

View File

@@ -27,7 +27,7 @@ public sealed class PriceGunSystem : EntitySystem
private void OnUtilityVerb(EntityUid uid, PriceGunComponent component, GetVerbsEvent<UtilityVerb> args) private void OnUtilityVerb(EntityUid uid, PriceGunComponent component, GetVerbsEvent<UtilityVerb> args)
{ {
if (!args.CanAccess || !args.CanInteract || args.Target == null) if (!args.CanAccess || !args.CanInteract)
return; return;
if (TryComp(args.Using, out UseDelayComponent? useDelay) && useDelay.ActiveDelay) 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) private void OnAfterInteract(EntityUid uid, PriceGunComponent component, AfterInteractEvent args)
{ {
if (!args.CanReach || args.Target == null) if (!args.CanReach || args.Target == null || args.Handled)
return; return;
if (TryComp(args.Used, out UseDelayComponent? useDelay) && useDelay.ActiveDelay) 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); _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); _useDelay.BeginDelay(uid, useDelay);
args.Handled = true;
} }
} }

View File

@@ -23,20 +23,17 @@ namespace Content.Server.Cargo.Systems;
/// </summary> /// </summary>
public sealed class PricingSystem : EntitySystem public sealed class PricingSystem : EntitySystem
{ {
[Dependency] private readonly IComponentFactory _factory = default!;
[Dependency] private readonly IConsoleHost _consoleHost = default!; [Dependency] private readonly IConsoleHost _consoleHost = default!;
[Dependency] private readonly IMapManager _mapManager = default!; [Dependency] private readonly IMapManager _mapManager = default!;
[Dependency] private readonly MobStateSystem _mobStateSystem = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly BodySystem _bodySystem = default!; [Dependency] private readonly BodySystem _bodySystem = default!;
[Dependency] private readonly MobStateSystem _mobStateSystem = default!;
/// <inheritdoc/> /// <inheritdoc/>
public override void Initialize() public override void Initialize()
{ {
SubscribeLocalEvent<StaticPriceComponent, PriceCalculationEvent>(CalculateStaticPrice);
SubscribeLocalEvent<StackPriceComponent, PriceCalculationEvent>(CalculateStackPrice);
SubscribeLocalEvent<MobPriceComponent, PriceCalculationEvent>(CalculateMobPrice); SubscribeLocalEvent<MobPriceComponent, PriceCalculationEvent>(CalculateMobPrice);
SubscribeLocalEvent<SolutionContainerManagerComponent, PriceCalculationEvent>(CalculateSolutionPrice);
_consoleHost.RegisterCommand("appraisegrid", _consoleHost.RegisterCommand("appraisegrid",
"Calculates the total value of the given grids.", "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) private void CalculateMobPrice(EntityUid uid, MobPriceComponent component, ref PriceCalculationEvent args)
{ {
// TODO: Estimated pricing.
if (args.Handled) if (args.Handled)
return; return;
@@ -106,26 +104,9 @@ public sealed class PricingSystem : EntitySystem
args.Price += (component.Price - partPenalty) * (_mobStateSystem.IsAlive(uid, state) ? 1.0 : component.DeathPenalty); 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) var price = 0.0;
return;
if (!TryComp<StackComponent>(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;
foreach (var solution in component.Solutions.Values) foreach (var solution in component.Solutions.Values)
{ {
@@ -136,45 +117,11 @@ public sealed class PricingSystem : EntitySystem
price += (float) reagent.Quantity * reagentProto.PricePerUnit; price += (float) reagent.Quantity * reagentProto.PricePerUnit;
} }
} }
args.Price += price;
}
private void CalculateStaticPrice(EntityUid uid, StaticPriceComponent component, ref PriceCalculationEvent args)
{
if (args.Handled)
return;
args.Price += component.Price;
}
/// <summary>
/// Get a rough price for an entityprototype. Does not consider contained entities.
/// </summary>
public double GetEstimatedPrice(EntityPrototype prototype, IComponentFactory? factory = null)
{
IoCManager.Resolve(ref factory);
var price = 0.0;
if (prototype.Components.TryGetValue(factory.GetComponentName(typeof(StaticPriceComponent)),
out var staticPriceProto))
{
var staticComp = (StaticPriceComponent) staticPriceProto.Component;
price += staticComp.Price;
}
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; return price;
} }
public double GetMaterialPrice(MaterialComponent component) private double GetMaterialPrice(MaterialComponent component)
{ {
double price = 0; double price = 0;
foreach (var (id, quantity) in component.Materials) foreach (var (id, quantity) in component.Materials)
@@ -184,6 +131,32 @@ public sealed class PricingSystem : EntitySystem
return price; return price;
} }
/// <summary>
/// Get a rough price for an entityprototype. Does not consider contained entities.
/// </summary>
public double GetEstimatedPrice(EntityPrototype prototype)
{
var ev = new EstimatedPriceCalculationEvent()
{
Prototype = prototype,
};
RaiseLocalEvent(ref ev);
if (ev.Handled)
return ev.Price;
var price = ev.Price;
price += GetMaterialsPrice(prototype);
price += GetSolutionsPrice(prototype);
price += GetStackPrice(prototype);
price += GetStaticPrice(prototype);
// TODO: Proper container support.
return price;
}
/// <summary> /// <summary>
/// Appraises an entity, returning it's price. /// Appraises an entity, returning it's price.
/// </summary> /// </summary>
@@ -201,7 +174,31 @@ public sealed class PricingSystem : EntitySystem
if (ev.Handled) if (ev.Handled)
return ev.Price; 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. //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<ContainerManagerComponent>(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<MaterialComponent>(uid, out var material) && !HasComp<StackPriceComponent>(uid)) if (TryComp<MaterialComponent>(uid, out var material) && !HasComp<StackPriceComponent>(uid))
{ {
@@ -209,21 +206,109 @@ public sealed class PricingSystem : EntitySystem
if (TryComp<StackComponent>(uid, out var stack)) if (TryComp<StackComponent>(uid, out var stack))
matPrice *= stack.Count; matPrice *= stack.Count;
ev.Price += matPrice; price += matPrice;
} }
if (TryComp<ContainerManagerComponent>(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) matPrice *= ((StackComponent) stackProto.Component).Count;
{
ev.Price += GetPrice(ent);
}
} }
price += matPrice;
} }
return ev.Price; return price;
}
private double GetSolutionsPrice(EntityUid uid)
{
var price = 0.0;
if (TryComp<SolutionContainerManagerComponent>(uid, out var solComp))
{
price += GetSolutionPrice(solComp);
}
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<StackPriceComponent>(uid, out var stackPrice) &&
TryComp<StackComponent>(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<StaticPriceComponent>(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;
} }
/// <summary> /// <summary>
@@ -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. /// A directed by-ref event fired on an entity when something needs to know it's price. This value is not cached.
/// </summary> /// </summary>
[ByRefEvent] [ByRefEvent]
public struct PriceCalculationEvent public record struct PriceCalculationEvent()
{ {
/// <summary> /// <summary>
/// The total price of the entity. /// The total price of the entity.
@@ -267,6 +352,23 @@ public struct PriceCalculationEvent
/// Whether this event was already handled. /// Whether this event was already handled.
/// </summary> /// </summary>
public bool Handled = false; public bool Handled = false;
}
public PriceCalculationEvent() { }
/// <summary>
/// Raised broadcast for an entity prototype to determine its estimated price.
/// </summary>
[ByRefEvent]
public record struct EstimatedPriceCalculationEvent()
{
public EntityPrototype Prototype;
/// <summary>
/// The total price of the entity.
/// </summary>
public double Price = 0;
/// <summary>
/// Whether this event was already handled.
/// </summary>
public bool Handled = false;
} }

View File

@@ -154,7 +154,6 @@ public sealed class StatValuesCommand : IConsoleCommand
{ {
var values = new List<string[]>(); var values = new List<string[]>();
var protoManager = IoCManager.Resolve<IPrototypeManager>(); var protoManager = IoCManager.Resolve<IPrototypeManager>();
var factory = IoCManager.Resolve<IComponentFactory>();
var priceSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<PricingSystem>(); var priceSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<PricingSystem>();
foreach (var proto in protoManager.EnumeratePrototypes<LatheRecipePrototype>()) foreach (var proto in protoManager.EnumeratePrototypes<LatheRecipePrototype>())
@@ -167,7 +166,7 @@ public sealed class StatValuesCommand : IConsoleCommand
cost += materialPrice * count; cost += materialPrice * count;
} }
var sell = priceSystem.GetEstimatedPrice(protoManager.Index<EntityPrototype>(proto.Result), factory); var sell = priceSystem.GetEstimatedPrice(protoManager.Index<EntityPrototype>(proto.Result));
values.Add(new[] values.Add(new[]
{ {

View File

@@ -25,7 +25,6 @@ namespace Content.Server.VendingMachines
{ {
public sealed class VendingMachineSystem : SharedVendingMachineSystem public sealed class VendingMachineSystem : SharedVendingMachineSystem
{ {
[Dependency] private readonly IComponentFactory _factory = default!;
[Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly AccessReaderSystem _accessReader = default!; [Dependency] private readonly AccessReaderSystem _accessReader = default!;
@@ -71,7 +70,7 @@ namespace Content.Server.VendingMachines
continue; continue;
} }
price += entry.Amount * _pricing.GetEstimatedPrice(proto, _factory); price += entry.Amount * _pricing.GetEstimatedPrice(proto);
} }
args.Price += price; args.Price += price;