2023-12-29 04:47:43 -08:00
|
|
|
|
using Content.Server.Administration;
|
2022-10-23 00:46:28 +02:00
|
|
|
|
using Content.Server.Body.Systems;
|
2022-06-03 10:56:11 -05:00
|
|
|
|
using Content.Server.Cargo.Components;
|
2024-09-02 06:26:04 -05:00
|
|
|
|
using Content.Shared.Chemistry.EntitySystems;
|
2022-06-03 10:56:11 -05:00
|
|
|
|
using Content.Shared.Administration;
|
2022-10-23 00:46:28 +02:00
|
|
|
|
using Content.Shared.Body.Components;
|
2025-05-24 19:36:38 +02:00
|
|
|
|
using Content.Shared.Cargo;
|
2023-10-14 09:45:28 -07:00
|
|
|
|
using Content.Shared.Chemistry.Components.SolutionManager;
|
2022-11-15 12:51:30 +01:00
|
|
|
|
using Content.Shared.Chemistry.Reagent;
|
2022-10-23 00:46:28 +02:00
|
|
|
|
using Content.Shared.Materials;
|
2023-01-13 16:57:10 -08:00
|
|
|
|
using Content.Shared.Mobs.Components;
|
|
|
|
|
|
using Content.Shared.Mobs.Systems;
|
2022-12-24 23:28:21 -05:00
|
|
|
|
using Content.Shared.Stacks;
|
2022-06-03 10:56:11 -05:00
|
|
|
|
using Robust.Shared.Console;
|
|
|
|
|
|
using Robust.Shared.Containers;
|
2023-10-19 12:34:31 -07:00
|
|
|
|
using Robust.Shared.Map.Components;
|
2022-09-15 11:53:17 +10:00
|
|
|
|
using Robust.Shared.Prototypes;
|
2022-06-03 10:56:11 -05:00
|
|
|
|
using Robust.Shared.Utility;
|
2023-12-29 04:47:43 -08:00
|
|
|
|
using System.Linq;
|
2025-05-29 00:22:47 +03:00
|
|
|
|
using Content.Server._CP14.Trading;
|
Trading request system (#1460)
* mapping public stores update
* base selling platform update
* basic UI setup
* Update coin icon textures
Refreshed the c, g, p, and s coin images in the interface textures. This likely improves their appearance or corrects previous visual issues.
* parse requests data into UI
* selling platform UI state now include price
Updated the selling platform UI to display the calculated price of placed items. Moved the UpdateSellingUIState logic from the shared system to the server system, and modified the CP14SellingPlatformUiState to include a price field. The client window now uses the state-provided price instead of a hardcoded value.
* Update selling UI state on item placed or removed
Added event subscriptions for ItemPlacedEvent and ItemRemovedEvent to update the selling UI state when items are placed or removed from the selling platform. Refactored UpdateSellingUIState to remove the user parameter, as it is no longer needed.
* sell button works now
Replaces the previous sell request mechanism with a new CP14TradingSellAttempt message for selling items on the platform. Updates client and server logic to use this new message, adds a CanSell helper for item validation, and refactors related UI and event handling code for improved clarity and maintainability.
* auto pricing requirements
* Refactor reputation reward to use cashback rate
Reputation rewards for selling requests are now calculated as a percentage (cashback) of the sale price, rather than a fixed value. Updated the relevant UI, server logic, and prototype fields to reflect this change. Also cleaned up the brad_potions.yml prototype file by removing a duplicate entry and correcting an ID.
* request rerolling
2025-06-23 01:21:25 +03:00
|
|
|
|
using Content.Shared.Cargo.Components;
|
2024-08-01 00:15:05 -04:00
|
|
|
|
using Content.Shared.Research.Prototypes;
|
2022-06-03 10:56:11 -05:00
|
|
|
|
|
|
|
|
|
|
namespace Content.Server.Cargo.Systems;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// This handles calculating the price of items, and implements two basic methods of pricing materials.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public sealed class PricingSystem : EntitySystem
|
|
|
|
|
|
{
|
|
|
|
|
|
[Dependency] private readonly IConsoleHost _consoleHost = default!;
|
2022-11-15 12:51:30 +01:00
|
|
|
|
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
2022-10-23 00:46:28 +02:00
|
|
|
|
[Dependency] private readonly BodySystem _bodySystem = default!;
|
2023-03-24 15:27:55 +11:00
|
|
|
|
[Dependency] private readonly MobStateSystem _mobStateSystem = default!;
|
2024-09-02 06:26:04 -05:00
|
|
|
|
[Dependency] private readonly SharedSolutionContainerSystem _solutionContainerSystem = default!;
|
2022-10-23 00:46:28 +02:00
|
|
|
|
|
2022-06-03 10:56:11 -05:00
|
|
|
|
/// <inheritdoc/>
|
|
|
|
|
|
public override void Initialize()
|
|
|
|
|
|
{
|
|
|
|
|
|
SubscribeLocalEvent<MobPriceComponent, PriceCalculationEvent>(CalculateMobPrice);
|
|
|
|
|
|
|
|
|
|
|
|
_consoleHost.RegisterCommand("appraisegrid",
|
|
|
|
|
|
"Calculates the total value of the given grids.",
|
|
|
|
|
|
"appraisegrid <grid Ids>", AppraiseGridCommand);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
[AdminCommand(AdminFlags.Debug)]
|
|
|
|
|
|
private void AppraiseGridCommand(IConsoleShell shell, string argstr, string[] args)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (args.Length == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
shell.WriteError("Not enough arguments.");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var gid in args)
|
|
|
|
|
|
{
|
2023-09-11 09:42:41 +10:00
|
|
|
|
if (!EntityManager.TryParseNetEntity(gid, out var gridId) || !gridId.Value.IsValid())
|
2022-06-03 10:56:11 -05:00
|
|
|
|
{
|
|
|
|
|
|
shell.WriteError($"Invalid grid ID \"{gid}\".");
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-10-19 12:34:31 -07:00
|
|
|
|
if (!TryComp(gridId, out MapGridComponent? mapGrid))
|
2022-06-03 10:56:11 -05:00
|
|
|
|
{
|
2022-10-10 10:41:32 +13:00
|
|
|
|
shell.WriteError($"Grid \"{gridId}\" doesn't exist.");
|
2022-06-03 10:56:11 -05:00
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
List<(double, EntityUid)> mostValuable = new();
|
|
|
|
|
|
|
2023-10-19 12:34:31 -07:00
|
|
|
|
var value = AppraiseGrid(gridId.Value, null, (uid, price) =>
|
2022-06-03 10:56:11 -05:00
|
|
|
|
{
|
|
|
|
|
|
mostValuable.Add((price, uid));
|
|
|
|
|
|
mostValuable.Sort((i1, i2) => i2.Item1.CompareTo(i1.Item1));
|
|
|
|
|
|
if (mostValuable.Count > 5)
|
|
|
|
|
|
mostValuable.Pop();
|
|
|
|
|
|
});
|
|
|
|
|
|
|
2023-08-06 22:43:34 -07:00
|
|
|
|
shell.WriteLine($"Grid {gid} appraised to {value} spesos.");
|
2022-06-03 10:56:11 -05:00
|
|
|
|
shell.WriteLine($"The top most valuable items were:");
|
|
|
|
|
|
foreach (var (price, ent) in mostValuable)
|
|
|
|
|
|
{
|
2023-08-06 22:43:34 -07:00
|
|
|
|
shell.WriteLine($"- {ToPrettyString(ent)} @ {price} spesos");
|
2022-06-03 10:56:11 -05:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void CalculateMobPrice(EntityUid uid, MobPriceComponent component, ref PriceCalculationEvent args)
|
|
|
|
|
|
{
|
2023-03-24 15:27:55 +11:00
|
|
|
|
// TODO: Estimated pricing.
|
2023-02-28 16:55:25 +01:00
|
|
|
|
if (args.Handled)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
2025-08-06 15:01:20 -04:00
|
|
|
|
if (!TryComp<MobStateComponent>(uid, out var state))
|
2022-06-03 10:56:11 -05:00
|
|
|
|
{
|
2025-08-06 15:01:20 -04:00
|
|
|
|
Log.Error($"Tried to get the mob price of {ToPrettyString(uid)}, which has no {nameof(MobStateComponent)}.");
|
2022-06-03 10:56:11 -05:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-06 15:01:20 -04:00
|
|
|
|
var partPenalty = 0.0;
|
|
|
|
|
|
if (TryComp<BodyComponent>(uid, out var body))
|
|
|
|
|
|
{
|
|
|
|
|
|
var partList = _bodySystem.GetBodyChildren(uid, body).ToList();
|
|
|
|
|
|
var totalPartsPresent = partList.Sum(_ => 1);
|
|
|
|
|
|
var totalParts = partList.Count;
|
2022-06-03 10:56:11 -05:00
|
|
|
|
|
2025-08-06 15:01:20 -04:00
|
|
|
|
var partRatio = totalPartsPresent / (double) totalParts;
|
|
|
|
|
|
partPenalty = component.Price * (1 - partRatio) * component.MissingBodyPartPenalty;
|
|
|
|
|
|
}
|
2022-06-03 10:56:11 -05:00
|
|
|
|
|
2022-12-19 19:25:35 -08:00
|
|
|
|
args.Price += (component.Price - partPenalty) * (_mobStateSystem.IsAlive(uid, state) ? 1.0 : component.DeathPenalty);
|
2022-06-03 10:56:11 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-12-29 04:47:43 -08:00
|
|
|
|
private double GetSolutionPrice(Entity<SolutionContainerManagerComponent> entity)
|
2023-12-28 17:58:14 -08:00
|
|
|
|
{
|
2023-12-29 04:47:43 -08:00
|
|
|
|
if (Comp<MetaDataComponent>(entity).EntityLifeStage < EntityLifeStage.MapInitialized)
|
|
|
|
|
|
return GetSolutionPrice(entity.Comp);
|
|
|
|
|
|
|
2023-12-28 17:58:14 -08:00
|
|
|
|
var price = 0.0;
|
|
|
|
|
|
|
2023-12-29 04:47:43 -08:00
|
|
|
|
foreach (var (_, soln) in _solutionContainerSystem.EnumerateSolutions((entity.Owner, entity.Comp)))
|
2023-12-28 17:58:14 -08:00
|
|
|
|
{
|
2023-12-29 04:47:43 -08:00
|
|
|
|
var solution = soln.Comp.Solution;
|
2023-12-28 20:45:42 -07:00
|
|
|
|
foreach (var (reagent, quantity) in solution.Contents)
|
2023-12-28 17:58:14 -08:00
|
|
|
|
{
|
|
|
|
|
|
if (!_prototypeManager.TryIndex<ReagentPrototype>(reagent.Prototype, out var reagentProto))
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
// TODO check ReagentData for price information?
|
|
|
|
|
|
price += (float) quantity * reagentProto.PricePerUnit;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return price;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-12-29 04:47:43 -08:00
|
|
|
|
private double GetSolutionPrice(SolutionContainerManagerComponent component)
|
|
|
|
|
|
{
|
|
|
|
|
|
var price = 0.0;
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var (_, prototype) in _solutionContainerSystem.EnumerateSolutions(component))
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var (reagent, quantity) in prototype.Contents)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!_prototypeManager.TryIndex<ReagentPrototype>(reagent.Prototype, out var reagentProto))
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
// TODO check ReagentData for price information?
|
|
|
|
|
|
price += (float) quantity * reagentProto.PricePerUnit;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return price;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-04-29 00:53:41 -04:00
|
|
|
|
private double GetMaterialPrice(PhysicalCompositionComponent component)
|
2022-06-03 10:56:11 -05:00
|
|
|
|
{
|
2023-03-24 15:27:55 +11:00
|
|
|
|
double price = 0;
|
2023-04-29 00:53:41 -04:00
|
|
|
|
foreach (var (id, quantity) in component.MaterialComposition)
|
2023-03-24 15:27:55 +11:00
|
|
|
|
{
|
|
|
|
|
|
price += _prototypeManager.Index<MaterialPrototype>(id).Price * quantity;
|
|
|
|
|
|
}
|
|
|
|
|
|
return price;
|
2022-06-03 10:56:11 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-08-01 00:15:05 -04:00
|
|
|
|
public double GetLatheRecipePrice(LatheRecipePrototype recipe)
|
|
|
|
|
|
{
|
|
|
|
|
|
var price = 0.0;
|
|
|
|
|
|
|
|
|
|
|
|
if (recipe.Result is { } result)
|
|
|
|
|
|
{
|
|
|
|
|
|
price += GetEstimatedPrice(_prototypeManager.Index(result));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (recipe.ResultReagents is { } resultReagents)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var (reagent, amount) in resultReagents)
|
|
|
|
|
|
{
|
|
|
|
|
|
price += (_prototypeManager.Index(reagent).PricePerUnit * amount).Double();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return price;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-09-15 11:53:17 +10:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Get a rough price for an entityprototype. Does not consider contained entities.
|
|
|
|
|
|
/// </summary>
|
2023-03-24 15:27:55 +11:00
|
|
|
|
public double GetEstimatedPrice(EntityPrototype prototype)
|
2022-09-15 11:53:17 +10:00
|
|
|
|
{
|
2025-05-24 19:36:38 +02:00
|
|
|
|
var ev = new EstimatedPriceCalculationEvent(prototype);
|
2022-09-15 11:53:17 +10:00
|
|
|
|
|
2023-03-24 15:27:55 +11:00
|
|
|
|
RaiseLocalEvent(ref ev);
|
2022-09-15 11:53:17 +10:00
|
|
|
|
|
2023-03-24 15:27:55 +11:00
|
|
|
|
if (ev.Handled)
|
|
|
|
|
|
return ev.Price;
|
2022-09-15 11:53:17 +10:00
|
|
|
|
|
2023-03-24 15:27:55 +11:00
|
|
|
|
var price = ev.Price;
|
|
|
|
|
|
price += GetMaterialsPrice(prototype);
|
|
|
|
|
|
price += GetSolutionsPrice(prototype);
|
2023-03-27 04:01:42 +11:00
|
|
|
|
// Can't use static price with stackprice
|
|
|
|
|
|
var oldPrice = price;
|
2023-03-24 15:27:55 +11:00
|
|
|
|
price += GetStackPrice(prototype);
|
2023-03-27 04:01:42 +11:00
|
|
|
|
|
|
|
|
|
|
if (oldPrice.Equals(price))
|
|
|
|
|
|
{
|
|
|
|
|
|
price += GetStaticPrice(prototype);
|
|
|
|
|
|
}
|
2023-03-24 15:27:55 +11:00
|
|
|
|
|
|
|
|
|
|
// TODO: Proper container support.
|
2022-09-15 11:53:17 +10:00
|
|
|
|
|
2023-01-08 11:36:32 +13:00
|
|
|
|
return price;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-06-03 10:56:11 -05:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Appraises an entity, returning it's price.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="uid">The entity to appraise.</param>
|
|
|
|
|
|
/// <returns>The price of the entity.</returns>
|
|
|
|
|
|
/// <remarks>
|
|
|
|
|
|
/// This fires off an event to calculate the price.
|
|
|
|
|
|
/// Calculating the price of an entity that somehow contains itself will likely hang.
|
|
|
|
|
|
/// </remarks>
|
2024-04-20 18:03:11 -04:00
|
|
|
|
public double GetPrice(EntityUid uid, bool includeContents = true)
|
2022-06-03 10:56:11 -05:00
|
|
|
|
{
|
|
|
|
|
|
var ev = new PriceCalculationEvent();
|
2022-09-15 11:53:17 +10:00
|
|
|
|
RaiseLocalEvent(uid, ref ev);
|
2022-06-03 10:56:11 -05:00
|
|
|
|
|
2023-02-28 16:55:25 +01:00
|
|
|
|
if (ev.Handled)
|
|
|
|
|
|
return ev.Price;
|
|
|
|
|
|
|
2023-03-24 15:27:55 +11:00
|
|
|
|
var price = ev.Price;
|
2022-06-03 10:56:11 -05:00
|
|
|
|
//TODO: Add an OpaqueToAppraisal component or similar for blocking the recursive descent into containers, or preventing material pricing.
|
2023-03-24 15:27:55 +11:00
|
|
|
|
// DO NOT FORGET TO UPDATE ESTIMATED PRICING
|
|
|
|
|
|
price += GetMaterialsPrice(uid);
|
|
|
|
|
|
price += GetSolutionsPrice(uid);
|
2023-03-27 04:01:42 +11:00
|
|
|
|
|
|
|
|
|
|
// Can't use static price with stackprice
|
|
|
|
|
|
var oldPrice = price;
|
2023-03-24 15:27:55 +11:00
|
|
|
|
price += GetStackPrice(uid);
|
2023-03-27 04:01:42 +11:00
|
|
|
|
|
|
|
|
|
|
if (oldPrice.Equals(price))
|
|
|
|
|
|
{
|
|
|
|
|
|
price += GetStaticPrice(uid);
|
|
|
|
|
|
}
|
2023-03-24 15:27:55 +11:00
|
|
|
|
|
2024-04-20 18:03:11 -04:00
|
|
|
|
if (includeContents && TryComp<ContainerManagerComponent>(uid, out var containers))
|
2023-03-24 15:27:55 +11:00
|
|
|
|
{
|
|
|
|
|
|
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;
|
2022-06-03 10:56:11 -05:00
|
|
|
|
|
2025-05-29 00:22:47 +03:00
|
|
|
|
//CP14 We take materials into account when calculating the price in any case.
|
|
|
|
|
|
var proto = MetaData(uid).EntityPrototype?.ID ?? "";
|
|
|
|
|
|
if ((HasComp<MaterialComponent>(uid) || proto.StartsWith("CP14")) &&
|
2023-04-29 00:53:41 -04:00
|
|
|
|
TryComp<PhysicalCompositionComponent>(uid, out var composition))
|
2022-06-03 10:56:11 -05:00
|
|
|
|
{
|
2023-04-29 00:53:41 -04:00
|
|
|
|
var matPrice = GetMaterialPrice(composition);
|
2022-06-03 10:56:11 -05:00
|
|
|
|
if (TryComp<StackComponent>(uid, out var stack))
|
2023-01-08 11:36:32 +13:00
|
|
|
|
matPrice *= stack.Count;
|
|
|
|
|
|
|
2023-03-24 15:27:55 +11:00
|
|
|
|
price += matPrice;
|
2022-06-03 10:56:11 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-03-24 15:27:55 +11:00
|
|
|
|
return price;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private double GetMaterialsPrice(EntityPrototype prototype)
|
|
|
|
|
|
{
|
|
|
|
|
|
double price = 0;
|
|
|
|
|
|
|
2025-05-29 00:22:47 +03:00
|
|
|
|
//CP14 We take materials into account when calculating the price in any case.
|
2025-05-29 00:50:36 +03:00
|
|
|
|
if ((prototype.Components.ContainsKey(Factory.GetComponentName<MaterialComponent>()) || prototype.ID.StartsWith("CP14")) &&
|
2025-05-20 15:08:55 +10:00
|
|
|
|
prototype.Components.TryGetValue(Factory.GetComponentName<PhysicalCompositionComponent>(), out var composition))
|
2022-06-03 10:56:11 -05:00
|
|
|
|
{
|
2023-04-29 00:53:41 -04:00
|
|
|
|
var compositionComp = (PhysicalCompositionComponent) composition.Component;
|
|
|
|
|
|
var matPrice = GetMaterialPrice(compositionComp);
|
2023-03-24 15:27:55 +11:00
|
|
|
|
|
2025-05-20 15:08:55 +10:00
|
|
|
|
if (prototype.Components.TryGetValue(Factory.GetComponentName<StackComponent>(), out var stackProto))
|
2022-06-03 10:56:11 -05:00
|
|
|
|
{
|
2023-03-24 15:27:55 +11:00
|
|
|
|
matPrice *= ((StackComponent) stackProto.Component).Count;
|
2022-06-03 10:56:11 -05:00
|
|
|
|
}
|
2023-03-24 15:27:55 +11:00
|
|
|
|
|
|
|
|
|
|
price += matPrice;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return price;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private double GetSolutionsPrice(EntityUid uid)
|
|
|
|
|
|
{
|
|
|
|
|
|
var price = 0.0;
|
|
|
|
|
|
|
|
|
|
|
|
if (TryComp<SolutionContainerManagerComponent>(uid, out var solComp))
|
|
|
|
|
|
{
|
2023-12-29 04:47:43 -08:00
|
|
|
|
price += GetSolutionPrice((uid, solComp));
|
2022-06-03 10:56:11 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-03-24 15:27:55 +11:00
|
|
|
|
return price;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private double GetSolutionsPrice(EntityPrototype prototype)
|
|
|
|
|
|
{
|
|
|
|
|
|
var price = 0.0;
|
|
|
|
|
|
|
2025-05-20 15:08:55 +10:00
|
|
|
|
if (prototype.Components.TryGetValue(Factory.GetComponentName<SolutionContainerManagerComponent>(), out var solManager))
|
2023-03-24 15:27:55 +11:00
|
|
|
|
{
|
|
|
|
|
|
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) &&
|
2023-04-10 00:38:20 -04:00
|
|
|
|
TryComp<StackComponent>(uid, out var stack) &&
|
|
|
|
|
|
!HasComp<MaterialComponent>(uid)) // don't double count material prices
|
2023-03-24 15:27:55 +11:00
|
|
|
|
{
|
|
|
|
|
|
price += stack.Count * stackPrice.Price;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return price;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private double GetStackPrice(EntityPrototype prototype)
|
|
|
|
|
|
{
|
|
|
|
|
|
var price = 0.0;
|
|
|
|
|
|
|
2025-05-20 15:08:55 +10:00
|
|
|
|
if (prototype.Components.TryGetValue(Factory.GetComponentName<StackPriceComponent>(), out var stackpriceProto) &&
|
|
|
|
|
|
prototype.Components.TryGetValue(Factory.GetComponentName<StackComponent>(), out var stackProto) &&
|
|
|
|
|
|
!prototype.Components.ContainsKey(Factory.GetComponentName<MaterialComponent>()))
|
2023-03-24 15:27:55 +11:00
|
|
|
|
{
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
2025-05-20 15:08:55 +10:00
|
|
|
|
if (prototype.Components.TryGetValue(Factory.GetComponentName<StaticPriceComponent>(), out var staticProto))
|
2023-03-24 15:27:55 +11:00
|
|
|
|
{
|
|
|
|
|
|
var staticPrice = (StaticPriceComponent) staticProto.Component;
|
|
|
|
|
|
price += staticPrice.Price;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return price;
|
2022-06-03 10:56:11 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Appraises a grid, this is mainly meant to be used by yarrs.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="grid">The grid to appraise.</param>
|
|
|
|
|
|
/// <param name="predicate">An optional predicate that controls whether or not the entity is counted toward the total.</param>
|
|
|
|
|
|
/// <param name="afterPredicate">An optional predicate to run after the price has been calculated. Useful for high scores or similar.</param>
|
|
|
|
|
|
/// <returns>The total value of the grid.</returns>
|
|
|
|
|
|
public double AppraiseGrid(EntityUid grid, Func<EntityUid, bool>? predicate = null, Action<EntityUid, double>? afterPredicate = null)
|
|
|
|
|
|
{
|
|
|
|
|
|
var xform = Transform(grid);
|
|
|
|
|
|
var price = 0.0;
|
2023-12-16 11:09:50 -05:00
|
|
|
|
var enumerator = xform.ChildEnumerator;
|
|
|
|
|
|
while (enumerator.MoveNext(out var child))
|
2022-06-03 10:56:11 -05:00
|
|
|
|
{
|
|
|
|
|
|
if (predicate is null || predicate(child))
|
|
|
|
|
|
{
|
|
|
|
|
|
var subPrice = GetPrice(child);
|
|
|
|
|
|
price += subPrice;
|
|
|
|
|
|
afterPredicate?.Invoke(child, subPrice);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return price;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|