using System.Linq; using Content.Server.Research.Components; using Content.Shared.Research.Components; using Content.Shared.Research.Prototypes; using Robust.Shared.GameStates; namespace Content.Server.Research.Systems; public sealed partial class ResearchSystem { /// /// Synchronizes this database against other, /// adding all technologies from the other that /// this one doesn't have. /// /// /// The other database /// Whether the other database should be synced against this one too or not. public void Sync(TechnologyDatabaseComponent component, TechnologyDatabaseComponent otherDatabase, bool twoway = true) { otherDatabase.TechnologyIds = otherDatabase.TechnologyIds.Union(component.TechnologyIds).ToList(); otherDatabase.RecipeIds = otherDatabase.RecipeIds.Union(component.RecipeIds).ToList(); if (twoway) Sync(otherDatabase, component, false); Dirty(component); } /// /// If there's a research client component attached to the owner entity, /// and the research client is connected to a research server, this method /// syncs against the research server, and the server against the local database. /// /// Whether it could sync or not public bool SyncWithServer(TechnologyDatabaseComponent component, ResearchClientComponent? clientComponent = null) { if (!Resolve(component.Owner, ref clientComponent, false)) return false; if (!TryComp(clientComponent.Server?.Owner, out var clientDatabase)) return false; Sync(component, clientDatabase); return true; } /// /// If possible, unlocks a technology on this database. /// /// /// /// public bool UnlockTechnology(TechnologyDatabaseComponent component, TechnologyPrototype technology) { if (!CanUnlockTechnology(component.Owner, technology, component)) return false; AddTechnology(component, technology.ID); return true; } /// /// Adds a technology to the database without checking if it could be unlocked. /// /// /// public void AddTechnology(TechnologyDatabaseComponent component, string technology) { if (!_prototypeManager.TryIndex(technology, out var prototype)) return; AddTechnology(component, prototype); } public void AddTechnology(TechnologyDatabaseComponent component, TechnologyPrototype technology) { component.TechnologyIds.Add(technology.ID); foreach (var unlock in technology.UnlockedRecipes) { if (component.RecipeIds.Contains(unlock)) continue; component.RecipeIds.Add(unlock); } Dirty(component); if (!TryComp(component.Owner, out var server)) return; foreach (var client in server.Clients) { if (!TryComp(client, out var console)) continue; UpdateConsoleInterface(console); } } public void AddLatheRecipe(TechnologyDatabaseComponent component, string recipe, bool dirty = true) { if (component.RecipeIds.Contains(recipe)) return; component.RecipeIds.Add(recipe); if (dirty) Dirty(component); } }