using System; using System.Collections; using System.Collections.Generic; using Content.Shared.Research; using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Prototypes; using Robust.Shared.Serialization; namespace Content.Shared.GameObjects.Components.Research { public class SharedTechnologyDatabaseComponent : Component, IEnumerable { public override string Name => "TechnologyDatabase"; public override uint? NetID => ContentNetIDs.TECHNOLOGY_DATABASE; protected List _technologies = new(); /// /// A read-only list of unlocked technologies. /// public IReadOnlyList Technologies => _technologies; 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; } public override void ExposeData(ObjectSerializer serializer) { base.ExposeData(serializer); serializer.DataReadWriteFunction( "technologies", new List(), techs => { var prototypeManager = IoCManager.Resolve(); foreach (var id in techs) { if (prototypeManager.TryIndex(id, out TechnologyPrototype tech)) { _technologies.Add(tech); } } }, GetTechnologyIdList); } } [Serializable, NetSerializable] public class TechnologyDatabaseState : ComponentState { public List Technologies; public TechnologyDatabaseState(List technologies) : base(ContentNetIDs.TECHNOLOGY_DATABASE) { Technologies = technologies; } public TechnologyDatabaseState(List technologies) : base(ContentNetIDs.TECHNOLOGY_DATABASE) { Technologies = new List(); foreach (var technology in technologies) { Technologies.Add(technology.ID); } } } }