diff --git a/src/main/java/net/ccbluex/liquidbounce/injection/mixins/minecraft/client/MixinMinecraftClient.java b/src/main/java/net/ccbluex/liquidbounce/injection/mixins/minecraft/client/MixinMinecraftClient.java index 2995ae44e36..d6a2eb7cea9 100644 --- a/src/main/java/net/ccbluex/liquidbounce/injection/mixins/minecraft/client/MixinMinecraftClient.java +++ b/src/main/java/net/ccbluex/liquidbounce/injection/mixins/minecraft/client/MixinMinecraftClient.java @@ -246,7 +246,7 @@ private void injectCombatPause(CallbackInfoReturnable cir) { return; } - if (CombatManager.INSTANCE.shouldPauseCombat()) { + if (CombatManager.INSTANCE.getShouldPauseCombat()) { cir.setReturnValue(false); } } diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/ModuleManager.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/ModuleManager.kt index 8def5cf7282..144c1ce8261 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/ModuleManager.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/ModuleManager.kt @@ -278,6 +278,7 @@ object ModuleManager : Listenable, Iterable by modules { ModuleScaffold, ModuleTimer, ModuleNuker, + ModuleExtinguish, // Client ModuleAutoConfig, diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/combat/ModuleAutoShoot.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/combat/ModuleAutoShoot.kt index 93e0828a5cb..283a6cd83f6 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/combat/ModuleAutoShoot.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/combat/ModuleAutoShoot.kt @@ -110,7 +110,7 @@ object ModuleAutoShoot : Module("AutoShoot", Category.COMBAT) { val simulatedTickHandler = handler { targetTracker.cleanup() - if (notDuringCombat && CombatManager.isInCombat()) { + if (notDuringCombat && CombatManager.isInCombat) { return@handler } @@ -149,11 +149,12 @@ object ModuleAutoShoot : Module("AutoShoot", Category.COMBAT) { val target = targetTracker.lockedOnTarget ?: return@repeatable // Cannot happen but we want to smart-cast + @Suppress("USELESS_IS_CHECK") if (target !is LivingEntity) { return@repeatable } - if (notDuringCombat && CombatManager.isInCombat()) { + if (notDuringCombat && CombatManager.isInCombat) { return@repeatable } diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/combat/killaura/ModuleKillAura.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/combat/killaura/ModuleKillAura.kt index 7f675c006c9..ad31efd3130 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/combat/killaura/ModuleKillAura.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/combat/killaura/ModuleKillAura.kt @@ -179,7 +179,7 @@ object ModuleKillAura : Module("KillAura", Category.COMBAT) { // Check if there is target to attack val target = targetTracker.lockedOnTarget - if (CombatManager.shouldPauseCombat()) { + if (CombatManager.shouldPauseCombat) { AutoBlock.stopBlocking() return@repeatable } diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/ModuleAvoidHazards.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/ModuleAvoidHazards.kt index 4765c51577f..6b7e3ff02f4 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/ModuleAvoidHazards.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/ModuleAvoidHazards.kt @@ -23,7 +23,14 @@ import net.ccbluex.liquidbounce.event.handler import net.ccbluex.liquidbounce.features.module.Category import net.ccbluex.liquidbounce.features.module.Module import net.ccbluex.liquidbounce.utils.block.getBlock -import net.minecraft.block.* +import net.minecraft.block.AbstractPressurePlateBlock +import net.minecraft.block.Block +import net.minecraft.block.CactusBlock +import net.minecraft.block.CobwebBlock +import net.minecraft.block.FireBlock +import net.minecraft.block.MagmaBlock +import net.minecraft.block.SweetBerryBushBlock +import net.minecraft.fluid.Fluids import net.minecraft.util.shape.VoxelShapes /** @@ -37,25 +44,35 @@ object ModuleAvoidHazards : Module("AvoidHazards", Category.MOVEMENT) { private val berryBush by boolean("BerryBush", true) private val pressurePlates by boolean("PressurePlates", true) private val fire by boolean("Fire", true) + private val lava by boolean("Lava", true) private val magmaBlocks by boolean("MagmaBlocks", true) // Conflicts with AvoidHazards val cobWebs by boolean("Cobwebs", true) + val UNSAFE_BLOCK_CAP = Block.createCuboidShape( + 0.0, + 0.0, + 0.0, + 16.0, + 4.0, + 16.0 + ) + @Suppress("unused") val shapeHandler = handler { event -> - if (cacti && event.state.block is CactusBlock) { - event.shape = VoxelShapes.fullCube() - } else if (berryBush && event.state.block is SweetBerryBushBlock) { - event.shape = VoxelShapes.fullCube() - } else if (fire && event.state.block is FireBlock) { - event.shape = VoxelShapes.fullCube() - } else if (cobWebs && event.state.block is CobwebBlock) { - event.shape = VoxelShapes.fullCube() - } else if (pressurePlates && event.state.block is AbstractPressurePlateBlock) { - event.shape = Block.createCuboidShape(0.0, 0.0, 0.0, 16.0, 4.0, 16.0) - } else if (magmaBlocks && event.pos.down().getBlock() is MagmaBlock) { - event.shape = Block.createCuboidShape(0.0, 0.0, 0.0, 16.0, 4.0, 16.0) + val block = event.state.block + val fluidState = event.state.fluidState + + event.shape = when { + block is CactusBlock && cacti -> VoxelShapes.fullCube() + block is SweetBerryBushBlock && berryBush -> VoxelShapes.fullCube() + block is FireBlock && fire -> VoxelShapes.fullCube() + block is CobwebBlock && cobWebs -> VoxelShapes.fullCube() + block is AbstractPressurePlateBlock && pressurePlates -> UNSAFE_BLOCK_CAP + event.pos.down().getBlock() is MagmaBlock && magmaBlocks -> UNSAFE_BLOCK_CAP + (fluidState.isOf(Fluids.LAVA) || fluidState.isOf(Fluids.FLOWING_LAVA)) && lava -> VoxelShapes.fullCube() + else -> return@handler } } diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/player/autobuff/ModuleAutoBuff.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/player/autobuff/ModuleAutoBuff.kt index 1cb16cce46a..51b4cf9db79 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/player/autobuff/ModuleAutoBuff.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/player/autobuff/ModuleAutoBuff.kt @@ -89,7 +89,7 @@ object ModuleAutoBuff : Module("AutoBuff", Category.PLAYER, aliases = arrayOf("A get() = features.filter { it.enabled } val repeatable = repeatable { - if (notDuringCombat && CombatManager.isInCombat()) { + if (notDuringCombat && CombatManager.isInCombat) { return@repeatable } diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/player/nofall/modes/NoFallMLG.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/player/nofall/modes/NoFallMLG.kt index 6f459fecb1d..b643549cd18 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/player/nofall/modes/NoFallMLG.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/player/nofall/modes/NoFallMLG.kt @@ -32,9 +32,9 @@ import net.ccbluex.liquidbounce.utils.aiming.raycast import net.ccbluex.liquidbounce.utils.block.doPlacement import net.ccbluex.liquidbounce.utils.block.getBlock import net.ccbluex.liquidbounce.utils.block.getState -import net.ccbluex.liquidbounce.utils.block.targetfinding.BlockPlacementTarget import net.ccbluex.liquidbounce.utils.block.targetfinding.BlockPlacementTargetFindingOptions import net.ccbluex.liquidbounce.utils.block.targetfinding.CenterTargetPositionFactory +import net.ccbluex.liquidbounce.utils.block.targetfinding.PlacementPlan import net.ccbluex.liquidbounce.utils.block.targetfinding.findBestBlockPlacementTarget import net.ccbluex.liquidbounce.utils.client.Chronometer import net.ccbluex.liquidbounce.utils.client.SilentHotbar @@ -62,7 +62,7 @@ internal object NoFallMLG : Choice("MLG") { private val rotationsConfigurable = tree(RotationsConfigurable(this)) - private var currentTarget: PlacementTarget? = null + private var currentTarget: PlacementPlan? = null private var lastPlacements = mutableListOf>() private val fallDamageBlockingBlocks = arrayOf( @@ -90,22 +90,12 @@ internal object NoFallMLG : Choice("MLG") { ) } - private class PlacementTarget( - val targetPos: BlockPos, - val placementTarget: BlockPlacementTarget, - val hotbarItemSlot: HotbarItemSlot - ) - val tickHandler = repeatable { val target = currentTarget ?: return@repeatable - val rotation = RotationManager.serverRotation - val rayTraceResult = raycast(rotation) ?: return@repeatable + val rayTraceResult = raycast() ?: return@repeatable - if (rayTraceResult.type != HitResult.Type.BLOCK - || rayTraceResult.blockPos != target.placementTarget.interactedBlockPos - || rayTraceResult.side != target.placementTarget.direction - ) { + if (target.doesCorrespondTo(rayTraceResult)) { return@repeatable } @@ -127,8 +117,8 @@ internal object NoFallMLG : Choice("MLG") { * 1. Preventing fall damage by placing something * 2. Picking up water which we placed earlier to prevent fall damage */ - private fun getCurrentGoal(): PlacementTarget? { - getCurrentMLGPlacementTarget()?.let { + private fun getCurrentGoal(): PlacementPlan? { + getCurrentMLGPlacementPlan()?.let { return it } @@ -142,8 +132,8 @@ internal object NoFallMLG : Choice("MLG") { /** * Finds a position to pickup placed water from */ - private fun getCurrentPickupTarget(): PlacementTarget? { - val bestPickupItem = Hotbar.findClosestItem(arrayOf(Items.BUCKET)) ?: return null + private fun getCurrentPickupTarget(): PlacementPlan? { + val bestPickupItem = Hotbar.findClosestItem(Items.BUCKET) ?: return null // Remove all time outed/invalid pickup targets from the list this.lastPlacements.removeIf { @@ -155,7 +145,7 @@ internal object NoFallMLG : Choice("MLG") { continue } - val possibleTarget = findPlacementTargetAtPos(lastPlacement.first, bestPickupItem) + val possibleTarget = findPlacementPlanAtPos(lastPlacement.first, bestPickupItem) if (possibleTarget != null) { return possibleTarget @@ -168,8 +158,8 @@ internal object NoFallMLG : Choice("MLG") { /** * Find a way to prevent fall damage if we are falling. */ - private fun getCurrentMLGPlacementTarget(): PlacementTarget? { - val itemForMLG = Hotbar.findClosestItem(itemsForMLG) + private fun getCurrentMLGPlacementPlan(): PlacementPlan? { + val itemForMLG = Hotbar.findClosestItem(items = itemsForMLG) if (player.fallDistance <= minFallDist || itemForMLG == null) { return null @@ -181,10 +171,10 @@ internal object NoFallMLG : Choice("MLG") { return null } - return findPlacementTargetAtPos(collision.up(), itemForMLG) + return findPlacementPlanAtPos(collision.up(), itemForMLG) } - private fun findPlacementTargetAtPos(pos: BlockPos, item: HotbarItemSlot): PlacementTarget? { + private fun findPlacementPlanAtPos(pos: BlockPos, item: HotbarItemSlot): PlacementPlan? { val options = BlockPlacementTargetFindingOptions( listOf(Vec3i(0, 0, 0)), item.itemStack, @@ -193,9 +183,9 @@ internal object NoFallMLG : Choice("MLG") { player.pos ) - val bestPlacementTarget = findBestBlockPlacementTarget(pos, options) ?: return null + val bestPlacementPlan = findBestBlockPlacementTarget(pos, options) ?: return null - return PlacementTarget(pos, bestPlacementTarget, item) + return PlacementPlan(pos, bestPlacementPlan, item) } } diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/player/nofall/modes/NoFallRettungsplatform.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/player/nofall/modes/NoFallRettungsplatform.kt index ce3ab3a678e..0aaa88d3a07 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/player/nofall/modes/NoFallRettungsplatform.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/player/nofall/modes/NoFallRettungsplatform.kt @@ -50,7 +50,7 @@ internal object NoFallRettungsplatform : Choice("Rettungsplatform") { * We are not checking for the item name, as there are different language options causing issues. */ private val itemToPlatform - get() = Hotbar.findClosestItem(arrayOf(Items.BLAZE_ROD, Items.MAGMA_CREAM)) + get() = Hotbar.findClosestItem(Items.BLAZE_ROD, Items.MAGMA_CREAM) val repatable = repeatable { if (player.fallDistance > 2f) { diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleExtinguish.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleExtinguish.kt new file mode 100644 index 00000000000..09cbc68ac43 --- /dev/null +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleExtinguish.kt @@ -0,0 +1,155 @@ +package net.ccbluex.liquidbounce.features.module.modules.world + +import net.ccbluex.liquidbounce.config.ToggleableConfigurable +import net.ccbluex.liquidbounce.event.events.SimulatedTickEvent +import net.ccbluex.liquidbounce.event.handler +import net.ccbluex.liquidbounce.event.repeatable +import net.ccbluex.liquidbounce.features.module.Category +import net.ccbluex.liquidbounce.features.module.Module +import net.ccbluex.liquidbounce.features.module.modules.player.nofall.ModuleNoFall +import net.ccbluex.liquidbounce.utils.aiming.RotationManager +import net.ccbluex.liquidbounce.utils.aiming.RotationsConfigurable +import net.ccbluex.liquidbounce.utils.aiming.raycast +import net.ccbluex.liquidbounce.utils.block.doPlacement +import net.ccbluex.liquidbounce.utils.block.targetfinding.BlockPlacementTargetFindingOptions +import net.ccbluex.liquidbounce.utils.block.targetfinding.CenterTargetPositionFactory +import net.ccbluex.liquidbounce.utils.block.targetfinding.PlacementPlan +import net.ccbluex.liquidbounce.utils.block.targetfinding.findBestBlockPlacementTarget +import net.ccbluex.liquidbounce.utils.client.Chronometer +import net.ccbluex.liquidbounce.utils.client.SilentHotbar +import net.ccbluex.liquidbounce.utils.combat.CombatManager +import net.ccbluex.liquidbounce.utils.entity.PlayerSimulationCache +import net.ccbluex.liquidbounce.utils.inventory.Hotbar +import net.ccbluex.liquidbounce.utils.kotlin.Priority +import net.ccbluex.liquidbounce.utils.math.toBlockPos +import net.minecraft.item.Items +import net.minecraft.util.math.BlockPos +import net.minecraft.util.math.Vec3i + +object ModuleExtinguish: Module("Extinguish", Category.WORLD) { + + private val cooldown by float("Cooldown", 1.0F, 0.0F..20.0F, "s") + private val notDuringCombat by boolean("NotDuringCombat", true) + + private object Pickup : ToggleableConfigurable(ModuleExtinguish, "Pickup", true) { + val pickupSpan by floatRange("PickupSpan", 0.1F..10.0F, 0.0F..20.0F, "s") + } + + init { + tree(Pickup) + } + + private var currentTarget: PlacementPlan? = null + + private val rotationsConfigurable = tree(RotationsConfigurable(this)) + + private val cooldownTimer = Chronometer() + + private var lastExtinguishPos: BlockPos? = null + private val lastAttemptTimer = Chronometer() + + val tickMovementHandler = handler { + this.currentTarget = null + + val target = findAction() ?: return@handler + + this.currentTarget = target + + RotationManager.aimAt( + target.placementTarget.rotation, + configurable = rotationsConfigurable, + priority = Priority.IMPORTANT_FOR_PLAYER_LIFE, + provider = ModuleNoFall + ) + } + + private fun findAction(): PlacementPlan? { + val pickupSpanStart = (Pickup.pickupSpan.start * 1000.0F).toLong() + val pickupSpanEnd = (Pickup.pickupSpan.endInclusive * 1000.0F).toLong() + + if (lastExtinguishPos != null && lastAttemptTimer.hasElapsed(pickupSpanEnd)) { + lastExtinguishPos = null + } + if (notDuringCombat && CombatManager.isInCombat) { + return null + } + + val pickupPos = this.lastExtinguishPos + + if (pickupPos != null && Pickup.enabled && this.lastAttemptTimer.hasElapsed(pickupSpanStart)) { + planPickup(pickupPos)?.let { + return it + } + } + + if (!player.isOnFire || !cooldownTimer.hasElapsed()) { + return null + } + + return planExtinguishing() + } + + val repeatable = repeatable { + val target = currentTarget ?: return@repeatable + + val rayTraceResult = raycast() ?: return@repeatable + + if (!target.doesCorrespondTo(rayTraceResult)) { + return@repeatable + } + + SilentHotbar.selectSlotSilently(this, target.hotbarItemSlot.hotbarSlotForServer, 1) + + val successFunction = { + cooldownTimer.waitForAtLeast((cooldown * 1000.0F).toLong()) + lastAttemptTimer.reset() + + lastExtinguishPos = target.placementTarget.placedBlock + + true + } + + doPlacement(rayTraceResult, onItemUseSuccess = successFunction, onPlacementSuccess = successFunction) + } + + private fun planExtinguishing(): PlacementPlan? { + val waterBucketSlot = Hotbar.findClosestItem(Items.WATER_BUCKET) ?: return null + + val simulation = PlayerSimulationCache.getSimulationForLocalPlayer() + + val frameOnGround = simulation.simulateBetween(0..20).firstOrNull { + it.onGround + } ?: return null + + val playerPos = frameOnGround.pos.toBlockPos() + + val options = BlockPlacementTargetFindingOptions( + listOf(Vec3i(0, 0, 0)), + waterBucketSlot.itemStack, + CenterTargetPositionFactory, + BlockPlacementTargetFindingOptions.PRIORITIZE_LEAST_BLOCK_DISTANCE, + frameOnGround.pos + ) + + val bestPlacementPlan = findBestBlockPlacementTarget(playerPos, options) ?: return null + + return PlacementPlan(playerPos, bestPlacementPlan, waterBucketSlot) + } + + private fun planPickup(blockPos: BlockPos): PlacementPlan? { + val bucket = Hotbar.findClosestItem(Items.BUCKET) ?: return null + + val options = BlockPlacementTargetFindingOptions( + listOf(Vec3i(0, 0, 0)), + bucket.itemStack, + CenterTargetPositionFactory, + BlockPlacementTargetFindingOptions.PRIORITIZE_LEAST_BLOCK_DISTANCE, + player.pos + ) + + val bestPlacementPlan = findBestBlockPlacementTarget(blockPos, options) ?: return null + + return PlacementPlan(blockPos, bestPlacementPlan, bucket) + } + +} diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleIgnite.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleIgnite.kt index 343667c52e0..399b0835a19 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleIgnite.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleIgnite.kt @@ -60,7 +60,7 @@ object ModuleIgnite : Module("Ignite", Category.WORLD) { private val rotationsConfigurable = tree(RotationsConfigurable(this)) private val itemToTrapEnemy - get() = Hotbar.findClosestItem(arrayOf(Items.LAVA_BUCKET, Items.FLINT_AND_STEEL)) + get() = Hotbar.findClosestItem(Items.LAVA_BUCKET, Items.FLINT_AND_STEEL) private val trapWorthyBlocks = arrayOf(Blocks.LAVA, Blocks.FIRE) @@ -125,7 +125,7 @@ object ModuleIgnite : Module("Ignite", Category.WORLD) { @Suppress("unused") val placementHandler = repeatable { val target = targetTracker.lockedOnTarget ?: return@repeatable - val raycast = raycast(RotationManager.serverRotation) ?: return@repeatable + val raycast = raycast() ?: return@repeatable if (raycast.type != HitResult.Type.BLOCK || raycast.blockPos != target.blockPos.down()) { return@repeatable diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleTimer.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleTimer.kt index fb78c7c1bc8..1420b3815c6 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleTimer.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleTimer.kt @@ -121,7 +121,7 @@ object ModuleTimer : Module("Timer", Category.WORLD, disableOnQuit = true) { private val allowNegative by boolean("AllowNegative", false) val repeatable = repeatable { - if (normalizeDuringCombat && CombatManager.isInCombat()) { + if (normalizeDuringCombat && CombatManager.isInCombat) { Timer.requestTimerSpeed(1f, Priority.IMPORTANT_FOR_USAGE_1, ModuleTimer) return@repeatable } @@ -155,7 +155,7 @@ object ModuleTimer : Module("Timer", Category.WORLD, disableOnQuit = true) { boostCapable = (boostCapable + addition).toInt().coerceAtMost(timeBoostTicks) } else { val speedUp = boostCapable > 0 || - (allowNegative && (CombatManager.isInCombat() || ModuleScaffold.enabled)) + (allowNegative && (CombatManager.isInCombat || ModuleScaffold.enabled)) if (!speedUp) { return@repeatable diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/autofarm/ModuleAutoFarm.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/autofarm/ModuleAutoFarm.kt index bdf80eea896..6596f5ef121 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/autofarm/ModuleAutoFarm.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/autofarm/ModuleAutoFarm.kt @@ -91,9 +91,9 @@ object ModuleAutoFarm : Module("AutoFarm", Category.WORLD) { val itemsForSoulsand = arrayOf(Items.NETHER_WART) private val itemForFarmland - get() = Hotbar.findClosestItem(itemsForFarmland) + get() = Hotbar.findClosestItem(items = itemsForFarmland) private val itemForSoulSand - get() = Hotbar.findClosestItem(itemsForFarmland) + get() = Hotbar.findClosestItem(items = itemsForFarmland) var currentTarget: BlockPos? = null diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/RaytracingExtensions.kt b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/RaytracingExtensions.kt index 095cd29ba90..5a789cc3ef2 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/RaytracingExtensions.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/RaytracingExtensions.kt @@ -101,7 +101,7 @@ fun raytraceBlock( } fun raycast( - rotation: Rotation, + rotation: Rotation = RotationManager.serverRotation, range: Double = max(player.blockInteractionRange, player.entityInteractionRange), includeFluids: Boolean = false, tickDelta: Float = 1.0f, diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/RotationsUtil.kt b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/RotationsUtil.kt index 61391fab1c2..c3c24eb6f68 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/RotationsUtil.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/RotationsUtil.kt @@ -292,7 +292,7 @@ object RotationManager : Listenable { /** * Checks if it should update the server-side rotations */ - private fun allowedToUpdate() = !CombatManager.shouldPauseRotation() + private fun allowedToUpdate() = !CombatManager.shouldPauseRotation fun rotationMatchesPreviousRotation(): Boolean { val player = mc.player ?: return false diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/utils/block/targetfinding/TargetFinding.kt b/src/main/kotlin/net/ccbluex/liquidbounce/utils/block/targetfinding/TargetFinding.kt index b012faeadda..32ed8971eb1 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/utils/block/targetfinding/TargetFinding.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/utils/block/targetfinding/TargetFinding.kt @@ -19,6 +19,7 @@ package net.ccbluex.liquidbounce.utils.block.targetfinding import net.ccbluex.liquidbounce.config.NamedChoice +import net.ccbluex.liquidbounce.features.module.modules.player.invcleaner.HotbarItemSlot import net.ccbluex.liquidbounce.utils.aiming.Rotation import net.ccbluex.liquidbounce.utils.aiming.RotationManager import net.ccbluex.liquidbounce.utils.block.canBeReplacedWith @@ -195,7 +196,7 @@ fun findBestBlockPlacementTarget( // Do we want to replace a block or place a block at a neighbor? This makes a difference as we would need to // target the block in order to replace it. If there is no block at the target position yet, we need to target // a neighboring block - val targetMode = if (blockStateToInvestigate.isAir || blockStateToInvestigate.fluidState != null) { + val targetMode = if (blockStateToInvestigate.isAir || !blockStateToInvestigate.fluidState.isEmpty) { BlockTargetingMode.PLACE_AT_NEIGHBOR } else { BlockTargetingMode.REPLACE_EXISTING_BLOCK @@ -319,3 +320,16 @@ data class BlockPlacementTarget( private fun isBlockSolid(state: BlockState, pos: BlockPos) = state.isSideSolid(mc.world!!, pos, Direction.UP, SideShapeType.CENTER) + +class PlacementPlan( + val targetPos: BlockPos, + val placementTarget: BlockPlacementTarget, + val hotbarItemSlot: HotbarItemSlot +) { + fun doesCorrespondTo(rayTraceResult: BlockHitResult, sideMustMatch: Boolean = true): Boolean { + return rayTraceResult.type == HitResult.Type.BLOCK + && rayTraceResult.blockPos == this.placementTarget.interactedBlockPos + && (!sideMustMatch || rayTraceResult.side == this.placementTarget.direction) + } +} + diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/utils/client/Chronometer.kt b/src/main/kotlin/net/ccbluex/liquidbounce/utils/client/Chronometer.kt index b4f1106c50f..831a6bdc1a8 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/utils/client/Chronometer.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/utils/client/Chronometer.kt @@ -28,8 +28,8 @@ class Chronometer(private var lastUpdate: Long = 0) { this.lastUpdate = System.currentTimeMillis() } - fun waitFor(ms: Long) { - this.lastUpdate = System.currentTimeMillis() + ms + fun waitForAtLeast(ms: Long) { + this.lastUpdate = this.lastUpdate.coerceAtLeast(System.currentTimeMillis() + ms) } } diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/utils/combat/CombatManager.kt b/src/main/kotlin/net/ccbluex/liquidbounce/utils/combat/CombatManager.kt index 9bad495af9a..143924cd75f 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/utils/combat/CombatManager.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/utils/combat/CombatManager.kt @@ -84,10 +84,14 @@ object CombatManager : Listenable { duringCombat = 40 } - fun shouldPauseCombat(): Boolean = this.pauseCombat > 0 - fun shouldPauseRotation(): Boolean = this.pauseRotation > 0 - fun shouldPauseBlocking(): Boolean = this.pauseBlocking > 0 - fun isInCombat(): Boolean = this.duringCombat > 0 + val shouldPauseCombat: Boolean + get() = this.pauseCombat > 0 + val shouldPauseRotation: Boolean + get() = this.pauseRotation > 0 + val shouldPauseBlocking: Boolean + get() = this.pauseBlocking > 0 + val isInCombat: Boolean + get() = this.duringCombat > 0 fun pauseCombatForAtLeast(pauseTime: Int) { this.pauseCombat = this.pauseCombat.coerceAtLeast(pauseTime) diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/utils/entity/PlayerSimulationCache.kt b/src/main/kotlin/net/ccbluex/liquidbounce/utils/entity/PlayerSimulationCache.kt index 5211989cb72..00a59a64bd0 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/utils/entity/PlayerSimulationCache.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/utils/entity/PlayerSimulationCache.kt @@ -67,7 +67,7 @@ class SimulatedPlayerCache(private val simulatedPlayer: SimulatedPlayer) { private val lock = ReentrantReadWriteLock() fun simulateUntil(ticks: Int) { - check(ticks > 0) { "ticks must be greater than 0" } + check(ticks >= 0) { "ticks may not be negative" } if (currentSimulationStep >= ticks) { return diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/utils/inventory/InventoryUtils.kt b/src/main/kotlin/net/ccbluex/liquidbounce/utils/inventory/InventoryUtils.kt index 5aeb63055d8..483cc6d5798 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/utils/inventory/InventoryUtils.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/utils/inventory/InventoryUtils.kt @@ -113,7 +113,7 @@ val ALL_SLOTS_IN_INVENTORY: List = object Hotbar { - fun findClosestItem(items: Array): HotbarItemSlot? { + fun findClosestItem(vararg items: Item): HotbarItemSlot? { return HOTBAR_SLOTS.filter { it.itemStack.item in items } .minByOrNull { abs(player.inventory.selectedSlot - it.hotbarSlotForServer) } }