diff --git a/README.md b/README.md index 673e339fa..cdfde75ab 100644 --- a/README.md +++ b/README.md @@ -400,6 +400,7 @@ Available in flavors [**Cleanroom**](https://www.curseforge.com/minecraft/modpac * **Binnie's Mods** * **Gather Windfall:** Allows Forestry farms to pick up ExtraTrees fruit * **Biomes O' Plenty** + * **Farmland Stuck Fix:** Fixes entities getting stuck when BOP farmland converts to dirt (MC-104259) * **Hot Spring Water:** Fixes rapid inflection of regeneration effects in hot spring water * **Blood Magic** * **Bound Tool Harvest Tweak:** Improves performance when harvesting blocks with Bound Tool's right-click and exposes block drops to HarvestDropsEvent diff --git a/src/main/java/mod/acgaming/universaltweaks/config/UTConfigMods.java b/src/main/java/mod/acgaming/universaltweaks/config/UTConfigMods.java index 33ac317b8..956bc7fa2 100644 --- a/src/main/java/mod/acgaming/universaltweaks/config/UTConfigMods.java +++ b/src/main/java/mod/acgaming/universaltweaks/config/UTConfigMods.java @@ -596,6 +596,11 @@ public static class BiomesOPlentyCategory @Config.Name("Hot Spring Water") @Config.Comment("Fixes rapid inflection of regeneration effects in hot spring water") public boolean utBoPHotSpringWaterToggle = true; + + @Config.RequiresMcRestart + @Config.Name("Farmland Stuck Fix") + @Config.Comment("Fixes entities getting stuck when BOP farmland converts to dirt (MC-104259)") + public boolean utBoPFarmlandStuckFixToggle = true; } public static class BloodMagicCategory diff --git a/src/main/java/mod/acgaming/universaltweaks/core/UTMixinLoader.java b/src/main/java/mod/acgaming/universaltweaks/core/UTMixinLoader.java index 31493d7dd..c1bbeb2cb 100644 --- a/src/main/java/mod/acgaming/universaltweaks/core/UTMixinLoader.java +++ b/src/main/java/mod/acgaming/universaltweaks/core/UTMixinLoader.java @@ -92,6 +92,7 @@ public class UTMixinLoader implements ILateMixinLoader put("mixins/mods/mixins.bibliocraft.printpress.json", c -> regularBiblioCraftLoaded() && UTConfigMods.BIBLIOCRAFT.utPrintingPressAnyBlackDyeToggle); put("mixins/mods/mixins.bibliocraft.transfer.json", c -> regularBiblioCraftLoaded() && UTConfigMods.BIBLIOCRAFT.utFixItemTransferToggle); put("mixins/mods/mixins.biomesoplenty.json", c -> c.isModPresent("biomesoplenty")); + put("mixins/mods/mixins.biomesoplenty.farmland.json", c -> c.isModPresent("biomesoplenty") && UTConfigMods.BIOMES_O_PLENTY.utBoPFarmlandStuckFixToggle); put("mixins/mods/mixins.biomesoplenty.sealevel.json", c -> c.isModPresent("biomesoplenty") && UTConfigTweaks.WORLD.utSeaLevel != 63); put("mixins/mods/mixins.bloodmagic.boundtool.json", c -> c.isModPresent("bloodmagic") && UTConfigMods.BLOOD_MAGIC.utBoundToolTweakToggle); put("mixins/mods/mixins.bloodmagic.dupes.json", c -> c.isModPresent("bloodmagic") && UTConfigMods.BLOOD_MAGIC.utDuplicationFixesToggle); diff --git a/src/main/java/mod/acgaming/universaltweaks/mods/biomesoplenty/mixin/UTBOPFarmlandMixin.java b/src/main/java/mod/acgaming/universaltweaks/mods/biomesoplenty/mixin/UTBOPFarmlandMixin.java new file mode 100644 index 000000000..8f7bf2912 --- /dev/null +++ b/src/main/java/mod/acgaming/universaltweaks/mods/biomesoplenty/mixin/UTBOPFarmlandMixin.java @@ -0,0 +1,90 @@ +package mod.acgaming.universaltweaks.mods.biomesoplenty.mixin; + +import net.minecraft.block.BlockFarmland; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraftforge.common.ForgeHooks; + +import biomesoplenty.common.block.BlockBOPFarmland; +import org.jetbrains.annotations.NotNull; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(value = BlockBOPFarmland.class, remap = false) +public abstract class UTBOPFarmlandMixin extends BlockFarmland +{ + + /// Mimicking the behavior of [BlockFarmland#turnToDirt(World, BlockPos)] + @Unique + private static boolean ut$turnToDirt(World world, BlockPos pos, IBlockState state) + { + boolean result = world.setBlockState(pos, state); + AxisAlignedBB sliver = field_194405_c.offset(pos); + for (Entity entity : world.getEntitiesWithinAABBExcludingEntity(null, sliver)) + { + double pushUp = Math.min(sliver.maxY - sliver.minY, sliver.maxY - entity.getEntityBoundingBox().minY); + entity.setPositionAndUpdate(entity.posX, entity.posY + pushUp + 0.001D, entity.posZ); + } + return result; + } + + @Shadow + public abstract IBlockState getDirtBlockState(IBlockState state); + + /** + * @author MCTian_mi + * @reason to mimic vanilla behavior + */ + @Overwrite + public void onFallenUpon(@NotNull World world, @NotNull BlockPos pos, @NotNull Entity entity, float fallDistance) + { + IBlockState dirtState = getDirtBlockState(world.getBlockState(pos)); + if (ForgeHooks.onFarmlandTrample(world, pos, dirtState, fallDistance, entity)) // Forge: Move logic to Entity#canTrample + { + ut$turnToDirt(world, pos, dirtState); + } + entity.fall(fallDistance, 1.0F); // Block#fall impl + } + + @Redirect( + method = "updateTick", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/world/World;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/state/IBlockState;)Z" + ) + ) + private boolean utBOPFarmlandUpdateTickTurnToDirt(World world, BlockPos pos, IBlockState state) + { + return ut$turnToDirt(world, pos, state); + } + + @Redirect( + method = "neighborChanged", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/world/World;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/state/IBlockState;)Z" + ) + ) + private boolean utBOPFarmlandNeighborChangedTurnToDirt(World world, BlockPos pos, IBlockState state) + { + return ut$turnToDirt(world, pos, state); + } + + @Unique + @Override + public void onBlockAdded(@NotNull World worldIn, @NotNull BlockPos pos, @NotNull IBlockState state) + { + // Not calling super 'cause it's hardcoded to turn this into dirt + if (worldIn.getBlockState(pos.up()).getMaterial().isSolid()) + { + ut$turnToDirt(worldIn, pos, getDirtBlockState(state)); + } + } +} diff --git a/src/main/resources/mixins/mods/mixins.biomesoplenty.farmland.json b/src/main/resources/mixins/mods/mixins.biomesoplenty.farmland.json new file mode 100644 index 000000000..9c704fd58 --- /dev/null +++ b/src/main/resources/mixins/mods/mixins.biomesoplenty.farmland.json @@ -0,0 +1,7 @@ +{ + "package": "mod.acgaming.universaltweaks.mods.biomesoplenty.mixin", + "refmap": "universaltweaks.refmap.json", + "minVersion": "0.8", + "compatibilityLevel": "JAVA_8", + "mixins": ["UTBOPFarmlandMixin"] +}