Files
copper-farmers/src/main/java/com/dynamitos/mixin/MoveItemsTaskMixin.java
T

207 lines
10 KiB
Java
Raw Normal View History

2025-10-25 22:47:29 +02:00
package com.dynamitos.mixin;
import java.util.Map;
import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Predicate;
import org.spongepowered.asm.mixin.Debug;
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;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.dynamitos.Copperfarmers;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.ai.brain.MemoryModuleState;
import net.minecraft.entity.ai.brain.MemoryModuleType;
import net.minecraft.entity.ai.brain.task.MoveItemsTask;
import net.minecraft.entity.ai.brain.task.MultiTickTask;
import net.minecraft.entity.mob.PathAwareEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Box;
import net.minecraft.world.World;
@Mixin(MoveItemsTask.class)
public abstract class MoveItemsTaskMixin extends MultiTickTask<PathAwareEntity> {
2025-10-26 14:23:07 +01:00
private MoveItemsTaskAccessor thisAccessor = (MoveItemsTaskAccessor) this;
2025-10-25 22:47:29 +02:00
public MoveItemsTaskMixin(Map<MemoryModuleType<?>, MemoryModuleState> requiredMemoryState) {
super(requiredMemoryState);
// TODO Auto-generated constructor stub
}
@Inject(method = "findStorage", at = @At("HEAD"), cancellable = true)
private void findStorage(ServerWorld world, PathAwareEntity entity,
CallbackInfoReturnable<Optional<MoveItemsTask.Storage>> callbackInfo) {
2025-10-26 08:36:53 +01:00
Copperfarmers.LOGGER.debug("Wrapped findStorage called");
2025-10-25 22:47:29 +02:00
Box box = ((MoveItemsTaskAccessor) this).copperfarmers$getSearchBoundingBox(entity);
if (!entity.getEquippedStack(EquipmentSlot.MAINHAND).isOf(Items.WHEAT_SEEDS)) {
return;
}
2025-11-06 16:42:18 +00:00
for (int z = (int) box.minZ; z <= box.maxZ; z++) {
2025-10-25 22:47:29 +02:00
for (int y = (int) box.minY; y <= box.maxY; y++) {
2025-11-06 16:42:18 +00:00
for (int x = (int) box.minX; x <= box.maxX; x++) {
2025-10-25 22:47:29 +02:00
var pos = new BlockPos(x, y, z);
var blockState = world.getBlockState(pos);
// if block is farmland
2025-10-26 14:23:07 +01:00
if (blockState.isOf(Blocks.FARMLAND) && world.isAir(pos.up())) {
2025-10-26 08:36:53 +01:00
Copperfarmers.LOGGER.debug("Found farmland at " + pos);
2025-10-29 16:38:52 +01:00
if (Math.random() < 0.5) {
callbackInfo
.setReturnValue(
Optional.of(new MoveItemsTask.Storage(pos, null, null, blockState)));
return;
}
2025-10-25 22:47:29 +02:00
}
}
}
}
}
@Inject(method = "testContainer", at = @At("HEAD"), cancellable = true)
private void testContainer(PathAwareEntity entity, BlockState state, CallbackInfoReturnable<Boolean> callbackInfo) {
2025-10-26 08:36:53 +01:00
Copperfarmers.LOGGER.debug("Wrapped testContainer called");
2025-10-26 14:23:07 +01:00
if (!MoveItemsTaskAccessor.copperfarmers$canPickUpItem(entity) && state.isOf(Blocks.FARMLAND)) {
Copperfarmers.LOGGER.debug("testContainer returning true for farmland");
2025-10-25 22:47:29 +02:00
callbackInfo.setReturnValue(true);
}
}
@Inject(method = "tickInteracting", at = @At("HEAD"), cancellable = true)
2025-10-26 14:23:07 +01:00
private void tickInteracting(MoveItemsTask.Storage storage, World world, PathAwareEntity entity,
CallbackInfo callbackInfo) {
2025-10-26 08:36:53 +01:00
Copperfarmers.LOGGER.debug("Wrapped tickInteracting called");
2025-10-26 14:23:07 +01:00
if (!thisAccessor.copperfarmers$isWithinRange(2.0, storage, world, entity,
thisAccessor.copperfarmers$atCenterY(entity))) {
thisAccessor.copperfarmers$transitionToTravelling(entity);
} else {
thisAccessor.copperfarmers$setInteractionTicks(thisAccessor.copperfarmers$getInteractionTicks() + 1);
thisAccessor.copperfarmers$setLookTarget(storage, entity);
2025-10-26 08:36:53 +01:00
Copperfarmers.LOGGER.debug("Interaction ticks: " + thisAccessor.copperfarmers$getInteractionTicks());
2025-10-26 14:23:07 +01:00
if (thisAccessor.copperfarmers$getInteractionTicks() >= 60) {
2025-10-26 08:36:53 +01:00
Copperfarmers.LOGGER.debug("Interacting with storage at " + storage.pos());
2025-10-26 14:23:07 +01:00
this.selectInteractionState2(
entity,
storage,
this::takeStack2,
(entityxx, inventory) -> thisAccessor.copperfarmers$invalidateTargetStorage(entity),
this::placeStack2,
(entityxx, inventory) -> thisAccessor.copperfarmers$invalidateTargetStorage(entity));
thisAccessor.copperfarmers$transitionToTravelling(entity);
}
}
2025-10-25 22:47:29 +02:00
callbackInfo.cancel();
}
@Inject(method = "transitionToInteracting", at = @At("HEAD"), cancellable = true)
2025-10-26 14:23:07 +01:00
private void transitionToInteracting(MoveItemsTask.Storage storage, PathAwareEntity entity,
CallbackInfo callbackInfo) {
2025-10-26 08:36:53 +01:00
Copperfarmers.LOGGER.debug("Wrapped transitionToInteracting called");
2025-10-26 14:23:07 +01:00
this.selectInteractionState2(
entity,
storage,
this.createSetInteractionStateCallback2(MoveItemsTask.InteractionState.PICKUP_ITEM),
this.createSetInteractionStateCallback2(MoveItemsTask.InteractionState.PICKUP_NO_ITEM),
this.createSetInteractionStateCallback2(MoveItemsTask.InteractionState.PLACE_ITEM),
this.createSetInteractionStateCallback2(MoveItemsTask.InteractionState.PLACE_NO_ITEM));
thisAccessor.copperfarmers$setNavigationState(MoveItemsTask.NavigationState.INTERACTING);
2025-10-25 22:47:29 +02:00
callbackInfo.cancel();
}
@Inject(method = "isUnchanged", at = @At("HEAD"), cancellable = true)
private void isUnchanged(World world, MoveItemsTask.Storage storage, CallbackInfoReturnable<Boolean> callbackInfo) {
2025-10-26 08:36:53 +01:00
Copperfarmers.LOGGER.debug("Wrapped isUnchanged called");
2025-10-26 14:23:07 +01:00
if (storage.state().isOf(Blocks.FARMLAND) && world.isAir(storage.pos().up())) {
Copperfarmers.LOGGER.debug("isUnchanged returning true for farmland at " + storage.pos());
2025-10-25 22:47:29 +02:00
callbackInfo.setReturnValue(true);
2025-10-26 14:23:07 +01:00
return;
2025-10-25 22:47:29 +02:00
}
2025-10-26 14:23:07 +01:00
Copperfarmers.LOGGER.debug("Storage state: " + storage.state() + " isAir: " + world.isAir(storage.pos().up()));
if (storage.blockEntity() == null) {
Copperfarmers.LOGGER.debug("No blockentity " + storage.pos());
callbackInfo.setReturnValue(false);
2025-10-26 14:23:07 +01:00
return;
}
2025-10-25 22:47:29 +02:00
}
private void placeStack2(PathAwareEntity entity, MoveItemsTask.Storage storage) {
2025-10-26 08:36:53 +01:00
Copperfarmers.LOGGER.debug("Wrapped placeStack called");
2025-10-25 22:47:29 +02:00
BlockPos pos = storage.pos();
ServerWorld world = (ServerWorld) entity.getEntityWorld();
if (world.getBlockState(pos).isOf(Blocks.FARMLAND) && world.isAir(pos.up())
&& entity.getEquippedStack(EquipmentSlot.MAINHAND).isOf(Items.WHEAT_SEEDS)) {
world.setBlockState(pos.up(), Blocks.WHEAT.getDefaultState());
entity.getEquippedStack(EquipmentSlot.MAINHAND).decrement(1);
if (entity.getEquippedStack(EquipmentSlot.MAINHAND).isEmpty()) {
thisAccessor.copperfarmers$resetVisitedPositions(entity);
} else {
thisAccessor.copperfarmers$invalidateTargetStorage(entity);
}
2025-10-26 08:36:53 +01:00
Copperfarmers.LOGGER.debug("Placed wheat seeds at " + pos.up());
2025-10-25 22:47:29 +02:00
return;
2025-10-26 10:20:17 +01:00
}
2025-10-26 14:23:07 +01:00
if (storage.inventory() == null) {
2025-10-26 10:20:17 +01:00
Copperfarmers.LOGGER.debug("No inventory to place items into at " + pos);
return;
2025-10-25 22:47:29 +02:00
}
2025-10-26 14:23:07 +01:00
ItemStack itemStack = MoveItemsTaskAccessor.copperfarmers$insertStack(entity, storage.inventory());
storage.inventory().markDirty();
entity.equipStack(EquipmentSlot.MAINHAND, itemStack);
if (itemStack.isEmpty()) {
thisAccessor.copperfarmers$resetVisitedPositions(entity);
} else {
thisAccessor.copperfarmers$invalidateTargetStorage(entity);
}
2025-10-25 22:47:29 +02:00
}
2025-10-26 14:23:07 +01:00
private void takeStack2(PathAwareEntity entity, MoveItemsTask.Storage storage) {
entity.equipStack(EquipmentSlot.MAINHAND,
MoveItemsTaskAccessor.copperfarmers$extractStack(storage.inventory()));
entity.setDropGuaranteed(EquipmentSlot.MAINHAND);
storage.inventory().markDirty();
thisAccessor.copperfarmers$resetVisitedPositions(entity);
}
2025-10-25 22:47:29 +02:00
private void selectInteractionState2(
2025-10-26 14:23:07 +01:00
PathAwareEntity entity,
MoveItemsTask.Storage storage,
BiConsumer<PathAwareEntity, MoveItemsTask.Storage> pickupItemCallback,
BiConsumer<PathAwareEntity, MoveItemsTask.Storage> pickupNoItemCallback,
BiConsumer<PathAwareEntity, MoveItemsTask.Storage> placeItemCallback,
BiConsumer<PathAwareEntity, MoveItemsTask.Storage> placeNoItemCallback) {
2025-10-26 08:36:53 +01:00
Copperfarmers.LOGGER.debug("Wrapped selectInteractionState called");
2025-10-25 22:47:29 +02:00
if (storage == null && entity.getEquippedStack(EquipmentSlot.MAINHAND).isOf(Items.WHEAT_SEEDS)) {
placeItemCallback.accept(entity, storage);
}
2025-10-26 14:23:07 +01:00
if (MoveItemsTaskAccessor.copperfarmers$canPickUpItem(entity)) {
if (MoveItemsTaskAccessor.copperfarmers$hasItem(storage.inventory())) {
pickupItemCallback.accept(entity, storage);
} else {
pickupNoItemCallback.accept(entity, storage);
}
} else if (storage.state().isOf(Blocks.FARMLAND)
2025-10-25 22:47:29 +02:00
|| MoveItemsTaskAccessor.copperfarmers$canInsert(entity, storage.inventory())) {
2025-10-26 14:23:07 +01:00
placeItemCallback.accept(entity, storage);
} else {
placeNoItemCallback.accept(entity, storage);
}
}
private BiConsumer<PathAwareEntity, MoveItemsTask.Storage> createSetInteractionStateCallback2(
MoveItemsTask.InteractionState state) {
return (entity, inventory) -> thisAccessor.copperfarmers$setInteractionState(state);
2025-10-25 22:47:29 +02:00
}
}