2024-09-20 15:28:44 +00:00
|
|
|
using KeepersCompound.LGS.Database.Chunks;
|
|
|
|
|
|
|
|
namespace KeepersCompound.LGS.Database;
|
|
|
|
|
|
|
|
public class ObjectHierarchy
|
|
|
|
{
|
2024-10-27 08:38:47 +00:00
|
|
|
private class DarkObject
|
2024-09-20 15:28:44 +00:00
|
|
|
{
|
|
|
|
public int objectId;
|
|
|
|
public int parentId;
|
|
|
|
public Dictionary<string, Property> properties;
|
|
|
|
|
|
|
|
public DarkObject(int id)
|
|
|
|
{
|
|
|
|
objectId = id;
|
|
|
|
parentId = 0;
|
|
|
|
properties = new Dictionary<string, Property>();
|
|
|
|
}
|
|
|
|
|
2024-10-27 08:38:47 +00:00
|
|
|
public T? GetProperty<T>(string propName) where T : Property
|
2024-09-20 15:28:44 +00:00
|
|
|
{
|
|
|
|
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>();
|
|
|
|
|
|
|
|
T GetMergedChunk<T>(string name) where T : IMergable
|
|
|
|
{
|
2024-10-05 13:57:40 +00:00
|
|
|
if (!db.TryGetChunk<T>(name, out var chunk))
|
2024-09-20 15:28:44 +00:00
|
|
|
{
|
2024-10-05 13:57:40 +00:00
|
|
|
throw new ArgumentException($"No chunk with name ({name}) found", nameof(name));
|
2024-09-20 15:28:44 +00:00
|
|
|
}
|
|
|
|
|
2024-10-05 13:57:40 +00:00
|
|
|
if (gam != null && gam.TryGetChunk<T>(name, out var gamChunk))
|
|
|
|
{
|
|
|
|
gamChunk.Merge(chunk);
|
|
|
|
return gamChunk;
|
|
|
|
}
|
|
|
|
return chunk;
|
2024-09-20 15:28:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Add parentages
|
|
|
|
var metaPropLinks = GetMergedChunk<LinkChunk>("L$MetaProp");
|
|
|
|
var metaPropLinkData = GetMergedChunk<LinkDataMetaProp>("LD$MetaProp");
|
|
|
|
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 AddProp<T>(string name) where T : Property, new()
|
|
|
|
{
|
|
|
|
var chunk = GetMergedChunk<PropertyChunk<T>>(name);
|
|
|
|
foreach (var prop in chunk.properties)
|
|
|
|
{
|
|
|
|
var id = prop.objectId;
|
2024-10-27 08:39:17 +00:00
|
|
|
if (!_objects.TryGetValue(id, out var value))
|
2024-09-20 15:28:44 +00:00
|
|
|
{
|
2024-10-27 08:39:17 +00:00
|
|
|
value = new DarkObject(id);
|
|
|
|
_objects.Add(id, value);
|
2024-09-20 15:28:44 +00:00
|
|
|
}
|
2024-10-27 08:39:17 +00:00
|
|
|
value.properties.TryAdd(name, prop);
|
2024-09-20 15:28:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
AddProp<PropLabel>("P$ModelName");
|
|
|
|
AddProp<PropVector>("P$Scale");
|
|
|
|
AddProp<PropRenderType>("P$RenderTyp");
|
2024-12-07 17:08:01 +00:00
|
|
|
AddProp<PropJointPos>("P$JointPos");
|
2024-09-20 15:28:44 +00:00
|
|
|
AddProp<PropString>("P$OTxtRepr0");
|
|
|
|
AddProp<PropString>("P$OTxtRepr1");
|
|
|
|
AddProp<PropString>("P$OTxtRepr2");
|
|
|
|
AddProp<PropString>("P$OTxtRepr3");
|
|
|
|
AddProp<PropFloat>("P$RenderAlp");
|
2024-09-22 12:18:11 +00:00
|
|
|
AddProp<PropLight>("P$Light");
|
2024-09-29 08:52:12 +00:00
|
|
|
AddProp<PropAnimLight>("P$AnimLight");
|
2024-09-22 12:18:11 +00:00
|
|
|
AddProp<PropLightColor>("P$LightColo");
|
2024-09-26 15:45:48 +00:00
|
|
|
AddProp<PropSpotlight>("P$Spotlight");
|
2024-09-20 15:28:44 +00:00
|
|
|
}
|
|
|
|
|
2024-09-29 09:09:09 +00:00
|
|
|
// TODO: Work out if there's some nice way to automatically decide if we inherit
|
2024-10-27 08:38:47 +00:00
|
|
|
public T? GetProperty<T>(int objectId, string propName, bool inherit = true) where T : Property
|
2024-09-20 15:28:44 +00:00
|
|
|
{
|
|
|
|
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);
|
2024-09-29 09:09:09 +00:00
|
|
|
if (prop != null || !inherit)
|
2024-09-20 15:28:44 +00:00
|
|
|
{
|
|
|
|
return prop;
|
|
|
|
}
|
|
|
|
parentId = obj.parentId;
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|