From c149663e54327bfcbec0b596aa7921801baaf239 Mon Sep 17 00:00:00 2001
From: Dvir <39403717+dvir001@users.noreply.github.com>
Date: Wed, 25 Dec 2024 04:31:37 +0200
Subject: [PATCH 01/13] Update EECCVars.cs (#2605)
---
Content.Shared/_EE/CCVar/EECCVars.cs | 127 +++++++++++++--------------
1 file changed, 62 insertions(+), 65 deletions(-)
diff --git a/Content.Shared/_EE/CCVar/EECCVars.cs b/Content.Shared/_EE/CCVar/EECCVars.cs
index b16d1fa01f0..378559a5037 100644
--- a/Content.Shared/_EE/CCVar/EECCVars.cs
+++ b/Content.Shared/_EE/CCVar/EECCVars.cs
@@ -1,81 +1,78 @@
-using Robust.Shared;
using Robust.Shared.Configuration;
-namespace Content.Shared._EE.CCVar
+namespace Content.Shared._EE.CCVar;
+
+[CVarDefs] // ReSharper disable once InconsistentNaming
+public sealed class EECCVars
{
- // ReSharper disable once InconsistentNaming
- [CVarDefs]
- public sealed class EECCVars : CVars
- {
- #region Jetpack System
+ #region Jetpack System
- ///
- /// When true, Jetpacks can be enabled anywhere, even in gravity.
- ///
- public static readonly CVarDef JetpackEnableAnywhere =
- CVarDef.Create("ee.jetpack.enable_anywhere", false, CVar.REPLICATED);
+ ///
+ /// When true, Jetpacks can be enabled anywhere, even in gravity.
+ ///
+ public static readonly CVarDef JetpackEnableAnywhere =
+ CVarDef.Create("ee.jetpack.enable_anywhere", false, CVar.REPLICATED);
- ///
- /// When true, jetpacks can be enabled on grids that have zero gravity.
- ///
- public static readonly CVarDef JetpackEnableInNoGravity =
- CVarDef.Create("ee.jetpack.enable_in_no_gravity", true, CVar.REPLICATED);
+ ///
+ /// When true, jetpacks can be enabled on grids that have zero gravity.
+ ///
+ public static readonly CVarDef JetpackEnableInNoGravity =
+ CVarDef.Create("ee.jetpack.enable_in_no_gravity", true, CVar.REPLICATED);
- #endregion
+ #endregion
- #region Contests System
+ #region Contests System
- ///
- /// The MASTER TOGGLE for the entire Contests System.
- /// ALL CONTESTS BELOW, regardless of type or setting will output 1f when false.
- ///
- public static readonly CVarDef DoContestsSystem =
- CVarDef.Create("contests.do_contests_system", true, CVar.REPLICATED | CVar.SERVER);
+ ///
+ /// The MASTER TOGGLE for the entire Contests System.
+ /// ALL CONTESTS BELOW, regardless of type or setting will output 1f when false.
+ ///
+ public static readonly CVarDef DoContestsSystem =
+ CVarDef.Create("ee.contests.do_contests_system", true, CVar.REPLICATED | CVar.SERVER);
- ///
- /// Contest functions normally include an optional override to bypass the clamp set by max_percentage.
- /// This CVar disables the bypass when false, forcing all implementations to comply with max_percentage.
- ///
- public static readonly CVarDef AllowClampOverride =
- CVarDef.Create("contests.allow_clamp_override", true, CVar.REPLICATED | CVar.SERVER);
- ///
- /// Toggles all MassContest functions. All mass contests output 1f when false
- ///
- public static readonly CVarDef DoMassContests =
- CVarDef.Create("contests.do_mass_contests", true, CVar.REPLICATED | CVar.SERVER);
+ ///
+ /// Contest functions normally include an optional override to bypass the clamp set by max_percentage.
+ /// This CVar disables the bypass when false, forcing all implementations to comply with max_percentage.
+ ///
+ public static readonly CVarDef AllowClampOverride =
+ CVarDef.Create("ee.contests.allow_clamp_override", true, CVar.REPLICATED | CVar.SERVER);
+ ///
+ /// Toggles all MassContest functions. All mass contests output 1f when false
+ ///
+ public static readonly CVarDef DoMassContests =
+ CVarDef.Create("ee.contests.do_mass_contests", true, CVar.REPLICATED | CVar.SERVER);
- ///
- /// Toggles all StaminaContest functions. All stamina contests output 1f when false
- ///
- public static readonly CVarDef DoStaminaContests =
- CVarDef.Create("contests.do_stamina_contests", true, CVar.REPLICATED | CVar.SERVER);
+ ///
+ /// Toggles all StaminaContest functions. All stamina contests output 1f when false
+ ///
+ public static readonly CVarDef DoStaminaContests =
+ CVarDef.Create("ee.contests.do_stamina_contests", true, CVar.REPLICATED | CVar.SERVER);
- ///
- /// Toggles all HealthContest functions. All health contests output 1f when false
- ///
- public static readonly CVarDef DoHealthContests =
- CVarDef.Create("contests.do_health_contests", true, CVar.REPLICATED | CVar.SERVER);
+ ///
+ /// Toggles all HealthContest functions. All health contests output 1f when false
+ ///
+ public static readonly CVarDef DoHealthContests =
+ CVarDef.Create("ee.contests.do_health_contests", true, CVar.REPLICATED | CVar.SERVER);
- ///
- /// Toggles all MindContest functions. All mind contests output 1f when false.
- /// MindContests are not currently implemented, and are awaiting completion of the Psionic Refactor
- ///
- public static readonly CVarDef DoMindContests =
- CVarDef.Create("contests.do_mind_contests", true, CVar.REPLICATED | CVar.SERVER);
+ ///
+ /// Toggles all MindContest functions. All mind contests output 1f when false.
+ /// MindContests are not currently implemented, and are awaiting completion of the Psionic Refactor
+ ///
+ public static readonly CVarDef DoMindContests =
+ CVarDef.Create("ee.contests.do_mind_contests", true, CVar.REPLICATED | CVar.SERVER);
- ///
- /// Toggles all MoodContest functions. All mood contests output 1f when false.
- ///
- public static readonly CVarDef DoMoodContests =
- CVarDef.Create("contests.do_mood_contests", true, CVar.REPLICATED | CVar.SERVER);
+ ///
+ /// Toggles all MoodContest functions. All mood contests output 1f when false.
+ ///
+ public static readonly CVarDef DoMoodContests =
+ CVarDef.Create("ee.contests.do_mood_contests", true, CVar.REPLICATED | CVar.SERVER);
- ///
- /// The maximum amount that Mass Contests can modify a physics multiplier, given as a +/- percentage
- /// Default of 0.25f outputs between * 0.75f and 1.25f
- ///
- public static readonly CVarDef MassContestsMaxPercentage =
- CVarDef.Create("contests.max_percentage", 0.25f, CVar.REPLICATED | CVar.SERVER);
+ ///
+ /// The maximum amount that Mass Contests can modify a physics multiplier, given as a +/- percentage
+ /// Default of 0.25f outputs between * 0.75f and 1.25f
+ ///
+ public static readonly CVarDef MassContestsMaxPercentage =
+ CVarDef.Create("ee.contests.max_percentage", 0.25f, CVar.REPLICATED | CVar.SERVER);
- #endregion
- }
+ #endregion
}
From bef531774520f16db52b5154d221984062455a23 Mon Sep 17 00:00:00 2001
From: Whatstone <166147148+whatston3@users.noreply.github.com>
Date: Wed, 25 Dec 2024 19:49:53 -0500
Subject: [PATCH 02/13] Flatpacks: rotatable, soil needs a shovel (#2608)
* Rotatable flatpacks
* soil crates need to be dug
* Directional sprites for docking airlock flatpacks
---
.../Construction/SharedFlatpackSystem.cs | 2 ++
.../Entities/Objects/Devices/flatpack.yml | 1 +
.../_NF/Entities/Objects/Devices/flatpacks.yml | 17 ++++++++++++-----
.../command_airlock_directional.png | Bin 0 -> 464 bytes
.../_NF/Objects/Devices/flatpack.rsi/meta.json | 3 +++
5 files changed, 18 insertions(+), 5 deletions(-)
create mode 100644 Resources/Textures/_NF/Objects/Devices/flatpack.rsi/command_airlock_directional.png
diff --git a/Content.Shared/Construction/SharedFlatpackSystem.cs b/Content.Shared/Construction/SharedFlatpackSystem.cs
index a83948b1674..9644800d773 100644
--- a/Content.Shared/Construction/SharedFlatpackSystem.cs
+++ b/Content.Shared/Construction/SharedFlatpackSystem.cs
@@ -93,6 +93,8 @@ private void OnFlatpackInteractUsing(Entity ent, ref Interact
if (_net.IsServer)
{
var spawn = Spawn(comp.Entity, _map.GridTileToLocal(grid, gridComp, buildPos));
+ if (TryComp(spawn, out TransformComponent? spawnXform)) // Frontier: rotatable flatpacks
+ spawnXform.LocalRotation = xform.LocalRotation.GetCardinalDir().ToAngle(); // Frontier: rotatable flatpacks
_adminLogger.Add(LogType.Construction,
LogImpact.Low,
$"{ToPrettyString(args.User):player} unpacked {ToPrettyString(spawn):entity} at {xform.Coordinates} from {ToPrettyString(uid):entity}");
diff --git a/Resources/Prototypes/Entities/Objects/Devices/flatpack.yml b/Resources/Prototypes/Entities/Objects/Devices/flatpack.yml
index 8a6424ffcc7..c6f9c7449f9 100644
--- a/Resources/Prototypes/Entities/Objects/Devices/flatpack.yml
+++ b/Resources/Prototypes/Entities/Objects/Devices/flatpack.yml
@@ -35,6 +35,7 @@
cpu_supply: "#A46106"
- type: StaticPrice
price: 250
+ - type: Rotatable # Frontier
- type: entity
parent: BaseFlatpack
diff --git a/Resources/Prototypes/_NF/Entities/Objects/Devices/flatpacks.yml b/Resources/Prototypes/_NF/Entities/Objects/Devices/flatpacks.yml
index 12971234f6b..27abddaeaa7 100644
--- a/Resources/Prototypes/_NF/Entities/Objects/Devices/flatpacks.yml
+++ b/Resources/Prototypes/_NF/Entities/Objects/Devices/flatpacks.yml
@@ -370,11 +370,13 @@
- type: entity
parent: UniformPrinterFlatpack
id: HydroponicsSoilNutritionFlatpack
- name: crate with fertile soil
- description: A crate with fertile soil used for constructing a soil bed for growing.
+ name: crate of fertile soil
+ description: A crate of fertile soil used for constructing a soil bed for growing. Spread it around with a shovel.
components:
- type: Flatpack
entity: HydroponicsSoilNutrition
+ qualityNeeded: Digging
+ unpackSound: /Audio/Items/shovel_dig.ogg
- type: Sprite
layers:
- state: soil
@@ -382,11 +384,13 @@
- type: entity
parent: UniformPrinterFlatpack
id: HydroponicsSoilEmptyFlatpack
- name: crate with soil
- description: A crate with soil used for constructing a soil bed for growing.
+ name: crate of soil
+ description: A crate of soil used for constructing a soil bed for growing. Spread it around with a shovel.
components:
- type: Flatpack
entity: HydroponicsSoilEmpty
+ qualityNeeded: Digging
+ unpackSound: /Audio/Items/shovel_dig.ogg
- type: Sprite
layers:
- state: soil
@@ -669,9 +673,12 @@
components:
- type: Flatpack
entity: AirlockShuttle
+ - type: Sprite
+ layers:
+ - state: command_airlock_directional
- type: entity
- parent: AirlockFlatpack
+ parent: AirlockShuttleFlatpack
id: AirlockGlassShuttleFlatpack
name: docking glass airlock flatpack
description: A flatpack used for constructing a glass docking airlock.
diff --git a/Resources/Textures/_NF/Objects/Devices/flatpack.rsi/command_airlock_directional.png b/Resources/Textures/_NF/Objects/Devices/flatpack.rsi/command_airlock_directional.png
new file mode 100644
index 0000000000000000000000000000000000000000..49f01a01d363dc3c5c37ca96cc52d05a5603201d
GIT binary patch
literal 464
zcmV;>0WbcEP)U#buwr|RDgxW2mmGNVr?JRXmA
z9PBtQI{Ur^NTsLhv$Hc8g92HS)F)P`Rm&~D;lw17`vXkN#Cug-TwF4pn&$E0;b#Ev
z708lA2m{<>qWx`*ZUuyaEJ?=35?YmO0RU8bGekv=!d@}(uv|V%r8h%_YWDzY)v~YZ
zTt3_4`3P65mKo8Ghn^0+tz$1g>rtQOauz^(z1XYujf4+}%}t^FIUVwmJsb
z-Ixa;nH=}ce+^(bG1(j!_KFB$u)o!~^Zl(XLKwbB_|dPUz+YeuNTl+75T8jY4{KB+
zy9oebS|;}LJVF@kEIcz3i#OMvT!;13A(ZkkEz`HpaooVO1Fyh)Rn75B%*H-U^W-|s
zaQiULOU!QZ-(24WHX_jIhKoyc-|B=XN9S6dHdLrkq22&D0)qfGL`@_B0000
Date: Thu, 26 Dec 2024 00:50:19 +0000
Subject: [PATCH 03/13] Automatic Changelog (#2608)
---
Resources/Changelog/Frontier.yml | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/Resources/Changelog/Frontier.yml b/Resources/Changelog/Frontier.yml
index 62a7ab1e93d..12d09316d55 100644
--- a/Resources/Changelog/Frontier.yml
+++ b/Resources/Changelog/Frontier.yml
@@ -6096,3 +6096,11 @@ Entries:
shots.
id: 5610
time: '2024-12-24T23:05:02.0000000+00:00'
+- author: whatston3
+ changes:
+ - type: Add
+ message: Flatpacks can be rotated, and respect their rotation when unpacked.
+ - type: Tweak
+ message: Soil crates now must be "assembled" with a shovel.
+ id: 5611
+ time: '2024-12-26T00:49:53.0000000+00:00'
From 33126876b3cb0bb4403b1ad81dca23119d2d4fbc Mon Sep 17 00:00:00 2001
From: Whatstone <166147148+whatston3@users.noreply.github.com>
Date: Thu, 26 Dec 2024 01:05:24 -0500
Subject: [PATCH 04/13] trade outpost: catwalks in cb1 (#2611)
---
Resources/Maps/_NF/POI/trade.yml | 22 ++++++++++------------
1 file changed, 10 insertions(+), 12 deletions(-)
diff --git a/Resources/Maps/_NF/POI/trade.yml b/Resources/Maps/_NF/POI/trade.yml
index 1fab43e1778..27b2a1d9789 100644
--- a/Resources/Maps/_NF/POI/trade.yml
+++ b/Resources/Maps/_NF/POI/trade.yml
@@ -9219,18 +9219,6 @@ entities:
parent: 1
- proto: CargoPalletSell
entities:
- - uid: 225
- components:
- - type: Transform
- rot: 3.141592653589793 rad
- pos: 61.5,22.5
- parent: 1
- - uid: 226
- components:
- - type: Transform
- rot: 3.141592653589793 rad
- pos: 63.5,22.5
- parent: 1
- uid: 228
components:
- type: Transform
@@ -9461,6 +9449,16 @@ entities:
- type: Transform
pos: 81.5,-7.5
parent: 1
+ - uid: 225
+ components:
+ - type: Transform
+ pos: 61.5,22.5
+ parent: 1
+ - uid: 226
+ components:
+ - type: Transform
+ pos: 63.5,22.5
+ parent: 1
- uid: 341
components:
- type: Transform
From fa4b9fd9fdf85aa848fd8654d13bc5f414b5f2ef Mon Sep 17 00:00:00 2001
From: Whatstone <166147148+whatston3@users.noreply.github.com>
Date: Thu, 26 Dec 2024 10:21:56 -0500
Subject: [PATCH 05/13] alt depot needs presets (#2613)
---
Resources/Prototypes/_NF/PointsOfInterest/depots.yml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Resources/Prototypes/_NF/PointsOfInterest/depots.yml b/Resources/Prototypes/_NF/PointsOfInterest/depots.yml
index 0b8eae5b82c..d6c3105327d 100644
--- a/Resources/Prototypes/_NF/PointsOfInterest/depots.yml
+++ b/Resources/Prototypes/_NF/PointsOfInterest/depots.yml
@@ -31,6 +31,7 @@
name: Cargo Depot
minimumDistance: 4500
maximumDistance: 6000
+ spawnGamePreset: [ NFAdventure, NFPirate ]
spawnGroup: CargoDepot
gridPath: /Maps/_NF/POI/cargodepotalt.yml
addComponents:
From cb6514197459774e92bc983f1848038a3ef522f3 Mon Sep 17 00:00:00 2001
From: FrontierATC
Date: Thu, 26 Dec 2024 15:22:25 +0000
Subject: [PATCH 06/13] Automatic Changelog (#2613)
---
Resources/Changelog/Frontier.yml | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/Resources/Changelog/Frontier.yml b/Resources/Changelog/Frontier.yml
index 12d09316d55..99b83bb1457 100644
--- a/Resources/Changelog/Frontier.yml
+++ b/Resources/Changelog/Frontier.yml
@@ -6104,3 +6104,9 @@ Entries:
message: Soil crates now must be "assembled" with a shovel.
id: 5611
time: '2024-12-26T00:49:53.0000000+00:00'
+- author: whatston3
+ changes:
+ - type: Fix
+ message: Cargo Depots should be spawning normally now.
+ id: 5612
+ time: '2024-12-26T15:21:56.0000000+00:00'
From 6e11ad492e82a1de79eac0f125fe44a013319382 Mon Sep 17 00:00:00 2001
From: Whatstone <166147148+whatston3@users.noreply.github.com>
Date: Thu, 26 Dec 2024 15:18:09 -0500
Subject: [PATCH 07/13] Random appearance for random pills (#2612)
* Better random pills
* Namespace matches folder
* Milon's suggestions
---
.../_NF/Chemistry/RandomPillSystem.cs | 26 +++++++++++++++++++
.../Chemistry/Components/PillComponent.cs | 6 +++++
.../Objects/Specific/Medical/randompill.yml | 2 ++
3 files changed, 34 insertions(+)
create mode 100644 Content.Server/_NF/Chemistry/RandomPillSystem.cs
diff --git a/Content.Server/_NF/Chemistry/RandomPillSystem.cs b/Content.Server/_NF/Chemistry/RandomPillSystem.cs
new file mode 100644
index 00000000000..9326703f323
--- /dev/null
+++ b/Content.Server/_NF/Chemistry/RandomPillSystem.cs
@@ -0,0 +1,26 @@
+using Content.Shared.Chemistry.Components;
+using Robust.Shared.Random;
+
+namespace Content.Server._NF.Chemistry;
+
+public sealed class RandomPillSystem : EntitySystem
+{
+ [Dependency] private readonly IRobustRandom _random = default!;
+
+ public const int MaxPillType = 21;
+
+ public override void Initialize()
+ {
+ base.Initialize();
+ SubscribeLocalEvent(OnMapInit);
+ }
+
+ private void OnMapInit(Entity ent, ref MapInitEvent componentInit)
+ {
+ if (ent.Comp.Random)
+ {
+ ent.Comp.PillType = (uint)_random.Next(MaxPillType);
+ Dirty(ent);
+ }
+ }
+}
diff --git a/Content.Shared/Chemistry/Components/PillComponent.cs b/Content.Shared/Chemistry/Components/PillComponent.cs
index ad32aa750a4..0cb356454d6 100644
--- a/Content.Shared/Chemistry/Components/PillComponent.cs
+++ b/Content.Shared/Chemistry/Components/PillComponent.cs
@@ -12,4 +12,10 @@ public sealed partial class PillComponent : Component
[DataField("pillType")]
[ViewVariables(VVAccess.ReadWrite)]
public uint PillType;
+
+ ///
+ /// Frontier: if true, pill appearance will be randomly generated on init.
+ ///
+ [DataField(serverOnly: true)]
+ public bool Random;
}
diff --git a/Resources/Prototypes/Entities/Objects/Specific/Medical/randompill.yml b/Resources/Prototypes/Entities/Objects/Specific/Medical/randompill.yml
index cdff0cdbe4a..26714e22ada 100644
--- a/Resources/Prototypes/Entities/Objects/Specific/Medical/randompill.yml
+++ b/Resources/Prototypes/Entities/Objects/Specific/Medical/randompill.yml
@@ -86,6 +86,8 @@
- type: RandomFillSolution
solution: food
weightedRandomId: RandomFillStrangePill
+ - type: Pill # Frontier
+ random: true # Frontier
# RandomSprite does not work with pill component
# - type: Sprite
# sprite: Objects/Specific/Chemistry/pills.rsi
From 6c50bddd754df671485fa93359e15197489823b5 Mon Sep 17 00:00:00 2001
From: Whatstone <166147148+whatston3@users.noreply.github.com>
Date: Thu, 26 Dec 2024 15:21:41 -0500
Subject: [PATCH 08/13] Selectively cherry-pick ss#32936 (thanks ilya246)
(#2610)
---
.../StackCustomSplitBoundUserInterface.cs | 41 +++++++++++++++++++
.../Stack/StackCustomSplitWindow.xaml | 15 +++++++
.../Stack/StackCustomSplitWindow.xaml.cs | 35 ++++++++++++++++
Content.Server/Stack/StackSystem.cs | 36 +++++++++++++++-
Content.Shared/Stacks/SharedStackSystem.cs | 6 +++
Content.Shared/Stacks/StackCustomSplit.cs | 22 ++++++++++
.../Locale/en-US/stack/stack-component.ftl | 9 ++++
.../Entities/Objects/Misc/space_cash.yml | 6 +++
.../_NF/Entities/Objects/Misc/space_cash.yml | 28 +++++++------
9 files changed, 184 insertions(+), 14 deletions(-)
create mode 100644 Content.Client/Stack/StackCustomSplitBoundUserInterface.cs
create mode 100644 Content.Client/Stack/StackCustomSplitWindow.xaml
create mode 100644 Content.Client/Stack/StackCustomSplitWindow.xaml.cs
create mode 100644 Content.Shared/Stacks/StackCustomSplit.cs
diff --git a/Content.Client/Stack/StackCustomSplitBoundUserInterface.cs b/Content.Client/Stack/StackCustomSplitBoundUserInterface.cs
new file mode 100644
index 00000000000..ff9a03580a9
--- /dev/null
+++ b/Content.Client/Stack/StackCustomSplitBoundUserInterface.cs
@@ -0,0 +1,41 @@
+// Cherry-picked from space-station-14#32938 courtesy of Ilya246
+using JetBrains.Annotations;
+using Content.Shared.Stacks;
+using Robust.Client.GameObjects;
+using Robust.Client.UserInterface;
+
+namespace Content.Client.Stack
+{
+ [UsedImplicitly]
+ public sealed class StackCustomSplitBoundUserInterface : BoundUserInterface
+ {
+ private IEntityManager _entManager;
+ private EntityUid _owner;
+ [ViewVariables]
+ private StackCustomSplitWindow? _window;
+
+ public StackCustomSplitBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
+ {
+ _owner = owner;
+ _entManager = IoCManager.Resolve();
+ }
+
+ protected override void Open()
+ {
+ base.Open();
+ _window = this.CreateWindow();
+
+ if (_entManager.TryGetComponent(_owner, out var comp))
+ _window.SetMax(comp.Count);
+
+ _window.ApplyButton.OnPressed += _ =>
+ {
+ if (int.TryParse(_window.AmountLineEdit.Text, out var i))
+ {
+ SendMessage(new StackCustomSplitAmountMessage(i));
+ _window.Close();
+ }
+ };
+ }
+ }
+}
diff --git a/Content.Client/Stack/StackCustomSplitWindow.xaml b/Content.Client/Stack/StackCustomSplitWindow.xaml
new file mode 100644
index 00000000000..2294d459415
--- /dev/null
+++ b/Content.Client/Stack/StackCustomSplitWindow.xaml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Content.Client/Stack/StackCustomSplitWindow.xaml.cs b/Content.Client/Stack/StackCustomSplitWindow.xaml.cs
new file mode 100644
index 00000000000..e07d8474a36
--- /dev/null
+++ b/Content.Client/Stack/StackCustomSplitWindow.xaml.cs
@@ -0,0 +1,35 @@
+// Cherry-picked from space-station-14#32938 courtesy of Ilya246
+using Robust.Client.AutoGenerated;
+using Robust.Client.UserInterface.Controls;
+using Robust.Client.UserInterface.CustomControls;
+using Robust.Client.UserInterface.XAML;
+
+namespace Content.Client.Stack
+{
+ [GenerateTypedNameReferences]
+ public sealed partial class StackCustomSplitWindow : DefaultWindow
+ {
+ private int _max = Int32.MaxValue;
+ private int _min = 1;
+
+ public StackCustomSplitWindow()
+ {
+ RobustXamlLoader.Load(this);
+ AmountLineEdit.OnTextChanged += OnValueChanged;
+ }
+
+ public void SetMax(int max)
+ {
+ _max = max;
+ MaximumAmount.Text = Loc.GetString("comp-stack-split-size", ("size", _max));
+ }
+
+ private void OnValueChanged(LineEdit.LineEditEventArgs args)
+ {
+ if (!int.TryParse(AmountLineEdit.Text, out var amount) || amount > _max || amount < _min)
+ ApplyButton.Disabled = true;
+ else
+ ApplyButton.Disabled = false;
+ }
+ }
+}
diff --git a/Content.Server/Stack/StackSystem.cs b/Content.Server/Stack/StackSystem.cs
index 7806ffeb097..69633d03517 100644
--- a/Content.Server/Stack/StackSystem.cs
+++ b/Content.Server/Stack/StackSystem.cs
@@ -15,6 +15,7 @@ namespace Content.Server.Stack
public sealed class StackSystem : SharedStackSystem
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
+ [Dependency] private readonly SharedUserInterfaceSystem _ui = default!; // Cherry-picked from space-station-14#32938 courtesy of Ilya246
public static readonly int[] DefaultSplitAmounts = { 1, 5, 10, 20, 50, 100, 500, 1000, 5000, 10000 };
@@ -170,16 +171,33 @@ private void OnStackAlternativeInteract(EntityUid uid, StackComponent stack, Get
if (!args.CanAccess || !args.CanInteract || args.Hands == null || stack.Count == 1)
return;
+ // Frontier: cherry-picked from ss14#32938, moved up top
+ var priority = 1;
+ if (_ui.HasUi(uid, StackCustomSplitUiKey.Key)) // Frontier: check for interface
+ {
+ AlternativeVerb custom = new()
+ {
+ Text = Loc.GetString("comp-stack-split-custom"),
+ Category = VerbCategory.Split,
+ Act = () =>
+ {
+ _ui.OpenUi(uid, StackCustomSplitUiKey.Key, args.User);
+ },
+ Priority = priority--
+ };
+ args.Verbs.Add(custom);
+ }
+ // End Frontier: cherry-picked from ss14#32938, moved up top
+
AlternativeVerb halve = new()
{
Text = Loc.GetString("comp-stack-split-halve"),
Category = VerbCategory.Split,
Act = () => UserSplit(uid, args.User, stack.Count / 2, stack),
- Priority = 1
+ Priority = priority-- // Frontier: 1= stack.Count)
@@ -200,6 +218,20 @@ private void OnStackAlternativeInteract(EntityUid uid, StackComponent stack, Get
}
}
+ // Cherry-picked from ss14#32938 courtesy of Ilya246
+ protected override void OnCustomSplitMessage(Entity ent, ref StackCustomSplitAmountMessage message)
+ {
+ var (uid, comp) = ent;
+
+ // digital ghosts shouldn't be allowed to split stacks
+ if (!(message.Actor is { Valid: true } user))
+ return;
+
+ var amount = message.Amount;
+ UserSplit(uid, user, amount, comp);
+ }
+ // End cherry-pick from ss14#32938 courtesy of Ilya246
+
private void UserSplit(EntityUid uid, EntityUid userUid, int amount,
StackComponent? stack = null,
TransformComponent? userTransform = null)
diff --git a/Content.Shared/Stacks/SharedStackSystem.cs b/Content.Shared/Stacks/SharedStackSystem.cs
index 7fe058afbaa..922e57a4161 100644
--- a/Content.Shared/Stacks/SharedStackSystem.cs
+++ b/Content.Shared/Stacks/SharedStackSystem.cs
@@ -37,11 +37,17 @@ public override void Initialize()
SubscribeLocalEvent(OnStackStarted);
SubscribeLocalEvent(OnStackExamined);
SubscribeLocalEvent(OnStackInteractUsing);
+ SubscribeLocalEvent(OnCustomSplitMessage); // cherry-pick #32938
_vvm.GetTypeHandler()
.AddPath(nameof(StackComponent.Count), (_, comp) => comp.Count, SetCount);
}
+ // Cherry-pick #32938 courtesy of Ilya246
+ // client shouldn't try to split stacks so do nothing on client
+ protected virtual void OnCustomSplitMessage(Entity ent, ref StackCustomSplitAmountMessage message) {}
+ // End cherry-pick #32938 courtesy of Ilya246
+
public override void Shutdown()
{
base.Shutdown();
diff --git a/Content.Shared/Stacks/StackCustomSplit.cs b/Content.Shared/Stacks/StackCustomSplit.cs
new file mode 100644
index 00000000000..ddfd7cd02d7
--- /dev/null
+++ b/Content.Shared/Stacks/StackCustomSplit.cs
@@ -0,0 +1,22 @@
+// Cherry-pick space-station-14#32938 courtesy of Ilya246
+using Robust.Shared.Serialization;
+
+namespace Content.Shared.Stacks
+{
+ [Serializable, NetSerializable]
+ public sealed class StackCustomSplitAmountMessage : BoundUserInterfaceMessage
+ {
+ public int Amount;
+
+ public StackCustomSplitAmountMessage(int amount)
+ {
+ Amount = amount;
+ }
+ }
+
+ [Serializable, NetSerializable]
+ public enum StackCustomSplitUiKey
+ {
+ Key,
+ }
+}
\ No newline at end of file
diff --git a/Resources/Locale/en-US/stack/stack-component.ftl b/Resources/Locale/en-US/stack/stack-component.ftl
index e8cbaa69df1..93ceea15107 100644
--- a/Resources/Locale/en-US/stack/stack-component.ftl
+++ b/Resources/Locale/en-US/stack/stack-component.ftl
@@ -20,4 +20,13 @@ comp-stack-becomes-full = Stack is now full.
# Text related to splitting a stack
comp-stack-split = You split the stack.
comp-stack-split-halve = Halve
+comp-stack-split-custom = Split amount...
comp-stack-split-too-small = Stack is too small to split.
+
+# Cherry-picked from space-station-14#32938 courtesy of Ilya246
+comp-stack-split-size = Max: {$size}
+
+ui-custom-stack-split-title = Split Amount
+ui-custom-stack-split-line-edit-placeholder = Amount
+ui-custom-stack-split-apply = Split
+# End cherry-pick from ss14#32938
\ No newline at end of file
diff --git a/Resources/Prototypes/Entities/Objects/Misc/space_cash.yml b/Resources/Prototypes/Entities/Objects/Misc/space_cash.yml
index 12dd680d9f6..c26ca15099f 100644
--- a/Resources/Prototypes/Entities/Objects/Misc/space_cash.yml
+++ b/Resources/Prototypes/Entities/Objects/Misc/space_cash.yml
@@ -35,6 +35,12 @@
- cash_100000 # Frontier: larger denominations
- cash_250000 # Frontier: larger denominations (cash_1000000
Date: Thu, 26 Dec 2024 20:22:07 +0000
Subject: [PATCH 09/13] Automatic Changelog (#2610)
---
Resources/Changelog/Frontier.yml | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/Resources/Changelog/Frontier.yml b/Resources/Changelog/Frontier.yml
index 99b83bb1457..1a8a3bd3f7a 100644
--- a/Resources/Changelog/Frontier.yml
+++ b/Resources/Changelog/Frontier.yml
@@ -6110,3 +6110,9 @@ Entries:
message: Cargo Depots should be spawning normally now.
id: 5612
time: '2024-12-26T15:21:56.0000000+00:00'
+- author: Ilya246 and whatston3
+ changes:
+ - type: Add
+ message: Spesos and spessos now support custom split amounts.
+ id: 5613
+ time: '2024-12-26T20:21:42.0000000+00:00'
From 63a30833939741a6b327b29f5dfff962e4c24303 Mon Sep 17 00:00:00 2001
From: Bonaout
Date: Thu, 26 Dec 2024 22:07:17 +0100
Subject: [PATCH 10/13] Add GPS app to pirate PDAs (#2617)
* Add GPS app to pirate PDAs
Description
* Update pda.yml
* Update pda.yml
---------
Co-authored-by: Dvir <39403717+dvir001@users.noreply.github.com>
---
Resources/Prototypes/Entities/Objects/Devices/pda.yml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Resources/Prototypes/Entities/Objects/Devices/pda.yml b/Resources/Prototypes/Entities/Objects/Devices/pda.yml
index 28bea188438..6247747e6bd 100644
--- a/Resources/Prototypes/Entities/Objects/Devices/pda.yml
+++ b/Resources/Prototypes/Entities/Objects/Devices/pda.yml
@@ -889,6 +889,7 @@
uiKey: enum.PdaUiKey.Key
preinstalled:
- NotekeeperCartridge
+ - AstroNavCartridge # Frontier
- type: entity
parent: BaseSecurityPDA
From e7f1ea77c56a77a852c9950dab490cf375efba19 Mon Sep 17 00:00:00 2001
From: FrontierATC
Date: Thu, 26 Dec 2024 21:07:43 +0000
Subject: [PATCH 11/13] Automatic Changelog (#2617)
---
Resources/Changelog/Frontier.yml | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/Resources/Changelog/Frontier.yml b/Resources/Changelog/Frontier.yml
index 1a8a3bd3f7a..7b8d21ceb44 100644
--- a/Resources/Changelog/Frontier.yml
+++ b/Resources/Changelog/Frontier.yml
@@ -6116,3 +6116,9 @@ Entries:
message: Spesos and spessos now support custom split amounts.
id: 5613
time: '2024-12-26T20:21:42.0000000+00:00'
+- author: Bonaout
+ changes:
+ - type: Tweak
+ message: Pirate PDAs now have the AstroNav program
+ id: 5614
+ time: '2024-12-26T21:07:18.0000000+00:00'
From ecd0e54b61224e2a0b22027cca0cf5650e967076 Mon Sep 17 00:00:00 2001
From: Dvir <39403717+dvir001@users.noreply.github.com>
Date: Thu, 26 Dec 2024 23:27:13 +0200
Subject: [PATCH 12/13] Update masks.yml (#2616)
* Update masks.yml
* Update masks.yml
---
Resources/Prototypes/Entities/Clothing/Masks/masks.yml | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/Resources/Prototypes/Entities/Clothing/Masks/masks.yml b/Resources/Prototypes/Entities/Clothing/Masks/masks.yml
index 27b585fe675..4a3614dcd0c 100644
--- a/Resources/Prototypes/Entities/Clothing/Masks/masks.yml
+++ b/Resources/Prototypes/Entities/Clothing/Masks/masks.yml
@@ -379,8 +379,8 @@
- type: Armor
modifiers:
coefficients:
- Blunt: 0.90
- Slash: 0.90
+ Blunt: 0.95 # Frontier 0.90<0.95
+ Slash: 0.95 # Frontier 0.90<0.95
Piercing: 0.95
Heat: 0.95
@@ -397,8 +397,8 @@
- type: Armor
modifiers:
coefficients:
- Blunt: 0.90
- Slash: 0.90
+ Blunt: 0.95 # Frontier 0.90<0.95
+ Slash: 0.95 # Frontier 0.90<0.95
Piercing: 0.95
Heat: 0.95
- type: PirateBountyItem # Frontier
From f8b16a19727e0c357a2b1ce49b1910c0dc18e20d Mon Sep 17 00:00:00 2001
From: Whatstone <166147148+whatston3@users.noreply.github.com>
Date: Thu, 26 Dec 2024 21:31:12 -0500
Subject: [PATCH 13/13] POI Spawning: Handle empty preset list, restrict protos
in NfAdventureRule (#2614)
* POI spawning: remove most presets, +preset checks
* organize dependencies
* curse of alphabetization
* Milon's suggestions
* missed refactor references
* restore the arrays
---
.../_NF/GameRule/NfAdventureRuleSystem.cs | 42 ++++++++++-------
.../_NF/GameRule/PointOfInterestPrototype.cs | 1 +
.../_NF/GameRule/PointOfInterestSystem.cs | 45 ++++++++++---------
3 files changed, 52 insertions(+), 36 deletions(-)
diff --git a/Content.Server/_NF/GameRule/NfAdventureRuleSystem.cs b/Content.Server/_NF/GameRule/NfAdventureRuleSystem.cs
index 68062cdb598..176eb06ba81 100644
--- a/Content.Server/_NF/GameRule/NfAdventureRuleSystem.cs
+++ b/Content.Server/_NF/GameRule/NfAdventureRuleSystem.cs
@@ -4,22 +4,23 @@
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
+using Content.Server._NF.Bank;
+using Content.Server._NF.GameRule.Components;
using Content.Server._NF.GameTicking.Events;
-using Content.Shared.GameTicking.Components;
-using Robust.Shared.Prototypes;
using Content.Server.Cargo.Components;
using Content.Server.GameTicking;
+using Content.Server.GameTicking.Presets;
using Content.Server.GameTicking.Rules;
-using Content.Shared._NF.CCVar; // Frontier
-using Robust.Shared.Configuration;
using Content.Shared._NF.Bank;
-using Content.Server._NF.GameRule.Components;
-using Content.Server._NF.Bank;
-using Robust.Shared.Player;
-using Robust.Shared.Network;
+using Content.Shared._NF.CCVar;
using Content.Shared.GameTicking;
-using Robust.Shared.Enums;
+using Content.Shared.GameTicking.Components;
using Robust.Server.Player;
+using Robust.Shared.Configuration;
+using Robust.Shared.Enums;
+using Robust.Shared.Network;
+using Robust.Shared.Player;
+using Robust.Shared.Prototypes;
namespace Content.Server._NF.GameRule;
@@ -28,14 +29,17 @@ namespace Content.Server._NF.GameRule;
///
public sealed class NFAdventureRuleSystem : GameRuleSystem
{
- [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
- [Dependency] private readonly IConfigurationManager _configurationManager = default!;
- [Dependency] private readonly IPlayerManager _playerManager = default!;
+ [Dependency] private readonly IConfigurationManager _cfg = default!;
+ [Dependency] private readonly IPlayerManager _player = default!;
+ [Dependency] private readonly IPrototypeManager _proto = default!;
[Dependency] private readonly BankSystem _bank = default!;
+ [Dependency] private readonly GameTicker _ticker = default!;
[Dependency] private readonly PointOfInterestSystem _poi = default!;
private readonly HttpClient _httpClient = new();
+ private readonly ProtoId _fallbackPresetID = "NFPirates";
+
public sealed class PlayerRoundBankInformation
{
// Initial balance, obtained on spawn
@@ -68,7 +72,7 @@ public override void Initialize()
SubscribeLocalEvent(OnPlayerSpawningEvent);
SubscribeLocalEvent(OnPlayerDetachedEvent);
SubscribeLocalEvent(OnRoundRestart);
- _playerManager.PlayerStatusChanged += PlayerManagerOnPlayerStatusChanged;
+ _player.PlayerStatusChanged += PlayerManagerOnPlayerStatusChanged;
}
protected override void AppendRoundEndText(EntityUid uid, NFAdventureRuleComponent component, GameRuleComponent gameRule, ref RoundEndTextAppendEvent ev)
@@ -196,8 +200,14 @@ protected override void Started(EntityUid uid, NFAdventureRuleComponent componen
List optionalProtos = new();
Dictionary> remainingUniqueProtosBySpawnGroup = new();
- foreach (var location in _prototypeManager.EnumeratePrototypes())
+ var currentPreset = _ticker.CurrentPreset?.ID ?? _fallbackPresetID;
+
+ foreach (var location in _proto.EnumeratePrototypes())
{
+ // Check if any preset is accepted (empty) or if current preset is supported.
+ if (location.SpawnGamePreset.Length > 0 && !location.SpawnGamePreset.Contains(currentPreset))
+ continue;
+
if (location.SpawnGroup == "CargoDepot")
depotProtos.Add(location);
else if (location.SpawnGroup == "MarketStation")
@@ -228,7 +238,7 @@ protected override void Started(EntityUid uid, NFAdventureRuleComponent componen
private async Task ReportRound(string message, int color = 0x77DDE7)
{
Logger.InfoS("discord", message);
- string webhookUrl = _configurationManager.GetCVar(NFCCVars.DiscordLeaderboardWebhook);
+ string webhookUrl = _cfg.GetCVar(NFCCVars.DiscordLeaderboardWebhook);
if (webhookUrl == string.Empty)
return;
@@ -249,7 +259,7 @@ private async Task ReportRound(string message, int color = 0x77DDE7)
private async Task ReportLedger(int color = 0xBF863F)
{
- string webhookUrl = _configurationManager.GetCVar(NFCCVars.DiscordLeaderboardWebhook);
+ string webhookUrl = _cfg.GetCVar(NFCCVars.DiscordLeaderboardWebhook);
if (webhookUrl == string.Empty)
return;
diff --git a/Content.Server/_NF/GameRule/PointOfInterestPrototype.cs b/Content.Server/_NF/GameRule/PointOfInterestPrototype.cs
index f29cf76474e..84baf23c519 100644
--- a/Content.Server/_NF/GameRule/PointOfInterestPrototype.cs
+++ b/Content.Server/_NF/GameRule/PointOfInterestPrototype.cs
@@ -52,6 +52,7 @@ public sealed partial class PointOfInterestPrototype : IPrototype
///
/// What gamepresets ID this POI is allowed to spawn on.
+ /// If left empty, all presets are allowed.
///
[DataField]
public ProtoId[] SpawnGamePreset { get; private set; } = [];
diff --git a/Content.Server/_NF/GameRule/PointOfInterestSystem.cs b/Content.Server/_NF/GameRule/PointOfInterestSystem.cs
index d58a70b924a..f9a910027f9 100644
--- a/Content.Server/_NF/GameRule/PointOfInterestSystem.cs
+++ b/Content.Server/_NF/GameRule/PointOfInterestSystem.cs
@@ -1,16 +1,16 @@
using System.Linq;
using System.Numerics;
+using Content.Server.Maps;
+using Content.Server.Station.Systems;
+using Content.Server.GameTicking;
+using Content.Shared._NF.CCVar;
+using Content.Shared.GameTicking;
using Robust.Server.GameObjects;
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;
@@ -20,14 +20,14 @@ namespace Content.Server._NF.GameRule;
//[Access(typeof(NfAdventureRuleSystem))]
public sealed class PointOfInterestSystem : EntitySystem
{
- [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
+ [Dependency] private readonly IConfigurationManager _cfg = default!;
+ [Dependency] private readonly IPrototypeManager _proto = default!;
[Dependency] private readonly IRobustRandom _random = default!;
- [Dependency] private readonly IConfigurationManager _configurationManager = default!;
+ [Dependency] private readonly GameTicker _ticker = 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!;
+ [Dependency] private readonly StationSystem _station = default!;
private List _stationCoords = new();
@@ -55,7 +55,7 @@ public void GenerateDepots(MapId mapUid, List depotPro
//by the number of depots set in our corresponding cvar
depotStations = new List();
- var depotCount = _configurationManager.GetCVar(NFCCVars.CargoDepots);
+ var depotCount = _cfg.GetCVar(NFCCVars.CargoDepots);
var rotation = 2 * Math.PI / depotCount;
var rotationOffset = _random.NextAngle() / depotCount;
@@ -68,7 +68,8 @@ public void GenerateDepots(MapId mapUid, List depotPro
{
var proto = _random.Pick(depotPrototypes);
- if (!proto.SpawnGamePreset.Contains(currentPreset))
+ // Safety check: ensure selected POIs are either fine in any preset or accepts this current one.
+ if (proto.SpawnGamePreset.Length > 0 && !proto.SpawnGamePreset.Contains(currentPreset))
continue;
Vector2i offset = new Vector2i((int) _random.Next(proto.MinimumDistance, proto.MaximumDistance), 0);
@@ -96,7 +97,7 @@ public void GenerateMarkets(MapId mapUid, List marketP
//ideal world
marketStations = new List();
- var marketCount = _configurationManager.GetCVar(NFCCVars.MarketStations);
+ var marketCount = _cfg.GetCVar(NFCCVars.MarketStations);
_random.Shuffle(marketPrototypes);
int marketsAdded = 0;
@@ -106,7 +107,8 @@ public void GenerateMarkets(MapId mapUid, List marketP
foreach (var proto in marketPrototypes)
{
- if (!proto.SpawnGamePreset.Contains(currentPreset))
+ // Safety check: ensure selected POIs are either fine in any preset or accepts this current one.
+ if (proto.SpawnGamePreset.Length > 0 && !proto.SpawnGamePreset.Contains(currentPreset))
continue;
if (marketsAdded >= marketCount)
@@ -130,7 +132,7 @@ public void GenerateOptionals(MapId mapUid, List optio
//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);
+ var optionalCount = _cfg.GetCVar(NFCCVars.OptionalStations);
_random.Shuffle(optionalPrototypes);
int optionalsAdded = 0;
@@ -140,7 +142,8 @@ public void GenerateOptionals(MapId mapUid, List optio
foreach (var proto in optionalPrototypes)
{
- if (!proto.SpawnGamePreset.Contains(currentPreset))
+ // Safety check: ensure selected POIs are either fine in any preset or accepts this current one.
+ if (proto.SpawnGamePreset.Length > 0 && !proto.SpawnGamePreset.Contains(currentPreset))
continue;
if (optionalsAdded >= optionalCount)
@@ -171,7 +174,8 @@ public void GenerateRequireds(MapId mapUid, List requi
foreach (var proto in requiredPrototypes)
{
- if (!proto.SpawnGamePreset.Contains(currentPreset))
+ // Safety check: ensure selected POIs are either fine in any preset or accepts this current one.
+ if (proto.SpawnGamePreset.Length > 0 && !proto.SpawnGamePreset.Contains(currentPreset))
continue;
var offset = GetRandomPOICoord(proto.MinimumDistance, proto.MaximumDistance);
@@ -205,7 +209,8 @@ public void GenerateUniques(MapId mapUid, Dictionary 0 && !proto.SpawnGamePreset.Contains(currentPreset))
continue;
var chance = _random.NextFloat(0, 1);
@@ -238,7 +243,7 @@ private bool TrySpawnPoiGrid(MapId mapUid, PointOfInterestPrototype proto, Vecto
string stationName = string.IsNullOrEmpty(overrideName) ? proto.Name : overrideName;
EntityUid? stationUid = null;
- if (_prototypeManager.TryIndex(proto.ID, out var stationProto))
+ if (_proto.TryIndex(proto.ID, out var stationProto))
{
stationUid = _station.InitializeNewStation(stationProto.Stations[proto.ID], mapUids, stationName);
}
@@ -270,8 +275,8 @@ private bool TrySpawnPoiGrid(MapId mapUid, PointOfInterestPrototype proto, Vecto
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
+ int numRetries = int.Max(_cfg.GetCVar(NFCCVars.POIPlacementRetries), 0);
+ float minDistance = float.Max(_cfg.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++)