private void ReadHeader(BinaryReader reader, ref Header header, uint offset) { switch (header.type) { case HeaderType.SpecialWorld: case HeaderType.World: { uint position = offset; while (position + 6 < offset + header.size) { reader.BaseStream.Seek(position, SeekOrigin.Begin); var nextHeader = ReadHeader(reader); ReadHeader(reader, ref nextHeader, position + 6); position += nextHeader.size; } } break; case HeaderType.ViewDistance: { viewDistance = reader.ReadSingle(); } break; case HeaderType.ClippingPlanes: { clippingPlanes = ReadVector2(reader); } break; case HeaderType.Fov: { FOV = reader.ReadSingle(); } break; case HeaderType.SpecialObject: case HeaderType.Object: { uint position = offset; Object newObject = new Object(); while (position + 6 < offset + header.size) { reader.BaseStream.Seek(position, SeekOrigin.Begin); var nextHeader = ReadHeader(reader); ReadObject(reader, ref nextHeader, ref newObject, position + 6); position += nextHeader.size; } if (header.type == HeaderType.Object) { objects.Add(newObject.name, newObject); } else { if (objects.ContainsKey(newObject.name)) { var targetObject = objects[newObject.name]; targetObject.specialType = newObject.specialType; targetObject.physicalObject = newObject.physicalObject; targetObject.doorObject = newObject.doorObject; } else { var go = BaseGenerator.FetchCacheReference(GameAPI.instance.missionManager.mission, newObject.name)?.gameObject; if (go != null) { var objDef = go.GetComponent <ObjectDefinition>(); if (objDef == null) { objDef = go.AddComponent <ObjectDefinition>(); } objDef.data = newObject; objDef.Init(); } else { objects.Add(newObject.name, newObject); } } } } break; } }