/// <summary> /// Performs initial setup for the panel; we no longer use Start() as that's not sufficiently reliable (race conditions), and is no longer needed, with the new create/destroy process. /// </summary> internal void Setup() { try { // Hide while we're setting up. isVisible = false; // Basic setup. canFocus = true; isInteractive = true; width = leftWidth + middleWidth + rightWidth + (spacing * 4); height = panelHeight + titleHeight + filterHeight + (spacing * 2) + bottomMargin; relativePosition = new Vector3(Mathf.Floor((GetUIView().fixedWidth - width) / 2), Mathf.Floor((GetUIView().fixedHeight - height) / 2)); backgroundSprite = "UnlockingPanel2"; // Titlebar. titleBar = AddUIComponent <UITitleBar>(); titleBar.Setup(); // Filter. filterBar = AddUIComponent <UIBuildingFilter>(); filterBar.width = width - (spacing * 2); filterBar.height = filterHeight; filterBar.relativePosition = new Vector3(spacing, titleHeight); // Event handler to dealth with changes to filtering. filterBar.eventFilteringChanged += (component, value) => { if (value == -1) { return; } int listCount = buildingSelection.rowsData.m_size; float position = buildingSelection.listPosition; buildingSelection.selectedIndex = -1; buildingSelection.rowsData = GenerateFastList(); }; // Set up panels. // Left panel - list of buildings. UIPanel leftPanel = AddUIComponent <UIPanel>(); leftPanel.width = leftWidth; leftPanel.height = panelHeight - checkFilterHeight; leftPanel.relativePosition = new Vector3(spacing, titleHeight + filterHeight + checkFilterHeight + spacing); // Middle panel - building preview and edit panels. UIPanel middlePanel = AddUIComponent <UIPanel>(); middlePanel.width = middleWidth; middlePanel.height = panelHeight; middlePanel.relativePosition = new Vector3(leftWidth + (spacing * 2), titleHeight + filterHeight + spacing); previewPanel = middlePanel.AddUIComponent <UIPreviewPanel>(); previewPanel.width = middlePanel.width; previewPanel.height = (panelHeight - spacing) / 2; previewPanel.relativePosition = Vector3.zero; previewPanel.Setup(); savePanel = middlePanel.AddUIComponent <UISavePanel>(); savePanel.width = middlePanel.width; savePanel.height = (panelHeight - spacing) / 2; savePanel.relativePosition = new Vector3(0, previewPanel.height + spacing); savePanel.Setup(); // Right panel - mod calculations. UIPanel rightPanel = AddUIComponent <UIPanel>(); rightPanel.width = rightWidth; rightPanel.height = panelHeight; rightPanel.relativePosition = new Vector3(leftWidth + middleWidth + (spacing * 3), titleHeight + filterHeight + spacing); buildingOptionsPanel = rightPanel.AddUIComponent <UIBuildingOptions>(); buildingOptionsPanel.width = rightWidth; buildingOptionsPanel.height = panelHeight; buildingOptionsPanel.relativePosition = Vector3.zero; buildingOptionsPanel.Setup(); // Building selection list. buildingSelection = UIFastList.Create <UIBuildingRow>(leftPanel); buildingSelection.backgroundSprite = "UnlockingPanel"; buildingSelection.width = leftPanel.width; buildingSelection.height = leftPanel.height; buildingSelection.canSelect = true; buildingSelection.rowHeight = 40; buildingSelection.autoHideScrollbar = true; buildingSelection.relativePosition = Vector3.zero; buildingSelection.rowsData = new FastList <object>(); // Set up filterBar to make sure selection filters are properly initialised before calling GenerateFastList. filterBar.Setup(); // Populate the list. buildingSelection.rowsData = GenerateFastList(); } catch (Exception e) { Debugging.LogException(e); } }
public static PloppableRICODefinition DeserializeRICODefinition(string packageName, Stream ricoDefStream, bool insanityOK) { // Note here we're using insanityOK as a local settings flag. string localOrAuthor = insanityOK ? "local" : "author"; try { XmlAttributes attrs = new XmlAttributes(); XmlElementAttribute attr = new XmlElementAttribute(); attr.ElementName = "RICOBuilding"; attr.Type = typeof(RICOBuilding); XmlAttributeOverrides attrOverrides = new XmlAttributeOverrides(); attrOverrides.Add(typeof(RICOBuilding), "Building", attrs); var streamReader = new System.IO.StreamReader(ricoDefStream); var xmlSerializer = new XmlSerializer(typeof(PloppableRICODefinition), attrOverrides); var result = xmlSerializer.Deserialize(streamReader) as PloppableRICODefinition; StringBuilder errorList; if (result.Buildings.Count == 0) { Debugging.Message("no parseable buildings in " + localOrAuthor + " XML settings file"); } else { foreach (var building in result.Buildings) { // Check for fatal errors in each building. errorList = building.fatalErrors; if (errorList.Length == 0) { // No fatal errors; check for non-fatal errors. errorList = building.nonFatalErrors; if (errorList.Length != 0) { // Errors found - how we report them depends on whether its local or author settings (we're assuming mod settings are fine). if (insanityOK && building.ricoEnabled) { // Errors in local settings need to be reported direct to user, except for buildings that aren't activated in RICO. Debugging.ErrorBuffer.Append(errorList.ToString()); Debugging.Message("non-fatal errors for building '" + building.name + "' in local settings"); } else if (Settings.debugLogging) { // Errors in other settings should be logged if verbose logging is enabled, but otherwise continue. errorList.Insert(0, "found the following non-fatal errors for building '" + building.name + "' in author settings:\r\n"); Debugging.Message(errorList.ToString()); } } // No fatal errors; building is good (enough). building.parent = result; } else { // Fatal errors! Need to be reported direct to user and the building ignored. Debugging.ErrorBuffer.Append(errorList.ToString()); Debugging.Message("fatal errors for building '" + building.name + "' in " + localOrAuthor + " settings"); } } } streamReader.Close(); result.clean(); return(result); } catch (Exception e) { Debugging.ErrorBuffer.AppendLine(String.Format("Unexpected Exception while deserializing " + localOrAuthor + " RICO file {0} ({1} [{2}])", packageName, e.Message, e.InnerException != null ? e.InnerException.Message : "")); return(null); } }
/// <summary> /// Harmony Transpiler to add checks to see if extractor buildings should be demolished if they're outside of a district with relevant specialization settings. /// </summary> /// <param name="instructions">Original ILCode</param> /// <returns>Replacement (patched) ILCode</returns> private static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions) { Debugging.Message("transpiler patching specialized building checks in IndustrialExtractorAI.SimulationStep"); return(CheckSpecTranspiler.Transpiler(instructions)); }
private static void RefreshMonumentsPanelRev(object instance) { Debugging.Message("RefreshMonumentsPanel reverse Harmony patch wasn't applied"); }