public MultiSetter(Creature creatureSettings, List<bool> appliedSettings, List<Creature>[] parents) { InitializeComponent(); if (appliedSettings.Count != 13) { DialogResult = DialogResult.Cancel; // invalid parameters } this.appliedSettings = appliedSettings; this.c = creatureSettings; parentComboBoxMother.naLabel = " - Mother n/a"; parentComboBoxFather.naLabel = " - Father n/a"; if (parents == null) { // disable parents, probably multiple species selected checkBoxMother.Enabled = false; checkBoxFather.Enabled = false; parentComboBoxMother.Enabled = false; parentComboBoxFather.Enabled = false; } else { parentComboBoxMother.ParentList = parents[0]; parentComboBoxFather.ParentList = parents[1]; uniqueSpecies = true; } checkBoxMother.Checked = false; checkBoxFather.Checked = false; pictureBox1.Image = CreatureColored.getColoredCreature(c.colors, (uniqueSpecies ? c.species : ""), new bool[] { true, true, true, true, true, true }); }
public PedigreeCreature(Creature creature, bool[] enabledColorRegions, int comboId = -1) { InitC(); this.Cursor = Cursors.Hand; this.enabledColorRegions = enabledColorRegions; this.comboId = comboId; setCreature(creature); }
public void Clear() { creature = null; ClearControls(); noCreatureSelected(); }
private bool createParentsChild(Creature creature, int x, int y, bool drawWithNoParents = false, bool highlightCreature = false) { if (creature != null && (drawWithNoParents || creature.Mother != null || creature.Father != null)) { // scrolloffset for control-locations (not for lines) int xS = AutoScrollPosition.X; int yS = AutoScrollPosition.Y; // creature PedigreeCreature pc = new PedigreeCreature(creature, enabledColorRegions); if (highlightCreature) pc.highlight = true; pc.Location = new Point(x + xS, y + yS + 40); Controls.Add(pc); pc.CreatureClicked += new PedigreeCreature.CreatureChangedEventHandler(CreatureClicked); pc.CreatureEdit += new PedigreeCreature.CreatureEditEventHandler(CreatureEdit); pc.BestBreedingPartners += new PedigreeCreature.CreaturePartnerEventHandler(BestBreedingPartners); pcs.Add(pc); // mother if (creature.Mother != null) { pc = new PedigreeCreature(creature.Mother, enabledColorRegions); pc.Location = new Point(x + xS, y + yS); Controls.Add(pc); pc.CreatureClicked += new PedigreeCreature.CreatureChangedEventHandler(CreatureClicked); pc.CreatureEdit += new PedigreeCreature.CreatureEditEventHandler(CreatureEdit); pc.BestBreedingPartners += new PedigreeCreature.CreaturePartnerEventHandler(BestBreedingPartners); pcs.Add(pc); } // father if (creature.Father != null) { pc = new PedigreeCreature(creature.Father, enabledColorRegions); pc.Location = new Point(x + xS, y + yS + 80); Controls.Add(pc); pc.CreatureClicked += new PedigreeCreature.CreatureChangedEventHandler(CreatureClicked); pc.CreatureEdit += new PedigreeCreature.CreatureEditEventHandler(CreatureEdit); pc.BestBreedingPartners += new PedigreeCreature.CreaturePartnerEventHandler(BestBreedingPartners); pcs.Add(pc); } // gene-inheritance-lines // better: if father < mother: 1, if mother < father: -1 int better; for (int s = 0; s < 7; s++) { better = 0; if (creature.Mother != null && creature.Father != null) { if (creature.Mother.levelsWild[s] < creature.Father.levelsWild[s]) better = -1; else if (creature.Mother.levelsWild[s] > creature.Father.levelsWild[s]) better = 1; } if (creature.Mother != null && creature.levelsWild[s] >= 0 && creature.levelsWild[s] == creature.Mother.levelsWild[s]) { lines[0].Add(new int[] { 38 + x + 28 * s, y + 33, 38 + x + 28 * s, y + 42, (better == -1 ? 1 : 2) }); } if (creature.Father != null && creature.levelsWild[s] >= 0 && creature.levelsWild[s] == creature.Father.levelsWild[s]) { lines[0].Add(new int[] { 38 + x + 28 * s, y + 83, 38 + x + 28 * s, y + 74, (better == 1 ? 1 : 2) }); } } return true; } return false; }
private ListViewItem createCreatureLVItem(Creature cr, ListViewGroup g) { int topStatsCount = cr.topStatsCount; string[] subItems = (new string[] { cr.name + (cr.status != CreatureStatus.Available ? " (" + Utils.statusSymbol(cr.status) + ")" : ""), cr.owner, Utils.genderSymbol(cr.gender), cr.domesticatedAt.ToString("yyyy'-'MM'-'dd HH':'mm"), cr.topness.ToString(), topStatsCount.ToString(), cr.generation.ToString(), cr.levelFound.ToString() }).Concat(cr.levelsWild.Select(x => x.ToString()).ToArray()).ToArray(); ListViewItem lvi = new ListViewItem(subItems, g); for (int s = 0; s < 8; s++) { // color unknown levels if (cr.levelsWild[s] < 0) { lvi.SubItems[s + 8].ForeColor = Color.WhiteSmoke; lvi.SubItems[s + 8].BackColor = Color.WhiteSmoke; } else lvi.SubItems[s + 8].BackColor = Utils.getColorFromPercent((int)(cr.levelsWild[s] * (s == 7 ? .357 : 2.5)), (considerStatHighlight[s] ? (cr.topBreedingStats[s] ? 0.2 : 0.7) : 0.93)); } lvi.SubItems[2].BackColor = cr.neutered ? SystemColors.GrayText : (cr.gender == Gender.Female ? Color.FromArgb(255, 230, 255) : (cr.gender == Gender.Male ? Color.FromArgb(220, 235, 255) : SystemColors.Window)); if (cr.status == CreatureStatus.Dead) { lvi.SubItems[0].ForeColor = SystemColors.GrayText; lvi.BackColor = Color.FromArgb(255, 250, 240); } if (cr.status == CreatureStatus.Unavailable) { lvi.SubItems[0].ForeColor = SystemColors.GrayText; } lvi.UseItemStyleForSubItems = false; // color for top-stats-nr if (topStatsCount > 0) { if (cr.topBreedingCreature) lvi.BackColor = Color.LightGreen; lvi.SubItems[5].BackColor = Utils.getColorFromPercent(topStatsCount * 8 + 44, 0.7); } else { lvi.SubItems[5].ForeColor = Color.LightGray; } // color for timestamp added if (cr.domesticatedAt.Year < 2015) { lvi.SubItems[3].Text = "n/a"; lvi.SubItems[3].ForeColor = Color.LightGray; } // color for topness lvi.SubItems[4].BackColor = Utils.getColorFromPercent(cr.topness * 2 - 100, 0.8); // topness is in percent. gradient from 50-100 // color for generation if (cr.generation == 0) lvi.SubItems[6].ForeColor = Color.LightGray; // color of WildLevelColumn if (cr.levelFound == 0) lvi.SubItems[7].ForeColor = Color.LightGray; lvi.Tag = cr; return lvi; }
private void setTesterEditCreature(Creature c = null, bool virtualCreature = false) { bool enable = (c != null); // set to a creature, or clear creatureInfoInputTester.ShowSaveButton = enable && !virtualCreature; labelCurrentTesterCreature.Text = (enable ? "Current Creature: " + c.name : ""); if (enable) { creatureInfoInputTester.mother = c.Mother; creatureInfoInputTester.father = c.Father; creatureInfoInputTester.CreatureName = c.name; creatureInfoInputTester.CreatureGender = c.gender; creatureInfoInputTester.CreatureOwner = c.owner; creatureInfoInputTester.CreatureStatus = c.status; creatureInfoInputTester.CreatureNote = c.note; creatureInfoInputTester.Cooldown = c.cooldownUntil; creatureInfoInputTester.Grown = c.growingUntil; creatureInfoInputTester.domesticatedAt = c.domesticatedAt; creatureInfoInputTester.Neutered = c.neutered; updateParentListInput(creatureInfoInputTester); } else { creatureInfoInputTester.mother = null; creatureInfoInputTester.father = null; creatureInfoInputTester.CreatureName = ""; creatureInfoInputTester.CreatureGender = Gender.Unknown; creatureInfoInputTester.CreatureStatus = CreatureStatus.Available; creatureInfoInputTester.Cooldown = DateTime.Now.AddHours(-1); creatureInfoInputTester.Grown = DateTime.Now.AddHours(-1); creatureInfoInputTester.domesticatedAt = DateTime.Now; creatureInfoInputTester.Neutered = false; } creatureTesterEdit = c; }
/// <summary> /// Call this function to update the displayed values of a creature. Usually called after a creature was edited. /// </summary> /// <param name="sender"></param> /// <param name="cr">Creature that was changed</param> /// <param name="creatureStatusChanged"></param> private void updateCreatureValues(Creature cr, bool creatureStatusChanged) { // data of the selected creature changed, update listview recalculateCreatureValues(cr); // if creaturestatus (available/dead) changed, recalculate topstats (dead creatures are not considered there) if (creatureStatusChanged) { calculateTopStats(creatureCollection.creatures.Where(c => c.species == cr.species).ToList()); filterLib(); } else { // int listViewLibrary replace old row with new one int ci = -1; for (int i = 0; i < listViewLibrary.Items.Count; i++) { if ((Creature)listViewLibrary.Items[i].Tag == cr) { ci = i; break; } } if (ci >= 0) listViewLibrary.Items[ci] = createCreatureLVItem(cr, listViewLibrary.Items[ci].Group); } // recreate ownerlist createOwnerList(); setCollectionChanged(true, cr.species); }
private void CreatureClicked(Creature c, int comboIndex, MouseEventArgs e) { SetCreature(c); }
private void CreatureEdit(Creature c, bool isVirtual) { EditCreature?.Invoke(c, isVirtual); }
public CreatureBox(Creature creature) { initializeVars(); setCreature(creature); }
/// <summary> /// Creates the controls that display a creature and its parents. /// </summary> /// <param name="creature"></param> /// <param name="x"></param> /// <param name="y"></param> /// <param name="drawWithNoParents"></param> /// <param name="highlightCreature"></param> /// <returns></returns> private bool CreateParentsChild(Creature creature, int x, int y, bool drawWithNoParents = false, bool highlightCreature = false) { if (creature == null || (!drawWithNoParents && creature.Mother == null && creature.Father == null)) { return(false); } // scrolloffset for control-locations (not for lines) int xS = AutoScrollPosition.X; int yS = AutoScrollPosition.Y; // creature AddCreatureControl(new PedigreeCreature(creature, enabledColorRegions) { Location = new Point(x + xS, y + yS + 40), Highlight = highlightCreature }); void AddCreatureControl(PedigreeCreature _pc) { splitContainer1.Panel2.Controls.Add(_pc); _pc.CreatureClicked += CreatureClicked; _pc.CreatureEdit += CreatureEdit; _pc.BestBreedingPartners += BestBreedingPartners; _pc.ExportToClipboard += exportToClipboard; pcs.Add(_pc); } // mother if (creature.Mother != null) { AddCreatureControl(new PedigreeCreature(creature.Mother, enabledColorRegions) { Location = new Point(x + xS, y + yS) }); } // father if (creature.Father != null) { AddCreatureControl(new PedigreeCreature(creature.Father, enabledColorRegions) { Location = new Point(x + xS, y + yS + 80) }); } // gene-inheritance-lines // better: if father < mother: 1, if mother < father: -1 for (int s = 0; s < PedigreeCreature.displayedStatsCount; s++) { int si = PedigreeCreature.displayedStats[s]; if (creature.valuesDom[si] <= 0) { continue; // don't display arrows for non used stats } int better = 0; if (creature.Mother != null && creature.Father != null) { if (creature.Mother.levelsWild[si] < creature.Father.levelsWild[si]) { better = -1; } else if (creature.Mother.levelsWild[si] > creature.Father.levelsWild[si]) { better = 1; } } // offspring can have stats that are up to 2 levels higher due to mutations. currently there are no decreasing levels due to mutations if (creature.Mother != null && creature.levelsWild[si] >= 0 && (creature.levelsWild[si] == creature.Mother.levelsWild[si] || creature.levelsWild[si] == creature.Mother.levelsWild[si] + 2)) { lines[0].Add(new[] { 38 + x + 29 * s, y + 33, 38 + x + 29 * s, y + 42, (better == -1 ? 1 : 2), (creature.levelsWild[si] > creature.Mother.levelsWild[si] ? 1 : 0) }); } if (creature.Father != null && creature.levelsWild[si] >= 0 && (creature.levelsWild[si] == creature.Father.levelsWild[si] || creature.levelsWild[si] == creature.Father.levelsWild[si] + 2)) { lines[0].Add(new[] { 38 + x + 29 * s, y + 83, 38 + x + 29 * s, y + 74, (better == 1 ? 1 : 2), (creature.levelsWild[si] > creature.Father.levelsWild[si] ? 1 : 0) }); } } return(true); }
private void initializeVars() { InitializeComponent(); this.creature = null; stats = new StatDisplay[] { statDisplayHP, statDisplaySt, statDisplayOx, statDisplayFo, statDisplayWe, statDisplayDm, statDisplaySp, statDisplayTo }; numUDLevelsDom = new NumericUpDown[] { numericUpDown1, numericUpDown2, numericUpDown3, numericUpDown4, numericUpDown5, numericUpDown6, numericUpDown7 }; stats[0].Title = "HP"; stats[1].Title = "St"; stats[2].Title = "Ox"; stats[3].Title = "Fo"; stats[4].Title = "We"; stats[5].Title = "Dm"; stats[6].Title = "Sp"; stats[7].Title = "To"; stats[5].Percent = true; stats[6].Percent = true; statDisplayTo.ShowBars = false; colorButtons = new Button[] { buttonColor1, buttonColor2, buttonColor3, buttonColor4, buttonColor5, buttonColor6 }; parentComboBoxMother.naLabel = "- Mother n/a"; parentComboBoxFather.naLabel = "- Father n/a"; // tooltips tt.SetToolTip(this.labelHeaderDomLevelSet, "Set the spend domesticated Levels here"); tt.SetToolTip(labelGender, "Gender of the Creature"); tt.SetToolTip(labelStatHeader, "Wild-levels, Domesticated-levels, Value that is inherited, Current Value of the Creature"); tt.SetToolTip(buttonEdit, "Edit"); tt.SetToolTip(labelM, "Mother"); tt.SetToolTip(labelF, "Father"); tt.SetToolTip(textBoxNote, "Note"); tt.SetToolTip(labelParents, "Mother and Father (if bred and choosen)"); tt.SetToolTip(buttonGender, "Gender"); tt.SetToolTip(buttonStatus, "Status: Available, Unavailable, Dead"); cp = new MyColorPicker(); }
public void setCreature(Creature creature) { Clear(); this.creature = creature; int si = Values.V.speciesNames.IndexOf(creature.species); if (si >= 0) colorRegions = Values.V.species[si].colors; else { colorRegions = new List<ColorRegion>(); for (int i = 0; i < 6; i++) { colorRegions.Add(new ColorRegion()); colorRegions[i].name = "n/a"; } } colorRegionUseds = colorRegions.Select(c => c.name != null).ToArray(); updateLabel(); renewLargeImage = true; }
// call this function to clear all contents of this element public void Clear() { parentComboBoxMother.Items.Clear(); parentComboBoxFather.Items.Clear(); parentList = new List<Creature>[2]; closeSettings(false); labelGender.Text = ""; groupBox1.Text = ""; creature = null; for (int s = 0; s < 8; s++) { stats[s].setNumbers(0, 0, 0, 0); } pictureBox1.Visible = false; for (int b = 0; b < 6; b++) colorButtons[b].Visible = false; }
private void CreatureEdit(Creature c, bool isVirtual) { if (EditCreature != null) EditCreature(c, isVirtual); }
public void Clear() { creature = null; ClearControls(); NoCreatureSelected(); }
/// <summary> /// Extracts possible level combinations for the given values. /// </summary> /// <param name="species"></param> /// <param name="level">Total level of the creature.</param> /// <param name="statIOs">Controls that display the stats</param> /// <param name="lowerTEBound">Lowest possible taming effectiveness</param> /// <param name="upperTEBound">Highest possible taming effectiveness</param> /// <param name="tamed"></param> /// <param name="bred"></param> /// <param name="imprintingBonusRounded"></param> /// <param name="adjustImprinting"></param> /// <param name="allowMoreThanHundredImprinting"></param> /// <param name="imprintingBonusMultiplier"></param> /// <param name="cuddleIntervalMultiplier"></param> /// <param name="considerWildLevelSteps"></param> /// <param name="wildLevelSteps"></param> /// <param name="highPrecisionInputs">If true, the input is expected to be a float value from an export file. /// If false, it's assumed to be a displayed value from the game with one decimal digit.</param> /// <param name="imprintingChanged"></param> public void ExtractLevels(Species species, int level, List<StatIO> statIOs, double lowerTEBound, double upperTEBound, bool tamed, bool bred, double imprintingBonusRounded, bool adjustImprinting, bool allowMoreThanHundredImprinting, double imprintingBonusMultiplier, double cuddleIntervalMultiplier, bool considerWildLevelSteps, int wildLevelSteps, bool highPrecisionInputs, out bool imprintingChanged) { List<CreatureStat> stats = species.stats; validResults = true; imprintingChanged = false; considerWildLevelSteps = considerWildLevelSteps && !bred && species.name.Substring(0, 3) != "Tek" && species.name != "Jerboa" ; this.bred = bred; postTamed = bred || tamed; List<MinMaxDouble> imprintingBonusList = new List<MinMaxDouble> { new MinMaxDouble(0) }; if (bred) { if (!adjustImprinting) { imprintingBonusList[0] = new MinMaxDouble(imprintingBonusRounded); } else { imprintingBonusList = CalculateImprintingBonus(species, imprintingBonusRounded, imprintingBonusMultiplier, cuddleIntervalMultiplier, statIOs[(int)StatNames.Torpidity].Input, statIOs[(int)StatNames.Food].Input); } } for (int IBi = 0; IBi < imprintingBonusList.Count; IBi++) { imprintingBonusRange = imprintingBonusList[IBi]; imprintingBonusRange.SetToIntersectionWith(0, (allowMoreThanHundredImprinting ? 5 : 1)); // it's assumed that a valid IB will not be larger than 500% var imprintingMultiplierRanges = new MinMaxDouble[Values.STATS_COUNT]; for (int s = 0; s < Values.STATS_COUNT; s++) { imprintingMultiplierRanges[s] = species.statImprintMult[s] != 0 ? new MinMaxDouble(1 + imprintingBonusRange.Min * imprintingBonusMultiplier * species.statImprintMult[s], 1 + imprintingBonusRange.Max * imprintingBonusMultiplier * species.statImprintMult[s]) : new MinMaxDouble(1); } var levelWildSumRange = new MinMaxInt((int)Math.Round((statIOs[(int)StatNames.Torpidity].Input / imprintingMultiplierRanges[(int)StatNames.Torpidity].Max - (postTamed ? stats[(int)StatNames.Torpidity].AddWhenTamed : 0) - stats[(int)StatNames.Torpidity].BaseValue) / (stats[(int)StatNames.Torpidity].BaseValue * stats[(int)StatNames.Torpidity].IncPerWildLevel)), (int)Math.Round((statIOs[(int)StatNames.Torpidity].Input / imprintingMultiplierRanges[(int)StatNames.Torpidity].Min - (postTamed ? stats[(int)StatNames.Torpidity].AddWhenTamed : 0) - stats[(int)StatNames.Torpidity].BaseValue) / (stats[(int)StatNames.Torpidity].BaseValue * stats[(int)StatNames.Torpidity].IncPerWildLevel))); var levelDomSumRange = new MinMaxInt(Math.Max(0, level - 1 - levelWildSumRange.Max), Math.Max(0, level - 1 - levelWildSumRange.Min)); levelWildSum = levelWildSumRange.Min; levelDomSum = levelDomSumRange.Min; // TODO implement range-mechanic levelsUndeterminedWild = levelWildSum; levelsUndeterminedDom = levelDomSum; if (bred) { // bred creatures always have 100% TE lowerTEBound = 1; upperTEBound = 1; } else { // sometimes it fails due to double-precision errors, e.g. // Pteranodon (Lvl 34, TE: 80%): HP: 415.9 (6, 0); St: 195 (6, 0); Ox: 240 (6, 0); Fo: 2150.4 (6, 0); We: 134.4 (6, 0); Dm: 141.6% (3, 0); Sp: 135% (0, 0); To: 358.1 (33); // will fail the extraction with a lowerTEBound of 0.8, it only extracts with a lowerTEBound of 0.79, then displays 0.8 as result for the TE. Adding these margins make it work as expected. lowerTEBound -= 0.0006; if (lowerTEBound < 0) lowerTEBound = 0; upperTEBound += 0.0006; } // check all possible level-combinations for (int s = 0; s < Values.STATS_COUNT; s++) { if (!species.UsesStat(s)) { results[s].Add(new StatResult(0, 0)); continue; } if (statIOs[s].Input <= 0) // if stat is unknown (e.g. oxygen sometimes is not shown) { results[s].Add(new StatResult(-1, 0)); continue; } statIOs[s].postTame = postTamed; // determine the precision of the input value // ARK displays one decimal digit, so the minimal error of a given number is assumed to be 0.06. // the theoretical value of a maximal error of 0.05 is too low. const float ARKDISPLAYVALUEERROR = 0.06f; // If an export file is used, the full float precision of the stat value is given, the precision is calculated then. // For values > 1e6 the float precision error is larger than 0.06 // always consider at least an error of. When using only the float-precision often the stat-calculations increase the resulting error to be much larger. const float MINVALUEERROR = 0.001f; // the error can increase due to the stat-calculation. Assume a factor of 10 for now, values lower than 6 were too low. const float CALCULATIONERRORFACTOR = 10f; float toleranceForThisStat = highPrecisionInputs || statIOs[s].Input * (Utils.precision(s) == 3 ? 100 : 1) > 1e6 ? Math.Max(MINVALUEERROR, ((float)statIOs[s].Input).FloatPrecision() * CALCULATIONERRORFACTOR) : ARKDISPLAYVALUEERROR * (Utils.precision(s) == 3 ? .01f : 1) ; //Console.WriteLine($"Precision stat {s}: {toleranceForThisStat}"); MinMaxDouble inputValue = new MinMaxDouble(statIOs[s].Input - toleranceForThisStat, statIOs[s].Input + toleranceForThisStat); double statBaseValue = stats[s].BaseValue; if (postTamed && s == (int)StatNames.Health) statBaseValue *= (double)species.TamedBaseHealthMultiplier;// + 0.00000000001; // todo double-precision handling bool withTEff = (postTamed && stats[s].MultAffinity > 0); if (withTEff) { statsWithTE.Add(s); } int minLW = 0; int maxLW; if (stats[s].IncPerWildLevel > 0) { double multAffinityFactor = stats[s].MultAffinity; if (postTamed) { // the multiplicative bonus is only multiplied with the TE if it is positive (i.e. negative boni won't get less bad if the TE is low) if (multAffinityFactor > 0) multAffinityFactor *= lowerTEBound; multAffinityFactor += 1; } else multAffinityFactor = 1; maxLW = (int)Math.Round(((inputValue.Max / multAffinityFactor - (postTamed ? stats[s].AddWhenTamed : 0)) / statBaseValue - 1) / stats[s].IncPerWildLevel); // floor is too unprecise } else { minLW = -1; maxLW = -1; } if (maxLW > levelWildSum) { maxLW = levelWildSum; } double maxLD = 0; if (!statIOs[s].DomLevelLockedZero && postTamed && species.DisplaysStat(s) && stats[s].IncPerTamedLevel > 0) { int ww = 0; // base wild level for the tamed creature needed to be alive if (statBaseValue + stats[s].AddWhenTamed < 0) { // e.g. Griffin // get lowest wild level at which the creature is alive while (StatValueCalculation.CalculateValue(species, s, ww, 0, true, lowerTEBound, 0, false) <= 0) { ww++; } } maxLD = Math.Round((inputValue.Max / ((statBaseValue * (1 + stats[s].IncPerWildLevel * ww) + stats[s].AddWhenTamed) * (1 + lowerTEBound * stats[s].MultAffinity)) - 1) / stats[s].IncPerTamedLevel); //floor is sometimes too low } if (maxLD > levelsUndeterminedDom) maxLD = levelsUndeterminedDom; if (maxLD < 0) maxLD = 0; 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.statImprintMult[s] != 0) statImprintingMultiplierRange = imprintingMultiplierRanges[s].Clone(); // if dom levels have no effect, just calculate the wild level // for flyers (without mods) this means for speed no wild levels at all (i.e. not unknown, but 0) // for the Diplodocus this means 0 wild levels in melee if (stats[s].IncPerTamedLevel == 0) { if (stats[s].IncPerWildLevel == 0) { // check if the input value is valid MinMaxDouble possibleStatValues = new MinMaxDouble(StatValueCalculation.CalculateValue(species, s, 0, 0, postTamed, lowerTEBound, imprintingBonusRange.Min, false), StatValueCalculation.CalculateValue(species, s, 0, 0, postTamed, upperTEBound, imprintingBonusRange.Max, false)); if (inputValue.Overlaps(possibleStatValues)) results[s].Add(new StatResult(0, 0, inputValue.Mean)); } else { MinMaxDouble lwRange = new MinMaxDouble(((inputValue.Min / (postTamed ? 1 + stats[s].MultAffinity : 1) - (postTamed ? stats[s].AddWhenTamed : 0)) / (statBaseValue * statImprintingMultiplierRange.Max) - 1) / stats[s].IncPerWildLevel, ((inputValue.Max / (postTamed ? 1 + stats[s].MultAffinity : 1) - (postTamed ? stats[s].AddWhenTamed : 0)) / (statBaseValue * statImprintingMultiplierRange.Min) - 1) / stats[s].IncPerWildLevel); int lw = (int)Math.Round(lwRange.Mean); if (lwRange.Includes(lw) && lw >= 0 && lw <= maxLW) { results[s].Add(new StatResult(lw, 0, inputValue.Mean)); } } // even if no result was found, there is no other valid continue; } for (int lw = minLW; lw < maxLW + 1; 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), statBaseValue * (1 + stats[s].IncPerWildLevel * lw) * statImprintingMultiplierRange.Max + (postTamed ? stats[s].AddWhenTamed : 0)); // value without domesticated levels if (!withTEff) { // calculate the only possible Ld, if it's an integer, take it. if (stats[s].IncPerTamedLevel > 0) { MinMaxDouble ldRange = new MinMaxDouble((inputValue.Min / (valueWODomRange.Max * (postTamed ? 1 + stats[s].MultAffinity : 1)) - 1) / stats[s].IncPerTamedLevel, (inputValue.Max / (valueWODomRange.Min * (postTamed ? 1 + stats[s].MultAffinity : 1)) - 1) / stats[s].IncPerTamedLevel); int ld = (int)Math.Round(ldRange.Mean); if (ldRange.Includes(ld) && ld >= 0 && ld <= maxLD) { results[s].Add(new StatResult(lw, ld, inputValue.Mean)); } } else { results[s].Add(new StatResult(lw, 0, inputValue.Mean)); } } else { for (int ld = 0; ld <= maxLD; ld++) { // taming bonus is dependant on taming-effectiveness // get tamingEffectiveness-possibility // calculate rounding-error thresholds. Here it's assumed that the displayed ingame value is maximal 0.5 off of the true ingame value MinMaxDouble tamingEffectiveness = new MinMaxDouble((inputValue.Min / (1 + stats[s].IncPerTamedLevel * ld) - valueWODomRange.Max) / (valueWODomRange.Max * stats[s].MultAffinity), (inputValue.Max / (1 + stats[s].IncPerTamedLevel * ld) - valueWODomRange.Min) / (valueWODomRange.Min * stats[s].MultAffinity)); if (tamingEffectiveness.Min > upperTEBound) continue; if (tamingEffectiveness.Max < lowerTEBound) break; // if tamingEff < lowerBound: break, in this d-loop it's getting only smaller // here it's ensured the TE overlaps the bounds, so we can clamp it to the bounds if (tamingEffectiveness.Min < lowerTEBound) tamingEffectiveness.Min = lowerTEBound; if (tamingEffectiveness.Max > upperTEBound) tamingEffectiveness.Max = upperTEBound; if (!bred) { // check if the totalLevel and the TE is possible by using the TE-levelbonus (credits for this check which sorts out more impossible results: https://github.com/VolatilePulse , thanks!) int levelPostTame = levelWildSum + 1; MinMaxInt levelPreTameRange = new MinMaxInt(Creature.CalculatePreTameWildLevel(levelPostTame, tamingEffectiveness.Max), Creature.CalculatePreTameWildLevel(levelPostTame, tamingEffectiveness.Min)); bool impossibleTE = true; for (int wildLevel = levelPreTameRange.Min; wildLevel <= levelPreTameRange.Max; wildLevel++) { MinMaxInt levelPostTameRange = new MinMaxInt((int)Math.Floor(wildLevel * (1 + tamingEffectiveness.Min / 2)), (int)Math.Floor(wildLevel * (1 + tamingEffectiveness.Max / 2))); if (levelPostTameRange.Includes(levelPostTame)) { impossibleTE = false; break; } } if (impossibleTE) continue; // test if TE with torpor-level of tamed-creatures results in a valid wild-level according to the possible levelSteps if (considerWildLevelSteps) { bool validWildLevel = false; for (int wildLevel = levelPreTameRange.Min; wildLevel <= levelPreTameRange.Max; wildLevel++) { if (wildLevel % wildLevelSteps == 0) { validWildLevel = true; break; } } if (!validWildLevel) continue; } // if another stat already is dependant on TE, check if this TE overlaps any of their TE-ranges. If not, TE is not possible (a creature can only have the same TE for all TE-dependant stats) if (statsWithTE.Count > 1) { bool TEExistant = false; for (int er = 0; er < results[statsWithTE[0]].Count; er++) { if (tamingEffectiveness.Overlaps(results[statsWithTE[0]][er].TE)) { TEExistant = true; break; } } if (!TEExistant) continue; } } results[s].Add(new StatResult(lw, ld, inputValue.Mean, tamingEffectiveness)); } } } } if (bred) { // if each stat has at least one result, assume the extraction was valid with the chosen IB if (EveryStatHasAtLeastOneResult) { // all stats have a result, don't test the other possible IBs imprintingChanged = (Math.Abs(imprintingBonusRounded - ImprintingBonus) > 0.01); break; } else if (IBi < imprintingBonusList.Count - 1) { // not all stats got a result, clear results for the next round Clear(); validResults = true; } } } }
private void determineBestBreeding(Creature chosenCreature = null) { string selectedSpecies = (chosenCreature != null ? chosenCreature.species : ""); bool newSpecies = false; if (selectedSpecies.Length == 0 && listViewSpeciesBP.SelectedIndices.Count > 0) selectedSpecies = (string)listViewSpeciesBP.SelectedItems[0].Tag; if (selectedSpecies.Length > 0 && breedingPlan1.currentSpecies != selectedSpecies) { breedingPlan1.currentSpecies = selectedSpecies; breedingPlan1.speciesIndex = Values.V.speciesNames.IndexOf(selectedSpecies); newSpecies = true; int s = Values.V.speciesNames.IndexOf(selectedSpecies); breedingPlan1.EnabledColorRegions = (s >= 0 ? Values.V.species[s].colors.Select(n => n.name != "").ToArray() : new bool[6] { true, true, true, true, true, true }); breedingPlanNeedsUpdate = true; } if (breedingPlanNeedsUpdate) breedingPlan1.Creatures = creatureCollection.creatures.Where(c => c.species == selectedSpecies && c.status == CreatureStatus.Available && !c.neutered && c.cooldownUntil < DateTime.Now && c.growingUntil < DateTime.Now).ToList(); breedingPlan1.statWeights = statWeighting1.Weightings; BreedingPlan.BreedingMode bm = BreedingPlan.BreedingMode.TopStatsConservative; if (radioButtonBPTopStats.Checked) bm = BreedingPlan.BreedingMode.TopStatsLucky; else if (radioButtonBPHighStats.Checked) bm = BreedingPlan.BreedingMode.BestNextGen; breedingPlan1.chosenCreature = chosenCreature; breedingPlan1.drawBestParents(bm, newSpecies); breedingPlanNeedsUpdate = false; }
private void showBestBreedingPartner(Creature c) { if (c.status != CreatureStatus.Available) { if (MessageBox.Show("Selected Creature is currently not marked as \"Available\" and thus cannot be considered for breeding. Do you want to change its status to \"Available\"?", "Selected Creature not Available", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { setStatus(new List<Creature>() { c }, CreatureStatus.Available); } else return; } determineBestBreeding(c); tabControlMain.SelectedTab = tabPageBreedingPlan; }
/// <summary> /// Call this function with a creature c to put all its stats in the levelup-tester (and go to the tester-tab) to see what it could become /// </summary> /// <param name="c">the creature to test</param> /// <param name="virtualCreature">set to true if the creature is not in the library</param> private void editCreatureInTester(Creature c, bool virtualCreature = false) { if (c != null) { cbbStatTestingSpecies.SelectedIndex = Values.V.speciesNames.IndexOf(c.species); NumericUpDownTestingTE.Value = (c.tamingEff >= 0 ? (decimal)c.tamingEff * 100 : 0); numericUpDownImprintingBonusTester.Value = (decimal)c.imprintingBonus * 100; checkBoxStatTestingBred.Checked = c.isBred; for (int s = 0; s < 7; s++) { testingIOs[s].LevelWild = c.levelsWild[s]; testingIOs[s].LevelDom = c.levelsDom[s]; } tabControlMain.SelectedTab = tabPageStatTesting; setTesterEditCreature(c, virtualCreature); } }
private void updateParentListInput(CreatureInfoInput input) { // set possible parents bool fromExtractor = input == creatureInfoInputExtractor; string species = (fromExtractor ? Values.V.speciesNames[sE] : cbbStatTestingSpecies.SelectedItem.ToString()); Creature creature = new Creature(species, "", "", 0, getCurrentWildLevels(fromExtractor)); List<Creature>[] parents = findParents(creature); input.ParentsSimilarities = findParentSimilarities(parents, creature); input.Parents = parents; input.parentListValid = true; }
private List<Creature>[] findParents(Creature creature) { var fatherList = from cr in creatureCollection.creatures where cr.species == creature.species && cr.gender == Gender.Male && cr != creature orderby cr.name ascending select cr; var motherList = from cr in creatureCollection.creatures where cr.species == creature.species && cr.gender == Gender.Female && cr != creature orderby cr.name ascending select cr; // display new results return new List<Creature>[2] { motherList.ToList(), fatherList.ToList() }; }
/// <summary> /// this function is called if the user enters the settings of a creature. Finds the possible parents and saves them in the creatureBox /// </summary> /// <param name="sender"></param> /// <param name="creature"></param> private void creatureBoxListView_FindParents(object sender, Creature creature) { List<Creature>[] parents = findParents(creature); creatureBoxListView.parentListSimilarity = findParentSimilarities(parents, creature); creatureBoxListView.parentList = parents; }
private List<int>[] findParentSimilarities(List<Creature>[] parents, Creature creature) { // similarities (number of equal wildlevels as creature, to find parents easier) int e;// number of equal wildlevels List<int> motherListSimilarities = new List<int>(); List<int> fatherListSimilarities = new List<int>(); List<int>[] parentListSimilarities = new List<int>[2] { motherListSimilarities, fatherListSimilarities }; if (parents[0] != null && parents[1] != null) { for (int ps = 0; ps < 2; ps++) { foreach (Creature c in parents[ps]) { e = 0; for (int s = 0; s < 7; s++) { if (creature.levelsWild[s] >= 0 && creature.levelsWild[s] == c.levelsWild[s]) e++; } parentListSimilarities[ps].Add(e); } // sort parents: put all creatures not available to the end, then the ones with 0 common stats to the end int moved = 0; for (int p = 0; p < parents[ps].Count - moved; p++) { if (parents[ps][p].status != CreatureStatus.Available) { parentListSimilarities[ps].Add(parentListSimilarities[ps][p]); parentListSimilarities[ps].RemoveAt(p); parents[ps].Add(parents[ps][p]); parents[ps].RemoveAt(p); moved++; p--; } } moved = 0; for (int p = 0; p < parents[ps].Count - moved; p++) { if (parentListSimilarities[ps][p] == 0) { parentListSimilarities[ps].Add(parentListSimilarities[ps][p]); parentListSimilarities[ps].RemoveAt(p); parents[ps].Add(parents[ps][p]); parents[ps].RemoveAt(p); moved++; p--; } } } } return parentListSimilarities; }
public void setCreature(Creature centralCreature, bool forceUpdate = false) { if (centralCreature == null) { creature = null; ClearControls(); } else if (creatures != null && (centralCreature != creature || forceUpdate)) { creature = centralCreature; // set children var children = from cr in creatures where cr.motherGuid == creature.guid || cr.fatherGuid == creature.guid orderby cr.name ascending select cr; this.children = children.ToList(); createPedigree(); } }
private void add2Lib(bool fromExtractor = true) { CreatureInfoInput input; bool bred; double te; string species; if (fromExtractor) { input = creatureInfoInputExtractor; species = Values.V.speciesNames[sE]; bred = checkBoxAlreadyBred.Checked; te = Extraction.E.uniqueTE(); } else { input = creatureInfoInputTester; species = Values.V.speciesNames[cbbStatTestingSpecies.SelectedIndex]; bred = checkBoxStatTestingBred.Checked; te = (double)NumericUpDownTestingTE.Value / 100; } Creature creature = new Creature(species, input.CreatureName, input.CreatureOwner, input.CreatureGender, getCurrentWildLevels(fromExtractor), getCurrentDomLevels(fromExtractor), te, bred); // set parents creature.Mother = input.mother; creature.Father = input.father; // cooldown-, growing-time creature.cooldownUntil = input.Cooldown; creature.growingUntil = input.Grown; creature.domesticatedAt = input.domesticatedAt; recalculateCreatureValues(creature); creature.recalculateAncestorGenerations(); creature.guid = Guid.NewGuid(); creatureCollection.creatures.Add(creature); setCollectionChanged(true, species); updateCreatureListings(Values.V.speciesNames.IndexOf(species)); // show only the added creatures' species listBoxSpeciesLib.SelectedIndex = listBoxSpeciesLib.Items.IndexOf(creature.species); tabControlMain.SelectedTab = tabPageLibrary; creatureInfoInputExtractor.parentListValid = false; creatureInfoInputTester.parentListValid = false; }
private void CreatureClicked(Creature c, int comboIndex, MouseEventArgs e) { setCreature(c, false); }
private void multiSetterToolStripMenuItem_Click(object sender, EventArgs e) { // shows a dialog to set multiple settings to all selected creatures if (listViewLibrary.SelectedIndices.Count > 0) { Creature c = new Creature(); List<bool> appliedSettings = new List<bool>(); for (int i = 0; i < 13; i++) appliedSettings.Add(false); List<Creature> selectedCreatures = new List<Creature>(); // check if multiple species are selected bool multipleSpecies = false; string sp = ((Creature)listViewLibrary.SelectedItems[0].Tag).species; c.species = sp; foreach (ListViewItem i in listViewLibrary.SelectedItems) { selectedCreatures.Add((Creature)i.Tag); if (((Creature)i.Tag).species != sp) { multipleSpecies = true; } } List<Creature>[] parents = null; if (!multipleSpecies) parents = findParents(c); MultiSetter ms = new MultiSetter(c, appliedSettings, parents); if (ms.ShowDialog() == DialogResult.OK) { foreach (Creature sc in selectedCreatures) { if (appliedSettings[0]) sc.owner = c.owner; if (appliedSettings[1]) sc.status = c.status; if (appliedSettings[2]) sc.gender = c.gender; if (appliedSettings[3]) sc.isBred = c.isBred; if (appliedSettings[4]) sc.motherGuid = c.motherGuid; if (appliedSettings[5]) sc.fatherGuid = c.fatherGuid; if (appliedSettings[6]) sc.note = c.note; if (appliedSettings[7]) sc.colors[0] = c.colors[0]; if (appliedSettings[8]) sc.colors[1] = c.colors[1]; if (appliedSettings[9]) sc.colors[2] = c.colors[2]; if (appliedSettings[10]) sc.colors[3] = c.colors[3]; if (appliedSettings[11]) sc.colors[4] = c.colors[4]; if (appliedSettings[12]) sc.colors[5] = c.colors[5]; } if (appliedSettings[4] || appliedSettings[5]) updateParents(selectedCreatures); createOwnerList(); setCollectionChanged(true, (!multipleSpecies ? sp : null)); filterLib(); } ms.Dispose(); } }
public void setCreature(Creature creature) { this.creature = creature; groupBox1.Text = (!onlyLevels && creature.status != CreatureStatus.Available ? "(" + Utils.statusSymbol(creature.status) + ") " : "") + creature.name; if (!onlyLevels && creature.status == CreatureStatus.Dead) { groupBox1.ForeColor = SystemColors.GrayText; tt.SetToolTip(groupBox1, "Creature has passed away"); } else if (!onlyLevels && creature.status == CreatureStatus.Unavailable) { groupBox1.ForeColor = SystemColors.GrayText; tt.SetToolTip(groupBox1, "Creature is currently not available"); } for (int s = 0; s < 7; s++) { if (creature.levelsWild[s] < 0) { labels[s].Text = "?"; labels[s].BackColor = Color.WhiteSmoke; labels[s].ForeColor = Color.LightGray; } else { labels[s].Text = creature.levelsWild[s].ToString(); labels[s].BackColor = Utils.getColorFromPercent((int)(creature.levelsWild[s] * 2.5), (creature.topBreedingStats[s] ? 0.2 : 0.7)); labels[s].ForeColor = SystemColors.ControlText; tt.SetToolTip(labels[s], Utils.statName(s) + ": " + (creature.valuesBreeding[s] * (Utils.precision(s) == 3 ? 100 : 1)).ToString() + (Utils.precision(s) == 3 ? "%" : "")); } labels[s].Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, (creature.topBreedingStats[s] ? System.Drawing.FontStyle.Bold : System.Drawing.FontStyle.Regular), System.Drawing.GraphicsUnit.Point, ((byte)(0))); } if (onlyLevels) { labelGender.Visible = false; pictureBox1.Visible = false; } else { labelGender.Visible = true; labelGender.Text = Utils.genderSymbol(creature.gender); labelGender.BackColor = Utils.genderColor(creature.gender); // creature Colors pictureBox1.Image = CreatureColored.getColoredCreature(creature.colors, "", enabledColorRegions, 24, 22, true); labelGender.Visible = true; pictureBox1.Visible = true; } }
/// <summary> /// call this function to recalculate all stat-values of Creature c according to its levels /// </summary> private void recalculateCreatureValues(Creature c) { int speciesIndex = Values.V.speciesNames.IndexOf(c.species); if (speciesIndex >= 0) { for (int s = 0; s < 8; s++) { c.valuesBreeding[s] = Stats.calculateValue(speciesIndex, s, c.levelsWild[s], 0, true, 1, 0); c.valuesDom[s] = Stats.calculateValue(speciesIndex, s, c.levelsWild[s], c.levelsDom[s], true, c.tamingEff, c.imprintingBonus); } } c.calculateLevelFound(); }
private void CreatureClicked(Creature c, int comboIndex, MouseEventArgs e) { if (comboIndex >= 0) setParents(comboIndex); }
private void setCreatureValuesToExtractor(Creature c, bool onlyWild = false) { if (c != null) { int speciesIndex = Values.V.speciesNames.IndexOf(c.species); if (speciesIndex >= 0) { // copy values over to extractor for (int s = 0; s < 8; s++) statIOs[s].Input = (onlyWild ? Stats.calculateValue(speciesIndex, s, c.levelsWild[s], 0, true, c.tamingEff, c.imprintingBonus) : c.valuesDom[s]); comboBoxSpeciesExtractor.SelectedIndex = speciesIndex; checkBoxAlreadyBred.Checked = c.isBred; numericUpDownImprintingBonusExtractor.Value = (decimal)c.imprintingBonus * 100; // set total level int level = (onlyWild ? c.levelsWild[7] : c.level); if (level >= 0 && level <= numericUpDownLevel.Maximum) numericUpDownLevel.Value = level; else numericUpDownLevel.Value = 0; tabControlMain.SelectedTab = tabPageExtractor; } else MessageBox.Show("Unknown Species. Try to update the species-stats, or redownload the tool.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
private void setParents(int comboIndex) { if (comboIndex < 0 || comboIndex > combinedTops[0].Count) { pedigreeCreatureBest.Clear(); pedigreeCreatureWorst.Clear(); labelInfo.Visible = false; labelProbabilityBest.Text = ""; return; } Creature crB = new Creature(currentSpecies, "", "", 0, new int[8], null, 100, true); Creature crW = new Creature(currentSpecies, "", "", 0, new int[8], null, 100, true); Creature mother = females[combinedTops[0][comboIndex]]; Creature father = males[combinedTops[1][comboIndex]]; crB.Mother = mother; crB.Father = father; crW.Mother = mother; crW.Father = father; double probabilityBest = 1; bool totalLevelUnknown = false; // if stats are unknown, total level is as well (==> oxygen, speed) for (int s = 0; s < 7; s++) { crB.levelsWild[s] = Math.Max(mother.levelsWild[s], father.levelsWild[s]); crB.valuesBreeding[s] = Stats.calculateValue(speciesIndex, s, crB.levelsWild[s], 0, true, 1, 0); crB.topBreedingStats[s] = (crB.levelsWild[s] == bestLevels[s]); crW.levelsWild[s] = Math.Min(mother.levelsWild[s], father.levelsWild[s]); crW.valuesBreeding[s] = Stats.calculateValue(speciesIndex, s, crW.levelsWild[s], 0, true, 1, 0); crW.topBreedingStats[s] = (crW.levelsWild[s] == bestLevels[s]); if (crB.levelsWild[s] == -1 || crW.levelsWild[s] == -1) totalLevelUnknown = true; if (crB.levelsWild[s] > crW.levelsWild[s]) probabilityBest *= .7; } crB.levelsWild[7] = crB.levelsWild.Sum(); crW.levelsWild[7] = crW.levelsWild.Sum(); crB.name = "Best Possible (" + crB.levelHatched + (totalLevelUnknown ? "+" : "") + ")"; crW.name = "Worst Possible (" + crW.levelHatched + (totalLevelUnknown ? "+" : "") + ")"; pedigreeCreatureBest.setCreature(crB); pedigreeCreatureWorst.setCreature(crW); labelProbabilityBest.Text = "Probability for this Best Possible outcome: " + Math.Round(100 * probabilityBest, 1).ToString() + "%"; // highlight parents int hiliId = comboOrder.IndexOf(comboIndex) * 2; for (int i = 0; i < pcs.Count; i++) pcs[i].highlight = (i == hiliId || i == hiliId + 1); }