public double uniqueTE() { double eff = -2; if (statsWithTE.Count > 0 && results[statsWithTE[0]].Count > chosenResults[statsWithTE[0]]) { for (int s = 0; s < statsWithTE.Count; s++) { for (int ss = s + 1; ss < statsWithTE.Count; ss++) { // effectiveness-calculation can be a bit off due to ingame-rounding if (results[statsWithTE[ss]].Count <= chosenResults[statsWithTE[ss]] || !MinMaxDouble.Overlaps(results[statsWithTE[s]][chosenResults[statsWithTE[s]]].TE, results[statsWithTE[ss]][chosenResults[statsWithTE[ss]]].TE)) { lastTEUnique = false; return(-1); // no unique TE } } } // calculate most probable real TE // get intersection of all TE-ranges MinMaxDouble te = new MinMaxDouble(-1); te = results[statsWithTE[0]][chosenResults[statsWithTE[0]]].TE.Clone(); for (int s = 1; s < statsWithTE.Count; s++) { // the overlap is ensured at this point te.SetToInsersectionWith(results[statsWithTE[s]][chosenResults[statsWithTE[s]]].TE); } eff = te.Mean; } lastTEUnique = eff >= 0; return(eff); }
private List <double> CalculateImprintingBonus(double imprintingBonusRounded, double imprintingBonusMultiplier, double cuddleIntervalMultiplier, List <CreatureStat> stats, int speciesIndex, double torpor, double food) { // classic way to calculate the ImprintingBonus, this is the most exact value, but will not work if the imprinting-gain was different (e.g. events, mods (S+Nanny)) double imprintingBonusFromGainPerCuddle = 0; if (Values.V.species[speciesIndex].breeding != null) { double imprintingGainPerCuddle = Utils.imprintingGainPerCuddle(Values.V.species[speciesIndex].breeding.maturationTimeAdjusted, cuddleIntervalMultiplier); imprintingBonusFromGainPerCuddle = Math.Round(imprintingBonusRounded / imprintingGainPerCuddle) * imprintingGainPerCuddle; } MinMaxInt wildLevelsFromImprintedTorpor = new MinMaxInt( (int)Math.Round(((((torpor / (1 + stats[7].MultAffinity)) - stats[7].AddWhenTamed) / ((1 + (imprintingBonusRounded + 0.005) * 0.2 * imprintingBonusMultiplier) * stats[7].BaseValue)) - 1) / stats[7].IncPerWildLevel), (int)Math.Round(((((torpor / (1 + stats[7].MultAffinity)) - stats[7].AddWhenTamed) / ((1 + (imprintingBonusRounded - 0.005) * 0.2 * imprintingBonusMultiplier) * stats[7].BaseValue)) - 1) / stats[7].IncPerWildLevel)); // assuming food has no dom-levels, extract the exact imprinting from this stat. If the range is in the range of the torpor-dependant IB, take this more precise value for the imprinting. (food has higher values and yields more precise results) MinMaxInt wildLevelsFromImprintedFood = new MinMaxInt( (int)Math.Round(((((food / (1 + stats[3].MultAffinity)) - stats[3].AddWhenTamed) / ((1 + (imprintingBonusRounded + 0.005) * 0.2 * imprintingBonusMultiplier) * stats[3].BaseValue)) - 1) / stats[3].IncPerWildLevel), (int)Math.Round(((((food / (1 + stats[3].MultAffinity)) - stats[3].AddWhenTamed) / ((1 + (imprintingBonusRounded - 0.005) * 0.2 * imprintingBonusMultiplier) * stats[3].BaseValue)) - 1) / stats[3].IncPerWildLevel)); List <MinMaxDouble> imprintingBonusList = new List <MinMaxDouble>(); List <int> otherStatsSupportIB = new List <int>(); // the number of other stats that support this IB-range // for high-level creatures the bonus from imprinting is so high, that a displayed and rounded value of the imprinting bonus can be possible with multiple torpor-levels, i.e. 1 %point IB results in a larger change than a level in torpor. for (int torporLevel = wildLevelsFromImprintedTorpor.Min; torporLevel <= wildLevelsFromImprintedTorpor.Max; torporLevel++) { int support = 0; MinMaxDouble imprintingBonusRange = new MinMaxDouble( (((torpor - 0.05) / (1 + stats[7].MultAffinity) - stats[7].AddWhenTamed) / Stats.calculateValue(speciesIndex, 7, torporLevel, 0, false, 0, 0) - 1) / (0.2 * imprintingBonusMultiplier), (((torpor + 0.05) / (1 + stats[7].MultAffinity) - stats[7].AddWhenTamed) / Stats.calculateValue(speciesIndex, 7, torporLevel, 0, false, 0, 0) - 1) / (0.2 * imprintingBonusMultiplier)); // check for each possible food-level the IB-range and if it can narrow down the range derived from the torpor (deriving from food is more precise, due to the higher values) for (int foodLevel = wildLevelsFromImprintedFood.Min; foodLevel <= wildLevelsFromImprintedFood.Max; foodLevel++) { MinMaxDouble imprintingBonusFromFood = new MinMaxDouble( (((food - 0.05) / (1 + stats[3].MultAffinity) - stats[3].AddWhenTamed) / Stats.calculateValue(speciesIndex, 3, foodLevel, 0, false, 0, 0) - 1) / (0.2 * imprintingBonusMultiplier), (((food + 0.05) / (1 + stats[3].MultAffinity) - stats[3].AddWhenTamed) / Stats.calculateValue(speciesIndex, 3, foodLevel, 0, false, 0, 0) - 1) / (0.2 * imprintingBonusMultiplier)); // NOTE. it's assumed if the IB-food is in the range of IB-torpor, the values are correct. This doesn't have to be true, but is very probable. If extraction-issues appear, this assumption could be the reason. //if (imprintingBonusFromTorpor.Includes(imprintingBonusFromFood) if (imprintingBonusRange.Overlaps(imprintingBonusFromFood)) { MinMaxDouble intersectionIB = new MinMaxDouble(imprintingBonusRange); intersectionIB.SetToInsersectionWith(imprintingBonusFromFood); if (Stats.calculateValue(speciesIndex, 7, torporLevel, 0, true, 1, intersectionIB.Min) <= torpor && Stats.calculateValue(speciesIndex, 7, torporLevel, 0, true, 1, intersectionIB.Max) >= torpor) { //imprintingBonusFromTorpor = imprintingBonusFromFood; imprintingBonusRange.SetToInsersectionWith(imprintingBonusFromFood); support++; } } } // if classic method results in value in the possible range, take this, probably most exact value if (imprintingBonusRange.Includes(imprintingBonusFromGainPerCuddle) && Stats.calculateValue(speciesIndex, 7, torporLevel, 0, true, 1, imprintingBonusFromGainPerCuddle) == torpor) { imprintingBonusRange.MinMax = imprintingBonusFromGainPerCuddle; support++; } imprintingBonusList.Add(imprintingBonusRange); otherStatsSupportIB.Add(support); } // sort IB according to the support they got by other stats, then return the distinct means of the possible ranges. return(imprintingBonusList.OrderByDescending(i => otherStatsSupportIB[imprintingBonusList.IndexOf(i)]).Select(i => i.Mean).Distinct().ToList()); }