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:
@@ -1,10 +1,7 @@
|
|||||||
using Content.Server.GameTicking;
|
using Content.Server.GameTicking;
|
||||||
using Content.Server.GameTicking.Commands;
|
|
||||||
using Content.Server.GameTicking.Rules;
|
using Content.Server.GameTicking.Rules;
|
||||||
using Content.Server.GameTicking.Rules.Components;
|
using Content.Server.GameTicking.Rules.Components;
|
||||||
using Content.Shared.CCVar;
|
|
||||||
using Content.Shared.GameTicking.Components;
|
using Content.Shared.GameTicking.Components;
|
||||||
using Robust.Shared.Configuration;
|
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
|
|
||||||
@@ -27,8 +24,12 @@ namespace Content.IntegrationTests.Tests.GameRules
|
|||||||
var sGameTicker = server.ResolveDependency<IEntitySystemManager>().GetEntitySystem<GameTicker>();
|
var sGameTicker = server.ResolveDependency<IEntitySystemManager>().GetEntitySystem<GameTicker>();
|
||||||
var sGameTiming = server.ResolveDependency<IGameTiming>();
|
var sGameTiming = server.ResolveDependency<IGameTiming>();
|
||||||
|
|
||||||
sGameTicker.StartGameRule("MaxTimeRestart", out var ruleEntity);
|
MaxTimeRestartRuleComponent maxTime = null;
|
||||||
Assert.That(entityManager.TryGetComponent<MaxTimeRestartRuleComponent>(ruleEntity, out var maxTime));
|
await server.WaitPost(() =>
|
||||||
|
{
|
||||||
|
sGameTicker.StartGameRule("MaxTimeRestart", out var ruleEntity);
|
||||||
|
Assert.That(entityManager.TryGetComponent<MaxTimeRestartRuleComponent>(ruleEntity, out maxTime));
|
||||||
|
});
|
||||||
|
|
||||||
Assert.That(server.EntMan.Count<GameRuleComponent>(), Is.EqualTo(1));
|
Assert.That(server.EntMan.Count<GameRuleComponent>(), Is.EqualTo(1));
|
||||||
Assert.That(server.EntMan.Count<ActiveGameRuleComponent>(), Is.EqualTo(1));
|
Assert.That(server.EntMan.Count<ActiveGameRuleComponent>(), Is.EqualTo(1));
|
||||||
|
|||||||
@@ -77,16 +77,17 @@ public sealed class TraitorRuleTest
|
|||||||
await pair.SetAntagPreference(TraitorAntagRoleName, true);
|
await pair.SetAntagPreference(TraitorAntagRoleName, true);
|
||||||
|
|
||||||
// Add the game rule
|
// Add the game rule
|
||||||
var gameRuleEnt = ticker.AddGameRule(TraitorGameRuleProtoId);
|
TraitorRuleComponent traitorRule = null;
|
||||||
Assert.That(entMan.TryGetComponent<TraitorRuleComponent>(gameRuleEnt, out var traitorRule));
|
|
||||||
|
|
||||||
// Ready up
|
|
||||||
ticker.ToggleReadyAll(true);
|
|
||||||
Assert.That(ticker.PlayerGameStatuses.Values.All(x => x == PlayerGameStatus.ReadyToPlay));
|
|
||||||
|
|
||||||
// Start the round
|
|
||||||
await server.WaitPost(() =>
|
await server.WaitPost(() =>
|
||||||
{
|
{
|
||||||
|
var gameRuleEnt = ticker.AddGameRule(TraitorGameRuleProtoId);
|
||||||
|
Assert.That(entMan.TryGetComponent<TraitorRuleComponent>(gameRuleEnt, out traitorRule));
|
||||||
|
|
||||||
|
// Ready up
|
||||||
|
ticker.ToggleReadyAll(true);
|
||||||
|
Assert.That(ticker.PlayerGameStatuses.Values.All(x => x == PlayerGameStatus.ReadyToPlay));
|
||||||
|
|
||||||
|
// Start the round
|
||||||
ticker.StartRound();
|
ticker.StartRound();
|
||||||
// Force traitor mode to start (skip the delay)
|
// Force traitor mode to start (skip the delay)
|
||||||
ticker.StartGameRule(gameRuleEnt);
|
ticker.StartGameRule(gameRuleEnt);
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ using JetBrains.Annotations;
|
|||||||
using Robust.Shared.Console;
|
using Robust.Shared.Console;
|
||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
|
using Robust.Shared.Localization;
|
||||||
|
|
||||||
namespace Content.Server.GameTicking;
|
namespace Content.Server.GameTicking;
|
||||||
|
|
||||||
@@ -71,6 +72,16 @@ public sealed partial class GameTicker
|
|||||||
var ruleEntity = Spawn(ruleId, MapCoordinates.Nullspace);
|
var ruleEntity = Spawn(ruleId, MapCoordinates.Nullspace);
|
||||||
_sawmill.Info($"Added game rule {ToPrettyString(ruleEntity)}");
|
_sawmill.Info($"Added game rule {ToPrettyString(ruleEntity)}");
|
||||||
_adminLogger.Add(LogType.EventStarted, $"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);
|
var ev = new GameRuleAddedEvent(ruleEntity, ruleId);
|
||||||
RaiseLocalEvent(ruleEntity, ref ev, true);
|
RaiseLocalEvent(ruleEntity, ref ev, true);
|
||||||
|
|||||||
@@ -2,11 +2,12 @@ using System.Linq;
|
|||||||
using Content.Server.Administration;
|
using Content.Server.Administration;
|
||||||
using Content.Server.GameTicking;
|
using Content.Server.GameTicking;
|
||||||
using Content.Server.GameTicking.Rules;
|
using Content.Server.GameTicking.Rules;
|
||||||
using Content.Server.GameTicking.Rules.Components;
|
|
||||||
using Content.Server.StationEvents.Components;
|
using Content.Server.StationEvents.Components;
|
||||||
using Content.Shared.Administration;
|
using Content.Shared.Administration;
|
||||||
|
using Content.Shared.EntityTable;
|
||||||
using Content.Shared.GameTicking.Components;
|
using Content.Shared.GameTicking.Components;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Random;
|
using Robust.Shared.Random;
|
||||||
using Robust.Shared.Toolshed;
|
using Robust.Shared.Toolshed;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
@@ -23,13 +24,17 @@ namespace Content.Server.StationEvents
|
|||||||
[Dependency] private readonly IRobustRandom _random = default!;
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
[Dependency] private readonly EventManagerSystem _event = default!;
|
[Dependency] private readonly EventManagerSystem _event = default!;
|
||||||
|
|
||||||
public const float MinEventTime = 60 * 3;
|
protected override void Started(EntityUid uid, BasicStationEventSchedulerComponent component, GameRuleComponent gameRule,
|
||||||
public const float MaxEventTime = 60 * 10;
|
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,
|
protected override void Ended(EntityUid uid, BasicStationEventSchedulerComponent component, GameRuleComponent gameRule,
|
||||||
GameRuleEndedEvent args)
|
GameRuleEndedEvent args)
|
||||||
{
|
{
|
||||||
component.TimeUntilNextEvent = BasicStationEventSchedulerComponent.MinimumTimeUntilFirstEvent;
|
component.TimeUntilNextEvent = component.MinimumTimeUntilFirstEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -49,10 +54,10 @@ namespace Content.Server.StationEvents
|
|||||||
if (eventScheduler.TimeUntilNextEvent > 0)
|
if (eventScheduler.TimeUntilNextEvent > 0)
|
||||||
{
|
{
|
||||||
eventScheduler.TimeUntilNextEvent -= frameTime;
|
eventScheduler.TimeUntilNextEvent -= frameTime;
|
||||||
return;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
_event.RunRandomEvent();
|
_event.RunRandomEvent(eventScheduler.ScheduledGameRules);
|
||||||
ResetTimer(eventScheduler);
|
ResetTimer(eventScheduler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -62,7 +67,7 @@ namespace Content.Server.StationEvents
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void ResetTimer(BasicStationEventSchedulerComponent component)
|
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
|
public sealed class StationEventCommand : ToolshedCommand
|
||||||
{
|
{
|
||||||
private EventManagerSystem? _stationEvent;
|
private EventManagerSystem? _stationEvent;
|
||||||
private BasicStationEventSchedulerSystem? _basicScheduler;
|
private EntityTableSystem? _entityTable;
|
||||||
|
private IComponentFactory? _compFac;
|
||||||
private IRobustRandom? _random;
|
private IRobustRandom? _random;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -88,10 +94,11 @@ namespace Content.Server.StationEvents
|
|||||||
/// to even exist) so I think it's fine.
|
/// to even exist) so I think it's fine.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[CommandImplementation("simulate")]
|
[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>();
|
_stationEvent ??= GetSys<EventManagerSystem>();
|
||||||
_basicScheduler ??= GetSys<BasicStationEventSchedulerSystem>();
|
_entityTable ??= GetSys<EntityTableSystem>();
|
||||||
|
_compFac ??= IoCManager.Resolve<IComponentFactory>();
|
||||||
_random ??= IoCManager.Resolve<IRobustRandom>();
|
_random ??= IoCManager.Resolve<IRobustRandom>();
|
||||||
|
|
||||||
var occurrences = new Dictionary<string, int>();
|
var occurrences = new Dictionary<string, int>();
|
||||||
@@ -101,6 +108,13 @@ namespace Content.Server.StationEvents
|
|||||||
occurrences.Add(ev.Key.ID, 0);
|
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++)
|
for (var i = 0; i < rounds; i++)
|
||||||
{
|
{
|
||||||
var curTime = TimeSpan.Zero;
|
var curTime = TimeSpan.Zero;
|
||||||
@@ -111,9 +125,16 @@ namespace Content.Server.StationEvents
|
|||||||
while (curTime.TotalSeconds < randomEndTime)
|
while (curTime.TotalSeconds < randomEndTime)
|
||||||
{
|
{
|
||||||
// sim an event
|
// 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 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)
|
if (ev == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -125,26 +146,40 @@ namespace Content.Server.StationEvents
|
|||||||
}
|
}
|
||||||
|
|
||||||
[CommandImplementation("lsprob")]
|
[CommandImplementation("lsprob")]
|
||||||
public IEnumerable<(string, float)> LsProb()
|
public IEnumerable<(string, float)> LsProb([CommandArgument] EntityPrototype eventScheduler)
|
||||||
{
|
{
|
||||||
|
_compFac ??= IoCManager.Resolve<IComponentFactory>();
|
||||||
_stationEvent ??= GetSys<EventManagerSystem>();
|
_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);
|
yield return (proto.ID, comp.Weight / totalWeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[CommandImplementation("lsprobtime")]
|
[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>();
|
_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)
|
foreach (var (proto, comp) in events)
|
||||||
{
|
{
|
||||||
@@ -153,12 +188,18 @@ namespace Content.Server.StationEvents
|
|||||||
}
|
}
|
||||||
|
|
||||||
[CommandImplementation("prob")]
|
[CommandImplementation("prob")]
|
||||||
public float Prob([CommandArgument] string eventId)
|
public float Prob([CommandArgument] EntityPrototype eventScheduler, [CommandArgument] string eventId)
|
||||||
{
|
{
|
||||||
|
_compFac ??= IoCManager.Resolve<IComponentFactory>();
|
||||||
_stationEvent ??= GetSys<EventManagerSystem>();
|
_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;
|
var weight = 0f;
|
||||||
if (events.TryFirstOrNull(p => p.Key.ID == eventId, out var pair))
|
if (events.TryFirstOrNull(p => p.Key.ID == eventId, out var pair))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,14 +1,35 @@
|
|||||||
namespace Content.Server.StationEvents.Components;
|
using Content.Shared.Destructible.Thresholds;
|
||||||
|
using Content.Shared.EntityTable.EntitySelectors;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Content.Server.StationEvents.Components;
|
||||||
|
|
||||||
[RegisterComponent, Access(typeof(BasicStationEventSchedulerSystem))]
|
[RegisterComponent, Access(typeof(BasicStationEventSchedulerSystem))]
|
||||||
public sealed partial class BasicStationEventSchedulerComponent : Component
|
public sealed partial class BasicStationEventSchedulerComponent : Component
|
||||||
{
|
{
|
||||||
public const float MinimumTimeUntilFirstEvent = 300;
|
/// <summary>
|
||||||
|
/// How long the the scheduler waits to begin starting rules.
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public float MinimumTimeUntilFirstEvent = 200;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// How long until the next check for an event runs
|
/// The minimum and maximum time between rule starts in seconds.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// Default value is how long until first event is allowed
|
[DataField]
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
public MinMax MinMaxEventTiming = new(3 * 60, 10 * 60);
|
||||||
public float TimeUntilNextEvent = MinimumTimeUntilFirstEvent;
|
|
||||||
|
/// <summary>
|
||||||
|
/// How long until the next check for an event runs, is initially set based on MinimumTimeUntilFirstEvent & MinMaxEventTiming.
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public float TimeUntilNextEvent;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The gamerules that the scheduler can choose from
|
||||||
|
/// </summary>
|
||||||
|
/// Reminder that though we could do all selection via the EntityTableSelector, we also need to consider various <see cref="StationEventComponent"/> restrictions.
|
||||||
|
/// As such, we want to pass a list of acceptable game rules, which are then parsed for restrictions by the <see cref="EventManagerSystem"/>.
|
||||||
|
[DataField(required: true)]
|
||||||
|
public EntityTableSelector ScheduledGameRules = default!;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
using Content.Shared.Random;
|
|
||||||
using Robust.Shared.Prototypes;
|
|
||||||
|
|
||||||
namespace Content.Server.StationEvents.Components;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This is used for running meteor swarm events at regular intervals.
|
|
||||||
/// </summary>
|
|
||||||
[RegisterComponent, Access(typeof(MeteorSchedulerSystem)), AutoGenerateComponentPause]
|
|
||||||
public sealed partial class MeteorSchedulerComponent : Component
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The weights for which swarms will be selected.
|
|
||||||
/// </summary>
|
|
||||||
[DataField]
|
|
||||||
public ProtoId<WeightedRandomEntityPrototype> Config = "DefaultConfig";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The time at which the next swarm occurs.
|
|
||||||
/// </summary>
|
|
||||||
[DataField, AutoPausedField]
|
|
||||||
public TimeSpan NextSwarmTime = TimeSpan.Zero;
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,17 +1,41 @@
|
|||||||
namespace Content.Server.StationEvents.Components;
|
using Content.Shared.EntityTable.EntitySelectors;
|
||||||
|
|
||||||
|
namespace Content.Server.StationEvents.Components;
|
||||||
|
|
||||||
[RegisterComponent, Access(typeof(RampingStationEventSchedulerSystem))]
|
[RegisterComponent, Access(typeof(RampingStationEventSchedulerSystem))]
|
||||||
public sealed partial class RampingStationEventSchedulerComponent : Component
|
public sealed partial class RampingStationEventSchedulerComponent : Component
|
||||||
{
|
{
|
||||||
[DataField("endTime"), ViewVariables(VVAccess.ReadWrite)]
|
/// <summary>
|
||||||
|
/// Average ending chaos modifier for the ramping event scheduler. Higher means faster.
|
||||||
|
/// Max chaos chosen for a round will deviate from this
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public float AverageChaos = 6f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 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.
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public float AverageEndTime = 40f;
|
||||||
|
|
||||||
|
[DataField]
|
||||||
public float EndTime;
|
public float EndTime;
|
||||||
|
|
||||||
[DataField("maxChaos"), ViewVariables(VVAccess.ReadWrite)]
|
[DataField]
|
||||||
public float MaxChaos;
|
public float MaxChaos;
|
||||||
|
|
||||||
[DataField("startingChaos"), ViewVariables(VVAccess.ReadWrite)]
|
[DataField]
|
||||||
public float StartingChaos;
|
public float StartingChaos;
|
||||||
|
|
||||||
[DataField("timeUntilNextEvent"), ViewVariables(VVAccess.ReadWrite)]
|
[DataField]
|
||||||
public float TimeUntilNextEvent;
|
public float TimeUntilNextEvent;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The gamerules that the scheduler can choose from
|
||||||
|
/// </summary>
|
||||||
|
/// Reminder that though we could do all selection via the EntityTableSelector, we also need to consider various <see cref="StationEventComponent"/> restrictions.
|
||||||
|
/// As such, we want to pass a list of acceptable game rules, which are then parsed for restrictions by the <see cref="EventManagerSystem"/>.
|
||||||
|
[DataField(required: true)]
|
||||||
|
public EntityTableSelector ScheduledGameRules = default!;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Server.Chat.Managers;
|
|
||||||
using Content.Server.GameTicking;
|
using Content.Server.GameTicking;
|
||||||
using Content.Server.RoundEnd;
|
using Content.Server.RoundEnd;
|
||||||
using Content.Server.StationEvents.Components;
|
using Content.Server.StationEvents.Components;
|
||||||
@@ -8,6 +7,8 @@ using Robust.Server.Player;
|
|||||||
using Robust.Shared.Configuration;
|
using Robust.Shared.Configuration;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Random;
|
using Robust.Shared.Random;
|
||||||
|
using Content.Shared.EntityTable.EntitySelectors;
|
||||||
|
using Content.Shared.EntityTable;
|
||||||
|
|
||||||
namespace Content.Server.StationEvents;
|
namespace Content.Server.StationEvents;
|
||||||
|
|
||||||
@@ -17,7 +18,7 @@ public sealed class EventManagerSystem : EntitySystem
|
|||||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||||
[Dependency] private readonly IRobustRandom _random = default!;
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
[Dependency] private readonly IPrototypeManager _prototype = 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] public readonly GameTicker GameTicker = default!;
|
||||||
[Dependency] private readonly RoundEndSystem _roundEnd = default!;
|
[Dependency] private readonly RoundEndSystem _roundEnd = default!;
|
||||||
|
|
||||||
@@ -34,7 +35,8 @@ public sealed class EventManagerSystem : EntitySystem
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Randomly runs a valid event.
|
/// Randomly runs a valid event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string RunRandomEvent()
|
[Obsolete("use overload taking EnityTableSelector instead or risk unexpected results")]
|
||||||
|
public void RunRandomEvent()
|
||||||
{
|
{
|
||||||
var randomEvent = PickRandomEvent();
|
var randomEvent = PickRandomEvent();
|
||||||
|
|
||||||
@@ -42,14 +44,86 @@ public sealed class EventManagerSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
var errStr = Loc.GetString("station-event-system-run-random-event-no-valid-events");
|
var errStr = Loc.GetString("station-event-system-run-random-event-no-valid-events");
|
||||||
Log.Error(errStr);
|
Log.Error(errStr);
|
||||||
return errStr;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var ent = GameTicker.AddGameRule(randomEvent);
|
GameTicker.AddGameRule(randomEvent);
|
||||||
var str = Loc.GetString("station-event-system-run-event",("eventName", ToPrettyString(ent)));
|
}
|
||||||
_chat.SendAdminAlert(str);
|
|
||||||
Log.Info(str);
|
/// <summary>
|
||||||
return str;
|
/// Randomly runs an event from provided EntityTableSelector.
|
||||||
|
/// </summary>
|
||||||
|
public void RunRandomEvent(EntityTableSelector limitedEventsTable)
|
||||||
|
{
|
||||||
|
if (!TryBuildLimitedEvents(limitedEventsTable, out var limitedEvents))
|
||||||
|
{
|
||||||
|
Log.Warning("Provided event table could not build dict!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns true if the provided EntityTableSelector gives at least one prototype with a StationEvent comp.
|
||||||
|
/// </summary>
|
||||||
|
public bool TryBuildLimitedEvents(EntityTableSelector limitedEventsTable, out Dictionary<EntityPrototype, StationEventComponent> limitedEvents)
|
||||||
|
{
|
||||||
|
limitedEvents = new Dictionary<EntityPrototype, StationEventComponent>();
|
||||||
|
|
||||||
|
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.
|
||||||
|
return false;
|
||||||
|
|
||||||
|
foreach (var eventid in selectedEvents)
|
||||||
|
{
|
||||||
|
if (!_prototype.TryIndex(eventid, out var eventproto))
|
||||||
|
{
|
||||||
|
Log.Warning("An event ID has no prototype index!");
|
||||||
|
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<StationEventComponent>(out var stationEvent, EntityManager.ComponentFactory))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!availableEvents.ContainsKey(eventproto))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
limitedEvents.Add(eventproto, stationEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!limitedEvents.Any())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -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;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 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
|
|
||||||
/// </summary>
|
|
||||||
public sealed class MeteorSchedulerSystem : GameRuleSystem<MeteorSchedulerComponent>
|
|
||||||
{
|
|
||||||
[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<MeteorSchedulerComponent> ent)
|
|
||||||
{
|
|
||||||
var swarmWeights = _prototypeManager.Index(ent.Comp.Config);
|
|
||||||
GameTicker.StartGameRule(swarmWeights.Pick(RobustRandom));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,22 +1,20 @@
|
|||||||
using Content.Server.GameTicking;
|
using Content.Server.GameTicking;
|
||||||
using Content.Server.GameTicking.Rules;
|
using Content.Server.GameTicking.Rules;
|
||||||
using Content.Server.GameTicking.Rules.Components;
|
|
||||||
using Content.Server.StationEvents.Components;
|
using Content.Server.StationEvents.Components;
|
||||||
using Content.Server.StationEvents.Events;
|
|
||||||
using Content.Shared.CCVar;
|
|
||||||
using Content.Shared.GameTicking.Components;
|
using Content.Shared.GameTicking.Components;
|
||||||
using Robust.Shared.Configuration;
|
|
||||||
using Robust.Shared.Random;
|
using Robust.Shared.Random;
|
||||||
|
|
||||||
namespace Content.Server.StationEvents;
|
namespace Content.Server.StationEvents;
|
||||||
|
|
||||||
public sealed class RampingStationEventSchedulerSystem : GameRuleSystem<RampingStationEventSchedulerComponent>
|
public sealed class RampingStationEventSchedulerSystem : GameRuleSystem<RampingStationEventSchedulerComponent>
|
||||||
{
|
{
|
||||||
[Dependency] private readonly IConfigurationManager _cfg = default!;
|
|
||||||
[Dependency] private readonly IRobustRandom _random = default!;
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
[Dependency] private readonly EventManagerSystem _event = default!;
|
[Dependency] private readonly EventManagerSystem _event = default!;
|
||||||
[Dependency] private readonly GameTicker _gameTicker = default!;
|
[Dependency] private readonly GameTicker _gameTicker = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the ChaosModifier which increases as round time increases to a point.
|
||||||
|
/// </summary>
|
||||||
public float GetChaosModifier(EntityUid uid, RampingStationEventSchedulerComponent component)
|
public float GetChaosModifier(EntityUid uid, RampingStationEventSchedulerComponent component)
|
||||||
{
|
{
|
||||||
var roundTime = (float) _gameTicker.RoundDuration().TotalSeconds;
|
var roundTime = (float) _gameTicker.RoundDuration().TotalSeconds;
|
||||||
@@ -30,14 +28,11 @@ public sealed class RampingStationEventSchedulerSystem : GameRuleSystem<RampingS
|
|||||||
{
|
{
|
||||||
base.Started(uid, component, gameRule, args);
|
base.Started(uid, component, gameRule, args);
|
||||||
|
|
||||||
var avgChaos = _cfg.GetCVar(CCVars.EventsRampingAverageChaos);
|
|
||||||
var avgTime = _cfg.GetCVar(CCVars.EventsRampingAverageEndTime);
|
|
||||||
|
|
||||||
// Worlds shittiest probability distribution
|
// Worlds shittiest probability distribution
|
||||||
// Got a complaint? Send them to
|
// 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)
|
// 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;
|
component.StartingChaos = component.MaxChaos / 10;
|
||||||
|
|
||||||
PickNextEventTime(uid, component);
|
PickNextEventTime(uid, component);
|
||||||
@@ -54,19 +49,22 @@ public sealed class RampingStationEventSchedulerSystem : GameRuleSystem<RampingS
|
|||||||
while (query.MoveNext(out var uid, out var scheduler, out var gameRule))
|
while (query.MoveNext(out var uid, out var scheduler, out var gameRule))
|
||||||
{
|
{
|
||||||
if (!GameTicker.IsGameRuleActive(uid, gameRule))
|
if (!GameTicker.IsGameRuleActive(uid, gameRule))
|
||||||
return;
|
continue;
|
||||||
|
|
||||||
if (scheduler.TimeUntilNextEvent > 0f)
|
if (scheduler.TimeUntilNextEvent > 0f)
|
||||||
{
|
{
|
||||||
scheduler.TimeUntilNextEvent -= frameTime;
|
scheduler.TimeUntilNextEvent -= frameTime;
|
||||||
return;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
PickNextEventTime(uid, scheduler);
|
PickNextEventTime(uid, scheduler);
|
||||||
_event.RunRandomEvent();
|
_event.RunRandomEvent(scheduler.ScheduledGameRules);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the timing of the next event addition.
|
||||||
|
/// </summary>
|
||||||
private void PickNextEventTime(EntityUid uid, RampingStationEventSchedulerComponent component)
|
private void PickNextEventTime(EntityUid uid, RampingStationEventSchedulerComponent component)
|
||||||
{
|
{
|
||||||
var mod = GetChaosModifier(uid, component);
|
var mod = GetChaosModifier(uid, component);
|
||||||
|
|||||||
@@ -110,32 +110,6 @@ namespace Content.Shared.CCVar
|
|||||||
public static readonly CVarDef<bool>
|
public static readonly CVarDef<bool>
|
||||||
EventsEnabled = CVarDef.Create("events.enabled", true, CVar.ARCHIVE | CVar.SERVERONLY);
|
EventsEnabled = CVarDef.Create("events.enabled", true, CVar.ARCHIVE | CVar.SERVERONLY);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 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.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly CVarDef<float>
|
|
||||||
EventsRampingAverageEndTime = CVarDef.Create("events.ramping_average_end_time", 40f, CVar.ARCHIVE | CVar.SERVERONLY);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Average ending chaos modifier for the ramping event scheduler.
|
|
||||||
/// Max chaos chosen for a round will deviate from this
|
|
||||||
/// </summary>
|
|
||||||
public static readonly CVarDef<float>
|
|
||||||
EventsRampingAverageChaos = CVarDef.Create("events.ramping_average_chaos", 6f, CVar.ARCHIVE | CVar.SERVERONLY);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Minimum time between meteor swarms in minutes.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly CVarDef<float>
|
|
||||||
MeteorSwarmMinTime = CVarDef.Create("events.meteor_swarm_min_time", 12.5f, CVar.ARCHIVE | CVar.SERVERONLY);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Maximum time between meteor swarms in minutes.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly CVarDef<float>
|
|
||||||
MeteorSwarmMaxTime = CVarDef.Create("events.meteor_swarm_max_time", 17.5f, CVar.ARCHIVE | CVar.SERVERONLY);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Game
|
* Game
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,2 +1,5 @@
|
|||||||
all-at-once-title = All at once
|
all-at-once-title = All at once
|
||||||
all-at-once-description = It's just not your day...
|
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.
|
||||||
@@ -1,2 +1,5 @@
|
|||||||
survival-title = Survival
|
survival-title = Survival
|
||||||
survival-description = No internal threats, but how long can the station survive increasingly chaotic and frequent events?
|
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!
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
zombie-title = Zombies
|
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.
|
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-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.
|
zombie-no-one-ready = No players readied up! Can't start Zombies.
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,22 @@
|
|||||||
|
# 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
|
||||||
|
- id: GiftsFireProtection
|
||||||
|
- id: GiftsJanitor
|
||||||
|
- id: GiftsMedical
|
||||||
|
- id: GiftsPizzaPartyLarge
|
||||||
|
- id: GiftsPizzaPartySmall
|
||||||
|
- id: GiftsSecurityGuns
|
||||||
|
- id: GiftsSecurityRiot
|
||||||
|
- id: GiftsSpacingSupplies
|
||||||
|
- id: GiftsVendingRestock
|
||||||
|
|
||||||
|
# Game Rules
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: CargoGiftsBase
|
id: CargoGiftsBase
|
||||||
parent: BaseGameRule
|
parent: BaseGameRule
|
||||||
|
|||||||
@@ -1,3 +1,40 @@
|
|||||||
|
- 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: 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
|
- type: entity
|
||||||
id: BaseStationEvent
|
id: BaseStationEvent
|
||||||
parent: BaseGameRule
|
parent: BaseGameRule
|
||||||
@@ -526,45 +563,6 @@
|
|||||||
sounds:
|
sounds:
|
||||||
collection: Paracusia
|
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
|
- type: entity
|
||||||
parent: BaseGameRule
|
parent: BaseGameRule
|
||||||
id: IonStorm
|
id: IonStorm
|
||||||
|
|||||||
@@ -1,21 +1,39 @@
|
|||||||
- type: entity
|
# Event Tables
|
||||||
parent: BaseGameRule
|
|
||||||
id: GameRuleMeteorScheduler
|
|
||||||
components:
|
|
||||||
- type: GameRule
|
|
||||||
minPlayers: 25
|
|
||||||
cancelPresetOnTooFewPlayers: false
|
|
||||||
- type: MeteorScheduler
|
|
||||||
|
|
||||||
- type: weightedRandomEntity
|
- type: entityTable
|
||||||
id: DefaultConfig
|
id: MeteorSwarmDustEventsTable
|
||||||
weights:
|
table: !type:AllSelector # we need to pass a list of rules, since rules have further restrictions to consider via StationEventComp
|
||||||
GameRuleSpaceDustMinor: 44
|
children:
|
||||||
GameRuleSpaceDustMajor: 22
|
- id: GameRuleSpaceDustMinor
|
||||||
GameRuleMeteorSwarmSmall: 18
|
- id: GameRuleSpaceDustMajor
|
||||||
GameRuleMeteorSwarmMedium: 10
|
|
||||||
GameRuleMeteorSwarmLarge: 5
|
- type: entityTable
|
||||||
GameRuleUristSwarm: 0.05
|
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
|
- type: weightedRandomEntity
|
||||||
id: MeteorSpawnAsteroidWallTable
|
id: MeteorSpawnAsteroidWallTable
|
||||||
@@ -29,7 +47,46 @@
|
|||||||
AsteroidRockPlasma: 2
|
AsteroidRockPlasma: 2
|
||||||
AsteroidRockDiamond: 2
|
AsteroidRockDiamond: 2
|
||||||
AsteroidRockUranium: 0.5
|
AsteroidRockUranium: 0.5
|
||||||
AsteroidRockBananium: 0.5
|
AsteroidRockBananium: 0.5
|
||||||
|
|
||||||
|
# Event Schedulers
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: BaseGameRule
|
||||||
|
id: MeteorSwarmScheduler
|
||||||
|
components:
|
||||||
|
- type: GameRule
|
||||||
|
- type: BasicStationEventScheduler
|
||||||
|
minimumTimeUntilFirstEvent: 300 # 5 min
|
||||||
|
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: 300 # 5 min
|
||||||
|
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
|
||||||
|
scheduledGameRules: !type:NestedSelector
|
||||||
|
tableId: BasicMeteorSwarmEventsTable
|
||||||
|
|
||||||
|
# Game Rules
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: BaseGameRule
|
parent: BaseGameRule
|
||||||
@@ -37,12 +94,19 @@
|
|||||||
abstract: true
|
abstract: true
|
||||||
components:
|
components:
|
||||||
- type: GameRule
|
- type: GameRule
|
||||||
|
- type: StationEvent
|
||||||
|
earliestStart: 12
|
||||||
|
minimumPlayers: 25
|
||||||
- type: MeteorSwarm
|
- type: MeteorSwarm
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: GameRuleMeteorSwarm
|
parent: GameRuleMeteorSwarm
|
||||||
id: GameRuleSpaceDustMinor
|
id: GameRuleSpaceDustMinor
|
||||||
components:
|
components:
|
||||||
|
- type: StationEvent
|
||||||
|
weight: 44
|
||||||
|
earliestStart: 2
|
||||||
|
minimumPlayers: 0
|
||||||
- type: MeteorSwarm
|
- type: MeteorSwarm
|
||||||
announcement: null
|
announcement: null
|
||||||
announcementSound: null
|
announcementSound: null
|
||||||
@@ -60,6 +124,9 @@
|
|||||||
parent: GameRuleMeteorSwarm
|
parent: GameRuleMeteorSwarm
|
||||||
id: GameRuleSpaceDustMajor
|
id: GameRuleSpaceDustMajor
|
||||||
components:
|
components:
|
||||||
|
- type: StationEvent
|
||||||
|
weight: 22
|
||||||
|
minimumPlayers: 0
|
||||||
- type: MeteorSwarm
|
- type: MeteorSwarm
|
||||||
announcement: station-event-space-dust-start-announcement
|
announcement: station-event-space-dust-start-announcement
|
||||||
announcementSound: /Audio/Announcements/attention.ogg
|
announcementSound: /Audio/Announcements/attention.ogg
|
||||||
@@ -77,6 +144,9 @@
|
|||||||
parent: GameRuleMeteorSwarm
|
parent: GameRuleMeteorSwarm
|
||||||
id: GameRuleMeteorSwarmSmall
|
id: GameRuleMeteorSwarmSmall
|
||||||
components:
|
components:
|
||||||
|
- type: StationEvent
|
||||||
|
weight: 18
|
||||||
|
minimumPlayers: 15
|
||||||
- type: MeteorSwarm
|
- type: MeteorSwarm
|
||||||
meteors:
|
meteors:
|
||||||
MeteorSmall: 7
|
MeteorSmall: 7
|
||||||
@@ -86,6 +156,8 @@
|
|||||||
parent: GameRuleMeteorSwarm
|
parent: GameRuleMeteorSwarm
|
||||||
id: GameRuleMeteorSwarmMedium
|
id: GameRuleMeteorSwarmMedium
|
||||||
components:
|
components:
|
||||||
|
- type: StationEvent
|
||||||
|
weight: 10
|
||||||
- type: MeteorSwarm
|
- type: MeteorSwarm
|
||||||
meteors:
|
meteors:
|
||||||
MeteorSmall: 3
|
MeteorSmall: 3
|
||||||
@@ -96,6 +168,8 @@
|
|||||||
parent: GameRuleMeteorSwarm
|
parent: GameRuleMeteorSwarm
|
||||||
id: GameRuleMeteorSwarmLarge
|
id: GameRuleMeteorSwarmLarge
|
||||||
components:
|
components:
|
||||||
|
- type: StationEvent
|
||||||
|
weight: 5
|
||||||
- type: MeteorSwarm
|
- type: MeteorSwarm
|
||||||
meteors:
|
meteors:
|
||||||
MeteorSmall: 2
|
MeteorSmall: 2
|
||||||
@@ -106,6 +180,8 @@
|
|||||||
parent: GameRuleMeteorSwarm
|
parent: GameRuleMeteorSwarm
|
||||||
id: GameRuleUristSwarm
|
id: GameRuleUristSwarm
|
||||||
components:
|
components:
|
||||||
|
- type: StationEvent
|
||||||
|
weight: 0.05
|
||||||
- type: MeteorSwarm
|
- type: MeteorSwarm
|
||||||
announcement: station-event-meteor-urist-start-announcement
|
announcement: station-event-meteor-urist-start-announcement
|
||||||
announcementSound: /Audio/Announcements/attention.ogg
|
announcementSound: /Audio/Announcements/attention.ogg
|
||||||
@@ -117,3 +193,42 @@
|
|||||||
meteorsPerWave:
|
meteorsPerWave:
|
||||||
min: 10
|
min: 10
|
||||||
max: 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
|
||||||
|
|||||||
@@ -262,17 +262,68 @@
|
|||||||
prototype: InitialInfected
|
prototype: InitialInfected
|
||||||
|
|
||||||
# event schedulers
|
# 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: 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
|
- type: entity
|
||||||
id: BasicStationEventScheduler
|
id: BasicStationEventScheduler
|
||||||
parent: BaseGameRule
|
parent: BaseGameRule
|
||||||
components:
|
components:
|
||||||
- type: BasicStationEventScheduler
|
- type: BasicStationEventScheduler
|
||||||
|
scheduledGameRules: !type:NestedSelector
|
||||||
|
tableId: BasicGameRulesTable
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: RampingStationEventScheduler
|
id: RampingStationEventScheduler
|
||||||
parent: BaseGameRule
|
parent: BaseGameRule
|
||||||
components:
|
components:
|
||||||
- type: RampingStationEventScheduler
|
- type: RampingStationEventScheduler
|
||||||
|
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
|
||||||
|
minimumTimeUntilFirstEvent: 1200 # 20 mins
|
||||||
|
minMaxEventTiming:
|
||||||
|
min: 600 # 10 mins
|
||||||
|
max: 1800 # 30 mins
|
||||||
|
scheduledGameRules: !type:NestedSelector
|
||||||
|
tableId: SpaceTrafficControlTable
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: SpaceTrafficControlFriendlyEventScheduler
|
||||||
|
parent: BaseGameRule
|
||||||
|
components:
|
||||||
|
- type: BasicStationEventScheduler
|
||||||
|
minimumTimeUntilFirstEvent: 1200 # 20 mins
|
||||||
|
minMaxEventTiming:
|
||||||
|
min: 600 # 10 mins
|
||||||
|
max: 1800 # 30 mins
|
||||||
|
scheduledGameRules: !type:NestedSelector
|
||||||
|
tableId: UnknownShuttlesFriendlyTable
|
||||||
|
|
||||||
# variation passes
|
# variation passes
|
||||||
- type: entity
|
- type: entity
|
||||||
|
|||||||
@@ -1,3 +1,28 @@
|
|||||||
|
# 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
|
||||||
|
- id: UnknownShuttleTravelingCuisine
|
||||||
|
- id: UnknownShuttleDisasterEvacPod
|
||||||
|
- 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
|
||||||
|
|
||||||
|
- type: entityTable
|
||||||
|
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
|
||||||
|
|
||||||
|
# Shuttle Game Rules
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
abstract: true
|
abstract: true
|
||||||
parent: BaseGameRule
|
parent: BaseGameRule
|
||||||
|
|||||||
@@ -6,12 +6,31 @@
|
|||||||
showInVote: false # secret
|
showInVote: false # secret
|
||||||
description: survival-description
|
description: survival-description
|
||||||
rules:
|
rules:
|
||||||
|
- MeteorSwarmScheduler
|
||||||
- RampingStationEventScheduler
|
- 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:
|
||||||
|
- KesslerSyndromeScheduler
|
||||||
|
- RampingStationEventScheduler
|
||||||
|
- SpaceTrafficControlEventScheduler
|
||||||
- BasicRoundstartVariation
|
- BasicRoundstartVariation
|
||||||
|
|
||||||
- type: gamePreset
|
- type: gamePreset
|
||||||
id: AllAtOnce
|
id: AllAtOnce
|
||||||
|
alias:
|
||||||
|
- all
|
||||||
name: all-at-once-title
|
name: all-at-once-title
|
||||||
description: all-at-once-description
|
description: all-at-once-description
|
||||||
showInVote: false
|
showInVote: false
|
||||||
@@ -20,8 +39,34 @@
|
|||||||
- Traitor
|
- Traitor
|
||||||
- Revolutionary
|
- Revolutionary
|
||||||
- Zombie
|
- Zombie
|
||||||
|
- KesslerSyndromeScheduler
|
||||||
- RampingStationEventScheduler
|
- RampingStationEventScheduler
|
||||||
- GameRuleMeteorScheduler
|
- SpaceTrafficControlEventScheduler
|
||||||
|
- BasicRoundstartVariation
|
||||||
|
|
||||||
|
- 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
|
||||||
|
rules:
|
||||||
|
- Nukeops
|
||||||
|
- Traitor
|
||||||
|
- Revolutionary
|
||||||
|
- Zombie
|
||||||
|
- BasicStationEventScheduler
|
||||||
|
- KesslerSyndromeScheduler
|
||||||
|
- MeteorSwarmMildScheduler
|
||||||
|
- MeteorSwarmScheduler
|
||||||
|
- RampingStationEventScheduler
|
||||||
|
- SpaceTrafficControlEventScheduler
|
||||||
|
- SpaceTrafficControlFriendlyEventScheduler
|
||||||
|
- BasicRoundstartVariation
|
||||||
|
|
||||||
- type: gamePreset
|
- type: gamePreset
|
||||||
id: Extended
|
id: Extended
|
||||||
@@ -33,7 +78,8 @@
|
|||||||
description: extended-description
|
description: extended-description
|
||||||
rules:
|
rules:
|
||||||
- BasicStationEventScheduler
|
- BasicStationEventScheduler
|
||||||
- GameRuleMeteorScheduler
|
- MeteorSwarmScheduler
|
||||||
|
- SpaceTrafficControlEventScheduler
|
||||||
- BasicRoundstartVariation
|
- BasicRoundstartVariation
|
||||||
|
|
||||||
- type: gamePreset
|
- type: gamePreset
|
||||||
@@ -45,6 +91,7 @@
|
|||||||
showInVote: false #4boring4vote
|
showInVote: false #4boring4vote
|
||||||
description: greenshift-description
|
description: greenshift-description
|
||||||
rules:
|
rules:
|
||||||
|
- SpaceTrafficControlFriendlyEventScheduler
|
||||||
- BasicRoundstartVariation
|
- BasicRoundstartVariation
|
||||||
|
|
||||||
- type: gamePreset
|
- type: gamePreset
|
||||||
@@ -67,7 +114,9 @@
|
|||||||
description: secret-description
|
description: secret-description
|
||||||
rules:
|
rules:
|
||||||
- BasicStationEventScheduler
|
- BasicStationEventScheduler
|
||||||
- GameRuleMeteorScheduler
|
- MeteorSwarmScheduler
|
||||||
|
- SpaceTrafficControlEventScheduler
|
||||||
|
- BasicRoundstartVariation
|
||||||
|
|
||||||
- type: gamePreset
|
- type: gamePreset
|
||||||
id: SecretGreenshift #For Admin Use: Runs Greenshift but shows "Secret" in lobby.
|
id: SecretGreenshift #For Admin Use: Runs Greenshift but shows "Secret" in lobby.
|
||||||
@@ -76,6 +125,9 @@
|
|||||||
name: secret-title
|
name: secret-title
|
||||||
showInVote: false #Admin Use
|
showInVote: false #Admin Use
|
||||||
description: secret-description
|
description: secret-description
|
||||||
|
rules:
|
||||||
|
- SpaceTrafficControlFriendlyEventScheduler
|
||||||
|
- BasicRoundstartVariation
|
||||||
|
|
||||||
- type: gamePreset
|
- type: gamePreset
|
||||||
id: Sandbox
|
id: Sandbox
|
||||||
@@ -92,6 +144,7 @@
|
|||||||
id: Traitor
|
id: Traitor
|
||||||
alias:
|
alias:
|
||||||
- traitor
|
- traitor
|
||||||
|
- tator
|
||||||
name: traitor-title
|
name: traitor-title
|
||||||
description: traitor-description
|
description: traitor-description
|
||||||
showInVote: false
|
showInVote: false
|
||||||
@@ -99,7 +152,8 @@
|
|||||||
- Traitor
|
- Traitor
|
||||||
- SubGamemodesRule
|
- SubGamemodesRule
|
||||||
- BasicStationEventScheduler
|
- BasicStationEventScheduler
|
||||||
- GameRuleMeteorScheduler
|
- MeteorSwarmScheduler
|
||||||
|
- SpaceTrafficControlEventScheduler
|
||||||
- BasicRoundstartVariation
|
- BasicRoundstartVariation
|
||||||
|
|
||||||
- type: gamePreset
|
- type: gamePreset
|
||||||
@@ -126,7 +180,8 @@
|
|||||||
- Nukeops
|
- Nukeops
|
||||||
- SubGamemodesRule
|
- SubGamemodesRule
|
||||||
- BasicStationEventScheduler
|
- BasicStationEventScheduler
|
||||||
- GameRuleMeteorScheduler
|
- MeteorSwarmScheduler
|
||||||
|
- SpaceTrafficControlEventScheduler
|
||||||
- BasicRoundstartVariation
|
- BasicRoundstartVariation
|
||||||
|
|
||||||
- type: gamePreset
|
- type: gamePreset
|
||||||
@@ -142,7 +197,8 @@
|
|||||||
- Revolutionary
|
- Revolutionary
|
||||||
- SubGamemodesRule
|
- SubGamemodesRule
|
||||||
- BasicStationEventScheduler
|
- BasicStationEventScheduler
|
||||||
- GameRuleMeteorScheduler
|
- MeteorSwarmScheduler
|
||||||
|
- SpaceTrafficControlEventScheduler
|
||||||
- BasicRoundstartVariation
|
- BasicRoundstartVariation
|
||||||
|
|
||||||
- type: gamePreset
|
- type: gamePreset
|
||||||
@@ -159,5 +215,22 @@
|
|||||||
rules:
|
rules:
|
||||||
- Zombie
|
- Zombie
|
||||||
- BasicStationEventScheduler
|
- BasicStationEventScheduler
|
||||||
- GameRuleMeteorScheduler
|
- MeteorSwarmScheduler
|
||||||
|
- SpaceTrafficControlEventScheduler
|
||||||
|
- BasicRoundstartVariation
|
||||||
|
|
||||||
|
- type: gamePreset
|
||||||
|
id: Zombieteors
|
||||||
|
alias:
|
||||||
|
- zombieteors
|
||||||
|
- zombombies
|
||||||
|
- meteombies
|
||||||
|
name: zombieteors-title
|
||||||
|
description: zombieteors-description
|
||||||
|
showInVote: false
|
||||||
|
rules:
|
||||||
|
- Zombie
|
||||||
|
- BasicStationEventScheduler
|
||||||
|
- KesslerSyndromeScheduler
|
||||||
|
- SpaceTrafficControlEventScheduler
|
||||||
- BasicRoundstartVariation
|
- BasicRoundstartVariation
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
weights:
|
weights:
|
||||||
Nukeops: 0.20
|
Nukeops: 0.20
|
||||||
Traitor: 0.60
|
Traitor: 0.60
|
||||||
Zombie: 0.05
|
Zombie: 0.04
|
||||||
Survival: 0.10
|
Zombieteors: 0.01
|
||||||
|
Survival: 0.09
|
||||||
|
KesslerSyndrome: 0.01
|
||||||
Revolutionary: 0.05
|
Revolutionary: 0.05
|
||||||
|
|||||||
Reference in New Issue
Block a user