From 6ffd94a08e6056a12b661a17068c09b2ff4e603c Mon Sep 17 00:00:00 2001 From: ichttt Date: Tue, 2 May 2017 03:10:47 +0200 Subject: [PATCH] Create ItemFishedEvent, the event is cancelable, but items are not mutable. Use LootTables to control that. (#3705) --- .../projectile/EntityFishHook.java.patch | 37 ++++++++ .../event/entity/player/ItemFishedEvent.java | 90 +++++++++++++++++++ .../minecraftforge/test/ItemFishedTest.java | 46 ++++++++++ 3 files changed, 173 insertions(+) create mode 100644 patches/minecraft/net/minecraft/entity/projectile/EntityFishHook.java.patch create mode 100644 src/main/java/net/minecraftforge/event/entity/player/ItemFishedEvent.java create mode 100644 src/test/java/net/minecraftforge/test/ItemFishedTest.java diff --git a/patches/minecraft/net/minecraft/entity/projectile/EntityFishHook.java.patch b/patches/minecraft/net/minecraft/entity/projectile/EntityFishHook.java.patch new file mode 100644 index 0000000000..a6b56d4dec --- /dev/null +++ b/patches/minecraft/net/minecraft/entity/projectile/EntityFishHook.java.patch @@ -0,0 +1,37 @@ +--- ../src-base/minecraft/net/minecraft/entity/projectile/EntityFishHook.java ++++ ../src-work/minecraft/net/minecraft/entity/projectile/EntityFishHook.java +@@ -506,6 +506,7 @@ + { + int i = 0; + ++ net.minecraftforge.event.entity.player.ItemFishedEvent event = null; + if (this.field_146043_c != null) + { + this.func_184527_k(); +@@ -516,8 +517,16 @@ + { + LootContext.Builder lootcontext$builder = new LootContext.Builder((WorldServer)this.field_70170_p); + lootcontext$builder.func_186469_a((float)this.field_191518_aw + this.field_146042_b.func_184817_da()); ++ List result = this.field_70170_p.func_184146_ak().func_186521_a(LootTableList.field_186387_al).func_186462_a(this.field_70146_Z, lootcontext$builder.func_186471_a()); ++ event = new net.minecraftforge.event.entity.player.ItemFishedEvent(result, this.field_146051_au ? 2 : 1, this); ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event); ++ if (event.isCanceled()) ++ { ++ this.func_70106_y(); ++ return event.getRodDamage(); ++ } + +- for (ItemStack itemstack : this.field_70170_p.func_184146_ak().func_186521_a(LootTableList.field_186387_al).func_186462_a(this.field_70146_Z, lootcontext$builder.func_186471_a())) ++ for (ItemStack itemstack : result) + { + EntityItem entityitem = new EntityItem(this.field_70170_p, this.field_70165_t, this.field_70163_u, this.field_70161_v, itemstack); + double d0 = this.field_146042_b.field_70165_t - this.field_70165_t; +@@ -547,7 +556,7 @@ + } + + this.func_70106_y(); +- return i; ++ return event == null ? i : event.getRodDamage(); + } + else + { diff --git a/src/main/java/net/minecraftforge/event/entity/player/ItemFishedEvent.java b/src/main/java/net/minecraftforge/event/entity/player/ItemFishedEvent.java new file mode 100644 index 0000000000..a8d6dfd7b4 --- /dev/null +++ b/src/main/java/net/minecraftforge/event/entity/player/ItemFishedEvent.java @@ -0,0 +1,90 @@ +/* + * 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.entity.player; + +import com.google.common.base.Preconditions; +import net.minecraft.entity.projectile.EntityFishHook; +import net.minecraft.item.ItemStack; +import net.minecraft.util.NonNullList; +import net.minecraftforge.fml.common.eventhandler.Cancelable; + +import javax.annotation.Nonnegative; +import java.util.List; + +/** + * This event is called when a player fishes an item. + * + * This event is {@link net.minecraftforge.fml.common.eventhandler.Cancelable} + * Canceling the event will cause the player to receive no items at all. + * The hook will still take the damage specified + */ +@Cancelable +public class ItemFishedEvent extends PlayerEvent +{ + private final NonNullList stacks = NonNullList.create(); + private final EntityFishHook hook; + private int rodDamage; + + public ItemFishedEvent(List stacks, int rodDamage, EntityFishHook hook) + { + super(hook.getAngler()); + this.stacks.addAll(stacks); + this.rodDamage = rodDamage; + this.hook = hook; + } + + /** + * Get the damage the rod will take. + * @return The damage the rod will take + */ + public int getRodDamage() + { + return rodDamage; + } + + /** + * Specifies the amount of damage that the fishing rod should take. + * This is not added to the pre-existing damage to be taken. + * @param rodDamage The damage the rod will take. Must be nonnegative + */ + public void damageRodBy(@Nonnegative int rodDamage) + { + Preconditions.checkArgument(rodDamage >= 0); + this.rodDamage = rodDamage; + } + + /** + * Use this to get the items the player will receive. + * You cannot use this to modify the drops the player will get. + * If you want to affect the loot, you should use LootTables. + */ + public NonNullList getDrops() + { + return stacks; + } + + /** + * Use this to stuff related to the hook itself, like the position of the bobber. + */ + public EntityFishHook getHookEntity() + { + return hook; + } +} diff --git a/src/test/java/net/minecraftforge/test/ItemFishedTest.java b/src/test/java/net/minecraftforge/test/ItemFishedTest.java new file mode 100644 index 0000000000..8b10f7c9b1 --- /dev/null +++ b/src/test/java/net/minecraftforge/test/ItemFishedTest.java @@ -0,0 +1,46 @@ +package net.minecraftforge.test; + +import net.minecraft.entity.projectile.EntityFishHook; +import net.minecraft.init.Biomes; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.biome.Biome; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.entity.player.ItemFishedEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import org.apache.logging.log4j.Logger; + +@Mod(modid = "itemfishtest", name = "ItemFishTest", version = "1.0.0") +public class ItemFishedTest +{ + + private static final boolean ENABLE = false; + private static Logger logger; + + @Mod.EventHandler + public void onInit(FMLPreInitializationEvent event) + { + if (ENABLE) + { + logger = event.getModLog(); + logger.info("Enabling Fishing Test mod"); + MinecraftForge.EVENT_BUS.register(this); + } + } + + @SubscribeEvent + public void onItemFished(ItemFishedEvent event) + { + EntityFishHook hook = event.getHookEntity(); + BlockPos bobberPos = hook.getPosition(); + Biome biomeFishedAt = hook.getEntityWorld().getBiome(bobberPos); + logger.info("Item fished in Biome " + biomeFishedAt.getBiomeName()); + if (biomeFishedAt.equals(Biomes.OCEAN)) + { + logger.info("Canceling the event because biome is ocean"); + event.setCanceled(true); + } + event.damageRodBy(50); + } +}