From 27a07461b13fcfbd391c6abad7e9ad4e26e7b186 Mon Sep 17 00:00:00 2001 From: dexy Date: Thu, 11 Jul 2024 09:25:01 +1000 Subject: [PATCH] PR #223 but slightly nicer --- .../GameFiles/FileTypes/YmapFile.cs | 9 ++- .../GameFiles/MetaTypes/MetaTypes.cs | 64 ++++++++----------- 2 files changed, 29 insertions(+), 44 deletions(-) diff --git a/CodeWalker.Core/GameFiles/FileTypes/YmapFile.cs b/CodeWalker.Core/GameFiles/FileTypes/YmapFile.cs index 09a5e5a..d59c238 100644 --- a/CodeWalker.Core/GameFiles/FileTypes/YmapFile.cs +++ b/CodeWalker.Core/GameFiles/FileTypes/YmapFile.cs @@ -259,14 +259,13 @@ namespace CodeWalker.GameFiles private void EnsureEntities(Meta Meta) { - //CMloInstanceDefs = MetaTypes.ConvertDataArray(Meta, MetaName.CMloInstanceDef, CMapData.entities); - CMloInstanceDefs = MetaTypes.GetTypedDataArray(Meta, MetaName.CMloInstanceDef); + var eptrs = MetaTypes.GetPointerArray(Meta, _CMapData.entities); + + CMloInstanceDefs = MetaTypes.GetTypedPointerArray(Meta, MetaName.CMloInstanceDef, eptrs); if (CMloInstanceDefs != null) { } - var eptrs = MetaTypes.GetPointerArray(Meta, _CMapData.entities); - //CEntityDefs = MetaTypes.ConvertDataArray(Meta, MetaName.CEntityDef, CMapData.entities); - CEntityDefs = MetaTypes.GetTypedDataArray(Meta, MetaName.CEntityDef); + CEntityDefs = MetaTypes.GetTypedPointerArray(Meta, MetaName.CEntityDef, eptrs); if (CEntityDefs != null) { } diff --git a/CodeWalker.Core/GameFiles/MetaTypes/MetaTypes.cs b/CodeWalker.Core/GameFiles/MetaTypes/MetaTypes.cs index 785cd28..8b84b9d 100644 --- a/CodeWalker.Core/GameFiles/MetaTypes/MetaTypes.cs +++ b/CodeWalker.Core/GameFiles/MetaTypes/MetaTypes.cs @@ -1759,49 +1759,35 @@ namespace CodeWalker.GameFiles } - public static T[] GetTypedDataArray(Meta meta, MetaName name) where T : struct + public static T[] GetTypedPointerArray(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; - - MetaDataBlock startblock = null; - int startblockind = -1; - for (int i = 0; i < datablocks.Count; i++) + if (datablocks == null) return null; + int tsize = Marshal.SizeOf(typeof(T)); + var list = new List(); + for (int i = 0; i < arr.Length; i++) { - var block = datablocks[i]; - if (block.StructureNameHash == name) - { - startblock = block; - startblockind = i; - break; - } + ref var ptr = ref arr[i]; + var blockind = ptr.BlockIndex; + if (blockind < 0) continue; + if (blockind >= datablocks.Count) continue; + var block = datablocks[blockind]; + 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(block.Data, offset); + list.Add(item); } - if (startblock == null) - { - 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(meta, name, (uint)startblockind + 1, (uint)count); + if (list.Count == 0) return null; + return list.ToArray(); } public static T GetTypedData(Meta meta, MetaName name) where T : struct {