protected AbstractUiElement BuildUi()
        {
            // Normally, the selectLast flag indicates that a new element was just added to the end
            // of the list and should be selected. Now that we've reversed the list, new elements
            // are added to the beginning. We neuter the regular processing by forcing the flag
            // to false, and compensate by selecting the first screen, then selecting the first
            // entry once the original has finished building the screen.
            bool savedSelectLast = selectLast;

            selectLast = false;
            if (savedSelectLast)
            {
                currentScreen = 0;
            }
            AbstractUiElement result = OriginalBuildUi();

            if (savedSelectLast)
            {
                visiblePuzzles.First().SetSelected(true);
                // This method is called by the original, but now that we've changed the
                // selection, it must be called again to make sure the right buttons
                // are enabled.
                UpdateEnabledStateOfButtons();
            }
            return(result);
        }
Example #2
0
        private AbstractUiElement BuildReactorComponentsOptions()
        {
            // in-line array initialization causes the compiler to emit some code the patcher doesn't
            // support at the moment, so we'll initialize the arrays in the tedious long-hand way.
            int[] bonderCountOptions = new int[4];
            bonderCountOptions[0] = 0;
            bonderCountOptions[1] = 2;
            bonderCountOptions[2] = 4;
            bonderCountOptions[3] = 8;

            int[] extendedFeatureCountOptions = new int[5];
            for (int i = 0; i < 5; i++)
            {
                extendedFeatureCountOptions[i] = i;
            }

            int[] tunnelCountOptions = new int[4];
            tunnelCountOptions[0] = 0;
            tunnelCountOptions[1] = 2;
            tunnelCountOptions[2] = 3;
            tunnelCountOptions[3] = 4;

            AbstractUiElement[] firstRow = new AbstractUiElement[3];
            firstRow[0] = BuildReactorComponentOption(FeatureType.Bonder, bonderCountOptions);
            firstRow[1] = BuildReactorComponentOption(FeatureType.Sensor, extendedFeatureCountOptions);
            firstRow[2] = BuildReactorComponentOption(FeatureType.Teleporter, tunnelCountOptions);

            AbstractUiElement[] secondRow = new AbstractUiElement[2];
            secondRow[0] = BuildReactorComponentOption(FeatureType.Fuser, extendedFeatureCountOptions);
            secondRow[1] = BuildReactorComponentOption(FeatureType.Splitter, extendedFeatureCountOptions);

            AbstractUiElement[] rows = new AbstractUiElement[2];
            // Adjust the horizontal padding from 30px to 20px so the content won't overflow
            rows[0] = AbstractUiElement.LayoutHorizontally(VerticalAlignment.Center, 20, firstRow);
            rows[1] = AbstractUiElement.LayoutHorizontally(VerticalAlignment.Center, 20, secondRow);

            return(AbstractUiElement.LayoutVertically(HorizontalAlignment.Center, 20, rows));
        }
Example #3
0
        private void ShowPerformanceTab()
        {
            Optional <string>            cycleCounts       = (Optional <string>)Empty.INSTANCE;
            Optional <string>            reactorCounts     = (Optional <string>)Empty.INSTANCE;
            Optional <string>            symbolCounts      = (Optional <string>)Empty.INSTANCE;
            Optional <HistogramsContent> histogramsContent = LocalHistogramsUtils.GetScoreOrEmpty(CurrentPuzzle.name);

            if (histogramsContent.isPresent)
            {
                cycleCounts   = (Optional <string>)histogramsContent.GetValue().cycleCounts;
                reactorCounts = (Optional <string>)histogramsContent.GetValue().reactorCounts;
                symbolCounts  = (Optional <string>)histogramsContent.GetValue().symbolCounts;
            }
            bool isDefense = PuzzleManager.IsDefense(CurrentPuzzle.name);
            AbstractRenderable completedLabel = AbstractRenderable.MakeColoredLabel(FontManager.huge, Localization.Localize("Assignment Complete!", "ENGLISH ALPHABET ONLY"), LabelFactory.darkYellow);
            AbstractRenderable mainUIBlock;

            // here is the only change: the section that made a dummy box in the defense case was removed,
            // so that we show full metrics for them as well (sadly the game has no hist data)
            if (Constants.ShowLeaderboards())
            {
                Optional <MetricLeaderboard> cyclesLB   = PuzzlesUtils.GetSteamLBForLevelAndMetric(CurrentPuzzle.name, MetricType.Cycles);
                Optional <MetricLeaderboard> reactorsLB = PuzzlesUtils.GetSteamLBForLevelAndMetric(CurrentPuzzle.name, MetricType.Reactors);
                Optional <MetricLeaderboard> symbolsLB  = PuzzlesUtils.GetSteamLBForLevelAndMetric(CurrentPuzzle.name, MetricType.Symbols);
                Optional <int>     thisCycles           = thisScore.isPresent ? GetCycles_1(thisScore.GetValue()) : Optional <int> .ABSENT;
                Optional <int>     bestCycles           = bestScore.isPresent ? GetCycles_2(bestScore.GetValue()) : Optional <int> .ABSENT;
                Optional <int>     newBestCycles        = MinOptional(thisCycles, bestCycles);
                Optional <int>     thisReactors         = thisScore.isPresent ? GetReactors_1(thisScore.GetValue()) : Optional <int> .ABSENT;
                Optional <int>     bestReactors         = bestScore.isPresent ? GetReactors_2(bestScore.GetValue()) : Optional <int> .ABSENT;
                Optional <int>     newBestReactors      = MinOptional(thisReactors, bestReactors);
                Optional <int>     thisSymbols          = thisScore.isPresent ? GetSymbols_1(thisScore.GetValue()) : Optional <int> .ABSENT;
                Optional <int>     bestSymbols          = bestScore.isPresent ? GetSymbols_2(bestScore.GetValue()) : Optional <int> .ABSENT;
                Optional <int>     newBestSymbols       = MinOptional(thisSymbols, bestSymbols);
                AbstractRenderable pressTABLabel        = AbstractRenderable.EMPTY;
                if (SystemUtils.isSteamVersion)
                {
                    pressTABLabel = FontManager.tooltip.MakeRenderable(Localization.Localize("Press Tab to view\nGRAPHS."), HorizontalAlignment.Center, (Optional <int>)Empty.INSTANCE).WithColor(LabelFactory.paleBlue);
                }
                mainUIBlock = completedLabel.WithAddedRenderableBelow(AbstractRenderable.LayoutVertically(HorizontalAlignment.Center, 20, new AbstractRenderable[2]
                {
                    AbstractRenderable.MakeColoredLabel(FontManager.large, Localization.Localize("Your performance, compared to other engineers, is as follows:"), LabelFactory.paleBlue),
                    AbstractRenderable.LayoutHorizontally(VerticalAlignment.Center, 40, new AbstractRenderable[4]
                    {
                        pressTABLabel,
                        HistogramUtils.MakeLeaderboard(cyclesLB, newBestCycles, HistogramUtils.elapsedCycles, false, false, false),
                        HistogramUtils.MakeLeaderboard(reactorsLB, newBestReactors, HistogramUtils.reactorsUsed, false, false, false),
                        HistogramUtils.MakeLeaderboard(symbolsLB, newBestSymbols, HistogramUtils.symbolsUsed, false, false, false)
                    })
                }), HorizontalAlignment.Center, 20);
            }
            else
            {
                AbstractRenderable pressTABLabel = AbstractRenderable.EMPTY;
                if (SystemUtils.isSteamVersion)
                {
                    pressTABLabel = FontManager.tooltip.MakeRenderable(Localization.Localize("Press Tab to view\nLEADERBOARDS."), HorizontalAlignment.Center, (Optional <int>)Empty.INSTANCE).WithColor(LabelFactory.paleBlue);
                }
                AbstractRenderable[] histogramsBlock = new AbstractRenderable[4]
                {
                    pressTABLabel,
                    null,
                    null,
                    null
                };
                Optional <int>     thisCycles = thisScore.isPresent ? GetCycles_3(thisScore.GetValue()) : Optional <int> .ABSENT;
                Optional <int>     bestCycles = bestScore.isPresent ? GetCycles_4(bestScore.GetValue()) : Optional <int> .ABSENT;
                AbstractRenderable cyclesHist = HistogramUtils.MakeHistogram(cycleCounts, thisCycles, bestCycles, Localization.Localize("THIS"),
                                                                             HistogramUtils.elapsedCycles, false, false, false);
                histogramsBlock[1] = cyclesHist;
                Optional <int>     thisReactors = thisScore.isPresent ? GetReactors_3(thisScore.GetValue()) : Optional <int> .ABSENT;
                Optional <int>     bestReactors = bestScore.isPresent ? GetReactors_4(bestScore.GetValue()) : Optional <int> .ABSENT;
                AbstractRenderable reactorsHist = HistogramUtils.MakeHistogram(reactorCounts, thisReactors, bestReactors, Localization.Localize("THIS"),
                                                                               HistogramUtils.reactorsUsed, false, false, false);
                histogramsBlock[2] = reactorsHist;
                Optional <int>     thisSymbols = thisScore.isPresent ? GetSymbols_3(thisScore.GetValue()) : Optional <int> .ABSENT;
                Optional <int>     bestSymbols = bestScore.isPresent ? GetSymbols_4(bestScore.GetValue()) : Optional <int> .ABSENT;
                AbstractRenderable symbolsHist = HistogramUtils.MakeHistogram(symbolCounts, thisSymbols, bestSymbols, Localization.Localize("THIS"),
                                                                              HistogramUtils.symbolsUsed, false, false, false);
                histogramsBlock[3] = symbolsHist;
                AbstractRenderable   histogramsRow = AbstractRenderable.LayoutHorizontally(VerticalAlignment.Center, 40, histogramsBlock);
                AbstractRenderable[] mainBlock     = new AbstractRenderable[2]
                {
                    AbstractRenderable.MakeColoredLabel(FontManager.large, Localization.Localize("Your performance, compared to other engineers, is as follows:"), LabelFactory.paleBlue),
                    histogramsRow
                };
                AbstractRenderable mainRow = AbstractRenderable.LayoutVertically(HorizontalAlignment.Center, 20, mainBlock);
                mainUIBlock = completedLabel.WithAddedRenderableBelow(mainRow, HorizontalAlignment.Center, 20);
            }
            AbstractRenderable     achievBox       = BoxesButtonsFactory.MakeAngledBox(new Vector2i(560, 150), LabelFactory.paleBlue, LabelFactory.gray);
            Optional <Achievement> completedAchiev = CurrentPuzzle.GetCompletedAchievement();

            if (this.plaqueLevel.isPresent)
            {
                achievBox = achievBox.WithAddedCenteredRenderable(AbstractRenderable.MakeColoredLabel(FontManager.medium, Localization.Localize("Congratulations! You have been promoted to"), LabelFactory.paleBlue)
                                                                  .WithAddedRenderableBelow(AbstractRenderable.MakeColoredLabel(FontManager.large, this.plaqueLevel.GetValue(), LabelFactory.paleBlue), HorizontalAlignment.Center, 10));
            }
            else if (completedAchiev.isPresent && completedAchiev.GetValue().showAtLevelEnd)
            {
                achievBox = achievBox.WithAddedCenteredRenderable(AbstractRenderable.MakeColoredLabel(FontManager.large, Localization.Localize("Challenge complete!"), LabelFactory.paleBlue)
                                                                  .WithAddedRenderableBelow(completedAchiev.GetValue().AchievIcon(), HorizontalAlignment.Center, 0));
            }
            AbstractRenderable recordButtonContent = AbstractRenderable.LayoutVertically(HorizontalAlignment.Center, 0, new AbstractRenderable[5]
            {
                AbstractRenderable.MakeLabel(FontManager.large, Localization.Localize("Record Solution")),
                FontManager.normal.MakeRenderable(Localization.Localize("After recording your solution, you can save the video to your desktop or upload it to a YouTube account."), HorizontalAlignment.Center, (Optional <int>) 280),
                AbstractRenderable.MakeBlankRenderable(new BoundingBox(0, 0, 1, 8)),
                AbstractRenderable.MakeTexturedRectangle(ResourceUtils.LoadResource <TextureElement>("misc/youtube_small")),
                AbstractRenderable.MakeBlankRenderable(new BoundingBox(0, 0, 1, 8))
            });

            if (isDefense)
            {
                recordButtonContent = AbstractRenderable.MakeColoredLabel(FontManager.large, Localization.Localize("Record Solution"), LabelFactory.paleBlue)
                                      .WithAddedRenderableBelow(FontManager.normal.MakeRenderable(Localization.Localize("The details of this assignment are SpaceChem confidential and may not be shared with unprivileged employees."), HorizontalAlignment.Center, (Optional <int>) 280), HorizontalAlignment.Center, 0);
            }
            if (AbstractGame.FBOUnavailable || SystemUtils.GetOnlive())
            {
                recordButtonContent = AbstractRenderable.MakeColoredLabel(FontManager.large, Localization.Localize("Record Solution"), LabelFactory.paleBlue)
                                      .WithAddedRenderableBelow(FontManager.normal.MakeRenderable(Localization.Localize("This action is disabled."), HorizontalAlignment.Center, (Optional <int>) 280), HorizontalAlignment.Center, 0);
            }
            Button             recordButton;
            AbstractRenderable achievUIBlock = achievBox.WithAddedRenderableAbove(AbstractRenderable.MakeColoredLabel(FontManager.large, Localization.Localize("Additional Information"), LabelFactory.darkYellow), HorizontalAlignment.Right, 10);
            AbstractUiElement  performanceUI = AbstractUiElement.LayoutVertically(HorizontalAlignment.Center, 20, new AbstractUiElement[2]
            {
                (AbstractUiElement)mainUIBlock,
                AbstractUiElement.LayoutHorizontally(VerticalAlignment.Center, 30, new AbstractUiElement[2]
                {
                    (AbstractUiElement)achievUIBlock,
                    AbstractUiElement.LayoutVertically(HorizontalAlignment.Center, 15, new AbstractUiElement[1]
                    {
                        (recordButton = LabelFactory.MakeButtonWithContent(recordButtonContent, new Vector2i(300, 200), new Action(OpenRecordingScreen)))
                    })
                })
            });

            if (AbstractGame.FBOUnavailable || isDefense || SystemUtils.GetOnlive())
            {
                recordButton.SetEnabled(false);
            }
            AbstractRenderable performanceTab = AbstractRenderable.MakeTexturedRectangle(ResourceUtils.LoadResource <TextureElement>("mainmenu/story_background")).WithTranslation(7, 59)
                                                .NullSafeWithAddedRenderable(MakeTabButtonState(Localization.Localize("Performance"), false, false).WithTranslation(AfterVictoryScreen.positionTab3))
                                                .NullSafeWithAddedRenderable(AbstractRenderable.MakeTexturedRectangle(ResourceUtils.LoadResource <TextureElement>("mainmenu/story_tab_bottom")).WithTranslation(AfterVictoryScreen.positionTab3 + new Vector2i(0, 52)));

            wholeUI = new WholeUI((AbstractUI) new UiElementContainer(new ContainedUiElement[5]
            {
                new ContainedUiElement(Vector2i.NULL, MakeTopBar()),
                new ContainedUiElement(new Vector2i(AfterVictoryScreen.positionTab1), MakeTabButton(Localization.Localize("Story"), storyIsPresentAndUnlocked, new Action(ShowStoryTab_1))),
                new ContainedUiElement(new Vector2i(AfterVictoryScreen.positionTab2), MakeTabButton(Localization.Localize("Training"), trainingIsPresentAndUnlocked, new Action(ShowTrainingTab_1))),
                new ContainedUiElement(Vector2i.NULL, (AbstractUiElement)performanceTab),
                new ContainedUiElement(new Vector2i(512, 120), performanceUI)
            }), false, (Optional <AbstractUiElement>)Empty.INSTANCE, this);
        }