diff --git a/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs b/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs index a3c2440fe9..06289618f7 100644 --- a/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs +++ b/Content.Server/StationEvents/BasicStationEventSchedulerSystem.cs @@ -10,6 +10,7 @@ using JetBrains.Annotations; using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Toolshed; +using Robust.Shared.Toolshed.TypeParsers; using Robust.Shared.Utility; namespace Content.Server.StationEvents @@ -94,7 +95,7 @@ namespace Content.Server.StationEvents /// to even exist) so I think it's fine. /// [CommandImplementation("simulate")] - public IEnumerable<(string, float)> Simulate(EntityPrototype eventScheduler, int rounds, int playerCount, float roundEndMean, float roundEndStdDev) + public IEnumerable<(string, float)> Simulate([CommandArgument] Prototype eventSchedulerProto, [CommandArgument] int rounds, [CommandArgument] int playerCount, [CommandArgument] float roundEndMean, [CommandArgument] float roundEndStdDev) { _stationEvent ??= GetSys(); _entityTable ??= GetSys(); @@ -108,6 +109,8 @@ namespace Content.Server.StationEvents occurrences.Add(ev.Key.ID, 0); } + eventSchedulerProto.Deconstruct(out EntityPrototype eventScheduler); + if (!eventScheduler.TryGetComponent(out var basicScheduler, _compFac)) { return occurrences.Select(p => (p.Key, (float)p.Value)).OrderByDescending(p => p.Item2); @@ -118,7 +121,7 @@ namespace Content.Server.StationEvents for (var i = 0; i < rounds; i++) { var curTime = TimeSpan.Zero; - var randomEndTime = _random.NextGaussian(roundEndMean, roundEndStdDev) * 60; // *60 = minutes to seconds + var randomEndTime = _random.NextGaussian(roundEndMean, roundEndStdDev); // Its in minutes, should probably be a better time format once we get that in toolshed like [hh:mm:ss] if (randomEndTime <= 0) continue; @@ -127,14 +130,13 @@ namespace Content.Server.StationEvents // sim an event curTime += TimeSpan.FromSeconds(compMinMax.Next(_random)); - if (!_stationEvent.TryBuildLimitedEvents(basicScheduler.ScheduledGameRules, out var selectedEvents)) + var available = _stationEvent.AvailableEvents(false, playerCount, curTime); + if (!_stationEvent.TryBuildLimitedEvents(basicScheduler.ScheduledGameRules, available, out var selectedEvents)) { 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 - var ev = _stationEvent.FindEvent(plausibleEvents); + var ev = _stationEvent.FindEvent(selectedEvents); if (ev == null) continue; @@ -146,15 +148,18 @@ namespace Content.Server.StationEvents } [CommandImplementation("lsprob")] - public IEnumerable<(string, float)> LsProb(EntityPrototype eventScheduler) + public IEnumerable<(string, float)> LsProb([CommandArgument] Prototype eventSchedulerProto) { _compFac ??= IoCManager.Resolve(); _stationEvent ??= GetSys(); + eventSchedulerProto.Deconstruct(out EntityPrototype eventScheduler); + if (!eventScheduler.TryGetComponent(out var basicScheduler, _compFac)) yield break; - if (!_stationEvent.TryBuildLimitedEvents(basicScheduler.ScheduledGameRules, out var events)) + var available = _stationEvent.AvailableEvents(); + if (!_stationEvent.TryBuildLimitedEvents(basicScheduler.ScheduledGameRules, available, 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. @@ -165,19 +170,24 @@ namespace Content.Server.StationEvents } } - [CommandImplementation("lsprobtime")] - public IEnumerable<(string, float)> LsProbTime(EntityPrototype eventScheduler, float time) + [CommandImplementation("lsprobtheoretical")] + public IEnumerable<(string, float)> LsProbTime([CommandArgument] Prototype eventSchedulerProto, [CommandArgument] int playerCount, [CommandArgument] float time) { _compFac ??= IoCManager.Resolve(); _stationEvent ??= GetSys(); + eventSchedulerProto.Deconstruct(out EntityPrototype eventScheduler); + if (!eventScheduler.TryGetComponent(out var basicScheduler, _compFac)) yield break; - if (!_stationEvent.TryBuildLimitedEvents(basicScheduler.ScheduledGameRules, out var untimedEvents)) + var timemins = time * 60; + var theoryTime = TimeSpan.Zero + TimeSpan.FromSeconds(timemins); + var available = _stationEvent.AvailableEvents(false, playerCount, theoryTime); + if (!_stationEvent.TryBuildLimitedEvents(basicScheduler.ScheduledGameRules, available, out var untimedEvents)) yield break; - var events = untimedEvents.Where(pair => pair.Value.EarliestStart <= time).ToList(); + var events = untimedEvents.Where(pair => pair.Value.EarliestStart <= timemins).ToList(); var totalWeight = events.Sum(x => x.Value.Weight); // same subsetting issue as lsprob. @@ -188,15 +198,18 @@ namespace Content.Server.StationEvents } [CommandImplementation("prob")] - public float Prob(EntityPrototype eventScheduler, string eventId) + public float Prob([CommandArgument] Prototype eventSchedulerProto, [CommandArgument] string eventId) { _compFac ??= IoCManager.Resolve(); _stationEvent ??= GetSys(); + eventSchedulerProto.Deconstruct(out EntityPrototype eventScheduler); + if (!eventScheduler.TryGetComponent(out var basicScheduler, _compFac)) return 0f; - if (!_stationEvent.TryBuildLimitedEvents(basicScheduler.ScheduledGameRules, out var events)) + var available = _stationEvent.AvailableEvents(); + if (!_stationEvent.TryBuildLimitedEvents(basicScheduler.ScheduledGameRules, available, out var events)) return 0f; var totalWeight = events.Sum(x => x.Value.Weight); // same subsetting issue as lsprob. diff --git a/Content.Server/StationEvents/EventManagerSystem.cs b/Content.Server/StationEvents/EventManagerSystem.cs index a66499d0aa..6585fe3248 100644 --- a/Content.Server/StationEvents/EventManagerSystem.cs +++ b/Content.Server/StationEvents/EventManagerSystem.cs @@ -55,7 +55,10 @@ public sealed class EventManagerSystem : EntitySystem /// public void RunRandomEvent(EntityTableSelector limitedEventsTable) { - if (!TryBuildLimitedEvents(limitedEventsTable, out var limitedEvents)) + var availableEvents = AvailableEvents(); // handles the player counts and individual event restrictions. + // Putting this here only makes any sense in the context of the toolshed commands in BasicStationEventScheduler. Kill me. + + if (!TryBuildLimitedEvents(limitedEventsTable, availableEvents, out var limitedEvents)) { Log.Warning("Provided event table could not build dict!"); return; @@ -80,12 +83,14 @@ public sealed class EventManagerSystem : EntitySystem /// /// Returns true if the provided EntityTableSelector gives at least one prototype with a StationEvent comp. /// - public bool TryBuildLimitedEvents(EntityTableSelector limitedEventsTable, out Dictionary limitedEvents) + public bool TryBuildLimitedEvents( + EntityTableSelector limitedEventsTable, + Dictionary availableEvents, + out Dictionary limitedEvents + ) { 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!"); diff --git a/Resources/Locale/en-US/commands/toolshed-commands.ftl b/Resources/Locale/en-US/commands/toolshed-commands.ftl index 51f0745b3d..3a620b049b 100644 --- a/Resources/Locale/en-US/commands/toolshed-commands.ftl +++ b/Resources/Locale/en-US/commands/toolshed-commands.ftl @@ -43,11 +43,11 @@ command-description-stations-largestgrid = command-description-stations-rerollBounties = Clears all the current bounties for the station and gets a new selection. command-description-stationevent-lsprob = - Lists the probability of different station events occuring out of the entire pool. -command-description-stationevent-lsprobtime = - Lists the probability of different station events occuring based on the specified length of a round. + Given a BasicStationEventScheduler prototype, lists the probability of different station events occuring out of the entire pool with current conditions. +command-description-stationevent-lsprobtheoretical = + Given a BasicStationEventScheduler prototype, player count, and round time, lists the probability of different station events occuring based on the specified number of players and round time. command-description-stationevent-prob = - Returns the probability of a single station event occuring out of the entire pool. + Given a BasicStationEventScheduler prototype and an event prototype, returns the probability of a single station event occuring out of the entire pool with current conditions. command-description-admins-active = Returns a list of active admins. command-description-admins-all = @@ -83,7 +83,7 @@ command-description-mind-control = command-description-addaccesslog = Adds an access log to this entity. Do note that this bypasses the log's default limit and pause check. command-description-stationevent-simulate = - Simulates N number of rounds in which events will occur and prints the occurrences of every event after. + Given a BasicStationEventScheduler prototype, N Rounds, N Players, mean round end, and stddev of round end, Simulates N number of rounds in which events will occur and prints the occurrences of every event after. command-description-xenoartifact-list = List all EntityUids of spawned artifacts. command-description-xenoartifact-printMatrix =