Fix cargo product groups (#24212)

This commit is contained in:
Nemanja
2024-01-19 22:47:08 -05:00
committed by GitHub
parent 0b37dbbfbd
commit 21e77dffb0
9 changed files with 77 additions and 36 deletions

View File

@@ -50,7 +50,7 @@ namespace Content.Client.Cargo.BUI
base.Open(); base.Open();
var spriteSystem = EntMan.System<SpriteSystem>(); var spriteSystem = EntMan.System<SpriteSystem>();
_menu = new CargoConsoleMenu(IoCManager.Resolve<IPrototypeManager>(), spriteSystem); _menu = new CargoConsoleMenu(Owner, IoCManager.Resolve<EntityManager>(), IoCManager.Resolve<IPrototypeManager>(), spriteSystem);
var localPlayer = IoCManager.Resolve<IPlayerManager>()?.LocalPlayer?.ControlledEntity; var localPlayer = IoCManager.Resolve<IPlayerManager>()?.LocalPlayer?.ControlledEntity;
var description = new FormattedMessage(); var description = new FormattedMessage();

View File

@@ -1,6 +1,7 @@
using System.Linq; using System.Linq;
using Content.Client.UserInterface.Controls; using Content.Client.UserInterface.Controls;
using Content.Shared.Cargo; using Content.Shared.Cargo;
using Content.Shared.Cargo.Components;
using Content.Shared.Cargo.Prototypes; using Content.Shared.Cargo.Prototypes;
using Robust.Client.AutoGenerated; using Robust.Client.AutoGenerated;
using Robust.Client.GameObjects; using Robust.Client.GameObjects;
@@ -14,8 +15,10 @@ namespace Content.Client.Cargo.UI
[GenerateTypedNameReferences] [GenerateTypedNameReferences]
public sealed partial class CargoConsoleMenu : FancyWindow public sealed partial class CargoConsoleMenu : FancyWindow
{ {
private IEntityManager _entityManager;
private IPrototypeManager _protoManager; private IPrototypeManager _protoManager;
private SpriteSystem _spriteSystem; private SpriteSystem _spriteSystem;
private EntityUid _owner;
public event Action<ButtonEventArgs>? OnItemSelected; public event Action<ButtonEventArgs>? OnItemSelected;
public event Action<ButtonEventArgs>? OnOrderApproved; public event Action<ButtonEventArgs>? OnOrderApproved;
@@ -24,11 +27,13 @@ namespace Content.Client.Cargo.UI
private readonly List<string> _categoryStrings = new(); private readonly List<string> _categoryStrings = new();
private string? _category; private string? _category;
public CargoConsoleMenu(IPrototypeManager protoManager, SpriteSystem spriteSystem) public CargoConsoleMenu(EntityUid owner, IEntityManager entMan, IPrototypeManager protoManager, SpriteSystem spriteSystem)
{ {
RobustXamlLoader.Load(this); RobustXamlLoader.Load(this);
_entityManager = entMan;
_protoManager = protoManager; _protoManager = protoManager;
_spriteSystem = spriteSystem; _spriteSystem = spriteSystem;
_owner = owner;
Title = Loc.GetString("cargo-console-menu-title"); Title = Loc.GetString("cargo-console-menu-title");
@@ -53,7 +58,21 @@ namespace Content.Client.Cargo.UI
Categories.SelectId(id); Categories.SelectId(id);
} }
public IEnumerable<CargoProductPrototype> ProductPrototypes => _protoManager.EnumeratePrototypes<CargoProductPrototype>(); public IEnumerable<CargoProductPrototype> ProductPrototypes
{
get
{
var allowedGroups = _entityManager.GetComponentOrNull<CargoOrderConsoleComponent>(_owner)?.AllowedGroups;
foreach (var cargoPrototype in _protoManager.EnumeratePrototypes<CargoProductPrototype>())
{
if (!allowedGroups?.Contains(cargoPrototype.Group) ?? false)
continue;
yield return cargoPrototype;
}
}
}
/// <summary> /// <summary>
/// Populates the list of products that will actually be shown, using the current filters. /// Populates the list of products that will actually be shown, using the current filters.
@@ -80,7 +99,7 @@ namespace Content.Client.Cargo.UI
Product = prototype, Product = prototype,
ProductName = { Text = prototype.Name }, ProductName = { Text = prototype.Name },
MainButton = { ToolTip = prototype.Description }, MainButton = { ToolTip = prototype.Description },
PointCost = { Text = Loc.GetString("cargo-console-menu-points-amount", ("amount", prototype.PointCost.ToString())) }, PointCost = { Text = Loc.GetString("cargo-console-menu-points-amount", ("amount", prototype.Cost.ToString())) },
Icon = { Texture = _spriteSystem.Frame0(prototype.Icon) }, Icon = { Texture = _spriteSystem.Frame0(prototype.Icon) },
}; };
button.MainButton.OnPressed += args => button.MainButton.OnPressed += args =>

View File

@@ -44,7 +44,7 @@ public sealed class CargoTest
var ent = entManager.SpawnEntity(proto.Product, testMap.MapCoords); var ent = entManager.SpawnEntity(proto.Product, testMap.MapCoords);
var price = pricing.GetPrice(ent); var price = pricing.GetPrice(ent);
Assert.That(price, Is.AtMost(proto.PointCost), $"Found arbitrage on {proto.ID} cargo product! Cost is {proto.PointCost} but sell is {price}!"); Assert.That(price, Is.AtMost(proto.Cost), $"Found arbitrage on {proto.ID} cargo product! Cost is {proto.Cost} but sell is {price}!");
entManager.DeleteEntity(ent); entManager.DeleteEntity(ent);
} }
}); });
@@ -80,7 +80,7 @@ public sealed class CargoTest
foreach (var bounty in bounties) foreach (var bounty in bounties)
{ {
if (cargo.IsBountyComplete(ent, bounty)) if (cargo.IsBountyComplete(ent, bounty))
Assert.That(proto.PointCost, Is.GreaterThanOrEqualTo(bounty.Reward), $"Found arbitrage on {bounty.ID} cargo bounty! Product {proto.ID} costs {proto.PointCost} but fulfills bounty {bounty.ID} with reward {bounty.Reward}!"); Assert.That(proto.Cost, Is.GreaterThanOrEqualTo(bounty.Reward), $"Found arbitrage on {bounty.ID} cargo bounty! Product {proto.ID} costs {proto.Cost} but fulfills bounty {bounty.ID} with reward {bounty.Reward}!");
} }
entManager.DeleteEntity(ent); entManager.DeleteEntity(ent);

View File

@@ -1,17 +0,0 @@
using Robust.Shared.Audio;
namespace Content.Server.Cargo.Components
{
/// <summary>
/// Handles sending order requests to cargo. Doesn't handle orders themselves via shuttle or telepads.
/// </summary>
[RegisterComponent]
public sealed partial class CargoOrderConsoleComponent : Component
{
[DataField("soundError")] public SoundSpecifier ErrorSound =
new SoundPathSpecifier("/Audio/Effects/Cargo/buzz_sigh.ogg");
[DataField("soundConfirm")]
public SoundSpecifier ConfirmSound = new SoundPathSpecifier("/Audio/Effects/Cargo/ping.ogg");
}
}

View File

@@ -261,6 +261,9 @@ namespace Content.Server.Cargo.Systems
return; return;
} }
if (!component.AllowedGroups.Contains(product.Group))
return;
var data = GetOrderData(args, product, GenerateOrderId(orderDatabase)); var data = GetOrderData(args, product, GenerateOrderId(orderDatabase));
if (!TryAddOrder(stationUid.Value, data, orderDatabase)) if (!TryAddOrder(stationUid.Value, data, orderDatabase))
@@ -313,7 +316,7 @@ namespace Content.Server.Cargo.Systems
private static CargoOrderData GetOrderData(CargoConsoleAddOrderMessage args, CargoProductPrototype cargoProduct, int id) private static CargoOrderData GetOrderData(CargoConsoleAddOrderMessage args, CargoProductPrototype cargoProduct, int id)
{ {
return new CargoOrderData(id, cargoProduct.Product, cargoProduct.PointCost, args.Amount, args.Requester, args.Reason); return new CargoOrderData(id, cargoProduct.Product, cargoProduct.Cost, args.Amount, args.Requester, args.Reason);
} }
public static int GetOutstandingOrderCount(StationCargoOrderDatabaseComponent component) public static int GetOutstandingOrderCount(StationCargoOrderDatabaseComponent component)

View File

@@ -9,6 +9,7 @@ using Content.Server.Station.Systems;
using Content.Shared.Access.Systems; using Content.Shared.Access.Systems;
using Content.Shared.Administration.Logs; using Content.Shared.Administration.Logs;
using Content.Shared.Cargo; using Content.Shared.Cargo;
using Content.Shared.Cargo.Components;
using Content.Shared.Containers.ItemSlots; using Content.Shared.Containers.ItemSlots;
using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Components;
using JetBrains.Annotations; using JetBrains.Annotations;

View File

@@ -60,7 +60,7 @@ public sealed class CargoGiftsRule : StationEventSystem<CargoGiftsRuleComponent>
if (!_cargoSystem.AddAndApproveOrder( if (!_cargoSystem.AddAndApproveOrder(
station!.Value, station!.Value,
product.Product, product.Product,
product.PointCost, product.Cost,
qty, qty,
Loc.GetString(component.Sender), Loc.GetString(component.Sender),
Loc.GetString(component.Description), Loc.GetString(component.Description),

View File

@@ -0,0 +1,25 @@
using Content.Shared.Cargo.Prototypes;
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
namespace Content.Shared.Cargo.Components;
/// <summary>
/// Handles sending order requests to cargo. Doesn't handle orders themselves via shuttle or telepads.
/// </summary>
[RegisterComponent, NetworkedComponent]
public sealed partial class CargoOrderConsoleComponent : Component
{
[DataField("soundError")] public SoundSpecifier ErrorSound =
new SoundPathSpecifier("/Audio/Effects/Cargo/buzz_sigh.ogg");
[DataField("soundConfirm")]
public SoundSpecifier ConfirmSound = new SoundPathSpecifier("/Audio/Effects/Cargo/ping.ogg");
/// <summary>
/// All of the <see cref="CargoProductPrototype.Group"/>s that are supported.
/// </summary>
[DataField, ViewVariables(VVAccess.ReadWrite)]
public List<string> AllowedGroups = new() { "market" };
}

View File

@@ -1,12 +1,22 @@
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Array;
using Robust.Shared.Utility; using Robust.Shared.Utility;
namespace Content.Shared.Cargo.Prototypes namespace Content.Shared.Cargo.Prototypes
{ {
[Prototype("cargoProduct")] [Prototype]
public sealed partial class CargoProductPrototype : IPrototype public sealed partial class CargoProductPrototype : IPrototype, IInheritingPrototype
{ {
/// <inheritdoc />
[ParentDataField(typeof(AbstractPrototypeIdArraySerializer<CargoProductPrototype>))]
public string[]? Parents { get; }
/// <inheritdoc />
[NeverPushInheritance]
[AbstractDataField]
public bool Abstract { get; }
[DataField("name")] private string _name = string.Empty; [DataField("name")] private string _name = string.Empty;
[DataField("description")] private string _description = string.Empty; [DataField("description")] private string _description = string.Empty;
@@ -58,31 +68,31 @@ namespace Content.Shared.Cargo.Prototypes
/// <summary> /// <summary>
/// Texture path used in the CargoConsole GUI. /// Texture path used in the CargoConsole GUI.
/// </summary> /// </summary>
[DataField("icon")] [DataField]
public SpriteSpecifier Icon { get; private set; } = SpriteSpecifier.Invalid; public SpriteSpecifier Icon { get; private set; } = SpriteSpecifier.Invalid;
/// <summary> /// <summary>
/// The prototype name of the product. /// The entity prototype ID of the product.
/// </summary> /// </summary>
[DataField("product", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))] [DataField]
public string Product { get; private set; } = string.Empty; public EntProtoId Product { get; private set; } = string.Empty;
/// <summary> /// <summary>
/// The point cost of the product. /// The point cost of the product.
/// </summary> /// </summary>
[DataField("cost")] [DataField]
public int PointCost { get; private set; } public int Cost { get; private set; }
/// <summary> /// <summary>
/// The prototype category of the product. (e.g. Engineering, Medical) /// The prototype category of the product. (e.g. Engineering, Medical)
/// </summary> /// </summary>
[DataField("category")] [DataField]
public string Category { get; private set; } = string.Empty; public string Category { get; private set; } = string.Empty;
/// <summary> /// <summary>
/// The prototype group of the product. (e.g. Contraband) /// The prototype group of the product. (e.g. Contraband)
/// </summary> /// </summary>
[DataField("group")] [DataField]
public string Group { get; private set; } = string.Empty; public string Group { get; private set; } = "market";
} }
} }