From 4bf1181d62ac395e6bf82094b1dd855dd129c250 Mon Sep 17 00:00:00 2001 From: Avery Dobbins Date: Fri, 21 Jun 2024 13:19:40 -0400 Subject: [PATCH 01/37] works, still has testing values, im sure I did stupid shit. --- .../Rules/Components/RandomRuleComponent.cs | 25 +++++++ .../GameTicking/Rules/RandomRuleSystem.cs | 74 +++++++++++++++++++ .../BasicStationEventSchedulerSystem.cs | 11 +-- .../BasicStationEventSchedulerComponent.cs | 12 ++- .../RampingStationEventSchedulerComponent.cs | 10 ++- .../StationEvents/EventManagerSystem.cs | 60 ++++++++++++++- .../RampingStationEventSchedulerSystem.cs | 4 +- Resources/Prototypes/GameRules/roundstart.yml | 62 ++++++++++++++++ 8 files changed, 247 insertions(+), 11 deletions(-) create mode 100644 Content.Server/GameTicking/Rules/Components/RandomRuleComponent.cs create mode 100644 Content.Server/GameTicking/Rules/RandomRuleSystem.cs diff --git a/Content.Server/GameTicking/Rules/Components/RandomRuleComponent.cs b/Content.Server/GameTicking/Rules/Components/RandomRuleComponent.cs new file mode 100644 index 000000000000..d08e8cd1b2e2 --- /dev/null +++ b/Content.Server/GameTicking/Rules/Components/RandomRuleComponent.cs @@ -0,0 +1,25 @@ +using Content.Shared.Storage; + +namespace Content.Server.GameTicking.Rules.Components; + +[RegisterComponent, Access(typeof(RandomRuleSystem))] +public sealed partial class RandomRuleComponent : Component +{ + /// + /// The gamerules that get added at random. + /// + [DataField(required: true)] + public List SelectableGameRules = new(); + + /// + /// The maximum gamerules that get added at a time. + /// + [DataField] + public int MaxRules = 1; + + /// + /// The minimum gamerules that get added at a time. + /// + [DataField] + public int MinRules = 1; +} diff --git a/Content.Server/GameTicking/Rules/RandomRuleSystem.cs b/Content.Server/GameTicking/Rules/RandomRuleSystem.cs new file mode 100644 index 000000000000..06f307d2f5a9 --- /dev/null +++ b/Content.Server/GameTicking/Rules/RandomRuleSystem.cs @@ -0,0 +1,74 @@ +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using Content.Server.Administration.Logs; +using Content.Server.Chat.Managers; +using Content.Server.GameTicking.Presets; +using Content.Server.GameTicking.Rules.Components; +using Content.Shared.GameTicking.Components; +using Content.Shared.Random; +using Content.Shared.Database; +using Robust.Shared.Prototypes; +using Robust.Shared.Random; +using Robust.Shared.Configuration; +using Robust.Shared.Utility; +using Content.Shared.Storage; +using Microsoft.CodeAnalysis; + +namespace Content.Server.GameTicking.Rules; + +public sealed class RandomRuleSystem : GameRuleSystem +{ + [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly IAdminLogManager _adminLogger = default!; + [Dependency] private readonly IChatManager _chatManager = default!; + [Dependency] private readonly IComponentFactory _compFact = default!; + + private string _ruleCompName = default!; + public override void Initialize() + { + base.Initialize(); + } + + protected override void Added(EntityUid uid, RandomRuleComponent component, GameRuleComponent gameRule, GameRuleAddedEvent args) + { + var selectedRules = EntitySpawnCollection.GetSpawns(component.SelectableGameRules, _random); + + Random rnd = new Random(); + int ruleQuant = rnd.Next(component.MinRules, component.MaxRules); + + for (int i = 0; i < ruleQuant; i++) + { + string? slag = null; + + foreach (var rule in selectedRules) + { + if (selectedRules == null) + return; + /// If the station is already initialized, just start the rule, otherwise let that happen at the start of round. + if (GameTicker.RunLevel <= GameRunLevel.InRound) + GameTicker.AddGameRule(rule); + else + GameTicker.StartGameRule(rule); + slag = rule; + } + + ///prevents same gamerule twice in one run. + if (!string.IsNullOrEmpty(slag)) + { + selectedRules.RemoveAt(selectedRules.IndexOf(slag)); + } + } + } + + /// Read in the list of game rules + + /// Select one (or more) at random + + /// Add rule + + /// start rule + + + +} diff --git a/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs b/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs index 501d9033b9c0..e8ebc0f23b4a 100644 --- a/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs +++ b/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs @@ -23,8 +23,9 @@ public sealed class BasicStationEventSchedulerSystem : GameRuleSystem(); while (query.MoveNext(out var uid, out var eventScheduler, out var gameRule)) @@ -52,7 +53,7 @@ public override void Update(float frameTime) return; } - _event.RunRandomEvent(); + _event.RunLimitedEvent(eventScheduler.ScheduledGameRules); ResetTimer(eventScheduler); } } diff --git a/Content.Server/StationEvents/Components/BasicStationEventSchedulerComponent.cs b/Content.Server/StationEvents/Components/BasicStationEventSchedulerComponent.cs index a6ea139f04e7..d7653a1607e3 100644 --- a/Content.Server/StationEvents/Components/BasicStationEventSchedulerComponent.cs +++ b/Content.Server/StationEvents/Components/BasicStationEventSchedulerComponent.cs @@ -1,9 +1,11 @@ -namespace Content.Server.StationEvents.Components; +using Content.Shared.Storage; + +namespace Content.Server.StationEvents.Components; [RegisterComponent, Access(typeof(BasicStationEventSchedulerSystem))] public sealed partial class BasicStationEventSchedulerComponent : Component { - public const float MinimumTimeUntilFirstEvent = 300; + public const float MinimumTimeUntilFirstEvent = 30; // Someone yell at me if I dont change this back to 300, I need to test it without dying of old /// /// How long until the next check for an event runs @@ -11,4 +13,10 @@ public sealed partial class BasicStationEventSchedulerComponent : Component /// Default value is how long until first event is allowed [ViewVariables(VVAccess.ReadWrite)] public float TimeUntilNextEvent = MinimumTimeUntilFirstEvent; + + /// + /// The gamerules that the scheduler can choose from + /// + [DataField(required: true)] + public List ScheduledGameRules = new(); } diff --git a/Content.Server/StationEvents/Components/RampingStationEventSchedulerComponent.cs b/Content.Server/StationEvents/Components/RampingStationEventSchedulerComponent.cs index 53bc8b62a438..cd25dc4f7642 100644 --- a/Content.Server/StationEvents/Components/RampingStationEventSchedulerComponent.cs +++ b/Content.Server/StationEvents/Components/RampingStationEventSchedulerComponent.cs @@ -1,4 +1,6 @@ -namespace Content.Server.StationEvents.Components; +using Content.Shared.Storage; + +namespace Content.Server.StationEvents.Components; [RegisterComponent, Access(typeof(RampingStationEventSchedulerSystem))] public sealed partial class RampingStationEventSchedulerComponent : Component @@ -14,4 +16,10 @@ public sealed partial class RampingStationEventSchedulerComponent : Component [DataField("timeUntilNextEvent"), ViewVariables(VVAccess.ReadWrite)] public float TimeUntilNextEvent; + + /// + /// The gamerules that the scheduler can choose from + /// + [DataField(required: true)] + public List ScheduledGameRules = new(); } diff --git a/Content.Server/StationEvents/EventManagerSystem.cs b/Content.Server/StationEvents/EventManagerSystem.cs index f2fdb8ff5a7a..2fd428062da9 100644 --- a/Content.Server/StationEvents/EventManagerSystem.cs +++ b/Content.Server/StationEvents/EventManagerSystem.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using System.Linq; using Content.Server.Chat.Managers; using Content.Server.GameTicking; @@ -7,11 +8,13 @@ using Robust.Shared.Configuration; using Robust.Shared.Prototypes; using Robust.Shared.Random; +using Content.Shared.Storage; namespace Content.Server.StationEvents; public sealed class EventManagerSystem : EntitySystem { + [Dependency] private readonly IComponentFactory _compFac = default!; [Dependency] private readonly IConfigurationManager _configurationManager = default!; [Dependency] private readonly IPlayerManager _playerManager = default!; [Dependency] private readonly IRobustRandom _random = default!; @@ -44,7 +47,7 @@ public string RunRandomEvent() } var ent = GameTicker.AddGameRule(randomEvent); - var str = Loc.GetString("station-event-system-run-event",("eventName", ToPrettyString(ent))); + var str = Loc.GetString("station-event-system-run-event", ("eventName", ToPrettyString(ent))); _chat.SendAdminAlert(str); Log.Info(str); return str; @@ -60,6 +63,61 @@ public string RunRandomEvent() return FindEvent(availableEvents); } + /// + /// Randomly runs an event from provided list. + /// + public string? RunLimitedEvent(List? limitedEventsList) + { + if (limitedEventsList != null) + { + + + var selectedEvents = EntitySpawnCollection.GetSpawns(limitedEventsList, _random); // storage function for game rules, smh my head. + // fuck it though, it works and gives us all the random selection utility we want. + + Log.Info($"Picking from {limitedEventsList.Count} subsetted events"); + + var limitedEvents = new Dictionary(); + foreach (var eventid in selectedEvents) + { + if (!_prototype.TryIndex(eventid, out var eventproto)) + { + Log.Warning("An event ID has no prototype index!"); + continue; + } + + if (eventproto.Abstract) + continue; + + var stationEvent = _compFac.GetComponent(); // I think this fails to an exception? but I can't imagine a time when you would be okay with a fucked event scheduler / a scheduler trying to pull a non-station event. + + limitedEvents.Add(eventproto, stationEvent); + } + + var randomLimitedEvent = FindEvent(limitedEvents); // this picks the event, It might be better to use the EntitySpawnEntry to do it, but we still need to account for maxuimums or players counts and whatnot. + if (randomLimitedEvent == null) + { + Log.Warning("The selected random event is null!"); + return null; + } + + if (!_prototype.TryIndex(randomLimitedEvent, out _)) + { + Log.Warning("A requested event is not available!"); + return null; + } + + var ent = GameTicker.AddGameRule(randomLimitedEvent); + var str = Loc.GetString("station-event-system-run-event", ("eventName", ToPrettyString(ent))); + _chat.SendAdminAlert(str); + Log.Info(str); + return str; + } + Log.Warning("A scheduler has requested null as event!"); + return null; + } + + /// /// Pick a random event from the available events at this time, also considering their weightings. /// diff --git a/Content.Server/StationEvents/RampingStationEventSchedulerSystem.cs b/Content.Server/StationEvents/RampingStationEventSchedulerSystem.cs index f65105de0669..e069cb93e97e 100644 --- a/Content.Server/StationEvents/RampingStationEventSchedulerSystem.cs +++ b/Content.Server/StationEvents/RampingStationEventSchedulerSystem.cs @@ -1,4 +1,4 @@ -using Content.Server.GameTicking; +using Content.Server.GameTicking; using Content.Server.GameTicking.Rules; using Content.Server.GameTicking.Rules.Components; using Content.Server.StationEvents.Components; @@ -63,7 +63,7 @@ public override void Update(float frameTime) } PickNextEventTime(uid, scheduler); - _event.RunRandomEvent(); + _event.RunLimitedEvent(scheduler.ScheduledGameRules); } } diff --git a/Resources/Prototypes/GameRules/roundstart.yml b/Resources/Prototypes/GameRules/roundstart.yml index 923a01146062..2be2f1818973 100644 --- a/Resources/Prototypes/GameRules/roundstart.yml +++ b/Resources/Prototypes/GameRules/roundstart.yml @@ -254,12 +254,74 @@ parent: BaseGameRule components: - type: BasicStationEventScheduler + scheduledGameRules: + - id: ClosetSkeleton + - id: MouseMigration + - id: SlimesSpawn + - id: BluespaceArtifact + - id: ClericalError + - id: IonStorm + - id: KingRatMigration + - id: CockroachMigration + - id: SpiderClownSpawn + - id: VentClog + - id: GasLeak + - id: ImmovableRodSpawn + - id: BreakerFlip + - id: PowerGridCheck + - id: BluespaceLocker + - id: NinjaSpawn + - id: BureaucraticError + - id: DragonSpawn + - id: SpiderSpawn + - id: MimicVendorRule + - id: LoneOpsSpawn + - id: RevenantSpawn +# - id: MassHallucination # What the fuck is this? Is it its own whoosiwhatsit and not an event? + - id: SleeperAgentsRule + - id: AnomalySpawn + - id: SolarFlare + - id: KudzuGrowth + - id: ZombieOutbreak +# - id: CargoGiftMasterRule +# - id: ShuttleEventMasterRule - type: entity id: RampingStationEventScheduler parent: BaseGameRule components: - type: RampingStationEventScheduler + scheduledGameRules: + - id: ClosetSkeleton + - id: MouseMigration + - id: SlimesSpawn + - id: BluespaceArtifact + - id: ClericalError + - id: IonStorm + - id: KingRatMigration + - id: CockroachMigration + - id: SpiderClownSpawn + - id: VentClog + - id: GasLeak + - id: ImmovableRodSpawn + - id: BreakerFlip + - id: PowerGridCheck + - id: BluespaceLocker + - id: NinjaSpawn + - id: BureaucraticError + - id: DragonSpawn + - id: SpiderSpawn + - id: MimicVendorRule + - id: LoneOpsSpawn + - id: RevenantSpawn +# - id: MassHallucination # What the fuck is this? Is it its own whoosiwhatsit and not an event? + - id: SleeperAgents + - id: AnomalySpawn + - id: SolarFlare + - id: KudzuGrowth + - id: ZombieOutbreak +# - id: CargoGiftMasterRule +# - id: ShuttleEventMasterRule # variation passes - type: entity From cbe3c898cbb29e6d3357eb23f9aaeccf1fa4d1e2 Mon Sep 17 00:00:00 2001 From: Avery Dobbins Date: Fri, 21 Jun 2024 17:55:00 -0400 Subject: [PATCH 02/37] shitvent crapfactor --- .../BasicStationEventSchedulerSystem.cs | 4 +- .../BasicStationEventSchedulerComponent.cs | 2 +- .../StationEvents/EventManagerSystem.cs | 14 ++++++- .../Prototypes/GameRules/cargo_gifts.yml | 39 +++++++++++++++++++ Resources/Prototypes/GameRules/roundstart.yml | 7 ++-- .../Prototypes/GameRules/unknown_shuttles.yml | 22 +++++++++++ 6 files changed, 79 insertions(+), 9 deletions(-) diff --git a/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs b/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs index e8ebc0f23b4a..3ae61e165f98 100644 --- a/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs +++ b/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs @@ -38,8 +38,8 @@ public override void Update(float frameTime) { base.Update(frameTime); - // if (!_event.EventsEnabled) // commented for testing - // return; + if (!_event.EventsEnabled) // comment for testing + return; var query = EntityQueryEnumerator(); while (query.MoveNext(out var uid, out var eventScheduler, out var gameRule)) diff --git a/Content.Server/StationEvents/Components/BasicStationEventSchedulerComponent.cs b/Content.Server/StationEvents/Components/BasicStationEventSchedulerComponent.cs index d7653a1607e3..6ed246a9db56 100644 --- a/Content.Server/StationEvents/Components/BasicStationEventSchedulerComponent.cs +++ b/Content.Server/StationEvents/Components/BasicStationEventSchedulerComponent.cs @@ -5,7 +5,7 @@ namespace Content.Server.StationEvents.Components; [RegisterComponent, Access(typeof(BasicStationEventSchedulerSystem))] public sealed partial class BasicStationEventSchedulerComponent : Component { - public const float MinimumTimeUntilFirstEvent = 30; // Someone yell at me if I dont change this back to 300, I need to test it without dying of old + public const float MinimumTimeUntilFirstEvent = 300; // Someone yell at me if I dont change this back to 300, I need to test it without dying of old /// /// How long until the next check for an event runs diff --git a/Content.Server/StationEvents/EventManagerSystem.cs b/Content.Server/StationEvents/EventManagerSystem.cs index 2fd428062da9..9e811497d930 100644 --- a/Content.Server/StationEvents/EventManagerSystem.cs +++ b/Content.Server/StationEvents/EventManagerSystem.cs @@ -70,7 +70,13 @@ public string RunRandomEvent() { if (limitedEventsList != null) { + var availableEvents = AvailableEvents(); // handles the player counts and individual event restrictions + if (availableEvents.Count == 0) + { + Log.Warning("No events were available to run!"); + return null; + } var selectedEvents = EntitySpawnCollection.GetSpawns(limitedEventsList, _random); // storage function for game rules, smh my head. // fuck it though, it works and gives us all the random selection utility we want. @@ -89,12 +95,16 @@ public string RunRandomEvent() if (eventproto.Abstract) continue; - var stationEvent = _compFac.GetComponent(); // I think this fails to an exception? but I can't imagine a time when you would be okay with a fucked event scheduler / a scheduler trying to pull a non-station event. + if (!eventproto.TryGetComponent(out var stationEvent, _compFac)) + continue; + + if (!availableEvents.ContainsKey(eventproto)) + continue; limitedEvents.Add(eventproto, stationEvent); } - var randomLimitedEvent = FindEvent(limitedEvents); // this picks the event, It might be better to use the EntitySpawnEntry to do it, but we still need to account for maxuimums or players counts and whatnot. + var randomLimitedEvent = FindEvent(limitedEvents); // this picks the event, It might be better to use the GetSpawns to do it, but that will be a major rebalancing fuck. if (randomLimitedEvent == null) { Log.Warning("The selected random event is null!"); diff --git a/Resources/Prototypes/GameRules/cargo_gifts.yml b/Resources/Prototypes/GameRules/cargo_gifts.yml index ffc2ed404b70..a8a2fa2b8904 100644 --- a/Resources/Prototypes/GameRules/cargo_gifts.yml +++ b/Resources/Prototypes/GameRules/cargo_gifts.yml @@ -1,3 +1,42 @@ +# Add your new event to this RandomRule if you want it to happen via the basic/ramping schedulers. +- type: entity + parent: BaseGameRule + id: RandomCargoGiftsRule + components: + - type: RandomRule + selectableGameRules: + # Make the probability sum to 1 or I will remove your fingernails with toothpicks. + - id: GiftsPizzaPartySmall + prob: 0.1 + orGroup: Gifts + - id: GiftsPizzaPartyLarge + prob: 0.1 + orGroup: Gifts + - id: GiftsEngineering + prob: 0.1 + orGroup: Gifts + - id: GiftsVendingRestock + prob: 0.1 + orGroup: Gifts + - id: GiftsJanitor + prob: 0.1 + orGroup: Gifts + - id: GiftsMedical + prob: 0.1 + orGroup: Gifts + - id: GiftsSpacingSupplies + prob: 0.1 + orGroup: Gifts + - id: GiftsFireProtection + prob: 0.1 + orGroup: Gifts + - id: GiftsSecurityGuns + prob: 0.1 + orGroup: Gifts + - id: GiftsSecurityRiot + prob: 0.1 + orGroup: Gifts + - type: entity id: CargoGiftsBase parent: BaseGameRule diff --git a/Resources/Prototypes/GameRules/roundstart.yml b/Resources/Prototypes/GameRules/roundstart.yml index 2be2f1818973..7c1468818c5f 100644 --- a/Resources/Prototypes/GameRules/roundstart.yml +++ b/Resources/Prototypes/GameRules/roundstart.yml @@ -283,8 +283,8 @@ - id: SolarFlare - id: KudzuGrowth - id: ZombieOutbreak -# - id: CargoGiftMasterRule -# - id: ShuttleEventMasterRule + - id: RandomCargoGiftsRule + - id: RandomUnknownShuttleRule - type: entity id: RampingStationEventScheduler @@ -314,14 +314,13 @@ - id: MimicVendorRule - id: LoneOpsSpawn - id: RevenantSpawn -# - id: MassHallucination # What the fuck is this? Is it its own whoosiwhatsit and not an event? - id: SleeperAgents - id: AnomalySpawn - id: SolarFlare - id: KudzuGrowth - id: ZombieOutbreak # - id: CargoGiftMasterRule -# - id: ShuttleEventMasterRule + - id: RandomUnknownShuttleRule # variation passes - type: entity diff --git a/Resources/Prototypes/GameRules/unknown_shuttles.yml b/Resources/Prototypes/GameRules/unknown_shuttles.yml index 1ce365cd816b..107010066135 100644 --- a/Resources/Prototypes/GameRules/unknown_shuttles.yml +++ b/Resources/Prototypes/GameRules/unknown_shuttles.yml @@ -1,3 +1,25 @@ +# Add your new event to this RandomRule if you want it to happen via the basic/ramping schedulers. +- type: entity + parent: BaseGameRule + id: RandomUnknownShuttleRule + components: + - type: RandomRule + selectableGameRules: + # Make the probability sum to 1 or I will remove your fingernails with toothpicks. + - id: UnknownShuttleCargoLost + prob: 0.25 + orGroup: Shuttles + - id: UnknownShuttleTravelingCuisine + prob: 0.25 + orGroup: Shuttles + - id: UnknownShuttleDisasterEvacPod + prob: 0.3 + orGroup: Shuttles + - id: UnknownShuttleSyndieEvacPod + prob: 0.2 + orGroup: Shuttles + + - type: entity abstract: true parent: BaseGameRule From d3aace99c4ea7888bafe53861f951badba21877c Mon Sep 17 00:00:00 2001 From: Avery Dobbins Date: Fri, 21 Jun 2024 18:08:52 -0400 Subject: [PATCH 03/37] snap extra word out of existence --- Resources/Prototypes/GameRules/roundstart.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/Prototypes/GameRules/roundstart.yml b/Resources/Prototypes/GameRules/roundstart.yml index 7c1468818c5f..eddd0cc2c4e8 100644 --- a/Resources/Prototypes/GameRules/roundstart.yml +++ b/Resources/Prototypes/GameRules/roundstart.yml @@ -278,7 +278,7 @@ - id: LoneOpsSpawn - id: RevenantSpawn # - id: MassHallucination # What the fuck is this? Is it its own whoosiwhatsit and not an event? - - id: SleeperAgentsRule + - id: SleeperAgents - id: AnomalySpawn - id: SolarFlare - id: KudzuGrowth From 45566599e5750fd3e84a40a463a33033d9848efe Mon Sep 17 00:00:00 2001 From: Avery Dobbins Date: Fri, 21 Jun 2024 18:13:48 -0400 Subject: [PATCH 04/37] shit I died of old --- .../StationEvents/BasicStationEventSchedulerSystem.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs b/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs index 3ae61e165f98..93712e1c5162 100644 --- a/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs +++ b/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs @@ -24,8 +24,8 @@ public sealed class BasicStationEventSchedulerSystem : GameRuleSystem Date: Fri, 21 Jun 2024 18:23:44 -0400 Subject: [PATCH 05/37] remove useless inaccurate design comments --- Content.Server/GameTicking/Rules/RandomRuleSystem.cs | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/Content.Server/GameTicking/Rules/RandomRuleSystem.cs b/Content.Server/GameTicking/Rules/RandomRuleSystem.cs index 06f307d2f5a9..0cd4fe90f160 100644 --- a/Content.Server/GameTicking/Rules/RandomRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/RandomRuleSystem.cs @@ -60,15 +60,4 @@ protected override void Added(EntityUid uid, RandomRuleComponent component, Game } } } - - /// Read in the list of game rules - - /// Select one (or more) at random - - /// Add rule - - /// start rule - - - } From 4e44d6b975f8621f69ae29542ddccd218a75f721 Mon Sep 17 00:00:00 2001 From: Avery Dobbins Date: Fri, 21 Jun 2024 21:07:04 -0400 Subject: [PATCH 06/37] Oopsie, handle requirement params in RandomRuleSystem too --- .../GameTicking/Rules/RandomRuleSystem.cs | 34 ++++++++++++++----- .../StationEvents/EventManagerSystem.cs | 2 +- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/Content.Server/GameTicking/Rules/RandomRuleSystem.cs b/Content.Server/GameTicking/Rules/RandomRuleSystem.cs index 0cd4fe90f160..1f2baf8819fa 100644 --- a/Content.Server/GameTicking/Rules/RandomRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/RandomRuleSystem.cs @@ -1,18 +1,12 @@ -using System.Diagnostics.CodeAnalysis; -using System.Linq; using Content.Server.Administration.Logs; using Content.Server.Chat.Managers; -using Content.Server.GameTicking.Presets; using Content.Server.GameTicking.Rules.Components; +using Content.Server.StationEvents; using Content.Shared.GameTicking.Components; -using Content.Shared.Random; -using Content.Shared.Database; using Robust.Shared.Prototypes; using Robust.Shared.Random; -using Robust.Shared.Configuration; -using Robust.Shared.Utility; using Content.Shared.Storage; -using Microsoft.CodeAnalysis; +using Content.Server.StationEvents.Components; namespace Content.Server.GameTicking.Rules; @@ -23,6 +17,7 @@ public sealed class RandomRuleSystem : GameRuleSystem [Dependency] private readonly IAdminLogManager _adminLogger = default!; [Dependency] private readonly IChatManager _chatManager = default!; [Dependency] private readonly IComponentFactory _compFact = default!; + [Dependency] private readonly EventManagerSystem _event = default!; private string _ruleCompName = default!; public override void Initialize() @@ -39,6 +34,7 @@ protected override void Added(EntityUid uid, RandomRuleComponent component, Game for (int i = 0; i < ruleQuant; i++) { + var availableEvents = _event.AvailableEvents(); // handles the player counts and individual event restrictions, we need to do it each i incase it changes string? slag = null; foreach (var rule in selectedRules) @@ -47,9 +43,28 @@ protected override void Added(EntityUid uid, RandomRuleComponent component, Game return; /// If the station is already initialized, just start the rule, otherwise let that happen at the start of round. if (GameTicker.RunLevel <= GameRunLevel.InRound) + { GameTicker.AddGameRule(rule); + } else - GameTicker.StartGameRule(rule); + { + _prototypeManager.TryIndex(rule, out var ruleEnt); + if (ruleEnt == null) + { + Log.Warning("The selected random rule is null!"); + continue; + } + + if (ruleEnt.TryGetComponent(out _, _compFact)) + { + if (!availableEvents.ContainsKey(ruleEnt)) + { + Log.Warning("The selected random rule is not available!"); + continue; + } + GameTicker.StartGameRule(rule); + } + } slag = rule; } @@ -60,4 +75,5 @@ protected override void Added(EntityUid uid, RandomRuleComponent component, Game } } } + } diff --git a/Content.Server/StationEvents/EventManagerSystem.cs b/Content.Server/StationEvents/EventManagerSystem.cs index 9e811497d930..7e916e4a8bfd 100644 --- a/Content.Server/StationEvents/EventManagerSystem.cs +++ b/Content.Server/StationEvents/EventManagerSystem.cs @@ -64,7 +64,7 @@ public string RunRandomEvent() } /// - /// Randomly runs an event from provided list. + /// Randomly runs an event from provided EntitySpawnCollection. /// public string? RunLimitedEvent(List? limitedEventsList) { From 26606330149fb88711ade43d23a062bf3a8f61f3 Mon Sep 17 00:00:00 2001 From: Avery Dobbins Date: Fri, 21 Jun 2024 21:31:43 -0400 Subject: [PATCH 07/37] I'm a slash slinging hasher --- Content.Server/GameTicking/Rules/RandomRuleSystem.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Content.Server/GameTicking/Rules/RandomRuleSystem.cs b/Content.Server/GameTicking/Rules/RandomRuleSystem.cs index 1f2baf8819fa..1bb33bf7ceec 100644 --- a/Content.Server/GameTicking/Rules/RandomRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/RandomRuleSystem.cs @@ -41,7 +41,7 @@ protected override void Added(EntityUid uid, RandomRuleComponent component, Game { if (selectedRules == null) return; - /// If the station is already initialized, just start the rule, otherwise let that happen at the start of round. + // If the station is already initialized, just start the rule, otherwise let that happen at the start of round. if (GameTicker.RunLevel <= GameRunLevel.InRound) { GameTicker.AddGameRule(rule); @@ -68,7 +68,7 @@ protected override void Added(EntityUid uid, RandomRuleComponent component, Game slag = rule; } - ///prevents same gamerule twice in one run. + // prevents same gamerule twice in one run. if (!string.IsNullOrEmpty(slag)) { selectedRules.RemoveAt(selectedRules.IndexOf(slag)); From d2e71a2febca3bc8593bb99eecddd27c6d7b410e Mon Sep 17 00:00:00 2001 From: Avery Dobbins Date: Sat, 22 Jun 2024 16:55:09 -0400 Subject: [PATCH 08/37] Address reviews, add admin alerts I forgor --- .../Rules/Components/RandomRuleComponent.cs | 4 + .../GameTicking/Rules/RandomRuleSystem.cs | 78 ++++++++++--------- .../BasicStationEventSchedulerSystem.cs | 9 +-- .../StationEvents/EventManagerSystem.cs | 22 +++--- .../RampingStationEventSchedulerSystem.cs | 2 +- 5 files changed, 60 insertions(+), 55 deletions(-) diff --git a/Content.Server/GameTicking/Rules/Components/RandomRuleComponent.cs b/Content.Server/GameTicking/Rules/Components/RandomRuleComponent.cs index d08e8cd1b2e2..5bb363bc8f00 100644 --- a/Content.Server/GameTicking/Rules/Components/RandomRuleComponent.cs +++ b/Content.Server/GameTicking/Rules/Components/RandomRuleComponent.cs @@ -2,6 +2,10 @@ namespace Content.Server.GameTicking.Rules.Components; + +/// +/// Given a list of EntitySpawnEntries, selects between MinRules & MaxRules gamerules to add to the round without duplicates. +/// [RegisterComponent, Access(typeof(RandomRuleSystem))] public sealed partial class RandomRuleComponent : Component { diff --git a/Content.Server/GameTicking/Rules/RandomRuleSystem.cs b/Content.Server/GameTicking/Rules/RandomRuleSystem.cs index 1bb33bf7ceec..bf89188a3594 100644 --- a/Content.Server/GameTicking/Rules/RandomRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/RandomRuleSystem.cs @@ -7,72 +7,74 @@ using Robust.Shared.Random; using Content.Shared.Storage; using Content.Server.StationEvents.Components; +using System.Linq; namespace Content.Server.GameTicking.Rules; + +/// +/// Entities spawned with this component will try to add gamerules from the provided EntitySpawnEntry list. +/// This can be used to subset gamerules for balance, or to do something else like add it to a prototype if you want ninjas to start with meteors etc. +/// public sealed class RandomRuleSystem : GameRuleSystem { [Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly IRobustRandom _random = default!; - [Dependency] private readonly IAdminLogManager _adminLogger = default!; [Dependency] private readonly IChatManager _chatManager = default!; [Dependency] private readonly IComponentFactory _compFact = default!; [Dependency] private readonly EventManagerSystem _event = default!; - private string _ruleCompName = default!; - public override void Initialize() - { - base.Initialize(); - } - protected override void Added(EntityUid uid, RandomRuleComponent component, GameRuleComponent gameRule, GameRuleAddedEvent args) { var selectedRules = EntitySpawnCollection.GetSpawns(component.SelectableGameRules, _random); - Random rnd = new Random(); - int ruleQuant = rnd.Next(component.MinRules, component.MaxRules); + if (component.MinRules > component.MaxRules) + { + Log.Warning("Minimum rules is more than Maximum rules!"); + return; + } + + int ruleQuant = _random.Next(component.MinRules, component.MaxRules + 1); // the padding is required for expected result. Dont ask me why Next was implimented this way. + + if (selectedRules == null || selectedRules.Count == 0) + return; + + _random.Shuffle(selectedRules); + var nRules = selectedRules.Take(ruleQuant); // Does not allow duplicate selection, unless the EntitySpawnCollection had duplicate entries. - for (int i = 0; i < ruleQuant; i++) + var availableEvents = _event.AvailableEvents(); // handles the player counts and individual event restrictions, we need to do it each i incase it changes + + foreach (var rule in nRules) { - var availableEvents = _event.AvailableEvents(); // handles the player counts and individual event restrictions, we need to do it each i incase it changes - string? slag = null; + var ruleEnt = new EntityUid(); - foreach (var rule in selectedRules) + // If the station is already initialized, just start the rule, otherwise let that happen at the start of round. + if (GameTicker.RunLevel <= GameRunLevel.InRound) + { + ruleEnt = GameTicker.AddGameRule(rule); + } + else { - if (selectedRules == null) - return; - // If the station is already initialized, just start the rule, otherwise let that happen at the start of round. - if (GameTicker.RunLevel <= GameRunLevel.InRound) + if (!_prototypeManager.TryIndex(rule, out var ruleProto)) { - GameTicker.AddGameRule(rule); + Log.Warning("The selected random rule is missing a prototype!"); + continue; } - else + + if (ruleProto.TryGetComponent(out _, _compFact)) { - _prototypeManager.TryIndex(rule, out var ruleEnt); - if (ruleEnt == null) + if (!availableEvents.ContainsKey(ruleProto)) { - Log.Warning("The selected random rule is null!"); + Log.Warning("The selected random rule is not available!"); continue; } - - if (ruleEnt.TryGetComponent(out _, _compFact)) - { - if (!availableEvents.ContainsKey(ruleEnt)) - { - Log.Warning("The selected random rule is not available!"); - continue; - } - GameTicker.StartGameRule(rule); - } + GameTicker.StartGameRule(rule, out ruleEnt); } - slag = rule; } - // prevents same gamerule twice in one run. - if (!string.IsNullOrEmpty(slag)) - { - selectedRules.RemoveAt(selectedRules.IndexOf(slag)); - } + var str = Loc.GetString("station-event-system-run-event", ("eventName", ToPrettyString(ruleEnt))); + _chatManager.SendAdminAlert(str); + Log.Info(str); } } diff --git a/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs b/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs index 93712e1c5162..ae6f3d7d8970 100644 --- a/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs +++ b/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs @@ -23,9 +23,8 @@ public sealed class BasicStationEventSchedulerSystem : GameRuleSystem(); @@ -53,7 +52,7 @@ public override void Update(float frameTime) return; } - _event.RunLimitedEvent(eventScheduler.ScheduledGameRules); + _event.RunRandomEvent(eventScheduler.ScheduledGameRules); ResetTimer(eventScheduler); } } diff --git a/Content.Server/StationEvents/EventManagerSystem.cs b/Content.Server/StationEvents/EventManagerSystem.cs index 7e916e4a8bfd..364c00871790 100644 --- a/Content.Server/StationEvents/EventManagerSystem.cs +++ b/Content.Server/StationEvents/EventManagerSystem.cs @@ -53,20 +53,10 @@ public string RunRandomEvent() return str; } - /// - /// Randomly picks a valid event. - /// - public string? PickRandomEvent() - { - var availableEvents = AvailableEvents(); - Log.Info($"Picking from {availableEvents.Count} total available events"); - return FindEvent(availableEvents); - } - /// /// Randomly runs an event from provided EntitySpawnCollection. /// - public string? RunLimitedEvent(List? limitedEventsList) + public string? RunRandomEvent(List? limitedEventsList) { if (limitedEventsList != null) { @@ -128,6 +118,16 @@ public string RunRandomEvent() } + /// + /// Randomly picks a valid event. + /// + public string? PickRandomEvent() + { + var availableEvents = AvailableEvents(); + Log.Info($"Picking from {availableEvents.Count} total available events"); + return FindEvent(availableEvents); + } + /// /// Pick a random event from the available events at this time, also considering their weightings. /// diff --git a/Content.Server/StationEvents/RampingStationEventSchedulerSystem.cs b/Content.Server/StationEvents/RampingStationEventSchedulerSystem.cs index e069cb93e97e..5840fb542494 100644 --- a/Content.Server/StationEvents/RampingStationEventSchedulerSystem.cs +++ b/Content.Server/StationEvents/RampingStationEventSchedulerSystem.cs @@ -63,7 +63,7 @@ public override void Update(float frameTime) } PickNextEventTime(uid, scheduler); - _event.RunLimitedEvent(scheduler.ScheduledGameRules); + _event.RunRandomEvent(scheduler.ScheduledGameRules); } } From f92e6a4f39b75e1996cc535f1576e0346b8fb80b Mon Sep 17 00:00:00 2001 From: Avery Dobbins Date: Sun, 23 Jun 2024 20:06:42 -0400 Subject: [PATCH 09/37] EntityMan saves the day --- Content.Server/GameTicking/Rules/RandomRuleSystem.cs | 3 +-- Content.Server/StationEvents/EventManagerSystem.cs | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Content.Server/GameTicking/Rules/RandomRuleSystem.cs b/Content.Server/GameTicking/Rules/RandomRuleSystem.cs index bf89188a3594..af64bf8b2404 100644 --- a/Content.Server/GameTicking/Rules/RandomRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/RandomRuleSystem.cs @@ -21,7 +21,6 @@ public sealed class RandomRuleSystem : GameRuleSystem [Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly IChatManager _chatManager = default!; - [Dependency] private readonly IComponentFactory _compFact = default!; [Dependency] private readonly EventManagerSystem _event = default!; protected override void Added(EntityUid uid, RandomRuleComponent component, GameRuleComponent gameRule, GameRuleAddedEvent args) @@ -61,7 +60,7 @@ protected override void Added(EntityUid uid, RandomRuleComponent component, Game continue; } - if (ruleProto.TryGetComponent(out _, _compFact)) + if (ruleProto.TryGetComponent(out _, EntityManager.ComponentFactory)) { if (!availableEvents.ContainsKey(ruleProto)) { diff --git a/Content.Server/StationEvents/EventManagerSystem.cs b/Content.Server/StationEvents/EventManagerSystem.cs index 364c00871790..e9d68e9ba413 100644 --- a/Content.Server/StationEvents/EventManagerSystem.cs +++ b/Content.Server/StationEvents/EventManagerSystem.cs @@ -14,7 +14,6 @@ namespace Content.Server.StationEvents; public sealed class EventManagerSystem : EntitySystem { - [Dependency] private readonly IComponentFactory _compFac = default!; [Dependency] private readonly IConfigurationManager _configurationManager = default!; [Dependency] private readonly IPlayerManager _playerManager = default!; [Dependency] private readonly IRobustRandom _random = default!; @@ -85,7 +84,7 @@ public string RunRandomEvent() if (eventproto.Abstract) continue; - if (!eventproto.TryGetComponent(out var stationEvent, _compFac)) + if (!eventproto.TryGetComponent(out var stationEvent, EntityManager.ComponentFactory)) continue; if (!availableEvents.ContainsKey(eventproto)) From d44e076c2c7d335f0afdf141527c20814cc21f78 Mon Sep 17 00:00:00 2001 From: Avery Dobbins Date: Tue, 2 Jul 2024 14:56:35 -0400 Subject: [PATCH 10/37] address reviews 1 --- .../Rules/Components/RandomRuleComponent.cs | 11 +++------- .../GameTicking/Rules/RandomRuleSystem.cs | 21 +++++-------------- .../BasicStationEventSchedulerComponent.cs | 2 +- Resources/Prototypes/GameRules/roundstart.yml | 5 +++-- .../Prototypes/GameRules/unknown_shuttles.yml | 1 - 5 files changed, 12 insertions(+), 28 deletions(-) diff --git a/Content.Server/GameTicking/Rules/Components/RandomRuleComponent.cs b/Content.Server/GameTicking/Rules/Components/RandomRuleComponent.cs index 5bb363bc8f00..90527cceb9f1 100644 --- a/Content.Server/GameTicking/Rules/Components/RandomRuleComponent.cs +++ b/Content.Server/GameTicking/Rules/Components/RandomRuleComponent.cs @@ -1,3 +1,4 @@ +using Content.Shared.Destructible.Thresholds; using Content.Shared.Storage; namespace Content.Server.GameTicking.Rules.Components; @@ -16,14 +17,8 @@ public sealed partial class RandomRuleComponent : Component public List SelectableGameRules = new(); /// - /// The maximum gamerules that get added at a time. + /// The minimum and maximum gamerules that get added at a time. /// [DataField] - public int MaxRules = 1; - - /// - /// The minimum gamerules that get added at a time. - /// - [DataField] - public int MinRules = 1; + public MinMax MinMaxRules = new(1, 1); } diff --git a/Content.Server/GameTicking/Rules/RandomRuleSystem.cs b/Content.Server/GameTicking/Rules/RandomRuleSystem.cs index af64bf8b2404..4001a40b55d3 100644 --- a/Content.Server/GameTicking/Rules/RandomRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/RandomRuleSystem.cs @@ -1,4 +1,3 @@ -using Content.Server.Administration.Logs; using Content.Server.Chat.Managers; using Content.Server.GameTicking.Rules.Components; using Content.Server.StationEvents; @@ -6,7 +5,6 @@ using Robust.Shared.Prototypes; using Robust.Shared.Random; using Content.Shared.Storage; -using Content.Server.StationEvents.Components; using System.Linq; namespace Content.Server.GameTicking.Rules; @@ -27,13 +25,7 @@ protected override void Added(EntityUid uid, RandomRuleComponent component, Game { var selectedRules = EntitySpawnCollection.GetSpawns(component.SelectableGameRules, _random); - if (component.MinRules > component.MaxRules) - { - Log.Warning("Minimum rules is more than Maximum rules!"); - return; - } - - int ruleQuant = _random.Next(component.MinRules, component.MaxRules + 1); // the padding is required for expected result. Dont ask me why Next was implimented this way. + int ruleQuant = component.MinMaxRules.Next(_random); if (selectedRules == null || selectedRules.Count == 0) return; @@ -60,15 +52,12 @@ protected override void Added(EntityUid uid, RandomRuleComponent component, Game continue; } - if (ruleProto.TryGetComponent(out _, EntityManager.ComponentFactory)) + if (!availableEvents.ContainsKey(ruleProto)) { - if (!availableEvents.ContainsKey(ruleProto)) - { - Log.Warning("The selected random rule is not available!"); - continue; - } - GameTicker.StartGameRule(rule, out ruleEnt); + Log.Warning("The selected random rule is not available!"); + continue; } + GameTicker.StartGameRule(rule, out ruleEnt); } var str = Loc.GetString("station-event-system-run-event", ("eventName", ToPrettyString(ruleEnt))); diff --git a/Content.Server/StationEvents/Components/BasicStationEventSchedulerComponent.cs b/Content.Server/StationEvents/Components/BasicStationEventSchedulerComponent.cs index 6ed246a9db56..bdca1f925e95 100644 --- a/Content.Server/StationEvents/Components/BasicStationEventSchedulerComponent.cs +++ b/Content.Server/StationEvents/Components/BasicStationEventSchedulerComponent.cs @@ -5,7 +5,7 @@ namespace Content.Server.StationEvents.Components; [RegisterComponent, Access(typeof(BasicStationEventSchedulerSystem))] public sealed partial class BasicStationEventSchedulerComponent : Component { - public const float MinimumTimeUntilFirstEvent = 300; // Someone yell at me if I dont change this back to 300, I need to test it without dying of old + public const float MinimumTimeUntilFirstEvent = 300; /// /// How long until the next check for an event runs diff --git a/Resources/Prototypes/GameRules/roundstart.yml b/Resources/Prototypes/GameRules/roundstart.yml index eddd0cc2c4e8..85fed81a1c99 100644 --- a/Resources/Prototypes/GameRules/roundstart.yml +++ b/Resources/Prototypes/GameRules/roundstart.yml @@ -277,7 +277,7 @@ - id: MimicVendorRule - id: LoneOpsSpawn - id: RevenantSpawn -# - id: MassHallucination # What the fuck is this? Is it its own whoosiwhatsit and not an event? + - id: MassHallucinations - id: SleeperAgents - id: AnomalySpawn - id: SolarFlare @@ -314,12 +314,13 @@ - id: MimicVendorRule - id: LoneOpsSpawn - id: RevenantSpawn + - id: MassHallucinations - id: SleeperAgents - id: AnomalySpawn - id: SolarFlare - id: KudzuGrowth - id: ZombieOutbreak -# - id: CargoGiftMasterRule +# - id: RandomCargoGiftsRule - id: RandomUnknownShuttleRule # variation passes diff --git a/Resources/Prototypes/GameRules/unknown_shuttles.yml b/Resources/Prototypes/GameRules/unknown_shuttles.yml index 107010066135..3b041934ffd0 100644 --- a/Resources/Prototypes/GameRules/unknown_shuttles.yml +++ b/Resources/Prototypes/GameRules/unknown_shuttles.yml @@ -19,7 +19,6 @@ prob: 0.2 orGroup: Shuttles - - type: entity abstract: true parent: BaseGameRule From 5d23be6bc0baca419ef71e1f777adf06817c13a1 Mon Sep 17 00:00:00 2001 From: Avery Dobbins Date: Tue, 2 Jul 2024 15:14:04 -0400 Subject: [PATCH 11/37] eh, I actually don't care about the cargo gifts thing. --- Resources/Prototypes/GameRules/roundstart.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/Prototypes/GameRules/roundstart.yml b/Resources/Prototypes/GameRules/roundstart.yml index 85fed81a1c99..b72a977980df 100644 --- a/Resources/Prototypes/GameRules/roundstart.yml +++ b/Resources/Prototypes/GameRules/roundstart.yml @@ -320,7 +320,7 @@ - id: SolarFlare - id: KudzuGrowth - id: ZombieOutbreak -# - id: RandomCargoGiftsRule + - id: RandomCargoGiftsRule - id: RandomUnknownShuttleRule # variation passes From 28329bbd245a3f7f6e7b3d4309f9a6a9c725afb1 Mon Sep 17 00:00:00 2001 From: Avery Dobbins Date: Tue, 2 Jul 2024 15:27:06 -0400 Subject: [PATCH 12/37] started --- .../GameTicking/Rules/RandomRuleSystem.cs | 26 +++++++------------ 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/Content.Server/GameTicking/Rules/RandomRuleSystem.cs b/Content.Server/GameTicking/Rules/RandomRuleSystem.cs index 4001a40b55d3..572b1438b96b 100644 --- a/Content.Server/GameTicking/Rules/RandomRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/RandomRuleSystem.cs @@ -21,7 +21,7 @@ public sealed class RandomRuleSystem : GameRuleSystem [Dependency] private readonly IChatManager _chatManager = default!; [Dependency] private readonly EventManagerSystem _event = default!; - protected override void Added(EntityUid uid, RandomRuleComponent component, GameRuleComponent gameRule, GameRuleAddedEvent args) + protected override void Started(EntityUid uid, RandomRuleComponent component, GameRuleComponent gameRule, GameRuleStartedEvent args) { var selectedRules = EntitySpawnCollection.GetSpawns(component.SelectableGameRules, _random); @@ -39,26 +39,18 @@ protected override void Added(EntityUid uid, RandomRuleComponent component, Game { var ruleEnt = new EntityUid(); - // If the station is already initialized, just start the rule, otherwise let that happen at the start of round. - if (GameTicker.RunLevel <= GameRunLevel.InRound) + if (!_prototypeManager.TryIndex(rule, out var ruleProto)) { - ruleEnt = GameTicker.AddGameRule(rule); + Log.Warning("The selected random rule is missing a prototype!"); + continue; } - else - { - if (!_prototypeManager.TryIndex(rule, out var ruleProto)) - { - Log.Warning("The selected random rule is missing a prototype!"); - continue; - } - if (!availableEvents.ContainsKey(ruleProto)) - { - Log.Warning("The selected random rule is not available!"); - continue; - } - GameTicker.StartGameRule(rule, out ruleEnt); + if (!availableEvents.ContainsKey(ruleProto)) + { + Log.Warning("The selected random rule is not available!"); + continue; } + GameTicker.StartGameRule(rule, out ruleEnt); var str = Loc.GetString("station-event-system-run-event", ("eventName", ToPrettyString(ruleEnt))); _chatManager.SendAdminAlert(str); From 7c9a8ebb64351e6563520b9ed6d015427ca7129a Mon Sep 17 00:00:00 2001 From: Avery Dobbins Date: Sat, 20 Jul 2024 14:20:50 -0400 Subject: [PATCH 13/37] Do reviews --- .../GameTicking/GameTicker.GameRule.cs | 6 ++ .../GameTicking/Rules/RandomRuleSystem.cs | 8 +- .../StationEvents/EventManagerSystem.cs | 94 ++++++++----------- .../Prototypes/GameRules/cargo_gifts.yml | 27 ++---- Resources/Prototypes/GameRules/roundstart.yml | 80 ++++++++-------- .../Prototypes/GameRules/unknown_shuttles.yml | 5 - 6 files changed, 96 insertions(+), 124 deletions(-) diff --git a/Content.Server/GameTicking/GameTicker.GameRule.cs b/Content.Server/GameTicking/GameTicker.GameRule.cs index 2a33d01bd09e..4ccbaf3db1ac 100644 --- a/Content.Server/GameTicking/GameTicker.GameRule.cs +++ b/Content.Server/GameTicking/GameTicker.GameRule.cs @@ -1,5 +1,6 @@ using System.Linq; using Content.Server.Administration; +using Content.Server.Chat.Managers; using Content.Server.GameTicking.Rules.Components; using Content.Shared.Administration; using Content.Shared.Database; @@ -14,6 +15,8 @@ namespace Content.Server.GameTicking; public sealed partial class GameTicker { + [Dependency] private readonly IChatManager _chat = default!; + [ViewVariables] private readonly List<(TimeSpan, string)> _allPreviousGameRules = new(); /// @@ -71,6 +74,9 @@ public EntityUid AddGameRule(string ruleId) var ruleEntity = Spawn(ruleId, MapCoordinates.Nullspace); _sawmill.Info($"Added game rule {ToPrettyString(ruleEntity)}"); _adminLogger.Add(LogType.EventStarted, $"Added game rule {ToPrettyString(ruleEntity)}"); + var str = Loc.GetString("station-event-system-run-event", ("eventName", ToPrettyString(ruleEntity))); + _chat.SendAdminAlert(str); + Log.Info(str); var ev = new GameRuleAddedEvent(ruleEntity, ruleId); RaiseLocalEvent(ruleEntity, ref ev, true); diff --git a/Content.Server/GameTicking/Rules/RandomRuleSystem.cs b/Content.Server/GameTicking/Rules/RandomRuleSystem.cs index 572b1438b96b..80dbd9781812 100644 --- a/Content.Server/GameTicking/Rules/RandomRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/RandomRuleSystem.cs @@ -37,8 +37,6 @@ protected override void Started(EntityUid uid, RandomRuleComponent component, Ga foreach (var rule in nRules) { - var ruleEnt = new EntityUid(); - if (!_prototypeManager.TryIndex(rule, out var ruleProto)) { Log.Warning("The selected random rule is missing a prototype!"); @@ -50,11 +48,7 @@ protected override void Started(EntityUid uid, RandomRuleComponent component, Ga Log.Warning("The selected random rule is not available!"); continue; } - GameTicker.StartGameRule(rule, out ruleEnt); - - var str = Loc.GetString("station-event-system-run-event", ("eventName", ToPrettyString(ruleEnt))); - _chatManager.SendAdminAlert(str); - Log.Info(str); + GameTicker.StartGameRule(rule); } } diff --git a/Content.Server/StationEvents/EventManagerSystem.cs b/Content.Server/StationEvents/EventManagerSystem.cs index e9d68e9ba413..dffc3449d140 100644 --- a/Content.Server/StationEvents/EventManagerSystem.cs +++ b/Content.Server/StationEvents/EventManagerSystem.cs @@ -34,7 +34,7 @@ public override void Initialize() /// /// Randomly runs a valid event. /// - public string RunRandomEvent() + public void RunRandomEvent() { var randomEvent = PickRandomEvent(); @@ -42,78 +42,66 @@ public string RunRandomEvent() { var errStr = Loc.GetString("station-event-system-run-random-event-no-valid-events"); Log.Error(errStr); - return errStr; + return; } - var ent = GameTicker.AddGameRule(randomEvent); - var str = Loc.GetString("station-event-system-run-event", ("eventName", ToPrettyString(ent))); - _chat.SendAdminAlert(str); - Log.Info(str); - return str; + GameTicker.AddGameRule(randomEvent); + return; } /// /// Randomly runs an event from provided EntitySpawnCollection. /// - public string? RunRandomEvent(List? limitedEventsList) + public void RunRandomEvent(List limitedEventsList) { - if (limitedEventsList != null) - { - var availableEvents = AvailableEvents(); // handles the player counts and individual event restrictions + var availableEvents = AvailableEvents(); // handles the player counts and individual event restrictions - if (availableEvents.Count == 0) - { - Log.Warning("No events were available to run!"); - return null; - } + if (availableEvents.Count == 0) + { + Log.Warning("No events were available to run!"); + return; + } - var selectedEvents = EntitySpawnCollection.GetSpawns(limitedEventsList, _random); // storage function for game rules, smh my head. - // fuck it though, it works and gives us all the random selection utility we want. + var selectedEvents = EntitySpawnCollection.GetSpawns(limitedEventsList, _random); // storage function for game rules, smh my head. + // fuck it though, it works and gives us all the random selection utility we want. - Log.Info($"Picking from {limitedEventsList.Count} subsetted events"); + Log.Info($"Picking from {limitedEventsList.Count} subsetted events"); - var limitedEvents = new Dictionary(); - foreach (var eventid in selectedEvents) + var limitedEvents = new Dictionary(); + foreach (var eventid in selectedEvents) + { + if (!_prototype.TryIndex(eventid, out var eventproto)) { - if (!_prototype.TryIndex(eventid, out var eventproto)) - { - Log.Warning("An event ID has no prototype index!"); - continue; - } - - if (eventproto.Abstract) - continue; + Log.Warning("An event ID has no prototype index!"); + continue; + } - if (!eventproto.TryGetComponent(out var stationEvent, EntityManager.ComponentFactory)) - continue; + if (eventproto.Abstract) + continue; - if (!availableEvents.ContainsKey(eventproto)) - continue; + if (!eventproto.TryGetComponent(out var stationEvent, EntityManager.ComponentFactory)) + continue; - limitedEvents.Add(eventproto, stationEvent); - } + if (!availableEvents.ContainsKey(eventproto)) + continue; - var randomLimitedEvent = FindEvent(limitedEvents); // this picks the event, It might be better to use the GetSpawns to do it, but that will be a major rebalancing fuck. - if (randomLimitedEvent == null) - { - Log.Warning("The selected random event is null!"); - return null; - } + limitedEvents.Add(eventproto, stationEvent); + } - if (!_prototype.TryIndex(randomLimitedEvent, out _)) - { - Log.Warning("A requested event is not available!"); - return null; - } + var randomLimitedEvent = FindEvent(limitedEvents); // this picks the event, It might be better to use the GetSpawns to do it, but that will be a major rebalancing fuck. + if (randomLimitedEvent == null) + { + Log.Warning("The selected random event is null!"); + return; + } - var ent = GameTicker.AddGameRule(randomLimitedEvent); - var str = Loc.GetString("station-event-system-run-event", ("eventName", ToPrettyString(ent))); - _chat.SendAdminAlert(str); - Log.Info(str); - return str; + if (!_prototype.TryIndex(randomLimitedEvent, out _)) + { + Log.Warning("A requested event is not available!"); + return; } - Log.Warning("A scheduler has requested null as event!"); - return null; + + GameTicker.AddGameRule(randomLimitedEvent); } diff --git a/Resources/Prototypes/GameRules/cargo_gifts.yml b/Resources/Prototypes/GameRules/cargo_gifts.yml index a8a2fa2b8904..af921499d463 100644 --- a/Resources/Prototypes/GameRules/cargo_gifts.yml +++ b/Resources/Prototypes/GameRules/cargo_gifts.yml @@ -5,38 +5,27 @@ components: - type: RandomRule selectableGameRules: - # Make the probability sum to 1 or I will remove your fingernails with toothpicks. - - id: GiftsPizzaPartySmall - prob: 0.1 - orGroup: Gifts - - id: GiftsPizzaPartyLarge - prob: 0.1 - orGroup: Gifts - id: GiftsEngineering - prob: 0.1 orGroup: Gifts - - id: GiftsVendingRestock - prob: 0.1 + - id: GiftsFireProtection orGroup: Gifts - id: GiftsJanitor - prob: 0.1 orGroup: Gifts - id: GiftsMedical - prob: 0.1 orGroup: Gifts - - id: GiftsSpacingSupplies - prob: 0.1 + - id: GiftsPizzaPartyLarge orGroup: Gifts - - id: GiftsFireProtection - prob: 0.1 + - id: GiftsPizzaPartySmall orGroup: Gifts - id: GiftsSecurityGuns - prob: 0.1 orGroup: Gifts - id: GiftsSecurityRiot - prob: 0.1 orGroup: Gifts - + - id: GiftsSpacingSupplies + orGroup: Gifts + - id: GiftsVendingRestock + orGroup: Gifts + - type: entity id: CargoGiftsBase parent: BaseGameRule diff --git a/Resources/Prototypes/GameRules/roundstart.yml b/Resources/Prototypes/GameRules/roundstart.yml index b72a977980df..e07af2ab0550 100644 --- a/Resources/Prototypes/GameRules/roundstart.yml +++ b/Resources/Prototypes/GameRules/roundstart.yml @@ -255,36 +255,36 @@ components: - type: BasicStationEventScheduler scheduledGameRules: - - id: ClosetSkeleton - - id: MouseMigration - - id: SlimesSpawn + - id: AnomalySpawn - id: BluespaceArtifact + - id: BluespaceLocker + - id: BreakerFlip + - id: BureaucraticError - id: ClericalError - - id: IonStorm - - id: KingRatMigration + - id: ClosetSkeleton - id: CockroachMigration - - id: SpiderClownSpawn - - id: VentClog + - id: DragonSpawn - id: GasLeak - id: ImmovableRodSpawn - - id: BreakerFlip - - id: PowerGridCheck - - id: BluespaceLocker - - id: NinjaSpawn - - id: BureaucraticError - - id: DragonSpawn - - id: SpiderSpawn - - id: MimicVendorRule + - id: IonStorm + - id: KingRatMigration + - id: KudzuGrowth - id: LoneOpsSpawn - - id: RevenantSpawn - id: MassHallucinations + - id: MimicVendorRule + - id: MouseMigration + - id: NinjaSpawn + - id: PowerGridCheck + - id: RandomCargoGiftsRule + - id: RandomUnknownShuttleRule + - id: RevenantSpawn - id: SleeperAgents - - id: AnomalySpawn + - id: SlimesSpawn - id: SolarFlare - - id: KudzuGrowth + - id: SpiderClownSpawn + - id: SpiderSpawn + - id: VentClog - id: ZombieOutbreak - - id: RandomCargoGiftsRule - - id: RandomUnknownShuttleRule - type: entity id: RampingStationEventScheduler @@ -292,36 +292,36 @@ components: - type: RampingStationEventScheduler scheduledGameRules: - - id: ClosetSkeleton - - id: MouseMigration - - id: SlimesSpawn + - id: AnomalySpawn - id: BluespaceArtifact + - id: BluespaceLocker + - id: BreakerFlip + - id: BureaucraticError - id: ClericalError - - id: IonStorm - - id: KingRatMigration + - id: ClosetSkeleton - id: CockroachMigration - - id: SpiderClownSpawn - - id: VentClog + - id: DragonSpawn - id: GasLeak - id: ImmovableRodSpawn - - id: BreakerFlip - - id: PowerGridCheck - - id: BluespaceLocker - - id: NinjaSpawn - - id: BureaucraticError - - id: DragonSpawn - - id: SpiderSpawn - - id: MimicVendorRule + - id: IonStorm + - id: KingRatMigration + - id: KudzuGrowth - id: LoneOpsSpawn - - id: RevenantSpawn - id: MassHallucinations + - id: MimicVendorRule + - id: MouseMigration + - id: NinjaSpawn + - id: PowerGridCheck + - id: RandomCargoGiftsRule + - id: RandomUnknownShuttleRule + - id: RevenantSpawn - id: SleeperAgents - - id: AnomalySpawn + - id: SlimesSpawn - id: SolarFlare - - id: KudzuGrowth + - id: SpiderClownSpawn + - id: SpiderSpawn + - id: VentClog - id: ZombieOutbreak - - id: RandomCargoGiftsRule - - id: RandomUnknownShuttleRule # variation passes - type: entity diff --git a/Resources/Prototypes/GameRules/unknown_shuttles.yml b/Resources/Prototypes/GameRules/unknown_shuttles.yml index 3b041934ffd0..3f6d3df38a0e 100644 --- a/Resources/Prototypes/GameRules/unknown_shuttles.yml +++ b/Resources/Prototypes/GameRules/unknown_shuttles.yml @@ -5,18 +5,13 @@ components: - type: RandomRule selectableGameRules: - # Make the probability sum to 1 or I will remove your fingernails with toothpicks. - id: UnknownShuttleCargoLost - prob: 0.25 orGroup: Shuttles - id: UnknownShuttleTravelingCuisine - prob: 0.25 orGroup: Shuttles - id: UnknownShuttleDisasterEvacPod - prob: 0.3 orGroup: Shuttles - id: UnknownShuttleSyndieEvacPod - prob: 0.2 orGroup: Shuttles - type: entity From 63d3c199d45502125f69be038b89ebbd80caf888 Mon Sep 17 00:00:00 2001 From: Avery Dobbins Date: Sat, 20 Jul 2024 14:29:51 -0400 Subject: [PATCH 14/37] you actually meant 1.2 lmao --- Resources/Prototypes/GameRules/unknown_shuttles.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/Resources/Prototypes/GameRules/unknown_shuttles.yml b/Resources/Prototypes/GameRules/unknown_shuttles.yml index 3f6d3df38a0e..87b6ef3e6d74 100644 --- a/Resources/Prototypes/GameRules/unknown_shuttles.yml +++ b/Resources/Prototypes/GameRules/unknown_shuttles.yml @@ -10,6 +10,7 @@ - id: UnknownShuttleTravelingCuisine orGroup: Shuttles - id: UnknownShuttleDisasterEvacPod + prob: 1.2 orGroup: Shuttles - id: UnknownShuttleSyndieEvacPod orGroup: Shuttles From b1e31a12c9ac0225f2191bc01ccb460fdb075654 Mon Sep 17 00:00:00 2001 From: Avery Dobbins Date: Sat, 20 Jul 2024 15:00:44 -0400 Subject: [PATCH 15/37] dependency inheritance is a fickle bitch --- Content.Server/GameTicking/GameTicker.GameRule.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Content.Server/GameTicking/GameTicker.GameRule.cs b/Content.Server/GameTicking/GameTicker.GameRule.cs index 4ccbaf3db1ac..5f7608acfd9a 100644 --- a/Content.Server/GameTicking/GameTicker.GameRule.cs +++ b/Content.Server/GameTicking/GameTicker.GameRule.cs @@ -15,8 +15,6 @@ namespace Content.Server.GameTicking; public sealed partial class GameTicker { - [Dependency] private readonly IChatManager _chat = default!; - [ViewVariables] private readonly List<(TimeSpan, string)> _allPreviousGameRules = new(); /// @@ -75,7 +73,7 @@ public EntityUid AddGameRule(string ruleId) _sawmill.Info($"Added game rule {ToPrettyString(ruleEntity)}"); _adminLogger.Add(LogType.EventStarted, $"Added game rule {ToPrettyString(ruleEntity)}"); var str = Loc.GetString("station-event-system-run-event", ("eventName", ToPrettyString(ruleEntity))); - _chat.SendAdminAlert(str); + _chatManager.SendAdminAlert(str); Log.Info(str); var ev = new GameRuleAddedEvent(ruleEntity, ruleId); From e5a559a8fffe1ac740614cc4451e3e7bf76d5d62 Mon Sep 17 00:00:00 2001 From: Avery Dobbins Date: Sat, 20 Jul 2024 17:42:13 -0400 Subject: [PATCH 16/37] I have no idea. --- .../Tests/GameRules/RuleMaxTimeRestartTest.cs | 4 +++- Content.Server/GameTicking/GameTicker.GameRule.cs | 7 ++++++- Content.Server/StationEvents/EventManagerSystem.cs | 1 - 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Content.IntegrationTests/Tests/GameRules/RuleMaxTimeRestartTest.cs b/Content.IntegrationTests/Tests/GameRules/RuleMaxTimeRestartTest.cs index 4708bd10c08a..ca6de2002abb 100644 --- a/Content.IntegrationTests/Tests/GameRules/RuleMaxTimeRestartTest.cs +++ b/Content.IntegrationTests/Tests/GameRules/RuleMaxTimeRestartTest.cs @@ -1,4 +1,4 @@ -using Content.Server.GameTicking; +using Content.Server.GameTicking; using Content.Server.GameTicking.Commands; using Content.Server.GameTicking.Rules; using Content.Server.GameTicking.Rules.Components; @@ -6,6 +6,7 @@ using Content.Shared.GameTicking.Components; using Robust.Shared.Configuration; using Robust.Shared.GameObjects; +using Robust.Shared.Localization; using Robust.Shared.Timing; namespace Content.IntegrationTests.Tests.GameRules @@ -26,6 +27,7 @@ public async Task RestartTest() var entityManager = server.ResolveDependency(); var sGameTicker = server.ResolveDependency().GetEntitySystem(); var sGameTiming = server.ResolveDependency(); + var locManager = server.ResolveDependency(); sGameTicker.StartGameRule("MaxTimeRestart", out var ruleEntity); Assert.That(entityManager.TryGetComponent(ruleEntity, out var maxTime)); diff --git a/Content.Server/GameTicking/GameTicker.GameRule.cs b/Content.Server/GameTicking/GameTicker.GameRule.cs index 5f7608acfd9a..9655bc36fae2 100644 --- a/Content.Server/GameTicking/GameTicker.GameRule.cs +++ b/Content.Server/GameTicking/GameTicker.GameRule.cs @@ -1,6 +1,5 @@ using System.Linq; using Content.Server.Administration; -using Content.Server.Chat.Managers; using Content.Server.GameTicking.Rules.Components; using Content.Shared.Administration; using Content.Shared.Database; @@ -10,6 +9,7 @@ using Robust.Shared.Console; using Robust.Shared.Map; using Robust.Shared.Prototypes; +using Robust.Shared.Localization; namespace Content.Server.GameTicking; @@ -73,7 +73,12 @@ public EntityUid AddGameRule(string ruleId) _sawmill.Info($"Added game rule {ToPrettyString(ruleEntity)}"); _adminLogger.Add(LogType.EventStarted, $"Added game rule {ToPrettyString(ruleEntity)}"); var str = Loc.GetString("station-event-system-run-event", ("eventName", ToPrettyString(ruleEntity))); +#if !TOOLS +// Okay, best I can figure, this is something to do with thread pooling, and the LocalizationManager just kills itself when tests try to access it. +// ***maybe*** it could be sorted by making tests use IoCManager.InitThread() +// I have no fucking clue. It kills tests though and noone can see the alert in tests anyway, so here we are. _chatManager.SendAdminAlert(str); +#endif Log.Info(str); var ev = new GameRuleAddedEvent(ruleEntity, ruleId); diff --git a/Content.Server/StationEvents/EventManagerSystem.cs b/Content.Server/StationEvents/EventManagerSystem.cs index dffc3449d140..ac6e3c72a3d3 100644 --- a/Content.Server/StationEvents/EventManagerSystem.cs +++ b/Content.Server/StationEvents/EventManagerSystem.cs @@ -46,7 +46,6 @@ public void RunRandomEvent() } GameTicker.AddGameRule(randomEvent); - return; } /// From 423af3bd4c5bb4164bf8d490594a3101420bcb71 Mon Sep 17 00:00:00 2001 From: Avery Dobbins Date: Sat, 20 Jul 2024 18:17:14 -0400 Subject: [PATCH 17/37] Threads are for sheets not computers. --- .../Tests/GameRules/RuleMaxTimeRestartTest.cs | 8 ++++++-- Content.Server/GameTicking/GameTicker.GameRule.cs | 5 ----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/Content.IntegrationTests/Tests/GameRules/RuleMaxTimeRestartTest.cs b/Content.IntegrationTests/Tests/GameRules/RuleMaxTimeRestartTest.cs index ca6de2002abb..c0a666739648 100644 --- a/Content.IntegrationTests/Tests/GameRules/RuleMaxTimeRestartTest.cs +++ b/Content.IntegrationTests/Tests/GameRules/RuleMaxTimeRestartTest.cs @@ -29,8 +29,12 @@ public async Task RestartTest() var sGameTiming = server.ResolveDependency(); var locManager = server.ResolveDependency(); - sGameTicker.StartGameRule("MaxTimeRestart", out var ruleEntity); - Assert.That(entityManager.TryGetComponent(ruleEntity, out var maxTime)); + MaxTimeRestartRuleComponent maxTime = null; + await server.WaitPost(() => + { + sGameTicker.StartGameRule("MaxTimeRestart", out var ruleEntity); + Assert.That(entityManager.TryGetComponent(ruleEntity, out maxTime)); + }); Assert.That(server.EntMan.Count(), Is.EqualTo(1)); Assert.That(server.EntMan.Count(), Is.EqualTo(1)); diff --git a/Content.Server/GameTicking/GameTicker.GameRule.cs b/Content.Server/GameTicking/GameTicker.GameRule.cs index 9655bc36fae2..4f3c965bb20a 100644 --- a/Content.Server/GameTicking/GameTicker.GameRule.cs +++ b/Content.Server/GameTicking/GameTicker.GameRule.cs @@ -73,12 +73,7 @@ public EntityUid AddGameRule(string ruleId) _sawmill.Info($"Added game rule {ToPrettyString(ruleEntity)}"); _adminLogger.Add(LogType.EventStarted, $"Added game rule {ToPrettyString(ruleEntity)}"); var str = Loc.GetString("station-event-system-run-event", ("eventName", ToPrettyString(ruleEntity))); -#if !TOOLS -// Okay, best I can figure, this is something to do with thread pooling, and the LocalizationManager just kills itself when tests try to access it. -// ***maybe*** it could be sorted by making tests use IoCManager.InitThread() -// I have no fucking clue. It kills tests though and noone can see the alert in tests anyway, so here we are. _chatManager.SendAdminAlert(str); -#endif Log.Info(str); var ev = new GameRuleAddedEvent(ruleEntity, ruleId); From fe9b37b93d893684294480ac961392f003a16381 Mon Sep 17 00:00:00 2001 From: Avery Dobbins Date: Sat, 20 Jul 2024 19:03:16 -0400 Subject: [PATCH 18/37] fix traitor rule test --- .../Tests/GameRules/RuleMaxTimeRestartTest.cs | 1 + .../Tests/GameRules/TraitorRuleTest.cs | 17 +++++++++-------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/Content.IntegrationTests/Tests/GameRules/RuleMaxTimeRestartTest.cs b/Content.IntegrationTests/Tests/GameRules/RuleMaxTimeRestartTest.cs index c0a666739648..d5e14ca6cbcb 100644 --- a/Content.IntegrationTests/Tests/GameRules/RuleMaxTimeRestartTest.cs +++ b/Content.IntegrationTests/Tests/GameRules/RuleMaxTimeRestartTest.cs @@ -8,6 +8,7 @@ using Robust.Shared.GameObjects; using Robust.Shared.Localization; using Robust.Shared.Timing; +using System.Management; namespace Content.IntegrationTests.Tests.GameRules { diff --git a/Content.IntegrationTests/Tests/GameRules/TraitorRuleTest.cs b/Content.IntegrationTests/Tests/GameRules/TraitorRuleTest.cs index 31d33ba61746..d2717521b235 100644 --- a/Content.IntegrationTests/Tests/GameRules/TraitorRuleTest.cs +++ b/Content.IntegrationTests/Tests/GameRules/TraitorRuleTest.cs @@ -77,16 +77,17 @@ await server.WaitAssertion(() => await pair.SetAntagPreference(TraitorAntagRoleName, true); // Add the game rule - var gameRuleEnt = ticker.AddGameRule(TraitorGameRuleProtoId); - Assert.That(entMan.TryGetComponent(gameRuleEnt, out var traitorRule)); - - // Ready up - ticker.ToggleReadyAll(true); - Assert.That(ticker.PlayerGameStatuses.Values.All(x => x == PlayerGameStatus.ReadyToPlay)); - - // Start the round + TraitorRuleComponent traitorRule = null; await server.WaitPost(() => { + var gameRuleEnt = ticker.AddGameRule(TraitorGameRuleProtoId); + Assert.That(entMan.TryGetComponent(gameRuleEnt, out traitorRule)); + + // Ready up + ticker.ToggleReadyAll(true); + Assert.That(ticker.PlayerGameStatuses.Values.All(x => x == PlayerGameStatus.ReadyToPlay)); + + // Start the round ticker.StartRound(); // Force traitor mode to start (skip the delay) ticker.StartGameRule(gameRuleEnt); From 9d502aa3fb65e54f850cbf23652eab4b53ffd79f Mon Sep 17 00:00:00 2001 From: Avery Dobbins Date: Sat, 20 Jul 2024 20:31:44 -0400 Subject: [PATCH 19/37] fix round type tattling --- Content.Server/GameTicking/GameTicker.GameRule.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Content.Server/GameTicking/GameTicker.GameRule.cs b/Content.Server/GameTicking/GameTicker.GameRule.cs index d5177579d6dd..cf0b0eceb11a 100644 --- a/Content.Server/GameTicking/GameTicker.GameRule.cs +++ b/Content.Server/GameTicking/GameTicker.GameRule.cs @@ -73,7 +73,14 @@ public EntityUid AddGameRule(string ruleId) _sawmill.Info($"Added game rule {ToPrettyString(ruleEntity)}"); _adminLogger.Add(LogType.EventStarted, $"Added game rule {ToPrettyString(ruleEntity)}"); var str = Loc.GetString("station-event-system-run-event", ("eventName", ToPrettyString(ruleEntity))); +#if DEBUG _chatManager.SendAdminAlert(str); +#else + if (RunLevel == GameRunLevel.InRound) // avoids telling admins the round type before it starts so that can be handled elsewhere. + { + _chatManager.SendAdminAlert(str); + } +#endif Log.Info(str); var ev = new GameRuleAddedEvent(ruleEntity, ruleId); From a3345f2febe677b39d73d587279cd73d0b81dd45 Mon Sep 17 00:00:00 2001 From: Avery Dobbins Date: Mon, 12 Aug 2024 10:35:57 -0400 Subject: [PATCH 20/37] break things --- .../Components/BasicStationEventSchedulerComponent.cs | 4 ++-- .../Components/RampingStationEventSchedulerComponent.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Content.Server/StationEvents/Components/BasicStationEventSchedulerComponent.cs b/Content.Server/StationEvents/Components/BasicStationEventSchedulerComponent.cs index bdca1f925e95..b057e95dfe6a 100644 --- a/Content.Server/StationEvents/Components/BasicStationEventSchedulerComponent.cs +++ b/Content.Server/StationEvents/Components/BasicStationEventSchedulerComponent.cs @@ -1,4 +1,4 @@ -using Content.Shared.Storage; +using Content.Shared.EntityTable.EntitySelectors; namespace Content.Server.StationEvents.Components; @@ -18,5 +18,5 @@ public sealed partial class BasicStationEventSchedulerComponent : Component /// The gamerules that the scheduler can choose from /// [DataField(required: true)] - public List ScheduledGameRules = new(); + public EntityTableSelector ScheduledGameRules = default!; } diff --git a/Content.Server/StationEvents/Components/RampingStationEventSchedulerComponent.cs b/Content.Server/StationEvents/Components/RampingStationEventSchedulerComponent.cs index cd25dc4f7642..f2fd1addcf86 100644 --- a/Content.Server/StationEvents/Components/RampingStationEventSchedulerComponent.cs +++ b/Content.Server/StationEvents/Components/RampingStationEventSchedulerComponent.cs @@ -1,4 +1,4 @@ -using Content.Shared.Storage; +using Content.Shared.EntityTable.EntitySelectors; namespace Content.Server.StationEvents.Components; @@ -21,5 +21,5 @@ public sealed partial class RampingStationEventSchedulerComponent : Component /// The gamerules that the scheduler can choose from /// [DataField(required: true)] - public List ScheduledGameRules = new(); + public EntityTableSelector ScheduledGameRules = default!; } From a08f08cc7b13940608fc1344c3043838b1a9b1bd Mon Sep 17 00:00:00 2001 From: Avery Dobbins Date: Mon, 12 Aug 2024 18:43:25 -0400 Subject: [PATCH 21/37] It worky --- .../BasicStationEventSchedulerSystem.cs | 4 +- .../BasicStationEventSchedulerComponent.cs | 4 +- .../RampingStationEventSchedulerComponent.cs | 2 + .../StationEvents/EventManagerSystem.cs | 31 ++--- .../Prototypes/GameRules/cargo_gifts.yml | 25 ++-- Resources/Prototypes/GameRules/events.yml | 38 +++++++ Resources/Prototypes/GameRules/roundstart.yml | 107 ++++++++---------- .../Prototypes/GameRules/unknown_shuttles.yml | 32 ++++-- Resources/Prototypes/game_presets.yml | 15 +++ 9 files changed, 150 insertions(+), 108 deletions(-) diff --git a/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs b/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs index ae6f3d7d8970..655fbab4abe9 100644 --- a/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs +++ b/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs @@ -23,8 +23,8 @@ public sealed class BasicStationEventSchedulerSystem : GameRuleSystem /// How long until the next check for an event runs @@ -17,6 +17,8 @@ public sealed partial class BasicStationEventSchedulerComponent : Component /// /// The gamerules that the scheduler can choose from /// + /// Reminder that though we could do all selection via the EntityTableSelector, we also need to consider various restrictions. + /// As such, we want to pass a list of acceptable game rules, which are then parsed for restrictions by the . [DataField(required: true)] public EntityTableSelector ScheduledGameRules = default!; } diff --git a/Content.Server/StationEvents/Components/RampingStationEventSchedulerComponent.cs b/Content.Server/StationEvents/Components/RampingStationEventSchedulerComponent.cs index f2fd1addcf86..cf66189bc88c 100644 --- a/Content.Server/StationEvents/Components/RampingStationEventSchedulerComponent.cs +++ b/Content.Server/StationEvents/Components/RampingStationEventSchedulerComponent.cs @@ -20,6 +20,8 @@ public sealed partial class RampingStationEventSchedulerComponent : Component /// /// The gamerules that the scheduler can choose from /// + /// Reminder that though we could do all selection via the EntityTableSelector, we also need to consider various restrictions. + /// As such, we want to pass a list of acceptable game rules, which are then parsed for restrictions by the . [DataField(required: true)] public EntityTableSelector ScheduledGameRules = default!; } diff --git a/Content.Server/StationEvents/EventManagerSystem.cs b/Content.Server/StationEvents/EventManagerSystem.cs index c5b4527d4e10..ce9d162baf9e 100644 --- a/Content.Server/StationEvents/EventManagerSystem.cs +++ b/Content.Server/StationEvents/EventManagerSystem.cs @@ -1,4 +1,3 @@ -using System.Collections.Generic; using System.Linq; using Content.Server.Chat.Managers; using Content.Server.GameTicking; @@ -9,7 +8,8 @@ using Robust.Shared.Configuration; using Robust.Shared.Prototypes; using Robust.Shared.Random; -using Content.Shared.Storage; +using Content.Shared.EntityTable.EntitySelectors; +using Content.Shared.EntityTable; namespace Content.Server.StationEvents; @@ -19,7 +19,7 @@ public sealed class EventManagerSystem : EntitySystem [Dependency] private readonly IPlayerManager _playerManager = default!; [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly IPrototypeManager _prototype = default!; - [Dependency] private readonly IChatManager _chat = default!; + [Dependency] private readonly EntityTableSystem _entityTable = default!; [Dependency] public readonly GameTicker GameTicker = default!; [Dependency] private readonly RoundEndSystem _roundEnd = default!; @@ -53,20 +53,20 @@ public void RunRandomEvent() /// /// Randomly runs an event from provided EntitySpawnCollection. /// - public void RunRandomEvent(List limitedEventsList) + public void RunRandomEvent(EntityTableSelector limitedEventsList) { var availableEvents = AvailableEvents(); // handles the player counts and individual event restrictions - if (availableEvents.Count == 0) - { - Log.Warning("No events were available to run!"); - return; - } + //if (availableEvents.Count == 0) // Yell at me if I dont uncomment this. + //{ + // Log.Warning("No events were available to run!"); + // return; + //} - var selectedEvents = EntitySpawnCollection.GetSpawns(limitedEventsList, _random); // storage function for game rules, smh my head. - // fuck it though, it works and gives us all the random selection utility we want. + var selectedEvents = _entityTable.GetSpawns(limitedEventsList); - Log.Info($"Picking from {limitedEventsList.Count} subsetted events"); + if (selectedEvents.Any() != true) // This is here so if you fuck up the table it wont die. + return; var limitedEvents = new Dictionary(); foreach (var eventid in selectedEvents) @@ -77,14 +77,17 @@ public void RunRandomEvent(List limitedEventsList) continue; } + if (limitedEvents.ContainsKey(eventproto)) // This stops it from dying if you add duplicate entries in a fucked table + continue; + if (eventproto.Abstract) continue; if (!eventproto.TryGetComponent(out var stationEvent, EntityManager.ComponentFactory)) continue; - if (!availableEvents.ContainsKey(eventproto)) - continue; + //if (!availableEvents.ContainsKey(eventproto)) // Yell at me if I dont uncomment this. + // continue; limitedEvents.Add(eventproto, stationEvent); } diff --git a/Resources/Prototypes/GameRules/cargo_gifts.yml b/Resources/Prototypes/GameRules/cargo_gifts.yml index af921499d463..f4e4a5bf8fc6 100644 --- a/Resources/Prototypes/GameRules/cargo_gifts.yml +++ b/Resources/Prototypes/GameRules/cargo_gifts.yml @@ -1,30 +1,21 @@ -# Add your new event to this RandomRule if you want it to happen via the basic/ramping schedulers. -- type: entity - parent: BaseGameRule - id: RandomCargoGiftsRule - components: - - type: RandomRule - selectableGameRules: +# Tables -- Add your new event to this Table if you want it to happen via the basic/ramping schedulers. + +- type: entityTable + id: CargoGiftsTable + table: !type:GroupSelector # ~~we need to pass a list of rules, since rules have further restrictions to consider via StationEventComp~~ But we arent doing that shit yet, it picks a random one StationEventComp be damned. + children: - id: GiftsEngineering - orGroup: Gifts - id: GiftsFireProtection - orGroup: Gifts - id: GiftsJanitor - orGroup: Gifts - id: GiftsMedical - orGroup: Gifts - id: GiftsPizzaPartyLarge - orGroup: Gifts - id: GiftsPizzaPartySmall - orGroup: Gifts - id: GiftsSecurityGuns - orGroup: Gifts - id: GiftsSecurityRiot - orGroup: Gifts - id: GiftsSpacingSupplies - orGroup: Gifts - id: GiftsVendingRestock - orGroup: Gifts + +# Game Rules - type: entity id: CargoGiftsBase diff --git a/Resources/Prototypes/GameRules/events.yml b/Resources/Prototypes/GameRules/events.yml index fe9d6410d042..0bc51af61a58 100644 --- a/Resources/Prototypes/GameRules/events.yml +++ b/Resources/Prototypes/GameRules/events.yml @@ -1,3 +1,41 @@ +- type: entityTable + id: BasicCalmEventsTable + table: !type:AllSelector # we need to pass a list of rules, since rules have further restrictions to consider via StationEventComp + children: + - id: AnomalySpawn + - id: BluespaceArtifact + - id: BluespaceLocker + - id: BreakerFlip + - id: BureaucraticError + - id: ClericalError + - id: CockroachMigration + - id: GasLeak + - id: ImmovableRodSpawn + - id: IonStorm # its calm like 90% of the time smh + - id: KudzuGrowth + - id: MassHallucinations + - id: MimicVendorRule + - id: MouseMigration + - id: PowerGridCheck + - id: SlimesSpawn + - id: SolarFlare + - id: SpiderClownSpawn + - id: SpiderSpawn + - id: VentClog + +- type: entityTable + id: BasicAntagEventsTable + table: !type:AllSelector # we need to pass a list of rules, since rules have further restrictions to consider via StationEventComp + children: + - id: ClosetSkeleton + - id: DragonSpawn + - id: KingRatMigration + - id: NinjaSpawn + - id: RevenantSpawn + - id: SleeperAgents + - id: ZombieOutbreak + + - type: entity id: BaseStationEvent parent: BaseGameRule diff --git a/Resources/Prototypes/GameRules/roundstart.yml b/Resources/Prototypes/GameRules/roundstart.yml index 462926b54331..b94cf8ef2187 100644 --- a/Resources/Prototypes/GameRules/roundstart.yml +++ b/Resources/Prototypes/GameRules/roundstart.yml @@ -262,79 +262,62 @@ prototype: InitialInfected # event schedulers + +- type: entityTable + id: BasicGameRulesTable + table: !type:AllSelector # we need to pass a list of rules, since rules have further restrictions to consider via StationEventComp + children: + - !type:NestedSelector + tableId: BasicCalmEventsTable + - !type:NestedSelector + tableId: BasicAntagEventsTable + - !type:NestedSelector + tableId: CargoGiftsTable + - !type:NestedSelector + tableId: UnknownShuttlesTable + +- type: entityTable + id: SpaceTrafficControlTable + table: !type:AllSelector # we need to pass a list of rules, since rules have further restrictions to consider via StationEventComp + children: + - !type:NestedSelector + tableId: UnknownShuttlesFriendlyTable + - !type:NestedSelector + tableId: UnknownShuttlesFreelanceTable + - !type:NestedSelector + tableId: UnknownShuttlesHostileTable + - type: entity id: BasicStationEventScheduler parent: BaseGameRule components: - type: BasicStationEventScheduler - scheduledGameRules: - - id: AnomalySpawn - - id: BluespaceArtifact - - id: BluespaceLocker - - id: BreakerFlip - - id: BureaucraticError - - id: ClericalError - - id: ClosetSkeleton - - id: CockroachMigration - - id: DragonSpawn - - id: GasLeak - - id: ImmovableRodSpawn - - id: IonStorm - - id: KingRatMigration - - id: KudzuGrowth - - id: LoneOpsSpawn - - id: MassHallucinations - - id: MimicVendorRule - - id: MouseMigration - - id: NinjaSpawn - - id: PowerGridCheck - - id: RandomCargoGiftsRule - - id: RandomUnknownShuttleRule - - id: RevenantSpawn - - id: SleeperAgents - - id: SlimesSpawn - - id: SolarFlare - - id: SpiderClownSpawn - - id: SpiderSpawn - - id: VentClog - - id: ZombieOutbreak + scheduledGameRules: !type:NestedSelector + tableId: BasicGameRulesTable - type: entity id: RampingStationEventScheduler parent: BaseGameRule components: - type: RampingStationEventScheduler - scheduledGameRules: - - id: AnomalySpawn - - id: BluespaceArtifact - - id: BluespaceLocker - - id: BreakerFlip - - id: BureaucraticError - - id: ClericalError - - id: ClosetSkeleton - - id: CockroachMigration - - id: DragonSpawn - - id: GasLeak - - id: ImmovableRodSpawn - - id: IonStorm - - id: KingRatMigration - - id: KudzuGrowth - - id: LoneOpsSpawn - - id: MassHallucinations - - id: MimicVendorRule - - id: MouseMigration - - id: NinjaSpawn - - id: PowerGridCheck - - id: RandomCargoGiftsRule - - id: RandomUnknownShuttleRule - - id: RevenantSpawn - - id: SleeperAgents - - id: SlimesSpawn - - id: SolarFlare - - id: SpiderClownSpawn - - id: SpiderSpawn - - id: VentClog - - id: ZombieOutbreak + scheduledGameRules: !type:NestedSelector + tableId: BasicGameRulesTable + +- type: entity + id: SpaceTrafficControlEventScheduler # iff we make a selector for EntityTables that can respect StationEventComp restrictions, or somehow impliment them otherwise in said tables, + parent: BaseGameRule # we can remerge this with the other schedulers, but it will silently fail due to that limitation without a separate scheduler to balance atm. + components: + - type: BasicStationEventScheduler + scheduledGameRules: !type:NestedSelector + tableId: SpaceTrafficControlTable + +- type: entity + id: SpaceTrafficControlFriendlyEventScheduler + parent: BaseGameRule + components: + - type: BasicStationEventScheduler + scheduledGameRules: !type:NestedSelector + tableId: UnknownShuttlesFriendlyTable # variation passes - type: entity diff --git a/Resources/Prototypes/GameRules/unknown_shuttles.yml b/Resources/Prototypes/GameRules/unknown_shuttles.yml index 87b6ef3e6d74..ec0051690b4b 100644 --- a/Resources/Prototypes/GameRules/unknown_shuttles.yml +++ b/Resources/Prototypes/GameRules/unknown_shuttles.yml @@ -1,19 +1,27 @@ -# Add your new event to this RandomRule if you want it to happen via the basic/ramping schedulers. -- type: entity - parent: BaseGameRule - id: RandomUnknownShuttleRule - components: - - type: RandomRule - selectableGameRules: +# Shuttle Game Rule Tables -- If you dont add your rules to these they wont be used by the games schedulers. + +- type: entityTable + id: UnknownShuttlesFriendlyTable + table: !type:AllSelector # we need to pass a list of rules, since rules have further restrictions to consider via StationEventComp + children: - id: UnknownShuttleCargoLost - orGroup: Shuttles - id: UnknownShuttleTravelingCuisine - orGroup: Shuttles - id: UnknownShuttleDisasterEvacPod - prob: 1.2 - orGroup: Shuttles + - id: UnknownShuttleHonki + +- type: entityTable + id: UnknownShuttlesFreelanceTable + table: !type:AllSelector # we need to pass a list of rules, since rules have further restrictions to consider via StationEventComp + children: - id: UnknownShuttleSyndieEvacPod - orGroup: Shuttles + +- type: entityTable + id: UnknownShuttlesFriendlyTable + table: !type:AllSelector # we need to pass a list of rules, since rules have further restrictions to consider via StationEventComp + children: + - id: LoneOpsSpawn + +# Shuttle Game Rules - type: entity abstract: true diff --git a/Resources/Prototypes/game_presets.yml b/Resources/Prototypes/game_presets.yml index 3a3f07760b9a..e7f2656a42f9 100644 --- a/Resources/Prototypes/game_presets.yml +++ b/Resources/Prototypes/game_presets.yml @@ -8,6 +8,7 @@ rules: - RampingStationEventScheduler - GameRuleMeteorScheduler + - SpaceTrafficControlEventScheduler - BasicRoundstartVariation - type: gamePreset @@ -22,6 +23,8 @@ - Zombie - RampingStationEventScheduler - GameRuleMeteorScheduler + - SpaceTrafficControlEventScheduler + - BasicRoundstartVariation - type: gamePreset id: Extended @@ -34,6 +37,7 @@ rules: - BasicStationEventScheduler - GameRuleMeteorScheduler + - SpaceTrafficControlEventScheduler - BasicRoundstartVariation - type: gamePreset @@ -45,6 +49,7 @@ showInVote: false #4boring4vote description: greenshift-description rules: + - SpaceTrafficControlFriendlyEventScheduler - BasicRoundstartVariation - type: gamePreset @@ -68,6 +73,8 @@ rules: - BasicStationEventScheduler - GameRuleMeteorScheduler + - SpaceTrafficControlEventScheduler + - BasicRoundstartVariation - type: gamePreset id: SecretGreenshift #For Admin Use: Runs Greenshift but shows "Secret" in lobby. @@ -76,6 +83,9 @@ name: secret-title showInVote: false #Admin Use description: secret-description + rules: + - SpaceTrafficControlFriendlyEventScheduler + - BasicRoundstartVariation - type: gamePreset id: Sandbox @@ -92,6 +102,7 @@ id: Traitor alias: - traitor + - tator name: traitor-title description: traitor-description showInVote: false @@ -100,6 +111,7 @@ - SubGamemodesRule - BasicStationEventScheduler - GameRuleMeteorScheduler + - SpaceTrafficControlEventScheduler - BasicRoundstartVariation - type: gamePreset @@ -127,6 +139,7 @@ - SubGamemodesRule - BasicStationEventScheduler - GameRuleMeteorScheduler + - SpaceTrafficControlEventScheduler - BasicRoundstartVariation - type: gamePreset @@ -143,6 +156,7 @@ - SubGamemodesRule - BasicStationEventScheduler - GameRuleMeteorScheduler + - SpaceTrafficControlEventScheduler - BasicRoundstartVariation - type: gamePreset @@ -160,4 +174,5 @@ - Zombie - BasicStationEventScheduler - GameRuleMeteorScheduler + - SpaceTrafficControlEventScheduler - BasicRoundstartVariation From 9a5034879500a0e581f3e2b4f1e14e8733a4edd1 Mon Sep 17 00:00:00 2001 From: Avery Dobbins Date: Mon, 12 Aug 2024 23:25:06 -0400 Subject: [PATCH 22/37] Toolshed makes we want to drink depresso. --- .../GameTicking/Rules/RandomRuleSystem.cs | 3 +- .../BasicStationEventSchedulerSystem.cs | 67 ++++++++++++++----- .../BasicStationEventSchedulerComponent.cs | 11 +++ .../StationEvents/EventManagerSystem.cs | 53 ++++++++++----- 4 files changed, 98 insertions(+), 36 deletions(-) diff --git a/Content.Server/GameTicking/Rules/RandomRuleSystem.cs b/Content.Server/GameTicking/Rules/RandomRuleSystem.cs index 80dbd9781812..6ed0d1d10907 100644 --- a/Content.Server/GameTicking/Rules/RandomRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/RandomRuleSystem.cs @@ -12,13 +12,12 @@ namespace Content.Server.GameTicking.Rules; /// /// Entities spawned with this component will try to add gamerules from the provided EntitySpawnEntry list. -/// This can be used to subset gamerules for balance, or to do something else like add it to a prototype if you want ninjas to start with meteors etc. +/// This can be used to make events happen concurrently ex: if you want ninjas to start with meteors etc. /// public sealed class RandomRuleSystem : GameRuleSystem { [Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly IRobustRandom _random = default!; - [Dependency] private readonly IChatManager _chatManager = default!; [Dependency] private readonly EventManagerSystem _event = default!; protected override void Started(EntityUid uid, RandomRuleComponent component, GameRuleComponent gameRule, GameRuleStartedEvent args) diff --git a/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs b/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs index 655fbab4abe9..30a40d8bad0d 100644 --- a/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs +++ b/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs @@ -2,11 +2,12 @@ using Content.Server.Administration; using Content.Server.GameTicking; using Content.Server.GameTicking.Rules; -using Content.Server.GameTicking.Rules.Components; using Content.Server.StationEvents.Components; using Content.Shared.Administration; +using Content.Shared.EntityTable; using Content.Shared.GameTicking.Components; using JetBrains.Annotations; +using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Toolshed; using Robust.Shared.Utility; @@ -23,9 +24,6 @@ public sealed class BasicStationEventSchedulerSystem : GameRuleSystem private void ResetTimer(BasicStationEventSchedulerComponent component) { - component.TimeUntilNextEvent = _random.NextFloat(MinEventTime, MaxEventTime); + component.TimeUntilNextEvent = component.MinMaxEventTiming.Next(_random); } } @@ -70,7 +68,9 @@ private void ResetTimer(BasicStationEventSchedulerComponent component) public sealed class StationEventCommand : ToolshedCommand { private EventManagerSystem? _stationEvent; + private EntityTableSystem? _entityTable; private BasicStationEventSchedulerSystem? _basicScheduler; + private IComponentFactory? _compFac; private IRobustRandom? _random; /// @@ -88,10 +88,11 @@ public sealed class StationEventCommand : ToolshedCommand /// to even exist) so I think it's fine. /// [CommandImplementation("simulate")] - public IEnumerable<(string, float)> Simulate([CommandArgument] int rounds, [CommandArgument] int playerCount, [CommandArgument] float roundEndMean, [CommandArgument] float roundEndStdDev) + public IEnumerable<(string, float)> Simulate([CommandArgument] EntityPrototype eventScheduler, [CommandArgument] int rounds, [CommandArgument] int playerCount, [CommandArgument] float roundEndMean, [CommandArgument] float roundEndStdDev) { _stationEvent ??= GetSys(); - _basicScheduler ??= GetSys(); + _entityTable ??= GetSys(); + _compFac ??= IoCManager.Resolve(); _random ??= IoCManager.Resolve(); var occurrences = new Dictionary(); @@ -101,6 +102,13 @@ public sealed class StationEventCommand : ToolshedCommand occurrences.Add(ev.Key.ID, 0); } + if (!eventScheduler.TryGetComponent(out var basicScheduler, _compFac)) + { + return occurrences.Select(p => (p.Key, (float)p.Value)).OrderByDescending(p => p.Item2); + } + + var compMinMax = basicScheduler.MinMaxEventTiming; // we gotta do this since we cant execute on comp w/o an ent. + for (var i = 0; i < rounds; i++) { var curTime = TimeSpan.Zero; @@ -111,9 +119,16 @@ public sealed class StationEventCommand : ToolshedCommand while (curTime.TotalSeconds < randomEndTime) { // sim an event - curTime += TimeSpan.FromSeconds(_random.NextFloat(BasicStationEventSchedulerSystem.MinEventTime, BasicStationEventSchedulerSystem.MaxEventTime)); + curTime += TimeSpan.FromSeconds(compMinMax.Next(_random)); + + if (!_stationEvent.TryBuildLimitedEvents(basicScheduler.ScheduledGameRules, out var selectedEvents)) + { + continue; // or whatever. return?? maybe should break. + } var available = _stationEvent.AvailableEvents(false, playerCount, curTime); - var ev = _stationEvent.FindEvent(available); + var plausibleEvents = new Dictionary(available.Intersect(selectedEvents)); // C# makes me sad + + var ev = _stationEvent.FindEvent(plausibleEvents); if (ev == null) continue; @@ -125,12 +140,18 @@ public sealed class StationEventCommand : ToolshedCommand } [CommandImplementation("lsprob")] - public IEnumerable<(string, float)> LsProb() + public IEnumerable<(string, float)> LsProb([CommandArgument] EntityPrototype eventScheduler) { + _compFac ??= IoCManager.Resolve(); _stationEvent ??= GetSys(); - var events = _stationEvent.AllEvents(); - var totalWeight = events.Sum(x => x.Value.Weight); + if (!eventScheduler.TryGetComponent(out var basicScheduler, _compFac)) + yield break; + + if (!_stationEvent.TryBuildLimitedEvents(basicScheduler.ScheduledGameRules, out var events)) + yield break; + + var totalWeight = events.Sum(x => x.Value.Weight); // Well this shit definitely isnt correct now, and I see no way to make it correct. foreach (var (proto, comp) in events) { @@ -139,10 +160,18 @@ public sealed class StationEventCommand : ToolshedCommand } [CommandImplementation("lsprobtime")] - public IEnumerable<(string, float)> LsProbTime([CommandArgument] float time) + public IEnumerable<(string, float)> LsProbTime([CommandArgument] EntityPrototype eventScheduler, [CommandArgument] float time) { + _compFac ??= IoCManager.Resolve(); _stationEvent ??= GetSys(); - var events = _stationEvent.AllEvents().Where(pair => pair.Value.EarliestStart <= time).ToList(); + + if (!eventScheduler.TryGetComponent(out var basicScheduler, _compFac)) + yield break; + + if (!_stationEvent.TryBuildLimitedEvents(basicScheduler.ScheduledGameRules, out var untimedEvents)) + yield break; + + var events = untimedEvents.Where(pair => pair.Value.EarliestStart <= time).ToList(); var totalWeight = events.Sum(x => x.Value.Weight); @@ -153,10 +182,16 @@ public sealed class StationEventCommand : ToolshedCommand } [CommandImplementation("prob")] - public float Prob([CommandArgument] string eventId) + public float Prob([CommandArgument] EntityPrototype eventScheduler, [CommandArgument] string eventId) { + _compFac ??= IoCManager.Resolve(); _stationEvent ??= GetSys(); - var events = _stationEvent.AllEvents(); + + if (!eventScheduler.TryGetComponent(out var basicScheduler, _compFac)) + return 0f; + + if (!_stationEvent.TryBuildLimitedEvents(basicScheduler.ScheduledGameRules, out var events)) + return 0f; var totalWeight = events.Sum(x => x.Value.Weight); var weight = 0f; diff --git a/Content.Server/StationEvents/Components/BasicStationEventSchedulerComponent.cs b/Content.Server/StationEvents/Components/BasicStationEventSchedulerComponent.cs index de9aeb41ac60..60c684d6245f 100644 --- a/Content.Server/StationEvents/Components/BasicStationEventSchedulerComponent.cs +++ b/Content.Server/StationEvents/Components/BasicStationEventSchedulerComponent.cs @@ -1,12 +1,23 @@ +using Content.Shared.Destructible.Thresholds; using Content.Shared.EntityTable.EntitySelectors; + namespace Content.Server.StationEvents.Components; [RegisterComponent, Access(typeof(BasicStationEventSchedulerSystem))] public sealed partial class BasicStationEventSchedulerComponent : Component { + /// + /// How long the the scheduler waits to begin starting rules. + /// public const float MinimumTimeUntilFirstEvent = 30;//300; // Yell at me if I dont change this back. + /// + /// The minimum and maximum time between rule starts in seconds. + /// + [DataField] + public MinMax MinMaxEventTiming = new(3 * 60, 10 * 60); + /// /// How long until the next check for an event runs /// diff --git a/Content.Server/StationEvents/EventManagerSystem.cs b/Content.Server/StationEvents/EventManagerSystem.cs index ce9d162baf9e..55d2144c8470 100644 --- a/Content.Server/StationEvents/EventManagerSystem.cs +++ b/Content.Server/StationEvents/EventManagerSystem.cs @@ -53,7 +53,7 @@ public void RunRandomEvent() /// /// Randomly runs an event from provided EntitySpawnCollection. /// - public void RunRandomEvent(EntityTableSelector limitedEventsList) + public void RunRandomEvent(EntityTableSelector limitedEventsTable) { var availableEvents = AvailableEvents(); // handles the player counts and individual event restrictions @@ -63,12 +63,40 @@ public void RunRandomEvent(EntityTableSelector limitedEventsList) // return; //} - var selectedEvents = _entityTable.GetSpawns(limitedEventsList); + if (!TryBuildLimitedEvents(limitedEventsTable, out var limitedEvents)) + { + Log.Warning("Provided event table could not build dict!"); + return; + } - if (selectedEvents.Any() != true) // This is here so if you fuck up the table it wont die. + var randomLimitedEvent = FindEvent(limitedEvents); // this picks the event, It might be better to use the GetSpawns to do it, but that will be a major rebalancing fuck. + if (randomLimitedEvent == null) + { + Log.Warning("The selected random event is null!"); return; + } + + if (!_prototype.TryIndex(randomLimitedEvent, out _)) + { + Log.Warning("A requested event is not available!"); + return; + } + + GameTicker.AddGameRule(randomLimitedEvent); + } + + /// + /// Returns true if the provided EntityTableSelector gives at least one prototype with a StationEvent comp. + /// + public bool TryBuildLimitedEvents(EntityTableSelector limitedEventsTable, out Dictionary limitedEvents) + { + limitedEvents = new Dictionary(); + + var selectedEvents = _entityTable.GetSpawns(limitedEventsTable); + + if (selectedEvents.Any() != true) // This is here so if you fuck up the table it wont die. + return false; - var limitedEvents = new Dictionary(); foreach (var eventid in selectedEvents) { if (!_prototype.TryIndex(eventid, out var eventproto)) @@ -92,23 +120,12 @@ public void RunRandomEvent(EntityTableSelector limitedEventsList) limitedEvents.Add(eventproto, stationEvent); } - var randomLimitedEvent = FindEvent(limitedEvents); // this picks the event, It might be better to use the GetSpawns to do it, but that will be a major rebalancing fuck. - if (randomLimitedEvent == null) - { - Log.Warning("The selected random event is null!"); - return; - } - - if (!_prototype.TryIndex(randomLimitedEvent, out _)) - { - Log.Warning("A requested event is not available!"); - return; - } + if (!limitedEvents.Any()) + return false; - GameTicker.AddGameRule(randomLimitedEvent); + return true; } - /// /// Randomly picks a valid event. /// From 83a0e268f7d03a205da4c8da6a1807611402c780 Mon Sep 17 00:00:00 2001 From: Avery Dobbins Date: Tue, 13 Aug 2024 03:10:12 -0400 Subject: [PATCH 23/37] Finished? --- .../Rules/Components/RandomRuleComponent.cs | 24 --- .../GameTicking/Rules/RandomRuleSystem.cs | 54 ------- .../BasicStationEventSchedulerSystem.cs | 12 +- .../BasicStationEventSchedulerComponent.cs | 10 +- .../Components/MeteorSchedulerComponent.cs | 24 --- .../RampingStationEventSchedulerComponent.cs | 22 ++- .../StationEvents/MeteorSchedulerSystem.cs | 54 ------- .../RampingStationEventSchedulerSystem.cs | 7 +- Content.Shared/CCVar/CCVars.cs | 26 --- .../game-presets/preset-allatonce.ftl | 3 + .../game-presets/preset-survival.ftl | 3 + .../game-presets/preset-zombies.ftl | 3 + Resources/Prototypes/GameRules/events.yml | 40 ----- .../Prototypes/GameRules/meteorswarms.yml | 153 +++++++++++++++--- .../Prototypes/GameRules/unknown_shuttles.yml | 2 +- Resources/Prototypes/game_presets.yml | 51 ++++++ Resources/Prototypes/secret_weights.yml | 6 +- 17 files changed, 234 insertions(+), 260 deletions(-) delete mode 100644 Content.Server/GameTicking/Rules/Components/RandomRuleComponent.cs delete mode 100644 Content.Server/GameTicking/Rules/RandomRuleSystem.cs delete mode 100644 Content.Server/StationEvents/Components/MeteorSchedulerComponent.cs delete mode 100644 Content.Server/StationEvents/MeteorSchedulerSystem.cs diff --git a/Content.Server/GameTicking/Rules/Components/RandomRuleComponent.cs b/Content.Server/GameTicking/Rules/Components/RandomRuleComponent.cs deleted file mode 100644 index 90527cceb9f1..000000000000 --- a/Content.Server/GameTicking/Rules/Components/RandomRuleComponent.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Content.Shared.Destructible.Thresholds; -using Content.Shared.Storage; - -namespace Content.Server.GameTicking.Rules.Components; - - -/// -/// Given a list of EntitySpawnEntries, selects between MinRules & MaxRules gamerules to add to the round without duplicates. -/// -[RegisterComponent, Access(typeof(RandomRuleSystem))] -public sealed partial class RandomRuleComponent : Component -{ - /// - /// The gamerules that get added at random. - /// - [DataField(required: true)] - public List SelectableGameRules = new(); - - /// - /// The minimum and maximum gamerules that get added at a time. - /// - [DataField] - public MinMax MinMaxRules = new(1, 1); -} diff --git a/Content.Server/GameTicking/Rules/RandomRuleSystem.cs b/Content.Server/GameTicking/Rules/RandomRuleSystem.cs deleted file mode 100644 index 6ed0d1d10907..000000000000 --- a/Content.Server/GameTicking/Rules/RandomRuleSystem.cs +++ /dev/null @@ -1,54 +0,0 @@ -using Content.Server.Chat.Managers; -using Content.Server.GameTicking.Rules.Components; -using Content.Server.StationEvents; -using Content.Shared.GameTicking.Components; -using Robust.Shared.Prototypes; -using Robust.Shared.Random; -using Content.Shared.Storage; -using System.Linq; - -namespace Content.Server.GameTicking.Rules; - - -/// -/// Entities spawned with this component will try to add gamerules from the provided EntitySpawnEntry list. -/// This can be used to make events happen concurrently ex: if you want ninjas to start with meteors etc. -/// -public sealed class RandomRuleSystem : GameRuleSystem -{ - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - [Dependency] private readonly IRobustRandom _random = default!; - [Dependency] private readonly EventManagerSystem _event = default!; - - protected override void Started(EntityUid uid, RandomRuleComponent component, GameRuleComponent gameRule, GameRuleStartedEvent args) - { - var selectedRules = EntitySpawnCollection.GetSpawns(component.SelectableGameRules, _random); - - int ruleQuant = component.MinMaxRules.Next(_random); - - if (selectedRules == null || selectedRules.Count == 0) - return; - - _random.Shuffle(selectedRules); - var nRules = selectedRules.Take(ruleQuant); // Does not allow duplicate selection, unless the EntitySpawnCollection had duplicate entries. - - var availableEvents = _event.AvailableEvents(); // handles the player counts and individual event restrictions, we need to do it each i incase it changes - - foreach (var rule in nRules) - { - if (!_prototypeManager.TryIndex(rule, out var ruleProto)) - { - Log.Warning("The selected random rule is missing a prototype!"); - continue; - } - - if (!availableEvents.ContainsKey(ruleProto)) - { - Log.Warning("The selected random rule is not available!"); - continue; - } - GameTicker.StartGameRule(rule); - } - } - -} diff --git a/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs b/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs index 30a40d8bad0d..963f22271b56 100644 --- a/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs +++ b/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs @@ -24,10 +24,17 @@ public sealed class BasicStationEventSchedulerSystem : GameRuleSystem(available.Intersect(selectedEvents)); // C# makes me sad diff --git a/Content.Server/StationEvents/Components/BasicStationEventSchedulerComponent.cs b/Content.Server/StationEvents/Components/BasicStationEventSchedulerComponent.cs index 60c684d6245f..e65070d590cf 100644 --- a/Content.Server/StationEvents/Components/BasicStationEventSchedulerComponent.cs +++ b/Content.Server/StationEvents/Components/BasicStationEventSchedulerComponent.cs @@ -10,7 +10,8 @@ public sealed partial class BasicStationEventSchedulerComponent : Component /// /// How long the the scheduler waits to begin starting rules. /// - public const float MinimumTimeUntilFirstEvent = 30;//300; // Yell at me if I dont change this back. + [DataField] + public int MinimumTimeUntilFirstEvent = 30;//200; // Yell at me if I dont change this back. /// /// The minimum and maximum time between rule starts in seconds. @@ -19,11 +20,10 @@ public sealed partial class BasicStationEventSchedulerComponent : Component public MinMax MinMaxEventTiming = new(3 * 60, 10 * 60); /// - /// How long until the next check for an event runs + /// How long until the next check for an event runs, is initially set based on MinimumTimeUntilFirstEvent & MinMaxEventTiming. /// - /// Default value is how long until first event is allowed - [ViewVariables(VVAccess.ReadWrite)] - public float TimeUntilNextEvent = MinimumTimeUntilFirstEvent; + [DataField] + public float TimeUntilNextEvent; /// /// The gamerules that the scheduler can choose from diff --git a/Content.Server/StationEvents/Components/MeteorSchedulerComponent.cs b/Content.Server/StationEvents/Components/MeteorSchedulerComponent.cs deleted file mode 100644 index 23337f9261ed..000000000000 --- a/Content.Server/StationEvents/Components/MeteorSchedulerComponent.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Content.Shared.Random; -using Robust.Shared.Prototypes; - -namespace Content.Server.StationEvents.Components; - -/// -/// This is used for running meteor swarm events at regular intervals. -/// -[RegisterComponent, Access(typeof(MeteorSchedulerSystem)), AutoGenerateComponentPause] -public sealed partial class MeteorSchedulerComponent : Component -{ - /// - /// The weights for which swarms will be selected. - /// - [DataField] - public ProtoId Config = "DefaultConfig"; - - /// - /// The time at which the next swarm occurs. - /// - [DataField, AutoPausedField] - public TimeSpan NextSwarmTime = TimeSpan.Zero; - -} diff --git a/Content.Server/StationEvents/Components/RampingStationEventSchedulerComponent.cs b/Content.Server/StationEvents/Components/RampingStationEventSchedulerComponent.cs index cf66189bc88c..16a1c4bd0af6 100644 --- a/Content.Server/StationEvents/Components/RampingStationEventSchedulerComponent.cs +++ b/Content.Server/StationEvents/Components/RampingStationEventSchedulerComponent.cs @@ -5,16 +5,30 @@ namespace Content.Server.StationEvents.Components; [RegisterComponent, Access(typeof(RampingStationEventSchedulerSystem))] public sealed partial class RampingStationEventSchedulerComponent : Component { - [DataField("endTime"), ViewVariables(VVAccess.ReadWrite)] + /// + /// Average ending chaos modifier for the ramping event scheduler. Higher means faster. + /// Max chaos chosen for a round will deviate from this + /// + [DataField] + public float AverageChaos = 6f; + + /// + /// Average time (in minutes) for when the ramping event scheduler should stop increasing the chaos modifier. + /// Close to how long you expect a round to last, so you'll probably have to tweak this on downstreams. + /// + [DataField] + public float AverageEndTime = 30f; + + [DataField] public float EndTime; - [DataField("maxChaos"), ViewVariables(VVAccess.ReadWrite)] + [DataField] public float MaxChaos; - [DataField("startingChaos"), ViewVariables(VVAccess.ReadWrite)] + [DataField] public float StartingChaos; - [DataField("timeUntilNextEvent"), ViewVariables(VVAccess.ReadWrite)] + [DataField] public float TimeUntilNextEvent; /// diff --git a/Content.Server/StationEvents/MeteorSchedulerSystem.cs b/Content.Server/StationEvents/MeteorSchedulerSystem.cs deleted file mode 100644 index c5162293603a..000000000000 --- a/Content.Server/StationEvents/MeteorSchedulerSystem.cs +++ /dev/null @@ -1,54 +0,0 @@ -using Content.Server.GameTicking.Rules; -using Content.Server.StationEvents.Components; -using Content.Shared.CCVar; -using Content.Shared.GameTicking.Components; -using Content.Shared.Random.Helpers; -using Robust.Shared.Configuration; -using Robust.Shared.Prototypes; - -namespace Content.Server.StationEvents; - -/// -/// This handles scheduling and launching meteors at a station at regular intervals. -/// TODO: there is 100% a world in which this is genericized and can be used for lots of basic event scheduling -/// -public sealed class MeteorSchedulerSystem : GameRuleSystem -{ - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - [Dependency] private readonly IConfigurationManager _cfg = default!; - - private TimeSpan _meteorMinDelay; - private TimeSpan _meteorMaxDelay; - - public override void Initialize() - { - base.Initialize(); - - _cfg.OnValueChanged(CCVars.MeteorSwarmMinTime, f => { _meteorMinDelay = TimeSpan.FromMinutes(f); }, true); - _cfg.OnValueChanged(CCVars.MeteorSwarmMaxTime, f => { _meteorMaxDelay = TimeSpan.FromMinutes(f); }, true); - } - - protected override void Started(EntityUid uid, MeteorSchedulerComponent component, GameRuleComponent gameRule, GameRuleStartedEvent args) - { - base.Started(uid, component, gameRule, args); - - component.NextSwarmTime = Timing.CurTime + RobustRandom.Next(_meteorMinDelay, _meteorMaxDelay); - } - - protected override void ActiveTick(EntityUid uid, MeteorSchedulerComponent component, GameRuleComponent gameRule, float frameTime) - { - base.ActiveTick(uid, component, gameRule, frameTime); - - if (Timing.CurTime < component.NextSwarmTime) - return; - RunSwarm((uid, component)); - - component.NextSwarmTime += RobustRandom.Next(_meteorMinDelay, _meteorMaxDelay); - } - - private void RunSwarm(Entity ent) - { - var swarmWeights = _prototypeManager.Index(ent.Comp.Config); - GameTicker.StartGameRule(swarmWeights.Pick(RobustRandom)); - } -} diff --git a/Content.Server/StationEvents/RampingStationEventSchedulerSystem.cs b/Content.Server/StationEvents/RampingStationEventSchedulerSystem.cs index 5840fb542494..1973467545b6 100644 --- a/Content.Server/StationEvents/RampingStationEventSchedulerSystem.cs +++ b/Content.Server/StationEvents/RampingStationEventSchedulerSystem.cs @@ -30,14 +30,11 @@ protected override void Started(EntityUid uid, RampingStationEventSchedulerCompo { base.Started(uid, component, gameRule, args); - var avgChaos = _cfg.GetCVar(CCVars.EventsRampingAverageChaos); - var avgTime = _cfg.GetCVar(CCVars.EventsRampingAverageEndTime); - // Worlds shittiest probability distribution // Got a complaint? Send them to - component.MaxChaos = _random.NextFloat(avgChaos - avgChaos / 4, avgChaos + avgChaos / 4); + component.MaxChaos = _random.NextFloat(component.AverageChaos - component.AverageChaos / 4, component.AverageChaos + component.AverageChaos / 4); // This is in minutes, so *60 for seconds (for the chaos calc) - component.EndTime = _random.NextFloat(avgTime - avgTime / 4, avgTime + avgTime / 4) * 60f; + component.EndTime = _random.NextFloat(component.AverageEndTime - component.AverageEndTime / 4, component.AverageEndTime + component.AverageEndTime / 4) * 60f; component.StartingChaos = component.MaxChaos / 10; PickNextEventTime(uid, component); diff --git a/Content.Shared/CCVar/CCVars.cs b/Content.Shared/CCVar/CCVars.cs index 3049df28aeb2..adad4e6b00c3 100644 --- a/Content.Shared/CCVar/CCVars.cs +++ b/Content.Shared/CCVar/CCVars.cs @@ -110,32 +110,6 @@ public sealed class CCVars : CVars public static readonly CVarDef EventsEnabled = CVarDef.Create("events.enabled", true, CVar.ARCHIVE | CVar.SERVERONLY); - /// - /// Average time (in minutes) for when the ramping event scheduler should stop increasing the chaos modifier. - /// Close to how long you expect a round to last, so you'll probably have to tweak this on downstreams. - /// - public static readonly CVarDef - EventsRampingAverageEndTime = CVarDef.Create("events.ramping_average_end_time", 40f, CVar.ARCHIVE | CVar.SERVERONLY); - - /// - /// Average ending chaos modifier for the ramping event scheduler. - /// Max chaos chosen for a round will deviate from this - /// - public static readonly CVarDef - EventsRampingAverageChaos = CVarDef.Create("events.ramping_average_chaos", 6f, CVar.ARCHIVE | CVar.SERVERONLY); - - /// - /// Minimum time between meteor swarms in minutes. - /// - public static readonly CVarDef - MeteorSwarmMinTime = CVarDef.Create("events.meteor_swarm_min_time", 12.5f, CVar.ARCHIVE | CVar.SERVERONLY); - - /// - /// Maximum time between meteor swarms in minutes. - /// - public static readonly CVarDef - MeteorSwarmMaxTime = CVarDef.Create("events.meteor_swarm_max_time", 17.5f, CVar.ARCHIVE | CVar.SERVERONLY); - /* * Game */ diff --git a/Resources/Locale/en-US/game-ticking/game-presets/preset-allatonce.ftl b/Resources/Locale/en-US/game-ticking/game-presets/preset-allatonce.ftl index 3452b2faa969..ba4f62c4ca0a 100644 --- a/Resources/Locale/en-US/game-ticking/game-presets/preset-allatonce.ftl +++ b/Resources/Locale/en-US/game-ticking/game-presets/preset-allatonce.ftl @@ -1,2 +1,5 @@ all-at-once-title = All at once all-at-once-description = It's just not your day... + +aller-at-once-title = Aller at once +aller-at-once-description = You have fucked up now. You *have* fucked up now. \ No newline at end of file diff --git a/Resources/Locale/en-US/game-ticking/game-presets/preset-survival.ftl b/Resources/Locale/en-US/game-ticking/game-presets/preset-survival.ftl index 231733eabfb4..492bb9e34105 100644 --- a/Resources/Locale/en-US/game-ticking/game-presets/preset-survival.ftl +++ b/Resources/Locale/en-US/game-ticking/game-presets/preset-survival.ftl @@ -1,2 +1,5 @@ survival-title = Survival survival-description = No internal threats, but how long can the station survive increasingly chaotic and frequent events? + +kessler-syndrome-title = Kessler Syndrome +kessler-syndrome-description = No internal threats, but the station is quickly falling into a belt of meteors! \ No newline at end of file diff --git a/Resources/Locale/en-US/game-ticking/game-presets/preset-zombies.ftl b/Resources/Locale/en-US/game-ticking/game-presets/preset-zombies.ftl index efb5c6ef1e19..4d127d9fa535 100644 --- a/Resources/Locale/en-US/game-ticking/game-presets/preset-zombies.ftl +++ b/Resources/Locale/en-US/game-ticking/game-presets/preset-zombies.ftl @@ -1,6 +1,9 @@ zombie-title = Zombies zombie-description = The undead have been unleashed on the station! Work with the crew to survive the outbreak and secure the station. +zombieteors-title = Zombieteors +zombieteors-description = The undead have been unleashed on the station amid a cataclysmic meteor shower! Work with your fellow crew and do your best to survive! + zombie-not-enough-ready-players = Not enough players readied up for the game! There were {$readyPlayersCount} players readied up out of {$minimumPlayers} needed. Can't start Zombies. zombie-no-one-ready = No players readied up! Can't start Zombies. diff --git a/Resources/Prototypes/GameRules/events.yml b/Resources/Prototypes/GameRules/events.yml index 0bc51af61a58..56ffeda7f035 100644 --- a/Resources/Prototypes/GameRules/events.yml +++ b/Resources/Prototypes/GameRules/events.yml @@ -10,7 +10,6 @@ - id: ClericalError - id: CockroachMigration - id: GasLeak - - id: ImmovableRodSpawn - id: IonStorm # its calm like 90% of the time smh - id: KudzuGrowth - id: MassHallucinations @@ -564,45 +563,6 @@ sounds: collection: Paracusia -- type: entity - id: ImmovableRodSpawn - parent: BaseGameRule - components: - - type: StationEvent - startAnnouncement: station-event-immovable-rod-start-announcement - startAudio: - path: /Audio/Announcements/attention.ogg - weight: 3.5 - duration: 1 - earliestStart: 30 - minimumPlayers: 20 - - type: ImmovableRodRule - rodPrototypes: - - id: ImmovableRodKeepTilesStill - prob: 0.95 - orGroup: rodProto - - id: ImmovableRodMop - prob: 0.0072 - orGroup: rodProto - - id: ImmovableRodShark - prob: 0.0072 - orGroup: rodProto - - id: ImmovableRodClown - prob: 0.0072 - orGroup: rodProto - - id: ImmovableRodBanana - prob: 0.0072 - orGroup: rodProto - - id: ImmovableRodHammer - prob: 0.0072 - orGroup: rodProto - - id: ImmovableRodThrongler - prob: 0.0072 - orGroup: rodProto - - id: ImmovableRodGibstick - prob: 0.0072 - orGroup: rodProto - - type: entity parent: BaseGameRule id: IonStorm diff --git a/Resources/Prototypes/GameRules/meteorswarms.yml b/Resources/Prototypes/GameRules/meteorswarms.yml index 2f1cb4eba5ed..82fae5b356e6 100644 --- a/Resources/Prototypes/GameRules/meteorswarms.yml +++ b/Resources/Prototypes/GameRules/meteorswarms.yml @@ -1,21 +1,39 @@ -- type: entity - parent: BaseGameRule - id: GameRuleMeteorScheduler - components: - - type: GameRule - minPlayers: 25 - cancelPresetOnTooFewPlayers: false - - type: MeteorScheduler +# Event Tables -- type: weightedRandomEntity - id: DefaultConfig - weights: - GameRuleSpaceDustMinor: 44 - GameRuleSpaceDustMajor: 22 - GameRuleMeteorSwarmSmall: 18 - GameRuleMeteorSwarmMedium: 10 - GameRuleMeteorSwarmLarge: 5 - GameRuleUristSwarm: 0.05 +- type: entityTable + id: MeteorSwarmDustEventsTable + table: !type:AllSelector # we need to pass a list of rules, since rules have further restrictions to consider via StationEventComp + children: + - id: GameRuleSpaceDustMinor + - id: GameRuleSpaceDustMajor + +- type: entityTable + id: MeteorSwarmSmallChanceEventsTable + table: !type:AllSelector # we need to pass a list of rules, since rules have further restrictions to consider via StationEventComp + children: + - id: GameRuleMeteorSwarmSmall + prob: 0.15 + +- type: entityTable + id: MeteorSwarmMildTable + table: !type:AllSelector # we need to pass a list of rules, since rules have further restrictions to consider via StationEventComp + children: + - !type:NestedSelector + tableId: MeteorSwarmDustEventsTable + - !type:NestedSelector + tableId: MeteorSwarmSmallChanceEventsTable + +- type: entityTable + id: BasicMeteorSwarmEventsTable + table: !type:AllSelector # we need to pass a list of rules, since rules have further restrictions to consider via StationEventComp + children: + - !type:NestedSelector + tableId: MeteorSwarmDustEventsTable + - id: GameRuleMeteorSwarmSmall + - id: GameRuleMeteorSwarmMedium + - id: GameRuleMeteorSwarmLarge + - id: GameRuleUristSwarm + - id: ImmovableRodSpawn - type: weightedRandomEntity id: MeteorSpawnAsteroidWallTable @@ -29,7 +47,48 @@ AsteroidRockPlasma: 2 AsteroidRockDiamond: 2 AsteroidRockUranium: 0.5 - AsteroidRockBananium: 0.5 + AsteroidRockBananium: 0.5 + +# Event Schedulers + +- type: entity + parent: BaseGameRule + id: MeteorSwarmScheduler + components: + - type: GameRule + - type: BasicStationEventScheduler + minimumTimeUntilFirstEvent: 35 # 300 # 5 min # Yell at me if I dont fix this back to 300 + minMaxEventTiming: + min: 750 # 12.5 min + max: 930 # 17.5 min + scheduledGameRules: !type:NestedSelector + tableId: BasicMeteorSwarmEventsTable + +- type: entity + parent: BaseGameRule + id: MeteorSwarmMildScheduler + components: + - type: GameRule + - type: BasicStationEventScheduler + minimumTimeUntilFirstEvent: 35 # 300 # 5 min # Yell at me if I dont fix this back to 300 + minMaxEventTiming: + min: 750 # 12.5 min + max: 930 # 17.5 min + scheduledGameRules: !type:NestedSelector + tableId: MeteorSwarmMildTable + +- type: entity + parent: BaseGameRule + id: KesslerSyndromeScheduler + components: + - type: GameRule + - type: RampingStationEventScheduler + minimumTimeUntilFirstEvent: + minMaxEventTiming: + scheduledGameRules: !type:NestedSelector + tableId: BasicMeteorSwarmEventsTable + +# Game Rules - type: entity parent: BaseGameRule @@ -37,12 +96,19 @@ abstract: true components: - type: GameRule + - type: StationEvent + earliestStart: 12 + minimumPlayers: 25 - type: MeteorSwarm - type: entity parent: GameRuleMeteorSwarm id: GameRuleSpaceDustMinor components: + - type: StationEvent + weight: 44 + earliestStart: 2 + minimumPlayers: 0 - type: MeteorSwarm announcement: null announcementSound: null @@ -60,6 +126,9 @@ parent: GameRuleMeteorSwarm id: GameRuleSpaceDustMajor components: + - type: StationEvent + weight: 22 + minimumPlayers: 0 - type: MeteorSwarm announcement: station-event-space-dust-start-announcement announcementSound: /Audio/Announcements/attention.ogg @@ -77,6 +146,9 @@ parent: GameRuleMeteorSwarm id: GameRuleMeteorSwarmSmall components: + - type: StationEvent + weight: 18 + minimumPlayers: 15 - type: MeteorSwarm meteors: MeteorSmall: 7 @@ -86,6 +158,8 @@ parent: GameRuleMeteorSwarm id: GameRuleMeteorSwarmMedium components: + - type: StationEvent + weight: 10 - type: MeteorSwarm meteors: MeteorSmall: 3 @@ -96,6 +170,8 @@ parent: GameRuleMeteorSwarm id: GameRuleMeteorSwarmLarge components: + - type: StationEvent + weight: 5 - type: MeteorSwarm meteors: MeteorSmall: 2 @@ -106,6 +182,8 @@ parent: GameRuleMeteorSwarm id: GameRuleUristSwarm components: + - type: StationEvent + weight: 0.05 - type: MeteorSwarm announcement: station-event-meteor-urist-start-announcement announcementSound: /Audio/Announcements/attention.ogg @@ -117,3 +195,42 @@ meteorsPerWave: min: 10 max: 10 + +- type: entity + id: ImmovableRodSpawn + parent: BaseGameRule + components: + - type: StationEvent + startAnnouncement: station-event-immovable-rod-start-announcement + startAudio: + path: /Audio/Announcements/attention.ogg + weight: 3.5 + duration: 1 + earliestStart: 30 + minimumPlayers: 25 + - type: ImmovableRodRule + rodPrototypes: + - id: ImmovableRodKeepTilesStill + prob: 0.95 + orGroup: rodProto + - id: ImmovableRodMop + prob: 0.0072 + orGroup: rodProto + - id: ImmovableRodShark + prob: 0.0072 + orGroup: rodProto + - id: ImmovableRodClown + prob: 0.0072 + orGroup: rodProto + - id: ImmovableRodBanana + prob: 0.0072 + orGroup: rodProto + - id: ImmovableRodHammer + prob: 0.0072 + orGroup: rodProto + - id: ImmovableRodThrongler + prob: 0.0072 + orGroup: rodProto + - id: ImmovableRodGibstick + prob: 0.0072 + orGroup: rodProto diff --git a/Resources/Prototypes/GameRules/unknown_shuttles.yml b/Resources/Prototypes/GameRules/unknown_shuttles.yml index ec0051690b4b..3f707fd57e1f 100644 --- a/Resources/Prototypes/GameRules/unknown_shuttles.yml +++ b/Resources/Prototypes/GameRules/unknown_shuttles.yml @@ -16,7 +16,7 @@ - id: UnknownShuttleSyndieEvacPod - type: entityTable - id: UnknownShuttlesFriendlyTable + id: UnknownShuttlesHostileTable table: !type:AllSelector # we need to pass a list of rules, since rules have further restrictions to consider via StationEventComp children: - id: LoneOpsSpawn diff --git a/Resources/Prototypes/game_presets.yml b/Resources/Prototypes/game_presets.yml index e7f2656a42f9..ab67c122281a 100644 --- a/Resources/Prototypes/game_presets.yml +++ b/Resources/Prototypes/game_presets.yml @@ -9,6 +9,22 @@ - RampingStationEventScheduler - GameRuleMeteorScheduler - SpaceTrafficControlEventScheduler + - SpaceTrafficControlFriendlyEventScheduler + - BasicRoundstartVariation + +- type: gamePreset + id: KesslerSyndrome + alias: + - kessler + - junk + - meteorhell + name: kessler-syndrome-title + showInVote: false # secret + description: kessler-syndrome-description + rules: + - RampingStationEventScheduler + - KesslerSyndromeScheduler + - SpaceTrafficControlEventScheduler - BasicRoundstartVariation - type: gamePreset @@ -22,7 +38,26 @@ - Revolutionary - Zombie - RampingStationEventScheduler + - KesslerSyndromeScheduler + - SpaceTrafficControlEventScheduler + - BasicRoundstartVariation + +- type: gamePreset + id: AllerAtOnce + name: aller-at-once-title + description: all-at-once-description + showInVote: false #Please god dont do this + rules: + - Nukeops + - Traitor + - Revolutionary + - Zombie + - BasicStationEventScheduler + - RampingStationEventScheduler + - MeteorSwarmMildScheduler - GameRuleMeteorScheduler + - KesslerSyndromeScheduler + - SpaceTrafficControlFriendlyEventScheduler - SpaceTrafficControlEventScheduler - BasicRoundstartVariation @@ -176,3 +211,19 @@ - GameRuleMeteorScheduler - SpaceTrafficControlEventScheduler - BasicRoundstartVariation + +- type: gamePreset + id: Zombieteors + alias: + - zombieteors + - zombombies + - meteombies + name: zombieteors-title + description: zombieteors-description + showInVote: false + rules: + - Zombie + - BasicStationEventScheduler + - KesslerSyndromeScheduler + - SpaceTrafficControlEventScheduler + - BasicRoundstartVariation diff --git a/Resources/Prototypes/secret_weights.yml b/Resources/Prototypes/secret_weights.yml index 7af610af6c7d..0a272e24c7c0 100644 --- a/Resources/Prototypes/secret_weights.yml +++ b/Resources/Prototypes/secret_weights.yml @@ -3,6 +3,8 @@ weights: Nukeops: 0.20 Traitor: 0.60 - Zombie: 0.05 - Survival: 0.10 + Zombie: 0.04 + Zombieteors: 0.01 + Survival: 0.09 + KesslerSyndrome: 0.01 Revolutionary: 0.05 From 047b8fa1811bf9f99797244bce197a5600367ee4 Mon Sep 17 00:00:00 2001 From: Avery Dobbins Date: Tue, 13 Aug 2024 03:19:29 -0400 Subject: [PATCH 24/37] remove debug values --- .../BasicStationEventSchedulerSystem.cs | 2 +- .../BasicStationEventSchedulerComponent.cs | 2 +- .../StationEvents/EventManagerSystem.cs | 20 +++++++++---------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs b/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs index 963f22271b56..fdb1ad6a9f24 100644 --- a/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs +++ b/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs @@ -129,7 +129,7 @@ public sealed class StationEventCommand : ToolshedCommand if (!_stationEvent.TryBuildLimitedEvents(basicScheduler.ScheduledGameRules, out var selectedEvents)) { - break; // shits fucked yo. + continue; // doesnt break because maybe the time is preventing events being available. } var available = _stationEvent.AvailableEvents(false, playerCount, curTime); var plausibleEvents = new Dictionary(available.Intersect(selectedEvents)); // C# makes me sad diff --git a/Content.Server/StationEvents/Components/BasicStationEventSchedulerComponent.cs b/Content.Server/StationEvents/Components/BasicStationEventSchedulerComponent.cs index e65070d590cf..47c76c1456cc 100644 --- a/Content.Server/StationEvents/Components/BasicStationEventSchedulerComponent.cs +++ b/Content.Server/StationEvents/Components/BasicStationEventSchedulerComponent.cs @@ -11,7 +11,7 @@ public sealed partial class BasicStationEventSchedulerComponent : Component /// How long the the scheduler waits to begin starting rules. /// [DataField] - public int MinimumTimeUntilFirstEvent = 30;//200; // Yell at me if I dont change this back. + public int MinimumTimeUntilFirstEvent = 200; /// /// The minimum and maximum time between rule starts in seconds. diff --git a/Content.Server/StationEvents/EventManagerSystem.cs b/Content.Server/StationEvents/EventManagerSystem.cs index 55d2144c8470..35038438baf8 100644 --- a/Content.Server/StationEvents/EventManagerSystem.cs +++ b/Content.Server/StationEvents/EventManagerSystem.cs @@ -55,14 +55,6 @@ public void RunRandomEvent() /// public void RunRandomEvent(EntityTableSelector limitedEventsTable) { - var availableEvents = AvailableEvents(); // handles the player counts and individual event restrictions - - //if (availableEvents.Count == 0) // Yell at me if I dont uncomment this. - //{ - // Log.Warning("No events were available to run!"); - // return; - //} - if (!TryBuildLimitedEvents(limitedEventsTable, out var limitedEvents)) { Log.Warning("Provided event table could not build dict!"); @@ -92,6 +84,14 @@ public bool TryBuildLimitedEvents(EntityTableSelector limitedEventsTable, out Di { limitedEvents = new Dictionary(); + var availableEvents = AvailableEvents(); // handles the player counts and individual event restrictions + + if (availableEvents.Count == 0) + { + Log.Warning("No events were available to run!"); + return false; + } + var selectedEvents = _entityTable.GetSpawns(limitedEventsTable); if (selectedEvents.Any() != true) // This is here so if you fuck up the table it wont die. @@ -114,8 +114,8 @@ public bool TryBuildLimitedEvents(EntityTableSelector limitedEventsTable, out Di if (!eventproto.TryGetComponent(out var stationEvent, EntityManager.ComponentFactory)) continue; - //if (!availableEvents.ContainsKey(eventproto)) // Yell at me if I dont uncomment this. - // continue; + if (!availableEvents.ContainsKey(eventproto)) + continue; limitedEvents.Add(eventproto, stationEvent); } From 03aeec7bb7d80192fe21b0ea0f007282b1256510 Mon Sep 17 00:00:00 2001 From: Avery Dobbins Date: Tue, 13 Aug 2024 03:37:04 -0400 Subject: [PATCH 25/37] timings --- Resources/Prototypes/GameRules/roundstart.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Resources/Prototypes/GameRules/roundstart.yml b/Resources/Prototypes/GameRules/roundstart.yml index b94cf8ef2187..b31974836482 100644 --- a/Resources/Prototypes/GameRules/roundstart.yml +++ b/Resources/Prototypes/GameRules/roundstart.yml @@ -308,6 +308,10 @@ parent: BaseGameRule # we can remerge this with the other schedulers, but it will silently fail due to that limitation without a separate scheduler to balance atm. components: - type: BasicStationEventScheduler + minimumTimeUntilFirstEvent: 1200 # 20 mins + minMaxEventTiming: + min: 600 # 10 mins + max: 1800 # 30 mins scheduledGameRules: !type:NestedSelector tableId: SpaceTrafficControlTable @@ -316,6 +320,10 @@ parent: BaseGameRule components: - type: BasicStationEventScheduler + minimumTimeUntilFirstEvent: 1200 # 20 mins + minMaxEventTiming: + min: 600 # 10 mins + max: 1800 # 30 mins scheduledGameRules: !type:NestedSelector tableId: UnknownShuttlesFriendlyTable From 3779b7f51933683807cc9004653dcf796cc3546c Mon Sep 17 00:00:00 2001 From: Avery Dobbins Date: Tue, 13 Aug 2024 03:40:38 -0400 Subject: [PATCH 26/37] use defaults --- Resources/Prototypes/GameRules/meteorswarms.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/Resources/Prototypes/GameRules/meteorswarms.yml b/Resources/Prototypes/GameRules/meteorswarms.yml index 82fae5b356e6..e5d76b3d5473 100644 --- a/Resources/Prototypes/GameRules/meteorswarms.yml +++ b/Resources/Prototypes/GameRules/meteorswarms.yml @@ -83,8 +83,6 @@ components: - type: GameRule - type: RampingStationEventScheduler - minimumTimeUntilFirstEvent: - minMaxEventTiming: scheduledGameRules: !type:NestedSelector tableId: BasicMeteorSwarmEventsTable From 601ec247a6a362e58f3e63df3723eac108e9b8f8 Mon Sep 17 00:00:00 2001 From: Avery Dobbins Date: Tue, 13 Aug 2024 03:45:38 -0400 Subject: [PATCH 27/37] alphabetize --- Resources/Prototypes/game_presets.yml | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/Resources/Prototypes/game_presets.yml b/Resources/Prototypes/game_presets.yml index ab67c122281a..2586ae188bb6 100644 --- a/Resources/Prototypes/game_presets.yml +++ b/Resources/Prototypes/game_presets.yml @@ -6,8 +6,8 @@ showInVote: false # secret description: survival-description rules: + - MeteorSwarmScheduler - RampingStationEventScheduler - - GameRuleMeteorScheduler - SpaceTrafficControlEventScheduler - SpaceTrafficControlFriendlyEventScheduler - BasicRoundstartVariation @@ -22,8 +22,8 @@ showInVote: false # secret description: kessler-syndrome-description rules: - - RampingStationEventScheduler - KesslerSyndromeScheduler + - RampingStationEventScheduler - SpaceTrafficControlEventScheduler - BasicRoundstartVariation @@ -37,8 +37,8 @@ - Traitor - Revolutionary - Zombie - - RampingStationEventScheduler - KesslerSyndromeScheduler + - RampingStationEventScheduler - SpaceTrafficControlEventScheduler - BasicRoundstartVariation @@ -53,12 +53,12 @@ - Revolutionary - Zombie - BasicStationEventScheduler - - RampingStationEventScheduler - - MeteorSwarmMildScheduler - - GameRuleMeteorScheduler - KesslerSyndromeScheduler - - SpaceTrafficControlFriendlyEventScheduler + - MeteorSwarmMildScheduler + - MeteorSwarmScheduler + - RampingStationEventScheduler - SpaceTrafficControlEventScheduler + - SpaceTrafficControlFriendlyEventScheduler - BasicRoundstartVariation - type: gamePreset @@ -71,7 +71,7 @@ description: extended-description rules: - BasicStationEventScheduler - - GameRuleMeteorScheduler + - MeteorSwarmScheduler - SpaceTrafficControlEventScheduler - BasicRoundstartVariation @@ -107,7 +107,7 @@ description: secret-description rules: - BasicStationEventScheduler - - GameRuleMeteorScheduler + - MeteorSwarmScheduler - SpaceTrafficControlEventScheduler - BasicRoundstartVariation @@ -145,7 +145,7 @@ - Traitor - SubGamemodesRule - BasicStationEventScheduler - - GameRuleMeteorScheduler + - MeteorSwarmScheduler - SpaceTrafficControlEventScheduler - BasicRoundstartVariation @@ -173,7 +173,7 @@ - Nukeops - SubGamemodesRule - BasicStationEventScheduler - - GameRuleMeteorScheduler + - MeteorSwarmScheduler - SpaceTrafficControlEventScheduler - BasicRoundstartVariation @@ -190,7 +190,7 @@ - Revolutionary - SubGamemodesRule - BasicStationEventScheduler - - GameRuleMeteorScheduler + - MeteorSwarmScheduler - SpaceTrafficControlEventScheduler - BasicRoundstartVariation @@ -208,7 +208,7 @@ rules: - Zombie - BasicStationEventScheduler - - GameRuleMeteorScheduler + - MeteorSwarmScheduler - SpaceTrafficControlEventScheduler - BasicRoundstartVariation From 0f22edfb6fa4df8a5163ee4ff6ffd9bba5935519 Mon Sep 17 00:00:00 2001 From: Avery Dobbins Date: Tue, 13 Aug 2024 03:55:33 -0400 Subject: [PATCH 28/37] bobby drop tables --- Resources/Prototypes/GameRules/roundstart.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/Resources/Prototypes/GameRules/roundstart.yml b/Resources/Prototypes/GameRules/roundstart.yml index b31974836482..8ef0db965827 100644 --- a/Resources/Prototypes/GameRules/roundstart.yml +++ b/Resources/Prototypes/GameRules/roundstart.yml @@ -273,8 +273,6 @@ tableId: BasicAntagEventsTable - !type:NestedSelector tableId: CargoGiftsTable - - !type:NestedSelector - tableId: UnknownShuttlesTable - type: entityTable id: SpaceTrafficControlTable From 7e5cf246c90b853e3b13416c8a1ffcd24169399b Mon Sep 17 00:00:00 2001 From: Avery Dobbins Date: Tue, 13 Aug 2024 04:40:08 -0400 Subject: [PATCH 29/37] Float required fr fr --- .../StationEvents/BasicStationEventSchedulerSystem.cs | 2 +- .../Components/BasicStationEventSchedulerComponent.cs | 2 +- Resources/Prototypes/game_presets.yml | 7 +++++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs b/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs index fdb1ad6a9f24..e7b1dca54da3 100644 --- a/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs +++ b/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs @@ -28,7 +28,7 @@ protected override void Started(EntityUid uid, BasicStationEventSchedulerCompone GameRuleStartedEvent args) { // A little starting variance so schedulers dont all proc at once. - component.TimeUntilNextEvent = RobustRandom.Next(component.MinimumTimeUntilFirstEvent, component.MinimumTimeUntilFirstEvent + 120); + component.TimeUntilNextEvent = RobustRandom.NextFloat(component.MinimumTimeUntilFirstEvent, component.MinimumTimeUntilFirstEvent + 120); } protected override void Ended(EntityUid uid, BasicStationEventSchedulerComponent component, GameRuleComponent gameRule, diff --git a/Content.Server/StationEvents/Components/BasicStationEventSchedulerComponent.cs b/Content.Server/StationEvents/Components/BasicStationEventSchedulerComponent.cs index 47c76c1456cc..b777831856b2 100644 --- a/Content.Server/StationEvents/Components/BasicStationEventSchedulerComponent.cs +++ b/Content.Server/StationEvents/Components/BasicStationEventSchedulerComponent.cs @@ -11,7 +11,7 @@ public sealed partial class BasicStationEventSchedulerComponent : Component /// How long the the scheduler waits to begin starting rules. /// [DataField] - public int MinimumTimeUntilFirstEvent = 200; + public float MinimumTimeUntilFirstEvent = 200; /// /// The minimum and maximum time between rule starts in seconds. diff --git a/Resources/Prototypes/game_presets.yml b/Resources/Prototypes/game_presets.yml index 2586ae188bb6..efce3c4e24cc 100644 --- a/Resources/Prototypes/game_presets.yml +++ b/Resources/Prototypes/game_presets.yml @@ -29,6 +29,8 @@ - type: gamePreset id: AllAtOnce + alias: + - all name: all-at-once-title description: all-at-once-description showInVote: false @@ -44,6 +46,11 @@ - type: gamePreset id: AllerAtOnce + alias: + - allall + - aller + - badidea + - punishment name: aller-at-once-title description: all-at-once-description showInVote: false #Please god dont do this From 0897b66062913db2decc2f087737720280caee2f Mon Sep 17 00:00:00 2001 From: Avery Dobbins Date: Tue, 13 Aug 2024 04:52:54 -0400 Subject: [PATCH 30/37] continue --- .../StationEvents/BasicStationEventSchedulerSystem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs b/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs index e7b1dca54da3..d268f8e704b1 100644 --- a/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs +++ b/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs @@ -54,7 +54,7 @@ public override void Update(float frameTime) if (eventScheduler.TimeUntilNextEvent > 0) { eventScheduler.TimeUntilNextEvent -= frameTime; - return; + continue; } _event.RunRandomEvent(eventScheduler.ScheduledGameRules); From e9eb54b9486f41d10122060be13165283a736064 Mon Sep 17 00:00:00 2001 From: Avery Dobbins Date: Tue, 13 Aug 2024 04:59:00 -0400 Subject: [PATCH 31/37] more continence --- .../StationEvents/RampingStationEventSchedulerSystem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Content.Server/StationEvents/RampingStationEventSchedulerSystem.cs b/Content.Server/StationEvents/RampingStationEventSchedulerSystem.cs index 1973467545b6..a0a27f257590 100644 --- a/Content.Server/StationEvents/RampingStationEventSchedulerSystem.cs +++ b/Content.Server/StationEvents/RampingStationEventSchedulerSystem.cs @@ -56,7 +56,7 @@ public override void Update(float frameTime) if (scheduler.TimeUntilNextEvent > 0f) { scheduler.TimeUntilNextEvent -= frameTime; - return; + continue; } PickNextEventTime(uid, scheduler); From 3ad515124bddd7017c4fca179b76362e275ac349 Mon Sep 17 00:00:00 2001 From: Avery Dobbins Date: Tue, 13 Aug 2024 04:59:52 -0400 Subject: [PATCH 32/37] uno mas --- .../StationEvents/RampingStationEventSchedulerSystem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Content.Server/StationEvents/RampingStationEventSchedulerSystem.cs b/Content.Server/StationEvents/RampingStationEventSchedulerSystem.cs index a0a27f257590..4123c4c2f433 100644 --- a/Content.Server/StationEvents/RampingStationEventSchedulerSystem.cs +++ b/Content.Server/StationEvents/RampingStationEventSchedulerSystem.cs @@ -51,7 +51,7 @@ public override void Update(float frameTime) while (query.MoveNext(out var uid, out var scheduler, out var gameRule)) { if (!GameTicker.IsGameRuleActive(uid, gameRule)) - return; + continue; if (scheduler.TimeUntilNextEvent > 0f) { From ba56c160e56fe4dbfd72677c1c1be8810195304d Mon Sep 17 00:00:00 2001 From: Avery Dobbins Date: Tue, 13 Aug 2024 05:09:28 -0400 Subject: [PATCH 33/37] obsolution --- Content.Server/StationEvents/EventManagerSystem.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Content.Server/StationEvents/EventManagerSystem.cs b/Content.Server/StationEvents/EventManagerSystem.cs index 35038438baf8..8d6953542f36 100644 --- a/Content.Server/StationEvents/EventManagerSystem.cs +++ b/Content.Server/StationEvents/EventManagerSystem.cs @@ -36,6 +36,7 @@ public override void Initialize() /// /// Randomly runs a valid event. /// + [Obsolete("use overload taking EnityTableSelector instead or risk unexpected results")] public void RunRandomEvent() { var randomEvent = PickRandomEvent(); @@ -51,7 +52,7 @@ public void RunRandomEvent() } /// - /// Randomly runs an event from provided EntitySpawnCollection. + /// Randomly runs an event from provided EntityTableSelector. /// public void RunRandomEvent(EntityTableSelector limitedEventsTable) { From 97cd0a361dec8c1a5225ee20ba07b5c2ee342cee Mon Sep 17 00:00:00 2001 From: Avery Dobbins Date: Tue, 13 Aug 2024 05:26:26 -0400 Subject: [PATCH 34/37] cleanup and documentations --- .../StationEvents/BasicStationEventSchedulerSystem.cs | 8 ++++---- Content.Server/StationEvents/EventManagerSystem.cs | 1 - .../RampingStationEventSchedulerSystem.cs | 11 ++++++----- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs b/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs index d268f8e704b1..bdc9a47e1867 100644 --- a/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs +++ b/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs @@ -158,8 +158,8 @@ public sealed class StationEventCommand : ToolshedCommand yield break; var totalWeight = events.Sum(x => x.Value.Weight); // Well this shit definitely isnt correct now, and I see no way to make it correct. - - foreach (var (proto, comp) in events) + // Its probably *fine* but it wont be accurate if the EntityTableSelector does any subsetting. + foreach (var (proto, comp) in events) // The only solution I see is to do a simulation, and we already have that, so...! { yield return (proto.ID, comp.Weight / totalWeight); } @@ -179,7 +179,7 @@ public sealed class StationEventCommand : ToolshedCommand var events = untimedEvents.Where(pair => pair.Value.EarliestStart <= time).ToList(); - var totalWeight = events.Sum(x => x.Value.Weight); + var totalWeight = events.Sum(x => x.Value.Weight); // same subsetting issue as lsprob. foreach (var (proto, comp) in events) { @@ -199,7 +199,7 @@ public float Prob([CommandArgument] EntityPrototype eventScheduler, [CommandArgu if (!_stationEvent.TryBuildLimitedEvents(basicScheduler.ScheduledGameRules, out var events)) return 0f; - var totalWeight = events.Sum(x => x.Value.Weight); + var totalWeight = events.Sum(x => x.Value.Weight); // same subsetting issue as lsprob. var weight = 0f; if (events.TryFirstOrNull(p => p.Key.ID == eventId, out var pair)) { diff --git a/Content.Server/StationEvents/EventManagerSystem.cs b/Content.Server/StationEvents/EventManagerSystem.cs index 8d6953542f36..bc6b1834002d 100644 --- a/Content.Server/StationEvents/EventManagerSystem.cs +++ b/Content.Server/StationEvents/EventManagerSystem.cs @@ -1,5 +1,4 @@ using System.Linq; -using Content.Server.Chat.Managers; using Content.Server.GameTicking; using Content.Server.RoundEnd; using Content.Server.StationEvents.Components; diff --git a/Content.Server/StationEvents/RampingStationEventSchedulerSystem.cs b/Content.Server/StationEvents/RampingStationEventSchedulerSystem.cs index 4123c4c2f433..a5dbe102ca13 100644 --- a/Content.Server/StationEvents/RampingStationEventSchedulerSystem.cs +++ b/Content.Server/StationEvents/RampingStationEventSchedulerSystem.cs @@ -1,22 +1,20 @@ using Content.Server.GameTicking; using Content.Server.GameTicking.Rules; -using Content.Server.GameTicking.Rules.Components; using Content.Server.StationEvents.Components; -using Content.Server.StationEvents.Events; -using Content.Shared.CCVar; using Content.Shared.GameTicking.Components; -using Robust.Shared.Configuration; using Robust.Shared.Random; namespace Content.Server.StationEvents; public sealed class RampingStationEventSchedulerSystem : GameRuleSystem { - [Dependency] private readonly IConfigurationManager _cfg = default!; [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly EventManagerSystem _event = default!; [Dependency] private readonly GameTicker _gameTicker = default!; + /// + /// Returns the ChaosModifier which increases as round time increases to a point. + /// public float GetChaosModifier(EntityUid uid, RampingStationEventSchedulerComponent component) { var roundTime = (float) _gameTicker.RoundDuration().TotalSeconds; @@ -64,6 +62,9 @@ public override void Update(float frameTime) } } + /// + /// Sets the timing of the next event addition. + /// private void PickNextEventTime(EntityUid uid, RampingStationEventSchedulerComponent component) { var mod = GetChaosModifier(uid, component); From 57d9f79aa6ed1c5c1fb335ac2e83c72c6d33094e Mon Sep 17 00:00:00 2001 From: Avery Dobbins Date: Tue, 13 Aug 2024 13:19:13 -0400 Subject: [PATCH 35/37] Yell at self --- Resources/Prototypes/GameRules/meteorswarms.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Resources/Prototypes/GameRules/meteorswarms.yml b/Resources/Prototypes/GameRules/meteorswarms.yml index e5d76b3d5473..d69fd9700b93 100644 --- a/Resources/Prototypes/GameRules/meteorswarms.yml +++ b/Resources/Prototypes/GameRules/meteorswarms.yml @@ -57,7 +57,7 @@ components: - type: GameRule - type: BasicStationEventScheduler - minimumTimeUntilFirstEvent: 35 # 300 # 5 min # Yell at me if I dont fix this back to 300 + minimumTimeUntilFirstEvent: 300 # 5 min minMaxEventTiming: min: 750 # 12.5 min max: 930 # 17.5 min @@ -70,7 +70,7 @@ components: - type: GameRule - type: BasicStationEventScheduler - minimumTimeUntilFirstEvent: 35 # 300 # 5 min # Yell at me if I dont fix this back to 300 + minimumTimeUntilFirstEvent: 300 # 5 min minMaxEventTiming: min: 750 # 12.5 min max: 930 # 17.5 min From 132f2de173a1b17e63b49bc4735da7cca6f09cca Mon Sep 17 00:00:00 2001 From: Avery Dobbins Date: Tue, 13 Aug 2024 13:34:21 -0400 Subject: [PATCH 36/37] use the right value defaults --- .../Components/RampingStationEventSchedulerComponent.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Content.Server/StationEvents/Components/RampingStationEventSchedulerComponent.cs b/Content.Server/StationEvents/Components/RampingStationEventSchedulerComponent.cs index 16a1c4bd0af6..8bf433144c7f 100644 --- a/Content.Server/StationEvents/Components/RampingStationEventSchedulerComponent.cs +++ b/Content.Server/StationEvents/Components/RampingStationEventSchedulerComponent.cs @@ -17,7 +17,7 @@ public sealed partial class RampingStationEventSchedulerComponent : Component /// Close to how long you expect a round to last, so you'll probably have to tweak this on downstreams. /// [DataField] - public float AverageEndTime = 30f; + public float AverageEndTime = 40f; [DataField] public float EndTime; From d75148b1731161ed92310db740f495d5ed409b03 Mon Sep 17 00:00:00 2001 From: Avery Dobbins Date: Tue, 13 Aug 2024 14:25:39 -0400 Subject: [PATCH 37/37] housekeeping --- .../Tests/GameRules/RuleMaxTimeRestartTest.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Content.IntegrationTests/Tests/GameRules/RuleMaxTimeRestartTest.cs b/Content.IntegrationTests/Tests/GameRules/RuleMaxTimeRestartTest.cs index d5e14ca6cbcb..c805d04a7124 100644 --- a/Content.IntegrationTests/Tests/GameRules/RuleMaxTimeRestartTest.cs +++ b/Content.IntegrationTests/Tests/GameRules/RuleMaxTimeRestartTest.cs @@ -1,14 +1,9 @@ using Content.Server.GameTicking; -using Content.Server.GameTicking.Commands; using Content.Server.GameTicking.Rules; using Content.Server.GameTicking.Rules.Components; -using Content.Shared.CCVar; using Content.Shared.GameTicking.Components; -using Robust.Shared.Configuration; using Robust.Shared.GameObjects; -using Robust.Shared.Localization; using Robust.Shared.Timing; -using System.Management; namespace Content.IntegrationTests.Tests.GameRules { @@ -28,7 +23,6 @@ public async Task RestartTest() var entityManager = server.ResolveDependency(); var sGameTicker = server.ResolveDependency().GetEntitySystem(); var sGameTiming = server.ResolveDependency(); - var locManager = server.ResolveDependency(); MaxTimeRestartRuleComponent maxTime = null; await server.WaitPost(() =>