using Content.Server.Chat.Managers; using Content.Server.GameTicking.Rules.Components; namespace Content.Server.GameTicking.Rules; public abstract partial class GameRuleSystem : EntitySystem where T : IComponent { [Dependency] protected readonly IChatManager ChatManager = default!; [Dependency] protected readonly GameTicker GameTicker = default!; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnGameRuleAdded); SubscribeLocalEvent(OnGameRuleStarted); SubscribeLocalEvent(OnGameRuleEnded); } private void OnGameRuleAdded(EntityUid uid, T component, ref GameRuleAddedEvent args) { if (!TryComp(uid, out var ruleData)) return; Added(uid, component, ruleData, args); } private void OnGameRuleStarted(EntityUid uid, T component, ref GameRuleStartedEvent args) { if (!TryComp(uid, out var ruleData)) return; Started(uid, component, ruleData, args); } private void OnGameRuleEnded(EntityUid uid, T component, ref GameRuleEndedEvent args) { if (!TryComp(uid, out var ruleData)) return; Ended(uid, component, ruleData, args); } /// /// Called when the gamerule is added /// protected virtual void Added(EntityUid uid, T component, GameRuleComponent gameRule, GameRuleAddedEvent args) { } /// /// Called when the gamerule begins /// protected virtual void Started(EntityUid uid, T component, GameRuleComponent gameRule, GameRuleStartedEvent args) { } /// /// Called when the gamerule ends /// protected virtual void Ended(EntityUid uid, T component, GameRuleComponent gameRule, GameRuleEndedEvent args) { } /// /// Called on an active gamerule entity in the Update function /// protected virtual void ActiveTick(EntityUid uid, T component, GameRuleComponent gameRule, float frameTime) { } protected EntityQueryEnumerator QueryActiveRules() { return EntityQueryEnumerator(); } protected bool TryRoundStartAttempt(RoundStartAttemptEvent ev, string localizedPresetName) { var query = EntityQueryEnumerator(); while (query.MoveNext(out _, out _, out _, out var gameRule)) { var minPlayers = gameRule.MinPlayers; if (!ev.Forced && ev.Players.Length < minPlayers) { ChatManager.SendAdminAnnouncement(Loc.GetString("preset-not-enough-ready-players", ("readyPlayersCount", ev.Players.Length), ("minimumPlayers", minPlayers), ("presetName", localizedPresetName))); ev.Cancel(); continue; } if (ev.Players.Length == 0) { ChatManager.DispatchServerAnnouncement(Loc.GetString("preset-no-one-ready")); ev.Cancel(); } } return !ev.Cancelled; } public override void Update(float frameTime) { base.Update(frameTime); var query = EntityQueryEnumerator(); while (query.MoveNext(out var uid, out var comp1, out var comp2)) { if (!GameTicker.IsGameRuleActive(uid, comp2)) continue; ActiveTick(uid, comp1, comp2, frameTime); } } }