コード例 #1
0
        public override void Save(Stream fileStream)
        {
            // Header
            var writer = new BINAWriter(fileStream, Header);

            writer.Write(0UL);
            writer.Write(0UL);

            writer.AddOffset("objectTableOffset", 8);
            writer.Write((ulong)Objects.Count);
            writer.Write((ulong)Objects.Count);
            writer.Write(0UL);

            // Objects
            writer.FillInOffsetLong("objectTableOffset", false, false);
            writer.AddOffsetTable("objectOffset", (uint)Objects.Count, 8);
            writer.FixPadding(16);

            for (int i = 0; i < Objects.Count; ++i)
            {
                var obj = Objects[i];
                writer.FillInOffsetLong($"objectOffset_{i}", false, false);
                WriteObject(writer, obj, i);
            }

            writer.FixPadding(16);

            // Object Parameters
            for (int i = 0; i < Objects.Count; ++i)
            {
                writer.FixPadding(16);
                WriteObjectParameters(writer, Objects[i], i);
            }

            writer.FinishWrite(Header);
        }
コード例 #2
0
        protected void WriteObject(BINAWriter writer, SetObject obj, int objID)
        {
            writer.Write(0UL);

            // Object Type
            writer.AddString($"objTypeOffset{objID}", obj.ObjectType, 8);

            // Object Name
            string name = "";

            if (obj.CustomData.ContainsKey("Name"))
            {
                name = (obj.CustomData["Name"].Data as string);
            }

            if (string.IsNullOrEmpty(name))
            {
                name = $"{obj.ObjectType}{objID}";
            }

            writer.AddString($"objNameOffset{objID}", name, 8);

            // Object Entry
            writer.Write((ushort)obj.ObjectID);
            writer.Write((obj.CustomData.ContainsKey("GroupID")) ?
                         (ushort)obj.CustomData["GroupID"].Data :
                         obj.GetCustomDataValue <ushort>("Unknown1"));

            writer.Write(obj.GetCustomDataValue <ushort>("ParentID"));
            writer.Write((obj.CustomData.ContainsKey("ParentGroupID")) ?
                         (ushort)obj.CustomData["ParentGroupID"].Data :
                         obj.GetCustomDataValue <ushort>("ParentUnknown1"));

            writer.Write(obj.Transform.Position);
            writer.Write(obj.Transform.Rotation.ToEulerAngles(true));

            writer.Write((obj.CustomData.ContainsKey("ChildPosOffset")) ?
                         (Vector3)obj.CustomData["ChildPosOffset"].Data :
                         obj.Transform.Position);

            writer.Write((obj.CustomData.ContainsKey("ChildRotOffset")) ?
                         (Vector3)obj.CustomData["ChildRotOffset"].Data :
                         obj.Transform.Rotation.ToEulerAngles(true));

            // Extra Parameter Entries
            uint extraParamCounts = (uint)obj.CustomData.Count;

            if (obj.CustomData.ContainsKey("Name"))
            {
                extraParamCounts -= 1;
            }

            if (obj.CustomData.ContainsKey("RangeOut"))
            {
                extraParamCounts -= 1;
            }

            if (obj.CustomData.ContainsKey("GroupID") ||
                obj.CustomData.ContainsKey("Unknown1"))
            {
                extraParamCounts -= 1;
            }

            if (obj.CustomData.ContainsKey("ParentID"))
            {
                extraParamCounts -= 1;
            }

            if (obj.CustomData.ContainsKey("ParentGroupID") ||
                obj.CustomData.ContainsKey("ParentUnknown1"))
            {
                extraParamCounts -= 1;
            }

            if (obj.CustomData.ContainsKey("ChildPosOffset"))
            {
                extraParamCounts -= 1;
            }

            if (obj.CustomData.ContainsKey("ChildRotOffset"))
            {
                extraParamCounts -= 1;
            }

            if (obj.CustomData.ContainsKey("RawByteLength"))
            {
                extraParamCounts -= 1;
            }

            writer.AddOffset($"extraParamsOffset{objID}", 8);
            writer.Write((ulong)extraParamCounts); // TODO
            writer.Write((ulong)extraParamCounts); // TODO
            writer.Write(0UL);
            writer.AddOffset($"objParamsOffset{objID}", 8);
            writer.FixPadding(16);

            writer.FillInOffsetLong($"extraParamsOffset{objID}", false, false);
            writer.AddOffsetTable($"extraParamOffset{objID}", extraParamCounts, 8);
            writer.FixPadding(16); // TODO: Make sure this is correct

            int i = -1;

            foreach (var customData in obj.CustomData)
            {
                if (customData.Key == "Name" || customData.Key == "GroupID" ||
                    customData.Key == "Unknown1" || customData.Key == "ParentID" ||
                    customData.Key == "ParentGroupID" || customData.Key == "ParentUnknown1" ||
                    customData.Key == "RangeOut" || customData.Key == "ChildPosOffset" ||
                    customData.Key == "ChildRotOffset" || customData.Key == "RawByteLength")
                {
                    continue;
                }

                writer.FillInOffsetLong(
                    $"extraParamOffset{objID}_{++i}", false, false);

                writer.Write(0UL);
                writer.AddString($"extraParamNameOffset{objID}{i}",
                                 (customData.Key == "RangeIn") ? "RangeSpawning" : customData.Key, 8);

                if (!WriteExtraParamLength(writer, customData))
                {
                    writer.Write(0);
                    Console.WriteLine(
                        $"WARNING: CustomData {customData.Key} skipped; Unknown Type!");
                }

                writer.AddOffset($"extraParamDataOffset{objID}{i}", 8);
            }

            // Extra Parameter Data
            foreach (var customData in obj.CustomData)
            {
                if (customData.Key == "Name" || customData.Key == "GroupID" ||
                    customData.Key == "Unknown1" || customData.Key == "ParentID" ||
                    customData.Key == "ParentGroupID" || customData.Key == "ParentUnknown1" ||
                    customData.Key == "RangeOut" || customData.Key == "ChildPosOffset" ||
                    customData.Key == "ChildRotOffset" || customData.Key == "RawByteLength")
                {
                    continue;
                }

                writer.FillInOffsetLong(
                    $"extraParamDataOffset{objID}{i}", false, false);

                if (!WriteExtraParamData(writer, obj, customData))
                {
                    writer.Write(0UL);
                }
            }
        }
コード例 #3
0
        public static void Write(BINAWriter writer, List <SetObject> objects, SOBJType type)
        {
            // Get some data we need to write the file
            var  objectsByType = new Dictionary <string, List <int> >();
            uint transformCount = 0, objTypeCount = 0;

            for (int objIndex = 0; objIndex < objects.Count; ++objIndex)
            {
                var obj = objects[objIndex];
                if (!objectsByType.ContainsKey(obj.ObjectType))
                {
                    objectsByType.Add(obj.ObjectType, new List <int>()
                    {
                        objIndex
                    });
                    ++objTypeCount;
                }
                else
                {
                    objectsByType[obj.ObjectType].Add(objIndex);
                }

                transformCount += (uint)obj.Children.Length + 1;
            }

            // SOBJ Header
            var sig = Signature.ToCharArray();

            if (!writer.IsBigEndian)
            {
                Array.Reverse(sig);
            }

            writer.Write(sig);
            writer.Write(1u); // TODO: Figure out what this value is.
            writer.Write(objTypeCount);
            writer.AddOffset("objTypeOffsetsOffset");

            writer.Write((type == SOBJType.LostWorld) ?
                         0 : 0xFFFFFFFF); // I doubt this matters at all tbh.
            writer.AddOffset("objOffsetsOffset");
            writer.Write(objects.Count);
            writer.WriteNulls(4);

            writer.Write(transformCount);

            // Object Offsets
            writer.FillInOffset("objOffsetsOffset", false);
            writer.AddOffsetTable("objOffset", (uint)objects.Count);

            // Object Types
            uint i = 0;

            writer.FillInOffset("objTypeOffsetsOffset", false);

            foreach (var obj in objectsByType)
            {
                writer.AddString($"objName_{i}", obj.Key);
                writer.Write((uint)obj.Value.Count);
                writer.AddOffset($"objIndicesOffset_{i}");

                ++i;
            }

            // Object Indices
            ushort i2 = 0;

            i = 0;

            foreach (var obj in objectsByType)
            {
                writer.FillInOffset($"objIndicesOffset_{i}", false);
                for (int i3 = 0; i3 < obj.Value.Count; ++i3)
                {
                    writer.Write(i2);
                    ++i2;
                }

                ++i;
            }

            // Objects
            writer.FixPadding(4);
            i = 0;

            foreach (var objType in objectsByType)
            {
                foreach (int objIndex in objType.Value)
                {
                    writer.FillInOffset($"objOffset_{i}", false);
                    WriteObject(writer, objects[objIndex], type);
                    writer.FixPadding(0x4);
                    ++i;
                }
            }

            // TODO: Clean this up
            writer.FixPadding(4);

            foreach (var objType in objectsByType)
            {
                foreach (int objIndex in objType.Value)
                {
                    // Transforms
                    writer.FixPadding(0x4);
                    writer.FillInOffset($"transformsOffset_{objects[objIndex].ObjectID}", false);
                    WriteTransform(writer, objects[objIndex].Transform,
                                   type == SOBJType.LostWorld);

                    foreach (var childTransform in objects[objIndex].Children)
                    {
                        WriteTransform(writer, childTransform,
                                       type == SOBJType.LostWorld);
                    }
                }
            }
        }