using Content.Server.Power.EntitySystems; using Content.Server.Station.Systems; using Content.Server.Research.Components; using Content.Shared.Research.Prototypes; namespace Content.Server.Research; public sealed partial class ResearchSystem { [Dependency] private readonly StationSystem _stationSystem = default!; private void InitializeServer() { SubscribeLocalEvent(OnServerStartup); SubscribeLocalEvent(OnServerShutdown); } private void OnServerShutdown(EntityUid uid, ResearchServerComponent component, ComponentShutdown args) { UnregisterServer(component); } private void OnServerStartup(EntityUid uid, ResearchServerComponent component, ComponentStartup args) { RegisterServer(component); } private bool CanRun(ResearchServerComponent component) { return this.IsPowered(component.Owner, EntityManager); } private void UpdateServer(ResearchServerComponent component, int time) { if (!CanRun(component)) return; component.Points += PointsPerSecond(component) * time; } public bool RegisterServerClient(ResearchServerComponent component, ResearchClientComponent clientComponent) { // Has to be on the same station if (_stationSystem.GetOwningStation(component.Owner) != _stationSystem.GetOwningStation(clientComponent.Owner)) return false; // TODO: This is shit but I'm just trying to fix RND for now until it gets bulldozed if (TryComp(clientComponent.Owner, out var source)) { if (component.PointSources.Contains(source)) return false; component.PointSources.Add(source); source.Server = component; } if (component.Clients.Contains(clientComponent)) return false; component.Clients.Add(clientComponent); clientComponent.Server = component; return true; } public void UnregisterServerClient(ResearchServerComponent component, ResearchClientComponent clientComponent) { if (TryComp(clientComponent.Owner, out var source)) { component.PointSources.Remove(source); } component.Clients.Remove(clientComponent); clientComponent.Server = null; } public bool IsTechnologyUnlocked(ResearchServerComponent component, TechnologyPrototype prototype, TechnologyDatabaseComponent? databaseComponent = null) { if (!Resolve(component.Owner, ref databaseComponent, false)) return false; return databaseComponent.IsTechnologyUnlocked(prototype); } public bool CanUnlockTechnology(ResearchServerComponent component, TechnologyPrototype technology, TechnologyDatabaseComponent? databaseComponent = null) { if (!Resolve(component.Owner, ref databaseComponent, false)) return false; if (!databaseComponent.CanUnlockTechnology(technology) || component.Points < technology.RequiredPoints || IsTechnologyUnlocked(component, technology, databaseComponent)) return false; return true; } public bool UnlockTechnology(ResearchServerComponent component, TechnologyPrototype prototype, TechnologyDatabaseComponent? databaseComponent = null) { if (!Resolve(component.Owner, ref databaseComponent, false)) return false; if (!CanUnlockTechnology(component, prototype, databaseComponent)) return false; var result = UnlockTechnology(databaseComponent, prototype); if (result) component.Points -= prototype.RequiredPoints; return result; } public int PointsPerSecond(ResearchServerComponent component) { var points = 0; // Is our machine powered, and are we below our limit of passive point gain? if (CanRun(component) && component.Points < (component.PassiveLimitPerSource * component.PointSources.Count)) { foreach (var source in component.PointSources) { if (CanProduce(source)) points += source.PointsPerSecond; } } return points; } }