using System; using System.Collections; using System.Collections.Generic; using Content.Shared.Research.Prototypes; using Robust.Shared.GameObjects; using Robust.Shared.GameStates; using Robust.Shared.IoC; using Robust.Shared.Prototypes; using Robust.Shared.Serialization; using Robust.Shared.Serialization.Manager.Attributes; namespace Content.Shared.Research.Components { [NetworkedComponent()] public class SharedTechnologyDatabaseComponent : Component, IEnumerable, ISerializationHooks { public override string Name => "TechnologyDatabase"; [DataField("technologies")] private List _technologyIds = new(); protected List _technologies = new(); /// /// A read-only list of unlocked technologies. /// public IReadOnlyList Technologies => _technologies; 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 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); } } } }