public override void Refresh()
        {
            if (TechRecords == null)
            {
                SetUpTechTable();
                SetUpTechTree();
            }

            foreach (var techRecord in TechRecords)
            {
                var recordedTech = techRecord.TechToDisplay;

                techRecord.CurrentProgress = TechCanon.GetProgressOnTechByCiv(recordedTech, ObjectToDisplay);

                if (TechCanon.IsTechDiscoveredByCiv(techRecord.TechToDisplay, ObjectToDisplay))
                {
                    techRecord.Status = TechnologyRecord.TechStatus.Discovered;
                }
                else if (ObjectToDisplay.TechQueue.Contains(techRecord.TechToDisplay))
                {
                    if (ObjectToDisplay.TechQueue.Peek() == techRecord.TechToDisplay)
                    {
                        techRecord.Status = TechnologyRecord.TechStatus.BeingResearched;
                    }
                    else
                    {
                        techRecord.Status = TechnologyRecord.TechStatus.InQueue;
                    }
                }
                else if (
                    SelectionMode != TechSelectionMode.ResearchFreeTech ||
                    TechCanon.IsTechAvailableToCiv(recordedTech, ObjectToDisplay)
                    )
                {
                    techRecord.Status = TechnologyRecord.TechStatus.Available;
                }
                else
                {
                    techRecord.Status = TechnologyRecord.TechStatus.Unavailable;
                }

                techRecord.CanBeClicked = SelectionMode != TechSelectionMode.SetTechQueue ||
                                          !TechCanon.IsTechDiscoveredByCiv(recordedTech, ObjectToDisplay);

                float sciencePerTurn = YieldLogic.GetYieldOfCivilization(ObjectToDisplay)[Simulation.YieldType.Science];

                if (sciencePerTurn > 0)
                {
                    techRecord.TurnsToResearch = (int)Math.Ceiling(
                        (techRecord.TechToDisplay.Cost - techRecord.CurrentProgress) / sciencePerTurn
                        );
                }
                else
                {
                    techRecord.TurnsToResearch = -1;
                }

                techRecord.Refresh();
            }
        }
        public override void Refresh()
        {
            if (ObjectToDisplay == null)
            {
                return;
            }

            if (ObjectToDisplay.TechQueue.Count > 0)
            {
                var activeTech = ObjectToDisplay.TechQueue.Peek();

                CurrentTechRecord.TechToDisplay   = activeTech;
                CurrentTechRecord.Status          = TechnologyRecord.TechStatus.BeingResearched;
                CurrentTechRecord.CurrentProgress = TechCanon.GetProgressOnTechByCiv(activeTech, ObjectToDisplay);

                float sciencePerTurn = YieldLogic.GetYieldOfCivilization(ObjectToDisplay)[Simulation.YieldType.Science];

                if (sciencePerTurn > 0)
                {
                    CurrentTechRecord.TurnsToResearch = (int)Math.Ceiling(
                        (activeTech.Cost - CurrentTechRecord.CurrentProgress) / sciencePerTurn
                        );
                }
                else
                {
                    CurrentTechRecord.TurnsToResearch = -1;
                }
            }
            else
            {
                CurrentTechRecord.TechToDisplay = null;
            }

            CurrentTechRecord.Refresh();
        }
        public void PerformResearch()
        {
            if (TechQueue.Count > 0)
            {
                var activeTech = TechQueue.Peek();

                int techProgress = TechCanon.GetProgressOnTechByCiv(activeTech, this);
                techProgress += LastScienceYield;

                if (techProgress >= activeTech.Cost && TechCanon.IsTechAvailableToCiv(activeTech, this))
                {
                    TechCanon.SetTechAsDiscoveredForCiv(activeTech, this);
                    TechQueue.Dequeue();
                }
                else
                {
                    TechCanon.SetProgressOnTechByCiv(activeTech, this, techProgress);
                }
            }
        }
        public void ComposeCivilizations(SerializableMapData mapData)
        {
            mapData.Civilizations = new List <SerializableCivilizationData>();

            foreach (var civilization in CivilizationFactory.AllCivilizations)
            {
                var civData = new SerializableCivilizationData()
                {
                    TemplateName     = civilization.Template.Name,
                    GoldStockpile    = civilization.GoldStockpile,
                    CultureStockpile = civilization.CultureStockpile,
                    DiscoveredTechs  = TechCanon.GetTechsDiscoveredByCiv(civilization).Select(tech => tech.Name).ToList(),
                    SocialPolicies   = PolicyComposer.ComposePoliciesFromCiv(civilization),
                };

                if (civilization.TechQueue != null && civilization.TechQueue.Count > 0)
                {
                    civData.TechQueue = civilization.TechQueue.Select(tech => tech.Name).ToList();
                }
                else
                {
                    civData.TechQueue = null;
                }

                var availableTechs = TechCanon.GetTechsAvailableToCiv(civilization);

                if (availableTechs.Count() > 0)
                {
                    foreach (var availableTech in availableTechs)
                    {
                        int progress = TechCanon.GetProgressOnTechByCiv(availableTech, civilization);
                        if (progress != 0)
                        {
                            if (civData.ProgressOnTechs == null)
                            {
                                civData.ProgressOnTechs = new Dictionary <string, int>();
                            }

                            civData.ProgressOnTechs[availableTech.Name] = progress;
                        }
                    }
                }
                else
                {
                    civData.ProgressOnTechs = null;
                }

                var exploredCells = Grid.Cells.Where(cell => ExplorationCanon.IsCellExploredByCiv(cell, civilization));

                civData.ExploredCells = exploredCells.Select(cell => cell.Coordinates).ToList();

                civData.FreeBuildings = FreeBuildingsCanon
                                        .GetFreeBuildingsForCiv(civilization)
                                        .Select(buildingList => buildingList.Select(buildingTemplate => buildingTemplate.name).ToList())
                                        .ToList();

                civData.GoldenAgeTurnsLeft = GoldenAgeCanon.GetTurnsLeftOnGoldenAgeForCiv(civilization);
                civData.GoldenAgeProgress  = GoldenAgeCanon.GetGoldenAgeProgressForCiv(civilization);
                civData.PreviousGoldenAges = GoldenAgeCanon.GetPreviousGoldenAgesForCiv(civilization);

                mapData.Civilizations.Add(civData);
            }

            mapData.CivDiscoveryPairs = CivDiscoveryCanon.GetDiscoveryPairs().Select(
                pair => new Tuple <string, string>(pair.Item1.Template.Name, pair.Item2.Template.Name)
                ).ToList();
        }