Example #1
0
        static VehicleMenu()
        {
            Menu = new UIMenuRefreshable("Siren Configuration", "~y~No vehicle selected");
            MenuController.Pool.AddAfterYield(Menu);
            Menu.WidthOffset             = 250;
            Menu.ControlDisablingEnabled = true;
            Menu.MouseControlsEnabled    = false;
            Menu.AllowCameraMovement     = true;

            BannerItem                      = new UIMenuItem("LiveLights by PNWParksFan", $"LiveLights was created by ~g~PNWParksFan~w~ using the RPH emergency lighting SDK. If you found this plugin useful and made something cool with it, ~y~please mention it in your credits/readme~w~. If you'd like to say thanks, you can donate to support my various modding projects at ~b~parksmods.com/donate~w~ and get member-exclusive perks. Press Enter to learn more!");
            BannerItem.RightLabel           = "v" + EntryPoint.CurrentFileVersion.ToString();
            BannerItem.LeftBadge            = UIMenuItem.BadgeStyle.Heart;
            BannerItem.BackColor            = Color.Black;
            BannerItem.ForeColor            = Color.LightSkyBlue;
            BannerItem.HighlightedBackColor = Color.LightSkyBlue;
            BannerItem.Activated           += OnBannerClicked;
            Menu.AddItem(BannerItem);

            if (EntryPoint.VersionCheck?.IsUpdateAvailable() == true)
            {
                UpdateItem                      = new UIMenuItem("Update Available", $"Version ~y~{EntryPoint.VersionCheck.LatestRelease.TagName}~w~ is available for download. Press ~b~Enter~w~ to download ~y~{EntryPoint.VersionCheck.LatestRelease.Name}~w~.");
                UpdateItem.RightLabel           = "~o~" + EntryPoint.VersionCheck.LatestRelease.TagName;
                UpdateItem.LeftBadge            = UIMenuItem.BadgeStyle.Alert;
                UpdateItem.BackColor            = Color.Black;
                UpdateItem.ForeColor            = Color.LightSkyBlue;
                UpdateItem.HighlightedBackColor = Color.LightSkyBlue;
                Menu.AddItem(UpdateItem);
                UpdateItem.Activated += OnUpdateClicked;
            }

            SirenSettingMenu           = new SirenSettingsSelectionMenu(null, true, true, true, false);
            SirenSettingSelectorItem   = SirenSettingMenu.CreateAndBindToSubmenuItem(Menu);
            SirenConfigMenu            = null; // new EmergencyLightingMenu(null);
            SirenConfigItem            = new UIMenuItem("Edit Emergency Lighting", defaultConfigMenuDesc);
            SirenConfigItem.RightLabel = "→";
            Menu.AddItem(SirenConfigItem);
            // Menu.BindMenuToItem(SirenConfigMenu.Menu, SirenConfigItem);

            EmergencyLightsOnItem = new UIMenuRefreshableCheckboxItem("Emergency Lights Enabled", false, "Toggle flashing lights on this vehicle");
            Menu.AddMenuDataBinding(EmergencyLightsOnItem, (x) => Vehicle.IsSirenOn = x, () => Vehicle.IsSirenOn);

            SirenAudioOnItem = new UIMenuRefreshableCheckboxItem("Siren Audio Enabled", false, "Toggle siren audio on this vehicle");
            Menu.AddMenuDataBinding(SirenAudioOnItem, (x) => Vehicle.IsSirenSilent = !x, () => !Vehicle.IsSirenSilent);

            SirenSettingMenu.OnSirenSettingSelected += OnSirenSelectionChanged;

            Refresh();
            Menu.RefreshIndex();

            if (UpdateItem != null)
            {
                Menu.CurrentSelection = 2;
            }
            else
            {
                Menu.CurrentSelection = 1;
            }
        }
Example #2
0
        public EmergencyLightingMenu(EmergencyLighting els)
        {
            this.ELS = els;

            Menu                         = new UIMenuRefreshable("Emergency Lighting Settings", $"~b~Siren Setting \"{els.Name}\"");
            Menu.WidthOffset             = 250;
            Menu.ControlDisablingEnabled = true;
            Menu.MouseControlsEnabled    = false;
            Menu.AllowCameraMovement     = true;

            // Main siren settings

            NameItem = new UIMenuStringSelector("Name", ELS.Name, "Siren setting name as shown in carcols.meta");
            Menu.AddMenuDataBinding(NameItem, (x) => ELS.Name = x, () => ELS.Name);

            BpmItem = new UIMenuUIntSelector("BPM", ELS.SequencerBpm, "Beats per minute");
            Menu.AddMenuDataBinding(BpmItem, (x) => ELS.SequencerBpm = x, () => ELS.SequencerBpm);

            TimeMultiplierItem = new UIMenuListItemSelector <float>("Time Multiplier", "Adjusts how fast BPM is scaled", ELS.TimeMultiplier, CommonSelectionItems.MultiplierFloat);
            Menu.AddMenuDataBinding(TimeMultiplierItem, (x) => ELS.TimeMultiplier = x, () => ELS.TimeMultiplier);

            TextureHashItem = new UIMenuListItemSelector <string>("Texture Hash", "Texture which is shown for environmental lighting from this vehicle", TextureHash.HashToString(ELS.TextureHash), TextureHash.lightTextureHashes.Values);
            TextureHashItem.ListMenuItem.SetAddNewItems((x) => x);
            Menu.AddMenuDataBinding(TextureHashItem, (x) => ELS.TextureHash = Utils.TextureHash.StringToHash(x), () => Utils.TextureHash.HashToString(ELS.TextureHash));

            FalloffMaxItem = new UIMenuListItemSelector <float>("Falloff Max", "Affects how far environmental lighting shines", ELS.LightFalloffMax, 8, 16, 32, 75, 100, 150, 200, 250, 300);
            Menu.AddMenuDataBinding(FalloffMaxItem, (x) => ELS.LightFalloffMax = x, () => ELS.LightFalloffMax);

            FalloffExponentItem = new UIMenuListItemSelector <float>("Falloff Exponent", "Affects how far environmental lighting shines", ELS.LightFalloffExponent, 8, 16, 32, 75, 100, 150, 200, 250, 300);
            Menu.AddMenuDataBinding(FalloffExponentItem, (x) => ELS.LightFalloffExponent = x, () => ELS.LightFalloffExponent);

            InnerConeAngleItem = new UIMenuListItemSelector <float>("Inner Cone Angle", "Inner angle of environmental lighting cone emitted from sirens", ELS.LightInnerConeAngle, 0f, 3f, 10f, 15f);
            Menu.AddMenuDataBinding(InnerConeAngleItem, (x) => ELS.LightInnerConeAngle = x, () => ELS.LightInnerConeAngle);

            OuterConeAngleItem = new UIMenuListItemSelector <float>("Outer Cone Angle", "Outer angle of environmental lighting cone emitted from sirens", ELS.LightOuterConeAngle, 30f, 40f, 50f, 60f, 70f, 80f, 90f);
            Menu.AddMenuDataBinding(OuterConeAngleItem, (x) => ELS.LightOuterConeAngle = x, () => ELS.LightOuterConeAngle);

            RealLightsItem = new UIMenuRefreshableCheckboxItem("Use Real Lights", ELS.UseRealLights, "Configured whether to use real lights (exact effect unknown)");
            Menu.AddMenuDataBinding(RealLightsItem, (x) => ELS.UseRealLights = x, () => ELS.UseRealLights);

            LightOffsetItem = new UIMenuFloatSelector("Light Offset", ELS.LightOffset, "Lighting offset");
            Menu.AddMenuDataBinding(LightOffsetItem, (x) => ELS.LightOffset = x, () => ELS.LightOffset);

            // Headlights

            HeadlightsMenu                = new UIMenuRefreshable(Menu.TitleText, "~b~Headlights");
            HeadlightsMenuItem            = new UIMenuItem("Headlights", "Modify headlight sequences and multipliers");
            HeadlightsMenuItem.RightLabel = "→";
            Menu.AddItem(HeadlightsMenuItem, 3);
            Menu.BindMenuAndCopyProperties(HeadlightsMenu, HeadlightsMenuItem);

            LeftHeadlightMultiplesItem = new UIMenuListItemSelector <byte>("Front Left Multiples", "Left headlight multiples per flash", ELS.LeftHeadLightMultiples, CommonSelectionItems.MultiplesBytes);
            HeadlightsMenu.AddMenuDataBinding(LeftHeadlightMultiplesItem, (x) => ELS.LeftHeadLightMultiples = x, () => ELS.LeftHeadLightMultiples);

            LeftHeadlightSequenceItem = new UIMenuSequenceItemSelector("Front Left Sequence", ELS.LeftHeadLightSequence, "Left headlight flash pattern sequence");
            HeadlightsMenu.AddMenuDataBinding(LeftHeadlightSequenceItem, (x) => ELS.LeftHeadLightSequence = x, () => ELS.LeftHeadLightSequence);

            RightHeadlightMultiplesItem = new UIMenuListItemSelector <byte>("Front Right Multiples", "Right headlight multiples per flash", ELS.RightHeadLightMultiples, CommonSelectionItems.MultiplesBytes);
            HeadlightsMenu.AddMenuDataBinding(RightHeadlightMultiplesItem, (x) => ELS.RightHeadLightMultiples = x, () => ELS.RightHeadLightMultiples);

            RightHeadlightSequenceItem = new UIMenuSequenceItemSelector("Front Right Sequence", ELS.RightHeadLightSequence, "Right headlight flash pattern sequence");
            HeadlightsMenu.AddMenuDataBinding(RightHeadlightSequenceItem, (x) => ELS.RightHeadLightSequence = x, () => ELS.RightHeadLightSequence);

            // Taillights

            TaillightsMenu                = new UIMenuRefreshable(Menu.TitleText, "~b~Taillights");
            TaillightsMenuItem            = new UIMenuItem("Taillights", "Modify Taillight sequences and multipliers");
            TaillightsMenuItem.RightLabel = "→";
            Menu.AddItem(TaillightsMenuItem, 4);
            Menu.BindMenuAndCopyProperties(TaillightsMenu, TaillightsMenuItem);

            LeftTaillightMultiplesItem = new UIMenuListItemSelector <byte>("Left Rear Multiples", "Left Taillight multiples per flash", ELS.LeftTailLightMultiples, CommonSelectionItems.MultiplesBytes);
            TaillightsMenu.AddMenuDataBinding(LeftTaillightMultiplesItem, (x) => ELS.LeftTailLightMultiples = x, () => ELS.LeftTailLightMultiples);

            LeftTaillightSequenceItem = new UIMenuSequenceItemSelector("Left Rear Sequence", ELS.LeftTailLightSequence, "Left Taillight flash pattern sequence");
            TaillightsMenu.AddMenuDataBinding(LeftTaillightSequenceItem, (x) => ELS.LeftTailLightSequence = x, () => ELS.LeftTailLightSequence);

            RightTaillightMultiplesItem = new UIMenuListItemSelector <byte>("Right Rear Multiples", "Right Taillight multiples per flash", ELS.RightTailLightMultiples, CommonSelectionItems.MultiplesBytes);
            TaillightsMenu.AddMenuDataBinding(RightTaillightMultiplesItem, (x) => ELS.RightTailLightMultiples = x, () => ELS.RightTailLightMultiples);

            RightTaillightSequenceItem = new UIMenuSequenceItemSelector("Right Rear Sequence", ELS.RightTailLightSequence, "Right Taillight flash pattern sequence");
            TaillightsMenu.AddMenuDataBinding(RightTaillightSequenceItem, (x) => ELS.RightTailLightSequence = x, () => ELS.RightTailLightSequence);

            // Sirens

            SirensMenuItem            = new UIMenuItem("Sirens", "Edit sequences and other settings for individual sirens");
            SirensMenuItem.RightLabel = "→";
            Menu.AddItem(SirensMenuItem, 3);
            SirensMenuItem.Activated += onSirenSubmenuActivated;
            SirenMenus = new List <EmergencyLightMenu>();

            // Create each siren menu
            for (int i = 0; i < 20; i++)
            {
                EmergencyLightMenu sirenMenu = new EmergencyLightMenu(ELS, i);
                sirenMenu.Menu.ParentItem = SirensMenuItem;
                sirenMenu.Menu.ParentMenu = Menu;
                Menu.AddSubMenuBinding(sirenMenu.Menu);
                Menu.CopyMenuProperties(sirenMenu.Menu, true);
                MenuController.Pool.AddMenuAndSubMenusToPool(sirenMenu.Menu, true);
                SirenMenus.Add(sirenMenu);
            }

            // Create switcher and add to menus
            // This has to be after the for loop above because all the menus need to be created before the switcher can be created
            SirenSwitcherItem = new UIMenuSwitchSelectable("Siren", "Select the siren to edit", SirenMenus);
            foreach (var sirenMenu in SirenMenus)
            {
                sirenMenu.Menu.AddItem(SirenSwitcherItem, 0);
                sirenMenu.Menu.RefreshIndex();
            }

            // Final stuff

            SequenceQuickEdit     = new SequenceQuickEditMenu(ELS, this);
            SequenceQuickEditItem = new UIMenuItem("Siren Sequence Quick Edit", "Edit flashiness sequences for all sirens on this siren setting at once");
            Menu.BindMenuAndCopyProperties(SequenceQuickEdit.Menu, SequenceQuickEditItem);
            SequenceQuickEditItem.Activated += OnQuickEditMenuOpened;
            Menu.AddItem(SequenceQuickEditItem, 4);
            SequenceQuickEditItem.RightLabel = "→";

            RefreshItem = new UIMenuItem("Refresh Siren Setting Data", "Refreshes the menu with the siren setting data for the current vehicle. Use this if the data may have been changed outside the menu.");
            Menu.AddRefreshItem(RefreshItem);

            CopyMenu                = new CopyMenu(this);
            CopyMenuItem            = new UIMenuItem("Copy", "Copy properties to/from this siren setting");
            CopyMenuItem.RightLabel = "→";
            Menu.BindMenuAndCopyProperties(CopyMenu.Menu, CopyMenuItem);
            Menu.AddItem(CopyMenuItem);

            /*
             * ImportCarcolsItem = new UIMenuItem("Import carcols.meta file", "Imports all siren settings in selected carcols.meta file");
             * Menu.AddItem(ImportCarcolsItem);
             * ImportCarcolsItem.Activated += OnImportExportClicked;
             */

            ExportCarcolsItem = new UIMenuItem("Export carcols.meta file", "Exports the siren setting currently being modified to a carcols.meta file");
            Menu.AddItem(ExportCarcolsItem);
            ExportCarcolsItem.Activated += OnImportExportClicked;

            ExportAllowOverwriteItem = new UIMenuCheckboxItem("Allow overwrite on export", Settings.DefaultOverwrite, "Allow exported carcols.meta files to overwrite existing files with the same name");
            Menu.AddItem(ExportAllowOverwriteItem);

            MenuController.Pool.AddAfterYield(Menu, HeadlightsMenu, TaillightsMenu, SequenceQuickEdit.Menu, CopyMenu.Menu);

            Menu.RefreshIndex();
        }
        public EmergencyLightMenu(EmergencyLighting els, int i)
        {
            this.Siren   = els.Lights[i];
            this.SirenID = (i + 1);

            Menu = new UIMenuRefreshable("Edit Siren", $"~b~Siren Setting \"{els.Name}\" > {DisplayText}");

            // Set up flashiness sub-menu
            FlashinessMenu                = new UIMenuRefreshable(Menu.TitleText, Menu.SubtitleText + " > Flashiness");
            FlashinessMenuItem            = new UIMenuItem("Flashiness Settings", "Configure sequence, multiples, angle, and other settings for ~y~flashing~w~ light");
            FlashinessMenuItem.RightLabel = "→";
            Menu.AddItem(FlashinessMenuItem);
            Menu.BindMenuToItem(FlashinessMenu, FlashinessMenuItem);

            // Set up rotation sub-menu
            RotationMenu                = new UIMenuRefreshable(Menu.TitleText, Menu.SubtitleText + " > Rotation");
            RotationMenuItem            = new UIMenuItem("Rotation Settings", "Configure sequence, multiples, angle, and other settings for ~y~rotating~w~ light");
            RotationMenuItem.RightLabel = "→";
            Menu.AddItem(RotationMenuItem);
            Menu.BindMenuToItem(RotationMenu, RotationMenuItem);

            // Set up corona sub-menu
            CoronaMenu                = new UIMenuRefreshable(Menu.TitleText, Menu.SubtitleText + " > Corona");
            CoronaMenuItem            = new UIMenuItem("Corona Settings", "Configure size, intensity, and other corona settings");
            CoronaMenuItem.RightLabel = "→";
            Menu.AddItem(CoronaMenuItem);
            Menu.BindMenuToItem(CoronaMenu, CoronaMenuItem);

            // Flashiness menu items
            FlashEnabledItem = new UIMenuRefreshableCheckboxItem("Flash Enabled", Siren.Flash, "Enable/disable this siren from flashing. Note: setting to False for a siren which was previously on may result in the siren being stuck on temporarily. Toggle vehicle's sirens off/on to reset.");
            FlashinessMenu.AddMenuDataBinding(FlashEnabledItem, (x) => Siren.Flash = x, () => Siren.Flash);

            FlashSequenceItem = new UIMenuSequenceItemSelector("Flash Sequence", Siren.FlashinessSequence, $"32-bit flash sequence for siren {SirenID}. ~g~1~w~ represents on, ~y~0~w~ represents off.");
            FlashinessMenu.AddMenuDataBinding(FlashSequenceItem, (x) => Siren.FlashinessSequence = x, () => Siren.FlashinessSequence, () => FlashSequenceRawItem);

            FlashSequenceRawItem = new UIMenuUIntSelector("Flash Sequence (raw)", Siren.FlashinessSequenceRaw, "32-bit unsigned integer representation of siren sequence. This value is how the sequence is represented in carcols.meta. Automatically updates/updated by binary formatted sequence above.");
            FlashinessMenu.AddMenuDataBinding(FlashSequenceRawItem, (x) => Siren.FlashinessSequenceRaw = x, () => Siren.FlashinessSequenceRaw, () => FlashSequenceItem);

            FlashMultiplesItem = new UIMenuListItemSelector <byte>("Flash Multiples", "How many times the corona flashes for each sequence step the light is on", Siren.FlashinessMultiples, CommonSelectionItems.MultiplesBytes);
            FlashinessMenu.AddMenuDataBinding(FlashMultiplesItem, (x) => Siren.FlashinessMultiples = x, () => Siren.FlashinessMultiples);

            FlashDeltaItem = new UIMenuListItemSelector <float>("Flash Delta", "Angle the light should flash at", Siren.FlashinessDelta, CommonSelectionItems.UnitCircleDegrees);
            FlashinessMenu.AddMenuDataBinding(FlashDeltaItem, (x) => Siren.FlashinessDelta = x, () => Siren.FlashinessDelta, () => FlashDeltaRadItem);

            FlashDeltaRadItem = new UIMenuFloatSelector("Flash Delta (Radians)", MathHelper.ConvertDegreesToRadians(Siren.FlashinessDelta), "Angle the light should flash at in radians");
            FlashinessMenu.AddMenuDataBinding(FlashDeltaRadItem, (x) => Siren.FlashinessDelta = MathHelper.ConvertRadiansToDegrees(x), () => MathHelper.ConvertDegreesToRadians(Siren.FlashinessDelta), () => FlashDeltaItem);

            FlashStartItem = new UIMenuListItemSelector <float>("Flash Start", "Starting rotation angle of the light (usually 0 for flashing sirens)", Siren.FlashinessStart, CommonSelectionItems.UnitCircleDegrees);
            FlashinessMenu.AddMenuDataBinding(FlashStartItem, (x) => Siren.FlashinessStart = x, () => Siren.FlashinessStart, () => FlashStartRadItem);

            FlashStartRadItem = new UIMenuFloatSelector("Flash Start (Radians)", MathHelper.ConvertDegreesToRadians(Siren.FlashinessStart), "Starting rotation angle of the light in radians");
            FlashinessMenu.AddMenuDataBinding(FlashStartRadItem, (x) => Siren.FlashinessStart = MathHelper.ConvertRadiansToDegrees(x), () => MathHelper.ConvertDegreesToRadians(Siren.FlashinessStart), () => FlashStartItem);

            FlashSpeedItem = new UIMenuFloatSelector("Flash Speed", Siren.FlashinessSpeed, "How fast the light flashes within each beat");
            FlashinessMenu.AddMenuDataBinding(FlashSpeedItem, (x) => Siren.FlashinessSpeed = x, () => Siren.FlashinessSpeed);

            FlashDirectionItem = new UIMenuRefreshableCheckboxItem("Flash Direction Enabled", Siren.FlashinessDirection, "Enable/disable flash direction");
            FlashinessMenu.AddMenuDataBinding(FlashDirectionItem, (x) => Siren.FlashinessDirection = x, () => Siren.FlashinessDirection);

            FlashSyncBpmItem = new UIMenuRefreshableCheckboxItem("Sync Flash to BPM", Siren.FlashinessSynchronizeToBpm, "Sync flash pattern to BPM");
            FlashinessMenu.AddMenuDataBinding(FlashSyncBpmItem, (x) => Siren.FlashinessSynchronizeToBpm = x, () => Siren.FlashinessSynchronizeToBpm);

            ScaleToggleItem = new UIMenuRefreshableCheckboxItem("Scale Sirens", Siren.Scale, "Enable/disable scaling sirens up when they flash. Should be enabled for flashing lights and disabled for rotating lights.");
            FlashinessMenu.AddMenuDataBinding(ScaleToggleItem, (x) => Siren.Scale = x, () => Siren.Scale);

            ScaleFactorItem = new UIMenuListItemSelector <byte>("Scale Factor", "How much to scale up siren when siren is flashed on. Default is 2 for most flashing sirens.", Siren.ScaleFactor, CommonSelectionItems.ScaleFactorByte);
            FlashinessMenu.AddMenuDataBinding(ScaleFactorItem, (x) => Siren.ScaleFactor = x, () => Siren.ScaleFactor);

            // Rotation menu items
            RotationEnabledItem = new UIMenuRefreshableCheckboxItem("Rotation Enabled", Siren.Rotate, "Enable/disable this siren from rotating. Note: setting to False for a siren which was previously on may result in the siren being stuck on temporarily. Toggle vehicle's sirens off/on to reset.");
            RotationMenu.AddMenuDataBinding(RotationEnabledItem, (x) => Siren.Rotate = x, () => Siren.Rotate);

            RotationSequenceItem = new UIMenuSequenceItemSelector("Rotation Sequence", Siren.RotationSequence, $"32-bit Rotation sequence for siren {SirenID}. ~g~1~w~ represents on, ~y~0~w~ represents off.");
            RotationMenu.AddMenuDataBinding(RotationSequenceItem, (x) => Siren.RotationSequence = x, () => Siren.RotationSequence, () => RotationSequenceRawItem);

            RotationSequenceRawItem = new UIMenuUIntSelector("Rotation Sequence (raw)", Siren.RotationSequenceRaw, "32-bit unsigned integer representation of siren sequence. This value is how the sequence is represented in carcols.meta. Automatically updates/updated by binary formatted sequence above.");
            RotationMenu.AddMenuDataBinding(RotationSequenceRawItem, (x) => Siren.RotationSequenceRaw = x, () => Siren.RotationSequenceRaw, () => RotationSequenceItem);

            RotationMultiplesItem = new UIMenuListItemSelector <byte>("Rotation Multiples", "How many times the corona rotates for each sequence step the light is on", Siren.RotationMultiples, CommonSelectionItems.MultiplesBytes);
            RotationMenu.AddMenuDataBinding(RotationMultiplesItem, (x) => Siren.RotationMultiples = x, () => Siren.RotationMultiples);

            RotationDeltaItem = new UIMenuListItemSelector <float>("Rotation Delta", "Angle the light should rotate to", Siren.RotationDelta, CommonSelectionItems.UnitCircleDegrees);
            RotationMenu.AddMenuDataBinding(RotationDeltaItem, (x) => Siren.RotationDelta = x, () => Siren.RotationDelta, () => RotationDeltaRadItem);

            RotationDeltaRadItem = new UIMenuFloatSelector("Rotation Delta (Radians)", MathHelper.ConvertDegreesToRadians(Siren.RotationDelta), "Angle the light should rotate to in radians");
            RotationMenu.AddMenuDataBinding(RotationDeltaRadItem, (x) => Siren.RotationDelta = MathHelper.ConvertRadiansToDegrees(x), () => MathHelper.ConvertDegreesToRadians(Siren.RotationDelta), () => RotationDeltaItem);

            RotationStartItem = new UIMenuListItemSelector <float>("Rotation Start", "Starting rotation angle of the light", Siren.RotationStart, CommonSelectionItems.UnitCircleDegrees);
            RotationMenu.AddMenuDataBinding(RotationStartItem, (x) => Siren.RotationStart = x, () => Siren.RotationStart, () => RotationStartRadItem);

            RotationStartRadItem = new UIMenuFloatSelector("Rotation Start (Radians)", MathHelper.ConvertDegreesToRadians(Siren.RotationStart), "Starting rotation angle of the light in radians");
            RotationMenu.AddMenuDataBinding(RotationStartRadItem, (x) => Siren.RotationStart = MathHelper.ConvertRadiansToDegrees(x), () => MathHelper.ConvertDegreesToRadians(Siren.RotationStart), () => RotationStartItem);

            RotationSpeedItem = new UIMenuFloatSelector("Rotation Speed", Siren.RotationSpeed, "How fast the light rotates within each beat");
            RotationMenu.AddMenuDataBinding(RotationSpeedItem, (x) => Siren.RotationSpeed = x, () => Siren.RotationSpeed);

            RotationDirectionItem = new UIMenuRefreshableCheckboxItem("Rotation Direction Enabled", Siren.RotationDirection, "Enable/disable rotation direction");
            RotationMenu.AddMenuDataBinding(RotationDirectionItem, (x) => Siren.RotationDirection = x, () => Siren.RotationDirection);

            RotationSyncBpmItem = new UIMenuRefreshableCheckboxItem("Sync Rotation to BPM", Siren.RotationSynchronizeToBpm, "Sync Rotation pattern to BPM");
            RotationMenu.AddMenuDataBinding(RotationSyncBpmItem, (x) => Siren.RotationSynchronizeToBpm = x, () => Siren.RotationSynchronizeToBpm);

            // Corona menu items
            CoronaIntensityItem = new UIMenuFloatSelector("Corona Intensity", Siren.CoronaIntensity, "Brightness/intensity of the corona for this siren");
            CoronaMenu.AddMenuDataBinding(CoronaIntensityItem, (x) => Siren.CoronaIntensity = x, () => Siren.CoronaIntensity);

            CoronaSizeItem = new UIMenuFloatSelector("Corona Size", Siren.CoronaSize, "Size of corona for this siren");
            CoronaMenu.AddMenuDataBinding(CoronaSizeItem, (x) => Siren.CoronaSize = x, () => Siren.CoronaSize);

            CoronaPullItem = new UIMenuFloatSelector("Corona Pull", Siren.CoronaPull, "Corona pull, affects how visible corona is through vehicle mesh");
            CoronaMenu.AddMenuDataBinding(CoronaPullItem, (x) => Siren.CoronaPull = x, () => Siren.CoronaPull);

            CoronaFaceCameraItem = new UIMenuRefreshableCheckboxItem("Corona Face Camera", Siren.CoronaFaceCamera, "Enable/disable corona to always be visible regardless of camera angle");
            CoronaMenu.AddMenuDataBinding(CoronaFaceCameraItem, (x) => Siren.CoronaFaceCamera = x, () => Siren.CoronaFaceCamera);

            // Remaining main menu items
            EnvLightItem = new UIMenuRefreshableCheckboxItem("Env Light", Siren.Light, "Enable/disable environmental lighting from this siren");
            Menu.AddMenuDataBinding(EnvLightItem, (x) => Siren.Light = x, () => Siren.Light);

            ColorItem = new UIMenuColorSelector("Color", "Color of corona and environmental lighting from this siren. You can any typical recognized color name (e.g. \"Indigo\"), or hex format as 0xAARRGGBB or 0xRRGGBB (e.g. \"0xFFFF00AA\").", Siren.Color, Settings.DefaultColors);
            Menu.AddMenuDataBinding(ColorItem, (x) => Siren.Color = x, () => Siren.Color);

            IntensityItem = new UIMenuListItemSelector <float>("Intensity", "Intensity of environmental lighting emitted by this light", Siren.Intensity, CommonSelectionItems.IntensityFloat);
            Menu.AddMenuDataBinding(IntensityItem, (x) => Siren.Intensity = x, () => Siren.Intensity);

            SpotLightItem = new UIMenuRefreshableCheckboxItem("Spot Light", Siren.SpotLight, "Enable/disable spotlight effect on environmental light from this siren");
            Menu.AddMenuDataBinding(SpotLightItem, (x) => Siren.SpotLight = x, () => Siren.SpotLight);

            CastShadowsItem = new UIMenuRefreshableCheckboxItem("Cast Shadows", Siren.CastShadows, "Enable/disable casting shadows with environmental light from this siren");
            Menu.AddMenuDataBinding(CastShadowsItem, (x) => Siren.CastShadows = x, () => Siren.CastShadows);

            LightGroupItem = new UIMenuListItemSelector <byte>("Light Group", "Light group for siren. Usage not documented.", Siren.LightGroup, CommonSelectionItems.LightGroupByte);
            Menu.AddMenuDataBinding(LightGroupItem, (x) => Siren.LightGroup = x, () => Siren.LightGroup);

            // Final setup
            FlashinessMenu.RefreshIndex();
            RotationMenu.RefreshIndex();
            CoronaMenu.RefreshIndex();
            Menu.RefreshIndex();
        }