Skip to content

Commit 48f1144

Browse files
committed
Propagating Blueprint
1 parent 51db458 commit 48f1144

File tree

6 files changed

+98
-52
lines changed

6 files changed

+98
-52
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright 2024 Lambda
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
package com.lambda.interaction.construction.blueprint
19+
20+
import com.lambda.context.SafeContext
21+
import com.lambda.threading.runSafe
22+
import com.lambda.util.extension.Structure
23+
import net.minecraft.util.math.Vec3i
24+
25+
data class PropagatingBlueprint(
26+
val onFinish: SafeContext.(Structure) -> Structure = { it },
27+
) : Blueprint() {
28+
fun next() {
29+
runSafe {
30+
structure = onFinish(structure)
31+
}
32+
}
33+
34+
override var structure: Structure = emptyMap()
35+
private set(value) {
36+
field = value
37+
bounds.update()
38+
}
39+
40+
override fun toString() = "Propagating Blueprint at ${center?.toShortString()}"
41+
42+
companion object {
43+
fun offset(offset: Vec3i): SafeContext.(Structure) -> Structure = {
44+
it.map { (pos, state) ->
45+
pos.add(offset) to state
46+
}.toMap()
47+
}
48+
49+
fun propagatingBlueprint(
50+
onFinish: SafeContext.(Structure) -> Structure,
51+
) = PropagatingBlueprint(onFinish)
52+
}
53+
}

common/src/main/kotlin/com/lambda/interaction/construction/blueprint/DynamicBlueprint.kt renamed to common/src/main/kotlin/com/lambda/interaction/construction/blueprint/TickingBlueprint.kt

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,12 @@ import com.lambda.threading.runSafe
2222
import com.lambda.util.extension.Structure
2323
import net.minecraft.util.math.Vec3i
2424

25-
data class DynamicBlueprint(
26-
val init: SafeContext.(Structure) -> Structure = { emptyMap() },
27-
val update: SafeContext.(Structure) -> Structure = { it },
25+
data class TickingBlueprint(
26+
val onTick: SafeContext.(Structure) -> Structure = { it },
2827
) : Blueprint() {
29-
fun update() {
28+
fun tick() {
3029
runSafe {
31-
structure = update(structure)
32-
}
33-
}
34-
35-
fun create() {
36-
runSafe {
37-
structure = init(structure)
30+
structure = onTick(structure)
3831
}
3932
}
4033

@@ -53,9 +46,8 @@ data class DynamicBlueprint(
5346
}.toMap()
5447
}
5548

56-
fun Structure.toBlueprint(
57-
init: SafeContext.(Structure) -> Structure = { this@toBlueprint },
49+
fun tickingBlueprint(
5850
onTick: SafeContext.(Structure) -> Structure,
59-
) = DynamicBlueprint(init = init, update = onTick)
51+
) = TickingBlueprint(onTick)
6052
}
6153
}

common/src/main/kotlin/com/lambda/interaction/construction/simulation/BuildSimulator.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ object BuildSimulator {
150150
val preprocessing = target.findProcessorForState()
151151

152152
preprocessing.sides.forEach { neighbor ->
153-
val hitPos = if (targetPosState.isAir) pos.offset(neighbor) else pos
153+
val hitPos = if (targetPosState.isAir || targetPosState.isLiquid) pos.offset(neighbor) else pos
154154
val hitSide = neighbor.opposite
155155

156156
val voxelShape = hitPos.blockState(world).getOutlineShape(world, hitPos)

common/src/main/kotlin/com/lambda/module/modules/player/HighwayTools.kt

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ import com.lambda.config.groups.BuildSettings
2121
import com.lambda.config.groups.InteractionSettings
2222
import com.lambda.config.groups.InventorySettings
2323
import com.lambda.config.groups.RotationSettings
24-
import com.lambda.interaction.construction.blueprint.StaticBlueprint.Companion.toBlueprint
24+
import com.lambda.interaction.construction.blueprint.Blueprint.Companion.emptyStructure
25+
import com.lambda.interaction.construction.blueprint.PropagatingBlueprint.Companion.propagatingBlueprint
2526
import com.lambda.interaction.construction.verify.TargetState
2627
import com.lambda.module.Module
2728
import com.lambda.module.tag.ModuleTag
@@ -93,7 +94,7 @@ object HighwayTools : Module(
9394
octant = player.octant
9495
startPos = player.blockPos
9596
currentPos = startPos
96-
buildSlice()
97+
buildHighway()
9798
}
9899
onDisable {
99100
runningTask?.cancel()
@@ -103,30 +104,29 @@ object HighwayTools : Module(
103104
}
104105
}
105106

106-
private fun buildSlice() {
107-
distanceMoved += sliceSize
108-
109-
var structure: Structure = mutableMapOf()
110-
val slice = generateSlice()
111-
repeat(sliceSize) {
112-
val vec = Vec3i(octant.offsetX, 0, octant.offsetZ)
113-
currentPos = currentPos.add(vec)
114-
structure = structure.plus(slice.map { it.key.add(currentPos) to it.value })
115-
}
116-
117-
runningTask = structure.toBlueprint().build(
118-
build = build,
119-
rotation = rotation,
120-
interact = interact,
121-
inventory = inventory,
122-
).finally {
107+
private fun buildHighway() {
108+
runningTask = propagatingBlueprint {
123109
if (distanceMoved < distance || distance < 0) {
124-
buildSlice()
110+
var structure = emptyStructure()
111+
val slice = generateSlice()
112+
repeat(sliceSize) {
113+
structure = structure.plus(slice.map { it.key.add(currentPos) to it.value })
114+
val vec = Vec3i(octant.offsetX, 0, octant.offsetZ)
115+
currentPos = currentPos.add(vec)
116+
}
117+
distanceMoved += sliceSize
118+
structure
125119
} else {
126120
this@HighwayTools.info("Highway built")
127121
disable()
122+
emptyStructure()
128123
}
129-
}.run()
124+
}.build(
125+
build = build,
126+
rotation = rotation,
127+
interact = interact,
128+
inventory = inventory,
129+
).run()
130130
}
131131

132132
private fun generateSlice(): Structure {
@@ -202,22 +202,24 @@ object HighwayTools : Module(
202202
}
203203

204204
if (walls != Material.None) {
205+
val wallElevation = rimHeight + if (pavement != Material.None) 1 else 0
206+
205207
// Left wall
206208
structure += generateDirectionalTube(
207209
orthogonal,
208210
1,
209-
height,
211+
height - wallElevation,
210212
-center + width,
211-
0,
213+
wallElevation,
212214
).associateWith { target(walls, wallMaterial) }
213215

214216
// Right wall
215217
structure += generateDirectionalTube(
216218
orthogonal,
217219
1,
218-
height,
220+
height - wallElevation,
219221
-center - 1,
220-
0,
222+
wallElevation,
221223
).associateWith { target(walls, wallMaterial) }
222224
}
223225

common/src/main/kotlin/com/lambda/module/modules/player/Nuker.kt

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@
1717

1818
package com.lambda.module.modules.player
1919

20-
import com.lambda.interaction.construction.blueprint.Blueprint.Companion.emptyStructure
21-
import com.lambda.interaction.construction.blueprint.DynamicBlueprint.Companion.toBlueprint
20+
import com.lambda.interaction.construction.blueprint.TickingBlueprint.Companion.tickingBlueprint
2221
import com.lambda.interaction.construction.verify.TargetState
2322
import com.lambda.module.Module
2423
import com.lambda.module.tag.ModuleTag
@@ -44,8 +43,7 @@ object Nuker : Module(
4443

4544
init {
4645
onEnable {
47-
task = emptyStructure()
48-
.toBlueprint {
46+
task = tickingBlueprint {
4947
val selection = BlockPos.iterateOutwards(player.blockPos, width, height, width)
5048
.asSequence()
5149
.map { it.blockPos }
@@ -59,7 +57,7 @@ object Nuker : Module(
5957
val floor = BlockPos.iterateOutwards(player.blockPos.down(), width, 0, width)
6058
.map { it.blockPos }
6159
.associateWith { TargetState.Solid }
62-
return@toBlueprint selection + floor
60+
return@tickingBlueprint selection + floor
6361
}
6462

6563
selection

common/src/main/kotlin/com/lambda/task/tasks/BuildTask.kt

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,14 @@ import com.lambda.config.groups.InventoryConfig
2424
import com.lambda.interaction.request.rotation.RotationConfig
2525
import com.lambda.context.SafeContext
2626
import com.lambda.event.events.MovementEvent
27-
import com.lambda.event.events.PacketEvent
2827
import com.lambda.event.events.TickEvent
2928
import com.lambda.event.events.WorldEvent
3029
import com.lambda.event.listener.SafeListener.Companion.listen
3130
import com.lambda.interaction.request.rotation.RotationManager.onRotate
3231
import com.lambda.interaction.construction.blueprint.Blueprint
3332
import com.lambda.interaction.construction.blueprint.Blueprint.Companion.toStructure
34-
import com.lambda.interaction.construction.blueprint.DynamicBlueprint
33+
import com.lambda.interaction.construction.blueprint.PropagatingBlueprint
34+
import com.lambda.interaction.construction.blueprint.TickingBlueprint
3535
import com.lambda.interaction.construction.blueprint.StaticBlueprint.Companion.toBlueprint
3636
import com.lambda.interaction.construction.context.BreakContext
3737
import com.lambda.interaction.construction.context.BuildContext
@@ -50,9 +50,6 @@ import com.lambda.util.Communication.info
5050
import com.lambda.util.Formatting.string
5151
import com.lambda.util.collections.LimitedDecayQueue
5252
import com.lambda.util.extension.Structure
53-
import net.minecraft.block.BlockState
54-
import net.minecraft.network.packet.s2c.play.BlockUpdateS2CPacket
55-
import net.minecraft.network.packet.s2c.play.ChunkDeltaUpdateS2CPacket
5653
import net.minecraft.util.math.BlockPos
5754

5855
class BuildTask @Ta5kBuilder constructor(
@@ -76,7 +73,7 @@ class BuildTask @Ta5kBuilder constructor(
7673
private var goodPositions = setOf<BlockPos>()
7774

7875
override fun SafeContext.onStart() {
79-
(blueprint as? DynamicBlueprint)?.create()
76+
(blueprint as? PropagatingBlueprint)?.next()
8077
}
8178

8279
init {
@@ -88,7 +85,7 @@ class BuildTask @Ta5kBuilder constructor(
8885
}
8986

9087
listen<TickEvent.Post> {
91-
(blueprint as? DynamicBlueprint)?.update()
88+
(blueprint as? TickingBlueprint)?.tick()
9289

9390
if (finishOnDone && blueprint.structure.isEmpty()) {
9491
failure("Structure is empty")
@@ -132,6 +129,10 @@ class BuildTask @Ta5kBuilder constructor(
132129
is BuildResult.Unbreakable,
133130
is BuildResult.Restricted,
134131
is BuildResult.NoPermission -> {
132+
if (blueprint is PropagatingBlueprint) {
133+
blueprint.next()
134+
return@listen
135+
}
135136
if (finishOnDone) success()
136137
}
137138

0 commit comments

Comments
 (0)