@@ -20,7 +20,7 @@ import net.minecraft.world.level.block.state.BlockState;
|
|||||||
@Mixin(targets = "net/minecraft/world/entity/animal/golem/CopperGolemAi")
|
@Mixin(targets = "net/minecraft/world/entity/animal/golem/CopperGolemAi")
|
||||||
public abstract class CopperGolemBehaviorHookMixin {
|
public abstract class CopperGolemBehaviorHookMixin {
|
||||||
|
|
||||||
public static void copperfarmers$handleFarmlandPlanting(
|
private static void copperfarmers$handleFarmlandPlanting(
|
||||||
CopperGolem golem, ServerLevel world, BlockPos pos, BlockState state) {
|
CopperGolem golem, ServerLevel world, BlockPos pos, BlockState state) {
|
||||||
|
|
||||||
BlockPos plantedAt = pos.above();
|
BlockPos plantedAt = pos.above();
|
||||||
@@ -34,7 +34,7 @@ public abstract class CopperGolemBehaviorHookMixin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void copperfarmers$handleFarmlandHarvesting(
|
private static void copperfarmers$handleFarmlandHarvesting(
|
||||||
CopperGolem golem, ServerLevel world, BlockPos pos, BlockState state) {
|
CopperGolem golem, ServerLevel world, BlockPos pos, BlockState state) {
|
||||||
|
|
||||||
BlockPos plantedAt = pos.above();
|
BlockPos plantedAt = pos.above();
|
||||||
@@ -52,7 +52,7 @@ public abstract class CopperGolemBehaviorHookMixin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean canPlantHere(ServerLevel world, BlockPos plantedAt) {
|
private static boolean canPlantHere(ServerLevel world, BlockPos plantedAt) {
|
||||||
BlockState above = world.getBlockState(plantedAt);
|
BlockState above = world.getBlockState(plantedAt);
|
||||||
return above.isAir() || true;
|
return above.isAir() || true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,32 +1,66 @@
|
|||||||
package com.dynamitos.mixin;
|
package com.dynamitos.mixin;
|
||||||
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
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.CopperFarmingRegistry;
|
import com.dynamitos.Copperfarmers;
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.world.level.block.Blocks;
|
import net.minecraft.world.level.block.Blocks;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.entity.PathfinderMob;
|
||||||
|
|
||||||
@Mixin(targets = "net/minecraft/world/entity/animal/golem/CopperGolemActivitySourcePredicate")
|
@Mixin(targets = "net/minecraft/world/entity/ai/behavior/TransportItemsBetweenContainers")
|
||||||
public abstract class FarmlandPredicateMixin {
|
public abstract class FarmlandPredicateMixin {
|
||||||
|
|
||||||
@Inject(method = "createStorageSourcePred", at = @At("HEAD"), cancellable = true)
|
@Inject(
|
||||||
private static void copperfarmers$modifyStorageSourcePred(
|
method = "getTransportTarget(Lnet/minecraft/server/level/ServerLevel;"
|
||||||
CallbackInfoReturnable<Predicate<BlockState>> callbackInfo) {
|
+ "Lnet/minecraft/world/entity/PathfinderMob;)"
|
||||||
Predicate<BlockState> original = callbackInfo.getReturnValue();
|
+ "Ljava/util/Optional;",
|
||||||
Predicate<BlockState> farmlandAware = state ->
|
at = @At("HEAD"),
|
||||||
state.is(Blocks.FARMLAND) || (original != null && original.test(state));
|
cancellable = true,
|
||||||
callbackInfo.setReturnValue(farmlandAware);
|
remap = false
|
||||||
}
|
)
|
||||||
|
private static void copperfarmers$overrideWithFarmlandTarget(
|
||||||
|
ServerLevel world, PathfinderMob entity,
|
||||||
|
CallbackInfoReturnable<java.util.Optional<Object>> cir) {
|
||||||
|
|
||||||
public static Predicate<BlockState> copperfarmers$createFarmlandPredicate() {
|
BlockPos center = new BlockPos(
|
||||||
return state ->
|
(int) entity.getX(), (int) entity.getY() + 1, (int) entity.getZ());
|
||||||
state.is(Blocks.FARMLAND) ||
|
|
||||||
CopperFarmingRegistry.getDestinationPredicate().test(state);
|
for (int dx = -32; dx <= 32; dx++) {
|
||||||
|
for (int dy = -16; dy <= 16; dy++) {
|
||||||
|
for (int dz = -32; dz <= 32; dz++) {
|
||||||
|
BlockPos pos = center.offset(dx, dy, dz);
|
||||||
|
BlockState state = world.getBlockState(pos);
|
||||||
|
|
||||||
|
if (state.is(Blocks.FARMLAND)) {
|
||||||
|
try {
|
||||||
|
Class<?> targetClass = Class.forName(
|
||||||
|
"net/minecraft/world/entity/ai/behavior/TransportItemsBetweenContainers$TransportItemTarget"
|
||||||
|
);
|
||||||
|
|
||||||
|
Object target = targetClass.getMethod("tryCreatePossibleTarget",
|
||||||
|
BlockPos.class, net.minecraft.world.level.Level.class)
|
||||||
|
.invoke(null, pos, world);
|
||||||
|
|
||||||
|
if (target != null) {
|
||||||
|
cir.setReturnValue(java.util.Optional.of(target));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Copperfarmers.LOGGER.warn("Failed to create TransportItemTarget at " + pos + ": " + ex.getClass().getSimpleName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cir.setReturnValue(java.util.Optional.empty());
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
package com.dynamitos.mixin;
|
package com.dynamitos.mixin;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||||
@@ -12,94 +10,71 @@ import net.minecraft.world.Container;
|
|||||||
import net.minecraft.world.entity.PathfinderMob;
|
import net.minecraft.world.entity.PathfinderMob;
|
||||||
import net.minecraft.world.entity.ai.behavior.TransportItemsBetweenContainers;
|
import net.minecraft.world.entity.ai.behavior.TransportItemsBetweenContainers;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.core.GlobalPos;
|
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.world.phys.AABB;
|
import net.minecraft.world.phys.AABB;
|
||||||
|
|
||||||
@Mixin(TransportItemsBetweenContainers.class)
|
@Mixin(TransportItemsBetweenContainers.class)
|
||||||
public interface TransportItemsBasedOnResearchAccessor {
|
public interface TransportItemsBasedOnResearchAccessor {
|
||||||
|
|
||||||
/** Access instance field via private setter */
|
|
||||||
@Invoker("setInteractionState")
|
@Invoker("setInteractionState")
|
||||||
void copperfarmers$setInteractionState(TransportItemsBetweenContainers.ContainerInteractionState state);
|
void copperfarmers$setInteractionState(TransportItemsBetweenContainers.ContainerInteractionState state);
|
||||||
|
|
||||||
@Invoker("setTransportingState")
|
@Invoker("setTransportingState")
|
||||||
void copperfarmers$setTransportingState(TransportItemsBetweenContainers.TransportItemState state);
|
void copperfarmers$setTransportingState(TransportItemsBetweenContainers.TransportItemState state);
|
||||||
|
|
||||||
/** Access the target search area via private method */
|
/** Get target search AABB via private method */
|
||||||
@Invoker("getTargetSearchArea")
|
@Invoker("getTargetSearchArea")
|
||||||
AABB copperfarmers$getTargetSearchArea(PathfinderMob entity);
|
AABB copperfarmers$getTargetSearchArea(PathfinderMob entity);
|
||||||
|
|
||||||
/** Access the center Y position via private method */
|
/** Get center Y position via private method (returns Vec3) */
|
||||||
@Invoker("atCenterY")
|
@Invoker("getCenterPos")
|
||||||
net.minecraft.world.phys.Vec3 copperfarmers$atCenterY(PathfinderMob entity);
|
net.minecraft.world.phys.Vec3 copperfarmers$getCenterY(PathfinderMob entity);
|
||||||
|
|
||||||
/** Check if target is within distance via private method */
|
/** Check if target is close enough via private instance method */
|
||||||
@Invoker("isWithinTargetDistance")
|
@Invoker("isWithinTargetDistance")
|
||||||
boolean copperfarmers$isWithinTargetDistance(double distance,
|
boolean copperfarmers$isWithinTargetDistance(double distance,
|
||||||
TransportItemsBetweenContainers.TransportItemTarget target,
|
TransportItemsBetweenContainers.TransportItemTarget target,
|
||||||
net.minecraft.world.level.Level world, PathfinderMob entity, net.minecraft.world.phys.Vec3 pos);
|
net.minecraft.world.level.Level world, PathfinderMob entity,
|
||||||
|
net.minecraft.world.phys.Vec3 pos);
|
||||||
|
|
||||||
/** Execute travel to target callback (protected method) */
|
/** Execute travel to target callback (protected method) */
|
||||||
@Invoker("onTravelToTarget")
|
@Invoker("onTravelToTarget")
|
||||||
void copperfarmers$onTravelToTarget(TransportItemsBetweenContainers.TransportItemTarget target,
|
void copperfarmers$onTravelToTarget(TransportItemsBetweenContainers.TransportItemTarget target,
|
||||||
net.minecraft.world.level.Level world, PathfinderMob entity);
|
net.minecraft.world.level.Level world, PathfinderMob entity);
|
||||||
|
|
||||||
/** Get center position for walking via private method */
|
|
||||||
@Invoker("getCenterPos")
|
|
||||||
net.minecraft.world.phys.Vec3 copperfarmers$getCenterPos(PathfinderMob entity);
|
|
||||||
|
|
||||||
/** Pick up items from container (private method) */
|
|
||||||
@Invoker("pickUpItems")
|
@Invoker("pickUpItems")
|
||||||
void copperfarmers$pickUpItems(PathfinderMob entity, Container container);
|
void copperfarmers$pickUpItems(PathfinderMob entity, Container container);
|
||||||
|
|
||||||
/** Put down item into container (private method) */
|
|
||||||
@Invoker("putDownItem")
|
@Invoker("putDownItem")
|
||||||
void copperfarmers$putDownItem(PathfinderMob entity, Container container);
|
void copperfarmers$putDownItem(PathfinderMob entity, Container container);
|
||||||
|
|
||||||
/** Static helper invoker for extracting items from containers */
|
/** Extract items from container (static private helper) ✓ */
|
||||||
@Invoker("pickupItemFromContainer")
|
@Invoker("pickupItemFromContainer")
|
||||||
static ItemStack copperfarmers$extractStack(Container inventory) {
|
static ItemStack copperfarmers$extractStack(Container inventory) {
|
||||||
return ItemStack.EMPTY;
|
return ItemStack.EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Invoker("getVisitedPositions")
|
/** Insert items into container (static private helper) ✓ */
|
||||||
void copperfarmers$resetVisitedPositions(PathfinderMob entity);
|
|
||||||
|
|
||||||
/** Static helper invoker for inserting items */
|
|
||||||
@Invoker("addItemsToContainer")
|
@Invoker("addItemsToContainer")
|
||||||
static ItemStack copperfarmers$insertStack(PathfinderMob entity, Container container) {
|
static ItemStack copperfarmers$insertStack(PathfinderMob entity, Container container) {
|
||||||
return ItemStack.EMPTY;
|
return ItemStack.EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Invoker("invalidateTargetStorage")
|
/** Check if entity is picking up items (static private method) ✓ */
|
||||||
void copperfarmers$invalidateTargetStorage(PathfinderMob entity);
|
|
||||||
|
|
||||||
/** Check if the entity can pick up items (static method) */
|
|
||||||
@Invoker("isPickingUpItems")
|
@Invoker("isPickingUpItems")
|
||||||
static boolean copperfarmers$canPickUpItem(PathfinderMob entity) {
|
static boolean copperfarmers$canPickUpItem(PathfinderMob entity) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Invoker("hasItem")
|
/** Check if target matches items requirement (static private method) ✓ */
|
||||||
static boolean copperfarmers$hasItem(Container inventory) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Check if target matches the golem's hand item requirement */
|
|
||||||
@Invoker("matchesLeavingItemsRequirement")
|
@Invoker("matchesLeavingItemsRequirement")
|
||||||
static boolean copperfarmers$canInsert(PathfinderMob entity, Container container) {
|
static boolean copperfarmers$canInsert(PathfinderMob entity, Container container) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Check if target has item matching hand (static private method) ✓ */
|
||||||
@Invoker("hasItemMatchingHandItem")
|
@Invoker("hasItemMatchingHandItem")
|
||||||
static boolean copperfarmers$hasItemMatchingHandItem(PathfinderMob entity, Container container) {
|
static boolean copperfarmers$hasItemMatchingHandItem(PathfinderMob entity, Container container) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get the transport target via private getTransportTarget method */
|
|
||||||
@Invoker("getTransportTarget")
|
|
||||||
Optional<TransportItemsBetweenContainers.TransportItemTarget> copperfarmers$getTransportTarget(
|
|
||||||
ServerLevel world, PathfinderMob entity);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
"compatibilityLevel": "JAVA_25",
|
"compatibilityLevel": "JAVA_25",
|
||||||
"mixins": [
|
"mixins": [
|
||||||
"CopperGolemBehaviorHookMixin",
|
"CopperGolemBehaviorHookMixin",
|
||||||
"FarmlandPredicateMixin",
|
|
||||||
"TransportItemsBasedOnResearchAccessor"
|
"TransportItemsBasedOnResearchAccessor"
|
||||||
],
|
],
|
||||||
"injectors": {
|
"injectors": {
|
||||||
|
|||||||
Reference in New Issue
Block a user