Skip to content

Commit f9b51ad

Browse files
Avanatikeremyfops
andauthored
Taskflow improvements (#82)
- **Rotation Management:** Replaced `requestRotation` with a flexible `rotate` DSL for cleaner and more consistent rotation handling. - **Inventory Enhancements:** Refactored inventory handling with new transaction utilities (`TransactionExecutor`, `QuickCraftTransaction`) and improved material prioritization. Introduced `accessEnderChest` configuration for better container filtering. - **TaskFlow Updates:** Streamlined task resolution with a `Resolvable` interface, enhanced nesting logic, and modularized `TaskFlowModule` references. - **Placement and Interaction Logic:** Simplified placement in `BuildTask`, added `AxisPreprocessor` and `BlockFaceProcessor`, and improved block interaction with `expectedPos` logic. - **Structure Handling:** Added support for NBT structure files, half-slab building, relative structure paths, and `StructureRegistry` for dynamic management. - **Mining and Pathing Fixes:** Enabled mining below the player with support, addressed reach misconceptions, and improved pathing performance. - **Event and Listener Management:** Simplified event listener cleanup with an `unsubscribe` approach and enhanced event-driven behaviors. - **Miscellaneous Improvements:** Fixed inventory crashes, clarified material categories, and optimized structure template discovery. --------- Co-authored-by: Edouard127 <46357922+Edouard127@users.noreply.github.com>
1 parent 393e846 commit f9b51ad

File tree

138 files changed

+3826
-1880
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

138 files changed

+3826
-1880
lines changed

build.gradle.kts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,20 @@
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+
118
import org.gradle.internal.jvm.*
219
import net.fabricmc.loom.api.LoomGradleExtensionAPI
320
import org.apache.tools.ant.taskdefs.condition.Os

common/src/main/java/com/lambda/mixin/MinecraftClientMixin.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
import com.lambda.Lambda;
2121
import com.lambda.event.EventFlow;
2222
import com.lambda.event.events.ClientEvent;
23-
import com.lambda.event.events.ScreenHandlerEvent;
23+
import com.lambda.event.events.InventoryEvent;
2424
import com.lambda.event.events.TickEvent;
2525
import com.lambda.module.modules.player.Interact;
2626
import net.minecraft.client.MinecraftClient;
@@ -78,15 +78,15 @@ private void onStartup(CallbackInfo ci) {
7878
private void onScreenOpen(@Nullable Screen screen, CallbackInfo ci) {
7979
if (screen == null) return;
8080
if (screen instanceof ScreenHandlerProvider<?> handledScreen) {
81-
EventFlow.post(new ScreenHandlerEvent.Open(handledScreen.getScreenHandler()));
81+
EventFlow.post(new InventoryEvent.Open(handledScreen.getScreenHandler()));
8282
}
8383
}
8484

8585
@Inject(method = "setScreen", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/Screen;removed()V", shift = At.Shift.AFTER))
8686
private void onScreenRemove(@Nullable Screen screen, CallbackInfo ci) {
8787
if (currentScreen == null) return;
8888
if (currentScreen instanceof ScreenHandlerProvider<?> handledScreen) {
89-
EventFlow.post(new ScreenHandlerEvent.Close(handledScreen.getScreenHandler()));
89+
EventFlow.post(new InventoryEvent.Close(handledScreen.getScreenHandler()));
9090
}
9191
}
9292

common/src/main/java/com/lambda/mixin/entity/ClientPlayInteractionManagerMixin.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,11 @@ public void interactItemHead(PlayerEntity player, Hand hand, CallbackInfoReturna
6666
}
6767
}
6868

69-
@Inject(method = "attackBlock", at = @At("HEAD"))
69+
@Inject(method = "attackBlock", at = @At("HEAD"), cancellable = true)
7070
public void onAttackBlock(BlockPos pos, Direction side, CallbackInfoReturnable<Boolean> cir) {
71-
if (EventFlow.post(new PlayerEvent.Attack.Block(pos, side)).isCanceled()) cir.cancel();
71+
if (EventFlow.post(new PlayerEvent.Attack.Block(pos, side)).isCanceled()) {
72+
cir.setReturnValue(false);
73+
}
7274
}
7375

7476
@Inject(method = "attackEntity", at = @At("HEAD"), cancellable = true)
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
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.mixin.network;
19+
20+
import com.lambda.event.EventFlow;
21+
import com.lambda.event.events.InventoryEvent;
22+
import net.minecraft.client.network.ClientPlayNetworkHandler;
23+
import net.minecraft.network.packet.s2c.play.ScreenHandlerSlotUpdateS2CPacket;
24+
import net.minecraft.network.packet.s2c.play.UpdateSelectedSlotS2CPacket;
25+
import org.spongepowered.asm.mixin.Mixin;
26+
import org.spongepowered.asm.mixin.injection.At;
27+
import org.spongepowered.asm.mixin.injection.Inject;
28+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
29+
30+
@Mixin(ClientPlayNetworkHandler.class)
31+
public class ClientPlayNetworkHandlerMixin {
32+
@Inject(method = "onUpdateSelectedSlot", at = @At(value = "TAIL"))
33+
private void onUpdateSelectedSlot(UpdateSelectedSlotS2CPacket packet, CallbackInfo ci) {
34+
EventFlow.post(new InventoryEvent.SelectedHotbarSlotUpdate(packet.getSlot()));
35+
}
36+
37+
@Inject(method = "onScreenHandlerSlotUpdate", at = @At(value = "TAIL"))
38+
private void onScreenHandlerSlotUpdate(ScreenHandlerSlotUpdateS2CPacket packet, CallbackInfo ci) {
39+
EventFlow.post(new InventoryEvent.SlotUpdate(packet.getSyncId(), packet.getRevision(), packet.getSlot(), packet.getStack()));
40+
}
41+
}

common/src/main/java/com/lambda/mixin/render/DebugHudMixin.java

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

1818
package com.lambda.mixin.render;
1919

20-
import com.lambda.task.RootTask;
20+
import com.lambda.task.TaskFlow;
2121
import com.lambda.util.DebugInfoHud;
2222
import net.minecraft.client.gui.hud.DebugHud;
2323
import org.spongepowered.asm.mixin.Mixin;
@@ -36,6 +36,6 @@ private void onGetRightText(CallbackInfoReturnable<List<String>> cir) {
3636

3737
@Inject(method = "getLeftText", at = @At(value = "TAIL"))
3838
private void onGetLeftText(CallbackInfoReturnable<List<String>> cir) {
39-
RootTask.INSTANCE.addInfo(cir.getReturnValue());
39+
cir.getReturnValue().addAll(List.of(TaskFlow.INSTANCE.toString().split("\n")));
4040
}
4141
}

common/src/main/java/com/lambda/mixin/render/ScreenHandlerMixin.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
package com.lambda.mixin.render;
1919

2020
import com.lambda.event.EventFlow;
21-
import com.lambda.event.events.ScreenHandlerEvent;
21+
import com.lambda.event.events.InventoryEvent;
2222
import net.minecraft.item.ItemStack;
2323
import net.minecraft.screen.ScreenHandler;
2424
import org.spongepowered.asm.mixin.Mixin;
@@ -32,6 +32,6 @@
3232
public class ScreenHandlerMixin {
3333
@Inject(method = "updateSlotStacks", at = @At("TAIL"))
3434
private void onUpdateSlotStacksHead(int revision, List<ItemStack> stacks, ItemStack cursorStack, CallbackInfo ci) {
35-
EventFlow.post(new ScreenHandlerEvent.Update(revision, stacks, cursorStack));
35+
EventFlow.post(new InventoryEvent.FullUpdate(revision, stacks, cursorStack));
3636
}
3737
}

common/src/main/java/com/lambda/mixin/world/ClientWorldMixin.java

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,6 @@
3434

3535
@Mixin(ClientWorld.class)
3636
public class ClientWorldMixin {
37-
@Inject(method = "handleBlockUpdate", at = @At("HEAD"), cancellable = true)
38-
private void handleBlockUpdateInject(BlockPos pos, BlockState state, int flags, CallbackInfo ci) {
39-
if (EventFlow.post(new WorldEvent.BlockUpdate(pos, state, flags)).isCanceled()) {
40-
ci.cancel();
41-
}
42-
}
43-
4437
@Inject(method = "addEntity", at = @At("HEAD"), cancellable = true)
4538
private void addEntity(Entity entity, CallbackInfo ci) {
4639
if (EventFlow.post(new WorldEvent.EntitySpawn(entity)).isCanceled()) ci.cancel();
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.mixin.world;
19+
20+
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
21+
import net.minecraft.block.Block;
22+
import net.minecraft.nbt.NbtCompound;
23+
import net.minecraft.registry.RegistryEntryLookup;
24+
import net.minecraft.structure.StructureTemplate;
25+
import org.spongepowered.asm.mixin.Mixin;
26+
import org.spongepowered.asm.mixin.Shadow;
27+
import org.spongepowered.asm.mixin.injection.At;
28+
import org.spongepowered.asm.mixin.injection.Inject;
29+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
30+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
31+
32+
import java.util.Objects;
33+
34+
@Mixin(StructureTemplate.class)
35+
public class StructureTemplateMixin {
36+
@Shadow
37+
private String author;
38+
39+
@ModifyReturnValue(method = "getAuthor()Ljava/lang/String;", at = @At("RETURN"))
40+
public String getAuthor(String original) {
41+
return Objects.equals(original, "?") || Objects.equals(original, "") ? "Unknown" : original;
42+
}
43+
44+
@Inject(method = "writeNbt(Lnet/minecraft/nbt/NbtCompound;)Lnet/minecraft/nbt/NbtCompound;", at = @At("TAIL"))
45+
public void writeNbt(NbtCompound nbt, CallbackInfoReturnable<NbtCompound> cir) {
46+
nbt.putString("author", author);
47+
}
48+
49+
@Inject(method = "readNbt(Lnet/minecraft/registry/RegistryEntryLookup;Lnet/minecraft/nbt/NbtCompound;)V", at = @At("TAIL"))
50+
public void readNbt(RegistryEntryLookup<Block> blockLookup, NbtCompound nbt, CallbackInfo ci) {
51+
author = nbt.getString("author");
52+
}
53+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
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.mixin.world;
19+
20+
import com.lambda.event.EventFlow;
21+
import com.lambda.event.events.WorldEvent;
22+
import net.minecraft.block.BlockState;
23+
import net.minecraft.util.math.BlockPos;
24+
import net.minecraft.world.World;
25+
import org.spongepowered.asm.mixin.Mixin;
26+
import org.spongepowered.asm.mixin.injection.At;
27+
import org.spongepowered.asm.mixin.injection.Inject;
28+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
29+
30+
@Mixin(World.class)
31+
public abstract class WorldMixin {
32+
@Inject(method = "onBlockChanged", at = @At("TAIL"))
33+
void onBlockChanged(BlockPos pos, BlockState oldBlock, BlockState newBlock, CallbackInfo ci) {
34+
EventFlow.post(new WorldEvent.BlockChange(pos, oldBlock, newBlock));
35+
}
36+
}

common/src/main/kotlin/com/lambda/command/commands/BuildCommand.kt

Lines changed: 42 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,24 @@
1717

1818
package com.lambda.command.commands
1919

20-
import com.lambda.brigadier.argument.literal
21-
import com.lambda.brigadier.execute
20+
import com.lambda.brigadier.CommandResult
21+
import com.lambda.brigadier.argument.*
22+
import com.lambda.brigadier.executeWithResult
23+
import com.lambda.brigadier.optional
2224
import com.lambda.brigadier.required
2325
import com.lambda.command.LambdaCommand
24-
import com.lambda.interaction.construction.Blueprint.Companion.toStructure
25-
import com.lambda.interaction.construction.DynamicBlueprint.Companion.toBlueprint
26-
import com.lambda.interaction.construction.verify.TargetState
26+
import com.lambda.interaction.construction.StructureRegistry
27+
import com.lambda.interaction.construction.blueprint.Blueprint.Companion.toStructure
28+
import com.lambda.interaction.construction.blueprint.StaticBlueprint.Companion.toBlueprint
29+
import com.lambda.task.TaskFlow.run
2730
import com.lambda.task.tasks.BuildTask.Companion.build
2831
import com.lambda.threading.runSafe
32+
import com.lambda.util.Communication.info
2933
import com.lambda.util.extension.CommandBuilder
30-
import net.minecraft.block.Blocks
31-
import net.minecraft.util.math.BlockBox
34+
import com.lambda.util.extension.move
35+
import java.nio.file.InvalidPathException
36+
import java.nio.file.NoSuchFileException
37+
import java.nio.file.Path
3238

3339
object BuildCommand : LambdaCommand(
3440
name = "Build",
@@ -37,26 +43,37 @@ object BuildCommand : LambdaCommand(
3743
) {
3844
override fun CommandBuilder.create() {
3945
required(literal("place")) {
40-
execute {
41-
runSafe {
42-
val materials = setOf(
43-
TargetState.Block(Blocks.NETHERRACK),
44-
TargetState.Block(Blocks.AIR),
45-
TargetState.Block(Blocks.COBBLESTONE),
46-
TargetState.Block(Blocks.AIR),
47-
)
48-
val facing = player.horizontalFacing
49-
val pos = player.blockPos.add(facing.vector.multiply(2))
46+
required(greedyString("structure")) { structure ->
47+
suggests { _, builder ->
48+
StructureRegistry.forEach { key, _ -> builder.suggest(key) }
49+
builder.buildFuture()
50+
}
51+
executeWithResult {
52+
val pathString = structure().value()
53+
runSafe<Unit> {
54+
try {
55+
StructureRegistry
56+
.loadStructureByRelativePath(Path.of(pathString))
57+
?.let { template ->
58+
info("Building structure $pathString with dimensions ${template.size.toShortString()} created by ${template.author}")
59+
template.toStructure()
60+
.move(player.blockPos)
61+
.toBlueprint()
62+
.build()
63+
.run()
5064

51-
BlockBox.create(pos, pos.add(facing.rotateYClockwise().vector.multiply(3)))
52-
.toStructure(TargetState.Block(Blocks.NETHERRACK))
53-
.toBlueprint {
54-
it.mapValues { (_, _) ->
55-
materials.elementAt((System.currentTimeMillis() / 5000).toInt() % materials.size)
56-
}
65+
return@executeWithResult CommandResult.success()
66+
}
67+
} catch (e: InvalidPathException) {
68+
return@executeWithResult CommandResult.failure("Invalid path $pathString")
69+
} catch (e: NoSuchFileException) {
70+
return@executeWithResult CommandResult.failure("Structure $pathString not found")
71+
} catch (e: Exception) {
72+
return@executeWithResult CommandResult.failure(e.message ?: "Failed to load structure $pathString")
5773
}
58-
.build(finishOnDone = false)
59-
.start(null)
74+
}
75+
76+
CommandResult.failure("Structure $pathString not found")
6077
}
6178
}
6279
}

0 commit comments

Comments
 (0)