Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package dev.ryanhcode.sable.mixin.entity.villager_poi;

import dev.ryanhcode.sable.Sable;
import dev.ryanhcode.sable.sublevel.SubLevel;
import dev.ryanhcode.sable.util.SubLevelPoiUtil;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.PathfinderMob;
import net.minecraft.world.entity.ai.behavior.AcquirePoi;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;

@Mixin(AcquirePoi.class)
public class AcquirePoiMixin {

/**
* When a villager is standing on a contraption, redirect the PoiManager scan center from the
* villager's global position to its plotyard position so it can find job sites inside the sublevel.
*/
@Redirect(
method = "*",
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/PathfinderMob;blockPosition()Lnet/minecraft/core/BlockPos;")
)
private static BlockPos sable$redirectScanCenter(final PathfinderMob mob) {
final SubLevel sl = Sable.HELPER.getTrackingSubLevel(mob);
if (sl == null) return mob.blockPosition();
return SubLevelPoiUtil.toPlotyard(sl, mob.position());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package dev.ryanhcode.sable.mixin.entity.villager_poi;

import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.llamalad7.mixinextras.sugar.Local;
import dev.ryanhcode.sable.sublevel.SubLevel;
import dev.ryanhcode.sable.util.SubLevelPoiUtil;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Position;
import net.minecraft.world.entity.ai.behavior.AssignProfessionFromJobSite;
import net.minecraft.world.entity.npc.Villager;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;

@Mixin(AssignProfessionFromJobSite.class)
public class AssignProfessionFromJobSiteMixin {

@WrapOperation(
method = "*",
at = @At(value = "INVOKE", target = "Lnet/minecraft/core/BlockPos;closerToCenterThan(Lnet/minecraft/core/Position;D)Z")
)
private static boolean sable$fixProximityCheck(
final BlockPos potentialSitePos, final Position entityPos, final double dist, final Operation<Boolean> original,
@Local(argsOnly = true, ordinal = 0) final Villager villager
) {
final SubLevel sl = SubLevelPoiUtil.getSubLevelForPos(villager.level(), potentialSitePos);
if (sl == null) return original.call(potentialSitePos, entityPos, dist);
return potentialSitePos.closerToCenterThan(
SubLevelPoiUtil.toPlotyard(sl, villager.position()).getCenter(), dist
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package dev.ryanhcode.sable.mixin.entity.villager_poi;

import dev.ryanhcode.sable.Sable;
import dev.ryanhcode.sable.sublevel.SubLevel;
import dev.ryanhcode.sable.util.SubLevelPoiUtil;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.ai.behavior.SetWalkTargetFromBlockMemory;
import net.minecraft.world.entity.npc.Villager;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;

@Mixin(SetWalkTargetFromBlockMemory.class)
public class SetWalkTargetFromBlockMemoryMixin {

@Redirect(
method = "*",
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/npc/Villager;blockPosition()Lnet/minecraft/core/BlockPos;")
)
private static BlockPos sable$redirectBlockPos(final Villager villager) {
final SubLevel sl = Sable.HELPER.getTrackingSubLevel(villager);
if (sl == null) return villager.blockPosition();
return SubLevelPoiUtil.toPlotyard(sl, villager.position());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package dev.ryanhcode.sable.mixin.entity.villager_poi;

import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.llamalad7.mixinextras.sugar.Local;
import dev.ryanhcode.sable.Sable;
import dev.ryanhcode.sable.sublevel.SubLevel;
import dev.ryanhcode.sable.util.SubLevelPoiUtil;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Position;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.ai.behavior.ValidateNearbyPoi;
import net.minecraft.world.phys.Vec3;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;

@Mixin(ValidateNearbyPoi.class)
public class ValidateNearbyPoiMixin {

@WrapOperation(
method = "*",
at = @At(value = "INVOKE", target = "Lnet/minecraft/core/BlockPos;closerToCenterThan(Lnet/minecraft/core/Position;D)Z")
)
private static boolean sable$fixProximityCheck(
final BlockPos storedPos, final Position entityPos, final double dist, final Operation<Boolean> original,
@Local(argsOnly = true, ordinal = 0) final LivingEntity entity
) {
final SubLevel sl = SubLevelPoiUtil.getSubLevelForPos(entity.level(), storedPos);
if (sl == null) return original.call(storedPos, entityPos, dist);

if (Sable.HELPER.getTrackingSubLevel(entity) == sl) {
return storedPos.closerToCenterThan(
SubLevelPoiUtil.toPlotyard(sl, entity.position()).getCenter(), dist
);
}

final Vec3 globalJobSitePos = Sable.HELPER.projectOutOfSubLevel(entity.level(), storedPos.getCenter());
return globalJobSitePos.closerThan(entity.position(), dist);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package dev.ryanhcode.sable.mixin.entity.villager_poi;

import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.llamalad7.mixinextras.sugar.Local;
import dev.ryanhcode.sable.sublevel.SubLevel;
import dev.ryanhcode.sable.util.SubLevelPoiUtil;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Position;
import net.minecraft.world.entity.ai.behavior.WorkAtPoi;
import net.minecraft.world.entity.npc.Villager;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;

@Mixin(WorkAtPoi.class)
public class WorkAtPoiMixin {

@WrapOperation(
method = {"checkExtraStartConditions(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/entity/npc/Villager;)Z",
"canStillUse(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/entity/npc/Villager;J)Z"},
at = @At(value = "INVOKE", target = "Lnet/minecraft/core/BlockPos;closerToCenterThan(Lnet/minecraft/core/Position;D)Z")
)
private boolean sable$fixProximityCheck(
final BlockPos jobSitePos, final Position entityPos, final double dist, final Operation<Boolean> original,
@Local(argsOnly = true, ordinal = 0) final Villager villager
) {
final SubLevel sl = SubLevelPoiUtil.getSubLevelForPos(villager.level(), jobSitePos);
if (sl == null) return original.call(jobSitePos, entityPos, dist);
return jobSitePos.closerToCenterThan(
SubLevelPoiUtil.toPlotyard(sl, villager.position()).getCenter(), dist
);
}
}
22 changes: 22 additions & 0 deletions common/src/main/java/dev/ryanhcode/sable/util/SubLevelPoiUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package dev.ryanhcode.sable.util;

import dev.ryanhcode.sable.Sable;
import dev.ryanhcode.sable.sublevel.SubLevel;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.Nullable;

public final class SubLevelPoiUtil {

private SubLevelPoiUtil() {}

public static @Nullable SubLevel getSubLevelForPos(final Level level, final BlockPos pos) {
return Sable.HELPER.getContaining(level, pos);
}

/** Converts a global entity position to the plotyard BlockPos within the given sublevel. */
public static BlockPos toPlotyard(final SubLevel sl, final Vec3 globalPos) {
return BlockPos.containing(sl.logicalPose().transformPositionInverse(globalPos));
}
}
5 changes: 5 additions & 0 deletions common/src/main/resources/sable.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,11 @@
"entity.entity_pathfinding.PathNavigationMixin",
"entity.entity_pathfinding.RandomPosMixin",
"entity.entity_pathfinding.WalkNodeEvaluatorMixin",
"entity.villager_poi.AcquirePoiMixin",
"entity.villager_poi.AssignProfessionFromJobSiteMixin",
"entity.villager_poi.ValidateNearbyPoiMixin",
"entity.villager_poi.SetWalkTargetFromBlockMemoryMixin",
"entity.villager_poi.WorkAtPoiMixin",
"entity.entity_rotations_and_riding.BlockMixin",
"entity.entity_rotations_and_riding.EntityMixin",
"entity.entity_rotations_and_riding.EntityTypeMixin",
Expand Down