using System.Collections.Generic; using KeepersCompound.LGS.Database.Chunks; namespace KeepersCompound.LGS.Database; public class ObjectHierarchy { public class DarkObject { public int objectId; public int parentId; public Dictionary properties; public DarkObject(int id) { objectId = id; parentId = 0; properties = new Dictionary(); } public T GetProperty(string propName) where T : Property { if (properties.TryGetValue(propName, out var prop)) { return (T)prop; } return null; } } private Dictionary _objects; public ObjectHierarchy(DbFile db, DbFile gam = null) { _objects = new Dictionary(); if (db.Chunks.TryGetValue("P$ModelName", out var modelNamesRaw) && db.Chunks.TryGetValue("P$Scale", out var scalesRaw) && db.Chunks.TryGetValue("P$RenderTyp", out var renderTypesRaw) && db.Chunks.TryGetValue("L$MetaProp", out var metaPropLinksRaw) && db.Chunks.TryGetValue("LD$MetaProp", out var metaPropLinkDataRaw)) { var modelNames = (PropertyChunk)modelNamesRaw; var scales = (PropertyChunk)scalesRaw; var renderTypes = (PropertyChunk)renderTypesRaw; var metaPropLinks = (LinkChunk)metaPropLinksRaw; var metaPropLinkData = (LinkDataMetaProp)metaPropLinkDataRaw; // Merge gam chunks if (gam != null && gam.Chunks.TryGetValue("P$ModelName", out var gamModelNames) && gam.Chunks.TryGetValue("P$Scale", out var gamScales) && gam.Chunks.TryGetValue("P$RenderTyp", out var gamRenderTypes) && gam.Chunks.TryGetValue("L$MetaProp", out var gamLinks) && gam.Chunks.TryGetValue("LD$MetaProp", out var gamLinkData)) { modelNames.properties.AddRange(((PropertyChunk)gamModelNames).properties); scales.properties.AddRange(((PropertyChunk)gamScales).properties); renderTypes.properties.AddRange(((PropertyChunk)gamRenderTypes).properties); metaPropLinks.links.AddRange(((LinkChunk)gamLinks).links); metaPropLinkData.linkData.AddRange(((LinkDataMetaProp)gamLinkData).linkData); } // Add parentages var length = metaPropLinks.links.Count; for (var i = 0; i < length; i++) { var link = metaPropLinks.links[i]; var linkData = metaPropLinkData.linkData[i]; var childId = link.source; var parentId = link.destination; if (!_objects.ContainsKey(childId)) { _objects.Add(childId, new DarkObject(childId)); } if (!_objects.ContainsKey(parentId)) { _objects.Add(parentId, new DarkObject(parentId)); } if (linkData.priority == 0) { _objects[childId].parentId = parentId; } } void TryAddProp(string propName, Property prop) { var id = prop.objectId; if (!_objects.ContainsKey(id)) { _objects.Add(id, new DarkObject(id)); } _objects[id].properties.TryAdd(propName, prop); } // TODO: Find a way to do this better foreach (var prop in modelNames.properties) { TryAddProp("P$ModelName", prop); } foreach (var prop in scales.properties) { TryAddProp("P$Scale", prop); } foreach (var prop in renderTypes.properties) { TryAddProp("P$RenderTyp", prop); } } } public T GetProperty(int objectId, string propName) where T : Property { if (!_objects.ContainsKey(objectId)) { return null; } var parentId = objectId; while (parentId != 0) { if (!_objects.TryGetValue(parentId, out var obj)) { return null; } var prop = obj.GetProperty(propName); if (prop != null) { return prop; } parentId = obj.parentId; } return null; } }