Пример #1
0
        public static void ToFilename(string name, BACFile bac, BCMFile bcm)
        {
            bac.Scripts.Remove(Script.NullScript);
            bac.VFXScripts.Remove(Script.NullScript);

            bac.Scripts    = new ObservableCollection <Script>(bac.Scripts.OrderBy(x => x.Index));
            bac.VFXScripts = new ObservableCollection <Script>(bac.VFXScripts.OrderBy(x => x.Index));

            using (var ms = new MemoryStream())
                using (var outFile = new BinaryWriter(ms))
                {
                    outFile.Write(1128350243);
                    outFile.Write(2686974);
                    outFile.Write(65537);

                    outFile.Write((short)(bac.Scripts.Last().Index + 1));
                    if (bac.VFXScripts.Count > 0)
                    {
                        outFile.Write((short)(bac.VFXScripts.Last().Index + 1));
                    }
                    else
                    {
                        outFile.Write((short)0);
                    }
                    outFile.Write(bac.HitboxTable.Last().Index + 1);

                    int OffsetOffset = (int)outFile.BaseStream.Position;

                    outFile.Write(0);
                    outFile.Write(0);
                    outFile.Write(0);
                    outFile.Write(0);
                    outFile.Write(0);
                    foreach (ObservableCollection <float> list in bac.UnknownFloatData)
                    {
                        foreach (float entry in list)
                        {
                            outFile.Write(entry);
                        }
                    }

                    /* Scripts */
                    int ScriptOffset = (int)outFile.BaseStream.Position;
                    for (int i = 0; i < bac.Scripts.Last().Index + 1; i++)
                    {
                        outFile.Write(0);
                    }
                    /* VFX Scripts */
                    int VFXScriptOffset = (int)outFile.BaseStream.Position;
                    if (bac.VFXScripts.Count != 0)
                    {
                        for (int i = 0; i < bac.VFXScripts.Last().Index + 1; i++)
                        {
                            outFile.Write(0);
                        }
                    }
                    else
                    {
                        VFXScriptOffset = 0;
                    }

                    /* Script Name Offsets */
                    int ScriptNameOffset = (int)outFile.BaseStream.Position;
                    for (int i = 0; i < bac.Scripts.Last().Index + 1; i++)
                    {
                        outFile.Write(0);
                    }

                    /* VFX Script Name Offsets */
                    int VFXScriptNameOffset = (int)outFile.BaseStream.Position;
                    if (bac.VFXScripts.Count == 0)
                    {
                        VFXScriptNameOffset = 0;
                    }
                    else
                    {
                        for (int i = 0; i < bac.VFXScripts.Last().Index + 1; i++)
                        {
                            outFile.Write(0);
                        }
                    }
                    /* Hitbox Table */
                    int HitboxTableOffset = (int)outFile.BaseStream.Position;
                    for (int i = 0; i < bac.HitboxTable.Last().Index + 1; i++)
                    {
                        outFile.Write(0);
                    }
                    outFile.BaseStream.Seek(0, SeekOrigin.End);

                    foreach (Script script in bac.Scripts)
                    {
                        int tmp = (int)outFile.BaseStream.Position;
                        writeScript(bac, bcm, outFile, script);
                        outFile.BaseStream.Seek(ScriptOffset + script.Index * 4);
                        outFile.Write(tmp);
                        outFile.Seek(0, SeekOrigin.End);
                    }
                    foreach (Script script in bac.VFXScripts)
                    {
                        int tmp = (int)outFile.BaseStream.Position;
                        writeScript(bac, bcm, outFile, script);
                        outFile.BaseStream.Seek(VFXScriptOffset + script.Index * 4);
                        outFile.Write(tmp);
                        outFile.Seek(0, SeekOrigin.End);
                    }
                    /* Hitbox Table */
                    foreach (HitBoxDataset dataset in bac.HitboxTable)
                    {
                        int tmp = (int)outFile.BaseStream.Position;
                        outFile.BaseStream.Seek(HitboxTableOffset + dataset.Index * 4);
                        outFile.Write(tmp);
                        outFile.Seek(0, SeekOrigin.End);
                        foreach (HitBoxData data in dataset.Data)
                        {
                            outFile.Write(data.Damage);
                            outFile.Write(data.Stun);
                            outFile.Write((ushort)data.Effect);
                            if (data.OnHit != null)
                            {
                                outFile.Write((short)(data.OnHit.Index - HitBoxData.getIndexOffset(data.Effect)));
                            }
                            else
                            {
                                outFile.Write((short)-1);
                            }
                            //0x8
                            outFile.Write(data.SelfHitstop);
                            outFile.Write(data.SelfShaking);
                            outFile.Write(data.TgtHitstop);
                            outFile.Write(data.TgtShaking);
                            //0x10
                            outFile.Write(data.HitGFX);
                            outFile.Write(data.Unknown1);
                            outFile.Write((short)data.Unused);
                            //0x18
                            outFile.Write(data.HitGFX2);
                            outFile.Write((int)data.Unused2);
                            outFile.Write((short)data.Unused3);
                            //0x20
                            outFile.Write(data.HitSFX);
                            outFile.Write(data.HitSFX2);
                            outFile.Write(data.TgtSFX);

                            outFile.Write(data.ArcadeScore);
                            outFile.Write(data.SelfMeter);
                            outFile.Write(data.TgtMeter);
                            outFile.Write(data.JuggleStart);
                            outFile.Write(data.TgtAnimTime);
                            outFile.Write((int)data.MiscFlag);
                            outFile.Write(data.VelX);
                            outFile.Write(data.VelY);

                            outFile.Write(data.VelZ);
                            outFile.Write(data.PushbackDist);
                            outFile.Write(data.AccX);
                            outFile.Write(data.AccY);
                            outFile.Write(data.AccZ);
                        }
                    }
                    /* Script Names+Offsets */

                    List <string> strings = new List <string>();
                    int           index   = 0;
                    foreach (Script tmp in bac.Scripts)
                    {
                        while (index != tmp.Index)
                        {
                            strings.Add(null);
                            index++;
                        }
                        index++;
                        if (tmp.Name != "null")
                        {
                            strings.Add(tmp.Name);
                        }
                        else
                        {
                            strings.Add(null);
                        }
                    }
                    Util.writeStringTable(outFile, ScriptNameOffset, strings);

                    strings.Clear();
                    index = 0;
                    foreach (Script tmp in bac.VFXScripts)
                    {
                        while (index != tmp.Index)
                        {
                            strings.Add(null);
                            index++;
                        }
                        index++;
                        strings.Add(tmp.Name);
                    }
                    Util.writeStringTable(outFile, VFXScriptNameOffset, strings);

                    outFile.BaseStream.Seek(0x14);
                    outFile.Write(ScriptOffset);
                    outFile.Write(VFXScriptOffset);
                    outFile.Write(ScriptNameOffset);
                    outFile.Write(VFXScriptNameOffset);
                    outFile.Write(HitboxTableOffset);

                    using (var fs = File.Create(name))
                    {
                        ms.WriteTo(fs);
                    }
                }
        }
Пример #2
0
        public static BACFile FromFilename(string name, BCMFile bcm)
        {
            using (var fs = File.OpenRead(name))
                using (var tracker = new TrackingStream(fs))
                    using (var inFile = new BinaryReader(tracker))
                    {
                        AELogger.Log(AELogger.O_SEPARATOR, false);
                        tracker.SetLabel("Header");

                        if (new String(inFile.ReadChars(4)) != "#BAC")
                        {
                            throw new IOException("Not a valid BAC file");
                        }
                        tracker.IgnoreBytes(8);
                        inFile.BaseStream.Seek(12);

                        ushort ScriptCount         = inFile.ReadUInt16();
                        ushort VFXScriptCount      = inFile.ReadUInt16();
                        uint   HitboxTableSize     = inFile.ReadUInt32();
                        int    ScriptOffset        = inFile.ReadInt32();
                        int    VFXScriptOffset     = inFile.ReadInt32();
                        int    ScriptNameOffset    = inFile.ReadInt32();
                        int    VFXScriptNameOffset = inFile.ReadInt32();
                        int    HitboxTableOffset   = inFile.ReadInt32();

                        AELogger.Log("Header done, reading floats");

                        var bac = new BACFile();
                        for (int i = 0; i < 0x1c; i++)
                        {
                            var list = new ObservableCollection <float>();
                            for (int j = 0; j < 6; j++)
                            {
                                list.Add(inFile.ReadSingle());
                            }
                            bac.UnknownFloatData.Add(list);
                        }
                        AELogger.Log("floats done, reading scripts");

                        for (int i = 0; i < ScriptCount; i++)
                        {
                            bac.Scripts.Add(new Script(i));
                        }
                        for (int i = 0; i < VFXScriptCount; i++)
                        {
                            bac.VFXScripts.Add(new Script(i));
                        }
                        for (int i = 0; i < HitboxTableSize; i++)
                        {
                            bac.HitboxTable.Add(new HitBoxDataset(i));
                        }

                        //Link BCM
                        if (bcm != null)
                        {
                            foreach (BCM.Move move in bcm.Moves)
                            {
                                if (move.ScriptIndex != -1)
                                {
                                    move.Script = bac.Scripts[move.ScriptIndex];
                                }
                            }
                        }
                        //Read Scripts
                        readScripts(inFile, bac.Scripts, bcm, ScriptCount, ScriptOffset, ScriptNameOffset, bac);
                        readScripts(inFile, bac.VFXScripts, bcm, VFXScriptCount, VFXScriptOffset, VFXScriptNameOffset, bac);
                        AELogger.Log("scripts done, reading hitboxtable");
                        //Read Hitbox Table
                        for (int i = 0; i < HitboxTableSize; i++)
                        {
                            tracker.SetLabel("HitboxTable#" + i.ToString());
                            inFile.BaseStream.Seek(HitboxTableOffset + i * 4);
                            inFile.BaseStream.Seek(inFile.ReadUInt32());
                            if (inFile.BaseStream.Position == 0)
                            {
                                continue;
                            }
                            var dataset = bac.HitboxTable[i];
                            LoadedHitBoxCount = i;
                            for (int j = 0; j < 12; j++)
                            {
                                HitBoxData data = new HitBoxData(j);
                                dataset.Data.Add(data);
                                data.Damage = inFile.ReadInt16();
                                data.Stun   = inFile.ReadInt16();
                                data.Effect = (HitBoxData.HitBoxEffect)inFile.ReadUInt16();
                                Util.LogUnkEnum(data.Effect, "Hitbox #" + dataset.Index, "hitboxdataset", j);

                                var index = inFile.ReadInt16() + HitBoxData.getIndexOffset(data.Effect);
                                if (index > -1)
                                {
                                    data.OnHit = bac.Scripts.Where(x => x.Index == index).First();
                                }
                                else
                                {
                                    data.OnHit = new Script(index);
                                    if (index <= -1)
                                    {
                                        AELogger.Log("negative index " + index + " in hitboxdata #" + i);
                                    }
                                }

                                data.SelfHitstop = inFile.ReadUInt16();
                                data.SelfShaking = inFile.ReadUInt16();
                                data.TgtHitstop  = inFile.ReadUInt16();
                                data.TgtShaking  = inFile.ReadUInt16();
                                data.HitGFX      = inFile.ReadInt16();
                                data.Unknown1    = inFile.ReadInt32();
                                data.Unused      = (Unused16)inFile.ReadInt16();
                                data.HitGFX2     = inFile.ReadInt16();
                                data.Unused2     = (Unused32)inFile.ReadInt32();
                                data.Unused3     = (Unused16)inFile.ReadInt16();
                                data.HitSFX      = inFile.ReadInt16();
                                data.HitSFX2     = inFile.ReadInt16();
                                data.TgtSFX      = inFile.ReadInt16();

                                data.ArcadeScore = inFile.ReadUInt16();
                                data.SelfMeter   = inFile.ReadInt16();
                                data.TgtMeter    = inFile.ReadInt16();
                                data.JuggleStart = inFile.ReadInt16();
                                data.TgtAnimTime = inFile.ReadInt16();
                                data.MiscFlag    = (HitBoxData.MiscFlags)inFile.ReadInt32();
                                data.VelX        = inFile.ReadSingle();
                                data.VelY        = inFile.ReadSingle();

                                data.VelZ         = inFile.ReadSingle();
                                data.PushbackDist = inFile.ReadSingle();
                                data.AccX         = inFile.ReadSingle();
                                data.AccY         = inFile.ReadSingle();
                                data.AccZ         = inFile.ReadSingle();
                            }
                        }
                        AELogger.Log("hitbox done");
                        List <HitBoxDataset> nullHitboxData = bac.HitboxTable.Where(x => x.Data.Count() == 0).ToList();
                        foreach (HitBoxDataset tmp in nullHitboxData)
                        {
                            bac.HitboxTable.Remove(tmp);
                        }
                        FilterScripts(bac.Scripts);
                        FilterScripts(bac.VFXScripts);
                        AELogger.Log(AELogger.O_SEPARATOR, false);

                        return(bac);
                    }
        }