From ab64d1a1665e93b3d1fa46065119356eabe7efd3 Mon Sep 17 00:00:00 2001 From: cpw Date: Tue, 26 Jul 2016 17:16:42 -0400 Subject: [PATCH] Fix a vanilla bug with the blockstate ID map not being properly symmetric with respect to block.getStateFromMeta - closes #3012 properly but probably has a random MCJIRA ticket somewhere too. --- .../net/minecraft/block/Block.java.patch | 13 ++++ .../fml/common/registry/GameData.java | 5 +- .../registry/BlockStateMappingsTest.java | 61 +++++++++++++++++++ 3 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 src/test/java/net/minecraftforge/fml/common/registry/BlockStateMappingsTest.java diff --git a/patches/minecraft/net/minecraft/block/Block.java.patch b/patches/minecraft/net/minecraft/block/Block.java.patch index db17f1058d..29c57c1db7 100644 --- a/patches/minecraft/net/minecraft/block/Block.java.patch +++ b/patches/minecraft/net/minecraft/block/Block.java.patch @@ -1337,3 +1337,16 @@ public static void func_149671_p() { func_176215_a(0, field_176230_a, (new BlockAir()).func_149663_c("air")); +@@ -1169,11 +2323,7 @@ + } + else + { +- for (IBlockState iblockstate : block16.func_176194_O().func_177619_a()) +- { +- int k = field_149771_c.func_148757_b(block16) << 4 | block16.func_176201_c(iblockstate); +- field_176229_d.func_148746_a(iblockstate, k); +- } ++// Handled in GameData.BlockCallbacks - leaving tripwire as it seems to be special cased + } + } + } diff --git a/src/main/java/net/minecraftforge/fml/common/registry/GameData.java b/src/main/java/net/minecraftforge/fml/common/registry/GameData.java index 445136a42e..3ed1790f4d 100644 --- a/src/main/java/net/minecraftforge/fml/common/registry/GameData.java +++ b/src/main/java/net/minecraftforge/fml/common/registry/GameData.java @@ -288,7 +288,10 @@ public class GameData ClearableObjectIntIdentityMap blockstateMap = (ClearableObjectIntIdentityMap)slaves.get(BLOCKSTATE_TO_ID); for (IBlockState state : block.getBlockState().getValidStates()) { - blockstateMap.put(state, blockId << 4 | block.getMetaFromState(state)); + final int meta = block.getMetaFromState(state); // meta value the block assigns for the state + final int bsmeta = blockId << 4 | meta; // computed blockstateid for that meta + final IBlockState blockState = block.getStateFromMeta(meta); // state that the block assigns for the meta value + blockstateMap.put(blockState, bsmeta); // store assigned state with computed blockstateid } } diff --git a/src/test/java/net/minecraftforge/fml/common/registry/BlockStateMappingsTest.java b/src/test/java/net/minecraftforge/fml/common/registry/BlockStateMappingsTest.java new file mode 100644 index 0000000000..9f1e910ed6 --- /dev/null +++ b/src/test/java/net/minecraftforge/fml/common/registry/BlockStateMappingsTest.java @@ -0,0 +1,61 @@ +package net.minecraftforge.fml.common.registry; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockDirt; +import net.minecraft.block.material.Material; +import net.minecraft.block.properties.PropertyBool; +import net.minecraft.block.properties.PropertyInteger; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +import net.minecraft.init.Bootstrap; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; +import net.minecraftforge.fml.common.DummyModContainer; +import net.minecraftforge.fml.common.Loader; +import net.minecraftforge.fml.common.ModMetadata; +import org.junit.BeforeClass; +import org.junit.Test; + +import javax.annotation.Nonnull; + +import static org.junit.Assert.assertEquals; + +/** + * Test block state mappings bidirectionality + */ +public class BlockStateMappingsTest +{ + @BeforeClass + public static void setup() + { + System.setProperty("fml.queryResult", "confirm"); + System.setProperty("fml.doNotBackup", "true"); + Loader.instance(); + Bootstrap.register(); + Loader.instance().setupTestHarness(new DummyModContainer(new ModMetadata() {{ + modId = "test"; + }})); + } + + @Test + public void testBlockStates() + { + // stems have a problem where the blockstate for meta 0 is not the same in the blockstate map and from block.getStateFromMeta + // This test asserts that the two values should be equivalent + // Specifically, in vanilla the state for meta 0 in the blockstatemap is facing=east,age=0 but the block says it's facing=up,age=0 + Block bl = Blocks.MELON_STEM; + int id = Block.getIdFromBlock(bl); + for (int meta = 0; meta < 8; meta++) + { + int realbsm = id << 4 | meta; // computed blockstateid for this meta + IBlockState realst = bl.getStateFromMeta(meta); // The state that the block assigns to this meta + int bsm = GameData.getBlockStateIDMap().get(realst); // The blockstateid for the meta's state + IBlockState foundst = GameData.getBlockStateIDMap().getByValue(realbsm); // The state that is stored for the computed blockstateid + assertEquals("Got computed blockstate ids that match", realbsm, bsm); + assertEquals("Got equal states", realst, foundst); + } + } + +}