Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add AutoPlaceHack #1051

Open
wants to merge 26 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
1ebb8d9
Add AutoPlaceHack
LilyKensa Aug 8, 2024
76a5b03
Merge branch 'master' into master
LilyKensa Aug 8, 2024
d4b624e
Merge pull request #1 from Wurst-Imperium/master
LilyKensa Aug 9, 2024
21ce72b
Add TeamEspHack & FilterNpcLikeSetting
LilyKensa Aug 9, 2024
32f85be
Merge pull request #2 from Wurst-Imperium/master
LilyKensa Aug 9, 2024
0998d1d
Merge pull request #3 from LilyKensa/teamesp-pr
LilyKensa Aug 9, 2024
e27ce53
Add FilterTeammatesSetting
LilyKensa Aug 10, 2024
0b0ec5f
Merge pull request #4 from LilyKensa/teamesp-pr
LilyKensa Aug 10, 2024
90e45c0
Add AimAssistHack onlyHoldingWeapon option
LilyKensa Aug 25, 2024
f3584a6
Merge pull request #5 from LilyKensa/onlyholdingweapon-pr
LilyKensa Aug 25, 2024
74c4def
Add TriggerBotHack blacklistedItems option
LilyKensa Aug 25, 2024
5559d0f
Merge pull request #6 from LilyKensa/triggerbotitemblacklist-pr
LilyKensa Aug 25, 2024
a1e7c2e
Add SafeWalkHack minDepth & motionPrediction options
LilyKensa Aug 25, 2024
bb0215f
Merge pull request #7 from LilyKensa/safewalkmindepth-pr
LilyKensa Aug 25, 2024
02e19a2
Merge v7.45.1 into 1.21
Alexander01998 Sep 24, 2024
334e507
Merge v7.46pre1 into 1.21
Alexander01998 Sep 24, 2024
ccb1292
Merge v7.46pre2 into 1.21
Alexander01998 Sep 24, 2024
d944be9
Merge v7.46pre3 into 1.21
Alexander01998 Sep 24, 2024
ad61d02
Merge tag 'v7.46pre3' into 1.21
Alexander01998 Sep 24, 2024
c7d8d4e
Merge v7.46 into 1.21
Alexander01998 Sep 27, 2024
31ea40e
Merge pull request #8 from Wurst-Imperium/1.21
LilyKensa Sep 29, 2024
6d9f820
Optional AutoReconnectHack death screen button
LilyKensa Oct 2, 2024
f1e9d11
Merge pull request #9 from LilyKensa/optionalmenu-pr
LilyKensa Oct 2, 2024
1aed3af
Merge tag 'v7.46.1' into 1.21
Alexander01998 Oct 11, 2024
1f7d318
Merge pull request #11 from Wurst-Imperium/1.21
LilyKensa Oct 11, 2024
41ab6d2
Merge branch 'master' of github.com:LilyKensa/Wurst into autoplace-pr
LilyKensa Oct 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ org.gradle.parallel=true
# Fabric Properties
# check these at https://fabricmc.net/develop/ and
# https://modrinth.com/mod/fabric-api/versions
minecraft_version=1.21.1
yarn_mappings=1.21.1+build.3
minecraft_version=1.21
yarn_mappings=1.21+build.9
loader_version=0.16.5

# Fabric API
fabric_version=0.105.0+1.21.1
fabric_version=0.102.0+1.21

# Mod Properties
mod_version = v7.46.1-MC1.21.1
mod_version = v7.46.1-MC1.21
maven_group = net.wurstclient
archives_base_name = Wurst-Client

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/net/wurstclient/WurstClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public enum WurstClient
public static IMinecraftClient IMC;

public static final String VERSION = "7.46.1";
public static final String MC_VERSION = "1.21.1";
public static final String MC_VERSION = "1.21";

private WurstAnalytics analytics;
private EventManager eventManager;
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/net/wurstclient/hack/HackList.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public final class HackList implements UpdateListener
public final AutoLeaveHack autoLeaveHack = new AutoLeaveHack();
public final AutoLibrarianHack autoLibrarianHack = new AutoLibrarianHack();
public final AutoEatHack autoEatHack = new AutoEatHack();
public final AutoPlaceHack autoPlaceHack = new AutoPlaceHack();
public final AutoFarmHack autoFarmHack = new AutoFarmHack();
public final AutoFishHack autoFishHack = new AutoFishHack();
public final AutoMineHack autoMineHack = new AutoMineHack();
Expand Down Expand Up @@ -172,6 +173,7 @@ public final class HackList implements UpdateListener
public final SpeedNukerHack speedNukerHack = new SpeedNukerHack();
public final SpiderHack spiderHack = new SpiderHack();
public final StepHack stepHack = new StepHack();
public final TeamEspHack teamEspHack = new TeamEspHack();
public final TemplateToolHack templateToolHack = new TemplateToolHack();
public final ThrowHack throwHack = new ThrowHack();
public final TillauraHack tillauraHack = new TillauraHack();
Expand Down
19 changes: 19 additions & 0 deletions src/main/java/net/wurstclient/hacks/AimAssistHack.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@

import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.entity.Entity;
import net.minecraft.item.AxeItem;
import net.minecraft.item.Item;
import net.minecraft.item.Items;
import net.minecraft.item.SwordItem;
import net.minecraft.util.math.Vec3d;
import net.wurstclient.Category;
import net.wurstclient.events.MouseUpdateListener;
Expand Down Expand Up @@ -50,6 +54,10 @@ public final class AimAssistHack extends Hack
"description.wurst.setting.aimassist.ignore_mouse_input", 0, 0, 1,
0.01, ValueDisplay.PERCENTAGE);

private final CheckboxSetting onlyHoldingWeapon = new CheckboxSetting(
"Only if holding weapon",
"Won't aim if not holding a weapon (Swords, axes & sticks.)", false);

private final CheckboxSetting checkLOS =
new CheckboxSetting("Check line of sight",
"description.wurst.setting.aimassist.check_line_of_sight", true);
Expand All @@ -60,6 +68,8 @@ public final class AimAssistHack extends Hack

private final EntityFilterList entityFilters =
new EntityFilterList(FilterPlayersSetting.genericCombat(false),
FilterTeammatesSetting.genericCombat(false),
FilterNpcLikeSetting.genericCombat(false),
FilterSleepingSetting.genericCombat(false),
FilterFlyingSetting.genericCombat(0),
FilterHostileSetting.genericCombat(false),
Expand Down Expand Up @@ -103,6 +113,7 @@ public AimAssistHack()
addSetting(ignoreMouseInput);
addSetting(checkLOS);
addSetting(aimWhileBlocking);
addSetting(onlyHoldingWeapon);

entityFilters.forEach(this::addSetting);
}
Expand Down Expand Up @@ -142,6 +153,14 @@ public void onUpdate()
if(MC.currentScreen instanceof HandledScreen)
return;

Item itemInHand = MC.player.getInventory().getMainHandStack().getItem();
if(onlyHoldingWeapon.isChecked() && !(itemInHand instanceof SwordItem
|| itemInHand instanceof AxeItem || itemInHand == Items.STICK))
{
target = null;
return;
}

if(!aimWhileBlocking.isChecked() && MC.player.isUsingItem())
return;

Expand Down
105 changes: 105 additions & 0 deletions src/main/java/net/wurstclient/hacks/AutoPlaceHack.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* Copyright (c) 2014-2024 Wurst-Imperium and contributors.
*
* This source code is subject to the terms of the GNU General Public
* License, version 3. If a copy of the GPL was not distributed with this
* file, You can obtain one at: https://www.gnu.org/licenses/gpl-3.0.txt
*/
package net.wurstclient.hacks;

import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.item.BlockItem;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.wurstclient.Category;
import net.wurstclient.SearchTags;
import net.wurstclient.events.UpdateListener;
import net.wurstclient.hack.Hack;
import net.wurstclient.settings.CheckboxSetting;
import net.wurstclient.util.BlockUtils;

@SearchTags({"bridge", "auto place"})
public final class AutoPlaceHack extends Hack implements UpdateListener
{
private final CheckboxSetting onlyBelowFeet =
new CheckboxSetting("Only Below Feet",
"Only place blocks when target block is 1 block below your feet.",
false);
private final CheckboxSetting fastPlace =
new CheckboxSetting("Always FastPlace",
"Builds as if FastPlace was enabled, even if it's not.", true);

public AutoPlaceHack()
{
super("AutoPlace");
setCategory(Category.BLOCKS);
addSetting(onlyBelowFeet);
addSetting(fastPlace);
}

@Override
public void onEnable()
{
EVENTS.add(UpdateListener.class, this);
}

@Override
public void onDisable()
{
EVENTS.remove(UpdateListener.class, this);
}

@Override
public void onUpdate()
{
if(MC.currentScreen instanceof HandledScreen)
return;

if(MC.itemUseCooldown != 0 && !fastPlace.isChecked())
return;
Alexander01998 marked this conversation as resolved.
Show resolved Hide resolved

ClientPlayerEntity player = MC.player;
assert player != null;
Comment on lines +66 to +67
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Avoid using assertions for null checks in production code.

Using assert statements for null checks is not recommended in production code because assertions may be disabled at runtime. Instead, consider implementing explicit null checks to prevent NullPointerException.

Apply this change:

-    assert player != null;
+    if (player == null)
+        return;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
ClientPlayerEntity player = MC.player;
assert player != null;
ClientPlayerEntity player = MC.player;
if (player == null)
return;


// Item in hand is not a block
if(!(player.getInventory().getStack(player.getInventory().selectedSlot)
.getItem() instanceof BlockItem))
return;

HitResult hitResult = MC.crosshairTarget;
if(hitResult == null || hitResult.getType() != HitResult.Type.BLOCK)
return;

BlockHitResult blockHitResult = (BlockHitResult)hitResult;
if(blockHitResult.getSide() == Direction.UP
|| blockHitResult.getSide() == Direction.DOWN)
return;
Comment on lines +78 to +81
Copy link

@coderabbitai coderabbitai bot Oct 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider allowing placement on the top and bottom faces.

Currently, the hack does not allow placing blocks when targeting the top or bottom face of a block. This might limit the usefulness of the hack in certain building scenarios.

Consider removing or adjusting this condition to allow more flexible block placement.

-    if(blockHitResult.getSide() == Direction.UP
-        || blockHitResult.getSide() == Direction.DOWN)
-        return;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
BlockHitResult blockHitResult = (BlockHitResult)hitResult;
if(blockHitResult.getSide() == Direction.UP
|| blockHitResult.getSide() == Direction.DOWN)
return;
BlockHitResult blockHitResult = (BlockHitResult)hitResult;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be made configurable in the settings. The PR author said they only want it to place blocks horizontally, but I agree this might limit its usefulness e.g. if you're trying to tower up.

Some different ideas for how the settings might work:

  • a single checkbox "Allow vertical placement"
  • an enum "Direction" ["Horizontal", "Vertical", "Both"]
  • multiple checkboxes "Place up", "Place down", "Place horizontal"
  • a long enum "Place directions" ["Horizontal", "Vertical", "Up only", "Down only", "Up/horizontal", "Down/horizontal", "All"]

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Alexander01998

Great suggestion! Making the placement directions configurable would enhance the flexibility of the AutoPlace hack.

You could implement this by adding an EnumSetting to allow users to select their preferred placement directions. Here's how you might do it:

private final EnumSetting<PlacementDirection> placementDirection =
    new EnumSetting<>("Placement Direction", PlacementDirection.values(), PlacementDirection.HORIZONTAL);

private enum PlacementDirection
{
    HORIZONTAL("Horizontal"),
    VERTICAL("Vertical"),
    BOTH("Both");

    private final String name;

    private PlacementDirection(String name)
    {
        this.name = name;
    }

    @Override
    public String toString()
    {
        return name;
    }
}

Then, adjust the onUpdate method to handle the selected option:

BlockHitResult blockHitResult = (BlockHitResult) hitResult;
Direction side = blockHitResult.getSide();

switch (placementDirection.getSelected())
{
    case HORIZONTAL:
        if (side == Direction.UP || side == Direction.DOWN)
            return;
        break;
    case VERTICAL:
        if (side.getAxis().isHorizontal())
            return;
        break;
    case BOTH:
        // Allow all directions
        break;
}

Alternatively, if you prefer multiple checkboxes for more granular control, you could add:

private final CheckboxSetting placeUp =
    new CheckboxSetting("Place Up", true);
private final CheckboxSetting placeDown =
    new CheckboxSetting("Place Down", true);
private final CheckboxSetting placeHorizontal =
    new CheckboxSetting("Place Horizontal", true);

And modify the onUpdate method accordingly:

BlockHitResult blockHitResult = (BlockHitResult) hitResult;
Direction side = blockHitResult.getSide();

if ((side == Direction.UP && !placeUp.isChecked()) ||
    (side == Direction.DOWN && !placeDown.isChecked()) ||
    (side.getAxis().isHorizontal() && !placeHorizontal.isChecked()))
    return;

This gives users the flexibility to enable or disable placement in specific directions based on their needs.

Let me know your thoughts on these options!


if(!BlockUtils.canBeClicked(blockHitResult.getBlockPos()))
return;
Alexander01998 marked this conversation as resolved.
Show resolved Hide resolved

BlockPos blockToPlacePos =
blockHitResult.getBlockPos().offset(blockHitResult.getSide());
if(!BlockUtils.getState(blockToPlacePos).isReplaceable())
return;

// Option: only below feet
if(blockToPlacePos.getY() != BlockPos.ofFloored(MC.player.getPos())
.down().getY() && onlyBelowFeet.isChecked())
return;
Comment on lines +91 to +94
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Simplify the condition for better readability.

The conditional statement can be simplified for clarity by checking onlyBelowFeet first before comparing positions.

Refactor the condition:

-    if(blockToPlacePos.getY() != BlockPos.ofFloored(MC.player.getPos())
-        .down().getY() && onlyBelowFeet.isChecked())
+    if (onlyBelowFeet.isChecked() && blockToPlacePos.getY() != MC.player.getBlockPos().down().getY())
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Option: only below feet
if(blockToPlacePos.getY() != BlockPos.ofFloored(MC.player.getPos())
.down().getY() && onlyBelowFeet.isChecked())
return;
// Option: only below feet
if (onlyBelowFeet.isChecked() && blockToPlacePos.getY() != MC.player.getBlockPos().down().getY())
return;


assert MC.interactionManager != null;
MC.interactionManager.interactItem(player, Hand.MAIN_HAND);
Comment on lines +96 to +97
Copy link

@coderabbitai coderabbitai bot Oct 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Redundant call to interactItem.

The call to MC.interactionManager.interactItem(player, Hand.MAIN_HAND); is unnecessary in this context because you are already interacting with the block using interactBlock. This might lead to unintended item interactions.

Remove the redundant method call:

-    MC.interactionManager.interactItem(player, Hand.MAIN_HAND);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
assert MC.interactionManager != null;
MC.interactionManager.interactItem(player, Hand.MAIN_HAND);
assert MC.interactionManager != null;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

interactBlock and interactItem work in complicated and confusing ways. Sometimes both need to be called and sometimes even twice to match vanilla Minecraft behavior. I'd recommend instead using Wurst's utility net.wurstclient.util.InteractionSimulator whenever possible.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Alexander01998, thank you for the clarification. Using InteractionSimulator makes sense to ensure consistent behavior with vanilla Minecraft. I've updated the code to use InteractionSimulator:

@Override
public void onUpdate()
{
    if(MC.currentScreen instanceof HandledScreen)
        return;
    
    if(MC.itemUseCooldown != 0 && !fastPlace.isChecked())
        return;
    
    ClientPlayerEntity player = MC.player;
    assert player != null;
    
    // Item in hand is not a block
    if(!(player.getInventory().getStack(player.getInventory().selectedSlot)
        .getItem() instanceof BlockItem))
        return;
    
    HitResult hitResult = MC.crosshairTarget;
    if(hitResult == null || hitResult.getType() != HitResult.Type.BLOCK)
        return;
    
    BlockHitResult blockHitResult = (BlockHitResult)hitResult;
    if(blockHitResult.getSide() == Direction.UP
        || blockHitResult.getSide() == Direction.DOWN)
        return;
    
    if(!BlockUtils.canBeClicked(blockHitResult.getBlockPos()))
        return;
    
    BlockPos blockToPlacePos =
        blockHitResult.getBlockPos().offset(blockHitResult.getSide());
    if(!BlockUtils.getState(blockToPlacePos).isReplaceable())
        return;
    
    // Option: only below feet
    if(blockToPlacePos.getY() != BlockPos.ofFloored(MC.player.getPos())
        .down().getY() && onlyBelowFeet.isChecked())
        return;
    
    // Use InteractionSimulator to simulate block placement
    InteractionSimulator.rightClickBlock(blockHitResult, Hand.MAIN_HAND);
}

(•ᴗ•) A curious rabbit tilts its head in understanding.

ActionResult actionResult = MC.interactionManager.interactBlock(player,
Hand.MAIN_HAND, blockHitResult);
if(actionResult.isAccepted())
MC.player.swingHand(Hand.MAIN_HAND);

MC.itemUseCooldown = 4;
Alexander01998 marked this conversation as resolved.
Show resolved Hide resolved
Comment on lines +66 to +103
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Handle potential NullPointerException for MC.interactionManager.

Similar to the player entity, MC.interactionManager could be null. Relying on assertions might not prevent exceptions in production.

Implement a null check:

-    assert MC.interactionManager != null;
+    if (MC.interactionManager == null)
+        return;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
ClientPlayerEntity player = MC.player;
assert player != null;
// Item in hand is not a block
if(!(player.getInventory().getStack(player.getInventory().selectedSlot)
.getItem() instanceof BlockItem))
return;
HitResult hitResult = MC.crosshairTarget;
if(hitResult == null || hitResult.getType() != HitResult.Type.BLOCK)
return;
BlockHitResult blockHitResult = (BlockHitResult)hitResult;
if(blockHitResult.getSide() == Direction.UP
|| blockHitResult.getSide() == Direction.DOWN)
return;
if(!BlockUtils.canBeClicked(blockHitResult.getBlockPos()))
return;
BlockPos blockToPlacePos =
blockHitResult.getBlockPos().offset(blockHitResult.getSide());
if(!BlockUtils.getState(blockToPlacePos).isReplaceable())
return;
// Option: only below feet
if(blockToPlacePos.getY() != BlockPos.ofFloored(MC.player.getPos())
.down().getY() && onlyBelowFeet.isChecked())
return;
assert MC.interactionManager != null;
MC.interactionManager.interactItem(player, Hand.MAIN_HAND);
ActionResult actionResult = MC.interactionManager.interactBlock(player,
Hand.MAIN_HAND, blockHitResult);
if(actionResult.isAccepted())
MC.player.swingHand(Hand.MAIN_HAND);
MC.itemUseCooldown = 4;
ClientPlayerEntity player = MC.player;
assert player != null;
// Item in hand is not a block
if(!(player.getInventory().getStack(player.getInventory().selectedSlot)
.getItem() instanceof BlockItem))
return;
HitResult hitResult = MC.crosshairTarget;
if(hitResult == null || hitResult.getType() != HitResult.Type.BLOCK)
return;
BlockHitResult blockHitResult = (BlockHitResult)hitResult;
if(blockHitResult.getSide() == Direction.UP
|| blockHitResult.getSide() == Direction.DOWN)
return;
if(!BlockUtils.canBeClicked(blockHitResult.getBlockPos()))
return;
BlockPos blockToPlacePos =
blockHitResult.getBlockPos().offset(blockHitResult.getSide());
if(!BlockUtils.getState(blockToPlacePos).isReplaceable())
return;
// Option: only below feet
if(blockToPlacePos.getY() != BlockPos.ofFloored(MC.player.getPos())
.down().getY() && onlyBelowFeet.isChecked())
return;
if (MC.interactionManager == null)
return;
MC.interactionManager.interactItem(player, Hand.MAIN_HAND);
ActionResult actionResult = MC.interactionManager.interactBlock(player,
Hand.MAIN_HAND, blockHitResult);
if(actionResult.isAccepted())
MC.player.swingHand(Hand.MAIN_HAND);
MC.itemUseCooldown = 4;

}
}
11 changes: 11 additions & 0 deletions src/main/java/net/wurstclient/hacks/AutoReconnectHack.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,18 @@
import net.wurstclient.DontBlock;
import net.wurstclient.SearchTags;
import net.wurstclient.hack.Hack;
import net.wurstclient.settings.CheckboxSetting;
import net.wurstclient.settings.SliderSetting;
import net.wurstclient.settings.SliderSetting.ValueDisplay;

@SearchTags({"auto reconnect", "AutoRejoin", "auto rejoin"})
@DontBlock
public final class AutoReconnectHack extends Hack
{
private final CheckboxSetting buttons = new CheckboxSetting(
"Reconnect screen button", "Shows a button on the reconnect"
+ " screen that lets you quickly enable AutoReconnect.",
true);
private final SliderSetting waitTime =
new SliderSetting("Wait time", "Time before reconnecting in seconds.",
5, 0, 60, 0.5, ValueDisplay.DECIMAL.withSuffix("s"));
Expand All @@ -26,9 +31,15 @@ public AutoReconnectHack()
{
super("AutoReconnect");
setCategory(Category.OTHER);
addSetting(buttons);
addSetting(waitTime);
}

public boolean shouldShowButtons()
{
return buttons.isChecked();
}

public int getWaitTicks()
{
return (int)(waitTime.getValue() * 20);
Expand Down
1 change: 1 addition & 0 deletions src/main/java/net/wurstclient/hacks/PlayerEspHack.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ public PlayerEspHack()
@Override
protected void onEnable()
{
WURST.getHax().teamEspHack.setEnabled(false);
EVENTS.add(UpdateListener.class, this);
EVENTS.add(CameraTransformViewBobbingListener.class, this);
EVENTS.add(RenderListener.class, this);
Expand Down
35 changes: 33 additions & 2 deletions src/main/java/net/wurstclient/hacks/SafeWalkHack.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,18 @@
"speed bridge helper"})
public final class SafeWalkHack extends Hack
{
private final SliderSetting minDepth = new SliderSetting("Min depth",
"Won't sneak if it isn't at least this deep.\n"
+ "Increase to stop SafeWalk from stucking on stairs.\n"
+ "Decrease to make SafeWalk sneak even at the edge of carpets.",
2.0, 0.1, 10, 0.1, ValueDisplay.DECIMAL.withSuffix("m"));

private final SliderSetting motionPrediction = new SliderSetting(
"Motion prediction",
"Predict your motion to sneak earlier.\n"
+ "If not stopping at edges, increase; If not stopping near a wall, decrease.",
2.0, 1, 5, 0.5, ValueDisplay.DECIMAL.withSuffix("x"));

private final CheckboxSetting sneak =
new CheckboxSetting("Sneak at edges", "Visibly sneak at edges.", false);

Expand All @@ -36,6 +48,8 @@ public SafeWalkHack()
{
super("SafeWalk");
setCategory(Category.MOVEMENT);
addSetting(minDepth);
addSetting(motionPrediction);
addSetting(sneak);
addSetting(edgeDistance);
}
Expand All @@ -54,10 +68,25 @@ protected void onDisable()
setSneaking(false);
}

public void onClipAtLedge(boolean clipping)
public boolean shouldClip()
{
ClientPlayerEntity player = MC.player;

Box box = player.getBoundingBox();
Box adjustedBox = box
.offset(player.getVelocity().multiply(motionPrediction.getValue()))
.stretch(0, -minDepth.getValue(), 0)
.expand(-edgeDistance.getValue(), 0, -edgeDistance.getValue());

return this.isEnabled() && MC.world.isSpaceEmpty(player, adjustedBox);
}

public void onClipAtLedge()
{
boolean clipping = false;

ClientPlayerEntity player = MC.player;

if(!isEnabled() || !sneak.isChecked() || !player.isOnGround())
{
if(sneaking)
Expand All @@ -67,7 +96,9 @@ public void onClipAtLedge(boolean clipping)
}

Box box = player.getBoundingBox();
Box adjustedBox = box.stretch(0, -player.getStepHeight(), 0)
Box adjustedBox = box
.offset(player.getVelocity().multiply(motionPrediction.getValue()))
.stretch(0, -minDepth.getValue(), 0)
.expand(-edgeDistance.getValue(), 0, -edgeDistance.getValue());

if(MC.world.isSpaceEmpty(player, adjustedBox))
Expand Down
Loading