Skip to content

Commit

Permalink
Add Extinguish module (#3795)
Browse files Browse the repository at this point in the history
  • Loading branch information
superblaubeere27 authored Aug 25, 2024
1 parent 204bc42 commit c537513
Show file tree
Hide file tree
Showing 19 changed files with 243 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ private void injectCombatPause(CallbackInfoReturnable<Boolean> cir) {
return;
}

if (CombatManager.INSTANCE.shouldPauseCombat()) {
if (CombatManager.INSTANCE.getShouldPauseCombat()) {
cir.setReturnValue(false);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ object ModuleManager : Listenable, Iterable<Module> by modules {
ModuleScaffold,
ModuleTimer,
ModuleNuker,
ModuleExtinguish,

// Client
ModuleAutoConfig,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ object ModuleAutoShoot : Module("AutoShoot", Category.COMBAT) {
val simulatedTickHandler = handler<SimulatedTickEvent> {
targetTracker.cleanup()

if (notDuringCombat && CombatManager.isInCombat()) {
if (notDuringCombat && CombatManager.isInCombat) {
return@handler
}

Expand Down Expand Up @@ -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
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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

/**
Expand All @@ -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<BlockShapeEvent> { 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
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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<Pair<BlockPos, Chronometer>>()

private val fallDamageBlockingBlocks = arrayOf(
Expand Down Expand Up @@ -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
}

Expand All @@ -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
}

Expand All @@ -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 {
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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,
Expand All @@ -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)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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<SimulatedTickEvent> {
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)
}

}
Loading

0 comments on commit c537513

Please sign in to comment.