From 70a205f7efa06e52a97efc4e8ddab358a0d6f2fa Mon Sep 17 00:00:00 2001
From: Dvir <39403717+dvir001@users.noreply.github.com>
Date: Sun, 22 Dec 2024 16:52:52 +0200
Subject: [PATCH] Multi gamemod support (#2541)
---
Content.IntegrationTests/PoolSettings.cs | 4 +-
.../Systems/ShipyardSystem.Consoles.cs | 1 -
...mponent.cs => NFAdventureRuleComponent.cs} | 7 +-
.../_NF/GameRule/NfAdventureRuleSystem.cs | 261 +--------------
.../_NF/GameRule/PointOfInterestPrototype.cs | 17 +-
.../_NF/GameRule/PointOfInterestSystem.cs | 299 ++++++++++++++++++
Content.Shared/CCVar/CCVars.cs | 2 +-
.../Locale/en-US/_NF/adventure/adventure.ftl | 8 +-
.../Prototypes/_NF/GameRules/roundstart.yml | 4 +-
.../_NF/PointsOfInterest/anomalousgeode.yml | 1 +
.../_NF/PointsOfInterest/anomalouslab.yml | 3 +-
.../_NF/PointsOfInterest/bahamamamas.yml | 1 +
.../_NF/PointsOfInterest/caseys.yml | 3 +-
.../_NF/PointsOfInterest/courthouse.yml | 3 +-
.../Prototypes/_NF/PointsOfInterest/cove.yml | 1 +
.../_NF/PointsOfInterest/depots.yml | 3 +-
.../_NF/PointsOfInterest/edison.yml | 9 +-
.../_NF/PointsOfInterest/grifty.yml | 3 +-
.../Prototypes/_NF/PointsOfInterest/lodge.yml | 1 +
.../_NF/PointsOfInterest/lpbravo.yml | 5 +-
.../_NF/PointsOfInterest/mchobo.yml | 3 +-
.../Prototypes/_NF/PointsOfInterest/nfsd.yml | 1 +
.../_NF/PointsOfInterest/northpole.yml | 5 +-
.../_NF/PointsOfInterest/omnichurch.yml | 5 +-
.../_NF/PointsOfInterest/thepit.yml | 1 +
.../_NF/PointsOfInterest/tinniasrest.yml | 1 +
.../Prototypes/_NF/PointsOfInterest/trade.yml | 1 +
.../_NF/PointsOfInterest/trademall.yml | 1 +
Resources/Prototypes/_NF/game_presets.yml | 28 +-
Resources/Prototypes/game_presets.yml | 10 +-
30 files changed, 396 insertions(+), 296 deletions(-)
rename Content.Server/_NF/GameRule/Components/{AdventureRuleComponent.cs => NFAdventureRuleComponent.cs} (58%)
rename {Content.Shared => Content.Server}/_NF/GameRule/PointOfInterestPrototype.cs (83%)
create mode 100644 Content.Server/_NF/GameRule/PointOfInterestSystem.cs
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/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 5ee7e6e8b7a..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.Warps;
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,223 +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)
- {
- 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..d58a70b924a
--- /dev/null
+++ b/Content.Server/_NF/GameRule/PointOfInterestSystem.cs
@@ -0,0 +1,299 @@
+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)
+ {
+ 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/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/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 d46469c1348..0b8eae5b82c 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:
@@ -64,4 +65,4 @@
stationProto: MarketFrontierOutpost
components:
- type: StationNameSetup
- mapNameTemplate: 'Cargo Depot' # Has a letter appended in NfAdventureSystem
\ No newline at end of file
+ mapNameTemplate: 'Cargo Depot' # Has a letter appended in NfAdventureSystem
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/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