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