Exemplo n.º 1
0
        public void extractLevels(int speciesI, int level, List <StatIO> statIOs, double lowerTEBound, double upperTEBound, bool autoDetectTamed,
                                  bool tamed, bool justTamed, bool bred, double imprintingBonusRounded, bool adjustImprinting, bool allowMoreThanHundredImprinting, bool extractImprintingFromTorpor, double imprintingBonusMultiplier, double cuddleIntervalMultiplier,
                                  bool considerWildLevelSteps, int wildLevelSteps, out bool imprintingChanged)
        {
            List <CreatureStat> stats = Values.V.species[speciesI].stats;

            validResults           = true;
            imprintingChanged      = false;
            considerWildLevelSteps = considerWildLevelSteps && !bred;

            this.bred = bred;
            if (bred)
            {
                postTamed = true;
            }
            else if (autoDetectTamed && stats[7].AddWhenTamed > 0)
            {
                // torpor is directly proportional to wild level. Check if creature is wild or tamed (doesn't work with creatures that have no additive bonus on torpor, e.g. the Giganotosaurus)
                postTamed = (Math.Round(stats[7].BaseValue * (1 + stats[7].IncPerWildLevel * Math.Round((statIOs[7].Input - stats[7].BaseValue) / (stats[7].BaseValue * stats[7].IncPerWildLevel))), 3) != statIOs[7].Input);
            }
            else
            {
                postTamed = tamed;
            }

            imprintingBonus = 0;
            if (bred)
            {
                if (!adjustImprinting)
                {
                    imprintingBonus = imprintingBonusRounded;
                }
                else if (extractImprintingFromTorpor)
                {
                    int wildLevelsFromImprintedTorpor = (int)Math.Round(((((statIOs[7].Input / (1 + stats[7].MultAffinity)) - stats[7].AddWhenTamed) / ((1 + imprintingBonusRounded * 0.2 * imprintingBonusMultiplier) * stats[7].BaseValue)) - 1) / stats[7].IncPerWildLevel);
                    imprintingBonus = ((statIOs[7].Input / (1 + stats[7].MultAffinity) - stats[7].AddWhenTamed) / Stats.calculateValue(speciesI, 7, wildLevelsFromImprintedTorpor, 0, false, 0, 0) - 1) / (0.2 * imprintingBonusMultiplier);

                    // assuming food has no dom-levels, extract the exact imprinting from this stat. If the difference is less than 0.01, take this (probably more precise) value for the imprinting. (food has higher values and yields more precise results)
                    int    wildLevelsFromImprintedFood = (int)Math.Round(((((statIOs[3].Input / (1 + stats[3].MultAffinity)) - stats[3].AddWhenTamed) / ((1 + imprintingBonusRounded * 0.2 * imprintingBonusMultiplier) * stats[3].BaseValue)) - 1) / stats[3].IncPerWildLevel);
                    double imprintingBonusFromFood     = ((statIOs[3].Input / (1 + stats[3].MultAffinity) - stats[3].AddWhenTamed) / Stats.calculateValue(speciesI, 3, wildLevelsFromImprintedFood, 0, false, 0, 0) - 1) / (0.2 * imprintingBonusMultiplier);
                    if (Math.Abs(imprintingBonus - imprintingBonusFromFood) < 0.01)
                    {
                        imprintingBonus = imprintingBonusFromFood;
                    }
                }
                else if (Values.V.species[speciesI].breeding != null && Values.V.species[speciesI].breeding.maturationTimeAdjusted > 0)
                {
                    double imprintingGainPerCuddle = Utils.imprintingGainPerCuddle(Values.V.species[speciesI].breeding.maturationTimeAdjusted, cuddleIntervalMultiplier);
                    imprintingBonus = Math.Round(Math.Round(imprintingBonusRounded / imprintingGainPerCuddle) * imprintingGainPerCuddle, 7);
                }
                if (!allowMoreThanHundredImprinting && imprintingBonus > 1)
                {
                    imprintingBonus = 1;
                }
                if (imprintingBonus < 0)
                {
                    imprintingBonus = 0;
                }
                if (Math.Abs(imprintingBonusRounded - imprintingBonus) > 0.01)
                {
                    imprintingChanged = true;
                }
            }
            double imprintingMultiplier = (1 + imprintingBonus * imprintingBonusMultiplier * .2);
            double torporLevelTamingMultMax, torporLevelTamingMultMin;

            torporLevelTamingMultMax = 1;
            torporLevelTamingMultMin = 1;
            if (postTamed && justTamed && !bred)
            {
                torporLevelTamingMultMax = (2 + upperTEBound) / (4 + upperTEBound);
                torporLevelTamingMultMin = (2 + lowerTEBound) / (4 + lowerTEBound);
            }
            levelWildFromTorporRange[0] = (int)Math.Round((statIOs[7].Input / imprintingMultiplier - (postTamed ? stats[7].AddWhenTamed : 0) - stats[7].BaseValue) * torporLevelTamingMultMin / (stats[7].BaseValue * stats[7].IncPerWildLevel), 0);
            levelWildFromTorporRange[1] = (int)Math.Round((statIOs[7].Input / imprintingMultiplier - (postTamed ? stats[7].AddWhenTamed : 0) - stats[7].BaseValue) * torporLevelTamingMultMax / (stats[7].BaseValue * stats[7].IncPerWildLevel), 0);

            domFreeMin = 0;
            domFreeMax = 0;
            // lower/upper Bound of each stat (wild has no upper bound as wild-speed and sometimes oxygen is unknown)
            if (postTamed)
            {
                domFreeMin = Math.Max(0, level - levelWildFromTorporRange[1] - 1);
                domFreeMax = Math.Max(0, level - levelWildFromTorporRange[0] - 1);
            }
            levelDomFromTorporAndTotalRange[0] = domFreeMin;
            levelDomFromTorporAndTotalRange[1] = domFreeMax;
            wildFreeMax = levelWildFromTorporRange[1];

            if (bred)
            {
                // bred creatures always have 100% TE
                lowerTEBound = 1;
                upperTEBound = 1;
            }

            // check all possible level-combinations
            for (int s = 7; s >= 0; s--)
            {
                if (stats[s].BaseValue > 0 && activeStats[s]) // if stat is used (oxygen sometimes is not)
                {
                    statIOs[s].postTame = postTamed;
                    double inputValue    = statIOs[s].Input;
                    double statBaseValue = stats[s].BaseValue;
                    if (postTamed)
                    {
                        statBaseValue *= (s == 0 ? (double)Values.V.species[speciesI].TamedBaseHealthMultiplier : 1);
                    }

                    double tamingEffectiveness = -1;
                    double valueWODom          = 0; // value without domesticated levels

                    bool withTEff = (postTamed && stats[s].MultAffinity > 0);
                    if (withTEff)
                    {
                        statsWithEff.Add(s);
                    }
                    double maxLW = 0;
                    if (stats[s].BaseValue > 0 && 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 = Math.Round(((inputValue / multAffinityFactor - (postTamed ? stats[s].AddWhenTamed : 0)) / statBaseValue - 1) / stats[s].IncPerWildLevel); // floor is too unprecise
                    }
                    if (s != 7 && maxLW > levelWildFromTorporRange[1])
                    {
                        maxLW = levelWildFromTorporRange[1];
                    }                                                                                           // torpor level can be too high right after taming (torpor bug in the game)

                    double maxLD = 0;
                    if (!statIOs[s].DomLevelZero && postTamed && stats[s].BaseValue > 0 && stats[s].IncPerTamedLevel > 0)
                    {
                        maxLD = Math.Round((inputValue / ((statBaseValue + stats[s].AddWhenTamed) * (1 + lowerTEBound * stats[s].MultAffinity)) - 1) / stats[s].IncPerTamedLevel); //floor is sometimes too unprecise
                    }
                    if (maxLD > domFreeMax)
                    {
                        maxLD = domFreeMax;
                    }
                    if (maxLD < 0)
                    {
                        maxLD = 0;
                    }

                    for (int w = 0; w < maxLW + 1; w++)
                    {
                        // imprinting bonus is applied to all stats except stamina (s==1) and oxygen (s==2) and speed (s==6)
                        valueWODom = statBaseValue * (1 + stats[s].IncPerWildLevel * w) * (s == 1 || s == 2 || (s == 6 && Values.V.species[speciesI].NoImprintingForSpeed == true) ? 1 : imprintingMultiplier) + (postTamed ? stats[s].AddWhenTamed : 0);
                        for (int d = 0; d < maxLD + 1; d++)
                        {
                            if (withTEff)
                            {
                                // taming bonus is dependant on taming-effectiveness
                                // get tamingEffectiveness-possibility
                                tamingEffectiveness = Math.Round((inputValue / (1 + stats[s].IncPerTamedLevel * d) - valueWODom) / (valueWODom * stats[s].MultAffinity), 4);

                                // calculate rounding-error thresholds. Here it's assumed that the displayed ingame value is maximal 0.6 off of the true ingame value
                                double tamingEffectivenessMax = Math.Round(((inputValue + (Utils.precision(s) == 3 ? 0.0006 : 0.06)) / (1 + stats[s].IncPerTamedLevel * d) - valueWODom) / (valueWODom * stats[s].MultAffinity), 4);
                                double tamingEffectivenessMin = Math.Round(((inputValue - (Utils.precision(s) == 3 ? 0.0006 : 0.06)) / (1 + stats[s].IncPerTamedLevel * d) - valueWODom) / (valueWODom * stats[s].MultAffinity), 4);

                                if (tamingEffectivenessMin <= 1 && tamingEffectiveness > 1)
                                {
                                    tamingEffectiveness = 1;
                                }
                                if (tamingEffectivenessMax >= lowerTEBound)
                                {
                                    if (tamingEffectivenessMin <= upperTEBound)
                                    {
                                        // test if TE with torpor-level of tamed-creatures results in a valid wild-level
                                        if (considerWildLevelSteps && s != 7 && tamingEffectiveness > 0)
                                        {
                                            int  preTameLevelMin = (int)((trueTorporLevel() + 1) / (1 + tamingEffectivenessMax / 2));
                                            int  preTameLevelMax = (int)Math.Ceiling((trueTorporLevel() + 1) / (1 + tamingEffectivenessMax / 2));
                                            bool validWildLevel  = false;
                                            for (int wl = preTameLevelMin; wl <= preTameLevelMax; wl++)
                                            {
                                                if (wl % wildLevelSteps == 0)
                                                {
                                                    validWildLevel = true;
                                                    break;
                                                }
                                            }
                                            if (!validWildLevel)
                                            {
                                                continue;
                                            }
                                        }

                                        results[s].Add(new StatResult(w, d, tamingEffectiveness, tamingEffectivenessMin, tamingEffectivenessMax));
                                    }
                                    else
                                    {
                                        continue;
                                    }
                                }
                                else
                                {
                                    // if tamingEff < lowerBound: break, in this loop it's getting only smaller
                                    break;
                                }
                            }
                            else if (Math.Abs((valueWODom * (postTamed ? 1 + stats[s].MultAffinity : 1) * (1 + stats[s].IncPerTamedLevel * d) - inputValue) * (Utils.precision(s) == 3 ? 100 : 1)) < 0.15)
                            {
                                results[s].Add(new StatResult(w, d));
                                break; // no other solution with this w possible
                            }
                        }
                    }
                }
                else
                {
                    results[s].Add(new StatResult(0, 0));
                }
            }
        }
Exemplo n.º 2
0
        private List <MinMaxDouble> CalculateImprintingBonus(Species species, double imprintingBonusRounded, double imprintingBonusMultiplier, double cuddleIntervalMultiplier, double torpor, double food)
        {
            List <MinMaxDouble> imprintingBonusList = new List <MinMaxDouble>();

            if (species.stats[(int)StatNames.Torpidity].BaseValue == 0 || species.stats[(int)StatNames.Torpidity].IncPerWildLevel == 0)
            {
                return(imprintingBonusList);                                                                                                                        // invalid species-data
            }
            // 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 (species.breeding != null)
            {
                double imprintingGainPerCuddle = Utils.imprintingGainPerCuddle(species.breeding.maturationTimeAdjusted, cuddleIntervalMultiplier);
                imprintingBonusFromGainPerCuddle = Math.Round(imprintingBonusRounded / imprintingGainPerCuddle) * imprintingGainPerCuddle;
            }

            MinMaxInt wildLevelsFromImprintedTorpor = new MinMaxInt(
                (int)Math.Round(((((torpor / (1 + species.stats[(int)StatNames.Torpidity].MultAffinity)) - species.stats[(int)StatNames.Torpidity].AddWhenTamed) / ((1 + (imprintingBonusRounded + 0.005) * 0.2 * imprintingBonusMultiplier) * species.stats[(int)StatNames.Torpidity].BaseValue)) - 1) / species.stats[(int)StatNames.Torpidity].IncPerWildLevel),
                (int)Math.Round(((((torpor / (1 + species.stats[(int)StatNames.Torpidity].MultAffinity)) - species.stats[(int)StatNames.Torpidity].AddWhenTamed) / ((1 + (imprintingBonusRounded - 0.005) * 0.2 * imprintingBonusMultiplier) * species.stats[(int)StatNames.Torpidity].BaseValue)) - 1) / species.stats[(int)StatNames.Torpidity].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 + species.stats[(int)StatNames.Food].MultAffinity)) - species.stats[(int)StatNames.Food].AddWhenTamed) / ((1 + (imprintingBonusRounded + 0.005) * 0.2 * imprintingBonusMultiplier) * species.stats[(int)StatNames.Food].BaseValue)) - 1) / species.stats[(int)StatNames.Food].IncPerWildLevel),
                (int)Math.Round(((((food / (1 + species.stats[(int)StatNames.Food].MultAffinity)) - species.stats[(int)StatNames.Food].AddWhenTamed) / ((1 + (imprintingBonusRounded - 0.005) * 0.2 * imprintingBonusMultiplier) * species.stats[(int)StatNames.Food].BaseValue)) - 1) / species.stats[(int)StatNames.Food].IncPerWildLevel));

            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 + species.stats[(int)StatNames.Torpidity].MultAffinity) - species.stats[(int)StatNames.Torpidity].AddWhenTamed) / Stats.calculateValue(species, (int)StatNames.Torpidity, torporLevel, 0, false, 0, 0) - 1) / (0.2 * imprintingBonusMultiplier),
                    (((torpor + 0.05) / (1 + species.stats[(int)StatNames.Torpidity].MultAffinity) - species.stats[(int)StatNames.Torpidity].AddWhenTamed) / Stats.calculateValue(species, (int)StatNames.Torpidity, 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 + species.stats[(int)StatNames.Food].MultAffinity) - species.stats[(int)StatNames.Food].AddWhenTamed) / Stats.calculateValue(species, (int)StatNames.Food, foodLevel, 0, false, 0, 0) - 1) / (0.2 * imprintingBonusMultiplier),
                        (((food + 0.05) / (1 + species.stats[(int)StatNames.Food].MultAffinity) - species.stats[(int)StatNames.Food].AddWhenTamed) / Stats.calculateValue(species, (int)StatNames.Food, 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.SetToIntersectionWith(imprintingBonusFromFood);
                        if (Stats.calculateValue(species, (int)StatNames.Torpidity, torporLevel, 0, true, 1, intersectionIB.Min) <= torpor &&
                            Stats.calculateValue(species, (int)StatNames.Torpidity, torporLevel, 0, true, 1, intersectionIB.Max) >= torpor)
                        {
                            //imprintingBonusFromTorpor = imprintingBonusFromFood;
                            imprintingBonusRange.SetToIntersectionWith(imprintingBonusFromFood);
                            support++;
                        }
                    }
                }

                // if classic method results in value in the possible range, take this, probably most exact value
                if (imprintingBonusRange.Includes(imprintingBonusFromGainPerCuddle) &&
                    Stats.calculateValue(species, (int)StatNames.Torpidity, torporLevel, 0, true, 1, imprintingBonusFromGainPerCuddle) == torpor)
                {
                    imprintingBonusRange.MinMax = imprintingBonusFromGainPerCuddle;
                    support++;
                }

                // TODO check if this range has already been added to avoid double loops in the extraction. if existant, update 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)]).ToList());
        }
Exemplo n.º 3
0
        public void extractLevels(int speciesI, int level, List <StatIO> statIOs, double lowerTEBound, double upperTEBound, bool autoDetectTamed,
                                  bool tamed, bool justTamed, bool bred, double imprintingBonusRounded, bool adjustImprinting, double imprintingBonusMultiplier, double cuddleIntervalMultiplier,
                                  bool considerWildLevelSteps, int wildLevelSteps, out bool imprintingChanged)
        {
            validResults           = true;
            imprintingChanged      = false;
            considerWildLevelSteps = considerWildLevelSteps && !bred;

            if (bred)
            {
                postTamed = true;
            }
            else if (autoDetectTamed && Values.V.species[speciesI].stats[7].AddWhenTamed > 0)
            {
                // torpor is directly proportional to wild level. Check if creature is wild or tamed (doesn't work with creatures that have no additive bonus on torpor, e.g. the Giganotosaurus)
                postTamed = (Math.Round(Values.V.species[speciesI].stats[7].BaseValue * (1 + Values.V.species[speciesI].stats[7].IncPerWildLevel * Math.Round((statIOs[7].Input - Values.V.species[speciesI].stats[7].BaseValue) / (Values.V.species[speciesI].stats[7].BaseValue * Values.V.species[speciesI].stats[7].IncPerWildLevel))), 3) != statIOs[7].Input);
            }
            else
            {
                postTamed = tamed;
            }

            imprintingBonus = 0;
            if (bred)
            {
                if (!adjustImprinting)
                {
                    imprintingBonus = imprintingBonusRounded;
                }
                else if (Values.V.species[speciesI].breeding != null && Values.V.species[speciesI].breeding.maturationTimeAdjusted > 0)
                {
                    double imprintingGainPerCuddle = Utils.imprintingGainPerCuddle(Values.V.species[speciesI].breeding.maturationTimeAdjusted, cuddleIntervalMultiplier);
                    imprintingBonus = Math.Round(Math.Round(imprintingBonusRounded / imprintingGainPerCuddle) * imprintingGainPerCuddle, 7);
                    if (imprintingBonus > 1)
                    {
                        imprintingBonus = 1;
                    }
                    if (Math.Abs(imprintingBonusRounded - imprintingBonus) > 0.01)
                    {
                        imprintingChanged = true;
                    }
                }
            }
            double imprintingMultiplier = (1 + imprintingBonus * imprintingBonusMultiplier * .2);

            // needed to handle Torpor-bug
            this.justTamed = false; // Torpor-bug got fixed :)) leaving the code for a while

            // Torpor-bug: if bonus levels are added due to taming-effectiveness, torpor is too high
            // instead of giving only the TE-bonus, the original wild levels W are added a second time to the torporlevels
            // the game does this after taming: toLvl = (Math.Floor(W*TE/2) > 0 ? 2*W + Math.Min(W*TE/2) : W);
            // the game should do (and does after some while, maybe a server-restart): toLvl = W + Math.Min(W*TE/2);
            // max level for wild according to torpor (possible bug ingame: torpor is depending on taming effectiveness 5/3 - 2 times "too high" for level after taming until server-restart (not only the bonus levels are added, but also the existing levels again)
            double torporLevelTamingMultMax, torporLevelTamingMultMin;
            bool   runTorporRangeAgain;

            do
            {
                runTorporRangeAgain      = false;
                torporLevelTamingMultMax = 1;
                torporLevelTamingMultMin = 1;
                if (postTamed && justTamed && !bred)
                {
                    torporLevelTamingMultMax = (2 + upperTEBound) / (4 + upperTEBound);
                    torporLevelTamingMultMin = (2 + lowerTEBound) / (4 + lowerTEBound);
                }
                levelWildFromTorporRange[0] = (int)Math.Round((statIOs[7].Input / imprintingMultiplier - (postTamed ? Values.V.species[speciesI].stats[7].AddWhenTamed : 0) - Values.V.species[speciesI].stats[7].BaseValue) * torporLevelTamingMultMin / (Values.V.species[speciesI].stats[7].BaseValue * Values.V.species[speciesI].stats[7].IncPerWildLevel), 0);
                levelWildFromTorporRange[1] = (int)Math.Round((statIOs[7].Input / imprintingMultiplier - (postTamed ? Values.V.species[speciesI].stats[7].AddWhenTamed : 0) - Values.V.species[speciesI].stats[7].BaseValue) * torporLevelTamingMultMax / (Values.V.species[speciesI].stats[7].BaseValue * Values.V.species[speciesI].stats[7].IncPerWildLevel), 0);

                // if level of torpor is higher than the total-level, the torporBug displayed a too high torpor. If the user didn't check the justTamed-checkbox, do it for them and recalculate the true torpor-level
                if (false && !runTorporRangeAgain && !justTamed && levelWildFromTorporRange[0] > level) // torpor bug got fixed, leaving the code for a while
                {
                    justTamed           = true;
                    this.justTamed      = true;
                    runTorporRangeAgain = true;
                }
                // if levelWildFromTorporRange[0] > level, then justTamed has to be true, then run the previous calculation again
            } while (runTorporRangeAgain);

            domFreeMin = 0;
            domFreeMax = 0;
            // lower/upper Bound of each stat (wild has no upper bound as wild-speed and sometimes oxygen is unknown)
            if (postTamed)
            {
                domFreeMin = Math.Max(0, level - levelWildFromTorporRange[1] - 1);
                domFreeMax = Math.Max(0, level - levelWildFromTorporRange[0] - 1);
            }
            levelDomFromTorporAndTotalRange[0] = domFreeMin;
            levelDomFromTorporAndTotalRange[1] = domFreeMax;
            wildFreeMax = levelWildFromTorporRange[1];

            if (bred)
            {
                // bred creatures always have 100% TE
                lowerTEBound = 1;
                upperTEBound = 1;
            }

            // check all possible level-combinations
            for (int s = 7; s >= 0; s--)
            {
                if (Values.V.species[speciesI].stats[s].BaseValue > 0 && activeStats[s]) // if stat is used (oxygen sometimes is not)
                {
                    statIOs[s].postTame = postTamed;
                    double inputValue    = statIOs[s].Input;
                    double statBaseValue = Values.V.species[speciesI].stats[s].BaseValue;
                    if (postTamed)
                    {
                        statBaseValue *= (s == 0 ? (double)Values.V.species[speciesI].TamedBaseHealthMultiplier : 1);
                    }

                    double tamingEffectiveness = -1;
                    double valueWODom          = 0; // value without domesticated levels

                    bool withTEff = (postTamed && Values.V.species[speciesI].stats[s].MultAffinity > 0);
                    if (withTEff)
                    {
                        statsWithEff.Add(s);
                    }
                    double maxLW = 0;
                    if (Values.V.species[speciesI].stats[s].BaseValue > 0 && Values.V.species[speciesI].stats[s].IncPerWildLevel > 0)
                    {
                        double multAffinityFactor = Values.V.species[speciesI].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 = Math.Round(((inputValue / multAffinityFactor - (postTamed ? Values.V.species[speciesI].stats[s].AddWhenTamed : 0)) / statBaseValue - 1) / Values.V.species[speciesI].stats[s].IncPerWildLevel); // floor is too unprecise
                    }
                    if (s != 7 && maxLW > levelWildFromTorporRange[1])
                    {
                        maxLW = levelWildFromTorporRange[1];
                    }                                                                                           // torpor level can be too high right after taming (torpor bug in the game)

                    double maxLD = 0;
                    if (!statIOs[s].DomLevelZero && postTamed && Values.V.species[speciesI].stats[s].BaseValue > 0 && Values.V.species[speciesI].stats[s].IncPerTamedLevel > 0)
                    {
                        maxLD = Math.Round((inputValue / ((statBaseValue + Values.V.species[speciesI].stats[s].AddWhenTamed) * (1 + lowerTEBound * Values.V.species[speciesI].stats[s].MultAffinity)) - 1) / Values.V.species[speciesI].stats[s].IncPerTamedLevel); //floor is sometimes too unprecise
                    }
                    if (maxLD > domFreeMax)
                    {
                        maxLD = domFreeMax;
                    }
                    if (maxLD < 0)
                    {
                        maxLD = 0;
                    }

                    for (int w = 0; w < maxLW + 1; w++)
                    {
                        // imprinting bonus is applied to all stats except stamina (s==1) and oxygen (s==2) and speed (s==6)
                        valueWODom = statBaseValue * (1 + Values.V.species[speciesI].stats[s].IncPerWildLevel * w) * (s == 1 || s == 2 || (s == 6 && Values.V.species[speciesI].NoImprintingForSpeed == true) ? 1 : imprintingMultiplier) + (postTamed ? Values.V.species[speciesI].stats[s].AddWhenTamed : 0);
                        for (int d = 0; d < maxLD + 1; d++)
                        {
                            if (withTEff)
                            {
                                // taming bonus is dependant on taming-effectiveness
                                // get tamingEffectiveness-possibility
                                tamingEffectiveness = Math.Round((inputValue / (1 + Values.V.species[speciesI].stats[s].IncPerTamedLevel * d) - valueWODom) / (valueWODom * Values.V.species[speciesI].stats[s].MultAffinity), 4);

                                // calculate rounding-error thresholds. Here it's assumed that the displayed ingame value is maximal 0.6 off of the true ingame value
                                double tamingEffectivenessMax = Math.Round(((inputValue + (Utils.precision(s) == 3 ? 0.0006 : 0.06)) / (1 + Values.V.species[speciesI].stats[s].IncPerTamedLevel * d) - valueWODom) / (valueWODom * Values.V.species[speciesI].stats[s].MultAffinity), 4);
                                double tamingEffectivenessMin = Math.Round(((inputValue - (Utils.precision(s) == 3 ? 0.0006 : 0.06)) / (1 + Values.V.species[speciesI].stats[s].IncPerTamedLevel * d) - valueWODom) / (valueWODom * Values.V.species[speciesI].stats[s].MultAffinity), 4);

                                if (tamingEffectivenessMin <= 1 && tamingEffectiveness > 1)
                                {
                                    tamingEffectiveness = 1;
                                }
                                if (tamingEffectivenessMax >= lowerTEBound)
                                {
                                    if (tamingEffectivenessMin <= upperTEBound)
                                    {
                                        // test if TE with torpor-level of tamed-creatures results in a valid wild-level
                                        if (considerWildLevelSteps && s != 7 && tamingEffectiveness > 0)
                                        {
                                            int  preTameLevelMin = (int)((trueTorporLevel(tamingEffectiveness) + 1) / (1 + tamingEffectivenessMax / 2));
                                            int  preTameLevelMax = (int)Math.Ceiling((trueTorporLevel(tamingEffectiveness) + 1) / (1 + tamingEffectivenessMax / 2));
                                            bool validWildLevel  = false;
                                            for (int wl = preTameLevelMin; wl <= preTameLevelMax; wl++)
                                            {
                                                if (wl % wildLevelSteps == 0)
                                                {
                                                    validWildLevel = true;
                                                    break;
                                                }
                                            }
                                            if (!validWildLevel)
                                            {
                                                continue;
                                            }
                                        }

                                        results[s].Add(new StatResult(w, d, tamingEffectiveness, tamingEffectivenessMin, tamingEffectivenessMax));
                                    }
                                    else
                                    {
                                        continue;
                                    }
                                }
                                else
                                {
                                    // if tamingEff < lowerBound: break, in this loop it's getting only smaller
                                    break;
                                }
                            }
                            else if (Math.Abs((valueWODom * (postTamed ? 1 + Values.V.species[speciesI].stats[s].MultAffinity : 1) * (1 + Values.V.species[speciesI].stats[s].IncPerTamedLevel * d) - inputValue) * (Utils.precision(s) == 3 ? 100 : 1)) < 0.15)
                            {
                                results[s].Add(new StatResult(w, d));
                                break; // no other solution with this w possible
                            }
                        }
                    }
                }
                else
                {
                    results[s].Add(new StatResult(0, 0));
                }
            }
        }