mirror of
https://mirror.ghproxy.com/https://github.com/dexyfex/CodeWalker
synced 2024-09-29 04:27:30 +08:00
PR #223 but slightly nicer
This commit is contained in:
parent
9b8331e696
commit
27a07461b1
@ -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)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user