CatStation/Content.IntegrationTests/Tests/GameRules/FailAndStartPresetTest.cs
Princess Cheeseballs 2c6ffecf62
Move GameTicker to Shared (#45834)
* Scope creep my ass

* why was this shit not pushed????

* gone...

* fix that

* review plus buildd

* asfsafsafsafsafas

* grug

* burber

* I'll fix this later

* shrimply die

* also this

* it's snerf or snuthin

* assaads

* round snend

* aaaa

* fix this shit for real

* actually, don't start GameRules until MapInit now that I think aboot it.

* forgot u

* don't actually need this part nullable

* Deffer comp removal

* one liner

* do that too

* chungus

* Honestly makes more sense here, plus WHY are we doing all that shit on "GameRuleAdded" rather than GameRuleStarted(?)

* deferred removal :V

* aaaaaaaaaaaaaaa

* whhop

* Whoop

* better

* landmine that I placed for myself then forgot about lmao

* cleanup

* FUCKING `!`

* gotovo

* amogus

* please don't check by metadata I beg

* waawsasfdfsasfa

* sfafsasfafsas

* fdsaasffsasfa

* code

* fix

* fasasffasfasfsad

* chungaas

* I may be stupid

* gra

* graaaaaaaaaaaaaaaaa

* comment

* gra

* clearing is not predicted and would require major refactors, so don't cache on client.

* lame shit :P

* last holes

* nukeopsfsafsasafsfafsa

* why  was that shit public bruh

* bubrbgwahrghfaka

* dynamic

* revert change that did nothing lmao
2026-09-16 19:34:19 +00:00

156 lines
4.9 KiB
C#

#nullable enable
using Content.IntegrationTests.Fixtures;
using Content.Server.GameTicking;
using Content.Shared.CCVar;
using Content.Shared.GameTicking;
using Content.Shared.GameTicking.Components;
using Content.Shared.GameTicking.Prototypes;
using Robust.Shared.GameObjects;
namespace Content.IntegrationTests.Tests.GameRules;
[TestFixture]
public sealed class FailAndStartPresetTest : GameTest
{
[TestPrototypes]
private const string Prototypes = @"
- type: gamePreset
id: TestPreset
alias:
- nukeops
name: Test Preset
description: """"
showInVote: false
rules:
- TestRule
- type: gamePreset
id: TestPresetTenPlayers
alias:
- nukeops
name: Test Preset 10 players
description: """"
showInVote: false
rules:
- TestRuleTenPlayers
- type: entity
id: TestRule
parent: BaseGameRule
categories: [ GameRules ]
components:
- type: GameRule
minPlayers: 0
- type: TestRule
- type: entity
id: TestRuleTenPlayers
parent: BaseGameRule
categories: [ GameRules ]
components:
- type: GameRule
minPlayers: 10
- type: TestRule
";
public override PoolSettings PoolSettings => new()
{
Dirty = true,
DummyTicker = false,
Connected = true,
InLobby = true
};
/// <summary>
/// Test that a nuke ops gamemode can start after failing to start once.
/// </summary>
[Test]
public async Task FailAndStartTest()
{
var pair = Pair;
var server = pair.Server;
var client = pair.Client;
var entMan = server.EntMan;
var ticker = server.System<ServerGameTicker>();
server.System<TestRuleSystem>().Run = true;
Assert.That(server.CfgMan.GetCVar(CCVars.GridFill), Is.False);
Assert.That(server.CfgMan.GetCVar(CCVars.GameLobbyFallbackEnabled), Is.True);
Assert.That(server.CfgMan.GetCVar(CCVars.GameLobbyDefaultPreset), Is.EqualTo("secret"));
server.CfgMan.SetCVar(CCVars.GridFill, true);
server.CfgMan.SetCVar(CCVars.GameLobbyFallbackEnabled, false);
server.CfgMan.SetCVar(CCVars.GameLobbyDefaultPreset, "TestPreset");
// Initially in the lobby
Assert.That(ticker.RunLevel, Is.EqualTo(GameRunLevel.PreRoundLobby));
Assert.That(client.AttachedEntity, Is.Null);
Assert.That(ticker.PlayerGameStatuses[client.User!.Value], Is.EqualTo(PlayerGameStatus.NotReadyToPlay));
// Try to start nukeops without readying up
await pair.WaitCommand("setgamepreset TestPresetTenPlayers 9999");
await pair.WaitCommand("startround");
await pair.RunTicksSync(10);
// Game should not have started
Assert.That(ticker.RunLevel, Is.EqualTo(GameRunLevel.PreRoundLobby));
Assert.That(ticker.PlayerGameStatuses[client.User!.Value], Is.EqualTo(PlayerGameStatus.NotReadyToPlay));
Assert.That(!client.EntMan.EntityExists(client.AttachedEntity));
var player = pair.Player!.AttachedEntity;
Assert.That(!entMan.EntityExists(player));
// Ready up and start nukeops
await pair.WaitClientCommand("toggleready True");
Assert.That(ticker.PlayerGameStatuses[client.User!.Value], Is.EqualTo(PlayerGameStatus.ReadyToPlay));
await pair.WaitCommand("setgamepreset TestPreset 9999");
await pair.WaitCommand("startround");
await pair.RunTicksSync(10);
// Game should have started
Assert.That(ticker.RunLevel, Is.EqualTo(GameRunLevel.InRound));
Assert.That(ticker.PlayerGameStatuses[client.User!.Value], Is.EqualTo(PlayerGameStatus.JoinedGame));
Assert.That(client.EntMan.EntityExists(client.AttachedEntity));
player = pair.Player!.AttachedEntity!.Value;
Assert.That(entMan.EntityExists(player));
ticker.SetGamePreset((GamePresetPrototype?) null);
server.CfgMan.SetCVar(CCVars.GridFill, false);
server.CfgMan.SetCVar(CCVars.GameLobbyFallbackEnabled, true);
server.CfgMan.SetCVar(CCVars.GameLobbyDefaultPreset, "secret");
server.System<TestRuleSystem>().Run = false;
}
}
public sealed partial class TestRuleSystem : EntitySystem
{
public bool Run;
public override void Initialize()
{
SubscribeLocalEvent<RoundStartAttemptEvent>(OnRoundStartAttempt);
}
private void OnRoundStartAttempt(RoundStartAttemptEvent args)
{
if (!Run)
return;
if (args.Forced || args.Cancelled)
return;
var query = EntityQueryEnumerator<TestRuleComponent, GameRuleComponent>();
while (query.MoveNext(out _, out _, out var gameRule))
{
var minPlayers = gameRule.MinPlayers;
if (!gameRule.CancelPresetOnTooFewPlayers)
continue;
if (args.Players.Length >= minPlayers)
continue;
args.Cancel();
}
}
}
[RegisterComponent]
public sealed partial class TestRuleComponent : Component;