Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
9602e3f
Added pathfinder
Avanatiker Feb 26, 2025
77f858c
Kinda working pathing
Avanatiker Feb 26, 2025
71bbfec
NodeTypes and different moves
Avanatiker Mar 1, 2025
86d7874
Theta*
Avanatiker Mar 2, 2025
4cd8e1d
Better support check and config cleanup
Avanatiker Mar 2, 2025
c694f16
Some fixes
Avanatiker Mar 3, 2025
3d0a784
Change target pos
Avanatiker Mar 5, 2025
9f23026
Test lib
Avanatiker Mar 5, 2025
72a5f49
D* Lite - 2D with tests
Avanatiker Mar 6, 2025
23c8fa2
3D Implementation
Avanatiker Mar 6, 2025
2d2bd55
Merge branch 'feature/dstar-lite' into feature/pathfinder
Avanatiker Mar 6, 2025
c0c63e7
Speed up clearance checks
Avanatiker Mar 25, 2025
da0efc1
More settings
Avanatiker Mar 26, 2025
1a5a9b9
Lazy D* Lite
Avanatiker Mar 26, 2025
314dd36
Incremental pathing on state updates and more settings
Avanatiker Mar 27, 2025
fc86013
Funny path renderer
Avanatiker Mar 27, 2025
6d878b8
D* cut off timeout
Avanatiker Mar 28, 2025
7339f60
Merge branch 'master' into feature/pathfinder
Avanatiker Apr 7, 2025
86d17d5
Optimized threading and graph renderer
Avanatiker Apr 8, 2025
fc26de3
Pathing command, detailed graph renderer, graph invalidation
Avanatiker Apr 14, 2025
7ccb5d4
Fix refining of path start
Avanatiker Apr 14, 2025
c65dfb5
Less frequent pathing updates
Avanatiker Apr 14, 2025
fb1ded1
Add render setting functionalities
Avanatiker Apr 14, 2025
a6f39f6
Improved renderer
Avanatiker Apr 15, 2025
cc433cb
Vertex invalidation approach
Avanatiker Apr 15, 2025
44c64ec
Incremental pathfinding with updateable weights
Avanatiker Apr 20, 2025
df12980
Node invalidation on world state update
Avanatiker Apr 21, 2025
d1d2302
Simplify invalidation
Avanatiker Apr 21, 2025
6d94e3c
Test graph connectivity on node invalidation
Avanatiker Apr 21, 2025
699ed38
Update rhs of newly created nodes
Avanatiker Apr 21, 2025
da2eedb
Clean move finder cache
Avanatiker Apr 21, 2025
5257bc8
Graph pruning on invalidation, graph consistency checks
Avanatiker Apr 22, 2025
19daf8a
Proper consistency test
Avanatiker Apr 24, 2025
ceb3dbb
Add path consistency tests and graph pruning improvements
Avanatiker Apr 30, 2025
63bc635
Refactor graph connectivity logic and improve block update handling.
Avanatiker Apr 30, 2025
e95314e
Merge remote-tracking branch 'origin/master' into feature/pathfinder
Avanatiker May 2, 2025
2bf4a18
Improve test quality
Avanatiker May 3, 2025
2a048a2
Slight code improvements
Avanatiker May 4, 2025
85a922e
Incremental package
Avanatiker May 4, 2025
669ebe1
Bidirectional graph initialization
Avanatiker May 4, 2025
9cc2ff4
Fix concurrency on graph render, relax path condition
Avanatiker May 5, 2025
1777e33
Dynamic connectivity
Avanatiker May 5, 2025
a321f12
Merge remote-tracking branch 'origin/master' into feature/pathfinder
Avanatiker Jul 3, 2025
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
171 changes: 171 additions & 0 deletions common/src/main/kotlin/com/lambda/command/commands/PathCommand.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
/*
* Copyright 2024 Lambda
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package com.lambda.command.commands

import com.lambda.brigadier.argument.boolean
import com.lambda.brigadier.argument.double
import com.lambda.brigadier.argument.integer
import com.lambda.brigadier.argument.literal
import com.lambda.brigadier.argument.value
import com.lambda.brigadier.execute
import com.lambda.brigadier.optional
import com.lambda.brigadier.required
import com.lambda.command.LambdaCommand
import com.lambda.module.modules.movement.Pathfinder
import com.lambda.pathing.move.MoveFinder
import com.lambda.util.Communication.info
import com.lambda.util.extension.CommandBuilder
import com.lambda.util.world.fastVectorOf
import com.lambda.util.world.string

object PathCommand : LambdaCommand(
name = "pathfinder",
usage = "path <invalidate | reset | update>",
description = "Finds a quick path through the world",
aliases = setOf("path")
) {
override fun CommandBuilder.create() {
required(literal("target")) {
required(integer("X", -30000000, 30000000)) { x ->
required(integer("Y", -64, 255)) { y ->
required(integer("Z", -30000000, 30000000)) { z ->
execute {
val v = fastVectorOf(x().value(), y().value(), z().value())
Pathfinder.target = v
this@PathCommand.info("Set new target at ${v.string}")
}
}
}
}
}

required(literal("invalidate")) {
required(integer("X", -30000000, 30000000)) { x ->
required(integer("Y", -64, 255)) { y ->
required(integer("Z", -30000000, 30000000)) { z ->
optional(boolean("prune")) { prune ->
execute {
val v = fastVectorOf(x().value(), y().value(), z().value())
val pruneGraph = if (prune != null) {
prune().value()
} else false
Pathfinder.dStar.invalidate(v, pruneGraph)
MoveFinder.clear(v)
Pathfinder.needsUpdate = true
this@PathCommand.info("Invalidated ${v.string}")
}
}
}
}
}
}

required(literal("remove")) {
required(integer("X", -30000000, 30000000)) { x ->
required(integer("Y", -64, 255)) { y ->
required(integer("Z", -30000000, 30000000)) { z ->
execute {
val v = fastVectorOf(x().value(), y().value(), z().value())
Pathfinder.graph.removeNode(v)
this@PathCommand.info("Removed ${v.string}")
}
}
}
}
}

required(literal("update")) {
required(integer("X", -30000000, 30000000)) { x ->
required(integer("Y", -64, 255)) { y ->
required(integer("Z", -30000000, 30000000)) { z ->
execute {
val u = fastVectorOf(x().value(), y().value(), z().value())
Pathfinder.dStar.updateVertex(u)
this@PathCommand.info("Updated ${u.string}")
}
}
}
}
}

required(literal("successor")) {
required(integer("X", -30000000, 30000000)) { x ->
required(integer("Y", -64, 255)) { y ->
required(integer("Z", -30000000, 30000000)) { z ->
execute {
val v = fastVectorOf(x().value(), y().value(), z().value())
this@PathCommand.info("Successors: ${Pathfinder.graph.successors[v]?.entries?.joinToString { "${it.key.string}: ${it.value}" }}")
}
}
}
}
}

required(literal("predecessors")) {
required(integer("X", -30000000, 30000000)) { x ->
required(integer("Y", -64, 255)) { y ->
required(integer("Z", -30000000, 30000000)) { z ->
execute {
val v = fastVectorOf(x().value(), y().value(), z().value())
this@PathCommand.info("Predecessors: ${Pathfinder.graph.predecessors[v]?.entries?.joinToString { "${it.key.string}: ${it.value}" }}")
}
}
}
}
}

required(literal("setEdge")) {
required(integer("X1", -30000000, 30000000)) { x1 ->
required(integer("Y1", -64, 255)) { y1 ->
required(integer("Z1", -30000000, 30000000)) { z1 ->
required(integer("X2", -30000000, 30000000)) { x2 ->
required(integer("Y2", -64, 255)) { y2 ->
required(integer("Z2", -30000000, 30000000)) { z2 ->
required(double("cost")) { cost ->
execute {
val v1 = fastVectorOf(x1().value(), y1().value(), z1().value())
val v2 = fastVectorOf(x2().value(), y2().value(), z2().value())
val c = cost().value()
Pathfinder.dStar.updateEdge(v1, v2, c)
Pathfinder.needsUpdate = true
this@PathCommand.info("Updated edge ${v1.string} -> ${v2.string} to cost of $c")
}
}
}
}
}
}
}
}
}

required(literal("clear")) {
execute {
Pathfinder.graph.clear()
this@PathCommand.info("Cleared graph")
}
}

required(literal("refresh")) {
execute {
Pathfinder.needsUpdate = true
this@PathCommand.info("Marked pathfinder for refresh")
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import com.lambda.util.extension.min
import net.minecraft.block.BlockState
import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Box
import net.minecraft.util.math.Vec3d
import net.minecraft.util.shape.VoxelShape
import java.awt.Color

Expand Down Expand Up @@ -222,3 +223,13 @@ fun StaticESPRenderer.buildOutline(
if (outlineMode.check(hasEast, hasSouth)) buildLine(trf, brf)
if (outlineMode.check(hasSouth, hasWest)) buildLine(tlf, blf)
}

fun StaticESPRenderer.buildLine(
start: Vec3d,
end: Vec3d,
color: Color,
) = outlineBuilder.use {
val v1 by lazy { vertex { vec3(start.x, start.y, start.z).color(color) } }
val v2 by lazy { vertex { vec3(end.x, end.y, end.z).color(color) } }
buildLine(v1, v2)
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,13 @@ import com.lambda.interaction.construction.simulation.BuildSimulator.simulate
import com.lambda.interaction.request.rotation.RotationConfig
import com.lambda.module.modules.client.TaskFlowModule
import com.lambda.threading.runSafe
import com.lambda.util.BlockUtils.blockState
import com.lambda.util.world.FastVector
import com.lambda.util.world.WorldUtils.playerBox
import com.lambda.util.world.WorldUtils.traversable
import com.lambda.util.world.toBlockPos
import com.lambda.util.world.toVec3d
import net.minecraft.client.network.ClientPlayerEntity
import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Box
import net.minecraft.util.math.Direction
import net.minecraft.util.math.Vec3d
import java.awt.Color

Expand All @@ -57,10 +56,7 @@ data class Simulation(
val isTooFar = blueprint.getClosestPointTo(view).distanceTo(view) > 10.0
runSafe {
if (isOutOfBounds && isTooFar) return@getOrPut emptySet()
val blockPos = pos.toBlockPos()
val isWalkable = blockState(blockPos.down()).isSideSolidFullSquare(world, blockPos, Direction.UP)
if (!isWalkable) return@getOrPut emptySet()
if (!playerFitsIn(blockPos)) return@getOrPut emptySet()
if (!traversable(pos.toBlockPos())) return@getOrPut emptySet()
}

blueprint.simulate(view, interact, rotation, inventory, build)
Expand All @@ -74,13 +70,7 @@ data class Simulation(
}
}

private fun SafeContext.playerFitsIn(pos: BlockPos): Boolean {
return world.isSpaceEmpty(Vec3d.ofBottomCenter(pos).playerBox())
}

companion object {
fun Vec3d.playerBox(): Box = Box(x - 0.3, y, z - 0.3, x + 0.3, y + 1.8, z + 0.3).contract(1.0E-6)

fun Blueprint.simulation(
interact: InteractionConfig = TaskFlowModule.interact,
rotation: RotationConfig = TaskFlowModule.rotation,
Expand Down
29 changes: 29 additions & 0 deletions common/src/main/kotlin/com/lambda/module/hud/PathfinderHUD.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright 2024 Lambda
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package com.lambda.module.hud

import com.lambda.module.HudModule
import com.lambda.module.modules.movement.Pathfinder
import com.lambda.module.tag.ModuleTag

object PathfinderHUD : HudModule.Text(
name = "PathfinderHUD",
defaultTags = setOf(ModuleTag.CLIENT),
) {
override fun getText() = Pathfinder.debugInfo()
}
Loading
Loading