Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
0944e8d
Fix reach misconceptions and inventory crash
Avanatiker Sep 30, 2024
b0892a3
Faster pathing
Avanatiker Sep 30, 2024
d15a366
Only allow ignoring blocks when they are in airspace
Avanatiker Sep 30, 2024
462f2e7
Fix collecting items
Avanatiker Oct 1, 2024
720c120
Added WorldEater
Avanatiker Oct 1, 2024
87e30a3
Allow mining below player if support is provided
Avanatiker Oct 1, 2024
deebe22
Merge branch 'master' into feature/taskflow
Avanatiker Oct 5, 2024
e5f4256
Merge branch 'master' into feature/taskflow
Avanatiker Oct 6, 2024
094c874
More dynamic configuration of the highway
Avanatiker Oct 7, 2024
1a44be4
Less confusing material category
Avanatiker Oct 7, 2024
550873e
Merge branch 'master' into feature/taskflow
Avanatiker Oct 8, 2024
ecb0418
Loading NBT structure files per command
Avanatiker Oct 9, 2024
7eacafc
feat: StructureRegistry
emyfops Oct 10, 2024
94efb70
Proper structure template file discovery
Avanatiker Oct 11, 2024
6ff5083
Ignore unobtainable block properties
Avanatiker Oct 11, 2024
7a77cc8
Sneak when placing onto interaction blocks
Avanatiker Oct 11, 2024
50bdef8
ToDo reminder for HALF properties
Avanatiker Oct 11, 2024
e0416a7
Merge branch 'master' into feature/taskflow
Avanatiker Oct 19, 2024
55ef7d3
Support for half slab building
Avanatiker Oct 19, 2024
fe691b1
Merge remote-tracking branch 'origin/master' into feature/taskflow
Avanatiker Oct 20, 2024
670324f
Restructure
Avanatiker Oct 20, 2024
0317cde
ref!: structure loader, management and conversion
emyfops Nov 10, 2024
437f9e9
grammar
emyfops Nov 10, 2024
466f3f3
Cleanup
Avanatiker Nov 10, 2024
a0ade28
Relative structure paths support
Avanatiker Nov 10, 2024
076e2c2
Some fixes
Avanatiker Nov 10, 2024
a9c5e30
fix: schem palette ordering
emyfops Nov 10, 2024
f28dd62
Merge and update copyright
Avanatiker Nov 11, 2024
1adbf71
Merge with master
Avanatiker Dec 14, 2024
468c355
Forcing horizontal rotation, placement preprocessor, lots of fixes
Avanatiker Dec 15, 2024
d91811f
Fix format
Avanatiker Dec 16, 2024
a5ea17c
Refactor Task system for enhanced flexibility and clarity
Avanatiker Dec 23, 2024
5cfdbac
Refactor block interaction logic to use expected positions
Avanatiker Dec 28, 2024
e68b215
Refactor task resolution and task nesting complexity
Avanatiker Dec 28, 2024
d0a1902
Refactor processor API and add Axis/BlockFace processors
Avanatiker Dec 30, 2024
9e0ba5a
Refactor placement handling in BuildTask implementation
Avanatiker Dec 30, 2024
7d8e384
Refactor inventory system configuration to enhance material handling.
Avanatiker Dec 30, 2024
ecd23e4
Refactor inventory and container structure
Avanatiker Dec 30, 2024
c14bd87
Refactor inventory and build configurations
Avanatiker Dec 30, 2024
653e71c
Proper drop collection
Avanatiker Dec 30, 2024
18c373b
Refactor rotation handling and placement logic
Avanatiker Dec 31, 2024
1de3f6f
Rework initialization logging
Avanatiker Jan 1, 2025
3442d57
Refactor event listener management in Task and EventFlow
Avanatiker Jan 1, 2025
cc8408a
Refactor inventory handling and transaction structure.
Avanatiker Jan 1, 2025
3a6f612
Merge branch 'master' into feature/taskflow
Avanatiker Jan 1, 2025
34b3fb1
Merge branch 'master' into feature/taskflow
Avanatiker Jan 1, 2025
573b69c
Clean up InventoryEvents
Avanatiker Jan 2, 2025
7a10323
Refactor rotation management and add Ender Chest access config.
Avanatiker Jan 2, 2025
72b99cb
Merge branch 'master' into feature/taskflow
Avanatiker Jan 2, 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
17 changes: 17 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
/*
* 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/>.
*/

import org.gradle.internal.jvm.*
import net.fabricmc.loom.api.LoomGradleExtensionAPI
import org.apache.tools.ant.taskdefs.condition.Os
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import com.lambda.Lambda;
import com.lambda.event.EventFlow;
import com.lambda.event.events.ClientEvent;
import com.lambda.event.events.ScreenHandlerEvent;
import com.lambda.event.events.InventoryEvent;
import com.lambda.event.events.TickEvent;
import com.lambda.module.modules.player.Interact;
import net.minecraft.client.MinecraftClient;
Expand Down Expand Up @@ -78,15 +78,15 @@ private void onStartup(CallbackInfo ci) {
private void onScreenOpen(@Nullable Screen screen, CallbackInfo ci) {
if (screen == null) return;
if (screen instanceof ScreenHandlerProvider<?> handledScreen) {
EventFlow.post(new ScreenHandlerEvent.Open(handledScreen.getScreenHandler()));
EventFlow.post(new InventoryEvent.Open(handledScreen.getScreenHandler()));
}
}

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,11 @@ public void interactItemHead(PlayerEntity player, Hand hand, CallbackInfoReturna
}
}

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

@Inject(method = "attackEntity", at = @At("HEAD"), cancellable = true)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* 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.mixin.network;

import com.lambda.event.EventFlow;
import com.lambda.event.events.InventoryEvent;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.network.packet.s2c.play.ScreenHandlerSlotUpdateS2CPacket;
import net.minecraft.network.packet.s2c.play.UpdateSelectedSlotS2CPacket;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(ClientPlayNetworkHandler.class)
public class ClientPlayNetworkHandlerMixin {
@Inject(method = "onUpdateSelectedSlot", at = @At(value = "TAIL"))
private void onUpdateSelectedSlot(UpdateSelectedSlotS2CPacket packet, CallbackInfo ci) {
EventFlow.post(new InventoryEvent.SelectedHotbarSlotUpdate(packet.getSlot()));
}

@Inject(method = "onScreenHandlerSlotUpdate", at = @At(value = "TAIL"))
private void onScreenHandlerSlotUpdate(ScreenHandlerSlotUpdateS2CPacket packet, CallbackInfo ci) {
EventFlow.post(new InventoryEvent.SlotUpdate(packet.getSyncId(), packet.getRevision(), packet.getSlot(), packet.getStack()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

package com.lambda.mixin.render;

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

@Inject(method = "getLeftText", at = @At(value = "TAIL"))
private void onGetLeftText(CallbackInfoReturnable<List<String>> cir) {
RootTask.INSTANCE.addInfo(cir.getReturnValue());
cir.getReturnValue().addAll(List.of(TaskFlow.INSTANCE.toString().split("\n")));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
package com.lambda.mixin.render;

import com.lambda.event.EventFlow;
import com.lambda.event.events.ScreenHandlerEvent;
import com.lambda.event.events.InventoryEvent;
import net.minecraft.item.ItemStack;
import net.minecraft.screen.ScreenHandler;
import org.spongepowered.asm.mixin.Mixin;
Expand All @@ -32,6 +32,6 @@
public class ScreenHandlerMixin {
@Inject(method = "updateSlotStacks", at = @At("TAIL"))
private void onUpdateSlotStacksHead(int revision, List<ItemStack> stacks, ItemStack cursorStack, CallbackInfo ci) {
EventFlow.post(new ScreenHandlerEvent.Update(revision, stacks, cursorStack));
EventFlow.post(new InventoryEvent.FullUpdate(revision, stacks, cursorStack));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,6 @@

@Mixin(ClientWorld.class)
public class ClientWorldMixin {
@Inject(method = "handleBlockUpdate", at = @At("HEAD"), cancellable = true)
private void handleBlockUpdateInject(BlockPos pos, BlockState state, int flags, CallbackInfo ci) {
if (EventFlow.post(new WorldEvent.BlockUpdate(pos, state, flags)).isCanceled()) {
ci.cancel();
}
}

@Inject(method = "addEntity", at = @At("HEAD"), cancellable = true)
private void addEntity(Entity entity, CallbackInfo ci) {
if (EventFlow.post(new WorldEvent.EntitySpawn(entity)).isCanceled()) ci.cancel();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* 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.mixin.world;

import com.llamalad7.mixinextras.injector.ModifyReturnValue;
import net.minecraft.block.Block;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.registry.RegistryEntryLookup;
import net.minecraft.structure.StructureTemplate;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

import java.util.Objects;

@Mixin(StructureTemplate.class)
public class StructureTemplateMixin {
@Shadow
private String author;

@ModifyReturnValue(method = "getAuthor()Ljava/lang/String;", at = @At("RETURN"))
public String getAuthor(String original) {
return Objects.equals(original, "?") || Objects.equals(original, "") ? "Unknown" : original;
}

@Inject(method = "writeNbt(Lnet/minecraft/nbt/NbtCompound;)Lnet/minecraft/nbt/NbtCompound;", at = @At("TAIL"))
public void writeNbt(NbtCompound nbt, CallbackInfoReturnable<NbtCompound> cir) {
nbt.putString("author", author);
}

@Inject(method = "readNbt(Lnet/minecraft/registry/RegistryEntryLookup;Lnet/minecraft/nbt/NbtCompound;)V", at = @At("TAIL"))
public void readNbt(RegistryEntryLookup<Block> blockLookup, NbtCompound nbt, CallbackInfo ci) {
author = nbt.getString("author");
}
}
36 changes: 36 additions & 0 deletions common/src/main/java/com/lambda/mixin/world/WorldMixin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* 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.mixin.world;

import com.lambda.event.EventFlow;
import com.lambda.event.events.WorldEvent;
import net.minecraft.block.BlockState;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(World.class)
public abstract class WorldMixin {
@Inject(method = "onBlockChanged", at = @At("TAIL"))
void onBlockChanged(BlockPos pos, BlockState oldBlock, BlockState newBlock, CallbackInfo ci) {
EventFlow.post(new WorldEvent.BlockChange(pos, oldBlock, newBlock));
}
}
67 changes: 42 additions & 25 deletions common/src/main/kotlin/com/lambda/command/commands/BuildCommand.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,24 @@

package com.lambda.command.commands

import com.lambda.brigadier.argument.literal
import com.lambda.brigadier.execute
import com.lambda.brigadier.CommandResult
import com.lambda.brigadier.argument.*
import com.lambda.brigadier.executeWithResult
import com.lambda.brigadier.optional
import com.lambda.brigadier.required
import com.lambda.command.LambdaCommand
import com.lambda.interaction.construction.Blueprint.Companion.toStructure
import com.lambda.interaction.construction.DynamicBlueprint.Companion.toBlueprint
import com.lambda.interaction.construction.verify.TargetState
import com.lambda.interaction.construction.StructureRegistry
import com.lambda.interaction.construction.blueprint.Blueprint.Companion.toStructure
import com.lambda.interaction.construction.blueprint.StaticBlueprint.Companion.toBlueprint
import com.lambda.task.TaskFlow.run
import com.lambda.task.tasks.BuildTask.Companion.build
import com.lambda.threading.runSafe
import com.lambda.util.Communication.info
import com.lambda.util.extension.CommandBuilder
import net.minecraft.block.Blocks
import net.minecraft.util.math.BlockBox
import com.lambda.util.extension.move
import java.nio.file.InvalidPathException
import java.nio.file.NoSuchFileException
import java.nio.file.Path

object BuildCommand : LambdaCommand(
name = "Build",
Expand All @@ -37,26 +43,37 @@ object BuildCommand : LambdaCommand(
) {
override fun CommandBuilder.create() {
required(literal("place")) {
execute {
runSafe {
val materials = setOf(
TargetState.Block(Blocks.NETHERRACK),
TargetState.Block(Blocks.AIR),
TargetState.Block(Blocks.COBBLESTONE),
TargetState.Block(Blocks.AIR),
)
val facing = player.horizontalFacing
val pos = player.blockPos.add(facing.vector.multiply(2))
required(greedyString("structure")) { structure ->
suggests { _, builder ->
StructureRegistry.forEach { key, _ -> builder.suggest(key) }
builder.buildFuture()
}
executeWithResult {
val pathString = structure().value()
runSafe<Unit> {
try {
StructureRegistry
.loadStructureByRelativePath(Path.of(pathString))
?.let { template ->
info("Building structure $pathString with dimensions ${template.size.toShortString()} created by ${template.author}")
template.toStructure()
.move(player.blockPos)
.toBlueprint()
.build()
.run()

BlockBox.create(pos, pos.add(facing.rotateYClockwise().vector.multiply(3)))
.toStructure(TargetState.Block(Blocks.NETHERRACK))
.toBlueprint {
it.mapValues { (_, _) ->
materials.elementAt((System.currentTimeMillis() / 5000).toInt() % materials.size)
}
return@executeWithResult CommandResult.success()
}
} catch (e: InvalidPathException) {
return@executeWithResult CommandResult.failure("Invalid path $pathString")
} catch (e: NoSuchFileException) {
return@executeWithResult CommandResult.failure("Structure $pathString not found")
} catch (e: Exception) {
return@executeWithResult CommandResult.failure(e.message ?: "Failed to load structure $pathString")
}
.build(finishOnDone = false)
.start(null)
}

CommandResult.failure("Structure $pathString not found")
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import com.lambda.module.modules.player.Replay
import com.lambda.util.FolderRegister
import com.lambda.util.FolderRegister.listRecursive
import com.lambda.util.extension.CommandBuilder
import kotlin.io.path.exists

object ReplayCommand : LambdaCommand(
name = "replay",
Expand All @@ -48,7 +49,7 @@ object ReplayCommand : LambdaCommand(
required(literal("load")) {
required(greedyString("replay filepath")) { replayName ->
suggests { _, builder ->
val dir = FolderRegister.replay
val dir = FolderRegister.replay.toFile()
dir.listRecursive { it.isFile }.forEach {
builder.suggest(it.relativeTo(dir).path)
}
Expand All @@ -63,7 +64,7 @@ object ReplayCommand : LambdaCommand(
}

try {
Replay.loadRecording(replayFile)
Replay.loadRecording(replayFile.toFile())
} catch (e: JsonSyntaxException) {
return@executeWithResult CommandResult.failure("Failed to load replay file: ${e.message}")
}
Expand Down
14 changes: 11 additions & 3 deletions common/src/main/kotlin/com/lambda/command/commands/TaskCommand.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,28 @@ import com.lambda.brigadier.argument.literal
import com.lambda.brigadier.execute
import com.lambda.brigadier.required
import com.lambda.command.LambdaCommand
import com.lambda.task.RootTask
import com.lambda.task.TaskFlow
import com.lambda.util.Communication.info
import com.lambda.util.extension.CommandBuilder

object TaskCommand : LambdaCommand(
name = "task",
usage = "task <cancel>",
usage = "task <cancel|clear>",
description = "Control tasks"
) {
override fun CommandBuilder.create() {
required(literal("cancel")) {
execute {
this@TaskCommand.info("Cancelling all tasks")
RootTask.cancel()
TaskFlow.cancel()
}
}

required(literal("clear")) {
execute {
this@TaskCommand.info("Clearing all tasks")
TaskFlow.cancel()
TaskFlow.clear()
}
}
}
Expand Down
Loading
Loading