PR #223 but slightly nicer

This commit is contained in:
dexy 2024-07-11 09:25:01 +10:00
parent 9b8331e696
commit 27a07461b1
2 changed files with 29 additions and 44 deletions

View File

@ -259,14 +259,13 @@ namespace CodeWalker.GameFiles
private void EnsureEntities(Meta Meta) private void EnsureEntities(Meta Meta)
{ {
//CMloInstanceDefs = MetaTypes.ConvertDataArray<CMloInstanceDef>(Meta, MetaName.CMloInstanceDef, CMapData.entities); var eptrs = MetaTypes.GetPointerArray(Meta, _CMapData.entities);
CMloInstanceDefs = MetaTypes.GetTypedDataArray<CMloInstanceDef>(Meta, MetaName.CMloInstanceDef);
CMloInstanceDefs = MetaTypes.GetTypedPointerArray<CMloInstanceDef>(Meta, MetaName.CMloInstanceDef, eptrs);
if (CMloInstanceDefs != null) if (CMloInstanceDefs != null)
{ } { }
var eptrs = MetaTypes.GetPointerArray(Meta, _CMapData.entities); CEntityDefs = MetaTypes.GetTypedPointerArray<CEntityDef>(Meta, MetaName.CEntityDef, eptrs);
//CEntityDefs = MetaTypes.ConvertDataArray<CEntityDef>(Meta, MetaName.CEntityDef, CMapData.entities);
CEntityDefs = MetaTypes.GetTypedDataArray<CEntityDef>(Meta, MetaName.CEntityDef);
if (CEntityDefs != null) if (CEntityDefs != null)
{ } { }

View File

@ -1759,49 +1759,35 @@ namespace CodeWalker.GameFiles
} }
public static T[] GetTypedDataArray<T>(Meta meta, MetaName name) where T : struct public static T[] GetTypedPointerArray<T>(Meta meta, MetaName name, MetaPOINTER[] arr) where T : struct
{ {
if ((meta == null) || (meta.DataBlocks == null)) return null; //this is really a bad hack just for ymap entities so as not to completely rewrite all of the YmapFile stuff.
//there could be subclasses in the array, which the returned struct array can't handle.
//so, this will return a filtered list with only types matching the given name parameter.
//NOTE: this is very similar to ConvertDataArray(Meta, MetaName, Array_StructurePointer)
if (arr == null) return null;//use GetPointerArray for this parameter
var datablocks = meta.DataBlocks.Data; var datablocks = meta.DataBlocks.Data;
if (datablocks == null) return null;
MetaDataBlock startblock = null; int tsize = Marshal.SizeOf(typeof(T));
int startblockind = -1; var list = new List<T>();
for (int i = 0; i < datablocks.Count; i++) for (int i = 0; i < arr.Length; i++)
{ {
var block = datablocks[i]; ref var ptr = ref arr[i];
if (block.StructureNameHash == name) var blockind = ptr.BlockIndex;
{ if (blockind < 0) continue;
startblock = block; if (blockind >= datablocks.Count) continue;
startblockind = i; var block = datablocks[blockind];
break; if (block == null) continue;
if (block.Data == null) continue;
if (block.StructureNameHash != name) continue;//filter only matching types
var offset = ptr.Offset;
if (offset < 0) continue;
if (offset + tsize > block.Data.Length) continue;
var item = ConvertData<T>(block.Data, offset);
list.Add(item);
} }
} if (list.Count == 0) return null;
if (startblock == null) return list.ToArray();
{
return null; //couldn't find the data.
}
int count = 0; //try figure out how many items there are, from the block size(s).
int itemsize = Marshal.SizeOf(typeof(T));
var currentblock = startblock;
int currentblockind = startblockind;
while (currentblock != null)
{
int blockitems = currentblock.DataLength / itemsize;
count += blockitems;
currentblockind++;
if (currentblockind >= datablocks.Count) break; //last block, can't go any further
currentblock = datablocks[currentblockind];
if (currentblock.StructureNameHash != name) break; //not the right block type, can't go further
}
if (count <= 0)
{
return null; //didn't find anything...
}
return ConvertDataArray<T>(meta, name, (uint)startblockind + 1, (uint)count);
} }
public static T GetTypedData<T>(Meta meta, MetaName name) where T : struct public static T GetTypedData<T>(Meta meta, MetaName name) where T : struct
{ {