/// <summary> /// Called by the game when the mod is initialised at the start of the loading process. /// </summary> /// <param name="loading">Loading mode (e.g. game, editor, scenario, etc.)</param> public override void OnCreated(ILoading loading) { base.OnCreated(loading); // Don't do anything if not in game (e.g. if we're going into an editor). if (loading.currentMode != AppMode.Game) { isModEnabled = false; Logging.KeyMessage("not loading into game, skipping activation"); // Set harmonyLoaded and PatchOperating flags to suppress Harmony warning when e.g. loading into editor. patchOperating = true; harmonyLoaded = true; // Unload Harmony patches and exit before doing anything further. Patcher.UnpatchAll(); return; } // Ensure that Harmony patches have been applied. harmonyLoaded = Patcher.Patched; if (!harmonyLoaded) { isModEnabled = false; Logging.Error("Harmony patches not applied; aborting"); return; } // Check for mod conflicts. if (ModUtils.IsModConflict()) { // Conflict detected. conflictingMod = true; isModEnabled = false; // Unload Harmony patches and exit before doing anything further. Patcher.UnpatchAll(); return; } // Passed all checks - okay to load (if we haven't already fo some reason). if (!isModEnabled) { isModEnabled = true; Logging.KeyMessage("v " + PloppableRICOMod.Version + " loading"); // Ensure patch watchdog flag is properly initialised. patchOperating = false; // Check for other mods, including any soft conflicts. softModConflct = ModUtils.CheckMods(); // Check for Advanced Building Level Control. ModUtils.ABLCReflection(); // Create instances if they don't already exist. if (convertPrefabs == null) { convertPrefabs = new ConvertPrefabs(); } if (xmlManager == null) { xmlManager = new RICOPrefabManager { prefabHash = new Dictionary <BuildingInfo, BuildingData>(), }; } // Reset broken prefabs list. brokenPrefabs = new List <BuildingInfo>(); // Read any local RICO settings. string ricoDefPath = "LocalRICOSettings.xml"; localRicoDef = null; if (!File.Exists(ricoDefPath)) { Logging.Message("no ", ricoDefPath, " file found"); } else { localRicoDef = RICOReader.ParseRICODefinition(ricoDefPath, isLocal: true); if (localRicoDef == null) { Logging.Message("no valid definitions in ", ricoDefPath); } } } }
/// <summary> /// Adds growable options tab to tabstrip. /// </summary> /// <param name="tabStrip">Tab strip to add to</param> /// <param name="tabIndex">Index number of tab</param> internal GrowableOptions(UITabstrip tabStrip, int tabIndex) { // Add tab and helper. UIPanel panel = PanelUtils.AddTab(tabStrip, Translations.Translate("PRR_OPTION_GRO"), tabIndex, true); UIHelper helper = new UIHelper(panel); // Add plop growables checkboxes. UIHelperBase plopGroup = helper.AddGroup(Translations.Translate("PRR_OPTION_PLP")); plopGroup.AddCheckbox(Translations.Translate("PRR_OPTION_RGR"), ModSettings.plopRico, isChecked => { ModSettings.plopRico = isChecked; }); plopGroup.AddCheckbox(Translations.Translate("PRR_OPTION_OTH"), ModSettings.plopOther, isChecked => { ModSettings.plopOther = isChecked; }); // Add no zone checks checkboxes. UIHelperBase zoneGroup = helper.AddGroup(Translations.Translate("PRR_OPTION_ZON")); zoneGroup.AddCheckbox(Translations.Translate("PRR_OPTION_RGR"), ModSettings.noZonesRico, isChecked => { ModSettings.noZonesRico = isChecked; }); zoneGroup.AddCheckbox(Translations.Translate("PRR_OPTION_OTH"), ModSettings.noZonesOther, isChecked => { ModSettings.noZonesOther = isChecked; }); // Add no specialisation checks checkboxes. UIHelperBase specGroup = helper.AddGroup(Translations.Translate("PRR_OPTION_SPC")); specGroup.AddCheckbox(Translations.Translate("PRR_OPTION_RGR"), ModSettings.noSpecRico, isChecked => { ModSettings.noSpecRico = isChecked; }); specGroup.AddCheckbox(Translations.Translate("PRR_OPTION_OTH"), ModSettings.noSpecOther, isChecked => { ModSettings.noSpecOther = isChecked; }); // Add 'make plopped growables historical' checkboxes. UIHelperBase histGroup = helper.AddGroup(Translations.Translate("PRR_OPTION_HST")); histGroup.AddCheckbox(Translations.Translate("PRR_OPTION_RGR"), ModSettings.historicalRico, isChecked => { ModSettings.historicalRico = isChecked; }); histGroup.AddCheckbox(Translations.Translate("PRR_OPTION_OTH"), ModSettings.historicalOther, isChecked => { ModSettings.historicalOther = isChecked; }); // Add level control checkboxes. UIHelperBase levelGroup = helper.AddGroup(Translations.Translate("PRR_OPTION_BLC")); // If we haven't already, check for Advanced Building Level Control. if (ModUtils.ablcLockBuildingLevel == null) { ModUtils.ABLCReflection(); } // Is it (still) null? if (ModUtils.ablcLockBuildingLevel != null) { // ABLC installed; display checkboxes. levelGroup.AddCheckbox(Translations.Translate("PRR_OPTION_RGR"), ModSettings.lockLevelRico, isChecked => { ModSettings.lockLevelRico = isChecked; }); levelGroup.AddCheckbox(Translations.Translate("PRR_OPTION_OTH"), ModSettings.lockLevelOther, isChecked => { ModSettings.lockLevelOther = isChecked; }); } // Add 'disable style despawn' checkbox. UIHelperBase styleGroup = helper.AddGroup(Translations.Translate("PRR_OPTION_STY")); styleGroup.AddCheckbox(Translations.Translate("PRR_OPTION_STR"), PrivateBuildingSimStep.disableStyleDespawn, isChecked => { PrivateBuildingSimStep.disableStyleDespawn = isChecked; }); }
/// <summary> /// Loads languages from CSV files. /// </summary> private void LoadLanguages() { // Clear existing dictionary. languages.Clear(); // Get the current assembly path and append our locale directory name. string assemblyPath = ModUtils.GetAssemblyPath(); if (!assemblyPath.IsNullOrWhiteSpace()) { string localePath = Path.Combine(assemblyPath, "Translations"); // Ensure that the directory exists before proceeding. if (Directory.Exists(localePath)) { // Load each file in directory and attempt to deserialise as a translation file. string[] translationFiles = Directory.GetFiles(localePath); foreach (string translationFile in translationFiles) { // Skip anything that's not marked as a .csv file. if (!translationFile.EndsWith(".csv")) { continue; } // Read file. FileStream fileStream = new FileStream(translationFile, FileMode.Open, FileAccess.Read); using (StreamReader reader = new StreamReader(fileStream)) { // Create new language instance for this file. Language thisLanguage = new Language(); string key = null; bool quoting = false; // Iterate through each line of file. string line = reader.ReadLine(); while (line != null) { // Are we parsing quoted lines? if (quoting) { // Parsing a quoted line - make sure we have a valid current key. if (!key.IsNullOrWhiteSpace()) { // Yes - if the line ends with a quote, trim the quote and add to existing dictionary entry and stop quoting. if (line.EndsWith("\"")) { quoting = false; thisLanguage.translationDictionary[key] += line.Substring(0, line.Length - 1); } else { // Line doesn't end with a quote - add line to existing dictionary entry and keep going. thisLanguage.translationDictionary[key] += line + Environment.NewLine; } } } else { // Not parsing quoted line - look for comma separator on this line. int commaPos = line.IndexOf(","); if (commaPos > 0) { // Comma found - split line into key and value, delimited by first comma. key = line.Substring(0, commaPos); string value = line.Substring(commaPos + 1); // Don't do anything if either key or value is invalid. if (!key.IsNullOrWhiteSpace() && !value.IsNullOrWhiteSpace()) { // Trim quotes off keys. if (key.StartsWith("\"")) { // Starts with quotation mark - if it also ends in a quotation mark, strip both quotation marks. if (key.EndsWith("\"")) { key = key.Substring(1, key.Length - 2); } else { // Doesn't end in a quotation mark, so just strip leading quotation mark. key = key.Substring(1); } } // Does this value start with a quotation mark? if (value.StartsWith("\"")) { // Starts with quotation mark - if it also ends in a quotation mark, strip both quotation marks. if (value.EndsWith("\"")) { value = value.Substring(1, value.Length - 2); } else { // Doesn't end in a quotation mark, so we've (presumably) got a multi-line quoted entry // Flag quoting mode and set initial value to start of quoted string (less leading quotation mark), plus trailing newline. quoting = true; value = value.Substring(1) + Environment.NewLine; } } // Check for reserved keywords. if (key.Equals(Language.CodeKey)) { // Language code. thisLanguage.uniqueName = value; } else if (key.Equals(Language.NameKey)) { // Language readable name. thisLanguage.readableName = value; } else { // Try to add key/value pair to translation dictionary, if it's valid. if (!value.IsNullOrWhiteSpace()) { // Check for duplicates. if (!thisLanguage.translationDictionary.ContainsKey(key)) { thisLanguage.translationDictionary.Add(key, value); } else { Logging.Error("duplicate translation key ", key, " in file ", translationFile); } } } } } else { // No comma delimiter found - append to previous line (if last-used key is valid). if (!key.IsNullOrWhiteSpace()) { thisLanguage.translationDictionary[key] += line; } } } // Read next line. line = reader.ReadLine(); } // Did we get a valid dictionary from this? if (thisLanguage.uniqueName != null && thisLanguage.readableName != null && thisLanguage.translationDictionary.Count > 0) { // Yes - add to languages dictionary. if (!languages.ContainsKey(thisLanguage.uniqueName)) { languages.Add(thisLanguage.uniqueName, thisLanguage); } else { Logging.Error("duplicate translation file for language ", thisLanguage.uniqueName); } } else { Logging.Error("file ", translationFile, " did not produce a valid translation dictionary"); } } } } else { Logging.Error("translations directory not found"); } } else { Logging.Error("assembly path was empty"); } }