public virtual void Save(Stream stream) { var output = new SaveWriter(stream, this); #region Basic Game Information (Header, Expansions, Mods) #region Header output.Write(SaveHelpers.FileStart); output.Write(0x08); output.Write(this.Version.Bytes); output.Write(this.Build.Bytes); WriteCurrentTurnNumber(output); output.Write((byte)this.GameMode); var headerCiv = HeaderCiv != null ? HeaderCiv.SaveName.Bytes : Players[0].Civilization != null ? Players[0].Civilization.SaveName.Bytes : BitConverter.GetBytes(0x00); output.Write(headerCiv); var headerDifficulty = HeaderDifficulty.HasValue ? HeaderDifficulty.Value : Players[0].Difficulty; output.Write(SaveHelpers.ConvertOptionEnumToSaveStr(headerDifficulty).Bytes); output.Write(SaveHelpers.ConvertOptionEnumToSaveStr(this.HeaderStartingEra.Value).Bytes); WriteCurrentEra(output); output.Write(SaveHelpers.ConvertOptionEnumToSaveStr(this.GamePace.Value).Bytes); output.Write(SaveHelpers.ConvertOptionEnumToSaveStr(this.Map.Size.Value).Bytes); output.Write(this.Map.Path.Bytes); #endregion #region Expansions output.Write(this._Expansions.Count); foreach (var expansion in this.Expansions) { output.Write(expansion.SaveId); output.Write(0x01); output.Write(expansion.SaveName.Bytes); } #endregion #region Mods output.Write(Mods.Count); foreach (var mod in this.Mods) { output.Write(mod.SaveId.Bytes); output.Write(0x01); output.Write(mod.SaveName.Bytes); } #endregion #endregion #region Nothing Important #region Unknown + Map Path output.WriteEmptyBlocks(2); WritePlayerColor(output); output.Write(HeaderCrazyBytes); output.Write(0x00); output.Write(0x03); output.Write(0x03); output.Write(0x02); output.Write(this.Map.Path.Bytes); #endregion output.Write(SaveHelpers.SectionDelimiter); output.WriteFullBlocks(SaveHelpers.StandardSectionBlockCount); #endregion #region Player Information output.WritePlayerNamesSection(); output.WritePlayerTypeSection(); output.WritePlayerSlotsSection(); output.WritePlayerTeamsSection(); output.WritePlayerDifficultiesSection(this.Expansions.Contains(Expansion.Expansion.BraveNewWorld)); WriteCivilizationsSection(output); WriteLeadersSection(output); #region Current Player Index output.Write(0x06); WriteCurrentPlayerIndex(output); output.WriteEmptyBlocks(3); #endregion #endregion #region Nothing Important #region Mostly Blank output.Write(SaveHelpers.SectionDelimiter); output.WriteFullBlocks(SaveHelpers.StandardSectionBlockCount); output.WriteEmptyBlocks(2); output.Write((byte)0x00); output.Write(0x02); output.Write(0x00); output.Write(SaveHelpers.FullBlock); output.WriteEmptyBlocks(8); #endregion output.WriteEmptySection(); output.WriteEmptySection(); #endregion WritePlayerPasswordsSection(output); #region Starting Era + Temperature Text Key + Unimportant Things #region Blank output.Write(SaveHelpers.SectionDelimiter); output.WriteEmptyBlocks(67); #endregion output.WriteTextKey("CLIMATE", "Temperate"); #region Actual Starting Era output.Write(0x00); output.Write(0x05); output.Write(0x05); output.Write(0x19); output.WriteEmptyBlocks(5); output.Write(new byte[] { 0x33, 0x33, 0x73, 0x3F, 0x00, 0x00, 0x80, 0x3E }); var startingEra = this.StartingEra.Value; var startingEraList = this.StartingEra.PossibleValues.Keys.ToList(); int startingEraIndex = startingEraList.IndexOf(startingEra); output.Write(startingEraIndex); #endregion #region Blank output.Write(SaveHelpers.SectionDelimiter); output.WriteEmptyBlocks(65); #endregion #region Blank output.Write(SaveHelpers.SectionDelimiter); output.WriteEmptyBlocks(64); #endregion #region Blank output.Write(0x07); output.Write(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }); #endregion #endregion #region Game Name + Time Offset + Turn Number output.WriteFullBlocks(1); output.Write(Name.Bytes); output.Write(TimeOffset); output.Write(GameStarted); WriteCurrentTurnNumber(output); output.Write((byte)0x02); output.WriteEmptyBlocks(2); #endregion output.WritePlayerDifficultiesSection(this.Expansions.Contains(Expansion.Expansion.BraveNewWorld)); #region Nothing Important #region Mostly Blank output.Write(SaveHelpers.SectionDelimiter); output.Write(0x03); output.WriteFullBlocks(SaveHelpers.StandardSectionBlockCount - 1); output.Write((byte)0x00); output.Write((byte)0x00); #endregion output.WriteEmptySection(); #endregion #region City-State Stuff + Random Seed #region Random Seed + Map Path + City-State Count output.WriteEmptyBlocks(2); output.Write((byte)0x00); output.Write(this.RandomSeed); output.Write((byte)0x00); output.Write((byte)0x00); output.Write(this.Map.Path.Bytes); output.WriteEmptyBlocks(2); output.Write(this.Map.NumberOfCityStates); #endregion #region City-States output.Write(SaveHelpers.SectionDelimiter); output.WriteEmptyBlocks(SaveHelpers.MaxPlayers); WriteMinorCivs(output); output.Write(0x00); #endregion #region City-State Bits output.Write(SaveHelpers.SectionDelimiter); for (int i = 0; i < Players.Length; i++) { if (Players[i].Civilization != null && Players[i].Civilization is CivilizationMinor) { output.Write(true); } else { output.Write(false); } } output.Write((byte)0x00); #endregion #endregion #region Turn Timer Seconds + Unimportant Things #region Unknown output.Write(0x04); output.Write(0x00); #endregion output.WriteFullSection(); output.WritePlayerNamesSection(); #region Turn Timer Seconds output.Write(0x05); output.Write(this.TurnTimer); #endregion #region A Bunch of Bools //Maybe IsPlayer? The only false is the Barbarians output.Write(SaveHelpers.SectionDelimiter); for (int i = 0; i < SaveHelpers.SectionDelimiter - 1; i++) { output.Write(true); } output.Write(false); #endregion #endregion #region Player Colors WritePlayerColorsSection(output); #endregion #region Repeated Data + Unimportant Things output.Write(new byte[] { 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00 }); #region Sea Level Text Key output.Write(SaveHelpers.SectionDelimiter); output.WriteEmptyBlocks(16); output.Write(0x01); output.Write(0x01); output.Write(0x00); output.WriteTextKey("SEALEVEL", "Medium"); output.Write(0x00); output.Write((byte)0x00); #endregion output.WritePlayerSlotsSection(); output.WritePlayerTypeSection(); #region Random Seed output.Write(0x00); output.Write(this.RandomSeed); output.Write(0x00); #endregion output.WritePlayerTeamsSection(); #region Turn Timer Text Key output.Write((byte)0x00); output.Write(0x04); output.Write(0x00); output.WriteTextKey("TURNTIMER", "Fast"); output.Write(0x19); output.Write(0x09); output.Write(0x03); output.Write(0x03); output.Write(0x04); output.Write((byte)0x00); #endregion #endregion #region Victory Conditions output.Write(0x05); output.Write(BitConverter.GetBytes(this.TimeVictory)); output.Write(BitConverter.GetBytes(this.ScienceVictory)); output.Write(BitConverter.GetBytes(this.DominationVictory)); output.Write(BitConverter.GetBytes(this.CulturalVictory)); output.Write(BitConverter.GetBytes(this.DiplomaticVictory)); #endregion #region Random Map Stuff output.Write(SaveHelpers.SectionDelimiter); output.WriteEmptyBlocks(16); if (this.HasGnkOrBnw) { output.Write(0x02); } int mapSizeId = (((int)this.Map.Size.Value) / 2) - 1; output.Write(mapSizeId); output.Write(0x00); var worldSize = SaveHelpers.ConvertOptionEnumToSaveStr(this.Map.Size.Value); output.WriteTextKey(worldSize.Prefix, worldSize.Value, true); output.Write(SaveHelpers.GetExpectedCrazyMapSizeBytes(this)); #endregion #region Options #region Game Options //Number of options output.Write(GetNumberOfSettings() + CustomSettings.Count); output.WriteGamePreference("DYNAMIC_TURNS", DynamicTurns); output.WriteGamePreference("SIMULTANEOUS_TURNS", SimultaneousTurns); output.WriteGamePreference("PITBOSS", Pitboss); output.WriteGamePreference("QUICK_COMBAT", QuickCombat); output.WriteGamePreference("QUICK_MOVEMENT", QuickMovement); output.WriteGamePreference("END_TURN_TIMER_ENABLED", EnableTurnTimer); output.WriteGamePreference("POLICY_SAVING", AllowPolicySaving); output.WriteGamePreference("PROMOTION_SAVING", AllowPromotionSaving); output.WriteGamePreference("COMPLETE_KILLS", CompleteKills); output.WriteGamePreference("DISABLE_START_BIAS", DisableStartBias); output.WriteGamePreference("NEW_RANDOM_SEED", NewRandomSeed); output.WriteGamePreference("NO_GOODY_HUTS", NoAncientRuins); output.WriteGamePreference("NO_BARBARIANS", NoBarbarians); output.WriteGamePreference("NO_CITY_RAZING", NoCityRazing); output.WriteGamePreference("ONE_CITY_CHALLENGE", OneCityChallenge); output.WriteGamePreference("RAGING_BARBARIANS", RagingBarbarians); output.WriteGamePreference("RANDOM_PERSONALITIES", RandomPersonalities); output.WriteGamePreference("ALWAYS_WAR", AlwaysWar); output.WriteGamePreference("ALWAYS_PEACE", AlwaysPeace); output.WriteGamePreference("NO_CHANGING_WAR_PEACE", NoChangingWarPeace); output.WriteGamePreference("LOCK_MODS", LockMods); output.WriteGamePreference("NO_SCIENCE", NoScience); output.WriteGamePreference("NO_POLICIES", NoPolicies); output.WriteGamePreference("NO_HAPPINESS", NoHappiness); if (HasGnkOrBnw) { output.WriteGamePreference("NO_ESPIONAGE", NoEspionage); output.WriteGamePreference("NO_RELIGION", NoReligion); } if (_Expansions.Contains(Expansion.Expansion.BraveNewWorld)) { output.WriteGamePreference("NO_LEAGUES", NoLeagues); output.WriteGamePreference("NO_CULTURE_OVERVIEW_UI", NoCultureOverviewUI); } foreach (var setting in CustomSettings) { output.WriteGamePreference(setting.Key, setting.Value); } #endregion #region Map Options var mapProperties = this.Map.MapProperties; output.Write(mapProperties.Count); int index = 1; foreach (var prop in mapProperties) { object value = prop.Value; var possibleValues = prop.PossibleValues.Keys.ToList(); var propIndex = possibleValues.IndexOf(value) + 1; var strProp = new SaveString(index.ToString()); output.Write(strProp.Bytes); output.Write(propIndex); index++; } #endregion #endregion #region Nothing Important #region Build Number var buildStr = new SaveString(this.Build + " FINAL RELEASE"); output.Write(buildStr.Bytes); #endregion output.Write(SaveHelpers.SectionDelimiter); output.WriteEmptyBlocks(16); output.Write(SaveHelpers.SectionDelimiter); output.WriteEmptyBlocks(16); #region Email Addresses (Ignore) output.Write(SaveHelpers.SectionDelimiter); output.WriteEmptyBlocks(64); #endregion #endregion WriteRawGameData(output); }
protected virtual void WriteCurrentEra(SaveWriter output) { output.Write(SaveHelpers.ConvertOptionEnumToSaveStr(this.HeaderStartingEra.Value).Bytes); }
protected override void WriteCurrentEra(SaveWriter output) { output.Write(SaveHelpers.ConvertOptionEnumToSaveStr(HeaderCurrentEra.Value).Bytes); }