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();
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 description = new FormattedMessage();

View File

@@ -1,6 +1,7 @@
using System.Linq;
using Content.Client.UserInterface.Controls;
using Content.Shared.Cargo;
using Content.Shared.Cargo.Components;
using Content.Shared.Cargo.Prototypes;
using Robust.Client.AutoGenerated;
using Robust.Client.GameObjects;
@@ -14,8 +15,10 @@ namespace Content.Client.Cargo.UI
[GenerateTypedNameReferences]
public sealed partial class CargoConsoleMenu : FancyWindow
{
private IEntityManager _entityManager;
private IPrototypeManager _protoManager;
private SpriteSystem _spriteSystem;
private EntityUid _owner;
public event Action<ButtonEventArgs>? OnItemSelected;
public event Action<ButtonEventArgs>? OnOrderApproved;
@@ -24,11 +27,13 @@ namespace Content.Client.Cargo.UI
private readonly List<string> _categoryStrings = new();
private string? _category;
public CargoConsoleMenu(IPrototypeManager protoManager, SpriteSystem spriteSystem)
public CargoConsoleMenu(EntityUid owner, IEntityManager entMan, IPrototypeManager protoManager, SpriteSystem spriteSystem)
{
RobustXamlLoader.Load(this);
_entityManager = entMan;
_protoManager = protoManager;
_spriteSystem = spriteSystem;
_owner = owner;
Title = Loc.GetString("cargo-console-menu-title");
@@ -53,7 +58,21 @@ namespace Content.Client.Cargo.UI
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>
/// 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,
ProductName = { Text = prototype.Name },
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) },
};
button.MainButton.OnPressed += args =>

View File

@@ -44,7 +44,7 @@ public sealed class CargoTest
var ent = entManager.SpawnEntity(proto.Product, testMap.MapCoords);
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);
}
});
@@ -80,7 +80,7 @@ public sealed class CargoTest
foreach (var bounty in bounties)
{
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);

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;
}
if (!component.AllowedGroups.Contains(product.Group))
return;
var data = GetOrderData(args, product, GenerateOrderId(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)
{
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)

View File

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

View File

@@ -60,7 +60,7 @@ public sealed class CargoGiftsRule : StationEventSystem<CargoGiftsRuleComponent>
if (!_cargoSystem.AddAndApproveOrder(
station!.Value,
product.Product,
product.PointCost,
product.Cost,
qty,
Loc.GetString(component.Sender),
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.Serialization.TypeSerializers.Implementations.Custom.Prototype;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Array;
using Robust.Shared.Utility;
namespace Content.Shared.Cargo.Prototypes
{
[Prototype("cargoProduct")]
public sealed partial class CargoProductPrototype : IPrototype
[Prototype]
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("description")] private string _description = string.Empty;
@@ -58,31 +68,31 @@ namespace Content.Shared.Cargo.Prototypes
/// <summary>
/// Texture path used in the CargoConsole GUI.
/// </summary>
[DataField("icon")]
[DataField]
public SpriteSpecifier Icon { get; private set; } = SpriteSpecifier.Invalid;
/// <summary>
/// The prototype name of the product.
/// The entity prototype ID of the product.
/// </summary>
[DataField("product", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
public string Product { get; private set; } = string.Empty;
[DataField]
public EntProtoId Product { get; private set; } = string.Empty;
/// <summary>
/// The point cost of the product.
/// </summary>
[DataField("cost")]
public int PointCost { get; private set; }
[DataField]
public int Cost { get; private set; }
/// <summary>
/// The prototype category of the product. (e.g. Engineering, Medical)
/// </summary>
[DataField("category")]
[DataField]
public string Category { get; private set; } = string.Empty;
/// <summary>
/// The prototype group of the product. (e.g. Contraband)
/// </summary>
[DataField("group")]
public string Group { get; private set; } = string.Empty;
[DataField]
public string Group { get; private set; } = "market";
}
}