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 List(); /// /// 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); if (serializer.Reading) { var techs = serializer.ReadDataField("technologies", new List()); var prototypeManager = IoCManager.Resolve(); foreach (var id in techs) { if (!prototypeManager.TryIndex(id, out TechnologyPrototype tech)) continue; _technologies.Add(tech); } } else if (serializer.Writing) { var techs = GetTechnologyIdList(); serializer.DataField(ref techs, "technologies", new List()); } } } [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); } } } }