/// <summary> /// Removes and deletes a custom override. /// </summary> private void DeleteOverride() { // Hide message. messageLabel.isVisible = false; // Don't do anything with invalid entries. if (currentSelection == null || currentSelection.name == null) { return; } Logging.Message("deleting custom override for ", currentSelection.name); // Remove any and all overrides. FloorData.instance.DeleteOverride(currentSelection); PopData.instance.DeleteOverride(currentSelection); // Update panel override. BuildingDetailsPanel.Panel.OverrideFloors = null; // Homes or jobs? if (currentSelection.GetService() == ItemClass.Service.Residential) { // Residential building - remove any legacy settings to avoid conflicts. OverrideUtils.RemoveResidential(currentSelection); // Update CitizenUnits for existing instances of this building. CitizenUnitUtils.UpdateCitizenUnits(currentSelection.name, currentSelection.GetService(), currentSelection.GetSubService(), false); } else { // Employment building - remove any legacy settings to avoid conflicts. OverrideUtils.RemoveWorker(currentSelection); } // Refresh the display so that all panels reflect the updated settings. BuildingDetailsPanel.Panel.Refresh(); homeJobsCount.textField.text = string.Empty; }
/// <summary> /// Saves and applies settings - save button event handler. /// </summary> private void SaveAndApply() { // Hide message. messageLabel.isVisible = false; // Don't do anything with invalid entries. if (currentSelection == null || currentSelection.name == null) { return; } // Are we doing population overrides? if (popCheck.isChecked) { // Read total floor count textfield if possible; ignore zero values if (int.TryParse(homeJobsCount.textField.text, out int homesJobs) && homesJobs != 0) { // Minimum value of 1. if (homesJobs < 1) { // Print warning message in red. messageLabel.textColor = new Color32(255, 0, 0, 255); messageLabel.text = Translations.Translate("RPR_ERR_ZERO"); messageLabel.isVisible = true; } else { // Set overide. PopData.instance.SetOverride(currentSelection, homesJobs); // Update CitizenUnits for existing building instances. CitizenUnitUtils.UpdateCitizenUnits(currentSelection.name, ItemClass.Service.None, currentSelection.GetSubService(), false); // Repopulate field with parsed value. homeJobLabel.text = homesJobs.ToString(); } } else { // TryParse couldn't parse any data; print warning message in red. messageLabel.textColor = new Color32(255, 0, 0, 255); messageLabel.text = Translations.Translate("RPR_ERR_INV"); messageLabel.isVisible = true; } } else { // Population override checkbox wasn't checked; remove any custom settings. PopData.instance.DeleteOverride(currentSelection); // Remove any legacy file settings to avoid conflicts. OverrideUtils.RemoveResidential(currentSelection); OverrideUtils.RemoveWorker(currentSelection); } // Are we doing floor overrides? if (floorCheck.isChecked) { // Attempt to parse values into override floor pack. FloorDataPack overrideFloors = TryParseFloors(); // Were we successful?. if (overrideFloors != null) { // Successful parsing - add override. FloorData.instance.SetOverride(currentSelection, overrideFloors); // Save configuration. ConfigUtils.SaveSettings(); // Update panel override. BuildingDetailsPanel.Panel.OverrideFloors = overrideFloors; // Repopulate fields with parsed values. UpdateFloorTextFields(overrideFloors.firstFloorMin.ToString(), overrideFloors.floorHeight.ToString()); } else { // Couldn't parse values; print warning message in red. messageLabel.textColor = new Color32(255, 0, 0, 255); messageLabel.text = Translations.Translate("RPR_ERR_INV"); messageLabel.isVisible = true; } } else { // Floor override checkbox wasn't checked; remove any floor override. FloorData.instance.DeleteOverride(currentSelection); } // Refresh the display so that all panels reflect the updated settings. BuildingDetailsPanel.Panel.Refresh(); }
/// <summary> /// Called whenever the currently selected building is changed to update the panel display. /// </summary> /// <param name="building">Newly selected building</param> public void SelectionChanged(BuildingInfo building) { // Make sure we have a valid selection before proceeding. if (building?.name == null) { return; } // Variables to compare actual counts vs. mod count, to see if there's another mod overriding counts. int appliedCount; int modCount; // Building model size, not plot size. Vector3 buildingSize = building.m_size; int floorCount; // Array used for calculations depending on building service/subservice (via DataStore). int[] array; // Default minimum number of homes or jobs is one; different service types will override this. int minHomesJobs = 1; int customHomeJobs; // Check for valid building AI. if (!(building.GetAI() is PrivateBuildingAI buildingAI)) { Logging.Error("invalid building AI type in building details for building ", building.name); return; } // Residential vs. workplace AI. if (buildingAI is ResidentialBuildingAI) { // Get appropriate calculation array. array = LegacyAIUtils.GetResidentialArray(building, (int)building.GetClassLevel()); // Set calculated homes label. homesJobsCalcLabel.text = Translations.Translate("RPR_CAL_HOM_CALC"); // Set customised homes label and get value (if any). homesJobsCustomLabel.text = Translations.Translate("RPR_CAL_HOM_CUST"); customHomeJobs = OverrideUtils.GetResidential(building); // Applied homes is what's actually being returned by the CaclulateHomeCount call to this building AI. // It differs from calculated homes if there's an override value for that building with this mod, or if another mod is overriding. appliedCount = buildingAI.CalculateHomeCount(building.GetClassLevel(), new Randomizer(0), building.GetWidth(), building.GetLength()); homesJobsActualLabel.text = Translations.Translate("RPR_CAL_HOM_APPL") + appliedCount; } else { // Workplace AI. // Default minimum number of jobs is 4. minHomesJobs = 4; // Find the correct array for the relevant building AI. switch (building.GetService()) { case ItemClass.Service.Commercial: array = LegacyAIUtils.GetCommercialArray(building, (int)building.GetClassLevel()); break; case ItemClass.Service.Office: array = LegacyAIUtils.GetOfficeArray(building, (int)building.GetClassLevel()); break; case ItemClass.Service.Industrial: if (buildingAI is IndustrialExtractorAI) { array = LegacyAIUtils.GetExtractorArray(building); } else { array = LegacyAIUtils.GetIndustryArray(building, (int)building.GetClassLevel()); } break; default: Logging.Error("invalid building service in building details for building ", building.name); return; } // Set calculated jobs label. homesJobsCalcLabel.text = Translations.Translate("RPR_CAL_JOB_CALC") + " "; // Set customised jobs label and get value (if any). homesJobsCustomLabel.text = Translations.Translate("RPR_CAL_JOB_CUST") + " "; customHomeJobs = OverrideUtils.GetWorker(building); // Applied jobs is what's actually being returned by the CalculateWorkplaceCount call to this building AI. // It differs from calculated jobs if there's an override value for that building with this mod, or if another mod is overriding. int[] jobs = new int[4]; buildingAI.CalculateWorkplaceCount(building.GetClassLevel(), new Randomizer(0), building.GetWidth(), building.GetLength(), out jobs[0], out jobs[1], out jobs[2], out jobs[3]); appliedCount = jobs[0] + jobs[1] + jobs[2] + jobs[3]; homesJobsActualLabel.text = Translations.Translate("RPR_CAL_JOB_APPL") + " " + appliedCount; // Show visitor count for commercial buildings. if (buildingAI is CommercialBuildingAI commercialAI) { visitCountLabel.Show(); visitCountLabel.text = Translations.Translate("RPR_CAL_VOL_VIS") + " " + commercialAI.CalculateVisitplaceCount(building.GetClassLevel(), new Randomizer(), building.GetWidth(), building.GetLength()); } else { visitCountLabel.Hide(); } // Display production count, or hide the label if not a production building. if (building.GetAI() is PrivateBuildingAI privateAI && (privateAI is OfficeBuildingAI || privateAI is IndustrialBuildingAI || privateAI is IndustrialExtractorAI)) { productionLabel.Show(); productionLabel.text = Translations.Translate("RPR_CAL_VOL_PRD") + " " + privateAI.CalculateProductionCapacity(building.GetClassLevel(), new ColossalFramework.Math.Randomizer(), building.GetWidth(), building.GetLength()).ToString(); }