Fix cargo product groups (#24212)
This commit is contained in:
@@ -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();
|
||||||
|
|
||||||
|
|||||||
@@ -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 =>
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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)
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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),
|
||||||
|
|||||||
@@ -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" };
|
||||||
|
}
|
||||||
|
|
||||||
@@ -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";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user