/// <summary>
 /// 刷新服务里程碑
 /// </summary>
 /// <param name="name"></param>
 /// <param name="milestoneInfo"></param>
 /// <param name="config"></param>
 /// <param name="inGroup"></param>
 private void RefreshServiceMilestones(string name, MilestoneInfo milestoneInfo, ModConfigModel config = null, bool inGroup = false)
 {
     if (config != null && config.ServiceExistsFeatures.Contains(name))
     {
         RefreshFeatureMilestones(name, milestoneInfo);
     }
     else if (EnumHelper.TryToEnumData(name, out PositionData <ItemClass.Service> serviceEnum))
     {
         if (milestoneInfo.GetLevel() < Singleton <UnlockManager> .instance.m_properties.m_ServiceMilestones[(int)serviceEnum.enumValue].GetLevel())
         {
             Singleton <UnlockManager> .instance.m_properties.m_ServiceMilestones[(int)serviceEnum.enumValue] = milestoneInfo;
             switch (name)
             {
             case "Monuments":
                 milestonesManager.UnlockMilestone("Statue of Industry Requirements");
                 milestonesManager.UnlockMilestone("Statue of Wealth Requirements");
                 milestonesManager.UnlockMilestone("Lazaret Plaza Requirements");
                 milestonesManager.UnlockMilestone("Statue of Shopping Requirements");
                 milestonesManager.UnlockMilestone("Plaza of the Dead Requirements");
                 if (managers.application.SupportsExpansion(Expansion.NaturalDisasters))
                 {
                     milestonesManager.UnlockMilestone("Meteor Park Requirements");
                 }
                 if (managers.application.SupportsExpansion(Expansion.GreenCities))
                 {
                     milestonesManager.UnlockMilestone("Bird And Bee Haven Requirements");
                 }
                 break;
             }
         }
     }
 }
Exemplo n.º 2
0
        public static void MilestoneUnlocked(MilestoneInfo info)
        {
            try
            {
                if (Mod.IsEnabled && Helper.HasTelemFlag(Mod.config.TelemetryLevel, Helper.TelemOption.DisableAll) ||
                    Helper.HasTelemFlag(Mod.config.TelemetryLevel, Helper.TelemOption.DisableMilestoneUnlock))
                {
                    if (Mod.DEBUG_LOG_ON)
                    {
                        Helper.dbgLog("Milestone telemetry disabled.");
                    }
                    return;
                }

                TelemetryKH telemetry = new TelemetryKH();
                telemetry.AddEvent("unlocking", new Telemetry.Pair[]
                {
                    new Telemetry.Pair("name", (!(info != null)) ? "Name unavailable" : info.name),
                    new Telemetry.Pair("gameTime", (!Singleton <SimulationManager> .exists) ? "Similation not running o_O" : Singleton <SimulationManager> .instance.m_currentGameTime.ToString("dd/MM/yyyy H:mm:ss"))
                });
                telemetry.Push();
            }
            catch (Exception ex)
            {
                CODebugBase <LogChannel> .Warn(LogChannel.HTTP, ex.GetType() + ": Telemetry event failed " + ex.Message);
            }
        }
 /// <summary>
 /// 刷新子服务里程碑
 /// </summary>
 /// <param name="subService"></param>
 /// <param name="milestoneInfo"></param>
 private void RefreshSubServiceMilestones(ItemClass.SubService subService, MilestoneInfo milestoneInfo)
 {
     if (milestoneInfo.GetLevel() < Singleton <UnlockManager> .instance.m_properties.m_SubServiceMilestones[(int)subService].GetLevel())
     {
         Singleton <UnlockManager> .instance.m_properties.m_SubServiceMilestones[(int)subService] = milestoneInfo;
     }
 }
        // Thread: Main
        public override void OnRefreshMilestones()
        {
            if (Singleton <SimulationManager> .instance.m_metaData.m_updateMode == SimulationManager.UpdateMode.NewGame)
            {
                // only do once
                if (!unlockedAreas)
                {
                    IAreas AreasManager = Managers.areas;

                    // calculate original cash
                    long originalCash = EconomyManager.instance.InternalCashAmount;

                    // causes rendering issue in new areas
                    Singleton <UnlockManager> .instance.UnlockAllProgressionMilestones();

                    // unlock all tiles
                    int rows = (int)Math.Sqrt(AreasManager.maxAreaCount);

                    for (int x = 0; x < rows; x++)
                    {
                        for (int y = 0; y < rows; y++)
                        {
                            int column = x;
                            int row    = y;

                            if (rows.Equals(3))
                            {
                                column = x + 1;
                                row    = y + 1;
                            }

                            if (!AreasManager.IsAreaUnlocked(column, row) && AreasManager.CanUnlockArea(column, row))
                            {
                                AreasManager.UnlockArea(column, row, false);
                            }
                        }
                    }

                    // copy milestone info so we can reset it to default
                    MilestoneInfo[] MilestoneInfos = new MilestoneInfo[UnlockManager.instance.m_allMilestones.Count];
                    UnlockManager.instance.m_allMilestones.Values.CopyTo(MilestoneInfos, 0);

                    UnlockManager.ResetMilestones(MilestoneInfos, false);

                    // calculated added cash
                    long finalCash      = EconomyManager.instance.InternalCashAmount;
                    int  cashDifference = Convert.ToInt32(originalCash - finalCash);

                    // remove cash difference
                    EconomyManager.instance.AddResource(EconomyManager.Resource.LoanAmount, cashDifference, ItemClass.Service.None, ItemClass.SubService.None, ItemClass.Level.None);
                }
            }

            unlockedAreas = true;
        }
        public static uint GetLevel(this MilestoneInfo milestone)
        {
            if (milestone != null)
            {
                switch (milestone.GetComparisonValue())
                {
                case 550:
                    return(1);

                case 1100:
                    return(2);

                case 1700:
                    return(3);

                case 3000:
                    return(4);

                case 6000:
                    return(5);

                case 9000:
                    return(6);

                case 12500:
                    return(7);

                case 20000:
                    return(8);

                case 25000:
                    return(9);

                case 40000:
                    return(10);

                case 55000:
                    return(11);

                case 80000:
                    return(12);

                case 100000:
                    return(13);

                default:
                    return(0);
                }
            }
            return(0);
        }
Exemplo n.º 6
0
        public static string GetLocalizedTooltip(Asset asset, PrefabInfo prefab, string title)
        {
            MilestoneInfo unlockMilestone = prefab.GetUnlockMilestone();

            string text = TooltipHelper.Format(new string[]
            {
                LocaleFormatter.Title,
                title,
                LocaleFormatter.Sprite,
                (!string.IsNullOrEmpty(prefab.m_InfoTooltipThumbnail)) ? prefab.m_InfoTooltipThumbnail : prefab.name,
                LocaleFormatter.Text,
                (asset.findIt2Description + Asset.GetLocalizedDescription(prefab)),
                LocaleFormatter.Locked,
                (!ToolsModifierControl.IsUnlocked(unlockMilestone)).ToString()
            });

            ToolsModifierControl.GetUnlockingInfo(unlockMilestone, out string unlockDesc, out string currentValue, out string targetValue, out string progress, out string locked);

            string addTooltip = TooltipHelper.Format(new string[]
            {
                LocaleFormatter.LockedInfo,
                locked,
                LocaleFormatter.UnlockDesc,
                unlockDesc,
                LocaleFormatter.UnlockPopulationProgressText,
                progress,
                LocaleFormatter.UnlockPopulationTarget,
                targetValue,
                LocaleFormatter.UnlockPopulationCurrent,
                currentValue
            });

            text = TooltipHelper.Append(text, addTooltip);
            PrefabAI aI = prefab.GetAI();

            if (aI != null)
            {
                text = TooltipHelper.Append(text, aI.GetLocalizedTooltip());
            }

            if (prefab is PropInfo || prefab is TreeInfo)
            {
                text = TooltipHelper.Append(text, TooltipHelper.Format(new string[]
                {
                    LocaleFormatter.Cost,
                    LocaleFormatter.FormatCost(prefab.GetConstructionCost(), false)
                }));
            }

            return(text);
        }
        private void SpawnEntry(string name, bool enabled, MilestoneInfo info)
        {
            var landscapingInfo = (LandscapingPanel.LandscapingInfo)
                                  typeof(LandscapingPanel).GetProperty("landscapingInfo", BindingFlags.NonPublic | BindingFlags.Instance)
                                  .GetValue(this, null);

            landscapingInfo.m_DirtPrice = Singleton <TerrainManager> .instance.m_properties.m_dirtPrice;
            float  cost = (float)((double)landscapingInfo.m_DirtPrice * 65536.0 / 262144.0 * 512.0 / 100.0);
            string str  = TooltipHelper.Format(LocaleFormatter.Title, Locale.Get("LANDSCAPING_TITLE", name), LocaleFormatter.Sprite, name, LocaleFormatter.Text, Locale.Get("LANDSCAPING_DESC", name), LocaleFormatter.Locked, (!enabled).ToString(), LocaleFormatter.Cost, LocaleFormatter.FormatCubicCost(cost));

            if (Singleton <UnlockManager> .exists)
            {
                string unlockDesc;
                string currentValue;
                string targetValue;
                string progress;
                string locked;
                ToolsModifierControl.GetUnlockingInfo(info, out unlockDesc, out currentValue, out targetValue, out progress, out locked);
                string addTooltip = TooltipHelper.Format(LocaleFormatter.LockedInfo, locked, LocaleFormatter.UnlockDesc, unlockDesc, LocaleFormatter.UnlockPopulationProgressText, progress, LocaleFormatter.UnlockPopulationTarget, targetValue, LocaleFormatter.UnlockPopulationCurrent, currentValue);
                str = TooltipHelper.Append(str, addTooltip);
            }
            //begin mod
            string         buttonName;
            UITextureAtlas buttonAtlas;
            UIComponent    tooltipBox;

            if (name == "Ditch")
            {
                buttonName  = "TerrainDitch";
                buttonAtlas = Util.CreateAtlasFromEmbeddedResources(Assembly.GetExecutingAssembly(), "NaturalResourcesBrush.resources", new List <string> {
                    "TerrainDitch"
                });
                tooltipBox = GeneratedPanel.landscapingTooltipBox;
            }
            else if (name == "Sand")
            {
                buttonName  = "ResourceSand";
                tooltipBox  = GeneratedPanel.tooltipBox;
                buttonAtlas = UIView.GetAView().defaultAtlas;
            }
            else
            {
                buttonName  = "Landscaping" + name;
                buttonAtlas = null;
                tooltipBox  = GeneratedPanel.landscapingTooltipBox;
            }
            var button = (UIButton)this.SpawnEntry(name, str, buttonName, (UITextureAtlas)buttonAtlas, tooltipBox, enabled);

            button.objectUserData = (object)landscapingInfo;
            //end mod
        }
        internal Node CreateMilestone(int parentID, string name)
        {
            MilestoneInfo info = new MilestoneInfo();

            info.Name     = name;
            info.ParentID = parentID;

            // create the node
            ReAuthenticateIfRequired();
            Node node = fCollaborationService.CreateMilestone(ref fCollaborationAuthentication, info);

            UpdateAuthenticationTokens(fCollaborationAuthentication.AuthenticationToken);

            return(node);
        }
        public void CheckUnlocks()
        {
            int milestoneNum = 99; // Unlock all disasters in case of error

            MilestoneInfo mi = Singleton <UnlockManager> .instance.GetCurrentMilestone();

            if (mi != null)
            {
                int.TryParse(mi.name.Substring(9), out milestoneNum);
            }

            if (milestoneNum >= 3)
            {
                container.ForestFire.Unlock();
            }
            if (milestoneNum >= 3)
            {
                container.Thunderstorm.Unlock();
            }
            if (milestoneNum >= 4)
            {
                container.Sinkhole.Unlock();
            }
            if (milestoneNum >= 5)
            {
                container.Tsunami.Unlock();
            }
            if (milestoneNum >= 5)
            {
                container.Tornado.Unlock();
            }
            if (milestoneNum >= 6)
            {
                container.Earthquake.Unlock();
            }
            if (milestoneNum >= 6)
            {
                container.MeteorStrike.Unlock();
            }
        }
        /// <summary>
        /// 刷新政策里程碑
        /// </summary>
        /// <param name="name"></param>
        /// <param name="milestoneInfo"></param>
        private void RefreshPolicyMilestones(string name, MilestoneInfo milestoneInfo)
        {
            if (EnumHelper.TryToEnumData(name, out PositionData <DistrictPolicies.Policies> policyEnum))
            {
                RefreshFeatureMilestones(UnlockManager.Feature.Policies.ToString(), milestoneInfo);
                if (EnumHelper.TryToEnumData(policyEnum.GetCategory(), out PositionData <DistrictPolicies.Types> policyTypeEnum))
                {
                    if (milestoneInfo.GetLevel() < Singleton <UnlockManager> .instance.m_properties.m_PolicyTypeMilestones[(int)policyTypeEnum.enumValue].GetLevel())
                    {
                        Singleton <UnlockManager> .instance.m_properties.m_PolicyTypeMilestones[(int)policyTypeEnum.enumValue] = milestoneInfo;
                    }
                }
                var i = (int)(policyEnum.enumValue & (DistrictPolicies.Policies) 31);
                switch (policyEnum.GetCategory())
                {
                case "Services":
                    if (milestoneInfo.GetLevel() < Singleton <UnlockManager> .instance.m_properties.m_ServicePolicyMilestones[i].GetLevel())
                    {
                        Singleton <UnlockManager> .instance.m_properties.m_ServicePolicyMilestones[i] = milestoneInfo;
                    }
                    break;

                case "Taxation":
                    if (milestoneInfo.GetLevel() < Singleton <UnlockManager> .instance.m_properties.m_TaxationPolicyMilestones[i].GetLevel())
                    {
                        Singleton <UnlockManager> .instance.m_properties.m_TaxationPolicyMilestones[i] = milestoneInfo;
                    }
                    break;

                case "CityPlanning":
                    if (milestoneInfo.GetLevel() < Singleton <UnlockManager> .instance.m_properties.m_CityPlanningPolicyMilestones[i].GetLevel())
                    {
                        Singleton <UnlockManager> .instance.m_properties.m_CityPlanningPolicyMilestones[i] = milestoneInfo;
                    }
                    break;
                }
            }
        }
Exemplo n.º 11
0
        public override bool CheckUnlocking()
        {
            MilestoneInfo unlockMilestoneInfo = null;

            try
            {
                if (!Singleton <UnlockManager> .instance.m_allMilestones.TryGetValue("Milestone" + this.m_milestone.ToString(), out unlockMilestoneInfo))
                {
                    unlockMilestoneInfo = null;
                }
                else
                {
                    //Debug.Log("Successcully read milestone");
                    this.m_info.m_UnlockMilestone = unlockMilestoneInfo;
                }
            }
            catch
            {
                //Debug.Log("Could not read milestone");
                unlockMilestoneInfo = null;
            }
            return(base.CheckUnlocking());
        }
        /// <summary>
        /// 刷新建筑里程碑
        /// </summary>
        /// <param name="name">建筑名称</param>
        /// <param name="milestoneInfo">新的里程碑进度</param>
        /// <param name="config">配置信息</param>
        /// <param name="inGroup">是否在组</param>
        private void RefreshBuildingMilestone(string name, MilestoneInfo milestoneInfo, ModConfigModel config, bool inGroup = false)
        {
            if (config.BuildingExistsRoads.Contains(name) || config.BuildingContainedRoads.Contains(name))
            {
                RefreshRoadMilestone(name, milestoneInfo, config);
            }
            else if (config.BuildingGroups.TryGetValue(name, out List <string> buildingGroup) && !inGroup)
            {
                foreach (string buildingName in buildingGroup)
                {
                    RefreshBuildingMilestone(buildingName, milestoneInfo, config, true);
                }
            }
            else if (PrefabCollection <BuildingInfo> .LoadedExists(name))
            {
                BuildingInfo building = PrefabCollection <BuildingInfo> .FindLoaded(name);

                if (milestoneInfo.GetLevel() < building.GetUnlockMilestone().GetLevel())
                {
                    building.m_UnlockMilestone = milestoneInfo;
                }
                RefreshRelatedMilestone(name, building.category, building.m_class.m_service, building.m_class.m_subService, milestoneInfo);
            }
        }
        /// <summary>
        /// 刷新道路里程碑
        /// </summary>
        /// <param name="name">道路名称</param>
        /// <param name="milestoneInfo">新的里程碑进度</param>
        /// <param name="config">配置信息</param>
        /// <param name="inGroup">是否在组</param>
        private void RefreshRoadMilestone(string name, MilestoneInfo milestoneInfo, ModConfigModel config, bool inGroup = false)
        {
            if (config.RoadExistsBuildings.Contains(name))
            {
                RefreshBuildingMilestone(name, milestoneInfo, config);
            }
            else if (config.RoadGroups.TryGetValue(name, out List <string> roadGroup) && !inGroup)
            {
                foreach (string roadName in roadGroup)
                {
                    RefreshRoadMilestone(roadName, milestoneInfo, config, true);
                }
            }
            else if (PrefabCollection <NetInfo> .LoadedExists(name))
            {
                NetInfo net = PrefabCollection <NetInfo> .FindLoaded(name);

                if (milestoneInfo.GetLevel() < net.GetUnlockMilestone().GetLevel())
                {
                    net.m_UnlockMilestone = milestoneInfo;
                }
                RefreshRelatedMilestone(name, net.category, net.m_class.m_service, net.m_class.m_subService, net.m_UnlockMilestone);
            }
        }
Exemplo n.º 14
0
        public static void MilestoneUnlocked(MilestoneInfo info)
        {
            try
            {
                if (Mod.IsEnabled && Helper.HasTelemFlag(Mod.config.TelemetryLevel, Helper.TelemOption.DisableAll) ||
                    Helper.HasTelemFlag(Mod.config.TelemetryLevel, Helper.TelemOption.DisableMilestoneUnlock))
                {
                    if (Mod.DEBUG_LOG_ON) { Helper.dbgLog("Milestone telemetry disabled."); }
                    return;
                }

                TelemetryKH telemetry = new TelemetryKH();
                telemetry.AddEvent("unlocking", new Telemetry.Pair[]
                {
                    new Telemetry.Pair("name", (!(info != null)) ? "Name unavailable" : info.name),
                    new Telemetry.Pair("gameTime", (!Singleton<SimulationManager>.exists) ? "Similation not running o_O" : Singleton<SimulationManager>.instance.m_currentGameTime.ToString("dd/MM/yyyy H:mm:ss"))
                });
                telemetry.Push();
            }
            catch (Exception ex)
            {
                CODebugBase<LogChannel>.Warn(LogChannel.HTTP, ex.GetType() + ": Telemetry event failed " + ex.Message);
            }
        }
Exemplo n.º 15
0
        protected override void SimulationStepImpl(int subStep)
        {
            if (this.m_linesUpdated)
            {
                this.m_linesUpdated = false;
                int num = this.m_updatedLines.Length;
                for (int i = 0; i < num; i++)
                {
                    ulong num2 = this.m_updatedLines[i];
                    if (num2 != 0uL)
                    {
                        for (int j = 0; j < 64; j++)
                        {
                            if ((num2 & 1uL << j) != 0uL)
                            {
                                ushort num3 = (ushort)(i << 6 | j);
                                if (this.m_lines.m_buffer[(int)num3].m_flags != TransportLine.Flags.None)
                                {
                                    if (BusTransportLineAI.UpdatePaths(ref this.m_lines.m_buffer[(int)num3], num3) && BusTransportLineAI.UpdateMeshData(ref this.m_lines.m_buffer[(int)num3], num3))
                                    //if (this.m_lines.m_buffer[(int)num3].UpdatePaths(num3) && this.m_lines.m_buffer[(int)num3].UpdateMeshData(num3))
                                    {
                                        num2 &= ~(1uL << j);
                                    }
                                }
                                else
                                {
                                    num2 &= ~(1uL << j);
                                }
                            }
                        }
                        this.m_updatedLines[i] = num2;
                        if (num2 != 0uL)
                        {
                            this.m_linesUpdated = true;
                        }
                    }
                }
            }
            if (this.m_patchesDirty)
            {
                this.m_patchesDirty = false;
                int num4 = this.m_patches.Length;
                for (int k = 0; k < num4; k++)
                {
                    TransportPatch transportPatch = this.m_patches[k];
                    int            num5           = 0;
                    while (transportPatch != null)
                    {
                        if (transportPatch.m_isDirty)
                        {
                            transportPatch.UpdateMeshData();
                        }
                        transportPatch = transportPatch.m_nextPatch;
                        if (++num5 >= 100)
                        {
                            CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace);

                            break;
                        }
                    }
                }
            }
            if (subStep != 0)
            {
                int num6 = (int)(Singleton <SimulationManager> .instance.m_currentFrameIndex & 255u);
                int num7 = num6 * 1;
                int num8 = (num6 + 1) * 1 - 1;
                for (int l = num7; l <= num8; l++)
                {
                    TransportLine.Flags flags = this.m_lines.m_buffer[l].m_flags;
                    if ((flags & (TransportLine.Flags.Created | TransportLine.Flags.Temporary)) == TransportLine.Flags.Created)
                    {
                        this.m_lines.m_buffer[l].SimulationStep((ushort)l);
                    }
                }
                if ((Singleton <SimulationManager> .instance.m_currentFrameIndex & 4095u) == 0u)
                {
                    StatisticsManager instance      = Singleton <StatisticsManager> .instance;
                    StatisticBase     statisticBase = instance.Acquire <StatisticArray>(StatisticType.AveragePassengers);
                    for (int m = 0; m < 5; m++)
                    {
                        this.m_passengers[m].Update();
                        this.m_passengers[m].Reset();
                        statisticBase.Acquire <StatisticInt32>(m, 5).Set((int)(this.m_passengers[m].m_residentPassengers.m_averageCount + this.m_passengers[m].m_touristPassengers.m_averageCount));
                    }
                }
            }
            if (subStep <= 1)
            {
                int num9  = (int)(Singleton <SimulationManager> .instance.m_currentTickIndex & 1023u);
                int num10 = num9 * PrefabCollection <TransportInfo> .PrefabCount() >> 10;

                int num11 = ((num9 + 1) * PrefabCollection <TransportInfo> .PrefabCount() >> 10) - 1;
                for (int n = num10; n <= num11; n++)
                {
                    TransportInfo prefab = PrefabCollection <TransportInfo> .GetPrefab((uint)n);

                    if (prefab != null)
                    {
                        MilestoneInfo unlockMilestone = prefab.m_UnlockMilestone;
                        if (unlockMilestone != null)
                        {
                            Singleton <UnlockManager> .instance.CheckMilestone(unlockMilestone, false, false);
                        }
                    }
                }
            }
        }
        private void SpawnEntry(string name, bool enabled, MilestoneInfo info)
        {
            var landscapingInfo = (LandscapingPanel.LandscapingInfo)
                typeof(LandscapingPanel).GetProperty("landscapingInfo", BindingFlags.NonPublic | BindingFlags.Instance)
                    .GetValue(this, null);

            landscapingInfo.m_DirtPrice = Singleton<TerrainManager>.instance.m_properties.m_dirtPrice;
            float cost = (float)((double)landscapingInfo.m_DirtPrice * 65536.0 / 262144.0 * 512.0 / 100.0);
            string str = TooltipHelper.Format(LocaleFormatter.Title, Locale.Get("LANDSCAPING_TITLE", name), LocaleFormatter.Sprite, name, LocaleFormatter.Text, Locale.Get("LANDSCAPING_DESC", name), LocaleFormatter.Locked, (!enabled).ToString(), LocaleFormatter.Cost, LocaleFormatter.FormatCubicCost(cost));
            if (Singleton<UnlockManager>.exists)
            {
                string unlockDesc;
                string currentValue;
                string targetValue;
                string progress;
                string locked;
                ToolsModifierControl.GetUnlockingInfo(info, out unlockDesc, out currentValue, out targetValue, out progress, out locked);
                string addTooltip = TooltipHelper.Format(LocaleFormatter.LockedInfo, locked, LocaleFormatter.UnlockDesc, unlockDesc, LocaleFormatter.UnlockPopulationProgressText, progress, LocaleFormatter.UnlockPopulationTarget, targetValue, LocaleFormatter.UnlockPopulationCurrent, currentValue);
                str = TooltipHelper.Append(str, addTooltip);
            }
            //begin mod
            string buttonName;
            UITextureAtlas buttonAtlas;
            UIComponent tooltipBox;
            if (name == "Ditch")
            {
                buttonName = "TerrainDitch";
                buttonAtlas = Util.CreateAtlasFromEmbeddedResources(Assembly.GetExecutingAssembly(), "NaturalResourcesBrush.resources", new List<string> { "TerrainDitch" });
                tooltipBox = GeneratedPanel.landscapingTooltipBox;
            }
            else if (name == "Sand")
            {
                buttonName = "ResourceSand";
                tooltipBox = GeneratedPanel.tooltipBox;
                buttonAtlas = UIView.GetAView().defaultAtlas;
            }
            else
            {
                buttonName = "Landscaping" + name;
                buttonAtlas = null;
                tooltipBox = GeneratedPanel.landscapingTooltipBox;
            }
            var button = (UIButton)this.SpawnEntry(name, str, buttonName, (UITextureAtlas)buttonAtlas, tooltipBox, enabled);
            button.objectUserData = (object)landscapingInfo;
            //end mod
        }
		// Thread: Main
		public override void OnRefreshMilestones() {

			if (Singleton<SimulationManager>.instance.m_metaData.m_updateMode == SimulationManager.UpdateMode.NewGame) {
				
				// only do once
				if (! unlockedAreas) {
					IAreas AreasManager = Managers.areas;

					// calculate original cash
					long originalCash = EconomyManager.instance.InternalCashAmount;

					// causes rendering issue in new areas
					Singleton<UnlockManager>.instance.UnlockAllProgressionMilestones();

					// unlock all tiles
					int rows = (int)Math.Sqrt (AreasManager.maxAreaCount);

					for (int x = 0; x < rows; x++) {

						for (int y = 0; y < rows; y++) {
							int column = x;
							int row = y;

							if (rows.Equals (3)) {
								column = x + 1;
								row = y + 1;
							}

							if (!AreasManager.IsAreaUnlocked (column, row) && AreasManager.CanUnlockArea(column, row) ) {
								AreasManager.UnlockArea(column, row, false);
							}
						}         
					}

					// copy milestone info so we can reset it to default
					MilestoneInfo[] MilestoneInfos = new MilestoneInfo[UnlockManager.instance.m_allMilestones.Count];
					UnlockManager.instance.m_allMilestones.Values.CopyTo (MilestoneInfos, 0);

					UnlockManager.ResetMilestones(MilestoneInfos, false);

					// calculated added cash
					long finalCash = EconomyManager.instance.InternalCashAmount;
					int cashDifference = Convert.ToInt32(originalCash - finalCash);

					// remove cash difference
					EconomyManager.instance.AddResource(EconomyManager.Resource.LoanAmount, cashDifference, ItemClass.Service.None, ItemClass.SubService.None, ItemClass.Level.None);
				}
			}

			unlockedAreas = true;
		}
        /// <summary>
        /// 刷新功能里程碑
        /// </summary>
        /// <param name="name"></param>
        /// <param name="milestoneInfo"></param>
        /// <param name="config"></param>
        /// <param name="inGroup"></param>
        private void RefreshFeatureMilestones(string name, MilestoneInfo milestoneInfo, ModConfigModel config = null, bool inGroup = false)
        {
            if (config != null && config.FeatureGroups.TryGetValue(name, out List <string> featureGroup) && !inGroup)
            {
                foreach (string item in featureGroup)
                {
                    RefreshFeatureMilestones(item, milestoneInfo, config, true);
                }
            }
            else if (EnumHelper.TryToEnumData(name, out PositionData <UnlockManager.Feature> featureEnum))
            {
                if (milestoneInfo.GetLevel() < Singleton <UnlockManager> .instance.m_properties.m_FeatureMilestones[(int)featureEnum.enumValue].GetLevel())
                {
                    Singleton <UnlockManager> .instance.m_properties.m_FeatureMilestones[(int)featureEnum.enumValue] = milestoneInfo;
                    switch (name)
                    {
                    case "MonumentLevel2":
                        milestonesManager.UnlockMilestone("Fountain of LifeDeath Requirements");
                        milestonesManager.UnlockMilestone("Friendly Neighborhood Requirements");
                        milestonesManager.UnlockMilestone("Transport Tower Requirements");
                        milestonesManager.UnlockMilestone("Trash Mall Requirements");
                        milestonesManager.UnlockMilestone("Posh Mall Requirements");
                        if (managers.application.SupportsExpansion(Expansion.NaturalDisasters))
                        {
                            milestonesManager.UnlockMilestone("Disaster Memorial Requirements");
                        }
                        if (managers.application.SupportsExpansion(Expansion.GreenCities))
                        {
                            milestonesManager.UnlockMilestone("Climate Research Station Requirements");
                        }
                        if (managers.application.SupportsExpansion(Expansion.Parks))
                        {
                            milestonesManager.UnlockMilestone("Clock Tower Requirements");
                        }
                        break;

                    case "MonumentLevel3":
                        milestonesManager.UnlockMilestone("Colossal Offices Requirements");
                        milestonesManager.UnlockMilestone("Official Park Requirements");
                        milestonesManager.UnlockMilestone("CourtHouse Requirements");
                        milestonesManager.UnlockMilestone("Grand Mall Requirements");
                        milestonesManager.UnlockMilestone("Cityhall Requirements");
                        if (managers.application.SupportsExpansion(Expansion.NaturalDisasters))
                        {
                            milestonesManager.UnlockMilestone("Helicopter Park Requirements");
                        }
                        if (managers.application.SupportsExpansion(Expansion.Parks))
                        {
                            milestonesManager.UnlockMilestone("Old Market Street Requirements");
                        }
                        break;

                    case "MonumentLevel4":
                        milestonesManager.UnlockMilestone("Business Park Requirements");
                        milestonesManager.UnlockMilestone("Library Requirements");
                        milestonesManager.UnlockMilestone("Observatory Requirements");
                        milestonesManager.UnlockMilestone("Opera House Requirements");
                        milestonesManager.UnlockMilestone("Oppression Office Requirements");
                        if (managers.application.SupportsExpansion(Expansion.NaturalDisasters))
                        {
                            milestonesManager.UnlockMilestone("Pyramid Of Safety Requirements");
                        }
                        if (managers.application.SupportsExpansion(Expansion.GreenCities))
                        {
                            milestonesManager.UnlockMilestone("Floating Gardens Requirements");
                        }
                        if (managers.application.SupportsExpansion(Expansion.Parks))
                        {
                            milestonesManager.UnlockMilestone("Sea Fortress Requirements");
                        }
                        break;

                    case "MonumentLevel5":
                        milestonesManager.UnlockMilestone("ScienceCenter Requirements");
                        milestonesManager.UnlockMilestone("Servicing Services Requirements");
                        milestonesManager.UnlockMilestone("SeaWorld Requirements");
                        milestonesManager.UnlockMilestone("Expocenter Requirements");
                        milestonesManager.UnlockMilestone("High Interest Tower Requirements");
                        milestonesManager.UnlockMilestone("Academic Library Prerequisites");
                        milestonesManager.UnlockMilestone("Aviation Club Prerequisites");
                        if (managers.application.SupportsExpansion(Expansion.NaturalDisasters))
                        {
                            milestonesManager.UnlockMilestone("Sphinx Of Scenarios Requirements");
                        }
                        if (managers.application.SupportsExpansion(Expansion.GreenCities))
                        {
                            milestonesManager.UnlockMilestone("Ziggurat Garden Requirements");
                        }
                        if (managers.application.SupportsExpansion(Expansion.Parks))
                        {
                            milestonesManager.UnlockMilestone("Observation Tower Requirements");
                        }
                        break;

                    case "MonumentLevel6":
                        milestonesManager.UnlockMilestone("Cathedral of Plentitude Requirements");
                        milestonesManager.UnlockMilestone("Stadium Requirements");
                        milestonesManager.UnlockMilestone("Modern Art Museum Requirements");
                        milestonesManager.UnlockMilestone("SeaAndSky Scraper Requirements");
                        milestonesManager.UnlockMilestone("Theater of Wonders Requirements");
                        if (managers.application.SupportsExpansion(Expansion.NaturalDisasters))
                        {
                            milestonesManager.UnlockMilestone("Unicorn Park Requirements");
                        }
                        if (managers.application.SupportsExpansion(Expansion.GreenCities))
                        {
                            milestonesManager.UnlockMilestone("Central Park Requirements");
                        }
                        if (managers.application.SupportsExpansion(Expansion.Parks))
                        {
                            milestonesManager.UnlockMilestone("Statue Of Colossalus Requirements");
                        }
                        break;
                    }
                }
            }
        }
        /// <summary>
        /// 刷新相关的里程碑(服务、子服务、功能等)
        /// </summary>
        /// <param name="name"></param>
        /// <param name="category"></param>
        /// <param name="service"></param>
        /// <param name="subService"></param>
        /// <param name="milestoneInfo"></param>
        private void RefreshRelatedMilestone(string name, string category, ItemClass.Service service, ItemClass.SubService subService, MilestoneInfo milestoneInfo)
        {
            switch (category)
            {
            case "LandscapingPaths":
            case "LandscapingWaterStructures":
                RefreshFeatureMilestones(UnlockManager.Feature.Landscaping.ToString(), milestoneInfo);
                break;

            case "IndustryFishing":
                RefreshServiceMilestones(ItemClass.Service.Garbage.ToString(), milestoneInfo);
                RefreshFeatureMilestones(UnlockManager.Feature.Fishing.ToString(), milestoneInfo);
                break;

            case "IndustryWarehouses":
                RefreshServiceMilestones(ItemClass.Service.Garbage.ToString(), milestoneInfo);
                RefreshFeatureMilestones(UnlockManager.Feature.IndustryAreas.ToString(), milestoneInfo);
                break;

            case "MonumentFootball":
                RefreshFeatureMilestones(UnlockManager.Feature.Football.ToString(), milestoneInfo);
                break;

            case "MonumentConcerts":
                RefreshFeatureMilestones(UnlockManager.Feature.Concerts.ToString(), milestoneInfo);
                break;

            case "RoadsIntersection":
                BuildingInfo building = PrefabCollection <BuildingInfo> .FindLoaded(name);

                IntersectionAI intersectionAI = building.m_buildingAI as IntersectionAI;
                if (milestoneInfo.GetLevel() < intersectionAI.GetUnlockMilestone().GetLevel())
                {
                    SetPrivateVariable(intersectionAI, "m_cachedUnlockMilestone", milestoneInfo);
                }
                break;

            case "FireDepartmentDisaster":
                RefreshServiceMilestones(ItemClass.Service.FireDepartment.ToString(), milestoneInfo);
                RefreshFeatureMilestones(UnlockManager.Feature.DisasterResponse.ToString(), milestoneInfo);
                break;

            case "PublicTransportShip":
                RefreshFeatureMilestones(UnlockManager.Feature.Ferry.ToString(), milestoneInfo);
                break;

            case "PublicTransportPlane":
                if (name.Contains("Blimp"))
                {
                    RefreshFeatureMilestones(UnlockManager.Feature.Blimp.ToString(), milestoneInfo);
                }
                else if (name.Contains("Helicopter"))
                {
                    RefreshFeatureMilestones(UnlockManager.Feature.Helicopter.ToString(), milestoneInfo);
                }
                break;

            case "PublicTransportTrolleybus":
                RefreshFeatureMilestones(UnlockManager.Feature.Trolleybus.ToString(), milestoneInfo);
                break;

            case "BeautificationExpansion1":
                RefreshFeatureMilestones(UnlockManager.Feature.ParkAreas.ToString(), milestoneInfo);
                break;
            }
            RefreshServiceMilestones(service.ToString(), milestoneInfo);
            RefreshSubServiceMilestones(subService, milestoneInfo);
        }
        public void RefreshMilestones(ModConfigModel config)
        {
            CustomMilestoneModel customMilestone = XmlHelper.FromXmlFile <CustomMilestoneModel>(_xmlFilePath);

            if (customMilestone.Rebuild)
            {
                customMilestone.Rebuild = false;

                //读取默认道路信息
                for (uint index = 0; index < PrefabCollection <NetInfo> .LoadedCount(); index++)
                {
                    NetInfo net = PrefabCollection <NetInfo> .GetLoaded(index);

                    if (config.RoadIncludes.Contains(config.Renames.GetRename(net.name)) && !customMilestone.Exists(config.Renames.GetRename(net.name)))
                    {
                        if (config.BuildingExistsRoads.Contains(config.Renames.GetRename(net.name)))
                        {
                            customMilestone.Milestones[net.GetUnlockMilestone().GetLevel()].Buildings.Add(new ItemModel()
                            {
                                Name          = config.Renames.GetRename(net.name),
                                LocalizedName = net.GetLocalizedTitle(),
                                Expansions    = net.m_class.m_service.ToString() + "|" + net.m_class.m_subService.ToString() + "|" + net.category
                            });
                        }
                        else
                        {
                            customMilestone.Milestones[net.GetUnlockMilestone().GetLevel()].Roads.Add(new ItemModel()
                            {
                                Name          = config.Renames.GetRename(net.name),
                                LocalizedName = net.GetLocalizedTitle(),
                                Expansions    = net.m_class.m_service.ToString() + "|" + net.m_class.m_subService.ToString() + "|" + net.category
                            });
                        }
                    }
                }

                //读取默认建筑信息
                for (uint index = 0; index < PrefabCollection <BuildingInfo> .LoadedCount(); index++)
                {
                    BuildingInfo building = PrefabCollection <BuildingInfo> .GetLoaded(index);

                    if (config.BuildingIncludes.Contains(config.Renames.GetRename(building.name)) && !customMilestone.Exists(config.Renames.GetRename(building.name)))
                    {
                        if (config.RoadExistsBuildings.Contains(config.Renames.GetRename(building.name)))
                        {
                            customMilestone.Milestones[building.GetUnlockMilestone().GetLevel()].Roads.Add(new ItemModel()
                            {
                                Name          = config.Renames.GetRename(building.name),
                                LocalizedName = building.GetLocalizedTitle(),
                                Expansions    = building.m_class.m_service.ToString() + "|" + building.m_class.m_subService.ToString() + "|" + building.category
                            });
                        }
                        else
                        {
                            customMilestone.Milestones[building.GetUnlockMilestone().GetLevel()].Buildings.Add(new ItemModel()
                            {
                                Name          = config.Renames.GetRename(building.name),
                                LocalizedName = building.GetLocalizedTitle(),
                                Expansions    = building.m_class.m_service.ToString() + "|" + building.m_class.m_subService.ToString() + "|" + building.category
                            });
                        }
                    }
                }

                //读取默认功能信息
                foreach (var featureEnum in Utils.GetOrderedEnumData <UnlockManager.Feature>())
                {
                    if (config.Features.Contains(featureEnum.enumName) && !customMilestone.Exists(featureEnum.enumName, "Feature"))
                    {
                        var level = Singleton <UnlockManager> .instance.m_properties.m_FeatureMilestones[(int)featureEnum.enumValue].GetLevel();
                        if (config.ServiceExistsFeatures.Contains(featureEnum.enumName))
                        {
                            customMilestone.Milestones[level].Services.Add(new ItemModel()
                            {
                                Name          = featureEnum.enumName,
                                LocalizedName = featureEnum.GetLocalizedName(),
                            });
                        }
                        else
                        {
                            customMilestone.Milestones[level].Features.Add(new ItemModel()
                            {
                                Name          = featureEnum.enumName,
                                LocalizedName = featureEnum.GetLocalizedName(),
                            });
                        }
                    }
                }

                //读取默认服务信息
                foreach (var serviceEnum in Utils.GetOrderedEnumData <ItemClass.Service>())
                {
                    if (config.Services.Contains(serviceEnum.enumName) && !customMilestone.Exists(serviceEnum.enumName, "Service"))
                    {
                        var level = Singleton <UnlockManager> .instance.m_properties.m_ServiceMilestones[(int)serviceEnum.enumValue].GetLevel();
                        customMilestone.Milestones[level].Services.Add(new ItemModel()
                        {
                            Name          = serviceEnum.enumName,
                            LocalizedName = serviceEnum.GetLocalizedName(),
                        });
                    }
                }

                //读取默认服务政策信息
                foreach (var policyEnum in Utils.GetOrderedEnumData <DistrictPolicies.Policies>("Services"))
                {
                    var index = (int)(policyEnum.enumValue & (DistrictPolicies.Policies) 31);
                    var level = Singleton <UnlockManager> .instance.m_properties.m_ServicePolicyMilestones[index].GetLevel();
                    customMilestone.Milestones[level].Policies.Add(new ItemModel()
                    {
                        Name          = policyEnum.enumName,
                        LocalizedName = policyEnum.GetLocalizedName(),
                        Expansions    = policyEnum.enumCategory
                    });
                }

                //读取默认税收政策信息
                foreach (var policyEnum in Utils.GetOrderedEnumData <DistrictPolicies.Policies>("Taxation"))
                {
                    var index = (int)(policyEnum.enumValue & (DistrictPolicies.Policies) 31);
                    var level = Singleton <UnlockManager> .instance.m_properties.m_TaxationPolicyMilestones[index].GetLevel();
                    customMilestone.Milestones[level].Policies.Add(new ItemModel()
                    {
                        Name          = policyEnum.enumName,
                        LocalizedName = policyEnum.GetLocalizedName(),
                        Expansions    = policyEnum.enumCategory
                    });
                }

                //读取默认城市规划政策信息
                foreach (var policyEnum in Utils.GetOrderedEnumData <DistrictPolicies.Policies>("CityPlanning"))
                {
                    var index = (int)(policyEnum.enumValue & (DistrictPolicies.Policies) 31);
                    var level = Singleton <UnlockManager> .instance.m_properties.m_CityPlanningPolicyMilestones[index].GetLevel();
                    customMilestone.Milestones[level].Policies.Add(new ItemModel()
                    {
                        Name          = policyEnum.enumName,
                        LocalizedName = policyEnum.GetLocalizedName(),
                        Expansions    = policyEnum.enumCategory
                    });
                }

                //读取默认信息面板信息
                foreach (var infoMode in Utils.GetOrderedEnumData <InfoManager.InfoMode>())
                {
                    var level = Singleton <UnlockManager> .instance.m_properties.m_InfoModeMilestones[(int)infoMode.enumValue].GetLevel();
                    customMilestone.Milestones[level].InfoViews.Add(new ItemModel()
                    {
                        Name          = infoMode.enumName,
                        LocalizedName = Locale.Get("INFOVIEWS", infoMode.enumName)
                    });
                }

                XmlHelper.ToXmlFile(customMilestone, _xmlFilePath);
            }
            else
            {
                MilestoneInfo[] progressionMilestones = Singleton <UnlockManager> .instance.m_properties.m_progressionMilestones;

                //根据配置文件刷新里程碑信息
                foreach (MilestoneModel milestoneModel in customMilestone.Milestones)
                {
                    MilestoneInfo milestoneInfo = milestoneModel.Level > 0 ? progressionMilestones[milestoneModel.Level - 1] : null;

                    //刷新里程碑奖金、地块
                    var count = (milestoneModel.Level == 0 && milestoneModel.PurchaseAreasCount == 0) ? 1 : milestoneModel.PurchaseAreasCount;
                    var total = customMilestone.Milestones.Take(Array.IndexOf(customMilestone.Milestones, milestoneModel)).Sum(m => m.PurchaseAreasCount);
                    for (int i = total; i < total + count && i < 9; i++)
                    {
                        Singleton <UnlockManager> .instance.m_properties.m_AreaMilestones[i] = milestoneInfo;
                    }
                    if (milestoneInfo != null)
                    {
                        milestoneInfo.m_rewardCash = milestoneModel.RewardCash.Value;
                    }

                    //刷新道路
                    foreach (var roadModel in milestoneModel.Roads)
                    {
                        if (config.RoadIncludes.Contains(roadModel.Name) || config.RoadExistsBuildings.Contains(roadModel.Name))
                        {
                            RefreshRoadMilestone(roadModel.Name, milestoneInfo, config);
                        }
                    }

                    //刷新建筑
                    foreach (var buildingModel in milestoneModel.Buildings)
                    {
                        if (config.BuildingIncludes.Contains(buildingModel.Name) || config.BuildingExistsRoads.Contains(buildingModel.Name))
                        {
                            RefreshBuildingMilestone(buildingModel.Name, milestoneInfo, config);
                        }
                    }

                    //刷新功能
                    foreach (var featureModel in milestoneModel.Features)
                    {
                        if (config.Features.Contains(featureModel.Name))
                        {
                            RefreshFeatureMilestones(featureModel.Name, milestoneInfo, config);
                        }
                    }

                    //刷新服务
                    foreach (var serviceModel in milestoneModel.Services)
                    {
                        if (config.Services.Contains(serviceModel.Name) || config.ServiceExistsFeatures.Contains(serviceModel.Name))
                        {
                            RefreshServiceMilestones(serviceModel.Name, milestoneInfo, config);
                        }
                    }

                    //刷新政策
                    foreach (var policyModel in milestoneModel.Policies)
                    {
                        RefreshPolicyMilestones(policyModel.Name, milestoneInfo);
                    }
                }
            }
        }