Exemple #1
0
        /// <summary>
        /// Checks if the game has all required building prefabs currently in memory.
        /// </summary>
        bool AllPrefabsAvailable()
        {
            try
            {
                PrefabLoader.Create().LookupSimulationPrefabs();
                return(PrefabLoader.instance.AllPrefabsAvailable());
            }
            catch (Exception e)
            {
                UnityEngine.Debug.LogException(e);
            }

            return(true);
        }
Exemple #2
0
        const string ROUTINE = "<InitializePrefabs>c__Iterator6"; // TODO make robust

        internal PrefabLoader()
        {
            instance = this;
            Type coroutine = typeof(BuildingCollection).GetNestedType(ROUTINE, BindingFlags.NonPublic);

            nameField      = coroutine?.GetField("name", BindingFlags.NonPublic | BindingFlags.Instance);
            prefabsField   = coroutine?.GetField("prefabs", BindingFlags.NonPublic | BindingFlags.Instance);
            prefabsField2  = coroutine?.GetField("<$>prefabs", BindingFlags.NonPublic | BindingFlags.Instance);
            replacesField  = coroutine?.GetField("replaces", BindingFlags.NonPublic | BindingFlags.Instance);
            replacesField2 = coroutine?.GetField("<$>replaces", BindingFlags.NonPublic | BindingFlags.Instance);

            if (nameField != null && prefabsField != null && prefabsField2 != null && replacesField != null && replacesField2 != null)
            {
                init(typeof(LoadingManager), "QueueLoadingAction");
            }
        }
Exemple #3
0
        /// <summary>
        /// Creates the list of standard prefab levels to load.
        /// </summary>
        KeyValuePair <string, float>[] SetLevels()
        {
            if (Settings.settings.SkipPrefabs)
            {
                PrefabLoader.Create().Deploy();
            }

            LoadingManager.instance.m_supportsExpansion[0] = Check(369150);
            LoadingManager.instance.m_supportsExpansion[1] = Check(420610);
            LoadingManager.instance.m_supportsExpansion[2] = Check(515191);
            LoadingManager.instance.m_supportsExpansion[3] = Check(547502);
            LoadingManager.instance.m_supportsExpansion[4] = Check(614580);
            LoadingManager.instance.m_supportsExpansion[5] = Check(715191);
            LoadingManager.instance.m_supportsExpansion[6] = Check(715194);
            LoadingManager.instance.m_supportsExpansion[7] = Check(944071);
            LoadingManager.instance.m_supportsExpansion[8] = Check(1146930);


            bool isWinter = SimulationManager.instance.m_metaData.m_environment == "Winter";

            if (isWinter && !LoadingManager.instance.m_supportsExpansion[1])
            {
                SimulationManager.instance.m_metaData.m_environment = "Sunny";
                isWinter = false;
            }

            List <KeyValuePair <string, float> > levels = new List <KeyValuePair <string, float> >(18);
            string scene = (string)Util.Invoke(LoadingManager.instance, "GetLoadingScene");

            if (!string.IsNullOrEmpty(scene))
            {
                levels.Add(new KeyValuePair <string, float>(scene, 0.015f));
            }

            levels.Add(new KeyValuePair <string, float>(SimulationManager.instance.m_metaData.m_environment + "Prefabs", 0.12f));

            if ((bool)Util.Invoke(LoadingManager.instance, "LoginUsed"))
            {
                levels.Add(new KeyValuePair <string, float>(isWinter ? "WinterLoginPackPrefabs" : "LoginPackPrefabs", 0.121f));
            }

            levels.Add(new KeyValuePair <string, float>(isWinter ? "WinterPreorderPackPrefabs" : "PreorderPackPrefabs", 0.122f));
            levels.Add(new KeyValuePair <string, float>(isWinter ? "WinterSignupPackPrefabs" : "SignupPackPrefabs", 0.123f));

            if (Check(346791))
            {
                levels.Add(new KeyValuePair <string, float>("DeluxePackPrefabs", 0.124f));
            }

            if (PlatformService.IsAppOwned(238370u))
            {
                levels.Add(new KeyValuePair <string, float>("MagickaPackPrefabs", 0.125f));
            }

            if (LoadingManager.instance.m_supportsExpansion[0])
            {
                levels.Add(new KeyValuePair <string, float>(isWinter ? "WinterExpansion1Prefabs" : "Expansion1Prefabs", 0.126f));
            }

            if (LoadingManager.instance.m_supportsExpansion[1])
            {
                levels.Add(new KeyValuePair <string, float>("Expansion2Prefabs", 0.127f));
            }

            if (LoadingManager.instance.m_supportsExpansion[2])
            {
                levels.Add(new KeyValuePair <string, float>("Expansion3Prefabs", 0.128f));
            }

            if (LoadingManager.instance.m_supportsExpansion[3])
            {
                levels.Add(new KeyValuePair <string, float>("Expansion4Prefabs", 0.129f));
            }

            if (LoadingManager.instance.m_supportsExpansion[4])
            {
                levels.Add(new KeyValuePair <string, float>(isWinter ? "WinterExpansion5Prefabs" : "Expansion5Prefabs", 0.131f));
            }

            if (LoadingManager.instance.m_supportsExpansion[5])
            {
                levels.Add(new KeyValuePair <string, float>(SimulationManager.instance.m_metaData.m_environment + "Expansion6Prefabs", 0.132f));
            }

            if (LoadingManager.instance.m_supportsExpansion[6])
            {
                levels.Add(new KeyValuePair <string, float>(isWinter ? "WinterExpansion7Prefabs" : "Expansion7Prefabs", 0.133f));
            }

            if (LoadingManager.instance.m_supportsExpansion[7])
            {
                levels.Add(new KeyValuePair <string, float>(isWinter ? "WinterExpansion8Prefabs" : "Expansion8Prefabs", 0.1f));
            }

            if (LoadingManager.instance.m_supportsExpansion[8])
            {
                levels.Add(new KeyValuePair <string, float>(isWinter ? "WinterExpansion9Prefabs" : "Expansion9Prefabs", 0.11f));
            }

            for (int i = 0; i < levelStrings.Length; i++)
            {
                if (Check(levelStrings[i].Value))
                {
                    levels.Add(new KeyValuePair <string, float>(levelStrings[i].Key, 0.134f + i * 0.01f / levelStrings.Length));
                }
            }

            if (Check(715190))
            {
                Package.Asset asset = PackageManager.FindAssetByName("System." + DistrictStyle.kEuropeanSuburbiaStyleName);

                if (asset != null && asset.isEnabled)
                {
                    levels.Add(new KeyValuePair <string, float>("ModderPack3Prefabs", 0.144f));
                }
            }

            if (Check(563850))
            {
                levels.Add(new KeyValuePair <string, float>("ChinaPackPrefabs", 0.145f));
            }

            Package.Asset europeanStyles = PackageManager.FindAssetByName("System." + DistrictStyle.kEuropeanStyleName);

            if (europeanStyles != null && europeanStyles.isEnabled)
            {
                levels.Add(new KeyValuePair <string, float>(SimulationManager.instance.m_metaData.m_environment.Equals("Europe") ? "EuropeNormalPrefabs" : "EuropeStylePrefabs", 0.15f));
            }

            return(levels.ToArray());
        }
Exemple #4
0
        public IEnumerator LoadLevelCoroutine(Package.Asset asset, string playerScene, string uiScene, SimulationMetaData ngs, bool forceEnvironmentReload)
        {
            string scene;
            int    i;

            yield return(null);

            try
            {
                Util.InvokeVoid(LoadingManager.instance, "PreLoadLevel");
            }
            catch (Exception e)
            {
                Util.DebugPrint("PreLoadLevel: exception from some mod.");
                UnityEngine.Debug.LogException(e);
            }

            if (!LoadingManager.instance.LoadingAnimationComponent.AnimationLoaded)
            {
                LoadingManager.instance.m_loadingProfilerScenes.BeginLoading("LoadingAnimation");
                yield return(SceneManager.LoadSceneAsync("LoadingAnimation", LoadSceneMode.Additive));

                LoadingManager.instance.m_loadingProfilerScenes.EndLoading();
            }

            DateTime  skipStamp = Settings.settings.LoadSkipFile();
            AsyncTask task      = Singleton <SimulationManager> .instance.AddAction("Loading", (IEnumerator)Util.Invoke(LoadingManager.instance, "LoadSimulationData", asset, ngs));

            LoadSaveStatus.activeTask = task;

            if (LoadingManager.instance.m_loadedEnvironment == null) // loading from main menu
            {
                fastLoad = false;
            }
            else // loading from in-game (the pause menu)
            {
                while (!LoadingManager.instance.m_metaDataLoaded && !task.completedOrFailed) // IL_139
                {
                    yield return(null);
                }

                if (SimulationManager.instance.m_metaData == null)
                {
                    SimulationManager.instance.m_metaData = new SimulationMetaData();
                    SimulationManager.instance.m_metaData.m_environment = "Sunny";
                    SimulationManager.instance.m_metaData.Merge(ngs);
                }

                Util.InvokeVoid(LoadingManager.instance, "MetaDataLoaded"); // No OnCreated
                string mapThemeName = SimulationManager.instance.m_metaData.m_MapThemeMetaData?.name;
                fastLoad = SimulationManager.instance.m_metaData.m_environment == LoadingManager.instance.m_loadedEnvironment &&
                           mapThemeName == LoadingManager.instance.m_loadedMapTheme && !forceEnvironmentReload;

                // The game is nicely optimized when loading from the pause menu. We must specifically address the following situations:
                // - environment (biome) stays the same
                // - map theme stays the same
                // - forceEnvironmentReload is false
                // - 'load used assets' is enabled
                // - not all assets and prefabs used in the save being loaded are currently in memory
                // - prefab skipping has changed.

                if (fastLoad)
                {
                    // Check custom asset availability.
                    if (Settings.settings.loadUsed && !IsKnownFastLoad(asset))
                    {
                        while (!IsSaveDeserialized())
                        {
                            yield return(null);
                        }

                        fastLoad = AllAssetsAvailable();
                    }

                    // Check building prefab availability.
                    if (fastLoad)
                    {
                        if (skipStamp != savedSkipStamp)
                        {
                            fastLoad = false;
                        }
                        else if (Settings.settings.SkipPrefabs && !IsKnownFastLoad(asset))
                        {
                            while (!IsSaveDeserialized())
                            {
                                yield return(null);
                            }

                            fastLoad = AllPrefabsAvailable();
                        }
                    }

                    if (fastLoad) // optimized load
                    {
                        if (Settings.settings.SkipPrefabs && skippedPrefabs[0] != null)
                        {
                            while (!IsSaveDeserialized())
                            {
                                yield return(null);
                            }

                            PrefabLoader.Create().SetSkippedPrefabs(skippedPrefabs);
                            LoadingManager.instance.QueueLoadingAction(PrefabLoader.RemoveSkippedFromSimulation());
                        }

                        LoadingManager.instance.QueueLoadingAction((IEnumerator)Util.Invoke(LoadingManager.instance, "EssentialScenesLoaded"));
                        LoadingManager.instance.QueueLoadingAction((IEnumerator)Util.Invoke(LoadingManager.instance, "RenderDataReady"));
                        Util.DebugPrint("fast load at", Profiling.Millis);
                    }
                    else // fallback to full load
                    {
                        DestroyLoadedPrefabs();
                        LoadingManager.instance.m_loadedEnvironment = null;
                        LoadingManager.instance.m_loadedMapTheme    = null;
                        Util.DebugPrint("fallback to full load at", Profiling.Millis);
                    }
                }
                else // full load
                {
                    // Notice that there is a race condition in the base game at this point: DestroyAllPrefabs ruins the simulation
                    // if its deserialization has progressed far enough. Typically there is no problem.
                    Util.InvokeVoid(LoadingManager.instance, "DestroyAllPrefabs");
                    LoadingManager.instance.m_loadedEnvironment = null;
                    LoadingManager.instance.m_loadedMapTheme    = null;
                    Util.DebugPrint("full load at", Profiling.Millis);
                }
            }

            // Full load.
            if (LoadingManager.instance.m_loadedEnvironment == null) // IL_27C
            {
                AsyncOperation op;
                Reset();
                fullLoadTime   = DateTime.Now;
                savedSkipStamp = skipStamp;
                Array.Clear(skippedPrefabs, 0, skippedPrefabs.Length);
                loadingLock     = Util.Get(LoadingManager.instance, "m_loadingLock");
                mainThreadQueue = (Queue <IEnumerator>)Util.Get(LoadingManager.instance, "m_mainThreadQueue");

                if (!string.IsNullOrEmpty(playerScene))
                {
                    LoadingManager.instance.m_loadingProfilerScenes.BeginLoading(playerScene);
                    op = SceneManager.LoadSceneAsync(playerScene, LoadSceneMode.Single);

                    while (!op.isDone) // IL_2FF
                    {
                        LoadingManager.instance.SetSceneProgress(op.progress * 0.01f);
                        yield return(null);
                    }

                    LoadingManager.instance.m_loadingProfilerScenes.EndLoading();
                }

                while (!LoadingManager.instance.m_metaDataLoaded && !task.completedOrFailed) // IL_33C
                {
                    yield return(null);
                }

                if (SimulationManager.instance.m_metaData == null)
                {
                    SimulationManager.instance.m_metaData = new SimulationMetaData();
                    SimulationManager.instance.m_metaData.m_environment = "Sunny";
                    SimulationManager.instance.m_metaData.Merge(ngs);
                }

                try
                {
                    Util.InvokeVoid(LoadingManager.instance, "MetaDataLoaded"); // OnCreated if loading from the main manu
                }
                catch (Exception e)
                {
                    Util.DebugPrint("OnCreated: exception from some mod.");
                    UnityEngine.Debug.LogException(e);
                }

                KeyValuePair <string, float>[] levels = SetLevels();
                float currentProgress = 0.10f;

                for (i = 0; i < levels.Length; i++)
                {
                    scene = levels[i].Key;
                    LoadingManager.instance.m_loadingProfilerScenes.BeginLoading(scene);
                    op = SceneManager.LoadSceneAsync(scene, LoadSceneMode.Additive);

                    while (!op.isDone)
                    {
                        LoadingManager.instance.SetSceneProgress(currentProgress + op.progress * (levels[i].Value - currentProgress));
                        yield return(null);
                    }

                    LoadingManager.instance.m_loadingProfilerScenes.EndLoading();
                    currentProgress = levels[i].Value;
                }

                PrefabLoader.instance?.Revert();

                if (Settings.settings.SkipPrefabs)
                {
                    LoadingManager.instance.QueueLoadingAction(PrefabLoader.RemoveSkippedFromSimulation());
                }

                // Some major mods (Network Extensions 1 & 2, Single Train Track, Metro Overhaul) have a race condition issue
                // in their NetInfo Installer. Everything goes fine if LoadCustomContent() below is NOT queued before the
                // said Installers have finished. This is just a workaround for the issue. The actual fix should be in
                // the Installers. Notice that the built-in loader of the game is also affected.

                do
                {
                    yield return(null);

                    yield return(null);

                    lock (loadingLock)
                    {
                        i = mainThreadQueue.Count;
                    }
                }while (i > 0);

                AssetLoader.Create().Setup();
                LoadingManager.instance.QueueLoadingAction(AssetLoader.instance.LoadCustomContent());
                RenderManager.Managers_CheckReferences();
                LoadingManager.instance.QueueLoadingAction((IEnumerator)Util.Invoke(LoadingManager.instance, "EssentialScenesLoaded"));
                RenderManager.Managers_InitRenderData();
                LoadingManager.instance.QueueLoadingAction((IEnumerator)Util.Invoke(LoadingManager.instance, "RenderDataReady"));
                simulationFailed = HasFailed(task);

                // Performance optimization: do not load scenes while custom assets are loading.
                while (!assetsFinished)
                {
                    yield return(null);
                }

                scene = SimulationManager.instance.m_metaData.m_environment + "Properties";

                if (!string.IsNullOrEmpty(scene))
                {
                    LoadingManager.instance.m_loadingProfilerScenes.BeginLoading(scene);
                    op = SceneManager.LoadSceneAsync(scene, LoadSceneMode.Additive);

                    while (!op.isDone) // IL_C47
                    {
                        LoadingManager.instance.SetSceneProgress(0.85f + op.progress * 0.05f);
                        yield return(null);
                    }

                    LoadingManager.instance.m_loadingProfilerScenes.EndLoading();
                }

                if (!simulationFailed)
                {
                    simulationFailed = HasFailed(task);
                }

                if (!string.IsNullOrEmpty(uiScene)) // IL_C67
                {
                    LoadingManager.instance.m_loadingProfilerScenes.BeginLoading(uiScene);
                    op = SceneManager.LoadSceneAsync(uiScene, LoadSceneMode.Additive);

                    while (!op.isDone) // IL_CDE
                    {
                        LoadingManager.instance.SetSceneProgress(0.90f + op.progress * 0.08f);
                        yield return(null);
                    }

                    LoadingManager.instance.m_loadingProfilerScenes.EndLoading();
                }

                LoadingManager.instance.m_loadedEnvironment = SimulationManager.instance.m_metaData.m_environment; // IL_CFE
                LoadingManager.instance.m_loadedMapTheme    = SimulationManager.instance.m_metaData.m_MapThemeMetaData?.name;
            }
            else
            {
                scene = (string)Util.Invoke(LoadingManager.instance, "GetLoadingScene");

                if (!string.IsNullOrEmpty(scene))
                {
                    LoadingManager.instance.m_loadingProfilerScenes.BeginLoading(scene);
                    yield return(SceneManager.LoadSceneAsync(scene, LoadSceneMode.Additive));

                    LoadingManager.instance.m_loadingProfilerScenes.EndLoading();
                }
            }

            LoadingManager.instance.SetSceneProgress(1f); // IL_DBF

            if (!simulationFailed)
            {
                simulationFailed = HasFailed(task);
            }

            while (!task.completedOrFailed) // IL_DED
            {
                yield return(null);
            }

            LoadingManager.instance.m_simulationDataLoaded = LoadingManager.instance.m_metaDataLoaded;
            LoadingManager.SimulationDataReadyHandler SimDataReady = Util.Get(LoadingManager.instance, "m_simulationDataReady") as LoadingManager.SimulationDataReadyHandler;
            SimDataReady?.Invoke();
            SimulationManager.UpdateMode mode = SimulationManager.UpdateMode.Undefined;

            if (ngs != null)
            {
                mode = ngs.m_updateMode;
            }

            LoadingManager.instance.QueueLoadingAction(CheckPolicies());
            LoadingManager.instance.QueueLoadingAction((IEnumerator)Util.Invoke(LoadingManager.instance, "LoadLevelComplete", mode));  // OnLevelLoaded
            PrefabLoader.instance?.Dispose();
            LoadingManager.instance.QueueLoadingAction(LoadingComplete());
            knownFastLoads[asset.checksum] = true;
            AssetLoader.PrintMem();
        }
Exemple #5
0
        public IEnumerator LoadCustomContent()
        {
            LoadingManager.instance.m_loadingProfilerMain.BeginLoading("LoadCustomContent");
            LoadingManager.instance.m_loadingProfilerCustomContent.Reset();
            LoadingManager.instance.m_loadingProfilerCustomAsset.Reset();
            LoadingManager.instance.m_loadingProfilerCustomContent.BeginLoading("District Styles");
            LoadingManager.instance.m_loadingProfilerCustomAsset.PauseLoading();
            LevelLoader.instance.assetsStarted = true;

            int                              i, j;
            DistrictStyle                    districtStyle;
            DistrictStyleMetaData            districtStyleMetaData;
            List <DistrictStyle>             districtStyles         = new List <DistrictStyle>();
            HashSet <string>                 styleBuildings         = new HashSet <string>();
            FastList <DistrictStyleMetaData> districtStyleMetaDatas = new FastList <DistrictStyleMetaData>();
            FastList <Package>               districtStylePackages  = new FastList <Package>();

            Package.Asset europeanStyles = PackageManager.FindAssetByName("System." + DistrictStyle.kEuropeanStyleName);

            if (europeanStyles != null && europeanStyles.isEnabled)
            {
                districtStyle = new DistrictStyle(DistrictStyle.kEuropeanStyleName, true);
                Util.InvokeVoid(LoadingManager.instance, "AddChildrenToBuiltinStyle", GameObject.Find("European Style new"), districtStyle, false);
                Util.InvokeVoid(LoadingManager.instance, "AddChildrenToBuiltinStyle", GameObject.Find("European Style others"), districtStyle, true);

                if (Settings.settings.SkipPrefabs)
                {
                    PrefabLoader.RemoveSkippedFromStyle(districtStyle);
                }

                districtStyles.Add(districtStyle);
            }

            if ((bool)typeof(LoadingManager).GetMethod("DLC", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(LoadingManager.instance, new object[] { 715190u }))
            {
                Package.Asset asset = PackageManager.FindAssetByName("System." + DistrictStyle.kEuropeanSuburbiaStyleName);

                if (asset != null && asset.isEnabled)
                {
                    districtStyle = new DistrictStyle(DistrictStyle.kEuropeanSuburbiaStyleName, true);
                    Util.InvokeVoid(LoadingManager.instance, "AddChildrenToBuiltinStyle", GameObject.Find("Modder Pack 3"), districtStyle, false);

                    if (Settings.settings.SkipPrefabs)
                    {
                        PrefabLoader.RemoveSkippedFromStyle(districtStyle);
                    }

                    districtStyles.Add(districtStyle);
                }
            }

            if (Settings.settings.SkipPrefabs)
            {
                PrefabLoader.UnloadSkipped();
            }

            foreach (Package.Asset asset in PackageManager.FilterAssets(UserAssetType.DistrictStyleMetaData))
            {
                try
                {
                    if (asset != null && asset.isEnabled)
                    {
                        districtStyleMetaData = asset.Instantiate <DistrictStyleMetaData>();

                        if (districtStyleMetaData != null && !districtStyleMetaData.builtin)
                        {
                            districtStyleMetaDatas.Add(districtStyleMetaData);
                            districtStylePackages.Add(asset.package);

                            if (districtStyleMetaData.assets != null)
                            {
                                for (i = 0; i < districtStyleMetaData.assets.Length; i++)
                                {
                                    styleBuildings.Add(districtStyleMetaData.assets[i]);
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    CODebugBase <LogChannel> .Warn(LogChannel.Modding, string.Concat(new object[] { ex.GetType(), ": Loading custom district style failed[", asset, "]\n", ex.Message }));
                }
            }

            LoadingManager.instance.m_loadingProfilerCustomAsset.ContinueLoading();
            LoadingManager.instance.m_loadingProfilerCustomContent.EndLoading();

            if (Settings.settings.loadUsed)
            {
                UsedAssets.Create();
            }

            lastMillis = Profiling.Millis;
            LoadingScreen.instance.DualSource.Add("Custom Assets");
            LoadingManager.instance.m_loadingProfilerCustomContent.BeginLoading("Calculating asset load order");
            Package.Asset[] queue = GetLoadQueue(styleBuildings);
            Util.DebugPrint("LoadQueue", queue.Length, Profiling.Millis);
            LoadingManager.instance.m_loadingProfilerCustomContent.EndLoading();
            plugins = (Dictionary <string, PluginInfo>)Util.Get(Singleton <PluginManager> .instance, "m_Plugins");
            //PrintPlugins();

            LoadingManager.instance.m_loadingProfilerCustomContent.BeginLoading("Loading Custom Assets");
            Sharing.instance.Start(queue);
            beginMillis = Profiling.Millis;

            for (i = 0; i < queue.Length; i++)
            {
                Package.Asset assetRef = queue[i];

                if ((i & 63) == 0)
                {
                    PrintMem(i);
                }

                Sharing.instance.WaitForWorkers();

                try
                {
                    stack.Clear();
                    LoadImpl(assetRef);
                }
                catch (Exception e)
                {
                    AssetFailed(assetRef, assetRef.package, e);
                }

                Sharing.instance.ManageLoadQueue(i);

                if (Profiling.Millis - lastMillis > yieldInterval)
                {
                    lastMillis = Profiling.Millis;
                    progress   = 0.15f + (i + 1) * 0.7f / queue.Length;
                    LoadingScreen.instance.SetProgress(progress, progress, assetCount, assetCount - i - 1 + queue.Length, beginMillis, lastMillis);
                    yield return(null);
                }
            }

            lastMillis = Profiling.Millis;
            LoadingScreen.instance.SetProgress(0.85f, 1f, assetCount, assetCount, beginMillis, lastMillis);
            LoadingManager.instance.m_loadingProfilerCustomContent.EndLoading();
            Util.DebugPrint("Custom assets loaded in", lastMillis - beginMillis);
            PrintMem();
            queue = null;
            stack.Clear();
            Report();

            LoadingManager.instance.m_loadingProfilerCustomContent.BeginLoading("Finalizing District Styles");
            LoadingManager.instance.m_loadingProfilerCustomAsset.PauseLoading();

            for (i = 0; i < districtStyleMetaDatas.m_size; i++)
            {
                try
                {
                    districtStyleMetaData = districtStyleMetaDatas.m_buffer[i];
                    districtStyle         = new DistrictStyle(districtStyleMetaData.name, false);

                    if (districtStylePackages.m_buffer[i].GetPublishedFileID() != PublishedFileId.invalid)
                    {
                        districtStyle.PackageName = districtStylePackages.m_buffer[i].packageName;
                    }

                    if (districtStyleMetaData.assets != null)
                    {
                        for (j = 0; j < districtStyleMetaData.assets.Length; j++)
                        {
                            BuildingInfo bi = CustomDeserializer.FindLoaded <BuildingInfo>(districtStyleMetaData.assets[j] + "_Data");

                            if (bi != null)
                            {
                                districtStyle.Add(bi);

                                if (districtStyleMetaData.builtin) // this is always false
                                {
                                    bi.m_dontSpawnNormally = !districtStyleMetaData.assetRef.isEnabled;
                                }
                            }
                            else
                            {
                                CODebugBase <LogChannel> .Warn(LogChannel.Modding, "Warning: Missing asset (" + districtStyleMetaData.assets[j] + ") in style " + districtStyleMetaData.name);
                            }
                        }

                        districtStyles.Add(districtStyle);
                    }
                }
                catch (Exception ex)
                {
                    CODebugBase <LogChannel> .Warn(LogChannel.Modding, ex.GetType() + ": Loading district style failed\n" + ex.Message);
                }
            }

            Singleton <DistrictManager> .instance.m_Styles = districtStyles.ToArray();

            if (Singleton <BuildingManager> .exists)
            {
                Singleton <BuildingManager> .instance.InitializeStyleArray(districtStyles.Count);
            }

            LoadingManager.instance.m_loadingProfilerCustomAsset.ContinueLoading();
            LoadingManager.instance.m_loadingProfilerCustomContent.EndLoading();
            LoadingManager.instance.m_loadingProfilerMain.EndLoading();
            LevelLoader.instance.assetsFinished = true;
        }