/// <summary> /// Called by the game when level loading is complete. /// </summary> /// <param name="mode">Loading mode (e.g. game, editor, scenario, etc.)</param> public override void OnLevelLoaded(LoadMode mode) { base.OnLevelLoaded(mode); // Check to see that Harmony 2 was properly loaded. if (!Patcher.Patched) { // Harmony 2 wasn't loaded. Logging.Error("Harmony patches not applied; aborting"); // Display warning message. ListMessageBox harmonyBox = MessageBoxBase.ShowModal <ListMessageBox>(); // Key text items. harmonyBox.AddParas(Translations.Translate("ERR_HAR0"), Translations.Translate("ZAM_ERR_HAR"), Translations.Translate("ZAM_ERR_FAT"), Translations.Translate("ERR_HAR1")); // List of dot points. harmonyBox.AddList(Translations.Translate("ERR_HAR2"), Translations.Translate("ERR_HAR3")); // Closing para. harmonyBox.AddParas(Translations.Translate("MES_PAGE")); // Don't do anything further. return; } }
/// <summary> /// Called by the game when level loading is complete. /// </summary> /// <param name="mode">Loading mode (e.g. game, editor, scenario, etc.)</param> public override void OnLevelLoaded(LoadMode mode) { // Check to see that Harmony 2 was properly loaded. if (!harmonyLoaded) { // Harmony 2 wasn't loaded; display warning notification and exit. ListMessageBox harmonyBox = MessageBoxBase.ShowModal <ListMessageBox>(); // Key text items. harmonyBox.AddParas(Translations.Translate("ERR_HAR0"), Translations.Translate("ABLC_ERR_HAR"), Translations.Translate("ABLC_ERR_FAT"), Translations.Translate("ERR_HAR1")); // List of dot points. harmonyBox.AddList(Translations.Translate("ERR_HAR2"), Translations.Translate("ERR_HAR3")); // Closing para. harmonyBox.AddParas(Translations.Translate("MES_PAGE")); // Exit. return; } // Check to see if a conflicting mod has been detected. if (conflictingMod) { // Mod conflict detected - display warning notification and exit. ListMessageBox modConflictBox = MessageBoxBase.ShowModal <ListMessageBox>(); // Key text items. modConflictBox.AddParas(Translations.Translate("ERR_CON0"), Translations.Translate("ABLC_ERR_FAT"), Translations.Translate("ABLC_ERR_CON0"), Translations.Translate("ERR_CON1")); // Add conflicting mod name(s). modConflictBox.AddList(ModUtils.conflictingModNames.ToArray()); // Closing para. modConflictBox.AddParas(Translations.Translate("ABLC_ERR_CON1")); // Exit. return; } // Load mod if it's enabled. if (isModEnabled) { // Check for Ploppable RICO Revisited. ModUtils.RICOReflection(); // Hook info panel events. DistrictPanelManager.Hook(); BuildingPanelManager.Hook(); // Add building info panel button. BuildingPanelManager.AddInfoPanelButton(); } }
/// <summary> /// Called by the game when level loading is complete. /// </summary> /// <param name="mode">Loading mode (e.g. game, editor, scenario, etc.)</param> public override void OnLevelLoaded(LoadMode mode) { base.OnLevelLoaded(mode); // Check watchdog flag. if (!patchOperating) { // Patch wasn't operating; display harmony error and abort. harmonyLoaded = false; isModEnabled = false; } // Check to see that Harmony 2 was properly loaded. if (!harmonyLoaded) { // Harmony 2 wasn't loaded; display warning notification and exit. ListMessageBox harmonyBox = MessageBoxBase.ShowModal <ListMessageBox>(); // Key text items. harmonyBox.AddParas(Translations.Translate("ERR_HAR0"), Translations.Translate("PRR_ERR_HAR"), Translations.Translate("PRR_ERR_FAT"), Translations.Translate("ERR_HAR1")); // List of dot points. harmonyBox.AddList(Translations.Translate("ERR_HAR2"), Translations.Translate("ERR_HAR3")); // Closing para. harmonyBox.AddParas(Translations.Translate("MES_PAGE")); } // Check to see if a conflicting mod has been detected. if (conflictingMod) { // Mod conflict detected - display warning notification and exit. ListMessageBox modConflictBox = MessageBoxBase.ShowModal <ListMessageBox>(); // Key text items. modConflictBox.AddParas(Translations.Translate("ERR_CON0"), Translations.Translate("PRR_ERR_CON0"), Translations.Translate("PRR_ERR_FAT"), Translations.Translate("ERR_CON1")); // Add conflicting mod name(s). modConflictBox.AddList(ModUtils.conflictingModNames.ToArray()); // Closing para. modConflictBox.AddParas(Translations.Translate("PRR_ERR_CON1")); } }
/// <summary> /// Called by the game when level loading is complete. /// </summary> /// <param name="mode">Loading mode (e.g. game, editor, scenario, etc.)</param> public override void OnLevelLoaded(LoadMode mode) { base.OnLevelLoaded(mode); // Check to see that Harmony 2 was properly loaded. if (!harmonyLoaded) { // Harmony 2 wasn't loaded; display warning notification and exit. ListMessageBox harmonyBox = MessageBoxBase.ShowModal <ListMessageBox>(); // Key text items. harmonyBox.AddParas(Translations.Translate("ERR_HAR0"), Translations.Translate("RPR_ERR_HAR"), Translations.Translate("RPR_ERR_FAT"), Translations.Translate("ERR_HAR1")); // List of dot points. harmonyBox.AddList(Translations.Translate("ERR_HAR2"), Translations.Translate("ERR_HAR3")); // Closing para. harmonyBox.AddParas(Translations.Translate("MES_PAGE")); } // Check to see if a conflicting mod has been detected. if (conflictingMod) { // Mod conflict detected - display warning notification and exit. ListMessageBox modConflictBox = MessageBoxBase.ShowModal <ListMessageBox>(); // Key text items. modConflictBox.AddParas(Translations.Translate("ERR_CON0"), Translations.Translate("RPR_ERR_CON0"), Translations.Translate("RPR_ERR_FAT"), Translations.Translate("ERR_CON1")); // Add conflicting mod name(s). modConflictBox.AddList(ModUtils.conflictingModNames.ToArray()); // Closing para. modConflictBox.AddParas(Translations.Translate("RPR_ERR_CON1")); } // Don't do anything further if mod hasn't activated for whatever reason (mod conflict, harmony error, something else). if (!isModEnabled) { // Disable keystrokes. UIThreading.operating = false; return; } // Show legacy choice message box if this save hasn't been flagged as being from Realistic Population 2. if (!ModSettings.isRealPop2Save) { MessageBoxBase.ShowModal <LegacyChoiceMessageBox>(); } // Record initial (default) school settings and apply ours over the top. SchoolData.instance.OnLoad(); // IF a legacy file exists, flag it for writing. if (File.Exists(DataStore.currentFileLocation)) { Logging.KeyMessage("found legacy settings file"); XMLUtilsWG.writeToLegacy = true; } // Add button to building info panels. BuildingDetailsPanel.AddInfoPanelButton(); Logging.KeyMessage("loading complete"); // Display update notification. WhatsNew.ShowWhatsNew(); // Set up options panel event handler. OptionsPanel.OptionsEventHook(); // Check and record CitizenUnits count. Logging.KeyMessage("citizen unit count is currently ", ColossalFramework.Singleton <CitizenManager> .instance.m_unitCount.ToString()); }
/// <summary> /// Called by the game when level loading is complete. /// </summary> /// <param name="mode">Loading mode (e.g. game, editor, scenario, etc.)</param> public override void OnLevelLoaded(LoadMode mode) { Logging.Message("commencing loading checks"); base.OnLevelLoaded(mode); // Don't do anything further if we're not operating. if (!isModEnabled) { Logging.Message("exiting"); return; } // Check to see that Harmony 2 was properly loaded. if (!Patcher.Patched) { // Harmony 2 wasn't loaded; abort. Logging.Error("Harmony patches not applied; aborting"); isModEnabled = false; // Display warning message. ListMessageBox harmonyBox = MessageBoxBase.ShowModal <ListMessageBox>(); // Key text items. harmonyBox.AddParas(Translations.Translate("ERR_HAR0"), Translations.Translate("BOB_ERR_HAR"), Translations.Translate("BOB_ERR_FAT"), Translations.Translate("ERR_HAR1")); // List of dot points. harmonyBox.AddList(Translations.Translate("ERR_HAR2"), Translations.Translate("ERR_HAR3")); // Closing para. harmonyBox.AddParas(Translations.Translate("MES_PAGE")); // Don't do anything further. return; } Logging.Message("loading checks passed"); // Build lists of loaded prefabs. PrefabLists.BuildLists(); // Load prop packs. new NetworkPackReplacement(); // Load configuration file. ConfigurationUtils.LoadConfig(); // Set up BOB tool. ToolsModifierControl.toolController.gameObject.AddComponent <BOBTool>(); // Display update notification. WhatsNew.ShowWhatsNew(); // Set up Network Skins 2 reflection. ModUtils.NS2Reflection(); // Enable thin wires, if applicable. if (ModSettings.ThinnerWires) { ElectricalWires.Instance.ApplyThinnerWires(); } // Force update of any dirty net or building prefabs from replacement process. Logging.Message("updating dirty prefabs"); BuildingData.Update(); NetData.Update(); // Set up options panel event handler. OptionsPanel.OptionsEventHook(); // Display any exception message that occured during load. InfoPanelManager.CheckException(); // Activate tool hotkey. UIThreading.Operating = true; Logging.Message("loading complete"); }
/// <summary> /// Called by the game when level loading is complete. /// </summary> /// <param name="mode">Loading mode (e.g. game, editor, scenario, etc.)</param> public override void OnLevelLoaded(LoadMode mode) { base.OnLevelLoaded(mode); // Check to see if a conflicting mod has been detected. if (conflictingMod) { // Mod conflict detected - display warning notification and exit. ListMessageBox modConflictBox = MessageBoxBase.ShowModal <ListMessageBox>(); // Key text items. modConflictBox.AddParas(Translations.Translate("ERR_CON0"), Translations.Translate("LBR_ERR_FAT"), Translations.Translate("LBR_ERR_CON0"), Translations.Translate("ERR_CON1")); // Add conflicting mod name(s). modConflictBox.AddList(ModUtils.conflictingModNames.ToArray()); // Closing para. modConflictBox.AddParas(Translations.Translate("LBR_ERR_CON1")); } // Don't do anything if we're not enabled or we've already been here. if (isModEnabled && !isModCreated) { // Wait for Harmony if it hasn't already happened. //if (!Patcher.patched) { // Set timeout counter, just in case. DateTime startTime = DateTime.Now; try { Logging.Message("waiting for Harmony"); while (!Patcher.patched) { if (CitiesHarmony.API.HarmonyHelper.IsHarmonyInstalled) { Patcher.PatchAll(); break; } // Three minutes should be sufficient wait. if (DateTime.Now > startTime.AddMinutes(3)) { throw new TimeoutException("Harmony loading timeout: " + startTime.ToString() + " : " + DateTime.Now.ToString()); } } } catch (Exception e) { Logging.LogException(e, "Harmony loading exception"); // Harmony 2 wasn't loaded; display warning notification and exit. ListMessageBox harmonyBox = MessageBoxBase.ShowModal <ListMessageBox>(); // Key text items. harmonyBox.AddParas(Translations.Translate("ERR_HAR0"), Translations.Translate("LBR_ERR_HAR"), Translations.Translate("LBR_ERR_FAT"), Translations.Translate("ERR_HAR1")); // List of dot points. harmonyBox.AddList(Translations.Translate("ERR_HAR2"), Translations.Translate("ERR_HAR3")); // Closing para. harmonyBox.AddParas(Translations.Translate("MES_PAGE")); } } Logging.Message("Harmony ready, proceeding"); // Set flag. isModCreated = true; // Load and apply mod settings (configuration file loaded above). settingsFile = Configuration <SettingsFile> .Load(); ModSettings.VanillaCalcs = settingsFile.UseVanilla; ModSettings.LegacyCalcs = settingsFile.UseLegacy; ModSettings.CustomRetirement = settingsFile.CustomRetirement; ModSettings.RetirementYear = settingsFile.RetirementYear; ModSettings.UseTransportModes = settingsFile.UseTransportModes; ModSettings.randomImmigrantEd = settingsFile.RandomImmigrantEd; Logging.UseDeathLog = settingsFile.LogDeaths; Logging.UseImmigrationLog = settingsFile.LogImmigrants; Logging.UseTransportLog = settingsFile.LogTransport; Logging.UseSicknessLog = settingsFile.LogSickness; // Apply sickness probabilities. CalculateSicknessProbabilities(); // Report status. Logging.Message("death logging ", Logging.UseDeathLog ? "enabled" : "disabled", ", immigration logging ", Logging.UseImmigrationLog ? "enabled" : "disabled", ", transportation logging ", Logging.UseTransportLog ? "enabled" : "disabled"); // Prime Threading.counter to continue from frame index. int temp = (int)(Singleton <SimulationManager> .instance.m_currentFrameIndex / 4096u); Threading.counter = temp % DataStore.lifeSpanMultiplier; try { WG_XMLBaseVersion xml = new XML_VersionTwo(); xml.WriteXML(currentFileLocation); } catch (Exception e) { Logging.LogException(e, "XML configuration file error"); } // Set up options panel event handler. OptionsPanel.OptionsEventHook(); Logging.KeyMessage("successfully loaded"); // Display update notifications. WhatsNew.ShowWhatsNew(); } }
public static void Run(string[] args, Type applicationType) { // check the endianness if (!BitConverter.IsLittleEndian) { logger.Error("This software assumes a little-endianness OS, your OS uses a big-endian system. Exiting"); return; } // TODO: check if all dependencies exists // TODO: also 32/64 bit (freetype or other dlls) // retrieve the current thread's culture as the initial culture CultureInfo culture = (CultureInfo)Thread.CurrentThread.CurrentCulture.Clone(); // startup argument variables bool nogui = false; bool startupConfigAndInit = false; bool startupStartRun = false; string parameterFile = @""; string source = ""; List <string[]> filters = new List <string[]>(); // See if we are providing a graphical user interface (GUI) // // Note: done seperately because it will detemine whether error messages are // also show as message dialogs, instead of only written to the log file for (int i = 0; i < args.Length; i++) { string argument = args[i].ToLower(); if (argument == "-nogui") { nogui = true; } } // process all startup arguments for (int i = 0; i < args.Length; i++) { string argument = args[i].ToLower(); // check if the configuration and initialization should be done automatically at startup if (argument == "-startupconfigandinit") { startupConfigAndInit = true; } // check if the run should be started automatically at startup if (argument == "-startupstartrun") { startupStartRun = true; } // check if the source is given if (argument == "-source") { // the next element should be the source, try to retrieve if (args.Length >= i + 1 && !string.IsNullOrEmpty(args[i + 1])) { // check if valid source int[] sourceIdx = ArrayHelper.jaggedArrayCompare(args[i + 1], availableSources, null, new int[] { 0 }, true); if (sourceIdx == null) { string errMessage = "Could not find the source module '" + args[i + 1] + "' requested as startup argument), choose one of the following: " + ArrayHelper.jaggedArrayJoin(", ", availableSources, 0); logger.Error(errMessage); if (!nogui) { MessageBox.Show(errMessage, "Requested source module not found", MessageBoxButtons.OK, MessageBoxIcon.Error); } return; } else { // store the source-type as a string source = availableSources[sourceIdx[0]][1]; } } } // check if the parameterfile is given if (argument == "-parameterfile") { // the next element should be the parameter file, try to retrieve if (args.Length >= i + 1 && !string.IsNullOrEmpty(args[i + 1])) { parameterFile = args[i + 1]; } } // check if the language is given if (argument == "-language") { // the next element should contain the culture name if (args.Length >= i + 1 && !string.IsNullOrEmpty(args[i + 1])) { try { // overwrite the culture with the given argument, this will cause the respective language // resource file to be used (unless it does not exists, then it will revert to english) culture = new CultureInfo(args[i + 1]); // message logger.Info("Language/culture set to '" + args[i + 1] + "'"); } catch (Exception) { // with an exception the original culture object is ruined // therefore re(clone) the current culture from the thread culture = (CultureInfo)Thread.CurrentThread.CurrentCulture.Clone(); // message logger.Error("Language argument given but unknown culture, using the local culture (language)"); } } } } // adjust decimal seperator and group seperator culture.NumberFormat.NumberDecimalSeparator = "."; culture.NumberFormat.NumberGroupSeparator = ""; culture.NumberFormat.NumberGroupSizes = new int[] { 0 }; // set the culture for every future thread and the current thread CultureInfo.DefaultThreadCurrentCulture = culture; CultureInfo.DefaultThreadCurrentUICulture = culture; Thread.CurrentThread.CurrentCulture = culture; Thread.CurrentThread.CurrentUICulture = culture; // try to read the pipeline modules (source and filters) from the <AppName>.Config file try { // if no valid source was parsed from a command-line argument, then try to retrieve a valid source from the <appname>.config file KeyValueConfigurationElement appConfigSource = PipelineConfigurationSection.Pipeline.Source; if (string.IsNullOrEmpty(source) && !string.IsNullOrEmpty(appConfigSource.Value)) { int[] sourceIdx = ArrayHelper.jaggedArrayCompare(appConfigSource.Value, availableSources, null, new int[] { 0 }, true); if (sourceIdx != null) { // store the source-type as a string source = availableSources[sourceIdx[0]][1]; } else { string errMessage = "Could not find the source module '" + appConfigSource.Value + "' requested in the <appname>.config file, choose one of the following: " + ArrayHelper.jaggedArrayJoin(", ", availableSources, 0); logger.Error(errMessage); if (!nogui) { MessageBox.Show(errMessage, "Requested source module not found", MessageBoxButtons.OK, MessageBoxIcon.Error); } return; } } // if no valid filters were parsed from a command-line argument, then try to retrieve valid filters from the <appname>.config file List <FilterConfigurationElement> appConfigFilters = PipelineConfigurationSection.Pipeline.Filters.All; if (filters.Count == 0 && appConfigFilters.Count > 0) { for (int iFilter = 0; iFilter < appConfigFilters.Count; iFilter++) { string filterName = appConfigFilters[iFilter].Name; string filterType = appConfigFilters[iFilter].Type; // check if valid filter int[] filterIdx = ArrayHelper.jaggedArrayCompare(filterType, availableFilters, null, new int[] { 0 }, true); if (filterIdx == null) { string errMessage = "A filter-module of the type '" + filterType + "' was requested in the <appname>.config file, but could not be found. The following filter-types are available: " + ArrayHelper.jaggedArrayJoin(", ", availableFilters, 0); logger.Error(errMessage); if (!nogui) { MessageBox.Show(errMessage, "Requested filter module not found", MessageBoxButtons.OK, MessageBoxIcon.Error); } return; } else { // add the filter as a string array with two values (filter-type and filter-name) filters.Add(new string[] { availableFilters[filterIdx[0]][1], filterName }); } } } } catch (Exception e) { string errMessage = "Error while reading the Pipeline config section in the <appname>.config file: " + e.Message; logger.Error(errMessage); if (!nogui) { MessageBox.Show(errMessage, "Error in the <appname>.config file", MessageBoxButtons.OK, MessageBoxIcon.Warning); } } // if no source passed using command-line or <appname>.config file then allow the user to choose a source by popup if (string.IsNullOrEmpty(source)) { source = ListMessageBox.ShowSingle("Source", availableSources); if (string.IsNullOrEmpty(source)) { return; } } // // Setup and initialize Palmtree // // name this thread if (Thread.CurrentThread.Name == null) { Thread.CurrentThread.Name = "Main Thread"; } // create the main (control) object MainThread mainThread = new MainThread(startupConfigAndInit, startupStartRun, nogui); // variable for the GUI interface object GUIMain gui = null; // check if the GUI should be loaded/shown if (!nogui) { // create the GUI interface object gui = new GUIMain(); // create a GUI (as a separate process) // and pass a reference to the experiment for the GUI to pull information from and push commands to the experiment object Thread thread = new Thread(() => { // name this thread if (Thread.CurrentThread.Name == null) { Thread.CurrentThread.Name = "GUI Thread"; } // setup the GUI Application.EnableVisualStyles(); // start and run the GUI //try { Application.Run(gui); //} catch (Exception e) { //logger.Error("Exception in GUI: " + e.Message); //} // message logger.Info("GUI (thread) stopped"); }); thread.SetApartmentState(ApartmentState.STA); thread.Start(); // wait for the GUI to start or a maximum amount of 5 seconds (5.000 / 50 = 100) int waitCounter = 100; while (!gui.isLoaded() && waitCounter > 0) { Thread.Sleep(50); waitCounter--; } } // message versions logger.Info("MainBoot version " + MainBoot.getClassVersion()); logger.Info("MainThread version " + MainThread.getClassVersion()); // message if (Environment.Is64BitProcess) { logger.Debug("Processes are run in a 64 bit environment"); } else { logger.Debug("Processes are run in a 32 bit environment"); } // setup and initialize the pipeline if (mainThread.initPipeline(source, filters, applicationType)) { // check if a parameter file was given to load at startup if (!String.IsNullOrEmpty(parameterFile)) { // load parameter file to the applications parametersets ParameterManager.loadParameterFile(parameterFile, ParameterManager.getParameterSets()); } // continue to run as the main thread mainThread.run(); } else { // on failure string errMessage = "Error while initializing modules, inspect the log for more information"; logger.Error(errMessage); if (!nogui) { gui.modalMessageDelegate(errMessage, "Initialization error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } // check if there is a gui, and close it by delegate if (gui != null) { gui.closeDelegate(); gui = null; Thread.Sleep(100); // allow GUI threads to terminate, before calling Application.Exit() } // stop all the winforms (Informs all message pumps that they must terminate, and then closes all application windows after the messages have been processed.) Application.Exit(); // exit the environment Environment.Exit(0); }
/// <summary> /// Called by the game when level loading is complete. /// </summary> /// <param name="mode">Loading mode (e.g. game, editor, scenario, etc.)</param> public override void OnLevelLoaded(LoadMode mode) { base.OnLevelLoaded(mode); // Check to see that Harmony 2 was properly loaded. if (!Patcher.Patched) { // Harmony 2 wasn't loaded; display warning notification and exit. ListMessageBox harmonyBox = MessageBoxBase.ShowModal <ListMessageBox>(); // Key text items. harmonyBox.AddParas(Translations.Translate("ERR_HAR0"), Translations.Translate("PGC_ERR_HAR"), Translations.Translate("PGC_ERR_FAT"), Translations.Translate("ERR_HAR1")); // List of dot points. harmonyBox.AddList(Translations.Translate("ERR_HAR2"), Translations.Translate("ERR_HAR3")); // Closing para. harmonyBox.AddParas(Translations.Translate("MES_PAGE")); // Don't do anything further. return; } // Was Plop the Growables detected? if (ptgDetected) { // Plop the Growables detected - display warning notification and exit. ListMessageBox modConflictBox = MessageBoxBase.ShowModal <ListMessageBox>(); // Key text items. modConflictBox.AddParas(Translations.Translate("PGC_PTG0"), Translations.Translate("PGC_PTG1"), Translations.Translate("PGC_PTG2")); // Don't do anything further. return; } // Did data read succesfully occur? if (!dataLoaded) { // Mod conflict detected - display warning notification and exit. ListMessageBox modConflictBox = MessageBoxBase.ShowModal <ListMessageBox>(); // Key text items. modConflictBox.AddParas(Translations.Translate("PGC_ERR_DSZ"), Translations.Translate("PGC_ERR_FAT")); // Don't do anything further. return; } // Checks passed - now check to see if we've got Advanced Building Level Control installed and active. ModUtils.ABLCReflection(); if (ModUtils.ablcLockBuildingLevel != null) { // Get building manager. BuildingManager instance = Singleton <BuildingManager> .instance; if (instance == null) { Logging.Error("couldn't get building manager"); return; } // Iterate through each building ID in the list of deserialized PtG IDs. foreach (ushort buildingID in PlopTheGrowables.buildingList) { byte level = instance.m_buildings.m_buffer[buildingID].m_level; Logging.Message("locking building level for building ", buildingID.ToString(), " to ", level.ToString()); ModUtils.ablcLockBuildingLevel.Invoke(null, new object[] { buildingID, level }); } } }