Esempio n. 1
0
        /// <summary>
        /// Updates button states (enabled/disabled) according to current control states.
        /// </summary>
        protected override void UpdateButtonStates()
        {
            // Disable by default (selectively (re)-enable if eligible).
            replaceButton.Disable();
            revertButton.Disable();

            // Buttons are only enabled if a current target item is selected.
            if (CurrentTargetItem != null)
            {
                // Replacement requires a valid replacement selection.
                if (ReplacementPrefab != null)
                {
                    replaceButton.Enable();
                }

                // Reversion requires a currently active replacement.
                if (CurrentTargetItem.replacementPrefab != null)
                {
                    revertButton.Enable();
                    revertButton.tooltip = Translations.Translate("BOB_PNL_REV_UND");
                }
                else
                {
                    revertButton.tooltip = Translations.Translate("BOB_PNL_REV_TIP");
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Adds an icon toggle checkbox.
        /// </summary>
        /// <param name="parent">Parent component</param>
        /// <param name="xPos">Relative X position</param>
        /// <param name="yPos">Relative Y position</param>
        /// <param name="atlasName">Atlas name (for loading from file)</param>
        /// <param name="tooltipKey">Tooltip translation key</param>
        /// <returns>New checkbox</returns>
        protected UICheckBox IconToggleCheck(UIComponent parent, float xPos, float yPos, string atlasName, string tooltipKey)
        {
            // Size and position.
            UICheckBox checkBox = parent.AddUIComponent <UICheckBox>();

            checkBox.width            = ToggleSize;
            checkBox.height           = ToggleSize;
            checkBox.clipChildren     = true;
            checkBox.relativePosition = new Vector2(xPos, yPos);

            // Checkbox sprites.
            UISprite sprite = checkBox.AddUIComponent <UISprite>();

            sprite.name             = "UncheckedSprite";
            sprite.atlas            = TextureUtils.LoadSpriteAtlas(atlasName);
            sprite.spriteName       = "disabled";
            sprite.size             = new Vector2(ToggleSize, ToggleSize);
            sprite.relativePosition = Vector3.zero;

            checkBox.checkedBoxObject = sprite.AddUIComponent <UISprite>();
            ((UISprite)checkBox.checkedBoxObject).atlas      = TextureUtils.LoadSpriteAtlas(atlasName);
            ((UISprite)checkBox.checkedBoxObject).spriteName = "pressed";
            checkBox.checkedBoxObject.size             = new Vector2(ToggleSize, ToggleSize);
            checkBox.checkedBoxObject.relativePosition = Vector3.zero;

            checkBox.tooltip = Translations.Translate(tooltipKey);

            return(checkBox);
        }
Esempio n. 3
0
        /// <summary>
        /// Adds mod options tab to tabstrip.
        /// </summary>
        /// <param name="tabStrip">Tab strip to add to</param>
        /// <param name="tabIndex">Index number of tab</param>
        internal GeneralOptionsPanel(UITabstrip tabStrip, int tabIndex)
        {
            // Add tab and helper.
            UIPanel  panel  = PanelUtils.AddTab(tabStrip, Translations.Translate("BOB_OPT_GEN"), tabIndex);
            UIHelper helper = new UIHelper(panel);

            panel.autoLayout = true;

            // Language dropdown.
            UIDropDown languageDrop = UIControls.AddPlainDropDown(panel, Translations.Translate("TRN_CHOICE"), Translations.LanguageList, Translations.Index);

            languageDrop.eventSelectedIndexChanged += (control, index) => Translations.Index = index;

            // Hotkey control.
            panel.gameObject.AddComponent <OptionsKeymapping>();

            // Default grouping behaviour.
            string[] groupItems = new string[]
            {
                Translations.Translate("BOB_PER_LST"),
                Translations.Translate("BOB_PER_SIN"),
                Translations.Translate("BOB_PER_GRP")
            };
            UIDropDown groupDropDown = UIControls.AddPlainDropDown(panel, Translations.Translate("BOB_PER_IND"), groupItems, ModSettings.indDefault, 350f);

            groupDropDown.eventSelectedIndexChanged += (control, index) => ModSettings.indDefault = index;

            // Rember last position.
            UICheckBox rememberPosCheck = UIControls.AddPlainCheckBox(panel, Translations.Translate("BOB_OPT_POS"));

            rememberPosCheck.isChecked          = ModSettings.rememberPosition;
            rememberPosCheck.eventCheckChanged += (control, isChecked) => ModSettings.rememberPosition = isChecked;
        }
Esempio n. 4
0
        /// <summary>
        /// Sets the target prefab.
        /// </summary>
        /// <param name="targetPrefabInfo">Target prefab to set</param>
        internal override void SetTarget(PrefabInfo targetPrefabInfo)
        {
            // Base setup.
            base.SetTarget(targetPrefabInfo);

            // Title label.
            SetTitle(Translations.Translate("BOB_NAM"));

            // Replace text label.
            UILabel replaceLabel = AddUIComponent <UILabel>();

            replaceLabel.text             = Translations.Translate("BOB_PNL_REP");
            replaceLabel.relativePosition = new Vector2(MidControlX, ReplaceLabelY);

            // Set trees/props.
            propCheck.isChecked = !InitialTreeCheckedState;
            treeCheck.isChecked = InitialTreeCheckedState;

            // Populate target list and select target item.
            TargetList();
            targetList.FindTargetItem(targetPrefabInfo);

            // Update button states.
            UpdateButtonStates();

            // Apply Harmony rendering patches.
            Patcher.PatchMapOverlays(true);
        }
Esempio n. 5
0
        /// <summary>
        /// Adds a BOB slider to the specified component.
        /// </summary>
        /// <param name="parent">Parent component</param>
        /// <param name="xPos">Relative X position</param
        /// <param name="yPos">Relative Y position</param
        /// <param name="width">Slider width</param>
        /// <param name="labelKey">Text label translation key</param>
        /// <param name="minValue">Minimum displayed value</param
        /// <param name="maxValue">Maximum displayed value</param>
        /// <param name="stepSize">Minimum slider step size</param>
        /// <param name="name">Slider name</param>
        /// <returns>New BOBSlider</returns>
        protected BOBSlider AddBOBSlider(UIComponent parent, float xPos, float yPos, float width, string labelKey, float minValue, float maxValue, float stepSize, string name)
        {
            const float SliderY             = 18f;
            const float ValueY              = 3f;
            const float LabelY              = -13f;
            const float SliderHeight        = 18f;
            const float FloatTextFieldWidth = 45f;
            const float IntTextFieldWidth   = 38f;


            // Slider control.
            BOBSlider newSlider = parent.AddUIComponent <BOBSlider>();

            newSlider.size             = new Vector2(width, SliderHeight);
            newSlider.relativePosition = new Vector2(xPos, yPos + SliderY);
            newSlider.name             = name;

            // Value field - added to parent, not to slider, otherwise slider catches all input attempts.  Integer textfields (stepsize == 1) have shorter widths.
            float       textFieldWidth = stepSize == 1 ? IntTextFieldWidth : FloatTextFieldWidth;
            UITextField valueField     = UIControls.TinyTextField(parent, xPos + Margin + newSlider.width - textFieldWidth, yPos + ValueY, textFieldWidth);

            // Title label.
            UILabel titleLabel = UIControls.AddLabel(newSlider, 0f, LabelY, Translations.Translate(labelKey), textScale: 0.7f);

            // Autoscale tile label text, with minimum size 0.35.
            while (titleLabel.width > newSlider.width - textFieldWidth && titleLabel.textScale > 0.35f)
            {
                titleLabel.textScale -= 0.05f;
            }

            // Slider track.
            UISlicedSprite sliderSprite = newSlider.AddUIComponent <UISlicedSprite>();

            sliderSprite.atlas            = TextureUtils.InGameAtlas;
            sliderSprite.spriteName       = "BudgetSlider";
            sliderSprite.size             = new Vector2(newSlider.width, 9f);
            sliderSprite.relativePosition = new Vector2(0f, 4f);

            // Slider thumb.
            UISlicedSprite sliderThumb = newSlider.AddUIComponent <UISlicedSprite>();

            sliderThumb.atlas      = TextureUtils.InGameAtlas;
            sliderThumb.spriteName = "SliderBudget";
            newSlider.thumbObject  = sliderThumb;

            // Set references.
            newSlider.ValueField = valueField;

            // Event handler for textfield.
            newSlider.ValueField.eventTextSubmitted += newSlider.OnTextSubmitted;

            // Set initial values.
            newSlider.StepSize  = stepSize;
            newSlider.maxValue  = maxValue;
            newSlider.minValue  = minValue;
            newSlider.TrueValue = 0f;

            return(newSlider);
        }
Esempio n. 6
0
        /// <summary>
        /// Prop check event handler.
        /// </summary>
        /// <param name="control">Calling component (unused)</param>
        /// <param name="isChecked">New checked state</param>
        protected override void PropCheckChanged(UIComponent control, bool isChecked)
        {
            base.PropCheckChanged(control, isChecked);

            // Toggle replace button atlas.
            replaceButton.atlas   = isChecked ? TextureUtils.LoadSpriteAtlas("BOB-Props") : TextureUtils.LoadSpriteAtlas("BOB-Trees");
            replaceButton.tooltip = Translations.Translate(ReplaceTooltipKey);
        }
Esempio n. 7
0
        /// <summary>
        /// Constructor.
        /// </summary>
        internal BOBPanelBase()
        {
            // Basic behaviour.
            autoLayout    = false;
            canFocus      = true;
            isInteractive = true;

            // Appearance.
            backgroundSprite = "MenuPanel2";
            opacity          = PanelOpacity;

            // Size.
            size = new Vector2(PanelWidth, PanelHeight);

            // Drag bar.
            UIDragHandle dragHandle = AddUIComponent <UIDragHandle>();

            dragHandle.width            = this.width - 50f;
            dragHandle.height           = this.height;
            dragHandle.relativePosition = Vector3.zero;
            dragHandle.target           = this;

            // Close button.
            UIButton closeButton = AddUIComponent <UIButton>();

            closeButton.relativePosition = new Vector2(width - 35, 2);
            closeButton.normalBgSprite   = "buttonclose";
            closeButton.hoveredBgSprite  = "buttonclosehover";
            closeButton.pressedBgSprite  = "buttonclosepressed";
            closeButton.eventClick      += (component, clickEvent) => CloseEvent();

            // Name filter.
            nameFilter = UIControls.SmallLabelledTextField(this, width - 200f - Margin, TitleHeight + Margin, Translations.Translate("BOB_FIL_NAME"));
            // Event handlers for name filter textbox.
            nameFilter.eventTextChanged   += (control, text) => LoadedList();
            nameFilter.eventTextSubmitted += (control, text) => LoadedList();

            // Vanilla filter.
            hideVanilla                    = UIControls.LabelledCheckBox((UIComponent)(object)this, nameFilter.relativePosition.x, nameFilter.relativePosition.y + nameFilter.height + (Margin / 2f), Translations.Translate("BOB_PNL_HDV"), 12f, 0.7f);
            hideVanilla.isChecked          = ModSettings.hideVanilla;
            hideVanilla.eventCheckChanged += VanillaCheckChanged;

            // Mode label.
            modeLabel = UIControls.AddLabel(this, Margin, ToggleHeaderY, Translations.Translate("BOB_PNL_MOD"), textScale: 0.8f);

            // Tree/Prop checkboxes.
            propCheck                    = IconToggleCheck(this, Margin, ToggleY, "BOB-PropsSmall", "BOB_PNL_PRP");
            treeCheck                    = IconToggleCheck(this, Margin + ToggleSize, ToggleY, "BOB-TreesSmall", "BOB_PNL_TRE");
            propCheck.isChecked          = !InitialTreeCheckedState;
            treeCheck.isChecked          = InitialTreeCheckedState;
            propCheck.eventCheckChanged += PropCheckChanged;
            treeCheck.eventCheckChanged += TreeCheckChanged;
        }
Esempio n. 8
0
        /// <summary>
        /// Adds mod options tab to tabstrip.
        /// </summary>
        /// <param name="tabStrip">Tab strip to add to</param>
        /// <param name="tabIndex">Index number of tab</param>
        internal RuiningOptionsPanel(UITabstrip tabStrip, int tabIndex)
        {
            // Add tab and helper.
            UIPanel  panel  = PanelUtils.AddTab(tabStrip, Translations.Translate("BOB_OPT_RUI"), tabIndex);
            UIHelper helper = new UIHelper(panel);

            panel.autoLayout = true;

            UIHelperBase ruinGroup = helper.AddGroup(Translations.Translate("BOB_OPT_RGL"));

            // Checkboxes.
            ruinGroup.AddCheckbox(Translations.Translate("BOB_OPT_RRT"), ModSettings.StopTreeRuining, (value) => ModSettings.StopTreeRuining = value);
            ruinGroup.AddCheckbox(Translations.Translate("BOB_OPT_RRP"), ModSettings.StopPropRuining, (value) => ModSettings.StopPropRuining = value);
        }
Esempio n. 9
0
        /// <summary>
        /// Setup this control
        /// Called by Unity immediately before the first update.
        /// </summary>
        public void Start()
        {
            // Get the template from the game and attach it here.
            UIPanel uIPanel = component.AttachUIComponent(UITemplateManager.GetAsGameObject("KeyBindingTemplate")) as UIPanel;

            // Find our sub-components.
            label  = uIPanel.Find <UILabel>("Name");
            button = uIPanel.Find <UIButton>("Binding");

            // Attach our event handlers.
            button.eventKeyDown   += (control, keyEvent) => OnKeyDown(keyEvent);
            button.eventMouseDown += (control, mouseEvent) => OnMouseDown(mouseEvent);

            // Set label and button text.
            label.text  = Translations.Translate("BOB_OPT_KEY");
            button.text = SavedInputKey.ToLocalizedString("KEYNAME", ModSettings.CurrentHotkey);
        }
Esempio n. 10
0
        /// <summary>
        /// Constructor - creates panel.
        /// </summary>
        internal BOBScalePanel()
        {
            // Default position - centre in screen.
            relativePosition = new Vector2(Mathf.Floor((GetUIView().fixedWidth - width) / 2), Mathf.Floor((GetUIView().fixedHeight - height) / 2));

            // Title label.
            SetTitle(Translations.Translate("BOB_NAM") + " : " + Translations.Translate("BOB_SCA_TIT"));

            // Minimum scale slider.
            minScaleSlider = AddBOBSlider(this, ControlX, MinOffsetY, ControlWidth - (Margin * 2f), "BOB_SCA_MIN", 0.5f, 2f, 0.5f, "MinScale");
            minScaleSlider.eventValueChanged += MinScaleValue;
            minScaleSlider.value              = 1f;
            maxScaleSlider = AddBOBSlider(this, ControlX, MaxOffsetY + 40f, ControlWidth - (Margin * 2f), "BOB_SCA_MAX", 0.5f, 2f, 0.5f, "MaxScale");
            maxScaleSlider.eventValueChanged += MaxScaleValue;
            maxScaleSlider.value              = 1f;

            // Revert button.
            revertButton = UIControls.AddSmallerButton(this, ControlX, RevertY, Translations.Translate("BOB_PNL_REV"), ControlWidth);
            revertButton.eventClicked += Revert;
            revertButton.Disable();

            // Loaded prop list.
            UIPanel loadedPanel = AddUIComponent <UIPanel>();

            loadedPanel.width            = LoadedWidth;
            loadedPanel.height           = ListHeight;
            loadedPanel.relativePosition = new Vector2(LoadedX, ListY);
            loadedList = UIFastList.Create <UILoadedScalingPropRow>(loadedPanel);
            ListSetup(loadedList);

            // Order button.
            loadedNameButton = ArrowButton(this, LoadedX + 10f, ListY - 20f);
            loadedNameButton.eventClicked += SortLoaded;

            loadedCreatorButton = ArrowButton(this, LoadedX + UILoadedScalingPropRow.CreatorX + 10f, ListY - 20f);
            loadedCreatorButton.eventClicked += SortLoaded;

            // Default is name ascending.
            SetFgSprites(loadedNameButton, "IconUpArrow2");

            // Populate loaded list.
            LoadedList();

            // Bring to front.
            BringToFront();
        }
Esempio n. 11
0
        /// <summary>
        /// Adds mod options tab to tabstrip.
        /// </summary>
        /// <param name="tabStrip">Tab strip to add to</param>
        /// <param name="tabIndex">Index number of tab</param>
        internal VisualOptionsPanel(UITabstrip tabStrip, int tabIndex)
        {
            // Add tab and helper.
            UIPanel  panel  = PanelUtils.AddTab(tabStrip, Translations.Translate("BOB_OPT_VIS"), tabIndex);
            UIHelper helper = new UIHelper(panel);

            panel.autoLayout = true;

            // Ruining.
            UIHelperBase ruinGroup = helper.AddGroup(Translations.Translate("BOB_OPT_RUI") + " - " + Translations.Translate("BOB_OPT_RGL"));

            ruinGroup.AddCheckbox(Translations.Translate("BOB_OPT_RRT"), ModSettings.StopTreeRuining, (value) => ModSettings.StopTreeRuining = value);
            ruinGroup.AddCheckbox(Translations.Translate("BOB_OPT_RRP"), ModSettings.StopPropRuining, (value) => ModSettings.StopPropRuining = value);

            // Electrical wire thickness.
            UIHelperBase wiresGroup = helper.AddGroup(Translations.Translate("BOB_OPT_WIR"));

            wiresGroup.AddCheckbox(Translations.Translate("BOB_OPT_WTH"), ModSettings.ThinnerWires, (value) => ModSettings.ThinnerWires = value);
        }
Esempio n. 12
0
        /// <summary>
        /// Initialise the tool.
        /// Called by unity when the tool is created.
        /// </summary>
        protected override void Awake()
        {
            base.Awake();

            // Initializae PropAPI.
            PropAPI.Initialize();

            // Load cursors.
            lightCursor = TextureUtils.LoadCursor("BOB-CursorLight.png");
            darkCursor  = TextureUtils.LoadCursor("BOB-CursorDark.png");
            m_cursor    = darkCursor;

            // Create new UUI button.
            UIComponent uuiButton = UUIHelpers.RegisterToolButton(
                name: nameof(BOBTool),
                groupName: null,                 // default group
                tooltip: Translations.Translate("BOB_NAM"),
                tool: this,
                icon: UUIHelpers.LoadTexture(UUIHelpers.GetFullPath <BOBMod>("Resources", "BOB-UUI.png"))
                //hotkeys: new UUIHotKeys { ActivationKey = ModSettings.PanelSavedKey }
                );
        }
Esempio n. 13
0
        /// <summary>
        /// Adds an icon-style button to the specified component at the specified coordinates.
        /// </summary>
        /// <param name="parent">Parent UIComponent</param>
        /// <param name="xPos">Relative X position</param>
        /// <param name="yPos">Relative Y position</param>
        /// <param name="size">Button size (square)</param>
        /// <param name="tooltipKey">Tooltip translation key</param>
        /// <param name="atlas">Icon atlas</param>
        /// <returns>New UIButton</returns>
        protected UIButton AddIconButton(UIComponent parent, float xPos, float yPos, float size, string tooltipKey, UITextureAtlas atlas)
        {
            UIButton newButton = parent.AddUIComponent <UIButton>();

            // Size and position.
            newButton.relativePosition = new Vector2(xPos, yPos);
            newButton.height           = size;
            newButton.width            = size;

            // Appearance.
            newButton.atlas = atlas;

            newButton.normalFgSprite   = "normal";
            newButton.focusedFgSprite  = "normal";
            newButton.hoveredFgSprite  = "hovered";
            newButton.disabledFgSprite = "disabled";
            newButton.pressedFgSprite  = "pressed";

            // Tooltip.
            newButton.tooltip = Translations.Translate(tooltipKey);

            return(newButton);
        }
Esempio n. 14
0
        /// <summary>
        /// Performs initial setup
        /// </summary>
        /// <param name="parentTransform">Parent transform</param>
        /// <param name="targetPrefabInfo">Currently selected target prefab</param>
        internal override void Setup(Transform parentTransform, PrefabInfo targetPrefabInfo)
        {
            try
            {
                // Perform basic panel setup.
                base.Setup(parentTransform, targetPrefabInfo);

                Logging.Message("commencing InfoPanel setup");

                // Replace all button.
                replaceAllButton = AddIconButton(this, MidControlX + replaceButton.width, ReplaceY, BigIconSize, ReplaceAllTooltipKey, ReplaceAllAtlas);
                replaceAllButton.eventClicked += ReplaceAll;

                // Probability.
                UIPanel probabilityPanel = Sliderpanel(this, MidControlX, ProbabilityY, SliderHeight);
                probabilitySlider                = AddBOBSlider(probabilityPanel, 0f, "BOB_PNL_PRB", 0, 100, 1);
                probabilitySlider.TrueValue      = 100f;
                probabilitySlider.LimitToVisible = true;

                // Angle.
                UIPanel anglePanel = Sliderpanel(this, MidControlX, AngleY, SliderHeight);
                angleSlider = AddBOBSlider(anglePanel, 0f, "BOB_PNL_ANG", -180, 180, 1);

                Logging.Message("Creating offset panel");

                // Offset panel.
                UIPanel offsetPanel = Sliderpanel(this, MidControlX, OffsetPanelY, OffsetPanelHeight);
                UILabel offsetLabel = UIControls.AddLabel(offsetPanel, 0f, OffsetLabelY, Translations.Translate("BOB_PNL_OFF"));
                offsetLabel.textAlignment = UIHorizontalAlignment.Center;
                while (offsetLabel.width > MidControlWidth)
                {
                    offsetLabel.textScale -= 0.05f;
                    offsetLabel.PerformLayout();
                }
                offsetLabel.relativePosition = new Vector2((offsetPanel.width - offsetLabel.width) / 2f, OffsetLabelY);

                // Offset sliders.
                xSlider = AddBOBSlider(offsetPanel, XOffsetY, "BOB_PNL_XOF", -8f, 8f, 0.01f);
                ySlider = AddBOBSlider(offsetPanel, YOffsetY, "BOB_PNL_YOF", -8f, 8f, 0.01f);
                zSlider = AddBOBSlider(offsetPanel, ZOffsetY, "BOB_PNL_ZOF", -8f, 8f, 0.01f);

                // Set initial button states.
                UpdateButtonStates();

                // Normal/random toggle.
                randomCheck = UIControls.LabelledCheckBox((UIComponent)(object)this, hideVanilla.relativePosition.x, hideVanilla.relativePosition.y + hideVanilla.height + (Margin / 2f), Translations.Translate("BOB_PNL_RSW"), 12f, 0.7f);
                randomCheck.eventCheckChanged += RandomCheckChanged;

                // Random settings button.
                UIButton randomButton = UIControls.EvenSmallerButton(this, RightX - 200f, TitleHeight + Margin + 20f, Translations.Translate("BOB_PNL_RST"));
                randomButton.eventClicked += (control, clickEvent) => BOBRandomPanel.Create();

                Logging.Message("InfoPanel setup completed");
            }
            catch (Exception e)
            {
                Logging.LogException(e, "exception setting up InfoPanel");
            }
        }
Esempio n. 15
0
        /// <summary>
        /// Generates and displays a building row.
        /// </summary>
        /// <param name="data">Object to list</param>
        /// <param name="isRowOdd">If the row is an odd-numbered row (for background banding)</param>
        public void Display(object data, bool isRowOdd)
        {
            // Perform initial setup for new rows.
            if (nameLabel == null)
            {
                isVisible     = true;
                canFocus      = true;
                isInteractive = true;
                width         = parent.width;
                height        = RowHeight;

                // Add object name label.
                nameLabel           = AddUIComponent <UILabel>();
                nameLabel.width     = this.width - 10f;
                nameLabel.textScale = TextScale;

                // Add index text label.
                indexLabel                  = AddUIComponent <UILabel>();
                indexLabel.width            = IndexWidth;
                indexLabel.textScale        = TextScale;
                indexLabel.relativePosition = new Vector2(IndexLabelX, PaddingY);
            }

            // Add line sprite if we need to (initially hidden).
            if (lineSprite == null)
            {
                lineSprite                  = AddUIComponent <UISprite>();
                lineSprite.size             = new Vector2(17f, 17f);
                lineSprite.relativePosition = new Vector2(3f, 3f);
                lineSprite.Hide();
            }

            // Set initial label position.
            labelX = LeftMargin;

            // See if our attached data is a raw PropInfo (e.g an available prop item as opposed to a PropListItem replacment record).
            thisPrefab = data as PrefabInfo;
            if (thisPrefab == null)
            {
                // Hide any existing line sprites; it will be re-shown as necessary.
                if (lineSprite != null)
                {
                    lineSprite.Hide();

                    // Adjust name label position to accomodate.
                    labelX += PackageMargin;
                }

                // Text to display - StringBuilder due to the amount of manipulation we're doing.
                StringBuilder displayText = new StringBuilder();

                // Not a raw PropInfo, so it should be a PropListItem replacement record.
                // Set local references.
                thisItem = data as PropListItem;
                index    = thisItem.index;

                // See if this is a network prop.
                NetPropListItem thisNetItem = data as NetPropListItem;

                // Display index number if this is an individual reference.
                if (thisItem.index >= 0)
                {
                    indexLabel.text = thisItem.index.ToString();

                    // Adjust name label position to accomodate.
                    labelX += IndexWidth;
                }
                else
                {
                    indexLabel.text = "";
                }

                bool hasReplacement = false;

                // Check to see if there's a currently active individual replacement.
                if (thisItem.individualPrefab != null)
                {
                    // A replacement is currently active - include it in the text.
                    displayText.Append(PrefabLists.GetDisplayName(thisItem.individualPrefab.name));

                    // Append probability to the label, if we're showing it.
                    if (thisItem.showProbs)
                    {
                        displayText.Append(" ");
                        displayText.Append(thisItem.individualProb);
                        displayText.Append("%");
                    }

                    // Set flag.
                    hasReplacement = true;
                }
                // If no current individual replacement, check to see if there's a currently active building/network replacement.
                else if (thisItem.replacementPrefab != null)
                {
                    // A replacement is currently active - include it in the text.
                    displayText.Append(PrefabLists.GetDisplayName(thisItem.replacementPrefab.name));

                    // Append probability to the label, if we're showing it.
                    if (thisItem.showProbs)
                    {
                        displayText.Append(" ");
                        displayText.Append(thisItem.replacementProb);
                        displayText.Append("%");
                    }

                    // Set flag.
                    hasReplacement = true;

                    // Show building replacement sprite.
                    lineSprite.atlas      = TextureUtils.LoadSpriteAtlas(thisNetItem == null ? "bob_single_building_small" : "bob_road_small");
                    lineSprite.spriteName = "normal";
                    lineSprite.tooltip    = Translations.Translate(thisNetItem == null ? "BOB_SPR_SBL" : "BOB_SPR_SNT");
                    lineSprite.Show();
                }
                // If no current building/network replacement, check to see if any all- replacement is currently active.
                else if (thisItem.allPrefab != null)
                {
                    // An all- replacement is currently active; append name to the label.
                    displayText.Append(PrefabLists.GetDisplayName(thisItem.allPrefab.name));

                    // Append probability if this is not a network item and we're showing probs.
                    if (thisNetItem == null && thisItem.showProbs)
                    {
                        displayText.Append(" ");
                        displayText.Append(thisItem.allProb);
                        displayText.Append("%");
                    }

                    // Set flag.
                    hasReplacement = true;

                    // Show all- replacement sprite.
                    lineSprite.atlas      = TextureUtils.LoadSpriteAtlas(thisNetItem == null ? "bob_buildings_small" : "bob_all_roads_small");
                    lineSprite.spriteName = "normal";
                    lineSprite.tooltip    = Translations.Translate(thisNetItem == null ? "BOB_SPR_ABL" : "BOB_SPR_ANT");
                    lineSprite.Show();
                }
                // If no other replacements, chek to see if any pack replacement is currently active
                else if (thisItem.packagePrefab != null)
                {
                    // Yes; append name to the label.
                    displayText.Append(PrefabLists.GetDisplayName(thisItem.packagePrefab.name));

                    // Set flag.
                    hasReplacement = true;

                    // Show package replacement sprite.
                    lineSprite.atlas      = TextureUtils.LoadSpriteAtlas("bob_prop_pack_small");
                    lineSprite.spriteName = "normal";
                    lineSprite.tooltip    = Translations.Translate("BOB_SPR_PCK");
                    lineSprite.Show();
                }

                // Do we have a replacement?
                if (hasReplacement)
                {
                    // Yes; append "was" to the display name.
                    displayText.Append("; ");
                    displayText.Append(Translations.Translate("BOB_ROW_WAS"));
                    displayText.Append(" ");
                }

                // Original prefab display name.
                displayText.Append(PrefabLists.GetDisplayName(thisItem.originalPrefab.name));

                // Show original probability in brackets immediately afterwards.
                if (thisItem.showProbs)
                {
                    displayText.Append(" (");
                    displayText.Append(thisItem.originalProb);
                    displayText.Append("%)");
                }

                // Set display text.
                nameLabel.text = displayText.ToString();
            }
            else
            {
                // Attached data is a raw PropInfo; just display its (cleaned-up) name.
                nameLabel.text = PrefabLists.GetDisplayName(thisPrefab.name);
            }

            // Set label position
            nameLabel.relativePosition = new Vector2(labelX, PaddingY);

            // Set initial background as deselected state.
            Deselect(isRowOdd);
        }
Esempio n. 16
0
        /// <summary>
        /// Performs initial setup
        /// </summary>
        /// <param name="parentTransform">Parent transform</param>
        /// <param name="targetPrefabInfo">Currently selected target prefab</param>
        internal override void Setup(Transform parentTransform, PrefabInfo targetPrefabInfo)
        {
            // Set target reference.
            currentNet = targetPrefabInfo as NetInfo;

            // Base setup.
            base.Setup(parentTransform, targetPrefabInfo);

            // Add pack button.
            UIButton packButton = UIControls.EvenSmallerButton(this, RightX - 200f, TitleHeight + (Margin / 2f), Translations.Translate("BOB_PNL_PKB"));

            packButton.eventClicked += (component, clickEvent) => PackPanelManager.Create();

            // Populate target list and select target item.
            TargetList();

            // Apply Harmony rendering patches.
            Patcher.PatchNetworkOverlays(true);
        }
Esempio n. 17
0
        /// <summary>
        /// Sets the target prefab.
        /// </summary>
        /// <param name="targetPrefabInfo">Target prefab to set</param>
        internal override void SetTarget(PrefabInfo targetPrefabInfo)
        {
            // Don't do anything if invalid target, or target hasn't changed.
            if (!(targetPrefabInfo is BuildingInfo) || selectedPrefab == targetPrefabInfo)
            {
                return;
            }

            // Base setup.
            base.SetTarget(targetPrefabInfo);

            // Set target reference.
            currentBuilding = SelectedBuilding;

            // Does this building have sub-buildings?
            if (currentBuilding.m_subBuildings != null && currentBuilding.m_subBuildings.Length > 0)
            {
                // Yes - create lists of sub-buildings (names and infos).
                int numSubs    = currentBuilding.m_subBuildings.Length;
                int numChoices = numSubs + 1;
                SubBuildingNames    = new string[numChoices];
                subBuildings        = new BuildingInfo[numChoices];
                SubBuildingNames[0] = PrefabLists.GetDisplayName(currentBuilding);
                subBuildings[0]     = currentBuilding;

                object[] subBuildingIndexes = new object[numChoices];
                subBuildingIndexes[0] = 0;

                for (int i = 0; i < numSubs; ++i)
                {
                    SubBuildingNames[i + 1]   = PrefabLists.GetDisplayName(currentBuilding.m_subBuildings[i].m_buildingInfo);
                    subBuildings[i + 1]       = currentBuilding.m_subBuildings[i].m_buildingInfo;
                    subBuildingIndexes[i + 1] = i + 1;
                }

                // Add sub-building menu, if it doesn't already exist.
                if (subBuildingPanel == null)
                {
                    subBuildingPanel = this.AddUIComponent <UIPanel>();

                    // Basic behaviour.
                    subBuildingPanel.autoLayout    = false;
                    subBuildingPanel.canFocus      = true;
                    subBuildingPanel.isInteractive = true;

                    // Appearance.
                    subBuildingPanel.backgroundSprite = "MenuPanel2";
                    subBuildingPanel.opacity          = PanelOpacity;

                    // Size and position.
                    subBuildingPanel.size             = new Vector2(200f, PanelHeight - TitleHeight);
                    subBuildingPanel.relativePosition = new Vector2(-205f, TitleHeight);

                    // Heading.
                    UILabel subTitleLabel = UIControls.AddLabel(subBuildingPanel, 5f, 5f, Translations.Translate("BOB_PNL_SUB"), 190f);
                    subTitleLabel.textAlignment    = UIHorizontalAlignment.Center;
                    subTitleLabel.relativePosition = new Vector2(5f, (TitleHeight - subTitleLabel.height) / 2f);

                    // List panel.
                    UIPanel subBuildingListPanel = subBuildingPanel.AddUIComponent <UIPanel>();
                    subBuildingListPanel.relativePosition = new Vector2(Margin, TitleHeight);
                    subBuildingListPanel.width            = subBuildingPanel.width - (Margin * 2f);
                    subBuildingListPanel.height           = subBuildingPanel.height - TitleHeight - (Margin * 2f);


                    subBuildingList = UIFastList.Create <UISubBuildingRow>(subBuildingListPanel);
                    ListSetup(subBuildingList);

                    // Create return fastlist from our filtered list.
                    subBuildingList.rowsData = new FastList <object>
                    {
                        m_buffer = subBuildingIndexes,
                        m_size   = subBuildingIndexes.Length
                    };
                }
                else
                {
                    // If the sub-building panel has already been created. just make sure it's visible.
                    subBuildingPanel.Show();
                }
            }
            else
            {
                // Otherwise, hide the sub-building panel (if it exists).
                subBuildingPanel?.Hide();
            }

            // Populate target list and select target item.
            TargetList();

            // Apply Harmony rendering patches.
            RenderOverlays.CurrentBuilding = selectedPrefab as BuildingInfo;
            Patcher.PatchBuildingOverlays(true);
        }
Esempio n. 18
0
        /// <summary>
        /// Performs initial setup
        /// </summary>
        /// <param name="parentTransform">Parent transform</param>
        /// <param name="targetPrefabInfo">Currently selected target prefab</param>
        internal override void Setup(Transform parentTransform, PrefabInfo targetPrefabInfo)
        {
            System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
            stopwatch.Start();

            // Set target reference.
            currentBuilding = targetPrefabInfo as BuildingInfo;

            // Base setup.
            base.Setup(parentTransform, targetPrefabInfo);

            Logging.Message("base setup time ", stopwatch.ElapsedMilliseconds.ToString());

            // Add group checkbox.
            indCheck = UIControls.LabelledCheckBox(this, 155f, TitleHeight + Margin, Translations.Translate("BOB_PNL_IND"), 12f, 0.7f);

            // Does this building have sub-buildings?
            if (currentBuilding.m_subBuildings != null && currentBuilding.m_subBuildings.Length > 0)
            {
                // Yes - create lists of sub-buildings (names and infos).
                int      numSubs          = currentBuilding.m_subBuildings.Length;
                int      numChoices       = numSubs + 1;
                string[] subBuildingNames = new string[numChoices];
                subBuildings        = new BuildingInfo[numChoices];
                subBuildingNames[0] = PrefabLists.GetDisplayName(currentBuilding.name);
                subBuildings[0]     = currentBuilding;

                for (int i = 0; i < numSubs; ++i)
                {
                    subBuildingNames[i + 1] = PrefabLists.GetDisplayName(currentBuilding.m_subBuildings[i].m_buildingInfo.name);
                    subBuildings[i + 1]     = currentBuilding.m_subBuildings[i].m_buildingInfo;
                }

                // Add sub-building menu.
                subBuildingMenu = UIControls.AddLabelledDropDown(this, 155f, indCheck.relativePosition.y + indCheck.height + (Margin / 2f), Translations.Translate("BOB_PNL_SUB"), 250f, 20f, 0.7f, 15, 4);
                subBuildingMenu.listBackground = "GenericPanelDark";
                subBuildingMenu.items          = subBuildingNames;
                subBuildingMenu.selectedIndex  = 0;

                // Sub-building menu event handler.
                subBuildingMenu.eventSelectedIndexChanged += (control, index) =>
                {
                    // Set current building.
                    currentBuilding = subBuildings[index];

                    // Reset current items.
                    CurrentTargetItem = null;
                    replacementPrefab = null;

                    // Reset loaded lists.
                    LoadedList();
                    TargetList();
                };
            }

            // Event handler for group checkbox.
            indCheck.eventCheckChanged += (control, isChecked) =>
            {
                // Rebuild target list.
                TargetList();

                // Clear selection.
                targetList.selectedIndex = -1;
                CurrentTargetItem        = null;

                // Store current group state as most recent state.
                ModSettings.lastInd = isChecked;

                // Toggle replace all button visibility.
                if (isChecked)
                {
                    replaceAllButton.Hide();
                }
                else
                {
                    replaceAllButton.Show();
                }
            };

            // Set grouped checkbox initial state according to preferences.
            switch (ModSettings.indDefault)
            {
            case 0:
                // Most recent state.
                indCheck.isChecked = ModSettings.lastInd;
                break;

            case 1:
                // Grouping off by default.
                indCheck.isChecked = false;
                break;

            case 2:
                // Grouping on by default.
                indCheck.isChecked = true;
                break;
            }

            // Populate target list and select target item.
            TargetList();

            Logging.Message("building setup time ", stopwatch.ElapsedMilliseconds.ToString());

            // Apply Harmony rendering patches.
            RenderOverlays.CurrentBuilding = selectedPrefab as BuildingInfo;
            Patcher.PatchBuildingOverlays(true);

            stopwatch.Stop();
            Logging.Message("Harmony patching time ", stopwatch.ElapsedMilliseconds.ToString());
        }
Esempio n. 19
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)
        {
            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");
        }
Esempio n. 20
0
        /// <summary>
        /// Adds configurations panel tab to tabstrip.
        /// </summary>
        /// <param name="tabStrip">Tab strip to add to</param>
        /// <param name="tabIndex">Index number of tab</param>
        internal ConfigurationsPanel(UITabstrip tabStrip, int tabIndex)
        {
            // Set reference.
            instance = this;

            // Determine if we're in-game or not; use status of replacer managers to determine.
            inGame = BuildingReplacement.Instance != null && NetworkReplacement.Instance != null;

            // Add tab and helper.
            UIPanel  panel  = PanelUtils.AddTab(tabStrip, Translations.Translate("BOB_OPT_CFG"), tabIndex);
            UIHelper helper = new UIHelper(panel);

            panel.autoLayout = false;

            // Config list panel.
            UIPanel configListPanel = panel.AddUIComponent <UIPanel>();

            configListPanel.width            = ListWidth;
            configListPanel.height           = ListHeight;
            configListPanel.relativePosition = new Vector2(Margin, ListY);

            // Config selection list.
            configList = UIFastList.Create <UIConfigRow>(configListPanel);
            configList.backgroundSprite  = "UnlockingPanel";
            configList.width             = configListPanel.width;
            configList.height            = configListPanel.height;
            configList.canSelect         = true;
            configList.rowHeight         = RowHeight;
            configList.autoHideScrollbar = true;
            configList.relativePosition  = Vector2.zero;
            configList.rowsData          = new FastList <object>();

            // File name textfield.
            UILabel fileTextLabel = UIControls.AddLabel(panel, ControlPanelX, ListY, "New configuration name:");

            fileNameField = UIControls.AddTextField(panel, ControlPanelX, ListY + fileTextLabel.height);
            fileNameField.eventTextChanged += (control, text) => UpdateButtonStates();

            // Buttons.
            activeCopyButton = UIControls.AddButton(panel, ControlPanelX, ListY + 70f, Translations.Translate("BOB_CFG_SAC"), 300f, scale: 0.8f);
            activeCopyButton.eventClicked   += NewCurrent;
            selectedCopyButton               = UIControls.AddButton(panel, ControlPanelX, ListY + 105f, Translations.Translate("BOB_CFG_SSC"), 300f, scale: 0.8f);
            selectedCopyButton.eventClicked += CopySelected;
            newCleanButton = UIControls.AddButton(panel, ControlPanelX, ListY + 140f, Translations.Translate("BOB_CFG_SEC"), 300f, scale: 0.8f);
            newCleanButton.eventClicked += NewClean;
            deleteButton = UIControls.AddButton(panel, ControlPanelX, ListY + 210f, Translations.Translate("BOB_CFG_DEL"), 300f, scale: 0.8f);
            deleteButton.eventClicked += Delete;

            // Ingame buttons - 'use custom' check and apply and nuke buttons.
            if (inGame)
            {
                // Use custom check box.
                customCheck = UIControls.LabelledCheckBox(panel, Margin, ToolBarY, Translations.Translate("BOB_CFG_UCS"));
                customCheck.eventCheckChanged += (control, isChecked) =>
                {
                    // If we've got a valid selection, set the current config name to this.
                    if (isChecked && !string.IsNullOrEmpty(selectedConfig))
                    {
                        ConfigurationUtils.CurrentSavedConfigName = selectedConfig;
                    }
                };

                // Apply button.
                UIButton applyButton = UIControls.AddButton(panel, Margin, FooterY, Translations.Translate("BOB_CFG_LAA"), 400f, scale: 0.8f);
                applyButton.eventClicked += Apply;

                // Use global configuration button.
                UIButton globalButton = UIControls.AddButton(panel, Margin, FooterY + 50f, Translations.Translate("BOB_CFG_LGL"), 400f, scale: 0.8f);
                globalButton.eventClicked += UseGlobal;

                // Clean up config button.
                UIButton cleanUpButton = UIControls.AddButton(panel, Margin + 50f, FooterY + 150f, Translations.Translate("BOB_CFG_CLE"), 300f);
                cleanUpButton.tooltip       = Translations.Translate("BOB_CFG_CLE_TIP");
                cleanUpButton.eventClicked += (control, clickEvent) => ConfigurationUtils.Cleanup();

                // Nuke all settings button.
                UIButton nukeButton = UIControls.AddButton(panel, Margin + 50f, FooterY + 200f, Translations.Translate("BOB_NUKE"), 300f);
                nukeButton.eventClicked += (control, clickEvent) =>
                {
                    // Revert all-building and building settings.
                    ReplacementUtils.NukeSettings();

                    // Save clean configuration.
                    //ConfigurationUtils.SaveConfig(ConfigurationUtils.CurrentSavedConfigName, true);
                };
            }

            // Populate selection list and set initial button states.
            RefreshList();

            // Select current pack if we've got one.
            if (customCheck != null && customCheck.isChecked)
            {
                // Try to select current config name.
                selectedConfig = configList.FindItem(ConfigurationUtils.CurrentSavedConfigName);

                // Did we find it?
                if (selectedConfig == null)
                {
                    // Not found; uncheck the use custom check.
                    customCheck.isChecked = false;
                }
            }

            // Set initial button states.
            UpdateButtonStates();
        }
Esempio n. 21
0
        /// <summary>
        /// MouseDown event handler to handle mouse clicks; primarily used to prime hotkey entry.
        /// </summary>
        /// <param name="mouseEvent">Mouse button event parameter</param>
        public void OnMouseDown(UIMouseEventParameter mouseEvent)
        {
            // Use the event.
            mouseEvent.Use();

            // Check to see if we're already primed for hotkey entry.
            if (isPrimed)
            {
                // We were already primed; is this a bindable mouse button?
                if (mouseEvent.buttons == UIMouseButton.Left || mouseEvent.buttons == UIMouseButton.Right)
                {
                    // Not a bindable mouse button - set the button text and cancel priming.
                    button.text = SavedInputKey.ToLocalizedString("KEYNAME", ModSettings.CurrentHotkey);
                    UIView.PopModal();
                    isPrimed = false;
                }
                else
                {
                    // Bindable mouse button - do keybinding as if this was a keystroke.
                    KeyCode mouseCode;

                    switch (mouseEvent.buttons)
                    {
                    // Convert buttons to keycodes (we don't bother with left and right buttons as they're non-bindable).
                    case UIMouseButton.Middle:
                        mouseCode = KeyCode.Mouse2;
                        break;

                    case UIMouseButton.Special0:
                        mouseCode = KeyCode.Mouse3;
                        break;

                    case UIMouseButton.Special1:
                        mouseCode = KeyCode.Mouse4;
                        break;

                    case UIMouseButton.Special2:
                        mouseCode = KeyCode.Mouse5;
                        break;

                    case UIMouseButton.Special3:
                        mouseCode = KeyCode.Mouse6;
                        break;

                    default:
                        // No valid button pressed: exit without doing anything.
                        return;
                    }

                    // We got a valid mouse button key - apply settings and save.
                    ApplyKey(SavedInputKey.Encode(mouseCode, IsControlDown(), IsShiftDown(), IsAltDown()));
                }
            }
            else
            {
                // We weren't already primed - set our text and focus the button.
                button.buttonsMask = (UIMouseButton.Left | UIMouseButton.Right | UIMouseButton.Middle | UIMouseButton.Special0 | UIMouseButton.Special1 | UIMouseButton.Special2 | UIMouseButton.Special3);
                button.text        = Translations.Translate("BOB_OPT_PRS");
                button.Focus();

                // Prime for new keybinding entry.
                isPrimed = true;
                UIView.PushModal(button);
            }
        }