private IEnumerator ResetCellVisibility()
        {
            yield return(new WaitForEndOfFrame());

            while (Grid.Chunks.Any(chunk => chunk.IsRefreshing))
            {
                yield return(new WaitForEndOfFrame());
            }

            VisibilityCanon.ClearCellVisibility();

            foreach (var unit in UnitFactory.AllUnits)
            {
                var unitOwner = UnitPossessionCanon.GetOwnerOfPossession(unit);

                foreach (var visibleCell in UnitLineOfSightLogic.GetCellsVisibleToUnit(unit))
                {
                    VisibilityCanon.IncreaseCellVisibilityToCiv(visibleCell, unitOwner);
                    ExplorationCanon.SetCellAsExploredByCiv(visibleCell, unitOwner);
                }
            }

            foreach (var city in CityFactory.AllCities)
            {
                var cityOwner = CityPossessionCanon.GetOwnerOfPossession(city);

                foreach (var visibleCell in CityLineOfSightLogic.GetCellsVisibleToCity(city))
                {
                    VisibilityCanon.IncreaseCellVisibilityToCiv(visibleCell, cityOwner);
                    ExplorationCanon.SetCellAsExploredByCiv(visibleCell, cityOwner);
                }
            }

            foreach (var cell in Grid.Cells)
            {
                HexCellShaderData.RefreshVisibility(cell);
            }

            ResetVisionCoroutine = null;

            yield break;
        }
        public void DecomposeCivilizations(SerializableMapData mapData)
        {
            foreach (var civData in mapData.Civilizations)
            {
                var civTemplate = AvailableCivTemplates.Where(template => template.Name.Equals(civData.TemplateName)).FirstOrDefault();

                var newCiv = CivilizationFactory.Create(civTemplate);

                newCiv.GoldStockpile    = civData.GoldStockpile;
                newCiv.CultureStockpile = civData.CultureStockpile;

                PolicyComposer.DecomposePoliciesIntoCiv(civData.SocialPolicies, newCiv);

                DecomposeTechs(civData, newCiv);

                if (civData.ExploredCells != null)
                {
                    foreach (var exploredCoords in civData.ExploredCells)
                    {
                        var exploredCell = Grid.GetCellAtCoordinates(exploredCoords);

                        ExplorationCanon.SetCellAsExploredByCiv(exploredCell, newCiv);
                    }
                }

                DecomposeFreeBuildings(civData, newCiv);

                GoldenAgeCanon.SetGoldenAgeProgressForCiv(newCiv, civData.GoldenAgeProgress);
                GoldenAgeCanon.SetPreviousGoldenAgesForCiv(newCiv, civData.PreviousGoldenAges);

                if (civData.GoldenAgeTurnsLeft > 0)
                {
                    GoldenAgeCanon.StartGoldenAgeForCiv(newCiv, civData.GoldenAgeTurnsLeft);
                }
            }

            foreach (var discoveryPair in mapData.CivDiscoveryPairs)
            {
                var civOne = CivilizationFactory.AllCivilizations.Where(civ => civ.Template.Name.Equals(discoveryPair.Item1)).FirstOrDefault();
                var civTwo = CivilizationFactory.AllCivilizations.Where(civ => civ.Template.Name.Equals(discoveryPair.Item2)).FirstOrDefault();

                if (CivDiscoveryCanon.CanEstablishDiscoveryBetweenCivs(civOne, civTwo))
                {
                    CivDiscoveryCanon.EstablishDiscoveryBetweenCivs(civOne, civTwo);
                }
                else
                {
                    throw new InvalidOperationException(
                              string.Format("Invalid discovery for civs of template names {0} and {1}", discoveryPair.Item1, discoveryPair.Item2)
                              );
                }
            }
        }