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/AsbServer/Connection.cs b/ARKBreedingStats/AsbServer/Connection.cs
index cee24de1..40a49a0c 100644
--- a/ARKBreedingStats/AsbServer/Connection.cs
+++ b/ARKBreedingStats/AsbServer/Connection.cs
@@ -37,7 +37,7 @@ public static async void StartListeningAsync(
try
{
- using (var client = new HttpClient())
+ var client = FileService.GetHttpClient;
using (var response = await client.GetAsync(requestUri, HttpCompletionOption.ResponseHeadersRead))
{
if (!response.IsSuccessStatusCode)
@@ -186,16 +186,17 @@ public static async void SendCreatureData(Creature creature, string token)
{
if (creature == null || string.IsNullOrEmpty(token)) return;
- using (var client = new HttpClient())
+ var client = FileService.GetHttpClient;
+
+ var contentString = Newtonsoft.Json.JsonConvert.SerializeObject(ImportExportGun.ConvertCreatureToExportGunFile(creature, out _));
+ var msg = new HttpRequestMessage(HttpMethod.Put, ApiUri + "export/" + token);
+ msg.Content = new StringContent(contentString, Encoding.UTF8, "application/json");
+ msg.Content.Headers.Add("Content-Length", contentString.Length.ToString());
+ using (var response = await client.SendAsync(msg))
{
- var contentString = Newtonsoft.Json.JsonConvert.SerializeObject(ImportExportGun.ConvertCreatureToExportGunFile(creature, out _));
- var msg = new HttpRequestMessage(HttpMethod.Put, ApiUri + "export/" + token);
- msg.Content = new StringContent(contentString, Encoding.UTF8, "application/json");
- msg.Content.Headers.Add("Content-Length", contentString.Length.ToString());
- var response = await client.SendAsync(msg);
Console.WriteLine($"Sent creature data of {creature} using token: {token}\nContent:\n{contentString}");
Console.WriteLine(msg.ToString());
- Console.WriteLine($"Response: Status: {(int)response.StatusCode}, ReasonPhrase: {response.ReasonPhrase}");
+ Console.WriteLine($"Response: StatusCode {(int)response.StatusCode}, ReasonPhrase: {response.ReasonPhrase}");
}
}
diff --git a/ARKBreedingStats/BreedingPlanning/BreedingScore.cs b/ARKBreedingStats/BreedingPlanning/BreedingScore.cs
index 31ef4ae1..d5b05bc9 100644
--- a/ARKBreedingStats/BreedingPlanning/BreedingScore.cs
+++ b/ARKBreedingStats/BreedingPlanning/BreedingScore.cs
@@ -86,8 +86,8 @@ public static List CalculateBreedingScores(Creature[] females, Cre
{
if (s == Stats.Torpidity || !species.UsesStat(s)) continue;
bestPossLevels[s] = 0;
- int higherLevel = Math.Max(female.levelsWild[s] + female.levelsMutated?[s] ?? 0, male.levelsWild[s] + male.levelsMutated?[s] ?? 0);
- int lowerLevel = Math.Min(female.levelsWild[s] + female.levelsMutated?[s] ?? 0, male.levelsWild[s] + male.levelsMutated?[s] ?? 0);
+ int higherLevel = Math.Max(female.levelsWild[s] + (female.levelsMutated?[s] ?? 0), male.levelsWild[s] + (male.levelsMutated?[s] ?? 0));
+ int lowerLevel = Math.Min(female.levelsWild[s] + (female.levelsMutated?[s] ?? 0), male.levelsWild[s] + (male.levelsMutated?[s] ?? 0));
if (higherLevel < 0) higherLevel = 0;
if (lowerLevel < 0) lowerLevel = 0;
maxPossibleOffspringLevel += higherLevel;
diff --git a/ARKBreedingStats/FileService.cs b/ARKBreedingStats/FileService.cs
index ce2c7a83..c46b620b 100644
--- a/ARKBreedingStats/FileService.cs
+++ b/ARKBreedingStats/FileService.cs
@@ -1,5 +1,6 @@
using System;
using System.IO;
+using System.Net.Http;
using System.Reflection;
using System.Runtime.Serialization;
@@ -280,5 +281,20 @@ internal static bool IsValidJsonFile(string filePath)
//}
//catch { return false; }
}
+
+ private static HttpClient _httpClient;
+
+ ///
+ /// Returns a static HttpClient. It's apparently better to reuse on object per app only.
+ ///
+ public static HttpClient GetHttpClient
+ {
+ get
+ {
+ if (_httpClient == null)
+ _httpClient = new HttpClient();
+ return _httpClient;
+ }
+ }
}
}
diff --git a/ARKBreedingStats/Form1.cs b/ARKBreedingStats/Form1.cs
index f43838b0..7cc99510 100644
--- a/ARKBreedingStats/Form1.cs
+++ b/ARKBreedingStats/Form1.cs
@@ -273,7 +273,7 @@ private void Form1_Load(object sender, EventArgs e)
if (Properties.Settings.Default.LibraryShowMutationLevelColumns)
toolStripMenuItemMutationColumns.Checked = true;
else
- ShowLibraryMutationLevels(false);
+ ToggleLibraryMutationLevelColumns(false);
_creatureListSorter.SortColumnIndex = Properties.Settings.Default.listViewSortCol;
_creatureListSorter.Order = Properties.Settings.Default.listViewSortAsc
@@ -1282,14 +1282,17 @@ private void Form1_FormClosed(object sender, FormClosedEventArgs e)
}
// Save column-widths, display-indices and sort-order of the TimerControlListView
- SaveListViewSettings(timerList1.ListViewTimers, "TCLVColumnWidths", "TCLVColumnDisplayIndices", "TCLVSortCol", "TCLVSortAsc");
- SaveListViewSettings(pedigree1.ListViewCreatures, "PedigreeListViewColumnWidths");
+ SaveListViewSettings(timerList1.ListViewTimers, nameof(Properties.Settings.TCLVColumnWidths),
+ nameof(Properties.Settings.TCLVColumnDisplayIndices), nameof(Properties.Settings.TCLVSortCol), nameof(Properties.Settings.TCLVSortAsc));
+ SaveListViewSettings(pedigree1.ListViewCreatures, nameof(Properties.Settings.PedigreeListViewColumnWidths));
Properties.Settings.Default.PedigreeWidthLeftColum = pedigree1.LeftColumnWidth;
- SaveListViewSettings(tribesControl1.ListViewPlayers, "PlayerListColumnWidths", "PlayerListColumnDisplayIndices", "PlayerListSortColumn", "PlayerListSortAsc");
+ SaveListViewSettings(tribesControl1.ListViewPlayers, nameof(Properties.Settings.PlayerListColumnWidths),
+ nameof(Properties.Settings.PlayerListColumnDisplayIndices), nameof(Properties.Settings.PlayerListSortColumn), nameof(Properties.Settings.PlayerListSortAsc));
// Save column-widths, display-indices and sort-order of the listViewLibrary
- ShowLibraryMutationLevels(true); // restore collapsed column widths before saving
- SaveListViewSettings(listViewLibrary, "columnWidths", "libraryColumnDisplayIndices");
+ if (!Properties.Settings.Default.LibraryShowMutationLevelColumns)
+ ToggleLibraryMutationLevelColumns(true); // restore collapsed column widths before saving
+ SaveListViewSettings(listViewLibrary, nameof(Properties.Settings.columnWidths), nameof(Properties.Settings.libraryColumnDisplayIndices));
Properties.Settings.Default.listViewSortCol = _creatureListSorter.SortColumnIndex;
Properties.Settings.Default.listViewSortAsc = _creatureListSorter.Order == SortOrder.Ascending;
@@ -2089,7 +2092,7 @@ private void SetupExportFileWatcher()
if (_fileWatcherExports == null)
{
_fileWatcherExports =
- new FileWatcherExports(exportFolderDefault, ImportExportedAddIfPossible_WatcherThread);
+ new FileWatcherExports(exportFolderDefault, ImportExportedFileChanged, this);
}
else
{
diff --git a/ARKBreedingStats/Form1.extractor.cs b/ARKBreedingStats/Form1.extractor.cs
index 9751feec..31a17458 100644
--- a/ARKBreedingStats/Form1.extractor.cs
+++ b/ARKBreedingStats/Form1.extractor.cs
@@ -328,8 +328,9 @@ private bool ExtractLevels(bool autoExtraction = false, bool statInputsHighPreci
}
// get mean-level (most probable for the wild levels)
- // TODO handle species without wild levels in speed better (some flyers)
- double meanWildLevel = Math.Round((double)_extractor.LevelWildSum / 7, 1);
+ var statsWithLevels = Enumerable.Range(0, Stats.StatsCount).Aggregate(0,
+ (c, s) => c += s != Stats.Torpidity && speciesSelector1.SelectedSpecies.CanLevelUpWildOrHaveMutations(s) ? 1 : 0);
+ double meanWildLevel = Math.Round((double)_extractor.LevelWildSum / statsWithLevels, 1);
bool nonUniqueStats = false;
for (int s = 0; s < Stats.StatsCount; s++)
diff --git a/ARKBreedingStats/Form1.importExported.cs b/ARKBreedingStats/Form1.importExported.cs
index 1c73b371..75fbe8cf 100644
--- a/ARKBreedingStats/Form1.importExported.cs
+++ b/ARKBreedingStats/Form1.importExported.cs
@@ -166,16 +166,18 @@ private void ExportedCreatureList_CopyValuesToExtractor(importExported.ExportedC
}
}
- private void ImportExportedAddIfPossible_WatcherThread(string filePath, importExported.FileWatcherExports fwe)
+ ///
+ /// The fileWatcher detected a new or changed file in the watched folder.
+ ///
+ private void ImportExportedFileChanged(string filePath, importExported.FileWatcherExports fwe)
{
fwe.Watching = false;
- // wait a moment until the file is readable. why is this necessary? blocked by fileWatcher?
+ // wait a moment until the file is fully written
System.Threading.Thread.Sleep(200);
- // moving to the archived folder can trigger another fileWatcherEvent, first check if the file is still there
+ // moving a file to the archived folder can trigger another fileWatcherEvent, first check if the file is still there
if (File.Exists(filePath))
- // fileWatcher is on another thread, invoke ui-thread to work with ui
- Invoke(new Action(delegate { ImportExportedAddIfPossible(filePath); }));
+ ImportExportedAddIfPossible(filePath);
fwe.Watching = true;
}
diff --git a/ARKBreedingStats/Form1.library.cs b/ARKBreedingStats/Form1.library.cs
index fa229742..209d1ffd 100644
--- a/ARKBreedingStats/Form1.library.cs
+++ b/ARKBreedingStats/Form1.library.cs
@@ -12,6 +12,7 @@
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
+using ARKBreedingStats.importExportGun;
using ARKBreedingStats.library;
using ARKBreedingStats.settings;
@@ -2076,12 +2077,12 @@ private void resetColumnWidthNoMutationLevelColumnsToolStripMenuItem_Click(objec
private void restoreMutationLevelsASAToolStripMenuItem_Click(object sender, EventArgs e)
{
- LibraryColumnsMutationsWidth(false);
+ ToggleLibraryMutationLevelColumns(true, true);
}
private void collapseMutationsLevelsASEToolStripMenuItem_Click(object sender, EventArgs e)
{
- LibraryColumnsMutationsWidth(true);
+ ToggleLibraryMutationLevelColumns(false);
}
private void ResetColumnWidthListViewLibrary(bool mutationColumnWidthsZero)
@@ -2093,25 +2094,18 @@ private void ResetColumnWidthListViewLibrary(bool mutationColumnWidthsZero)
: ci < ColumnIndexFirstStat || ci >= ColumnIndexPostColor ? 60
: ci >= ColumnIndexFirstStat + Stats.StatsCount + Stats.StatsCount ? 30 // color
: ci < ColumnIndexFirstStat + Stats.StatsCount ? statWidths[ci - ColumnIndexFirstStat] // wild levels
+ : ci - ColumnIndexFirstStat - Stats.StatsCount == Stats.Torpidity ? 0 // no mutations for torpidity
: (int)(statWidths[ci - ColumnIndexFirstStat - Stats.StatsCount] * 1.24); // mutated needs space for one more letter
- if (mutationColumnWidthsZero)
- LibraryColumnsMutationsWidth(true);
+ // save in settings so it can be used when toggle the mutation columns, which use the settings
+ var widths = new int[listViewLibrary.Columns.Count];
+ for (int c = 0; c < widths.Length; c++)
+ widths[c] = listViewLibrary.Columns[c].Width;
+ Properties.Settings.Default.columnWidths = widths;
- listViewLibrary.EndUpdate();
- }
+ if (mutationColumnWidthsZero)
+ ToggleLibraryMutationLevelColumns(false);
- ///
- /// Set width of mutation level columns to zero or restore.
- ///
- private void LibraryColumnsMutationsWidth(bool collapse)
- {
- listViewLibrary.BeginUpdate();
- var statWidths = Stats.UsuallyVisibleStats.Select(w => !collapse && w ? 38 : 0).ToArray();
- for (int c = 0; c < Stats.StatsCount; c++)
- {
- listViewLibrary.Columns[c + ColumnIndexFirstStat + Stats.StatsCount].Width = statWidths[c];
- }
listViewLibrary.EndUpdate();
}
@@ -2119,20 +2113,30 @@ private void toolStripMenuItemMutationColumns_CheckedChanged(object sender, Even
{
var showMutationColumns = toolStripMenuItemMutationColumns.Checked;
Properties.Settings.Default.LibraryShowMutationLevelColumns = showMutationColumns;
- ShowLibraryMutationLevels(showMutationColumns);
+ ToggleLibraryMutationLevelColumns(showMutationColumns);
}
///
/// Set width of library mutation level columns to 0 or restore.
///
- private void ShowLibraryMutationLevels(bool show)
+ private void ToggleLibraryMutationLevelColumns(bool show, bool resetWidth = false)
{
var widths = Properties.Settings.Default.columnWidths;
- if (widths == null || widths.Length < ColumnIndexFirstStat + 2 * Stats.StatsCount) return;
-
+ if (widths == null || widths.Length < ColumnIndexFirstStat + 2 * Stats.StatsCount)
+ {
+ SaveListViewSettings(listViewLibrary, nameof(Properties.Settings.columnWidths), nameof(Properties.Settings.libraryColumnDisplayIndices));
+ widths = Properties.Settings.Default.columnWidths;
+ }
+
listViewLibrary.BeginUpdate();
if (show)
{
+ if (resetWidth)
+ {
+ var mutationStatWidths = Stats.UsuallyVisibleStats.Select((v, i) => v && i != Stats.Torpidity ? 37 : 0).ToArray();
+ mutationStatWidths.CopyTo(widths, ColumnIndexFirstStat + Stats.StatsCount);
+ }
+
for (int ci = ColumnIndexFirstStat + Stats.StatsCount; ci < ColumnIndexFirstStat + 2 * Stats.StatsCount; ci++)
listViewLibrary.Columns[ci].Width = widths[ci];
}
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/NamePattern.cs b/ARKBreedingStats/NamePatterns/NamePattern.cs
index f9844ff3..3bc64761 100644
--- a/ARKBreedingStats/NamePatterns/NamePattern.cs
+++ b/ARKBreedingStats/NamePatterns/NamePattern.cs
@@ -16,6 +16,8 @@ public static class NamePattern
///
private const string PipeEscapeSequence = @"\pipe";
+ public static Random Random = new Random();
+
///
/// Generate a creature name with the naming pattern.
///
@@ -203,9 +205,6 @@ public static Dictionary CreateTokenDictionary(Creature creature
double imp = creature.imprintingBonus * 100;
double eff = creature.tamingEff * 100;
- Random rand = new Random(DateTime.Now.Millisecond);
- string randStr = rand.Next(0, 999999).ToString("000000");
-
string effImp = "Z";
string prefix = string.Empty;
if (creature.isBred)
@@ -332,7 +331,7 @@ public static Dictionary CreateTokenDictionary(Creature creature
{ "genn", (speciesCreatures?.Count(c=>c.generation==generation) ?? 0 + 1).ToString()},
{ "nr_in_gen", nrInGeneration.ToString()},
{ "nr_in_gen_sex", nrInGenerationAndSameSex.ToString()},
- { "rnd", randStr },
+ { "rnd", Random.Next(0, 999999).ToString("000000")},
{ "ln", libraryCreatureCount.ToString()},
{ "tn", speciesCount.ToString()},
{ "sn", speciesSexCount.ToString()},
diff --git a/ARKBreedingStats/NamePatterns/NamePatternFunctions.cs b/ARKBreedingStats/NamePatterns/NamePatternFunctions.cs
index efa45ff7..4ebff1d5 100644
--- a/ARKBreedingStats/NamePatterns/NamePatternFunctions.cs
+++ b/ARKBreedingStats/NamePatterns/NamePatternFunctions.cs
@@ -51,6 +51,7 @@ private static string ParametersInvalid(string specificError, string expression,
{"float_div", FunctionFloatDiv},
{"div", FunctionDiv},
{"casing", FunctionCasing},
+ {"rand", FunctionRand },
{"replace", FunctionReplace},
{"regexreplace", FunctionRegExReplace},
{"customreplace", FunctionCustomReplace},
@@ -58,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)
@@ -247,6 +249,20 @@ private static string FunctionCasing(Match m, NamePatternParameters p)
return ParametersInvalid($"casing expects 'U', 'L' or 'T', given is '{m.Groups[3].Value}'", m.Groups[0].Value, p.DisplayError);
}
+ private static string FunctionRand(Match m, NamePatternParameters p)
+ {
+ // parameter: 1: to (if one parameter), from (if two parameters), 2: to
+ // to is exclusive
+ int.TryParse(m.Groups[2].Value, out var from);
+ if (!int.TryParse(m.Groups[3].Value, out var to))
+ {
+ to = from;
+ from = 0;
+ }
+ if (from < 0 || from >= to) return string.Empty;
+ return NamePattern.Random.Next(from, to).ToString();
+ }
+
private static string FunctionReplace(Match m, NamePatternParameters p)
{
// parameter: 1: replace, 2: text, 3: find, 4: replace
@@ -360,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 0e76df89..74cbdbd6 100644
--- a/ARKBreedingStats/NamePatterns/PatternEditor.cs
+++ b/ARKBreedingStats/NamePatterns/PatternEditor.cs
@@ -527,20 +527,22 @@ private void InsertText(string text)
{"expr", "{{#expr: expression }}, simple calculation with two operands and one operator. Possible operators are +, -, *, /.\n{{#expr: {hp} * 2 }}" },
{"len", "{{#len: string }}, returns the length of the passed string.\n{{#len: {isTophp}{isTopdm}{isTopwe} }}" },
{"substring","{{#substring: text | start | length }}. Length can be omitted. If start is negative it takes the characters from the end. If length is negative it takes the characters until that position from the end\n{{#substring: {species} | 0 | 4 }}"},
+ {"rand","{{#rand: min | max (exclusive) }} or {{#rand: max (exclusive) }}\n{{#rand: 100 }}"},
{"replace","{{#replace: text | find | replaceBy }}\n{{#replace: {species} | Aberrant | Ab }}"},
{"regexreplace","{{#regexreplace: text | pattern | replaceBy }}\nUse &{ instead {, &&vline; instead | and &} instead of }.\n{{#regexreplace: hp-st-we- | \\-$ | }}"},
{"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/Properties/AssemblyInfo.cs b/ARKBreedingStats/Properties/AssemblyInfo.cs
index e812401e..eec1282a 100644
--- a/ARKBreedingStats/Properties/AssemblyInfo.cs
+++ b/ARKBreedingStats/Properties/AssemblyInfo.cs
@@ -30,6 +30,6 @@
// Revision
//
[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("0.59.4.0")]
+[assembly: AssemblyFileVersion("0.59.5.0")]
[assembly: NeutralResourcesLanguage("en")]
diff --git a/ARKBreedingStats/StatResult.cs b/ARKBreedingStats/StatResult.cs
index 84610d5d..53e0643e 100644
--- a/ARKBreedingStats/StatResult.cs
+++ b/ARKBreedingStats/StatResult.cs
@@ -15,5 +15,7 @@ public StatResult(int levelWild, int levelDom, MinMaxDouble? TE = null)
this.levelDom = levelDom;
this.TE = TE ?? new MinMaxDouble(-1);
}
+
+ public override string ToString() => $"w: {levelWild}, d: {levelDom}, TE: {TE.Mean:.000}";
}
}
diff --git a/ARKBreedingStats/_manifest.json b/ARKBreedingStats/_manifest.json
index 7a72e678..b3cec913 100644
--- a/ARKBreedingStats/_manifest.json
+++ b/ARKBreedingStats/_manifest.json
@@ -4,7 +4,7 @@
"ARK Smart Breeding": {
"Id": "ARK Smart Breeding",
"Category": "main",
- "version": "0.59.4.0"
+ "version": "0.59.5.0"
},
"SpeciesColorImages": {
"Id": "SpeciesColorImages",
diff --git a/ARKBreedingStats/importExported/FileWatcherExports.cs b/ARKBreedingStats/importExported/FileWatcherExports.cs
index 6b8735cd..f353f016 100644
--- a/ARKBreedingStats/importExported/FileWatcherExports.cs
+++ b/ARKBreedingStats/importExported/FileWatcherExports.cs
@@ -1,5 +1,6 @@
using System;
using System.IO;
+using System.Windows.Forms;
namespace ARKBreedingStats.importExported
{
@@ -8,13 +9,14 @@ public class FileWatcherExports : IDisposable
private readonly FileSystemWatcher _fileWatcherExport;
private readonly Action _callbackNewFile;
- public FileWatcherExports(string folderToWatch, Action callbackNewFile)
+ public FileWatcherExports(string folderToWatch, Action callbackNewFile, Control synchronizingObject)
{
_callbackNewFile = callbackNewFile;
_fileWatcherExport = new FileSystemWatcher
{
- NotifyFilter = NotifyFilters.LastWrite
+ NotifyFilter = NotifyFilters.LastWrite,
+ SynchronizingObject = synchronizingObject
};
_fileWatcherExport.Created += OnChanged;
_fileWatcherExport.Changed += OnChanged;
diff --git a/ARKBreedingStats/importExported/ImportExported.cs b/ARKBreedingStats/importExported/ImportExported.cs
index db9dff44..9ec313be 100644
--- a/ARKBreedingStats/importExported/ImportExported.cs
+++ b/ARKBreedingStats/importExported/ImportExported.cs
@@ -101,7 +101,7 @@ public static CreatureValues ImportExportedCreature(string filePath)
break;
case "DinoClass":
// despite the property is called DinoClass it contains the complete blueprint-path
- cv.Species = Values.V.SpeciesByBlueprint(text,true);
+ cv.Species = Values.V.SpeciesByBlueprint(text, true);
if (cv.Species == null)
cv.speciesBlueprint = text; // species is unknown, check the needed mods later
break;
@@ -144,7 +144,10 @@ public static CreatureValues ImportExportedCreature(string filePath)
break;
case "BabyAge":
if (cv.Species?.breeding != null)
+ {
cv.growingUntil = DateTime.Now.AddSeconds((int)(cv.Species.breeding.maturationTimeAdjusted * (1 - value)));
+ if (value < 1) cv.isBred = true;
+ }
break;
case "CharacterLevel":
cv.level = (int)value;
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/json/values/_manifest.json b/ARKBreedingStats/json/values/_manifest.json
index 288ef31d..693318b2 100644
--- a/ARKBreedingStats/json/values/_manifest.json
+++ b/ARKBreedingStats/json/values/_manifest.json
@@ -6,7 +6,7 @@
"mod": { "id": "1083349027", "tag": "SpeedyFlyers", "title": "Najs Speedy Flyers" }
},
"1090809604-Pyria.json": {
- "version": "358.17.1700355701",
+ "version": "358.17.1703902790",
"mod": { "id": "1090809604", "tag": "Pyria", "title": "Pyria: Mythos Evolved" }
},
"1092784125-Gryphons.json": {
@@ -30,7 +30,7 @@
"mod": { "id": "1139775728", "tag": "Confuciusornis", "title": "Confuciusornis" }
},
"1169020368-Trex.json": {
- "version": "358.17.1701004683",
+ "version": "358.17.1703269186",
"mod": { "id": "1169020368", "tag": "Trex", "title": "Ark Creature Rebalance (AG Reborn)" }
},
"1178308359-ShadDragon.json": {
diff --git a/ARKBreedingStats/library/CreatureCollection.cs b/ARKBreedingStats/library/CreatureCollection.cs
index 424290ac..f7ef4908 100644
--- a/ARKBreedingStats/library/CreatureCollection.cs
+++ b/ARKBreedingStats/library/CreatureCollection.cs
@@ -80,7 +80,7 @@ public CreatureCollection()
/// Indicates the game the library is used for. Possible values are "ASE" (default) for ARK: Survival Evolved or "ASA" for ARK: Survival Ascended.
///
[JsonProperty("Game")]
- private string _game = "ASE";
+ private string _game = Ark.Ase;
///
/// Used for the exportGun mod.
@@ -150,6 +150,12 @@ public CreatureCollection()
private Dictionary _creatureCountBySpecies;
private int _totalCreatureCount;
+ ///
+ /// ServerMultipliers uri on the server to pull the settings.
+ ///
+ [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
+ public string ServerSettingsUriSource;
+
///
/// Calculates a hashcode for a list of mods and their order. Can be used to check for changes.
///
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/ARKBreedingStats/settings/Settings.Designer.cs b/ARKBreedingStats/settings/Settings.Designer.cs
index f6b49e4f..6f48f8a7 100644
--- a/ARKBreedingStats/settings/Settings.Designer.cs
+++ b/ARKBreedingStats/settings/Settings.Designer.cs
@@ -98,6 +98,8 @@ private void InitializeComponent()
this.label12 = new System.Windows.Forms.Label();
this.numericUpDownMaxBreedingSug = new ARKBreedingStats.uiControls.Nud();
this.groupBox5 = new System.Windows.Forms.GroupBox();
+ this.NudWildDinoCharacterFoodDrainMultiplier = new ARKBreedingStats.uiControls.Nud();
+ this.label69 = new System.Windows.Forms.Label();
this.label67 = new System.Windows.Forms.Label();
this.NudWildDinoTorporDrainMultiplier = new ARKBreedingStats.uiControls.Nud();
this.nudDinoCharacterFoodDrainEvent = new ARKBreedingStats.uiControls.Nud();
@@ -349,8 +351,8 @@ private void InitializeComponent()
this.label1 = new System.Windows.Forms.Label();
this.panel1 = new System.Windows.Forms.Panel();
this.colorDialog1 = new System.Windows.Forms.ColorDialog();
- this.label69 = new System.Windows.Forms.Label();
- this.NudWildDinoCharacterFoodDrainMultiplier = new ARKBreedingStats.uiControls.Nud();
+ this.BtRemoteServerSettingsUri = new System.Windows.Forms.Button();
+ this.TbRemoteServerSettingsUri = new System.Windows.Forms.TextBox();
this.groupBoxMultiplier.SuspendLayout();
this.groupBox2.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.nudTamedDinoCharacterFoodDrain)).BeginInit();
@@ -383,6 +385,7 @@ private void InitializeComponent()
((System.ComponentModel.ISupportInitialize)(this.nudChartLevelEvenMin)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.numericUpDownMaxBreedingSug)).BeginInit();
this.groupBox5.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.NudWildDinoCharacterFoodDrainMultiplier)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.NudWildDinoTorporDrainMultiplier)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.nudDinoCharacterFoodDrainEvent)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.nudTamingSpeedEvent)).BeginInit();
@@ -459,7 +462,6 @@ private void InitializeComponent()
((System.ComponentModel.ISupportInitialize)(this.nudWaitBeforeScreenCapture)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.nudWhiteThreshold)).BeginInit();
this.panel1.SuspendLayout();
- ((System.ComponentModel.ISupportInitialize)(this.NudWildDinoCharacterFoodDrainMultiplier)).BeginInit();
this.SuspendLayout();
//
// groupBoxMultiplier
@@ -1503,6 +1505,39 @@ private void InitializeComponent()
this.groupBox5.TabStop = false;
this.groupBox5.Text = "Taming-Multiplier";
//
+ // NudWildDinoCharacterFoodDrainMultiplier
+ //
+ this.NudWildDinoCharacterFoodDrainMultiplier.DecimalPlaces = 6;
+ this.NudWildDinoCharacterFoodDrainMultiplier.ForeColor = System.Drawing.SystemColors.WindowText;
+ this.NudWildDinoCharacterFoodDrainMultiplier.Location = new System.Drawing.Point(183, 71);
+ this.NudWildDinoCharacterFoodDrainMultiplier.Maximum = new decimal(new int[] {
+ 10000,
+ 0,
+ 0,
+ 0});
+ this.NudWildDinoCharacterFoodDrainMultiplier.Name = "NudWildDinoCharacterFoodDrainMultiplier";
+ this.NudWildDinoCharacterFoodDrainMultiplier.NeutralNumber = new decimal(new int[] {
+ 0,
+ 0,
+ 0,
+ 0});
+ this.NudWildDinoCharacterFoodDrainMultiplier.Size = new System.Drawing.Size(72, 20);
+ this.NudWildDinoCharacterFoodDrainMultiplier.TabIndex = 4;
+ this.NudWildDinoCharacterFoodDrainMultiplier.Value = new decimal(new int[] {
+ 1,
+ 0,
+ 0,
+ 0});
+ //
+ // label69
+ //
+ this.label69.AutoSize = true;
+ this.label69.Location = new System.Drawing.Point(10, 73);
+ this.label69.Name = "label69";
+ this.label69.Size = new System.Drawing.Size(186, 13);
+ this.label69.TabIndex = 7;
+ this.label69.Text = "WildDinoCharacterFoodDrainMultiplier";
+ //
// label67
//
this.label67.AutoSize = true;
@@ -1652,7 +1687,7 @@ private void InitializeComponent()
//
// label15
//
- this.label15.Location = new System.Drawing.Point(451, 575);
+ this.label15.Location = new System.Drawing.Point(450, 548);
this.label15.Name = "label15";
this.label15.Size = new System.Drawing.Size(289, 77);
this.label15.TabIndex = 9;
@@ -1833,15 +1868,17 @@ private void InitializeComponent()
//
this.tabPageMultipliers.AllowDrop = true;
this.tabPageMultipliers.AutoScroll = true;
+ this.tabPageMultipliers.Controls.Add(this.TbRemoteServerSettingsUri);
+ this.tabPageMultipliers.Controls.Add(this.BtSettingsToClipboard);
+ this.tabPageMultipliers.Controls.Add(this.btExportMultipliers);
+ this.tabPageMultipliers.Controls.Add(this.BtRemoteServerSettingsUri);
this.tabPageMultipliers.Controls.Add(this.CbKeepMultipliersForNewLibrary);
this.tabPageMultipliers.Controls.Add(this.BtAutoImportLocalSettings);
this.tabPageMultipliers.Controls.Add(this.panel3);
this.tabPageMultipliers.Controls.Add(this.BtImportSettingsSelectFile);
this.tabPageMultipliers.Controls.Add(this.CbAtlasSettings);
- this.tabPageMultipliers.Controls.Add(this.BtSettingsToClipboard);
this.tabPageMultipliers.Controls.Add(this.groupBox29);
this.tabPageMultipliers.Controls.Add(this.label34);
- this.tabPageMultipliers.Controls.Add(this.btExportMultipliers);
this.tabPageMultipliers.Controls.Add(this.groupBox18);
this.tabPageMultipliers.Controls.Add(this.label27);
this.tabPageMultipliers.Controls.Add(this.cbSingleplayerSettings);
@@ -1876,7 +1913,7 @@ private void InitializeComponent()
// BtAutoImportLocalSettings
//
this.BtAutoImportLocalSettings.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(255)))), ((int)(((byte)(192)))));
- this.BtAutoImportLocalSettings.Location = new System.Drawing.Point(407, 642);
+ this.BtAutoImportLocalSettings.Location = new System.Drawing.Point(407, 628);
this.BtAutoImportLocalSettings.Name = "BtAutoImportLocalSettings";
this.BtAutoImportLocalSettings.Size = new System.Drawing.Size(152, 23);
this.BtAutoImportLocalSettings.TabIndex = 17;
@@ -1918,7 +1955,7 @@ private void InitializeComponent()
//
// BtImportSettingsSelectFile
//
- this.BtImportSettingsSelectFile.Location = new System.Drawing.Point(565, 642);
+ this.BtImportSettingsSelectFile.Location = new System.Drawing.Point(565, 628);
this.BtImportSettingsSelectFile.Name = "BtImportSettingsSelectFile";
this.BtImportSettingsSelectFile.Size = new System.Drawing.Size(167, 23);
this.BtImportSettingsSelectFile.TabIndex = 15;
@@ -1980,7 +2017,7 @@ private void InitializeComponent()
//
// label34
//
- this.label34.Location = new System.Drawing.Point(404, 676);
+ this.label34.Location = new System.Drawing.Point(404, 682);
this.label34.Name = "label34";
this.label34.Size = new System.Drawing.Size(338, 34);
this.label34.TabIndex = 10;
@@ -2031,7 +2068,7 @@ private void InitializeComponent()
//
this.label27.AutoSize = true;
this.label27.Font = new System.Drawing.Font("Microsoft Sans Serif", 16F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.label27.Location = new System.Drawing.Point(408, 576);
+ this.label27.Location = new System.Drawing.Point(407, 562);
this.label27.Name = "label27";
this.label27.Size = new System.Drawing.Size(37, 26);
this.label27.TabIndex = 12;
@@ -2110,7 +2147,7 @@ private void InitializeComponent()
//
// buttonEventToDefault
//
- this.buttonEventToDefault.Location = new System.Drawing.Point(604, 547);
+ this.buttonEventToDefault.Location = new System.Drawing.Point(512, 137);
this.buttonEventToDefault.Name = "buttonEventToDefault";
this.buttonEventToDefault.Size = new System.Drawing.Size(136, 23);
this.buttonEventToDefault.TabIndex = 8;
@@ -2147,7 +2184,7 @@ private void InitializeComponent()
this.tabPageGeneral.Location = new System.Drawing.Point(4, 22);
this.tabPageGeneral.Name = "tabPageGeneral";
this.tabPageGeneral.Padding = new System.Windows.Forms.Padding(3);
- this.tabPageGeneral.Size = new System.Drawing.Size(750, 722);
+ this.tabPageGeneral.Size = new System.Drawing.Size(750, 744);
this.tabPageGeneral.TabIndex = 0;
this.tabPageGeneral.Text = "General";
this.tabPageGeneral.UseVisualStyleBackColor = true;
@@ -2602,7 +2639,7 @@ private void InitializeComponent()
this.tabPageInfoGraphic.Controls.Add(this.label50);
this.tabPageInfoGraphic.Location = new System.Drawing.Point(4, 22);
this.tabPageInfoGraphic.Name = "tabPageInfoGraphic";
- this.tabPageInfoGraphic.Size = new System.Drawing.Size(750, 722);
+ this.tabPageInfoGraphic.Size = new System.Drawing.Size(750, 744);
this.tabPageInfoGraphic.TabIndex = 7;
this.tabPageInfoGraphic.Text = "Info Graphic";
this.tabPageInfoGraphic.UseVisualStyleBackColor = true;
@@ -2860,7 +2897,7 @@ private void InitializeComponent()
this.tabPageImportSavegame.Location = new System.Drawing.Point(4, 22);
this.tabPageImportSavegame.Name = "tabPageImportSavegame";
this.tabPageImportSavegame.Padding = new System.Windows.Forms.Padding(3);
- this.tabPageImportSavegame.Size = new System.Drawing.Size(750, 722);
+ this.tabPageImportSavegame.Size = new System.Drawing.Size(750, 744);
this.tabPageImportSavegame.TabIndex = 2;
this.tabPageImportSavegame.Text = "Import Savegame";
this.tabPageImportSavegame.UseVisualStyleBackColor = true;
@@ -3113,7 +3150,7 @@ private void InitializeComponent()
this.tabPageImportExported.Location = new System.Drawing.Point(4, 22);
this.tabPageImportExported.Name = "tabPageImportExported";
this.tabPageImportExported.Padding = new System.Windows.Forms.Padding(3);
- this.tabPageImportExported.Size = new System.Drawing.Size(750, 722);
+ this.tabPageImportExported.Size = new System.Drawing.Size(750, 744);
this.tabPageImportExported.TabIndex = 3;
this.tabPageImportExported.Text = "Import Exported";
this.tabPageImportExported.UseVisualStyleBackColor = true;
@@ -3622,7 +3659,7 @@ private void InitializeComponent()
this.tabPageTimers.Location = new System.Drawing.Point(4, 22);
this.tabPageTimers.Name = "tabPageTimers";
this.tabPageTimers.Padding = new System.Windows.Forms.Padding(3);
- this.tabPageTimers.Size = new System.Drawing.Size(750, 722);
+ this.tabPageTimers.Size = new System.Drawing.Size(750, 744);
this.tabPageTimers.TabIndex = 6;
this.tabPageTimers.Text = "Timers";
this.tabPageTimers.UseVisualStyleBackColor = true;
@@ -3706,7 +3743,7 @@ private void InitializeComponent()
this.customSCCustom.Location = new System.Drawing.Point(6, 139);
this.customSCCustom.Name = "customSCCustom";
this.customSCCustom.Size = new System.Drawing.Size(401, 23);
- this.customSCCustom.SoundFile = null;
+ this.customSCCustom.SoundFile = "";
this.customSCCustom.TabIndex = 4;
//
// customSCWakeup
@@ -3714,7 +3751,7 @@ private void InitializeComponent()
this.customSCWakeup.Location = new System.Drawing.Point(6, 81);
this.customSCWakeup.Name = "customSCWakeup";
this.customSCWakeup.Size = new System.Drawing.Size(401, 23);
- this.customSCWakeup.SoundFile = "";
+ this.customSCWakeup.SoundFile = null;
this.customSCWakeup.TabIndex = 2;
//
// customSCBirth
@@ -3722,7 +3759,7 @@ private void InitializeComponent()
this.customSCBirth.Location = new System.Drawing.Point(6, 110);
this.customSCBirth.Name = "customSCBirth";
this.customSCBirth.Size = new System.Drawing.Size(401, 23);
- this.customSCBirth.SoundFile = "";
+ this.customSCBirth.SoundFile = null;
this.customSCBirth.TabIndex = 3;
//
// customSCStarving
@@ -3730,7 +3767,7 @@ private void InitializeComponent()
this.customSCStarving.Location = new System.Drawing.Point(6, 52);
this.customSCStarving.Name = "customSCStarving";
this.customSCStarving.Size = new System.Drawing.Size(401, 23);
- this.customSCStarving.SoundFile = null;
+ this.customSCStarving.SoundFile = "";
this.customSCStarving.TabIndex = 1;
//
// label20
@@ -3748,7 +3785,7 @@ private void InitializeComponent()
this.tabPageOverlay.Location = new System.Drawing.Point(4, 22);
this.tabPageOverlay.Name = "tabPageOverlay";
this.tabPageOverlay.Padding = new System.Windows.Forms.Padding(3);
- this.tabPageOverlay.Size = new System.Drawing.Size(750, 722);
+ this.tabPageOverlay.Size = new System.Drawing.Size(750, 744);
this.tabPageOverlay.TabIndex = 5;
this.tabPageOverlay.Text = "Overlay";
this.tabPageOverlay.UseVisualStyleBackColor = true;
@@ -4128,7 +4165,7 @@ private void InitializeComponent()
this.tabPageOCR.Location = new System.Drawing.Point(4, 22);
this.tabPageOCR.Name = "tabPageOCR";
this.tabPageOCR.Padding = new System.Windows.Forms.Padding(3);
- this.tabPageOCR.Size = new System.Drawing.Size(750, 722);
+ this.tabPageOCR.Size = new System.Drawing.Size(750, 744);
this.tabPageOCR.TabIndex = 4;
this.tabPageOCR.Text = "OCR";
this.tabPageOCR.UseVisualStyleBackColor = true;
@@ -4449,38 +4486,22 @@ private void InitializeComponent()
this.panel1.Size = new System.Drawing.Size(758, 30);
this.panel1.TabIndex = 12;
//
- // label69
+ // BtRemoteServerSettingsUri
//
- this.label69.AutoSize = true;
- this.label69.Location = new System.Drawing.Point(10, 73);
- this.label69.Name = "label69";
- this.label69.Size = new System.Drawing.Size(186, 13);
- this.label69.TabIndex = 7;
- this.label69.Text = "WildDinoCharacterFoodDrainMultiplier";
+ this.BtRemoteServerSettingsUri.Location = new System.Drawing.Point(565, 657);
+ this.BtRemoteServerSettingsUri.Name = "BtRemoteServerSettingsUri";
+ this.BtRemoteServerSettingsUri.Size = new System.Drawing.Size(167, 23);
+ this.BtRemoteServerSettingsUri.TabIndex = 19;
+ this.BtRemoteServerSettingsUri.Text = "Import remote settings";
+ this.BtRemoteServerSettingsUri.UseVisualStyleBackColor = true;
+ this.BtRemoteServerSettingsUri.Click += new System.EventHandler(this.BtRemoteServerSettingsUri_Click);
//
- // NudWildDinoCharacterFoodDrainMultiplier
+ // TbRemoteServerSettingsUri
//
- this.NudWildDinoCharacterFoodDrainMultiplier.DecimalPlaces = 6;
- this.NudWildDinoCharacterFoodDrainMultiplier.ForeColor = System.Drawing.SystemColors.WindowText;
- this.NudWildDinoCharacterFoodDrainMultiplier.Location = new System.Drawing.Point(183, 71);
- this.NudWildDinoCharacterFoodDrainMultiplier.Maximum = new decimal(new int[] {
- 10000,
- 0,
- 0,
- 0});
- this.NudWildDinoCharacterFoodDrainMultiplier.Name = "NudWildDinoCharacterFoodDrainMultiplier";
- this.NudWildDinoCharacterFoodDrainMultiplier.NeutralNumber = new decimal(new int[] {
- 0,
- 0,
- 0,
- 0});
- this.NudWildDinoCharacterFoodDrainMultiplier.Size = new System.Drawing.Size(72, 20);
- this.NudWildDinoCharacterFoodDrainMultiplier.TabIndex = 4;
- this.NudWildDinoCharacterFoodDrainMultiplier.Value = new decimal(new int[] {
- 1,
- 0,
- 0,
- 0});
+ this.TbRemoteServerSettingsUri.Location = new System.Drawing.Point(407, 659);
+ this.TbRemoteServerSettingsUri.Name = "TbRemoteServerSettingsUri";
+ this.TbRemoteServerSettingsUri.Size = new System.Drawing.Size(152, 20);
+ this.TbRemoteServerSettingsUri.TabIndex = 20;
//
// Settings
//
@@ -4535,6 +4556,7 @@ private void InitializeComponent()
((System.ComponentModel.ISupportInitialize)(this.numericUpDownMaxBreedingSug)).EndInit();
this.groupBox5.ResumeLayout(false);
this.groupBox5.PerformLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.NudWildDinoCharacterFoodDrainMultiplier)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.NudWildDinoTorporDrainMultiplier)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.nudDinoCharacterFoodDrainEvent)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.nudTamingSpeedEvent)).EndInit();
@@ -4643,7 +4665,6 @@ private void InitializeComponent()
((System.ComponentModel.ISupportInitialize)(this.nudWaitBeforeScreenCapture)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.nudWhiteThreshold)).EndInit();
this.panel1.ResumeLayout(false);
- ((System.ComponentModel.ISupportInitialize)(this.NudWildDinoCharacterFoodDrainMultiplier)).EndInit();
this.ResumeLayout(false);
}
@@ -4971,5 +4992,7 @@ private void InitializeComponent()
private System.Windows.Forms.Label label68;
private uiControls.Nud NudWildDinoCharacterFoodDrainMultiplier;
private System.Windows.Forms.Label label69;
+ private System.Windows.Forms.Button BtRemoteServerSettingsUri;
+ private System.Windows.Forms.TextBox TbRemoteServerSettingsUri;
}
}
\ No newline at end of file
diff --git a/ARKBreedingStats/settings/Settings.cs b/ARKBreedingStats/settings/Settings.cs
index 1a03ec68..ecac9b50 100644
--- a/ARKBreedingStats/settings/Settings.cs
+++ b/ARKBreedingStats/settings/Settings.cs
@@ -5,7 +5,10 @@
using System.Drawing;
using System.IO;
using System.Linq;
+using System.Net.Http;
using System.Text.RegularExpressions;
+using System.Threading;
+using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Threading;
using ARKBreedingStats.importExportGun;
@@ -24,6 +27,7 @@ public partial class Settings : Form
public SettingsTabPages LastTabPageIndex;
public bool LanguageChanged;
public bool ColorRegionDisplayChanged;
+ private CancellationTokenSource _cancellationTokenSource;
public Settings(CreatureCollection cc, SettingsTabPages page)
{
@@ -254,6 +258,7 @@ private void LoadSettings(CreatureCollection cc)
nudBabyFoodConsumptionSpeedEvent.ValueSave = (decimal)multipliers.BabyFoodConsumptionSpeedMultiplier;
#endregion
+ TbRemoteServerSettingsUri.Text = cc.ServerSettingsUriSource;
checkBoxAutoSave.Checked = Properties.Settings.Default.autosave;
chkCollectionSync.Checked = Properties.Settings.Default.syncCollection;
NudWaitBeforeAutoLoad.ValueSave = Properties.Settings.Default.WaitBeforeAutoLoadMs;
@@ -520,6 +525,7 @@ private void SaveSettings()
_cc.serverMultipliersEvents.BabyFoodConsumptionSpeedMultiplier = (double)nudBabyFoodConsumptionSpeedEvent.Value;
#endregion
+ _cc.ServerSettingsUriSource = string.IsNullOrEmpty(TbRemoteServerSettingsUri.Text) ? null : TbRemoteServerSettingsUri.Text;
Properties.Settings.Default.autosave = checkBoxAutoSave.Checked;
Properties.Settings.Default.syncCollection = chkCollectionSync.Checked;
Properties.Settings.Default.WaitBeforeAutoLoadMs = (int)NudWaitBeforeAutoLoad.Value;
@@ -1693,5 +1699,82 @@ private void BtAutoImportLocalSettings_Click(object sender, EventArgs e)
if (localConfigPaths[importIndex].Item2 == Ark.Game.ASA) RbGameAsa.Checked = true;
else RbGameAse.Checked = true;
}
+
+ private async void BtRemoteServerSettingsUri_Click(object sender, EventArgs e)
+ {
+ var uri = TbRemoteServerSettingsUri.Text;
+ if (string.IsNullOrEmpty(uri))
+ {
+ MessageBoxes.ShowMessageBox("No url for a server settings file given. Enter the url to the text box near the button you just clicked.");
+ return;
+ }
+
+ if (_cancellationTokenSource != null)
+ {
+ _cancellationTokenSource.Cancel();
+ return;
+ }
+
+ try
+ {
+ var httpClient = FileService.GetHttpClient;
+ _cancellationTokenSource = new CancellationTokenSource();
+ BtRemoteServerSettingsUri.Text = "Cancel loading";
+ string settingsText = null;
+ using (var result = await httpClient.GetAsync(uri, _cancellationTokenSource.Token))
+ {
+ if (!result.IsSuccessStatusCode)
+ {
+ MessageBoxes.ShowMessageBox(
+ $"Error when trying to load settings from{Environment.NewLine}{uri}{Environment.NewLine}StatusCode {(int)result.StatusCode}: {result.ReasonPhrase}");
+ return;
+ }
+
+ settingsText = await result.Content.ReadAsStringAsync();
+ }
+
+ if (string.IsNullOrEmpty(settingsText))
+ {
+ MessageBoxes.ShowMessageBox(
+ $"The specified source{Environment.NewLine}{uri}{Environment.NewLine}contains not text, nothing was imported.");
+ return;
+ }
+
+ if (MessageBox.Show($"Apply the settings of the downloaded file?{Environment.NewLine}{uri}",
+ "Use downloaded settings?",
+ MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
+ {
+ ExtractSettingsFromText(settingsText, true);
+ }
+
+ }
+ catch (InvalidOperationException ex)
+ {
+ MessageBoxes.ShowMessageBox(
+ $"The given url{Environment.NewLine}{uri}{Environment.NewLine}is not valid.{Environment.NewLine}{ex.Message}",
+ "Invalid url");
+ }
+ catch (TaskCanceledException ex)
+ {
+ if (_cancellationTokenSource?.IsCancellationRequested == true)
+ {
+ // request canceled by user
+ return;
+ }
+ MessageBoxes.ShowMessageBox(
+ $"The given url{Environment.NewLine}{uri}{Environment.NewLine}didn't respond fast enough (timeout), maybe the url is incorrect.{Environment.NewLine}{ex.Message}",
+ "Timeout when loading server settings");
+ }
+ catch (Exception ex)
+ {
+ MessageBoxes.ExceptionMessageBox(ex, "Server settings file couldn't be loaded.");
+ }
+ finally
+ {
+ _cancellationTokenSource?.Dispose();
+ _cancellationTokenSource = null;
+ BtRemoteServerSettingsUri.Text = "Load remote settings";
+ }
+ }
}
}
diff --git a/ARKBreedingStats/species/Species.cs b/ARKBreedingStats/species/Species.cs
index 87857ca7..ab707c77 100644
--- a/ARKBreedingStats/species/Species.cs
+++ b/ARKBreedingStats/species/Species.cs
@@ -161,6 +161,7 @@ private void Initialize(StreamingContext _)
var fullStatsRawLength = fullStatsRaw?.Length ?? 0;
+ _skipWildLevelStatsWithServerSettings = skipWildLevelStats;
usedStats = 0;
StatImprintMultipliers = statImprintMult ?? StatImprintMultipliersDefaultAse.ToArray();
@@ -173,6 +174,7 @@ private void Initialize(StreamingContext _)
if (altBaseStatsRaw?.ContainsKey(s) ?? false)
altStats[s] = new CreatureStat();
+ var usesStat = false;
completeRaws[s] = new double[] { 0, 0, 0, 0, 0 };
if (fullStatsRawLength > s && fullStatsRaw[s] != null)
{
@@ -183,11 +185,16 @@ private void Initialize(StreamingContext _)
completeRaws[s][i] = fullStatsRaw[s]?[i] ?? 0;
if (i == 0 && fullStatsRaw[s][0] > 0)
{
- usedStats |= (1 << s);
+ usesStat = true;
}
}
}
}
+ var statBit = (1 << s);
+ if (usesStat)
+ usedStats |= statBit;
+ else
+ _skipWildLevelStatsWithServerSettings |= statBit;
}
if (fullStatsRawLength != -0)
@@ -218,8 +225,6 @@ private void Initialize(StreamingContext _)
boneDamageAdjusters = boneDamageAdjustersCleanedUp;
}
- _skipWildLevelStatsWithServerSettings = skipWildLevelStats;
-
IsDomesticable = (taming != null && (taming.nonViolent || taming.violent))
|| (breeding != null && (breeding.incubationTime > 0 || breeding.gestationTime > 0));
}
diff --git a/ARKBreedingStats/uiControls/StatIO.cs b/ARKBreedingStats/uiControls/StatIO.cs
index e6f30777..728364f6 100644
--- a/ARKBreedingStats/uiControls/StatIO.cs
+++ b/ARKBreedingStats/uiControls/StatIO.cs
@@ -1,8 +1,10 @@
using System;
using System.Drawing;
using System.Windows.Forms;
+using System.Windows.Input;
using System.Windows.Threading;
using ARKBreedingStats.utils;
+using Cursors = System.Windows.Forms.Cursors;
namespace ARKBreedingStats
{
@@ -378,24 +380,29 @@ private void labelWildLevel_Click(object sender, EventArgs e)
{
OnClick(e);
- if (LevelMut > 1)
- {
- LevelWild += 2;
- LevelMut -= 2;
- LevelChangedDebouncer();
- }
+ var levelDelta = LevelDeltaMutationShift(LevelMut);
+ if (levelDelta <= 0) return;
+ LevelWild += levelDelta;
+ LevelMut -= levelDelta;
+ LevelChangedDebouncer();
}
private void labelMutatedLevel_Click(object sender, EventArgs e)
{
OnClick(e);
- if (LevelWild > 1)
- {
- LevelWild -= 2;
- LevelMut += 2;
- LevelChangedDebouncer();
- }
+ var levelDelta = LevelDeltaMutationShift(LevelWild);
+ if (levelDelta <= 0) return;
+ LevelWild -= levelDelta;
+ LevelMut += levelDelta;
+ LevelChangedDebouncer();
+ }
+
+ private int LevelDeltaMutationShift(int remainingLevel)
+ {
+ var levelDelta = Keyboard.Modifiers.HasFlag(System.Windows.Input.ModifierKeys.Shift) ? 10 : 2;
+ if (remainingLevel < levelDelta) levelDelta = (remainingLevel / 2) * 2;
+ return levelDelta;
}
private void labelDomLevel_Click(object sender, EventArgs e)
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