From c1ae2cdbf2dca2252b616d240236d13b316f7318 Mon Sep 17 00:00:00 2001 From: mezz Date: Mon, 3 Jul 2017 12:54:01 -0700 Subject: [PATCH] Improve furnace fuel handling (#4083) --- .../net/minecraft/item/Item.java.patch | 18 ++- .../tileentity/TileEntityFurnace.java.patch | 13 +- .../event/ForgeEventFactory.java | 21 ++++ .../furnace/FurnaceFuelBurnTimeEvent.java | 86 ++++++++++++++ .../fml/common/IFuelHandler.java | 6 + .../fml/common/registry/GameRegistry.java | 22 +++- .../debug/FurnaceFuelBurnTimeEventTest.java | 111 ++++++++++++++++++ .../models/item/flammable_gold_shovel.json | 6 + .../models/item/unburnable_wood_shovel.json | 6 + 9 files changed, 274 insertions(+), 15 deletions(-) create mode 100644 src/main/java/net/minecraftforge/event/furnace/FurnaceFuelBurnTimeEvent.java create mode 100644 src/test/java/net/minecraftforge/debug/FurnaceFuelBurnTimeEventTest.java create mode 100644 src/test/resources/assets/furnacefuelburntimeeventtest/models/item/flammable_gold_shovel.json create mode 100644 src/test/resources/assets/furnacefuelburntimeeventtest/models/item/unburnable_wood_shovel.json diff --git a/patches/minecraft/net/minecraft/item/Item.java.patch b/patches/minecraft/net/minecraft/item/Item.java.patch index 5764edcef9..a6d5590366 100644 --- a/patches/minecraft/net/minecraft/item/Item.java.patch +++ b/patches/minecraft/net/minecraft/item/Item.java.patch @@ -87,7 +87,7 @@ public CreativeTabs func_77640_w() { return this.field_77701_a; -@@ -438,11 +445,632 @@ +@@ -438,11 +445,642 @@ return false; } @@ -715,12 +715,22 @@ + return builder.build(); + } + ++ /** ++ * @return the fuel burn time for this itemStack in a furnace. ++ * Return 0 to make it not act as a fuel. ++ * Return -1 to let the default vanilla logic decide. ++ */ ++ public int getItemBurnTime(ItemStack itemStack) ++ { ++ return -1; ++ } ++ + /* ======================================== FORGE END =====================================*/ + public static void func_150900_l() { func_179214_a(Blocks.field_150350_a, new ItemAir(Blocks.field_150350_a)); -@@ -1002,6 +1630,8 @@ +@@ -1002,6 +1640,8 @@ private final float field_78010_h; private final float field_78011_i; private final int field_78008_j; @@ -729,7 +739,7 @@ private ToolMaterial(int p_i1874_3_, int p_i1874_4_, float p_i1874_5_, float p_i1874_6_, int p_i1874_7_) { -@@ -1037,6 +1667,7 @@ +@@ -1037,6 +1677,7 @@ return this.field_78008_j; } @@ -737,7 +747,7 @@ public Item func_150995_f() { if (this == WOOD) -@@ -1060,5 +1691,21 @@ +@@ -1060,5 +1701,21 @@ return this == DIAMOND ? Items.field_151045_i : null; } } diff --git a/patches/minecraft/net/minecraft/tileentity/TileEntityFurnace.java.patch b/patches/minecraft/net/minecraft/tileentity/TileEntityFurnace.java.patch index ee33e5b5e5..27cb14c431 100644 --- a/patches/minecraft/net/minecraft/tileentity/TileEntityFurnace.java.patch +++ b/patches/minecraft/net/minecraft/tileentity/TileEntityFurnace.java.patch @@ -62,19 +62,16 @@ } if (itemstack.func_77973_b() == Item.func_150898_a(Blocks.field_150360_v) && itemstack.func_77960_j() == 1 && !((ItemStack)this.field_145957_n.get(1)).func_190926_b() && ((ItemStack)this.field_145957_n.get(1)).func_77973_b() == Items.field_151133_ar) -@@ -316,6 +316,11 @@ +@@ -315,6 +315,8 @@ + } else { ++ int burnTime = net.minecraftforge.event.ForgeEventFactory.getItemBurnTime(p_145952_0_); ++ if (burnTime >= 0) return burnTime; Item item = p_145952_0_.func_77973_b(); -+ if (!item.getRegistryName().func_110624_b().equals("minecraft")) -+ { -+ int burnTime = net.minecraftforge.fml.common.registry.GameRegistry.getFuelValue(p_145952_0_); -+ if (burnTime != 0) return burnTime; -+ } if (item == Item.func_150898_a(Blocks.field_150376_bx)) - { -@@ -530,4 +535,22 @@ +@@ -530,4 +532,22 @@ { this.field_145957_n.clear(); } diff --git a/src/main/java/net/minecraftforge/event/ForgeEventFactory.java b/src/main/java/net/minecraftforge/event/ForgeEventFactory.java index 503a5a27ee..6ee1fa1b91 100644 --- a/src/main/java/net/minecraftforge/event/ForgeEventFactory.java +++ b/src/main/java/net/minecraftforge/event/ForgeEventFactory.java @@ -37,6 +37,7 @@ import net.minecraft.entity.passive.EntityAnimal; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer.SleepResult; import net.minecraft.init.Blocks; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ActionResult; @@ -103,6 +104,7 @@ import net.minecraftforge.event.entity.player.PlayerSleepInBedEvent; import net.minecraftforge.event.entity.player.PlayerWakeUpEvent; import net.minecraftforge.event.entity.player.SleepingLocationCheckEvent; import net.minecraftforge.event.entity.player.UseHoeEvent; +import net.minecraftforge.event.furnace.FurnaceFuelBurnTimeEvent; import net.minecraftforge.event.terraingen.ChunkGeneratorEvent; import net.minecraftforge.event.terraingen.PopulateChunkEvent; import net.minecraftforge.event.world.BlockEvent; @@ -115,6 +117,7 @@ import net.minecraftforge.event.world.WorldEvent; import net.minecraftforge.fml.common.ObfuscationReflectionHelper; import net.minecraftforge.fml.common.eventhandler.Event; import net.minecraftforge.fml.common.eventhandler.Event.Result; +import net.minecraftforge.fml.common.registry.GameRegistry; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -207,6 +210,24 @@ public class ForgeEventFactory return event.getResult(); } + public static int getItemBurnTime(@Nonnull ItemStack itemStack) + { + Item item = itemStack.getItem(); + int burnTime = item.getItemBurnTime(itemStack); + FurnaceFuelBurnTimeEvent event = new FurnaceFuelBurnTimeEvent(itemStack, burnTime); + MinecraftForge.EVENT_BUS.post(event); + if (event.getBurnTime() < 0) + { + // legacy handling + int fuelValue = GameRegistry.getFuelValueLegacy(itemStack); + if (fuelValue > 0) + { + return fuelValue; + } + } + return event.getBurnTime(); + } + public static int getExperienceDrop(EntityLivingBase entity, EntityPlayer attackingPlayer, int originalExperience) { LivingExperienceDropEvent event = new LivingExperienceDropEvent(entity, attackingPlayer, originalExperience); diff --git a/src/main/java/net/minecraftforge/event/furnace/FurnaceFuelBurnTimeEvent.java b/src/main/java/net/minecraftforge/event/furnace/FurnaceFuelBurnTimeEvent.java new file mode 100644 index 0000000000..f332a80cb4 --- /dev/null +++ b/src/main/java/net/minecraftforge/event/furnace/FurnaceFuelBurnTimeEvent.java @@ -0,0 +1,86 @@ +/* + * Minecraft Forge + * Copyright (c) 2016. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package net.minecraftforge.event.furnace; + +import javax.annotation.Nonnull; + +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.ForgeEventFactory; +import net.minecraftforge.fml.common.eventhandler.Cancelable; +import net.minecraftforge.fml.common.eventhandler.Event; + +/** + * {@link FurnaceFuelBurnTimeEvent} is fired when determining the fuel value for an ItemStack.
+ *
+ * To set the burn time of your own item, use {@link Item#getItemBurnTime(ItemStack)} instead.
+ *
+ * This event is fired from {@link ForgeEventFactory#getItemBurnTime(ItemStack)}.
+ *
+ * This event is {@link Cancelable} to prevent later handlers from changing the value.
+ *
+ * This event does not have a result. {@link HasResult}
+ *
+ * This event is fired on the {@link MinecraftForge#EVENT_BUS}. + **/ +@Cancelable +public class FurnaceFuelBurnTimeEvent extends Event +{ + @Nonnull + private final ItemStack itemStack; + private int burnTime; + + public FurnaceFuelBurnTimeEvent(@Nonnull ItemStack itemStack, int burnTime) + { + this.itemStack = itemStack; + this.burnTime = burnTime; + } + + /** + * Get the ItemStack "fuel" in question. + */ + @Nonnull + public ItemStack getItemStack() + { + return itemStack; + } + + /** + * Set the burn time for the given ItemStack. + * Setting it to 0 will prevent the item from being used as fuel, overriding vanilla's decision. + * Setting it to -1 will let vanilla decide on the fuel value, this is the default. + */ + public void setBurnTime(int burnTime) + { + this.burnTime = burnTime; + setCanceled(true); + } + + /** + * The resulting value of this event, the burn time for the ItemStack. + * A value of 0 will prevent the item from being used as fuel, overriding vanilla's decision. + * A value of -1 will let vanilla decide on the fuel value, this is the default for {@link Item#getItemBurnTime(ItemStack)}. + */ + public int getBurnTime() + { + return burnTime; + } +} diff --git a/src/main/java/net/minecraftforge/fml/common/IFuelHandler.java b/src/main/java/net/minecraftforge/fml/common/IFuelHandler.java index 253706e0dd..1b3d57b25b 100644 --- a/src/main/java/net/minecraftforge/fml/common/IFuelHandler.java +++ b/src/main/java/net/minecraftforge/fml/common/IFuelHandler.java @@ -19,8 +19,14 @@ package net.minecraftforge.fml.common; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraftforge.event.furnace.FurnaceFuelBurnTimeEvent; +/** + * @deprecated set your item's {@link Item#getItemBurnTime(ItemStack)} or subscribe to {@link FurnaceFuelBurnTimeEvent} instead. + */ +@Deprecated public interface IFuelHandler { int getBurnTime(ItemStack fuel); diff --git a/src/main/java/net/minecraftforge/fml/common/registry/GameRegistry.java b/src/main/java/net/minecraftforge/fml/common/registry/GameRegistry.java index 8f092fda6b..5afb3187c3 100644 --- a/src/main/java/net/minecraftforge/fml/common/registry/GameRegistry.java +++ b/src/main/java/net/minecraftforge/fml/common/registry/GameRegistry.java @@ -37,7 +37,6 @@ import net.minecraft.command.EntitySelector; import net.minecraft.command.ICommandSender; import net.minecraft.entity.Entity; import net.minecraft.item.Item; -import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.FurnaceRecipes; import net.minecraft.item.crafting.Ingredient; @@ -56,6 +55,8 @@ import net.minecraft.world.chunk.IChunkProvider; import net.minecraft.world.gen.IChunkGenerator; import net.minecraftforge.common.crafting.CraftingHelper; import net.minecraftforge.common.crafting.CraftingHelper.ShapedPrimer; +import net.minecraftforge.event.ForgeEventFactory; +import net.minecraftforge.event.furnace.FurnaceFuelBurnTimeEvent; import net.minecraftforge.fml.common.FMLLog; import net.minecraftforge.fml.common.IFuelHandler; import net.minecraftforge.fml.common.IWorldGenerator; @@ -65,8 +66,6 @@ import net.minecraftforge.registries.IForgeRegistryEntry; import net.minecraftforge.registries.RegistryManager; import net.minecraftforge.fml.common.IEntitySelectorFactory; -import org.apache.logging.log4j.Level; - import com.google.common.base.Strings; import com.google.common.base.Throwables; import com.google.common.collect.ImmutableList; @@ -237,12 +236,29 @@ public class GameRegistry TileEntity.register(key, tileEntityClass); } + /** + * @deprecated set your item's {@link Item#getItemBurnTime(ItemStack)} or subscribe to {@link FurnaceFuelBurnTimeEvent} instead. + */ + @Deprecated public static void registerFuelHandler(IFuelHandler handler) { fuelHandlers.add(handler); } + /** + * @deprecated use {@link ForgeEventFactory#getItemBurnTime(ItemStack)} + */ + @Deprecated public static int getFuelValue(@Nonnull ItemStack itemStack) + { + return ForgeEventFactory.getItemBurnTime(itemStack); + } + + /** + * @deprecated use {@link ForgeEventFactory#getItemBurnTime(ItemStack)} + */ + @Deprecated + public static int getFuelValueLegacy(@Nonnull ItemStack itemStack) { int fuelValue = 0; for (IFuelHandler handler : fuelHandlers) diff --git a/src/test/java/net/minecraftforge/debug/FurnaceFuelBurnTimeEventTest.java b/src/test/java/net/minecraftforge/debug/FurnaceFuelBurnTimeEventTest.java new file mode 100644 index 0000000000..5802c0dd66 --- /dev/null +++ b/src/test/java/net/minecraftforge/debug/FurnaceFuelBurnTimeEventTest.java @@ -0,0 +1,111 @@ +package net.minecraftforge.debug; + +import net.minecraft.client.renderer.block.model.ModelBakery; +import net.minecraft.client.renderer.block.model.ModelResourceLocation; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.init.Items; +import net.minecraft.item.Item; +import net.minecraft.item.ItemSpade; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.client.event.ModelRegistryEvent; +import net.minecraftforge.client.model.ModelLoader; +import net.minecraftforge.event.RegistryEvent; +import net.minecraftforge.event.furnace.FurnaceFuelBurnTimeEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.registry.GameRegistry; + +@Mod(modid = FurnaceFuelBurnTimeEventTest.MOD_ID, name = "Test for FurnaceFuelBurnTimeEvent", version = "1.0", acceptableRemoteVersions = "*") +@Mod.EventBusSubscriber +public class FurnaceFuelBurnTimeEventTest +{ + public static final String MOD_ID = "furnacefuelburntimeeventtest"; + private static final ResourceLocation unburnableWoodShovelName = new ResourceLocation(MOD_ID, "unburnable_wood_shovel"); + private static final ResourceLocation flammableGoldShovelName = new ResourceLocation(MOD_ID, "flammable_gold_shovel"); + @GameRegistry.ObjectHolder("unburnable_wood_shovel") + public static final Item UNBURNABLE_WOOD_SHOVEL = null; + @GameRegistry.ObjectHolder("flammable_gold_shovel") + public static final Item FLAMMABLE_GOLD_SHOVEL = null; + + @SubscribeEvent + public static void onFurnaceFuelBurnTimeEvent(FurnaceFuelBurnTimeEvent event) + { + ItemStack itemStack = event.getItemStack(); + Item item = itemStack.getItem(); + if (item == Items.SLIME_BALL) + { + event.setBurnTime(100); // make slime balls burn as fuel in the furnace + } + else if (item == Items.WOODEN_AXE) + { + event.setBurnTime(0); // do not allow the wooden axe to be used as fuel + } + } + + @SubscribeEvent + public static void registerItems(RegistryEvent.Register event) + { + event.getRegistry().register(new UnburnableWoodShovel().setRegistryName(unburnableWoodShovelName)); + event.getRegistry().register(new FlammableGoldShovel().setRegistryName(flammableGoldShovelName)); + } + + @SubscribeEvent + public static void registerModels(ModelRegistryEvent event) + { + { + final ModelResourceLocation location = new ModelResourceLocation(unburnableWoodShovelName, "inventory"); + ModelBakery.registerItemVariants(UNBURNABLE_WOOD_SHOVEL, location); + ModelLoader.setCustomMeshDefinition(UNBURNABLE_WOOD_SHOVEL, is -> location); + } + { + final ModelResourceLocation location = new ModelResourceLocation(flammableGoldShovelName, "inventory"); + ModelBakery.registerItemVariants(FLAMMABLE_GOLD_SHOVEL, location); + ModelLoader.setCustomMeshDefinition(FLAMMABLE_GOLD_SHOVEL, is -> location); + } + } + + public static class UnburnableWoodShovel extends ItemSpade + { + public UnburnableWoodShovel() + { + super(ToolMaterial.WOOD); + setCreativeTab(CreativeTabs.TOOLS); + setMaxStackSize(1); + } + + @Override + public int getItemBurnTime(ItemStack itemStack) + { + return 0; + } + + @Override + public String getItemStackDisplayName(ItemStack stack) + { + return "Unburnable Wooden Shovel"; + } + } + + public static class FlammableGoldShovel extends ItemSpade + { + public FlammableGoldShovel() + { + super(ToolMaterial.GOLD); + setCreativeTab(CreativeTabs.TOOLS); + setMaxStackSize(1); + } + + @Override + public int getItemBurnTime(ItemStack itemStack) + { + return 1000; + } + + @Override + public String getItemStackDisplayName(ItemStack stack) + { + return "Flammable Golden Shovel"; + } + } +} diff --git a/src/test/resources/assets/furnacefuelburntimeeventtest/models/item/flammable_gold_shovel.json b/src/test/resources/assets/furnacefuelburntimeeventtest/models/item/flammable_gold_shovel.json new file mode 100644 index 0000000000..2dde2f36b1 --- /dev/null +++ b/src/test/resources/assets/furnacefuelburntimeeventtest/models/item/flammable_gold_shovel.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "items/gold_shovel" + } +} diff --git a/src/test/resources/assets/furnacefuelburntimeeventtest/models/item/unburnable_wood_shovel.json b/src/test/resources/assets/furnacefuelburntimeeventtest/models/item/unburnable_wood_shovel.json new file mode 100644 index 0000000000..c461880e03 --- /dev/null +++ b/src/test/resources/assets/furnacefuelburntimeeventtest/models/item/unburnable_wood_shovel.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "items/wood_shovel" + } +}