diff --git a/src/main/java/dev/heliosclient/managers/ModuleManager.java b/src/main/java/dev/heliosclient/managers/ModuleManager.java index c5b02d2..854a998 100644 --- a/src/main/java/dev/heliosclient/managers/ModuleManager.java +++ b/src/main/java/dev/heliosclient/managers/ModuleManager.java @@ -218,7 +218,7 @@ public static T get(Class moduleClazz) { public static ArrayList getModuleByNameSearch(String moduleName, int amount) { ArrayList moduleS = new ArrayList<>(); if (moduleName.isEmpty()) return moduleS; - moduleName = moduleName.trim(); + moduleName = moduleName.trim().toLowerCase(); for (Module_ module : modules) { if (moduleS.size() >= amount) { @@ -229,15 +229,15 @@ public static ArrayList getModuleByNameSearch(String moduleName, int am moduleS.add(module); return moduleS; // Exact match found, return immediately } - if (module.name.trim().toLowerCase().contains(moduleName.toLowerCase())) { + if (module.name.trim().toLowerCase().contains(moduleName)) { moduleS.add(module); } } String finalModuleName = moduleName; moduleS.sort((m1, m2) -> { - int m1Score = StringUtils.getLevenshteinDistance(m1.name.trim().toLowerCase(), finalModuleName.toLowerCase()); - int m2Score = StringUtils.getLevenshteinDistance(m2.name.trim().toLowerCase(), finalModuleName.toLowerCase()); + int m1Score = StringUtils.getLevenshteinDistance(m1.name.trim().toLowerCase(), finalModuleName); + int m2Score = StringUtils.getLevenshteinDistance(m2.name.trim().toLowerCase(), finalModuleName); // First, sort by the score int scoreComparison = Integer.compare(m1Score, m2Score); diff --git a/src/main/java/dev/heliosclient/managers/NotificationManager.java b/src/main/java/dev/heliosclient/managers/NotificationManager.java index d3d4934..b2ad2cc 100644 --- a/src/main/java/dev/heliosclient/managers/NotificationManager.java +++ b/src/main/java/dev/heliosclient/managers/NotificationManager.java @@ -57,7 +57,7 @@ private static void updateNotifications() { // Add notifications from the queue until the maximum number is reached while (displayedNotifications.size() < MAX_DISPLAYED && !notificationQueue.isEmpty()) { Notification notification = notificationQueue.poll(); - if (notification == null) return; + if (notification == null) continue; notification.setCreationTime(System.currentTimeMillis()); notification.playSound(notification.soundEvent, notification.volume, notification.pitch); @@ -76,6 +76,7 @@ private static void updatePositions() { POSITION_MODE == Notification.PositionMode.BOTTOM_LEFT) ? screenHeight - VERTICAL_SPACING : VERTICAL_SPACING; + int targetX = calculateInitialTargetX(screenWidth); for (Notification notification : displayedNotifications) { @@ -103,7 +104,6 @@ private static void updatePositions() { default -> targetY; }; - // Update X position based on position mode and horizontal spacing int newX = calculateNotificationX(screenWidth, notification.getWidth(), targetX); notification.smoothMoveY(targetOffset); @@ -126,7 +126,6 @@ private static int calculateNotificationX(int screenWidth, int notificationWidth }; } - // Add method to set horizontal spacing public static void setHorizontalSpacing(int spacing) { HORIZONTAL_SPACING = Math.max(0, spacing); } diff --git a/src/main/java/dev/heliosclient/module/modules/movement/NoFall.java b/src/main/java/dev/heliosclient/module/modules/movement/NoFall.java index d8195da..1b1b8e0 100644 --- a/src/main/java/dev/heliosclient/module/modules/movement/NoFall.java +++ b/src/main/java/dev/heliosclient/module/modules/movement/NoFall.java @@ -2,11 +2,11 @@ import dev.heliosclient.event.SubscribeEvent; import dev.heliosclient.event.events.TickEvent; +import dev.heliosclient.event.events.player.PlayerMotionEvent; import dev.heliosclient.mixin.AccessorMinecraftClient; import dev.heliosclient.module.Categories; import dev.heliosclient.module.Module_; import dev.heliosclient.module.settings.*; -import dev.heliosclient.system.mixininterface.IVec3d; import dev.heliosclient.util.ChatUtils; import dev.heliosclient.util.blocks.BlockUtils; import dev.heliosclient.util.player.DamageUtils; @@ -14,10 +14,12 @@ import dev.heliosclient.util.player.RotationUtils; import net.minecraft.block.Block; import net.minecraft.block.Blocks; +import net.minecraft.block.LeavesBlock; import net.minecraft.fluid.Fluids; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; +import net.minecraft.network.packet.c2s.play.ClientCommandC2SPacket; import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket; import net.minecraft.util.Hand; import net.minecraft.util.hit.BlockHitResult; @@ -53,7 +55,7 @@ public class NoFall extends Module_ { .name("Mode") .description("Mode which should save player from fall height ") .onSettingChange(this) - .defaultValue(List.of("Classic", "AlwaysOnGround", "Clutch", "Disconnect (annoying)")) + .defaultValue(List.of("PositionAndOnGround", "OnGroundOnly", "Clutch", "Disconnect (annoying)")) .defaultListIndex(0) .build() ); @@ -118,14 +120,18 @@ public void onEnable() { @Override public void onSettingChange(Setting setting) { super.onSettingChange(setting); - if (cancelBounce.value && mode.value == 2) { + if ((setting == cancelBounce || setting == mode) && cancelBounce.value && mode.value == 2) { ChatUtils.sendHeliosMsg("(NoFall Clutch) SlimeBlocks will cause fall damage with cancelBounce on!"); } } @SubscribeEvent public void onTick(TickEvent.PLAYER event) { - assert mc.player != null; + if (mode.value == 2) { + if (shouldResetClutch()) { + cm.resetClutch(); + } + } if (mc.player.fallDistance >= fallHeight.value && !mc.player.isCreative()) { if (mode.value == 0) { // Second condition is to check if the y velocity of player is fast enough to cause damage. @@ -143,20 +149,12 @@ public void onTick(TickEvent.PLAYER event) { ) ); } else if (mode.value == 1) { - // Prevents the half-heart damage from classic mode + // Prevents the half-heart damage from PositionAndOnGround mode mc.player.networkHandler.sendPacket( new PlayerMoveC2SPacket.OnGroundOnly( true ) ); - - //Clutch mode! - } else if (mode.value == 2) { - - if (shouldResetClutch()) { - cm.resetClutch(); - } - clutch(); } else if (mode.value == 3) { int distance = 0; int y = (int) mc.player.getY(); @@ -177,45 +175,56 @@ public void onTick(TickEvent.PLAYER event) { } } } + @SubscribeEvent + public void onMotion(PlayerMotionEvent event) { + if (mc.player.fallDistance >= fallHeight.value && !mc.player.isCreative()) { + clutch(event); + } + } - private void clutch() { + private void clutch(PlayerMotionEvent event) { float health = mc.player.getHealth(); boolean shouldClutch = !onlyApplyNearDeath.value || DamageUtils.calcFallDamage(mc.player) >= health - 2; if (shouldClutch) { - BlockHitResult result = mc.world.raycast(new RaycastContext(mc.player.getPos(), mc.player.getPos().subtract(0, 4, 0), RaycastContext.ShapeType.OUTLINE, RaycastContext.FluidHandling.NONE, mc.player)); + double prevX = mc.player.getVelocity().x; + double prevZ = mc.player.getVelocity().z; + + if (stop.value) { + event.modifyMovement().heliosClient$setXZ(0, 0); + } + + BlockHitResult result = mc.world.raycast(new RaycastContext(mc.player.getPos(), mc.player.getPos().subtract(0, mc.interactionManager.getReachDistance() - 1, 0), RaycastContext.ShapeType.OUTLINE, RaycastContext.FluidHandling.NONE, mc.player)); if (result != null && result.getType() == HitResult.Type.BLOCK) { BlockPos bpDown = result.getBlockPos(); - if (!isPlayerAlreadySafe(bpDown)) { + if (!isPlayerAlreadySafe(result.getBlockPos())) { for (ClutchItem item : ClutchItem.values()) { - cm.clutch(item, bpDown); + cm.clutch(item, bpDown,event); if (cm.hasClutchedProperly()) { break; } } } - } + if (stop.value) + event.modifyMovement().heliosClient$setXZ(prevX, prevZ); } } private boolean shouldResetClutch() { - return mc.player.isOnGround() || mc.player.getBlockStateAtPos().getFluidState() != Fluids.EMPTY.getDefaultState(); + return mc.player.isOnGround() || + mc.player.getBlockStateAtPos().getFluidState() != Fluids.EMPTY.getDefaultState() || + mc.player.fallDistance < fallHeight.value; } - public boolean isPlayerAlreadySafe(BlockPos bpDown) { - Block block = mc.world.getBlockState(bpDown).getBlock(); - + public boolean isPlayerAlreadySafe(BlockPos blockPos) { if (forcePlace.value) { return false; } - //If the block is air, then it's not safe. - if (BlockUtils.airBreed(block)) { - return false; - } + Block block = mc.world.getBlockState(blockPos).getBlock(); //If block is clutch item then it's probably safe. (probably because we are not accounting fallDistance for now, // meaning haybales and slimeblocks may still kill you). @@ -266,12 +275,13 @@ public class ClutchManager { private boolean hasClutchedProperly = false; - public void clutch(ClutchItem item, BlockPos pos) { + public void clutch(ClutchItem item, BlockPos pos, PlayerMotionEvent event) { if (item == ClutchItem.WATER_BUCKET && mc.world.getDimensionKey() == DimensionTypes.THE_NETHER) { return; } int slot = InventoryUtils.findItemInHotbar(item.getItem()); + if (slot == -1) { hasClutchedProperly = false; return; @@ -282,29 +292,31 @@ public void clutch(ClutchItem item, BlockPos pos) { ItemStack stack = mc.player.getInventory().getStack(slot); int count = InventoryUtils.getItemStackCountSafe(stack); - - InventoryUtils.swapToSlot(slot, true); - //We want to rotate only when the player has set the rotate setting for blocks rotate(rotate.value, pos.toCenterPos(), item.getResultItem()); - double prevX = mc.player.getVelocity().x; - double prevZ = mc.player.getVelocity().z; - - if (stop.value) - ((IVec3d) mc.player.getVelocity()).heliosClient$setXZ(0, 0); + InventoryUtils.swapToSlot(slot, true); if (item.getResultItem() == null) { - double prevY = mc.player.getVelocity().y; + double prevY = event.getMovement().y; - ((IVec3d) mc.player.getVelocity()).heliosClient$setY(0); + event.modifyMovement().heliosClient$setY(0); - BlockUtils.place(pos, rotate.value,false, airPlace.value, slot == InventoryUtils.OFFHAND ? Hand.OFF_HAND : Hand.MAIN_HAND); - - ((IVec3d) mc.player.getVelocity()).heliosClient$setY(prevY); + BlockUtils.place(pos.up(), rotate.value,airPlace.value, slot == InventoryUtils.OFFHAND ? Hand.OFF_HAND : Hand.MAIN_HAND); + event.modifyMovement().heliosClient$setY(prevY); } else { + Block block = mc.world.getBlockState(pos).getBlock(); + if (BlockUtils.isClickable(block) || block instanceof LeavesBlock) { + mc.player.networkHandler.sendPacket(new ClientCommandC2SPacket(mc.player, ClientCommandC2SPacket.Mode.PRESS_SHIFT_KEY)); + mc.player.setSneaking(true); + } ((AccessorMinecraftClient) mc).rightClick(); + + if (BlockUtils.isClickable(block) || block instanceof LeavesBlock) { + mc.player.networkHandler.sendPacket(new ClientCommandC2SPacket(mc.player, ClientCommandC2SPacket.Mode.RELEASE_SHIFT_KEY)); + mc.player.setSneaking(false); + } } if (item.getResultItem() != null) { @@ -315,14 +327,15 @@ public void clutch(ClutchItem item, BlockPos pos) { hasClutchedProperly = newStack.getCount() != count; } - if (stop.value) - ((IVec3d) mc.player.getVelocity()).heliosClient$setXZ(prevX, prevZ); + if(hasClutchedProperly){ + InventoryUtils.swapBackHotbar(); + } } public void rotate(boolean rotate, Vec3d vec, Item resultItem) { if (resultItem == null && !rotate) return; - RotationUtils.lookAt(vec); + RotationUtils.instaLookAt(vec); } public boolean hasClutchedProperly() { diff --git a/src/main/java/dev/heliosclient/module/modules/movement/Scaffold.java b/src/main/java/dev/heliosclient/module/modules/movement/Scaffold.java index f5baa73..b97f11c 100644 --- a/src/main/java/dev/heliosclient/module/modules/movement/Scaffold.java +++ b/src/main/java/dev/heliosclient/module/modules/movement/Scaffold.java @@ -341,10 +341,10 @@ private boolean placeBlockPos(BlockPos pos, int itemSlot) { if (autoSwitch.value) { ScaffoldCount.setScaffoldStack(mc.player.getInventory().getStack(itemSlot)); - placeResult = BlockUtils.place(pos, airPlace.value, rotate.value, true, itemSlot, silentSwitch.value); + placeResult = BlockUtils.place(pos, airPlace.value, rotate.value, itemSlot, silentSwitch.value); } else { ScaffoldCount.setScaffoldStack(mc.player.getInventory().getMainHandStack()); - placeResult = BlockUtils.place(pos, airPlace.value, rotate.value, true); + placeResult = BlockUtils.place(pos, airPlace.value, rotate.value); } if (placeResult) { diff --git a/src/main/java/dev/heliosclient/module/modules/world/painter/Painter.java b/src/main/java/dev/heliosclient/module/modules/world/painter/Painter.java index 56da49c..643d999 100644 --- a/src/main/java/dev/heliosclient/module/modules/world/painter/Painter.java +++ b/src/main/java/dev/heliosclient/module/modules/world/painter/Painter.java @@ -358,7 +358,7 @@ public void onTick(TickEvent.CLIENT event) { boolean swapped = InventoryUtils.swapToSlot(slot, false); if (swapped) { - BlockUtils.place(changedPos, playerRotate.value,false, airPlace.value, slot == InventoryUtils.OFFHAND ? Hand.OFF_HAND : Hand.MAIN_HAND); + BlockUtils.place(changedPos, playerRotate.value,airPlace.value, slot == InventoryUtils.OFFHAND ? Hand.OFF_HAND : Hand.MAIN_HAND); } } } diff --git a/src/main/java/dev/heliosclient/ui/HeliosClientInfoScreen.java b/src/main/java/dev/heliosclient/ui/HeliosClientInfoScreen.java index 01129f7..c625b48 100644 --- a/src/main/java/dev/heliosclient/ui/HeliosClientInfoScreen.java +++ b/src/main/java/dev/heliosclient/ui/HeliosClientInfoScreen.java @@ -11,6 +11,7 @@ import net.minecraft.screen.ScreenTexts; import net.minecraft.text.Text; +//TODO: Make this pretty public class HeliosClientInfoScreen extends Screen { public static HeliosClientInfoScreen INSTANCE = new HeliosClientInfoScreen(); private final ThreePartsLayoutWidget layout = new ThreePartsLayoutWidget(this); @@ -40,5 +41,4 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { this.renderBackground(context, mouseX, mouseY, delta); super.render(context, mouseX, mouseY, delta); } - } diff --git a/src/main/java/dev/heliosclient/ui/notification/Notification.java b/src/main/java/dev/heliosclient/ui/notification/Notification.java index c82f8a5..f503ade 100644 --- a/src/main/java/dev/heliosclient/ui/notification/Notification.java +++ b/src/main/java/dev/heliosclient/ui/notification/Notification.java @@ -1,6 +1,7 @@ package dev.heliosclient.ui.notification; import dev.heliosclient.HeliosClient; +import dev.heliosclient.managers.NotificationManager; import dev.heliosclient.util.animation.Easing; import dev.heliosclient.util.animation.EasingType; import dev.heliosclient.util.fontutils.fxFontRenderer; @@ -11,9 +12,13 @@ public abstract class Notification { public static AnimationStyle ANIMATE = AnimationStyle.SLIDE; protected PositionMode positionMode = PositionMode.BOTTOM_RIGHT; + protected int screenWidth; protected int screenHeight; + /** + * This specifies if the notification is supposed to look "fancy" / "compact" + */ public static boolean IS_FANCY = false; protected int width = 1; @@ -83,6 +88,10 @@ protected void calculateInitialPosition() { } } + /** + * Override this method IF you want to remove animations. + * But then you will need to update x and y position to target position. + */ public void update() { timeElapsed = System.currentTimeMillis() - creationTime; @@ -138,8 +147,8 @@ protected void updatePopAnimation() { scale = 0; } } - x = targetX; - y = targetY; + this.x = targetX; + this.y = targetY; } // Helper methods for slide animation @@ -223,14 +232,22 @@ public void moveY(int deltaY) { y += deltaY; } + /** + * Linearly smoothened way to move to a Y position. + * This is different from the {@link #moveY(int)} as this takes a targetY instead of deltaY + */ public void smoothMoveY(int targetY) { int currentY = getY(); - // Calculate new Y with smoothness (easing) - int newY = Math.round((targetY - currentY) * 0.25f); + // Calculate new Y with linear smoothness (easing) + int newDeltaY = Math.round((targetY - currentY) * 0.25f); - moveY(newY); + moveY(newDeltaY); } + + /** + * This should be used update the notification's dimensions + */ protected void updateDimensions(int newWidth, int newHeight) { // Only recalculate if dimensions actually change if (this.width != newWidth || this.height != newHeight) { @@ -249,12 +266,19 @@ protected void updateDimensions(int newWidth, int newHeight) { y = targetY + deltaY; } } + public boolean isExpired() { return expired; } + /** + * Render the notification in this method + */ public abstract void render(MatrixStack matrices, int y, fxFontRenderer fontRenderer); + /** + * Override this method to play a sound when the notification is displayed. Called in {@link NotificationManager#updateNotifications()} + */ public void playSound(SoundEvent soundEvent, float volume, float pitch) {} public long getCreationTime() { diff --git a/src/main/java/dev/heliosclient/ui/notification/notifications/InfoNotification.java b/src/main/java/dev/heliosclient/ui/notification/notifications/InfoNotification.java index 305996a..422052e 100644 --- a/src/main/java/dev/heliosclient/ui/notification/notifications/InfoNotification.java +++ b/src/main/java/dev/heliosclient/ui/notification/notifications/InfoNotification.java @@ -80,6 +80,9 @@ public void render(MatrixStack matrices, int y, fxFontRenderer fontRenderer) { } private void renderFancyStyle(MatrixStack matrices, fxFontRenderer fontRenderer) { + //Fancy, but neither customisable nor practical. + //TODO : ^^^ + // Gradient background Renderer2D.drawRoundedGradientRectangle( matrices.peek().getPositionMatrix(), diff --git a/src/main/java/dev/heliosclient/util/blocks/BlockUtils.java b/src/main/java/dev/heliosclient/util/blocks/BlockUtils.java index 310dc18..7b01fab 100644 --- a/src/main/java/dev/heliosclient/util/blocks/BlockUtils.java +++ b/src/main/java/dev/heliosclient/util/blocks/BlockUtils.java @@ -69,7 +69,7 @@ public static boolean canBreakInstantly(BlockState state, float speed) { } public static boolean canPlace(BlockPos pos, BlockState state) { - if (pos == null || mc.world == null || !World.isValid(pos) || !mc.world.getBlockState(pos).isReplaceable() || !mc.world.isInBuildLimit(pos)) + if (pos == null || mc.world == null || !World.isValid(pos) || !state.isReplaceable() || !mc.world.isInBuildLimit(pos)) return false; return mc.world.getWorldBorder().contains(pos) && mc.world.canPlace(state, pos, ShapeContext.absent()); } @@ -215,18 +215,14 @@ public static boolean isPlaceable(BlockPos pos, boolean entityCheck) { } public static boolean place(BlockPos pos, boolean airPlace, boolean rotate) { - return place(pos, rotate, false, airPlace, Hand.MAIN_HAND); + return place(pos, rotate, airPlace, Hand.MAIN_HAND); } - public static boolean place(BlockPos pos, boolean airPlace, boolean rotate, boolean clientSideRotation) { - return place(pos, rotate, clientSideRotation, airPlace, Hand.MAIN_HAND); - } - - public static boolean place(BlockPos pos, boolean airPlace, boolean rotate, boolean clientSideRotation, int itemSlotHotbar, boolean silentSwitch) { + public static boolean place(BlockPos pos, boolean airPlace, boolean rotate, int itemSlotHotbar, boolean silentSwitch) { InventoryUtils.swapToSlot(itemSlotHotbar, silentSwitch); - boolean returnVal = place(pos, rotate, clientSideRotation, airPlace, itemSlotHotbar == InventoryUtils.OFFHAND ? Hand.OFF_HAND : Hand.MAIN_HAND); + boolean returnVal = place(pos, rotate, airPlace, itemSlotHotbar == InventoryUtils.OFFHAND ? Hand.OFF_HAND : Hand.MAIN_HAND); if (silentSwitch) InventoryUtils.swapBackHotbar(); @@ -256,7 +252,7 @@ public static boolean isClickable(Block block) { || block instanceof TrapdoorBlock; } - public static boolean place(BlockPos pos, boolean rotate, boolean clientSideRotation, boolean airPlace, Hand hand) { + public static boolean place(BlockPos pos, boolean rotate, boolean airPlace, Hand hand) { if (!canPlace(pos, mc.world.getBlockState(pos)) || mc.player.getStackInHand(hand) == null || mc.player.getStackInHand(hand).isEmpty()) return false; @@ -270,7 +266,6 @@ public static boolean place(BlockPos pos, boolean rotate, boolean clientSideRota neighbour = pos; } else { neighbour = airPlace ? pos : pos.offset(d); - hitPos = hitPos.add(d.getOffsetX() * 0.5, d.getOffsetY() * 0.5, d.getOffsetZ() * 0.5); } @@ -283,8 +278,8 @@ public static boolean place(BlockPos pos, boolean rotate, boolean clientSideRota float yaw = (float) RotationUtils.getYaw(hitPos); float pitch = (float) RotationUtils.getPitch(hitPos); - RotationUtils.setServerRotations(yaw,pitch); mc.getNetworkHandler().sendPacket(new PlayerMoveC2SPacket.LookAndOnGround(yaw, pitch, mc.player.isOnGround())); + RotationUtils.setServerRotations(yaw,pitch); } result = interactBlock(blockHitResult,neighborBlock,hand); @@ -299,7 +294,6 @@ private static ActionResult interactBlock(BlockHitResult blockHitResult,Block bl ActionResult result = mc.interactionManager.interactBlock(mc.player, hand, blockHitResult); - if (result.shouldSwingHand()) { mc.player.swingHand(hand); }