diff --git a/Content.Client/_NF/Trade/TradeCrateVisualizerSystem.cs b/Content.Client/_NF/Trade/TradeCrateVisualizerSystem.cs
new file mode 100644
index 00000000000..52ad24983c3
--- /dev/null
+++ b/Content.Client/_NF/Trade/TradeCrateVisualizerSystem.cs
@@ -0,0 +1,52 @@
+using Content.Shared._NF.Trade;
+using Robust.Client.GameObjects;
+using Robust.Shared.Prototypes;
+
+namespace Content.Client._NF.Trade;
+
+///
+/// Visualizer for trade crates, largely based on Nyano's mail visualizer (thank you)
+///
+public sealed class TradeCrateVisualizerSystem : VisualizerSystem
+{
+ [Dependency] private readonly IPrototypeManager _proto = default!;
+ [Dependency] private readonly SharedAppearanceSystem _appearance = default!;
+ [Dependency] private readonly SpriteSystem _sprite = default!;
+
+ private const string FallbackIconID = "CargoOther";
+ private const string CargoPriorityActiveState = "cargo_priority_active";
+ private const string CargoPriorityInactiveState = "cargo_priority_inactive";
+
+ protected override void OnAppearanceChange(EntityUid uid, TradeCrateComponent component, ref AppearanceChangeEvent args)
+ {
+ if (args.Sprite == null)
+ return;
+
+ _appearance.TryGetData(uid, TradeCrateVisuals.DestinationIcon, out string job, args.Component);
+
+ if (string.IsNullOrEmpty(job))
+ job = FallbackIconID;
+
+ if (!_proto.TryIndex(job, out var icon))
+ icon = _proto.Index(FallbackIconID);
+
+ args.Sprite.LayerSetTexture(TradeCrateVisualLayers.Icon, _sprite.Frame0(icon.Icon));
+ args.Sprite.LayerSetVisible(TradeCrateVisualLayers.Icon, true);
+ if (_appearance.TryGetData(uid, TradeCrateVisuals.IsPriority, out bool isPriority) && isPriority)
+ {
+ args.Sprite.LayerSetVisible(TradeCrateVisualLayers.Priority, true);
+ if (_appearance.TryGetData(uid, TradeCrateVisuals.IsPriorityInactive, out bool inactive) && inactive)
+ args.Sprite.LayerSetState(TradeCrateVisualLayers.Priority, CargoPriorityInactiveState);
+ else
+ args.Sprite.LayerSetState(TradeCrateVisualLayers.Priority, CargoPriorityActiveState);
+ }
+ else
+ args.Sprite.LayerSetVisible(TradeCrateVisualLayers.Priority, false);
+ }
+}
+
+public enum TradeCrateVisualLayers : byte
+{
+ Icon,
+ Priority
+}
diff --git a/Content.Server/Cargo/Systems/CargoSystem.Shuttle.cs b/Content.Server/Cargo/Systems/CargoSystem.Shuttle.cs
index 2270374fb86..d77a409f6cc 100644
--- a/Content.Server/Cargo/Systems/CargoSystem.Shuttle.cs
+++ b/Content.Server/Cargo/Systems/CargoSystem.Shuttle.cs
@@ -1,16 +1,16 @@
using Content.Server.Cargo.Components;
using Content.Shared.Stacks;
-using Content.Shared.Bank.Components;
using Content.Shared.Cargo;
using Content.Shared.Cargo.BUI;
using Content.Shared.Cargo.Components;
using Content.Shared.Cargo.Events;
using Content.Shared.GameTicking;
-using Content.Shared.Mobs;
using Robust.Shared.Map;
using Robust.Shared.Random;
using Robust.Shared.Audio;
-using Content.Shared.Mind.Components; // Frontier
+using Content.Server._NF.Cargo.Components; // Frontier
+using Content.Shared.Bank.Components; // Frontier
+using Content.Shared.Mobs; // Frontier
namespace Content.Server.Cargo.Systems;
@@ -67,11 +67,14 @@ private void UpdatePalletConsoleInterface(EntityUid uid)
new CargoPalletConsoleInterfaceState(0, 0, false));
return;
}
- GetPalletGoods(uid, gridUid, out var toSell, out var amount);
+ GetPalletGoods(uid, gridUid, out var toSell, out var amount, out var noModAmount); // Frontier: add noModAmount
+ // Frontier
if (TryComp(uid, out var priceMod))
{
amount *= priceMod.Mod;
}
+ amount += noModAmount;
+ // End Frontier
_uiSystem.SetUiState(uid, CargoPalletConsoleUiKey.Sale,
new CargoPalletConsoleInterfaceState((int) amount, toSell.Count, true));
}
@@ -259,11 +262,11 @@ public static double CalculateDistance(EntityCoordinates point1, EntityCoordinat
#region Station
- private bool SellPallets(EntityUid consoleUid, EntityUid gridUid, out double amount)
+ private bool SellPallets(EntityUid consoleUid, EntityUid gridUid, out double amount, out double noMultiplierAmount) // Frontier: add noMultiplierAmount
{
- GetPalletGoods(consoleUid, gridUid, out var toSell, out amount);
+ GetPalletGoods(consoleUid, gridUid, out var toSell, out amount, out noMultiplierAmount); // Frontier: add noMultiplierAmount
- Log.Debug($"Cargo sold {toSell.Count} entities for {amount}");
+ Log.Debug($"Cargo sold {toSell.Count} entities for {amount} (plus {noMultiplierAmount} without mods)"); // Frontier: add section in parentheses
if (toSell.Count == 0)
return false;
@@ -280,9 +283,10 @@ private bool SellPallets(EntityUid consoleUid, EntityUid gridUid, out double amo
return true;
}
- private void GetPalletGoods(EntityUid consoleUid, EntityUid gridUid, out HashSet toSell, out double amount)
+ private void GetPalletGoods(EntityUid consoleUid, EntityUid gridUid, out HashSet toSell, out double amount, out double noMultiplierAmount) // Frontier: add noMultiplierAmount
{
amount = 0;
+ noMultiplierAmount = 0;
toSell = new HashSet();
foreach (var (palletUid, _, _) in GetCargoPallets(consoleUid, gridUid, BuySellType.Sell))
@@ -313,7 +317,13 @@ private void GetPalletGoods(EntityUid consoleUid, EntityUid gridUid, out HashSet
if (price == 0)
continue;
toSell.Add(ent);
- amount += price;
+
+ // Frontier: check for items that are immune to market modifiers
+ if (HasComp(ent))
+ noMultiplierAmount += price;
+ else
+ amount += price;
+ // End Frontier: check for items that are immune to market modifiers
}
}
}
@@ -356,13 +366,16 @@ private void OnPalletSale(EntityUid uid, CargoPalletConsoleComponent component,
return;
}
- if (!SellPallets(uid, gridUid, out var price))
+ if (!SellPallets(uid, gridUid, out var price, out var noMultiplierPrice)) // Frontier: add noMultiplierPrice
return;
+ // Frontier: market modifiers & immune objects
if (TryComp(uid, out var priceMod))
{
price *= priceMod.Mod;
}
+ price += noMultiplierPrice;
+ // End Frontier: market modifiers & immune objects
var stackPrototype = _protoMan.Index(component.CashType);
_stack.Spawn((int) price, stackPrototype, xform.Coordinates);
_audio.PlayPvs(ApproveSound, uid);
@@ -374,6 +387,7 @@ private void OnPalletSale(EntityUid uid, CargoPalletConsoleComponent component,
private void OnRoundRestart(RoundRestartCleanupEvent ev)
{
Reset();
+ CleanupTradeCrateDestinations(); // Frontier
}
}
diff --git a/Content.Server/Cargo/Systems/CargoSystem.cs b/Content.Server/Cargo/Systems/CargoSystem.cs
index 5744584b839..8a8741bf06b 100644
--- a/Content.Server/Cargo/Systems/CargoSystem.cs
+++ b/Content.Server/Cargo/Systems/CargoSystem.cs
@@ -19,7 +19,7 @@
using Robust.Shared.Timing;
using Robust.Shared.Random;
using Content.Server._NF.SectorServices; // Frontier
-using Content.Shared._NF.Trade.Components; // Frontier
+using Content.Shared._NF.Trade; // Frontier
using Content.Shared.Whitelist; // Frontier
namespace Content.Server.Cargo.Systems;
@@ -50,7 +50,6 @@ public sealed partial class CargoSystem : SharedCargoSystem
private EntityQuery _xformQuery;
private EntityQuery _blacklistQuery;
- private EntityQuery _tradeCrateQuery;
private EntityQuery _mobQuery;
private EntityQuery _tradeQuery;
@@ -64,7 +63,6 @@ public override void Initialize()
_xformQuery = GetEntityQuery();
_blacklistQuery = GetEntityQuery();
- _tradeCrateQuery = GetEntityQuery();
_mobQuery = GetEntityQuery();
_tradeQuery = GetEntityQuery();
@@ -74,6 +72,7 @@ public override void Initialize()
InitializeBounty();
// Frontier: add specific initialization calls here.
InitializePirateBounty();
+ InitializeTradeCrates();
// End Frontier
}
diff --git a/Content.Server/_NF/Cargo/Components/IgnoreMarketModifierComponent.cs b/Content.Server/_NF/Cargo/Components/IgnoreMarketModifierComponent.cs
new file mode 100644
index 00000000000..f7c688b22eb
--- /dev/null
+++ b/Content.Server/_NF/Cargo/Components/IgnoreMarketModifierComponent.cs
@@ -0,0 +1,7 @@
+namespace Content.Server._NF.Cargo.Components;
+
+///
+/// Designates an entity as ignoring market modifiers.
+///
+[RegisterComponent]
+public sealed partial class IgnoreMarketModifierComponent : Component;
diff --git a/Content.Server/_NF/Cargo/Systems/CargoSystem.TradeCrates.cs b/Content.Server/_NF/Cargo/Systems/CargoSystem.TradeCrates.cs
new file mode 100644
index 00000000000..54c259ef5dd
--- /dev/null
+++ b/Content.Server/_NF/Cargo/Systems/CargoSystem.TradeCrates.cs
@@ -0,0 +1,111 @@
+using System.Threading;
+using Content.Server._NF.Trade;
+using Content.Shared._NF.Trade;
+using Content.Shared.Examine;
+using Timer = Robust.Shared.Timing.Timer;
+
+namespace Content.Server.Cargo.Systems; // Needs to collide with base namespace
+
+public sealed partial class CargoSystem
+{
+ private readonly List _destinations = new();
+
+ private void InitializeTradeCrates()
+ {
+ SubscribeLocalEvent(OnTradeCrateGetPriceEvent);
+ SubscribeLocalEvent(OnTradeCrateInit);
+ SubscribeLocalEvent(OnTradeCrateRemove);
+ SubscribeLocalEvent(OnTradeCrateExamined);
+
+ SubscribeLocalEvent(OnDestinationInit);
+ SubscribeLocalEvent(OnDestinationRemove);
+ }
+
+ private void OnTradeCrateGetPriceEvent(Entity ent, ref PriceCalculationEvent ev)
+ {
+ var owningStation = _station.GetOwningStation(ent);
+ var atDestination = ent.Comp.DestinationStation != EntityUid.Invalid
+ && owningStation == ent.Comp.DestinationStation
+ || HasComp(owningStation);
+ ev.Price = atDestination ? ent.Comp.ValueAtDestination : ent.Comp.ValueElsewhere;
+ if (ent.Comp.ExpressDeliveryTime != null)
+ {
+ if (_timing.CurTime <= ent.Comp.ExpressDeliveryTime && atDestination)
+ ev.Price += ent.Comp.ExpressOnTimeBonus;
+ else if (_timing.CurTime > ent.Comp.ExpressDeliveryTime)
+ ev.Price -= ent.Comp.ExpressLatePenalty;
+ }
+ ev.Price = double.Max(0.0, ev.Price); // Ensure non-negative values.
+ }
+
+ private void OnTradeCrateInit(Entity ent, ref ComponentInit ev)
+ {
+ // If there are no available destinations, tough luck.
+ if (_destinations.Count > 0)
+ {
+ var randomIndex = _random.Next(_destinations.Count);
+ // Better have more than one destination.
+ if (_station.GetOwningStation(ent) == _destinations[randomIndex])
+ {
+ randomIndex = (randomIndex + 1 + _random.Next(_destinations.Count - 1)) % _destinations.Count;
+ }
+ var destination = _destinations[randomIndex];
+ ent.Comp.DestinationStation = destination;
+ if (TryComp(destination, out var destComp))
+ _appearance.SetData(ent, TradeCrateVisuals.DestinationIcon, destComp.DestinationProto.Id);
+ }
+
+ if (ent.Comp.ExpressDeliveryDuration > TimeSpan.Zero)
+ {
+ ent.Comp.ExpressDeliveryTime = _timing.CurTime + ent.Comp.ExpressDeliveryDuration;
+ _appearance.SetData(ent, TradeCrateVisuals.IsPriority, true);
+
+ ent.Comp.ExpressCancelToken = new CancellationTokenSource();
+ Timer.Spawn((int)ent.Comp.ExpressDeliveryDuration.TotalMilliseconds,
+ () => DisableTradeCratePriority(ent),
+ ent.Comp.ExpressCancelToken.Token);
+ }
+ }
+
+ private void OnTradeCrateRemove(Entity ent, ref ComponentRemove ev)
+ {
+ ent.Comp.ExpressCancelToken?.Cancel();
+ }
+
+ // TODO: move to shared, share delivery time?
+ private void OnTradeCrateExamined(Entity ent, ref ExaminedEvent ev)
+ {
+ if (!TryComp(ent.Comp.DestinationStation, out MetaDataComponent? metadata))
+ return;
+
+ ev.PushMarkup(Loc.GetString("trade-crate-destination-station", ("destination", metadata.EntityName)));
+
+ if (ent.Comp.ExpressDeliveryTime == null)
+ return;
+
+ ev.PushMarkup(ent.Comp.ExpressDeliveryTime >= _timing.CurTime ?
+ Loc.GetString("trade-crate-priority-active") :
+ Loc.GetString("trade-crate-priority-inactive"));
+ }
+
+ private void DisableTradeCratePriority(EntityUid uid)
+ {
+ _appearance.SetData(uid, TradeCrateVisuals.IsPriorityInactive, true);
+ }
+
+ private void OnDestinationInit(Entity ent, ref ComponentInit ev)
+ {
+ if (!_destinations.Contains(ent))
+ _destinations.Add(ent);
+ }
+
+ private void OnDestinationRemove(Entity ent, ref ComponentRemove ev)
+ {
+ _destinations.Remove(ent);
+ }
+
+ private void CleanupTradeCrateDestinations()
+ {
+ _destinations.Clear();
+ }
+}
diff --git a/Content.Server/_NF/GameRule/PointOfInterestSystem.cs b/Content.Server/_NF/GameRule/PointOfInterestSystem.cs
index f9a910027f9..507092d2517 100644
--- a/Content.Server/_NF/GameRule/PointOfInterestSystem.cs
+++ b/Content.Server/_NF/GameRule/PointOfInterestSystem.cs
@@ -1,8 +1,9 @@
using System.Linq;
using System.Numerics;
+using Content.Server._NF.Trade;
+using Content.Server.GameTicking;
using Content.Server.Maps;
using Content.Server.Station.Systems;
-using Content.Server.GameTicking;
using Content.Shared._NF.CCVar;
using Content.Shared.GameTicking;
using Robust.Server.GameObjects;
@@ -84,6 +85,15 @@ public void GenerateDepots(MapId mapUid, List depotPro
overrideName += $" {i + 1}"; // " 27", " 28"...
if (TrySpawnPoiGrid(mapUid, proto, offset, out var depotUid, overrideName: overrideName) && depotUid is { Valid: true } depot)
{
+ // Nasty jank: set up destination in the station.
+ var depotStation = _station.GetOwningStation(depot);
+ if (TryComp(depotStation, out var destComp))
+ {
+ if (i < 26)
+ destComp.DestinationProto = $"Cargo{(char)('A' + i)}";
+ else
+ destComp.DestinationProto = "CargoOther";
+ }
depotStations.Add(depot);
AddStationCoordsToSet(offset); // adjust list of actual station coords
}
diff --git a/Content.Server/_NF/Trade/TradeCrateDestinationComponent.cs b/Content.Server/_NF/Trade/TradeCrateDestinationComponent.cs
new file mode 100644
index 00000000000..07f7a9f9d76
--- /dev/null
+++ b/Content.Server/_NF/Trade/TradeCrateDestinationComponent.cs
@@ -0,0 +1,14 @@
+using Content.Shared._NF.Trade;
+using Robust.Shared.Prototypes;
+
+namespace Content.Server._NF.Trade;
+
+///
+/// This is used to mark an entity to be used as a destination for trade crates.
+///
+[RegisterComponent]
+public sealed partial class TradeCrateDestinationComponent : Component
+{
+ [DataField(required: true)]
+ public ProtoId DestinationProto;
+}
diff --git a/Content.Server/_NF/Trade/TradeCrateWildcardDestinationComponent.cs b/Content.Server/_NF/Trade/TradeCrateWildcardDestinationComponent.cs
new file mode 100644
index 00000000000..a2055eb51d4
--- /dev/null
+++ b/Content.Server/_NF/Trade/TradeCrateWildcardDestinationComponent.cs
@@ -0,0 +1,8 @@
+namespace Content.Server._NF.Trade;
+
+///
+/// This marks a station as matching all trade crate destinations.
+/// Useful, for example, for black market stations or pirate coves.
+///
+[RegisterComponent]
+public sealed partial class TradeCrateWildcardDestinationComponent : Component;
diff --git a/Content.Shared/Access/Systems/AccessReaderSystem.cs b/Content.Shared/Access/Systems/AccessReaderSystem.cs
index d43e14daadd..2b0143d995f 100644
--- a/Content.Shared/Access/Systems/AccessReaderSystem.cs
+++ b/Content.Shared/Access/Systems/AccessReaderSystem.cs
@@ -16,7 +16,7 @@
using Robust.Shared.Collections;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
-using Content.Shared._NF.Trade.Components;
+using Content.Shared._NF.Trade;
namespace Content.Shared.Access.Systems;
diff --git a/Content.Shared/Lock/LockSystem.cs b/Content.Shared/Lock/LockSystem.cs
index b9a3c3fa290..531b852bef8 100644
--- a/Content.Shared/Lock/LockSystem.cs
+++ b/Content.Shared/Lock/LockSystem.cs
@@ -16,10 +16,7 @@
using JetBrains.Annotations;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Utility;
-using Content.Shared._NF.Trade.Components;
using Content.Shared.Emag.Components;
-using System.Text;
-using Content.Shared.Storage;
using Robust.Shared.Audio; // Frontier - DEMAG
namespace Content.Shared.Lock;
diff --git a/Content.Shared/_NF/Trade/TradeCrateComponent.cs b/Content.Shared/_NF/Trade/TradeCrateComponent.cs
index 03fdcedd15c..01dbf1f7816 100644
--- a/Content.Shared/_NF/Trade/TradeCrateComponent.cs
+++ b/Content.Shared/_NF/Trade/TradeCrateComponent.cs
@@ -1,9 +1,59 @@
-namespace Content.Shared._NF.Trade.Components;
+using System.Threading;
+using Content.Shared.Cargo;
+using Robust.Shared.GameStates;
+
+namespace Content.Shared._NF.Trade;
///
-/// This is used to mark an entity to be used in a trade crates
+/// This is used to mark an entity to be used as a trade crate
///
-[RegisterComponent]
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentPause, Access(typeof(SharedCargoSystem))]
public sealed partial class TradeCrateComponent : Component
{
+ ///
+ /// The value of the crate, in spesos, when delivered to its destination.
+ ///
+ [DataField(serverOnly: true)]
+ public int ValueAtDestination;
+
+ ///
+ /// The value of the crate, in spesos, when delivered elsewhere.
+ ///
+ [DataField(serverOnly: true)]
+ public int ValueElsewhere;
+
+ ///
+ /// If non-zero, this crate will be an express delivery.
+ ///
+ [DataField(serverOnly: true)]
+ public TimeSpan ExpressDeliveryDuration = TimeSpan.Zero;
+
+ ///
+ /// If non-null, the package must be redeemed before this time to arrive unpenalized.
+ ///
+ [ViewVariables, AutoPausedField]
+ public TimeSpan? ExpressDeliveryTime;
+
+ ///
+ /// The bonus this package will receive if delivered on-time.
+ ///
+ [DataField(serverOnly: true)]
+ public int ExpressOnTimeBonus;
+
+ ///
+ /// The penalty this package will receive if delivered late.
+ ///
+ [DataField(serverOnly: true)]
+ public int ExpressLatePenalty;
+
+ ///
+ /// This crate's destination.
+ ///
+ [ViewVariables]
+ public EntityUid DestinationStation;
+
+ ///
+ /// Cancellation token used to disable the express marker on the crate.
+ ///
+ public CancellationTokenSource? ExpressCancelToken;
}
diff --git a/Content.Shared/_NF/Trade/TradeCrateDestinationPrototype.cs b/Content.Shared/_NF/Trade/TradeCrateDestinationPrototype.cs
new file mode 100644
index 00000000000..085a37038f7
--- /dev/null
+++ b/Content.Shared/_NF/Trade/TradeCrateDestinationPrototype.cs
@@ -0,0 +1,22 @@
+using Robust.Shared.Prototypes;
+using Robust.Shared.Utility;
+
+namespace Content.Shared._NF.Trade;
+
+///
+/// A data structure that holds relevant
+/// information for trade crates (status icons).
+///
+[Prototype]
+public sealed partial class TradeCrateDestinationPrototype : IPrototype
+{
+ ///
+ [IdDataField]
+ public string ID { get; private set; } = default!;
+
+ ///
+ /// The icon that's displayed on the entity.
+ ///
+ [DataField(required: true)]
+ public SpriteSpecifier Icon = default!;
+}
diff --git a/Content.Shared/_NF/Trade/TradeCrateVisuals.cs b/Content.Shared/_NF/Trade/TradeCrateVisuals.cs
new file mode 100644
index 00000000000..d4986b3d0c9
--- /dev/null
+++ b/Content.Shared/_NF/Trade/TradeCrateVisuals.cs
@@ -0,0 +1,14 @@
+using Robust.Shared.Serialization;
+
+namespace Content.Shared._NF.Trade;
+
+///
+/// Stores the visuals for trade crates.
+///
+[Serializable, NetSerializable]
+public enum TradeCrateVisuals : byte
+{
+ IsPriority,
+ IsPriorityInactive,
+ DestinationIcon,
+}
diff --git a/Resources/Locale/en-US/_NF/cargo/trade-crate.ftl b/Resources/Locale/en-US/_NF/cargo/trade-crate.ftl
new file mode 100644
index 00000000000..07f805082a4
--- /dev/null
+++ b/Resources/Locale/en-US/_NF/cargo/trade-crate.ftl
@@ -0,0 +1,3 @@
+trade-crate-destination-station = This crate's destination is [color=springgreen]{$destination}[/color].
+trade-crate-priority-active = This crate is an [color=yellow]express delivery[/color]. It's [bold]still on time[/bold]!
+trade-crate-priority-inactive = This crate is an [color=#886600]express delivery[/color]. It's [bold]late[/bold].
diff --git a/Resources/Locale/en-US/_NF/guidebook/guides.ftl b/Resources/Locale/en-US/_NF/guidebook/guides.ftl
index 4bb723f2702..713a93c4b38 100644
--- a/Resources/Locale/en-US/_NF/guidebook/guides.ftl
+++ b/Resources/Locale/en-US/_NF/guidebook/guides.ftl
@@ -5,6 +5,7 @@ guide-entry-piloting = Piloting
guide-entry-startinggear = Starting Equipment
guide-entry-hiring = Hiring Crew
guide-entry-expeditions = Expeditions
+guide-entry-cargo-hauling = Cargo Hauling
guide-entry-shipyard = Shipyard
guide-entry-frontier-rules = Server Rules
diff --git a/Resources/Maps/_NF/Shuttles/Scrap/scrap-courserx.yml b/Resources/Maps/_NF/Shuttles/Scrap/scrap-courserx.yml
index 2b2da744e4f..897a0e47354 100644
--- a/Resources/Maps/_NF/Shuttles/Scrap/scrap-courserx.yml
+++ b/Resources/Maps/_NF/Shuttles/Scrap/scrap-courserx.yml
@@ -1407,7 +1407,7 @@ entities:
- type: Transform
pos: -0.5,14.5
parent: 1
-- proto: CrateTradeSecureNormalFilled
+- proto: CrateTradeSecureNormal
entities:
- uid: 64
components:
diff --git a/Resources/Maps/_NF/Shuttles/Scrap/scrap-hauler.yml b/Resources/Maps/_NF/Shuttles/Scrap/scrap-hauler.yml
index 1ded56ba271..6d930e8cc95 100644
--- a/Resources/Maps/_NF/Shuttles/Scrap/scrap-hauler.yml
+++ b/Resources/Maps/_NF/Shuttles/Scrap/scrap-hauler.yml
@@ -1892,7 +1892,7 @@ entities:
- type: Transform
pos: 3.5,11.5
parent: 1
-- proto: CrateTradeSecureNormalFilled
+- proto: CrateTradeSecureNormal
entities:
- uid: 144
components:
diff --git a/Resources/Prototypes/_NF/Catalog/Cargo/cargo_trade.yml b/Resources/Prototypes/_NF/Catalog/Cargo/cargo_trade.yml
index d8985d039b8..5aa339d457e 100644
--- a/Resources/Prototypes/_NF/Catalog/Cargo/cargo_trade.yml
+++ b/Resources/Prototypes/_NF/Catalog/Cargo/cargo_trade.yml
@@ -3,7 +3,7 @@
icon:
sprite: _NF/Structures/Storage/Crates/tradedark.rsi
state: icon
- product: CrateTradeSecureNormalFilled
+ product: CrateTradeSecureNormal
cost: 1000
category: cargoproduct-category-name-cargo
group: market
@@ -13,7 +13,7 @@
icon:
sprite: _NF/Structures/Storage/Crates/tradelight.rsi
state: icon
- product: CrateTradeSecureHighFilled
+ product: CrateTradeSecureHigh
cost: 2000
category: cargoproduct-category-name-cargo
group: market
diff --git a/Resources/Prototypes/_NF/Catalog/Fills/Crates/trade.yml b/Resources/Prototypes/_NF/Catalog/Fills/Crates/trade.yml
deleted file mode 100644
index 5976e5983f9..00000000000
--- a/Resources/Prototypes/_NF/Catalog/Fills/Crates/trade.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-- type: entity
- id: CrateTradeSecureNormalFilled
- parent: CrateTradeBaseSecureNormal
- name: cargo trading crate
- description: Contains goods made in the Frontier sector, ready to be sold on a cargo depot for higher value. MAKE SURE THE CRATE IS INTACT.
-
-- type: entity
- id: CrateTradeSecureHighFilled
- parent: CrateTradeBaseSecureHigh
- name: high value cargo trading crate
- description: Contains high value goods made in the Frontier sector, ready to be sold on a cargo depot for higher value. MAKE SURE THE CRATE IS INTACT.
diff --git a/Resources/Prototypes/_NF/Entities/Markers/Spawners/Random/salvage.yml b/Resources/Prototypes/_NF/Entities/Markers/Spawners/Random/salvage.yml
index 2b765ff8072..b29bdd9f7eb 100644
--- a/Resources/Prototypes/_NF/Entities/Markers/Spawners/Random/salvage.yml
+++ b/Resources/Prototypes/_NF/Entities/Markers/Spawners/Random/salvage.yml
@@ -596,8 +596,8 @@
- NFCrateSalvageAssortedGoodiesTrashCart
chance: 0.95
rarePrototypes:
- - CrateTradeSecureNormalFilled
- - CrateTradeSecureHighFilled
+ - CrateTradeSecureNormal
+ - CrateTradeSecureHigh
- CrateSalvageEquipment
- CrateTrashCartFilled
- CrateArtifactContainer
diff --git a/Resources/Prototypes/_NF/Entities/Structures/Storage/Crates/base_structurecrates.yml b/Resources/Prototypes/_NF/Entities/Structures/Storage/Crates/base_structurecrates.yml
index 98923751383..bbb337c290e 100644
--- a/Resources/Prototypes/_NF/Entities/Structures/Storage/Crates/base_structurecrates.yml
+++ b/Resources/Prototypes/_NF/Entities/Structures/Storage/Crates/base_structurecrates.yml
@@ -4,11 +4,24 @@
categories: [ HideSpawnMenu ]
components:
- type: TradeCrate
+ valueAtDestination: 1500
+ valueElsewhere: 400
- type: AccessReader
access: [["NuclearOperative"]]
- type: Icon
sprite: Structures/Storage/Crates/secure.rsi
- state: icon
+ layers:
+ - state: icon
+ - sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_other
+ offset: 0.275,-0.265
+ map: ["enum.TradeCrateVisualLayers.Icon"]
+ visible: false
+ - sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_priority_inactive
+ offset: 0.025,-0.265
+ map: ["enum.TradeCrateVisualLayers.Priority"]
+ visible: false
- type: Sprite
sprite: Structures/Storage/Crates/secure.rsi
- type: Damageable
@@ -35,3 +48,7 @@
- type: SentienceTarget
flavorKind: station-event-random-sentience-flavor-inanimate
weight: 0.01 # 100 trade crates = 1 animal
+ - type: Appearance
+ - type: EntityStorage
+ capacity: 0 # stores nothing
+ - type: IgnoreMarketModifier
diff --git a/Resources/Prototypes/_NF/Entities/Structures/Storage/Crates/crates.yml b/Resources/Prototypes/_NF/Entities/Structures/Storage/Crates/crates.yml
index c6d9ee717ed..455ac0ab179 100644
--- a/Resources/Prototypes/_NF/Entities/Structures/Storage/Crates/crates.yml
+++ b/Resources/Prototypes/_NF/Entities/Structures/Storage/Crates/crates.yml
@@ -28,14 +28,30 @@
- type: entity
parent: CrateTradeBaseSecure
- id: CrateTradeBaseSecureNormal
- name: cargo steel crate
- categories: [ HideSpawnMenu ]
+ id: CrateTradeSecureNormal
+ name: cargo trading crate
+ description: Contains goods made in the Frontier sector, ready to be sold at a cargo depot for higher value. MAKE SURE THE CRATE IS INTACT.
components:
- type: Icon
sprite: _NF/Structures/Storage/Crates/tradedark.rsi
- type: Sprite
sprite: _NF/Structures/Storage/Crates/tradedark.rsi
+ layers:
+ - state: icon
+ - sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_other
+ offset: 0.275,-0.265
+ map: ["enum.TradeCrateVisualLayers.Icon"]
+ visible: false
+ - sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_priority_inactive
+ offset: 0.025,-0.265
+ map: ["enum.TradeCrateVisualLayers.Priority"]
+ visible: false
+ - state: paper
+ sprite: Structures/Storage/Crates/labels.rsi
+ offset: "-0.5,0"
+ map: ["enum.PaperLabelVisuals.Layer"]
- type: EntityStorage
deleteContentsOnDestruction: true
- type: Fixtures
@@ -49,19 +65,39 @@
- SmallMobMask
layer:
- MachineLayer
- - type: StaticPrice
- price: 1000
- type: entity
parent: CrateTradeBaseSecure
- id: CrateTradeBaseSecureHigh
- name: high value cargo steel crate
- categories: [ HideSpawnMenu ]
+ id: CrateTradeSecureHigh
+ name: express cargo trading crate
+ description: An urgent crate of goods made in the Frontier sector, ready to be quickly sold at a cargo depot for higher value. MAKE SURE THE CRATE IS INTACT.
components:
+ - type: TradeCrate
+ valueAtDestination: 2500
+ valueElsewhere: 1200
+ expressDeliveryDuration: 1500 # twenty-five minutes, go go (worst distance is ~6.5 km trade-cargo A, then 12 km to cargo b, 15.4 min at 20 m/s, giving ~10 minutes in adverse conditions for cargo pickup and dropoff)
+ expressOnTimeBonus: 1500
+ expressLatePenalty: 1500 # 0/1000
- type: Icon
sprite: _NF/Structures/Storage/Crates/tradelight.rsi
- type: Sprite
sprite: _NF/Structures/Storage/Crates/tradelight.rsi
+ layers:
+ - state: icon
+ - sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_other
+ offset: 0.275,-0.265
+ map: ["enum.TradeCrateVisualLayers.Icon"]
+ visible: false
+ - sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_priority_inactive
+ offset: 0.025,-0.265
+ map: ["enum.TradeCrateVisualLayers.Priority"]
+ visible: false
+ - state: paper
+ sprite: Structures/Storage/Crates/labels.rsi
+ offset: "-0.5,0"
+ map: ["enum.PaperLabelVisuals.Layer"]
- type: EntityStorage
deleteContentsOnDestruction: true
- type: Fixtures
@@ -75,8 +111,6 @@
- SmallMobMask
layer:
- MachineLayer
- - type: StaticPrice
- price: 2000
- type: entity
parent:
@@ -121,8 +155,25 @@
sprite: _NF/Structures/Storage/Crates/contraband1_crate.rsi
- type: Sprite
sprite: _NF/Structures/Storage/Crates/contraband1_crate.rsi
- - type: StaticPrice
- price: 3000
+ layers:
+ - state: icon
+ - sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_other
+ offset: 0.275,-0.265
+ map: ["enum.TradeCrateVisualLayers.Icon"]
+ visible: false
+ - sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_priority_inactive
+ offset: 0.025,-0.265
+ map: ["enum.TradeCrateVisualLayers.Priority"]
+ visible: false
+ - state: paper
+ sprite: Structures/Storage/Crates/labels.rsi
+ offset: "-0.5,0"
+ map: ["enum.PaperLabelVisuals.Layer"]
+ - type: TradeCrate
+ valueAtDestination: 5000
+ valueElsewhere: 2500
- type: entity
parent: CrateTradeBaseSecureContraband
@@ -133,8 +184,28 @@
sprite: _NF/Structures/Storage/Crates/contraband2_crate.rsi
- type: Sprite
sprite: _NF/Structures/Storage/Crates/contraband2_crate.rsi
- - type: StaticPrice
- price: 5000
+ layers:
+ - state: icon
+ - sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_other
+ offset: 0.275,-0.265
+ map: ["enum.TradeCrateVisualLayers.Icon"]
+ visible: false
+ - sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_priority_inactive
+ offset: 0.025,-0.265
+ map: ["enum.TradeCrateVisualLayers.Priority"]
+ visible: false
+ - state: paper
+ sprite: Structures/Storage/Crates/labels.rsi
+ offset: "-0.5,0"
+ map: ["enum.PaperLabelVisuals.Layer"]
+ - type: TradeCrate
+ valueAtDestination: 6000
+ valueElsewhere: 2500
+ expressDeliveryDuration: 2400 # forty minutes, go go (timeout mostly for pirates & NFSD)
+ expressOnTimeBonus: 2000
+ expressLatePenalty: 1500
- type: entity
parent: CrateTradeBaseSecureContraband
@@ -145,8 +216,28 @@
sprite: _NF/Structures/Storage/Crates/contraband3_crate.rsi
- type: Sprite
sprite: _NF/Structures/Storage/Crates/contraband3_crate.rsi
- - type: StaticPrice
- price: 7500
+ layers:
+ - state: icon
+ - sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_other
+ offset: 0.275,-0.265
+ map: ["enum.TradeCrateVisualLayers.Icon"]
+ visible: false
+ - sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_priority_inactive
+ offset: 0.025,-0.265
+ map: ["enum.TradeCrateVisualLayers.Priority"]
+ visible: false
+ - state: paper
+ sprite: Structures/Storage/Crates/labels.rsi
+ offset: "-0.5,0"
+ map: ["enum.PaperLabelVisuals.Layer"]
+ - type: TradeCrate
+ valueAtDestination: 8000
+ valueElsewhere: 4000
+ expressDeliveryDuration: 2400 # forty minutes, go go (timeout mostly for pirates & NFSD)
+ expressOnTimeBonus: 4000
+ expressLatePenalty: 3000
- type: entity
parent: CrateTradeBaseSecureContraband
@@ -158,8 +249,28 @@
sprite: _NF/Structures/Storage/Crates/donkco_crate.rsi
- type: Sprite
sprite: _NF/Structures/Storage/Crates/donkco_crate.rsi
- - type: StaticPrice
- price: 15000
+ layers:
+ - state: icon
+ - sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_other
+ offset: 0.275,-0.265
+ map: ["enum.TradeCrateVisualLayers.Icon"]
+ visible: false
+ - sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_priority_inactive
+ offset: 0.025,-0.265
+ map: ["enum.TradeCrateVisualLayers.Priority"]
+ visible: false
+ - state: paper
+ sprite: Structures/Storage/Crates/labels.rsi
+ offset: "-0.5,0"
+ map: ["enum.PaperLabelVisuals.Layer"]
+ - type: TradeCrate
+ valueAtDestination: 12000
+ valueElsewhere: 5000
+ expressDeliveryDuration: 2400 # forty minutes, go go (timeout mostly for pirates & NFSD)
+ expressOnTimeBonus: 6000
+ expressLatePenalty: 3000
- type: entity
parent: CrateTradeBaseSecureContraband
@@ -171,8 +282,28 @@
sprite: _NF/Structures/Storage/Crates/cybersun_crate.rsi
- type: Sprite
sprite: _NF/Structures/Storage/Crates/cybersun_crate.rsi
- - type: StaticPrice
- price: 15000
+ layers:
+ - state: icon
+ - sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_other
+ offset: 0.275,-0.265
+ map: ["enum.TradeCrateVisualLayers.Icon"]
+ visible: false
+ - sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_priority_inactive
+ offset: 0.025,-0.265
+ map: ["enum.TradeCrateVisualLayers.Priority"]
+ visible: false
+ - state: paper
+ sprite: Structures/Storage/Crates/labels.rsi
+ offset: "-0.5,0"
+ map: ["enum.PaperLabelVisuals.Layer"]
+ - type: TradeCrate
+ valueAtDestination: 12000
+ valueElsewhere: 6000
+ expressDeliveryDuration: 2400 # forty minutes, go go (timeout mostly for pirates & NFSD)
+ expressOnTimeBonus: 6000
+ expressLatePenalty: 3000
- type: entity
parent: CrateSecgear
diff --git a/Resources/Prototypes/_NF/Guidebook/bank.yml b/Resources/Prototypes/_NF/Guidebook/bank.yml
deleted file mode 100644
index f762438eae1..00000000000
--- a/Resources/Prototypes/_NF/Guidebook/bank.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-- type: guideEntry
- id: Bank
- name: guide-entry-bank
- text: "/ServerInfo/_NF/Guidebook/Bank.xml"
- priority: 0
diff --git a/Resources/Prototypes/_NF/Guidebook/hiring.yml b/Resources/Prototypes/_NF/Guidebook/hiring.yml
deleted file mode 100644
index 38b679e7172..00000000000
--- a/Resources/Prototypes/_NF/Guidebook/hiring.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-- type: guideEntry
- id: Hiring
- name: guide-entry-hiring
- text: "/ServerInfo/_NF/Guidebook/Hiring.xml"
- priority: 1
diff --git a/Resources/Prototypes/_NF/Guidebook/nf14.yml b/Resources/Prototypes/_NF/Guidebook/nf14.yml
index 6144ff59beb..e2a507b6efc 100644
--- a/Resources/Prototypes/_NF/Guidebook/nf14.yml
+++ b/Resources/Prototypes/_NF/Guidebook/nf14.yml
@@ -7,7 +7,31 @@
- Bank
- Hiring
- Piloting
- - Survival # Moved out from Station and Shifts section
+ - Survival # Moved out from Station and Shifts section (upstream file)
- Expeditions
+ - CargoHauling # TODO: separate this out along with salvage and mining into some NF_Cargo section
- Shipyard
- - StartingGear
+
+- type: guideEntry
+ id: Bank
+ name: guide-entry-bank
+ text: "/ServerInfo/_NF/Guidebook/Bank.xml"
+ priority: 0
+
+- type: guideEntry
+ id: Hiring
+ name: guide-entry-hiring
+ text: "/ServerInfo/_NF/Guidebook/Hiring.xml"
+ priority: 1
+
+- type: guideEntry
+ id: Piloting
+ name: guide-entry-piloting
+ text: "/ServerInfo/_NF/Guidebook/Piloting.xml"
+ priority: 2
+
+- type: guideEntry
+ id: CargoHauling
+ name: guide-entry-cargo-hauling
+ text: "/ServerInfo/_NF/Guidebook/CargoHauling.xml"
+ priority: 5
diff --git a/Resources/Prototypes/_NF/Guidebook/piloting.yml b/Resources/Prototypes/_NF/Guidebook/piloting.yml
deleted file mode 100644
index 915418da943..00000000000
--- a/Resources/Prototypes/_NF/Guidebook/piloting.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-- type: guideEntry
- id: Piloting
- name: guide-entry-piloting
- text: "/ServerInfo/_NF/Guidebook/Piloting.xml"
- priority: 2
diff --git a/Resources/Prototypes/_NF/Guidebook/shipyard.yml b/Resources/Prototypes/_NF/Guidebook/shipyard.yml
index 70553a21489..cfaacba106c 100644
--- a/Resources/Prototypes/_NF/Guidebook/shipyard.yml
+++ b/Resources/Prototypes/_NF/Guidebook/shipyard.yml
@@ -2,7 +2,7 @@
id: Shipyard
name: guide-entry-shipyard
text: "/ServerInfo/_NF/Guidebook/Shipyard.xml"
- priority: 5
+ priority: 6
children:
- ShipyardAkupara
- ShipyardAmbition
diff --git a/Resources/Prototypes/_NF/PointsOfInterest/cove.yml b/Resources/Prototypes/_NF/PointsOfInterest/cove.yml
index bbd9f1175cd..45dd8882451 100644
--- a/Resources/Prototypes/_NF/PointsOfInterest/cove.yml
+++ b/Resources/Prototypes/_NF/PointsOfInterest/cove.yml
@@ -47,3 +47,4 @@
- type: StationDeadDropReporting
messageSet: Pirate
- type: StationDeadDropHintExempt
+ - type: TradeCrateWildcardDestination
diff --git a/Resources/Prototypes/_NF/PointsOfInterest/depots.yml b/Resources/Prototypes/_NF/PointsOfInterest/depots.yml
index 7de0d0c2eff..dee16dfb3be 100644
--- a/Resources/Prototypes/_NF/PointsOfInterest/depots.yml
+++ b/Resources/Prototypes/_NF/PointsOfInterest/depots.yml
@@ -38,7 +38,7 @@
- type: gameMap
id: CargoDepot
- mapName: 'Cargo Depot' # Has a letter appended in NfAdventureSystem
+ mapName: 'Cargo Depot' # Has a letter appended in PointOfInterestSystem
mapPath: /Maps/_NF/POI/cargodepotalt.yml
minPlayers: 0
stations:
@@ -46,11 +46,13 @@
stationProto: MarketFrontierOutpost
components:
- type: StationNameSetup
- mapNameTemplate: 'Cargo Depot' # Has a letter appended in NfAdventureSystem
+ mapNameTemplate: 'Cargo Depot' # Has a letter appended in PointOfInterestSystem
+ - type: TradeCrateDestination
+ destinationProto: CargoA # Redefined in PointOfInterestSystem
- type: gameMap
id: CargoDepotAlt
- mapName: 'Cargo Depot' # Has a letter appended in NfAdventureSystem
+ mapName: 'Cargo Depot' # Has a letter appended in PointOfInterestSystem
mapPath: /Maps/_NF/POI/cargodepotalt.yml
minPlayers: 0
stations:
@@ -58,4 +60,6 @@
stationProto: MarketFrontierOutpost
components:
- type: StationNameSetup
- mapNameTemplate: 'Cargo Depot' # Has a letter appended in NfAdventureSystem
+ mapNameTemplate: 'Cargo Depot' # Has a letter appended in PointOfInterestSystem
+ - type: TradeCrateDestination
+ destinationProto: CargoA # Redefined in PointOfInterestSystem
diff --git a/Resources/Prototypes/_NF/PointsOfInterest/trade.yml b/Resources/Prototypes/_NF/PointsOfInterest/trade.yml
index c621b0119ed..1974d46af32 100644
--- a/Resources/Prototypes/_NF/PointsOfInterest/trade.yml
+++ b/Resources/Prototypes/_NF/PointsOfInterest/trade.yml
@@ -36,3 +36,5 @@
mapNameTemplate: 'Trade Outpost'
- type: StationDeadDrop
maxDeadDrops: 3 # Many here, it's huge.
+ - type: TradeCrateDestination
+ destinationProto: Trade
diff --git a/Resources/Prototypes/_NF/PointsOfInterest/trademall.yml b/Resources/Prototypes/_NF/PointsOfInterest/trademall.yml
index 237c2588381..63be3c6d9cf 100644
--- a/Resources/Prototypes/_NF/PointsOfInterest/trademall.yml
+++ b/Resources/Prototypes/_NF/PointsOfInterest/trademall.yml
@@ -36,3 +36,5 @@
mapNameTemplate: 'Trade Mall'
- type: StationDeadDrop
maxDeadDrops: 2 # A few, its not as big as the original trade outpost
+ - type: TradeCrateDestination
+ destinationProto: Trade
diff --git a/Resources/Prototypes/_NF/trade_crate_destination_icons.yml b/Resources/Prototypes/_NF/trade_crate_destination_icons.yml
new file mode 100644
index 00000000000..c6e57df7119
--- /dev/null
+++ b/Resources/Prototypes/_NF/trade_crate_destination_icons.yml
@@ -0,0 +1,227 @@
+- type: tradeCrateDestination
+ id: AnomalousLab
+ icon:
+ sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: anomalous
+
+- type: tradeCrateDestination
+ id: Beacon
+ icon:
+ sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: beacon
+
+- type: tradeCrateDestination
+ id: CargoA
+ icon:
+ sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_a
+
+- type: tradeCrateDestination
+ id: CargoB
+ icon:
+ sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_b
+
+- type: tradeCrateDestination
+ id: CargoC
+ icon:
+ sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_c
+
+- type: tradeCrateDestination
+ id: CargoD
+ icon:
+ sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_d
+
+- type: tradeCrateDestination
+ id: CargoE
+ icon:
+ sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_e
+
+- type: tradeCrateDestination
+ id: CargoF
+ icon:
+ sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_f
+
+- type: tradeCrateDestination
+ id: CargoG
+ icon:
+ sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_g
+
+- type: tradeCrateDestination
+ id: CargoH
+ icon:
+ sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_h
+
+- type: tradeCrateDestination
+ id: CargoI
+ icon:
+ sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_i
+
+- type: tradeCrateDestination
+ id: CargoJ
+ icon:
+ sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_j
+
+- type: tradeCrateDestination
+ id: CargoK
+ icon:
+ sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_k
+
+- type: tradeCrateDestination
+ id: CargoL
+ icon:
+ sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_l
+
+- type: tradeCrateDestination
+ id: CargoM
+ icon:
+ sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_m
+
+- type: tradeCrateDestination
+ id: CargoN
+ icon:
+ sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_n
+
+- type: tradeCrateDestination
+ id: CargoO
+ icon:
+ sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_o
+
+- type: tradeCrateDestination
+ id: CargoP
+ icon:
+ sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_p
+
+- type: tradeCrateDestination
+ id: CargoQ
+ icon:
+ sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_q
+
+- type: tradeCrateDestination
+ id: CargoR
+ icon:
+ sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_r
+
+- type: tradeCrateDestination
+ id: CargoS
+ icon:
+ sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_s
+
+- type: tradeCrateDestination
+ id: CargoT
+ icon:
+ sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_t
+
+- type: tradeCrateDestination
+ id: CargoU
+ icon:
+ sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_u
+
+- type: tradeCrateDestination
+ id: CargoV
+ icon:
+ sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_v
+
+- type: tradeCrateDestination
+ id: CargoX
+ icon:
+ sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_x
+
+- type: tradeCrateDestination
+ id: CargoY
+ icon:
+ sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_y
+
+- type: tradeCrateDestination
+ id: CargoZ
+ icon:
+ sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_z
+
+- type: tradeCrateDestination
+ id: CargoOther
+ icon:
+ sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: cargo_other
+
+- type: tradeCrateDestination
+ id: Casino
+ icon:
+ sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: caseys
+
+- type: tradeCrateDestination
+ id: Courthouse
+ icon:
+ sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: courthouse
+
+- type: tradeCrateDestination
+ id: Edison
+ icon:
+ sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: edison
+
+- type: tradeCrateDestination
+ id: Frontier
+ icon:
+ sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: frontier
+
+- type: tradeCrateDestination
+ id: Lodge
+ icon:
+ sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: lodge
+
+- type: tradeCrateDestination
+ id: McHobo
+ icon:
+ sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: mchobo
+
+- type: tradeCrateDestination
+ id: MedicalPOI
+ icon:
+ sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: medical_poi
+
+- type: tradeCrateDestination
+ id: Prison
+ icon:
+ sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: prison
+
+- type: tradeCrateDestination
+ id: RestStop
+ icon:
+ sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: tinnias
+
+- type: tradeCrateDestination
+ id: Trade
+ icon:
+ sprite: _NF/Interface/Misc/cargo_destination_icons.rsi
+ state: trade
diff --git a/Resources/ServerInfo/_NF/Guidebook/CargoHauling.xml b/Resources/ServerInfo/_NF/Guidebook/CargoHauling.xml
new file mode 100644
index 00000000000..41cec1fc0d3
--- /dev/null
+++ b/Resources/ServerInfo/_NF/Guidebook/CargoHauling.xml
@@ -0,0 +1,33 @@
+
+ # Cargo Hauling
+
+One of the ways you can make money on the Frontier is by moving shipments of [color=peru]trading crates[/color].
+
+
+
+
+
+
+You can find these by:
+ * Buying them at [color=peru]cargo request computers[/color] at the [color=darkgreen]Trade Outpost[/color]
+ * Salvaging them from [color=#88b0d1]space wrecks[/color]
+ * Finding [color=#c83737]contraband crates[/color] to be smuggled (ask around to find out how)
+
+Each trading crate will have a destination symbol on the right side of the crate. Examining the crate (Shift+Click) shows the name of the station it should be delivered to.
+
+Selling a crate at its destination station will result in receiving more money than the crate's worth, while selling it at other stations will result in less.
+
+## Express Deliveries
+
+Some crates are labelled as [color=yellow]express deliveries[/color]. These provide a bonus if delivered [italic]to the destination[/italic] on time.
+
+
+
+
+
+
+To make deliveries in time, make sure to keep your cargo bay organized so the crates for each destination can be removed from the cargo bay in order.
+
+Remember, more hands make light work, so crew up to help deliveries run smoothly!
+
+
diff --git a/Resources/ServerInfo/_NF/Guidebook/Shipyard/Barge.xml b/Resources/ServerInfo/_NF/Guidebook/Shipyard/Barge.xml
index b1c13f38f09..f16f91aebf2 100644
--- a/Resources/ServerInfo/_NF/Guidebook/Shipyard/Barge.xml
+++ b/Resources/ServerInfo/_NF/Guidebook/Shipyard/Barge.xml
@@ -4,8 +4,8 @@
-
-
+
+
diff --git a/Resources/ServerInfo/_NF/Guidebook/Shipyard/Hauler.xml b/Resources/ServerInfo/_NF/Guidebook/Shipyard/Hauler.xml
index 776d34e1682..5850e3edba8 100644
--- a/Resources/ServerInfo/_NF/Guidebook/Shipyard/Hauler.xml
+++ b/Resources/ServerInfo/_NF/Guidebook/Shipyard/Hauler.xml
@@ -1,7 +1,7 @@
# HAULER-CLASS SALVAGE SHUTTLE
-
+
diff --git a/Resources/ServerInfo/_NF/Guidebook/Shipyard/Loader.xml b/Resources/ServerInfo/_NF/Guidebook/Shipyard/Loader.xml
index b1528e79346..59505362c02 100644
--- a/Resources/ServerInfo/_NF/Guidebook/Shipyard/Loader.xml
+++ b/Resources/ServerInfo/_NF/Guidebook/Shipyard/Loader.xml
@@ -1,8 +1,8 @@
# LOADER-CLASS CARGO SHUTTLE
-
-
+
+
diff --git a/Resources/ServerInfo/_NF/Guidebook/Shipyard/Vagabond.xml b/Resources/ServerInfo/_NF/Guidebook/Shipyard/Vagabond.xml
index 64a3298796c..2a147a5d3c9 100644
--- a/Resources/ServerInfo/_NF/Guidebook/Shipyard/Vagabond.xml
+++ b/Resources/ServerInfo/_NF/Guidebook/Shipyard/Vagabond.xml
@@ -3,8 +3,8 @@
-
-
+
+
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/anomalous.png b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/anomalous.png
new file mode 100644
index 00000000000..e45a0e7eab2
Binary files /dev/null and b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/anomalous.png differ
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/beacon.png b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/beacon.png
new file mode 100644
index 00000000000..277c55f8a84
Binary files /dev/null and b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/beacon.png differ
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_a.png b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_a.png
new file mode 100644
index 00000000000..2c423bc0e39
Binary files /dev/null and b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_a.png differ
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_b.png b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_b.png
new file mode 100644
index 00000000000..870ca78586d
Binary files /dev/null and b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_b.png differ
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_c.png b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_c.png
new file mode 100644
index 00000000000..f395cab7906
Binary files /dev/null and b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_c.png differ
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_d.png b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_d.png
new file mode 100644
index 00000000000..bb40259ac7e
Binary files /dev/null and b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_d.png differ
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_e.png b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_e.png
new file mode 100644
index 00000000000..6f290d4851e
Binary files /dev/null and b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_e.png differ
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_f.png b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_f.png
new file mode 100644
index 00000000000..3d3d1fe94fe
Binary files /dev/null and b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_f.png differ
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_g.png b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_g.png
new file mode 100644
index 00000000000..f8473ef9965
Binary files /dev/null and b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_g.png differ
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_h.png b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_h.png
new file mode 100644
index 00000000000..48cd1761fde
Binary files /dev/null and b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_h.png differ
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_i.png b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_i.png
new file mode 100644
index 00000000000..440fa53c299
Binary files /dev/null and b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_i.png differ
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_j.png b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_j.png
new file mode 100644
index 00000000000..18b74da3c94
Binary files /dev/null and b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_j.png differ
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_k.png b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_k.png
new file mode 100644
index 00000000000..38ed8b0146c
Binary files /dev/null and b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_k.png differ
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_l.png b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_l.png
new file mode 100644
index 00000000000..b6181507f73
Binary files /dev/null and b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_l.png differ
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_m.png b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_m.png
new file mode 100644
index 00000000000..c690a132a07
Binary files /dev/null and b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_m.png differ
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_n.png b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_n.png
new file mode 100644
index 00000000000..257b3a3365e
Binary files /dev/null and b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_n.png differ
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_o.png b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_o.png
new file mode 100644
index 00000000000..0c8357b7dcd
Binary files /dev/null and b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_o.png differ
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_other.png b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_other.png
new file mode 100644
index 00000000000..8ba3fe64f85
Binary files /dev/null and b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_other.png differ
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_p.png b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_p.png
new file mode 100644
index 00000000000..3f5113b4efb
Binary files /dev/null and b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_p.png differ
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_priority_active.png b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_priority_active.png
new file mode 100644
index 00000000000..1ad0b6d9645
Binary files /dev/null and b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_priority_active.png differ
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_priority_inactive.png b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_priority_inactive.png
new file mode 100644
index 00000000000..2db677ebc4c
Binary files /dev/null and b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_priority_inactive.png differ
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_q.png b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_q.png
new file mode 100644
index 00000000000..76e9ca4dff0
Binary files /dev/null and b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_q.png differ
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_r.png b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_r.png
new file mode 100644
index 00000000000..b19b264a08a
Binary files /dev/null and b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_r.png differ
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_s.png b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_s.png
new file mode 100644
index 00000000000..afc14f0595b
Binary files /dev/null and b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_s.png differ
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_t.png b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_t.png
new file mode 100644
index 00000000000..56d5d77571c
Binary files /dev/null and b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_t.png differ
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_u.png b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_u.png
new file mode 100644
index 00000000000..fe39e948b78
Binary files /dev/null and b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_u.png differ
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_v.png b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_v.png
new file mode 100644
index 00000000000..3be8d8f53cb
Binary files /dev/null and b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_v.png differ
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_w.png b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_w.png
new file mode 100644
index 00000000000..1687c94407d
Binary files /dev/null and b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_w.png differ
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_x.png b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_x.png
new file mode 100644
index 00000000000..b5ab5aaaac3
Binary files /dev/null and b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_x.png differ
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_y.png b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_y.png
new file mode 100644
index 00000000000..baa2d9555fa
Binary files /dev/null and b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_y.png differ
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_z.png b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_z.png
new file mode 100644
index 00000000000..a3cd2cbef8c
Binary files /dev/null and b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/cargo_z.png differ
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/caseys.png b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/caseys.png
new file mode 100644
index 00000000000..5b61a169f18
Binary files /dev/null and b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/caseys.png differ
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/courthouse.png b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/courthouse.png
new file mode 100644
index 00000000000..5a4dbdb6bed
Binary files /dev/null and b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/courthouse.png differ
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/edison.png b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/edison.png
new file mode 100644
index 00000000000..dcd625b5b61
Binary files /dev/null and b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/edison.png differ
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/frontier.png b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/frontier.png
new file mode 100644
index 00000000000..40d5d2e7fc9
Binary files /dev/null and b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/frontier.png differ
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/lodge.png b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/lodge.png
new file mode 100644
index 00000000000..6a21fa7bcd3
Binary files /dev/null and b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/lodge.png differ
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/mchobo.png b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/mchobo.png
new file mode 100644
index 00000000000..849d2604b9f
Binary files /dev/null and b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/mchobo.png differ
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/medical_poi.png b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/medical_poi.png
new file mode 100644
index 00000000000..2b7ab20bb0b
Binary files /dev/null and b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/medical_poi.png differ
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/meta.json b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/meta.json
new file mode 100644
index 00000000000..f2197de3dca
--- /dev/null
+++ b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/meta.json
@@ -0,0 +1,142 @@
+{
+ "version": 1,
+ "license": "CC-BY-SA-3.0",
+ "copyright": "Made by whatston3 (GitHub)",
+ "size": {
+ "x": 8,
+ "y": 8
+ },
+ "states": [
+ {
+ "name": "anomalous"
+ },
+ {
+ "name": "beacon"
+ },
+ {
+ "name": "cargo_a"
+ },
+ {
+ "name": "cargo_b"
+ },
+ {
+ "name": "cargo_c"
+ },
+ {
+ "name": "cargo_d"
+ },
+ {
+ "name": "cargo_e"
+ },
+ {
+ "name": "cargo_f"
+ },
+ {
+ "name": "cargo_g"
+ },
+ {
+ "name": "cargo_h"
+ },
+ {
+ "name": "cargo_i"
+ },
+ {
+ "name": "cargo_j"
+ },
+ {
+ "name": "cargo_k"
+ },
+ {
+ "name": "cargo_l"
+ },
+ {
+ "name": "cargo_m"
+ },
+ {
+ "name": "cargo_n"
+ },
+ {
+ "name": "cargo_o"
+ },
+ {
+ "name": "cargo_p"
+ },
+ {
+ "name": "cargo_q"
+ },
+ {
+ "name": "cargo_r"
+ },
+ {
+ "name": "cargo_s"
+ },
+ {
+ "name": "cargo_t"
+ },
+ {
+ "name": "cargo_u"
+ },
+ {
+ "name": "cargo_v"
+ },
+ {
+ "name": "cargo_w"
+ },
+ {
+ "name": "cargo_x"
+ },
+ {
+ "name": "cargo_y"
+ },
+ {
+ "name": "cargo_z"
+ },
+ {
+ "name": "cargo_other"
+ },
+ {
+ "name": "cargo_priority_active",
+ "delays": [
+ [
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2
+ ]
+ ]
+ },
+ {
+ "name": "cargo_priority_inactive"
+ },
+ {
+ "name": "caseys"
+ },
+ {
+ "name": "courthouse"
+ },
+ {
+ "name": "edison"
+ },
+ {
+ "name": "frontier"
+ },
+ {
+ "name": "lodge"
+ },
+ {
+ "name": "mchobo"
+ },
+ {
+ "name": "medical_poi"
+ },
+ {
+ "name": "prison"
+ },
+ {
+ "name": "tinnias"
+ },
+ {
+ "name": "trade"
+ }
+ ]
+}
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/prison.png b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/prison.png
new file mode 100644
index 00000000000..1d6e0013059
Binary files /dev/null and b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/prison.png differ
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/tinnias.png b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/tinnias.png
new file mode 100644
index 00000000000..2f34a3af52d
Binary files /dev/null and b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/tinnias.png differ
diff --git a/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/trade.png b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/trade.png
new file mode 100644
index 00000000000..1dfd3fa1535
Binary files /dev/null and b/Resources/Textures/_NF/Interface/Misc/cargo_destination_icons.rsi/trade.png differ
diff --git a/Resources/Textures/_NF/Structures/Storage/Crates/contraband1_crate.rsi/base.png b/Resources/Textures/_NF/Structures/Storage/Crates/contraband1_crate.rsi/base.png
index d91b7983526..4c4bd96ec35 100644
Binary files a/Resources/Textures/_NF/Structures/Storage/Crates/contraband1_crate.rsi/base.png and b/Resources/Textures/_NF/Structures/Storage/Crates/contraband1_crate.rsi/base.png differ
diff --git a/Resources/Textures/_NF/Structures/Storage/Crates/contraband1_crate.rsi/closed.png b/Resources/Textures/_NF/Structures/Storage/Crates/contraband1_crate.rsi/closed.png
index 078d097819f..092afe49d4a 100644
Binary files a/Resources/Textures/_NF/Structures/Storage/Crates/contraband1_crate.rsi/closed.png and b/Resources/Textures/_NF/Structures/Storage/Crates/contraband1_crate.rsi/closed.png differ
diff --git a/Resources/Textures/_NF/Structures/Storage/Crates/contraband1_crate.rsi/icon.png b/Resources/Textures/_NF/Structures/Storage/Crates/contraband1_crate.rsi/icon.png
index 21044e7f6e2..fa77480c74b 100644
Binary files a/Resources/Textures/_NF/Structures/Storage/Crates/contraband1_crate.rsi/icon.png and b/Resources/Textures/_NF/Structures/Storage/Crates/contraband1_crate.rsi/icon.png differ
diff --git a/Resources/Textures/_NF/Structures/Storage/Crates/contraband1_crate.rsi/open.png b/Resources/Textures/_NF/Structures/Storage/Crates/contraband1_crate.rsi/open.png
index 937245adf8b..89fd9755723 100644
Binary files a/Resources/Textures/_NF/Structures/Storage/Crates/contraband1_crate.rsi/open.png and b/Resources/Textures/_NF/Structures/Storage/Crates/contraband1_crate.rsi/open.png differ
diff --git a/Resources/Textures/_NF/Structures/Storage/Crates/contraband2_crate.rsi/base.png b/Resources/Textures/_NF/Structures/Storage/Crates/contraband2_crate.rsi/base.png
index 4c4bd96ec35..d91b7983526 100644
Binary files a/Resources/Textures/_NF/Structures/Storage/Crates/contraband2_crate.rsi/base.png and b/Resources/Textures/_NF/Structures/Storage/Crates/contraband2_crate.rsi/base.png differ
diff --git a/Resources/Textures/_NF/Structures/Storage/Crates/contraband2_crate.rsi/closed.png b/Resources/Textures/_NF/Structures/Storage/Crates/contraband2_crate.rsi/closed.png
index 092afe49d4a..078d097819f 100644
Binary files a/Resources/Textures/_NF/Structures/Storage/Crates/contraband2_crate.rsi/closed.png and b/Resources/Textures/_NF/Structures/Storage/Crates/contraband2_crate.rsi/closed.png differ
diff --git a/Resources/Textures/_NF/Structures/Storage/Crates/contraband2_crate.rsi/icon.png b/Resources/Textures/_NF/Structures/Storage/Crates/contraband2_crate.rsi/icon.png
index fa77480c74b..21044e7f6e2 100644
Binary files a/Resources/Textures/_NF/Structures/Storage/Crates/contraband2_crate.rsi/icon.png and b/Resources/Textures/_NF/Structures/Storage/Crates/contraband2_crate.rsi/icon.png differ
diff --git a/Resources/Textures/_NF/Structures/Storage/Crates/contraband2_crate.rsi/open.png b/Resources/Textures/_NF/Structures/Storage/Crates/contraband2_crate.rsi/open.png
index 89fd9755723..937245adf8b 100644
Binary files a/Resources/Textures/_NF/Structures/Storage/Crates/contraband2_crate.rsi/open.png and b/Resources/Textures/_NF/Structures/Storage/Crates/contraband2_crate.rsi/open.png differ
diff --git a/Resources/_NF/migration.yml b/Resources/_NF/migration.yml
index b64ad3579c4..5ad6d64f2e9 100644
--- a/Resources/_NF/migration.yml
+++ b/Resources/_NF/migration.yml
@@ -177,6 +177,10 @@ VehicleJanicart: NFVehicleJanicart
# 2024-12-22 Barrels
CrateSpaceCleaner: ChemicalBarrelSpaceCleaner
+# 2024-12-24 Trading Crate Destinations
+CrateTradeSecureNormalFilled: CrateTradeSecureNormal
+CrateTradeSecureHighFilled: CrateTradeSecureHigh
+
# 2024-12-27 Useless
ScienceTechFab: UnfinishedMachineFrame
ScienceTechFabCircuitboard: ProtolatheMachineCircuitboard