Example #1
0
 /// <summary>
 /// Creates a new ESD with the given format and no state groups.
 /// </summary>
 public ESD(ESDFormatType formatType, int darkSoulsCount)
 {
     FormatType      = formatType;
     DarkSoulsCount  = darkSoulsCount;
     Name            = null;
     Unk6C           = 1;
     Unk70           = 0;
     Unk74           = 0;
     Unk78           = 0;
     Unk7C           = 0;
     StateGroups     = new Dictionary <long, Dictionary <long, State> >();
     StateGroupNames = new Dictionary <long, string>();
     Metadata        = new ESDMetadata();
     LastSavedHash   = "";
 }
Example #2
0
        public void ReadWithContext(BinaryReaderEx br, EzSembleContext context)
        {
            LastSavedHash = br.GetMD5HashOfStream();

            string magic = br.AssertASCII("fSSL", "fsSL", "FSSL", "FsSL");

            FormatType = ESDFormatByMagic[magic];

            br.BigEndian = (FormatType == ESDFormatType.BigEndian32Bit || FormatType == ESDFormatType.BigEndian64Bit);

            context.IsBigEndian = br.BigEndian;

            br.AssertInt32(1);
            DarkSoulsCount = br.AssertInt32(1, 2, 3);
            br.AssertInt32(DarkSoulsCount);
            br.AssertInt32(0x54);
            int dataSize = br.ReadInt32();

            br.AssertInt32(6);
            br.AssertInt32(LongFormat ? 0x48 : 0x2C);
            br.AssertInt32(1);
            int stateGroupSize  = br.AssertInt32(LongFormat ? 0x20 : 0x10);
            int stateGroupCount = br.ReadInt32();
            int stateSize       = br.AssertInt32(LongFormat ? 0x48 : 0x24);
            int stateCount      = br.ReadInt32();

            br.AssertInt32(LongFormat ? 0x38 : 0x1C);
            int conditionCount = br.ReadInt32();

            br.AssertInt32(LongFormat ? 0x18 : 0x10);
            int commandCallCount = br.ReadInt32();

            br.AssertInt32(LongFormat ? 0x10 : 0x8);
            int commandArgCount        = br.ReadInt32();
            int conditionOffsetsOffset = br.ReadInt32();
            int conditionOffsetsCount  = br.ReadInt32();
            int nameBlockOffset        = br.ReadInt32();
            int nameLength             = br.ReadInt32();
            int unkOffset1             = br.ReadInt32();

            br.AssertInt32(0);
            int unkOffset2 = br.ReadInt32();

            br.AssertInt32(0);

            long dataStart = br.Position;

            Unk6C = br.AssertInt32(1, 0);
            Unk70 = br.ReadInt32();
            Unk74 = br.ReadInt32();
            Unk78 = br.ReadInt32();
            Unk7C = br.ReadInt32();
            if (LongFormat)
            {
                br.AssertInt32(0);
            }

            long stateGroupsOffset = ReadVarint(br, LongFormat);

            AssertVarint(br, LongFormat, stateGroupCount);
            long nameOffset = ReadVarint(br, LongFormat);

            AssertVarint(br, LongFormat, nameLength);
            long unkNull = DarkSoulsCount == 1 ? 0 : -1;

            AssertVarint(br, LongFormat, unkNull);
            AssertVarint(br, LongFormat, unkNull);

            if (nameLength > 0)
            {
                Name = br.GetUTF16(dataStart + nameOffset);
            }
            else
            {
                Name = null;
            }

            var stateGroupOffsets = new Dictionary <long, long[]>(stateGroupCount);

            for (int i = 0; i < stateGroupCount; i++)
            {
                long   id           = ReadVarint(br, LongFormat);
                long[] stateOffsets = ReadStateGroup(br, LongFormat, dataStart, stateSize);
                if (stateGroupOffsets.ContainsKey(id))
                {
                    throw new FormatException("Duplicate state group ID.");
                }
                stateGroupOffsets[id] = stateOffsets;
            }

            var states = new Dictionary <long, State>(stateCount);

            for (int i = 0; i < stateCount; i++)
            {
                states[br.Position - dataStart] = new State(context, br, LongFormat, dataStart);
            }

            var conditions = new Dictionary <long, Condition>(conditionCount);

            for (int i = 0; i < conditionCount; i++)
            {
                conditions[br.Position - dataStart] = new Condition(context, br, LongFormat, dataStart);
            }

            foreach (State state in states.Values)
            {
                state.GetConditions(conditions);
            }

            StateGroups = new Dictionary <long, Dictionary <long, State> >(stateGroupCount);
            var groupedStateOffsets = new Dictionary <long, Dictionary <long, long> >();

            foreach (long stateGroupID in stateGroupOffsets.Keys)
            {
                long[] stateOffsets = stateGroupOffsets[stateGroupID];
                Dictionary <long, State> stateGroup = TakeStates(stateSize, stateOffsets, states, out Dictionary <long, long> stateIDs);
                StateGroups[stateGroupID]         = stateGroup;
                groupedStateOffsets[stateGroupID] = stateIDs;

                foreach (State state in stateGroup.Values)
                {
                    foreach (Condition condition in state.Conditions)
                    {
                        condition.GetStateAndConditions(stateIDs, conditions);
                    }
                }
            }

            if (states.Count > 0)
            {
                throw new FormatException("Orphaned states found.");
            }

            foreach (var s in conditions)
            {
                s.Value.MetaRefID = s.Key;
                s.Value.Name      = $"Condition[{s.Key:X8}]";
            }

            foreach (var g in StateGroups.Keys)
            {
                foreach (var s in StateGroups[g])
                {
                    s.Value.Name = $"State{g}-{s.Value.ID}";
                }
            }

            StateGroupNames.Clear();
            foreach (var g in StateGroups)
            {
                StateGroupNames.Add(g.Key, $"StateGroup{g.Key}");
            }
        }