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

View File

@@ -1,3 +1,4 @@
using Content.Server.GameTicking.Rules.Configurations;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
namespace Content.Server.GameTicking.Rules; namespace Content.Server.GameTicking.Rules;
@@ -5,6 +6,9 @@ namespace Content.Server.GameTicking.Rules;
[Prototype("gameRule")] [Prototype("gameRule")]
public sealed class GameRulePrototype : IPrototype public sealed class GameRulePrototype : IPrototype
{ {
[IdDataFieldAttribute] [IdDataField]
public string ID { get; } = default!; 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; using JetBrains.Annotations;
namespace Content.Server.GameTicking.Rules; namespace Content.Server.GameTicking.Rules;
@@ -31,7 +32,7 @@ public abstract class GameRuleSystem : EntitySystem
private void OnGameRuleAdded(GameRuleAddedEvent ev) private void OnGameRuleAdded(GameRuleAddedEvent ev)
{ {
if (ev.Rule.ID != Prototype) if (ev.Rule.Configuration.Id != Prototype)
return; return;
Enabled = true; Enabled = true;
@@ -39,28 +40,28 @@ public abstract class GameRuleSystem : EntitySystem
private void OnGameRuleStarted(GameRuleStartedEvent ev) private void OnGameRuleStarted(GameRuleStartedEvent ev)
{ {
if (ev.Rule.ID != Prototype) if (ev.Rule.Configuration.Id != Prototype)
return; return;
Started(); Started(ev.Rule.Configuration);
} }
private void OnGameRuleEnded(GameRuleEndedEvent ev) private void OnGameRuleEnded(GameRuleEndedEvent ev)
{ {
if (ev.Rule.ID != Prototype) if (ev.Rule.Configuration.Id != Prototype)
return; return;
Enabled = false; Enabled = false;
Ended(); Ended(ev.Rule.Configuration);
} }
/// <summary> /// <summary>
/// Called when the game rule has been started.. /// Called when the game rule has been started..
/// </summary> /// </summary>
public abstract void Started(); public abstract void Started(GameRuleConfiguration configuration);
/// <summary> /// <summary>
/// Called when the game rule has ended.. /// Called when the game rule has ended..
/// </summary> /// </summary>
public abstract void Ended(); public abstract void Ended(GameRuleConfiguration configuration);
} }

View File

@@ -1,5 +1,6 @@
using System.Threading; using System.Threading;
using Content.Server.Chat.Managers; using Content.Server.Chat.Managers;
using Content.Server.GameTicking.Rules.Configurations;
using Robust.Server.Player; using Robust.Server.Player;
using Timer = Robust.Shared.Timing.Timer; using Timer = Robust.Shared.Timing.Timer;
@@ -24,12 +25,16 @@ public sealed class InactivityTimeRestartRuleSystem : GameRuleSystem
SubscribeLocalEvent<GameRunLevelChangedEvent>(RunLevelChanged); 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; _playerManager.PlayerStatusChanged += PlayerStatusChanged;
} }
public override void Ended() public override void Ended(GameRuleConfiguration _)
{ {
_playerManager.PlayerStatusChanged -= PlayerStatusChanged; _playerManager.PlayerStatusChanged -= PlayerStatusChanged;

View File

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

View File

@@ -1,6 +1,7 @@
using System.Linq; using System.Linq;
using Content.Server.CharacterAppearance.Components; using Content.Server.CharacterAppearance.Components;
using Content.Server.Chat.Managers; using Content.Server.Chat.Managers;
using Content.Server.GameTicking.Rules.Configurations;
using Content.Server.Nuke; using Content.Server.Nuke;
using Content.Server.Players; using Content.Server.Players;
using Content.Server.Roles; using Content.Server.Roles;
@@ -298,10 +299,10 @@ public sealed class NukeopsRuleSystem : GameRuleSystem
} }
public override void Started() public override void Started(GameRuleConfiguration _)
{ {
_opsWon = false; _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; using Content.Server.Sandbox;
namespace Content.Server.GameTicking.Rules; namespace Content.Server.GameTicking.Rules;
@@ -8,12 +9,12 @@ public sealed class SandboxRuleSystem : GameRuleSystem
public override string Prototype => "Sandbox"; public override string Prototype => "Sandbox";
public override void Started() public override void Started(GameRuleConfiguration _)
{ {
_sandbox.IsSandboxEnabled = true; _sandbox.IsSandboxEnabled = true;
} }
public override void Ended() public override void Ended(GameRuleConfiguration _)
{ {
_sandbox.IsSandboxEnabled = false; _sandbox.IsSandboxEnabled = false;
} }

View File

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

View File

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

View File

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

View File

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

View File

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