Skip to content

Commit c28e38b

Browse files
committed
use ticking blueprints for placing containers
1 parent 7f78b68 commit c28e38b

File tree

6 files changed

+72
-57
lines changed

6 files changed

+72
-57
lines changed

common/src/main/kotlin/com/lambda/interaction/construction/blueprint/PropagatingBlueprint.kt

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,14 @@ import com.lambda.util.extension.Structure
2323
import net.minecraft.util.math.Vec3i
2424

2525
data class PropagatingBlueprint(
26-
val onFinish: SafeContext.(Structure) -> Structure = { it },
26+
val onFinish: SafeContext.(Structure) -> Structure? = { it },
2727
) : Blueprint() {
28-
fun next() {
28+
fun next() =
2929
runSafe {
30-
structure = onFinish(structure)
30+
onFinish(structure)?.also { new ->
31+
structure = new
32+
}
3133
}
32-
}
3334

3435
override var structure: Structure = emptyMap()
3536
private set(value) {
@@ -40,14 +41,14 @@ data class PropagatingBlueprint(
4041
override fun toString() = "Propagating Blueprint at ${center?.toShortString()}"
4142

4243
companion object {
43-
fun offset(offset: Vec3i): SafeContext.(Structure) -> Structure = {
44+
fun offset(offset: Vec3i): SafeContext.(Structure) -> Structure? = {
4445
it.map { (pos, state) ->
4546
pos.add(offset) to state
4647
}.toMap()
4748
}
4849

4950
fun propagatingBlueprint(
50-
onFinish: SafeContext.(Structure) -> Structure,
51+
onFinish: SafeContext.(Structure) -> Structure?,
5152
) = PropagatingBlueprint(onFinish)
5253
}
5354
}

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

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,14 @@ import com.lambda.util.extension.Structure
2323
import net.minecraft.util.math.Vec3i
2424

2525
data class TickingBlueprint(
26-
val onTick: SafeContext.(Structure) -> Structure = { it },
26+
val onTick: SafeContext.(Structure) -> Structure? = { it },
2727
) : Blueprint() {
28-
fun tick() {
28+
fun tick() =
2929
runSafe {
30-
structure = onTick(structure)
30+
onTick(structure)?.also { new ->
31+
structure = new
32+
}
3133
}
32-
}
3334

3435
override var structure: Structure = emptyMap()
3536
private set(value) {
@@ -40,14 +41,14 @@ data class TickingBlueprint(
4041
override fun toString() = "Dynamic Blueprint at ${center?.toShortString()}"
4142

4243
companion object {
43-
fun offset(offset: Vec3i): SafeContext.(Structure) -> Structure = {
44+
fun offset(offset: Vec3i): SafeContext.(Structure) -> Structure? = {
4445
it.map { (pos, state) ->
4546
pos.add(offset) to state
4647
}.toMap()
4748
}
4849

4950
fun tickingBlueprint(
50-
onTick: SafeContext.(Structure) -> Structure,
51+
onTick: SafeContext.(Structure) -> Structure?,
5152
) = TickingBlueprint(onTick)
5253
}
5354
}

common/src/main/kotlin/com/lambda/task/Task.kt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -185,9 +185,7 @@ abstract class Task<Result> : Nameable, Muteable {
185185
}
186186

187187
@Ta5kBuilder
188-
fun failure(message: String) {
189-
failure(IllegalStateException(message))
190-
}
188+
fun failure(message: String) = failure(IllegalStateException(message))
191189

192190
@Ta5kBuilder
193191
fun failure(

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

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ class BuildTask @Ta5kBuilder constructor(
7070
private val interactionConfig: InteractionConfig = TaskFlowModule.interaction,
7171
private val inventory: InventoryConfig = TaskFlowModule.inventory,
7272
private val hotbar: HotbarConfig = TaskFlowModule.hotbar,
73-
) : Task<Unit>() {
73+
) : Task<Structure>() {
7474
override val name: String get() = "Building $blueprint with ${(breaks / (age / 20.0 + 0.001)).string} b/s ${(placements / (age / 20.0 + 0.001)).string} p/s"
7575

7676
private val pendingInteractions = ConcurrentLinkedQueue<BuildContext>()
@@ -89,7 +89,7 @@ class BuildTask @Ta5kBuilder constructor(
8989
} else null
9090

9191
override fun SafeContext.onStart() {
92-
(blueprint as? PropagatingBlueprint)?.next()
92+
iteratePropagating()
9393
}
9494

9595
init {
@@ -115,12 +115,9 @@ class BuildTask @Ta5kBuilder constructor(
115115
is BuildResult.Unbreakable,
116116
is BuildResult.Restricted,
117117
is BuildResult.NoPermission -> {
118-
if (blueprint is PropagatingBlueprint) {
119-
blueprint.next()
120-
return@listen
121-
}
118+
if (iteratePropagating()) return@listen
122119

123-
if (finishOnDone) success()
120+
if (finishOnDone) success(blueprint.structure)
124121
}
125122

126123
is BuildResult.NotVisible,
@@ -195,7 +192,9 @@ class BuildTask @Ta5kBuilder constructor(
195192
}
196193

197194
listen<TickEvent.Post> {
198-
(blueprint as? TickingBlueprint)?.tick()
195+
if (blueprint is TickingBlueprint) {
196+
blueprint.tick() ?: failure("Failed to tick the ticking blueprint")
197+
}
199198

200199
if (finishOnDone && blueprint.structure.isEmpty()) {
201200
failure("Structure is empty")
@@ -234,6 +233,12 @@ class BuildTask @Ta5kBuilder constructor(
234233
return true
235234
} ?: false
236235

236+
fun iteratePropagating() =
237+
if (blueprint is PropagatingBlueprint) {
238+
blueprint.next() ?: failure("Failed to propagate the next blueprint")
239+
true
240+
} else false
241+
237242
companion object {
238243
@Ta5kBuilder
239244
fun build(

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import com.lambda.config.groups.InteractionConfig
2121
import com.lambda.event.events.InventoryEvent
2222
import com.lambda.event.events.TickEvent
2323
import com.lambda.event.listener.SafeListener.Companion.listen
24+
import com.lambda.interaction.request.interacting.InteractConfig
2425
import com.lambda.interaction.request.rotating.RotationConfig
2526
import com.lambda.interaction.request.rotating.visibilty.lookAtBlock
2627
import com.lambda.module.modules.client.TaskFlowModule
@@ -34,9 +35,9 @@ import net.minecraft.util.math.Direction
3435
class OpenContainer @Ta5kBuilder constructor(
3536
private val blockPos: BlockPos,
3637
private val waitForSlotLoad: Boolean = true,
37-
private val rotate: Boolean = true,
3838
private val rotation: RotationConfig = TaskFlowModule.rotation,
39-
private val interact: InteractionConfig = TaskFlowModule.interaction,
39+
private val interact: InteractConfig = TaskFlowModule.build.interacting,
40+
private val interactionConfig: InteractionConfig = TaskFlowModule.interaction,
4041
private val sides: Set<Direction> = Direction.entries.toSet(),
4142
) : Task<ScreenHandler>() {
4243
override val name get() = "${containerState.description(inScope)} at ${blockPos.toShortString()}"
@@ -83,8 +84,8 @@ class OpenContainer @Ta5kBuilder constructor(
8384
listen<TickEvent.Pre> {
8485
if (containerState != State.SCOPING) return@listen
8586

86-
val target = lookAtBlock(blockPos, sides, config = interact)
87-
if (rotate && !target.requestBy(rotation).done) return@listen
87+
val target = lookAtBlock(blockPos, sides, config = interactionConfig)
88+
if (interact.rotate && !target.requestBy(rotation).done) return@listen
8889

8990
val hitResult = target.hit?.hitIfValid()?.blockResult ?: return@listen
9091
interaction.interactBlock(player, Hand.MAIN_HAND, hitResult)

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

Lines changed: 39 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import com.lambda.config.groups.InteractionConfig
2222
import com.lambda.context.SafeContext
2323
import com.lambda.interaction.construction.blueprint.Blueprint.Companion.toStructure
2424
import com.lambda.interaction.construction.blueprint.StaticBlueprint.Companion.toBlueprint
25+
import com.lambda.interaction.construction.blueprint.TickingBlueprint.Companion.tickingBlueprint
2526
import com.lambda.interaction.construction.result.BuildResult
2627
import com.lambda.interaction.construction.result.PlaceResult
2728
import com.lambda.interaction.construction.simulation.BuildSimulator.simulate
@@ -32,6 +33,7 @@ import com.lambda.module.modules.client.TaskFlowModule
3233
import com.lambda.task.Task
3334
import com.lambda.task.tasks.BuildTask.Companion.build
3435
import com.lambda.util.BlockUtils.blockPos
36+
import com.lambda.util.BlockUtils.blockState
3537
import com.lambda.util.item.ItemUtils.shulkerBoxes
3638
import net.minecraft.block.ChestBlock
3739
import net.minecraft.entity.mob.ShulkerEntity
@@ -51,39 +53,46 @@ class PlaceContainer @Ta5kBuilder constructor(
5153
override val name: String get() = "Placing container ${startStack.name.string}"
5254

5355
override fun SafeContext.onStart() {
54-
val results = BlockPos.iterateOutwards(player.blockPos, 4, 3, 4)
55-
.map { it.blockPos }
56-
.flatMap {
57-
it.blockPos
58-
.toStructure(TargetState.Stack(startStack))
59-
.toBlueprint()
60-
.simulate(player.eyePos)
56+
tickingBlueprint { current ->
57+
if (current.isNotEmpty() &&
58+
current.all { it.value.matches(blockState(it.key), it.key, world) })
59+
{
60+
return@tickingBlueprint current
6161
}
6262

63-
// ToDo: Check based on if we can move the player close enough rather than y level once the custom pathfinder is merged
64-
val succeeds = results.filterIsInstance<PlaceResult.Place>().filter {
65-
canBeOpened(startStack, it.blockPos, it.context.result.side) && it.blockPos.y == player.blockPos.y
66-
}
67-
val wrongStacks = results.filterIsInstance<BuildResult.WrongItemSelection>().filter {
68-
canBeOpened(startStack, it.blockPos, it.context.result.side) && it.blockPos.y == player.blockPos.y
69-
}
70-
(succeeds + wrongStacks).minOrNull()?.let { result ->
71-
build(
72-
build = build,
73-
rotation = rotation,
74-
interact = interact,
75-
inventory = inventory,
76-
) {
77-
result.blockPos
78-
.toStructure(TargetState.Stack(startStack))
79-
.toBlueprint()
80-
}.finally {
81-
success(result.blockPos)
82-
}.execute(this@PlaceContainer)
83-
return
84-
}
63+
val results = BlockPos.iterateOutwards(player.blockPos, 4, 3, 4)
64+
.map { it.blockPos }
65+
.flatMap {
66+
it.blockPos
67+
.toStructure(TargetState.Stack(startStack))
68+
.toBlueprint()
69+
.simulate(player.eyePos)
70+
}
8571

86-
failure("No valid placement found")
72+
// ToDo: Check based on if we can move the player close enough rather than y level once the custom pathfinder is merged
73+
val succeeds = results.filterIsInstance<PlaceResult.Place>().filter {
74+
canBeOpened(startStack, it.blockPos, it.context.result.side) && it.blockPos.y == player.blockPos.y
75+
}
76+
val wrongStacks = results.filterIsInstance<BuildResult.WrongItemSelection>().filter {
77+
canBeOpened(startStack, it.blockPos, it.context.result.side) && it.blockPos.y == player.blockPos.y
78+
}
79+
(succeeds + wrongStacks).minOrNull()
80+
?.blockPos
81+
?.toStructure(TargetState.Stack(startStack))
82+
}.build(
83+
true,
84+
false,
85+
build = build,
86+
rotation = rotation,
87+
interact = interact,
88+
inventory = inventory
89+
).finally {
90+
val pos = it.keys.firstOrNull() ?: run {
91+
failure("The returned structure was empty")
92+
return@finally
93+
}
94+
success(pos)
95+
}.execute(this@PlaceContainer)
8796
}
8897

8998
private fun SafeContext.canBeOpened(

0 commit comments

Comments
 (0)