using System; using System.Collections.Generic; using System.ComponentModel; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CodeWalker.GameFiles { [TypeConverter(typeof(ExpandableObjectConverter))] public class YtypFile : PackedFile { public RpfFileEntry FileEntry { get; set; } public Meta Meta { get; set; } public PsoFile Pso { get; set; } public RbfFile Rbf { get; set; } public CMapTypes CMapTypes { get; set; } //public CBaseArchetypeDef[] CBaseArchetypeDefs { get; set; } //public CTimeArchetypeDef[] CTimeArchetypeDefs { get; set; } //public CMloArchetypeDef[] CMloArchetypeDefs { get; set; } public CExtensionDefAudioEmitter[] AudioEmitters { get; set; } //public CEntityDef[] CEntityDefs { get; set; } public CCompositeEntityType[] CompositeEntityTypes { get; set; } public uint NameHash { get; set; } public string[] Strings { get; set; } public Archetype[] AllArchetypes { get; set; } public MetaWrapper[] Extensions { get; set; } public override string ToString() { return (FileEntry != null) ? FileEntry.Name : string.Empty; } public void Load(byte[] data, RpfFileEntry entry) { FileEntry = entry; RpfResourceFileEntry resentry = entry as RpfResourceFileEntry; if (resentry == null) { MemoryStream ms = new MemoryStream(data); if (RbfFile.IsRBF(ms)) { Rbf = new RbfFile(); Rbf.Load(ms); } else if (PsoFile.IsPSO(ms)) { Pso = new PsoFile(); Pso.Load(ms); //PsoTypes.EnsurePsoTypes(Pso); } else { } return; } ResourceDataReader rd = new ResourceDataReader(resentry, data); Meta = rd.ReadBlock(); CMapTypes = MetaTypes.GetTypedData(Meta, MetaName.CMapTypes); List allarchs = new List(); var ptrs = MetaTypes.GetPointerArray(Meta, CMapTypes.archetypes); if (ptrs != null) { for (int i = 0; i < ptrs.Length; i++) { var ptr = ptrs[i]; int blocki = ptr.BlockID - 1; int offset = ptr.ItemOffset * 16;//block data size... if (blocki >= Meta.DataBlocks.Count) { continue; } var block = Meta.DataBlocks[blocki]; if ((offset < 0) || (block.Data == null) || (offset >= block.Data.Length)) { continue; } var ba = new Archetype(); switch (block.StructureNameHash) { case MetaName.CBaseArchetypeDef: var basearch = PsoTypes.ConvertDataRaw(block.Data, offset); ba.Init(this, basearch); ba.Extensions = MetaTypes.GetExtensions(Meta, basearch.extensions); break; case MetaName.CTimeArchetypeDef: var timearch = PsoTypes.ConvertDataRaw(block.Data, offset); ba.Init(this, timearch); ba.Extensions = MetaTypes.GetExtensions(Meta, timearch.CBaseArchetypeDef.extensions); break; case MetaName.CMloArchetypeDef: var mloarch = PsoTypes.ConvertDataRaw(block.Data, offset); ba.Init(this, mloarch); ba.Extensions = MetaTypes.GetExtensions(Meta, mloarch.CBaseArchetypeDef.extensions); MloArchetypeData mlod = new MloArchetypeData(); mlod.entities = MetaTypes.ConvertDataArray(Meta, MetaName.CEntityDef, mloarch.entities); mlod.rooms = MetaTypes.ConvertDataArray(Meta, MetaName.CMloRoomDef, mloarch.rooms); mlod.portals = MetaTypes.ConvertDataArray(Meta, MetaName.CMloPortalDef, mloarch.portals); mlod.entitySets = MetaTypes.ConvertDataArray(Meta, MetaName.CMloEntitySet, mloarch.entitySets); mlod.timeCycleModifiers = MetaTypes.ConvertDataArray(Meta, MetaName.CMloTimeCycleModifier, mloarch.timeCycleModifiers); ba.MloData = mlod; //if (mlod.entities != null) //{ // for (int e = 0; e < mlod.entities.Length; e++) // { // EnsureEntityExtensions(Meta, ref mlod.entities[e]); // } //} break; default: continue; } allarchs.Add(ba); } } AllArchetypes = allarchs.ToArray(); Extensions = MetaTypes.GetExtensions(Meta, CMapTypes.extensions); if (Extensions != null) { } AudioEmitters = MetaTypes.GetTypedDataArray(Meta, MetaName.CExtensionDefAudioEmitter); if (AudioEmitters != null) { } //CEntityDefs = MetaTypes.GetTypedDataArray(Meta, MetaName.CEntityDef); CompositeEntityTypes = MetaTypes.ConvertDataArray(Meta, MetaName.CCompositeEntityType, CMapTypes.compositeEntityTypes); if (CompositeEntityTypes != null) { } NameHash = CMapTypes.name; if (NameHash == 0) { int ind = entry.NameLower.LastIndexOf('.'); if (ind > 0) { NameHash = JenkHash.GenHash(entry.NameLower.Substring(0, ind)); } else { NameHash = JenkHash.GenHash(entry.NameLower); } } Strings = MetaTypes.GetStrings(Meta); if (Strings != null) { foreach (string str in Strings) { JenkIndex.Ensure(str); //just shove them in there } } foreach (var block in Meta.DataBlocks) { switch(block.StructureNameHash) { case MetaName.CMapTypes: case MetaName.CTimeArchetypeDef: case MetaName.CBaseArchetypeDef: case MetaName.CMloArchetypeDef: case MetaName.CMloTimeCycleModifier: case MetaName.CMloRoomDef: case MetaName.CMloPortalDef: case MetaName.CMloEntitySet: case MetaName.CEntityDef: case MetaName.CExtensionDefParticleEffect: case MetaName.CExtensionDefAudioCollisionSettings: case MetaName.CExtensionDefSpawnPoint: case MetaName.CExtensionDefSpawnPointOverride: case MetaName.CExtensionDefExplosionEffect: case MetaName.CExtensionDefAudioEmitter: case MetaName.CExtensionDefLadder: case MetaName.CExtensionDefBuoyancy: case MetaName.CExtensionDefExpression: case MetaName.CExtensionDefLightShaft: case MetaName.CExtensionDefLightEffect: case MetaName.CExtensionDefDoor: case MetaName.CExtensionDefWindDisturbance: case MetaName.CExtensionDefProcObject: case MetaName.CLightAttrDef: case MetaName.STRING: //case MetaName.SectionUNKNOWN2: //case MetaName.SectionUNKNOWN3: //case MetaName.SectionUNKNOWN8: case MetaName.POINTER: case MetaName.UINT: case MetaName.VECTOR4: break; default: break; } } //MetaTypes.ParseMetaData(Meta); //RpfResourceFileEntry resentry = entry as RpfResourceFileEntry; //if (resentry == null) //{ // throw new Exception("File entry wasn't a resource! (is it binary data?)"); //} //ResourceDataReader rd = new ResourceDataReader(resentry, data); //Meta = rd.ReadBlock(); //MetaTypes.EnsureMetaTypes(Meta); //MetaTypes.ParseMetaData(Meta); } } }