252 lines
8.9 KiB
C#
252 lines
8.9 KiB
C#
using System.Linq;
|
|
using Content.Server.Power.EntitySystems;
|
|
using Content.Shared.Research.Components;
|
|
using Content.Shared.Storage;
|
|
using Robust.Shared.Containers;
|
|
|
|
namespace Content.Server.Research.Systems;
|
|
|
|
public sealed partial class ResearchSystem
|
|
{
|
|
private void InitializeServer()
|
|
{
|
|
SubscribeLocalEvent<ResearchServerComponent, ComponentStartup>(OnServerStartup);
|
|
SubscribeLocalEvent<ResearchServerComponent, ComponentShutdown>(OnServerShutdown);
|
|
SubscribeLocalEvent<ResearchServerComponent, TechnologyDatabaseModifiedEvent>(OnServerDatabaseModified);
|
|
SubscribeLocalEvent<ResearchServerComponent, EntInsertedIntoContainerMessage>(OnServerInsertItem); // Horizon
|
|
SubscribeLocalEvent<ResearchServerComponent, EntRemovedFromContainerMessage>(OnServerRemoveItem); // Horizon
|
|
SubscribeLocalEvent<ResearchServerComponent, AnchorStateChangedEvent>(OnServerAnchorChanged); // Frontier
|
|
SubscribeLocalEvent<ResearchServerComponent, EntParentChangedMessage>(OnServerParentChanged); // Frontier
|
|
}
|
|
|
|
private void OnServerStartup(EntityUid uid, ResearchServerComponent component, ComponentStartup args)
|
|
{
|
|
var unusedId = EntityQuery<ResearchServerComponent>(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<EntityUid>(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);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Registers a client to the specified server.
|
|
/// </summary>
|
|
/// <param name="client">The client being registered</param>
|
|
/// <param name="server">The server the client is being registered to</param>
|
|
/// <param name="clientComponent"></param>
|
|
/// <param name="serverComponent"></param>
|
|
/// <param name="dirtyServer">Whether or not to dirty the server component after registration</param>
|
|
public void RegisterClient(EntityUid client, EntityUid server, ResearchClientComponent? clientComponent = null,
|
|
ResearchServerComponent? serverComponent = null, bool dirtyServer = true)
|
|
{
|
|
if (!Resolve(client, ref clientComponent, false) || !Resolve(server, ref serverComponent, false))
|
|
return;
|
|
|
|
if (serverComponent.Clients.Contains(client))
|
|
return;
|
|
|
|
// Frontier: check grids
|
|
if (!TryComp(client, out TransformComponent? clientXform)
|
|
|| !TryComp(server, out TransformComponent? serverXform)
|
|
|| clientXform.GridUid == null
|
|
|| clientXform.GridUid != serverXform.GridUid) // server null check implicit
|
|
return;
|
|
// End Frontier
|
|
|
|
serverComponent.Clients.Add(client);
|
|
clientComponent.Server = server;
|
|
SyncClientWithServer(client, clientComponent: clientComponent);
|
|
|
|
if (dirtyServer && !TerminatingOrDeleted(server))
|
|
{
|
|
Dirty(server, serverComponent);
|
|
Dirty(client, clientComponent); // Horizon
|
|
}
|
|
|
|
var ev = new ResearchRegistrationChangedEvent(server);
|
|
RaiseLocalEvent(client, ref ev);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Unregisters a client from its server
|
|
/// </summary>
|
|
/// <param name="client"></param>
|
|
/// <param name="clientComponent"></param>
|
|
/// <param name="dirtyServer"></param>
|
|
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);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Unregisters a client from its server
|
|
/// </summary>
|
|
/// <param name="client"></param>
|
|
/// <param name="server"></param>
|
|
/// <param name="clientComponent"></param>
|
|
/// <param name="serverComponent"></param>
|
|
/// <param name="dirtyServer"></param>
|
|
public void UnregisterClient(EntityUid client, EntityUid server, ResearchClientComponent? clientComponent = null,
|
|
ResearchServerComponent? serverComponent = null, bool dirtyServer = true)
|
|
{
|
|
if (!Resolve(client, ref clientComponent, false) || !Resolve(server, ref serverComponent, false))
|
|
return;
|
|
|
|
serverComponent.Clients.Remove(client);
|
|
clientComponent.Server = null;
|
|
SyncClientWithServer(client, clientComponent: clientComponent);
|
|
|
|
if (dirtyServer && !TerminatingOrDeleted(server))
|
|
{
|
|
Dirty(server, serverComponent);
|
|
Dirty(client, clientComponent); // Horizon
|
|
}
|
|
|
|
var ev = new ResearchRegistrationChangedEvent(null);
|
|
RaiseLocalEvent(client, ref ev);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the amount of points generated by all the server's sources in a second.
|
|
/// </summary>
|
|
/// <param name="uid"></param>
|
|
/// <param name="component"></param>
|
|
/// <returns></returns>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds a specified number of points to a server.
|
|
/// </summary>
|
|
/// <param name="uid">The server</param>
|
|
/// <param name="points">The amount of points being added</param>
|
|
/// <param name="component"></param>
|
|
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);
|
|
}
|
|
|
|
// Horizon start
|
|
// ReSharper disable EnforceForeachStatementBraces
|
|
private void OnServerInsertItem(EntityUid uid, ResearchServerComponent comp, EntInsertedIntoContainerMessage _)
|
|
{
|
|
foreach (var client in comp.Clients)
|
|
UpdateClientInterface(client);
|
|
}
|
|
|
|
private void OnServerRemoveItem(EntityUid uid, ResearchServerComponent comp, EntRemovedFromContainerMessage _)
|
|
{
|
|
foreach (var client in comp.Clients)
|
|
UpdateClientInterface(client);
|
|
}
|
|
// Horizon end
|
|
// Frontier: unanchoring server
|
|
private void OnServerAnchorChanged(Entity<ResearchServerComponent> ent, ref AnchorStateChangedEvent args)
|
|
{
|
|
if (args.Anchored || ent.Comp.Clients.Count <= 0)
|
|
return;
|
|
|
|
// Server yanked, unregister the clients.
|
|
var clientList = new List<EntityUid>(ent.Comp.Clients);
|
|
bool clientsRemoved = false;
|
|
foreach (var client in clientList)
|
|
{
|
|
UnregisterClient(client, ent, serverComponent: ent.Comp, dirtyServer: false);
|
|
clientsRemoved = true;
|
|
}
|
|
|
|
if (clientsRemoved)
|
|
Dirty(ent);
|
|
}
|
|
|
|
private void OnServerParentChanged(Entity<ResearchServerComponent> ent, ref EntParentChangedMessage args)
|
|
{
|
|
if (TerminatingOrDeleted(ent))
|
|
return;
|
|
|
|
EntityUid? serverGrid = null;
|
|
if (TryComp(ent, out TransformComponent? xform))
|
|
serverGrid = xform.GridUid;
|
|
|
|
// Server yanked, unregister the clients.
|
|
var clientList = new List<EntityUid>(ent.Comp.Clients);
|
|
bool clientsRemoved = false;
|
|
foreach (var client in clientList)
|
|
{
|
|
if (serverGrid == null
|
|
|| !TryComp(client, out TransformComponent? clientXform)
|
|
|| clientXform.GridUid != serverGrid)
|
|
{
|
|
UnregisterClient(client, ent, serverComponent: ent.Comp, dirtyServer: false);
|
|
clientsRemoved = true;
|
|
}
|
|
}
|
|
|
|
if (clientsRemoved)
|
|
Dirty(ent);
|
|
}
|
|
// End Frontier
|
|
}
|