private Game(IGameData gameData) { _difficulty = gameData.Difficulty; _competition = (gameData.OpponentCount + 1); _players = new Player[_competition + 1]; _cities = new List <City>(); _units = new List <IUnit>(); ushort[] advanceFirst = gameData.AdvanceFirstDiscovery; bool[][,] visibility = gameData.TileVisibility; for (int i = 0; i < _players.Length; i++) { ICivilization[] civs = Common.Civilizations.Where(c => c.PreferredPlayerNumber == i).ToArray(); ICivilization civ = civs[gameData.CivilizationIdentity[i] % civs.Length]; Player player = (_players[i] = new Player(civ, gameData.LeaderNames[i], gameData.CitizenNames[i], gameData.CivilizationNames[i])); player.Destroyed += PlayerDestroyed; player.Gold = gameData.PlayerGold[i]; player.Science = gameData.ResearchProgress[i]; player.Government = Reflect.GetGovernments().FirstOrDefault(x => x.Id == gameData.Government[i]); player.TaxesRate = gameData.TaxRate[i]; player.LuxuriesRate = 10 - gameData.ScienceRate[i] - player.TaxesRate; player.StartX = (short)gameData.StartingPositionX[i]; // Set map visibility for (int xx = 0; xx < 80; xx++) { for (int yy = 0; yy < 50; yy++) { if (!visibility[i][xx, yy]) { continue; } if (i == 0 && Map[xx, yy].Hut) { Map[xx, yy].Hut = false; } player.Explore(xx, yy, 0); } } byte[] advanceIds = gameData.DiscoveredAdvanceIDs[i]; Common.Advances.Where(x => advanceIds.Any(id => x.Id == id)).ToList().ForEach(x => { player.AddAdvance(x, false); if (advanceFirst[x.Id] != player.Civilization.Id) { return; } SetAdvanceOrigin(x, player); }); } GameTurn = gameData.GameTurn; CityNames = gameData.CityNames; HumanPlayer = _players[gameData.HumanPlayer]; HumanPlayer.CurrentResearch = Common.Advances.FirstOrDefault(a => a.Id == gameData.CurrentResearch); _anthologyTurn = gameData.NextAnthologyTurn; Dictionary <byte, City> cityList = new Dictionary <byte, City>(); foreach (CityData cityData in gameData.Cities) { City city = new City(cityData.Owner) { X = cityData.X, Y = cityData.Y, NameId = cityData.NameId, Size = cityData.ActualSize, Food = cityData.Food, Shields = cityData.Shields }; city.SetProduction(cityData.CurrentProduction); city.SetResourceTiles(cityData.ResourceTiles); // Set city buildings foreach (byte buildingId in cityData.Buildings) { city.AddBuilding(Common.Buildings.First(b => b.Id == buildingId)); } // Set city wonders foreach (IWonder wonder in Common.Wonders) { if (gameData.Wonders[wonder.Id] != cityData.Id) { continue; } city.AddWonder(wonder); } _cities.Add(city); foreach (byte fortifiedUnit in cityData.FortifiedUnits) { IUnit unit = CreateUnit((UnitType)fortifiedUnit, city.X, city.Y); unit.Status = (byte)(1 << 3); unit.Owner = city.Owner; unit.SetHome(city); _units.Add(unit); } cityList.Add(cityData.Id, city); } UnitData[][] unitData = gameData.Units; for (byte p = 0; p < 8; p++) { if (!gameData.ActiveCivilizations[p]) { continue; } foreach (UnitData data in unitData[p]) { IUnit unit = CreateUnit((UnitType)data.TypeId, data.X, data.Y); if (unit == null) { continue; } unit.Status = data.Status; unit.Owner = p; unit.PartMoves = (byte)(data.RemainingMoves % 3); unit.MovesLeft = (byte)((data.RemainingMoves - unit.PartMoves) / 3); if (data.GotoX != 0xFF) { unit.Goto = new Point(data.GotoX, data.GotoY); } if (cityList.ContainsKey(data.HomeCityId)) { unit.SetHome(cityList[data.HomeCityId]); } _units.Add(unit); } } _replayData.AddRange(gameData.ReplayData); // Game Settings bool[] options = gameData.GameOptions; Settings.InstantAdvice = options[0]; Settings.AutoSave = options[1]; Settings.EndOfTurn = options[2]; Settings.Animations = options[3]; Settings.Sound = options[4]; Settings.EnemyMoves = options[5]; Settings.CivilopediaText = options[6]; // Settings.Palace = options[7]; _currentPlayer = gameData.HumanPlayer; for (int i = 0; i < _units.Count(); i++) { if (_units[i].Owner != gameData.HumanPlayer || _units[i].Busy) { continue; } _activeUnit = i; if (_units[i].MovesLeft > 0) { break; } } }
private Game(IGameData gameData) { _difficulty = gameData.Difficulty; _competition = (gameData.OpponentCount + 1); _players = new Player[_competition + 1]; _cities = new List <City>(); _units = new List <IUnit>(); ushort[] advanceFirst = gameData.AdvanceFirstDiscovery; bool[][,] visibility = gameData.TileVisibility; for (int i = 0; i < _players.Length; i++) { ICivilization[] civs = Common.Civilizations.Where(c => c.PreferredPlayerNumber == i).ToArray(); ICivilization civ = civs[gameData.CivilizationIdentity[i] % civs.Length]; Player player = (_players[i] = new Player(civ, gameData.LeaderNames[i], gameData.CitizenNames[i], gameData.CivilizationNames[i])); if (i != 0) // don't need for barbarians (?) { player.Destroyed += PlayerDestroyed; } player.Gold = gameData.PlayerGold[i]; player.Science = gameData.ResearchProgress[i]; player.Government = Reflect.GetGovernments().FirstOrDefault(x => x.Id == gameData.Government[i]); player.TaxesRate = gameData.TaxRate[i]; player.LuxuriesRate = 10 - gameData.ScienceRate[i] - player.TaxesRate; player.StartX = (short)gameData.StartingPositionX[i]; // Set map visibility for (int xx = 0; xx < 80; xx++) { for (int yy = 0; yy < 50; yy++) { if (!visibility[i][xx, yy]) { continue; } if (i == 0 && Map[xx, yy].Hut) { Map[xx, yy].Hut = false; } player.Explore(xx, yy, 0); } } byte[] advanceIds = gameData.DiscoveredAdvanceIDs[i]; Common.Advances.Where(x => advanceIds.Any(id => x.Id == id)).ToList().ForEach(x => { player.AddAdvance(x, false); if (advanceFirst[x.Id] != player.Civilization.Id) { return; } SetAdvanceOrigin(x, player); }); } GameTurn = gameData.GameTurn; CityNames = gameData.CityNames; HumanPlayer = _players[gameData.HumanPlayer]; HumanPlayer.CurrentResearch = Common.Advances.FirstOrDefault(a => a.Id == gameData.CurrentResearch); _anthologyTurn = gameData.NextAnthologyTurn; Dictionary <byte, City> cityList = new Dictionary <byte, City>(); foreach (CityData cityData in gameData.Cities) { City city = new City(cityData.Owner) { X = cityData.X, Y = cityData.Y, NameId = cityData.NameId, Size = cityData.ActualSize, Food = cityData.Food, Shields = cityData.Shields }; city.SetProduction(cityData.CurrentProduction); city.SetResourceTiles(cityData.ResourceTiles); // Set city buildings foreach (byte buildingId in cityData.Buildings) { city.AddBuilding(Common.Buildings.First(b => b.Id == buildingId)); } // Set city wonders foreach (IWonder wonder in Common.Wonders) { if (gameData.Wonders[wonder.Id] != cityData.Id) { continue; } city.AddWonder(wonder); } _cities.Add(city); foreach (byte fortifiedUnit in cityData.FortifiedUnits) { // fire-eggs 20190622 corrected restore of "fortified" units // Unit id is actually in lower 6 bits // see https://forums.civfanatics.com/threads/sve-file-format.493581/page-4 int unitId = fortifiedUnit & 0x3F; bool fortified = (fortifiedUnit & 0x40) != 0; bool veteran = (fortifiedUnit & 0x80) != 0; IUnit unit = CreateUnit((UnitType)unitId, city.X, city.Y); if (unit == null) { Log("Unknown fortified unit found: {0}", fortifiedUnit); continue; } unit.Status = (byte)(fortified ? 8 : 0 + (veteran ? 32 : 0)); unit.Owner = city.Owner; unit.SetHome(city); _units.Add(unit); } cityList.Add(cityData.Id, city); } // TODO fire-eggs: wrong when playing with fewer than 7? UnitData[][] unitData = gameData.Units; for (byte p = 0; p < 8; p++) { if (!gameData.ActiveCivilizations[p]) { continue; } foreach (UnitData data in unitData[p]) { IUnit unit = CreateUnit((UnitType)data.TypeId, data.X, data.Y); if (unit == null) { continue; } unit.Status = data.Status; unit.Owner = p; unit.PartMoves = (byte)(data.RemainingMoves % 3); unit.MovesLeft = (byte)((data.RemainingMoves - unit.PartMoves) / 3); if (data.GotoX != 0xFF) { unit.Goto = new Point(data.GotoX, data.GotoY); } if (cityList.ContainsKey(data.HomeCityId)) { unit.SetHome(cityList[data.HomeCityId]); } _units.Add(unit); } } _replayData.AddRange(gameData.ReplayData); // fire-eggs fix issue #68: don't repeat any 'civilization destroyed' messages on game load foreach (ReplayData replayData in _replayData) { if (replayData is ReplayData.CivilizationDestroyed foo) { // TODO fire-eggs: wrong when playing with fewer than 7? int dex = foo.DestroyedId - (foo.DestroyedId > 7 ? 7 : 0); _players[dex]._destroyed = true; } } // Game Settings InstantAdvice = (Settings.InstantAdvice == GameOption.On); AutoSave = (Settings.AutoSave != GameOption.Off); EndOfTurn = (Settings.EndOfTurn == GameOption.On); Animations = (Settings.Animations != GameOption.Off); Sound = (Settings.Sound != GameOption.Off); EnemyMoves = (Settings.EnemyMoves != GameOption.Off); CivilopediaText = (Settings.CivilopediaText != GameOption.Off); Palace = (Settings.Palace != GameOption.Off); bool[] options = gameData.GameOptions; if (Settings.InstantAdvice == GameOption.Default) { InstantAdvice = options[0]; } if (Settings.AutoSave == GameOption.Default) { AutoSave = options[1]; } if (Settings.EndOfTurn == GameOption.Default) { EndOfTurn = options[2]; } if (Settings.Animations == GameOption.Default) { Animations = options[3]; } if (Settings.Sound == GameOption.Default) { Sound = options[4]; } if (Settings.EnemyMoves == GameOption.Default) { EnemyMoves = options[5]; } if (Settings.CivilopediaText == GameOption.Default) { CivilopediaText = options[6]; } if (Settings.Palace == GameOption.Default) { Palace = options[7]; } _currentPlayer = gameData.HumanPlayer; for (int i = 0; i < _units.Count(); i++) { if (_units[i].Owner != gameData.HumanPlayer || _units[i].Busy) { continue; } _activeUnit = i; if (_units[i].MovesLeft > 0) { break; } } }