diff --git a/ARKBreedingStats/ARKBreedingStats.csproj b/ARKBreedingStats/ARKBreedingStats.csproj index da648cf2..b0efff1c 100644 --- a/ARKBreedingStats/ARKBreedingStats.csproj +++ b/ARKBreedingStats/ARKBreedingStats.csproj @@ -99,6 +99,7 @@ + Component @@ -666,6 +667,15 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + TextTemplatingFileGenerator _manifest.json diff --git a/ARKBreedingStats/NamePatterns/NameList.cs b/ARKBreedingStats/NamePatterns/NameList.cs new file mode 100644 index 00000000..571894d9 --- /dev/null +++ b/ARKBreedingStats/NamePatterns/NameList.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ARKBreedingStats.NamePatterns +{ + /// + /// Loads a list of names from a file. + /// + internal static class NameList + { + /// + /// Contains all name lists, key is the fileName suffix. + /// + private static readonly Dictionary nameLists = new Dictionary(); + private static readonly Dictionary listFileCheckedAt = new Dictionary(); + + /// + /// Returns a name from a list. If the file wasn't checked recently, it's checked and reloaded. + /// + public static string GetName(int nameIndex = 0, string listSuffix = null) + { + if (nameIndex < 0) return null; + var nameList = GetNameList(listSuffix); + if (nameList == null || nameList.Length == 0) return null; + + if (nameIndex >= nameList.Length) + nameIndex %= nameList.Length; + return nameList[nameIndex]; + } + + /// + /// Returns a name list. + /// + public static string[] GetNameList(string listSuffix = null) + { + if (listSuffix == null) listSuffix = string.Empty; + string[] list; + if (!listFileCheckedAt.TryGetValue(listSuffix, out var checkedAt) + || (DateTime.Now - checkedAt).TotalSeconds > 10 + || !nameLists.TryGetValue(listSuffix, out list)) + { + list = LoadList(listSuffix, checkedAt); + } + return list; + } + + private static string[] LoadList(string listSuffix, DateTime checkedAt) + { + var filePath = FileService.GetJsonPath("creatureNames" + listSuffix + ".txt"); + + if (!File.Exists(filePath)) return null; + try + { + if (new FileInfo(filePath).LastWriteTime > checkedAt) + { + var list = File.ReadAllLines(filePath); + nameLists[listSuffix] = list; + } + listFileCheckedAt[listSuffix] = DateTime.Now; + return nameLists[listSuffix]; + } + catch { } + return null; + } + } +} diff --git a/ARKBreedingStats/NamePatterns/NamePatternFunctions.cs b/ARKBreedingStats/NamePatterns/NamePatternFunctions.cs index da7579d6..4ebff1d5 100644 --- a/ARKBreedingStats/NamePatterns/NamePatternFunctions.cs +++ b/ARKBreedingStats/NamePatterns/NamePatternFunctions.cs @@ -59,7 +59,8 @@ private static string ParametersInvalid(string specificError, string expression, {"color", FunctionColor}, {"colornew", FunctionColorNew}, {"indexof", FunctionIndexOf}, - {"md5", FunctionMd5} + {"md5", FunctionMd5}, + {"listname", FunctionListName } }; private static string FunctionIf(Match m, NamePatternParameters p) @@ -375,6 +376,14 @@ private static string FunctionMd5(Match m, NamePatternParameters p) return sb.ToString(); } + private static string FunctionListName(Match m, NamePatternParameters p) + { + // parameter: 1: name index, 2: list suffix + if (!int.TryParse(m.Groups[2].Value, out var nameIndex)) return string.Empty; + + return NameList.GetName(nameIndex, m.Groups[3].Value); + } + public static void Dispose() { _md5?.Dispose(); diff --git a/ARKBreedingStats/NamePatterns/PatternEditor.cs b/ARKBreedingStats/NamePatterns/PatternEditor.cs index d2094323..74cbdbd6 100644 --- a/ARKBreedingStats/NamePatterns/PatternEditor.cs +++ b/ARKBreedingStats/NamePatterns/PatternEditor.cs @@ -533,15 +533,16 @@ private void InsertText(string text) {"customreplace","{{#customreplace: text }}. Replaces the text with a value saved in the file customReplacings.json.\nIf a second parameter is given, that is returned if the key is not available.\n{{#customreplace: {species} }}"}, {"float divide by","{{#float_div: number | divisor | formatString }}, can be used to display stat-values in thousands, e.g. '{{#float_div: {hp_vb} | 1000 | F2 }}kHP'.\n{{#float_div: {hp_vb} | 1000 | F2 }}"}, {"divide by","{{#div: number | divisor }}, can be used to display stat-values in thousands, e.g. '{{#div: {hp_vb} | 1000 }}kHP'.\n{{#div: {hp_vb} | 1000 }}"}, - {"padleft","{{#padleft: number | length | padding character }}\n{{#padleft: {hp_vb} | 8 | 0 }}"}, - {"padright","{{#padright: number | length | padding character }}\n{{#padright: {hp_vb} | 8 | _ }}"}, + {"listName","{{#listName: nameIndex | listSuffix }}, takes a name from a list in the file creatureNames[suffix].txt\n{{#listName: 0 | {sex_short} }}"}, + {"padLeft","{{#padLeft: number | length | padding character }}\n{{#padLeft: {hp_vb} | 8 | 0 }}"}, + {"padRight","{{#padRight: number | length | padding character }}\n{{#padRight: {hp_vb} | 8 | _ }}"}, {"casing","{{#casing: text | case (U, L, T) }}. U for UPPER, L for lower, T for Title.\n{{#casing: {species} | U }}"}, {"time","{{#time: formatString }}\n{{#time: yyyy-MM-dd_HH:mm }}"}, {"format","{{#format: number | formatString }}\n{{#format: {hp_vb} | 000000 }}"}, {"format_int","Like #format, but supports \"x\" in the format for hexadecimal representations. {{#format_int: number | formatString }}\n{{#format_int: {{#color: 0 }} | x2 }}"}, {"color","{{#color: regionId | return color name | return value even for unused regions }}. Returns the colorId of the region. If the second parameter is not empty, the color name will be returned. Unused regions will only return a value if the third value is not empty.\n{{#color: 0 | true }}"}, {"colorNew","{{#colorNew: regionId }}. Returns newInRegion if the region contains a color that is not yet available in that species. Returns newInSpecies if that color is not yet available in any region of that species.\n{{#colorNew: 0 }}"}, - {"indexof","{{#indexof: source string | string to find }}. Returns the index of the second parameter in the first parameter. If the string is not contained, an empty string will be returned.\n{{#indexof: hello | ll }}"}, + {"indexOf","{{#indexof: source string | string to find }}. Returns the index of the second parameter in the first parameter. If the string is not contained, an empty string will be returned.\n{{#indexof: hello | ll }}"}, {"md5", "{{#md5: string }}, returns the md5 hash of a given string\n{{#md5: {hp}{st}{we} }}"} }; diff --git a/ARKBreedingStats/json/creatureNamesF.txt b/ARKBreedingStats/json/creatureNamesF.txt new file mode 100644 index 00000000..784baa65 --- /dev/null +++ b/ARKBreedingStats/json/creatureNamesF.txt @@ -0,0 +1,38 @@ +Aurora +Bess +Bones +Breeze +Casey +Casia +Catlin +Chromy +Chuckles +Cosmo +Cupcake +Danele +Daphne +Durva +Electra +Ellie +Elora +Flare +Ginger +Hope +Indigo +Jackie +Layka +Myst +Nectar +Oracle +Pandora +Peachy +Peanuts +Princess +Raye +Sabre +Shellbie +Shine +Tia +Vanity +Wilde +Zara \ No newline at end of file diff --git a/ARKBreedingStats/json/creatureNamesM.txt b/ARKBreedingStats/json/creatureNamesM.txt new file mode 100644 index 00000000..062216f2 --- /dev/null +++ b/ARKBreedingStats/json/creatureNamesM.txt @@ -0,0 +1,19 @@ +Austin +Bran +Cosmo +Dearborn +Eclipse +Fuzz +Gazoo +Hercules +Indy +Jiggles +Lightning +Marble +Noah +Pepper +Rancher +Sparkler +Tweeter +Whiskers +Zion \ No newline at end of file diff --git a/ARKBreedingStats/json/creatureNamesU.txt b/ARKBreedingStats/json/creatureNamesU.txt new file mode 100644 index 00000000..71d013db --- /dev/null +++ b/ARKBreedingStats/json/creatureNamesU.txt @@ -0,0 +1,28 @@ +Acorn +Bailey +Blaze +Casey +Caramel +Dara +Echo +Fluffy +Goldy +Harper +Indie +Java +Kiwi +Lake +Marley +Max +Ninja +Olive +Onyx +Phoenix +Quinn +Riley +Sable +Scout +Smokey +Sunny +Tiny +Waffles \ No newline at end of file diff --git a/ARKBreedingStats/library/DummyCreatures.cs b/ARKBreedingStats/library/DummyCreatures.cs index 22c0cd47..52d7323c 100644 --- a/ARKBreedingStats/library/DummyCreatures.cs +++ b/ARKBreedingStats/library/DummyCreatures.cs @@ -3,6 +3,7 @@ using System.Linq; using ARKBreedingStats.BreedingPlanning; using ARKBreedingStats.Library; +using ARKBreedingStats.NamePatterns; using ARKBreedingStats.species; using ARKBreedingStats.values; @@ -15,6 +16,9 @@ public static class DummyCreatures { public static DummyCreatureCreationSettings LastSettings; + private static string[] _namesFemale; + private static string[] _namesMale; + /// /// Creates a list of random creatures. /// @@ -147,18 +151,29 @@ public static Creature CreateCreature(Species species, double difficulty = 5, bo string name = null; if (doTame) { + if (_namesFemale == null) + _namesFemale = NameList.GetNameList("F"); + if (_namesMale == null) + _namesMale = NameList.GetNameList("M"); var names = sex == Sex.Female ? _namesFemale : _namesMale; - name = names[rand.Next(names.Length)]; - if (nameCounter != null) + if (names == null) { - if (nameCounter.TryGetValue(name, out var nameCount)) - { - nameCounter[name]++; - name += $" {nameCount + 1}"; - } - else + name = "?"; + } + else + { + name = names[rand.Next(names.Length)]; + if (nameCounter != null) { - nameCounter.Add(name, 1); + if (nameCounter.TryGetValue(name, out var nameCount)) + { + nameCounter[name]++; + name += $" {nameCount + 1}"; + } + else + { + nameCounter.Add(name, 1); + } } } } @@ -377,9 +392,6 @@ private static List BreedCreatures(Creature[] creatures, Species speci } - private static readonly string[] _namesFemale = { "Aurora", "Bess", "Bones", "Breeze", "Casey", "Casia", "Catlin", "Chromy", "Chuckles", "Cosmo", "Cupcake", "Danele", "Daphne", "Durva", "Electra", "Ellie", "Elora", "Flare", "Ginger", "Hope", "Indigo", "Jackie", "Layka", "Myst", "Nectar", "Oracle", "Pandora", "Peachy", "Peanuts", "Princess", "Raye", "Sabre", "Shellbie", "Shine", "Tia", "Vanity", "Wilde", "Zara" }; - private static readonly string[] _namesMale = { "Austin", "Bran", "Cosmo", "Dearborn", "Eclipse", "Fuzz", "Gazoo", "Hercules", "Indy", "Jiggles", "Lightning", "Marble", "Noah", "Pepper", "Rancher", "Sparkler", "Tweeter", "Whiskers", "Zion" }; - #region Binomial distributed levels /// diff --git a/setup.iss b/setup.iss index 4653a5c8..08c4cf9a 100644 --- a/setup.iss +++ b/setup.iss @@ -89,6 +89,7 @@ Source: "{#ReleaseDir}\tr\*"; DestDir: "{app}\tr\"; Excludes: "*.pdb,*.xml"; Fla Source: "{#ReleaseDir}\zh\*"; DestDir: "{app}\zh\"; Excludes: "*.pdb,*.xml"; Flags: ignoreversion skipifsourcedoesntexist Source: "{#ReleaseDir}\_manifest.json"; DestDir: "{localappdata}\{#AppName}\"; Flags: ignoreversion Source: "{#ReleaseDir}\json\*.json"; DestDir: "{localappdata}\{#AppName}\json\"; Flags: ignoreversion +Source: "{#ReleaseDir}\json\*.txt"; DestDir: "{localappdata}\{#AppName}\json\"; Flags: ignoreversion Source: "{#ReleaseDir}\json\values\values.json"; DestDir: "{localappdata}\{#AppName}\json\values\"; Flags: ignoreversion Source: "{#ReleaseDir}\json\values\ASA-values.json"; DestDir: "{localappdata}\{#AppName}\json\values\"; Flags: ignoreversion Source: "{#ReleaseDir}\json\values\_manifest.json"; DestDir: "{localappdata}\{#AppName}\json\values\"; Flags: ignoreversion