Пример #1
0
 private void initLocalization()
 {
     Loc.LoadResourceFile();
     Utils.InitializeLocalizations();
 }
Пример #2
0
        /// <summary>
        /// Import exported file. Used by a fileWatcher.
        /// </summary>
        /// <param name="filePath"></param>
        private void ImportExportedAddIfPossible(string filePath)
        {
            bool alreadyExists       = ExtractExportedFileInExtractor(filePath);
            bool added               = false;
            bool copyNameToClipboard = Properties.Settings.Default.copyNameToClipboardOnImportWhenAutoNameApplied &&
                                       (Properties.Settings.Default.applyNamePatternOnImportIfEmptyName ||
                                        (!alreadyExists && Properties.Settings.Default.applyNamePatternOnAutoImportForNewCreatures));
            Species species = speciesSelector1.SelectedSpecies;

            if (_extractor.uniqueResults ||
                (alreadyExists && _extractor.validResults))
            {
                AddCreatureToCollection(true, goToLibraryTab: false);
                SetMessageLabelText($"Successful {(alreadyExists ? "updated" : "added")} {creatureInfoInputExtractor.CreatureName} ({species.name}) of the exported file\n" + filePath, MessageBoxIcon.Information);
                added = true;
            }

            bool topLevels    = false;
            bool newTopLevels = false;

            // give feedback in overlay
            string    infoText;
            Color     textColor;
            const int colorSaturation = 200;

            if (added)
            {
                var sb = new StringBuilder();
                sb.AppendLine($"{species.name} \"{creatureInfoInputExtractor.CreatureName}\" {(alreadyExists ? "updated in " : "added to")} the library.");
                if (copyNameToClipboard)
                {
                    sb.AppendLine("Name copied to clipboard.");
                }

                for (int s = 0; s < values.Values.STATS_COUNT; s++)
                {
                    int statIndex = values.Values.statsDisplayOrder[s];
                    if (!species.UsesStat(statIndex))
                    {
                        continue;
                    }

                    sb.Append($"{Utils.StatName(statIndex, true, species.IsGlowSpecies)}: {_statIOs[statIndex].LevelWild} ({_statIOs[statIndex].BreedingValue})");
                    if (_statIOs[statIndex].TopLevel == StatIOStatus.NewTopLevel)
                    {
                        sb.Append($" {Loc.S("newTopLevel")}");
                        newTopLevels = true;
                    }
                    else if (_statIOs[statIndex].TopLevel == StatIOStatus.TopLevel)
                    {
                        sb.Append($" {Loc.S("topLevel")}");
                        topLevels = true;
                    }
                    sb.AppendLine();
                }

                infoText  = sb.ToString();
                textColor = Color.FromArgb(colorSaturation, 255, colorSaturation);
            }
            else
            {
                infoText  = $"Creature \"{creatureInfoInputExtractor.CreatureName}\" couldn't be extracted uniquely, manual level selection is necessary.";
                textColor = Color.FromArgb(255, colorSaturation, colorSaturation);
            }

            _overlay?.SetInfoText(infoText, textColor);

            if (added)
            {
                if (Properties.Settings.Default.MoveAutoImportedFileToSubFolder)
                {
                    string importedPath = Path.Combine(Path.GetDirectoryName(filePath), "imported");
                    if (!FileService.TryCreateDirectory(importedPath, out string errorMessage))
                    {
                        MessageBox.Show($"Subfolder\n{importedPath}\ncould not be created.\n{errorMessage}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                    FileService.TryMoveFile(filePath, Path.Combine(importedPath, Path.GetFileName(filePath)));
                }
                else if (Properties.Settings.Default.DeleteAutoImportedFile)
                {
                    FileService.TryDeleteFile(filePath);
                }
            }
            else if (copyNameToClipboard)
            {
                // extraction failed, user might expect the name of the new creature in the clipboard
                Clipboard.SetText("Automatic extraction was not possible");
            }

            if (Properties.Settings.Default.PlaySoundOnAutoImport)
            {
                if (added)
                {
                    if (newTopLevels)
                    {
                        Utils.BeepSignal(3);
                    }
                    else if (topLevels)
                    {
                        Utils.BeepSignal(2);
                    }
                    else
                    {
                        Utils.BeepSignal(1);
                    }
                }
                else
                {
                    Utils.BeepSignal(0);
                }
            }
        }
Пример #3
0
        private void setLocalizations(bool init = true)
        {
            if (init)
            {
                initLocalization();
            }

            // menu
            Loc.ControlText(fileToolStripMenuItem);
            Loc.ControlText(newToolStripMenuItem);
            Loc.ControlText(loadToolStripMenuItem);
            Loc.ControlText(loadAndAddToolStripMenuItem);
            Loc.ControlText(saveToolStripMenuItem);
            Loc.ControlText(saveAsToolStripMenuItem);
            Loc.ControlText(importingFromSavegameToolStripMenuItem);
            Loc.ControlText(importingFromSavegameEmptyToolStripMenuItem);
            //Loc.ControlText(runDefaultExtractionAndImportFileToolStripMenuItem);
            //Loc.ControlText(runDefaultExtractionToolStripMenuItem);
            //Loc.ControlText(importCreatedJsonfileToolStripMenuItem);
            Loc.ControlText(importExportedCreaturesToolStripMenuItem);
            //Loc.ControlText(runDefaultExtractionAndImportFileToolStripMenuItem);
            //Loc.ControlText(runDefaultExtractionToolStripMenuItem);
            //Loc.ControlText(importCreatedJsonfileToolStripMenuItem);
            Loc.ControlText(modValueManagerToolStripMenuItem);
            Loc.ControlText(settingsToolStripMenuItem);
            Loc.ControlText(openSettingsToolStripMenuItem);
            Loc.ControlText(quitToolStripMenuItem);
            Loc.ControlText(editToolStripMenuItem);
            Loc.ControlText(exportValuesToClipboardToolStripMenuItem);
            Loc.ControlText(importValuesFromClipboardToolStripMenuItem);
            Loc.ControlText(setStatusToolStripMenuItem);
            Loc.ControlText(multiSetterToolStripMenuItem);
            Loc.ControlText(deleteSelectedToolStripMenuItem);
            Loc.ControlText(findDuplicatesToolStripMenuItem);
            Loc.ControlText(copyCreatureToolStripMenuItem);
            Loc.ControlText(pasteCreatureToolStripMenuItem);
            Loc.ControlText(libraryFilterToolStripMenuItem);
            Loc.ControlText(helpToolStripMenuItem);
            Loc.ControlText(aboutToolStripMenuItem);
            Loc.ControlText(onlinehelpToolStripMenuItem);
            Loc.ControlText(BreedingPlanHelpToolStripMenuItem);
            Loc.ControlText(extractionIssuesToolStripMenuItem);
            Loc.ControlText(checkForUpdatedStatsToolStripMenuItem);
            Loc.ControlText(toolStripButtonCopy2Tester);
            Loc.ControlText(toolStripButtonCopy2Extractor);
            Loc.ControlText(toolStripButtonClear);
            Loc.ControlText(toolStripButtonAddNote);
            Loc.ControlText(toolStripButtonRemoveNote);
            Loc.ControlText(toolStripButtonDeleteExpiredIncubationTimers);
            Loc.ControlText(toolStripButtonSaveCreatureValuesTemp);
            Loc.ControlText(toolStripButtonDeleteTempCreature);
            Loc.ControlText(tsBtAddAsExtractionTest);
            Loc.ControlText(copyToMultiplierTesterToolStripButton);

            // top bar
            Loc.ControlText(cbGuessSpecies, _tt);
            Loc.ControlText(btReadValuesFromArk, _tt);
            Loc.ControlText(btImportLastExported, _tt);
            Loc.ControlText(cbToggleOverlay);

            // tester
            Loc.ControlText(tabPageStatTesting, "statTesting");
            Loc.ControlText(rbWildTester, "wild");
            Loc.ControlText(rbTamedTester, "tamed");
            Loc.ControlText(rbBredTester, "bred");
            Loc.ControlText(lbTesterWildLevel, "wildLvl");
            Loc.ControlText(lbTesterDomLevel, "domLvl");
            Loc.ControlText(lbCurrentValue, "currentValue");
            Loc.ControlText(lbBreedingValueTester, "breedingValue");
            Loc.ControlText(lbNotYetTamed);
            Loc.ControlText(gpPreviewEdit);
            Loc.ControlText(lbTestingInfo);
            Loc.ControlText(gbStatChart, "statChart");
            Loc.ControlText(lbCurrentCreature, "CurrentCreature");
            Loc.SetToolTip(lbImprintedCount, _tt);
            Loc.SetToolTip(lbTesterDomLevel, "domLevelExplanation", _tt);
            Loc.SetToolTip(lbTesterWildLevel, "wildLevelExplanation", _tt);

            // extractor
            Loc.ControlText(tabPageExtractor, "extractor");
            Loc.ControlText(lbCurrentStatEx, "currentStatValue");
            Loc.ControlText(lbExtractorWildLevel, "wildLvl");
            Loc.ControlText(lbExtractorDomLevel, "domLvl");
            Loc.ControlText(lbSum);
            Loc.ControlText(lbShouldBe);
            Loc.ControlText(lbImprintingFailInfo);
            Loc.ControlText(cbExactlyImprinting, _tt);
            Loc.ControlText(btExtractLevels);
            Loc.ControlText(cbQuickWildCheck, _tt);
            Loc.ControlText(rbWildExtractor, "wild");
            Loc.ControlText(rbTamedExtractor, "tamed");
            Loc.ControlText(rbBredExtractor, "bred");
            Loc.SetToolTip(lbImprintingCuddleCountExtractor, _tt);
            Loc.SetToolTip(lbSumWild, _tt);
            Loc.SetToolTip(lbSumDom, _tt);
            Loc.SetToolTip(lbSumDomSB, _tt);
            Loc.SetToolTip(lbListening, _tt);
            Loc.SetToolTip(lbExtractorDomLevel, "domLevelExplanation", _tt);
            Loc.SetToolTip(lbExtractorWildLevel, "wildLevelExplanation", _tt);

            // library
            Loc.ControlText(tabPageLibrary, "library");
            columnHeaderName.Text       = Loc.S("Name");
            columnHeaderOwner.Text      = Loc.S("Owner");
            columnHeaderTribe.Text      = Loc.S("Tribe");
            columnHeaderNote.Text       = Loc.S("Note");
            columnHeaderServer.Text     = Loc.S("Server");
            columnHeaderHP.Text         = Utils.StatName(StatNames.Health, true);
            columnHeaderSt.Text         = Utils.StatName(StatNames.Stamina, true);
            columnHeaderOx.Text         = Utils.StatName(StatNames.Oxygen, true);
            columnHeaderFo.Text         = Utils.StatName(StatNames.Food, true);
            columnHeaderWe.Text         = Utils.StatName(StatNames.Weight, true);
            columnHeaderDm.Text         = Utils.StatName(StatNames.MeleeDamageMultiplier, true);
            columnHeaderSp.Text         = Utils.StatName(StatNames.SpeedMultiplier, true);
            columnHeaderTo.Text         = Utils.StatName(StatNames.Torpidity, true);
            columnHeaderWa.Text         = Utils.StatName(StatNames.CraftingSpeedMultiplier, true);
            columnHeaderTemp.Text       = Utils.StatName(StatNames.Temperature, true);
            columnHeaderCr.Text         = Utils.StatName(StatNames.Water, true);
            columnHeaderFr.Text         = Utils.StatName(StatNames.TemperatureFortitude, true);
            columnHeaderTopStatsNr.Text = Loc.S("Top");
            columnHeaderTopness.Text    = Loc.S("topPercentage");
            columnHeaderGen.Text        = Loc.S("Generation_Abb");
            columnHeaderLW.Text         = Loc.S("LevelWild_Abb");
            columnHeaderMutations.Text  = Loc.S("Mutations_Abb");
            columnHeaderAdded.Text      = Loc.S("added");
            columnHeaderCooldown.Text   = Loc.S("cooldownGrowing");
            columnHeaderColor0.Text     = Loc.S("C0");
            columnHeaderColor1.Text     = Loc.S("C1");
            columnHeaderColor2.Text     = Loc.S("C2");
            columnHeaderColor3.Text     = Loc.S("C3");
            columnHeaderColor4.Text     = Loc.S("C4");
            columnHeaderColor5.Text     = Loc.S("C5");

            // other tabs
            Loc.ControlText(tabPagePedigree, "pedigree");
            Loc.ControlText(tabPageTaming, "Taming");
            Loc.ControlText(tabPageBreedingPlan, "BreedingPlan");
            Loc.ControlText(tabPageRaising, "Raising");
            Loc.ControlText(tabPagePlayerTribes, "Player");

            // other controls
            creatureInfoInputTester.SetLocalizations();
            creatureInfoInputExtractor.SetLocalizations();
            pedigree1.SetLocalizations();
            tamingControl1.SetLocalizations();
            breedingPlan1.SetLocalizations();
        }
Пример #4
0
        public void SetSpecies(Species species, bool forceRefresh = false)
        {
            if (species == null || (_selectedSpecies == species && !forceRefresh))
            {
                return;
            }

            _selectedSpecies = species;

            if (species.taming == null)
            {
                NoTamingData();
                return;
            }

            this.SuspendDrawing();
            SuspendLayout();

            string speciesName = species.name;

            linkLabelWikiPage.Text = "Wiki: " + speciesName;
            linkLabelWikiPage.Tag  = speciesName;
            _tt.SetToolTip(linkLabelWikiPage, ArkWiki.WikiUrl(speciesName));

            // bone damage adjusters
            _boneDamageAdjustersImmobilization = Taming.BoneDamageAdjustersImmobilization(_selectedSpecies,
                                                                                          out Dictionary <string, double> boneDamageAdjusters);

            int ib = 0;

            foreach (KeyValuePair <string, double> bd in boneDamageAdjusters)
            {
                ib++;
                if (ib >= _rbBoneDamageAdjusters.Count)
                {
                    RadioButton rbBD = new RadioButton();
                    flcBodyDamageMultipliers.Controls.Add(rbBD);
                    flcBodyDamageMultipliers.SetFlowBreak(rbBD, true);
                    rbBD.AutoSize = true;

                    _rbBoneDamageAdjusters.Add(rbBD);
                    _rbBoneDamageAdjusterValues.Add(1);
                    rbBD.CheckedChanged += rbBoneDamage_CheckedChanged;
                }
                _rbBoneDamageAdjusterValues[ib]    = bd.Value;
                _rbBoneDamageAdjusters[ib].Text    = $"{Loc.S(bd.Key)} (× {bd.Value})";
                _rbBoneDamageAdjusters[ib].Visible = true;
            }
            for (int j = ib + 1; j < _rbBoneDamageAdjusters.Count; j++)
            {
                _rbBoneDamageAdjusters[j].Visible = false;
            }
            _rbBoneDamageAdjusters[0].Checked = true;
            // bone damage adjusters adjusted

            _updateCalculation = false;
            TamingData td = species.taming;

            _kibbleRecipe = string.Empty;

            // list all recipes of kibbles that give a reasonable affinity (assuming that is larger or equal than 100)
            foreach (var k in Kibbles.K.kibble)
            {
                var kibbleName = $"{k.Key} Kibble";
                var kibbleFood = Values.V.GetTamingFood(species, kibbleName);

                if (kibbleFood != null &&
                    kibbleFood.affinity >= 100)
                {
                    _kibbleRecipe += $"\n\n{k.Key} Kibble:{k.Value.RecipeAsText()}";
                }
            }

            _foodDepletion = td.foodConsumptionBase * td.foodConsumptionMult * _tamingFoodRateMultiplier;

            SetTamingFoodControls(species);

            _updateCalculation = true;
            UpdateFirstFeedingWaiting();
            UpdateTamingData();
            if (Properties.Settings.Default.TamingFoodOrderByTime)
            {
                SetOrderOfTamingFood(true, true);
            }

            ResumeLayout();
            this.ResumeDrawing();
        }
Пример #5
0
 public void SetLocalizations()
 {
     Loc.ControlText(lbPedigreeEmpty);
 }
Пример #6
0
        private void UpdateTamingData()
        {
            if (!_updateCalculation || _selectedSpecies == null)
            {
                return;
            }
            if (_selectedSpecies.taming == null)
            {
                NoTamingData();
                return;
            }

            Enabled = true;
            UpdateKOCounting();

            TimeSpan duration = new TimeSpan();
            int      narcoBerries = 0, ascerbicMushrooms = 0, narcotics = 0, bioToxines = 0, bonusLevel = 0;
            double   te = 0;

            _neededHunger = 0;
            bool enoughFood     = false;
            var  usedFood       = new List <string>();
            var  foodAmount     = new List <int>();
            var  foodAmountUsed = new List <int>();

            quickTamingInfos = "n/a";
            int  level    = (int)nudLevel.Value;
            bool tameable = _selectedSpecies.taming.nonViolent || _selectedSpecies.taming.violent;

            if (tameable && _selectedSpecies.taming.eats != null)
            {
                int foodCounter = _selectedSpecies.taming.eats.Length;
                foreach (TamingFoodControl tfc in _foodControls)
                {
                    if (foodCounter == 0)
                    {
                        break;
                    }
                    foodCounter--;

                    usedFood.Add(tfc.FoodName);
                    foodAmount.Add(tfc.amount);
                    tfc.maxFood        = Taming.FoodAmountNeeded(_selectedSpecies, level, _tamingSpeedMultiplier, tfc.FoodName, _selectedSpecies.taming.nonViolent);
                    tfc.tamingDuration = Taming.TamingDuration(_selectedSpecies, tfc.maxFood, tfc.FoodName, _tamingFoodRateMultiplier, _selectedSpecies.taming.nonViolent);
                }
                Taming.TamingTimes(_selectedSpecies, level, _tamingSpeedMultiplier, _tamingFoodRateMultiplier, usedFood, foodAmount, out foodAmountUsed, out duration, out narcoBerries, out ascerbicMushrooms, out narcotics, out bioToxines, out te, out _neededHunger, out bonusLevel, out enoughFood);

                for (int f = 0; f < foodAmountUsed.Count; f++)
                {
                    _foodControls[f].foodUsed = foodAmountUsed[f];
                }
            }

            labelResult.ForeColor = SystemColors.ControlText;
            if (!tameable)
            {
                labelResult.Text      = Loc.S("speciesNotTameable");
                labelResult.ForeColor = Color.Red;
            }
            else if (enoughFood)
            {
                labelResult.Text = $"It takes {Utils.DurationUntil(duration)} to tame the {_selectedSpecies.name}.\n\n" +
                                   $"Taming Effectiveness: {Math.Round(100 * te, 1)} %\n" +
                                   $"Bonus-Level: +{bonusLevel} (total level after Taming: {(nudLevel.Value + bonusLevel)})\n\n" +
                                   $"Food has to drop by {_neededHunger:F1} units.\n\n" +
                                   $"{narcoBerries} Narcoberries or\n" +
                                   $"{ascerbicMushrooms} Ascerbic Mushrooms or\n" +
                                   $"{narcotics} Narcotics or\n" +
                                   $"{bioToxines} Bio Toxines are needed{_firstFeedingWaiting}";

                labelResult.Text += _kibbleRecipe;
            }
            else if (foodAmountUsed.Count == 0)
            {
                labelResult.Text = Loc.S("noTamingData");
            }
            else
            {
                labelResult.Text = Loc.S("notEnoughFoodToTame");
            }

            numericUpDownCurrentTorpor.ValueSave = (decimal)(_selectedSpecies.stats[(int)StatNames.Torpidity].BaseValue * (1 + _selectedSpecies.stats[(int)StatNames.Torpidity].IncPerWildLevel * (level - 1)));

            nudTotalFood.Value   = (decimal)(_selectedSpecies.stats[(int)StatNames.Food].BaseValue * (1 + _selectedSpecies.stats[(int)StatNames.Food].IncPerWildLevel * (level / 7))); // approximating the food level
            nudCurrentFood.Value = nudTotalFood.Value;
            UpdateTimeToFeedAll(enoughFood);

            //// quickTame infos
            if (foodAmountUsed.Any())
            {
                quickTamingInfos = Taming.QuickInfoOneFood(_selectedSpecies, level, _tamingSpeedMultiplier, _tamingFoodRateMultiplier, _foodControls[0].FoodName, _foodControls[0].maxFood, _foodControls[0].foodNameDisplay);
                // show raw meat or mejoberries as alternative (often used)
                for (int i = 1; i < usedFood.Count; i++)
                {
                    if (usedFood[i] == "Raw Meat" || usedFood[i] == "Mejoberry")
                    {
                        quickTamingInfos += "\n\n" + Taming.QuickInfoOneFood(_selectedSpecies, level, _tamingSpeedMultiplier, _tamingFoodRateMultiplier, _foodControls[i].FoodName, _foodControls[i].maxFood, _foodControls[i].foodNameDisplay);
                        break;
                    }
                }

                quickTamingInfos += "\n\n" + _koNumbers
                                    + "\n\n" + _boneDamageAdjustersImmobilization
                                    + _firstFeedingWaiting
                                    + _kibbleRecipe;
            }
        }
Пример #7
0
        /// <summary>
        /// Update the info when all food can be fed at once.
        /// </summary>
        private void UpdateTimeToFeedAll(bool enoughFood = true)
        {
            double hunger = (double)(nudTotalFood.Value - nudCurrentFood.Value);

            if (hunger < 0)
            {
                hunger = 0;
            }
            if (hunger > _neededHunger)
            {
                hunger = _neededHunger;
            }
            var durationStarving = new TimeSpan(0, 0, (int)((_neededHunger - hunger) / _foodDepletion));

            lbTimeUntilStarving.Text = (enoughFood ? $"{Loc.S("TimeUntilFeedingAllFood")}: {Utils.Duration(durationStarving)}" : string.Empty);
            if ((double)nudTotalFood.Value < _neededHunger)
            {
                lbTimeUntilStarving.Text     += (lbTimeUntilStarving.Text.Length > 0 ? "\n" : string.Empty) + $"{Loc.S("WarningMoreStarvingThanFood")}";
                lbTimeUntilStarving.ForeColor = Color.DarkRed;
            }
            else
            {
                lbTimeUntilStarving.ForeColor = SystemColors.ControlText;
            }

            _starvingTime = DateTime.Now.Add(durationStarving);
        }
Пример #8
0
        /// <summary>
        /// Loads the given creature collection file.
        /// </summary>
        /// <param name="filePath">File that contains the collection</param>
        /// <param name="keepCurrentCreatures">add the creatures of the loaded file to the current ones</param>
        /// <param name="keepCurrentSelections">don't change the species selection or tab</param>
        /// <returns></returns>
        private bool LoadCollectionFile(string filePath, bool keepCurrentCreatures = false, bool keepCurrentSelections = false)
        {
            Species selectedSpecies        = speciesSelector1.SelectedSpecies;
            Species selectedlibrarySpecies = listBoxSpeciesLib.SelectedItem as Species;

            if (string.IsNullOrEmpty(filePath) || !File.Exists(filePath))
            {
                MessageBox.Show($"Save file with name \"{filePath}\" does not exist!", $"File not found - {Utils.ApplicationNameVersion}", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return(false);
            }

            CreatureCollection previouslyLoadedCreatureCollection = _creatureCollection;

            // Wait until the file is readable
            const int numberOfRetries = 5;
            const int delayOnRetry    = 1000;

            FileStream fileStream = null;

            for (int i = 1; i <= numberOfRetries; ++i)
            {
                // sometimes a synchronized file has only 0 bytes, i.e. it's not yet synchronized fully. In this case wait a bit and try again
                if (Properties.Settings.Default.syncCollection && new FileInfo(filePath).Length == 0)
                {
                    Thread.Sleep(delayOnRetry);
                    continue;
                }
                try
                {
                    if (Path.GetExtension(filePath).ToLower() == ".xml")
                    {
                        // old format for backwards compatibility
                        using (fileStream = File.OpenRead(filePath))
                        {
                            // use xml-serializer for old library-format
                            XmlSerializer reader = new XmlSerializer(typeof(oldLibraryFormat.CreatureCollectionOld));
                            var           creatureCollectionOld = (oldLibraryFormat.CreatureCollectionOld)reader.Deserialize(fileStream);

                            List <Mod> mods = null;
                            // first check if additional values are used, and if the according values-file is already available.
                            // if not, abort conversion and first make sure the file is available, e.g. downloaded
                            if (!string.IsNullOrEmpty(creatureCollectionOld.additionalValues))
                            {
                                // usually the old filename is equal to the mod-tag
                                bool   modFound = false;
                                string modTag   = Path.GetFileNameWithoutExtension(creatureCollectionOld.additionalValues).Replace(" ", "").ToLower().Replace("gaiamod", "gaia");
                                foreach (KeyValuePair <string, ModInfo> tmi in Values.V.modsManifest.modsByTag)
                                {
                                    if (tmi.Key.ToLower() == modTag)
                                    {
                                        modFound = true;

                                        MessageBox.Show("The library contains creatures of modded species. For a correct file-conversion the correct mod-values file is needed.\n\n"
                                                        + "If the mod-value file is not loaded, the conversion may assign wrong species to your creatures.\n"
                                                        + "If the mod-value file is not available locally, it will be tried to download it.",
                                                        $"Mod values needed - {Utils.ApplicationNameVersion}", MessageBoxButtons.OK, MessageBoxIcon.Information);

                                        if (Values.V.loadedModsHash != CreatureCollection.CalculateModListHash(new List <Mod>()))
                                        {
                                            LoadStatAndKibbleValues(false); // reset values to default
                                        }
                                        LoadModValueFiles(new List <string> {
                                            tmi.Value.mod.FileName
                                        }, true, true, out mods);
                                        break;
                                    }
                                }
                                if (!modFound &&
                                    MessageBox.Show("The additional-values file in the library you're loading is unknown. You should first get a values-file in the new format for that mod.\n"
                                                    + "If you're loading the library the conversion of some modded species to the new format may fail and the according creatures have to be imported again later.\n\n"
                                                    + $"File:\n{filePath}\n"
                                                    + $"unknown mod-file: {modTag}\n\n"
                                                    + "Do you want to load the library and risk losing creatures?", $"Unknown mod-file - {Utils.ApplicationNameVersion}",
                                                    MessageBoxButtons.YesNo, MessageBoxIcon.Warning) != DialogResult.Yes)
                                {
                                    return(false);
                                }
                            }

                            _creatureCollection         = oldLibraryFormat.FormatConverter.ConvertXml2Asb(creatureCollectionOld, filePath);
                            _creatureCollection.ModList = mods;

                            if (_creatureCollection == null)
                            {
                                throw new Exception("Conversion failed");
                            }

                            string fileNameWOExt = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath));
                            // check if new fileName is not yet existing
                            filePath = fileNameWOExt + CollectionFileExtension;
                            if (File.Exists(filePath))
                            {
                                int fi = 2;
                                while (File.Exists(fileNameWOExt + "_" + fi + CollectionFileExtension))
                                {
                                    fi++;
                                }
                                filePath = fileNameWOExt + "_" + fi + CollectionFileExtension;
                            }

                            // save converted library
                            SaveCollectionToFileName(filePath);
                        }
                    }
                    else
                    {
                        // new json-format
                        if (FileService.LoadJSONFile(filePath, out CreatureCollection readCollection, out string errorMessage))
                        {
                            if (!Version.TryParse(readCollection.FormatVersion, out Version ccVersion) ||
                                !Version.TryParse(CreatureCollection.CURRENT_FORMAT_VERSION, out Version currentVersion) ||
                                ccVersion > currentVersion)
                            {
                                throw new FormatException("Unhandled format version");
                            }
                            _creatureCollection = readCollection;
                        }
                        else
                        {
                            MessageBox.Show($"Error while trying to read the library-file\n{filePath}\n\n{errorMessage}",
                                            $"{Loc.S("error")} - {Utils.ApplicationNameVersion}", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            return(false);
                        }
                    }

                    break;
                }
Пример #9
0
        private void SetCreatureValuesToExtractor(Creature c, bool onlyWild = false)
        {
            if (c != null)
            {
                Species species = c.Species;
                if (species != null)
                {
                    ClearAll();
                    // copy values over to extractor
                    for (int s = 0; s < Values.STATS_COUNT; s++)
                    {
                        _statIOs[s].Input = onlyWild ? StatValueCalculation.CalculateValue(species, s, c.levelsWild[s], 0, true, c.tamingEff, c.imprintingBonus) : c.valuesDom[s];
                    }
                    speciesSelector1.SetSpecies(species);

                    if (c.isBred)
                    {
                        rbBredExtractor.Checked = true;
                    }
                    else if (c.tamingEff >= 0)
                    {
                        rbTamedExtractor.Checked = true;
                    }
                    else
                    {
                        rbWildExtractor.Checked = true;
                    }

                    numericUpDownImprintingBonusExtractor.ValueSave = (decimal)c.imprintingBonus * 100;
                    // set total level
                    int level = onlyWild ? c.levelsWild[(int)StatNames.Torpidity] : c.Level;
                    numericUpDownLevel.ValueSave = level;

                    tabControlMain.SelectedTab = tabPageExtractor;
                }
                else
                {
                    MessageBox.Show("Unknown Species. Try to update the species-stats, or redownload the tool.", $"{Loc.S("error")} - {Utils.ApplicationNameVersion}",
                                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }
Пример #10
0
        private void SaveCollectionToFileName(string filePath)
        {
            // remove expired timers if setting is set
            if (Properties.Settings.Default.DeleteExpiredTimersOnSaving)
            {
                timerList1.DeleteAllExpiredTimers(false, false);
            }

            // Wait until the file is writeable
            const int  numberOfRetries = 5;
            const int  delayOnRetry    = 1000;
            bool       fileSaved       = false;
            FileStream fileStream      = null;

            for (int i = 1; i <= numberOfRetries; ++i)
            {
                try
                {
                    _fileSync.JustSaving();
                    using (StreamWriter file = File.CreateText(filePath))
                    {
                        JsonSerializer serializer = new JsonSerializer()
                        {
                            Formatting           = Properties.Settings.Default.prettifyCollectionJson ? Formatting.Indented : Formatting.None,
                            DateTimeZoneHandling = DateTimeZoneHandling.Utc // save all date-times as UTC, so synced files don't change the timezones
                        };
                        serializer.Serialize(file, _creatureCollection);
                    }

                    fileSaved = true;
                    Properties.Settings.Default.LastSaveFile = filePath;

                    break; // when file is saved, break
                }
                catch (IOException)
                {
                    // if file is not saveable
                    Thread.Sleep(delayOnRetry);
                }
                catch (System.Runtime.Serialization.SerializationException e)
                {
                    MessageBox.Show($"Error during serialization.\nErrormessage:\n\n{e.Message}" + (e.InnerException == null ? string.Empty : $"\n\nInnerException:{e.InnerException.Message}"),
                                    $"{Loc.S("error")} - {Utils.ApplicationNameVersion}", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
                }
                catch (InvalidOperationException e)
                {
                    MessageBox.Show($"Error during serialization.\nErrormessage:\n\n{e.Message}" + (e.InnerException == null ? string.Empty : $"\n\nInnerException:{e.InnerException.Message}"),
                                    $"{Loc.S("error")} - {Utils.ApplicationNameVersion}", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
                }
                finally
                {
                    fileStream?.Close();
                }
            }

            if (fileSaved)
            {
                SetCollectionChanged(false);
            }
            else
            {
                MessageBox.Show($"This file couldn\'t be saved:\n{filePath}\nMaybe the file is used by another application.", $"{Loc.S("error")} - {Utils.ApplicationNameVersion}", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
Пример #11
0
        private void NewCollection()
        {
            if (_collectionDirty &&
                MessageBox.Show("Your Creature Collection has been modified since it was last saved, " +
                                "are you sure you want to discard your changes and create a new Library without saving?",
                                "Discard Changes?", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) != DialogResult.Yes)
            {
                return;
            }

            if (_creatureCollection.modIDs?.Any() ?? false)
            {
                // if old collection had additionalValues, load the original ones to reset all modded values
                var(statValuesLoaded, _) = LoadStatAndKibbleValues(applySettings: false);
                if (!statValuesLoaded)
                {
                    MessageBox.Show("Couldn't load stat values. Please redownload the application.", $"{Loc.S("error")} while loading the stat-values - {Utils.ApplicationNameVersion}", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }

            if (_creatureCollection.serverMultipliers == null)
            {
                _creatureCollection.serverMultipliers = Values.V.serverMultipliersPresets.GetPreset(ServerMultipliersPresets.OFFICIAL);
            }
            // use previously used multipliers again in the new file
            ServerMultipliers oldMultipliers = _creatureCollection.serverMultipliers;

            _creatureCollection = new CreatureCollection
            {
                serverMultipliers = oldMultipliers,
                ModList           = new List <Mod>()
            };
            _creatureCollection.FormatVersion = CreatureCollection.CURRENT_FORMAT_VERSION;
            pedigree1.Clear();
            breedingPlan1.Clear();
            ApplySettingsToValues();
            InitializeCollection();

            UpdateCreatureListings();
            creatureBoxListView.Clear();
            Properties.Settings.Default.LastSaveFile = null;
            _currentFileName = null;
            _fileSync.ChangeFile(_currentFileName);
            SetCollectionChanged(false);
        }
Пример #12
0
        public void SetSpecies(Species species, bool forceRefresh = false)
        {
            if (species == null || (selectedSpecies == species && !forceRefresh))
            {
                return;
            }

            selectedSpecies = species;

            if (species.taming == null)
            {
                NoTamingData();
                return;
            }

            SuspendLayout();

            string speciesName = species.name;

            linkLabelWikiPage.Text = "Wiki: " + speciesName;
            linkLabelWikiPage.Tag  = speciesName;

            // bone damage adjusters
            boneDamageAdjustersImmobilization = Taming.BoneDamageAdjustersImmobilization(selectedSpecies,
                                                                                         out Dictionary <string, double> boneDamageAdjusters);

            int ib = 0;

            foreach (KeyValuePair <string, double> bd in boneDamageAdjusters)
            {
                ib++;
                if (ib >= rbBoneDamageAdjusters.Count)
                {
                    RadioButton rbBD = new RadioButton();
                    flcBodyDamageMultipliers.Controls.Add(rbBD);
                    flcBodyDamageMultipliers.SetFlowBreak(rbBD, true);
                    rbBD.AutoSize = true;

                    rbBoneDamageAdjusters.Add(rbBD);
                    rbBoneDamageAdjusterValues.Add(1);
                    rbBD.CheckedChanged += rbBoneDamage_CheckedChanged;
                }
                rbBoneDamageAdjusterValues[ib]    = bd.Value;
                rbBoneDamageAdjusters[ib].Text    = $"{Loc.s(bd.Key)} (× {bd.Value})";
                rbBoneDamageAdjusters[ib].Visible = true;
            }
            for (int j = ib + 1; j < rbBoneDamageAdjusters.Count; j++)
            {
                rbBoneDamageAdjusters[j].Visible = false;
            }
            rbBoneDamageAdjusters[0].Checked = true;
            // bone damage adjusters adjusted

            updateCalculation = false;
            TamingData td = species.taming;

            kibbleRecipe = "";


            // TODO replace with new kibble recipes
            //if (td.favoriteKibble != null && Kibbles.K.kibble.ContainsKey(td.favoriteKibble))
            //{
            //    kibbleRecipe = "\n\nKibble:" + Kibbles.K.kibble[td.favoriteKibble].RecipeAsText();
            //}

            foodDepletion = td.foodConsumptionBase * td.foodConsumptionMult * tamingFoodRateMultiplier;

            int i = 0;

            if (td.eats != null)
            {
                for (i = 0; i < td.eats.Count; i++)
                {
                    string            f = td.eats[i];
                    TamingFoodControl tf;

                    // if Augmented are not wanted, and food control already exist, update it and hide it.
                    if (!checkBoxAugmented.Checked && f.Contains("Augmented"))
                    {
                        if (i < foodControls.Count)
                        {
                            tf          = foodControls[i];
                            tf.FoodName = f;
                            tf.Hide();
                        }
                        continue;
                    }

                    if (i >= foodControls.Count)
                    {
                        tf = new TamingFoodControl(f);
                        tf.valueChanged += UpdateTamingData;
                        tf.Clicked      += OnlyOneFood;
                        foodControls.Add(tf);
                        flpTamingFood.Controls.Add(tf);
                    }
                    else
                    {
                        tf          = foodControls[i];
                        tf.FoodName = f;
                        tf.Show();
                    }
                    if (f == "Kibble")
                    {
                        tf.foodNameDisplay = $"Kibble ({td.favoriteKibble} {Loc.s("Egg")})";
                    }
                    if (td.specialFoodValues != null && td.specialFoodValues.ContainsKey(f) && td.specialFoodValues[f].quantity > 1)
                    {
                        tf.foodNameDisplay = td.specialFoodValues[f].quantity + "× " + tf.foodNameDisplay;
                    }
                }
            }

            for (int fci = foodControls.Count - 1; fci >= i; fci--)
            {
                foodControls[fci].Hide();
            }

            if (i > 0)
            {
                foodControls[0].amount = Taming.FoodAmountNeeded(species, (int)nudLevel.Value, tamingSpeedMultiplier, foodControls[0].FoodName, td.nonViolent);
            }

            updateCalculation = true;
            UpdateFirstFeedingWaiting();
            UpdateTamingData();

            ResumeLayout();
        }
        /// <summary>
        /// Import exported file. Used by a fileWatcher.
        /// </summary>
        /// <param name="filePath"></param>
        private void ImportExportedAddIfPossible(string filePath)
        {
            var loadResult = ExtractExportedFileInExtractor(filePath);

            if (!loadResult.HasValue)
            {
                return;
            }

            bool alreadyExists       = loadResult.Value;
            bool added               = false;
            bool copyNameToClipboard = Properties.Settings.Default.copyNameToClipboardOnImportWhenAutoNameApplied &&
                                       (Properties.Settings.Default.applyNamePatternOnAutoImportAlways ||
                                        Properties.Settings.Default.applyNamePatternOnImportIfEmptyName ||
                                        (!alreadyExists && Properties.Settings.Default.applyNamePatternOnAutoImportForNewCreatures)
                                       );
            Species  species  = speciesSelector1.SelectedSpecies;
            Creature creature = null;

            if (_extractor.UniqueResults ||
                (alreadyExists && _extractor.ValidResults))
            {
                creature = AddCreatureToCollection(true, goToLibraryTab: Properties.Settings.Default.AutoImportGotoLibraryAfterSuccess);
                SetMessageLabelText($"Successful {(alreadyExists ? "updated" : "added")} {creature.name} ({species.name}) of the exported file\n" + filePath, MessageBoxIcon.Information, filePath);
                added = true;
            }

            bool topLevels    = false;
            bool newTopLevels = false;

            // give feedback in overlay
            string    infoText;
            Color     textColor;
            const int colorSaturation = 200;

            if (added)
            {
                var sb = new StringBuilder();
                sb.AppendLine($"{species.name} \"{creature.name}\" {(alreadyExists ? "updated in " : "added to")} the library.");
                if (copyNameToClipboard)
                {
                    sb.AppendLine("Name copied to clipboard.");
                }

                for (int s = 0; s < values.Values.STATS_COUNT; s++)
                {
                    int statIndex = values.Values.statsDisplayOrder[s];
                    if (!species.UsesStat(statIndex))
                    {
                        continue;
                    }

                    sb.Append($"{Utils.StatName(statIndex, true, species.statNames)}: { _statIOs[statIndex].LevelWild} ({_statIOs[statIndex].BreedingValue})");
                    if (_statIOs[statIndex].TopLevel == StatIOStatus.NewTopLevel)
                    {
                        sb.Append($" {Loc.S("newTopLevel")}");
                        newTopLevels = true;
                    }
                    else if (_statIOs[statIndex].TopLevel == StatIOStatus.TopLevel)
                    {
                        sb.Append($" {Loc.S("topLevel")}");
                        topLevels = true;
                    }
                    sb.AppendLine();
                }

                infoText  = sb.ToString();
                textColor = Color.FromArgb(colorSaturation, 255, colorSaturation);
            }
            else
            {
                infoText  = $"Creature \"{creatureInfoInputExtractor.CreatureName}\" couldn't be extracted uniquely, manual level selection is necessary.";
                textColor = Color.FromArgb(255, colorSaturation, colorSaturation);
            }

            if (_overlay != null)
            {
                _overlay.SetInfoText(infoText, textColor);
                if (Properties.Settings.Default.DisplayInheritanceInOverlay && creature != null)
                {
                    _overlay.SetInheritanceCreatures(creature, creature.Mother, creature.Father);
                }
            }

            if (added)
            {
                if (Properties.Settings.Default.DeleteAutoImportedFile)
                {
                    FileService.TryDeleteFile(filePath);
                }
                else if (Properties.Settings.Default.MoveAutoImportedFileToSubFolder || Properties.Settings.Default.AutoImportedExportFileRename)
                {
                    string newPath = Properties.Settings.Default.MoveAutoImportedFileToSubFolder
                        ? (string.IsNullOrEmpty(Properties.Settings.Default.ImportExportedArchiveFolder)
                            ? Path.Combine(Path.GetDirectoryName(filePath), "imported")
                            : Properties.Settings.Default.ImportExportedArchiveFolder)
                        : Path.GetDirectoryName(filePath);

                    if (Properties.Settings.Default.MoveAutoImportedFileToSubFolder &&
                        !FileService.TryCreateDirectory(newPath, out string errorMessage))
                    {
                        MessageBoxes.ShowMessageBox($"Subfolder\n{newPath}\ncould not be created.\n{errorMessage}");
                        return;
                    }

                    string namePattern = Properties.Settings.Default.AutoImportedExportFileRenamePattern;

                    string newFileName = Properties.Settings.Default.AutoImportedExportFileRename && !string.IsNullOrWhiteSpace(namePattern)
                        ? NamePatterns.GenerateCreatureName(creature,
                                                            _creatureCollection.creatures.Where(c => c.Species == speciesSelector1.SelectedSpecies).ToArray(), null, null,
                                                            _customReplacingNamingPattern, false, -1, false, namePattern)
                        : Path.GetFileName(filePath);

                    string newFileNameWithoutExtension = Path.GetFileNameWithoutExtension(newFileName);
                    string newFileNameExtension        = Path.GetExtension(newFileName);
                    string newFilePath = Path.Combine(newPath, newFileName);
                    int    fileSuffix  = 1;
                    while (File.Exists(newFilePath))
                    {
                        newFilePath = Path.Combine(newPath, $"{newFileNameWithoutExtension}_{++fileSuffix}{newFileNameExtension}");
                    }

                    if (FileService.TryMoveFile(filePath, newFilePath))
                    {
                        _librarySelectionInfoClickPath = newFilePath;
                    }
                }
            }
            else if (copyNameToClipboard)
            {
                // extraction failed, user might expect the name of the new creature in the clipboard
                Clipboard.SetText("Automatic extraction was not possible");
            }

            if (Properties.Settings.Default.PlaySoundOnAutoImport)
            {
                if (added)
                {
                    if (alreadyExists)
                    {
                        SoundFeedback.BeepSignal(SoundFeedback.FeedbackSounds.Indifferent);
                    }
                    if (newTopLevels)
                    {
                        SoundFeedback.BeepSignal(SoundFeedback.FeedbackSounds.Great);
                    }
                    else if (topLevels)
                    {
                        SoundFeedback.BeepSignal(SoundFeedback.FeedbackSounds.Good);
                    }
                    else
                    {
                        SoundFeedback.BeepSignal(SoundFeedback.FeedbackSounds.Success);
                    }
                }
                else
                {
                    SoundFeedback.BeepSignal(SoundFeedback.FeedbackSounds.Failure);
                }
            }
        }
Пример #14
0
 /// <summary>
 /// Returns the formated timespan and also the DateTime when the timespan is over
 /// </summary>
 /// <param name="ts">timespan of countdown</param>
 /// <returns>Returns the timespan and the DateTime when the timespan is over</returns>
 public static string DurationUntil(TimeSpan ts)
 {
     return(ts.ToString("d':'hh':'mm':'ss") + " (" + Loc.S("until") + ": " + ShortTimeDate(DateTime.Now.Add(ts)) + ")");
 }
Пример #15
0
 public static void InitializeLocalizations()
 {
     _statNames    = new[] { Loc.S("Health"), Loc.S("Stamina"), Loc.S("Torpidity"), Loc.S("Oxygen"), Loc.S("Food"), Loc.S("Water"), Loc.S("Temperature"), Loc.S("Weight"), Loc.S("Damage"), Loc.S("Speed"), Loc.S("Fortitude"), Loc.S("Crafting Speed") };
     _statNamesAbb = new[] { Loc.S("Health_Abb"), Loc.S("Stamina_Abb"), Loc.S("Torpidity_Abb"), Loc.S("Oxygen_Abb"), Loc.S("Food_Abb"), Loc.S("Water_Abb"), Loc.S("Temperature_Abb"), Loc.S("Weight_Abb"), Loc.S("Damage_Abb"), Loc.S("Speed_Abb"), Loc.S("Fortitude_Abb"), Loc.S("Crafting Speed_Abb") };
 }
Пример #16
0
        public static string KnockoutInfo(Species species, int level, double longneck, double crossbow, double bow, double slingshot,
                                          double club, double prod, double harpoon, double boneDamageAdjuster, out bool knockoutNeeded, out string koNumbers)
        {
            koNumbers      = string.Empty;
            knockoutNeeded = false;
            if (species?.taming != null)
            {
                //total torpor for level
                double totalTorpor = species.stats[(int)StatNames.Torpidity].BaseValue * (1 + species.stats[(int)StatNames.Torpidity].IncPerWildLevel * (level - 1));
                // torpor depletion per second for level
                double torporDeplPS = TorporDepletionPS(species.taming.torporDepletionPS0, level);

                knockoutNeeded = species.taming.violent;
                string warning = string.Empty;
                if (!knockoutNeeded)
                {
                    warning = "+++ Creature must not be knocked out for taming! +++\n\n";
                }

                // print needed tranq arrows needed to ko creature.
                // wooden club: 10 torpor
                // slingshot: 14 dmg, stone - tranq - mult: 1.75 ==> 24.5 torpor
                // Bow - arrow causes 20 dmg, tranqMultiplier are 2 + 2.5 = 4.5 ==> 90 Torpor / arrow.
                // crossbow 35 dmg * 4.5 ==> 157.5 torpor
                // longneck dart: 26 * 8.5 = 221
                // shocking tranq dart: 26*17 = 442
                // electric prod: 226

                koNumbers = (harpoon > 0 ? Math.Ceiling(totalTorpor / (306 * boneDamageAdjuster * harpoon)) + " × " + Loc.s("TranqSpearBolts") + "\n" : string.Empty)
                            + (longneck > 0 ? Math.Ceiling(totalTorpor / (442 * boneDamageAdjuster * longneck)) + " × " + Loc.s("ShockingTranqDarts") + "\n" : string.Empty)
                            + (longneck > 0 ? Math.Ceiling(totalTorpor / (221 * boneDamageAdjuster * longneck)) + " × " + Loc.s("TranqDarts") + "\n" : string.Empty)
                            + (prod > 0 ? Math.Ceiling(totalTorpor / (226 * boneDamageAdjuster * prod)) + " × " + Loc.s("ElectricProdHits") + "\n" : string.Empty)
                            + (crossbow > 0 ? Math.Ceiling(totalTorpor / (157.5 * boneDamageAdjuster * crossbow)) + " × " + Loc.s("TranqArrowsCrossBow") + "\n" : string.Empty)
                            + (bow > 0 ? Math.Ceiling(totalTorpor / (90 * boneDamageAdjuster * bow)) + " × " + Loc.s("TranqArrowsBow") + "\n" : string.Empty)
                            + (slingshot > 0 ? Math.Ceiling(totalTorpor / (24.5 * boneDamageAdjuster * slingshot)) + " × " + Loc.s("SlingshotHits") + "\n" : string.Empty)
                            + (club > 0 ? Math.Ceiling(totalTorpor / (10 * boneDamageAdjuster * club)) + " × " + Loc.s("WoodenClubHits") + "\n" : string.Empty);

                // torpor depletion per s
                string torporDepletion = string.Empty;
                if (torporDeplPS > 0)
                {
                    torporDepletion = "\n" + Loc.s("TimeUntilTorporDepleted") + ": " + Utils.DurationUntil(new TimeSpan(0, 0, (int)Math.Round(totalTorpor / torporDeplPS)))
                                      + "\n" + Loc.s("TorporDepletion") + ": " + Math.Round(torporDeplPS, 2)
                                      + " / s;\n" + Loc.s("ApproxOneNarcoberryEvery") + " " + Math.Round(7.5 / torporDeplPS + 3, 1)
                                      + " s " + Loc.s("OrOneAscerbicMushroom") + " " + Math.Round(25 / torporDeplPS + 3, 1)
                                      + " s " + Loc.s("OrOneNarcoticEvery") + " " + Math.Round(40 / torporDeplPS + 8, 1)
                                      + " s " + Loc.s("OrOneBioToxinEvery") + " " + Math.Round(80 / torporDeplPS + 16, 1) + " s";
                }

                return(warning + koNumbers + torporDepletion);
            }
            return(string.Empty);
        }