internal override void UnserializeChunk(UndertaleReader reader) { reader.Position -= 4; int chunkLength = reader.ReadInt32(); uint chunkEnd = reader.Position + (uint)chunkLength; uint beginPosition = reader.Position; // Figure out where the starts/ends of each shader object are int count = reader.ReadInt32(); uint[] objectLocations = new uint[count + 1]; for (int i = 0; i < count; i++) { objectLocations[i] = (uint)reader.ReadInt32(); } objectLocations[count] = chunkEnd; Dictionary <uint, UndertaleObject> objPool = reader.GetOffsetMap(); Dictionary <UndertaleObject, uint> objPoolRev = reader.GetOffsetMapRev(); // Setup base shader objects with boundaries set. Load into object pool // so that they don't immediately discard. for (int i = 0; i < count; i++) { UndertaleShader s = new UndertaleShader { _EntryEnd = objectLocations[i + 1] }; objPool.Add(objectLocations[i], s); objPoolRev.Add(s, objectLocations[i]); } reader.Position = beginPosition; base.UnserializeChunk(reader); }
public void Unserialize(UndertaleReader reader) { // This reads the string content immediately, if necessary (which it should be) UndertaleString ForceReadString() { UndertaleString res = reader.ReadUndertaleString(); uint returnTo = reader.Position; reader.Position = reader.GetOffsetMapRev()[res]; reader.ReadUndertaleObject <UndertaleString>(); reader.Position = returnTo; return(res); } ModelName = ForceReadString(); Name = reader.ReadUndertaleString(); BuiltinName = reader.ReadInt32(); Traits = reader.ReadInt32(); IsCreationTrack = reader.ReadBoolean(); int tagCount = reader.ReadInt32(); int ownedResCount = reader.ReadInt32(); int trackCount = reader.ReadInt32(); Tags = new List <int>(); for (int i = 0; i < tagCount; i++) { Tags.Add(reader.ReadInt32()); } OwnedResources = new List <UndertaleResource>(); for (int i = 0; i < ownedResCount; i++) { GMAnimCurveString = ForceReadString(); if (GMAnimCurveString.Content != "GMAnimCurve") { throw new IOException("Expected GMAnimCurve"); } UndertaleAnimationCurve res = new UndertaleAnimationCurve(); res.Unserialize(reader); OwnedResources.Add(res); } Tracks = new List <Track>(); for (int i = 0; i < trackCount; i++) { Tracks.Add(reader.ReadUndertaleObject <Track>()); } // Now, handle specific keyframe/etc. data switch (ModelName.Content) { case "GMAudioTrack": Keyframes = reader.ReadUndertaleObject <AudioKeyframes>(); break; case "GMInstanceTrack": Keyframes = reader.ReadUndertaleObject <InstanceKeyframes>(); break; case "GMGraphicTrack": Keyframes = reader.ReadUndertaleObject <GraphicKeyframes>(); break; case "GMSequenceTrack": Keyframes = reader.ReadUndertaleObject <SequenceKeyframes>(); break; case "GMSpriteFramesTrack": Keyframes = reader.ReadUndertaleObject <SpriteFramesKeyframes>(); break; case "GMAssetTrack": // TODO? throw new NotImplementedException("GMAssetTrack not implemented, report this"); case "GMBoolTrack": Keyframes = reader.ReadUndertaleObject <BoolKeyframes>(); break; case "GMStringTrack": Keyframes = reader.ReadUndertaleObject <StringKeyframes>(); break; // TODO? //case "GMIntTrack": // Keyframes = reader.ReadUndertaleObject<IntKeyframes>(); // break; case "GMRealTrack": Keyframes = reader.ReadUndertaleObject <RealKeyframes>(); break; } }