2023-09-17 18:51:42 +06:00
|
|
|
using System.Diagnostics.CodeAnalysis;
|
|
|
|
|
using Content.Server.Administration.Logs;
|
|
|
|
|
using Content.Server.Chat.Systems;
|
|
|
|
|
using Content.Server.GameTicking.Rules;
|
|
|
|
|
using Content.Server.GameTicking.Rules.Components;
|
|
|
|
|
using Content.Server.Station.Components;
|
|
|
|
|
using Content.Shared.Database;
|
|
|
|
|
using Robust.Shared.Audio.Systems;
|
|
|
|
|
using Robust.Shared.Player;
|
|
|
|
|
using Robust.Shared.Timing;
|
|
|
|
|
|
2024-03-30 11:33:13 +07:00
|
|
|
namespace Content.Server._White.AspectsSystem.Base;
|
2023-09-17 18:51:42 +06:00
|
|
|
|
2024-03-30 11:33:13 +07:00
|
|
|
/// <summary>
|
|
|
|
|
/// Base class for aspect systems.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <typeparam name="T">The type of component to which the system is applied.</typeparam>
|
|
|
|
|
public abstract class AspectSystem<T> : GameRuleSystem<T> where T : Component
|
|
|
|
|
{
|
|
|
|
|
[Dependency] private readonly IAdminLogManager _adminLogManager = default!;
|
|
|
|
|
[Dependency] private readonly IGameTiming _timing = default!;
|
|
|
|
|
[Dependency] private readonly ChatSystem _chatSystem = default!;
|
|
|
|
|
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
2023-09-17 18:51:42 +06:00
|
|
|
|
2024-03-30 11:33:13 +07:00
|
|
|
protected ISawmill Sawmill = default!;
|
2023-09-17 18:51:42 +06:00
|
|
|
|
2024-03-30 11:33:13 +07:00
|
|
|
public override void Initialize()
|
|
|
|
|
{
|
|
|
|
|
base.Initialize();
|
2023-09-17 18:51:42 +06:00
|
|
|
|
2024-03-30 11:33:13 +07:00
|
|
|
Sawmill = Logger.GetSawmill("aspects");
|
|
|
|
|
}
|
2023-09-17 18:51:42 +06:00
|
|
|
|
2024-03-30 11:33:13 +07:00
|
|
|
/// <summary>
|
|
|
|
|
/// Called every tick when this aspect is running.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public override void Update(float frameTime)
|
|
|
|
|
{
|
|
|
|
|
base.Update(frameTime);
|
2023-09-17 18:51:42 +06:00
|
|
|
|
2024-03-30 11:33:13 +07:00
|
|
|
var query = EntityQueryEnumerator<AspectComponent, GameRuleComponent>();
|
|
|
|
|
while (query.MoveNext(out var uid, out var aspect, out var ruleData))
|
2023-09-17 18:51:42 +06:00
|
|
|
{
|
2024-03-30 11:33:13 +07:00
|
|
|
if (!GameTicker.IsGameRuleAdded(uid, ruleData))
|
|
|
|
|
continue;
|
2023-09-17 18:51:42 +06:00
|
|
|
|
2024-03-30 11:33:13 +07:00
|
|
|
if (!GameTicker.IsGameRuleActive(uid, ruleData) && _timing.CurTime >= aspect.StartTime)
|
2023-09-17 18:51:42 +06:00
|
|
|
{
|
2024-03-30 11:33:13 +07:00
|
|
|
GameTicker.StartGameRule(uid, ruleData);
|
2023-09-17 18:51:42 +06:00
|
|
|
}
|
|
|
|
|
}
|
2024-03-30 11:33:13 +07:00
|
|
|
}
|
2023-09-17 18:51:42 +06:00
|
|
|
|
2024-03-30 11:33:13 +07:00
|
|
|
/// <summary>
|
|
|
|
|
/// Called when an aspect is added to an entity.
|
|
|
|
|
/// </summary>
|
|
|
|
|
protected override void Added(EntityUid uid, T component, GameRuleComponent gameRule, GameRuleAddedEvent args)
|
|
|
|
|
{
|
|
|
|
|
base.Added(uid, component, gameRule, args);
|
2023-09-17 18:51:42 +06:00
|
|
|
|
2024-03-30 11:33:13 +07:00
|
|
|
if (!TryComp<AspectComponent>(uid, out var aspect))
|
|
|
|
|
return;
|
2023-09-17 18:51:42 +06:00
|
|
|
|
2024-03-30 11:33:13 +07:00
|
|
|
_adminLogManager.Add(LogType.AspectAnnounced, $"Aspect added {ToPrettyString(uid)}");
|
2023-09-17 18:51:42 +06:00
|
|
|
|
2024-03-30 11:33:13 +07:00
|
|
|
if (aspect is { Description: not null, IsHidden: false })
|
2023-09-17 18:51:42 +06:00
|
|
|
{
|
2024-03-30 11:33:13 +07:00
|
|
|
_chatSystem.DispatchGlobalAnnouncement(aspect.Description, playSound: false,
|
|
|
|
|
colorOverride: Color.Aquamarine);
|
2023-09-17 18:51:42 +06:00
|
|
|
}
|
|
|
|
|
|
2024-03-30 11:33:13 +07:00
|
|
|
_audio.PlayGlobal(aspect.StartAudio, Filter.Broadcast(), true);
|
|
|
|
|
aspect.StartTime = _timing.CurTime + aspect.StartDelay;
|
|
|
|
|
}
|
2023-09-17 18:51:42 +06:00
|
|
|
|
2024-03-30 11:33:13 +07:00
|
|
|
/// <summary>
|
|
|
|
|
/// Called when an aspect is started.
|
|
|
|
|
/// </summary>
|
|
|
|
|
protected override void Started(
|
|
|
|
|
EntityUid uid,
|
|
|
|
|
T component,
|
|
|
|
|
GameRuleComponent gameRule,
|
|
|
|
|
GameRuleStartedEvent args)
|
|
|
|
|
{
|
|
|
|
|
base.Started(uid, component, gameRule, args);
|
2023-09-17 18:51:42 +06:00
|
|
|
|
2024-03-30 11:33:13 +07:00
|
|
|
if (!TryComp<AspectComponent>(uid, out _))
|
|
|
|
|
return;
|
2023-09-17 18:51:42 +06:00
|
|
|
|
2024-03-30 11:33:13 +07:00
|
|
|
_adminLogManager.Add(LogType.AspectStarted, LogImpact.High, $"Aspect started: {ToPrettyString(uid)}");
|
|
|
|
|
}
|
2023-09-17 18:51:42 +06:00
|
|
|
|
2024-03-30 11:33:13 +07:00
|
|
|
/// <summary>
|
|
|
|
|
/// Called when an aspect is ended.
|
|
|
|
|
/// </summary>
|
|
|
|
|
protected override void Ended(EntityUid uid, T component, GameRuleComponent gameRule, GameRuleEndedEvent args)
|
|
|
|
|
{
|
|
|
|
|
base.Ended(uid, component, gameRule, args);
|
2023-09-17 18:51:42 +06:00
|
|
|
|
2024-03-30 11:33:13 +07:00
|
|
|
if (!TryComp<AspectComponent>(uid, out var aspect))
|
|
|
|
|
return;
|
2023-09-17 18:51:42 +06:00
|
|
|
|
2024-03-30 11:33:13 +07:00
|
|
|
_adminLogManager.Add(LogType.AspectStopped, $"Aspect ended: {ToPrettyString(uid)}");
|
2023-09-17 18:51:42 +06:00
|
|
|
|
2024-03-30 11:33:13 +07:00
|
|
|
if (aspect is { Name: not null, IsHidden: false })
|
2023-09-17 18:51:42 +06:00
|
|
|
{
|
2024-03-30 11:33:13 +07:00
|
|
|
_chatSystem.DispatchGlobalAnnouncement($"Именем аспекта являлось: {aspect.Name}", playSound: false,
|
|
|
|
|
colorOverride: Color.Aquamarine);
|
2023-10-19 02:32:18 +09:00
|
|
|
}
|
|
|
|
|
|
2024-03-30 11:33:13 +07:00
|
|
|
_audio.PlayGlobal(aspect.EndAudio, Filter.Broadcast(), true);
|
|
|
|
|
}
|
2024-01-29 01:02:37 +07:00
|
|
|
|
2024-03-30 11:33:13 +07:00
|
|
|
#region Helpers
|
2023-09-18 22:52:46 +09:00
|
|
|
|
2024-03-30 11:33:13 +07:00
|
|
|
/// <summary>
|
|
|
|
|
/// Forces this aspect to end prematurely.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="uid">The entity UID on which the aspect is being performed.</param>
|
|
|
|
|
/// <param name="component">The game rule component associated with this aspect (optional).</param>
|
|
|
|
|
protected void ForceEndSelf(EntityUid uid, GameRuleComponent? component = null)
|
|
|
|
|
{
|
|
|
|
|
GameTicker.EndGameRule(uid, component);
|
|
|
|
|
}
|
2023-09-18 22:52:46 +09:00
|
|
|
|
2024-03-30 11:33:13 +07:00
|
|
|
protected bool TryGetStationGrids(
|
|
|
|
|
[NotNullWhen(true)] out EntityUid? targetStation,
|
|
|
|
|
[NotNullWhen(true)] out HashSet<EntityUid>? grids)
|
|
|
|
|
{
|
|
|
|
|
if (!TryGetRandomStation(out targetStation))
|
|
|
|
|
{
|
|
|
|
|
targetStation = EntityUid.Invalid;
|
|
|
|
|
grids = null;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2023-09-18 22:52:46 +09:00
|
|
|
|
2024-03-30 11:33:13 +07:00
|
|
|
grids = Comp<StationDataComponent>(targetStation.Value).Grids;
|
2023-09-17 18:51:42 +06:00
|
|
|
|
2024-03-30 11:33:13 +07:00
|
|
|
return grids.Count > 0;
|
|
|
|
|
}
|
2023-09-17 18:51:42 +06:00
|
|
|
|
2024-01-29 01:02:37 +07:00
|
|
|
#endregion
|
2024-03-30 11:33:13 +07:00
|
|
|
}
|