refactor event schedulers to use explicit game rules (#29320)
* works, still has testing values, im sure I did stupid shit. * shitvent crapfactor * snap extra word out of existence * shit I died of old * remove useless inaccurate design comments * Oopsie, handle requirement params in RandomRuleSystem too * I'm a slash slinging hasher * Address reviews, add admin alerts I forgor * EntityMan saves the day * address reviews 1 * eh, I actually don't care about the cargo gifts thing. * started * Do reviews * you actually meant 1.2 lmao * dependency inheritance is a fickle bitch * I have no idea. * Threads are for sheets not computers. * fix traitor rule test * fix round type tattling * break things * It worky * Toolshed makes we want to drink depresso. * Finished? * remove debug values * timings * use defaults * alphabetize * bobby drop tables * Float required fr fr * continue * more continence * uno mas * obsolution * cleanup and documentations * Yell at self * use the right value defaults * housekeeping
This commit is contained in:
@@ -2,11 +2,12 @@ using System.Linq;
|
||||
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,13 +24,17 @@ namespace Content.Server.StationEvents
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly EventManagerSystem _event = default!;
|
||||
|
||||
public const float MinEventTime = 60 * 3;
|
||||
public const float MaxEventTime = 60 * 10;
|
||||
protected override void Started(EntityUid uid, BasicStationEventSchedulerComponent component, GameRuleComponent gameRule,
|
||||
GameRuleStartedEvent args)
|
||||
{
|
||||
// A little starting variance so schedulers dont all proc at once.
|
||||
component.TimeUntilNextEvent = RobustRandom.NextFloat(component.MinimumTimeUntilFirstEvent, component.MinimumTimeUntilFirstEvent + 120);
|
||||
}
|
||||
|
||||
protected override void Ended(EntityUid uid, BasicStationEventSchedulerComponent component, GameRuleComponent gameRule,
|
||||
GameRuleEndedEvent args)
|
||||
{
|
||||
component.TimeUntilNextEvent = BasicStationEventSchedulerComponent.MinimumTimeUntilFirstEvent;
|
||||
component.TimeUntilNextEvent = component.MinimumTimeUntilFirstEvent;
|
||||
}
|
||||
|
||||
|
||||
@@ -49,10 +54,10 @@ namespace Content.Server.StationEvents
|
||||
if (eventScheduler.TimeUntilNextEvent > 0)
|
||||
{
|
||||
eventScheduler.TimeUntilNextEvent -= frameTime;
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
_event.RunRandomEvent();
|
||||
_event.RunRandomEvent(eventScheduler.ScheduledGameRules);
|
||||
ResetTimer(eventScheduler);
|
||||
}
|
||||
}
|
||||
@@ -62,7 +67,7 @@ namespace Content.Server.StationEvents
|
||||
/// </summary>
|
||||
private void ResetTimer(BasicStationEventSchedulerComponent component)
|
||||
{
|
||||
component.TimeUntilNextEvent = _random.NextFloat(MinEventTime, MaxEventTime);
|
||||
component.TimeUntilNextEvent = component.MinMaxEventTiming.Next(_random);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,7 +75,8 @@ namespace Content.Server.StationEvents
|
||||
public sealed class StationEventCommand : ToolshedCommand
|
||||
{
|
||||
private EventManagerSystem? _stationEvent;
|
||||
private BasicStationEventSchedulerSystem? _basicScheduler;
|
||||
private EntityTableSystem? _entityTable;
|
||||
private IComponentFactory? _compFac;
|
||||
private IRobustRandom? _random;
|
||||
|
||||
/// <summary>
|
||||
@@ -88,10 +94,11 @@ namespace Content.Server.StationEvents
|
||||
/// to even exist) so I think it's fine.
|
||||
/// </remarks>
|
||||
[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<EventManagerSystem>();
|
||||
_basicScheduler ??= GetSys<BasicStationEventSchedulerSystem>();
|
||||
_entityTable ??= GetSys<EntityTableSystem>();
|
||||
_compFac ??= IoCManager.Resolve<IComponentFactory>();
|
||||
_random ??= IoCManager.Resolve<IRobustRandom>();
|
||||
|
||||
var occurrences = new Dictionary<string, int>();
|
||||
@@ -101,6 +108,13 @@ namespace Content.Server.StationEvents
|
||||
occurrences.Add(ev.Key.ID, 0);
|
||||
}
|
||||
|
||||
if (!eventScheduler.TryGetComponent<BasicStationEventSchedulerComponent>(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 +125,16 @@ namespace Content.Server.StationEvents
|
||||
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; // doesnt break because maybe the time is preventing events being available.
|
||||
}
|
||||
var available = _stationEvent.AvailableEvents(false, playerCount, curTime);
|
||||
var ev = _stationEvent.FindEvent(available);
|
||||
var plausibleEvents = new Dictionary<EntityPrototype, StationEventComponent>(available.Intersect(selectedEvents)); // C# makes me sad
|
||||
|
||||
var ev = _stationEvent.FindEvent(plausibleEvents);
|
||||
if (ev == null)
|
||||
continue;
|
||||
|
||||
@@ -125,26 +146,40 @@ namespace Content.Server.StationEvents
|
||||
}
|
||||
|
||||
[CommandImplementation("lsprob")]
|
||||
public IEnumerable<(string, float)> LsProb()
|
||||
public IEnumerable<(string, float)> LsProb([CommandArgument] EntityPrototype eventScheduler)
|
||||
{
|
||||
_compFac ??= IoCManager.Resolve<IComponentFactory>();
|
||||
_stationEvent ??= GetSys<EventManagerSystem>();
|
||||
var events = _stationEvent.AllEvents();
|
||||
|
||||
var totalWeight = events.Sum(x => x.Value.Weight);
|
||||
if (!eventScheduler.TryGetComponent<BasicStationEventSchedulerComponent>(out var basicScheduler, _compFac))
|
||||
yield break;
|
||||
|
||||
foreach (var (proto, comp) in events)
|
||||
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.
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
[CommandImplementation("lsprobtime")]
|
||||
public IEnumerable<(string, float)> LsProbTime([CommandArgument] float time)
|
||||
public IEnumerable<(string, float)> LsProbTime([CommandArgument] EntityPrototype eventScheduler, [CommandArgument] float time)
|
||||
{
|
||||
_compFac ??= IoCManager.Resolve<IComponentFactory>();
|
||||
_stationEvent ??= GetSys<EventManagerSystem>();
|
||||
var events = _stationEvent.AllEvents().Where(pair => pair.Value.EarliestStart <= time).ToList();
|
||||
|
||||
var totalWeight = events.Sum(x => x.Value.Weight);
|
||||
if (!eventScheduler.TryGetComponent<BasicStationEventSchedulerComponent>(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); // same subsetting issue as lsprob.
|
||||
|
||||
foreach (var (proto, comp) in events)
|
||||
{
|
||||
@@ -153,12 +188,18 @@ namespace Content.Server.StationEvents
|
||||
}
|
||||
|
||||
[CommandImplementation("prob")]
|
||||
public float Prob([CommandArgument] string eventId)
|
||||
public float Prob([CommandArgument] EntityPrototype eventScheduler, [CommandArgument] string eventId)
|
||||
{
|
||||
_compFac ??= IoCManager.Resolve<IComponentFactory>();
|
||||
_stationEvent ??= GetSys<EventManagerSystem>();
|
||||
var events = _stationEvent.AllEvents();
|
||||
|
||||
var totalWeight = events.Sum(x => x.Value.Weight);
|
||||
if (!eventScheduler.TryGetComponent<BasicStationEventSchedulerComponent>(out var basicScheduler, _compFac))
|
||||
return 0f;
|
||||
|
||||
if (!_stationEvent.TryBuildLimitedEvents(basicScheduler.ScheduledGameRules, out var events))
|
||||
return 0f;
|
||||
|
||||
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))
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user