Fixing golems
build / build (push) Successful in 2m42s

This commit is contained in:
Dynamitos
2025-10-26 14:23:07 +01:00
parent ba6bd0be35
commit 0b87d27579
2 changed files with 98 additions and 75 deletions
@@ -1,12 +1,17 @@
package com.dynamitos.mixin; package com.dynamitos.mixin;
import java.util.function.Predicate;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.dynamitos.Copperfarmers;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
import net.minecraft.block.entity.ChestBlockEntity;
import net.minecraft.entity.ai.brain.task.MoveItemsTask; import net.minecraft.entity.ai.brain.task.MoveItemsTask;
import net.minecraft.entity.passive.CopperGolemBrain; import net.minecraft.entity.passive.CopperGolemBrain;
import net.minecraft.entity.passive.CopperGolemEntity; import net.minecraft.entity.passive.CopperGolemEntity;
@@ -46,4 +51,15 @@ public abstract class CopperGolemBrainMixin {
} }
}); });
} }
@Inject(method = "createStoragePredicate", at = @At("HEAD"), cancellable = true)
private static void createStoragePredicate(CallbackInfoReturnable<Predicate<MoveItemsTask.Storage>> callbackInfo) {
callbackInfo.setReturnValue(storage -> {
if (storage.state().isOf(Blocks.FARMLAND)) {
Copperfarmers.LOGGER.debug("Storage predicate returning false for farmland at " + storage.pos());
return false;
}
return storage.blockEntity() instanceof ChestBlockEntity chestBlockEntity ? !chestBlockEntity.getViewingUsers().isEmpty() : false;
});
}
} }
@@ -34,6 +34,8 @@ import net.minecraft.world.World;
@Mixin(MoveItemsTask.class) @Mixin(MoveItemsTask.class)
public abstract class MoveItemsTaskMixin extends MultiTickTask<PathAwareEntity> { public abstract class MoveItemsTaskMixin extends MultiTickTask<PathAwareEntity> {
private MoveItemsTaskAccessor thisAccessor = (MoveItemsTaskAccessor) this;
public MoveItemsTaskMixin(Map<MemoryModuleType<?>, MemoryModuleState> requiredMemoryState) { public MoveItemsTaskMixin(Map<MemoryModuleType<?>, MemoryModuleState> requiredMemoryState) {
super(requiredMemoryState); super(requiredMemoryState);
// TODO Auto-generated constructor stub // TODO Auto-generated constructor stub
@@ -54,9 +56,10 @@ public abstract class MoveItemsTaskMixin extends MultiTickTask<PathAwareEntity>
var pos = new BlockPos(x, y, z); var pos = new BlockPos(x, y, z);
var blockState = world.getBlockState(pos); var blockState = world.getBlockState(pos);
// if block is farmland // if block is farmland
if(blockState.isOf(Blocks.FARMLAND) && world.isAir(pos.up())) { if (blockState.isOf(Blocks.FARMLAND) && world.isAir(pos.up())) {
Copperfarmers.LOGGER.debug("Found farmland at " + pos); Copperfarmers.LOGGER.debug("Found farmland at " + pos);
callbackInfo.setReturnValue(Optional.of(new MoveItemsTask.Storage(pos, null, null, blockState))); callbackInfo
.setReturnValue(Optional.of(new MoveItemsTask.Storage(pos, null, null, blockState)));
return; return;
} }
} }
@@ -67,67 +70,71 @@ public abstract class MoveItemsTaskMixin extends MultiTickTask<PathAwareEntity>
@Inject(method = "testContainer", at = @At("HEAD"), cancellable = true) @Inject(method = "testContainer", at = @At("HEAD"), cancellable = true)
private void testContainer(PathAwareEntity entity, BlockState state, CallbackInfoReturnable<Boolean> callbackInfo) { private void testContainer(PathAwareEntity entity, BlockState state, CallbackInfoReturnable<Boolean> callbackInfo) {
Copperfarmers.LOGGER.debug("Wrapped testContainer called"); Copperfarmers.LOGGER.debug("Wrapped testContainer called");
if(state.isOf(Blocks.FARMLAND)) { if (!MoveItemsTaskAccessor.copperfarmers$canPickUpItem(entity) && state.isOf(Blocks.FARMLAND)) {
Copperfarmers.LOGGER.debug("testContainer returning true for farmland");
callbackInfo.setReturnValue(true); callbackInfo.setReturnValue(true);
} }
} }
@Inject(method = "tickInteracting", at = @At("HEAD"), cancellable = true) @Inject(method = "tickInteracting", at = @At("HEAD"), cancellable = true)
private void tickInteracting(MoveItemsTask.Storage storage, World world, PathAwareEntity entity, CallbackInfo callbackInfo) { private void tickInteracting(MoveItemsTask.Storage storage, World world, PathAwareEntity entity,
CallbackInfo callbackInfo) {
Copperfarmers.LOGGER.debug("Wrapped tickInteracting called"); Copperfarmers.LOGGER.debug("Wrapped tickInteracting called");
MoveItemsTaskAccessor thisAccessor = (MoveItemsTaskAccessor)this; if (!thisAccessor.copperfarmers$isWithinRange(2.0, storage, world, entity,
if (!thisAccessor.copperfarmers$isWithinRange(2.0, storage, world, entity, thisAccessor.copperfarmers$atCenterY(entity))) { thisAccessor.copperfarmers$atCenterY(entity))) {
thisAccessor.copperfarmers$transitionToTravelling(entity); thisAccessor.copperfarmers$transitionToTravelling(entity);
} else { } else {
thisAccessor.copperfarmers$setInteractionTicks(thisAccessor.copperfarmers$getInteractionTicks() + 1); thisAccessor.copperfarmers$setInteractionTicks(thisAccessor.copperfarmers$getInteractionTicks() + 1);
thisAccessor.copperfarmers$setLookTarget(storage, entity); thisAccessor.copperfarmers$setLookTarget(storage, entity);
Copperfarmers.LOGGER.debug("Interaction ticks: " + thisAccessor.copperfarmers$getInteractionTicks()); Copperfarmers.LOGGER.debug("Interaction ticks: " + thisAccessor.copperfarmers$getInteractionTicks());
if (thisAccessor.copperfarmers$getInteractionTicks() >= 60) { if (thisAccessor.copperfarmers$getInteractionTicks() >= 60) {
Copperfarmers.LOGGER.debug("Interacting with storage at " + storage.pos()); Copperfarmers.LOGGER.debug("Interacting with storage at " + storage.pos());
this.selectInteractionState2( this.selectInteractionState2(
entity, entity,
storage, storage,
this::takeStack2, this::takeStack2,
(entityxx, inventory) -> thisAccessor.copperfarmers$invalidateTargetStorage(entity), (entityxx, inventory) -> thisAccessor.copperfarmers$invalidateTargetStorage(entity),
this::placeStack2, this::placeStack2,
(entityxx, inventory) -> thisAccessor.copperfarmers$invalidateTargetStorage(entity) (entityxx, inventory) -> thisAccessor.copperfarmers$invalidateTargetStorage(entity));
); thisAccessor.copperfarmers$transitionToTravelling(entity);
thisAccessor.copperfarmers$transitionToTravelling(entity); }
} }
}
callbackInfo.cancel(); callbackInfo.cancel();
} }
@Inject(method = "transitionToInteracting", at = @At("HEAD"), cancellable = true) @Inject(method = "transitionToInteracting", at = @At("HEAD"), cancellable = true)
private void transitionToInteracting(MoveItemsTask.Storage storage, PathAwareEntity entity, CallbackInfo callbackInfo) { private void transitionToInteracting(MoveItemsTask.Storage storage, PathAwareEntity entity,
CallbackInfo callbackInfo) {
Copperfarmers.LOGGER.debug("Wrapped transitionToInteracting called"); Copperfarmers.LOGGER.debug("Wrapped transitionToInteracting called");
this.selectInteractionState2( this.selectInteractionState2(
entity, entity,
storage, storage,
this.createSetInteractionStateCallback2(MoveItemsTask.InteractionState.PICKUP_ITEM), this.createSetInteractionStateCallback2(MoveItemsTask.InteractionState.PICKUP_ITEM),
this.createSetInteractionStateCallback2(MoveItemsTask.InteractionState.PICKUP_NO_ITEM), this.createSetInteractionStateCallback2(MoveItemsTask.InteractionState.PICKUP_NO_ITEM),
this.createSetInteractionStateCallback2(MoveItemsTask.InteractionState.PLACE_ITEM), this.createSetInteractionStateCallback2(MoveItemsTask.InteractionState.PLACE_ITEM),
this.createSetInteractionStateCallback2(MoveItemsTask.InteractionState.PLACE_NO_ITEM) this.createSetInteractionStateCallback2(MoveItemsTask.InteractionState.PLACE_NO_ITEM));
); thisAccessor.copperfarmers$setNavigationState(MoveItemsTask.NavigationState.INTERACTING);
((MoveItemsTaskAccessor)this).copperfarmers$setNavigationState(MoveItemsTask.NavigationState.INTERACTING);
callbackInfo.cancel(); callbackInfo.cancel();
} }
@Inject(method = "isUnchanged", at = @At("HEAD"), cancellable = true) @Inject(method = "isUnchanged", at = @At("HEAD"), cancellable = true)
private void isUnchanged(World world, MoveItemsTask.Storage storage, CallbackInfoReturnable<Boolean> callbackInfo) { private void isUnchanged(World world, MoveItemsTask.Storage storage, CallbackInfoReturnable<Boolean> callbackInfo) {
Copperfarmers.LOGGER.debug("Wrapped isUnchanged called"); Copperfarmers.LOGGER.debug("Wrapped isUnchanged called");
if(storage.state().isOf(Blocks.FARMLAND) && world.isAir(storage.pos().up())) { if (storage.state().isOf(Blocks.FARMLAND) && world.isAir(storage.pos().up())) {
Copperfarmers.LOGGER.debug("isUnchanged returning true for farmland at " + storage.pos());
callbackInfo.setReturnValue(true); callbackInfo.setReturnValue(true);
return;
} }
if(storage.inventory() == null) { Copperfarmers.LOGGER.debug("Storage state: " + storage.state() + " isAir: " + world.isAir(storage.pos().up()));
Copperfarmers.LOGGER.debug("No inventory at " + storage.pos()); if (storage.blockEntity() == null) {
Copperfarmers.LOGGER.debug("No blockentity " + storage.pos());
callbackInfo.setReturnValue(false); callbackInfo.setReturnValue(false);
return;
} }
} }
private void placeStack2(PathAwareEntity entity, MoveItemsTask.Storage storage) { private void placeStack2(PathAwareEntity entity, MoveItemsTask.Storage storage) {
Copperfarmers.LOGGER.debug("Wrapped placeStack called"); Copperfarmers.LOGGER.debug("Wrapped placeStack called");
MoveItemsTaskAccessor thisAccessor = (MoveItemsTaskAccessor)this;
BlockPos pos = storage.pos(); BlockPos pos = storage.pos();
ServerWorld world = (ServerWorld) entity.getEntityWorld(); ServerWorld world = (ServerWorld) entity.getEntityWorld();
if (world.getBlockState(pos).isOf(Blocks.FARMLAND) && world.isAir(pos.up()) if (world.getBlockState(pos).isOf(Blocks.FARMLAND) && world.isAir(pos.up())
@@ -142,55 +149,55 @@ public abstract class MoveItemsTaskMixin extends MultiTickTask<PathAwareEntity>
Copperfarmers.LOGGER.debug("Placed wheat seeds at " + pos.up()); Copperfarmers.LOGGER.debug("Placed wheat seeds at " + pos.up());
return; return;
} }
if(storage.inventory() == null) { if (storage.inventory() == null) {
Copperfarmers.LOGGER.debug("No inventory to place items into at " + pos); Copperfarmers.LOGGER.debug("No inventory to place items into at " + pos);
return; return;
} }
ItemStack itemStack = MoveItemsTaskAccessor.copperfarmers$insertStack(entity, storage.inventory()); ItemStack itemStack = MoveItemsTaskAccessor.copperfarmers$insertStack(entity, storage.inventory());
storage.inventory().markDirty(); storage.inventory().markDirty();
entity.equipStack(EquipmentSlot.MAINHAND, itemStack); entity.equipStack(EquipmentSlot.MAINHAND, itemStack);
if (itemStack.isEmpty()) { if (itemStack.isEmpty()) {
thisAccessor.copperfarmers$resetVisitedPositions(entity); thisAccessor.copperfarmers$resetVisitedPositions(entity);
} else { } else {
thisAccessor.copperfarmers$invalidateTargetStorage(entity); thisAccessor.copperfarmers$invalidateTargetStorage(entity);
} }
} }
private void takeStack2(PathAwareEntity entity, MoveItemsTask.Storage storage) { private void takeStack2(PathAwareEntity entity, MoveItemsTask.Storage storage) {
MoveItemsTaskAccessor thisAccessor = (MoveItemsTaskAccessor)this; entity.equipStack(EquipmentSlot.MAINHAND,
entity.equipStack(EquipmentSlot.MAINHAND, MoveItemsTaskAccessor.copperfarmers$extractStack(storage.inventory())); MoveItemsTaskAccessor.copperfarmers$extractStack(storage.inventory()));
entity.setDropGuaranteed(EquipmentSlot.MAINHAND); entity.setDropGuaranteed(EquipmentSlot.MAINHAND);
storage.inventory().markDirty(); storage.inventory().markDirty();
thisAccessor.copperfarmers$resetVisitedPositions(entity); thisAccessor.copperfarmers$resetVisitedPositions(entity);
} }
private void selectInteractionState2( private void selectInteractionState2(
PathAwareEntity entity, PathAwareEntity entity,
MoveItemsTask.Storage storage, MoveItemsTask.Storage storage,
BiConsumer<PathAwareEntity, MoveItemsTask.Storage> pickupItemCallback, BiConsumer<PathAwareEntity, MoveItemsTask.Storage> pickupItemCallback,
BiConsumer<PathAwareEntity, MoveItemsTask.Storage> pickupNoItemCallback, BiConsumer<PathAwareEntity, MoveItemsTask.Storage> pickupNoItemCallback,
BiConsumer<PathAwareEntity, MoveItemsTask.Storage> placeItemCallback, BiConsumer<PathAwareEntity, MoveItemsTask.Storage> placeItemCallback,
BiConsumer<PathAwareEntity, MoveItemsTask.Storage> placeNoItemCallback) BiConsumer<PathAwareEntity, MoveItemsTask.Storage> placeNoItemCallback) {
{
Copperfarmers.LOGGER.debug("Wrapped selectInteractionState called"); Copperfarmers.LOGGER.debug("Wrapped selectInteractionState called");
if (storage == null && entity.getEquippedStack(EquipmentSlot.MAINHAND).isOf(Items.WHEAT_SEEDS)) { if (storage == null && entity.getEquippedStack(EquipmentSlot.MAINHAND).isOf(Items.WHEAT_SEEDS)) {
placeItemCallback.accept(entity, storage); placeItemCallback.accept(entity, storage);
} }
if (MoveItemsTaskAccessor.copperfarmers$canPickUpItem(entity)) { if (MoveItemsTaskAccessor.copperfarmers$canPickUpItem(entity)) {
if (MoveItemsTaskAccessor.copperfarmers$hasItem(storage.inventory())) { if (MoveItemsTaskAccessor.copperfarmers$hasItem(storage.inventory())) {
pickupItemCallback.accept(entity, storage); pickupItemCallback.accept(entity, storage);
} else { } else {
pickupNoItemCallback.accept(entity, storage); pickupNoItemCallback.accept(entity, storage);
} }
} else if (storage.state().isOf(Blocks.FARMLAND) } else if (storage.state().isOf(Blocks.FARMLAND)
|| MoveItemsTaskAccessor.copperfarmers$canInsert(entity, storage.inventory())) { || MoveItemsTaskAccessor.copperfarmers$canInsert(entity, storage.inventory())) {
placeItemCallback.accept(entity, storage); placeItemCallback.accept(entity, storage);
} else { } else {
placeNoItemCallback.accept(entity, storage); placeNoItemCallback.accept(entity, storage);
} }
} }
private BiConsumer<PathAwareEntity, MoveItemsTask.Storage> createSetInteractionStateCallback2(MoveItemsTask.InteractionState state) { private BiConsumer<PathAwareEntity, MoveItemsTask.Storage> createSetInteractionStateCallback2(
return (entity, inventory) -> ((MoveItemsTaskAccessor)this).copperfarmers$setInteractionState(state); MoveItemsTask.InteractionState state) {
} return (entity, inventory) -> thisAccessor.copperfarmers$setInteractionState(state);
}
} }