From 7c0d94ce9c7481fe4a122aa5731aa3becbaf317f Mon Sep 17 00:00:00 2001 From: LexManos Date: Fri, 16 Nov 2018 23:15:39 -0800 Subject: [PATCH] Patch work, most of block classes, and fix eclipse run configs. --- build.gradle | 20 +- .../PlayerAdvancements.java.patch | 19 + .../criterion/ItemPredicate.java.patch | 38 ++ .../net/minecraft/block/Block.java.patch | 188 ++++++++- .../block/BlockAbstractBanner.java.patch | 22 ++ .../net/minecraft/block/BlockBed.java.patch | 13 + .../net/minecraft/block/BlockBush.java.patch | 32 ++ .../minecraft/block/BlockCactus.java.patch | 63 +++ .../net/minecraft/block/BlockChest.java.patch | 11 + .../block/BlockChorusFlower.java.patch | 20 + .../net/minecraft/block/BlockCocoa.java.patch | 39 ++ .../net/minecraft/block/BlockCrops.java.patch | 64 +++ .../minecraft/block/BlockDeadBush.java.patch | 26 ++ .../block/BlockDirtSnowySpreadable.java.patch | 10 + .../block/BlockDoublePlant.java.patch | 19 + .../minecraft/block/BlockDropper.java.patch | 11 + .../block/BlockEnchantmentTable.java.patch | 11 + .../block/BlockEnderChest.java.patch | 11 + .../minecraft/block/BlockFalling.java.patch | 21 + .../minecraft/block/BlockFarmland.java.patch | 24 ++ .../net/minecraft/block/BlockFence.java.patch | 41 ++ .../minecraft/block/BlockFenceGate.java.patch | 26 ++ .../net/minecraft/block/BlockFire.java.patch | 208 ++++++++++ .../minecraft/block/BlockFlowerPot.java.patch | 11 + .../net/minecraft/block/BlockIce.java.patch | 25 ++ .../minecraft/block/BlockLadder.java.patch | 28 ++ .../minecraft/block/BlockLeaves.java.patch | 97 +++++ .../block/BlockMobSpawner.java.patch | 31 ++ .../minecraft/block/BlockMushroom.java.patch | 11 + .../block/BlockNetherWart.java.patch | 45 +++ .../net/minecraft/block/BlockNote.java.patch | 23 ++ .../net/minecraft/block/BlockOre.java.patch | 39 ++ .../block/BlockRailPowered.java.patch | 29 ++ .../BlockShearableDoublePlant.java.patch | 45 +++ .../BlockPistonStructureHelper.java.patch | 53 +++ .../block/state/IBlockState.java.patch | 8 + .../net/minecraft/world/World.java.patch | 23 +- .../world/dimension/Dimension.java.patch | 31 +- .../client/model/pipeline/BlockInfo.java | 2 +- .../minecraftforge/common/EnumPlantType.java | 2 +- .../net/minecraftforge/common/ForgeHooks.java | 15 +- .../net/minecraftforge/common/IPlantable.java | 22 +- .../net/minecraftforge/common/IShearable.java | 4 +- .../common/asm/RuntimeEnumExtender.java | 3 +- .../common/extensions/IForgeBlock.java | 372 ++++++++++++------ .../common/extensions/IForgeBlockState.java | 221 ++++++++--- .../event/ForgeEventFactory.java | 2 +- .../event/world/BlockEvent.java | 8 +- .../event/world/NoteBlockEvent.java | 37 +- .../net/minecraftforge/fml/UnsafeHacks.java | 3 - .../minecraftforge/registries/GameData.java | 14 +- 51 files changed, 1865 insertions(+), 276 deletions(-) create mode 100644 patches/minecraft/net/minecraft/advancements/PlayerAdvancements.java.patch create mode 100644 patches/minecraft/net/minecraft/advancements/criterion/ItemPredicate.java.patch create mode 100644 patches/minecraft/net/minecraft/block/BlockAbstractBanner.java.patch create mode 100644 patches/minecraft/net/minecraft/block/BlockBed.java.patch create mode 100644 patches/minecraft/net/minecraft/block/BlockBush.java.patch create mode 100644 patches/minecraft/net/minecraft/block/BlockCactus.java.patch create mode 100644 patches/minecraft/net/minecraft/block/BlockChest.java.patch create mode 100644 patches/minecraft/net/minecraft/block/BlockChorusFlower.java.patch create mode 100644 patches/minecraft/net/minecraft/block/BlockCocoa.java.patch create mode 100644 patches/minecraft/net/minecraft/block/BlockCrops.java.patch create mode 100644 patches/minecraft/net/minecraft/block/BlockDeadBush.java.patch create mode 100644 patches/minecraft/net/minecraft/block/BlockDirtSnowySpreadable.java.patch create mode 100644 patches/minecraft/net/minecraft/block/BlockDoublePlant.java.patch create mode 100644 patches/minecraft/net/minecraft/block/BlockDropper.java.patch create mode 100644 patches/minecraft/net/minecraft/block/BlockEnchantmentTable.java.patch create mode 100644 patches/minecraft/net/minecraft/block/BlockEnderChest.java.patch create mode 100644 patches/minecraft/net/minecraft/block/BlockFalling.java.patch create mode 100644 patches/minecraft/net/minecraft/block/BlockFarmland.java.patch create mode 100644 patches/minecraft/net/minecraft/block/BlockFence.java.patch create mode 100644 patches/minecraft/net/minecraft/block/BlockFenceGate.java.patch create mode 100644 patches/minecraft/net/minecraft/block/BlockFire.java.patch create mode 100644 patches/minecraft/net/minecraft/block/BlockFlowerPot.java.patch create mode 100644 patches/minecraft/net/minecraft/block/BlockIce.java.patch create mode 100644 patches/minecraft/net/minecraft/block/BlockLadder.java.patch create mode 100644 patches/minecraft/net/minecraft/block/BlockLeaves.java.patch create mode 100644 patches/minecraft/net/minecraft/block/BlockMobSpawner.java.patch create mode 100644 patches/minecraft/net/minecraft/block/BlockMushroom.java.patch create mode 100644 patches/minecraft/net/minecraft/block/BlockNetherWart.java.patch create mode 100644 patches/minecraft/net/minecraft/block/BlockNote.java.patch create mode 100644 patches/minecraft/net/minecraft/block/BlockOre.java.patch create mode 100644 patches/minecraft/net/minecraft/block/BlockRailPowered.java.patch create mode 100644 patches/minecraft/net/minecraft/block/BlockShearableDoublePlant.java.patch create mode 100644 patches/minecraft/net/minecraft/block/state/BlockPistonStructureHelper.java.patch diff --git a/build.gradle b/build.gradle index 6ade675d85..5cd0ef1430 100644 --- a/build.gradle +++ b/build.gradle @@ -119,11 +119,17 @@ project(':forge') { clientRun { main = 'net.minecraftforge.fml.LaunchTesting' environment = [ - target: 'fmldevclient' + target: 'fmldevclient', + assetDirectory: downloadAssets.output, + nativesDirectory: extractNatives.output ] properties = [ - target: 'fmldevclient', - assetDirectory: downloadAssets.output + 'org.lwjgl.util.Debug': 'true', + 'org.lwjgl.util.DebugLoader': 'true', + 'mc.version': MC_VERSION, + 'mcp.version': MCP_VERSION, + 'forge.version': "${project.version.substring(MC_VERSION.length() + 1)}".toString(), + 'forge.spec': SPEC_VERSION ] } serverRun { @@ -131,6 +137,12 @@ project(':forge') { environment = [ target: 'fmldevserver' ] + properties = [ + 'mc.version': MC_VERSION, + 'mcp.version': MCP_VERSION, + 'forge.version': "${project.version.substring(MC_VERSION.length() + 1)}".toString(), + 'forge.spec': SPEC_VERSION + ] } } @@ -207,7 +219,7 @@ project(':forge') { ] environment += [ target:'fmldevclient', - assetDirectory: file("${gradle.getGradleUserHomeDir()}/caches/forge_gradle/assets/"), + assetDirectory: downloadAssets.output, nativesDirectory: extractNatives.output ] workingDir 'runclient' diff --git a/patches/minecraft/net/minecraft/advancements/PlayerAdvancements.java.patch b/patches/minecraft/net/minecraft/advancements/PlayerAdvancements.java.patch new file mode 100644 index 0000000000..f4295d9111 --- /dev/null +++ b/patches/minecraft/net/minecraft/advancements/PlayerAdvancements.java.patch @@ -0,0 +1,19 @@ +--- a/net/minecraft/advancements/PlayerAdvancements.java ++++ b/net/minecraft/advancements/PlayerAdvancements.java +@@ -174,6 +174,8 @@ + } + + public boolean func_192750_a(Advancement p_192750_1_, String p_192750_2_) { ++ // Forge: don't grant advancements for fake players ++ if (this.field_192762_j instanceof net.minecraftforge.common.util.FakePlayer) return false; + boolean flag = false; + AdvancementProgress advancementprogress = this.func_192747_a(p_192750_1_); + boolean flag1 = advancementprogress.func_192105_a(); +@@ -186,6 +188,7 @@ + if (p_192750_1_.func_192068_c() != null && p_192750_1_.func_192068_c().func_193220_i() && this.field_192762_j.field_70170_p.func_82736_K().func_82766_b("announceAdvancements")) { + this.field_192756_d.func_184103_al().func_148539_a(new TextComponentTranslation("chat.type.advancement." + p_192750_1_.func_192068_c().func_192291_d().func_192307_a(), new Object[]{this.field_192762_j.func_145748_c_(), p_192750_1_.func_193123_j()})); + } ++ net.minecraftforge.common.ForgeHooks.onAdvancement(this.field_192762_j, p_192750_1_); + } + } + diff --git a/patches/minecraft/net/minecraft/advancements/criterion/ItemPredicate.java.patch b/patches/minecraft/net/minecraft/advancements/criterion/ItemPredicate.java.patch new file mode 100644 index 0000000000..4cd3ca5eb1 --- /dev/null +++ b/patches/minecraft/net/minecraft/advancements/criterion/ItemPredicate.java.patch @@ -0,0 +1,38 @@ +--- a/net/minecraft/advancements/criterion/ItemPredicate.java ++++ b/net/minecraft/advancements/criterion/ItemPredicate.java +@@ -23,6 +23,8 @@ + import net.minecraft.util.ResourceLocation; + + public class ItemPredicate { ++ private static final Map> custom_predicates = new java.util.HashMap<>(); ++ private static final Map> unmod_predicates = java.util.Collections.unmodifiableMap(custom_predicates); + public static final ItemPredicate field_192495_a = new ItemPredicate(); + @Nullable + private final Tag field_200018_b; +@@ -89,6 +91,11 @@ + public static ItemPredicate func_192492_a(@Nullable JsonElement p_192492_0_) { + if (p_192492_0_ != null && !p_192492_0_.isJsonNull()) { + JsonObject jsonobject = JsonUtils.func_151210_l(p_192492_0_, "item"); ++ if (jsonobject.has("type")) { ++ final ResourceLocation rl = new ResourceLocation(JsonUtils.func_151200_h(jsonobject, "type")); ++ if (custom_predicates.containsKey(rl)) return custom_predicates.get(rl).apply(jsonobject); ++ else throw new JsonSyntaxException("There is no ItemPredicate of type "+rl); ++ } + MinMaxBounds.IntBound minmaxbounds$intbound = MinMaxBounds.IntBound.func_211344_a(jsonobject.get("count")); + MinMaxBounds.IntBound minmaxbounds$intbound1 = MinMaxBounds.IntBound.func_211344_a(jsonobject.get("durability")); + if (jsonobject.has("data")) { +@@ -180,6 +187,14 @@ + } + } + ++ public static void register(ResourceLocation name, java.util.function.Function deserializer) { ++ custom_predicates.put(name, deserializer); ++ } ++ ++ public static Map> getPredicates() { ++ return unmod_predicates; ++ } ++ + public static class Builder { + private final List field_200312_a = Lists.newArrayList(); + @Nullable diff --git a/patches/minecraft/net/minecraft/block/Block.java.patch b/patches/minecraft/net/minecraft/block/Block.java.patch index d792d7d5b9..633ea725f8 100644 --- a/patches/minecraft/net/minecraft/block/Block.java.patch +++ b/patches/minecraft/net/minecraft/block/Block.java.patch @@ -1,6 +1,12 @@ --- a/net/minecraft/block/Block.java +++ b/net/minecraft/block/Block.java -@@ -74,7 +74,7 @@ +@@ -71,14 +71,19 @@ + import net.minecraft.world.World; + import net.minecraftforge.api.distmarker.Dist; + import net.minecraftforge.api.distmarker.OnlyIn; ++import net.minecraftforge.common.EnumPlantType; ++import net.minecraftforge.common.IPlantable; ++ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -8,8 +14,63 @@ +public class Block extends net.minecraftforge.registries.ForgeRegistryEntry implements IItemProvider, net.minecraftforge.common.extensions.IForgeBlock { protected static final Logger field_196273_d = LogManager.getLogger(); private static final ResourceLocation field_176230_a = new ResourceLocation("air"); - public static final RegistryNamespacedDefaultedByKey field_149771_c = new RegistryNamespacedDefaultedByKey(field_176230_a); -@@ -502,8 +502,8 @@ +- public static final RegistryNamespacedDefaultedByKey field_149771_c = new RegistryNamespacedDefaultedByKey(field_176230_a); +- public static final ObjectIntIdentityMap field_176229_d = new ObjectIntIdentityMap(); ++ @Deprecated //Forge: Do not use, use ForgeRegistries ++ public static final RegistryNamespacedDefaultedByKey field_149771_c = net.minecraftforge.registries.GameData.getWrapperDefaulted(Block.class); ++ @Deprecated //Forge: Do not use, use GameRegistry ++ public static final ObjectIntIdentityMap field_176229_d = net.minecraftforge.registries.GameData.getBlockStateIDMap(); + protected final int field_149784_t; + protected final float field_149782_v; + protected final float field_149781_w; +@@ -316,7 +321,7 @@ + + @Deprecated + public boolean func_196253_a(IBlockState p_196253_1_, BlockItemUseContext p_196253_2_) { +- return this.field_149764_J.func_76222_j() && p_196253_2_.func_195996_i().func_77973_b() != this.func_199767_j(); ++ return p_196253_1_.func_185904_a().func_76222_j() && p_196253_2_.func_195996_i().func_77973_b() != this.func_199767_j(); + } + + @Deprecated +@@ -328,8 +333,9 @@ + return this.field_149789_z; + } + ++ @Deprecated //Forge: New State sensitive version. + public boolean func_149716_u() { +- return this instanceof ITileEntityProvider; ++ return hasTileEntity(func_176223_P()); + } + + @Deprecated +@@ -340,11 +346,11 @@ + @Deprecated + @OnlyIn(Dist.CLIENT) + public int func_185484_c(IBlockState p_185484_1_, IWorldReader p_185484_2_, BlockPos p_185484_3_) { +- int i = p_185484_2_.func_175626_b(p_185484_3_, p_185484_1_.func_185906_d()); ++ int i = p_185484_2_.func_175626_b(p_185484_3_, p_185484_1_.getLightValue(p_185484_2_, p_185484_3_)); + if (i == 0 && p_185484_1_.func_177230_c() instanceof BlockSlab) { + p_185484_3_ = p_185484_3_.func_177977_b(); + p_185484_1_ = p_185484_2_.func_180495_p(p_185484_3_); +- return p_185484_2_.func_175626_b(p_185484_3_, p_185484_1_.func_185906_d()); ++ return p_185484_2_.func_175626_b(p_185484_3_, p_185484_1_.getLightValue(p_185484_2_, p_185484_3_)); + } else { + return i; + } +@@ -486,8 +492,12 @@ + + @Deprecated + public void func_196243_a(IBlockState p_196243_1_, World p_196243_2_, BlockPos p_196243_3_, IBlockState p_196243_4_, boolean p_196243_5_) { ++ if (hasTileEntity(p_196243_1_) && !(this instanceof BlockContainer)) { ++ p_196243_2_.func_175713_t(p_196243_3_); ++ } + } + ++ @Deprecated //Forge: Use fortune/location sensitive version + public int func_196264_a(IBlockState p_196264_1_, Random p_196264_2_) { + return 1; + } +@@ -502,30 +512,27 @@ if (f == -1.0F) { return 0.0F; } else { @@ -20,7 +81,64 @@ } } -@@ -625,6 +625,7 @@ + @Deprecated + public void func_196255_a(IBlockState p_196255_1_, World p_196255_2_, BlockPos p_196255_3_, float p_196255_4_, int p_196255_5_) { +- if (!p_196255_2_.field_72995_K) { +- int i = this.func_196251_a(p_196255_1_, p_196255_5_, p_196255_2_, p_196255_3_, p_196255_2_.field_73012_v); +- +- for(int j = 0; j < i; ++j) { +- if (!(p_196255_4_ < 1.0F) || !(p_196255_2_.field_73012_v.nextFloat() > p_196255_4_)) { +- Item item = this.func_199769_a(p_196255_1_, p_196255_2_, p_196255_3_, p_196255_5_).func_199767_j(); +- if (item != Items.field_190931_a) { +- func_180635_a(p_196255_2_, p_196255_3_, new ItemStack(item)); +- } +- } +- } +- ++ if (!p_196255_2_.field_72995_K && !p_196255_2_.restoringBlockSnapshots) { // do not drop items while restoring blockstates, prevents item dupe ++ NonNullList drops = NonNullList.func_191196_a(); ++ getDrops(p_196255_1_, drops, p_196255_2_, p_196255_3_, p_196255_5_); // use the old method until it gets removed, for backward compatibility ++ p_196255_4_ = net.minecraftforge.event.ForgeEventFactory.fireBlockHarvesting(drops, p_196255_2_, p_196255_3_, p_196255_1_, p_196255_5_, p_196255_4_, false, harvesters.get()); ++ drops.forEach(stack -> func_180635_a(p_196255_2_, p_196255_3_, stack)); + } + } + + public static void func_180635_a(World p_180635_0_, BlockPos p_180635_1_, ItemStack p_180635_2_) { +- if (!p_180635_0_.field_72995_K && !p_180635_2_.func_190926_b() && p_180635_0_.func_82736_K().func_82766_b("doTileDrops")) { ++ if (!p_180635_0_.field_72995_K && !p_180635_2_.func_190926_b() && p_180635_0_.func_82736_K().func_82766_b("doTileDrops") && !p_180635_0_.restoringBlockSnapshots) {// do not drop items while restoring blockstates, prevents item dupe ++ if (captureDrops.get()) { ++ capturedDrops.get().add(p_180635_2_); ++ return; ++ } + float f = 0.5F; + double d0 = (double)(p_180635_0_.field_73012_v.nextFloat() * 0.5F) + 0.25D; + double d1 = (double)(p_180635_0_.field_73012_v.nextFloat() * 0.5F) + 0.25D; +@@ -547,6 +554,7 @@ + + } + ++ @Deprecated //Forge: State sensitive version + public float func_149638_a() { + return this.field_149781_w; + } +@@ -615,16 +623,22 @@ + public void func_180657_a(World p_180657_1_, EntityPlayer p_180657_2_, BlockPos p_180657_3_, IBlockState p_180657_4_, @Nullable TileEntity p_180657_5_, ItemStack p_180657_6_) { + p_180657_2_.func_71029_a(StatList.field_188065_ae.func_199076_b(this)); + p_180657_2_.func_71020_j(0.005F); +- if (this.func_149700_E() && EnchantmentHelper.func_77506_a(Enchantments.field_185306_r, p_180657_6_) > 0) { ++ if (this.canSilkHarvest(p_180657_4_, p_180657_1_, p_180657_3_, p_180657_2_) && EnchantmentHelper.func_77506_a(Enchantments.field_185306_r, p_180657_6_) > 0) { ++ NonNullList items = NonNullList.func_191196_a(); + ItemStack itemstack = this.func_180643_i(p_180657_4_); +- func_180635_a(p_180657_1_, p_180657_3_, itemstack); ++ if (!itemstack.func_190926_b()) items.add(itemstack); ++ net.minecraftforge.event.ForgeEventFactory.fireBlockHarvesting(items, p_180657_1_, p_180657_3_, p_180657_4_, 0, 1.0f, true, p_180657_2_); ++ items.forEach(e -> func_180635_a(p_180657_1_, p_180657_3_, e)); + } else { ++ harvesters.set(p_180657_2_); + int i = EnchantmentHelper.func_77506_a(Enchantments.field_185308_t, p_180657_6_); + p_180657_4_.func_196949_c(p_180657_1_, p_180657_3_, i); ++ harvesters.set(null); + } } @@ -28,7 +146,15 @@ protected boolean func_149700_E() { return this.func_176223_P().func_185917_h() && !this.func_149716_u(); } -@@ -755,6 +756,7 @@ +@@ -681,6 +695,7 @@ + p_176216_2_.field_70181_x = 0.0D; + } + ++ @Deprecated // Forge: Use more sensitive version below: getPickBlock + public ItemStack func_185473_a(IBlockReader p_185473_1_, BlockPos p_185473_2_, IBlockState p_185473_3_) { + return new ItemStack(this); + } +@@ -755,6 +770,7 @@ } } @@ -36,12 +162,22 @@ public SoundType func_185467_w() { return this.field_149762_H; } -@@ -1604,4 +1606,56 @@ +@@ -1147,7 +1163,7 @@ + func_196254_a("chiseled_quartz_block", new Block(Block.Builder.func_200949_a(Material.field_151576_e, MapColor.field_151677_p).func_200943_b(0.8F))); + func_196254_a("quartz_pillar", new BlockRotatedPillar(Block.Builder.func_200949_a(Material.field_151576_e, MapColor.field_151677_p).func_200943_b(0.8F))); + func_196254_a("quartz_stairs", new BlockStairs(block42.func_176223_P(), Block.Builder.func_200950_a(block42))); +- func_196254_a("activator_rail", new BlockRailPowered(Block.Builder.func_200945_a(Material.field_151594_q).func_200942_a().func_200943_b(0.7F).func_200947_a(SoundType.field_185852_e))); ++ func_196254_a("activator_rail", new BlockRailPowered(Block.Builder.func_200945_a(Material.field_151594_q).func_200942_a().func_200943_b(0.7F).func_200947_a(SoundType.field_185852_e), true)); + func_196254_a("dropper", new BlockDropper(Block.Builder.func_200945_a(Material.field_151576_e).func_200943_b(3.5F))); + func_196254_a("white_terracotta", new Block(Block.Builder.func_200949_a(Material.field_151576_e, MapColor.field_193561_M).func_200948_a(1.25F, 4.2F))); + func_196254_a("orange_terracotta", new Block(Block.Builder.func_200949_a(Material.field_151576_e, MapColor.field_193562_N).func_200948_a(1.25F, 4.2F))); +@@ -1604,4 +1620,83 @@ return Objects.hash(this.field_212164_a, this.field_212165_b, this.field_212166_c); } } + /* ======================================== FORGE START =====================================*/ -+ private ThreadLocal silkCheck = new ThreadLocal<>(); ++ protected Random RANDOM = new Random(); ++ protected ThreadLocal harvesters = new ThreadLocal<>(); + private net.minecraftforge.common.ToolType harvestTool; + private int harvestLevel; + protected static ThreadLocal captureDrops = ThreadLocal.withInitial(() -> false); @@ -68,12 +204,6 @@ + return this.func_149700_E() && !state.hasTileEntity(); + } + -+ @Override -+ public void onBlockExploded(IBlockState state, World world, BlockPos pos, Explosion explosion) { -+ world.func_175698_g(pos); -+ func_180652_a(world, pos, explosion); -+ } -+ + @Nullable + @Override + public net.minecraftforge.common.ToolType getHarvestTool(IBlockState state) { @@ -85,6 +215,38 @@ + return harvestLevel; //TODO: RE-Evaluate + } + ++ @Override ++ public boolean canSustainPlant(IBlockState state, IBlockReader world, BlockPos pos, EnumFacing facing, IPlantable plantable) { ++ IBlockState plant = plantable.getPlant(world, pos.func_177972_a(facing)); ++ EnumPlantType type = plantable.getPlantType(world, pos.func_177972_a(facing)); ++ ++ if (plant.func_177230_c() == Blocks.field_150434_aF) ++ return this.getBlock() == Blocks.field_150434_aF || this.getBlock() == Blocks.field_150354_m || this.getBlock() == Blocks.field_196611_F; ++ ++ if (plant.func_177230_c() == Blocks.field_196608_cF) ++ return true; ++ ++ if (plantable instanceof BlockBush && ((BlockBush)plantable).func_200014_a_(state, world, pos)) ++ return true; ++ ++ switch (type) { ++ case Desert: return this.getBlock() == Blocks.field_150354_m || this.getBlock() == Blocks.field_150405_ch || this.getBlock() instanceof BlockGlazedTerracotta; ++ case Nether: return this.getBlock() == Blocks.field_150425_aM; ++ case Crop: return this.getBlock() == Blocks.field_150458_ak; ++ case Cave: return state.func_185896_q(); ++ case Plains: return this.getBlock() == Blocks.field_150349_c || this.getBlock() == Blocks.field_150346_d || this.getBlock() == Blocks.field_150458_ak; ++ case Water: return state.func_185904_a() == Material.field_151586_h; //&& state.getValue(BlockLiquidWrapper) ++ case Beach: ++ boolean isBeach = this.getBlock() == Blocks.field_150349_c || this.getBlock() == Blocks.field_150346_d || this.getBlock() == Blocks.field_150354_m; ++ boolean hasWater = (world.func_180495_p(pos.func_177974_f()).func_185904_a() == Material.field_151586_h || ++ world.func_180495_p(pos.func_177976_e()).func_185904_a() == Material.field_151586_h || ++ world.func_180495_p(pos.func_177978_c()).func_185904_a() == Material.field_151586_h || ++ world.func_180495_p(pos.func_177968_d()).func_185904_a() == Material.field_151586_h); ++ return isBeach && hasWater; ++ } ++ return false; ++ } ++ + static { + net.minecraftforge.common.ForgeHooks.setBlockToolSetter((block, tool, level) -> { + block.harvestTool = tool; diff --git a/patches/minecraft/net/minecraft/block/BlockAbstractBanner.java.patch b/patches/minecraft/net/minecraft/block/BlockAbstractBanner.java.patch new file mode 100644 index 0000000000..4a420fe599 --- /dev/null +++ b/patches/minecraft/net/minecraft/block/BlockAbstractBanner.java.patch @@ -0,0 +1,22 @@ +--- a/net/minecraft/block/BlockAbstractBanner.java ++++ b/net/minecraft/block/BlockAbstractBanner.java +@@ -50,7 +50,7 @@ + } + + public void func_196255_a(IBlockState p_196255_1_, World p_196255_2_, BlockPos p_196255_3_, float p_196255_4_, int p_196255_5_) { +- func_180635_a(p_196255_2_, p_196255_3_, this.func_185473_a(p_196255_2_, p_196255_3_, p_196255_1_)); ++ super.func_196255_a(p_196255_1_, p_196255_2_, p_196255_3_, p_196255_4_, p_196255_5_); + } + + public void func_180657_a(World p_180657_1_, EntityPlayer p_180657_2_, BlockPos p_180657_3_, IBlockState p_180657_4_, @Nullable TileEntity p_180657_5_, ItemStack p_180657_6_) { +@@ -73,4 +73,10 @@ + public EnumDyeColor func_196285_M_() { + return this.field_196286_a; + } ++ ++ @Override ++ public void getDrops(IBlockState state, net.minecraft.util.NonNullList drops, World world, BlockPos pos, int fortune) { ++ TileEntity te = world.func_175625_s(pos); ++ drops.add((te instanceof TileEntityBanner) ? ((TileEntityBanner)te).func_190615_l(state) : func_185473_a(world, pos, state)); ++ } + } diff --git a/patches/minecraft/net/minecraft/block/BlockBed.java.patch b/patches/minecraft/net/minecraft/block/BlockBed.java.patch new file mode 100644 index 0000000000..3c998966e4 --- /dev/null +++ b/patches/minecraft/net/minecraft/block/BlockBed.java.patch @@ -0,0 +1,13 @@ +--- a/net/minecraft/block/BlockBed.java ++++ b/net/minecraft/block/BlockBed.java +@@ -66,7 +66,9 @@ + } + } + +- if (p_196250_2_.field_73011_w.func_76567_e() && p_196250_2_.func_180494_b(p_196250_3_) != Biomes.field_76778_j) { ++ net.minecraft.world.dimension.Dimension.SleepResult sleepResult = p_196250_2_.field_73011_w.canSleepAt(p_196250_4_, p_196250_3_); ++ if (sleepResult != net.minecraft.world.dimension.Dimension.SleepResult.BED_EXPLODES) { ++ if (sleepResult == net.minecraft.world.dimension.Dimension.SleepResult.DENY) return true; + if (p_196250_1_.func_177229_b(field_176471_b)) { + EntityPlayer entityplayer = this.func_176470_e(p_196250_2_, p_196250_3_); + if (entityplayer != null) { diff --git a/patches/minecraft/net/minecraft/block/BlockBush.java.patch b/patches/minecraft/net/minecraft/block/BlockBush.java.patch new file mode 100644 index 0000000000..2ebb73e446 --- /dev/null +++ b/patches/minecraft/net/minecraft/block/BlockBush.java.patch @@ -0,0 +1,32 @@ +--- a/net/minecraft/block/BlockBush.java ++++ b/net/minecraft/block/BlockBush.java +@@ -10,7 +10,7 @@ + import net.minecraft.world.IWorld; + import net.minecraft.world.IWorldReaderBase; + +-public class BlockBush extends Block { ++public class BlockBush extends Block implements net.minecraftforge.common.IPlantable { + protected BlockBush(Block.Builder p_i48437_1_) { + super(p_i48437_1_); + } +@@ -26,6 +26,8 @@ + + public boolean func_196260_a(IBlockState p_196260_1_, IWorldReaderBase p_196260_2_, BlockPos p_196260_3_) { + BlockPos blockpos = p_196260_3_.func_177977_b(); ++ if (p_196260_1_.func_177230_c() == this) //Forge: This function is called during world gen and placement, before this block is set, so if we are not 'here' then assume it's the pre-check. ++ return p_196260_2_.func_180495_p(blockpos).canSustainPlant(p_196260_2_, blockpos, EnumFacing.UP, this); + return this.func_200014_a_(p_196260_2_.func_180495_p(blockpos), p_196260_2_, blockpos); + } + +@@ -44,4 +46,11 @@ + public int func_200011_d(IBlockState p_200011_1_, IBlockReader p_200011_2_, BlockPos p_200011_3_) { + return 0; + } ++ ++ @Override ++ public IBlockState getPlant(IBlockReader world, BlockPos pos) { ++ IBlockState state = world.func_180495_p(pos); ++ if (state.func_177230_c() != this) return func_176223_P(); ++ return state; ++ } + } diff --git a/patches/minecraft/net/minecraft/block/BlockCactus.java.patch b/patches/minecraft/net/minecraft/block/BlockCactus.java.patch new file mode 100644 index 0000000000..dde294a1ea --- /dev/null +++ b/patches/minecraft/net/minecraft/block/BlockCactus.java.patch @@ -0,0 +1,63 @@ +--- a/net/minecraft/block/BlockCactus.java ++++ b/net/minecraft/block/BlockCactus.java +@@ -21,7 +21,7 @@ + import net.minecraft.world.IWorldReaderBase; + import net.minecraft.world.World; + +-public class BlockCactus extends Block { ++public class BlockCactus extends Block implements net.minecraftforge.common.IPlantable { + public static final IntegerProperty field_176587_a = BlockStateProperties.field_208171_X; + protected static final VoxelShape field_196400_b = Block.func_208617_a(1.0D, 0.0D, 1.0D, 15.0D, 15.0D, 15.0D); + protected static final VoxelShape field_196401_c = Block.func_208617_a(1.0D, 0.0D, 1.0D, 15.0D, 16.0D, 15.0D); +@@ -32,6 +32,7 @@ + } + + public void func_196267_b(IBlockState p_196267_1_, World p_196267_2_, BlockPos p_196267_3_, Random p_196267_4_) { ++ if (!p_196267_2_.func_205050_e(p_196267_3_, 1)) return; // Forge: prevent growing cactus from loading unloaded chunks with block update + if (!p_196267_1_.func_196955_c(p_196267_2_, p_196267_3_)) { + p_196267_2_.func_175655_b(p_196267_3_, true); + } else { +@@ -44,6 +45,7 @@ + + if (i < 3) { + int j = p_196267_1_.func_177229_b(field_176587_a); ++ if(net.minecraftforge.common.ForgeHooks.onCropsGrowPre(p_196267_2_, blockpos, p_196267_1_, true)) { + if (j == 15) { + p_196267_2_.func_175656_a(blockpos, this.func_176223_P()); + IBlockState iblockstate = (IBlockState)p_196267_1_.func_206870_a(field_176587_a, Integer.valueOf(0)); +@@ -52,7 +54,8 @@ + } else { + p_196267_2_.func_180501_a(p_196267_3_, (IBlockState)p_196267_1_.func_206870_a(field_176587_a, Integer.valueOf(j + 1)), 4); + } +- ++ net.minecraftforge.common.ForgeHooks.onCropsGrowPost(p_196267_2_, p_196267_3_, p_196267_1_); ++ } + } + } + } +@@ -91,8 +94,8 @@ + } + } + +- Block block = p_196260_2_.func_180495_p(p_196260_3_.func_177977_b()).func_177230_c(); +- return (block == Blocks.field_150434_aF || block == Blocks.field_150354_m || block == Blocks.field_196611_F) && !p_196260_2_.func_180495_p(p_196260_3_.func_177984_a()).func_185904_a().func_76224_d(); ++ IBlockState soil = p_196260_2_.func_180495_p(p_196260_3_.func_177977_b()); ++ return soil.canSustainPlant(p_196260_2_, p_196260_3_.func_177977_b(), EnumFacing.UP, this) && !p_196260_2_.func_180495_p(p_196260_3_.func_177984_a()).func_185904_a().func_76224_d(); + } + + public void func_196262_a(IBlockState p_196262_1_, World p_196262_2_, BlockPos p_196262_3_, Entity p_196262_4_) { +@@ -114,4 +117,14 @@ + public boolean func_196266_a(IBlockState p_196266_1_, IBlockReader p_196266_2_, BlockPos p_196266_3_, PathType p_196266_4_) { + return false; + } ++ ++ @Override ++ public net.minecraftforge.common.EnumPlantType getPlantType(IBlockReader world, BlockPos pos) { ++ return net.minecraftforge.common.EnumPlantType.Desert; ++ } ++ ++ @Override ++ public IBlockState getPlant(IBlockReader world, BlockPos pos) { ++ return func_176223_P(); ++ } + } diff --git a/patches/minecraft/net/minecraft/block/BlockChest.java.patch b/patches/minecraft/net/minecraft/block/BlockChest.java.patch new file mode 100644 index 0000000000..a9f7af1b41 --- /dev/null +++ b/patches/minecraft/net/minecraft/block/BlockChest.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/block/BlockChest.java ++++ b/net/minecraft/block/BlockChest.java +@@ -258,7 +258,7 @@ + } + + private boolean func_176456_n(IBlockReader p_176456_1_, BlockPos p_176456_2_) { +- return p_176456_1_.func_180495_p(p_176456_2_.func_177984_a()).func_185915_l(); ++ return p_176456_1_.func_180495_p(p_176456_2_.func_177984_a()).doesSideBlockChestOpening(p_176456_1_, p_176456_2_.func_177984_a(), EnumFacing.DOWN); + } + + private boolean func_176453_o(World p_176453_1_, BlockPos p_176453_2_) { diff --git a/patches/minecraft/net/minecraft/block/BlockChorusFlower.java.patch b/patches/minecraft/net/minecraft/block/BlockChorusFlower.java.patch new file mode 100644 index 0000000000..b739b3ed09 --- /dev/null +++ b/patches/minecraft/net/minecraft/block/BlockChorusFlower.java.patch @@ -0,0 +1,20 @@ +--- a/net/minecraft/block/BlockChorusFlower.java ++++ b/net/minecraft/block/BlockChorusFlower.java +@@ -42,7 +42,7 @@ + BlockPos blockpos = p_196267_3_.func_177984_a(); + if (p_196267_2_.func_175623_d(blockpos) && blockpos.func_177956_o() < 256) { + int i = p_196267_1_.func_177229_b(field_185607_a); +- if (i < 5) { ++ if (i < 5 && net.minecraftforge.common.ForgeHooks.onCropsGrowPre(p_196267_2_, blockpos, p_196267_1_, true)) { + boolean flag = false; + boolean flag1 = false; + IBlockState iblockstate = p_196267_2_.func_180495_p(p_196267_3_.func_177977_b()); +@@ -99,7 +99,7 @@ + } else { + this.func_185605_c(p_196267_2_, p_196267_3_); + } +- ++ net.minecraftforge.common.ForgeHooks.onCropsGrowPost(p_196267_2_, p_196267_3_, p_196267_1_); + } + } + } diff --git a/patches/minecraft/net/minecraft/block/BlockCocoa.java.patch b/patches/minecraft/net/minecraft/block/BlockCocoa.java.patch new file mode 100644 index 0000000000..52e4517b1d --- /dev/null +++ b/patches/minecraft/net/minecraft/block/BlockCocoa.java.patch @@ -0,0 +1,39 @@ +--- a/net/minecraft/block/BlockCocoa.java ++++ b/net/minecraft/block/BlockCocoa.java +@@ -34,10 +34,11 @@ + } + + public void func_196267_b(IBlockState p_196267_1_, World p_196267_2_, BlockPos p_196267_3_, Random p_196267_4_) { +- if (p_196267_2_.field_73012_v.nextInt(5) == 0) { ++ if (true) { + int i = p_196267_1_.func_177229_b(field_176501_a); +- if (i < 2) { ++ if (i < 2 && net.minecraftforge.common.ForgeHooks.onCropsGrowPre(p_196267_2_, p_196267_3_, p_196267_1_, p_196267_2_.field_73012_v.nextInt(5) == 0)) { + p_196267_2_.func_180501_a(p_196267_3_, (IBlockState)p_196267_1_.func_206870_a(field_176501_a, Integer.valueOf(i + 1)), 2); ++ net.minecraftforge.common.ForgeHooks.onCropsGrowPost(p_196267_2_, p_196267_3_, p_196267_1_); + } + } + +@@ -90,14 +91,20 @@ + } + + public void func_196255_a(IBlockState p_196255_1_, World p_196255_2_, BlockPos p_196255_3_, float p_196255_4_, int p_196255_5_) { +- int i = p_196255_1_.func_177229_b(field_176501_a); ++ super.func_196255_a(p_196255_1_, p_196255_2_, p_196255_3_, p_196255_4_, p_196255_5_); ++ } ++ ++ @Override ++ public void getDrops(IBlockState state, net.minecraft.util.NonNullList drops, World world, BlockPos pos, int fortune) { ++ super.getDrops(state, drops, world, pos, fortune); ++ int i = state.func_177229_b(field_176501_a); + int j = 1; + if (i >= 2) { + j = 3; + } + + for(int k = 0; k < j; ++k) { +- func_180635_a(p_196255_2_, p_196255_3_, new ItemStack(Items.field_196130_bo)); ++ drops.add(new ItemStack(Items.field_196130_bo)); + } + + } diff --git a/patches/minecraft/net/minecraft/block/BlockCrops.java.patch b/patches/minecraft/net/minecraft/block/BlockCrops.java.patch new file mode 100644 index 0000000000..3e084ec777 --- /dev/null +++ b/patches/minecraft/net/minecraft/block/BlockCrops.java.patch @@ -0,0 +1,64 @@ +--- a/net/minecraft/block/BlockCrops.java ++++ b/net/minecraft/block/BlockCrops.java +@@ -9,6 +9,7 @@ + import net.minecraft.state.StateContainer; + import net.minecraft.state.properties.BlockStateProperties; + import net.minecraft.util.IItemProvider; ++import net.minecraft.util.NonNullList; + import net.minecraft.util.math.BlockPos; + import net.minecraft.util.math.MathHelper; + import net.minecraft.util.math.shapes.VoxelShape; +@@ -55,12 +56,14 @@ + + public void func_196267_b(IBlockState p_196267_1_, World p_196267_2_, BlockPos p_196267_3_, Random p_196267_4_) { + super.func_196267_b(p_196267_1_, p_196267_2_, p_196267_3_, p_196267_4_); ++ if (!p_196267_2_.func_205050_e(p_196267_3_, 1)) return; // Forge: prevent loading unloaded chunks when checking neighbor's light + if (p_196267_2_.func_201669_a(p_196267_3_.func_177984_a(), 0) >= 9) { + int i = this.func_185527_x(p_196267_1_); + if (i < this.func_185526_g()) { + float f = func_180672_a(this, p_196267_2_, p_196267_3_); +- if (p_196267_4_.nextInt((int)(25.0F / f) + 1) == 0) { ++ if (net.minecraftforge.common.ForgeHooks.onCropsGrowPre(p_196267_2_, p_196267_3_, p_196267_1_, p_196267_4_.nextInt((int)(25.0F / f) + 1) == 0)) { + p_196267_2_.func_180501_a(p_196267_3_, this.func_185528_e(i + 1), 2); ++ net.minecraftforge.common.ForgeHooks.onCropsGrowPost(p_196267_2_, p_196267_3_, p_196267_1_); + } + } + } +@@ -89,9 +92,9 @@ + for(int j = -1; j <= 1; ++j) { + float f1 = 0.0F; + IBlockState iblockstate = p_180672_1_.func_180495_p(blockpos.func_177982_a(i, 0, j)); +- if (iblockstate.func_177230_c() == Blocks.field_150458_ak) { ++ if (iblockstate.canSustainPlant(p_180672_1_, blockpos.func_177982_a(i, 0, j), net.minecraft.util.EnumFacing.UP, (net.minecraftforge.common.IPlantable)p_180672_0_)) { + f1 = 1.0F; +- if (iblockstate.func_177229_b(BlockFarmland.field_176531_a) > 0) { ++ if (iblockstate.isFertile(p_180672_1_, blockpos.func_177982_a(i, 0, j))) { + f1 = 3.0F; + } + } +@@ -135,15 +138,19 @@ + } + + public void func_196255_a(IBlockState p_196255_1_, World p_196255_2_, BlockPos p_196255_3_, float p_196255_4_, int p_196255_5_) { +- super.func_196255_a(p_196255_1_, p_196255_2_, p_196255_3_, p_196255_4_, 0); +- if (!p_196255_2_.field_72995_K) { +- int i = this.func_185527_x(p_196255_1_); ++ super.func_196255_a(p_196255_1_, p_196255_2_, p_196255_3_, p_196255_4_, p_196255_5_); ++ } ++ ++ @Override ++ public void getDrops(IBlockState state, NonNullList drops, World world, BlockPos pos, int fortune) { ++ { ++ int i = this.func_185527_x(state); + if (i >= this.func_185526_g()) { +- int j = 3 + p_196255_5_; ++ int j = 3 + fortune; + + for(int k = 0; k < j; ++k) { +- if (p_196255_2_.field_73012_v.nextInt(2 * this.func_185526_g()) <= i) { +- func_180635_a(p_196255_2_, p_196255_3_, new ItemStack(this.func_199772_f())); ++ if (world.field_73012_v.nextInt(2 * this.func_185526_g()) <= i) { ++ drops.add(new ItemStack(this.func_199772_f())); + } + } + } diff --git a/patches/minecraft/net/minecraft/block/BlockDeadBush.java.patch b/patches/minecraft/net/minecraft/block/BlockDeadBush.java.patch new file mode 100644 index 0000000000..5c25396d6a --- /dev/null +++ b/patches/minecraft/net/minecraft/block/BlockDeadBush.java.patch @@ -0,0 +1,26 @@ +--- a/net/minecraft/block/BlockDeadBush.java ++++ b/net/minecraft/block/BlockDeadBush.java +@@ -14,7 +14,7 @@ + import net.minecraft.world.IBlockReader; + import net.minecraft.world.World; + +-public class BlockDeadBush extends BlockBush { ++public class BlockDeadBush extends BlockBush implements net.minecraftforge.common.IShearable { + protected static final VoxelShape field_196397_a = Block.func_208617_a(2.0D, 0.0D, 2.0D, 14.0D, 13.0D, 14.0D); + + protected BlockDeadBush(Block.Builder p_i48418_1_) { +@@ -46,4 +46,14 @@ + + super.func_180657_a(p_180657_1_, p_180657_2_, p_180657_3_, flag ? Blocks.field_150350_a.func_176223_P() : p_180657_4_, p_180657_5_, p_180657_6_); + } ++ ++ @Override ++ public boolean isShearable(ItemStack item, net.minecraft.world.IWorldReader world, BlockPos pos) { ++ return false; ++ } ++ ++ @Override ++ public java.util.List onSheared(ItemStack item, net.minecraft.world.IWorldReader world, BlockPos pos, int fortune) { ++ return java.util.Arrays.asList(new ItemStack(Blocks.field_196555_aI)); ++ } + } diff --git a/patches/minecraft/net/minecraft/block/BlockDirtSnowySpreadable.java.patch b/patches/minecraft/net/minecraft/block/BlockDirtSnowySpreadable.java.patch new file mode 100644 index 0000000000..11cee0ddcc --- /dev/null +++ b/patches/minecraft/net/minecraft/block/BlockDirtSnowySpreadable.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/block/BlockDirtSnowySpreadable.java ++++ b/net/minecraft/block/BlockDirtSnowySpreadable.java +@@ -25,6 +25,7 @@ + + public void func_196267_b(IBlockState p_196267_1_, World p_196267_2_, BlockPos p_196267_3_, Random p_196267_4_) { + if (!p_196267_2_.field_72995_K) { ++ if (!p_196267_2_.func_205050_e(p_196267_3_, 3)) return; // Forge: prevent loading unloaded chunks when checking neighbor's light and spreading + if (!func_196383_a(p_196267_2_, p_196267_3_)) { + p_196267_2_.func_175656_a(p_196267_3_, Blocks.field_150346_d.func_176223_P()); + } else { diff --git a/patches/minecraft/net/minecraft/block/BlockDoublePlant.java.patch b/patches/minecraft/net/minecraft/block/BlockDoublePlant.java.patch new file mode 100644 index 0000000000..57b78b8539 --- /dev/null +++ b/patches/minecraft/net/minecraft/block/BlockDoublePlant.java.patch @@ -0,0 +1,19 @@ +--- a/net/minecraft/block/BlockDoublePlant.java ++++ b/net/minecraft/block/BlockDoublePlant.java +@@ -43,7 +43,7 @@ + @Nullable + public IBlockState func_196258_a(BlockItemUseContext p_196258_1_) { + BlockPos blockpos = p_196258_1_.func_195995_a(); +- return blockpos.func_177956_o() < 255 && p_196258_1_.func_195991_k().func_180495_p(blockpos.func_177984_a()).func_196953_a(p_196258_1_) ? super.func_196258_a(p_196258_1_) : null; ++ return blockpos.func_177956_o() < p_196258_1_.func_195991_k().func_72800_K() - 1 && p_196258_1_.func_195991_k().func_180495_p(blockpos.func_177984_a()).func_196953_a(p_196258_1_) ? super.func_196258_a(p_196258_1_) : null; + } + + public void func_180633_a(World p_180633_1_, BlockPos p_180633_2_, IBlockState p_180633_3_, EntityLivingBase p_180633_4_, ItemStack p_180633_5_) { +@@ -51,6 +51,7 @@ + } + + public boolean func_196260_a(IBlockState p_196260_1_, IWorldReaderBase p_196260_2_, BlockPos p_196260_3_) { ++ if (p_196260_1_.func_177230_c() != this) return super.func_196260_a(p_196260_1_, p_196260_2_, p_196260_3_); //Forge: This function is called during world gen and placement, before this block is set, so if we are not 'here' then assume it's the pre-check. + if (p_196260_1_.func_177229_b(field_176492_b) != DoubleBlockHalf.UPPER) { + return super.func_196260_a(p_196260_1_, p_196260_2_, p_196260_3_); + } else { diff --git a/patches/minecraft/net/minecraft/block/BlockDropper.java.patch b/patches/minecraft/net/minecraft/block/BlockDropper.java.patch new file mode 100644 index 0000000000..f638945049 --- /dev/null +++ b/patches/minecraft/net/minecraft/block/BlockDropper.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/block/BlockDropper.java ++++ b/net/minecraft/block/BlockDropper.java +@@ -37,7 +37,7 @@ + p_176439_1_.func_175718_b(1001, p_176439_2_, 0); + } else { + ItemStack itemstack = tileentitydispenser.func_70301_a(i); +- if (!itemstack.func_190926_b()) { ++ if (!itemstack.func_190926_b() && net.minecraftforge.items.VanillaInventoryCodeHooks.dropperInsertHook(p_176439_1_, p_176439_2_, tileentitydispenser, i, itemstack)) { + EnumFacing enumfacing = (EnumFacing)p_176439_1_.func_180495_p(p_176439_2_).func_177229_b(field_176441_a); + IInventory iinventory = TileEntityHopper.func_195484_a(p_176439_1_, p_176439_2_.func_177972_a(enumfacing)); + ItemStack itemstack1; diff --git a/patches/minecraft/net/minecraft/block/BlockEnchantmentTable.java.patch b/patches/minecraft/net/minecraft/block/BlockEnchantmentTable.java.patch new file mode 100644 index 0000000000..c5df74a30c --- /dev/null +++ b/patches/minecraft/net/minecraft/block/BlockEnchantmentTable.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/block/BlockEnchantmentTable.java ++++ b/net/minecraft/block/BlockEnchantmentTable.java +@@ -49,7 +49,7 @@ + if (p_180655_4_.nextInt(16) == 0) { + for(int k = 0; k <= 1; ++k) { + BlockPos blockpos = p_180655_3_.func_177982_a(i, k, j); +- if (p_180655_2_.func_180495_p(blockpos).func_177230_c() == Blocks.field_150342_X) { ++ if (p_180655_2_.func_180495_p(blockpos).getEnchantPowerBonus(p_180655_2_, p_180655_3_) > 0) { + if (!p_180655_2_.func_175623_d(p_180655_3_.func_177982_a(i / 2, 0, j / 2))) { + break; + } diff --git a/patches/minecraft/net/minecraft/block/BlockEnderChest.java.patch b/patches/minecraft/net/minecraft/block/BlockEnderChest.java.patch new file mode 100644 index 0000000000..1475e74568 --- /dev/null +++ b/patches/minecraft/net/minecraft/block/BlockEnderChest.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/block/BlockEnderChest.java ++++ b/net/minecraft/block/BlockEnderChest.java +@@ -81,7 +81,7 @@ + InventoryEnderChest inventoryenderchest = p_196250_4_.func_71005_bN(); + TileEntity tileentity = p_196250_2_.func_175625_s(p_196250_3_); + if (inventoryenderchest != null && tileentity instanceof TileEntityEnderChest) { +- if (p_196250_2_.func_180495_p(p_196250_3_.func_177984_a()).func_185915_l()) { ++ if (p_196250_2_.func_180495_p(p_196250_3_.func_177984_a()).doesSideBlockChestOpening(p_196250_2_, p_196250_3_.func_177984_a(), EnumFacing.DOWN)) { + return true; + } else if (p_196250_2_.field_72995_K) { + return true; diff --git a/patches/minecraft/net/minecraft/block/BlockFalling.java.patch b/patches/minecraft/net/minecraft/block/BlockFalling.java.patch new file mode 100644 index 0000000000..1f38e69eb9 --- /dev/null +++ b/patches/minecraft/net/minecraft/block/BlockFalling.java.patch @@ -0,0 +1,21 @@ +--- a/net/minecraft/block/BlockFalling.java ++++ b/net/minecraft/block/BlockFalling.java +@@ -48,7 +48,9 @@ + p_176503_1_.func_72838_d(entityfallingblock); + } + } else { ++ IBlockState state = func_176223_P(); + if (p_176503_1_.func_180495_p(p_176503_2_).func_177230_c() == this) { ++ state = p_176503_1_.func_180495_p(p_176503_2_); + p_176503_1_.func_175698_g(p_176503_2_); + } + +@@ -58,7 +60,7 @@ + } + + if (blockpos.func_177956_o() > 0) { +- p_176503_1_.func_175656_a(blockpos.func_177984_a(), this.func_176223_P()); ++ p_176503_1_.func_175656_a(blockpos.func_177984_a(), state); //Forge: Fix loss of state information during world gen. + } + } + diff --git a/patches/minecraft/net/minecraft/block/BlockFarmland.java.patch b/patches/minecraft/net/minecraft/block/BlockFarmland.java.patch new file mode 100644 index 0000000000..9342f73644 --- /dev/null +++ b/patches/minecraft/net/minecraft/block/BlockFarmland.java.patch @@ -0,0 +1,24 @@ +--- a/net/minecraft/block/BlockFarmland.java ++++ b/net/minecraft/block/BlockFarmland.java +@@ -79,7 +79,7 @@ + } + + public void func_180658_a(World p_180658_1_, BlockPos p_180658_2_, Entity p_180658_3_, float p_180658_4_) { +- if (!p_180658_1_.field_72995_K && p_180658_1_.field_73012_v.nextFloat() < p_180658_4_ - 0.5F && p_180658_3_ instanceof EntityLivingBase && (p_180658_3_ instanceof EntityPlayer || p_180658_1_.func_82736_K().func_82766_b("mobGriefing")) && p_180658_3_.field_70130_N * p_180658_3_.field_70130_N * p_180658_3_.field_70131_O > 0.512F) { ++ if (!p_180658_1_.field_72995_K && net.minecraftforge.common.ForgeHooks.onFarmlandTrample(p_180658_1_, p_180658_2_, Blocks.field_150346_d.func_176223_P(), p_180658_4_, p_180658_3_)) { // Forge: Move logic to Entity#canTrample + func_199610_d(p_180658_1_.func_180495_p(p_180658_2_), p_180658_1_, p_180658_2_); + } + +@@ -90,9 +90,9 @@ + p_199610_1_.func_175656_a(p_199610_2_, func_199601_a(p_199610_0_, Blocks.field_150346_d.func_176223_P(), p_199610_1_, p_199610_2_)); + } + +- private static boolean func_176529_d(IBlockReader p_176529_0_, BlockPos p_176529_1_) { +- Block block = p_176529_0_.func_180495_p(p_176529_1_.func_177984_a()).func_177230_c(); +- return block instanceof BlockCrops || block instanceof BlockStem || block instanceof BlockAttachedStem; ++ private boolean func_176529_d(IBlockReader p_176529_0_, BlockPos p_176529_1_) { ++ IBlockState state = p_176529_0_.func_180495_p(p_176529_1_.func_177984_a()); ++ return state.func_177230_c() instanceof net.minecraftforge.common.IPlantable && canSustainPlant(state, p_176529_0_, p_176529_1_, EnumFacing.UP, (net.minecraftforge.common.IPlantable)state.func_177230_c()); + } + + private static boolean func_176530_e(IWorldReaderBase p_176530_0_, BlockPos p_176530_1_) { diff --git a/patches/minecraft/net/minecraft/block/BlockFence.java.patch b/patches/minecraft/net/minecraft/block/BlockFence.java.patch new file mode 100644 index 0000000000..4e09f3c0b3 --- /dev/null +++ b/patches/minecraft/net/minecraft/block/BlockFence.java.patch @@ -0,0 +1,41 @@ +--- a/net/minecraft/block/BlockFence.java ++++ b/net/minecraft/block/BlockFence.java +@@ -64,15 +64,12 @@ + IBlockReader iblockreader = p_196258_1_.func_195991_k(); + BlockPos blockpos = p_196258_1_.func_195995_a(); + IFluidState ifluidstate = p_196258_1_.func_195991_k().func_204610_c(p_196258_1_.func_195995_a()); +- BlockPos blockpos1 = blockpos.func_177978_c(); +- BlockPos blockpos2 = blockpos.func_177974_f(); +- BlockPos blockpos3 = blockpos.func_177968_d(); +- BlockPos blockpos4 = blockpos.func_177976_e(); +- IBlockState iblockstate = iblockreader.func_180495_p(blockpos1); +- IBlockState iblockstate1 = iblockreader.func_180495_p(blockpos2); +- IBlockState iblockstate2 = iblockreader.func_180495_p(blockpos3); +- IBlockState iblockstate3 = iblockreader.func_180495_p(blockpos4); +- return (IBlockState)((IBlockState)((IBlockState)((IBlockState)((IBlockState)super.func_196258_a(p_196258_1_).func_206870_a(field_196409_a, Boolean.valueOf(this.func_196416_a(iblockstate, iblockstate.func_193401_d(iblockreader, blockpos1, EnumFacing.SOUTH))))).func_206870_a(field_196411_b, Boolean.valueOf(this.func_196416_a(iblockstate1, iblockstate1.func_193401_d(iblockreader, blockpos2, EnumFacing.WEST))))).func_206870_a(field_196413_c, Boolean.valueOf(this.func_196416_a(iblockstate2, iblockstate2.func_193401_d(iblockreader, blockpos3, EnumFacing.NORTH))))).func_206870_a(field_196414_y, Boolean.valueOf(this.func_196416_a(iblockstate3, iblockstate3.func_193401_d(iblockreader, blockpos4, EnumFacing.EAST))))).func_206870_a(field_204514_u, Boolean.valueOf(ifluidstate.func_206886_c() == Fluids.field_204546_a)); ++ return super.func_196258_a(p_196258_1_) ++ .func_206870_a(field_196409_a, canFenceConnectTo(iblockreader, blockpos, EnumFacing.NORTH)) ++ .func_206870_a(field_196411_b, canFenceConnectTo(iblockreader, blockpos, EnumFacing.EAST)) ++ .func_206870_a(field_196413_c, canFenceConnectTo(iblockreader, blockpos, EnumFacing.SOUTH)) ++ .func_206870_a(field_196414_y, canFenceConnectTo(iblockreader, blockpos, EnumFacing.WEST)) ++ .func_206870_a(field_204514_u, Boolean.valueOf(ifluidstate.func_206886_c() == Fluids.field_204546_a)); + } + + public IBlockState func_196271_a(IBlockState p_196271_1_, EnumFacing p_196271_2_, IBlockState p_196271_3_, IWorld p_196271_4_, BlockPos p_196271_5_, BlockPos p_196271_6_) { +@@ -90,4 +87,16 @@ + public BlockFaceShape func_193383_a(IBlockReader p_193383_1_, IBlockState p_193383_2_, BlockPos p_193383_3_, EnumFacing p_193383_4_) { + return p_193383_4_ != EnumFacing.UP && p_193383_4_ != EnumFacing.DOWN ? BlockFaceShape.MIDDLE_POLE : BlockFaceShape.CENTER; + } ++ ++ @Override ++ public boolean canBeConnectedTo(IBlockState state, IBlockReader world, BlockPos pos, EnumFacing facing) { ++ IBlockState other = world.func_180495_p(pos.func_177972_a(facing)); ++ return func_196416_a(other, other.func_193401_d(world, pos.func_177972_a(facing), facing.func_176734_d())); ++ } ++ ++ private boolean canFenceConnectTo(IBlockReader world, BlockPos pos, EnumFacing facing) { ++ BlockPos offset = pos.func_177972_a(facing); ++ IBlockState other = world.func_180495_p(offset); ++ return other.canBeConnectedTo(world, offset, facing.func_176734_d()) || func_176223_P().canBeConnectedTo(world, pos, facing.func_176734_d()); ++ } + } diff --git a/patches/minecraft/net/minecraft/block/BlockFenceGate.java.patch b/patches/minecraft/net/minecraft/block/BlockFenceGate.java.patch new file mode 100644 index 0000000000..915baaefbf --- /dev/null +++ b/patches/minecraft/net/minecraft/block/BlockFenceGate.java.patch @@ -0,0 +1,26 @@ +--- a/net/minecraft/block/BlockFenceGate.java ++++ b/net/minecraft/block/BlockFenceGate.java +@@ -100,7 +100,7 @@ + } + + private boolean func_196380_i(IBlockState p_196380_1_) { +- return p_196380_1_.func_177230_c() == Blocks.field_150463_bK || p_196380_1_.func_177230_c() == Blocks.field_196723_eg; ++ return p_196380_1_.func_177230_c() == Blocks.field_150463_bK || p_196380_1_.func_177230_c() == Blocks.field_196723_eg || p_196380_1_.func_177230_c() instanceof BlockWall; + } + + public boolean func_196250_a(IBlockState p_196250_1_, World p_196250_2_, BlockPos p_196250_3_, EntityPlayer p_196250_4_, EnumHand p_196250_5_, EnumFacing p_196250_6_, float p_196250_7_, float p_196250_8_, float p_196250_9_) { +@@ -145,4 +145,14 @@ + return BlockFaceShape.UNDEFINED; + } + } ++ ++ @Override ++ public boolean canBeConnectedTo(IBlockState state, IBlockReader world, BlockPos pos, EnumFacing facing) { ++ if (state.func_193401_d(world, pos, facing) == BlockFaceShape.MIDDLE_POLE) { ++ Block other = world.func_180495_p(pos.func_177972_a(facing)).func_177230_c(); ++ return other instanceof BlockFence || other instanceof BlockWall; ++ } ++ return false; ++ } ++ + } diff --git a/patches/minecraft/net/minecraft/block/BlockFire.java.patch b/patches/minecraft/net/minecraft/block/BlockFire.java.patch new file mode 100644 index 0000000000..92c370a4b3 --- /dev/null +++ b/patches/minecraft/net/minecraft/block/BlockFire.java.patch @@ -0,0 +1,208 @@ +--- a/net/minecraft/block/BlockFire.java ++++ b/net/minecraft/block/BlockFire.java +@@ -63,13 +63,13 @@ + + public IBlockState func_196448_a(IBlockReader p_196448_1_, BlockPos p_196448_2_) { + IBlockState iblockstate = p_196448_1_.func_180495_p(p_196448_2_.func_177977_b()); +- if (!iblockstate.func_185896_q() && !this.func_196446_i(iblockstate)) { ++ if (!iblockstate.func_185896_q() && !this.canCatchFire(p_196448_1_, p_196448_2_, EnumFacing.UP)) { + IBlockState iblockstate1 = this.func_176223_P(); + + for(EnumFacing enumfacing : EnumFacing.values()) { + BooleanProperty booleanproperty = field_196449_B.get(enumfacing); + if (booleanproperty != null) { +- iblockstate1 = (IBlockState)iblockstate1.func_206870_a(booleanproperty, Boolean.valueOf(this.func_196446_i(p_196448_1_.func_180495_p(p_196448_2_.func_177972_a(enumfacing))))); ++ iblockstate1 = iblockstate1.func_206870_a(booleanproperty, this.canCatchFire(p_196448_1_, p_196448_2_.func_177972_a(enumfacing), enumfacing.func_176734_d())); + } + } + +@@ -97,12 +97,13 @@ + + public void func_196267_b(IBlockState p_196267_1_, World p_196267_2_, BlockPos p_196267_3_, Random p_196267_4_) { + if (p_196267_2_.func_82736_K().func_82766_b("doFireTick")) { ++ if (!p_196267_2_.func_205050_e(p_196267_3_, 2)) return; // Forge: prevent loading unloaded chunks when spreading fire + if (!p_196267_1_.func_196955_c(p_196267_2_, p_196267_3_)) { + p_196267_2_.func_175698_g(p_196267_3_); + } + +- Block block = p_196267_2_.func_180495_p(p_196267_3_.func_177977_b()).func_177230_c(); +- boolean flag = p_196267_2_.field_73011_w instanceof EndDimension && block == Blocks.field_150357_h || block == Blocks.field_150424_aL || block == Blocks.field_196814_hQ; ++ IBlockState other = p_196267_2_.func_180495_p(p_196267_3_.func_177977_b()); ++ boolean flag = other.isFireSource(p_196267_2_, p_196267_3_.func_177977_b(), EnumFacing.UP); + int i = p_196267_1_.func_177229_b(field_176543_a); + if (!flag && p_196267_2_.func_72896_J() && this.func_176537_d(p_196267_2_, p_196267_3_) && p_196267_4_.nextFloat() < 0.2F + (float)i * 0.03F) { + p_196267_2_.func_175698_g(p_196267_3_); +@@ -116,14 +117,14 @@ + if (!flag) { + p_196267_2_.func_205220_G_().func_205360_a(p_196267_3_, this, this.func_149738_a(p_196267_2_) + p_196267_4_.nextInt(10)); + if (!this.func_196447_a(p_196267_2_, p_196267_3_)) { +- if (!p_196267_2_.func_180495_p(p_196267_3_.func_177977_b()).func_185896_q() || i > 3) { ++ if (p_196267_2_.func_180495_p(p_196267_3_.func_177977_b()).func_193401_d(p_196267_2_, p_196267_3_.func_177977_b(), EnumFacing.UP) != BlockFaceShape.SOLID || i > 3) { + p_196267_2_.func_175698_g(p_196267_3_); + } + + return; + } + +- if (i == 15 && p_196267_4_.nextInt(4) == 0 && !this.func_196446_i(p_196267_2_.func_180495_p(p_196267_3_.func_177977_b()))) { ++ if (i == 15 && p_196267_4_.nextInt(4) == 0 && !this.canCatchFire(p_196267_2_, p_196267_3_.func_177977_b(), EnumFacing.UP)) { + p_196267_2_.func_175698_g(p_196267_3_); + return; + } +@@ -131,12 +132,12 @@ + + boolean flag1 = p_196267_2_.func_180502_D(p_196267_3_); + int k = flag1 ? -50 : 0; +- this.func_176536_a(p_196267_2_, p_196267_3_.func_177974_f(), 300 + k, p_196267_4_, i); +- this.func_176536_a(p_196267_2_, p_196267_3_.func_177976_e(), 300 + k, p_196267_4_, i); +- this.func_176536_a(p_196267_2_, p_196267_3_.func_177977_b(), 250 + k, p_196267_4_, i); +- this.func_176536_a(p_196267_2_, p_196267_3_.func_177984_a(), 250 + k, p_196267_4_, i); +- this.func_176536_a(p_196267_2_, p_196267_3_.func_177978_c(), 300 + k, p_196267_4_, i); +- this.func_176536_a(p_196267_2_, p_196267_3_.func_177968_d(), 300 + k, p_196267_4_, i); ++ this.tryCatchFire(p_196267_2_, p_196267_3_.func_177974_f(), 300 + k, p_196267_4_, i, EnumFacing.WEST); ++ this.tryCatchFire(p_196267_2_, p_196267_3_.func_177976_e(), 300 + k, p_196267_4_, i, EnumFacing.EAST); ++ this.tryCatchFire(p_196267_2_, p_196267_3_.func_177977_b(), 250 + k, p_196267_4_, i, EnumFacing.UP); ++ this.tryCatchFire(p_196267_2_, p_196267_3_.func_177984_a(), 250 + k, p_196267_4_, i, EnumFacing.DOWN); ++ this.tryCatchFire(p_196267_2_, p_196267_3_.func_177978_c(), 300 + k, p_196267_4_, i, EnumFacing.SOUTH); ++ this.tryCatchFire(p_196267_2_, p_196267_3_.func_177968_d(), 300 + k, p_196267_4_, i, EnumFacing.NORTH); + BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos(); + + for(int l = -1; l <= 1; ++l) { +@@ -174,28 +175,31 @@ + return p_176537_1_.func_175727_C(p_176537_2_) || p_176537_1_.func_175727_C(p_176537_2_.func_177976_e()) || p_176537_1_.func_175727_C(p_176537_2_.func_177974_f()) || p_176537_1_.func_175727_C(p_176537_2_.func_177978_c()) || p_176537_1_.func_175727_C(p_176537_2_.func_177968_d()); + } + ++ @Deprecated //Forge: Use IForgeBlockState.getFlammability + public int func_176532_c(Block p_176532_1_) { + return this.field_149848_b.getInt(p_176532_1_); + } + ++ @Deprecated //Forge: Use IForgeBlockState.getFireSpreadSpeed + public int func_176534_d(Block p_176534_1_) { + return this.field_149849_a.getInt(p_176534_1_); + } + +- private void func_176536_a(World p_176536_1_, BlockPos p_176536_2_, int p_176536_3_, Random p_176536_4_, int p_176536_5_) { +- int i = this.func_176532_c(p_176536_1_.func_180495_p(p_176536_2_).func_177230_c()); +- if (p_176536_4_.nextInt(p_176536_3_) < i) { +- IBlockState iblockstate = p_176536_1_.func_180495_p(p_176536_2_); +- if (p_176536_4_.nextInt(p_176536_5_ + 10) < 5 && !p_176536_1_.func_175727_C(p_176536_2_)) { +- int j = Math.min(p_176536_5_ + p_176536_4_.nextInt(5) / 4, 15); +- p_176536_1_.func_180501_a(p_176536_2_, (IBlockState)this.func_196448_a(p_176536_1_, p_176536_2_).func_206870_a(field_176543_a, Integer.valueOf(j)), 3); ++ private void tryCatchFire(World worldIn, BlockPos pos, int chance, Random random, int age, EnumFacing face) { ++ IBlockState other = worldIn.func_180495_p(pos); ++ int i = other.getFlammability(worldIn, pos, face); ++ if (random.nextInt(chance) < i) { ++ IBlockState iblockstate = worldIn.func_180495_p(pos); ++ if (random.nextInt(age + 10) < 5 && !worldIn.func_175727_C(pos)) { ++ int j = Math.min(age + random.nextInt(5) / 4, 15); ++ worldIn.func_180501_a(pos, (IBlockState)this.func_196448_a(worldIn, pos).func_206870_a(field_176543_a, Integer.valueOf(j)), 3); + } else { +- p_176536_1_.func_175698_g(p_176536_2_); ++ worldIn.func_175698_g(pos); + } + + Block block = iblockstate.func_177230_c(); + if (block instanceof BlockTNT) { +- ((BlockTNT)block).func_196534_a(p_176536_1_, p_176536_2_); ++ ((BlockTNT)block).func_196534_a(worldIn, pos); + } + } + +@@ -203,7 +207,7 @@ + + private boolean func_196447_a(IBlockReader p_196447_1_, BlockPos p_196447_2_) { + for(EnumFacing enumfacing : EnumFacing.values()) { +- if (this.func_196446_i(p_196447_1_.func_180495_p(p_196447_2_.func_177972_a(enumfacing)))) { ++ if (this.canCatchFire(p_196447_1_, p_196447_2_.func_177972_a(enumfacing), enumfacing.func_176734_d())) { + return true; + } + } +@@ -218,7 +222,7 @@ + int i = 0; + + for(EnumFacing enumfacing : EnumFacing.values()) { +- i = Math.max(this.func_176534_d(p_176538_1_.func_180495_p(p_176538_2_.func_177972_a(enumfacing)).func_177230_c()), i); ++ i = Math.max(p_176538_1_.func_180495_p(p_176538_2_.func_177972_a(enumfacing)).getFlammability(p_176538_1_, p_176538_2_.func_177972_a(enumfacing), enumfacing.func_176734_d()), i); + } + + return i; +@@ -229,6 +233,7 @@ + return false; + } + ++ @Deprecated //Forge: Use canCatchFire with more context + public boolean func_196446_i(IBlockState p_196446_1_) { + return this.func_176534_d(p_196446_1_.func_177230_c()) > 0; + } +@@ -251,8 +256,8 @@ + p_180655_2_.func_184134_a((double)((float)p_180655_3_.func_177958_n() + 0.5F), (double)((float)p_180655_3_.func_177956_o() + 0.5F), (double)((float)p_180655_3_.func_177952_p() + 0.5F), SoundEvents.field_187643_bs, SoundCategory.BLOCKS, 1.0F + p_180655_4_.nextFloat(), p_180655_4_.nextFloat() * 0.7F + 0.3F, false); + } + +- if (!p_180655_2_.func_180495_p(p_180655_3_.func_177977_b()).func_185896_q() && !this.func_196446_i(p_180655_2_.func_180495_p(p_180655_3_.func_177977_b()))) { +- if (this.func_196446_i(p_180655_2_.func_180495_p(p_180655_3_.func_177976_e()))) { ++ if (p_180655_2_.func_180495_p(p_180655_3_.func_177977_b()).func_193401_d(p_180655_2_, p_180655_3_.func_177977_b(), EnumFacing.UP) != BlockFaceShape.SOLID && !this.canCatchFire(p_180655_2_, p_180655_3_.func_177977_b(), EnumFacing.UP)) { ++ if (this.canCatchFire(p_180655_2_, p_180655_3_.func_177976_e(), EnumFacing.EAST)) { + for(int j = 0; j < 2; ++j) { + double d3 = (double)p_180655_3_.func_177958_n() + p_180655_4_.nextDouble() * (double)0.1F; + double d8 = (double)p_180655_3_.func_177956_o() + p_180655_4_.nextDouble(); +@@ -261,7 +266,7 @@ + } + } + +- if (this.func_196446_i(p_180655_2_.func_180495_p(p_180655_3_.func_177974_f()))) { ++ if (this.canCatchFire(p_180655_2_, p_180655_3_.func_177974_f(), EnumFacing.WEST)) { + for(int k = 0; k < 2; ++k) { + double d4 = (double)(p_180655_3_.func_177958_n() + 1) - p_180655_4_.nextDouble() * (double)0.1F; + double d9 = (double)p_180655_3_.func_177956_o() + p_180655_4_.nextDouble(); +@@ -270,7 +275,7 @@ + } + } + +- if (this.func_196446_i(p_180655_2_.func_180495_p(p_180655_3_.func_177978_c()))) { ++ if (this.canCatchFire(p_180655_2_, p_180655_3_.func_177978_c(), EnumFacing.SOUTH)) { + for(int l = 0; l < 2; ++l) { + double d5 = (double)p_180655_3_.func_177958_n() + p_180655_4_.nextDouble(); + double d10 = (double)p_180655_3_.func_177956_o() + p_180655_4_.nextDouble(); +@@ -279,7 +284,7 @@ + } + } + +- if (this.func_196446_i(p_180655_2_.func_180495_p(p_180655_3_.func_177968_d()))) { ++ if (this.canCatchFire(p_180655_2_, p_180655_3_.func_177968_d(), EnumFacing.NORTH)) { + for(int i1 = 0; i1 < 2; ++i1) { + double d6 = (double)p_180655_3_.func_177958_n() + p_180655_4_.nextDouble(); + double d11 = (double)p_180655_3_.func_177956_o() + p_180655_4_.nextDouble(); +@@ -288,7 +293,7 @@ + } + } + +- if (this.func_196446_i(p_180655_2_.func_180495_p(p_180655_3_.func_177984_a()))) { ++ if (this.canCatchFire(p_180655_2_, p_180655_3_.func_177984_a(), EnumFacing.DOWN)) { + for(int j1 = 0; j1 < 2; ++j1) { + double d7 = (double)p_180655_3_.func_177958_n() + p_180655_4_.nextDouble(); + double d12 = (double)(p_180655_3_.func_177956_o() + 1) - p_180655_4_.nextDouble() * (double)0.1F; +@@ -320,10 +325,23 @@ + } + + public void func_180686_a(Block p_180686_1_, int p_180686_2_, int p_180686_3_) { ++ if (p_180686_1_ == Blocks.field_150350_a) throw new IllegalArgumentException("Tried to set air on fire... This is bad."); + this.field_149849_a.put(p_180686_1_, p_180686_2_); + this.field_149848_b.put(p_180686_1_, p_180686_3_); + } + ++ /** ++ * Side sensitive version that calls the block function. ++ * ++ * @param world The current world ++ * @param pos Block position ++ * @param face The side the fire is coming from ++ * @return True if the face can catch fire. ++ */ ++ public boolean canCatchFire(IBlockReader world, BlockPos pos, EnumFacing face) { ++ return world.func_180495_p(pos).isFlammable(world, pos, face); ++ } ++ + public static void func_149843_e() { + BlockFire blockfire = (BlockFire)Blocks.field_150480_ab; + blockfire.func_180686_a(Blocks.field_196662_n, 5, 20); diff --git a/patches/minecraft/net/minecraft/block/BlockFlowerPot.java.patch b/patches/minecraft/net/minecraft/block/BlockFlowerPot.java.patch new file mode 100644 index 0000000000..a50fbc266a --- /dev/null +++ b/patches/minecraft/net/minecraft/block/BlockFlowerPot.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/block/BlockFlowerPot.java ++++ b/net/minecraft/block/BlockFlowerPot.java +@@ -22,7 +22,7 @@ + import net.minecraft.world.World; + + public class BlockFlowerPot extends Block { +- private static final Map field_196451_b = Maps.newHashMap(); ++ private static final Map field_196451_b = Maps.newHashMap(); //TODO: Delegates + protected static final VoxelShape field_196450_a = Block.func_208617_a(5.0D, 0.0D, 5.0D, 11.0D, 6.0D, 11.0D); + private final Block field_196452_c; + diff --git a/patches/minecraft/net/minecraft/block/BlockIce.java.patch b/patches/minecraft/net/minecraft/block/BlockIce.java.patch new file mode 100644 index 0000000000..9eb580ac7f --- /dev/null +++ b/patches/minecraft/net/minecraft/block/BlockIce.java.patch @@ -0,0 +1,25 @@ +--- a/net/minecraft/block/BlockIce.java ++++ b/net/minecraft/block/BlockIce.java +@@ -34,8 +34,10 @@ + public void func_180657_a(World p_180657_1_, EntityPlayer p_180657_2_, BlockPos p_180657_3_, IBlockState p_180657_4_, @Nullable TileEntity p_180657_5_, ItemStack p_180657_6_) { + p_180657_2_.func_71029_a(StatList.field_188065_ae.func_199076_b(this)); + p_180657_2_.func_71020_j(0.005F); +- if (this.func_149700_E() && EnchantmentHelper.func_77506_a(Enchantments.field_185306_r, p_180657_6_) > 0) { +- func_180635_a(p_180657_1_, p_180657_3_, this.func_180643_i(p_180657_4_)); ++ if (this.canSilkHarvest(p_180657_4_, p_180657_1_, p_180657_3_, p_180657_2_) && EnchantmentHelper.func_77506_a(Enchantments.field_185306_r, p_180657_6_) > 0) { ++ net.minecraft.util.NonNullList items = net.minecraft.util.NonNullList.func_193580_a(ItemStack.field_190927_a, func_180643_i(p_180657_4_)); ++ net.minecraftforge.event.ForgeEventFactory.fireBlockHarvesting(items, p_180657_1_, p_180657_3_, p_180657_4_, 0, 1.0f, true, p_180657_2_); ++ items.stream().filter(e -> !e.func_190926_b()).forEach(e -> func_180635_a(p_180657_1_, p_180657_3_, e)); + } else { + if (p_180657_1_.field_73011_w.func_177500_n()) { + p_180657_1_.func_175698_g(p_180657_3_); +@@ -43,7 +45,9 @@ + } + + int i = EnchantmentHelper.func_77506_a(Enchantments.field_185308_t, p_180657_6_); ++ harvesters.set(p_180657_2_); + p_180657_4_.func_196949_c(p_180657_1_, p_180657_3_, i); ++ harvesters.set(null); + Material material = p_180657_1_.func_180495_p(p_180657_3_.func_177977_b()).func_185904_a(); + if (material.func_76230_c() || material.func_76224_d()) { + p_180657_1_.func_175656_a(p_180657_3_, Blocks.field_150355_j.func_176223_P()); diff --git a/patches/minecraft/net/minecraft/block/BlockLadder.java.patch b/patches/minecraft/net/minecraft/block/BlockLadder.java.patch new file mode 100644 index 0000000000..02ea1bb2aa --- /dev/null +++ b/patches/minecraft/net/minecraft/block/BlockLadder.java.patch @@ -0,0 +1,28 @@ +--- a/net/minecraft/block/BlockLadder.java ++++ b/net/minecraft/block/BlockLadder.java +@@ -3,6 +3,7 @@ + import javax.annotation.Nullable; + import net.minecraft.block.state.BlockFaceShape; + import net.minecraft.block.state.IBlockState; ++import net.minecraft.entity.EntityLivingBase; + import net.minecraft.fluid.Fluid; + import net.minecraft.fluid.IFluidState; + import net.minecraft.init.Blocks; +@@ -20,6 +21,7 @@ + import net.minecraft.util.math.shapes.VoxelShape; + import net.minecraft.world.IBlockReader; + import net.minecraft.world.IWorld; ++import net.minecraft.world.IWorldReader; + import net.minecraft.world.IWorldReaderBase; + + public class BlockLadder extends Block implements IBucketPickupHandler, ILiquidContainer { +@@ -151,4 +153,9 @@ + return false; + } + } ++ ++ @Override ++ public boolean isLadder(IBlockState state, IWorldReader world, BlockPos pos, EntityLivingBase entity) { ++ return true; ++ } + } diff --git a/patches/minecraft/net/minecraft/block/BlockLeaves.java.patch b/patches/minecraft/net/minecraft/block/BlockLeaves.java.patch new file mode 100644 index 0000000000..95b0156054 --- /dev/null +++ b/patches/minecraft/net/minecraft/block/BlockLeaves.java.patch @@ -0,0 +1,97 @@ +--- a/net/minecraft/block/BlockLeaves.java ++++ b/net/minecraft/block/BlockLeaves.java +@@ -1,6 +1,9 @@ + package net.minecraft.block; + ++import java.util.List; + import java.util.Random; ++ ++import javax.annotation.Nonnull; + import javax.annotation.Nullable; + import net.minecraft.block.state.IBlockState; + import net.minecraft.entity.player.EntityPlayer; +@@ -22,11 +25,12 @@ + import net.minecraft.util.math.BlockPos; + import net.minecraft.world.IBlockReader; + import net.minecraft.world.IWorld; ++import net.minecraft.world.IWorldReader; + import net.minecraft.world.World; + import net.minecraftforge.api.distmarker.Dist; + import net.minecraftforge.api.distmarker.OnlyIn; + +-public class BlockLeaves extends Block { ++public class BlockLeaves extends Block implements net.minecraftforge.common.IShearable { + public static final IntegerProperty field_208494_a = BlockStateProperties.field_208514_aa; + public static final BooleanProperty field_208495_b = BlockStateProperties.field_208515_s; + protected static boolean field_196478_c; +@@ -122,28 +126,37 @@ + } + + public void func_196255_a(IBlockState p_196255_1_, World p_196255_2_, BlockPos p_196255_3_, float p_196255_4_, int p_196255_5_) { +- if (!p_196255_2_.field_72995_K) { +- int i = this.func_196472_i(p_196255_1_); +- if (p_196255_5_ > 0) { +- i -= 2 << p_196255_5_; ++ super.func_196255_a(p_196255_1_, p_196255_2_, p_196255_3_, p_196255_4_, p_196255_5_); ++ } ++ ++ @Override ++ public void getDrops(IBlockState state, net.minecraft.util.NonNullList drops, World worldIn, BlockPos pos, int fortune) { ++ { ++ int i = this.func_196472_i(state); ++ if (fortune > 0) { ++ i -= 2 << fortune; + if (i < 10) { + i = 10; + } + } + +- if (p_196255_2_.field_73012_v.nextInt(i) == 0) { +- func_180635_a(p_196255_2_, p_196255_3_, new ItemStack(this.func_199769_a(p_196255_1_, p_196255_2_, p_196255_3_, p_196255_5_))); ++ if (worldIn.field_73012_v.nextInt(i) == 0) { ++ ItemStack drop = new ItemStack(this.func_199769_a(state, worldIn, pos, fortune)); ++ if (!drop.func_190926_b()) ++ drops.add(drop); + } + + i = 200; +- if (p_196255_5_ > 0) { +- i -= 10 << p_196255_5_; ++ if (fortune > 0) { ++ i -= 10 << fortune; + if (i < 40) { + i = 40; + } + } + +- this.func_196474_a(p_196255_2_, p_196255_3_, p_196255_1_, i); ++ captureDrops(true); ++ this.func_196474_a(worldIn, pos, state, i); ++ drops.addAll(captureDrops(false)); + } + + } +@@ -173,13 +186,7 @@ + } + + public void func_180657_a(World p_180657_1_, EntityPlayer p_180657_2_, BlockPos p_180657_3_, IBlockState p_180657_4_, @Nullable TileEntity p_180657_5_, ItemStack p_180657_6_) { +- if (!p_180657_1_.field_72995_K && p_180657_6_.func_77973_b() == Items.field_151097_aZ) { +- p_180657_2_.func_71029_a(StatList.field_188065_ae.func_199076_b(this)); +- p_180657_2_.func_71020_j(0.005F); +- func_180635_a(p_180657_1_, p_180657_3_, new ItemStack(this)); +- } else { + super.func_180657_a(p_180657_1_, p_180657_2_, p_180657_3_, p_180657_4_, p_180657_5_, p_180657_6_); +- } + } + + protected void func_206840_a(StateContainer.Builder p_206840_1_) { +@@ -189,4 +196,9 @@ + public IBlockState func_196258_a(BlockItemUseContext p_196258_1_) { + return func_208493_b((IBlockState)this.func_176223_P().func_206870_a(field_208495_b, Boolean.valueOf(true)), p_196258_1_.func_195991_k(), p_196258_1_.func_195995_a()); + } ++ ++ @Override ++ public List onSheared(@Nonnull ItemStack item, IWorldReader world, BlockPos pos, int fortune) { ++ return java.util.Arrays.asList(new ItemStack(this)); ++ } + } diff --git a/patches/minecraft/net/minecraft/block/BlockMobSpawner.java.patch b/patches/minecraft/net/minecraft/block/BlockMobSpawner.java.patch new file mode 100644 index 0000000000..41e4ae4a45 --- /dev/null +++ b/patches/minecraft/net/minecraft/block/BlockMobSpawner.java.patch @@ -0,0 +1,31 @@ +--- a/net/minecraft/block/BlockMobSpawner.java ++++ b/net/minecraft/block/BlockMobSpawner.java +@@ -10,9 +10,12 @@ + import net.minecraft.util.IItemProvider; + import net.minecraft.util.math.BlockPos; + import net.minecraft.world.IBlockReader; ++import net.minecraft.world.IWorldReader; + import net.minecraft.world.World; + + public class BlockMobSpawner extends BlockContainer { ++ private static final java.util.Random RAND = new java.util.Random(); ++ + protected BlockMobSpawner(Block.Builder p_i48364_1_) { + super(p_i48364_1_); + } +@@ -27,10 +30,13 @@ + + public void func_196255_a(IBlockState p_196255_1_, World p_196255_2_, BlockPos p_196255_3_, float p_196255_4_, int p_196255_5_) { + super.func_196255_a(p_196255_1_, p_196255_2_, p_196255_3_, p_196255_4_, p_196255_5_); +- int i = 15 + p_196255_2_.field_73012_v.nextInt(15) + p_196255_2_.field_73012_v.nextInt(15); +- this.func_180637_b(p_196255_2_, p_196255_3_, i); + } + ++ @Override ++ public int getExpDrop(IBlockState state, IWorldReader world, BlockPos pos, int fortune) { ++ return 15 + RAND.nextInt(15) + RAND.nextInt(15); ++ } ++ + public EnumBlockRenderType func_149645_b(IBlockState p_149645_1_) { + return EnumBlockRenderType.MODEL; + } diff --git a/patches/minecraft/net/minecraft/block/BlockMushroom.java.patch b/patches/minecraft/net/minecraft/block/BlockMushroom.java.patch new file mode 100644 index 0000000000..4fa801387c --- /dev/null +++ b/patches/minecraft/net/minecraft/block/BlockMushroom.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/block/BlockMushroom.java ++++ b/net/minecraft/block/BlockMushroom.java +@@ -64,7 +64,7 @@ + IBlockState iblockstate = p_196260_2_.func_180495_p(blockpos); + Block block = iblockstate.func_177230_c(); + if (block != Blocks.field_150391_bh && block != Blocks.field_196661_l) { +- return p_196260_2_.func_201669_a(p_196260_3_, 0) < 13 && this.func_200014_a_(iblockstate, p_196260_2_, blockpos); ++ return p_196260_2_.func_201669_a(p_196260_3_, 0) < 13 && iblockstate.canSustainPlant(p_196260_2_, blockpos, net.minecraft.util.EnumFacing.UP, this); + } else { + return true; + } diff --git a/patches/minecraft/net/minecraft/block/BlockNetherWart.java.patch b/patches/minecraft/net/minecraft/block/BlockNetherWart.java.patch new file mode 100644 index 0000000000..e44c334dfe --- /dev/null +++ b/patches/minecraft/net/minecraft/block/BlockNetherWart.java.patch @@ -0,0 +1,45 @@ +--- a/net/minecraft/block/BlockNetherWart.java ++++ b/net/minecraft/block/BlockNetherWart.java +@@ -33,26 +33,33 @@ + + public void func_196267_b(IBlockState p_196267_1_, World p_196267_2_, BlockPos p_196267_3_, Random p_196267_4_) { + int i = p_196267_1_.func_177229_b(field_176486_a); +- if (i < 3 && p_196267_4_.nextInt(10) == 0) { +- p_196267_1_ = (IBlockState)p_196267_1_.func_206870_a(field_176486_a, Integer.valueOf(i + 1)); +- p_196267_2_.func_180501_a(p_196267_3_, p_196267_1_, 2); ++ if (i < 3 && net.minecraftforge.common.ForgeHooks.onCropsGrowPre(p_196267_2_, p_196267_3_, p_196267_1_, p_196267_4_.nextInt(10) == 0)) { ++ IBlockState newState = (IBlockState)p_196267_1_.func_206870_a(field_176486_a, Integer.valueOf(i + 1)); ++ p_196267_2_.func_180501_a(p_196267_3_, newState, 2); ++ net.minecraftforge.common.ForgeHooks.onCropsGrowPost(p_196267_2_, p_196267_3_, p_196267_1_); ++ p_196267_1_ = newState; + } + + super.func_196267_b(p_196267_1_, p_196267_2_, p_196267_3_, p_196267_4_); + } + + public void func_196255_a(IBlockState p_196255_1_, World p_196255_2_, BlockPos p_196255_3_, float p_196255_4_, int p_196255_5_) { +- if (!p_196255_2_.field_72995_K) { ++ super.func_196255_a(p_196255_1_, p_196255_2_, p_196255_3_, p_196255_4_, p_196255_5_); ++ } ++ ++ @Override ++ public void getDrops(IBlockState state, net.minecraft.util.NonNullList drops, World worldIn, BlockPos pos, int fortune) { ++ { + int i = 1; +- if (p_196255_1_.func_177229_b(field_176486_a) >= 3) { +- i = 2 + p_196255_2_.field_73012_v.nextInt(3); +- if (p_196255_5_ > 0) { +- i += p_196255_2_.field_73012_v.nextInt(p_196255_5_ + 1); ++ if (state.func_177229_b(field_176486_a) >= 3) { ++ i = 2 + worldIn.field_73012_v.nextInt(3); ++ if (fortune > 0) { ++ i += worldIn.field_73012_v.nextInt(fortune + 1); + } + } + + for(int j = 0; j < i; ++j) { +- func_180635_a(p_196255_2_, p_196255_3_, new ItemStack(Items.field_151075_bm)); ++ drops.add(new ItemStack(Items.field_151075_bm)); + } + + } diff --git a/patches/minecraft/net/minecraft/block/BlockNote.java.patch b/patches/minecraft/net/minecraft/block/BlockNote.java.patch new file mode 100644 index 0000000000..dbbb7e9b91 --- /dev/null +++ b/patches/minecraft/net/minecraft/block/BlockNote.java.patch @@ -0,0 +1,23 @@ +--- a/net/minecraft/block/BlockNote.java ++++ b/net/minecraft/block/BlockNote.java +@@ -59,7 +59,9 @@ + if (p_196250_2_.field_72995_K) { + return true; + } else { +- p_196250_1_ = (IBlockState)p_196250_1_.func_177231_a(field_196485_c); ++ int _new = net.minecraftforge.common.ForgeHooks.onNoteChange(p_196250_2_, p_196250_3_, p_196250_1_, p_196250_1_.func_177229_b(field_196485_c), p_196250_1_.func_177231_a(field_196485_c).func_177229_b(field_196485_c)); ++ if (_new == -1) return false; ++ p_196250_1_ = (IBlockState)p_196250_1_.func_206870_a(field_196485_c, _new); + p_196250_2_.func_180501_a(p_196250_3_, p_196250_1_, 3); + this.func_196482_a(p_196250_2_, p_196250_3_); + p_196250_4_.func_195066_a(StatList.field_188087_U); +@@ -75,6 +77,9 @@ + } + + public boolean func_189539_a(IBlockState p_189539_1_, World p_189539_2_, BlockPos p_189539_3_, int p_189539_4_, int p_189539_5_) { ++ net.minecraftforge.event.world.NoteBlockEvent.Play e = new net.minecraftforge.event.world.NoteBlockEvent.Play(p_189539_2_, p_189539_3_, p_189539_1_, p_189539_1_.func_177229_b(field_196485_c), p_189539_1_.func_177229_b(field_196483_a)); ++ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(e)) return false; ++ p_189539_1_ = p_189539_1_.func_206870_a(field_196485_c, e.getVanillaNoteId()).func_206870_a(field_196483_a, e.getInstrument()); + int i = p_189539_1_.func_177229_b(field_196485_c); + float f = (float)Math.pow(2.0D, (double)(i - 12) / 12.0D); + p_189539_2_.func_184133_a((EntityPlayer)null, p_189539_3_, ((NoteBlockInstrument)p_189539_1_.func_177229_b(field_196483_a)).func_208088_a(), SoundCategory.RECORDS, 3.0F, f); diff --git a/patches/minecraft/net/minecraft/block/BlockOre.java.patch b/patches/minecraft/net/minecraft/block/BlockOre.java.patch new file mode 100644 index 0000000000..82153b9e75 --- /dev/null +++ b/patches/minecraft/net/minecraft/block/BlockOre.java.patch @@ -0,0 +1,39 @@ +--- a/net/minecraft/block/BlockOre.java ++++ b/net/minecraft/block/BlockOre.java +@@ -49,23 +49,27 @@ + + public void func_196255_a(IBlockState p_196255_1_, World p_196255_2_, BlockPos p_196255_3_, float p_196255_4_, int p_196255_5_) { + super.func_196255_a(p_196255_1_, p_196255_2_, p_196255_3_, p_196255_4_, p_196255_5_); +- if (this.func_199769_a(p_196255_1_, p_196255_2_, p_196255_3_, p_196255_5_) != this) { ++ } ++ ++ @Override ++ public int getExpDrop(IBlockState state, net.minecraft.world.IWorldReader reader, BlockPos pos, int fortune) { ++ World world = reader instanceof World ? (World)reader : null; ++ if (world == null || this.func_199769_a(state, world, pos, fortune) != this) { + int i = 0; + if (this == Blocks.field_150365_q) { +- i = MathHelper.func_76136_a(p_196255_2_.field_73012_v, 0, 2); ++ i = MathHelper.func_76136_a(RANDOM, 0, 2); + } else if (this == Blocks.field_150482_ag) { +- i = MathHelper.func_76136_a(p_196255_2_.field_73012_v, 3, 7); ++ i = MathHelper.func_76136_a(RANDOM, 3, 7); + } else if (this == Blocks.field_150412_bA) { +- i = MathHelper.func_76136_a(p_196255_2_.field_73012_v, 3, 7); ++ i = MathHelper.func_76136_a(RANDOM, 3, 7); + } else if (this == Blocks.field_150369_x) { +- i = MathHelper.func_76136_a(p_196255_2_.field_73012_v, 2, 5); ++ i = MathHelper.func_76136_a(RANDOM, 2, 5); + } else if (this == Blocks.field_196766_fg) { +- i = MathHelper.func_76136_a(p_196255_2_.field_73012_v, 2, 5); ++ i = MathHelper.func_76136_a(RANDOM, 2, 5); + } +- +- this.func_180637_b(p_196255_2_, p_196255_3_, i); ++ return i; + } +- ++ return 0; + } + + public ItemStack func_185473_a(IBlockReader p_185473_1_, BlockPos p_185473_2_, IBlockState p_185473_3_) { diff --git a/patches/minecraft/net/minecraft/block/BlockRailPowered.java.patch b/patches/minecraft/net/minecraft/block/BlockRailPowered.java.patch new file mode 100644 index 0000000000..29feb0d926 --- /dev/null +++ b/patches/minecraft/net/minecraft/block/BlockRailPowered.java.patch @@ -0,0 +1,29 @@ +--- a/net/minecraft/block/BlockRailPowered.java ++++ b/net/minecraft/block/BlockRailPowered.java +@@ -15,10 +15,16 @@ + public class BlockRailPowered extends BlockRailBase { + public static final EnumProperty field_176568_b = BlockStateProperties.field_208166_S; + public static final BooleanProperty field_176569_M = BlockStateProperties.field_208194_u; ++ private final boolean isActivator; + + protected BlockRailPowered(Block.Builder p_i48349_1_) { +- super(true, p_i48349_1_); ++ this(p_i48349_1_, false); ++ } ++ ++ protected BlockRailPowered(Block.Builder builder, boolean isActivator) { ++ super(true, builder); + this.func_180632_j((IBlockState)((IBlockState)(this.field_176227_L.func_177621_b()).func_206870_a(field_176568_b, RailShape.NORTH_SOUTH)).func_206870_a(field_176569_M, Boolean.valueOf(false))); ++ this.isActivator = isActivator; + } + + protected boolean func_176566_a(World p_176566_1_, BlockPos p_176566_2_, IBlockState p_176566_3_, boolean p_176566_4_, int p_176566_5_) { +@@ -100,7 +106,7 @@ + + protected boolean func_208071_a(World p_208071_1_, BlockPos p_208071_2_, boolean p_208071_3_, int p_208071_4_, RailShape p_208071_5_) { + IBlockState iblockstate = p_208071_1_.func_180495_p(p_208071_2_); +- if (iblockstate.func_177230_c() != this) { ++ if (!(iblockstate.func_177230_c() instanceof BlockRailPowered) || isActivator != ((BlockRailPowered)iblockstate.func_177230_c()).isActivator) { + return false; + } else { + RailShape railshape = (RailShape)iblockstate.func_177229_b(field_176568_b); diff --git a/patches/minecraft/net/minecraft/block/BlockShearableDoublePlant.java.patch b/patches/minecraft/net/minecraft/block/BlockShearableDoublePlant.java.patch new file mode 100644 index 0000000000..6606d747ab --- /dev/null +++ b/patches/minecraft/net/minecraft/block/BlockShearableDoublePlant.java.patch @@ -0,0 +1,45 @@ +--- a/net/minecraft/block/BlockShearableDoublePlant.java ++++ b/net/minecraft/block/BlockShearableDoublePlant.java +@@ -1,5 +1,7 @@ + package net.minecraft.block; + ++import java.util.List; ++ + import net.minecraft.block.state.IBlockState; + import net.minecraft.init.Blocks; + import net.minecraft.init.Items; +@@ -11,7 +13,7 @@ + import net.minecraft.util.math.BlockPos; + import net.minecraft.world.World; + +-public class BlockShearableDoublePlant extends BlockDoublePlant { ++public class BlockShearableDoublePlant extends BlockDoublePlant implements net.minecraftforge.common.IShearable { + public static final EnumProperty field_208063_b = BlockDoublePlant.field_176492_b; + private final Block field_196392_b; + +@@ -26,9 +28,7 @@ + } + + protected void func_196391_a(IBlockState p_196391_1_, World p_196391_2_, BlockPos p_196391_3_, ItemStack p_196391_4_) { +- if (p_196391_4_.func_77973_b() == Items.field_151097_aZ) { +- func_180635_a(p_196391_2_, p_196391_3_, new ItemStack(this.field_196392_b, 2)); +- } else { ++ { + super.func_196391_a(p_196391_1_, p_196391_2_, p_196391_3_, p_196391_4_); + } + +@@ -37,4 +37,14 @@ + public IItemProvider func_199769_a(IBlockState p_199769_1_, World p_199769_2_, BlockPos p_199769_3_, int p_199769_4_) { + return p_199769_1_.func_177229_b(field_208063_b) == DoubleBlockHalf.LOWER && this == Blocks.field_196804_gh && p_199769_2_.field_73012_v.nextInt(8) == 0 ? Items.field_151014_N : Items.field_190931_a; + } ++ ++ @Override ++ public boolean isShearable(ItemStack item, net.minecraft.world.IWorldReader world, BlockPos pos) { ++ return false; ++ } ++ ++ @Override ++ public List onSheared(ItemStack item, net.minecraft.world.IWorldReader world, BlockPos pos, int fortune) { ++ return java.util.Arrays.asList(new ItemStack(this.field_196392_b, 2)); ++ } + } diff --git a/patches/minecraft/net/minecraft/block/state/BlockPistonStructureHelper.java.patch b/patches/minecraft/net/minecraft/block/state/BlockPistonStructureHelper.java.patch new file mode 100644 index 0000000000..c160ea7afd --- /dev/null +++ b/patches/minecraft/net/minecraft/block/state/BlockPistonStructureHelper.java.patch @@ -0,0 +1,53 @@ +--- a/net/minecraft/block/state/BlockPistonStructureHelper.java ++++ b/net/minecraft/block/state/BlockPistonStructureHelper.java +@@ -51,7 +51,7 @@ + } else { + for(int i = 0; i < this.field_177258_e.size(); ++i) { + BlockPos blockpos = this.field_177258_e.get(i); +- if (this.field_177261_a.func_180495_p(blockpos).func_177230_c() == Blocks.field_180399_cE && !this.func_177250_b(blockpos)) { ++ if (this.field_177261_a.func_180495_p(blockpos).isStickyBlock() && !this.func_177250_b(blockpos)) { + return false; + } + } +@@ -62,8 +62,7 @@ + + private boolean func_177251_a(BlockPos p_177251_1_, EnumFacing p_177251_2_) { + IBlockState iblockstate = this.field_177261_a.func_180495_p(p_177251_1_); +- Block block = iblockstate.func_177230_c(); +- if (iblockstate.func_196958_f()) { ++ if (iblockstate.isAir(field_177261_a, p_177251_1_)) { + return true; + } else if (!BlockPistonBase.func_185646_a(iblockstate, this.field_177261_a, p_177251_1_, this.field_177257_d, false, p_177251_2_)) { + return true; +@@ -76,11 +75,10 @@ + if (i + this.field_177258_e.size() > 12) { + return false; + } else { +- while(block == Blocks.field_180399_cE) { ++ while(iblockstate.isStickyBlock()) { + BlockPos blockpos = p_177251_1_.func_177967_a(this.field_177257_d.func_176734_d(), i); + iblockstate = this.field_177261_a.func_180495_p(blockpos); +- block = iblockstate.func_177230_c(); +- if (iblockstate.func_196958_f() || !BlockPistonBase.func_185646_a(iblockstate, this.field_177261_a, blockpos, this.field_177257_d, false, this.field_177257_d.func_176734_d()) || blockpos.equals(this.field_177259_b)) { ++ if (iblockstate.isAir(field_177261_a, blockpos) || !BlockPistonBase.func_185646_a(iblockstate, this.field_177261_a, blockpos, this.field_177257_d, false, this.field_177257_d.func_176734_d()) || blockpos.equals(this.field_177259_b)) { + break; + } + +@@ -107,7 +105,7 @@ + + for(int l = 0; l <= k + i1; ++l) { + BlockPos blockpos2 = this.field_177258_e.get(l); +- if (this.field_177261_a.func_180495_p(blockpos2).func_177230_c() == Blocks.field_180399_cE && !this.func_177250_b(blockpos2)) { ++ if (this.field_177261_a.func_180495_p(blockpos2).isStickyBlock() && !this.func_177250_b(blockpos2)) { + return false; + } + } +@@ -116,7 +114,7 @@ + } + + iblockstate = this.field_177261_a.func_180495_p(blockpos1); +- if (iblockstate.func_196958_f()) { ++ if (iblockstate.isAir(field_177261_a, blockpos1)) { + return true; + } + diff --git a/patches/minecraft/net/minecraft/block/state/IBlockState.java.patch b/patches/minecraft/net/minecraft/block/state/IBlockState.java.patch index 1a47ddc3f5..1843b73034 100644 --- a/patches/minecraft/net/minecraft/block/state/IBlockState.java.patch +++ b/patches/minecraft/net/minecraft/block/state/IBlockState.java.patch @@ -9,3 +9,11 @@ ThreadLocal> field_208776_a = ThreadLocal.>withInitial(() -> { Object2ByteOpenHashMap object2byteopenhashmap = new Object2ByteOpenHashMap(); object2byteopenhashmap.defaultReturnValue((byte)127); +@@ -109,6 +109,7 @@ + return this.func_177230_c().func_180659_g(this, p_185909_1_, p_185909_2_); + } + ++ @Deprecated//Forge: Use position sensitive version + default IBlockState func_185907_a(Rotation p_185907_1_) { + return this.func_177230_c().func_185499_a(this, p_185907_1_); + } diff --git a/patches/minecraft/net/minecraft/world/World.java.patch b/patches/minecraft/net/minecraft/world/World.java.patch index 4c775ef69d..6884fc8945 100644 --- a/patches/minecraft/net/minecraft/world/World.java.patch +++ b/patches/minecraft/net/minecraft/world/World.java.patch @@ -1,10 +1,6 @@ --- a/net/minecraft/world/World.java +++ b/net/minecraft/world/World.java -@@ -68,10 +68,11 @@ - import net.minecraft.world.storage.WorldSavedDataStorage; - import net.minecraftforge.api.distmarker.Dist; - import net.minecraftforge.api.distmarker.OnlyIn; -+ +@@ -71,7 +71,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -13,7 +9,16 @@ protected static final Logger field_195596_d = LogManager.getLogger(); private static final EnumFacing[] field_200007_a = EnumFacing.values(); private int field_181546_a = 63; -@@ -121,6 +122,7 @@ +@@ -110,6 +110,8 @@ + private final WorldBorder field_175728_M; + int[] field_72994_J; + ++ public boolean restoringBlockSnapshots = false; ++ + protected World(ISaveHandler p_i45749_1_, WorldInfo p_i45749_2_, Dimension p_i45749_3_, Profiler p_i45749_4_, boolean p_i45749_5_) { + this.field_73021_x = Lists.newArrayList(this.field_184152_t); + this.field_72985_G = true; +@@ -121,6 +123,7 @@ this.field_73011_w = p_i45749_3_; this.field_72995_K = p_i45749_5_; this.field_175728_M = p_i45749_3_.func_177501_r(); @@ -21,7 +26,7 @@ } public IWorld func_175643_b() { -@@ -2397,4 +2399,31 @@ +@@ -2397,4 +2400,31 @@ public abstract RecipeManager func_199532_z(); public abstract NetworkTagManager func_205772_D(); @@ -29,7 +34,7 @@ + /* ======================================== FORGE START =====================================*/ + + private net.minecraftforge.common.util.WorldCapabilityData capabilityData; -+ ++ + protected void initCapabilities() + { + net.minecraftforge.common.capabilities.ICapabilityProvider parent = field_73011_w.initCapabilities(); @@ -46,7 +51,7 @@ + capabilityData.setCapabilities(field_73011_w, getCapabilities()); + } + } -+ ++ + protected WorldSavedDataStorage perWorldStorage; //Moved to a getter to simulate final without being final so we can load in subclasses. + public WorldSavedDataStorage getPerWorldStorage() + { diff --git a/patches/minecraft/net/minecraft/world/dimension/Dimension.java.patch b/patches/minecraft/net/minecraft/world/dimension/Dimension.java.patch index b2b5fbb0a5..815c328fe7 100644 --- a/patches/minecraft/net/minecraft/world/dimension/Dimension.java.patch +++ b/patches/minecraft/net/minecraft/world/dimension/Dimension.java.patch @@ -9,11 +9,11 @@ public static final float[] field_111203_a = new float[]{1.0F, 0.75F, 0.5F, 0.25F, 0.0F, 0.25F, 0.5F, 0.75F}; protected World field_76579_a; protected boolean field_76575_d; -@@ -141,4 +141,76 @@ +@@ -141,4 +141,91 @@ public abstract boolean func_76568_b(int p_76568_1_, int p_76568_2_); public abstract DimensionType func_186058_p(); -+ ++ + /*======================================= Forge Start =========================================*/ + private net.minecraftforge.client.IRenderHandler skyRenderer = null; + private net.minecraftforge.client.IRenderHandler cloudRenderer = null; @@ -39,14 +39,14 @@ + { + return this.skyRenderer; + } -+ ++ + @OnlyIn(Dist.CLIENT) + @Override + public void setSkyRenderer(net.minecraftforge.client.IRenderHandler skyRenderer) + { + this.skyRenderer = skyRenderer; + } -+ ++ + @Nullable + @OnlyIn(Dist.CLIENT) + @Override @@ -54,14 +54,14 @@ + { + return cloudRenderer; + } -+ ++ + @OnlyIn(Dist.CLIENT) + @Override + public void setCloudRenderer(net.minecraftforge.client.IRenderHandler renderer) + { + cloudRenderer = renderer; + } -+ ++ + @Nullable + @OnlyIn(Dist.CLIENT) + @Override @@ -69,14 +69,14 @@ + { + return weatherRenderer; + } -+ ++ + @OnlyIn(Dist.CLIENT) + @Override + public void setWeatherRenderer(net.minecraftforge.client.IRenderHandler renderer) + { + weatherRenderer = renderer; + } -+ ++ + @Override + public void resetRainAndThunder() + { @@ -84,5 +84,20 @@ + field_76579_a.func_72912_H().func_76084_b(false); + field_76579_a.func_72912_H().func_76090_f(0); + field_76579_a.func_72912_H().func_76069_a(false); ++ } ++ ++ /** ++ * Determines if the player can sleep in this world (or if the bed should explode for example). ++ * ++ * @param player The player that is attempting to sleep ++ * @param pos The location where the player tries to sleep at (the position of the clicked on bed for example) ++ * @return the result of a player trying to sleep at the given location ++ */ ++ public SleepResult canSleepAt(net.minecraft.entity.player.EntityPlayer player, BlockPos pos) { ++ return (this.func_76567_e() && this.field_76579_a.func_180494_b(pos) != net.minecraft.init.Biomes.field_76778_j) ? SleepResult.ALLOW : SleepResult.BED_EXPLODES; ++ } ++ ++ public enum SleepResult { ++ ALLOW, DENY, BED_EXPLODES + } } diff --git a/src/main/java/net/minecraftforge/client/model/pipeline/BlockInfo.java b/src/main/java/net/minecraftforge/client/model/pipeline/BlockInfo.java index eaa0c73d7e..3efc18bbff 100644 --- a/src/main/java/net/minecraftforge/client/model/pipeline/BlockInfo.java +++ b/src/main/java/net/minecraftforge/client/model/pipeline/BlockInfo.java @@ -123,7 +123,7 @@ public class BlockInfo { BlockPos pos = blockPos.add(x - 1, y - 1, z - 1); IBlockState state = world.getBlockState(pos); - t[x][y][z] = state.getLightOpacity(world, pos) < 15; + t[x][y][z] = state.getOpacity(world, pos) < 15; int brightness = state.getPackedLightmapCoords(world, pos); s[x][y][z] = (brightness >> 0x14) & 0xF; b[x][y][z] = (brightness >> 0x04) & 0xF; diff --git a/src/main/java/net/minecraftforge/common/EnumPlantType.java b/src/main/java/net/minecraftforge/common/EnumPlantType.java index 83503d2441..815c739f78 100644 --- a/src/main/java/net/minecraftforge/common/EnumPlantType.java +++ b/src/main/java/net/minecraftforge/common/EnumPlantType.java @@ -47,5 +47,5 @@ public enum EnumPlantType * @param name the name of the type of plant, you had better follow the style above * @return the acquired {@link EnumPlantType}, a new one if not found. */ - public static EnumPlantType create(String name, int test, long bar, String foo){ return null; } + public static EnumPlantType create(String name){ return null; } } diff --git a/src/main/java/net/minecraftforge/common/ForgeHooks.java b/src/main/java/net/minecraftforge/common/ForgeHooks.java index 4d9eb6ebe7..5e507da3bb 100644 --- a/src/main/java/net/minecraftforge/common/ForgeHooks.java +++ b/src/main/java/net/minecraftforge/common/ForgeHooks.java @@ -657,11 +657,6 @@ public class ForgeHooks return event.getEntityItem(); } - public static float getEnchantPower(@Nonnull World world, @Nonnull BlockPos pos) - { - return world.getBlockState(pos).getEnchantPowerBonus(world, pos); - } - @Nullable public static ITextComponent onServerChatEvent(NetHandlerPlayServer net, String raw, ITextComponent comp) { @@ -1177,7 +1172,7 @@ public class ForgeHooks return (ev.getResult() == net.minecraftforge.eventbus.api.Event.Result.ALLOW || (ev.getResult() == net.minecraftforge.eventbus.api.Event.Result.DEFAULT && def)); } - public static void onCropsGrowPost(World worldIn, BlockPos pos, IBlockState state, IBlockState blockState) + public static void onCropsGrowPost(World worldIn, BlockPos pos, IBlockState state) { MinecraftForge.EVENT_BUS.post(new BlockEvent.CropGrowEvent.Post(worldIn, pos, state, worldIn.getBlockState(pos))); } @@ -1267,7 +1262,6 @@ public class ForgeHooks public static boolean onFarmlandTrample(World world, BlockPos pos, IBlockState state, float fallDistance, Entity entity) { - if (entity.canTrample(state, pos, fallDistance)) { BlockEvent.FarmlandTrampleEvent event = new BlockEvent.FarmlandTrampleEvent(world, pos, state, fallDistance, entity); @@ -1318,4 +1312,11 @@ public class ForgeHooks } } + + public static int onNoteChange(World world, BlockPos pos, IBlockState state, int old, int _new) { + NoteBlockEvent.Change event = new NoteBlockEvent.Change(world, pos, state, old, _new); + if (MinecraftForge.EVENT_BUS.post(event)) + return -1; + return event.getVanillaNoteId(); + } } diff --git a/src/main/java/net/minecraftforge/common/IPlantable.java b/src/main/java/net/minecraftforge/common/IPlantable.java index ee8db043f2..fba11ace91 100644 --- a/src/main/java/net/minecraftforge/common/IPlantable.java +++ b/src/main/java/net/minecraftforge/common/IPlantable.java @@ -19,12 +19,28 @@ package net.minecraftforge.common; +import net.minecraft.block.BlockCrops; +import net.minecraft.block.BlockFlower; +import net.minecraft.block.BlockSapling; import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; import net.minecraft.util.math.BlockPos; -import net.minecraft.world.IWorldReader; +import net.minecraft.world.IBlockReader; public interface IPlantable { - EnumPlantType getPlantType(IWorldReader world, BlockPos pos); - IBlockState getPlant(IWorldReader world, BlockPos pos); + default EnumPlantType getPlantType(IBlockReader world, BlockPos pos) { + if (this instanceof BlockCrops) return EnumPlantType.Crop; + if (this instanceof BlockSapling) return EnumPlantType.Plains; + if (this instanceof BlockFlower) return EnumPlantType.Plains; + if (this == Blocks.DEAD_BUSH) return EnumPlantType.Desert; + if (this == Blocks.LILY_PAD) return EnumPlantType.Water; + if (this == Blocks.RED_MUSHROOM) return EnumPlantType.Cave; + if (this == Blocks.BROWN_MUSHROOM) return EnumPlantType.Cave; + if (this == Blocks.NETHER_WART) return EnumPlantType.Nether; + if (this == Blocks.TALL_GRASS) return EnumPlantType.Plains; + return net.minecraftforge.common.EnumPlantType.Plains; + } + + IBlockState getPlant(IBlockReader world, BlockPos pos); } diff --git a/src/main/java/net/minecraftforge/common/IShearable.java b/src/main/java/net/minecraftforge/common/IShearable.java index 4e361312ec..f9348ec0d2 100644 --- a/src/main/java/net/minecraftforge/common/IShearable.java +++ b/src/main/java/net/minecraftforge/common/IShearable.java @@ -48,7 +48,9 @@ public interface IShearable * @param pos Block's position in world. * @return If this is shearable, and onSheared should be called. */ - boolean isShearable(@Nonnull ItemStack item, IWorldReader world, BlockPos pos); + default boolean isShearable(@Nonnull ItemStack item, IWorldReader world, BlockPos pos) { + return true; + } /** * Performs the shear function on this object. diff --git a/src/main/java/net/minecraftforge/common/asm/RuntimeEnumExtender.java b/src/main/java/net/minecraftforge/common/asm/RuntimeEnumExtender.java index 68b893a4f4..36f4ec8e0d 100644 --- a/src/main/java/net/minecraftforge/common/asm/RuntimeEnumExtender.java +++ b/src/main/java/net/minecraftforge/common/asm/RuntimeEnumExtender.java @@ -95,8 +95,9 @@ public class RuntimeEnumExtender implements ILaunchPluginService { { LOGGER.error(()->new AdvancedLogMessageAdapter(sb-> { sb.append("Enum has create method with no matching constructor:\n"); + sb.append(" Enum: " + classType.getDescriptor()).append("\n"); sb.append(" Target: ").append(desc).append("\n"); - classNode.methods.stream().filter(m -> m.name.equals("")).forEach(m -> sb.append(" :").append(m.desc).append("\n")); + classNode.methods.stream().filter(m -> m.name.equals("")).forEach(m -> sb.append(" : ").append(m.desc).append("\n")); })); throw new IllegalStateException("Enum has create method with no matching constructor: " + desc); } diff --git a/src/main/java/net/minecraftforge/common/extensions/IForgeBlock.java b/src/main/java/net/minecraftforge/common/extensions/IForgeBlock.java index 0f664e7e2b..866c53b4d6 100644 --- a/src/main/java/net/minecraftforge/common/extensions/IForgeBlock.java +++ b/src/main/java/net/minecraftforge/common/extensions/IForgeBlock.java @@ -33,8 +33,12 @@ import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.EntitySpawnPlacementRegistry; +import net.minecraft.entity.boss.EntityDragon; +import net.minecraft.entity.boss.EntityWither; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.projectile.EntityWitherSkull; import net.minecraft.init.Blocks; +import net.minecraft.init.Items; import net.minecraft.init.MobEffects; import net.minecraft.item.EnumDyeColor; import net.minecraft.item.Item; @@ -42,6 +46,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.pathfinding.PathNodeType; import net.minecraft.state.IProperty; import net.minecraft.state.properties.BedPart; +import net.minecraft.tileentity.TileEntity; import net.minecraft.util.*; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; @@ -51,9 +56,11 @@ import net.minecraft.world.Explosion; import net.minecraft.world.IBlockReader; import net.minecraft.world.IWorld; import net.minecraft.world.IWorldReader; +import net.minecraft.world.IWorldReaderBase; import net.minecraft.world.IWorldWriter; import net.minecraft.world.World; import net.minecraft.world.WorldServer; +import net.minecraft.world.dimension.EndDimension; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.common.EnumPlantType; @@ -121,7 +128,7 @@ public interface IForgeBlock * @param pos Block position in world * @return True if the block is a full cube */ - default boolean isNormalCube(IBlockState state, IWorldReader world, BlockPos pos) + default boolean isNormalCube(IBlockState state, IBlockReader world, BlockPos pos) { return state.isNormalCube(); } @@ -167,11 +174,75 @@ public interface IForgeBlock */ default boolean hasTileEntity(IBlockState state) { - return this.getBlock().hasTileEntity(); + return this instanceof ITileEntityProvider; } + /** + * Called throughout the code as a replacement for ITileEntityProvider.createNewTileEntity + * Return the same thing you would from that function. + * This will fall back to ITileEntityProvider.createNewTileEntity(World) if this block is a ITileEntityProvider + * + * @param state The state of the current block + * @param world The world to create the TE in + * @return A instance of a class extending TileEntity + */ + @Nullable + default TileEntity createTileEntity(IBlockState state, IBlockReader world) + { + if (getBlock() instanceof ITileEntityProvider) + return ((ITileEntityProvider)getBlock()).createNewTileEntity(world); + return null; + } + + /** + * Return true from this function if the player with silk touch can harvest this block directly, and not it's normal drops. + * + * @param state current block state + * @param world The world + * @param pos Block position in world + * @param player The player doing the harvesting + * @return True if the block can be directly harvested using silk touch + */ boolean canSilkHarvest(IBlockState state, IWorldReader world, BlockPos pos, EntityPlayer player); + /** + * Determines if the player can harvest this block, obtaining it's drops when the block is destroyed. + * + * @param world The current world + * @param pos The block's current position + * @param player The player damaging the block + * @return True to spawn the drops + */ + default public boolean canHarvestBlock(IBlockState state, IBlockReader world, BlockPos pos, EntityPlayer player) + { + return net.minecraftforge.common.ForgeHooks.canHarvestBlock(state, player, world, pos); + } + + /** + * Called when a player removes a block. This is responsible for + * actually destroying the block, and the block is intact at time of call. + * This is called regardless of whether the player can harvest the block or + * not. + * + * Return true if the block is actually destroyed. + * + * Note: When used in multiplayer, this is called on both client and + * server sides! + * + * @param state The current state. + * @param world The current world + * @param player The player damaging the block, may be null + * @param pos Block position in world + * @param willHarvest True if Block.harvestBlock will be called after this, if the return in true. + * Can be useful to delay the destruction of tile entities till after harvestBlock + * @return True if the block is actually destroyed. + */ + default boolean removedByPlayer(IBlockState state, World world, BlockPos pos, EntityPlayer player, boolean willHarvest) + { + getBlock().onBlockHarvested(world, pos, state, player); + return world.setBlockState(pos, net.minecraft.init.Blocks.AIR.getDefaultState(), world.isRemote ? 11 : 3); + } + /** * Determines if this block is classified as a Bed, Allowing * players to sleep in it, though the block has to specifically @@ -198,10 +269,9 @@ public interface IForgeBlock * @param type The Mob Category Type * @return True to allow a mob of the specified category to spawn, false to prevent it. */ - @SuppressWarnings("deprecation") default boolean canCreatureSpawn(IBlockState state, IWorldReader world, BlockPos pos, EntitySpawnPlacementRegistry.SpawnPlacementType type) { - return this.getBlock().isTopSolid(state); + return state.isTopSolid(); } /** * Returns the position that the player is moved to upon @@ -276,18 +346,6 @@ public interface IForgeBlock */ default void beginLeaveDecay(IBlockState state, IWorldReader world, BlockPos pos) {} - /** - * Determines if this block can prevent leaves connected to it from decaying. - * @param state The current state - * @param world The current world - * @param pos Block position in world - * @return true if the presence this block can prevent leaves from decaying. - */ - default boolean canSustainLeaves(IBlockState state, IWorldReader world, BlockPos pos) - { - return false; - } - /** * Determines if this block is considered a leaf block, used to apply the leaf decay and generation system. * @@ -330,17 +388,6 @@ public interface IForgeBlock return isAir(state, world, pos) || isLeaves(state, world, pos); } - /** - * - * @param world The current world - * @param pos Block position in world - * @return true if the block is wood (logs) - */ - default boolean isWood(IBlockState state, IWorldReader world, BlockPos pos) - { - return false; - } - /** * Determines if the current block is replaceable by Ore veins during world generation. * @@ -352,7 +399,7 @@ public interface IForgeBlock * @return True to allow this block to be replaced by a ore */ default boolean isReplaceableOreGen(IBlockState state, IWorldReader world, BlockPos pos, Predicate target) - { + { //TODO: Re-evaluate with new world gen return target.test(state); } @@ -379,7 +426,10 @@ public interface IForgeBlock * @param pos Block position in world * @param explosion The explosion instance affecting the block */ - void onBlockExploded(IBlockState state, World world, BlockPos pos, Explosion explosion); + default void onBlockExploded(IBlockState state, World world, BlockPos pos, Explosion explosion) { + world.removeBlock(pos); + getBlock().onExplosionDestroy(world, pos, explosion); + } /** * Determine if this block can make a redstone connection on the side provided, @@ -452,6 +502,7 @@ public interface IForgeBlock { return false; } + /** * Allows a block to override the standard vanilla running particles. * This is called from {@link Entity#spawnRunningParticles} and is called both, @@ -504,47 +555,7 @@ public interface IForgeBlock * @param plantable The plant that wants to check * @return True to allow the plant to be planted/stay. */ - default boolean canSustainPlant(IBlockState state, IWorldReader world, BlockPos pos, EnumFacing facing, IPlantable plantable) - { - IBlockState plant = plantable.getPlant(world, pos.offset(facing)); - EnumPlantType type = plantable.getPlantType(world, pos.offset(facing)); - - if (plant.getBlock() == Blocks.CACTUS) - { - return this.getBlock() == Blocks.CACTUS && this.getBlock() == Blocks.SAND; - } - - if (plant.getBlock() == Blocks.SUGAR_CANE) - { - return true; - } - - if (plantable instanceof BlockBush && ((BlockBush)plantable).isValidPosition(state, world, pos)) - { - return true; - } - - switch (type) - { - case Desert: return this.getBlock() == Blocks.SAND || this.getBlock() == Blocks.TERRACOTTA || - this.getBlock() instanceof BlockGlazedTerracotta; - case Nether: return this.getBlock() == Blocks.SOUL_SAND; - case Crop: return this.getBlock() == Blocks.FARMLAND; - case Cave: return state.isTopSolid(); - case Plains: return this.getBlock() == Blocks.GRASS || this.getBlock() == Blocks.DIRT || - this.getBlock() == Blocks.FARMLAND; - case Water: return state.getMaterial() == Material.WATER; //&& state.getValue(BlockLiquidWrapper) - case Beach: - boolean isBeach = this.getBlock() == Blocks.GRASS || this.getBlock() == Blocks.DIRT || - this.getBlock() == Blocks.SAND; - boolean hasWater = (world.getBlockState(pos.east()).getMaterial() == Material.WATER || - world.getBlockState(pos.west()).getMaterial() == Material.WATER || - world.getBlockState(pos.north()).getMaterial() == Material.WATER || - world.getBlockState(pos.south()).getMaterial() == Material.WATER); - return isBeach && hasWater; - } - return false; - } + boolean canSustainPlant(IBlockState state, IBlockReader world, BlockPos pos, EnumFacing facing, IPlantable plantable); /** * Called when a plant grows on this block, only implemented for saplings using the WorldGen*Trees classes right now. @@ -575,7 +586,7 @@ public interface IForgeBlock * @param pos Block position in world * @return True if the soil should be considered fertile. */ - default boolean isFertile(IBlockState state, IWorldReader world, BlockPos pos) + default boolean isFertile(IBlockState state, IBlockReader world, BlockPos pos) { if (this.getBlock() == Blocks.FARMLAND) return state.get(BlockFarmland.MOISTURE) > 0; @@ -583,24 +594,6 @@ public interface IForgeBlock return false; } - /** - * Location aware and overrideable version of the lightOpacity array, - * return the number to subtract from the light value when it passes through this block. - * - * This is not guaranteed to have the tile entity in place before this is called, so it is - * Recommended that you have your tile entity call relight after being placed if you - * rely on it for light info. - * - * @param state The Block state - * @param world The current world - * @param pos Block position in world - * @return The amount of light to block, 0 for air, 255 for fully opaque. - */ - default int getLightOpacity(IBlockState state, IWorldReader world, BlockPos pos) - { - return state.getOpacity(world, pos); - } - /** * Determines if this block can be used as the base of a beacon. * @@ -628,46 +621,33 @@ public interface IForgeBlock return 0; } - default boolean rotateBlock(IBlockState state, IWorld world, BlockPos pos, EnumFacing axis) + @SuppressWarnings("deprecation") + default IBlockState rotate(IBlockState state, IWorld world, BlockPos pos, Rotation direction) { - state.getValues().keySet().forEach(prop -> + return state.rotate(direction); + } + + /** + * Get the rotations that can apply to the block at the specified coordinates. Null means no rotations are possible. + * Note, this is up to the block to decide. It may not be accurate or representative. + * @param state The current state + * @param world The world + * @param pos Block position in world + * @return An array of valid axes to rotate around, or null for none or unknown + */ + @Nullable + default EnumFacing[] getValidRotations(IBlockState state, IBlockReader world, BlockPos pos) + { + for (IProperty prop : state.getProperties()) { - if (prop.getName().equals("facing") || prop.getName().equals("rotation") && prop.getValueClass() == EnumFacing.class) + if ((prop.getName().equals("facing") || prop.getName().equals("rotation")) && prop.getValueClass() == EnumFacing.class) { - Block block = state.getBlock(); - if (!(block instanceof BlockBed) && !(block instanceof BlockPistonExtension)) - { - IBlockState newState; - @SuppressWarnings("unchecked") - IProperty facingIProperty = (IProperty) prop; - EnumFacing facing = state.get(facingIProperty); - Collection validFacing = facingIProperty.getAllowedValues(); - - // rotate horizontal facings clockwise - if (validFacing.size() == 4 && !validFacing.contains(EnumFacing.UP) && !validFacing.contains(EnumFacing.DOWN)) - { - newState = state.with(facingIProperty, facing.rotateY()); - } - else - { - // rotate other facings about the axis - EnumFacing rotatedFacing = facing.rotateAround(axis.getAxis()); - if (validFacing.contains(rotatedFacing)) - { - newState = state.with(facingIProperty, rotatedFacing); - } - else // abnormal facing property, just cycle it - { - newState = state.cycle(facingIProperty); - } - } - - world.setBlockState(pos, newState, 3); - } - + @SuppressWarnings("unchecked") + Collection values = ((Collection)prop.getAllowedValues()); + return values.toArray(new EnumFacing[values.size()]); } - }); - return false; + } + return null; } /** @@ -691,8 +671,21 @@ public interface IForgeBlock * @param fortune * @return Amount of XP from breaking this block. */ + @SuppressWarnings("unchecked") default boolean recolorBlock(IBlockState state, IWorld world, BlockPos pos, EnumFacing facing, EnumDyeColor color) { + for (IProperty prop : state.getProperties()) + { + if (prop.getName().equals("color") && prop.getValueClass() == EnumDyeColor.class) + { + EnumDyeColor current = (EnumDyeColor)state.get(prop); + if (current != color && prop.getAllowedValues().contains(color)) + { + world.setBlockState(pos, state.with(((IProperty)prop), color), 3); + return true; + } + } + } return false; } @@ -782,7 +775,6 @@ public interface IForgeBlock { return this.getBlock().getRenderLayer() == layer; } - // For Internal use only to capture droped items inside getDrops /** * Sensitive version of getSoundType @@ -891,7 +883,7 @@ public interface IForgeBlock * @param facing The side the connecting block is on * @return True to allow another block to connect to this block */ - default boolean canBeConnectedTo(IBlockState state, IWorldReader world, BlockPos pos, EnumFacing facing) + default boolean canBeConnectedTo(IBlockState state, IBlockReader world, BlockPos pos, EnumFacing facing) { return false; } @@ -914,16 +906,15 @@ public interface IForgeBlock * @param side The side of this block that the chest lid is trying to open into * @return true if the chest should be prevented from opening by this block */ - @SuppressWarnings("deprecation") - default boolean doesSideBlockChestOpening(IBlockState blockState, IWorldReader world, BlockPos pos, EnumFacing side) + default boolean doesSideBlockChestOpening(IBlockState blockState, IBlockReader world, BlockPos pos, EnumFacing side) { ResourceLocation registryName = this.getBlock().getRegistryName(); if (registryName != null && "minecraft".equals(registryName.getNamespace())) { // maintain the vanilla behavior of https://bugs.mojang.com/browse/MC-378 - return isNormalCube(blockState, world, pos); + return blockState.isNormalCube(world, pos); } - return this.getBlock().isTopSolid(blockState); + return blockState.isTopSolid(); } /** @@ -935,4 +926,123 @@ public interface IForgeBlock return state.getBlock() == Blocks.SLIME_BLOCK; } + /** + * This gets a complete list of items dropped from this block. + * + * @param state Current state + * @param drops add all items this block drops to this drops list + * @param world The current world, Currently hard 'World' and not 'IBlockReder' because vanilla needs it. + * @param pos Block position in world + * @param fortune Breakers fortune level + */ + default void getDrops(IBlockState state, NonNullList drops, World world, BlockPos pos, int fortune) + { + int count = getBlock().getItemsToDropCount(state, fortune, world, pos, world.rand); + for (int i = 0; i < count; i++) + { + Item item = getBlock().getItemDropped(state, world, pos, fortune).asItem(); + if (item != Items.AIR) + drops.add(new ItemStack(item)); + } + } + + /** + * Chance that fire will spread and consume this block. + * 300 being a 100% chance, 0, being a 0% chance. + * + * @param state The current state + * @param world The current world + * @param pos Block position in world + * @param face The face that the fire is coming from + * @return A number ranging from 0 to 300 relating used to determine if the block will be consumed by fire + */ + default int getFlammability(IBlockState state, IBlockReader world, BlockPos pos, EnumFacing face) + { + return ((BlockFire)Blocks.FIRE).getFlammability(getBlock()); + } + + /** + * Called when fire is updating, checks if a block face can catch fire. + * + * + * @param state The current state + * @param world The current world + * @param pos Block position in world + * @param face The face that the fire is coming from + * @return True if the face can be on fire, false otherwise. + */ + default boolean isFlammable(IBlockState state, IBlockReader world, BlockPos pos, EnumFacing face) + { + return state.getFlammability(world, pos, face) > 0; + } + + /** + * Called when fire is updating on a neighbor block. + * The higher the number returned, the faster fire will spread around this block. + * + * @param state The current state + * @param world The current world + * @param pos Block position in world + * @param face The face that the fire is coming from + * @return A number that is used to determine the speed of fire growth around the block + */ + default int getFireSpreadSpeed(IBlockState state, IBlockReader world, BlockPos pos, EnumFacing face) + { + return ((BlockFire)Blocks.FIRE).getEncouragement(getBlock()); + } + + /** + * Currently only called by fire when it is on top of this block. + * Returning true will prevent the fire from naturally dying during updating. + * Also prevents firing from dying from rain. + * + * @param state The current state + * @param world The current world + * @param pos Block position in world + * @param side The face that the fire is coming from + * @return True if this block sustains fire, meaning it will never go out. + */ + default boolean isFireSource(IBlockState state, IBlockReader world, BlockPos pos, EnumFacing side) + { + if (side != EnumFacing.UP) + return false; + if (getBlock() == Blocks.NETHERRACK || getBlock() == Blocks.MAGMA_BLOCK) + return true; + if (world instanceof World && ((World)world).dimension instanceof EndDimension && getBlock() == Blocks.BEDROCK) + return true; + return false; + } + + /** + * Determines if this block is can be destroyed by the specified entities normal behavior. + * + * @param state The current state + * @param world The current world + * @param pos Block position in world + * @return True to allow the ender dragon to destroy this block + */ + default boolean canEntityDestroy(IBlockState state, IBlockReader world, BlockPos pos, Entity entity) + { + if (entity instanceof EntityDragon) + { + return this != Blocks.BARRIER && + this != Blocks.OBSIDIAN && + this != Blocks.END_STONE && + this != Blocks.BEDROCK && + this != Blocks.END_PORTAL && + this != Blocks.END_PORTAL_FRAME && + this != Blocks.COMMAND_BLOCK && + this != Blocks.REPEATING_COMMAND_BLOCK && + this != Blocks.CHAIN_COMMAND_BLOCK && + this != Blocks.IRON_BARS && + this != Blocks.END_GATEWAY; + } + else if ((entity instanceof EntityWither) || + (entity instanceof EntityWitherSkull)) + { + return EntityWither.canDestroyBlock(getBlock()); + } + + return true; + } } diff --git a/src/main/java/net/minecraftforge/common/extensions/IForgeBlockState.java b/src/main/java/net/minecraftforge/common/extensions/IForgeBlockState.java index 523996c4e7..660d7c72da 100644 --- a/src/main/java/net/minecraftforge/common/extensions/IForgeBlockState.java +++ b/src/main/java/net/minecraftforge/common/extensions/IForgeBlockState.java @@ -24,7 +24,6 @@ import java.util.function.Predicate; import javax.annotation.Nullable; import net.minecraft.block.*; -import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; import net.minecraft.client.particle.ParticleManager; import net.minecraft.entity.Entity; @@ -35,8 +34,8 @@ import net.minecraft.item.EnumDyeColor; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.pathfinding.PathNodeType; +import net.minecraft.tileentity.TileEntity; import net.minecraft.util.*; -import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.Vec3d; @@ -107,7 +106,7 @@ public interface IForgeBlockState * @param pos Block position in world * @return True if the block is a full cube */ - default boolean isNormalCube(IWorldReader world, BlockPos pos) + default boolean isNormalCube(IBlockReader world, BlockPos pos) { return getBlockState().getBlock().isNormalCube(getBlockState(), world, pos); } @@ -142,11 +141,70 @@ public interface IForgeBlockState return getBlockState().getBlock().hasTileEntity(getBlockState()); } + /** + * Called throughout the code as a replacement for ITileEntityProvider.createNewTileEntity + * Return the same thing you would from that function. + * This will fall back to ITileEntityProvider.createNewTileEntity(World) if this block is a ITileEntityProvider + * + * @param world The world to create the TE in + * @return A instance of a class extending TileEntity + */ + @Nullable + default TileEntity createTileEntity(IBlockReader world) + { + return getBlockState().getBlock().createTileEntity(getBlockState(), world); + } + + /** + * Return true from this function if the player with silk touch can harvest this block directly, and not it's normal drops. + * + * @param world The world + * @param pos Block position in world + * @param player The player doing the harvesting + * @return True if the block can be directly harvested using silk touch + */ default boolean canSilkHarvest(IWorldReader world, BlockPos pos, EntityPlayer player) { return getBlockState().getBlock().canSilkHarvest(getBlockState(), world, pos, player); } + /** + * Determines if the player can harvest this block, obtaining it's drops when the block is destroyed. + * + * @param world The current world + * @param pos The block's current position + * @param player The player damaging the block + * @return True to spawn the drops + */ + default boolean canHarvestBlock(IBlockReader world, BlockPos pos, EntityPlayer player) + { + return getBlockState().getBlock().canHarvestBlock(getBlockState(), world, pos, player); + } + + + /** + * Called when a player removes a block. This is responsible for + * actually destroying the block, and the block is intact at time of call. + * This is called regardless of whether the player can harvest the block or + * not. + * + * Return true if the block is actually destroyed. + * + * Note: When used in multiplayer, this is called on both client and + * server sides! + * + * @param world The current world + * @param player The player damaging the block, may be null + * @param pos Block position in world + * @param willHarvest True if Block.harvestBlock will be called after this, if the return in true. + * Can be useful to delay the destruction of tile entities till after harvestBlock + * @return True if the block is actually destroyed. + */ + default boolean removedByPlayer(World world, BlockPos pos, EntityPlayer player, boolean willHarvest) + { + return getBlockState().getBlock().removedByPlayer(getBlockState(), world, pos, player, willHarvest); + } + /** * Determines if this block is classified as a Bed, Allowing * players to sleep in it, though the block has to specifically @@ -239,17 +297,6 @@ public interface IForgeBlockState getBlockState().getBlock().beginLeaveDecay(getBlockState(), world, pos); } - /** - * Determines if this block can prevent leaves connected to it from decaying. - * @param world The current world - * @param pos Block position in world - * @return true if the presence this block can prevent leaves from decaying. - */ - default boolean canSustainLeaves(IWorldReader world, BlockPos pos) - { - return getBlockState().getBlock().canSustainLeaves(getBlockState(), world, pos); - } - /** * Determines if this block is considered a leaf block, used to apply the leaf decay and generation system. * @@ -289,17 +336,6 @@ public interface IForgeBlockState return getBlockState().getBlock().canBeReplacedByLeaves(getBlockState(), world, pos); } - /** - * - * @param world The current world - * @param pos Block position in world - * @return true if the block is wood (logs) - */ - default boolean isWood(IWorldReader world, BlockPos pos) - { - return getBlockState().getBlock().isWood(getBlockState(), world, pos); - } - /** * Determines if the current block is replaceable by Ore veins during world generation. * @@ -457,7 +493,7 @@ public interface IForgeBlockState * @param plantable The plant that wants to check * @return True to allow the plant to be planted/stay. */ - default boolean canSustainPlant(IWorldReader world, BlockPos pos, EnumFacing facing, IPlantable plantable) + default boolean canSustainPlant(IBlockReader world, BlockPos pos, EnumFacing facing, IPlantable plantable) { return getBlockState().getBlock().canSustainPlant(getBlockState(), world, pos, facing, plantable); } @@ -489,29 +525,11 @@ public interface IForgeBlockState * @param pos Block position in world * @return True if the soil should be considered fertile. */ - default boolean isFertile(IWorldReader world, BlockPos pos) + default boolean isFertile(IBlockReader world, BlockPos pos) { return getBlockState().getBlock().isFertile(getBlockState(), world, pos); } - /** - * Location aware and overrideable version of the lightOpacity array, - * return the number to subtract from the light value when it passes through this block. - * - * This is not guaranteed to have the tile entity in place before this is called, so it is - * Recommended that you have your tile entity call relight after being placed if you - * rely on it for light info. - * - * @param state The Block state - * @param world The current world - * @param pos Block position in world - * @return The amount of light to block, 0 for air, 255 for fully opaque. - */ - default int getLightOpacity(IWorldReader world, BlockPos pos) - { - return getBlockState().getBlock().getLightOpacity(getBlockState(), world, pos); - } - /** * Determines if this block can be used as the base of a beacon. * @@ -524,6 +542,7 @@ public interface IForgeBlockState { return getBlockState().getBlock().isBeaconBase(getBlockState(), world, pos, beacon); } + /** * Gathers how much experience this block drops when broken. * @@ -537,9 +556,9 @@ public interface IForgeBlockState return getBlockState().getBlock().getExpDrop(getBlockState(), world, pos, fortune); } - default boolean rotateBlock(IWorld world, BlockPos pos, EnumFacing axis) + default IBlockState rotate(IWorld world, BlockPos pos, Rotation direction) { - return getBlockState().getBlock().rotateBlock(getBlockState(), world, pos, axis); + return getBlockState().getBlock().rotate(getBlockState(), world, pos, direction); } @@ -554,6 +573,16 @@ public interface IForgeBlockState return getBlockState().getBlock().getEnchantPowerBonus(getBlockState(), world, pos); } + /** + * //TODO: Re-Evaluate + * Gathers how much experience this block drops when broken. + * + * @param state The current state + * @param world The world + * @param pos Block position + * @param fortune + * @return Amount of XP from breaking this block. + */ default boolean recolorBlock(IWorld world, BlockPos pos, EnumFacing facing, EnumDyeColor color) { return getBlockState().getBlock().recolorBlock(getBlockState(), world, pos, facing, color); @@ -723,7 +752,6 @@ public interface IForgeBlockState return getBlockState().getBlock().getStateForPlacement(getBlockState(), facing, state2, world, pos1, pos2, hand); } - /** * Determines if another block can connect to this block * @@ -732,7 +760,7 @@ public interface IForgeBlockState * @param facing The side the connecting block is on * @return True to allow another block to connect to this block */ - default boolean canBeConnectedTo(IWorldReader world, BlockPos pos, EnumFacing facing) + default boolean canBeConnectedTo(IBlockReader world, BlockPos pos, EnumFacing facing) { return getBlockState().getBlock().canBeConnectedTo(getBlockState(), world, pos, facing); } @@ -755,7 +783,7 @@ public interface IForgeBlockState * @param side The side of this block that the chest lid is trying to open into * @return true if the chest should be prevented from opening by this block */ - default boolean doesSideBlockChestOpening(IWorldReader world, BlockPos pos, EnumFacing side) + default boolean doesSideBlockChestOpening(IBlockReader world, BlockPos pos, EnumFacing side) { return getBlockState().getBlock().doesSideBlockChestOpening(getBlockState(), world, pos, side); } @@ -769,4 +797,97 @@ public interface IForgeBlockState return getBlockState().getBlock().isStickyBlock(getBlockState()); } + /** + * This gets a complete list of items dropped from this block. + * + * @param drops add all items this block drops to this drops list + * @param world The current world + * @param pos Block position in world + * @param fortune Breakers fortune level + */ + default void getDrops(NonNullList drops, World world, BlockPos pos, int fortune) + { + getBlockState().getBlock().getDrops(getBlockState(), drops, world, pos, fortune); + } + + /** + * Chance that fire will spread and consume this block. + * 300 being a 100% chance, 0, being a 0% chance. + * + * @param world The current world + * @param pos Block position in world + * @param face The face that the fire is coming from + * @return A number ranging from 0 to 300 relating used to determine if the block will be consumed by fire + */ + default int getFlammability(IBlockReader world, BlockPos pos, EnumFacing face) + { + return getBlockState().getBlock().getFlammability(getBlockState(), world, pos, face); + } + + /** + * Called when fire is updating, checks if a block face can catch fire. + * + * @param world The current world + * @param pos Block position in world + * @param face The face that the fire is coming from + * @return True if the face can be on fire, false otherwise. + */ + default boolean isFlammable(IBlockReader world, BlockPos pos, EnumFacing face) + { + return getBlockState().getBlock().isFlammable(getBlockState(), world, pos, face); + } + + /** + * Called when fire is updating on a neighbor block. + * The higher the number returned, the faster fire will spread around this block. + * + * @param world The current world + * @param pos Block position in world + * @param face The face that the fire is coming from + * @return A number that is used to determine the speed of fire growth around the block + */ + default int getFireSpreadSpeed(IBlockReader world, BlockPos pos, EnumFacing face) + { + return getBlockState().getBlock().getFireSpreadSpeed(getBlockState(), world, pos, face); + } + + /** + * Currently only called by fire when it is on top of this block. + * Returning true will prevent the fire from naturally dying during updating. + * Also prevents firing from dying from rain. + * + * @param world The current world + * @param pos Block position in world + * @param side The face that the fire is coming from + * @return True if this block sustains fire, meaning it will never go out. + */ + default boolean isFireSource(IBlockReader world, BlockPos pos, EnumFacing side) + { + return getBlockState().getBlock().isFireSource(getBlockState(), world, pos, side); + } + + /** + * Determines if this block is can be destroyed by the specified entities normal behavior. + * + * @param world The current world + * @param pos Block position in world + * @return True to allow the ender dragon to destroy this block + */ + default boolean canEntityDestroy(IBlockReader world, BlockPos pos, Entity entity) + { + return getBlockState().getBlock().canEntityDestroy(getBlockState(), world, pos, entity); + } + + /** + * Get the rotations that can apply to the block at the specified coordinates. Null means no rotations are possible. + * Note, this is up to the block to decide. It may not be accurate or representative. + * @param world The world + * @param pos Block position in world + * @return An array of valid axes to rotate around, or null for none or unknown + */ + @Nullable + default EnumFacing[] getValidRotations(IBlockReader world, BlockPos pos) + { + return getBlockState().getBlock().getValidRotations(getBlockState(), world, pos); + } } diff --git a/src/main/java/net/minecraftforge/event/ForgeEventFactory.java b/src/main/java/net/minecraftforge/event/ForgeEventFactory.java index e8935a2a7c..692834f1d3 100644 --- a/src/main/java/net/minecraftforge/event/ForgeEventFactory.java +++ b/src/main/java/net/minecraftforge/event/ForgeEventFactory.java @@ -254,7 +254,7 @@ public class ForgeEventFactory return event.getDisplayname(); } - public static float fireBlockHarvesting(List drops, World world, BlockPos pos, IBlockState state, int fortune, float dropChance, boolean silkTouch, EntityPlayer player) + public static float fireBlockHarvesting(NonNullList drops, World world, BlockPos pos, IBlockState state, int fortune, float dropChance, boolean silkTouch, EntityPlayer player) { BlockEvent.HarvestDropsEvent event = new BlockEvent.HarvestDropsEvent(world, pos, state, fortune, dropChance, drops, player, silkTouch); MinecraftForge.EVENT_BUS.post(event); diff --git a/src/main/java/net/minecraftforge/event/world/BlockEvent.java b/src/main/java/net/minecraftforge/event/world/BlockEvent.java index 7e34b524f0..72fecd46aa 100644 --- a/src/main/java/net/minecraftforge/event/world/BlockEvent.java +++ b/src/main/java/net/minecraftforge/event/world/BlockEvent.java @@ -22,17 +22,15 @@ package net.minecraftforge.event.world; import java.util.EnumSet; import java.util.List; -import net.minecraft.block.Block; import net.minecraft.block.BlockPortal; -import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Enchantments; import net.minecraft.item.ItemStack; import net.minecraft.util.EnumHand; +import net.minecraft.util.NonNullList; import net.minecraft.util.math.BlockPos; import net.minecraft.util.EnumFacing; import net.minecraft.world.World; @@ -90,12 +88,12 @@ public class BlockEvent extends Event public static class HarvestDropsEvent extends BlockEvent { private final int fortuneLevel; - private final List drops; + private final NonNullList drops; private final boolean isSilkTouching; private float dropChance; // Change to e.g. 1.0f, if you manipulate the list and want to guarantee it always drops private final EntityPlayer harvester; // May be null for non-player harvesting such as explosions or machines - public HarvestDropsEvent(World world, BlockPos pos, IBlockState state, int fortuneLevel, float dropChance, List drops, EntityPlayer harvester, boolean isSilkTouching) + public HarvestDropsEvent(World world, BlockPos pos, IBlockState state, int fortuneLevel, float dropChance, NonNullList drops, EntityPlayer harvester, boolean isSilkTouching) { super(world, pos, state); this.fortuneLevel = fortuneLevel; diff --git a/src/main/java/net/minecraftforge/event/world/NoteBlockEvent.java b/src/main/java/net/minecraftforge/event/world/NoteBlockEvent.java index b23fbb97f4..3f1e525765 100644 --- a/src/main/java/net/minecraftforge/event/world/NoteBlockEvent.java +++ b/src/main/java/net/minecraftforge/event/world/NoteBlockEvent.java @@ -20,6 +20,7 @@ package net.minecraftforge.event.world; import net.minecraft.block.state.IBlockState; +import net.minecraft.state.properties.NoteBlockInstrument; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.eventbus.api.Cancelable; @@ -86,20 +87,20 @@ public class NoteBlockEvent extends BlockEvent @Cancelable public static class Play extends NoteBlockEvent { - private Instrument instrument; + private NoteBlockInstrument instrument; - public Play(World world, BlockPos pos, IBlockState state, int note, int instrument) + public Play(World world, BlockPos pos, IBlockState state, int note, NoteBlockInstrument instrument) { super(world, pos, state, note); - this.setInstrument(Instrument.fromId(instrument)); + this.instrument = instrument; } - public Instrument getInstrument() + public NoteBlockInstrument getInstrument() { return instrument; } - public void setInstrument(Instrument instrument) + public void setInstrument(NoteBlockInstrument instrument) { this.instrument = instrument; } @@ -133,32 +134,6 @@ public class NoteBlockEvent extends BlockEvent } } - /** - * Describes the types of musical Instruments that can be played by a Noteblock. - * The Instrument being played can be overridden with {@link NoteBlockEvent.Play#setInstrument(Instrument)} - */ - public static enum Instrument - { - PIANO, - BASSDRUM, - SNARE, - CLICKS, - BASSGUITAR, - FLUTE, - BELL, - GUITAR, - CHIME, - XYLOPHONE; - - // cache to avoid creating a new array every time - private static final Instrument[] values = values(); - - static Instrument fromId(int id) - { - return id < 0 || id >= values.length ? PIANO : values[id]; - } - } - /** * Information about the pitch of a Noteblock note. * For altered notes such as G-Sharp / A-Flat the Sharp variant is used here. diff --git a/src/main/java/net/minecraftforge/fml/UnsafeHacks.java b/src/main/java/net/minecraftforge/fml/UnsafeHacks.java index fb9e1b73d3..a91411e56c 100644 --- a/src/main/java/net/minecraftforge/fml/UnsafeHacks.java +++ b/src/main/java/net/minecraftforge/fml/UnsafeHacks.java @@ -19,9 +19,6 @@ package net.minecraftforge.fml; -import net.minecraft.network.Packet; -import net.minecraft.network.PacketBuffer; -import net.minecraftforge.fml.network.ICustomPacket; import sun.misc.Unsafe; import java.lang.reflect.Field; diff --git a/src/main/java/net/minecraftforge/registries/GameData.java b/src/main/java/net/minecraftforge/registries/GameData.java index 551cebd33c..20074039b5 100644 --- a/src/main/java/net/minecraftforge/registries/GameData.java +++ b/src/main/java/net/minecraftforge/registries/GameData.java @@ -281,12 +281,15 @@ public class GameData { static final BlockCallbacks INSTANCE = new BlockCallbacks(); - @SuppressWarnings("deprecation") @Override public void onAdd(IForgeRegistryInternal owner, RegistryManager stage, int id, Block block, @Nullable Block oldBlock) { @SuppressWarnings("unchecked") ClearableObjectIntIdentityMap blockstateMap = owner.getSlaveMap(BLOCKSTATE_TO_ID, ClearableObjectIntIdentityMap.class); + + int offset = 0; + for (IBlockState state : block.getStateContainer().getValidStates()) + blockstateMap.put(state, id + offset++); /* if ("minecraft:tripwire".equals(block.getRegistryName().toString())) //Tripwire is crap so we have to special case whee! @@ -329,29 +332,26 @@ public class GameData @Override public void onClear(IForgeRegistryInternal owner, RegistryManager stage) { -// owner.getSlaveMap(BLOCKSTATE_TO_ID, ClearableObjectIntIdentityMap.class).clear(); + owner.getSlaveMap(BLOCKSTATE_TO_ID, ClearableObjectIntIdentityMap.class).clear(); } @Override public void onCreate(IForgeRegistryInternal owner, RegistryManager stage) { -/* final ClearableObjectIntIdentityMap idMap = new ClearableObjectIntIdentityMap() { - @SuppressWarnings("deprecation") @Override public int get(IBlockState key) { Integer integer = (Integer)this.identityMap.get(key); // There are some cases where this map is queried to serialize a state that is valid, //but somehow not in this list, so attempt to get real metadata. Doing this hear saves us 7 patches - if (integer == null && key != null) - integer = this.identityMap.get(key.getBlock().getStateFromMeta(key.getBlock().getMetaFromState(key))); + //if (integer == null && key != null) + // integer = this.identityMap.get(key.getBlock().getStateFromMeta(key.getBlock().getMetaFromState(key))); return integer == null ? -1 : integer.intValue(); } }; owner.setSlaveMap(BLOCKSTATE_TO_ID, idMap); -*/ owner.setSlaveMap(BLOCK_TO_ITEM, Maps.newHashMap()); }