Skip to content

Commit 63bc635

Browse files
committed
Refactor graph connectivity logic and improve block update handling.
Abstracted grid connectivity into reusable methods for cleaner and more flexible code. Enhanced block update listener to skip redundant updates and improved logging clarity. Simplified pathfinding and traversal checks for better maintainability.
1 parent ceb3dbb commit 63bc635

File tree

4 files changed

+32
-60
lines changed

4 files changed

+32
-60
lines changed

common/src/main/kotlin/com/lambda/module/modules/movement/Pathfinder.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,11 +132,12 @@ object Pathfinder : Module(
132132
}
133133

134134
listen<WorldEvent.BlockUpdate.Client> {
135+
if (it.newState == it.oldState) return@listen
135136
val pos = it.pos.toFastVec()
136137
MoveFinder.clear(pos)
137138
dStar.invalidate(pos, pathing.pruneGraph)
138139
needsUpdate = true
139-
info("Updated block at ${it.pos.asString()} to ${it.newState.block.name.string} rescheduled D*Lite.")
140+
info("Updated block at ${it.pos.asString()} from ${it.oldState.block.name.string} to ${it.newState.block.name.string} rescheduled D*Lite.")
140141
}
141142

142143
listen<RotationEvent.StrafeInput> { event ->

common/src/main/kotlin/com/lambda/pathing/dstar/DStarLite.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import com.lambda.graphics.gl.Matrices.withVertexTransform
2323
import com.lambda.graphics.renderer.gui.FontRenderer
2424
import com.lambda.graphics.renderer.gui.FontRenderer.drawString
2525
import com.lambda.pathing.PathingSettings
26+
import com.lambda.util.GraphUtil
2627
import com.lambda.util.math.Vec2d
2728
import com.lambda.util.math.minus
2829
import com.lambda.util.math.plus
@@ -152,7 +153,7 @@ class DStarLite(
152153
*/
153154
fun invalidate(u: FastVector, prune: Boolean = false) {
154155
val modified = mutableSetOf(u)
155-
(graph.neighbors(u) + u).forEach { v ->
156+
(GraphUtil.n26(u).keys + u).forEach { v ->
156157
val current = graph.neighbors(v)
157158
val updated = graph.nodeInitializer(v)
158159
val removed = current.filter { w -> w !in updated }

common/src/main/kotlin/com/lambda/pathing/move/MoveFinder.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,7 @@ object MoveFinder {
5252
private val nodeTypeCache = HashMap<FastVector, NodeType>()
5353

5454
fun SafeContext.moveOptions(origin: FastVector, heuristic: KFunction1<FastVector, Double>, config: PathingConfig): Set<Move> {
55-
val nodeType = findPathType(origin)
56-
if (nodeType == NodeType.BLOCKED) return emptySet()
55+
if (!traversable(origin.toBlockPos())) return setOf()
5756
return EightWayDirection.entries.flatMap { direction ->
5857
(-1..1).mapNotNull { y ->
5958
getPathNode(heuristic, origin, direction, y, config)

common/src/main/kotlin/com/lambda/util/GraphUtil.kt

Lines changed: 27 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -44,79 +44,50 @@ object GraphUtil {
4444

4545
// 6-connectivity (Axis-aligned moves only)
4646
fun createGridGraph6Conn(blockedNodes: MutableSet<FastVector> = mutableSetOf()): LazyGraph {
47-
val cost = 1.0
4847
return LazyGraph { node ->
49-
if (node in blockedNodes) return@LazyGraph emptyMap()
50-
val neighbors = mutableMapOf<FastVector, Double>()
51-
val x = node.x
52-
val y = node.y
53-
val z = node.z
54-
// Add neighbors differing by 1 in exactly one dimension
55-
neighbors[fastVectorOf(x + 1, y, z)] = cost
56-
neighbors[fastVectorOf(x - 1, y, z)] = cost
57-
neighbors[fastVectorOf(x, y + 1, z)] = cost
58-
neighbors[fastVectorOf(x, y - 1, z)] = cost
59-
neighbors[fastVectorOf(x, y, z + 1)] = cost
60-
neighbors[fastVectorOf(x, y, z - 1)] = cost
61-
neighbors.minus(blockedNodes)
48+
if (node in blockedNodes) emptyMap()
49+
else n6(node).filterKeys { it !in blockedNodes }
6250
}
6351
}
6452

6553
// 18-connectivity (Axis-aligned + Face diagonal moves)
6654
fun createGridGraph18Conn(blockedNodes: MutableSet<FastVector> = mutableSetOf()): LazyGraph {
67-
val cost1 = 1.0 // Axis-aligned
68-
val cost2 = sqrt(2.0) // Face diagonal
6955
return LazyGraph { node ->
70-
if (node in blockedNodes) return@LazyGraph emptyMap()
71-
val neighbors = mutableMapOf<FastVector, Double>()
72-
val x = node.x
73-
val y = node.y
74-
val z = node.z
75-
for (dx in -1..1) {
76-
for (dy in -1..1) {
77-
for (dz in -1..1) {
78-
if (dx == 0 && dy == 0 && dz == 0) continue // Skip self
79-
val distSq = dx*dx + dy*dy + dz*dz
80-
if (distSq > 2) continue // Exclude cube diagonals (distSq = 3)
81-
82-
val cost = if (distSq == 1) cost1 else cost2
83-
neighbors[fastVectorOf(x + dx, y + dy, z + dz)] = cost
84-
}
85-
}
86-
}
87-
neighbors.minus(blockedNodes)
56+
if (node in blockedNodes) emptyMap()
57+
else n18(node).filterKeys { it !in blockedNodes }
8858
}
8959
}
9060

9161
// 26-connectivity (Axis-aligned + Face diagonal + Cube diagonal moves)
9262
fun createGridGraph26Conn(blockedNodes: MutableSet<FastVector> = mutableSetOf()): LazyGraph {
93-
val cost1 = 1.0 // Axis-aligned
94-
val cost2 = sqrt(2.0) // Face diagonal
95-
val cost3 = sqrt(3.0) // Cube diagonal
9663
return LazyGraph { node ->
97-
if (node in blockedNodes) return@LazyGraph emptyMap()
98-
val neighbors = mutableMapOf<FastVector, Double>()
99-
val x = node.x
100-
val y = node.y
101-
val z = node.z
102-
for (dx in -1..1) {
103-
for (dy in -1..1) {
104-
for (dz in -1..1) {
105-
if (dx == 0 && dy == 0 && dz == 0) continue // Skip self
64+
if (node in blockedNodes) emptyMap()
65+
else n26(node).filterKeys { it !in blockedNodes }
66+
}
67+
}
68+
69+
fun n6(o: FastVector) = neighborhood(o, minDistSq = 1, maxDistSq = 1)
70+
fun n18(o: FastVector) = neighborhood(o, minDistSq = 1, maxDistSq = 2)
71+
fun n26(o: FastVector) = neighborhood(o, minDistSq = 1, maxDistSq = 3)
10672

107-
val cost = when (dx*dx + dy*dy + dz*dz) {
108-
1 -> cost1
109-
2 -> cost2
110-
3 -> cost3
111-
else -> continue // Should not happen with dx/dy/dz in -1..1
73+
fun neighborhood(origin: FastVector, minDistSq: Int = 1, maxDistSq: Int = 1): Map<FastVector, Double> =
74+
(-1..1).flatMap { dx ->
75+
(-1..1).flatMap { dy ->
76+
(-1..1).mapNotNull { dz ->
77+
val distSq = dx*dx + dy*dy + dz*dz
78+
if (distSq in minDistSq..maxDistSq) {
79+
val neighbor = fastVectorOf(origin.x + dx, origin.y + dy, origin.z + dz)
80+
val cost = when (distSq) {
81+
1 -> 1.0
82+
2 -> sqrt(2.0)
83+
3 -> sqrt(3.0)
84+
else -> error("Unexpected squared distance: $distSq")
11285
}
113-
neighbors[fastVectorOf(x + dx, y + dy, z + dz)] = cost
114-
}
86+
neighbor to cost
87+
} else null
11588
}
11689
}
117-
neighbors.minus(blockedNodes)
118-
}
119-
}
90+
}.toMap()
12091

12192
fun List<FastVector>.string() = joinToString(" -> ") { it.string }
12293
fun List<FastVector>.length() = zipWithNext { a, b -> a dist b }.sum()

0 commit comments

Comments
 (0)