expedition rewards (#16972)

Co-authored-by: deltanedas <@deltanedas:kde.org>
Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
This commit is contained in:
deltanedas
2023-06-16 05:19:02 +00:00
committed by GitHub
parent f7e4a69b65
commit b9f24b2681
19 changed files with 845 additions and 1582 deletions

View File

@@ -129,13 +129,13 @@ namespace Content.Client.Cargo.UI
foreach (var order in orders) foreach (var order in orders)
{ {
var product = _protoManager.Index<CargoProductPrototype>(order.ProductId); var product = _protoManager.Index<EntityPrototype>(order.ProductId);
var productName = product.Name; var productName = product.Name;
var row = new CargoOrderRow var row = new CargoOrderRow
{ {
Order = order, Order = order,
Icon = { Texture = _spriteSystem.Frame0(product.Icon) }, Icon = { Texture = _spriteSystem.Frame0(product) },
ProductName = ProductName =
{ {
Text = Loc.GetString( Text = Loc.GetString(

View File

@@ -39,13 +39,13 @@ namespace Content.Client.Cargo.UI
foreach (var order in orders) foreach (var order in orders)
{ {
var product = _protoManager.Index<CargoProductPrototype>(order.ProductId); var product = _protoManager.Index<EntityPrototype>(order.ProductId);
var productName = product.Name; var productName = product.Name;
var row = new CargoOrderRow var row = new CargoOrderRow
{ {
Order = order, Order = order,
Icon = { Texture = _spriteSystem.Frame0(product.Icon) }, Icon = { Texture = _spriteSystem.Frame0(product) },
ProductName = ProductName =
{ {
Text = Loc.GetString( Text = Loc.GetString(

View File

@@ -18,6 +18,8 @@ using Content.Shared.Access.Components;
using Robust.Server.GameObjects; using Robust.Server.GameObjects;
using Robust.Shared.Map; using Robust.Shared.Map;
using Robust.Shared.Players; using Robust.Shared.Players;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
namespace Content.Server.Cargo.Systems namespace Content.Server.Cargo.Systems
{ {
@@ -33,14 +35,6 @@ namespace Content.Server.Cargo.Systems
/// </summary> /// </summary>
private float _timer; private float _timer;
[Dependency] private readonly IdCardSystem _idCardSystem = default!;
[Dependency] private readonly AccessReaderSystem _accessReaderSystem = default!;
[Dependency] private readonly DeviceLinkSystem _linker = default!;
[Dependency] private readonly PopupSystem _popup = default!;
[Dependency] private readonly StationSystem _station = default!;
[Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
private void InitializeConsole() private void InitializeConsole()
{ {
SubscribeLocalEvent<CargoOrderConsoleComponent, CargoConsoleAddOrderMessage>(OnAddOrderMessage); SubscribeLocalEvent<CargoOrderConsoleComponent, CargoConsoleAddOrderMessage>(OnAddOrderMessage);
@@ -72,6 +66,8 @@ namespace Content.Server.Cargo.Systems
{ {
_timer += frameTime; _timer += frameTime;
// TODO: Doesn't work with serialization and shouldn't just be updating every delay
// client can just interp this just fine on its own.
while (_timer > Delay) while (_timer > Delay)
{ {
_timer -= Delay; _timer -= Delay;
@@ -124,7 +120,7 @@ namespace Content.Server.Cargo.Systems
} }
// Invalid order // Invalid order
if (!_protoMan.TryIndex<CargoProductPrototype>(order.ProductId, out var product)) if (!_protoMan.HasIndex<EntityPrototype>(order.ProductId))
{ {
ConsolePopup(args.Session, Loc.GetString("cargo-console-invalid-product")); ConsolePopup(args.Session, Loc.GetString("cargo-console-invalid-product"));
PlayDenySound(uid, component); PlayDenySound(uid, component);
@@ -152,7 +148,7 @@ namespace Content.Server.Cargo.Systems
PlayDenySound(uid, component); PlayDenySound(uid, component);
} }
var cost = product.PointCost * order.OrderQuantity; var cost = order.Price * order.OrderQuantity;
// Not enough balance // Not enough balance
if (cost > bankAccount.Balance) if (cost > bankAccount.Balance)
@@ -163,7 +159,7 @@ namespace Content.Server.Cargo.Systems
} }
_idCardSystem.TryFindIdCard(player, out var idCard); _idCardSystem.TryFindIdCard(player, out var idCard);
order.SetApproverData(idCard); order.SetApproverData(idCard?.FullName, idCard?.JobTitle);
_audio.PlayPvs(_audio.GetSound(component.ConfirmSound), uid); _audio.PlayPvs(_audio.GetSound(component.ConfirmSound), uid);
// Log order approval // Log order approval
@@ -190,11 +186,20 @@ namespace Content.Server.Cargo.Systems
return; return;
var bank = GetBankAccount(component); var bank = GetBankAccount(component);
if (bank == null) return; if (bank == null)
var orderDatabase = GetOrderDatabase(component); return;
if (orderDatabase == null) return;
var data = GetOrderData(args, GenerateOrderId(orderDatabase)); var orderDatabase = GetOrderDatabase(component);
if (orderDatabase == null)
return;
if (!_protoMan.TryIndex<CargoProductPrototype>(args.CargoProductId, out var product))
{
_sawmill.Error($"Tried to add invalid cargo product {args.CargoProductId} as order!");
return;
}
var data = GetOrderData(args, product, GenerateOrderId(orderDatabase));
if (!TryAddOrder(orderDatabase, data)) if (!TryAddOrder(orderDatabase, data))
{ {
@@ -239,9 +244,9 @@ namespace Content.Server.Cargo.Systems
_audio.PlayPvs(_audio.GetSound(component.ErrorSound), uid); _audio.PlayPvs(_audio.GetSound(component.ErrorSound), uid);
} }
private CargoOrderData GetOrderData(CargoConsoleAddOrderMessage args, int id) private CargoOrderData GetOrderData(CargoConsoleAddOrderMessage args, CargoProductPrototype cargoProduct, int id)
{ {
return new CargoOrderData(id, args.ProductId, args.Amount, args.Requester, args.Reason); return new CargoOrderData(id, cargoProduct.Product, cargoProduct.PointCost, args.Amount, args.Requester, args.Reason);
} }
public int GetOutstandingOrderCount(StationCargoOrderDatabaseComponent component) public int GetOutstandingOrderCount(StationCargoOrderDatabaseComponent component)
@@ -286,21 +291,15 @@ namespace Content.Server.Cargo.Systems
} }
} }
public bool AddAndApproveOrder(StationCargoOrderDatabaseComponent component, string productId, int qty, string sender, string description, string dest) public bool AddAndApproveOrder(StationCargoOrderDatabaseComponent component, string spawnId, int cost, int qty, string sender, string description, string dest)
{ {
if (!_prototypeManager.HasIndex<CargoProductPrototype>(productId)) DebugTools.Assert(_protoMan.HasIndex<EntityPrototype>(spawnId));
{
_sawmill.Warning($"CargoSystem.Orders could not find CargoProductPrototype for '{productId}' in {description}.");
// Pretend that it worked OK, since we don't want the caller to try again.
return true;
}
// Make an order // Make an order
var id = GenerateOrderId(component); var id = GenerateOrderId(component);
var order = new CargoOrderData(id, productId, qty, sender, description); var order = new CargoOrderData(id, spawnId, cost, qty, sender, description);
// Approve it now // Approve it now
order.SetApproverData(new IdCardComponent(){FullName = dest, JobTitle = sender}); order.SetApproverData(dest, sender);
// Log order addition // Log order addition
_adminLogger.Add(LogType.Action, LogImpact.Low, _adminLogger.Add(LogType.Action, LogImpact.Low,
@@ -368,7 +367,7 @@ namespace Content.Server.Cargo.Systems
if (PopFrontOrder(orderDB, out var order)) if (PopFrontOrder(orderDB, out var order))
{ {
// Create the item itself // Create the item itself
var item = Spawn(_protoMan.Index<CargoProductPrototype>(order.ProductId).Product, whereToPutIt); var item = Spawn(order.ProductId, whereToPutIt);
// Create a sheet of paper to write the order details on // Create a sheet of paper to write the order details on
var printed = EntityManager.SpawnEntity(paperPrototypeToPrint, whereToPutIt); var printed = EntityManager.SpawnEntity(paperPrototypeToPrint, whereToPutIt);

View File

@@ -29,15 +29,6 @@ public sealed partial class CargoSystem
* Handles cargo shuttle mechanics. * Handles cargo shuttle mechanics.
*/ */
[Dependency] private readonly IComponentFactory _factory = default!;
[Dependency] private readonly IConfigurationManager _cfgManager = default!;
[Dependency] private readonly IMapManager _mapManager = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly EntityLookupSystem _lookup = default!;
[Dependency] private readonly PricingSystem _pricing = default!;
[Dependency] private readonly ShuttleConsoleSystem _console = default!;
[Dependency] private readonly StackSystem _stack = default!;
public MapId? CargoMap { get; private set; } public MapId? CargoMap { get; private set; }
private void InitializeShuttle() private void InitializeShuttle()
@@ -191,7 +182,7 @@ public sealed partial class CargoSystem
// We won't be able to fit the whole order on, so make one // We won't be able to fit the whole order on, so make one
// which represents the space we do have left: // which represents the space we do have left:
var reducedOrder = new CargoOrderData(order.OrderId, var reducedOrder = new CargoOrderData(order.OrderId,
order.ProductId, spaceRemaining, order.Requester, order.Reason); order.ProductId, order.Price, spaceRemaining, order.Requester, order.Reason);
orders.Add(reducedOrder); orders.Add(reducedOrder);
} }
else else
@@ -335,7 +326,7 @@ public sealed partial class CargoSystem
} }
SellPallets(gridUid, out var price); SellPallets(gridUid, out var price);
var stackPrototype = _prototypeManager.Index<StackPrototype>(component.CashType); var stackPrototype = _protoMan.Index<StackPrototype>(component.CashType);
_stack.Spawn((int)price, stackPrototype, uid.ToCoordinates()); _stack.Spawn((int)price, stackPrototype, uid.ToCoordinates());
UpdatePalletConsoleInterface(uid); UpdatePalletConsoleInterface(uid);
} }

View File

@@ -12,9 +12,6 @@ namespace Content.Server.Cargo.Systems;
public sealed partial class CargoSystem public sealed partial class CargoSystem
{ {
[Dependency] private readonly PaperSystem _paperSystem = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
private void InitializeTelepad() private void InitializeTelepad()
{ {
SubscribeLocalEvent<CargoTelepadComponent, ComponentInit>(OnInit); SubscribeLocalEvent<CargoTelepadComponent, ComponentInit>(OnInit);

View File

@@ -1,17 +1,46 @@
using Content.Server.Access.Systems;
using Content.Server.Cargo.Components; using Content.Server.Cargo.Components;
using Content.Server.DeviceLinking.Systems;
using Content.Server.Paper;
using Content.Server.Popups;
using Content.Server.Shuttles.Systems;
using Content.Server.Stack;
using Content.Server.Station.Systems; using Content.Server.Station.Systems;
using Content.Shared.Access.Systems;
using Content.Shared.Administration.Logs;
using Content.Shared.Cargo; using Content.Shared.Cargo;
using Content.Shared.Containers.ItemSlots; using Content.Shared.Containers.ItemSlots;
using JetBrains.Annotations; using JetBrains.Annotations;
using Robust.Server.GameObjects;
using Robust.Shared.Configuration;
using Robust.Shared.Map;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Random;
namespace Content.Server.Cargo.Systems; namespace Content.Server.Cargo.Systems;
public sealed partial class CargoSystem : SharedCargoSystem public sealed partial class CargoSystem : SharedCargoSystem
{ {
[Dependency] private readonly IComponentFactory _factory = default!;
[Dependency] private readonly IConfigurationManager _cfgManager = default!;
[Dependency] private readonly IMapManager _mapManager = default!;
[Dependency] private readonly IPrototypeManager _protoMan = default!; [Dependency] private readonly IPrototypeManager _protoMan = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
[Dependency] private readonly AccessReaderSystem _accessReaderSystem = default!;
[Dependency] private readonly DeviceLinkSystem _linker = default!;
[Dependency] private readonly EntityLookupSystem _lookup = default!;
[Dependency] private readonly IdCardSystem _idCardSystem = default!;
[Dependency] private readonly ItemSlotsSystem _slots = default!; [Dependency] private readonly ItemSlotsSystem _slots = default!;
[Dependency] private readonly PaperSystem _paperSystem = default!;
[Dependency] private readonly PopupSystem _popup = default!;
[Dependency] private readonly PricingSystem _pricing = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly ShuttleConsoleSystem _console = default!;
[Dependency] private readonly StackSystem _stack = default!;
[Dependency] private readonly StationSystem _station = default!;
[Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
private ISawmill _sawmill = default!; private ISawmill _sawmill = default!;

View File

@@ -1,6 +1,8 @@
using Content.Shared.Random;
using Content.Shared.Salvage; using Content.Shared.Salvage;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Server.Salvage.Expeditions; namespace Content.Server.Salvage.Expeditions;
@@ -27,7 +29,7 @@ public sealed class SalvageExpeditionComponent : Component
/// <summary> /// <summary>
/// Station whose mission this is. /// Station whose mission this is.
/// </summary> /// </summary>
[ViewVariables, DataField("station")] [DataField("station")]
public EntityUid Station; public EntityUid Station;
[ViewVariables] public bool Completed = false; [ViewVariables] public bool Completed = false;
@@ -48,6 +50,12 @@ public sealed class SalvageExpeditionComponent : Component
{ {
Params = AudioParams.Default.WithVolume(-15), Params = AudioParams.Default.WithVolume(-15),
}; };
/// <summary>
/// The difficulty this mission had or, in the future, was selected.
/// </summary>
[ViewVariables(VVAccess.ReadWrite), DataField("difficulty")]
public DifficultyRating Difficulty;
} }
public enum ExpeditionStage : byte public enum ExpeditionStage : byte

View File

@@ -1,13 +1,17 @@
using System.Linq; using Content.Server.Cargo.Components;
using System.Threading; using Content.Server.Cargo.Systems;
using Robust.Shared.CPUJob.JobQueues;
using Robust.Shared.CPUJob.JobQueues.Queues;
using Content.Server.Salvage.Expeditions; using Content.Server.Salvage.Expeditions;
using Content.Server.Salvage.Expeditions.Structure; using Content.Server.Salvage.Expeditions.Structure;
using Content.Server.Station.Systems; using Content.Server.Station.Systems;
using Content.Shared.CCVar; using Content.Shared.CCVar;
using Content.Shared.Random;
using Content.Shared.Random.Helpers;
using Content.Shared.Examine; using Content.Shared.Examine;
using Content.Shared.Salvage; using Content.Shared.Salvage;
using Robust.Shared.CPUJob.JobQueues;
using Robust.Shared.CPUJob.JobQueues.Queues;
using System.Linq;
using System.Threading;
namespace Content.Server.Salvage; namespace Content.Server.Salvage;
@@ -17,6 +21,8 @@ public sealed partial class SalvageSystem
* Handles setup / teardown of salvage expeditions. * Handles setup / teardown of salvage expeditions.
*/ */
[Dependency] private readonly CargoSystem _cargo = default!;
private const int MissionLimit = 5; private const int MissionLimit = 5;
private readonly JobQueue _salvageQueue = new(); private readonly JobQueue _salvageQueue = new();
@@ -99,7 +105,7 @@ public sealed partial class SalvageSystem
// Finish mission // Finish mission
if (TryComp<SalvageExpeditionDataComponent>(component.Station, out var data)) if (TryComp<SalvageExpeditionDataComponent>(component.Station, out var data))
{ {
FinishExpedition(data, component, null); FinishExpedition(data, uid, component, null);
} }
} }
@@ -141,7 +147,7 @@ public sealed partial class SalvageSystem
} }
} }
private void FinishExpedition(SalvageExpeditionDataComponent component, SalvageExpeditionComponent expedition, EntityUid? shuttle) private void FinishExpedition(SalvageExpeditionDataComponent component, EntityUid uid, SalvageExpeditionComponent expedition, EntityUid? shuttle)
{ {
// Finish mission cleanup. // Finish mission cleanup.
switch (expedition.MissionParams.MissionType) switch (expedition.MissionParams.MissionType)
@@ -150,7 +156,7 @@ public sealed partial class SalvageSystem
case SalvageMissionType.Mining: case SalvageMissionType.Mining:
expedition.Completed = true; expedition.Completed = true;
if (shuttle != null && TryComp<SalvageMiningExpeditionComponent>(expedition.Owner, out var mining)) if (shuttle != null && TryComp<SalvageMiningExpeditionComponent>(uid, out var mining))
{ {
var xformQuery = GetEntityQuery<TransformComponent>(); var xformQuery = GetEntityQuery<TransformComponent>();
var entities = new List<EntityUid>(); var entities = new List<EntityUid>();
@@ -169,18 +175,19 @@ public sealed partial class SalvageSystem
break; break;
} }
// Payout already handled elsewhere. // Handle payout after expedition has finished
if (expedition.Completed) if (expedition.Completed)
{ {
_sawmill.Debug($"Completed mission {expedition.MissionParams.MissionType} with seed {expedition.MissionParams.Seed}"); _sawmill.Debug($"Completed mission {expedition.MissionParams.MissionType} with seed {expedition.MissionParams.Seed}");
component.NextOffer = _timing.CurTime + TimeSpan.FromSeconds(_cooldown); component.NextOffer = _timing.CurTime + TimeSpan.FromSeconds(_cooldown);
Announce(expedition.Owner, Loc.GetString("salvage-expedition-mission-completed")); Announce(uid, Loc.GetString("salvage-expedition-mission-completed"));
GiveRewards(expedition);
} }
else else
{ {
_sawmill.Debug($"Failed mission {expedition.MissionParams.MissionType} with seed {expedition.MissionParams.Seed}"); _sawmill.Debug($"Failed mission {expedition.MissionParams.MissionType} with seed {expedition.MissionParams.Seed}");
component.NextOffer = _timing.CurTime + TimeSpan.FromSeconds(_failedCooldown); component.NextOffer = _timing.CurTime + TimeSpan.FromSeconds(_failedCooldown);
Announce(expedition.Owner, Loc.GetString("salvage-expedition-mission-failed")); Announce(uid, Loc.GetString("salvage-expedition-mission-failed"));
} }
component.ActiveMission = 0; component.ActiveMission = 0;
@@ -270,4 +277,51 @@ public sealed partial class SalvageSystem
{ {
args.PushMarkup(Loc.GetString("salvage-expedition-structure-examine")); args.PushMarkup(Loc.GetString("salvage-expedition-structure-examine"));
} }
private void GiveRewards(SalvageExpeditionComponent comp)
{
// send it to cargo, no rewards otherwise.
if (!TryComp<StationCargoOrderDatabaseComponent>(comp.Station, out var cargoDb))
{
return;
}
var ids = RewardsForDifficulty(comp.Difficulty);
foreach (var id in ids)
{
// pick a random reward to give
var rewards = _prototypeManager.Index<WeightedRandomPrototype>(id);
var reward = rewards.Pick(_random);
var sender = Loc.GetString("cargo-gift-default-sender");
var desc = Loc.GetString("salvage-expedition-reward-description");
var dest = Loc.GetString("cargo-gift-default-dest");
_cargo.AddAndApproveOrder(cargoDb, reward, 0, 1, sender, desc, dest);
}
}
/// <summary>
/// Get a list of WeightedRandomPrototype IDs with the rewards for a certain difficulty.
/// </summary>
private string[] RewardsForDifficulty(DifficultyRating rating)
{
var common = "SalvageRewardCommon";
var rare = "SalvageRewardRare";
var epic = "SalvageRewardEpic";
switch (rating)
{
case DifficultyRating.Minimal:
return new string[] { common, common, common };
case DifficultyRating.Minor:
return new string[] { common, common, rare };
case DifficultyRating.Moderate:
return new string[] { common, rare, rare };
case DifficultyRating.Hazardous:
return new string[] { rare, rare, epic };
case DifficultyRating.Extreme:
return new string[] { rare, epic, epic };
default:
throw new NotImplementedException();
}
}
} }

View File

@@ -163,8 +163,7 @@ public sealed partial class SalvageSystem
else if (comp.Stage < ExpeditionStage.MusicCountdown && remaining < TimeSpan.FromMinutes(2)) else if (comp.Stage < ExpeditionStage.MusicCountdown && remaining < TimeSpan.FromMinutes(2))
{ {
// TODO: Some way to play audio attached to a map for players. // TODO: Some way to play audio attached to a map for players.
comp.Stream = _audio.PlayGlobal(comp.Sound, comp.Stream = _audio.PlayGlobal(comp.Sound, Filter.BroadcastMap(Comp<MapComponent>(uid).MapId), true);
Filter.BroadcastMap(Comp<MapComponent>(uid).MapId), true);
comp.Stage = ExpeditionStage.MusicCountdown; comp.Stage = ExpeditionStage.MusicCountdown;
Announce(uid, Loc.GetString("salvage-expedition-announcement-countdown-minutes", ("duration", TimeSpan.FromMinutes(2).Minutes))); Announce(uid, Loc.GetString("salvage-expedition-announcement-countdown-minutes", ("duration", TimeSpan.FromMinutes(2).Minutes)));
} }
@@ -209,7 +208,7 @@ public sealed partial class SalvageSystem
} }
} }
// Mining missions: NOOP // Mining missions: NOOP since it's handled after ftling
// Structure missions // Structure missions
var structureQuery = EntityQueryEnumerator<SalvageStructureExpeditionComponent, SalvageExpeditionComponent>(); var structureQuery = EntityQueryEnumerator<SalvageStructureExpeditionComponent, SalvageExpeditionComponent>();

View File

@@ -133,6 +133,7 @@ public sealed class SpawnSalvageMissionJob : Job<bool>
expedition.Station = Station; expedition.Station = Station;
expedition.EndTime = _timing.CurTime + mission.Duration; expedition.EndTime = _timing.CurTime + mission.Duration;
expedition.MissionParams = _missionParams; expedition.MissionParams = _missionParams;
expedition.Difficulty = _missionParams.Difficulty;
// Don't want consoles to have the incorrect name until refreshed. // Don't want consoles to have the incorrect name until refreshed.
var ftlUid = _entManager.CreateEntityUninitialized("FTLPoint", new EntityCoordinates(mapUid, Vector2.Zero)); var ftlUid = _entManager.CreateEntityUninitialized("FTLPoint", new EntityCoordinates(mapUid, Vector2.Zero));

View File

@@ -68,7 +68,16 @@ public sealed class CargoGiftsRule : StationEventSystem<CargoGiftsRuleComponent>
var (productId, qty) = component.Gifts.First(); var (productId, qty) = component.Gifts.First();
component.Gifts.Remove(productId); component.Gifts.Remove(productId);
if (!_cargoSystem.AddAndApproveOrder(cargoDb, productId, qty, Loc.GetString(component.Sender), Loc.GetString(component.Description), Loc.GetString(component.Dest))) var product = _prototypeManager.Index<CargoProductPrototype>(productId);
if (!_cargoSystem.AddAndApproveOrder(
cargoDb,
product.Product,
product.PointCost,
qty,
Loc.GetString(component.Sender),
Loc.GetString(component.Description),
Loc.GetString(component.Dest)))
{ {
break; break;
} }

View File

@@ -6,13 +6,18 @@ namespace Content.Shared.Cargo
[NetSerializable, Serializable] [NetSerializable, Serializable]
public sealed class CargoOrderData public sealed class CargoOrderData
{ {
/// <summary>
/// Price when the order was added.
/// </summary>
public int Price;
/// <summary> /// <summary>
/// A unique (arbitrary) ID which identifies this order. /// A unique (arbitrary) ID which identifies this order.
/// </summary> /// </summary>
public readonly int OrderId; public readonly int OrderId;
/// <summary> /// <summary>
/// Prototype id for the item to create /// Prototype Id for the item to be created
/// </summary> /// </summary>
public readonly string ProductId; public readonly string ProductId;
@@ -24,7 +29,7 @@ namespace Content.Shared.Cargo
/// <summary> /// <summary>
/// How many instances of this order that we've already dispatched /// How many instances of this order that we've already dispatched
/// <summary> /// </summary>
public int NumDispatched = 0; public int NumDispatched = 0;
public readonly string Requester; public readonly string Requester;
@@ -34,25 +39,26 @@ namespace Content.Shared.Cargo
public bool Approved => Approver is not null; public bool Approved => Approver is not null;
public string? Approver; public string? Approver;
public CargoOrderData(int orderId, string productId, int amount, string requester, string reason) public CargoOrderData(int orderId, string productId, int price, int amount, string requester, string reason)
{ {
OrderId = orderId; OrderId = orderId;
ProductId = productId; ProductId = productId;
Price = price;
OrderQuantity = amount; OrderQuantity = amount;
Requester = requester; Requester = requester;
Reason = reason; Reason = reason;
} }
public void SetApproverData(IdCardComponent? idCard) public void SetApproverData(string? fullName, string? jobTitle)
{ {
var sb = new StringBuilder(); var sb = new StringBuilder();
if (!string.IsNullOrWhiteSpace(idCard?.FullName)) if (!string.IsNullOrWhiteSpace(fullName))
{ {
sb.Append($"{idCard.FullName} "); sb.Append($"{fullName} ");
} }
if (!string.IsNullOrWhiteSpace(idCard?.JobTitle)) if (!string.IsNullOrWhiteSpace(jobTitle))
{ {
sb.Append($"({idCard.JobTitle})"); sb.Append($"({jobTitle})");
} }
Approver = sb.ToString(); Approver = sb.ToString();
} }

View File

@@ -10,14 +10,14 @@ public sealed class CargoConsoleAddOrderMessage : BoundUserInterfaceMessage
{ {
public string Requester; public string Requester;
public string Reason; public string Reason;
public string ProductId; public string CargoProductId;
public int Amount; public int Amount;
public CargoConsoleAddOrderMessage(string requester, string reason, string productId, int amount) public CargoConsoleAddOrderMessage(string requester, string reason, string cargoProductId, int amount)
{ {
Requester = requester; Requester = requester;
Reason = reason; Reason = reason;
ProductId = productId; CargoProductId = cargoProductId;
Amount = amount; Amount = amount;
} }
} }

View File

@@ -46,3 +46,4 @@ salvage-expedition-announcement-countdown-minutes = {$duration} minutes remainin
salvage-expedition-announcement-countdown-seconds = {$duration} seconds remaining to complete the expedition. salvage-expedition-announcement-countdown-seconds = {$duration} seconds remaining to complete the expedition.
salvage-expedition-announcement-dungeon = Dungeon is located {$direction}. salvage-expedition-announcement-dungeon = Dungeon is located {$direction}.
salvage-expedition-completed = Expedition is completed. salvage-expedition-completed = Expedition is completed.
salvage-expedition-reward-description = Mission completion reward

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -67,27 +67,60 @@
offset: 0.0 offset: 0.0
- type: entity - type: entity
name: Salvage T3/4 Machine Parts Spawner
id: SalvagePartsT3Spawner
parent: MarkerBase parent: MarkerBase
id: SalvagePartsT3T4Spawner
name: tier 3/4 machine part
components: components:
- type: Sprite - type: Sprite
layers: layers:
- state: red - sprite: Objects/Misc/stock_parts.rsi
- sprite: Objects/Misc/stock_parts.rsi state: super_matter_bin
state: super_matter_bin - type: RandomSpawner
- type: RandomSpawner rarePrototypes:
rarePrototypes: - QuadraticCapacitorStockPart
- QuadraticCapacitorStockPart - FemtoManipulatorStockPart
- FemtoManipulatorStockPart - BluespaceMatterBinStockPart
- BluespaceMatterBinStockPart rareChance: 0.05
rareChance: 0.05 prototypes:
prototypes: - SuperCapacitorStockPart
- SuperCapacitorStockPart - PicoManipulatorStockPart
- PicoManipulatorStockPart - SuperMatterBinStockPart
- SuperMatterBinStockPart chance: 0.95
chance: 0.95 offset: 0.0
offset: 0.0
- type: entity
parent: MarkerBase
id: SalvagePartsT3Spawner
name: tier 3 machine part
suffix: Spawner
components:
- type: Sprite
layers:
- sprite: Objects/Misc/stock_parts.rsi
state: super_matter_bin
- type: RandomSpawner
prototypes:
- SuperCapacitorStockPart
- PicoManipulatorStockPart
- SuperMatterBinStockPart
offset: 0.0
- type: entity
parent: MarkerBase
id: SalvagePartsT4Spawner
name: tier 4 machine part
suffix: Spawner
components:
- type: Sprite
layers:
- sprite: Objects/Misc/stock_parts.rsi
state: bluespace_matter_bin
- type: RandomSpawner
prototypes:
- QuadraticCapacitorStockPart
- PicoManipulatorStockPart
- BluespaceMatterBinStockPart
offset: 0.0
- type: entity - type: entity
name: Salvage Mob Spawner name: Salvage Mob Spawner

View File

@@ -238,3 +238,19 @@
- type: Tag - type: Tag
tags: tags:
- Bottle - Bottle
- type: entity
parent: BaseChemistryEmptyBottle
id: CognizineChemistryBottle
name: cognizine bottle
components:
- type: SolutionContainerManager
solutions:
drink:
maxVol: 30
reagents:
- ReagentId: Cognizine
Quantity: 30
- type: Tag
tags:
- Bottle

View File

@@ -0,0 +1,61 @@
- type: weightedRandom
id: SalvageRewardCommon
weights:
# basic materials
CrateMaterialGlass: 1.0
CrateMaterialPlasteel: 1.0
CrateMaterialPlastic: 1.0
CrateMaterialSteel: 1.0
# things the station might want
CrateEngineeringAMEJar: 0.25
CrateFoodPizzaLarge: 0.25
CrateFoodSoftdrinks: 0.25
CrateFunATV: 0.25
CrateFunInstrumentsVariety: 0.25
CrateSalvageEquipment: 0.25
RandomArtifactSpawner: 0.25
# weighted down since it sells for a lot
NuclearBombKeg: 0.1
- type: weightedRandom
id: SalvageRewardRare
weights:
# rare materials
IngotGold: 1.0
IngotSilver: 1.0
SheetPlasma: 1.0
SheetUranium: 1.0
SalvagePartsT3Spawner: 1.0
SalvagePartsT3T4Spawner: 1.0
# things the expedition team might want
CrateEmergencyBruteKit: 0.5
CrateMedicalSupplies: 0.5
CrateSecurityRiot: 0.5
# cloning boards
CloningPodMachineCircuitboard: 0.5
MedicalScannerMachineCircuitboard: 0.5
CloningConsoleComputerCircuitboard: 0.5
# basic weapons
CrateArmorySMG: 0.25
CrateArmoryLaser: 0.25
WeaponMakeshiftLaser: 0.25
# rare weapons
WeaponSubMachineGunC20r: 0.1
- type: weightedRandom
id: SalvageRewardEpic
weights:
# rare machinery
SecurityTechFabCircuitboard: 1.0
ResearchAndDevelopmentServerMachineCircuitboard: 1.0
SalvagePartsT4Spawner: 1.0
# rare weapons
WeaponAdvancedLaser: 1.0
WeaponLaserCannon: 1.0
WeaponXrayCannon: 1.0
WeaponSniperHristov: 1.0
# extremely rare weapons
WeaponLauncherRocket: 0.1
# rare chemicals
CognizineChemistryBottle: 1.0
OmnizineChemistryBottle: 1.0