Exemple #1
0
    /// <summary>
    ///   Loads the help screen with texts from the json file
    ///   and turn it into help boxes
    /// </summary>
    private void BuildHelpTexts(string category)
    {
        var helpTexts = SimulationParameters.Instance.GetHelpTexts(category);

        foreach (var text in helpTexts.Messages)
        {
            var message = TranslationServer.Translate(text.Message);

            var helpBox = HelpBoxScene.Instance();
            helpBox.GetNode <CustomRichTextLabel>("MarginContainer/CustomRichTextLabel").ExtendedBbcode = message;

            if (text.Column == HelpText.TextColumn.Left)
            {
                leftColumn.AddChild(helpBox);
            }
            else if (text.Column == HelpText.TextColumn.Right)
            {
                rightColumn.AddChild(helpBox);
            }
            else
            {
                GD.PrintErr("Help text doesn't have a column set, couldn't be added into the container");

                // Queued as otherwise help text's ExtendedBbcode would be applied on a disposed object
                Invoke.Instance.Queue(helpBox.DetachAndQueueFree);
            }
        }
    }
Exemple #2
0
        private void OnDropDownLegendItemSelected(int index)
        {
            if (!Dropdown.Popup.IsItemCheckable(index))
            {
                return;
            }

            var result = chart.UpdateDataSetVisibility(
                Dropdown.Popup.GetItemText(index), !Dropdown.Popup.IsItemChecked(index));

            switch (result)
            {
            case DataSetVisibilityUpdateResult.MaxVisibleLimitReached:
                ToolTipManager.Instance.ShowPopup(string.Format(
                                                      CultureInfo.CurrentCulture, TranslationServer.Translate(
                                                          "MAX_VISIBLE_DATASET_WARNING"), chart.MaxDisplayedDataSet), 1f);
                break;

            case DataSetVisibilityUpdateResult.MinVisibleLimitReached:
                ToolTipManager.Instance.ShowPopup(string.Format(
                                                      CultureInfo.CurrentCulture, TranslationServer.Translate(
                                                          "MIN_VISIBLE_DATASET_WARNING"), chart.MinDisplayedDataSet), 1f);
                break;
            }
        }
        /// <summary>
        ///   Combines artwork title, artist name and extended description into one structured string.
        /// </summary>
        /// <param name="extended">
        ///     Includes the extended description if true (and it's not empty).
        /// </param>
        public string BuildDescription(bool extended)
        {
            var result = string.Empty;

            if (!string.IsNullOrEmpty(Title) && !string.IsNullOrEmpty(Artist))
            {
                result += string.Format(
                    CultureInfo.CurrentCulture, TranslationServer.Translate("ARTWORK_TITLE"), Title, Artist);
            }
            else if (string.IsNullOrEmpty(Title) && !string.IsNullOrEmpty(Artist))
            {
                result += string.Format(CultureInfo.CurrentCulture, TranslationServer.Translate("ART_BY"), Artist);
            }
            else if (!string.IsNullOrEmpty(Title) && string.IsNullOrEmpty(Artist))
            {
                result += Title;
            }

            if (extended && !string.IsNullOrEmpty(Description))
            {
                result += $"\n{Description}";
            }

            return(result);
        }
Exemple #4
0
    public void SubmitWorkshopItemUpdate(ulong updateHandle, string changeNotes, Action <WorkshopResult> callback)
    {
        if (workshopUpdateCallback != null)
        {
            throw new InvalidOperationException("Workshop update is already in-progress");
        }

        workshopUpdateCallback = callback ?? throw new ArgumentException("callback is required");

        // Steam docs say this constant is unused, but at least currently it seems to be the same value as the document
        // description max length
        if (changeNotes?.Length > Steam.PublishedDocumentChangeDescriptionMax)
        {
            callback.Invoke(new WorkshopResult()
            {
                Success         = false,
                TranslatedError = TranslationServer.Translate("CHANGE_DESCRIPTION_IS_TOO_LONG"),
            });
            return;
        }

        GD.Print("Submitting workshop update with handle: ", updateHandle);

        Steam.SubmitItemUpdate(updateHandle, changeNotes);
    }
Exemple #5
0
    private static void PerformSave(InProgressSave inProgress, Save save)
    {
        try
        {
            save.SaveToFile();
            inProgress.ReportStatus(true, TranslationServer.Translate("SAVING_SUCCEEDED"));
        }
        catch (Exception e)
        {
            // ReSharper disable HeuristicUnreachableCode ConditionIsAlwaysTrueOrFalse
            if (!Constants.CATCH_SAVE_ERRORS)
#pragma warning disable 162
            {
                throw;
            }
#pragma warning restore 162

            inProgress.ReportStatus(false, TranslationServer.Translate("SAVING_FAILED"),
                                    e.ToString());
            return;
        }

        if (inProgress.Type == SaveInformation.SaveType.AutoSave)
        {
            QueueRemoveExcessAutoSaves();
        }

        if (inProgress.Type == SaveInformation.SaveType.QuickSave)
        {
            QueueRemoveExcessQuickSaves();
        }
    }
Exemple #6
0
    /// <summary>
    ///   Truncates large numbers with suffix added (e.g. M for million).
    ///   Adapted from https://stackoverflow.com/a/30181106 to allow negatives and translation.
    /// </summary>
    public static string FormatNumber(this double number, bool withSuffix = true)
    {
        if (number is >= 1000000000 or <= -1000000000)
        {
            return(withSuffix ?
                   string.Format(
                       CultureInfo.CurrentCulture, TranslationServer.Translate("BILLION_ABBREVIATION"),
                       number.ToString("0,,,.###", CultureInfo.CurrentCulture)) :
                   number.ToString("0,,,.###", CultureInfo.CurrentCulture));
        }

        if (number is >= 1000000 or <= -1000000)
        {
            return(withSuffix ?
                   string.Format(
                       CultureInfo.CurrentCulture, TranslationServer.Translate("MILLION_ABBREVIATION"),
                       number.ToString("0,,.##", CultureInfo.CurrentCulture)) :
                   number.ToString("0,,.##", CultureInfo.CurrentCulture));
        }

        if (number is >= 1000 or <= -1000)
        {
            return(withSuffix ?
                   string.Format(
                       CultureInfo.CurrentCulture, TranslationServer.Translate("KILO_ABBREVIATION"),
                       number.ToString("0,.#", CultureInfo.CurrentCulture)) :
                   number.ToString("0,.#", CultureInfo.CurrentCulture));
        }

        return(number.ToString("0.#", CultureInfo.CurrentCulture));
    }
Exemple #7
0
 public override void _Notification(int what)
 {
     if (what == NotificationTranslationChanged)
     {
         HUD.UpdatePatchInfo(TranslationServer.Translate(CurrentGame.GameWorld.Map.CurrentPatch.Name));
     }
 }
Exemple #8
0
    /// <summary>
    ///   Switches to the editor
    /// </summary>
    public void MoveToEditor()
    {
        // Increase the population by the constant for the player reproducing
        var playerSpecies = GameWorld.PlayerSpecies;

        GameWorld.AlterSpeciesPopulation(
            playerSpecies, Constants.PLAYER_REPRODUCTION_POPULATION_GAIN_CONSTANT,
            TranslationServer.Translate("PLAYER_REPRODUCED"),
            false, Constants.PLAYER_REPRODUCTION_POPULATION_GAIN_COEFFICIENT);

        var scene = SceneManager.Instance.LoadScene(MainGameState.MicrobeEditor);

        var editor = (MicrobeEditor)scene.Instance();

        editor.CurrentGame   = CurrentGame;
        editor.ReturnToStage = this;

        // We don't free this here as the editor will return to this scene
        if (SceneManager.Instance.SwitchToScene(editor, true) != this)
        {
            throw new Exception("failed to keep the current scene root");
        }

        MovingToEditor = false;
    }
Exemple #9
0
    public void Init()
    {
        if (initStarted)
        {
            throw new InvalidOperationException("Can't initialize Steam more than once");
        }

        initStarted = true;
        GD.Print("Starting Steam load");

        var stats = Steam.SteamInit(true);

        if (!stats.Contains("status") || stats["status"] as int? != 1)
        {
            GD.Print("Steam load failed with code:", stats["status"]);
            GD.PrintErr("Verbal status: ", stats["verbal"]);
            SetError(TranslationServer.Translate("STEAM_CLIENT_INIT_FAILED"), stats["verbal"] as string);
            return;
        }

        GD.Print("Steam load finished");
        IsLoaded = true;

        RefreshCurrentUserInfo();

        if (IsOwned == true)
        {
            GD.Print("Game is owned by current Steam user");
        }

        // TODO: remove this cast once GodotSteam is updated
        AppId = (uint)Steam.GetAppID();

        GD.Print("Our app id is: ", AppId);
    }
Exemple #10
0
    /// <summary>
    ///   Checks that all the new info in the upload form is good
    /// </summary>
    /// <returns>True if good, false if not good (also sets the general error message)</returns>
    private bool ValidateForm()
    {
        if (string.IsNullOrWhiteSpace(editedTitle.Text))
        {
            SetError(TranslationServer.Translate("MISSING_TITLE"));
            return(false);
        }

        if (string.IsNullOrWhiteSpace(editedDescription.Text))
        {
            SetError(TranslationServer.Translate("MISSING_DESCRIPTION"));
            return(false);
        }

        // TODO: would be nice to somehow get the Steam constants in here...

        if (editedDescription.Text.Length > 8000)
        {
            SetError(TranslationServer.Translate("DESCRIPTION_TOO_LONG"));
            return(false);
        }

        if (changeNotes.Text.Length > 8000)
        {
            SetError(TranslationServer.Translate("CHANGE_DESCRIPTION_IS_TOO_LONG"));
            return(false);
        }

        if (editedTags.Text is { Length : > 0 })
Exemple #11
0
    private string GetTranslatedHeading(string team)
    {
        switch (team)
        {
        case ProgrammingTeamName: return(TranslationServer.Translate("PROGRAMMING_TEAM"));

        case TheoryTeamName: return(TranslationServer.Translate("THEORY_TEAM"));

        case GraphicsTeamName: return(TranslationServer.Translate("GRAPHICS_TEAM"));

        case SoundTeamName: return(TranslationServer.Translate("SOUND_TEAM"));

        case OutreachTeamName: return(TranslationServer.Translate("OUTREACH_TEAM"));

        case GameDesignTeamName: return(TranslationServer.Translate("GAME_DESIGN_TEAM"));

        case TestingTeamName: return(TranslationServer.Translate("TESTING_TEAM"));

        case ProjectManagementTeamName: return(TranslationServer.Translate("PROJECT_MANAGEMENT_TEAM"));

        case "Pull Requests / Programming": return(TranslationServer.Translate("PULL_REQUESTS_PROGRAMMING"));

        case "VIP_PATRONS": return(TranslationServer.Translate("VIP_PATRONS"));

        case "DEV_BUILD_PATRONS": return(TranslationServer.Translate("DEV_BUILD_PATRONS"));

        case "SUPPORTER_PATRONS": return(TranslationServer.Translate("SUPPORTER_PATRONS"));

        case "January": return(TranslationServer.Translate("JANUARY"));

        case "February": return(TranslationServer.Translate("FEBRUARY"));

        case "March": return(TranslationServer.Translate("MARCH"));

        case "April": return(TranslationServer.Translate("APRIL"));

        case "May": return(TranslationServer.Translate("MAY"));

        case "June": return(TranslationServer.Translate("JUNE"));

        case "July": return(TranslationServer.Translate("JULY"));

        case "August": return(TranslationServer.Translate("AUGUST"));

        case "September": return(TranslationServer.Translate("SEPTEMBER"));

        case "October": return(TranslationServer.Translate("OCTOBER"));

        case "November": return(TranslationServer.Translate("NOVEMBER"));

        case "December": return(TranslationServer.Translate("DECEMBER"));

        default:
            GD.Print(
                $"unknown heading '{team}' needs to be added to " +
                $"{nameof(CreditsScroll)}.{nameof(GetTranslatedHeading)}");
            return(team);
        }
    }
Exemple #12
0
    private static string GetTranslatedText(Type type, object instance, object[] attributes)
    {
        var data = (TranslateFromAttribute)attributes[0];

        var source = GetTargetField(type, data);

        return(TranslationServer.Translate((string)source.GetValue(instance)));
    }
Exemple #13
0
    private void LoadEndRemarks()
    {
        int offset = GetNextDynamicSectionOffset() + OffsetBeforeNextDynamicPart;

        CreateDynamicPart(offset, TranslationServer.Translate("THANKS_FOR_PLAYING"));

        // This is the last section so when these items have all scrolled off the credits trigger the end signal
    }
Exemple #14
0
 private void ShowOverwriteConfirm(string name)
 {
     // The chosen filename ({0}) already exists. Overwrite?
     overwriteConfirm.DialogText = string.Format(CultureInfo.CurrentCulture,
                                                 TranslationServer.Translate("THE_CHOSEN_FILENAME_ALREADY_EXISTS"),
                                                 name);
     overwriteConfirm.PopupCenteredShrink();
 }
Exemple #15
0
    private void Step()
    {
        switch (state)
        {
        case State.Initial:
            // On this frame a pause menu might still be open, wait until next frame for it to close before
            // taking a screenshot
            state = State.Screenshot;
            break;

        case State.Screenshot:
        {
            save = createSaveData.Invoke(this);
            SaveStatusOverlay.Instance.ShowMessage(TranslationServer.Translate("SAVING"),
                                                   Mathf.Inf);

            state = State.SaveData;
            break;
        }

        case State.SaveData:
        {
            save.Name = saveNameTask.Result;

            GD.Print("Creating a save with name: ", save.Name);
            performSave.Invoke(this, save);
            state = State.Finished;
            break;
        }

        case State.Finished:
        {
            stopwatch.Stop();
            GD.Print("save finished, success: ", success, " message: ", message, " elapsed: ", stopwatch.Elapsed);

            if (success)
            {
                SaveStatusOverlay.Instance.ShowMessage(message);

                currentGameRoot.Invoke().GetTree().Paused = returnToPauseState;
            }
            else
            {
                SaveStatusOverlay.Instance.ShowMessage(TranslationServer.Translate("SAVE_FAILED"));
                SaveStatusOverlay.Instance.ShowError(TranslationServer.Translate("ERROR_SAVING"),
                                                     message, exception);
            }

            return;
        }

        default:
            throw new InvalidOperationException();
        }

        Invoke.Instance.Queue(Step);
    }
Exemple #16
0
    private void UpdatePatchSettings(bool isLoading)
    {
        patchManager.ApplyChangedPatchSettingsIfNeeded(GameWorld.Map.CurrentPatch, !isLoading);

        HUD.UpdatePatchInfo(TranslationServer.Translate(GameWorld.Map.CurrentPatch.Name));
        HUD.UpdateEnvironmentalBars(GameWorld.Map.CurrentPatch.Biome);

        UpdateBackground();
    }
Exemple #17
0
 public static string Get(string key)
 {
     // wrapper for the Godot's Tr system
     if (TranslationServer.Translate(key) != string.Empty)
     {
         return(TranslationServer.Translate(key));
     }
     return(key);
 }
Exemple #18
0
    private void OnRebindButtonPressed()
    {
        WaitingForInput = true;
        button.Text     = TranslationServer.Translate("PRESS_KEY_DOT_DOT_DOT");
        xButton.Visible = true;

        // Notify InputManager that input rebinding has started and it should not react to input
        InputManager.PerformingRebind = true;
    }
Exemple #19
0
    private void OnRebindButtonPressed()
    {
        WaitingForInput = true;
        button.Text     = TranslationServer.Translate("PRESS_KEY_DOT_DOT_DOT");
        xButton.Visible = true;

        // Signal to the input manager that a rebinding has started
        // and it should ignore input untill the rebind is finished
        InputManager.RebindingIsActive = true;
    }
Exemple #20
0
    private void SetError(string?message)
    {
        if (message == null)
        {
            ClearError();
        }

        errorDisplay.Text = string.Format(CultureInfo.CurrentCulture, TranslationServer.Translate("FORM_ERROR_MESSAGE"),
                                          message);
    }
Exemple #21
0
    public string ToString(string format, IFormatProvider formatProvider)
    {
        if (formatStringArgs == null || formatStringArgs.Length == 0)
        {
            return(format ?? TranslationServer.Translate(translationKey));
        }

        return(string.Format(formatProvider ?? CultureInfo.CurrentCulture,
                             format ?? TranslationServer.Translate(translationKey), formatStringArgs));
    }
Exemple #22
0
    private static bool PreventSavingIfExtinct(InProgressSave inProgress, Save save)
    {
        if (!save.SavedProperties.GameWorld.PlayerSpecies.IsExtinct)
        {
            return(false);
        }

        inProgress.ReportStatus(false, TranslationServer.Translate("SAVING_NOT_POSSIBLE"),
                                TranslationServer.Translate("PLAYER_EXTINCT"), false);
        return(true);
    }
Exemple #23
0
    private string?ValidateFormData()
    {
        if (editedInfo == null)
        {
            throw new InvalidOperationException("Validate form called without editing info");
        }

        if (string.IsNullOrWhiteSpace(editedInfo.InternalName))
        {
            SetError(TranslationServer.Translate("INTERNAL_NAME_REQUIRED"));
            return(null);
        }

        if (!char.IsUpper(editedInfo.InternalName, 0))
        {
            SetError(TranslationServer.Translate("INTERNAL_NAME_REQUIRES_CAPITAL"));
            return(null);
        }

        if (ModLoader.LoadModInfo(editedInfo.InternalName, false) != null)
        {
            SetError(TranslationServer.Translate("INTERNAL_NAME_IN_USE"));
            return(null);
        }

        var serialized = new StringWriter();

        var finalResult = new FullModDetails(editedInfo.InternalName,
                                             Path.Combine(Constants.ModLocations[Constants.ModLocations.Count - 1], internalName.Text), editedInfo);

        try
        {
            JsonSerializer.Create().Serialize(serialized, finalResult);
        }
        catch (JsonSerializationException e)
        {
            SetError(string.Format(CultureInfo.CurrentCulture,
                                   TranslationServer.Translate("MISSING_OR_INVALID_REQUIRED_FIELD"), e.Message));
            return(null);
        }

        try
        {
            ModManager.ValidateModInfo(editedInfo, true);
        }
        catch (Exception e)
        {
            SetError(string.Format(CultureInfo.CurrentCulture,
                                   TranslationServer.Translate("ADDITIONAL_VALIDATION_FAILED"), e.Message));
            return(null);
        }

        return(serialized.ToString());
    }
Exemple #24
0
 private void OnSaveNameTextEntered(string newName)
 {
     if (IsSaveNameValid(newName))
     {
         SaveButtonPressed();
     }
     else
     {
         ToolTipManager.Instance.ShowPopup(TranslationServer.Translate("INVALID_SAVE_NAME_POPUP"), 2.5f);
     }
 }
Exemple #25
0
        internal static string Translate(string format, params string[] pp)
        {
            var tranFormat = TranslationServer.Translate(format);

            if (pp.Count() == 0)
            {
                return(tranFormat);
            }

            return(String.Format(tranFormat, pp));
        }
Exemple #26
0
    private void OnDeletePressed(string saveName)
    {
        GUICommon.Instance.PlayButtonPressSound();

        saveToBeDeleted = saveName;

        // Deleting this save cannot be undone, are you sure you want to permanently delete {0}?
        deleteConfirmDialog.DialogText = string.Format(CultureInfo.CurrentCulture,
                                                       TranslationServer.Translate("SAVE_DELETE_WARNING"),
                                                       saveName);
        deleteConfirmDialog.PopupCenteredShrink();
    }
Exemple #27
0
    /// <summary>
    ///   Applies all patch related settings that are needed to be
    ///   set. Like different spawners, despawning old entities if the
    ///   patch changed etc.
    /// </summary>
    /// <returns>
    ///   True if the patch is changed from the previous one. False if the patch is not changed.
    /// </returns>
    public bool ApplyChangedPatchSettingsIfNeeded(Patch currentPatch)
    {
        var patchIsChanged = false;

        if (previousPatch != currentPatch && !skipDespawn)
        {
            if (previousPatch != null)
            {
                GD.Print("Previous patch (", TranslationServer.Translate(previousPatch.Name), ") different to " +
                         "current patch (", TranslationServer.Translate(currentPatch.Name), ") despawning all entities.");
            }
            else
            {
                GD.Print("Previous patch doesn't exist, despawning all entities.");
            }

            // Despawn old entities
            spawnSystem.DespawnAll();

            // And also all timed entities
            timedLife.DespawnAll();

            // Clear compounds
            compoundCloudSystem.EmptyAllClouds();

            patchIsChanged = true;
        }

        previousPatch = currentPatch;
        skipDespawn   = false;

        GD.Print("Applying patch (", TranslationServer.Translate(currentPatch.Name), ") settings");

        // Update environment for process system
        processSystem.SetBiome(currentPatch.Biome);

        // Apply spawn system settings
        UnmarkAllSpawners();

        // Cloud spawners should be added first due to the way the
        // total entity count is limited
        HandleCloudSpawns(currentPatch.Biome);
        HandleChunkSpawns(currentPatch.Biome);
        HandleCellSpawns(currentPatch);

        RemoveNonMarkedSpawners();

        // Change the lighting
        UpdateLight(currentPatch.BiomeTemplate);

        return(patchIsChanged);
    }
Exemple #28
0
    private string?GetDescriptiveSteamError(int result)
    {
        // Note: the exact problem varies a bit based on the action being performed, but for faster implementation
        // these are not separated by operation type TODO: (yet)
        switch (result)
        {
        case Steam.ResultOk:
            return(null);

        case Steam.ResultInsufficientPrivilege:
            return(TranslationServer.Translate("STEAM_ERROR_INSUFFICIENT_PRIVILEGE"));

        case Steam.ResultBanned:
            return(TranslationServer.Translate("STEAM_ERROR_BANNED"));

        case Steam.ResultTimeout:
            return(TranslationServer.Translate("STEAM_ERROR_TIMEOUT"));

        case Steam.ResultNotLoggedOn:
            return(TranslationServer.Translate("STEAM_ERROR_NOT_LOGGED_IN"));

        case Steam.ResultServiceUnavailable:
            return(TranslationServer.Translate("STEAM_ERROR_UNAVAILABLE"));

        case Steam.ResultInvalidParam:
            return(TranslationServer.Translate("STEAM_ERROR_INVALID_PARAMETER"));

        case Steam.ResultLimitExceeded:
            return(TranslationServer.Translate("STEAM_ERROR_CLOUD_LIMIT_EXCEEDED"));

        case Steam.ResultFileNotFound:
            return(TranslationServer.Translate("STEAM_ERROR_FILE_NOT_FOUND"));

        case Steam.ResultDuplicateRequest:
            return(TranslationServer.Translate("STEAM_ERROR_ALREADY_UPLOADED"));

        case Steam.ResultDuplicateName:
            return(TranslationServer.Translate("STEAM_ERROR_DUPLICATE_NAME"));

        case Steam.ResultServiceReadOnly:
            return(TranslationServer.Translate("STEAM_ERROR_ACCOUNT_READ_ONLY"));

        case Steam.ResultAccessDenied:
            return(TranslationServer.Translate("STEAM_ERROR_ACCOUNT_DOES_NOT_OWN_PRODUCT"));

        case Steam.ResultLockingFailed:
            return(TranslationServer.Translate("STEAM_ERROR_LOCKING_FAILED"));

        default:
            return(TranslationServer.Translate("STEAM_ERROR_UNKNOWN"));
        }
    }
Exemple #29
0
 private void UpdateStoreNameLabel()
 {
     if (!SteamHandler.Instance.IsLoaded)
     {
         storeLoggedInDisplay.Visible = false;
     }
     else
     {
         storeLoggedInDisplay.Visible = true;
         storeLoggedInDisplay.Text    = string.Format(CultureInfo.CurrentCulture,
                                                      TranslationServer.Translate("STORE_LOGGED_IN_AS"), SteamHandler.Instance.DisplayName);
     }
 }
    public override Control CreateLegend(Dictionary <string, ChartDataSet> datasets, string title)
    {
        var result = (CustomDropDown)base.CreateLegend(datasets, title);

        foreach (var species in extinctSpecies)
        {
            AddSpeciesToList(species, TranslationServer.Translate("EXTINCT_SPECIES"));
        }

        result.CreateElements();

        return(result);
    }