Example #1
0
        /// <summary>
        /// Resolves the naming-pattern functions
        /// </summary>
        /// <returns></returns>
        private static string ResolveFunction(Match m, NamePatternParameters parameters)
        {
            // function parameters can be non numeric if numbers are parsed
            try
            {
                if (!parameters.ProcessNumberField && m.Groups[2].Value.Contains("{n}"))
                {
                    return(m.Groups[0].Value);
                }

                return(NamePatternFunctions.ResolveFunction(m, parameters));
            }
            catch (Exception ex)
            {
                MessageBoxes.ExceptionMessageBox(ex, $"The syntax of the following pattern function\n{m.Groups[0].Value}\ncannot be processed and will be ignored.", "Naming pattern function error");
            }
            return(string.Empty);
        }
Example #2
0
        /// <summary>
        /// Generate a creature name with the naming pattern.
        /// </summary>
        public static string GenerateCreatureName(Creature creature, Creature[] sameSpecies, int[] speciesTopLevels, int[] speciesLowestLevels, Dictionary <string, string> customReplacings, bool showDuplicateNameWarning, int namingPatternIndex, bool showTooLongWarning = true, string pattern = null, bool displayError = true, Dictionary <string, string> tokenDictionary = null)
        {
            var creatureNames = sameSpecies?.Where(c => c.guid != creature.guid).Select(x => x.name).ToArray() ?? new string[0];

            if (pattern == null)
            {
                if (namingPatternIndex == -1)
                {
                    pattern = string.Empty;
                }
                else
                {
                    pattern = Properties.Settings.Default.NamingPatterns?[namingPatternIndex] ?? string.Empty;
                }
            }

            if (creature.topness == 0)
            {
                if (speciesTopLevels == null)
                {
                    creature.topness = 1000;
                }
                else
                {
                    int topLevelSum      = 0;
                    int creatureLevelSum = 0;
                    for (int s = 0; s < Values.STATS_COUNT; s++)
                    {
                        if (s != (int)StatNames.Torpidity &&
                            creature.Species.UsesStat(s) &&
                            (Properties.Settings.Default.consideredStats & (1 << s)) != 0
                            )
                        {
                            int creatureLevel = Math.Max(0, creature.levelsWild[s]);
                            topLevelSum      += Math.Max(creatureLevel, speciesTopLevels[s]);
                            creatureLevelSum += creatureLevel;
                        }
                    }
                    if (topLevelSum != 0)
                    {
                        creature.topness = (short)(creatureLevelSum * 1000f / topLevelSum);
                    }
                    else
                    {
                        creature.topness = 1000;
                    }
                }

                if (tokenDictionary != null)
                {
                    tokenDictionary["topPercent"] = (creature.topness / 10f).ToString();
                }
            }

            if (tokenDictionary == null)
            {
                tokenDictionary = CreateTokenDictionary(creature, sameSpecies, speciesTopLevels, speciesLowestLevels);
            }
            // first resolve keys, then functions
            string name = ResolveFunctions(
                ResolveKeysToValues(tokenDictionary, pattern.Replace("\r", string.Empty).Replace("\n", string.Empty)),
                creature, customReplacings, displayError, false);

            if (name.Contains("{n}"))
            {
                // replace the unique number key with the lowest possible positive number >= 1 to get a unique name.
                string numberedUniqueName;
                string lastNumberedUniqueName = null;

                int n = 1;
                do
                {
                    numberedUniqueName = ResolveFunctions(
                        ResolveKeysToValues(tokenDictionary, name, n++),
                        creature, customReplacings, displayError, true);

                    // check if numberedUniqueName actually is different, else break the potentially infinite loop. E.g. it is not different if {n} is an unreached if branch or was altered with other functions
                    if (numberedUniqueName == lastNumberedUniqueName)
                    {
                        break;
                    }

                    lastNumberedUniqueName = numberedUniqueName;
                } while (creatureNames.Contains(numberedUniqueName, StringComparer.OrdinalIgnoreCase));
                name = numberedUniqueName;
            }

            // evaluate escaped characters
            name = NamePatternFunctions.UnEscapeSpecialCharacters(name.Replace(PipeEscapeSequence, "|"));

            if (showDuplicateNameWarning && creatureNames.Contains(name, StringComparer.OrdinalIgnoreCase))
            {
                MessageBox.Show($"The generated name for the creature\n{name}\nalready exists in the library.\n\nConsider adding {{n}} or {{sn}} in the pattern to generate unique names.", "Name already exists", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            else if (showTooLongWarning && name.Length > 24)
            {
                MessageBox.Show("The generated name is longer than 24 characters, the name will look like this in game:\n" + name.Substring(0, 24), "Name too long for game", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }

            return(name);
        }