139 lines
4.6 KiB
C#
139 lines
4.6 KiB
C#
|
|
||
|
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<string, Property> properties;
|
||
|
|
||
|
public DarkObject(int id)
|
||
|
{
|
||
|
objectId = id;
|
||
|
parentId = 0;
|
||
|
properties = new Dictionary<string, Property>();
|
||
|
}
|
||
|
|
||
|
public T GetProperty<T>(string propName) where T : Property
|
||
|
{
|
||
|
if (properties.TryGetValue(propName, out var prop))
|
||
|
{
|
||
|
return (T)prop;
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private Dictionary<int, DarkObject> _objects;
|
||
|
|
||
|
public ObjectHierarchy(DbFile db, DbFile gam = null)
|
||
|
{
|
||
|
_objects = new Dictionary<int, DarkObject>();
|
||
|
|
||
|
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<PropModelName>)modelNamesRaw;
|
||
|
var scales = (PropertyChunk<PropScale>)scalesRaw;
|
||
|
var renderTypes = (PropertyChunk<PropRenderType>)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<PropModelName>)gamModelNames).properties);
|
||
|
scales.properties.AddRange(((PropertyChunk<PropScale>)gamScales).properties);
|
||
|
renderTypes.properties.AddRange(((PropertyChunk<PropRenderType>)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<T>(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<T>(propName);
|
||
|
if (prop != null)
|
||
|
{
|
||
|
return prop;
|
||
|
}
|
||
|
parentId = obj.parentId;
|
||
|
}
|
||
|
|
||
|
return null;
|
||
|
}
|
||
|
}
|