diff --git a/ARKBreedingStats/Ark.cs b/ARKBreedingStats/Ark.cs
index 12b31be6..84507fef 100644
--- a/ARKBreedingStats/Ark.cs
+++ b/ARKBreedingStats/Ark.cs
@@ -1,7 +1,4 @@
-using System.Linq;
-using ARKBreedingStats.species;
-
-namespace ARKBreedingStats
+namespace ARKBreedingStats
{
///
/// Constants of the game Ark.
@@ -92,8 +89,7 @@ public static class Ark
#region Colors
public const byte ColorFirstId = 1;
- public const byte ColorMaxId = 200;
- public const byte DyeFirstId = 201;
+ public const byte DyeFirstIdASE = 201;
public const byte DyeMaxId = 255;
///
/// When choosing a random color for a mutation, ARK can erroneously select an undefined color. Usually this is color id 227 (one too high to be defined).
@@ -111,6 +107,28 @@ public static class Ark
/// The name is trimmed to this length in game.
///
public const int MaxCreatureNameLength = 24;
+
+ public enum Game
+ {
+ ///
+ /// ARK: Survival Evolved (2015)
+ ///
+ ASE,
+ ///
+ /// ARK: Survival Ascended (2023)
+ ///
+ ASA
+ }
+
+ ///
+ /// Collection indicator for ARK: Survival Evolved.
+ ///
+ public const string Ase = "ASE";
+
+ ///
+ /// Collection indicator for ARK: Survival Ascended, also the mod tag id for the ASA values.
+ ///
+ public const string Asa = "ASA";
}
///
diff --git a/ARKBreedingStats/BreedingPlanning/BreedingPlan.cs b/ARKBreedingStats/BreedingPlanning/BreedingPlan.cs
index 9bf91186..76c71ee1 100644
--- a/ARKBreedingStats/BreedingPlanning/BreedingPlan.cs
+++ b/ARKBreedingStats/BreedingPlanning/BreedingPlan.cs
@@ -787,7 +787,7 @@ private void SetBestLevels(int[] bestLevels, IEnumerable creatures, bo
: string.Format(Loc.S(bestInSpecies ? "BestPossibleSpeciesLibrary" : "BestPossibleSpeciesLibraryFiltered"), _currentSpecies.name);
Creature crB = new Creature(_currentSpecies, bestLevelsOfWhat,
- null, null, 0, new int[Stats.StatsCount], null, 1, true, levelStep: levelStep);
+ null, null, 0, new int[Stats.StatsCount], null, null, 1, true, levelStep: levelStep);
bool totalLevelUnknown = false;
for (int s = 0; s < Stats.StatsCount; s++)
{
diff --git a/ARKBreedingStats/Extraction.cs b/ARKBreedingStats/Extraction.cs
index b920dbd0..8776085e 100644
--- a/ARKBreedingStats/Extraction.cs
+++ b/ARKBreedingStats/Extraction.cs
@@ -123,6 +123,8 @@ public void ExtractLevels(Species species, int level, StatIO[] statIOs, double l
if (imprintingBonusList == null)
imprintingBonusList = new List { new MinMaxDouble(0) };
+ double[] statImprintMultipliers = species.StatImprintMultipliers;
+
for (int IBi = 0; IBi < imprintingBonusList.Count; IBi++)
{
_imprintingBonusRange = imprintingBonusList[IBi];
@@ -133,7 +135,7 @@ public void ExtractLevels(Species species, int level, StatIO[] statIOs, double l
var imprintingMultiplierRanges = new MinMaxDouble[Stats.StatsCount];
for (int s = 0; s < Stats.StatsCount; s++)
{
- double statImprintingMultiplier = species.StatImprintMultipliers[s];
+ double statImprintingMultiplier = statImprintMultipliers[s];
imprintingMultiplierRanges[s] = statImprintingMultiplier != 0
? new MinMaxDouble(1 + _imprintingBonusRange.Min * imprintingBonusMultiplier * statImprintingMultiplier,
1 + _imprintingBonusRange.Max * imprintingBonusMultiplier * statImprintingMultiplier)
@@ -237,7 +239,7 @@ public void ExtractLevels(Species species, int level, StatIO[] statIOs, double l
MinMaxDouble statImprintingMultiplierRange = new MinMaxDouble(1);
// only use imprintingMultiplier for stats that use them. Stamina and Oxygen don't use ist. Sometimes speed neither.
- if (bred && species.StatImprintMultipliers[s] != 0)
+ if (bred && statImprintMultipliers[s] != 0)
statImprintingMultiplierRange = imprintingMultiplierRanges[s].Clone();
// if dom levels have no effect, just calculate the wild level
@@ -268,7 +270,7 @@ public void ExtractLevels(Species species, int level, StatIO[] statIOs, double l
}
bool resultWasSortedOutBecauseOfImpossibleTe = false;
- for (int lw = minLW; lw < maxLW + 1; lw++)
+ for (int lw = minLW; lw <= maxLW; lw++)
{
// imprinting bonus is applied to all stats except stamina (s==1) and oxygen (s==2) and speed (s==6)
MinMaxDouble valueWODomRange = new MinMaxDouble(statBaseValue * (1 + stats[s].IncPerWildLevel * lw) * statImprintingMultiplierRange.Min + (PostTamed ? stats[s].AddWhenTamed : 0),
diff --git a/ARKBreedingStats/Form1.Designer.cs b/ARKBreedingStats/Form1.Designer.cs
index 7011fa4a..08c3ba97 100644
--- a/ARKBreedingStats/Form1.Designer.cs
+++ b/ARKBreedingStats/Form1.Designer.cs
@@ -176,6 +176,7 @@ private void InitializeComponent()
this.lbTestingInfo = new System.Windows.Forms.Label();
this.creatureInfoInputTester = new ARKBreedingStats.CreatureInfoInput();
this.tabPageExtractor = new System.Windows.Forms.TabPage();
+ this.LbAsa = new System.Windows.Forms.Label();
this.creatureAnalysis1 = new ARKBreedingStats.uiControls.CreatureAnalysis();
this.LbBlueprintPath = new System.Windows.Forms.Label();
this.BtCopyIssueDumpToClipboard = new System.Windows.Forms.Button();
@@ -234,6 +235,7 @@ private void InitializeComponent()
this.columnHeaderStatus = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeaderTribe = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeaderStatusIcon = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+ this.columnHeaderMutagen = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.contextMenuStripLibrary = new System.Windows.Forms.ContextMenuStrip(this.components);
this.toolStripMenuItemEdit = new System.Windows.Forms.ToolStripMenuItem();
this.editAllSelectedToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
@@ -357,7 +359,6 @@ private void InitializeComponent()
this.contextMenuStripLibraryHeader = new System.Windows.Forms.ContextMenuStrip(this.components);
this.toolStripMenuItemResetLibraryColumnWidths = new System.Windows.Forms.ToolStripMenuItem();
this.speciesSelector1 = new ARKBreedingStats.SpeciesSelector();
- this.columnHeaderMutagen = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.groupBox1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.numericUpDownImprintingBonusTester)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.NumericUpDownTestingTE)).BeginInit();
@@ -634,6 +635,11 @@ private void InitializeComponent()
this.NumericUpDownTestingTE.DecimalPlaces = 2;
this.NumericUpDownTestingTE.ForeColor = System.Drawing.SystemColors.WindowText;
this.NumericUpDownTestingTE.Location = new System.Drawing.Point(6, 19);
+ this.NumericUpDownTestingTE.Minimum = new decimal(new int[] {
+ 1,
+ 0,
+ 0,
+ -2147483648});
this.NumericUpDownTestingTE.Name = "NumericUpDownTestingTE";
this.NumericUpDownTestingTE.NeutralNumber = new decimal(new int[] {
0,
@@ -1751,6 +1757,7 @@ private void InitializeComponent()
// tabPageExtractor
//
this.tabPageExtractor.AutoScroll = true;
+ this.tabPageExtractor.Controls.Add(this.LbAsa);
this.tabPageExtractor.Controls.Add(this.creatureAnalysis1);
this.tabPageExtractor.Controls.Add(this.LbBlueprintPath);
this.tabPageExtractor.Controls.Add(this.BtCopyIssueDumpToClipboard);
@@ -1780,6 +1787,17 @@ private void InitializeComponent()
this.tabPageExtractor.Text = "Extractor";
this.tabPageExtractor.UseVisualStyleBackColor = true;
//
+ // LbAsa
+ //
+ this.LbAsa.AutoSize = true;
+ this.LbAsa.Font = new System.Drawing.Font("Microsoft Sans Serif", 6F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.LbAsa.ForeColor = System.Drawing.Color.DarkGray;
+ this.LbAsa.Location = new System.Drawing.Point(295, 66);
+ this.LbAsa.Name = "LbAsa";
+ this.LbAsa.Size = new System.Drawing.Size(20, 9);
+ this.LbAsa.TabIndex = 56;
+ this.LbAsa.Text = "ASA";
+ //
// creatureAnalysis1
//
this.creatureAnalysis1.Location = new System.Drawing.Point(851, 265);
@@ -2326,6 +2344,11 @@ private void InitializeComponent()
this.columnHeaderStatusIcon.Text = "Status";
this.columnHeaderStatusIcon.Width = 35;
//
+ // columnHeaderMutagen
+ //
+ this.columnHeaderMutagen.Text = "Mutagen";
+ this.columnHeaderMutagen.Width = 30;
+ //
// contextMenuStripLibrary
//
this.contextMenuStripLibrary.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
@@ -3514,11 +3537,6 @@ private void InitializeComponent()
this.speciesSelector1.SplitterDistance = 500;
this.speciesSelector1.TabIndex = 0;
//
- // columnHeaderMutagen
- //
- this.columnHeaderMutagen.Text = "Mutagen";
- this.columnHeaderMutagen.Width = 30;
- //
// Form1
//
this.AcceptButton = this.btExtractLevels;
@@ -3951,5 +3969,6 @@ private void InitializeComponent()
private System.Windows.Forms.CheckBox CbLibraryInfoUseFilter;
private System.Windows.Forms.TextBox TbMessageLabel;
private System.Windows.Forms.ColumnHeader columnHeaderMutagen;
+ private System.Windows.Forms.Label LbAsa;
}
}
diff --git a/ARKBreedingStats/Form1.collection.cs b/ARKBreedingStats/Form1.collection.cs
index 4bcecf93..cac29906 100644
--- a/ARKBreedingStats/Form1.collection.cs
+++ b/ARKBreedingStats/Form1.collection.cs
@@ -558,6 +558,7 @@ private bool LoadCollectionFile(string filePath, bool keepCurrentCreatures = fal
speciesSelector1.SetSpecies(_creatureCollection.creatures[0].Species);
// set library species to what it was before loading
+ selectedLibrarySpecies = Values.V.SpeciesByBlueprint(selectedLibrarySpecies?.blueprintPath);
if (selectedLibrarySpecies != null)
listBoxSpeciesLib.SelectedItem = selectedLibrarySpecies;
else if (Properties.Settings.Default.LibrarySelectSelectedSpeciesOnLoad)
diff --git a/ARKBreedingStats/Form1.cs b/ARKBreedingStats/Form1.cs
index 465e9446..17b34826 100644
--- a/ARKBreedingStats/Form1.cs
+++ b/ARKBreedingStats/Form1.cs
@@ -462,7 +462,8 @@ private void Form1_Load(object sender, EventArgs e)
var filterPresets = Properties.Settings.Default.LibraryFilterPresets;
if (filterPresets != null)
ToolStripTextBoxLibraryFilter.AutoCompleteCustomSource.AddRange(filterPresets);
-
+
+ UpdateAsaIndicator();
UpdatePatternButtons();
SetupAutoLoadFileWatcher();
@@ -1109,9 +1110,9 @@ private async void CheckForUpdates(bool silentCheck = false, bool selectDefaultI
(bool statValuesLoaded, bool kibbleValuesLoaded) success = (false, false);
if (LoadStatValues(Values.V, forceReload))
{
+ speciesSelector1.SetSpeciesLists(Values.V.species, Values.V.aliases);
if (applySettings)
ApplySettingsToValues();
- speciesSelector1.SetSpeciesLists(Values.V.species, Values.V.aliases);
UpdateStatusBar();
success.statValuesLoaded = true;
}
@@ -1628,13 +1629,6 @@ private void ExtractBaby(Creature mother, Creature father)
tabControlMain.SelectedTab = tabPageExtractor;
}
- private void NumericUpDownTestingTE_ValueChanged(object sender, EventArgs e)
- {
- UpdateAllTesterValues();
- lbWildLevelTester.Text =
- $"{Loc.S("preTameLevel")}: {Math.Ceiling(Math.Round((_testingIOs[Stats.Torpidity].LevelWild + 1) / (1 + NumericUpDownTestingTE.Value / 200), 6))}";
- }
-
private void numericUpDownImprintingBonusTester_ValueChanged(object sender, EventArgs e)
{
UpdateAllTesterValues();
@@ -1719,7 +1713,7 @@ private void ExportSelectedCreatureToClipboard(bool breeding = true, bool ARKml
var levelStep = _creatureCollection.getWildLevelStep();
Creature creature = new Creature(species, input.CreatureName, input.CreatureOwner,
input.CreatureTribe, input.CreatureSex, GetCurrentWildLevels(fromExtractor),
- GetCurrentDomLevels(fromExtractor), te, bred, imprinting, levelStep)
+ GetCurrentDomLevels(fromExtractor), GetCurrentMutLevels(fromExtractor), te, bred, imprinting, levelStep)
{
colors = input.RegionColors,
ArkId = input.ArkId
@@ -1971,6 +1965,7 @@ private void OpenSettingsDialog(SettingsTabPages page = SettingsTabPages.Unknown
bool libraryTopCreatureColorHighlight = Properties.Settings.Default.LibraryHighlightTopCreatures;
bool considerWastedStatsForTopCreatures = Properties.Settings.Default.ConsiderWastedStatsForTopCreatures;
+ var gameSettingBefore = _creatureCollection.Game;
using (Settings settingsForm = new Settings(_creatureCollection, page))
{
@@ -1991,6 +1986,28 @@ private void OpenSettingsDialog(SettingsTabPages page = SettingsTabPages.Unknown
}
}
+ if (_creatureCollection.Game != gameSettingBefore)
+ {
+ // ASA setting changed
+ var asaCurrentlyLoaded = _creatureCollection.modIDs?.Contains(Ark.Asa) == true;
+
+ if ((_creatureCollection.Game == Ark.Asa) ^ asaCurrentlyLoaded)
+ {
+ if (asaCurrentlyLoaded)
+ {
+ _creatureCollection.modIDs.Remove(Ark.Asa);
+ _creatureCollection.ModList.RemoveAll(m => m.id == Ark.Asa);
+ }
+ else
+ {
+ if (_creatureCollection.modIDs == null) _creatureCollection.modIDs = new List();
+ _creatureCollection.modIDs.Insert(0, Ark.Asa);
+ }
+ _creatureCollection.modListHash = 0; // making sure the mod values are reevaluated
+ ReloadModValuesOfCollectionIfNeeded(!asaCurrentlyLoaded, false, false);
+ }
+ }
+
ApplySettingsToValues();
CreatureColored.InitializeSpeciesImageLocation();
creatureBoxListView.CreatureCollection = _creatureCollection;
@@ -2443,7 +2460,7 @@ private bool SetOverlayLocation()
private void toolStripButtonCopy2Tester_Click(object sender, EventArgs e)
{
double te = _extractor.UniqueTamingEffectiveness();
- NumericUpDownTestingTE.ValueSave = (decimal)(te >= 0 ? te * 100 : 80);
+ TamingEffectivenessTester = te;
numericUpDownImprintingBonusTester.Value = numericUpDownImprintingBonusExtractor.Value;
if (rbBredExtractor.Checked)
rbBredTester.Checked = true;
@@ -2687,6 +2704,7 @@ private bool LoadModValuesOfCollection(CreatureCollection cc, bool showResult, b
{
// nothing to do, and no error, the modHash seems to be wrong.
cc.UpdateModList();
+ UpdateAsaIndicator();
return true;
}
@@ -2715,7 +2733,17 @@ private bool LoadModValuesOfCollection(CreatureCollection cc, bool showResult, b
"Unknown mod IDs", MessageBoxButtons.OK, MessageBoxIcon.Warning);
bool result = LoadModValueFiles(filePaths, showResult, applySettings, out _);
+ UpdateAsaIndicator();
return result;
+
+ }
+
+ ///
+ /// Displays a small indicator in the UI if the ASA values are loaded.
+ ///
+ private void UpdateAsaIndicator()
+ {
+ LbAsa.Visible = _creatureCollection.Game == Ark.Asa;
}
private void loadAdditionalValuesToolStripMenuItem_Click(object sender, EventArgs e)
@@ -2730,17 +2758,32 @@ private void loadAdditionalValuesToolStripMenuItem_Click(object sender, EventArg
(Properties.Settings.Default.ModManagerWindowRect, _) = Utils.GetWindowRectangle(modValuesManager);
}
+ // if Asa values are added or removed manually, adjust Asa setting
+ _creatureCollection.Game = _creatureCollection.modIDs?.Contains(Ark.Asa) == true ? Ark.Asa : null;
+ ReloadModValuesOfCollectionIfNeeded();
+ }
+
+ ///
+ /// Loads mod value files according to the ModList of the library.
+ ///
+ /// If true the values are not reset to the default first.
+ private void ReloadModValuesOfCollectionIfNeeded(bool onlyAdd = false, bool showResult = true, bool applySettings = true)
+ {
// if the mods for the library changed,
// first check if all mod value files are available and load missing files if possible,
// then reload all values and mod values
if (_creatureCollection.ModValueReloadNeeded)
{
- var modValuesNeedToBeLoaded = _creatureCollection.ModList?.Any() == true;
- // first reset values to default
- LoadStatAndKibbleValues(!modValuesNeedToBeLoaded);
+ var modValuesNeedToBeLoaded = _creatureCollection.modIDs?.Any() == true;
+ // first reset values to default if needed
+ if (!onlyAdd)
+ LoadStatAndKibbleValues(!modValuesNeedToBeLoaded);
// then load mod values if any
if (modValuesNeedToBeLoaded)
- LoadModValuesOfCollection(_creatureCollection, true, true);
+ LoadModValuesOfCollection(_creatureCollection, showResult, applySettings);
+ else
+ UpdateAsaIndicator();
+
SetCollectionChanged(true);
}
}
@@ -2862,7 +2905,7 @@ private void SetCreatureValuesToTester(CreatureValues cv)
SetCreatureValuesToInfoInput(cv, creatureInfoInputTester);
- NumericUpDownTestingTE.ValueSave = (decimal)cv.tamingEffMin * 100;
+ TamingEffectivenessTester = cv.tamingEffMin;
if (cv.isBred)
rbBredTester.Checked = true;
@@ -3050,7 +3093,7 @@ private void UpdatePatternButtons()
creatureInfoInputTester.SetNamePatternButtons(Properties.Settings.Default.NamingPatterns);
}
- private void ExtractionTestControl1_CopyToTester(string speciesBP, int[] wildLevels, int[] domLevels,
+ private void ExtractionTestControl1_CopyToTester(string speciesBP, int[] wildLevels, int[] domLevels, int[] mutLevels,
bool postTamed, bool bred, double te, double imprintingBonus, bool gotoTester,
testCases.TestCaseControl tcc)
{
@@ -3060,7 +3103,7 @@ private void ExtractionTestControl1_CopyToTester(string speciesBP, int[] wildLev
if (species != null)
{
EditCreatureInTester(
- new Creature(species, null, null, null, Sex.Unknown, wildLevels, domLevels,
+ new Creature(species, null, null, null, Sex.Unknown, wildLevels, domLevels, mutLevels,
te, bred, imprintingBonus), true);
if (gotoTester) tabControlMain.SelectedTab = tabPageStatTesting;
}
@@ -3170,7 +3213,7 @@ private void tsBtAddAsExtractionTest_Click(object sender, EventArgs e)
bred = rbBredTester.Checked,
postTamed = rbTamedTester.Checked || rbBredTester.Checked
};
- etc.tamingEff = etc.bred ? 1 : etc.postTamed ? (double)NumericUpDownTestingTE.Value / 100 : 0;
+ etc.tamingEff = etc.bred ? 1 : etc.postTamed ? TamingEffectivenessTester : -3;
etc.imprintingBonus = etc.bred ? (double)numericUpDownImprintingBonusTester.Value / 100 : 0;
etc.levelsDom = GetCurrentDomLevels(false);
etc.levelsWild = GetCurrentWildLevels(false);
@@ -3209,7 +3252,7 @@ private void copyToMultiplierTesterToolStripButton_Click(object sender, EventArg
wildLevels,
GetCurrentDomLevels(false),
(int)numericUpDownLevel.Value,
- (double)NumericUpDownTestingTE.Value / 100,
+ TamingEffectivenessTester,
(double)(fromExtractor
? numericUpDownImprintingBonusExtractor.Value
: numericUpDownImprintingBonusTester.Value) / 100,
@@ -3675,8 +3718,7 @@ private void Form1_KeyUp(object sender, KeyEventArgs e)
return;
}
-
- if (!e.Control) return;
+ if (!e.Control || e.Alt) return;
int index;
diff --git a/ARKBreedingStats/Form1.extractor.cs b/ARKBreedingStats/Form1.extractor.cs
index b84cc534..1589cc83 100644
--- a/ARKBreedingStats/Form1.extractor.cs
+++ b/ARKBreedingStats/Form1.extractor.cs
@@ -177,12 +177,16 @@ private void ShowSumOfChosenLevels()
}
}
- if (_statIOs[s].LevelWild > 255)
- levelStatus |= LevelStatus.UltraMaxLevel;
- else if (_statIOs[s].LevelWild == 255)
- levelStatus |= LevelStatus.MaxLevel;
- else if (_statIOs[s].LevelWild == 254)
- levelStatus |= LevelStatus.MaxLevelForLevelUp;
+ // ASA can have up to 511 levels because 255 mutation levels also contribute to the wild value. TODO separate to mutation levels
+ if (_creatureCollection.Game != Ark.Asa)
+ {
+ if (_statIOs[s].LevelWild > 255)
+ levelStatus |= LevelStatus.UltraMaxLevel;
+ else if (_statIOs[s].LevelWild == 255)
+ levelStatus |= LevelStatus.MaxLevel;
+ else if (_statIOs[s].LevelWild == 254)
+ levelStatus |= LevelStatus.MaxLevelForLevelUp;
+ }
if (levelStatus != LevelStatus.Neutral)
_statIOs[s].TopLevel = levelStatus;
@@ -1134,7 +1138,8 @@ private Creature GetCreatureFromInput(bool fromExtractor, Species species, int?
imprinting = (double)numericUpDownImprintingBonusTester.Value / 100;
}
- Creature creature = new Creature(species, input.CreatureName, input.CreatureOwner, input.CreatureTribe, input.CreatureSex, GetCurrentWildLevels(fromExtractor), GetCurrentDomLevels(fromExtractor), te, bred, imprinting, levelStep: levelStep)
+ Creature creature = new Creature(species, input.CreatureName, input.CreatureOwner, input.CreatureTribe, input.CreatureSex,
+ GetCurrentWildLevels(fromExtractor), GetCurrentDomLevels(fromExtractor), GetCurrentMutLevels(fromExtractor), te, bred, imprinting, levelStep: levelStep)
{
// set parents
Mother = input.Mother,
diff --git a/ARKBreedingStats/Form1.library.cs b/ARKBreedingStats/Form1.library.cs
index 63d3836f..c13f4eac 100644
--- a/ARKBreedingStats/Form1.library.cs
+++ b/ARKBreedingStats/Form1.library.cs
@@ -194,8 +194,6 @@ private bool IsArkIdUniqueOrOnlyPlaceHolder(Creature creature)
///
/// Returns the wild levels from the extractor or tester in an array.
///
- ///
- ///
private int[] GetCurrentWildLevels(bool fromExtractor = true)
{
int[] levelsWild = new int[Stats.StatsCount];
@@ -209,8 +207,6 @@ private int[] GetCurrentWildLevels(bool fromExtractor = true)
///
/// Returns the domesticated levels from the extractor or tester in an array.
///
- ///
- ///
private int[] GetCurrentDomLevels(bool fromExtractor = true)
{
int[] levelsDom = new int[Stats.StatsCount];
@@ -221,6 +217,19 @@ private int[] GetCurrentDomLevels(bool fromExtractor = true)
return levelsDom;
}
+ ///
+ /// Returns the mutated levels from the extractor or tester in an array.
+ ///
+ private int[] GetCurrentMutLevels(bool fromExtractor = true)
+ {
+ int[] levelsMut = new int[Stats.StatsCount];
+ for (int s = 0; s < Stats.StatsCount; s++)
+ {
+ levelsMut[s] = fromExtractor ? _statIOs[s].LevelMut : _testingIOs[s].LevelMut;
+ }
+ return levelsMut;
+ }
+
///
/// Call after the creatureCollection-object was created anew (e.g. after loading a file)
///
diff --git a/ARKBreedingStats/Form1.tester.cs b/ARKBreedingStats/Form1.tester.cs
index 7176330d..493e07b7 100644
--- a/ARKBreedingStats/Form1.tester.cs
+++ b/ARKBreedingStats/Form1.tester.cs
@@ -37,7 +37,7 @@ private void EditCreatureInTester(Creature c, bool virtualCreature = false)
return;
speciesSelector1.SetSpecies(c.Species);
- NumericUpDownTestingTE.ValueSave = c.tamingEff >= 0 ? (decimal)c.tamingEff * 100 : 0;
+ TamingEffectivenessTester = c.tamingEff;
numericUpDownImprintingBonusTester.ValueSave = (decimal)c.imprintingBonus * 100;
if (c.isBred)
rbBredTester.Checked = true;
@@ -132,7 +132,9 @@ private void TestingStatIoValueUpdate(StatIO sIo)
//statGraphs1.setGraph(sE, 0, testingIOs[0].LevelWild, testingIOs[0].LevelDom, !radioButtonTesterWild.Checked, (double)NumericUpDownTestingTE.Value / 100, (double)numericUpDownImprintingBonusTester.Value / 100);
if (sIo.statIndex == Stats.Torpidity)
- lbWildLevelTester.Text = "PreTame Level: " + Math.Ceiling(Math.Round((_testingIOs[Stats.Torpidity].LevelWild + 1) / (1 + NumericUpDownTestingTE.Value / 200), 6));
+ {
+ DisplayPreTamedLevelTester();
+ }
var levelWarning = string.Empty;
if (wildLevel255)
@@ -153,7 +155,7 @@ private void TestingStatIOsRecalculateValue(StatIO sIo)
sIo.BreedingValue = StatValueCalculation.CalculateValue(speciesSelector1.SelectedSpecies, sIo.statIndex, sIo.LevelWild, 0, true, 1, 0);
sIo.Input = StatValueCalculation.CalculateValue(speciesSelector1.SelectedSpecies, sIo.statIndex, sIo.LevelWild, sIo.LevelDom,
rbTamedTester.Checked || rbBredTester.Checked,
- rbBredTester.Checked ? 1 : (double)NumericUpDownTestingTE.Value / 100,
+ rbBredTester.Checked ? 1 : Math.Max(0, TamingEffectivenessTester),
rbBredTester.Checked ? (double)numericUpDownImprintingBonusTester.Value / 100 : 0);
}
@@ -167,7 +169,7 @@ private void creatureInfoInputTester_Save2Library_Clicked(CreatureInfoInput send
if (_creatureTesterEdit == null)
return;
// check if wild levels are changed, if yes warn that the creature can become invalid
- bool wildChanged = Math.Abs(_creatureTesterEdit.tamingEff - (double)NumericUpDownTestingTE.Value / 100) > .0005;
+ bool wildChanged = Math.Abs(_creatureTesterEdit.tamingEff - TamingEffectivenessTester) > .0005;
if (!wildChanged)
{
int[] wildLevels = GetCurrentWildLevels(false);
@@ -379,9 +381,30 @@ private void PbCreatureColorsExtractor_Click(object sender, EventArgs e)
creature.ExportInfoGraphicToClipboard(CreatureCollection.CurrentCreatureCollection);
}
+ private void NumericUpDownTestingTE_ValueChanged(object sender, EventArgs e)
+ {
+ UpdateAllTesterValues();
+ DisplayPreTamedLevelTester();
+ }
+
+ private void DisplayPreTamedLevelTester()
+ {
+ if (TamingEffectivenessTester >= 0)
+ lbWildLevelTester.Text =
+ $"{Loc.S("preTameLevel")}: {Creature.CalculatePreTameWildLevel(_testingIOs[Stats.Torpidity].LevelWild + 1, TamingEffectivenessTester)}";
+ else
+ lbWildLevelTester.Text =
+ $"{Loc.S("preTameLevel")}: {Loc.S("unknown")}";
+ }
+
///
- /// Returns the taming effectiveness for the creature in the Tester. -3 indicates a wild creature.
+ /// Taming effectiveness for the creature in the Tester (range 0-1).
+ /// -1 indicates unknown, -3 a wild creature.
///
- private double TamingEffectivenessTester => rbWildTester.Checked ? -3 : (double)NumericUpDownTestingTE.Value / 100;
+ private double TamingEffectivenessTester
+ {
+ get => rbWildTester.Checked ? -3 : (double)NumericUpDownTestingTE.Value / 100;
+ set => NumericUpDownTestingTE.ValueSave = (decimal)(value >= 0 ? value * 100 : -1);
+ }
}
}
diff --git a/ARKBreedingStats/Form1.values.cs b/ARKBreedingStats/Form1.values.cs
index 8f0a1c83..eb355620 100644
--- a/ARKBreedingStats/Form1.values.cs
+++ b/ARKBreedingStats/Form1.values.cs
@@ -36,9 +36,9 @@ private bool LoadModValueFiles(List modFilesToLoad, bool showResult, boo
if (modFilesLoaded)
{
+ speciesSelector1.SetSpeciesLists(Values.V.species, Values.V.aliases);
if (applySettings)
ApplySettingsToValues();
- speciesSelector1.SetSpeciesLists(Values.V.species, Values.V.aliases);
}
if (showResult && !string.IsNullOrEmpty(resultsMessage))
MessageBox.Show(resultsMessage, "Loading Mod Values", MessageBoxButtons.OK, MessageBoxIcon.Information);
diff --git a/ARKBreedingStats/ImportSavegame.cs b/ARKBreedingStats/ImportSavegame.cs
index 57328d9c..9f486c0c 100644
--- a/ARKBreedingStats/ImportSavegame.cs
+++ b/ARKBreedingStats/ImportSavegame.cs
@@ -155,6 +155,7 @@ private Creature ConvertGameObject(GameObject creatureObject, int? levelStep)
int[] wildLevels = Enumerable.Repeat(-1, Stats.StatsCount).ToArray(); // -1 is unknown
int[] tamedLevels = new int[Stats.StatsCount];
+ int[] mutatedLevels = new int[Stats.StatsCount];
for (int i = 0; i < Stats.StatsCount; i++)
{
@@ -165,6 +166,7 @@ private Creature ConvertGameObject(GameObject creatureObject, int? levelStep)
for (int i = 0; i < Stats.StatsCount; i++)
{
tamedLevels[i] = statusObject.GetPropertyValue("NumberOfLevelUpPointsAppliedTamed", i)?.ByteValue ?? 0;
+ //mutatedLevels[i] = statusObject.GetPropertyValue("NumberOfLevelUpPointsAppliedMutated", i)?.ByteValue ?? 0; // TODO
}
float ti = statusObject.GetPropertyValue("TamedIneffectivenessModifier", defaultValue: float.NaN);
@@ -174,7 +176,7 @@ private Creature ConvertGameObject(GameObject creatureObject, int? levelStep)
Creature creature = new Creature(species,
creatureObject.GetPropertyValue("TamedName"), owner, creatureObject.GetPropertyValue("TribeName"),
creatureObject.IsFemale() ? Sex.Female : Sex.Male,
- wildLevels, tamedLevels, te,
+ wildLevels, tamedLevels, mutatedLevels, te,
!string.IsNullOrWhiteSpace(creatureObject.GetPropertyValue("ImprinterName")),
statusObject.GetPropertyValue("DinoImprintingQuality"),
levelStep
diff --git a/ARKBreedingStats/Properties/AssemblyInfo.cs b/ARKBreedingStats/Properties/AssemblyInfo.cs
index 0bb2c48f..ee14d63e 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.56.3.0")]
+[assembly: AssemblyFileVersion("0.57.0.1")]
[assembly: NeutralResourcesLanguage("en")]
diff --git a/ARKBreedingStats/_manifest.json b/ARKBreedingStats/_manifest.json
index aae82b71..d206d12f 100644
--- a/ARKBreedingStats/_manifest.json
+++ b/ARKBreedingStats/_manifest.json
@@ -4,7 +4,7 @@
"ARK Smart Breeding": {
"Id": "ARK Smart Breeding",
"Category": "main",
- "version": "0.56.3.0"
+ "version": "0.57.0.1"
},
"SpeciesColorImages": {
"Id": "SpeciesColorImages",
diff --git a/ARKBreedingStats/importExportGun/ExportGunCreatureFile.cs b/ARKBreedingStats/importExportGun/ExportGunCreatureFile.cs
index e630f0bb..a8ed4ada 100644
--- a/ARKBreedingStats/importExportGun/ExportGunCreatureFile.cs
+++ b/ARKBreedingStats/importExportGun/ExportGunCreatureFile.cs
@@ -55,6 +55,7 @@ internal class Stat
{
public int Wild { get; set; }
public int Tamed { get; set; }
+ public int Mutated { get; set; }
public float Value { get; set; }
}
}
diff --git a/ARKBreedingStats/importExportGun/ImportExportGun.cs b/ARKBreedingStats/importExportGun/ImportExportGun.cs
index 3ba88e07..7dc6c3c4 100644
--- a/ARKBreedingStats/importExportGun/ImportExportGun.cs
+++ b/ARKBreedingStats/importExportGun/ImportExportGun.cs
@@ -59,11 +59,13 @@ private static Creature ConvertExportGunToCreature(ExportGunCreatureFile ec, out
var wildLevels = new int[Stats.StatsCount];
var domLevels = new int[Stats.StatsCount];
+ var mutLevels = new int[Stats.StatsCount];
var si = 0;
foreach (var s in ec.Stats)
{
wildLevels[si] = s.Wild;
domLevels[si] = s.Tamed;
+ mutLevels[si] = s.Mutated;
si++;
}
@@ -78,7 +80,7 @@ private static Creature ConvertExportGunToCreature(ExportGunCreatureFile ec, out
;
var c = new Creature(species, ec.DinoName, !string.IsNullOrEmpty(ec.OwningPlayerName) ? ec.OwningPlayerName : !string.IsNullOrEmpty(ec.ImprinterName) ? ec.ImprinterName : ec.TamerString,
- ec.TribeName, species.noGender ? Sex.Unknown : ec.IsFemale ? Sex.Female : Sex.Male, wildLevels, domLevels,
+ ec.TribeName, species.noGender ? Sex.Unknown : ec.IsFemale ? Sex.Female : Sex.Male, wildLevels, domLevels, mutLevels,
isWild ? -3 : ec.TameEffectiveness, !string.IsNullOrEmpty(ec.ImprinterName), ec.DinoImprintingQuality,
CreatureCollection.CurrentCreatureCollection?.wildLevelStep)
{
diff --git a/ARKBreedingStats/library/Creature.cs b/ARKBreedingStats/library/Creature.cs
index e87c9c21..fabb19ed 100644
--- a/ARKBreedingStats/library/Creature.cs
+++ b/ARKBreedingStats/library/Creature.cs
@@ -25,6 +25,8 @@ public class Creature : IEquatable
public int[] levelsWild;
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
public int[] levelsDom;
+ [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
+ public int[] levelsMutated;
///
/// The taming effectiveness (0: 0, 1: 100 %).
@@ -204,7 +206,8 @@ public DateTime? growingUntil
public Creature() { }
- public Creature(Species species, string name, string owner = null, string tribe = null, Sex sex = Sex.Unknown, int[] levelsWild = null, int[] levelsDom = null, double tamingEff = 0, bool isBred = false, double imprinting = 0, int? levelStep = null)
+ public Creature(Species species, string name, string owner = null, string tribe = null, Sex sex = Sex.Unknown,
+ int[] levelsWild = null, int[] levelsDom = null, int[] levelsMutated = null, double tamingEff = 0, bool isBred = false, double imprinting = 0, int? levelStep = null)
{
Species = species;
this.name = name ?? string.Empty;
@@ -213,6 +216,7 @@ public Creature(Species species, string name, string owner = null, string tribe
this.sex = sex;
this.levelsWild = levelsWild;
this.levelsDom = levelsDom ?? new int[Stats.StatsCount];
+ this.levelsMutated = levelsMutated;
this.isBred = isBred;
if (isBred)
{
@@ -572,7 +576,7 @@ public void InitializeFlags()
///
///
///
- internal static int CalculatePreTameWildLevel(int postTameLevel, double tamingEffectiveness) => (int)Math.Ceiling(postTameLevel / (1 + tamingEffectiveness / 2));
+ internal static int CalculatePreTameWildLevel(int postTameLevel, double tamingEffectiveness) => (int)Math.Ceiling(Math.Round(postTameLevel / (1 + tamingEffectiveness / 2), 6));
}
public enum Sex
diff --git a/ARKBreedingStats/library/CreatureCollection.cs b/ARKBreedingStats/library/CreatureCollection.cs
index 8711b0a2..23675bac 100644
--- a/ARKBreedingStats/library/CreatureCollection.cs
+++ b/ARKBreedingStats/library/CreatureCollection.cs
@@ -76,6 +76,12 @@ public CreatureCollection()
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
public bool AtlasSettings;
+ ///
+ /// Indicates the game the library is used for. Possible values are "ASE" (default) for ARK: Survival Evolved or "ASA" for ARK: Survival Ascended.
+ ///
+ [JsonProperty]
+ public string Game = "ASE";
+
///
/// Used for the exportGun mod.
/// This hash is used to determine if an imported creature file is using the current server multipliers.
@@ -100,7 +106,6 @@ public CreatureCollection()
///
/// Hash-Code that represents the loaded mod-values and their order
///
- [JsonProperty]
public int modListHash;
[JsonProperty]
diff --git a/ARKBreedingStats/library/ExportImportCreatures.cs b/ARKBreedingStats/library/ExportImportCreatures.cs
index 4cb0f563..e3f1beaf 100644
--- a/ARKBreedingStats/library/ExportImportCreatures.cs
+++ b/ARKBreedingStats/library/ExportImportCreatures.cs
@@ -283,7 +283,7 @@ private static Creature ParseCreature(string creatureValues)
{
if (string.IsNullOrEmpty(creatureValues)) return null;
- const string statRegex = @"(?: (\w+): [\d.]+(?: ?%)? \((\d+)(?:, (\d+))?\);)?";
+ const string statRegex = @"(?: (\w+): [\d.]+(?: ?%)? \((\d+)(?:, (\d+))?\);)?"; // TODO mutated levels
Regex r = new Regex(
@"(.*?) \(([^,]+), Lvl \d+(?:, (?:wild|TE: ([\d.]+) ?%|Impr: ([\d.]+) ?%))?(?:, (Female|Male))?\):" + string.Concat(Enumerable.Repeat(statRegex, Stats.StatsCount)));
@@ -430,6 +430,7 @@ bool ParseBool(int regExGroup)
{
levelsWild[si] = int.Parse(m.Groups[groupIndexOfFirstWildLevel + si].Value.Trim());
levelsDom[si] = int.Parse(m.Groups[groupIndexOfFirstWildLevel + Stats.StatsCount + si].Value.Trim());
+ // TODO mutated levels
}
var colorIds = new byte[Ark.ColorRegionCount];
@@ -439,7 +440,7 @@ bool ParseBool(int regExGroup)
}
var creature = new Creature(species, m.Groups[3].Value.Trim(), m.Groups[4].Value.Trim(), m.Groups[6].Value.Trim(), sex,
- levelsWild, levelsDom, te, isBred, imprintingBonus)
+ levelsWild, levelsDom, null, te, isBred, imprintingBonus)
{
imprinterName = m.Groups[5].Value.Trim(),
server = m.Groups[7].Value.Trim(),
diff --git a/ARKBreedingStats/multiplierTesting/StatsMultiplierTesting.cs b/ARKBreedingStats/multiplierTesting/StatsMultiplierTesting.cs
index dd90f8eb..74b93116 100644
--- a/ARKBreedingStats/multiplierTesting/StatsMultiplierTesting.cs
+++ b/ARKBreedingStats/multiplierTesting/StatsMultiplierTesting.cs
@@ -239,12 +239,14 @@ public void SetSpecies(Species species, bool forceUpdate = false)
bool customStatsAvailable =
_cc?.CustomSpeciesStats?.TryGetValue(species.blueprintPath, out customStatOverrides) ?? false;
+ var statImprintMultipliers = _selectedSpecies.StatImprintMultipliers;
+
for (int s = 0; s < Stats.StatsCount; s++)
{
_statControls[s].SetStatValues(_selectedSpecies.fullStatsRaw[s], customStatsAvailable ? customStatOverrides?[s] : null,
_selectedSpecies.altBaseStatsRaw != null && _selectedSpecies.altBaseStatsRaw.TryGetValue(s, out var altV) ? altV / _selectedSpecies.fullStatsRaw[s][0] : 1,
!CbAllowFlyerSpeedLeveling.Checked && species.isFlyer && s == Stats.SpeedMultiplier);
- _statControls[s].StatImprintingBonusMultiplier = customStatsAvailable ? customStatOverrides?[Stats.StatsCount]?[s] ?? _selectedSpecies.StatImprintMultipliers[s] : _selectedSpecies.StatImprintMultipliers[s];
+ _statControls[s].StatImprintingBonusMultiplier = customStatsAvailable ? customStatOverrides?[Stats.StatsCount]?[s] ?? statImprintMultipliers[s] : statImprintMultipliers[s];
_statControls[s].Visible = species.UsesStat(s);
_statControls[s].StatName = $"[{s}]{Utils.StatName(s, true, species.statNames)}";
}
@@ -342,7 +344,7 @@ internal void CheckIfMultipliersAreEqualToSettings()
private void llStatCalculation_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
- ArkWiki.OpenPage("Creature_Stats_Calculation");
+ ArkWiki.OpenPage("Creature_stats_calculation");
}
public CreatureCollection CreatureCollection
diff --git a/ARKBreedingStats/settings/ATImportFileLocationDialog.cs b/ARKBreedingStats/settings/ATImportFileLocationDialog.cs
index 5b319e1a..aa25e67c 100644
--- a/ARKBreedingStats/settings/ATImportFileLocationDialog.cs
+++ b/ARKBreedingStats/settings/ATImportFileLocationDialog.cs
@@ -1,5 +1,4 @@
using System;
-using System.Diagnostics;
using System.IO;
using System.Windows.Forms;
using ARKBreedingStats.utils;
diff --git a/ARKBreedingStats/settings/Settings.Designer.cs b/ARKBreedingStats/settings/Settings.Designer.cs
index 12a16cd9..3b535457 100644
--- a/ARKBreedingStats/settings/Settings.Designer.cs
+++ b/ARKBreedingStats/settings/Settings.Designer.cs
@@ -120,6 +120,7 @@ private void InitializeComponent()
this.checkBoxDisplayHiddenStats = new System.Windows.Forms.CheckBox();
this.tabControlSettings = new System.Windows.Forms.TabControl();
this.tabPageMultipliers = new System.Windows.Forms.TabPage();
+ this.BtImportSettingsSelectFile = new System.Windows.Forms.Button();
this.CbAtlasSettings = new System.Windows.Forms.CheckBox();
this.BtSettingsToClipboard = new System.Windows.Forms.Button();
this.groupBox29 = new System.Windows.Forms.GroupBox();
@@ -310,6 +311,7 @@ private void InitializeComponent()
this.label21 = new System.Windows.Forms.Label();
this.nudOverlayInfoDuration = new ARKBreedingStats.uiControls.Nud();
this.chkbSpeechRecognition = new System.Windows.Forms.CheckBox();
+ this.label66 = new System.Windows.Forms.Label();
this.tabPageOCR = new System.Windows.Forms.TabPage();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.label62 = new System.Windows.Forms.Label();
@@ -335,7 +337,9 @@ 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.label66 = new System.Windows.Forms.Label();
+ this.panel3 = new System.Windows.Forms.Panel();
+ this.RbGameAse = new System.Windows.Forms.RadioButton();
+ this.RbGameAsa = new System.Windows.Forms.RadioButton();
this.groupBoxMultiplier.SuspendLayout();
this.groupBox2.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.nudTamedDinoCharacterFoodDrain)).BeginInit();
@@ -442,6 +446,7 @@ private void InitializeComponent()
((System.ComponentModel.ISupportInitialize)(this.nudWaitBeforeScreenCapture)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.nudWhiteThreshold)).BeginInit();
this.panel1.SuspendLayout();
+ this.panel3.SuspendLayout();
this.SuspendLayout();
//
// groupBoxMultiplier
@@ -1597,7 +1602,7 @@ private void InitializeComponent()
//
// label15
//
- this.label15.Location = new System.Drawing.Point(453, 555);
+ this.label15.Location = new System.Drawing.Point(451, 536);
this.label15.Name = "label15";
this.label15.Size = new System.Drawing.Size(289, 77);
this.label15.TabIndex = 9;
@@ -1778,6 +1783,8 @@ private void InitializeComponent()
//
this.tabPageMultipliers.AllowDrop = true;
this.tabPageMultipliers.AutoScroll = true;
+ 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);
@@ -1804,10 +1811,20 @@ private void InitializeComponent()
this.tabPageMultipliers.DragDrop += new System.Windows.Forms.DragEventHandler(this.tabPage2_DragDrop);
this.tabPageMultipliers.DragEnter += new System.Windows.Forms.DragEventHandler(this.tabPage2_DragEnter);
//
+ // BtImportSettingsSelectFile
+ //
+ this.BtImportSettingsSelectFile.Location = new System.Drawing.Point(618, 599);
+ this.BtImportSettingsSelectFile.Name = "BtImportSettingsSelectFile";
+ this.BtImportSettingsSelectFile.Size = new System.Drawing.Size(114, 23);
+ this.BtImportSettingsSelectFile.TabIndex = 15;
+ this.BtImportSettingsSelectFile.Text = "Settings from file";
+ this.BtImportSettingsSelectFile.UseVisualStyleBackColor = true;
+ this.BtImportSettingsSelectFile.Click += new System.EventHandler(this.BtImportSettingsSelectFile_Click);
+ //
// CbAtlasSettings
//
this.CbAtlasSettings.AutoSize = true;
- this.CbAtlasSettings.Location = new System.Drawing.Point(264, 23);
+ this.CbAtlasSettings.Location = new System.Drawing.Point(289, 23);
this.CbAtlasSettings.Name = "CbAtlasSettings";
this.CbAtlasSettings.Size = new System.Drawing.Size(99, 17);
this.CbAtlasSettings.TabIndex = 14;
@@ -1897,7 +1914,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(417, 555);
+ this.label27.Location = new System.Drawing.Point(408, 536);
this.label27.Name = "label27";
this.label27.Size = new System.Drawing.Size(37, 26);
this.label27.TabIndex = 12;
@@ -3944,6 +3961,16 @@ private void InitializeComponent()
this.chkbSpeechRecognition.Text = "Speech Recognition (displays taming info, e.g. say \"Rex level 30\")";
this.chkbSpeechRecognition.UseVisualStyleBackColor = true;
//
+ // label66
+ //
+ this.label66.AutoSize = true;
+ this.label66.Font = new System.Drawing.Font("Microsoft Sans Serif", 16F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label66.Location = new System.Drawing.Point(6, 16);
+ this.label66.Name = "label66";
+ this.label66.Size = new System.Drawing.Size(37, 26);
+ this.label66.TabIndex = 19;
+ this.label66.Text = "💡";
+ //
// tabPageOCR
//
this.tabPageOCR.AutoScroll = true;
@@ -4261,15 +4288,37 @@ private void InitializeComponent()
this.panel1.Size = new System.Drawing.Size(758, 30);
this.panel1.TabIndex = 12;
//
- // label66
- //
- this.label66.AutoSize = true;
- this.label66.Font = new System.Drawing.Font("Microsoft Sans Serif", 16F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.label66.Location = new System.Drawing.Point(6, 16);
- this.label66.Name = "label66";
- this.label66.Size = new System.Drawing.Size(37, 26);
- this.label66.TabIndex = 19;
- this.label66.Text = "💡";
+ // panel3
+ //
+ this.panel3.Controls.Add(this.RbGameAsa);
+ this.panel3.Controls.Add(this.RbGameAse);
+ this.panel3.Location = new System.Drawing.Point(154, 19);
+ this.panel3.Name = "panel3";
+ this.panel3.Size = new System.Drawing.Size(117, 26);
+ this.panel3.TabIndex = 16;
+ //
+ // RbGameAse
+ //
+ this.RbGameAse.AutoSize = true;
+ this.RbGameAse.Checked = true;
+ this.RbGameAse.Location = new System.Drawing.Point(3, 3);
+ this.RbGameAse.Name = "RbGameAse";
+ this.RbGameAse.Size = new System.Drawing.Size(46, 17);
+ this.RbGameAse.TabIndex = 0;
+ this.RbGameAse.TabStop = true;
+ this.RbGameAse.Text = "ASE";
+ this.RbGameAse.UseVisualStyleBackColor = true;
+ //
+ // RbGameAsa
+ //
+ this.RbGameAsa.AutoSize = true;
+ this.RbGameAsa.Location = new System.Drawing.Point(55, 3);
+ this.RbGameAsa.Name = "RbGameAsa";
+ this.RbGameAsa.Size = new System.Drawing.Size(46, 17);
+ this.RbGameAsa.TabIndex = 1;
+ this.RbGameAsa.TabStop = true;
+ this.RbGameAsa.Text = "ASA";
+ this.RbGameAsa.UseVisualStyleBackColor = true;
//
// Settings
//
@@ -4428,6 +4477,8 @@ private void InitializeComponent()
((System.ComponentModel.ISupportInitialize)(this.nudWaitBeforeScreenCapture)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.nudWhiteThreshold)).EndInit();
this.panel1.ResumeLayout(false);
+ this.panel3.ResumeLayout(false);
+ this.panel3.PerformLayout();
this.ResumeLayout(false);
}
@@ -4740,5 +4791,9 @@ private void InitializeComponent()
private uiControls.Nud NudOverlayRelativeFontSize;
private System.Windows.Forms.Label label65;
private System.Windows.Forms.Label label66;
+ private System.Windows.Forms.Button BtImportSettingsSelectFile;
+ private System.Windows.Forms.Panel panel3;
+ private System.Windows.Forms.RadioButton RbGameAsa;
+ private System.Windows.Forms.RadioButton RbGameAse;
}
}
\ No newline at end of file
diff --git a/ARKBreedingStats/settings/Settings.cs b/ARKBreedingStats/settings/Settings.cs
index 27a15edb..b404d432 100644
--- a/ARKBreedingStats/settings/Settings.cs
+++ b/ARKBreedingStats/settings/Settings.cs
@@ -13,7 +13,6 @@
using ARKBreedingStats.library;
using ARKBreedingStats.uiControls;
using ARKBreedingStats.utils;
-using static System.Net.Mime.MediaTypeNames;
namespace ARKBreedingStats.settings
{
@@ -209,6 +208,8 @@ private void LoadSettings(CreatureCollection cc)
}
cbSingleplayerSettings.Checked = cc.singlePlayerSettings;
CbAtlasSettings.Checked = _cc.AtlasSettings;
+ if (_cc.Game == Ark.Asa) RbGameAsa.Checked = true;
+ else RbGameAse.Checked = true;
nudMaxDomLevels.ValueSave = cc.maxDomLevel;
numericUpDownMaxBreedingSug.ValueSave = cc.maxBreedingSuggestions;
@@ -466,6 +467,8 @@ private void SaveSettings()
_cc.singlePlayerSettings = cbSingleplayerSettings.Checked;
_cc.AtlasSettings = CbAtlasSettings.Checked;
+ _cc.Game = RbGameAsa.Checked ? Ark.Asa : Ark.Ase;
+
_cc.maxDomLevel = (int)nudMaxDomLevels.Value;
_cc.maxWildLevel = (int)nudMaxWildLevels.Value;
_cc.maxServerLevel = (int)nudMaxServerLevel.Value;
@@ -1593,5 +1596,20 @@ private void CbNaturalSorting_CheckedChanged(object sender, EventArgs e)
CbNaturalSortIgnoreSpaces.Checked = false;
CbNaturalSortIgnoreSpaces.Enabled = isChecked;
}
+
+ private void BtImportSettingsSelectFile_Click(object sender, EventArgs e)
+ {
+ // import settings from text file
+ using (var dlg = new OpenFileDialog
+ {
+ Filter = "ARK Multiplier File (*.ini)|*.ini",
+ InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop),
+ CheckFileExists = true
+ })
+ {
+ if (dlg.ShowDialog() != DialogResult.OK) return;
+ ExtractSettingsFromFile(dlg.FileName);
+ }
+ }
}
}
diff --git a/ARKBreedingStats/species/ARKColors.cs b/ARKBreedingStats/species/ARKColors.cs
index a55be360..b855d41e 100644
--- a/ARKBreedingStats/species/ARKColors.cs
+++ b/ARKBreedingStats/species/ARKColors.cs
@@ -26,7 +26,7 @@ public class ArkColors
///
/// If mods are loaded, each mod has its colors (or null if no color definitions are given) in the according order.
///
- private List> _modColors;
+ private List<(List colors, int dyeStartIndex)> _modColors;
public ArkColors(List baseColorList)
{
@@ -36,9 +36,9 @@ public ArkColors(List baseColorList)
///
/// Adds Ark colors of a mod value file to the base values. Should be called even if the mod has no color definitions (ARK can then add missing colors that where left out before due to mod-overwriting).
///
- internal void AddModArkColors(List modColors)
+ internal void AddModArkColors((List colors, int dyeStartIndex) modColors)
{
- if (_modColors == null) _modColors = new List>();
+ if (_modColors == null) _modColors = new List<(List colors, int dyeStartIndex)>();
_modColors.Add(modColors);
}
@@ -60,33 +60,42 @@ public void InitializeArkColors()
_colorsByName = new Dictionary();
_colorsById = new Dictionary { { 0, new ArkColor() } };
var nextFreeColorId = Ark.ColorFirstId;
- var nextFreeDyeId = Ark.DyeFirstId;
+ var nextFreeDyeId = Ark.DyeFirstIdASE;
+ var colorIdMax = Ark.DyeFirstIdASE - 1;
var noMoreAvailableColorId = false;
var noMoreAvailableDyeId = false;
+ var baseColorsAdded = false;
+ void AddBaseColors()
+ {
+ AddColorDefinitions(_baseColors);
+ baseColorsAdded = true;
+ }
+
// no mods are loaded or first mod has no color overrides, use base colors first
if (_modColors?.Any() != true)
{
- AddColorDefinitions(_baseColors);
+ AddBaseColors();
}
else
{
// add mod color definitions, these are appended if the color name doesn't exist yet
- var baseColorsAdded = false;
foreach (var modColors in _modColors)
{
- if (modColors == null)
+ if (modColors.colors == null)
{
// if the mod has no color definitions, it uses the base color definitions; add them if not yet added
if (!baseColorsAdded)
- {
- AddColorDefinitions(_baseColors);
- baseColorsAdded = true;
- }
+ AddBaseColors();
+
continue;
}
- AddColorDefinitions(modColors);
+ // if the mod only overwrites colors, it needs the base colors loaded
+ if (modColors.dyeStartIndex != 0 && !baseColorsAdded)
+ AddBaseColors();
+
+ AddColorDefinitions(modColors.colors, (byte)modColors.dyeStartIndex);
}
// dye colors are apparently added independently from the colors, even if base colors are not added. This might need more testing, so far no mods are found that add dye colors.
@@ -96,9 +105,17 @@ public void InitializeArkColors()
}
}
- void AddColorDefinitions(IEnumerable colorDefinitions)
+ // if dyeStartIndex != 0 the dye information from the mod colors overwrites the existing definitions from the index/id on
+ void AddColorDefinitions(IEnumerable colorDefinitions, byte dyeStartIndex = 0)
{
if (colorDefinitions == null) return;
+
+ if (dyeStartIndex != 0 && dyeStartIndex <= Ark.DyeMaxId)
+ {
+ nextFreeDyeId = dyeStartIndex;
+ noMoreAvailableDyeId = false;
+ }
+
foreach (var c in colorDefinitions)
{
var colorNameExists = _colorsByName.ContainsKey(c.Name);
@@ -118,13 +135,13 @@ void AddColorDefinitions(IEnumerable colorDefinitions)
if (noMoreAvailableColorId) continue;
c.Id = nextFreeColorId;
- if (nextFreeColorId == Ark.ColorMaxId)
+ if (nextFreeColorId == colorIdMax)
noMoreAvailableColorId = true;
else nextFreeColorId++;
}
if (!colorNameExists)
_colorsByName.Add(c.Name, c);
- _colorsById.Add(c.Id, c);
+ _colorsById[c.Id] = c;
}
}
@@ -251,7 +268,7 @@ public byte[] GetRandomColors(Random rand = null)
{
if (ColorsList?.Any() != true)
return new byte[Ark.ColorRegionCount];
-
+
if (rand == null)
rand = new Random();
diff --git a/ARKBreedingStats/species/Species.cs b/ARKBreedingStats/species/Species.cs
index 5c377144..04dde93c 100644
--- a/ARKBreedingStats/species/Species.cs
+++ b/ARKBreedingStats/species/Species.cs
@@ -58,6 +58,12 @@ public class Species
///
public CreatureStat[] altStats;
+ ///
+ /// Multipliers for each stat for the mutated levels. Introduced in ASA.
+ ///
+ [JsonProperty]
+ public float[] mutationMult;
+
///
/// Indicates if a stat is shown in game represented by bit-flags
///
@@ -69,6 +75,12 @@ public class Species
///
private int usedStats;
+ ///
+ /// Indicates if a stat won't get wild levels for spawned creatures represented by bit-flags
+ ///
+ [JsonProperty]
+ private int skipWildLevelStats;
+
///
/// Indicates if the species is affected by the setting AllowFlyerSpeedLeveling
///
@@ -122,26 +134,37 @@ public class Species
/// creates properties that are not created during deserialization. They are set later with the raw-values with the multipliers applied.
///
[OnDeserialized]
- private void Initialize(StreamingContext context)
+ private void Initialize(StreamingContext _)
{
// TODO: Base species are maybe not used in game and may only lead to confusion (e.g. Giganotosaurus).
+ if (string.IsNullOrEmpty(blueprintPath)) return; // blueprint path is needed for identification
+
InitializeNames();
stats = new CreatureStat[Stats.StatsCount];
if (altBaseStatsRaw != null)
altStats = new CreatureStat[Stats.StatsCount];
+ var fullStatsRawLength = fullStatsRaw?.Length ?? 0;
+
usedStats = 0;
+
double[][] completeRaws = new double[Stats.StatsCount][];
for (int s = 0; s < Stats.StatsCount; s++)
{
+ // so far it seems stats that are skipped in wild are not displayed either
+ var statBit = (1 << s);
+ if ((skipWildLevelStats & statBit) != 0)
+ displayedStats &= ~statBit;
+
+
stats[s] = new CreatureStat();
if (altBaseStatsRaw?.ContainsKey(s) ?? false)
altStats[s] = new CreatureStat();
completeRaws[s] = new double[] { 0, 0, 0, 0, 0 };
- if (fullStatsRaw.Length > s && fullStatsRaw[s] != null)
+ if (fullStatsRawLength > s && fullStatsRaw[s] != null)
{
for (int i = 0; i < 5; i++)
{
@@ -156,7 +179,10 @@ private void Initialize(StreamingContext context)
}
}
}
- fullStatsRaw = completeRaws;
+
+ if (fullStatsRawLength != -0)
+ fullStatsRaw = completeRaws;
+
if (TamedBaseHealthMultiplier == null)
TamedBaseHealthMultiplier = 1;
@@ -169,9 +195,6 @@ private void Initialize(StreamingContext context)
colors = allColorRegions;
}
- if (string.IsNullOrEmpty(blueprintPath))
- blueprintPath = string.Empty;
-
if (boneDamageAdjusters != null && boneDamageAdjusters.Any())
{
// cleanup boneDamageMultipliers. Remove duplicates. Improve names.
@@ -191,9 +214,20 @@ private void Initialize(StreamingContext context)
IsDomesticable = (taming != null && (taming.nonViolent || taming.violent))
|| (breeding != null && (breeding.incubationTime > 0 || breeding.gestationTime > 0));
- if (statImprintMult == null) statImprintMult = new double[] { 0.2, 0, 0.2, 0, 0.2, 0.2, 0, 0.2, 0.2, 0.2, 0, 0 }; // default values for the stat imprint multipliers
+ if (statImprintMult == null) statImprintMult = StatImprintMultipliersDefaultAse;
+ if (mutationMult == null) mutationMult = MutationMultipliersDefault;
}
+ ///
+ /// Default values for the stat imprint multipliers in ASE
+ ///
+ private static readonly double[] StatImprintMultipliersDefaultAse = { 0.2, 0, 0.2, 0, 0.2, 0.2, 0, 0.2, 0.2, 0.2, 0, 0 };
+
+ ///
+ /// Default values for the mutated levels multipliers.
+ ///
+ private static readonly float[] MutationMultipliersDefault = { 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f };
+
///
/// Sets the name, descriptive name and variant info.
///
@@ -291,16 +325,17 @@ public void SetCustomImprintingMultipliers(double?[] overrides)
///
/// Returns if the species uses a stat, i.e. it has a base value > 0.
///
- ///
- ///
- public bool UsesStat(int statIndex) => (usedStats & 1 << statIndex) != 0;
+ public bool UsesStat(int statIndex) => (usedStats & (1 << statIndex)) != 0;
///
/// Returns if the species displays a stat ingame in the inventory.
///
- ///
- ///
- public bool DisplaysStat(int statIndex) => (displayedStats & 1 << statIndex) != 0;
+ public bool DisplaysStat(int statIndex) => (displayedStats & (1 << statIndex)) != 0;
+
+ ///
+ /// Returns if a spawned creature can have wild levels in a stat.
+ ///
+ public bool CanLevelupWild(int statIndex) => (skipWildLevelStats & (1 << statIndex)) == 0;
public override string ToString()
{
@@ -356,5 +391,29 @@ public byte[] RandomSpeciesColors(Random rand = null)
return randomColors;
}
+
+ ///
+ /// Override provided properties of the species, e.g. from a mod values file. This is only done if the blueprint path is the same.
+ ///
+ public void LoadOverrides(Species overrides)
+ {
+ if (overrides.name != null) name = overrides.name;
+ if (overrides.variants != null) variants = overrides.variants;
+ if (overrides.fullStatsRaw != null) fullStatsRaw = overrides.fullStatsRaw;
+ if (overrides.altBaseStatsRaw != null) altBaseStatsRaw = overrides.altBaseStatsRaw;
+ if (overrides.displayedStats != 0) displayedStats = overrides.displayedStats;
+ if (overrides.skipWildLevelStats != 0) skipWildLevelStats = overrides.skipWildLevelStats;
+ if (overrides.TamedBaseHealthMultiplier != null) TamedBaseHealthMultiplier = overrides.TamedBaseHealthMultiplier;
+ if (overrides.statImprintMult != null) statImprintMult = overrides.statImprintMult;
+ if (overrides.mutationMult != null) mutationMult = overrides.mutationMult;
+ if (overrides.colors != null) colors = overrides.colors;
+ if (overrides.taming != null) taming = overrides.taming;
+ if (overrides.breeding != null) breeding = overrides.breeding;
+ if (overrides.boneDamageAdjusters != null) boneDamageAdjusters = overrides.boneDamageAdjusters;
+ if (overrides.immobilizedBy != null) immobilizedBy = overrides.immobilizedBy;
+ if (overrides.statNames != null) statNames = overrides.statNames;
+
+ Initialize(new StreamingContext());
+ }
}
}
diff --git a/ARKBreedingStats/testCases/ExtractionTestCase.cs b/ARKBreedingStats/testCases/ExtractionTestCase.cs
index 650fd8fb..a2917334 100644
--- a/ARKBreedingStats/testCases/ExtractionTestCase.cs
+++ b/ARKBreedingStats/testCases/ExtractionTestCase.cs
@@ -16,6 +16,7 @@ public class ExtractionTestCase
public double[] statValues;
public int[] levelsWild;
public int[] levelsDom;
+ public int[] levelsMut;
public bool postTamed;
public bool bred;
public double tamingEff;
diff --git a/ARKBreedingStats/testCases/TestCaseControl.cs b/ARKBreedingStats/testCases/TestCaseControl.cs
index 6d2894f8..b8840578 100644
--- a/ARKBreedingStats/testCases/TestCaseControl.cs
+++ b/ARKBreedingStats/testCases/TestCaseControl.cs
@@ -10,7 +10,7 @@ namespace ARKBreedingStats.testCases
public partial class TestCaseControl : UserControl
{
public delegate void CopyTestToExtractorEventHandler(string speciesBp, int level, double[] statValues, bool postTamed, bool bred, double imprintingBonus, bool gotoExtractor, TestCaseControl tcc);
- public delegate void CopyTestToTesterEventHandler(string speciesBp, int[] wildLevels, int[] domLevels, bool postTamed, bool bred, double te, double imprintingBonus, bool gotoTester, TestCaseControl tcc);
+ public delegate void CopyTestToTesterEventHandler(string speciesBp, int[] wildLevels, int[] domLevels, int[] mutLevels, bool postTamed, bool bred, double te, double imprintingBonus, bool gotoTester, TestCaseControl tcc);
public delegate void RemoveTestCaseEventHandler(TestCaseControl tcc);
public event CopyTestToExtractorEventHandler CopyToExtractor;
public event CopyTestToTesterEventHandler CopyToTester;
@@ -48,7 +48,7 @@ private void bt2Ex_Click(object sender, EventArgs e)
private void bt2Te_Click(object sender, EventArgs e)
{
- CopyToTester?.Invoke(TestCase.speciesBlueprintPath, TestCase.levelsWild, TestCase.levelsDom, TestCase.postTamed, TestCase.bred, TestCase.tamingEff, TestCase.imprintingBonus, true, this);
+ CopyToTester?.Invoke(TestCase.speciesBlueprintPath, TestCase.levelsWild, TestCase.levelsDom, TestCase.levelsMut, TestCase.postTamed, TestCase.bred, TestCase.tamingEff, TestCase.imprintingBonus, true, this);
}
private void btRunTest_Click(object sender, EventArgs e)
diff --git a/ARKBreedingStats/uiControls/StatIO.cs b/ARKBreedingStats/uiControls/StatIO.cs
index 570b02bf..2be93465 100644
--- a/ARKBreedingStats/uiControls/StatIO.cs
+++ b/ARKBreedingStats/uiControls/StatIO.cs
@@ -94,6 +94,20 @@ public int LevelDom
}
}
+ public int LevelMut
+ {
+ get => 0;
+ set { }
+ // TODO
+ //get => (short)numLvM.Value;
+ //set
+ //{
+ // labelMutLevel.Text = value.ToString();
+ // labelMutLevel.ForeColor = value == 0 ? Color.Gray : Color.Black;
+ // numLvM.Value = value;
+ //}
+ }
+
public double BreedingValue
{
get => _breedingValue;
diff --git a/ARKBreedingStats/utils/ExportFolderLocation.cs b/ARKBreedingStats/utils/ExportFolderLocation.cs
index 3fd64a2d..3fd645ed 100644
--- a/ARKBreedingStats/utils/ExportFolderLocation.cs
+++ b/ARKBreedingStats/utils/ExportFolderLocation.cs
@@ -47,21 +47,28 @@ private static bool ExtractSteamExportLocations(out (string path, string launche
}
var configFilePath = Path.Combine(steamPath, "config", "config.vdf");
+ var libraryFoldersFilePath = Path.Combine(steamPath, "config", "libraryfolders.vdf");
if (!File.Exists(configFilePath))
{
error = $"Steam config file {configFilePath} not found.";
return false;
}
- if (!ReadSteamPlayerIdsAndArkInstallPaths(configFilePath,
+ if (!ReadSteamPlayerIdsAndArkInstallPaths(configFilePath, libraryFoldersFilePath,
out (string steamPlayerName, string steamPlayerId)[] steamNamesIds, out string[] arkInstallFolders,
out error)) return false;
- var relativeArkPath = Path.Combine("steamapps", "common", "ARK");
- var possibleArkPaths = new List { Path.Combine(steamPath, relativeArkPath) };
- possibleArkPaths.AddRange(arkInstallFolders.Select(f => Path.Combine(f, relativeArkPath)));
+ var relativeAsePath = Path.Combine("steamapps", "common", "ARK");
+ var relativeAsaPath = Path.Combine("steamapps", "common", "ARK Survival Ascended");
+ var possibleArkPaths = new List<(string Path, Ark.Game Game)>
+ {
+ (Path.Combine(steamPath, relativeAsePath), Ark.Game.ASE),
+ (Path.Combine(steamPath, relativeAsaPath), Ark.Game.ASA)
+ }; // use steam folder as default
+ possibleArkPaths.AddRange(arkInstallFolders.Select(f => (Path.Combine(f, relativeAsePath), Ase: Ark.Game.ASE)));
+ possibleArkPaths.AddRange(arkInstallFolders.Select(f => (Path.Combine(f, relativeAsaPath), Asa: Ark.Game.ASA)));
- var existingArkPaths = possibleArkPaths.Where(Directory.Exists).ToArray();
+ var existingArkPaths = possibleArkPaths.Distinct().Where(p => Directory.Exists(p.Path)).ToArray();
if (!existingArkPaths.Any())
{
@@ -72,13 +79,20 @@ private static bool ExtractSteamExportLocations(out (string path, string launche
var relativeExportFolder = RelativeExportFolder();
// there can be multiple steam users, so list the possible export folder for each user
- exportFolders = new (string, string)[existingArkPaths.Length * steamNamesIds.Length];
+ exportFolders = new (string, string)[existingArkPaths.Length * (steamNamesIds.Length + 1)];
int i = 0;
foreach (var arkPath in existingArkPaths)
{
foreach (var steamNameId in steamNamesIds)
- exportFolders[i++] = (Path.Combine(arkPath, relativeExportFolder, steamNameId.steamPlayerId),
- steamNameId.steamPlayerName);
+ exportFolders[i++] = (
+ arkPath.Game == Ark.Game.ASE
+ ? Path.Combine(arkPath.Path, relativeExportFolder, steamNameId.steamPlayerId)
+ : Path.Combine(arkPath.Path, relativeExportFolder), // ASA doesn't use steam id as subfolder
+ $"{steamNameId.steamPlayerName} ({arkPath.Game})"
+ );
+ // for export gun mod
+ exportFolders[i++] = (Path.Combine(arkPath.Path, relativeExportFolder, "ASB"),
+ $"ExportGun ({arkPath.Game})");
}
return true;
@@ -141,7 +155,7 @@ private static bool GetSteamInstallationPath(out string steamPath)
///
/// Reads the steam config file (config.vdf) and returns a list of player ids and Ark install locations.
///
- private static bool ReadSteamPlayerIdsAndArkInstallPaths(string steamConfigFilePath, out (string steamPlayerName, string steamPlayerId)[] steamPlayerIds,
+ private static bool ReadSteamPlayerIdsAndArkInstallPaths(string steamConfigFilePath, string steamLibraryFoldersFilePath, out (string steamPlayerName, string steamPlayerId)[] steamPlayerIds,
out string[] arkInstallPaths, out string error)
{
steamPlayerIds = null;
@@ -174,12 +188,21 @@ private static bool ReadSteamPlayerIdsAndArkInstallPaths(string steamConfigFileP
steamPlayerIds = (from Match mi in mm select (mi.Groups[1].Value, mi.Groups[2].Value)).ToArray();
- // steam library locations
+ // steam library locations. TODO maybe not existing anymore and only in libraryfolders.vdf
var libraryRegEx = new Regex(@"""BaseInstallFolder_\d+""\s*""([^""]+)""");
mm = libraryRegEx.Matches(configFileContent);
var removeEscapeBackslashes = new Regex(@"\\(.)");
arkInstallPaths = (from Match mi in mm select removeEscapeBackslashes.Replace(mi.Groups[1].Value, "$1")).ToArray();
+ // using libraryfolders.vdf
+ if (!string.IsNullOrEmpty(steamLibraryFoldersFilePath) && File.Exists(steamLibraryFoldersFilePath))
+ {
+ var pathRegex = new Regex(@"""path""\s*""([^""]+)""");
+ mm = pathRegex.Matches(File.ReadAllText(steamLibraryFoldersFilePath));
+ if (mm.Count > 0)
+ arkInstallPaths = arkInstallPaths.Concat(from Match mi in mm select removeEscapeBackslashes.Replace(mi.Groups[1].Value, "$1")).ToArray();
+ }
+
bool anyPlayerIds = steamPlayerIds.Any();
if (!anyPlayerIds)
error = "No steam accounts in the steam config file found.";
diff --git a/ARKBreedingStats/values/Values.cs b/ARKBreedingStats/values/Values.cs
index 775f24c2..3de0e5cb 100644
--- a/ARKBreedingStats/values/Values.cs
+++ b/ARKBreedingStats/values/Values.cs
@@ -230,20 +230,26 @@ public bool LoadModValues(IEnumerable modFilesToLoad, bool throwExceptio
{
if (string.IsNullOrWhiteSpace(sp.blueprintPath)) continue;
- if (blueprintPathDuplicateChecking.TryGetValue(sp.blueprintPath, out var originalSpecies))
- _V.species.Remove(originalSpecies);
- blueprintPathDuplicateChecking[sp.blueprintPath] = sp;
-
- _V.species.Add(sp);
- sp.Mod = modValues.mod;
speciesAddedCount++;
+
+ if (blueprintPathDuplicateChecking.TryGetValue(sp.blueprintPath, out var originalSpecies))
+ {
+ originalSpecies.LoadOverrides(sp);
+ originalSpecies.Mod = modValues.mod;
+ }
+ else
+ {
+ blueprintPathDuplicateChecking[sp.blueprintPath] = sp;
+ _V.species.Add(sp);
+ sp.Mod = modValues.mod;
+ }
}
}
// mod colors (even if the mod doesn't add colors, the order of colors can change)
if (!modValues.mod.expansion)
{
- Colors.AddModArkColors(modValues.ArkColorsDyesParsed);
+ Colors.AddModArkColors((modValues.ArkColorsDyesParsed, modValues.dyeStartIndex));
colorsAdded = true;
}
@@ -490,6 +496,7 @@ public void ApplyMultipliers(CreatureCollection cc, bool eventMultipliers = fals
currentServerMultipliers.FixZeroValues();
double[] defaultMultipliers = new double[] { 1, 1, 1, 1 }; // used if serverMultipliers don't specify non-default values
+ var useAsa = cc.Game == Ark.Asa;
foreach (Species sp in species)
{
@@ -541,6 +548,8 @@ public void ApplyMultipliers(CreatureCollection cc, bool eventMultipliers = fals
sp.altStats[s].IncPerWildLevel = altFactor * sp.stats[s].IncPerWildLevel;
}
+ // single player adjustments if set and available
+
if (singlePlayerServerMultipliers?.statMultipliers?[s] == null)
continue;
@@ -571,7 +580,19 @@ double GetRawStatValue(int statIndex, int statValueTypeIndex, bool customOverrid
}
// imprinting multiplier override
- sp.SetCustomImprintingMultipliers(customOverrideExists && cc.CustomSpeciesStats[sp.blueprintPath].Length > Stats.StatsCount ? cc.CustomSpeciesStats[sp.blueprintPath][Stats.StatsCount] : null);
+ var imprintingMultiplierOverrides =
+ customOverrideExists && cc.CustomSpeciesStats[sp.blueprintPath].Length > Stats.StatsCount
+ ? cc.CustomSpeciesStats[sp.blueprintPath][Stats.StatsCount]
+ : null;
+
+ // adjustments for ASA (0 for speed)
+ if (imprintingMultiplierOverrides == null && useAsa)
+ {
+ imprintingMultiplierOverrides = sp.StatImprintMultipliers.Select(d => (double?)d).ToArray();
+ imprintingMultiplierOverrides[Stats.SpeedMultiplier] = 0;
+ }
+
+ sp.SetCustomImprintingMultipliers(imprintingMultiplierOverrides);
// ATLAS multipliers
diff --git a/ARKBreedingStats/values/ValuesFile.cs b/ARKBreedingStats/values/ValuesFile.cs
index 82054992..f0af3def 100644
--- a/ARKBreedingStats/values/ValuesFile.cs
+++ b/ARKBreedingStats/values/ValuesFile.cs
@@ -16,10 +16,10 @@ public class ValuesFile
///
protected static bool IsValidFormatVersion(string version) =>
version != null
- && (
- version == "1.12" // format with 12 stats (minimum required format)
+ && (version == "1.12" // format with 12 stats (minimum required format)
|| version == "1.13" // introduced remaps for blueprintPaths
|| version == "1.14-flyerspeed" // introduced isFlyer property for AllowFlyerSpeedLeveling
+ || version == "1.15-asa" // for new properties in ARK: Survival Ascended
);
[JsonProperty]
@@ -32,10 +32,19 @@ protected static bool IsValidFormatVersion(string version) =>
public Version Version;
[JsonProperty]
public List species;
+
+ ///
+ /// If not zero it indicates the values file contains new dye definitions that should overwrite the existing base definitions.
+ ///
+ [JsonProperty]
+ public int dyeStartIndex;
+
[JsonProperty("colorDefinitions")]
private object[][] _colorDefinitions;
+
[JsonProperty("dyeDefinitions")]
private object[][] _dyeDefinitions;
+
internal List ArkColorsDyesParsed;
///