예제 #1
0
        private void WriteType3(List <BSA.BSA_Type3> type, int hdrOffset, int dataOffset)
        {
            if (type != null)
            {
                //Hdr data
                bytes = Utils.ReplaceRange(bytes, BitConverter.GetBytes(bytes.Count() - hdrOffset + 8), hdrOffset);

                for (int i = 0; i < type.Count(); i++)
                {
                    bytes.AddRange(BitConverter.GetBytes(type[i].StartTime));
                    bytes.AddRange(BitConverter.GetBytes(GetTypeEndTime(type[i].StartTime, type[i].Duration)));
                }

                //Main Type Data
                bytes = Utils.ReplaceRange(bytes, BitConverter.GetBytes(bytes.Count() - dataOffset + 12), dataOffset);

                for (int i = 0; i < type.Count(); i++)
                {
                    bytes.AddRange(BitConverter.GetBytes(type[i].I_00));
                    bytes.AddRange(BitConverter.GetBytes(type[i].I_02));
                    bytes.AddRange(BitConverter.GetBytes(type[i].I_04));
                    bytes.Add(Int4Converter.GetByte(type[i].I_06_a, type[i].I_06_b, "Hitbox I_06 > a", "Hitbox I_06 > b"));
                    bytes.Add(Int4Converter.GetByte(type[i].I_06_c, type[i].I_06_d, "Hitbox I_06 > c", "Hitbox I_06 > d"));
                    bytes.AddRange(BitConverter.GetBytes(type[i].F_08));
                    bytes.AddRange(BitConverter.GetBytes(type[i].F_12));
                    bytes.AddRange(BitConverter.GetBytes(type[i].F_16));
                    bytes.AddRange(BitConverter.GetBytes(type[i].F_20));
                    bytes.AddRange(BitConverter.GetBytes(type[i].F_24));
                    bytes.AddRange(BitConverter.GetBytes(type[i].F_28));
                    bytes.AddRange(BitConverter.GetBytes(type[i].F_32));
                    bytes.AddRange(BitConverter.GetBytes(type[i].F_36));
                    bytes.AddRange(BitConverter.GetBytes(type[i].F_40));
                    bytes.AddRange(BitConverter.GetBytes(type[i].F_44));
                    bytes.AddRange(BitConverter.GetBytes(type[i].I_48));
                    bytes.AddRange(BitConverter.GetBytes(type[i].I_50));
                    bytes.AddRange(BitConverter.GetBytes(type[i].I_52));
                    bytes.AddRange(BitConverter.GetBytes(type[i].I_54));
                    bytes.AddRange(BitConverter.GetBytes(type[i].I_56));
                    bytes.AddRange(BitConverter.GetBytes(type[i].FirstHit));
                    bytes.AddRange(BitConverter.GetBytes(type[i].MultipleHits));
                    bytes.AddRange(BitConverter.GetBytes(type[i].LastHit));
                }
            }
        }
예제 #2
0
        private void Write()
        {
            //offsets
            List <int>    StrOffsets    = new List <int>();
            List <string> StrToWrite    = new List <string>();
            List <int>    Type0_Offsets = new List <int>();

            bytes.AddRange(BitConverter.GetBytes((ushort)37568));
            bytes.AddRange(BitConverter.GetBytes((ushort)65535));
            bytes.AddRange(BitConverter.GetBytes(ecfFile.I_12));
            bytes.AddRange(new byte[12]);

            if (ecfFile.Entries != null)
            {
                bytes.AddRange(BitConverter.GetBytes((short)ecfFile.Entries.Count()));
                bytes.AddRange(BitConverter.GetBytes(32));


                for (int i = 0; i < ecfFile.Entries.Count(); i++)
                {
                    bytes.AddRange(BitConverter.GetBytes(ecfFile.Entries[i].F_00));
                    bytes.AddRange(BitConverter.GetBytes(ecfFile.Entries[i].F_04));
                    bytes.AddRange(BitConverter.GetBytes(ecfFile.Entries[i].F_08));
                    bytes.AddRange(BitConverter.GetBytes(ecfFile.Entries[i].F_12));
                    bytes.AddRange(BitConverter.GetBytes(ecfFile.Entries[i].F_16));
                    bytes.AddRange(BitConverter.GetBytes(ecfFile.Entries[i].F_20));
                    bytes.AddRange(BitConverter.GetBytes(ecfFile.Entries[i].F_24));
                    bytes.AddRange(BitConverter.GetBytes(ecfFile.Entries[i].F_28));
                    bytes.AddRange(BitConverter.GetBytes(ecfFile.Entries[i].F_32));
                    bytes.AddRange(BitConverter.GetBytes(ecfFile.Entries[i].F_36));
                    bytes.AddRange(BitConverter.GetBytes(ecfFile.Entries[i].F_40));
                    bytes.AddRange(BitConverter.GetBytes(ecfFile.Entries[i].F_44));
                    bytes.AddRange(BitConverter.GetBytes(ecfFile.Entries[i].F_48));
                    bytes.AddRange(BitConverter.GetBytes((ushort)ecfFile.Entries[i].I_52));
                    bytes.AddRange(BitConverter.GetBytes(ecfFile.Entries[i].I_54));
                    bytes.AddRange(BitConverter.GetBytes(ecfFile.Entries[i].I_56));
                    bytes.AddRange(BitConverter.GetBytes(ecfFile.Entries[i].I_58));
                    bytes.AddRange(BitConverter.GetBytes(ecfFile.Entries[i].I_60));
                    bytes.AddRange(BitConverter.GetBytes(ecfFile.Entries[i].I_62));

                    foreach (UInt16 value in ecfFile.Entries[i].I_64)
                    {
                        bytes.AddRange(BitConverter.GetBytes(value));
                    }

                    if (!String.IsNullOrWhiteSpace(ecfFile.Entries[i].Unk_Str))
                    {
                        StrOffsets.Add(bytes.Count());
                        StrToWrite.Add(ecfFile.Entries[i].Unk_Str);
                    }

                    bytes.AddRange(new byte[4]);

                    bytes.AddRange(BitConverter.GetBytes(ecfFile.Entries[i].I_96));
                    if (ecfFile.Entries[i].Type0 != null)
                    {
                        bytes.AddRange(BitConverter.GetBytes((short)ecfFile.Entries[i].Type0.Count()));
                        Type0_Offsets.Add(bytes.Count());
                        bytes.AddRange(BitConverter.GetBytes(8));
                    }
                    else
                    {
                        Type0_Offsets.Add(bytes.Count());
                        bytes.AddRange(new byte[6]);
                    }
                }


                //Writing Type0s
                for (int i = 0; i < ecfFile.Entries.Count(); i++)
                {
                    if (ecfFile.Entries[i].Type0 != null)
                    {
                        bytes = Utils.ReplaceRange(bytes, BitConverter.GetBytes(bytes.Count() - Type0_Offsets[i] + 4), Type0_Offsets[i]);

                        List <int> Type0EntryOffsets = new List <int>();

                        foreach (var e in ecfFile.Entries[i].Type0)
                        {
                            int I_01_b = (e.I_01_b == true) ? 1 : 0;
                            int I_02   = (e.I_02 == true) ? 1 : 0;
                            bytes.AddRange(new byte[4] {
                                (byte)e.I_00, Int4Converter.GetByte((byte)e.GetComponent(), (byte)I_01_b, "Animation: Component", "Animation: Interpolated"), (byte)I_02, e.I_03
                            });
                            bytes.AddRange(BitConverter.GetBytes(e.I_04));
                            bytes.AddRange(BitConverter.GetBytes((short)e.Keyframes.Count()));
                            Type0EntryOffsets.Add(bytes.Count());
                            bytes.AddRange(new byte[8]);

                            //Sort keyframes
                            if (e.Keyframes != null)
                            {
                                e.Keyframes = Sorting.SortEntries2(e.Keyframes);
                            }
                        }

                        for (int a = 0; a < ecfFile.Entries[i].Type0.Count(); a++)
                        {
                            int entryOffset = Type0EntryOffsets[a] - 8;
                            bytes = Utils.ReplaceRange(bytes, BitConverter.GetBytes(bytes.Count() - entryOffset), Type0EntryOffsets[a]);

                            int floatListOffset = WriteKeyframe(ecfFile.Entries[i].Type0[a].Keyframes);

                            bytes = Utils.ReplaceRange(bytes, BitConverter.GetBytes(floatListOffset - entryOffset), Type0EntryOffsets[a] + 4);
                        }
                    }
                }



                //Writing Strings
                for (int i = 0; i < StrToWrite.Count(); i++)
                {
                    int entryOffset = StrOffsets[i] - 92;
                    bytes = Utils.ReplaceRange(bytes, BitConverter.GetBytes(bytes.Count() - entryOffset), StrOffsets[i]);
                    bytes.AddRange(Encoding.ASCII.GetBytes(StrToWrite[i]));
                    bytes.Add(0);
                }
            }
            else
            {
                bytes.AddRange(new byte[8]);
            }



            if (writeToDisk)
            {
                File.WriteAllBytes(saveLocation, bytes.ToArray());
            }
        }
예제 #3
0
        private void Write()
        {
            bytes.AddRange(BitConverter.GetBytes(bsaFile.I_08));
            bytes.AddRange(BitConverter.GetBytes(bsaFile.I_16));
            bytes.AddRange(BitConverter.GetBytes((short)EntryCount));
            bytes.AddRange(BitConverter.GetBytes(24));

            //MainEntry pointer list
            for (int a = 0; a < EntryCount; a++)
            {
                for (int i = 0; i < bsaFile.BSA_Entries.Count(); i++)
                {
                    if (a == bsaFile.BSA_Entries[i].Index)
                    {
                        //Entry exists
                        MainEntryOffsets.Add(bytes.Count());
                        bytes.AddRange(new byte[4]);
                        break;
                    }
                    if (i == bsaFile.BSA_Entries.Count() - 1)
                    {
                        //Null entry
                        bytes.AddRange(new byte[4]);
                        break;
                    }
                }
            }

            for (int i = 0; i < bsaFile.BSA_Entries.Count(); i++)
            {
                bytes = Utils.ReplaceRange(bytes, BitConverter.GetBytes(bytes.Count()), MainEntryOffsets[i]);

                int Unk1_Count = 0;
                int Unk2_Count = 0;
                if (bsaFile.BSA_Entries[i].SubEntries != null)
                {
                    Unk1_Count = (bsaFile.BSA_Entries[i].SubEntries.Unk1 != null) ? bsaFile.BSA_Entries[i].SubEntries.Unk1.Count() : 0;
                    Unk2_Count = (bsaFile.BSA_Entries[i].SubEntries.Unk2 != null) ? bsaFile.BSA_Entries[i].SubEntries.Unk2.Count() : 0;
                }


                bytes.AddRange(BitConverter.GetBytes(bsaFile.BSA_Entries[i].I_00));
                bytes.AddRange(BitConverter.GetBytes((short)Unk1_Count));
                bytes.AddRange(BitConverter.GetBytes((short)Unk2_Count));
                int Unk1_Offset = bytes.Count();
                bytes.AddRange(new byte[4]);
                int Unk2_Offset = bytes.Count();
                bytes.AddRange(new byte[4]);
                bytes.Add(Int4Converter.GetByte(bsaFile.BSA_Entries[i].I_16_a, bsaFile.BSA_Entries[i].I_16_b, "BSA_Entry: I_16 > a", "BSA_Entry: I_16 > b"));
                bytes.Add(bsaFile.BSA_Entries[i].I_17);
                bytes.AddRange(BitConverter.GetBytes(bsaFile.BSA_Entries[i].I_18));
                bytes.AddRange(BitConverter.GetBytes(bsaFile.BSA_Entries[i].I_22));
                bytes.AddRange(BitConverter.GetBytes(bsaFile.BSA_Entries[i].I_24));
                bytes.AddRange(BitConverter.GetBytes(bsaFile.BSA_Entries[i].I_26));
                bytes.AddRange(BitConverter.GetBytes(bsaFile.BSA_Entries[i].I_28));
                bytes.AddRange(BitConverter.GetBytes(bsaFile.BSA_Entries[i].I_30));
                bytes.AddRange(BitConverter.GetBytes(bsaFile.BSA_Entries[i].I_32));
                bytes.AddRange(BitConverter.GetBytes((short)BsaTypeCount(bsaFile.BSA_Entries[i])));
                int SubEntries_Offset = bytes.Count();
                bytes.AddRange(new byte[4]);

                if (bsaFile.BSA_Entries[i].SubEntries != null)
                {
                    WriteUnk1(bsaFile.BSA_Entries[i].SubEntries.Unk1, Unk1_Offset);
                    WriteUnk2(bsaFile.BSA_Entries[i].SubEntries.Unk2, Unk2_Offset);
                }

                WriteTypes(bsaFile.BSA_Entries[i], SubEntries_Offset);
            }
        }
예제 #4
0
        public static EMA_Command Read(byte[] rawBytes, int offset, float[] values, EMA_File emaFile, EmaType _emaType)
        {
            EMA_Command command = new EMA_Command();

            command.emaType = _emaType;

            if (emaFile.HasSkeleton)
            {
                command.BoneName = emaFile.GetBoneName(BitConverter.ToUInt16(rawBytes, offset + 0));
            }
            else
            {
                //This ema has no skeleton, thus no bones
                command.BoneName = null;
            }

            command.I_02 = rawBytes[offset + 2];

            BitArray flags_b = new BitArray(new byte[1] {
                Int4Converter.ToInt4(rawBytes[offset + 3])[1]
            });
            BitArray flags_a = new BitArray(new byte[1] {
                Int4Converter.ToInt4(rawBytes[offset + 3])[0]
            });

            command.I_03_b1 = flags_b[0];
            command.I_03_b2_Int16ForTime       = flags_b[1];
            command.I_03_b3_Int16ForValueIndex = flags_b[2];
            command.I_03_b4 = flags_b[3];
            command.I_03_a4 = flags_a[3];
            flags_a[3]      = false;
            command.I_03_a  = Int4Converter.GetByte(Utils.ConvertToByte(flags_a), 0);


            command.Keyframes = new ObservableCollection <EMA_Keyframe>();

            ushort keyframeCount = BitConverter.ToUInt16(rawBytes, offset + 4);
            ushort indexOffset   = BitConverter.ToUInt16(rawBytes, offset + 6);

            for (int i = 0; i < keyframeCount; i++)
            {
                ushort        time;
                float         value;
                string        value2 = null;
                string        value3 = null;
                string        value4 = null;
                KeyframeFlags flags;

                if (command.I_03_b2_Int16ForTime)
                {
                    time = BitConverter.ToUInt16(rawBytes, offset + 8 + (i * 2));
                }
                else
                {
                    time = rawBytes[offset + 8 + i];
                }

                if (command.I_03_b3_Int16ForValueIndex)
                {
                    value = values[BitConverter.ToUInt16(rawBytes, offset + indexOffset + (i * 4))];
                    flags = (KeyframeFlags)BitConverter.ToUInt16(rawBytes, offset + indexOffset + 2 + (i * 4));
                    int extraOffset = 0;

                    if (flags.HasFlag(KeyframeFlags.QuadraticBezier))
                    {
                        ushort idx = (ushort)(BitConverter.ToUInt16(rawBytes, offset + indexOffset + (i * 4)) + 1);

                        //idx might be out of range due to a bug with an older version of the parser... so in that case set it to value
                        if (idx <= values.Length - 1)
                        {
                            value2 = values[idx].ToString();
                        }
                        else
                        {
                            value2 = value.ToString();
                        }

                        extraOffset++;
                    }

                    if (flags.HasFlag(KeyframeFlags.CubicBezier))
                    {
                        ushort idx = (ushort)(BitConverter.ToUInt16(rawBytes, offset + indexOffset + (i * 4)) + 1 + extraOffset);

                        //idx might be out of range due to a bug with an older version of the parser... so in that case set it to value
                        if (idx + 1 <= values.Length - 1)
                        {
                            value3 = values[idx].ToString();
                            value4 = values[idx + 1].ToString();
                        }
                        else
                        {
                            value3 = value.ToString();
                            value4 = value.ToString();
                        }

                        extraOffset++;
                    }
                }
                else
                {
                    value = values[rawBytes[offset + indexOffset + (i * 2)]];
                    flags = (KeyframeFlags)rawBytes[offset + indexOffset + 1 + (i * 2)];
                    int extraOffset = 0;

                    if (flags.HasFlag(KeyframeFlags.QuadraticBezier))
                    {
                        byte idx = (byte)(rawBytes[offset + indexOffset + (i * 2)] + 1);

                        if (idx <= values.Length - 1)
                        {
                            value2 = values[idx].ToString();
                        }
                        else
                        {
                            value2 = value.ToString();
                        }
                    }

                    if (flags.HasFlag(KeyframeFlags.CubicBezier))
                    {
                        byte idx = (byte)(rawBytes[offset + indexOffset + (i * 2)] + 1 + extraOffset);

                        if (idx + 1 <= values.Length - 1)
                        {
                            value3 = values[idx].ToString();
                            value4 = values[idx + 1].ToString();
                        }
                        else
                        {
                            value3 = value.ToString();
                            value4 = value.ToString();
                        }
                    }
                }

                command.Keyframes.Add(new EMA_Keyframe()
                {
                    Time          = time,
                    Value         = value,
                    Flags         = flags,
                    Value2        = value2,
                    CubicBezier_1 = value3,
                    CubicBezier_2 = value4
                });
            }

            return(command);
        }
예제 #5
0
        public byte[] Write()
        {
            List <byte> bytes = new List <byte>();

            int        animCount       = GetIndexedAnimationCount();
            List <int> animNameOffsets = new List <int>();

            //Header
            bytes.AddRange(BitConverter.GetBytes(EMA_SIGNATURE));
            bytes.AddRange(BitConverter.GetBytes((ushort)65534));
            bytes.AddRange(BitConverter.GetBytes((ushort)32));
            bytes.AddRange(BitConverter.GetBytes((int)Version));
            bytes.AddRange(new byte[4]); //Skeleton offset
            bytes.AddRange(BitConverter.GetBytes((ushort)animCount));
            bytes.AddRange(BitConverter.GetBytes(I_18));
            bytes.AddRange(BitConverter.GetBytes(I_20));
            bytes.AddRange(BitConverter.GetBytes(I_24));
            bytes.AddRange(BitConverter.GetBytes(I_28));

            //Animation pointers
            bytes.AddRange(new byte[4 * animCount]);

            //Animations
            foreach (var anim in Animations)
            {
                int animStartOffset = bytes.Count;
                bytes = Utils.ReplaceRange(bytes, BitConverter.GetBytes(bytes.Count), 32 + (anim.Index * 4));

                List <float> values = anim.GetValues();

                bytes.AddRange(BitConverter.GetBytes(anim.I_00));
                bytes.AddRange(BitConverter.GetBytes((ushort)anim.CommandCount));
                bytes.AddRange(BitConverter.GetBytes((int)values.Count));
                bytes.AddRange(BitConverter.GetBytes((ushort)anim.I_08));
                bytes.AddRange(BitConverter.GetBytes((ushort)anim.I_10));
                animNameOffsets.Add(bytes.Count);
                bytes.AddRange(new byte[4]); //Name offset
                bytes.AddRange(new byte[4]); //value offset
                bytes.AddRange(new byte[4 * anim.CommandCount]);

                //Commands
                for (int i = 0; i < anim.CommandCount; i++)
                {
                    int startCommandOffset = bytes.Count;
                    bytes = Utils.ReplaceRange(bytes, BitConverter.GetBytes(bytes.Count - animStartOffset), animStartOffset + 20 + (i * 4));

                    anim.Commands[i].SetFlags(); //Calculate the known flags

                    if (HasSkeleton)
                    {
                        bytes.AddRange(BitConverter.GetBytes((ushort)GetBoneIndex(anim.Commands[i].BoneName)));
                    }
                    else
                    {
                        bytes.AddRange(new byte[2]);
                    }

                    bytes.Add(anim.Commands[i].I_02);

                    var bitArray_b = new BitArray(new bool[8] {
                        anim.Commands[i].I_03_b1, anim.Commands[i].I_03_b2_Int16ForTime, anim.Commands[i].I_03_b3_Int16ForValueIndex, anim.Commands[i].I_03_b4, false, false, false, false
                    });
                    var bitArray_a = new BitArray(new byte[1] {
                        anim.Commands[i].I_03_a
                    });

                    bitArray_a[3] = anim.Commands[i].I_03_a4;
                    bytes.Add((byte)Int4Converter.GetByte(Utils.ConvertToByte(bitArray_a), Utils.ConvertToByte(bitArray_b)));
                    bytes.AddRange(BitConverter.GetBytes((ushort)anim.Commands[i].KeyframeCount));
                    bytes.AddRange(new byte[2]);

                    //Sort keyframes
                    if (anim.Commands[i].KeyframeCount > 0)
                    {
                        var sortedList = anim.Commands[i].Keyframes.ToList();
                        sortedList.Sort((x, y) => x.Time - y.Time);
                        anim.Commands[i].Keyframes = new ObservableCollection <EMA_Keyframe>(sortedList);
                    }

                    //Write Time
                    for (int a = 0; a < anim.Commands[i].KeyframeCount; a++)
                    {
                        if (anim.Commands[i].I_03_b2_Int16ForTime)
                        {
                            bytes.AddRange(BitConverter.GetBytes(anim.Commands[i].Keyframes[a].Time));
                        }
                        else
                        {
                            bytes.Add((byte)anim.Commands[i].Keyframes[a].Time);
                        }
                    }

                    //Add padding
                    bytes.AddRange(new byte[Utils.CalculatePadding(bytes.Count - startCommandOffset, 4)]);

                    //Write value/index
                    bytes = Utils.ReplaceRange(bytes, BitConverter.GetBytes((ushort)(bytes.Count - startCommandOffset)), startCommandOffset + 6);
                    for (int a = 0; a < anim.Commands[i].KeyframeCount; a++)
                    {
                        if (anim.Commands[i].I_03_b3_Int16ForValueIndex)
                        {
                            bytes.AddRange(BitConverter.GetBytes((ushort)anim.Commands[i].Keyframes[a].index));
                            bytes.AddRange(BitConverter.GetBytes((ushort)anim.Commands[i].Keyframes[a].Flags));
                        }
                        else
                        {
                            bytes.Add((byte)anim.Commands[i].Keyframes[a].index);
                            bytes.Add((byte)anim.Commands[i].Keyframes[a].Flags);
                        }
                    }

                    //Add padding
                    bytes.AddRange(new byte[Utils.CalculatePadding(bytes.Count - startCommandOffset, 4)]);
                }

                //Values
                int valuesStartOffset = bytes.Count;
                bytes = Utils.ReplaceRange(bytes, BitConverter.GetBytes(bytes.Count - animStartOffset), animStartOffset + 16);
                foreach (var value in values)
                {
                    if (anim.I_10 == ValueType.Float16)
                    {
                        bytes.AddRange(Half.GetBytes((Half)value));
                    }
                    else if (anim.I_10 == ValueType.Float32 || anim.I_10 == ValueType.Float32_2)
                    {
                        bytes.AddRange(BitConverter.GetBytes(value));
                    }
                    else
                    {
                        throw new InvalidDataException("Unknown ValueType. Cannot continue.");
                    }
                }
                bytes.AddRange(new byte[Utils.CalculatePadding(bytes.Count - valuesStartOffset, 4)]);
            }

            //Skeleton
            if (HasSkeleton)
            {
                bytes.AddRange(new byte[Utils.CalculatePadding(bytes.Count, 16)]);
                bytes = Utils.ReplaceRange(bytes, BitConverter.GetBytes(bytes.Count), 12);
                bytes.AddRange(skeleton.Write());
            }

            //Strings (animations)
            for (int i = 0; i < Animations.Count; i++)
            {
                if (!String.IsNullOrWhiteSpace(Animations[i].Name))
                {
                    bytes = Utils.ReplaceRange(bytes, BitConverter.GetBytes(bytes.Count - animNameOffsets[i] + 12), animNameOffsets[i]);
                    bytes.AddRange(new byte[10]);
                    bytes.Add((byte)Animations[i].Name.Length);
                    bytes.AddRange(Encoding.ASCII.GetBytes(Animations[i].Name));
                    bytes.Add(0);
                }
            }

            return(bytes.ToArray());
        }
예제 #6
0
        void WriteBinaryEEPK()
        {
            int    totalEffects         = 0;
            ushort totalAssetContainers = 0;

            if (eepk_File.Effects != null)
            {
                if (eepk_File.Effects.Count > 0)
                {
                    totalEffects = eepk_File.Effects[eepk_File.Effects.Count() - 1].IndexNum;
                    totalEffects++;
                }
            }
            if (eepk_File.Assets != null)
            {
                totalAssetContainers = (ushort)eepk_File.Assets.Count;
            }

            //Effect ID related Pointers
            List <int>    effectIdPointers       = new List <int>(); //Pointer Section entries - All of these lists will be synced up in entries
            List <int>    effectIdActualPosition = new List <int>(); //Offsets to the Effect ID entry (the "ID List")
            List <string> eskStringsToWrite      = new List <string>();
            List <int>    eskStringPointers      = new List <int>();

            //Asset Section lists and values
            List <int>    containerOneOffset         = new List <int>();//Asset container for asset header block data
            List <int>    containerTwoOffset         = new List <int>();
            List <int>    containerThreeOffset       = new List <int>();
            List <int>    assetDataBlockOffset       = new List <int>();
            List <int>    pointerToStringPointerList = new List <int>();    //the long list of pointers which point to the strings at end of file
            List <int>    unkNumberPointer           = new List <int>();    //pointer just before pointerToStringPointerList
            List <int>    stringPointerListOffsets   = new List <int>();    //the actual list of pointers to the strings (pointerToStringPointerList points to this)
            List <string> fileStringsToWrite         = new List <string>(); //All asset entry strings to write at end of file

            //Initial header data
            bytes = Utils.ReplaceRange(bytes, BitConverter.GetBytes(totalAssetContainers), 12);
            bytes = Utils.ReplaceRange(bytes, BitConverter.GetBytes(totalEffects), 14);

            //Effect ID Pointer Section (creates a pointer list and fills each entry with 4 empty bytes for now. The relevant entries will be filled with pointers when that data is written.
            int actualIds = 0;

            if (totalEffects > 0)
            {
                for (int i = 0; i < totalEffects; i++)
                {
                    bytes.AddRange(new List <byte> {
                        0, 0, 0, 0
                    });
                    if (i == eepk_File.Effects[actualIds].IndexNum)
                    {
                        effectIdPointers.Add(bytes.Count() - 4);
                        actualIds++;
                    }
                }
            }

            if (totalAssetContainers > 0)
            {
                for (int i = 0; i < totalAssetContainers; i++)
                {
                    ushort assetCount = (ushort)((eepk_File.Assets[i].AssetEntries != null) ? eepk_File.Assets[i].AssetEntries.Count() : 0);

                    bytes.AddRange(BitConverter.GetBytes(HexConverter.ToInt32(eepk_File.Assets[i].I_00)));
                    bytes.AddRange(new byte[4] {
                        HexConverter.ToInt8(eepk_File.Assets[i].I_04), HexConverter.ToInt8(eepk_File.Assets[i].I_05), HexConverter.ToInt8(eepk_File.Assets[i].I_06), HexConverter.ToInt8(eepk_File.Assets[i].I_07)
                    });
                    bytes.AddRange(BitConverter.GetBytes(HexConverter.ToInt32(eepk_File.Assets[i].I_08)));
                    bytes.AddRange(BitConverter.GetBytes(HexConverter.ToInt32(eepk_File.Assets[i].I_12)));
                    bytes.AddRange(BitConverter.GetBytes((ushort)eepk_File.Assets[i].I_16));
                    bytes.AddRange(new byte[12]);
                    bytes.AddRange(BitConverter.GetBytes(assetCount));
                    assetDataBlockOffset.Add(bytes.Count());
                    bytes.AddRange(new List <byte> {
                        0, 0, 0, 0
                    });
                    containerOneOffset.Add(bytes.Count());
                    bytes.AddRange(new List <byte> {
                        0, 0, 0, 0
                    });
                    containerTwoOffset.Add(bytes.Count());
                    bytes.AddRange(new List <byte> {
                        0, 0, 0, 0
                    });
                    containerThreeOffset.Add(bytes.Count());
                    bytes.AddRange(new List <byte> {
                        0, 0, 0, 0
                    });
                }



                for (int i = 0; i < totalAssetContainers; i++)
                {
                    //Asset Entry data

                    if (eepk_File.Assets[i].AssetEntries != null)
                    {
                        bytes = Utils.ReplaceRange(bytes, BitConverter.GetBytes(bytes.Count() + 32 - assetDataBlockOffset[i]), assetDataBlockOffset[i]);

                        for (int a = 0; a < eepk_File.Assets[i].AssetEntries.Count(); a++)
                        {
                            //Adds the container entries, and placeholder data for the eventual pointers to the string section
                            bytes.AddRange(BitConverter.GetBytes(eepk_File.Assets[i].AssetEntries[a].I_00));
                            bytes.Add((byte)eepk_File.Assets[i].I_16);
                            int actualCountOfFiles = eepk_File.Assets[i].AssetEntries[a].FILES.Where(p => p.Path != "NULL").Count();
                            bytes.Add((byte)actualCountOfFiles);
                            unkNumberPointer.Add(bytes.Count());
                            bytes.AddRange(new List <byte> {
                                0, 0, 0, 0
                            });
                            pointerToStringPointerList.Add(bytes.Count());
                            bytes.AddRange(new List <byte> {
                                0, 0, 0, 0
                            });
                        }
                    }
                }

                int assetContainerIteration = 0;
                for (int i = 0; i < totalAssetContainers; i++)
                {//String pointer section (between Asset Container Entries and ID List)
                    if (eepk_File.Assets[i].AssetEntries != null)
                    {
                        for (int a = 0; a < eepk_File.Assets[i].AssetEntries.Count(); a++)
                        {
                            //Iterating over the Asset Entries of a Main Container
                            int actualCountOfFiles = eepk_File.Assets[i].AssetEntries[a].FILES.Where(p => p.Path != "NULL").Count();

                            bytes = Utils.ReplaceRange(bytes, BitConverter.GetBytes(bytes.Count() + 8 - pointerToStringPointerList[assetContainerIteration]), pointerToStringPointerList[assetContainerIteration]);
                            assetContainerIteration++;
                            for (int e = 0; e < actualCountOfFiles; e++)
                            {
                                //Looping for each number in I_03
                                //eepk_File.Assets[i].AssetEntries[a].FILES[e] = eepk_File.Assets[i].AssetEntries[a].FILES[e].Replace("*", " ");//bug fix for white space in file names, here the white space is restored
                                fileStringsToWrite.Add(eepk_File.Assets[i].AssetEntries[a].FILES[e].Path);
                                stringPointerListOffsets.Add(bytes.Count());
                                bytes.AddRange(new List <byte> {
                                    0, 0, 0, 0
                                });
                            }
                        }
                    }
                }
            }

            if (totalEffects > 0)
            {
                for (int i = 0; i < actualIds; i++)
                {
                    bytes = Utils.ReplaceRange(bytes, BitConverter.GetBytes(bytes.Count()), effectIdPointers[i]); //Setting the offsets in the initial Effect ID pointer section
                    effectIdActualPosition.Add(bytes.Count());
                    bytes.AddRange(BitConverter.GetBytes(eepk_File.Effects[i].IndexNum));
                    bytes.AddRange(BitConverter.GetBytes(eepk_File.Effects[i].I_02));
                    bytes.AddRange(new List <byte> {
                        0, 0, 0, 0, 0, 0
                    });
                    bytes.AddRange(BitConverter.GetBytes((short)eepk_File.Effects[i].EffectParts.Count()));
                    bytes.AddRange(new List <byte> {
                        0, 0, 0, 0
                    });
                }

                for (int i = 0; i < actualIds; i++)
                {//Each effect
                    bytes = Utils.ReplaceRange(bytes, BitConverter.GetBytes(bytes.Count() - effectIdActualPosition[i]), effectIdActualPosition[i] + 12);
                    //Above line: setting offset to Effect Entry Start in the Effect ID Entry
                    for (int a = 0; a < eepk_File.Effects[i].EffectParts.Count(); a++)
                    {//Each entry/size
                        BitArray compositeBits_I_32 = new BitArray(new bool[8] {
                            eepk_File.Effects[i].EffectParts[a].I_32_0, eepk_File.Effects[i].EffectParts[a].I_32_1, eepk_File.Effects[i].EffectParts[a].I_32_2, eepk_File.Effects[i].EffectParts[a].I_32_3, eepk_File.Effects[i].EffectParts[a].I_32_4, eepk_File.Effects[i].EffectParts[a].I_32_5, eepk_File.Effects[i].EffectParts[a].I_32_6, eepk_File.Effects[i].EffectParts[a].I_32_7
                        });
                        BitArray compositeBits_I_39 = new BitArray(new bool[8] {
                            eepk_File.Effects[i].EffectParts[a].I_39_0, eepk_File.Effects[i].EffectParts[a].I_39_1, eepk_File.Effects[i].EffectParts[a].I_39_2, eepk_File.Effects[i].EffectParts[a].I_39_3, eepk_File.Effects[i].EffectParts[a].I_39_4, eepk_File.Effects[i].EffectParts[a].I_39_5, eepk_File.Effects[i].EffectParts[a].I_39_6, eepk_File.Effects[i].EffectParts[a].I_39_7
                        });
                        BitArray compositeBits_I_36 = new BitArray(new bool[8] {
                            eepk_File.Effects[i].EffectParts[a].I_36_0, eepk_File.Effects[i].EffectParts[a].I_36_1, eepk_File.Effects[i].EffectParts[a].I_36_2, eepk_File.Effects[i].EffectParts[a].I_36_3, eepk_File.Effects[i].EffectParts[a].I_36_4, eepk_File.Effects[i].EffectParts[a].I_36_5, eepk_File.Effects[i].EffectParts[a].I_36_6, eepk_File.Effects[i].EffectParts[a].I_36_6
                        });
                        BitArray compositeBits_I_37 = new BitArray(new bool[8] {
                            eepk_File.Effects[i].EffectParts[a].I_37_0, eepk_File.Effects[i].EffectParts[a].I_37_1, eepk_File.Effects[i].EffectParts[a].I_37_2, eepk_File.Effects[i].EffectParts[a].I_37_3, eepk_File.Effects[i].EffectParts[a].I_37_4, eepk_File.Effects[i].EffectParts[a].I_37_5, eepk_File.Effects[i].EffectParts[a].I_37_6, eepk_File.Effects[i].EffectParts[a].I_37_6
                        });


                        bytes.AddRange(BitConverter.GetBytes(eepk_File.Effects[i].EffectParts[a].I_00));
                        bytes.Add((byte)eepk_File.Effects[i].EffectParts[a].I_02);
                        bytes.Add((byte)eepk_File.Effects[i].EffectParts[a].I_03);
                        bytes.Add(eepk_File.Effects[i].EffectParts[a].I_04);
                        bytes.Add((byte)eepk_File.Effects[i].EffectParts[a].I_05);
                        bytes.Add(eepk_File.Effects[i].EffectParts[a].I_06);
                        bytes.Add(eepk_File.Effects[i].EffectParts[a].I_07);
                        bytes.AddRange(BitConverter.GetBytes(eepk_File.Effects[i].EffectParts[a].I_08));
                        bytes.AddRange(BitConverter.GetBytes(eepk_File.Effects[i].EffectParts[a].I_12));
                        bytes.AddRange(BitConverter.GetBytes(eepk_File.Effects[i].EffectParts[a].I_16));
                        bytes.AddRange(BitConverter.GetBytes(eepk_File.Effects[i].EffectParts[a].I_20));
                        bytes.AddRange(BitConverter.GetBytes(eepk_File.Effects[i].EffectParts[a].F_24));
                        bytes.AddRange(BitConverter.GetBytes(eepk_File.Effects[i].EffectParts[a].I_28));
                        bytes.AddRange(BitConverter.GetBytes(eepk_File.Effects[i].EffectParts[a].I_30));
                        bytes.Add(Utils.ConvertToByte(compositeBits_I_32));
                        bytes.Add(0);
                        bytes.AddRange(BitConverter.GetBytes(eepk_File.Effects[i].EffectParts[a].I_34));
                        bytes.Add(Utils.ConvertToByte(compositeBits_I_36));
                        bytes.Add(Utils.ConvertToByte(compositeBits_I_37));
                        bytes.Add(Int4Converter.GetByte(HexConverter.ToInt8(eepk_File.Effects[i].EffectParts[a].I_38_a), HexConverter.ToInt8(eepk_File.Effects[i].EffectParts[a].I_38_b), "Flag_38 a", "Flag_38 b"));
                        bytes.Add(Utils.ConvertToByte(compositeBits_I_39));
                        bytes.AddRange(BitConverter.GetBytes(eepk_File.Effects[i].EffectParts[a].POSITION_X));
                        bytes.AddRange(BitConverter.GetBytes(eepk_File.Effects[i].EffectParts[a].POSITION_Y));
                        bytes.AddRange(BitConverter.GetBytes(eepk_File.Effects[i].EffectParts[a].POSITION_Z));

                        bytes.AddRange(BitConverter.GetBytes((float)Utils.ConvertDegreesToRadians(eepk_File.Effects[i].EffectParts[a].F_52)));
                        bytes.AddRange(BitConverter.GetBytes((float)Utils.ConvertDegreesToRadians(eepk_File.Effects[i].EffectParts[a].F_56)));
                        bytes.AddRange(BitConverter.GetBytes((float)Utils.ConvertDegreesToRadians(eepk_File.Effects[i].EffectParts[a].F_60)));
                        bytes.AddRange(BitConverter.GetBytes((float)Utils.ConvertDegreesToRadians(eepk_File.Effects[i].EffectParts[a].F_64)));
                        bytes.AddRange(BitConverter.GetBytes((float)Utils.ConvertDegreesToRadians(eepk_File.Effects[i].EffectParts[a].F_68)));
                        bytes.AddRange(BitConverter.GetBytes((float)Utils.ConvertDegreesToRadians(eepk_File.Effects[i].EffectParts[a].F_72)));

                        bytes.AddRange(BitConverter.GetBytes(eepk_File.Effects[i].EffectParts[a].SIZE_1));
                        bytes.AddRange(BitConverter.GetBytes(eepk_File.Effects[i].EffectParts[a].SIZE_2));
                        bytes.AddRange(BitConverter.GetBytes(eepk_File.Effects[i].EffectParts[a].F_84));
                        bytes.AddRange(BitConverter.GetBytes(eepk_File.Effects[i].EffectParts[a].F_88));
                        bytes.AddRange(BitConverter.GetBytes(eepk_File.Effects[i].EffectParts[a].I_92));
                        bytes.AddRange(BitConverter.GetBytes(eepk_File.Effects[i].EffectParts[a].I_94));
                        eskStringPointers.Add(bytes.Count());
                        eskStringsToWrite.Add(eepk_File.Effects[i].EffectParts[a].ESK);
                        bytes.AddRange(new List <byte> {
                            0, 0, 0, 0
                        });
                    }
                }
            }

            if (totalAssetContainers > 0)
            {
                int strIteration2      = 0;
                int unkNumberIteration = 0;
                int strIteration       = 0;
                for (int i = 0; i < totalAssetContainers; i++)
                {//Writing string section
                    if (eepk_File.Assets[i].FILES[0] != "NULL")
                    {
                        bytes = Utils.ReplaceRange(bytes, BitConverter.GetBytes(bytes.Count() + 36 - containerOneOffset[i]), containerOneOffset[i]);
                        bytes.AddRange(Encoding.ASCII.GetBytes(eepk_File.Assets[i].FILES[0])); bytes.Add(0);
                    }
                    if (eepk_File.Assets[i].FILES[1] != "NULL")
                    {
                        bytes = Utils.ReplaceRange(bytes, BitConverter.GetBytes(bytes.Count() + 40 - containerTwoOffset[i]), containerTwoOffset[i]);
                        bytes.AddRange(Encoding.ASCII.GetBytes(eepk_File.Assets[i].FILES[1])); bytes.Add(0);
                    }
                    if (eepk_File.Assets[i].FILES[2] != "NULL")
                    {
                        bytes = Utils.ReplaceRange(bytes, BitConverter.GetBytes(bytes.Count() + 44 - containerThreeOffset[i]), containerThreeOffset[i]);
                        bytes.AddRange(Encoding.ASCII.GetBytes(eepk_File.Assets[i].FILES[2])); bytes.Add(0);
                    }

                    if (eepk_File.Assets[i].AssetEntries != null)
                    {
                        for (int a = 0; a < eepk_File.Assets[i].AssetEntries.Count(); a++)
                        {
                            int actualCountFile = eepk_File.Assets[i].AssetEntries[a].FILES.Where(p => p.Path != "NULL").Count();

                            bytes = Utils.ReplaceRange(bytes, BitConverter.GetBytes(bytes.Count() + 4 - unkNumberPointer[unkNumberIteration]), unkNumberPointer[unkNumberIteration]);
                            unkNumberIteration++;
                            for (int s = 0; s < actualCountFile; s++)
                            {
                                //Set number offset here
                                if (eepk_File.Assets[i].AssetEntries[a].FILES[s].Path == "NULL")
                                {
                                    bytes.Add(255);
                                }
                                else
                                {
                                    bytes.Add(Convert.ToByte(Utils.GetEepkFileTypeNumber(eepk_File.Assets[i].AssetEntries[a].FILES[s].Path)));
                                }
                            }

                            for (int s = 0; s < actualCountFile; s++)
                            {
                                //Set string offset here
                                if (eepk_File.Assets[i].AssetEntries[a].FILES[s].Path != "NULL")
                                {
                                    bytes = Utils.ReplaceRange(bytes, BitConverter.GetBytes(bytes.Count() + 8 - pointerToStringPointerList[strIteration2]), stringPointerListOffsets[strIteration]);
                                    bytes.AddRange(Encoding.ASCII.GetBytes(eepk_File.Assets[i].AssetEntries[a].FILES[s].Path)); bytes.Add(0);
                                }
                                strIteration++;
                            }
                            strIteration2++;
                        }
                    }
                }
            }

            if (totalEffects > 0)
            {
                for (int i = 0; i < eskStringsToWrite.Count(); i++)
                {
                    if (eskStringsToWrite[i] != "NULL" && !String.IsNullOrWhiteSpace(eskStringsToWrite[i]))
                    {
                        bytes = Utils.ReplaceRange(bytes, BitConverter.GetBytes(bytes.Count() + 96 - eskStringPointers[i]), eskStringPointers[i]);
                        bytes.AddRange(Encoding.ASCII.GetBytes(eskStringsToWrite[i])); bytes.Add(0);
                    }
                }
            }

            if (totalAssetContainers > 0)
            {
                bytes = Utils.ReplaceRange(bytes, BitConverter.GetBytes(assetDataBlockOffset[0] - 32), 16); //Pointer to Asset Section
            }
            if (totalEffects > 0)
            {
                bytes = Utils.ReplaceRange(bytes, BitConverter.GetBytes(24), 20);        //Pointer to Effect Pointer List
            }
            bytes = Utils.ReplaceRange(bytes, BitConverter.GetBytes(eepk_File.I_08), 8); //Unknown data in header
        }