Skip to content

Commit

Permalink
POI Spawning: Handle empty preset list, restrict protos in NfAdventur…
Browse files Browse the repository at this point in the history
…eRule (#2614)

* POI spawning: remove most presets, +preset checks

* organize dependencies

* curse of alphabetization

* Milon's suggestions

* missed refactor references

* restore the arrays
  • Loading branch information
whatston3 authored Dec 27, 2024
1 parent ecd0e54 commit f8b16a1
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 36 deletions.
42 changes: 26 additions & 16 deletions Content.Server/_NF/GameRule/NfAdventureRuleSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -28,14 +29,17 @@ namespace Content.Server._NF.GameRule;
/// </summary>
public sealed class NFAdventureRuleSystem : GameRuleSystem<NFAdventureRuleComponent>
{
[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<GamePresetPrototype> _fallbackPresetID = "NFPirates";

public sealed class PlayerRoundBankInformation
{
// Initial balance, obtained on spawn
Expand Down Expand Up @@ -68,7 +72,7 @@ public override void Initialize()
SubscribeLocalEvent<PlayerSpawnCompleteEvent>(OnPlayerSpawningEvent);
SubscribeLocalEvent<PlayerDetachedEvent>(OnPlayerDetachedEvent);
SubscribeLocalEvent<RoundRestartCleanupEvent>(OnRoundRestart);
_playerManager.PlayerStatusChanged += PlayerManagerOnPlayerStatusChanged;
_player.PlayerStatusChanged += PlayerManagerOnPlayerStatusChanged;
}

protected override void AppendRoundEndText(EntityUid uid, NFAdventureRuleComponent component, GameRuleComponent gameRule, ref RoundEndTextAppendEvent ev)
Expand Down Expand Up @@ -196,8 +200,14 @@ protected override void Started(EntityUid uid, NFAdventureRuleComponent componen
List<PointOfInterestPrototype> optionalProtos = new();
Dictionary<string, List<PointOfInterestPrototype>> remainingUniqueProtosBySpawnGroup = new();

foreach (var location in _prototypeManager.EnumeratePrototypes<PointOfInterestPrototype>())
var currentPreset = _ticker.CurrentPreset?.ID ?? _fallbackPresetID;

foreach (var location in _proto.EnumeratePrototypes<PointOfInterestPrototype>())
{
// 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")
Expand Down Expand Up @@ -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;

Expand All @@ -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;

Expand Down
1 change: 1 addition & 0 deletions Content.Server/_NF/GameRule/PointOfInterestPrototype.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public sealed partial class PointOfInterestPrototype : IPrototype

/// <summary>
/// What gamepresets ID this POI is allowed to spawn on.
/// If left empty, all presets are allowed.
/// </summary>
[DataField]
public ProtoId<GamePresetPrototype>[] SpawnGamePreset { get; private set; } = [];
Expand Down
45 changes: 25 additions & 20 deletions Content.Server/_NF/GameRule/PointOfInterestSystem.cs
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -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<Vector2> _stationCoords = new();

Expand Down Expand Up @@ -55,7 +55,7 @@ public void GenerateDepots(MapId mapUid, List<PointOfInterestPrototype> depotPro
//by the number of depots set in our corresponding cvar

depotStations = new List<EntityUid>();
var depotCount = _configurationManager.GetCVar(NFCCVars.CargoDepots);
var depotCount = _cfg.GetCVar(NFCCVars.CargoDepots);
var rotation = 2 * Math.PI / depotCount;
var rotationOffset = _random.NextAngle() / depotCount;

Expand All @@ -68,7 +68,8 @@ public void GenerateDepots(MapId mapUid, List<PointOfInterestPrototype> 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);
Expand Down Expand Up @@ -96,7 +97,7 @@ public void GenerateMarkets(MapId mapUid, List<PointOfInterestPrototype> marketP
//ideal world

marketStations = new List<EntityUid>();
var marketCount = _configurationManager.GetCVar(NFCCVars.MarketStations);
var marketCount = _cfg.GetCVar(NFCCVars.MarketStations);
_random.Shuffle(marketPrototypes);
int marketsAdded = 0;

Expand All @@ -106,7 +107,8 @@ public void GenerateMarkets(MapId mapUid, List<PointOfInterestPrototype> 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)
Expand All @@ -130,7 +132,7 @@ public void GenerateOptionals(MapId mapUid, List<PointOfInterestPrototype> 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<EntityUid>();
var optionalCount = _configurationManager.GetCVar(NFCCVars.OptionalStations);
var optionalCount = _cfg.GetCVar(NFCCVars.OptionalStations);
_random.Shuffle(optionalPrototypes);
int optionalsAdded = 0;

Expand All @@ -140,7 +142,8 @@ public void GenerateOptionals(MapId mapUid, List<PointOfInterestPrototype> 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)
Expand Down Expand Up @@ -171,7 +174,8 @@ public void GenerateRequireds(MapId mapUid, List<PointOfInterestPrototype> 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);
Expand Down Expand Up @@ -205,7 +209,8 @@ public void GenerateUniques(MapId mapUid, Dictionary<string, List<PointOfInteres
_random.Shuffle(prototypeList);
foreach (var proto in prototypeList)
{
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 chance = _random.NextFloat(0, 1);
Expand Down Expand Up @@ -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<GameMapPrototype>(proto.ID, out var stationProto))
if (_proto.TryIndex<GameMapPrototype>(proto.ID, out var stationProto))
{
stationUid = _station.InitializeNewStation(stationProto.Stations[proto.ID], mapUids, stationName);
}
Expand Down Expand Up @@ -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++)
Expand Down

0 comments on commit f8b16a1

Please sign in to comment.