From 22ea5a23ad2a2ff8660a353c7da7f8e2cda1b37a Mon Sep 17 00:00:00 2001 From: AEnterprise Date: Tue, 31 Oct 2017 19:20:59 +0100 Subject: [PATCH] Improve performance of World.collidesWithAnyBlock (#4286) --- .../net/minecraft/world/World.java.patch | 17 ++- .../event/ForgeEventFactory.java | 8 ++ .../debug/CollisionBoxesEventTest.java | 101 ++++++++++++++++++ .../blockstates/box_block.json | 10 ++ 4 files changed, 132 insertions(+), 4 deletions(-) create mode 100644 src/test/java/net/minecraftforge/debug/CollisionBoxesEventTest.java create mode 100644 src/test/resources/assets/collisionboxexeventtest/blockstates/box_block.json diff --git a/patches/minecraft/net/minecraft/world/World.java.patch b/patches/minecraft/net/minecraft/world/World.java.patch index 550a943061..0afb51c2d2 100644 --- a/patches/minecraft/net/minecraft/world/World.java.patch +++ b/patches/minecraft/net/minecraft/world/World.java.patch @@ -219,14 +219,23 @@ this.func_72964_e(i, j).func_76612_a(p_72838_1_); this.field_72996_f.add(p_72838_1_); this.func_72923_a(p_72838_1_); -@@ -1268,6 +1332,7 @@ - } +@@ -1227,6 +1291,7 @@ + IBlockState iblockstate = Blocks.field_150348_b.func_176223_P(); + BlockPos.PooledMutableBlockPos blockpos$pooledmutableblockpos = BlockPos.PooledMutableBlockPos.func_185346_s(); + ++ if (p_191504_3_ && !net.minecraftforge.event.ForgeEventFactory.gatherCollisionBoxes(this, p_191504_1_, p_191504_2_, p_191504_4_)) return true; + try + { + for (int k1 = i; k1 < j; ++k1) +@@ -1269,7 +1334,7 @@ iblockstate1.func_185908_a(this, blockpos$pooledmutableblockpos, p_191504_2_, p_191504_4_, p_191504_1_, false); -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.GetCollisionBoxesEvent(this, null, p_191504_2_, p_191504_4_)); - if (p_191504_3_ && !p_191504_4_.isEmpty()) +- if (p_191504_3_ && !p_191504_4_.isEmpty()) ++ if (p_191504_3_ && !net.minecraftforge.event.ForgeEventFactory.gatherCollisionBoxes(this, p_191504_1_, p_191504_2_, p_191504_4_)) { + boolean flag5 = true; + return flag5; @@ -1319,11 +1384,10 @@ } } diff --git a/src/main/java/net/minecraftforge/event/ForgeEventFactory.java b/src/main/java/net/minecraftforge/event/ForgeEventFactory.java index 89da108284..ab8dfa69db 100644 --- a/src/main/java/net/minecraftforge/event/ForgeEventFactory.java +++ b/src/main/java/net/minecraftforge/event/ForgeEventFactory.java @@ -49,6 +49,7 @@ import net.minecraft.util.NonNullList; import net.minecraft.util.ResourceLocation; import net.minecraft.util.SoundCategory; import net.minecraft.util.SoundEvent; +import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.text.ChatType; @@ -114,6 +115,7 @@ import net.minecraftforge.event.world.BlockEvent.MultiPlaceEvent; import net.minecraftforge.event.world.BlockEvent.NeighborNotifyEvent; import net.minecraftforge.event.world.BlockEvent.PlaceEvent; import net.minecraftforge.event.world.ExplosionEvent; +import net.minecraftforge.event.world.GetCollisionBoxesEvent; import net.minecraftforge.event.world.WorldEvent; import net.minecraftforge.fml.common.ObfuscationReflectionHelper; import net.minecraftforge.fml.common.eventhandler.Event; @@ -682,4 +684,10 @@ public class ForgeEventFactory { return !MinecraftForge.EVENT_BUS.post(new LivingDestroyBlockEvent(entity, pos, state)); } + + public static boolean gatherCollisionBoxes(World world, Entity entity, AxisAlignedBB aabb, List outList) + { + MinecraftForge.EVENT_BUS.post(new GetCollisionBoxesEvent(world, entity, aabb, outList)); + return outList.isEmpty(); + } } diff --git a/src/test/java/net/minecraftforge/debug/CollisionBoxesEventTest.java b/src/test/java/net/minecraftforge/debug/CollisionBoxesEventTest.java new file mode 100644 index 0000000000..dce610f182 --- /dev/null +++ b/src/test/java/net/minecraftforge/debug/CollisionBoxesEventTest.java @@ -0,0 +1,101 @@ +package net.minecraftforge.debug; + +import java.util.ArrayList; + +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.Item; +import net.minecraft.item.ItemBlock; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; + +import net.minecraftforge.event.RegistryEvent; +import net.minecraftforge.event.world.GetCollisionBoxesEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.registry.GameRegistry; + +@Mod(modid = CollisionBoxesEventTest.MODID, name = "CollisionBoxesEventTest", version = "1.0", acceptableRemoteVersions = "*") +@Mod.EventBusSubscriber +public class CollisionBoxesEventTest +{ + public static final String MODID = "collisionboxexeventtest"; + + public static final boolean ENABLED = true; + @GameRegistry.ObjectHolder("box_block") + private static final Block BOX_BLOCK = null; + private static final ArrayList locations = new ArrayList<>(); + + @SubscribeEvent + public static void registerBlock(RegistryEvent.Register event) + { + if (ENABLED) + { + event.getRegistry().register(new BoxBlock()); + } + } + + @SubscribeEvent + public static void registerItem(RegistryEvent.Register event) + { + if (ENABLED) + { + event.getRegistry().register(new ItemBlock(BOX_BLOCK).setRegistryName(new ResourceLocation(MODID, "box_block"))); + } + } + + + @SubscribeEvent + public static void getBoxes(GetCollisionBoxesEvent event) + { + AxisAlignedBB box = event.getAabb(); + + for (BlockPos pos: locations) + { + for (EnumFacing facing: EnumFacing.HORIZONTALS) + { + AxisAlignedBB temp = new AxisAlignedBB(pos).offset(new Vec3d(facing.getDirectionVec())); + if (box.intersects(temp)) + event.getCollisionBoxesList().add(temp); + } + } + } + + private static class BoxBlock extends Block + { + + public BoxBlock() + { + super(Material.ROCK); + setRegistryName(new ResourceLocation(MODID, "box_block")); + setCreativeTab(CreativeTabs.MISC); + } + + @Override + public void breakBlock(World worldIn, BlockPos pos, IBlockState state) + { + locations.remove(pos); + } + + @Override + public void onBlockPlacedBy(World worldIn, BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack stack) + { + locations.add(pos); + } + + + @Override + public String getUnlocalizedName() { + return "CollisionBoxes event test block"; + } + + } +} \ No newline at end of file diff --git a/src/test/resources/assets/collisionboxexeventtest/blockstates/box_block.json b/src/test/resources/assets/collisionboxexeventtest/blockstates/box_block.json new file mode 100644 index 0000000000..0ca7c1abea --- /dev/null +++ b/src/test/resources/assets/collisionboxexeventtest/blockstates/box_block.json @@ -0,0 +1,10 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "minecraft:bedrock" + }, + "variants": { + "normal": [{}], + "inventory": [{}] + } +}