/// <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 = ""; }
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}"); } }