using Content.Server.Atmos.EntitySystems; using Content.Shared.GameTicking.Components; using Robust.Server.GameObjects; using Robust.Shared.Random; using Robust.Shared.Timing; namespace Content.Server.GameTicking.Rules; public abstract partial class GameRuleSystem : EntitySystem where T : IComponent { [Dependency] protected IGameTiming Timing = default!; [Dependency] protected IRobustRandom RobustRandom = default!; [Dependency] protected GameTicker GameTicker = default!; // Not protected, just to be used in utility methods [Dependency] private AtmosphereSystem _atmosphere = default!; [Dependency] private MapSystem _map = default!; [Dependency] protected EntityQuery GameRuleQuery = default!; [Dependency] protected EntityQuery RuleQuery = default!; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnGameRuleAdded); SubscribeLocalEvent(OnGameRuleStarted); SubscribeLocalEvent(OnGameRuleEnded); SubscribeLocalEvent(OnRoundEndTextAppend); } private void OnGameRuleAdded(EntityUid uid, T component, ref GameRuleAddedEvent args) { if (!GameRuleQuery.TryComp(uid, out var ruleData)) return; Added(uid, component, ruleData, args); } private void OnGameRuleStarted(EntityUid uid, T component, ref GameRuleStartedEvent args) { if (!GameRuleQuery.TryComp(uid, out var ruleData)) return; Started(uid, component, ruleData, args); } private void OnGameRuleEnded(EntityUid uid, T component, ref GameRuleEndedEvent args) { if (!GameRuleQuery.TryComp(uid, out var ruleData)) return; Ended(uid, component, ruleData, args); } private void OnRoundEndTextAppend(RoundEndTextAppendEvent ev) { var query = QueryAllRules(); while (query.MoveNext(out var uid, out var comp, out var ruleData)) { AppendRoundEndText(uid, comp, ruleData, ref ev); } } /// /// 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 at the end of a round when text needs to be added for a game rule. /// protected virtual void AppendRoundEndText(EntityUid uid, T component, GameRuleComponent gameRule, ref RoundEndTextAppendEvent args) { } /// /// Called on an active gamerule entity in the Update function /// protected virtual void ActiveTick(EntityUid uid, T component, GameRuleComponent gameRule, float frameTime) { } 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); } } }