From da4f06a618d9b49804c052d5d9529761d6c53d3c Mon Sep 17 00:00:00 2001 From: GTNH-Colen <54497873+GTNH-Colen@users.noreply.github.com> Date: Thu, 27 Jun 2024 14:30:45 +0100 Subject: [PATCH] Fix bee breeding overflowing with mutation. --- .../forestry/apiculture/genetics/Bee.java | 7 +++-- .../apiculture/genetics/BeeMutation.java | 6 ++-- .../core/genetics/mutations/Mutation.java | 4 ++- .../java/forestry/core/utils/MathUtil.java | 29 +++++++++++++++++++ 4 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 src/main/java/forestry/core/utils/MathUtil.java diff --git a/src/main/java/forestry/apiculture/genetics/Bee.java b/src/main/java/forestry/apiculture/genetics/Bee.java index 2238fb55b..fdfb6b1f0 100644 --- a/src/main/java/forestry/apiculture/genetics/Bee.java +++ b/src/main/java/forestry/apiculture/genetics/Bee.java @@ -67,6 +67,9 @@ import forestry.core.utils.Log; import forestry.core.utils.StringUtil; import forestry.core.utils.vect.Vect; +import static forestry.core.utils.MathUtil.safeAdd; +import static forestry.core.utils.MathUtil.safeMultiply; + public class Bee extends IndividualLiving implements IBee { private int generation; @@ -699,9 +702,9 @@ public class Bee extends IndividualLiving implements IBee { // boost chance for researched mutations if (breedingTracker.isResearched(beeMutation)) { - float mutationBoost = chance * (Config.researchMutationBoostMultiplier - 1.0f); + float mutationBoost = safeMultiply(chance, Config.researchMutationBoostMultiplier - 1.0f); mutationBoost = Math.min(Config.maxResearchMutationBoostPercent, mutationBoost); - chance += mutationBoost; + chance = safeAdd(chance, mutationBoost); } if (chance > world.rand.nextFloat() * 100) { diff --git a/src/main/java/forestry/apiculture/genetics/BeeMutation.java b/src/main/java/forestry/apiculture/genetics/BeeMutation.java index 832ee8603..a7856cba1 100644 --- a/src/main/java/forestry/apiculture/genetics/BeeMutation.java +++ b/src/main/java/forestry/apiculture/genetics/BeeMutation.java @@ -21,6 +21,8 @@ import forestry.api.apiculture.IBeeRoot; import forestry.api.genetics.IAllele; import forestry.core.genetics.mutations.Mutation; +import static forestry.core.utils.MathUtil.safeMultiply; + public class BeeMutation extends Mutation implements IBeeMutationCustom { public BeeMutation(IAlleleBeeSpecies bee0, IAlleleBeeSpecies bee1, IAllele[] result, int chance) { @@ -49,8 +51,8 @@ public class BeeMutation extends Mutation implements IBeeMutationCustom { IBeeModifier beeHousingModifier = BeeManager.beeRoot.createBeeHousingModifier(housing); IBeeModifier beeModeModifier = BeeManager.beeRoot.getBeekeepingMode(world).getBeeModifier(); - processedChance *= beeHousingModifier.getMutationModifier(genome0, genome1, processedChance); - processedChance *= beeModeModifier.getMutationModifier(genome0, genome1, processedChance); + processedChance = safeMultiply(processedChance, beeHousingModifier.getMutationModifier(genome0, genome1, processedChance)); + processedChance = safeMultiply(processedChance, beeModeModifier.getMutationModifier(genome0, genome1, processedChance)); return processedChance; } diff --git a/src/main/java/forestry/core/genetics/mutations/Mutation.java b/src/main/java/forestry/core/genetics/mutations/Mutation.java index 68a9628cb..a84251578 100644 --- a/src/main/java/forestry/core/genetics/mutations/Mutation.java +++ b/src/main/java/forestry/core/genetics/mutations/Mutation.java @@ -25,6 +25,8 @@ import forestry.api.genetics.IGenome; import forestry.api.genetics.IMutationCondition; import forestry.api.genetics.IMutationCustom; +import static forestry.core.utils.MathUtil.safeMultiply; + public abstract class Mutation implements IMutationCustom { private final int chance; @@ -126,7 +128,7 @@ public abstract class Mutation implements IMutationCustom { IGenome genome1, IClimateProvider climate) { float mutationChance = chance; for (IMutationCondition mutationCondition : mutationConditions) { - mutationChance *= mutationCondition.getChance(world, x, y, z, allele0, allele1, genome0, genome1, climate); + mutationChance = safeMultiply(mutationChance, mutationCondition.getChance(world, x, y, z, allele0, allele1, genome0, genome1, climate)); if (mutationChance == 0) { return 0; } diff --git a/src/main/java/forestry/core/utils/MathUtil.java b/src/main/java/forestry/core/utils/MathUtil.java new file mode 100644 index 000000000..7f3b0fe59 --- /dev/null +++ b/src/main/java/forestry/core/utils/MathUtil.java @@ -0,0 +1,29 @@ +package forestry.core.utils; + +public class MathUtil { + + public static float safeMultiply(float a, float b) { + if (a > 0 && b > 0 && a > Float.MAX_VALUE / b) { + return Float.MAX_VALUE; + } else if (a > 0 && b < 0 && a > Float.MIN_VALUE / b) { + return Float.MIN_VALUE; + } else if (a < 0 && b > 0 && a < Float.MIN_VALUE / b) { + return Float.MIN_VALUE; + } else if (a < 0 && b < 0 && a < Float.MAX_VALUE / b) { + return Float.MAX_VALUE; + } else { + return a * b; + } + } + + public static float safeAdd(float a, float b) { + if (a > 0 && b > 0 && a > Float.MAX_VALUE - b) { + return Float.MAX_VALUE; + } else if (a < 0 && b < 0 && a < Float.MIN_VALUE - b) { + return Float.MIN_VALUE; + } else { + return a + b; + } + } + +}