diff --git a/Content.IntegrationTests/PoolSettings.cs b/Content.IntegrationTests/PoolSettings.cs
index 187af4569f9..5cebda0bfa1 100644
--- a/Content.IntegrationTests/PoolSettings.cs
+++ b/Content.IntegrationTests/PoolSettings.cs
@@ -1,4 +1,4 @@
-#nullable enable
+#nullable enable
using Robust.Shared.Random;
@@ -93,7 +93,7 @@ public sealed class PoolSettings
///
/// Frontier: the preset to run the game in.
/// Set to secret for upstream tests to mimic upstream behaviour.
- /// If you need to check adventure game rule things, set this to Adventure.
+ /// If you need to check adventure game rule things, set this to nfadventure or nfpirate.
///
public string GameLobbyDefaultPreset { get; set; } = "secret";
diff --git a/Content.Server/AlertLevel/AlertLevelSystem.cs b/Content.Server/AlertLevel/AlertLevelSystem.cs
index 8e43bf6a715..71ad018603a 100644
--- a/Content.Server/AlertLevel/AlertLevelSystem.cs
+++ b/Content.Server/AlertLevel/AlertLevelSystem.cs
@@ -172,8 +172,7 @@ public void SetLevel(EntityUid station, string level, bool playSound, bool annou
return;
// End Frontier
- if (!Resolve(station, ref dataComponent) // Frontier: remove component
- || component.AlertLevels == null
+ if (component.AlertLevels == null // Frontier: remove component, resolve station to data component later
|| !component.AlertLevels.Levels.TryGetValue(level, out var detail)
|| component.CurrentLevel == level)
{
@@ -196,7 +195,7 @@ public void SetLevel(EntityUid station, string level, bool playSound, bool annou
component.CurrentLevel = level;
component.IsLevelLocked = locked;
- var stationName = dataComponent.EntityName;
+ //var stationName = dataComponent.EntityName; // Frontier: remove station name
var name = level.ToLower();
@@ -232,8 +231,9 @@ public void SetLevel(EntityUid station, string level, bool playSound, bool annou
}
}
- if (announce)
+ if (announce && Resolve(station, ref dataComponent)) // Frontier: add Resolve for dataComponent
{
+ var stationName = dataComponent.EntityName; // Frontier: moved down
_chatSystem.DispatchStationAnnouncement(station, announcementFull, playDefaultSound: playDefault,
colorOverride: detail.Color, sender: stationName);
}
diff --git a/Content.Server/Light/EntitySystems/EmergencyLightSystem.cs b/Content.Server/Light/EntitySystems/EmergencyLightSystem.cs
index 9f820bdf701..633a027ef8f 100644
--- a/Content.Server/Light/EntitySystems/EmergencyLightSystem.cs
+++ b/Content.Server/Light/EntitySystems/EmergencyLightSystem.cs
@@ -32,6 +32,8 @@ public override void Initialize()
SubscribeLocalEvent(OnAlertLevelChanged);
SubscribeLocalEvent(OnEmergencyExamine);
SubscribeLocalEvent(OnEmergencyPower);
+
+ SubscribeLocalEvent(OnMapInit); // Frontier
}
private void OnEmergencyPower(Entity entity, ref PowerChangedEvent args)
@@ -245,4 +247,21 @@ private void TurnOn(Entity entity, Color color)
_appearance.SetData(entity.Owner, EmergencyLightVisuals.On, true);
_ambient.SetAmbience(entity.Owner, true);
}
+
+ // Frontier: ensure the lights are accurate to the station
+ private void OnMapInit(Entity entity, ref MapInitEvent ev)
+ {
+ if (!TryComp(_sectorService.GetServiceEntity(), out var alert))
+ return;
+
+ if (alert.AlertLevels == null || !alert.AlertLevels.Levels.TryGetValue(alert.CurrentLevel, out var details))
+ return;
+
+ entity.Comp.ForciblyEnabled = details.ForceEnableEmergencyLights;
+ if (details.ForceEnableEmergencyLights)
+ TurnOn(entity, details.EmergencyLightColor);
+ else
+ TurnOff(entity, details.EmergencyLightColor);
+ }
+ // End Frontier
}
diff --git a/Content.Server/Shipyard/Systems/ShipyardSystem.Consoles.cs b/Content.Server/Shipyard/Systems/ShipyardSystem.Consoles.cs
index 62d225badd7..923371f3b1e 100644
--- a/Content.Server/Shipyard/Systems/ShipyardSystem.Consoles.cs
+++ b/Content.Server/Shipyard/Systems/ShipyardSystem.Consoles.cs
@@ -3,7 +3,6 @@
using Content.Server.Radio.EntitySystems;
using Content.Server._NF.Bank;
using Content.Server.Shipyard.Components;
-using Content.Shared._NF.GameRule;
using Content.Shared.Bank.Components;
using Content.Shared.Shipyard.Events;
using Content.Shared.Shipyard.BUI;
diff --git a/Content.Server/_NF/GameRule/Components/AdventureRuleComponent.cs b/Content.Server/_NF/GameRule/Components/NFAdventureRuleComponent.cs
similarity index 58%
rename from Content.Server/_NF/GameRule/Components/AdventureRuleComponent.cs
rename to Content.Server/_NF/GameRule/Components/NFAdventureRuleComponent.cs
index fc85a5209c6..2ea4339bb70 100644
--- a/Content.Server/_NF/GameRule/Components/AdventureRuleComponent.cs
+++ b/Content.Server/_NF/GameRule/Components/NFAdventureRuleComponent.cs
@@ -1,10 +1,7 @@
-using Content.Shared.Procedural;
-using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
-
namespace Content.Server._NF.GameRule.Components;
-[RegisterComponent, Access(typeof(NfAdventureRuleSystem))]
-public sealed partial class AdventureRuleComponent : Component
+[RegisterComponent, Access(typeof(NFAdventureRuleSystem))]
+public sealed partial class NFAdventureRuleComponent : Component
{
public List NFPlayerMinds = new();
public List CargoDepots = new();
diff --git a/Content.Server/_NF/GameRule/NfAdventureRuleSystem.cs b/Content.Server/_NF/GameRule/NfAdventureRuleSystem.cs
index 0e662f01759..68062cdb598 100644
--- a/Content.Server/_NF/GameRule/NfAdventureRuleSystem.cs
+++ b/Content.Server/_NF/GameRule/NfAdventureRuleSystem.cs
@@ -1,24 +1,15 @@
using System.Linq;
using System.Net.Http;
-using System.Numerics;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
-using Content.Shared._NF.GameRule;
using Content.Server._NF.GameTicking.Events;
-using Robust.Server.GameObjects;
-using Robust.Server.Maps;
using Content.Shared.GameTicking.Components;
-using Robust.Shared.Map;
using Robust.Shared.Prototypes;
-using Robust.Shared.Random;
-using Content.Server.Shuttles.Systems;
using Content.Server.Cargo.Components;
using Content.Server.GameTicking;
using Content.Server.GameTicking.Rules;
-using Content.Server.Maps;
-using Content.Server.Station.Systems;
using Content.Shared._NF.CCVar; // Frontier
using Robust.Shared.Configuration;
using Content.Shared._NF.Bank;
@@ -29,26 +20,19 @@
using Content.Shared.GameTicking;
using Robust.Shared.Enums;
using Robust.Server.Player;
-using Content.Server._NF.Trade;
namespace Content.Server._NF.GameRule;
///
/// This handles the dungeon and trading post spawning, as well as round end capitalism summary
///
-public sealed class NfAdventureRuleSystem : GameRuleSystem
+public sealed class NFAdventureRuleSystem : GameRuleSystem
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
- [Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly IConfigurationManager _configurationManager = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;
- [Dependency] private readonly MapLoaderSystem _map = default!;
- [Dependency] private readonly MetaDataSystem _meta = default!;
- [Dependency] private readonly StationSystem _station = default!;
- [Dependency] private readonly ShuttleSystem _shuttle = default!;
- [Dependency] private readonly PhysicsSystem _physics = default!;
[Dependency] private readonly BankSystem _bank = default!;
- [Dependency] private readonly StationRenameWarpsSystems _renameWarps = default!;
+ [Dependency] private readonly PointOfInterestSystem _poi = default!;
private readonly HttpClient _httpClient = new();
@@ -77,11 +61,6 @@ public PlayerRoundBankInformation(int startBalance, string name, NetUserId userI
[ViewVariables]
private Dictionary _players = new();
- private float _distanceOffset = 1f;
- private List _stationCoords = new();
-
- private MapId _mapId;
-
///
public override void Initialize()
{
@@ -92,7 +71,7 @@ public override void Initialize()
_playerManager.PlayerStatusChanged += PlayerManagerOnPlayerStatusChanged;
}
- protected override void AppendRoundEndText(EntityUid uid, AdventureRuleComponent component, GameRuleComponent gameRule, ref RoundEndTextAppendEvent ev)
+ protected override void AppendRoundEndText(EntityUid uid, NFAdventureRuleComponent component, GameRuleComponent gameRule, ref RoundEndTextAppendEvent ev)
{
ev.AddLine(Loc.GetString("adventure-list-start"));
var allScore = new List>();
@@ -206,12 +185,9 @@ private void OnRoundRestart(RoundRestartCleanupEvent ev)
_players.Clear();
}
- protected override void Started(EntityUid uid, AdventureRuleComponent component, GameRuleComponent gameRule, GameRuleStartedEvent args)
+ protected override void Started(EntityUid uid, NFAdventureRuleComponent component, GameRuleComponent gameRule, GameRuleStartedEvent args)
{
- _mapId = GameTicker.DefaultMap;
-
- _distanceOffset = _configurationManager.GetCVar(NFCCVars.POIDistanceModifier);
- _stationCoords = new List();
+ var mapUid = GameTicker.DefaultMap;
//First, we need to grab the list and sort it into its respective spawning logics
List depotProtos = new();
@@ -237,11 +213,11 @@ protected override void Started(EntityUid uid, AdventureRuleComponent component,
remainingUniqueProtosBySpawnGroup[location.SpawnGroup].Add(location);
}
}
- GenerateDepots(depotProtos, out component.CargoDepots);
- GenerateMarkets(marketProtos, out component.MarketStations);
- GenerateRequireds(requiredProtos, out component.RequiredPois);
- GenerateOptionals(optionalProtos, out component.OptionalPois);
- GenerateUniques(remainingUniqueProtosBySpawnGroup, out component.UniquePois);
+ _poi.GenerateDepots(mapUid, depotProtos, out component.CargoDepots);
+ _poi.GenerateMarkets(mapUid, marketProtos, out component.MarketStations);
+ _poi.GenerateRequireds(mapUid, requiredProtos, out component.RequiredPois);
+ _poi.GenerateOptionals(mapUid, optionalProtos, out component.OptionalPois);
+ _poi.GenerateUniques(mapUid, remainingUniqueProtosBySpawnGroup, out component.UniquePois);
base.Started(uid, component, gameRule, args);
@@ -249,232 +225,6 @@ protected override void Started(EntityUid uid, AdventureRuleComponent component,
RaiseLocalEvent(EntityUid.Invalid, new StationsGeneratedEvent(), broadcast: true); // TODO: attach this to a meaningful entity.
}
- private void GenerateDepots(List depotPrototypes, out List depotStations)
- {
- //For depots, we want them to fill a circular type dystance formula to try to keep them as far apart as possible
- //Therefore, we will be taking our range properties and treating them as magnitudes of a direction vector divided
- //by the number of depots set in our corresponding cvar
-
- depotStations = new List();
- var depotCount = _configurationManager.GetCVar(NFCCVars.CargoDepots);
- var rotation = 2 * Math.PI / depotCount;
- var rotationOffset = _random.NextAngle() / depotCount;
-
- for (int i = 0; i < depotCount && depotPrototypes.Count > 0; i++)
- {
- var proto = _random.Pick(depotPrototypes);
- Vector2i offset = new Vector2i((int) (_random.Next(proto.MinimumDistance, proto.MaximumDistance) * _distanceOffset), 0);
- offset = offset.Rotate(rotationOffset);
- rotationOffset += rotation;
- // Append letter to depot name.
-
- string overrideName = proto.Name;
- if (i < 26)
- overrideName += $" {(char)('A' + i)}"; // " A" ... " Z"
- else
- overrideName += $" {i + 1}"; // " 27", " 28"...
- if (TrySpawnPoiGrid(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
- }
- }
- }
-
- private void GenerateMarkets(List marketPrototypes, out List marketStations)
- {
- //For market stations, we are going to allow for a bit of randomness and a different offset configuration. We dont
- //want copies of this one, since these can be more themed and duplicate names, for instance, can make for a less
- //ideal world
-
- marketStations = new List();
- var marketCount = _configurationManager.GetCVar(NFCCVars.MarketStations);
- _random.Shuffle(marketPrototypes);
- int marketsAdded = 0;
- foreach (var proto in marketPrototypes)
- {
- if (marketsAdded >= marketCount)
- break;
-
- var offset = GetRandomPOICoord(proto.MinimumDistance, proto.MaximumDistance, true);
-
- if (TrySpawnPoiGrid(proto, offset, out var marketUid) && marketUid is { Valid: true } market)
- {
- marketStations.Add(market);
- marketsAdded++;
- AddStationCoordsToSet(offset);
- }
- }
- }
-
- private void GenerateOptionals(List optionalPrototypes, out List optionalStations)
- {
- //Stations that do not have a defined grouping in their prototype get a default of "Optional" and get put into the
- //generic random rotation of POIs. This should include traditional places like Tinnia's rest, the Science Lab, The Pit,
- //and most RP places. This will essentially put them all into a pool to pull from, and still does not use the RNG function.
-
- optionalStations = new List();
- var optionalCount = _configurationManager.GetCVar(NFCCVars.OptionalStations);
- _random.Shuffle(optionalPrototypes);
- int optionalsAdded = 0;
- foreach (var proto in optionalPrototypes)
- {
- if (optionalsAdded >= optionalCount)
- break;
-
- var offset = GetRandomPOICoord(proto.MinimumDistance, proto.MaximumDistance, true);
-
- if (TrySpawnPoiGrid(proto, offset, out var optionalUid) && optionalUid is { Valid: true } uid)
- {
- optionalStations.Add(uid);
- AddStationCoordsToSet(offset);
- }
- }
- }
-
- private void GenerateRequireds(List requiredPrototypes, out List requiredStations)
- {
- //Stations are required are ones that are vital to function but otherwise still follow a generic random spawn logic
- //Traditionally these would be stations like Expedition Lodge, NFSD station, Prison/Courthouse POI, etc.
- //There are no limit to these, and any prototype marked alwaysSpawn = true will get pulled out of any list that isnt Markets/Depots
- //And will always appear every time, and also will not be included in other optional/dynamic lists
-
- requiredStations = new List();
- foreach (var proto in requiredPrototypes)
- {
- var offset = GetRandomPOICoord(proto.MinimumDistance, proto.MaximumDistance, true);
-
- if (TrySpawnPoiGrid(proto, offset, out var requiredUid) && requiredUid is { Valid: true } uid)
- {
- requiredStations.Add(uid);
- AddStationCoordsToSet(offset);
- }
- }
- }
-
- private void GenerateUniques(Dictionary> uniquePrototypes, out List uniqueStations)
- {
- //Unique locations are semi-dynamic groupings of POIs that rely each independantly on the SpawnChance per POI prototype
- //Since these are the remainder, and logically must have custom-designated groupings, we can then know to subdivide
- //our random pool into these found groups.
- //To do this with an equal distribution on a per-POI, per-round percentage basis, we are going to ensure a random
- //pick order of which we analyze our weighted chances to spawn, and if successful, remove every entry of that group
- //entirely.
-
- uniqueStations = new List();
- foreach (var prototypeList in uniquePrototypes.Values)
- {
- // Try to spawn
- _random.Shuffle(prototypeList);
- foreach (var proto in prototypeList)
- {
- var chance = _random.NextFloat(0, 1);
- if (chance <= proto.SpawnChance)
- {
- var offset = GetRandomPOICoord(proto.MinimumDistance, proto.MaximumDistance, true);
-
- if (TrySpawnPoiGrid(proto, offset, out var optionalUid) && optionalUid is { Valid: true } uid)
- {
- uniqueStations.Add(uid);
- AddStationCoordsToSet(offset);
- break;
- }
- }
- }
- }
- }
-
- private bool TrySpawnPoiGrid(PointOfInterestPrototype proto, Vector2 offset, out EntityUid? gridUid, string? overrideName = null)
- {
- gridUid = null;
- if (_map.TryLoad(_mapId, proto.GridPath.ToString(), out var mapUids,
- new MapLoadOptions
- {
- Offset = offset,
- Rotation = _random.NextAngle()
- }))
- {
-
- string stationName = string.IsNullOrEmpty(overrideName) ? proto.Name : overrideName;
-
- EntityUid? stationUid = null;
- if (_prototypeManager.TryIndex(proto.ID, out var stationProto))
- {
- stationUid = _station.InitializeNewStation(stationProto.Stations[proto.ID], mapUids, stationName);
- }
-
- foreach (var grid in mapUids)
- {
- var meta = EnsureComp(grid);
- _meta.SetEntityName(grid, stationName, meta);
-
- EntityManager.AddComponents(grid, proto.AddComponents);
- }
-
- // Rename warp points after set up if needed
- if (proto.NameWarp)
- {
- bool? hideWarp = proto.HideWarp ? true : null;
- if (stationUid != null)
- _renameWarps.SyncWarpPointsToStation(stationUid.Value, forceAdminOnly: hideWarp);
- else
- _renameWarps.SyncWarpPointsToGrids(mapUids, forceAdminOnly: hideWarp);
- }
-
- gridUid = mapUids[0];
- return true;
- }
-
- return false;
- }
-
- private Vector2 GetRandomPOICoord(float unscaledMinRange, float unscaledMaxRange, bool scaleRange)
- {
- int numRetries = int.Max(_configurationManager.GetCVar(NFCCVars.POIPlacementRetries), 0);
- float minDistance = float.Max(_configurationManager.GetCVar(NFCCVars.MinPOIDistance), 0); // Constant at the end to avoid NaN weirdness
-
- Vector2 coords = _random.NextVector2(unscaledMinRange, unscaledMaxRange);
- if (scaleRange)
- coords *= _distanceOffset;
- for (int i = 0; i < numRetries; i++)
- {
- bool positionIsValid = true;
- foreach (var station in _stationCoords)
- {
- if (Vector2.Distance(station, coords) < minDistance)
- {
- positionIsValid = false;
- break;
- }
- }
-
- // We have a valid position
- if (positionIsValid)
- break;
-
- // No vector yet, get next value.
- coords = _random.NextVector2(unscaledMinRange, unscaledMaxRange);
- if (scaleRange)
- coords *= _distanceOffset;
- }
-
- return coords;
- }
-
- private void AddStationCoordsToSet(Vector2 coords)
- {
- _stationCoords.Add(coords);
- }
-
private async Task ReportRound(string message, int color = 0x77DDE7)
{
Logger.InfoS("discord", message);
diff --git a/Content.Shared/_NF/GameRule/PointOfInterestPrototype.cs b/Content.Server/_NF/GameRule/PointOfInterestPrototype.cs
similarity index 83%
rename from Content.Shared/_NF/GameRule/PointOfInterestPrototype.cs
rename to Content.Server/_NF/GameRule/PointOfInterestPrototype.cs
index b1b11cd5963..f29cf76474e 100644
--- a/Content.Shared/_NF/GameRule/PointOfInterestPrototype.cs
+++ b/Content.Server/_NF/GameRule/PointOfInterestPrototype.cs
@@ -1,8 +1,8 @@
+using Content.Server.GameTicking.Presets;
using Robust.Shared.Prototypes;
-using Robust.Shared.Serialization;
using Robust.Shared.Utility;
-namespace Content.Shared._NF.GameRule;
+namespace Content.Server._NF.GameRule;
///
/// Describes information for a single point of interest to be spawned in the world
@@ -11,7 +11,6 @@ namespace Content.Shared._NF.GameRule;
[Serializable]
public sealed partial class PointOfInterestPrototype : IPrototype
{
- ///
[IdDataField]
public string ID { get; private set; } = default!;
@@ -22,13 +21,13 @@ public sealed partial class PointOfInterestPrototype : IPrototype
public string Name { get; private set; } = "";
///
- /// Should we set the warppoint name based on the grid name.
+ /// Should we set the warppoint name based on the grid name.
///
[DataField]
public bool NameWarp { get; set; } = true;
///
- /// If true, makes the warp point admin-only (hiding it for players).
+ /// If true, makes the warp point admin-only (hiding it for players).
///
[DataField]
public bool HideWarp { get; set; } = false;
@@ -46,11 +45,17 @@ public sealed partial class PointOfInterestPrototype : IPrototype
public int MaximumDistance { get; private set; } = 10000;
///
- /// Components to be added to any spawned grids.
+ /// Components to be added to any spawned grids.
///
[DataField]
public ComponentRegistry AddComponents { get; set; } = new();
+ ///
+ /// What gamepresets ID this POI is allowed to spawn on.
+ ///
+ [DataField]
+ public ProtoId[] SpawnGamePreset { get; private set; } = [];
+
///
/// If the POI does not belong to a pre-defined group, it will default to the "unique" internal category and will
/// use this float from 0-1 as a raw chance to spawn each round.
diff --git a/Content.Server/_NF/GameRule/PointOfInterestSystem.cs b/Content.Server/_NF/GameRule/PointOfInterestSystem.cs
new file mode 100644
index 00000000000..6e9dbd89c96
--- /dev/null
+++ b/Content.Server/_NF/GameRule/PointOfInterestSystem.cs
@@ -0,0 +1,308 @@
+using System.Linq;
+using System.Numerics;
+using Robust.Server.GameObjects;
+using Robust.Server.Maps;
+using Robust.Shared.Configuration;
+using Robust.Shared.Map;
+using Robust.Shared.Prototypes;
+using Robust.Shared.Random;
+using Content.Server.Maps;
+using Content.Server.Station.Systems;
+using Content.Server.GameTicking;
+using Content.Shared._NF.CCVar;
+using Content.Shared.GameTicking;
+
+namespace Content.Server._NF.GameRule;
+
+///
+/// This handles the dungeon and trading post spawning, as well as round end capitalism summary
+///
+//[Access(typeof(NfAdventureRuleSystem))]
+public sealed class PointOfInterestSystem : EntitySystem
+{
+ [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
+ [Dependency] private readonly IRobustRandom _random = default!;
+ [Dependency] private readonly IConfigurationManager _configurationManager = default!;
+ [Dependency] private readonly MapLoaderSystem _map = default!;
+ [Dependency] private readonly MetaDataSystem _meta = default!;
+ [Dependency] private readonly StationSystem _station = default!;
+ [Dependency] private readonly StationRenameWarpsSystems _renameWarps = default!;
+ [Dependency] private readonly GameTicker _ticker = default!;
+
+ private List _stationCoords = new();
+
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ SubscribeLocalEvent(OnRoundRestart);
+ }
+
+ private void OnRoundRestart(RoundRestartCleanupEvent ev)
+ {
+ _stationCoords.Clear();
+ }
+
+ private void AddStationCoordsToSet(Vector2 coords)
+ {
+ _stationCoords.Add(coords);
+ }
+
+ public void GenerateDepots(MapId mapUid, List depotPrototypes, out List depotStations)
+ {
+ //For depots, we want them to fill a circular type dystance formula to try to keep them as far apart as possible
+ //Therefore, we will be taking our range properties and treating them as magnitudes of a direction vector divided
+ //by the number of depots set in our corresponding cvar
+
+ depotStations = new List();
+ var depotCount = _configurationManager.GetCVar(NFCCVars.CargoDepots);
+ var rotation = 2 * Math.PI / depotCount;
+ var rotationOffset = _random.NextAngle() / depotCount;
+
+ if (_ticker.CurrentPreset is null)
+ return;
+
+ var currentPreset = _ticker.CurrentPreset.ID;
+
+ for (int i = 0; i < depotCount && depotPrototypes.Count > 0; i++)
+ {
+ var proto = _random.Pick(depotPrototypes);
+
+ if (!proto.SpawnGamePreset.Contains(currentPreset))
+ continue;
+
+ Vector2i offset = new Vector2i((int) _random.Next(proto.MinimumDistance, proto.MaximumDistance), 0);
+ offset = offset.Rotate(rotationOffset);
+ rotationOffset += rotation;
+ // Append letter to depot name.
+
+ string overrideName = proto.Name;
+ if (i < 26)
+ overrideName += $" {(char)('A' + i)}"; // " A" ... " Z"
+ else
+ 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
+ }
+ }
+ }
+
+ public void GenerateMarkets(MapId mapUid, List marketPrototypes, out List marketStations)
+ {
+ //For market stations, we are going to allow for a bit of randomness and a different offset configuration. We dont
+ //want copies of this one, since these can be more themed and duplicate names, for instance, can make for a less
+ //ideal world
+
+ marketStations = new List();
+ var marketCount = _configurationManager.GetCVar(NFCCVars.MarketStations);
+ _random.Shuffle(marketPrototypes);
+ int marketsAdded = 0;
+
+ if (_ticker.CurrentPreset is null)
+ return;
+ var currentPreset = _ticker.CurrentPreset.ID;
+
+ foreach (var proto in marketPrototypes)
+ {
+ if (!proto.SpawnGamePreset.Contains(currentPreset))
+ continue;
+
+ if (marketsAdded >= marketCount)
+ break;
+
+ var offset = GetRandomPOICoord(proto.MinimumDistance, proto.MaximumDistance);
+
+ if (TrySpawnPoiGrid(mapUid, proto, offset, out var marketUid) && marketUid is { Valid: true } market)
+ {
+ marketStations.Add(market);
+ marketsAdded++;
+ AddStationCoordsToSet(offset);
+ }
+ }
+ }
+
+ public void GenerateOptionals(MapId mapUid, List optionalPrototypes, out List optionalStations)
+ {
+ //Stations that do not have a defined grouping in their prototype get a default of "Optional" and get put into the
+ //generic random rotation of POIs. This should include traditional places like Tinnia's rest, the Science Lab, The Pit,
+ //and most RP places. This will essentially put them all into a pool to pull from, and still does not use the RNG function.
+
+ optionalStations = new List();
+ var optionalCount = _configurationManager.GetCVar(NFCCVars.OptionalStations);
+ _random.Shuffle(optionalPrototypes);
+ int optionalsAdded = 0;
+
+ if (_ticker.CurrentPreset is null)
+ return;
+ var currentPreset = _ticker.CurrentPreset.ID;
+
+ foreach (var proto in optionalPrototypes)
+ {
+ if (!proto.SpawnGamePreset.Contains(currentPreset))
+ continue;
+
+ if (optionalsAdded >= optionalCount)
+ break;
+
+ var offset = GetRandomPOICoord(proto.MinimumDistance, proto.MaximumDistance);
+
+ if (TrySpawnPoiGrid(mapUid, proto, offset, out var optionalUid) && optionalUid is { Valid: true } uid)
+ {
+ optionalStations.Add(uid);
+ AddStationCoordsToSet(offset);
+ }
+ }
+ }
+
+ public void GenerateRequireds(MapId mapUid, List requiredPrototypes, out List requiredStations)
+ {
+ //Stations are required are ones that are vital to function but otherwise still follow a generic random spawn logic
+ //Traditionally these would be stations like Expedition Lodge, NFSD station, Prison/Courthouse POI, etc.
+ //There are no limit to these, and any prototype marked alwaysSpawn = true will get pulled out of any list that isnt Markets/Depots
+ //And will always appear every time, and also will not be included in other optional/dynamic lists
+
+ requiredStations = new List();
+
+ if (_ticker.CurrentPreset is null)
+ return;
+ var currentPreset = _ticker.CurrentPreset!.ID;
+
+ foreach (var proto in requiredPrototypes)
+ {
+ if (!proto.SpawnGamePreset.Contains(currentPreset))
+ continue;
+
+ var offset = GetRandomPOICoord(proto.MinimumDistance, proto.MaximumDistance);
+
+ if (TrySpawnPoiGrid(mapUid, proto, offset, out var requiredUid) && requiredUid is { Valid: true } uid)
+ {
+ requiredStations.Add(uid);
+ AddStationCoordsToSet(offset);
+ }
+ }
+ }
+
+ public void GenerateUniques(MapId mapUid, Dictionary> uniquePrototypes, out List uniqueStations)
+ {
+ //Unique locations are semi-dynamic groupings of POIs that rely each independantly on the SpawnChance per POI prototype
+ //Since these are the remainder, and logically must have custom-designated groupings, we can then know to subdivide
+ //our random pool into these found groups.
+ //To do this with an equal distribution on a per-POI, per-round percentage basis, we are going to ensure a random
+ //pick order of which we analyze our weighted chances to spawn, and if successful, remove every entry of that group
+ //entirely.
+
+ uniqueStations = new List();
+
+ if (_ticker.CurrentPreset is null)
+ return;
+ var currentPreset = _ticker.CurrentPreset!.ID;
+
+ foreach (var prototypeList in uniquePrototypes.Values)
+ {
+ // Try to spawn
+ _random.Shuffle(prototypeList);
+ foreach (var proto in prototypeList)
+ {
+ if (!proto.SpawnGamePreset.Contains(currentPreset))
+ continue;
+
+ var chance = _random.NextFloat(0, 1);
+ if (chance <= proto.SpawnChance)
+ {
+ var offset = GetRandomPOICoord(proto.MinimumDistance, proto.MaximumDistance);
+
+ if (TrySpawnPoiGrid(mapUid, proto, offset, out var optionalUid) && optionalUid is { Valid: true } uid)
+ {
+ uniqueStations.Add(uid);
+ AddStationCoordsToSet(offset);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ private bool TrySpawnPoiGrid(MapId mapUid, PointOfInterestPrototype proto, Vector2 offset, out EntityUid? gridUid, string? overrideName = null)
+ {
+ gridUid = null;
+ if (_map.TryLoad(mapUid, proto.GridPath.ToString(), out var mapUids,
+ new MapLoadOptions
+ {
+ Offset = offset,
+ Rotation = _random.NextAngle()
+ }))
+ {
+
+ string stationName = string.IsNullOrEmpty(overrideName) ? proto.Name : overrideName;
+
+ EntityUid? stationUid = null;
+ if (_prototypeManager.TryIndex(proto.ID, out var stationProto))
+ {
+ stationUid = _station.InitializeNewStation(stationProto.Stations[proto.ID], mapUids, stationName);
+ }
+
+ foreach (var grid in mapUids)
+ {
+ var meta = EnsureComp(grid);
+ _meta.SetEntityName(grid, stationName, meta);
+
+ EntityManager.AddComponents(grid, proto.AddComponents);
+ }
+
+ // Rename warp points after set up if needed
+ if (proto.NameWarp)
+ {
+ bool? hideWarp = proto.HideWarp ? true : null;
+ if (stationUid != null)
+ _renameWarps.SyncWarpPointsToStation(stationUid.Value, forceAdminOnly: hideWarp);
+ else
+ _renameWarps.SyncWarpPointsToGrids(mapUids, forceAdminOnly: hideWarp);
+ }
+
+ gridUid = mapUids[0];
+ return true;
+ }
+
+ return false;
+ }
+
+ private Vector2 GetRandomPOICoord(float unscaledMinRange, float unscaledMaxRange)
+ {
+ int numRetries = int.Max(_configurationManager.GetCVar(NFCCVars.POIPlacementRetries), 0);
+ float minDistance = float.Max(_configurationManager.GetCVar(NFCCVars.MinPOIDistance), 0); // Constant at the end to avoid NaN weirdness
+
+ Vector2 coords = _random.NextVector2(unscaledMinRange, unscaledMaxRange);
+ for (int i = 0; i < numRetries; i++)
+ {
+ bool positionIsValid = true;
+ foreach (var station in _stationCoords)
+ {
+ if (Vector2.Distance(station, coords) < minDistance)
+ {
+ positionIsValid = false;
+ break;
+ }
+ }
+
+ // We have a valid position
+ if (positionIsValid)
+ break;
+
+ // No vector yet, get next value.
+ coords = _random.NextVector2(unscaledMinRange, unscaledMaxRange);
+ }
+
+ return coords;
+ }
+}
diff --git a/Content.Shared/CCVar/CCVars.cs b/Content.Shared/CCVar/CCVars.cs
index 6427dbbf734..790b77e1d11 100644
--- a/Content.Shared/CCVar/CCVars.cs
+++ b/Content.Shared/CCVar/CCVars.cs
@@ -163,7 +163,7 @@ public static readonly CVarDef
/// Controls the default game preset.
///
public static readonly CVarDef
- GameLobbyDefaultPreset = CVarDef.Create("game.defaultpreset", "adventure", CVar.ARCHIVE); // Frontier: secret
/// Controls if the game can force a different preset if the current preset's criteria are not met.
diff --git a/Resources/Changelog/Frontier.yml b/Resources/Changelog/Frontier.yml
index fa4e36c83cc..3b8cffce1e6 100644
--- a/Resources/Changelog/Frontier.yml
+++ b/Resources/Changelog/Frontier.yml
@@ -6041,3 +6041,27 @@ Entries:
message: Alert levels are now sector-wide, with appropriate announcements.
id: 5604
time: '2024-12-21T01:12:26.0000000+00:00'
+- author: whatston3
+ changes:
+ - type: Fix
+ message: Emergency lights start in their appropriate state when built.
+ id: 5605
+ time: '2024-12-21T20:28:31.0000000+00:00'
+- author: dustylens
+ changes:
+ - type: Remove
+ message: >-
+ majority of chemistry jugs removed from sale, to be replaced with new
+ barrels.
+ id: 5606
+ time: '2024-12-21T23:05:32.0000000+00:00'
+- author: dvir001
+ changes:
+ - type: Add
+ message: >-
+ Added barrels of chems, oil, water, fuel, booze, etc. to wrecks, rare
+ chems to cargo.
+ - type: Tweak
+ message: The ChefVend now contains one jar of each oil.
+ id: 5607
+ time: '2024-12-21T23:06:11.0000000+00:00'
diff --git a/Resources/Locale/en-US/_NF/adventure/adventure.ftl b/Resources/Locale/en-US/_NF/adventure/adventure.ftl
index 3e1a1268163..9ee3991db5d 100644
--- a/Resources/Locale/en-US/_NF/adventure/adventure.ftl
+++ b/Resources/Locale/en-US/_NF/adventure/adventure.ftl
@@ -11,8 +11,12 @@ adventure-webhook-top-loss = lost a total of {$amount}.
adventure-webhook-ledger-start = Ledger Summary
-adventure-title = New Frontier Adventure Mode
-adventure-description = Join a ship crew or buy your own and explore, research, salvage, or haul your way to riches!
+nf-adventure-title = Adventure
+nf-adventure-description = Join a ship crew or buy your own and explore, research, salvage, or haul your way to riches!
+
+nf-pirate-title = Pirates
+nf-pirate-description = A gang of pirates is on the loose! Take care out in space and try not to get plundered!
+
currency = Spesos
shipyard-rules-default1 =
diff --git a/Resources/Locale/en-US/_NF/reagents/labels.ftl b/Resources/Locale/en-US/_NF/reagents/labels.ftl
new file mode 100644
index 00000000000..981cbabf836
--- /dev/null
+++ b/Resources/Locale/en-US/_NF/reagents/labels.ftl
@@ -0,0 +1,49 @@
+# Labels for reagent barrels
+# Elements & basic reagents
+reagent-label-aluminium = [bold]Aluminium[/bold]
+reagent-label-carbon = [bold]Carbon[/bold]
+reagent-label-chlorine = [bold]Chlorine[/bold]
+reagent-label-copper = [bold]Copper[/bold]
+reagent-label-ethanol = [bold]Ethanol[/bold]
+reagent-label-fluorine = [bold]Fluorine[/bold]
+reagent-label-gold = [bold]Gold[/bold]
+reagent-label-hydrogen = [bold]Hydrogen[/bold]
+reagent-label-iodine = [bold]Iodine[/bold]
+reagent-label-iron = [bold]Iron[/bold]
+reagent-label-lithium = [bold]Lithium[/bold]
+reagent-label-mercury = [bold]Mercury[/bold]
+reagent-label-nitrogen = [bold]Nitrogen[/bold]
+reagent-label-oxygen = [bold]Oxygen[/bold]
+reagent-label-phosphorus = [bold]Phosphorus[/bold]
+reagent-label-potassium = [bold]Potassium[/bold]
+reagent-label-radium = [bold]Radium[/bold]
+reagent-label-silicon = [bold]Silicon[/bold]
+reagent-label-silver = [bold]Silver[/bold]
+reagent-label-sodium = [bold]Sodium[/bold]
+reagent-label-sugar = [bold]Sugar[/bold]
+reagent-label-sulfur = [bold]Sulfur[/bold]
+# Service & other reagents
+reagent-label-cornoil = [bold]Corn Oil[/bold]
+reagent-label-diethylamine = [bold]Diethylamine[/bold]
+reagent-label-ketchup = [bold]Ketchup[/bold]
+reagent-label-mayo = [bold]Mayonnaise[/bold]
+reagent-label-mustard = [bold]Mustard[/bold]
+reagent-label-oil = [bold]Oil[/bold]
+reagent-label-oil-olive = [bold]Olive Oil[/bold]
+reagent-label-space-cleaner = [bold]Space Cleaner[/bold]
+reagent-label-space-lube = [bold]Space Lube[/bold]
+reagent-label-welding-fuel = [bold]Welding Fuel[/bold]
+# Drinks
+reagent-label-absinthe = [bold]Absinthe[/bold]
+reagent-label-ale = [bold]Ale[/bold]
+reagent-label-beer = [bold]Beer[/bold]
+reagent-label-coffeeliqueur = [bold]Coffee Liqueur[/bold]
+reagent-label-cognac = [bold]Cognac[/bold]
+reagent-label-gin = [bold]Gin[/bold]
+reagent-label-rum = [bold]Rum[/bold]
+reagent-label-tequila = [bold]Tequila[/bold]
+reagent-label-vermouth = [bold]Vermouth[/bold]
+reagent-label-vodka = [bold]Vodka[/bold]
+reagent-label-water = [bold]Water[/bold]
+reagent-label-whiskey = [bold]Whiskey[/bold]
+reagent-label-wine = [bold]Wine[/bold]
diff --git a/Resources/Prototypes/Catalog/Cargo/cargo_food.yml b/Resources/Prototypes/Catalog/Cargo/cargo_food.yml
index e1c67ee941c..280d386c87a 100644
--- a/Resources/Prototypes/Catalog/Cargo/cargo_food.yml
+++ b/Resources/Prototypes/Catalog/Cargo/cargo_food.yml
@@ -75,12 +75,13 @@
category: cargoproduct-category-name-food
group: market
-# - type: cargoProduct
- # id: FoodSoftdrinksLarge
- # icon:
- # sprite: Objects/Consumable/Drinks/colabottle.rsi
- # state: icon
- # product: CrateFoodSoftdrinksLarge
- # cost: 2400
- # category: cargoproduct-category-name-food
- # group: market
+- type: cargoProduct
+ id: FoodSoftdrinksLarge
+ abstract: true # Frontier
+ icon:
+ sprite: Objects/Consumable/Drinks/colabottle.rsi
+ state: icon
+ product: CrateFoodSoftdrinksLarge
+ cost: 2400
+ category: cargoproduct-category-name-food
+ group: market
diff --git a/Resources/Prototypes/Catalog/Cargo/cargo_medical.yml b/Resources/Prototypes/Catalog/Cargo/cargo_medical.yml
index 9475f346ba4..bcdb0e417dc 100644
--- a/Resources/Prototypes/Catalog/Cargo/cargo_medical.yml
+++ b/Resources/Prototypes/Catalog/Cargo/cargo_medical.yml
@@ -130,6 +130,7 @@
- type: cargoProduct
id: ChemistryP
+ abstract: true # Frontier
icon:
sprite: Structures/Storage/Crates/chemcrate_secure.rsi
state: icon
@@ -140,6 +141,7 @@
- type: cargoProduct
id: ChemistryS
+ abstract: true # Frontier
icon:
sprite: Structures/Storage/Crates/chemcrate_secure.rsi
state: icon
@@ -150,6 +152,7 @@
- type: cargoProduct
id: CrateChemistryD
+ abstract: true # Frontier
icon:
sprite: Structures/Storage/Crates/chemcrate_secure.rsi
state: icon
diff --git a/Resources/Prototypes/Catalog/VendingMachines/Inventories/chefvend.yml b/Resources/Prototypes/Catalog/VendingMachines/Inventories/chefvend.yml
index b5eb2c20dc6..7a1d8763ce2 100644
--- a/Resources/Prototypes/Catalog/VendingMachines/Inventories/chefvend.yml
+++ b/Resources/Prototypes/Catalog/VendingMachines/Inventories/chefvend.yml
@@ -10,18 +10,16 @@
# FoodCondimentPacketSalt: 4 # Frontier - Replaced with big salt
ReagentContainerSalt: 5 # Frontier
ReagentContainerPepper: 5 # Frontier
- DrinkKegPlasticKetchup: 1 # Frontier - Refills
- DrinkKegPlasticMustard: 1 # Frontier - Refills
FoodCondimentBottleEnzyme: 5 # Frontier 2<5
FoodCondimentBottleHotsauce: 2
FoodCondimentBottleKetchup: 2
FoodCondimentBottleBBQ: 2
FoodCondimentBottleVinegar: 5 # Frontier 2<5
# ReagentContainerOliveoil: 2 # Frontier - Replaced with OilJarOlive
- OilJarOlive: 3
- OilJarCorn: 3
- OilJarGhee: 3
ReagentContainerMayo: 2
+ OilJarOlive: 1 # Frontier
+ OilJarCorn: 1 # Frontier
+ OilJarGhee: 1 # Frontier
#VariantCubeBox: 3 # Frontier
MonkeyCubeBox: 2 # Frontier
KoboldCubeBox: 2 # Frontier
diff --git a/Resources/Prototypes/_NF/Catalog/Cargo/cargo_medical.yml b/Resources/Prototypes/_NF/Catalog/Cargo/cargo_medical.yml
index 8b4eb3385d1..98b52d524af 100644
--- a/Resources/Prototypes/_NF/Catalog/Cargo/cargo_medical.yml
+++ b/Resources/Prototypes/_NF/Catalog/Cargo/cargo_medical.yml
@@ -7,3 +7,302 @@
cost: 3000
category: cargoproduct-category-name-medical
group: market
+
+- type: cargoProduct
+ id: CargoBarrel
+ name: barrel (empty)
+ icon:
+ sprite: _NF/Objects/Storage/Barrels/white.rsi
+ state: icon
+ product: MetalBarrelWhite
+ cost: 2000
+ category: cargoproduct-category-name-medical
+ group: market
+
+- type: cargoProduct
+ id: CargoBarrelCarbon
+ name: barrel of carbon
+ abstract: true
+ icon:
+ sprite: _NF/Objects/Storage/Barrels/black.rsi
+ state: icon
+ product: ChemicalBarrelCarbon
+ cost: 5000
+ category: cargoproduct-category-name-medical
+ group: market
+
+- type: cargoProduct
+ id: CargoBarrelIodine
+ name: barrel of iodine
+ abstract: true
+ icon:
+ sprite: _NF/Objects/Storage/Barrels/red.rsi
+ state: icon
+ product: ChemicalBarrelIodine
+ cost: 5000
+ category: cargoproduct-category-name-medical
+ group: market
+
+- type: cargoProduct
+ id: CargoBarrelFluorine
+ name: barrel of fluorine
+# abstract: true
+ icon:
+ sprite: _NF/Objects/Storage/Barrels/blue.rsi
+ state: icon
+ product: ChemicalBarrelFluorine
+ cost: 5000
+ category: cargoproduct-category-name-medical
+ group: market
+
+- type: cargoProduct
+ id: CargoBarrelChlorine
+ name: barrel of chlorine
+ abstract: true
+ icon:
+ sprite: _NF/Objects/Storage/Barrels/green.rsi
+ state: icon
+ product: ChemicalBarrelChlorine
+ cost: 5000
+ category: cargoproduct-category-name-medical
+ group: market
+
+- type: cargoProduct
+ id: CargoBarrelAluminium
+ name: barrel of aluminium
+# abstract: true
+ icon:
+ sprite: _NF/Objects/Storage/Barrels/white.rsi
+ state: icon
+ product: ChemicalBarrelAluminium
+ cost: 5000
+ category: cargoproduct-category-name-medical
+ group: market
+
+- type: cargoProduct
+ id: CargoBarrelPhosphorus
+ name: barrel of phosphorus
+# abstract: true
+ icon:
+ sprite: _NF/Objects/Storage/Barrels/red.rsi
+ state: icon
+ product: ChemicalBarrelPhosphorus
+ cost: 5000
+ category: cargoproduct-category-name-medical
+ group: market
+
+- type: cargoProduct
+ id: CargoBarrelSulfur
+ name: barrel of sulfur
+ abstract: true
+ icon:
+ sprite: _NF/Objects/Storage/Barrels/yellow.rsi
+ state: icon
+ product: ChemicalBarrelSulfur
+ cost: 5000
+ category: cargoproduct-category-name-medical
+ group: market
+
+- type: cargoProduct
+ id: CargoBarrelSilicon
+ name: barrel of silicon
+ abstract: true
+ icon:
+ sprite: _NF/Objects/Storage/Barrels/black.rsi
+ state: icon
+ product: ChemicalBarrelSilicon
+ cost: 5000
+ category: cargoproduct-category-name-medical
+ group: market
+
+- type: cargoProduct
+ id: CargoBarrelHydrogen
+ name: barrel of hydrogen
+ abstract: true
+ icon:
+ sprite: _NF/Objects/Storage/Barrels/white.rsi
+ state: icon
+ product: ChemicalBarrelHydrogen
+ cost: 5000
+ category: cargoproduct-category-name-medical
+ group: market
+
+- type: cargoProduct
+ id: CargoBarrelLithium
+ name: barrel of lithium
+# abstract: true
+ icon:
+ sprite: _NF/Objects/Storage/Barrels/grey.rsi
+ state: icon
+ product: ChemicalBarrelLithium
+ cost: 5000
+ category: cargoproduct-category-name-medical
+ group: market
+
+- type: cargoProduct
+ id: CargoBarrelSodium
+ name: barrel of sodium
+ abstract: true
+ icon:
+ sprite: _NF/Objects/Storage/Barrels/grey.rsi
+ state: icon
+ product: ChemicalBarrelSodium
+ cost: 5000
+ category: cargoproduct-category-name-medical
+ group: market
+
+- type: cargoProduct
+ id: CargoBarrelPotassium
+ name: barrel of potassium
+ abstract: true
+ icon:
+ sprite: _NF/Objects/Storage/Barrels/yellow.rsi
+ state: icon
+ product: ChemicalBarrelPotassium
+ cost: 5000
+ category: cargoproduct-category-name-medical
+ group: market
+
+- type: cargoProduct
+ id: CargoBarrelRadium
+ name: barrel of radium
+# abstract: true
+ icon:
+ sprite: _NF/Objects/Storage/Barrels/green.rsi
+ state: icon
+ product: ChemicalBarrelRadium
+ cost: 5000
+ category: cargoproduct-category-name-medical
+ group: market
+
+- type: cargoProduct
+ id: CargoBarrelIron
+ name: barrel of iron
+ abstract: true
+ icon:
+ sprite: _NF/Objects/Storage/Barrels/grey.rsi
+ state: icon
+ product: ChemicalBarrelIron
+ cost: 5000
+ category: cargoproduct-category-name-medical
+ group: market
+
+- type: cargoProduct
+ id: CargoBarrelCopper
+ name: barrel of copper
+# abstract: true
+ icon:
+ sprite: _NF/Objects/Storage/Barrels/red.rsi
+ state: icon
+ product: ChemicalBarrelCopper
+ cost: 5000
+ category: cargoproduct-category-name-medical
+ group: market
+
+- type: cargoProduct
+ id: CargoBarrelGold
+ name: barrel of gold
+ abstract: true
+ icon:
+ sprite: _NF/Objects/Storage/Barrels/yellow.rsi
+ state: icon
+ product: ChemicalBarrelGold
+ cost: 5000
+ category: cargoproduct-category-name-medical
+ group: market
+
+- type: cargoProduct
+ id: CargoBarrelMercury
+ name: barrel of mercury
+# abstract: true
+ icon:
+ sprite: _NF/Objects/Storage/Barrels/grey.rsi
+ state: icon
+ product: ChemicalBarrelMercury
+ cost: 5000
+ category: cargoproduct-category-name-medical
+ group: market
+
+- type: cargoProduct
+ id: CargoBarrelSilver
+ name: barrel of silver
+ abstract: true
+ icon:
+ sprite: _NF/Objects/Storage/Barrels/white.rsi
+ state: icon
+ product: ChemicalBarrelSilver
+ cost: 5000
+ category: cargoproduct-category-name-medical
+ group: market
+
+- type: cargoProduct
+ id: CargoBarrelEthanol
+ name: barrel of ethanol
+# abstract: true
+ icon:
+ sprite: _NF/Objects/Storage/Barrels/blue.rsi
+ state: icon
+ product: ChemicalBarrelEthanol
+ cost: 5000
+ category: cargoproduct-category-name-medical
+ group: market
+
+- type: cargoProduct
+ id: CargoBarrelSugar
+ name: barrel of sugar
+ abstract: true
+ icon:
+ sprite: _NF/Objects/Storage/Barrels/white.rsi
+ state: icon
+ product: ChemicalBarrelSugar
+ cost: 5000
+ category: cargoproduct-category-name-medical
+ group: market
+
+- type: cargoProduct
+ id: CargoBarrelNitrogen
+ name: barrel of nitrogen
+# abstract: true
+ icon:
+ sprite: _NF/Objects/Storage/Barrels/red.rsi
+ state: icon
+ product: ChemicalBarrelNitrogen
+ cost: 5000
+ category: cargoproduct-category-name-medical
+ group: market
+
+- type: cargoProduct
+ id: CargoBarrelOxygen
+ name: barrel of oxygen
+ abstract: true
+ icon:
+ sprite: _NF/Objects/Storage/Barrels/blue.rsi
+ state: icon
+ product: ChemicalBarrelOxygen
+ cost: 5000
+ category: cargoproduct-category-name-medical
+ group: market
+
+- type: cargoProduct
+ id: CargoBarrelOil
+ name: barrel of oil
+ abstract: true
+ icon:
+ sprite: _NF/Objects/Storage/Barrels/black.rsi
+ state: icon
+ product: ChemicalBarrelOil
+ cost: 5000
+ category: cargoproduct-category-name-medical
+ group: market
+
+- type: cargoProduct
+ id: CargoBarrelDiethylamine
+ name: barrel of diethylamine
+ abstract: true
+ icon:
+ sprite: _NF/Objects/Storage/Barrels/green.rsi
+ state: icon
+ product: ChemicalBarrelDiethylamine
+ cost: 5000
+ category: cargoproduct-category-name-medical
+ group: market
diff --git a/Resources/Prototypes/_NF/Catalog/Cargo/cargo_service.yml b/Resources/Prototypes/_NF/Catalog/Cargo/cargo_service.yml
index 206d951c793..2a9b0df5e60 100644
--- a/Resources/Prototypes/_NF/Catalog/Cargo/cargo_service.yml
+++ b/Resources/Prototypes/_NF/Catalog/Cargo/cargo_service.yml
@@ -1,10 +1,10 @@
- type: cargoProduct
- id: BulkSpaceCleaner
+ id: CargoBarreSpaceCleaner
icon:
- sprite: Objects/Specific/Chemistry/jug.rsi
- state: jug
- product: CrateSpaceCleaner
- cost: 2000
+ sprite: _NF/Objects/Storage/Barrels/blue.rsi
+ state: icon
+ product: ChemicalBarrelSpaceCleaner
+ cost: 3500
category: cargoproduct-category-name-service
group: market
diff --git a/Resources/Prototypes/_NF/Catalog/Fills/Crates/chemistry.yml b/Resources/Prototypes/_NF/Catalog/Fills/Crates/chemistry.yml
deleted file mode 100644
index 18dee491c22..00000000000
--- a/Resources/Prototypes/_NF/Catalog/Fills/Crates/chemistry.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-- type: entity
- id: CrateSpaceCleaner
- parent: CrateGenericSteel
- name: bulk space cleaner crate
- description: For a large mess.
- components:
- - type: StorageFill
- contents:
- - id: JugSpaceCleaner
- amount: 5
diff --git a/Resources/Prototypes/_NF/Entities/Markers/Spawners/Random/dungeon_items_kitchen.yml b/Resources/Prototypes/_NF/Entities/Markers/Spawners/Random/dungeon_items_kitchen.yml
index db2775f1a85..9da9c833bfc 100644
--- a/Resources/Prototypes/_NF/Entities/Markers/Spawners/Random/dungeon_items_kitchen.yml
+++ b/Resources/Prototypes/_NF/Entities/Markers/Spawners/Random/dungeon_items_kitchen.yml
@@ -225,7 +225,6 @@
- CrateMousetrapBoxes
- CrateFoodBarSupply
- CrateServiceBoozeDispenser
- - CrateSpaceCleaner
- CrateServiceKitCleanades
chance: 0.9
offset: 0.0
diff --git a/Resources/Prototypes/_NF/Entities/Markers/Spawners/Random/salvage.yml b/Resources/Prototypes/_NF/Entities/Markers/Spawners/Random/salvage.yml
index ce6a811dda9..6705e794405 100644
--- a/Resources/Prototypes/_NF/Entities/Markers/Spawners/Random/salvage.yml
+++ b/Resources/Prototypes/_NF/Entities/Markers/Spawners/Random/salvage.yml
@@ -350,8 +350,9 @@
- type: entity
name: salvage tank spawner
- id: SalvageTankSpawner
+ id: SalvageTankSpawnerHighCapacity
parent: MarkerBase
+ suffix: High Capacity, 95%
components:
- type: Sprite
layers:
@@ -360,15 +361,9 @@
state: fueltank
- type: RandomSpawner
prototypes:
- - WaterTankFull
- - WeldingFuelTankFull
-# - WaterCooler
- chance: 0.95
- rarePrototypes:
- - WeldingFuelTankHighCapacity
+# - WeldingFuelTankHighCapacity
- WaterTankHighCapacity
- rareChance: 0.05
- offset: 0.0
+ chance: 0.95
- type: entity
name: salvage locker spawner
@@ -596,3 +591,113 @@
# - SpawnMobPurpleSnake # Why are they xeno
rareChance: 0.2
offset: 0.0
+
+- type: entity
+ id: NFSalvageChemicalBarrelSpawner
+ parent: MarkerBase
+ components:
+ - type: Sprite
+ layers:
+ - state: green
+ - sprite: _NF/Objects/Storage/Barrels/grey.rsi
+ state: icon
+ - type: RandomSpawner
+ prototypes: # Filled versions
+ - ChemicalBarrelCarbon
+ - ChemicalBarrelIodine
+ - ChemicalBarrelFluorine
+ - ChemicalBarrelChlorine
+ - ChemicalBarrelAluminium
+ - ChemicalBarrelPhosphorus
+ - ChemicalBarrelSulfur
+ - ChemicalBarrelSilicon
+ - ChemicalBarrelHydrogen
+ - ChemicalBarrelLithium
+ - ChemicalBarrelSodium
+ - ChemicalBarrelPotassium
+ - ChemicalBarrelRadium
+ - ChemicalBarrelIron
+ - ChemicalBarrelCopper
+ - ChemicalBarrelGold
+ - ChemicalBarrelMercury
+ - ChemicalBarrelSilver
+ - ChemicalBarrelEthanol
+ - ChemicalBarrelSugar
+ - ChemicalBarrelNitrogen
+ - ChemicalBarrelOxygen
+ chance: 0.95
+ offset: 0.1 # Little offset, it's free-standing
+
+- type: entity
+ id: NFSalvageServiceBarrelSpawner
+ parent: MarkerBase
+ components:
+ - type: Sprite
+ layers:
+ - state: green
+ - sprite: _NF/Objects/Storage/Barrels/grey.rsi
+ state: icon
+ - type: RandomSpawner
+ prototypes: # Filled versions
+ - ChemicalBarrelOil
+ - ChemicalBarrelDiethylamine
+ - ChemicalBarrelMustard
+ - ChemicalBarrelKetchup
+ - ChemicalBarrelMayo
+ - ChemicalBarrelCornoil
+ - ChemicalBarrelOliveoil
+ - ChemicalBarrelSpaceLube
+ - ChemicalBarrelSpaceCleaner
+ chance: 0.95
+ offset: 0.1 # Little offset, it's free-standing
+
+- type: entity
+ id: NFSalvageDrinkableBarrelSpawner
+ parent: MarkerBase
+ components:
+ - type: Sprite
+ layers:
+ - state: green
+ - sprite: _NF/Objects/Storage/Barrels/red.rsi
+ state: icon
+ - type: RandomSpawner
+ prototypes: # Filled versions
+ - ChemicalBarrelWater
+ rarePrototypes:
+ - ChemicalBarrelAbsinthe
+ - ChemicalBarrelAle
+ - ChemicalBarrelBeer
+ - ChemicalBarrelCoffeeLiqueur
+ - ChemicalBarrelCognac
+ - ChemicalBarrelGin
+ - ChemicalBarrelMead
+ - ChemicalBarrelRum
+ - ChemicalBarrelTequila
+ - ChemicalBarrelVermouth
+ - ChemicalBarrelVodka
+ - ChemicalBarrelWhiskey
+ - ChemicalBarrelWine
+ rareChance: 0.5
+ chance: 0.95
+ offset: 0.1 # Little offset, it's free-standing
+
+- type: entity
+ id: NFSalvageEmptyBarrelSpawner
+ parent: MarkerBase
+ components:
+ - type: Sprite
+ layers:
+ - state: green
+ - sprite: _NF/Objects/Storage/Barrels/red.rsi
+ state: icon
+ - type: RandomSpawner
+ prototypes:
+ - MetalBarrelGrey
+ - MetalBarrelBlue
+ - MetalBarrelRed
+ - MetalBarrelYellow
+ - MetalBarrelGreen
+ - MetalBarrelWhite
+ - MetalBarrelBlack
+ - ChemicalBarrelExplosiveEmpty
+ offset: 0.1 # Little offset, it's free-standing
diff --git a/Resources/Prototypes/_NF/Entities/Objects/Consumable/Food/ingredients.yml b/Resources/Prototypes/_NF/Entities/Objects/Consumable/Food/ingredients.yml
index 62da2be141d..0703cc52627 100644
--- a/Resources/Prototypes/_NF/Entities/Objects/Consumable/Food/ingredients.yml
+++ b/Resources/Prototypes/_NF/Entities/Objects/Consumable/Food/ingredients.yml
@@ -75,36 +75,6 @@
- ReagentId: CocoaPowder
Quantity: 50
-- type: entity
- parent: DrinkKegPlastic
- id: DrinkKegPlasticKetchup
- name: ketchup keg
- components:
- - type: SolutionContainerManager
- solutions:
- drink:
- maxVol: 600
- reagents:
- - ReagentId: Ketchup
- Quantity: 600
- - type: StaticPrice
- price: 60
-
-- type: entity
- parent: DrinkKegPlastic
- id: DrinkKegPlasticMustard
- name: mustard keg
- components:
- - type: SolutionContainerManager
- solutions:
- drink:
- maxVol: 600
- reagents:
- - ReagentId: Mustard
- Quantity: 600
- - type: StaticPrice
- price: 60
-
- type: entity
name: raw coffee beans
parent: FoodProduceBase
diff --git a/Resources/Prototypes/_NF/Entities/Objects/Specific/chemical-containers.yml b/Resources/Prototypes/_NF/Entities/Objects/Specific/chemical-containers.yml
index bcd319f1ce5..7bb29f92987 100644
--- a/Resources/Prototypes/_NF/Entities/Objects/Specific/chemical-containers.yml
+++ b/Resources/Prototypes/_NF/Entities/Objects/Specific/chemical-containers.yml
@@ -1,18 +1,3 @@
-- type: entity
- parent: Jug
- id: JugSpaceCleaner
- suffix: space cleaner
- categories: [ HideSpawnMenu ]
- components:
- - type: Label
- currentLabel: reagent-name-space-cleaner
- - type: SolutionContainerManager
- solutions:
- beaker:
- reagents:
- - ReagentId: SpaceCleaner
- Quantity: 200
-
- type: entity
name: bluespace jug
parent: Jug
diff --git a/Resources/Prototypes/_NF/Entities/Structures/Storage/Crates/barrel.yml b/Resources/Prototypes/_NF/Entities/Structures/Storage/Crates/barrel.yml
new file mode 100644
index 00000000000..1b568262482
--- /dev/null
+++ b/Resources/Prototypes/_NF/Entities/Structures/Storage/Crates/barrel.yml
@@ -0,0 +1,1326 @@
+- type: entity
+ parent: CrateGeneric
+ id: WoodenBarrel
+ name: wooden barrel
+ description: A musty old wooden barrel.
+ components:
+ - type: Sprite
+ sprite: _NF/Objects/Storage/Barrels/wood.rsi
+ layers:
+ - state: icon
+ map: ["enum.StorageVisualLayers.Base"]
+ - state: closed
+ map: ["enum.StorageVisualLayers.Door"]
+ - type: Icon
+ sprite: _NF/Objects/Storage/Barrels/wood.rsi
+ state: icon
+ - type: Damageable
+ damageContainer: StructuralInorganic
+ damageModifierSet: Wood
+ - type: Destructible
+ thresholds:
+ - trigger:
+ !type:DamageTrigger
+ damage: 30
+ behaviors:
+ - !type:PlaySoundBehavior
+ sound:
+ collection: WoodDestroy
+ - !type:SpawnEntitiesBehavior
+ spawn:
+ MaterialWoodPlank1:
+ min: 1
+ max: 4
+ - !type:DoActsBehavior
+ acts: [ "Destruction" ]
+ - type: Construction
+ graph: WoodenBarrel
+ node: woodenbarrel
+ containers:
+ - entity_storage
+ - type: Fixtures
+ fixtures:
+ fix1:
+ shape:
+ !type:PhysShapeAabb
+ bounds: "-0.2,-0.3,0.2,0.4"
+ density: 150
+ mask:
+ - SmallMobMask #this is so they can go under plastic flaps
+ layer:
+ - MachineLayer
+ - type: Climbable
+ - type: StaticPrice
+ price: 50
+
+- type: entity
+ parent: StorageTank
+ id: BaseBarrel
+ name: metal barrel
+ description: A metal barrel. It can be filled with liquid.
+ abstract: true
+ components:
+ - type: Sprite
+ sprite: _NF/Objects/Storage/Barrels/grey.rsi
+ layers:
+ - state: icon
+ - state: icon_open
+ map: ["enum.OpenableVisuals.Layer"]
+ visible: false
+ - state: paper
+ map: ["enum.PaperLabelVisuals.Layer"]
+ visible: false
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ maxVol: 1000
+ - type: ExaminableSolution
+ solution: tank
+ - type: UserInterface
+ interfaces:
+ enum.TransferAmountUiKey.Key:
+ type: TransferAmountBoundUserInterface
+ - type: DrawableSolution
+ solution: tank
+ - type: InjectableSolution
+ solution: tank
+ - type: Spillable
+ solution: tank
+ spillDelay: 10
+ - type: DumpableSolution
+ solution: tank
+ - type: Fixtures
+ fixtures:
+ fix1:
+ shape:
+ !type:PhysShapeAabb
+ bounds: "-0.2,-0.3,0.2,0.4"
+ density: 200
+ mask:
+ - SmallMobMask #this is so they can go under plastic flaps
+ layer:
+ - MachineLayer
+ - type: Transform
+ noRot: false
+ - type: Damageable
+ damageContainer: StructuralInorganic
+ damageModifierSet: Metallic
+ - type: GenericVisualizer
+ visuals:
+ enum.OpenableVisuals.Opened:
+ enum.OpenableVisuals.Layer:
+ True: { visible: true }
+ False: { visible: false }
+ enum.PaperLabelVisuals.HasLabel:
+ enum.PaperLabelVisuals.Layer:
+ True: { visible: true }
+ False: { visible: false }
+ enum.PaperLabelVisuals.LabelType:
+ enum.PaperLabelVisuals.Layer:
+ Paper: { state: paper }
+ Bounty: { state: paper }
+ CaptainsPaper: { state: paper }
+ Invoice: { state: paper }
+ - type: Appearance
+ - type: PaperLabel
+ labelSlot:
+ insertVerbText: Attach Label
+ ejectVerbText: Remove Label
+ whitelist:
+ components:
+ - Paper
+ - type: ItemSlots
+ - type: ContainerContainer
+ containers:
+ paper_label: !type:ContainerSlot
+ - type: Openable
+ sound:
+ collection: valveSqueak
+ closeable: true
+ closeSound:
+ collection: valveSqueak
+ - type: Sealable
+ - type: StaticPrice
+ price: 1000
+
+- type: entity
+ id: MetalBarrelGrey
+ parent: BaseBarrel
+ components:
+ - type: Sprite
+ sprite: _NF/Objects/Storage/Barrels/grey.rsi
+
+- type: entity
+ id: MetalBarrelBlue
+ parent: BaseBarrel
+ components:
+ - type: Sprite
+ sprite: _NF/Objects/Storage/Barrels/blue.rsi
+
+- type: entity
+ id: MetalBarrelRed
+ parent: BaseBarrel
+ components:
+ - type: Sprite
+ sprite: _NF/Objects/Storage/Barrels/red.rsi
+
+- type: entity
+ id: MetalBarrelYellow
+ parent: BaseBarrel
+ components:
+ - type: Sprite
+ sprite: _NF/Objects/Storage/Barrels/yellow.rsi
+
+- type: entity
+ id: MetalBarrelGreen
+ parent: BaseBarrel
+ components:
+ - type: Sprite
+ sprite: _NF/Objects/Storage/Barrels/green.rsi
+
+- type: entity
+ id: MetalBarrelWhite
+ parent: BaseBarrel
+ components:
+ - type: Sprite
+ sprite: _NF/Objects/Storage/Barrels/white.rsi
+
+- type: entity
+ id: MetalBarrelBlack
+ parent: BaseBarrel
+ components:
+ - type: Sprite
+ sprite: _NF/Objects/Storage/Barrels/black.rsi
+
+- type: entity
+ id: ChemicalBarrelExplosiveEmpty
+ parent: MetalBarrelRed
+ name: explosive barrel
+ suffix: Empty
+ description: The ancient and mysterious symbol on the front is believed to have once meant 'Use me as cover!' in days of yore.
+ components:
+ - type: Sprite
+ sprite: _NF/Objects/Storage/Barrels/red.rsi
+ layers:
+ - state: icon
+ - state: icon_open
+ map: ["enum.OpenableVisuals.Layer"]
+ visible: false
+ - state: metal_explosive_label
+ - state: paper
+ map: ["enum.PaperLabelVisuals.Layer"]
+ visible: false
+
+- type: entity
+ id: ChemicalBarrelExplosiveFilled
+ parent: ChemicalBarrelExplosiveEmpty
+ suffix: Filled
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: WeldingFuel
+ Quantity: 1000
+ - type: DamageOnToolInteract
+ tools: Welding
+ weldingDamage:
+ types:
+ Heat: 10
+ - type: PacifismDangerousAttack
+ - type: Explosive # This is dumb since you can refill it with water and it will still explode, so be it.
+ explosionType: Default
+ totalIntensity: 60
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelWeldingFuel
+
+- type: entity
+ id: LabelWeldingFuel
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-welding-fuel
+
+- type: entity
+ parent: MetalBarrelBlack
+ id: ChemicalBarrelCarbon
+ suffix: Carbon
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Carbon
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelCarbon
+
+- type: entity
+ id: LabelCarbon
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-carbon
+
+- type: entity
+ parent: MetalBarrelRed
+ id: ChemicalBarrelIodine
+ suffix: Iodine
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Iodine
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelIodine
+
+- type: entity
+ id: LabelIodine
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-iodine
+
+- type: entity
+ parent: MetalBarrelBlue
+ id: ChemicalBarrelFluorine
+ suffix: Fluorine
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Fluorine
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelFluorine
+
+- type: entity
+ id: LabelFluorine
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-fluorine
+
+- type: entity
+ parent: MetalBarrelGreen
+ id: ChemicalBarrelChlorine
+ suffix: Chlorine
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Chlorine
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelChlorine
+
+- type: entity
+ id: LabelChlorine
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-chlorine
+
+- type: entity
+ parent: MetalBarrelWhite
+ id: ChemicalBarrelAluminium
+ suffix: Aluminium
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Aluminium
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelAluminium
+
+- type: entity
+ id: LabelAluminium
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-aluminium
+
+- type: entity
+ parent: MetalBarrelRed
+ id: ChemicalBarrelPhosphorus
+ suffix: Phosphorus
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Phosphorus
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelPhosphorus
+
+- type: entity
+ id: LabelPhosphorus
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-phosphorus
+
+- type: entity
+ parent: MetalBarrelYellow
+ id: ChemicalBarrelSulfur
+ suffix: Sulfur
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Sulfur
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelSulfur
+
+- type: entity
+ id: LabelSulfur
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-sulfur
+
+- type: entity
+ parent: MetalBarrelBlack
+ id: ChemicalBarrelSilicon
+ suffix: Silicon
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Silicon
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelSilicon
+
+- type: entity
+ id: LabelSilicon
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-silicon
+
+- type: entity
+ parent: MetalBarrelWhite
+ id: ChemicalBarrelHydrogen
+ suffix: Hydrogen
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Hydrogen
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelHydrogen
+
+- type: entity
+ id: LabelHydrogen
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-hydrogen
+
+- type: entity
+ parent: MetalBarrelGrey
+ id: ChemicalBarrelLithium
+ suffix: Lithium
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Lithium
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelLithium
+
+- type: entity
+ id: LabelLithium
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-lithium
+
+- type: entity
+ parent: MetalBarrelGrey
+ id: ChemicalBarrelSodium
+ suffix: Sodium
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Sodium
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelSodium
+
+- type: entity
+ id: LabelSodium
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-sodium
+
+- type: entity
+ parent: MetalBarrelYellow
+ id: ChemicalBarrelPotassium
+ suffix: Potassium
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Potassium
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelPotassium
+
+- type: entity
+ id: LabelPotassium
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-potassium
+
+- type: entity
+ parent: MetalBarrelGreen
+ id: ChemicalBarrelRadium
+ suffix: Radium
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Radium
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelRadium
+
+- type: entity
+ id: LabelRadium
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-radium
+
+- type: entity
+ parent: MetalBarrelGrey
+ id: ChemicalBarrelIron
+ suffix: Iron
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Iron
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelIron
+
+- type: entity
+ id: LabelIron
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-iron
+
+- type: entity
+ parent: MetalBarrelRed
+ id: ChemicalBarrelCopper
+ suffix: Copper
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Copper
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelCopper
+
+- type: entity
+ id: LabelCopper
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-copper
+
+- type: entity
+ parent: MetalBarrelYellow
+ id: ChemicalBarrelGold
+ suffix: Gold
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Gold
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelGold
+
+- type: entity
+ id: LabelGold
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-gold
+
+- type: entity
+ parent: MetalBarrelGrey
+ id: ChemicalBarrelMercury
+ suffix: Mercury
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Mercury
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelMercury
+
+- type: entity
+ id: LabelMercury
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-mercury
+
+- type: entity
+ parent: MetalBarrelWhite
+ id: ChemicalBarrelSilver
+ suffix: Silver
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Silver
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelSilver
+
+- type: entity
+ id: LabelSilver
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-silver
+
+- type: entity
+ parent: MetalBarrelBlue
+ id: ChemicalBarrelEthanol
+ suffix: Ethanol
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Ethanol
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelEthanol
+
+- type: entity
+ id: LabelEthanol
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-ethanol
+
+- type: entity
+ parent: MetalBarrelWhite
+ id: ChemicalBarrelSugar
+ suffix: Sugar
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Sugar
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelSugar
+
+- type: entity
+ id: LabelSugar
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-sugar
+
+- type: entity
+ parent: MetalBarrelRed
+ id: ChemicalBarrelNitrogen
+ suffix: Nitrogen
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Nitrogen
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelNitrogen
+
+- type: entity
+ id: LabelNitrogen
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-nitrogen
+
+- type: entity
+ parent: MetalBarrelBlue
+ id: ChemicalBarrelOxygen
+ suffix: Oxygen
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Oxygen
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelOxygen
+
+- type: entity
+ id: LabelOxygen
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-oxygen
+
+- type: entity
+ parent: MetalBarrelBlack
+ id: ChemicalBarrelOil
+ suffix: Oil
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Oil
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelOil
+
+- type: entity
+ id: LabelOil
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-oil
+
+- type: entity
+ parent: MetalBarrelGreen
+ id: ChemicalBarrelDiethylamine
+ suffix: Diethylamine
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Diethylamine
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelDiethylamine
+
+- type: entity
+ id: LabelDiethylamine
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-diethylamine
+
+- type: entity
+ parent: MetalBarrelYellow
+ id: ChemicalBarrelMustard
+ suffix: Mustard
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Mustard
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelMustard
+
+- type: entity
+ id: LabelMustard
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-mustard
+
+- type: entity
+ parent: MetalBarrelRed
+ id: ChemicalBarrelKetchup
+ suffix: Ketchup
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Ketchup
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelKetchup
+
+- type: entity
+ id: LabelKetchup
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-ketchup
+
+- type: entity
+ parent: MetalBarrelWhite
+ id: ChemicalBarrelMayo
+ suffix: Mayo
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Mayo
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelMayo
+
+- type: entity
+ id: LabelMayo
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-mayo
+
+- type: entity
+ parent: MetalBarrelYellow
+ id: ChemicalBarrelCornoil
+ suffix: Cornoil
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Cornoil
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelCornoil
+
+- type: entity
+ id: LabelCornoil
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-cornoil
+
+- type: entity
+ parent: MetalBarrelGreen
+ id: ChemicalBarrelOliveoil
+ suffix: Olive Oil
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: OilOlive
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelOilOlive
+
+- type: entity
+ id: LabelOilOlive
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-oil-olive
+
+- type: entity
+ parent: MetalBarrelGreen
+ id: ChemicalBarrelSpaceLube
+ suffix: Space Lube
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: SpaceLube
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelSpaceLube
+
+- type: entity
+ id: LabelSpaceLube
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-space-lube
+
+- type: entity
+ parent: MetalBarrelBlue
+ id: ChemicalBarrelSpaceCleaner
+ suffix: Space Cleaner
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: SpaceCleaner
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelSpaceCleaner
+
+- type: entity
+ id: LabelSpaceCleaner
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-space-cleaner
+
+- type: entity
+ parent: MetalBarrelBlue
+ id: ChemicalBarrelWater
+ suffix: Water
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Water
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelWater
+
+- type: entity
+ id: LabelWater
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-water
+
+- type: entity
+ parent: MetalBarrelYellow
+ id: ChemicalBarrelWhiskey
+ suffix: Whiskey
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Whiskey
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelWhiskey
+
+- type: entity
+ id: LabelWhiskey
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-whiskey
+
+- type: entity
+ parent: MetalBarrelWhite
+ id: ChemicalBarrelVodka
+ suffix: Vodka
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Vodka
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelVodka
+
+- type: entity
+ id: LabelVodka
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-vodka
+
+- type: entity
+ parent: MetalBarrelGreen
+ id: ChemicalBarrelTequila
+ suffix: Tequila
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Tequila
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelTequila
+
+- type: entity
+ id: LabelTequila
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-tequila
+
+- type: entity
+ parent: MetalBarrelRed
+ id: ChemicalBarrelRum
+ suffix: Rum
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Rum
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelRum
+
+- type: entity
+ id: LabelRum
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-rum
+
+- type: entity
+ parent: MetalBarrelBlue
+ id: ChemicalBarrelGin
+ suffix: Gin
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Gin
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelGin
+
+- type: entity
+ id: LabelGin
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-gin
+
+- type: entity
+ parent: MetalBarrelRed
+ id: ChemicalBarrelCoffeeLiqueur
+ suffix: Coffee Liqeueur
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: CoffeeLiqueur
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelCoffeeLiqueur
+
+- type: entity
+ id: LabelCoffeeLiqueur
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-coffeeliqueur
+
+- type: entity
+ parent: MetalBarrelGreen
+ id: ChemicalBarrelAbsinthe
+ suffix: Absinthe
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Absinthe
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelAbsinthe
+
+- type: entity
+ id: LabelAbsinthe
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-absinthe
+
+- type: entity
+ parent: MetalBarrelRed
+ id: ChemicalBarrelAle
+ suffix: Ale
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Ale
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelAle
+
+- type: entity
+ id: LabelAle
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-ale
+
+- type: entity
+ parent: MetalBarrelGreen
+ id: ChemicalBarrelVermouth
+ suffix: Vermouth
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Vermouth
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelVermouth
+
+- type: entity
+ id: LabelVermouth
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-vermouth
+
+- type: entity
+ parent: MetalBarrelRed
+ id: ChemicalBarrelWine
+ suffix: Wine
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Wine
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelWine
+
+- type: entity
+ id: LabelWine
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-wine
+
+- type: entity
+ parent: MetalBarrelGrey
+ id: ChemicalBarrelBeer
+ suffix: Beer
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Beer
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelBeer
+
+- type: entity
+ id: LabelBeer
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-beer
+
+- type: entity
+ parent: MetalBarrelBlack
+ id: ChemicalBarrelCognac
+ suffix: Cognac
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Cognac
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelCognac
+
+- type: entity
+ id: LabelCognac
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-cognac
+
+- type: entity
+ parent: MetalBarrelYellow
+ id: ChemicalBarrelMead
+ suffix: Mead
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ tank:
+ reagents:
+ - ReagentId: Mead
+ Quantity: 1000
+ - type: ContainerFill
+ containers:
+ paper_label:
+ - LabelMead
+
+- type: entity
+ id: LabelMead
+ parent: Paper
+ categories: [HideSpawnMenu]
+ components:
+ - type: Paper
+ content: reagent-label-mead
+
diff --git a/Resources/Prototypes/_NF/Entities/World/Debris/wrecks.yml b/Resources/Prototypes/_NF/Entities/World/Debris/wrecks.yml
index 5633ac69a75..349862552d2 100644
--- a/Resources/Prototypes/_NF/Entities/World/Debris/wrecks.yml
+++ b/Resources/Prototypes/_NF/Entities/World/Debris/wrecks.yml
@@ -56,12 +56,18 @@
# Big loot
- id: NFSalvageMaterialCrateSpawner
prob: 0.9
+ - id: NFSalvageChemicalBarrelSpawner
+ prob: 0.08
+ - id: NFSalvageServiceBarrelSpawner
+ prob: 0.02
+ - id: NFSalvageDrinkableBarrelSpawner
+ prob: 0.02
+ - id: NFSalvageEmptyBarrelSpawner
+ prob: 0.03
- id: SalvageCanisterSpawner
prob: 0.2
- id: SalvageLockerSpawner
prob: 0.2
- - id: SalvageTankSpawner
- prob: 0.15
- id: SalvageGeneratorSpawner
prob: 0.1
- id: SalvageFurnitureSpawner
@@ -70,6 +76,8 @@
prob: 0.1
- id: RandomArtifactSpawner
prob: 0.05
+ - id: SalvageTankSpawnerHighCapacity
+ prob: 0.0005
# Medical
- id: MedicalPodFilled # Medical bounties
prob: 0.03
diff --git a/Resources/Prototypes/_NF/GameRules/roundstart.yml b/Resources/Prototypes/_NF/GameRules/roundstart.yml
index 836fcc0a69b..a2214693626 100644
--- a/Resources/Prototypes/_NF/GameRules/roundstart.yml
+++ b/Resources/Prototypes/_NF/GameRules/roundstart.yml
@@ -1,9 +1,9 @@
- type: entity
- id: Adventure
+ id: NFAdventure
parent: BaseGameRule
categories: [ HideSpawnMenu ]
components:
- - type: AdventureRule
+ - type: NFAdventureRule
- type: entity
id: BluespaceEventScheduler
diff --git a/Resources/Prototypes/_NF/PointsOfInterest/anomalousgeode.yml b/Resources/Prototypes/_NF/PointsOfInterest/anomalousgeode.yml
index b52fb814288..00644f0686e 100644
--- a/Resources/Prototypes/_NF/PointsOfInterest/anomalousgeode.yml
+++ b/Resources/Prototypes/_NF/PointsOfInterest/anomalousgeode.yml
@@ -13,6 +13,7 @@
name: 'Anomalous Geode'
minimumDistance: 2100
maximumDistance: 3800
+ spawnGamePreset: [ NFAdventure, NFPirate ]
spawnGroup: ScienceLab
gridPath: /Maps/_NF/POI/anomalousgeode.yml
addComponents:
diff --git a/Resources/Prototypes/_NF/PointsOfInterest/anomalouslab.yml b/Resources/Prototypes/_NF/PointsOfInterest/anomalouslab.yml
index b3c705241ce..6d6a37e5db0 100644
--- a/Resources/Prototypes/_NF/PointsOfInterest/anomalouslab.yml
+++ b/Resources/Prototypes/_NF/PointsOfInterest/anomalouslab.yml
@@ -1,6 +1,6 @@
# Author Info
# GitHub: RealIHANOfficial (??)
-# Discord:
+# Discord:
# Maintainer Info
# GitHub: ???
@@ -13,6 +13,7 @@
name: 'Anomalous Lab'
minimumDistance: 2100
maximumDistance: 3800
+ spawnGamePreset: [ NFAdventure, NFPirate ]
spawnGroup: ScienceLab
gridPath: /Maps/_NF/POI/anomalouslab.yml
addComponents:
diff --git a/Resources/Prototypes/_NF/PointsOfInterest/bahamamamas.yml b/Resources/Prototypes/_NF/PointsOfInterest/bahamamamas.yml
index 9c89370ccc4..794d1c19e1f 100644
--- a/Resources/Prototypes/_NF/PointsOfInterest/bahamamamas.yml
+++ b/Resources/Prototypes/_NF/PointsOfInterest/bahamamamas.yml
@@ -13,6 +13,7 @@
name: "Bahama Mama's"
minimumDistance: 1200
maximumDistance: 2900
+ spawnGamePreset: [ NFAdventure, NFPirate ]
spawnGroup: RestStop
gridPath: /Maps/_NF/POI/bahama.yml
addComponents:
diff --git a/Resources/Prototypes/_NF/PointsOfInterest/caseys.yml b/Resources/Prototypes/_NF/PointsOfInterest/caseys.yml
index e4ff899c439..bad9005947c 100644
--- a/Resources/Prototypes/_NF/PointsOfInterest/caseys.yml
+++ b/Resources/Prototypes/_NF/PointsOfInterest/caseys.yml
@@ -1,5 +1,5 @@
# Author Info
-# GitHub:
+# GitHub:
# Discord: Terezi (??)
# Maintainer Info
@@ -13,6 +13,7 @@
name: "Crazy Casey's Casino"
minimumDistance: 3250
maximumDistance: 5600
+ spawnGamePreset: [ NFAdventure, NFPirate ]
gridPath: /Maps/_NF/POI/caseyscasino.yml
addComponents:
- type: IFF
diff --git a/Resources/Prototypes/_NF/PointsOfInterest/courthouse.yml b/Resources/Prototypes/_NF/PointsOfInterest/courthouse.yml
index e56ca7a0ff5..a35d46d3eda 100644
--- a/Resources/Prototypes/_NF/PointsOfInterest/courthouse.yml
+++ b/Resources/Prototypes/_NF/PointsOfInterest/courthouse.yml
@@ -7,12 +7,13 @@
# Discord: ???
# Notes:
-#
+#
- type: pointOfInterest
id: Courthouse
name: "Courthouse"
minimumDistance: 1150
maximumDistance: 2050
+ spawnGamePreset: [ NFAdventure, NFPirate ]
spawnGroup: Required
gridPath: /Maps/_NF/POI/courthouse.yml
addComponents:
diff --git a/Resources/Prototypes/_NF/PointsOfInterest/cove.yml b/Resources/Prototypes/_NF/PointsOfInterest/cove.yml
index 3a6810a9a91..57bb4d1c336 100644
--- a/Resources/Prototypes/_NF/PointsOfInterest/cove.yml
+++ b/Resources/Prototypes/_NF/PointsOfInterest/cove.yml
@@ -13,6 +13,7 @@
name: Pirate Cove
minimumDistance: 10000
maximumDistance: 15000
+ spawnGamePreset: [ NFPirate ]
spawnGroup: Required
gridPath: /Maps/_NF/POI/cove.yml
hideWarp: true
diff --git a/Resources/Prototypes/_NF/PointsOfInterest/depots.yml b/Resources/Prototypes/_NF/PointsOfInterest/depots.yml
index edf5435e393..53abefb0626 100644
--- a/Resources/Prototypes/_NF/PointsOfInterest/depots.yml
+++ b/Resources/Prototypes/_NF/PointsOfInterest/depots.yml
@@ -13,6 +13,7 @@
name: Cargo Depot
minimumDistance: 4500
maximumDistance: 6000
+ spawnGamePreset: [ NFAdventure, NFPirate ]
spawnGroup: CargoDepot
gridPath: /Maps/_NF/POI/cargodepot.yml
addComponents:
@@ -44,7 +45,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:
@@ -52,13 +53,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 NfAdventureSystem
+ 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:
@@ -66,6 +67,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 NfAdventureSystem
+ destinationProto: CargoA # Redefined in PointOfInterestSystem
diff --git a/Resources/Prototypes/_NF/PointsOfInterest/edison.yml b/Resources/Prototypes/_NF/PointsOfInterest/edison.yml
index c06777fa9bb..04bbf80b51d 100644
--- a/Resources/Prototypes/_NF/PointsOfInterest/edison.yml
+++ b/Resources/Prototypes/_NF/PointsOfInterest/edison.yml
@@ -1,5 +1,5 @@
# Author Info
-# GitHub:
+# GitHub:
# Discord: Checkraze
# Maintainer Info
@@ -7,14 +7,15 @@
# Discord: ???
# Notes:
-#
+#
# - type: pointOfInterest
# id: Edison
# name: 'Edison Power Plant'
# minimumDistance: 3650
# maximumDistance: 6400
+ # spawnGamePreset: [ NFAdventure, NFPirate ]
# spawnGroup: Required
- # gridPath: /Maps/_NF/POI/edison.yml
+ # gridPath: /Maps/_NF/POI/edison.yml
# addComponents:
# - type: IFF
# color: "#3737C8"
@@ -38,4 +39,4 @@
# availableJobs:
# Pilot: [ 0, 0 ]
# Mercenary: [ 0, 0 ]
- # Contractor: [ 0, 0 ]
\ No newline at end of file
+ # Contractor: [ 0, 0 ]
diff --git a/Resources/Prototypes/_NF/PointsOfInterest/grifty.yml b/Resources/Prototypes/_NF/PointsOfInterest/grifty.yml
index 4b9d434f497..cb5fce22f97 100644
--- a/Resources/Prototypes/_NF/PointsOfInterest/grifty.yml
+++ b/Resources/Prototypes/_NF/PointsOfInterest/grifty.yml
@@ -1,5 +1,5 @@
# Author Info
-# GitHub:
+# GitHub:
# Discord: ???
# Maintainer Info
@@ -13,6 +13,7 @@
name: "Grifty's Gas n Grub"
minimumDistance: 3250
maximumDistance: 5600
+ spawnGamePreset: [ NFAdventure, NFPirate ]
spawnGroup: Scrapyard
gridPath: /Maps/_NF/POI/grifty.yml
addComponents:
diff --git a/Resources/Prototypes/_NF/PointsOfInterest/lodge.yml b/Resources/Prototypes/_NF/PointsOfInterest/lodge.yml
index b9d5ce3ebac..eb09273a2e4 100644
--- a/Resources/Prototypes/_NF/PointsOfInterest/lodge.yml
+++ b/Resources/Prototypes/_NF/PointsOfInterest/lodge.yml
@@ -13,6 +13,7 @@
name: 'Expeditionary Lodge'
minimumDistance: 1650
maximumDistance: 3400
+ spawnGamePreset: [ NFAdventure, NFPirate ]
spawnGroup: Required
gridPath: /Maps/_NF/POI/lodge.yml
addComponents:
diff --git a/Resources/Prototypes/_NF/PointsOfInterest/lpbravo.yml b/Resources/Prototypes/_NF/PointsOfInterest/lpbravo.yml
index 478b777968f..7f135395d5b 100644
--- a/Resources/Prototypes/_NF/PointsOfInterest/lpbravo.yml
+++ b/Resources/Prototypes/_NF/PointsOfInterest/lpbravo.yml
@@ -1,5 +1,5 @@
# Author Info
-# GitHub:
+# GitHub:
# Discord: Checkraze
# Maintainer Info
@@ -13,6 +13,7 @@
name: 'Listening Point Bravo'
minimumDistance: 4000
maximumDistance: 6000
+ spawnGamePreset: [ NFAdventure, NFPirate ]
spawnGroup: SyndicateFOB
gridPath: /Maps/_NF/POI/lpbravo.yml
hideWarp: true
@@ -39,4 +40,4 @@
mapNameTemplate: 'Listening Point Bravo'
- type: StationJobs
availableJobs: {}
- - type: StationDeadDropHintExempt
\ No newline at end of file
+ - type: StationDeadDropHintExempt
diff --git a/Resources/Prototypes/_NF/PointsOfInterest/mchobo.yml b/Resources/Prototypes/_NF/PointsOfInterest/mchobo.yml
index ef4b3ece947..aa6a3e70c2b 100644
--- a/Resources/Prototypes/_NF/PointsOfInterest/mchobo.yml
+++ b/Resources/Prototypes/_NF/PointsOfInterest/mchobo.yml
@@ -8,12 +8,13 @@
# Notes:
# Dumping ground of broken dreams and broken ships.
-# Based on the McCargo built by Dvir01 (https://github.com/dvir001) and ruined with drunken pride by Tych0.
+# Based on the McCargo built by Dvir01 (https://github.com/dvir001) and ruined with drunken pride by Tych0.
- type: pointOfInterest
id: McHobo
name: Derelict McCargo
minimumDistance: 3250
maximumDistance: 5600
+ spawnGamePreset: [ NFAdventure, NFPirate ]
spawnGroup: Scrapyard
gridPath: /Maps/_NF/POI/mchobo.yml
addComponents:
diff --git a/Resources/Prototypes/_NF/PointsOfInterest/nfsd.yml b/Resources/Prototypes/_NF/PointsOfInterest/nfsd.yml
index 09336a02ce0..d993915f438 100644
--- a/Resources/Prototypes/_NF/PointsOfInterest/nfsd.yml
+++ b/Resources/Prototypes/_NF/PointsOfInterest/nfsd.yml
@@ -13,6 +13,7 @@
name: 'NFSD Outpost'
minimumDistance: 750
maximumDistance: 1000
+ spawnGamePreset: [ NFAdventure, NFPirate ]
spawnGroup: Required
gridPath: /Maps/_NF/POI/nfsd.yml
addComponents:
diff --git a/Resources/Prototypes/_NF/PointsOfInterest/northpole.yml b/Resources/Prototypes/_NF/PointsOfInterest/northpole.yml
index 59324e7c148..47a9c84fc8b 100644
--- a/Resources/Prototypes/_NF/PointsOfInterest/northpole.yml
+++ b/Resources/Prototypes/_NF/PointsOfInterest/northpole.yml
@@ -1,5 +1,5 @@
# Author Info
-# GitHub:
+# GitHub:
# Discord: Checkraze
# Maintainer Info
@@ -13,6 +13,7 @@
name: "The North Pole"
minimumDistance: 2150
maximumDistance: 4850
+ spawnGamePreset: [ NFAdventure, NFPirate ]
spawnGroup: Christmas
spawnChance: 0
gridPath: /Maps/_NF/POI/northpole.yml
@@ -23,4 +24,4 @@
flags: [HideLabel]
- type: Shuttle
angularDamping: 999999
- linearDamping: 999999
\ No newline at end of file
+ linearDamping: 999999
diff --git a/Resources/Prototypes/_NF/PointsOfInterest/omnichurch.yml b/Resources/Prototypes/_NF/PointsOfInterest/omnichurch.yml
index 43a8df90949..8a0861058c2 100644
--- a/Resources/Prototypes/_NF/PointsOfInterest/omnichurch.yml
+++ b/Resources/Prototypes/_NF/PointsOfInterest/omnichurch.yml
@@ -7,12 +7,13 @@
# Discord: ???
# Notes:
-#
+#
- type: pointOfInterest
id: Omnichurch
name: "Omnichurch Beacon"
minimumDistance: 2200
maximumDistance: 4900
+ spawnGamePreset: [ NFAdventure, NFPirate ]
gridPath: /Maps/_NF/POI/beacon.yml
addComponents:
- type: IFF
@@ -20,4 +21,4 @@
readOnly: true
- type: Shuttle
angularDamping: 999999
- linearDamping: 999999
\ No newline at end of file
+ linearDamping: 999999
diff --git a/Resources/Prototypes/_NF/PointsOfInterest/thepit.yml b/Resources/Prototypes/_NF/PointsOfInterest/thepit.yml
index 80ceac9e771..8a13ec26b97 100644
--- a/Resources/Prototypes/_NF/PointsOfInterest/thepit.yml
+++ b/Resources/Prototypes/_NF/PointsOfInterest/thepit.yml
@@ -13,6 +13,7 @@
name: "The Pit"
minimumDistance: 2200
maximumDistance: 4200
+ spawnGamePreset: [ NFAdventure, NFPirate ]
spawnGroup: Arena
gridPath: /Maps/_NF/POI/arena.yml
addComponents:
diff --git a/Resources/Prototypes/_NF/PointsOfInterest/tinniasrest.yml b/Resources/Prototypes/_NF/PointsOfInterest/tinniasrest.yml
index 5ca2436ec0b..c7f48701a94 100644
--- a/Resources/Prototypes/_NF/PointsOfInterest/tinniasrest.yml
+++ b/Resources/Prototypes/_NF/PointsOfInterest/tinniasrest.yml
@@ -13,6 +13,7 @@
name: "Tinnia's Rest"
minimumDistance: 1200
maximumDistance: 2900
+ spawnGamePreset: [ NFAdventure, NFPirate ]
spawnGroup: RestStop
gridPath: /Maps/_NF/POI/tinnia.yml
addComponents:
diff --git a/Resources/Prototypes/_NF/PointsOfInterest/trade.yml b/Resources/Prototypes/_NF/PointsOfInterest/trade.yml
index 475cd67bf6a..555f321139b 100644
--- a/Resources/Prototypes/_NF/PointsOfInterest/trade.yml
+++ b/Resources/Prototypes/_NF/PointsOfInterest/trade.yml
@@ -13,6 +13,7 @@
name: Trade Outpost
minimumDistance: 1500
maximumDistance: 2500
+ spawnGamePreset: [ NFAdventure, NFPirate ]
spawnGroup: MarketStation
gridPath: /Maps/_NF/POI/trade.yml
addComponents:
diff --git a/Resources/Prototypes/_NF/PointsOfInterest/trademall.yml b/Resources/Prototypes/_NF/PointsOfInterest/trademall.yml
index 5c14ca2b5ae..9b7e75158fb 100644
--- a/Resources/Prototypes/_NF/PointsOfInterest/trademall.yml
+++ b/Resources/Prototypes/_NF/PointsOfInterest/trademall.yml
@@ -13,6 +13,7 @@
name: Trade Mall
minimumDistance: 1500
maximumDistance: 2500
+ spawnGamePreset: [ NFAdventure, NFPirate ]
spawnGroup: MarketStation
gridPath: /Maps/_NF/POI/trademall.yml
addComponents:
diff --git a/Resources/Prototypes/_NF/Recipes/Crafting/Graphs/barrel.yml b/Resources/Prototypes/_NF/Recipes/Crafting/Graphs/barrel.yml
new file mode 100644
index 00000000000..ac91b2e2370
--- /dev/null
+++ b/Resources/Prototypes/_NF/Recipes/Crafting/Graphs/barrel.yml
@@ -0,0 +1,26 @@
+- type: constructionGraph
+ id: WoodenBarrel
+ start: start
+ graph:
+ - node: start
+ edges:
+ - to: woodenbarrel
+ steps:
+ - material: WoodPlank
+ amount: 5
+ doAfter: 5
+
+ - node: woodenbarrel
+ entity: WoodenBarrel
+ edges:
+ - to: start
+ steps:
+ - tool: Prying
+ doAfter: 2
+ completed:
+ - !type:SpawnPrototype
+ prototype: MaterialWoodPlank1
+ amount: 5
+ - !type:EmptyAllContainers
+ - !type:DeleteEntity
+
diff --git a/Resources/Prototypes/_NF/Recipes/Crafting/barrel.yml b/Resources/Prototypes/_NF/Recipes/Crafting/barrel.yml
new file mode 100644
index 00000000000..a6649928cba
--- /dev/null
+++ b/Resources/Prototypes/_NF/Recipes/Crafting/barrel.yml
@@ -0,0 +1,12 @@
+- type: construction
+ name: wooden barrel
+ id: WoodenBarrel
+ graph: WoodenBarrel
+ startNode: start
+ targetNode: woodenbarrel
+ category: construction-category-storage
+ description: A musty old wooden barrel.
+ icon:
+ sprite: _NF/Objects/Storage/Barrels/wood.rsi
+ state: icon
+ objectType: Structure
\ No newline at end of file
diff --git a/Resources/Prototypes/_NF/game_presets.yml b/Resources/Prototypes/_NF/game_presets.yml
index b87244e0a7f..6c39e92fdb9 100644
--- a/Resources/Prototypes/_NF/game_presets.yml
+++ b/Resources/Prototypes/_NF/game_presets.yml
@@ -1,12 +1,30 @@
- type: gamePreset
- id: Adventure
+ id: NFAdventure
alias:
+ - nfadventure
- adventure
- name: adventure-title
- description: adventure-description
- showInVote: false
+ name: nf-adventure-title
+ description: nf-adventure-description
+ showInVote: true
rules:
- - Adventure
+ - NFAdventure
+ - BasicStationEventScheduler
+ - BluespaceEventScheduler
+ - BluespaceDungeonEventScheduler
+ - BluespaceSalvageEventScheduler
+ - SmugglingEventScheduler
+ - FrontierRoundstartVariation
+
+- type: gamePreset
+ id: NFPirate
+ alias:
+ - nfpirate
+ - pirate
+ name: nf-pirate-title
+ description: nf-pirate-description
+ showInVote: true
+ rules:
+ - NFAdventure
- BasicStationEventScheduler
- BluespaceEventScheduler
- BluespaceDungeonEventScheduler
diff --git a/Resources/Prototypes/game_presets.yml b/Resources/Prototypes/game_presets.yml
index 945b4a8c83b..ad66624f7f5 100644
--- a/Resources/Prototypes/game_presets.yml
+++ b/Resources/Prototypes/game_presets.yml
@@ -91,7 +91,7 @@
showInVote: false #4boring4vote
description: greenshift-description
rules:
- - SpaceTrafficControlFriendlyEventScheduler
+ - SpaceTrafficControlFriendlyEventScheduler
- BasicRoundstartVariation
- type: gamePreset
@@ -100,7 +100,7 @@
- secret
- sekrit
name: secret-title
- showInVote: true
+ showInVote: false # Frontier: true < false
description: secret-description
rules:
- Secret
@@ -126,7 +126,7 @@
showInVote: false #Admin Use
description: secret-description
rules:
- - SpaceTrafficControlFriendlyEventScheduler
+ - SpaceTrafficControlFriendlyEventScheduler
- BasicRoundstartVariation
- type: gamePreset
@@ -164,7 +164,7 @@
name: death-match-title
description: death-match-description
maxPlayers: 15
- showInVote: true
+ showInVote: false # Frontier: true < false
supportedMaps: DeathMatchMapPool
rules:
- DeathMatch31
@@ -233,4 +233,4 @@
- BasicStationEventScheduler
- KesslerSyndromeScheduler
- SpaceTrafficControlEventScheduler
- - BasicRoundstartVariation
\ No newline at end of file
+ - BasicRoundstartVariation
diff --git a/Resources/Textures/_NF/Objects/Storage/Barrels/black.rsi/icon.png b/Resources/Textures/_NF/Objects/Storage/Barrels/black.rsi/icon.png
new file mode 100644
index 00000000000..ee1382a4809
Binary files /dev/null and b/Resources/Textures/_NF/Objects/Storage/Barrels/black.rsi/icon.png differ
diff --git a/Resources/Textures/_NF/Objects/Storage/Barrels/black.rsi/icon_open.png b/Resources/Textures/_NF/Objects/Storage/Barrels/black.rsi/icon_open.png
new file mode 100644
index 00000000000..9cc195f27d0
Binary files /dev/null and b/Resources/Textures/_NF/Objects/Storage/Barrels/black.rsi/icon_open.png differ
diff --git a/Resources/Textures/_NF/Objects/Storage/Barrels/black.rsi/meta.json b/Resources/Textures/_NF/Objects/Storage/Barrels/black.rsi/meta.json
new file mode 100644
index 00000000000..a6e9f155347
--- /dev/null
+++ b/Resources/Textures/_NF/Objects/Storage/Barrels/black.rsi/meta.json
@@ -0,0 +1,23 @@
+{
+ "version": 1,
+ "license": "CC-BY-SA-3.0",
+ "copyright": "Taken from tgstation PR https://github.com/tgstation/tgstation/pull/38977, modified by rosieposieeee & whatston3",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "states": [
+ {
+ "name": "icon"
+ },
+ {
+ "name": "icon_open"
+ },
+ {
+ "name": "paper"
+ },
+ {
+ "name": "metal_explosive_label"
+ }
+ ]
+}
diff --git a/Resources/Textures/_NF/Objects/Storage/Barrels/black.rsi/metal_explosive_label.png b/Resources/Textures/_NF/Objects/Storage/Barrels/black.rsi/metal_explosive_label.png
new file mode 100644
index 00000000000..b1b977b07e8
Binary files /dev/null and b/Resources/Textures/_NF/Objects/Storage/Barrels/black.rsi/metal_explosive_label.png differ
diff --git a/Resources/Textures/_NF/Objects/Storage/Barrels/black.rsi/paper.png b/Resources/Textures/_NF/Objects/Storage/Barrels/black.rsi/paper.png
new file mode 100644
index 00000000000..08d7f696fec
Binary files /dev/null and b/Resources/Textures/_NF/Objects/Storage/Barrels/black.rsi/paper.png differ
diff --git a/Resources/Textures/_NF/Objects/Storage/Barrels/blue.rsi/icon.png b/Resources/Textures/_NF/Objects/Storage/Barrels/blue.rsi/icon.png
new file mode 100644
index 00000000000..1bf90ce9918
Binary files /dev/null and b/Resources/Textures/_NF/Objects/Storage/Barrels/blue.rsi/icon.png differ
diff --git a/Resources/Textures/_NF/Objects/Storage/Barrels/blue.rsi/icon_open.png b/Resources/Textures/_NF/Objects/Storage/Barrels/blue.rsi/icon_open.png
new file mode 100644
index 00000000000..9cc195f27d0
Binary files /dev/null and b/Resources/Textures/_NF/Objects/Storage/Barrels/blue.rsi/icon_open.png differ
diff --git a/Resources/Textures/_NF/Objects/Storage/Barrels/blue.rsi/meta.json b/Resources/Textures/_NF/Objects/Storage/Barrels/blue.rsi/meta.json
new file mode 100644
index 00000000000..a6e9f155347
--- /dev/null
+++ b/Resources/Textures/_NF/Objects/Storage/Barrels/blue.rsi/meta.json
@@ -0,0 +1,23 @@
+{
+ "version": 1,
+ "license": "CC-BY-SA-3.0",
+ "copyright": "Taken from tgstation PR https://github.com/tgstation/tgstation/pull/38977, modified by rosieposieeee & whatston3",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "states": [
+ {
+ "name": "icon"
+ },
+ {
+ "name": "icon_open"
+ },
+ {
+ "name": "paper"
+ },
+ {
+ "name": "metal_explosive_label"
+ }
+ ]
+}
diff --git a/Resources/Textures/_NF/Objects/Storage/Barrels/blue.rsi/metal_explosive_label.png b/Resources/Textures/_NF/Objects/Storage/Barrels/blue.rsi/metal_explosive_label.png
new file mode 100644
index 00000000000..b1b977b07e8
Binary files /dev/null and b/Resources/Textures/_NF/Objects/Storage/Barrels/blue.rsi/metal_explosive_label.png differ
diff --git a/Resources/Textures/_NF/Objects/Storage/Barrels/blue.rsi/paper.png b/Resources/Textures/_NF/Objects/Storage/Barrels/blue.rsi/paper.png
new file mode 100644
index 00000000000..08d7f696fec
Binary files /dev/null and b/Resources/Textures/_NF/Objects/Storage/Barrels/blue.rsi/paper.png differ
diff --git a/Resources/Textures/_NF/Objects/Storage/Barrels/green.rsi/icon.png b/Resources/Textures/_NF/Objects/Storage/Barrels/green.rsi/icon.png
new file mode 100644
index 00000000000..101ec3f6d1b
Binary files /dev/null and b/Resources/Textures/_NF/Objects/Storage/Barrels/green.rsi/icon.png differ
diff --git a/Resources/Textures/_NF/Objects/Storage/Barrels/green.rsi/icon_open.png b/Resources/Textures/_NF/Objects/Storage/Barrels/green.rsi/icon_open.png
new file mode 100644
index 00000000000..9cc195f27d0
Binary files /dev/null and b/Resources/Textures/_NF/Objects/Storage/Barrels/green.rsi/icon_open.png differ
diff --git a/Resources/Textures/_NF/Objects/Storage/Barrels/green.rsi/meta.json b/Resources/Textures/_NF/Objects/Storage/Barrels/green.rsi/meta.json
new file mode 100644
index 00000000000..a6e9f155347
--- /dev/null
+++ b/Resources/Textures/_NF/Objects/Storage/Barrels/green.rsi/meta.json
@@ -0,0 +1,23 @@
+{
+ "version": 1,
+ "license": "CC-BY-SA-3.0",
+ "copyright": "Taken from tgstation PR https://github.com/tgstation/tgstation/pull/38977, modified by rosieposieeee & whatston3",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "states": [
+ {
+ "name": "icon"
+ },
+ {
+ "name": "icon_open"
+ },
+ {
+ "name": "paper"
+ },
+ {
+ "name": "metal_explosive_label"
+ }
+ ]
+}
diff --git a/Resources/Textures/_NF/Objects/Storage/Barrels/green.rsi/metal_explosive_label.png b/Resources/Textures/_NF/Objects/Storage/Barrels/green.rsi/metal_explosive_label.png
new file mode 100644
index 00000000000..b1b977b07e8
Binary files /dev/null and b/Resources/Textures/_NF/Objects/Storage/Barrels/green.rsi/metal_explosive_label.png differ
diff --git a/Resources/Textures/_NF/Objects/Storage/Barrels/green.rsi/paper.png b/Resources/Textures/_NF/Objects/Storage/Barrels/green.rsi/paper.png
new file mode 100644
index 00000000000..08d7f696fec
Binary files /dev/null and b/Resources/Textures/_NF/Objects/Storage/Barrels/green.rsi/paper.png differ
diff --git a/Resources/Textures/_NF/Objects/Storage/Barrels/grey.rsi/icon.png b/Resources/Textures/_NF/Objects/Storage/Barrels/grey.rsi/icon.png
new file mode 100644
index 00000000000..a417ce2e29c
Binary files /dev/null and b/Resources/Textures/_NF/Objects/Storage/Barrels/grey.rsi/icon.png differ
diff --git a/Resources/Textures/_NF/Objects/Storage/Barrels/grey.rsi/icon_open.png b/Resources/Textures/_NF/Objects/Storage/Barrels/grey.rsi/icon_open.png
new file mode 100644
index 00000000000..9cc195f27d0
Binary files /dev/null and b/Resources/Textures/_NF/Objects/Storage/Barrels/grey.rsi/icon_open.png differ
diff --git a/Resources/Textures/_NF/Objects/Storage/Barrels/grey.rsi/meta.json b/Resources/Textures/_NF/Objects/Storage/Barrels/grey.rsi/meta.json
new file mode 100644
index 00000000000..a6e9f155347
--- /dev/null
+++ b/Resources/Textures/_NF/Objects/Storage/Barrels/grey.rsi/meta.json
@@ -0,0 +1,23 @@
+{
+ "version": 1,
+ "license": "CC-BY-SA-3.0",
+ "copyright": "Taken from tgstation PR https://github.com/tgstation/tgstation/pull/38977, modified by rosieposieeee & whatston3",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "states": [
+ {
+ "name": "icon"
+ },
+ {
+ "name": "icon_open"
+ },
+ {
+ "name": "paper"
+ },
+ {
+ "name": "metal_explosive_label"
+ }
+ ]
+}
diff --git a/Resources/Textures/_NF/Objects/Storage/Barrels/grey.rsi/metal_explosive_label.png b/Resources/Textures/_NF/Objects/Storage/Barrels/grey.rsi/metal_explosive_label.png
new file mode 100644
index 00000000000..b1b977b07e8
Binary files /dev/null and b/Resources/Textures/_NF/Objects/Storage/Barrels/grey.rsi/metal_explosive_label.png differ
diff --git a/Resources/Textures/_NF/Objects/Storage/Barrels/grey.rsi/paper.png b/Resources/Textures/_NF/Objects/Storage/Barrels/grey.rsi/paper.png
new file mode 100644
index 00000000000..08d7f696fec
Binary files /dev/null and b/Resources/Textures/_NF/Objects/Storage/Barrels/grey.rsi/paper.png differ
diff --git a/Resources/Textures/_NF/Objects/Storage/Barrels/red.rsi/icon.png b/Resources/Textures/_NF/Objects/Storage/Barrels/red.rsi/icon.png
new file mode 100644
index 00000000000..6c37208bcfa
Binary files /dev/null and b/Resources/Textures/_NF/Objects/Storage/Barrels/red.rsi/icon.png differ
diff --git a/Resources/Textures/_NF/Objects/Storage/Barrels/red.rsi/icon_open.png b/Resources/Textures/_NF/Objects/Storage/Barrels/red.rsi/icon_open.png
new file mode 100644
index 00000000000..9cc195f27d0
Binary files /dev/null and b/Resources/Textures/_NF/Objects/Storage/Barrels/red.rsi/icon_open.png differ
diff --git a/Resources/Textures/_NF/Objects/Storage/Barrels/red.rsi/meta.json b/Resources/Textures/_NF/Objects/Storage/Barrels/red.rsi/meta.json
new file mode 100644
index 00000000000..a6e9f155347
--- /dev/null
+++ b/Resources/Textures/_NF/Objects/Storage/Barrels/red.rsi/meta.json
@@ -0,0 +1,23 @@
+{
+ "version": 1,
+ "license": "CC-BY-SA-3.0",
+ "copyright": "Taken from tgstation PR https://github.com/tgstation/tgstation/pull/38977, modified by rosieposieeee & whatston3",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "states": [
+ {
+ "name": "icon"
+ },
+ {
+ "name": "icon_open"
+ },
+ {
+ "name": "paper"
+ },
+ {
+ "name": "metal_explosive_label"
+ }
+ ]
+}
diff --git a/Resources/Textures/_NF/Objects/Storage/Barrels/red.rsi/metal_explosive_label.png b/Resources/Textures/_NF/Objects/Storage/Barrels/red.rsi/metal_explosive_label.png
new file mode 100644
index 00000000000..b1b977b07e8
Binary files /dev/null and b/Resources/Textures/_NF/Objects/Storage/Barrels/red.rsi/metal_explosive_label.png differ
diff --git a/Resources/Textures/_NF/Objects/Storage/Barrels/red.rsi/paper.png b/Resources/Textures/_NF/Objects/Storage/Barrels/red.rsi/paper.png
new file mode 100644
index 00000000000..08d7f696fec
Binary files /dev/null and b/Resources/Textures/_NF/Objects/Storage/Barrels/red.rsi/paper.png differ
diff --git a/Resources/Textures/_NF/Objects/Storage/Barrels/white.rsi/icon.png b/Resources/Textures/_NF/Objects/Storage/Barrels/white.rsi/icon.png
new file mode 100644
index 00000000000..c935fef87d4
Binary files /dev/null and b/Resources/Textures/_NF/Objects/Storage/Barrels/white.rsi/icon.png differ
diff --git a/Resources/Textures/_NF/Objects/Storage/Barrels/white.rsi/icon_open.png b/Resources/Textures/_NF/Objects/Storage/Barrels/white.rsi/icon_open.png
new file mode 100644
index 00000000000..9cc195f27d0
Binary files /dev/null and b/Resources/Textures/_NF/Objects/Storage/Barrels/white.rsi/icon_open.png differ
diff --git a/Resources/Textures/_NF/Objects/Storage/Barrels/white.rsi/meta.json b/Resources/Textures/_NF/Objects/Storage/Barrels/white.rsi/meta.json
new file mode 100644
index 00000000000..a6e9f155347
--- /dev/null
+++ b/Resources/Textures/_NF/Objects/Storage/Barrels/white.rsi/meta.json
@@ -0,0 +1,23 @@
+{
+ "version": 1,
+ "license": "CC-BY-SA-3.0",
+ "copyright": "Taken from tgstation PR https://github.com/tgstation/tgstation/pull/38977, modified by rosieposieeee & whatston3",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "states": [
+ {
+ "name": "icon"
+ },
+ {
+ "name": "icon_open"
+ },
+ {
+ "name": "paper"
+ },
+ {
+ "name": "metal_explosive_label"
+ }
+ ]
+}
diff --git a/Resources/Textures/_NF/Objects/Storage/Barrels/white.rsi/metal_explosive_label.png b/Resources/Textures/_NF/Objects/Storage/Barrels/white.rsi/metal_explosive_label.png
new file mode 100644
index 00000000000..b1b977b07e8
Binary files /dev/null and b/Resources/Textures/_NF/Objects/Storage/Barrels/white.rsi/metal_explosive_label.png differ
diff --git a/Resources/Textures/_NF/Objects/Storage/Barrels/white.rsi/paper.png b/Resources/Textures/_NF/Objects/Storage/Barrels/white.rsi/paper.png
new file mode 100644
index 00000000000..08d7f696fec
Binary files /dev/null and b/Resources/Textures/_NF/Objects/Storage/Barrels/white.rsi/paper.png differ
diff --git a/Resources/Textures/_NF/Objects/Storage/Barrels/wood.rsi/closed.png b/Resources/Textures/_NF/Objects/Storage/Barrels/wood.rsi/closed.png
new file mode 100644
index 00000000000..b111827b8e5
Binary files /dev/null and b/Resources/Textures/_NF/Objects/Storage/Barrels/wood.rsi/closed.png differ
diff --git a/Resources/Textures/_NF/Objects/Storage/Barrels/wood.rsi/icon.png b/Resources/Textures/_NF/Objects/Storage/Barrels/wood.rsi/icon.png
new file mode 100644
index 00000000000..bfc92c166d4
Binary files /dev/null and b/Resources/Textures/_NF/Objects/Storage/Barrels/wood.rsi/icon.png differ
diff --git a/Resources/Textures/_NF/Objects/Storage/Barrels/wood.rsi/meta.json b/Resources/Textures/_NF/Objects/Storage/Barrels/wood.rsi/meta.json
new file mode 100644
index 00000000000..8e941fd7d61
--- /dev/null
+++ b/Resources/Textures/_NF/Objects/Storage/Barrels/wood.rsi/meta.json
@@ -0,0 +1,20 @@
+{
+ "version": 1,
+ "license": "CC-BY-SA-3.0",
+ "copyright": "Taken from tgstation PR https://github.com/tgstation/tgstation/pull/38977, modified by rosieposieeee",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "states": [
+ {
+ "name": "closed"
+ },
+ {
+ "name": "open"
+ },
+ {
+ "name": "icon"
+ }
+ ]
+}
diff --git a/Resources/Textures/_NF/Objects/Storage/Barrels/wood.rsi/open.png b/Resources/Textures/_NF/Objects/Storage/Barrels/wood.rsi/open.png
new file mode 100644
index 00000000000..bfc92c166d4
Binary files /dev/null and b/Resources/Textures/_NF/Objects/Storage/Barrels/wood.rsi/open.png differ
diff --git a/Resources/Textures/_NF/Objects/Storage/Barrels/yellow.rsi/icon.png b/Resources/Textures/_NF/Objects/Storage/Barrels/yellow.rsi/icon.png
new file mode 100644
index 00000000000..a22bef0ff3f
Binary files /dev/null and b/Resources/Textures/_NF/Objects/Storage/Barrels/yellow.rsi/icon.png differ
diff --git a/Resources/Textures/_NF/Objects/Storage/Barrels/yellow.rsi/icon_open.png b/Resources/Textures/_NF/Objects/Storage/Barrels/yellow.rsi/icon_open.png
new file mode 100644
index 00000000000..9cc195f27d0
Binary files /dev/null and b/Resources/Textures/_NF/Objects/Storage/Barrels/yellow.rsi/icon_open.png differ
diff --git a/Resources/Textures/_NF/Objects/Storage/Barrels/yellow.rsi/meta.json b/Resources/Textures/_NF/Objects/Storage/Barrels/yellow.rsi/meta.json
new file mode 100644
index 00000000000..a6e9f155347
--- /dev/null
+++ b/Resources/Textures/_NF/Objects/Storage/Barrels/yellow.rsi/meta.json
@@ -0,0 +1,23 @@
+{
+ "version": 1,
+ "license": "CC-BY-SA-3.0",
+ "copyright": "Taken from tgstation PR https://github.com/tgstation/tgstation/pull/38977, modified by rosieposieeee & whatston3",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "states": [
+ {
+ "name": "icon"
+ },
+ {
+ "name": "icon_open"
+ },
+ {
+ "name": "paper"
+ },
+ {
+ "name": "metal_explosive_label"
+ }
+ ]
+}
diff --git a/Resources/Textures/_NF/Objects/Storage/Barrels/yellow.rsi/metal_explosive_label.png b/Resources/Textures/_NF/Objects/Storage/Barrels/yellow.rsi/metal_explosive_label.png
new file mode 100644
index 00000000000..b1b977b07e8
Binary files /dev/null and b/Resources/Textures/_NF/Objects/Storage/Barrels/yellow.rsi/metal_explosive_label.png differ
diff --git a/Resources/Textures/_NF/Objects/Storage/Barrels/yellow.rsi/paper.png b/Resources/Textures/_NF/Objects/Storage/Barrels/yellow.rsi/paper.png
new file mode 100644
index 00000000000..08d7f696fec
Binary files /dev/null and b/Resources/Textures/_NF/Objects/Storage/Barrels/yellow.rsi/paper.png differ
diff --git a/Resources/_NF/migration.yml b/Resources/_NF/migration.yml
index 5097766ff00..51d4980573f 100644
--- a/Resources/_NF/migration.yml
+++ b/Resources/_NF/migration.yml
@@ -169,4 +169,7 @@ NFPosterContrabandFsbSpiritDD: NFPosterContrabandFsbSpirit
NFPosterContrabandEmsCoordsDD: NFPosterContrabandEmsCoords
# 2024-12-09 Wreck
-RandomItem: null
\ No newline at end of file
+RandomItem: null
+
+# 2024-12-22 Barrels
+CrateSpaceCleaner: ChemicalBarrelSpaceCleaner
\ No newline at end of file