Implement game rule configs. Game rules are now proper prototypes instead of just an alias for a system. (#8539)

This commit is contained in:
Moony
2022-06-11 22:27:05 -05:00
committed by GitHub
parent de9c5084e0
commit 58ddb19cd2
16 changed files with 139 additions and 29 deletions

View File

@@ -0,0 +1,13 @@
namespace Content.Server.GameTicking.Rules.Configurations;
/// <summary>
/// Configures a game rule, providing information like what maps to use or how long to run.
/// </summary>
[ImplicitDataDefinitionForInheritors]
public abstract class GameRuleConfiguration
{
/// <summary>
/// The game rule this configuration is intended for.
/// </summary>
public abstract string Id { get; }
}

View File

@@ -0,0 +1,14 @@
using JetBrains.Annotations;
namespace Content.Server.GameTicking.Rules.Configurations;
/// <summary>
/// A generic configuration, for game rules that don't have special config data.
/// </summary>
[UsedImplicitly]
public sealed class GenericGameRuleConfiguration : GameRuleConfiguration
{
[DataField("id", required: true)]
private string _id = default!;
public override string Id => _id;
}

View File

@@ -0,0 +1,17 @@
using JetBrains.Annotations;
namespace Content.Server.GameTicking.Rules.Configurations;
/// <summary>
/// Configures the <see cref="InactivityTimeRestartRuleSystem"/> game rule.
/// </summary>
[UsedImplicitly]
public sealed class InactivityGameRuleConfiguration : GameRuleConfiguration
{
public override string Id => "InactivityTimeRestart"; // The value for this in the system isn't static and can't be made static. RIP.
[DataField("inactivityMaxTime", required: true)]
public TimeSpan InactivityMaxTime { get; }
[DataField("roundEndDelay", required: true)]
public TimeSpan RoundEndDelay { get; }
}

View File

@@ -0,0 +1,17 @@
using JetBrains.Annotations;
namespace Content.Server.GameTicking.Rules.Configurations;
/// <summary>
/// Configures the <see cref="InactivityTimeRestartRuleSystem"/> game rule.
/// </summary>
[UsedImplicitly]
public sealed class MaxTimeRestartRuleConfiguration : GameRuleConfiguration
{
public override string Id => "MaxTimeRestart"; // The value for this in the system isn't static and can't be made static. RIP.
[DataField("roundMaxTime", required: true)]
public TimeSpan RoundMaxTime { get; }
[DataField("roundEndDelay", required: true)]
public TimeSpan RoundEndDelay { get; }
}

View File

@@ -1,4 +1,5 @@
using Content.Server.Chat.Managers;
using Content.Server.GameTicking.Rules.Configurations;
using Content.Shared.CCVar;
using Content.Shared.Damage;
using Content.Shared.MobState.Components;
@@ -33,14 +34,14 @@ public sealed class DeathMatchRuleSystem : GameRuleSystem
SubscribeLocalEvent<DamageChangedEvent>(OnHealthChanged);
}
public override void Started()
public override void Started(GameRuleConfiguration _)
{
_chatManager.DispatchServerAnnouncement(Loc.GetString("rule-death-match-added-announcement"));
_playerManager.PlayerStatusChanged += OnPlayerStatusChanged;
}
public override void Ended()
public override void Ended(GameRuleConfiguration _)
{
_deadCheckTimer = null;
_restartTimer = null;

View File

@@ -1,3 +1,4 @@
using Content.Server.GameTicking.Rules.Configurations;
using Robust.Shared.Prototypes;
namespace Content.Server.GameTicking.Rules;
@@ -5,6 +6,9 @@ namespace Content.Server.GameTicking.Rules;
[Prototype("gameRule")]
public sealed class GameRulePrototype : IPrototype
{
[IdDataFieldAttribute]
[IdDataField]
public string ID { get; } = default!;
[DataField("config", required: true)]
public GameRuleConfiguration Configuration { get; } = default!;
}

View File

@@ -1,3 +1,4 @@
using Content.Server.GameTicking.Rules.Configurations;
using JetBrains.Annotations;
namespace Content.Server.GameTicking.Rules;
@@ -31,7 +32,7 @@ public abstract class GameRuleSystem : EntitySystem
private void OnGameRuleAdded(GameRuleAddedEvent ev)
{
if (ev.Rule.ID != Prototype)
if (ev.Rule.Configuration.Id != Prototype)
return;
Enabled = true;
@@ -39,28 +40,28 @@ public abstract class GameRuleSystem : EntitySystem
private void OnGameRuleStarted(GameRuleStartedEvent ev)
{
if (ev.Rule.ID != Prototype)
if (ev.Rule.Configuration.Id != Prototype)
return;
Started();
Started(ev.Rule.Configuration);
}
private void OnGameRuleEnded(GameRuleEndedEvent ev)
{
if (ev.Rule.ID != Prototype)
if (ev.Rule.Configuration.Id != Prototype)
return;
Enabled = false;
Ended();
Ended(ev.Rule.Configuration);
}
/// <summary>
/// Called when the game rule has been started..
/// </summary>
public abstract void Started();
public abstract void Started(GameRuleConfiguration configuration);
/// <summary>
/// Called when the game rule has ended..
/// </summary>
public abstract void Ended();
public abstract void Ended(GameRuleConfiguration configuration);
}

View File

@@ -1,5 +1,6 @@
using System.Threading;
using Content.Server.Chat.Managers;
using Content.Server.GameTicking.Rules.Configurations;
using Robust.Server.Player;
using Timer = Robust.Shared.Timing.Timer;
@@ -24,12 +25,16 @@ public sealed class InactivityTimeRestartRuleSystem : GameRuleSystem
SubscribeLocalEvent<GameRunLevelChangedEvent>(RunLevelChanged);
}
public override void Started()
public override void Started(GameRuleConfiguration config)
{
if (config is not InactivityGameRuleConfiguration inactivityConfig)
return;
InactivityMaxTime = inactivityConfig.InactivityMaxTime;
RoundEndDelay = inactivityConfig.RoundEndDelay;
_playerManager.PlayerStatusChanged += PlayerStatusChanged;
}
public override void Ended()
public override void Ended(GameRuleConfiguration _)
{
_playerManager.PlayerStatusChanged -= PlayerStatusChanged;

View File

@@ -1,5 +1,6 @@
using System.Threading;
using Content.Server.Chat.Managers;
using Content.Server.GameTicking.Rules.Configurations;
using Timer = Robust.Shared.Timing.Timer;
namespace Content.Server.GameTicking.Rules;
@@ -22,17 +23,19 @@ public sealed class MaxTimeRestartRuleSystem : GameRuleSystem
SubscribeLocalEvent<GameRunLevelChangedEvent>(RunLevelChanged);
}
public override void Started()
public override void Started(GameRuleConfiguration config)
{
if (config is not MaxTimeRestartRuleConfiguration maxTimeRestartConfig)
return;
RoundMaxTime = maxTimeRestartConfig.RoundMaxTime;
RoundEndDelay = maxTimeRestartConfig.RoundEndDelay;
if(GameTicker.RunLevel == GameRunLevel.InRound)
RestartTimer();
}
public override void Ended()
public override void Ended(GameRuleConfiguration _)
{
RoundMaxTime = TimeSpan.FromMinutes(5);
RoundEndDelay = TimeSpan.FromMinutes(10);
StopTimer();
}

View File

@@ -1,6 +1,7 @@
using System.Linq;
using Content.Server.CharacterAppearance.Components;
using Content.Server.Chat.Managers;
using Content.Server.GameTicking.Rules.Configurations;
using Content.Server.Nuke;
using Content.Server.Players;
using Content.Server.Roles;
@@ -298,10 +299,10 @@ public sealed class NukeopsRuleSystem : GameRuleSystem
}
public override void Started()
public override void Started(GameRuleConfiguration _)
{
_opsWon = false;
}
public override void Ended() { }
public override void Ended(GameRuleConfiguration _) { }
}

View File

@@ -1,3 +1,4 @@
using Content.Server.GameTicking.Rules.Configurations;
using Content.Server.Sandbox;
namespace Content.Server.GameTicking.Rules;
@@ -8,12 +9,12 @@ public sealed class SandboxRuleSystem : GameRuleSystem
public override string Prototype => "Sandbox";
public override void Started()
public override void Started(GameRuleConfiguration _)
{
_sandbox.IsSandboxEnabled = true;
}
public override void Ended()
public override void Ended(GameRuleConfiguration _)
{
_sandbox.IsSandboxEnabled = false;
}

View File

@@ -1,5 +1,6 @@
using System.Linq;
using Content.Server.GameTicking.Presets;
using Content.Server.GameTicking.Rules.Configurations;
using Content.Shared.Random;
using Content.Shared.Random.Helpers;
using Robust.Shared.Prototypes;
@@ -15,12 +16,12 @@ public sealed class SecretRuleSystem : GameRuleSystem
public override string Prototype => "Secret";
public override void Started()
public override void Started(GameRuleConfiguration _)
{
PickRule();
}
public override void Ended()
public override void Ended(GameRuleConfiguration _)
{
// noop
// Preset should already handle it.

View File

@@ -1,6 +1,7 @@
using System.Linq;
using System.Threading;
using Content.Server.Chat.Managers;
using Content.Server.GameTicking.Rules.Configurations;
using Content.Server.Players;
using Content.Server.Roles;
using Content.Server.Station.Components;
@@ -202,7 +203,7 @@ public sealed class SuspicionRuleSystem : GameRuleSystem
}
}
public override void Started()
public override void Started(GameRuleConfiguration _)
{
_playerManager.PlayerStatusChanged += PlayerManagerOnPlayerStatusChanged;
@@ -268,7 +269,7 @@ public sealed class SuspicionRuleSystem : GameRuleSystem
Timer.SpawnRepeating(DeadCheckDelay, CheckWinConditions, _checkTimerCancel.Token);
}
public override void Ended()
public override void Ended(GameRuleConfiguration _)
{
_doorSystem.AccessType = SharedDoorSystem.AccessTypes.Id;
EndTime = null;

View File

@@ -1,6 +1,7 @@
using System.Linq;
using Content.Server.Atmos.EntitySystems;
using Content.Server.Chat.Managers;
using Content.Server.GameTicking.Rules.Configurations;
using Content.Server.Hands.Components;
using Content.Server.PDA;
using Content.Server.Players;
@@ -196,14 +197,14 @@ public sealed class TraitorDeathMatchRuleSystem : GameRuleSystem
ev.AddLine(string.Join('\n', lines));
}
public override void Started()
public override void Started(GameRuleConfiguration _)
{
_restarter.RoundMaxTime = TimeSpan.FromMinutes(30);
_restarter.RestartTimer();
_safeToEndRound = true;
}
public override void Ended()
public override void Ended(GameRuleConfiguration _)
{
}

View File

@@ -1,5 +1,6 @@
using System.Linq;
using Content.Server.Chat.Managers;
using Content.Server.GameTicking.Rules.Configurations;
using Content.Server.Objectives.Interfaces;
using Content.Server.Players;
using Content.Server.Roles;
@@ -48,9 +49,9 @@ public sealed class TraitorRuleSystem : GameRuleSystem
SubscribeLocalEvent<RoundEndTextAppendEvent>(OnRoundEndText);
}
public override void Started() {}
public override void Started(GameRuleConfiguration _) {}
public override void Ended()
public override void Ended(GameRuleConfiguration _)
{
_traitors.Clear();
}

View File

@@ -1,29 +1,58 @@
- type: gameRule
id: DeathMatch
config:
!type:GenericGameRuleConfiguration
id: DeathMatch
- type: gameRule
id: InactivityTimeRestart
config:
!type:InactivityGameRuleConfiguration
inactivityMaxTime: 600
roundEndDelay: 10
- type: gameRule
id: MaxTimeRestart
config:
!type:MaxTimeRestartRuleConfiguration
roundMaxTime: 300
roundEndDelay: 10
- type: gameRule
id: Nukeops
config:
!type:GenericGameRuleConfiguration
id: Nukeops
- type: gameRule
id: Pirates
- type: gameRule
id: Suspicion
config:
!type:GenericGameRuleConfiguration
id: Suspicion
- type: gameRule
id: Traitor
config:
!type:GenericGameRuleConfiguration
id: Traitor
- type: gameRule
id: TraitorDeathMatch
config:
!type:GenericGameRuleConfiguration
id: TraitorDeathMatch
- type: gameRule
id: Sandbox
config:
!type:GenericGameRuleConfiguration
id: Sandbox
- type: gameRule
id: Secret
config:
!type:GenericGameRuleConfiguration
id: Secret