public Story Read(Stream stream) { var story = new Story(); using (var reader = new OsiReader(stream, story)) { var header = new SaveFileHeader(); header.Read(reader); reader.MinorVersion = header.MinorVersion; reader.MajorVersion = header.MajorVersion; story.MinorVersion = header.MinorVersion; story.MajorVersion = header.MajorVersion; if (reader.Ver > OsiVersion.VerLastSupported) { var msg = String.Format( "Osiris version v{0}.{1} unsupported; this tool supports loading up to version 1.12.", reader.MajorVersion, reader.MinorVersion ); throw new InvalidDataException(msg); } if (reader.Ver >= OsiVersion.VerScramble) { reader.Scramble = 0xAD; } if (reader.Ver >= OsiVersion.VerAddTypeMap) { story.Types = ReadTypes(reader); foreach (var type in story.Types) { if (type.Value.Alias != 0) { reader.TypeAliases.Add(type.Key, type.Value.Alias); } } } else { story.Types = new Dictionary <uint, OsirisType>(); } if (reader.Ver >= OsiVersion.VerExternalStringTable && reader.Ver < OsiVersion.VerRemoveExternalStringTable) { story.ExternalStringTable = ReadStrings(reader); } else { story.ExternalStringTable = new List <string>(); } story.Types[0] = OsirisType.MakeBuiltin(0, "UNKNOWN"); story.Types[1] = OsirisType.MakeBuiltin(1, "INTEGER"); if (reader.Ver >= OsiVersion.VerEnhancedTypes) { story.Types[2] = OsirisType.MakeBuiltin(2, "INTEGER64"); story.Types[3] = OsirisType.MakeBuiltin(3, "REAL"); story.Types[4] = OsirisType.MakeBuiltin(4, "STRING"); story.Types[5] = OsirisType.MakeBuiltin(5, "GUIDSTRING"); } else { story.Types[2] = OsirisType.MakeBuiltin(2, "FLOAT"); story.Types[3] = OsirisType.MakeBuiltin(3, "STRING"); } story.DivObjects = reader.ReadList <OsirisDivObject>(); story.Functions = reader.ReadList <Function>(); story.Nodes = ReadNodes(reader); story.Adapters = ReadAdapters(reader); story.Databases = ReadDatabases(reader); story.Goals = ReadGoals(reader, story); story.GlobalActions = reader.ReadList <Call>(); foreach (var node in story.Nodes) { node.Value.PostLoad(story); } return(story); } }
public void Write(Stream stream, Story story) { using (Writer = new OsiWriter(stream)) { foreach (var node in story.Nodes) { node.Value.PreSave(story); } Writer.MajorVersion = story.MajorVersion; Writer.MinorVersion = story.MinorVersion; var header = new SaveFileHeader(); if (Writer.Ver >= OsiVersion.VerExternalStringTable) { header.Version = "Osiris save file dd. 03/30/17 07:28:20. Version 1.8."; } else { header.Version = "Osiris save file dd. 02/10/15 12:44:13. Version 1.5."; } header.MajorVersion = story.MajorVersion; header.MinorVersion = story.MinorVersion; header.BigEndian = false; header.Unused = 0; // Debug flags used in D:OS EE and D:OS 2 header.DebugFlags = 0x000C10A0; header.Write(Writer); if (Writer.Ver > OsiVersion.VerLastSupported) { var msg = String.Format( "Osiris version v{0}.{1} unsupported; this tool supports saving up to version 1.11.", Writer.MajorVersion, Writer.MinorVersion ); throw new InvalidDataException(msg); } if (Writer.Ver >= OsiVersion.VerScramble) { Writer.Scramble = 0xAD; } if (Writer.Ver >= OsiVersion.VerAddTypeMap) { // Don't export builtin types, only externally declared ones var types = story.Types.Values.Where(t => !t.IsBuiltin).ToList(); WriteTypes(types); } // TODO: regenerate string table? if (Writer.Ver >= OsiVersion.VerExternalStringTable && Writer.Ver < OsiVersion.VerRemoveExternalStringTable) { WriteStrings(story.ExternalStringTable); } Writer.WriteList(story.DivObjects); Writer.WriteList(story.Functions); WriteNodes(story.Nodes); WriteAdapters(story.Adapters); WriteDatabases(story.Databases); WriteGoals(story.Goals); Writer.WriteList(story.GlobalActions); foreach (var node in story.Nodes) { node.Value.PostSave(story); } } }
public Story Read(Stream stream) { var story = new Story(); using (var reader = new OsiReader(stream, story)) { var header = new SaveFileHeader(); header.Read(reader); reader.MinorVersion = header.MinorVersion; reader.MajorVersion = header.MajorVersion; story.MinorVersion = header.MinorVersion; story.MajorVersion = header.MajorVersion; if (reader.Ver > OsiVersion.VerLastSupported) { var msg = String.Format( "Osiris version v{0}.{1} unsupported; this tool supports loading up to version 1.12.", reader.MajorVersion, reader.MinorVersion ); throw new InvalidDataException(msg); } if (reader.Ver >= OsiVersion.VerScramble) { reader.Scramble = 0xAD; } story.Types = ReadTypes(reader, story); if (reader.Ver >= OsiVersion.VerExternalStringTable && reader.Ver < OsiVersion.VerRemoveExternalStringTable) { story.ExternalStringTable = ReadStrings(reader); } else { story.ExternalStringTable = new List <string>(); } story.Types[0] = OsirisType.MakeBuiltin(0, "UNKNOWN"); story.Types[1] = OsirisType.MakeBuiltin(1, "INTEGER"); if (reader.Ver >= OsiVersion.VerEnhancedTypes) { story.Types[2] = OsirisType.MakeBuiltin(2, "INTEGER64"); story.Types[3] = OsirisType.MakeBuiltin(3, "REAL"); story.Types[4] = OsirisType.MakeBuiltin(4, "STRING"); // BG3 defines GUIDSTRING in the .osi file if (!story.Types.ContainsKey(5)) { story.Types[5] = OsirisType.MakeBuiltin(5, "GUIDSTRING"); } } else { story.Types[2] = OsirisType.MakeBuiltin(2, "FLOAT"); story.Types[3] = OsirisType.MakeBuiltin(3, "STRING"); // Populate custom type IDs for versions that had no type alias map if (reader.Ver < OsiVersion.VerAddTypeMap) { for (byte typeId = 4; typeId <= 17; typeId++) { story.Types[typeId] = OsirisType.MakeBuiltin(typeId, $"TYPE{typeId}"); story.Types[typeId].Alias = 3; reader.TypeAliases.Add(typeId, 3); } } } story.DivObjects = reader.ReadList <OsirisDivObject>(); story.Functions = reader.ReadList <Function>(); story.Nodes = ReadNodes(reader); story.Adapters = ReadAdapters(reader); story.Databases = ReadDatabases(reader); story.Goals = ReadGoals(reader, story); story.GlobalActions = reader.ReadList <Call>(); story.FunctionSignatureMap = new Dictionary <string, Function>(); foreach (var func in story.Functions) { story.FunctionSignatureMap.Add(func.Name.Name + "/" + func.Name.Parameters.Types.Count.ToString(), func); } foreach (var node in story.Nodes) { node.Value.PostLoad(story); } return(story); } }