using System.Collections; using Content.Shared.Research.Prototypes; using Robust.Shared.GameStates; using Robust.Shared.Prototypes; using Robust.Shared.Serialization; namespace Content.Shared.Research.Components { [NetworkedComponent()] public abstract class SharedTechnologyDatabaseComponent : Component, IEnumerable, ISerializationHooks { [DataField("technologies")] private List _technologyIds = new(); public List Technologies = new(); void ISerializationHooks.BeforeSerialization() { var techIds = new List(); foreach (var tech in Technologies) { techIds.Add(tech.ID); } _technologyIds = techIds; } void ISerializationHooks.AfterDeserialization() { var prototypeManager = IoCManager.Resolve(); foreach (var id in _technologyIds) { if (prototypeManager.TryIndex(id, out TechnologyPrototype? tech)) { Technologies.Add(tech); } } } public IEnumerator GetEnumerator() { return Technologies.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } /// /// Returns a list with the IDs of all unlocked technologies. /// /// A list of technology IDs public List GetTechnologyIdList() { List techIds = new List(); foreach (var tech in Technologies) { techIds.Add(tech.ID); } return techIds; } /// /// Returns whether a technology is unlocked on this database or not. /// /// The technology to be checked /// Whether it is unlocked or not public bool IsTechnologyUnlocked(TechnologyPrototype technology) { return Technologies.Contains(technology); } /// /// Returns whether a technology can be unlocked on this database, /// taking parent technologies into account. /// /// The technology to be checked /// Whether it could be unlocked or not public bool CanUnlockTechnology(TechnologyPrototype technology) { if (technology == null || IsTechnologyUnlocked(technology)) return false; var protoMan = IoCManager.Resolve(); foreach (var technologyId in technology.RequiredTechnologies) { protoMan.TryIndex(technologyId, out TechnologyPrototype? requiredTechnology); if (requiredTechnology == null) return false; if (!IsTechnologyUnlocked(requiredTechnology)) return false; } return true; } } [Serializable, NetSerializable] public sealed class TechnologyDatabaseState : ComponentState { public List Technologies; public TechnologyDatabaseState(List technologies) { Technologies = technologies; } public TechnologyDatabaseState(List technologies) { Technologies = new List(); foreach (var technology in technologies) { Technologies.Add(technology.ID); } } } }