//find the chunk, replace the chunk, perhaps create or remove the reference public static void ReplaceChunk(this GenericRCOLResource rcolResource, MLOD.Mesh mesh, string field, IResourceKey rk, ARCOLBlock block) { ARCOLBlock current = GenericRCOLResource.ChunkReference.GetBlock(rcolResource, (GenericRCOLResource.ChunkReference)mesh[field].Value) as ARCOLBlock; if (block != null) { if (current != null) // replacing is easy { if (current.Tag != block.Tag) { throw new Exception(string.Format("mesh field {0} is '{1}' but replacement is '{2}'.", field, current.Tag, block.Tag)); } // ...not entirely sure if these are required... current.Data = block.Data; block = current; } else // adding is okay { rcolResource.ChunkEntries.Add(new GenericRCOLResource.ChunkEntry(0, null, new TGIBlock(0, null, rk), block)); mesh[field] = new TypedValue(typeof(GenericRCOLResource.ChunkReference), GenericRCOLResource.ChunkReference.CreateReference(rcolResource, rk), "X"); } } else // deleting is not allowed - we can only null the reference, not remove the chunk { mesh[field] = new TypedValue(typeof(GenericRCOLResource.ChunkReference), new GenericRCOLResource.ChunkReference(0, null, 0), "X"); } }
static int Main(params string[] args) { #if DEBUG if (args.Length == 0) { TGIBlock tgib = new TGIBlock(0, null, "ITG", 0x736884F1, 0, 0); ARCOLBlock rcol = GenericRCOLResourceHandler.CreateRCOLBlock(0, null, 0x736884F1); GenericRCOLResource.ChunkEntry ce = new GenericRCOLResource.ChunkEntry(0, null, tgib, rcol); GenericRCOLResource grr = new GenericRCOLResource(0, null); grr.ChunkEntries.Add(ce); Clipboard.SetData(DataFormats.Serializable, grr.Stream); } #endif return(s3pi.Helpers.RunHelper.Run(typeof(MainForm), args)); }
//find the chunk, replace the chunk, perhaps create or remove the reference public static void ReplaceChunk(this GenericRCOLResource rcolResource, MLOD.Mesh mesh, string field, IResourceKey rk, ARCOLBlock block) { ARCOLBlock current = GenericRCOLResource.ChunkReference.GetBlock(rcolResource, (GenericRCOLResource.ChunkReference)mesh[field].Value) as ARCOLBlock; if (block != null) { if (current != null) // replacing is easy { if (current.Tag != block.Tag) throw new Exception(string.Format("mesh field {0} is '{1}' but replacement is '{2}'.", field, current.Tag, block.Tag)); // ...not entirely sure if these are required... current.Data = block.Data; block = current; } else // adding is okay { rcolResource.ChunkEntries.Add(new GenericRCOLResource.ChunkEntry(0, null, new TGIBlock(0, null, rk), block)); mesh[field] = new TypedValue(typeof(GenericRCOLResource.ChunkReference), GenericRCOLResource.ChunkReference.CreateReference(rcolResource, rk), "X"); } } else // deleting is not allowed - we can only null the reference, not remove the chunk { mesh[field] = new TypedValue(typeof(GenericRCOLResource.ChunkReference), new GenericRCOLResource.ChunkReference(0, null, 0), "X"); } }
static GenericRCOLResourceHandler() { typeRegistry = new Dictionary <uint, Type>(); tagRegistry = new Dictionary <string, Type>(); string folder = Path.GetDirectoryName(typeof(GenericRCOLResourceHandler).Assembly.Location); foreach (string path in Directory.GetFiles(folder, "*.dll")) { //Protect load of DLL try { Assembly dotNetDll = Assembly.LoadFile(path); Type[] types = dotNetDll.GetTypes(); foreach (Type t in types) { if (t.IsAbstract) { continue; } if (!t.IsSubclassOf(typeof(ARCOLBlock))) { continue; } //Protect instantiating class try { ConstructorInfo ctor = t.GetConstructor(new Type[] { typeof(int), typeof(EventHandler), typeof(Stream), }); if (ctor == null) { continue; } ARCOLBlock arb = (ARCOLBlock)ctor.Invoke(new object[] { 0, null, null }); if (!typeRegistry.ContainsKey(arb.ResourceType)) { typeRegistry.Add(arb.ResourceType, arb.GetType()); } if (!tagRegistry.ContainsKey(arb.Tag)) { tagRegistry.Add(arb.Tag, arb.GetType()); } } catch { } } } catch { } } StringReader sr = new StringReader(Resources.RCOLResources); resourceTypes = new List <string>(); string s; while ((s = sr.ReadLine()) != null) { if (s.StartsWith(";")) { continue; } string[] t = s.Split(new char[] { ' ' }, 4, StringSplitOptions.RemoveEmptyEntries); if (t[2].Equals("Y")) { resourceTypes.Add(t[0]); } } }
/// <summary> /// Create a ChunkEntry from an existing <see cref="TGIBlock"/> and an existing <see cref="ARCOLBlock"/>. /// </summary> /// <param name="APIversion">Unused; the requested API version.</param> /// <param name="handler">The change event handler.</param> /// <param name="tgiBlock">An existing <see cref="T:TGIBlock"/>.</param> /// <param name="rcolBlock">An existing <see cref="ARCOLBlock"/>.</param> public ChunkEntry(int APIversion, EventHandler handler, TGIBlock tgiBlock, ARCOLBlock rcolBlock) : base(APIversion, handler) { this.tgiBlock = tgiBlock.Clone(handler) as TGIBlock; this.rcolBlock = rcolBlock.Clone(handler) as ARCOLBlock; }