using System.Linq; using Content.Server.Power.EntitySystems; using Content.Shared.Research.Components; namespace Content.Server.Research.Systems; public sealed partial class ResearchSystem { private void InitializeServer() { SubscribeLocalEvent(OnServerStartup); SubscribeLocalEvent(OnServerShutdown); SubscribeLocalEvent(OnServerDatabaseModified); } private void OnServerStartup(EntityUid uid, ResearchServerComponent component, ComponentStartup args) { var unusedId = EntityQuery(true) .Max(s => s.Id) + 1; component.Id = unusedId; Dirty(uid, component); } private void OnServerShutdown(EntityUid uid, ResearchServerComponent component, ComponentShutdown args) { foreach (var client in new List(component.Clients)) { UnregisterClient(client, uid, serverComponent: component, dirtyServer: false); } } private void OnServerDatabaseModified(EntityUid uid, ResearchServerComponent component, ref TechnologyDatabaseModifiedEvent args) { foreach (var client in component.Clients) { RaiseLocalEvent(client, ref args); } } private bool CanRun(EntityUid uid) { return this.IsPowered(uid, EntityManager); } private void UpdateServer(EntityUid uid, int time, ResearchServerComponent? component = null) { if (!Resolve(uid, ref component)) return; if (!CanRun(uid)) return; ModifyServerPoints(uid, GetPointsPerSecond(uid, component) * time, component); } /// /// Registers a client to the specified server. /// /// The client being registered /// The server the client is being registered to /// /// /// Whether or not to dirty the server component after registration public void RegisterClient(EntityUid client, EntityUid server, ResearchClientComponent? clientComponent = null, ResearchServerComponent? serverComponent = null, bool dirtyServer = true) { if (!Resolve(client, ref clientComponent) || !Resolve(server, ref serverComponent)) return; if (serverComponent.Clients.Contains(client)) return; serverComponent.Clients.Add(client); clientComponent.Server = server; SyncClientWithServer(client, clientComponent: clientComponent); if (dirtyServer) Dirty(server, serverComponent); var ev = new ResearchRegistrationChangedEvent(server); RaiseLocalEvent(client, ref ev); } /// /// Unregisterse a client from its server /// /// /// /// public void UnregisterClient(EntityUid client, ResearchClientComponent? clientComponent = null, bool dirtyServer = true) { if (!Resolve(client, ref clientComponent)) return; if (clientComponent.Server is not { } server) return; UnregisterClient(client, server, clientComponent, dirtyServer: dirtyServer); } /// /// Unregisters a client from its server /// /// /// /// /// /// public void UnregisterClient(EntityUid client, EntityUid server, ResearchClientComponent? clientComponent = null, ResearchServerComponent? serverComponent = null, bool dirtyServer = true) { if (!Resolve(client, ref clientComponent) || !Resolve(server, ref serverComponent)) return; serverComponent.Clients.Remove(client); clientComponent.Server = null; SyncClientWithServer(client, clientComponent: clientComponent); if (dirtyServer) { Dirty(server, serverComponent); } var ev = new ResearchRegistrationChangedEvent(null); RaiseLocalEvent(client, ref ev); } /// /// Gets the amount of points generated by all the server's sources in a second. /// /// /// /// public int GetPointsPerSecond(EntityUid uid, ResearchServerComponent? component = null) { var points = 0; if (!Resolve(uid, ref component)) return points; if (!CanRun(uid)) return points; var ev = new ResearchServerGetPointsPerSecondEvent(uid, points); foreach (var client in component.Clients) { RaiseLocalEvent(client, ref ev); } return ev.Points; } /// /// Adds a specified number of points to a server. /// /// The server /// The amount of points being added /// public void ModifyServerPoints(EntityUid uid, int points, ResearchServerComponent? component = null) { if (points == 0) return; if (!Resolve(uid, ref component)) return; component.Points += points; var ev = new ResearchServerPointsChangedEvent(uid, component.Points, points); foreach (var client in component.Clients) { RaiseLocalEvent(client, ref ev); } Dirty(uid, component); } }