diff --git a/README.md b/README.md index a854423..1824696 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ # AutoClicky (Fabric) -Best in-game minecraft autoclicker +Best in-game minecraft autoclicker (click on this preview photo to see video demonstration) -![AutoClickyPreview](https://i.ibb.co/vcS14hP/eng-preview.png) +[![Click to see preview video](https://i.ibb.co/WfBpgJ9/2024-08-20-19-21-50.png)](https://www.youtube.com/watch?v=C8sh3hMvoHk) ## Features -- In `new combat system` mode, Autoclicky will click exactly on the timing when the weapon's cooldown is over to do a lot of damage +- In new combat system mode, Autoclicky will click exactly on the timing when the weapon's cooldown is over to do a lot of damage - To switch between 1.8 and 1.9+ PvP systems, simply click the `New combat (1.9+)` or `Old combat (1.8)` button at the top - Left and right mouse button autoclicker - A clever auto jump that jumps before hitting and always deals critical damage @@ -20,12 +20,14 @@ Best in-game minecraft autoclicker - Use `H` to switch between the new or old combat system - You can change all of these keys in the minecraft control settings +## Disclaimer +I (mod author) do not take any responsibility for your banned accounts on public servers. If you want to use AutoClicky on public servers, you take all responsibility on yourself. The mod is recommended to use in single player game + ## Download -- [GitHub Releases](https://github.com/breelock/autoclicky/releases) (New versions appear here before anyone else) +- [GitHub Releases](https://github.com/breelock/autoclicky/releases) - [CurseForge](https://www.curseforge.com/minecraft/mc-mods/autoclicky) - [Modrinth](https://modrinth.com/mod/autoclicky) +- [Minecraft Inside](https://minecraft-inside.ru/mods/178960-autoclicky.html) ## Dependencies -- [Fabric API](https://www.curseforge.com/minecraft/mc-mods/fabric-api) - -## \ No newline at end of file +- [Fabric API](https://www.curseforge.com/minecraft/mc-mods/fabric-api) \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index a7dc3d5..fab7605 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,7 +9,7 @@ yarn_mappings=1.19.2+build.28 loader_version=0.16.2 # Mod Properties -mod_version=1.2.0 +mod_version=1.2.1 maven_group=com.breelock.autoclicky archives_base_name=autoclicky diff --git a/src/main/java/com/breelock/autoclicky/PlayerMethods.java b/src/main/java/com/breelock/autoclicky/PlayerMethods.java index eeb1471..a4538b4 100644 --- a/src/main/java/com/breelock/autoclicky/PlayerMethods.java +++ b/src/main/java/com/breelock/autoclicky/PlayerMethods.java @@ -3,7 +3,11 @@ import net.minecraft.block.Blocks; import net.minecraft.client.MinecraftClient; import net.minecraft.entity.Entity; +import net.minecraft.entity.attribute.EntityAttributes; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.AxeItem; import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; import net.minecraft.tag.FluidTags; import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; @@ -11,6 +15,7 @@ import net.minecraft.util.hit.EntityHitResult; import net.minecraft.util.hit.HitResult; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; public class PlayerMethods { public static void attack(MinecraftClient client, boolean isNewPvP) { @@ -18,30 +23,40 @@ public static void attack(MinecraftClient client, boolean isNewPvP) { boolean isInLava = client.world.getBlockState(new BlockPos(client.player.getX(), client.player.getY(), client.player.getZ())).getBlock() == Blocks.LAVA || client.player.isSubmergedIn(FluidTags.LAVA); boolean isOnGround = client.player.isOnGround() && !client.player.isTouchingWater() && !isInLava; + float jumpCooldown = 400f; + float cooldownTime = getAttackSpeedInTicks(client.player) * 50; + float attackCooldown = getAttackCooldownInTicks(client.player) * 50; + if (isNewPvP) { if (ModConfig.NewPvP.onlyEntity) { if (client.crosshairTarget.getType() == HitResult.Type.ENTITY) { - if (client.player.getAttackCooldownProgress(0.0F) >= 0.7F && ModConfig.NewPvP.autoJump && client.player.isOnGround() && !client.player.isTouchingWater() && !isInLava) - client.player.jump(); - - if (client.player.getAttackCooldownProgress(0.0F) >= 1.0F) { - if (!isOnGround && client.player.getVelocity().y < -0.1 || client.player.isOnGround() || client.player.getAbilities().flying || client.player.isTouchingWater() || isInLava) { - if (interrupt(client, true)) return; - PlayerMethods.attackEntity(client); + if (!targetIsProtectedByShield(client, ((EntityHitResult) client.crosshairTarget).getEntity())) { + if (attackCooldown >= cooldownTime - jumpCooldown && ModConfig.NewPvP.autoJump && client.player.isOnGround() && !client.player.isTouchingWater() && !isInLava) + client.player.jump(); + + if (attackCooldown >= cooldownTime) { + if (!isOnGround && client.player.getVelocity().y < -0.1 || client.player.isOnGround() || client.player.getAbilities().flying || client.player.isTouchingWater() || isInLava) { + if (interrupt(client, true)) return; + PlayerMethods.attackEntity(client); + } } } } } else { - if (client.crosshairTarget.getType() == HitResult.Type.ENTITY && client.player.getAttackCooldownProgress(0.0F) >= 0.7F && ModConfig.NewPvP.autoJump && client.player.isOnGround() && !client.player.isTouchingWater() && !isInLava) - client.player.jump(); + if (client.crosshairTarget.getType() == HitResult.Type.ENTITY && attackCooldown >= cooldownTime - jumpCooldown && ModConfig.NewPvP.autoJump && client.player.isOnGround() && !client.player.isTouchingWater() && !isInLava) { + if (!targetIsProtectedByShield(client, ((EntityHitResult) client.crosshairTarget).getEntity())) + client.player.jump(); + } - if (client.player.getAttackCooldownProgress(0.0F) >= 1.0F) { + if (attackCooldown >= cooldownTime) { if (interrupt(client, true)) return; if (client.crosshairTarget.getType() == HitResult.Type.ENTITY) { - if (!isOnGround && client.player.getVelocity().y < -0.1 || client.player.isOnGround() || client.player.getAbilities().flying || client.player.isTouchingWater() || isInLava) - PlayerMethods.attackEntity(client); + if (!targetIsProtectedByShield(client, ((EntityHitResult) client.crosshairTarget).getEntity())) { + if (!isOnGround && client.player.getVelocity().y < -0.1 || client.player.isOnGround() || client.player.getAbilities().flying || client.player.isTouchingWater() || isInLava) + PlayerMethods.attackEntity(client); + } } else if (client.crosshairTarget.getType() == HitResult.Type.BLOCK) PlayerMethods.breakBlock(client); @@ -122,6 +137,30 @@ private static void attackEntity(MinecraftClient client) { } } + private static boolean targetIsProtectedByShield(MinecraftClient client, Entity targetEntity) { + if (client.player != null) { + if (targetEntity instanceof PlayerEntity) { + PlayerEntity targetPlayer = (PlayerEntity) targetEntity; + ItemStack heldItem = client.player.getMainHandStack(); + if (heldItem.getItem() instanceof AxeItem) + return false; + + return targetPlayer.isUsingItem() && targetPlayer.getActiveItem().getItem() == Items.SHIELD; + } + } + return false; + } + + private static int getAttackCooldownInTicks(PlayerEntity player) { + float cooldown = player.getAttackCooldownProgress(0.0f); + return MathHelper.ceil(cooldown * getAttackSpeedInTicks(player)); + } + + private static float getAttackSpeedInTicks(PlayerEntity player) { + float attackSpeed = (float) player.getAttributeValue(EntityAttributes.GENERIC_ATTACK_SPEED); + return (1.0f / attackSpeed) * 20.0f; + } + private static void breakBlock(MinecraftClient client) { if (client != null && client.interactionManager != null && client.player != null && client.world != null) { BlockHitResult blockHitResult = (BlockHitResult) client.crosshairTarget;