From 9ccd3a9ed07fe295a208194bf9e21d1bb8a60c30 Mon Sep 17 00:00:00 2001 From: FreneticFeline Date: Wed, 9 Aug 2017 21:12:11 -0400 Subject: [PATCH] Backport entity clear protection and recast delay config to 1.11 --- build.gradle | 2 +- .../autofish/AutoFishEventHandler.java | 96 +++++++++++++++---- .../minecraft/autofish/ModAutoFish.java | 6 ++ 3 files changed, 87 insertions(+), 17 deletions(-) diff --git a/build.gradle b/build.gradle index 965fe88..fa36df8 100644 --- a/build.gradle +++ b/build.gradle @@ -13,7 +13,7 @@ buildscript { apply plugin: 'net.minecraftforge.gradle.forge' -version = "1.11-1.2" +version = "1.11-1.4" group= "net.unladenswallow.minecraft.autofish" // http://maven.apache.org/guides/mini/guide-naming-conventions.html archivesBaseName = "mod_autofish_forge" diff --git a/src/main/java/net/unladenswallow/minecraft/autofish/AutoFishEventHandler.java b/src/main/java/net/unladenswallow/minecraft/autofish/AutoFishEventHandler.java index 3347206..288ee76 100644 --- a/src/main/java/net/unladenswallow/minecraft/autofish/AutoFishEventHandler.java +++ b/src/main/java/net/unladenswallow/minecraft/autofish/AutoFishEventHandler.java @@ -10,6 +10,8 @@ import net.minecraft.item.ItemStack; import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumHand; +import net.minecraftforge.event.entity.player.PlayerInteractEvent; +import net.minecraftforge.fml.client.FMLClientHandler; import net.minecraftforge.fml.client.event.ConfigChangedEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent; @@ -20,36 +22,86 @@ public class AutoFishEventHandler { private EntityPlayer player; private long castScheduledAt = 0L; private long startedReelDelayAt = 0L; - private static final int CAST_QUEUE_TICK_DELAY = 30; + private long startedCastDelayAt = 0L; + private boolean isFishing = false; + + private static final int TICKS_PER_SECOND = 20; + + /** How long to suppress checking for a bite after starting to reel in. If we check for a bite while reeling + in, we may think we have a bite and try to reel in again, which will actually cause a re-cast and lose the fish */ private static final int REEL_TICK_DELAY = 5; + + /** How long to wait after casting to check for Entity Clear. If we check too soon, the hook entity + isn't in the world yet, and will trigger a false alarm and cause infinite recasting. */ + private static final int CAST_TICK_DELAY = 5; + + /** When Break Prevention is enabled, how low to let the durability get before stopping or switching rods */ private static final int AUTOFISH_BREAKPREVENT_THRESHOLD = 2; + + /** The threshold for vertical movement of the fish hook that determines when a fish is biting, if using + the movement method of detection. */ private static final double MOTION_Y_THRESHOLD = -0.05d; + public AutoFishEventHandler() { + this.minecraft = FMLClientHandler.instance().getClient(); + } + @SubscribeEvent public void onClientTickEvent(ClientTickEvent event) { - this.minecraft = Minecraft.getMinecraft(); if (ModAutoFish.config_autofish_enable && !this.minecraft.isGamePaused() && this.minecraft.player != null) { this.player = this.minecraft.player; - if (playerHookInWater() && !isDuringReelDelay() && isFishBiting()) { - startReelDelay(); - playerUseRod(); - scheduleNextCast(); - } else if (isTimeToCast()) { - if (needToSwitchRods()) { - tryToSwitchRods(); + if (playerIsHoldingRod()) { + if (playerHookInWater() && !isDuringReelDelay() && isFishBiting()) { + startReelDelay(); + reelIn(); + scheduleNextCast(); + } else if (isTimeToCast()) { + if (needToSwitchRods()) { + tryToSwitchRods(); + } + if (playerCanCast()) { + startFishing(); + } + // Resetting these values is not strictly necessary, but will improve the performance + // of the check that potentially occurs every tick. + resetReelDelay(); + resetCastSchedule(); } - if (playerCanCast()) { - playerUseRod(); + + if (ModAutoFish.config_autofish_entityClearProtect && this.isFishing && !isDuringCastDelay() && this.player.fishEntity == null) { + AutoFishLogger.info("Entity Clear detected. Re-casting."); + this.isFishing = false; + startFishing(); } - // Resetting these values is not strictly necessary, but will improve the performance - // of the check that potentially occurs every tick. - resetReelDelay(); - resetCastSchedule(); + + } else { + this.isFishing = false; + } + } + } + + @SubscribeEvent + public void onPlayerUseItem(PlayerInteractEvent.RightClickItem event) { + // Only do this on the client side + if (event.getWorld().isRemote && playerIsHoldingRod()) { + this.isFishing = !this.isFishing; +// AutoFishLogger.info("Player %s fishing", this.isFishing ? "started" : "stopped"); + if (this.isFishing) { + startCastDelay(); } } } + private void reelIn() { + playerUseRod(); + } + + private void startFishing() { + playerUseRod(); + startCastDelay(); + } + private void resetCastSchedule() { this.castScheduledAt = 0; } @@ -70,6 +122,13 @@ private void startReelDelay() { this.startedReelDelayAt = this.minecraft.world.getTotalWorldTime(); } + /* + * Trigger a delay so that entity clear protection doesn't kick in during cast. + */ + private void startCastDelay() { + this.startedCastDelayAt = this.minecraft.world.getTotalWorldTime(); + } + private void resetReelDelay() { startedReelDelayAt = 0; } @@ -78,6 +137,10 @@ private boolean isDuringReelDelay() { return (this.startedReelDelayAt != 0 && this.minecraft.world.getTotalWorldTime() < this.startedReelDelayAt + REEL_TICK_DELAY); } + private boolean isDuringCastDelay() { + return (this.startedCastDelayAt != 0 && this.minecraft.world.getTotalWorldTime() < this.startedCastDelayAt + CAST_TICK_DELAY); + } + private boolean playerHookInWater() { return this.player.fishEntity != null && this.player.fishEntity.isInWater(); @@ -111,6 +174,7 @@ private boolean isFishBiting() { private boolean isFishBiting_fromMovement() { EntityFishHook fishEntity = this.player.fishEntity; if (fishEntity != null + // Checking for no X and Z motion prevents a false alarm when the hook is moving through the air && fishEntity.motionX == 0 && fishEntity.motionZ == 0 && fishEntity.motionY < MOTION_Y_THRESHOLD) { @@ -172,7 +236,7 @@ private EnumActionResult playerUseRod() { } private boolean isTimeToCast() { - return (this.castScheduledAt != 0 && this.minecraft.world.getTotalWorldTime() > this.castScheduledAt + CAST_QUEUE_TICK_DELAY); + return (this.castScheduledAt != 0 && this.minecraft.world.getTotalWorldTime() > this.castScheduledAt + (ModAutoFish.config_autofish_recastDelay * TICKS_PER_SECOND)); } private void tryToSwitchRods() { diff --git a/src/main/java/net/unladenswallow/minecraft/autofish/ModAutoFish.java b/src/main/java/net/unladenswallow/minecraft/autofish/ModAutoFish.java index 69b03f8..86825ed 100644 --- a/src/main/java/net/unladenswallow/minecraft/autofish/ModAutoFish.java +++ b/src/main/java/net/unladenswallow/minecraft/autofish/ModAutoFish.java @@ -19,6 +19,10 @@ public class ModAutoFish { public static final boolean CONFIG_DEFAULT_AUTOFISH_MULTIROD = false; public static boolean config_autofish_preventBreak; public static final boolean CONFIG_DEFAULT_AUTOFISH_PREVENTBREAK = false; + public static boolean config_autofish_entityClearProtect; + public static final boolean CONFIG_DEFAULT_AUTOFISH_ENTITYCLEARPROTECT = false; + public static int config_autofish_recastDelay; + public static final int CONFIG_DEFAULT_AUTOFISH_RECASTDELAY = 2; @SidedProxy(clientSide="net.unladenswallow.minecraft.autofish.ClientProxy", serverSide="net.unladenswallow.minecraft.autofish.ServerProxy") public static CommonProxy proxy; @@ -44,6 +48,8 @@ public static void syncConfig() { config_autofish_enable = configFile.getBoolean("Enable AutoFish", Configuration.CATEGORY_GENERAL, CONFIG_DEFAULT_AUTOFISH_ENABLE, "Automatically reel in and re-cast when a fish nibbles the hook."); config_autofish_multirod = configFile.getBoolean("Enable MultiRod", Configuration.CATEGORY_GENERAL, CONFIG_DEFAULT_AUTOFISH_MULTIROD, "Automatically switch to a new fishing rod when the current rod breaks, if one is available in the hotbar."); config_autofish_preventBreak = configFile.getBoolean("Enable Break Protection", Configuration.CATEGORY_GENERAL, CONFIG_DEFAULT_AUTOFISH_PREVENTBREAK, "Stop fishing or switch to a new rod before the current rod breaks."); + config_autofish_entityClearProtect = configFile.getBoolean("Enable Enity Clear Protection", Configuration.CATEGORY_GENERAL, CONFIG_DEFAULT_AUTOFISH_ENTITYCLEARPROTECT, "Re-cast after the server clears entities. EXPERIMENTAL"); + config_autofish_recastDelay = configFile.getInt("Re-Cast Delay", Configuration.CATEGORY_GENERAL, CONFIG_DEFAULT_AUTOFISH_RECASTDELAY, 1, 10, "Time (in seconds) to wait before automatically re-casting. Increase this value if server lag causes re-casting to fail."); if (configFile.hasChanged()) { configFile.save();