using System; using System.Collections.Generic; using Oni.Metadata; namespace Oni.Objects { internal class ObjcDatWriter : Importer { private readonly TypeTag tag; private readonly string name; private readonly List objects; private readonly Type type; private ObjcDatWriter(TypeTag tag, string name, List objects) { this.tag = tag; this.name = name; this.objects = objects; if (tag == TypeTag.CHAR) type = typeof(Character); else if (tag == TypeTag.WEAP) type = typeof(Weapon); else if (tag == TypeTag.PART) type = typeof(Particle); else if (tag == TypeTag.PWRU) type = typeof(PowerUp); else if (tag == TypeTag.FLAG) type = typeof(Flag); else if (tag == TypeTag.DOOR) type = typeof(Door); else if (tag == TypeTag.CONS) type = typeof(Objects.Console); else if (tag == TypeTag.FURN) type = typeof(Furniture); else if (tag == TypeTag.TRIG) type = typeof(Trigger); else if (tag == TypeTag.TRGV) type = typeof(TriggerVolume); else if (tag == TypeTag.SNDG) type = typeof(Objects.Sound); else if (tag == TypeTag.TURR) type = typeof(Turret); else if (tag == TypeTag.NEUT) type = typeof(Neutral); else if (tag == TypeTag.PATR) type = typeof(PatrolPath); } private enum TypeTag { CHAR = 0x43484152, CMBT = 0x434d4254, CONS = 0x434f4e53, DOOR = 0x444f4f52, FLAG = 0x464c4147, FURN = 0x4655524e, MELE = 0x4d454c45, NEUT = 0x4e455554, PART = 0x50415254, PATR = 0x50415452, PWRU = 0x50575255, SNDG = 0x534e4447, TRGV = 0x54524756, TRIG = 0x54524947, TURR = 0x54555252, WEAP = 0x57454150 } public static void Write(List objects, string outputDirPath) { System.Console.Error.WriteLine("Writing {0} objects...", objects.Count); Write(TypeTag.CHAR, "Character", objects, outputDirPath); Write(TypeTag.CONS, "Console", objects, outputDirPath); Write(TypeTag.DOOR, "Door", objects, outputDirPath); Write(TypeTag.FLAG, "Flag", objects, outputDirPath); Write(TypeTag.FURN, "Furniture", objects, outputDirPath); Write(TypeTag.NEUT, "Neutral", objects, outputDirPath); Write(TypeTag.PART, "Particle", objects, outputDirPath); Write(TypeTag.PATR, "Patrol Path", objects, outputDirPath); Write(TypeTag.PWRU, "PowerUp", objects, outputDirPath); Write(TypeTag.SNDG, "Sound", objects, outputDirPath); Write(TypeTag.TRIG, "Trigger", objects, outputDirPath); Write(TypeTag.TRGV, "Trigger Volume", objects, outputDirPath); Write(TypeTag.TURR, "Turret", objects, outputDirPath); Write(TypeTag.WEAP, "Weapon", objects, outputDirPath); } private static void Write(TypeTag tag, string name, List objects, string outputDirPath) { var writer = new ObjcDatWriter(tag, name, objects); writer.Import(null, outputDirPath); } public override void Import(string filePath, string outputDirPath) { BeginImport(); var bina = CreateInstance(TemplateTag.BINA, "CJBO" + name); int offset = RawWriter.Align32(); int size = WriteCollection(RawWriter); using (var writer = bina.OpenWrite()) { writer.Write(size); writer.Write(offset); } Write(outputDirPath); } private int WriteCollection(BinaryWriter raw) { int start = raw.Position; raw.Write((int)BinaryTag.OBJC); raw.Write(0); raw.Write(39); foreach (var obj in objects.Where(o => o.GetType() == type)) { int objectStartPosition = raw.Position; raw.Write(0); raw.Write((int)tag); obj.Write(raw); raw.Position = Utils.Align4(raw.Position); int objectSize = raw.Position - objectStartPosition - 4; raw.WriteAt(objectStartPosition, objectSize); } raw.Write(0); int size = raw.Position - start; raw.WriteAt(start + 4, size - 8); return size; } } }