优化寻路

优化砍罚目标选择
优化行为顺序
This commit is contained in:
xypp
2025-04-27 22:57:56 +08:00
parent 0aa91679e3
commit 5eaf45a113
23 changed files with 443 additions and 130 deletions

View File

@@ -28,7 +28,8 @@ public class UsefulTaskExtension implements ILittleMaid {
MemoryModuleRegistry.DESTROY_TARGET.get(), MemoryModuleRegistry.DESTROY_TARGET.get(),
MemoryModuleRegistry.PLACE_TARGET.get(), MemoryModuleRegistry.PLACE_TARGET.get(),
MemoryModuleRegistry.BLOCK_UP_TARGET.get(), MemoryModuleRegistry.BLOCK_UP_TARGET.get(),
MemoryModuleRegistry.RATE_LIMIT_TOKEN.get() MemoryModuleRegistry.BLOCK_VALIDATION.get(),
MemoryModuleRegistry.CURRENT_WORK.get()
); );
} }
}); });

View File

@@ -9,6 +9,7 @@ import net.minecraft.world.entity.ai.memory.MemoryModuleType;
import net.minecraft.world.entity.ai.memory.MemoryStatus; import net.minecraft.world.entity.ai.memory.MemoryStatus;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import studio.fantasyit.maid_useful_task.memory.BlockUpContext; import studio.fantasyit.maid_useful_task.memory.BlockUpContext;
import studio.fantasyit.maid_useful_task.memory.CurrentWork;
import studio.fantasyit.maid_useful_task.task.IMaidBlockUpTask; import studio.fantasyit.maid_useful_task.task.IMaidBlockUpTask;
import studio.fantasyit.maid_useful_task.util.Conditions; import studio.fantasyit.maid_useful_task.util.Conditions;
import studio.fantasyit.maid_useful_task.util.MaidUtils; import studio.fantasyit.maid_useful_task.util.MaidUtils;
@@ -28,11 +29,12 @@ public class BlockUpDestroyBehavior extends Behavior<EntityMaid> {
} }
public BlockUpDestroyBehavior() { public BlockUpDestroyBehavior() {
super(Map.of(),200); super(Map.of(),500);
} }
@Override @Override
protected boolean checkExtraStartConditions(ServerLevel p_22538_, EntityMaid p_22539_) { protected boolean checkExtraStartConditions(ServerLevel p_22538_, EntityMaid p_22539_) {
if(!Conditions.isCurrent(p_22539_, CurrentWork.BLOCKUP_DOWN)) return false;
if (!MemoryUtil.getBlockUpContext(p_22539_).hasTarget()) return false; if (!MemoryUtil.getBlockUpContext(p_22539_).hasTarget()) return false;
if (MemoryUtil.getBlockUpContext(p_22539_).getStatus() != BlockUpContext.STATUS.DOWN) return false; if (MemoryUtil.getBlockUpContext(p_22539_).getStatus() != BlockUpContext.STATUS.DOWN) return false;
return Conditions.hasReachedValidTargetOrReset(p_22539_, 0.8f); return Conditions.hasReachedValidTargetOrReset(p_22539_, 0.8f);
@@ -63,8 +65,7 @@ public class BlockUpDestroyBehavior extends Behavior<EntityMaid> {
BlockPos targetPos = maid.blockPosition().below(); BlockPos targetPos = maid.blockPosition().below();
maid.swing(InteractionHand.MAIN_HAND); maid.swing(InteractionHand.MAIN_HAND);
MemoryUtil.setLookAt(maid, targetPos); MemoryUtil.setLookAt(maid, targetPos);
BlockState targetBlockState = level.getBlockState(targetPos); float speed = MaidUtils.getDestroyProgressDelta(maid, targetPos);
float speed = fakePlayer.getMainHandItem().getDestroySpeed(targetBlockState) / fakePlayer.getDigSpeed(targetBlockState, targetPos) / 30;
progress += speed; progress += speed;
if (progress >= 1f) { if (progress >= 1f) {
MaidUtils.destroyBlock(maid, targetPos); MaidUtils.destroyBlock(maid, targetPos);
@@ -75,7 +76,8 @@ public class BlockUpDestroyBehavior extends Behavior<EntityMaid> {
@Override @Override
protected void stop(ServerLevel p_22548_, EntityMaid maid, long p_22550_) { protected void stop(ServerLevel p_22548_, EntityMaid maid, long p_22550_) {
super.stop(p_22548_, maid, p_22550_); super.stop(p_22548_, maid, p_22550_);
context.setStatus(BlockUpContext.STATUS.IDLE); context.clearStartTarget();
MemoryUtil.clearTarget(maid); MemoryUtil.clearTarget(maid);
MemoryUtil.setCurrent(maid, CurrentWork.IDLE);
} }
} }

View File

@@ -11,6 +11,7 @@ import net.minecraft.world.level.levelgen.structure.BoundingBox;
import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import studio.fantasyit.maid_useful_task.memory.BlockUpContext; import studio.fantasyit.maid_useful_task.memory.BlockUpContext;
import studio.fantasyit.maid_useful_task.memory.CurrentWork;
import studio.fantasyit.maid_useful_task.task.IMaidBlockUpTask; import studio.fantasyit.maid_useful_task.task.IMaidBlockUpTask;
import studio.fantasyit.maid_useful_task.util.Conditions; import studio.fantasyit.maid_useful_task.util.Conditions;
import studio.fantasyit.maid_useful_task.util.MaidUtils; import studio.fantasyit.maid_useful_task.util.MaidUtils;
@@ -34,6 +35,7 @@ public class BlockUpPlaceBehavior extends Behavior<EntityMaid> {
@Override @Override
protected boolean checkExtraStartConditions(ServerLevel p_22538_, EntityMaid p_22539_) { protected boolean checkExtraStartConditions(ServerLevel p_22538_, EntityMaid p_22539_) {
if (!Conditions.isCurrent(p_22539_, CurrentWork.BLOCKUP_UP)) return false;
if (!MemoryUtil.getBlockUpContext(p_22539_).hasTarget()) return false; if (!MemoryUtil.getBlockUpContext(p_22539_).hasTarget()) return false;
if (MemoryUtil.getBlockUpContext(p_22539_).getStatus() != BlockUpContext.STATUS.UP) return false; if (MemoryUtil.getBlockUpContext(p_22539_).getStatus() != BlockUpContext.STATUS.UP) return false;
return Conditions.hasReachedValidTargetOrReset(p_22539_, 0.8f); return Conditions.hasReachedValidTargetOrReset(p_22539_, 0.8f);
@@ -42,7 +44,7 @@ public class BlockUpPlaceBehavior extends Behavior<EntityMaid> {
@Override @Override
protected boolean canStillUse(ServerLevel p_22545_, EntityMaid maid, long p_22547_) { protected boolean canStillUse(ServerLevel p_22545_, EntityMaid maid, long p_22547_) {
if (MemoryUtil.getBlockUpContext(maid).getStatus() != BlockUpContext.STATUS.UP) return false; if (MemoryUtil.getBlockUpContext(maid).getStatus() != BlockUpContext.STATUS.UP) return false;
if (!p_22545_.getBlockState(maid.blockPosition().above().above()).isAir()) return false; if (maid.onGround() && !p_22545_.getBlockState(maid.blockPosition().above().above()).isAir()) return false;
return !(maid.blockPosition().equals(context.getTargetPos()) && maid.onGround()); return !(maid.blockPosition().equals(context.getTargetPos()) && maid.onGround());
} }
@@ -99,10 +101,14 @@ public class BlockUpPlaceBehavior extends Behavior<EntityMaid> {
protected void stop(ServerLevel p_22548_, EntityMaid maid, long p_22550_) { protected void stop(ServerLevel p_22548_, EntityMaid maid, long p_22550_) {
super.stop(p_22548_, maid, p_22550_); super.stop(p_22548_, maid, p_22550_);
context.setStatus(BlockUpContext.STATUS.IDLE); context.setStatus(BlockUpContext.STATUS.IDLE);
if (!maid.blockPosition().equals(context.getTargetPos())) { if (context.hasTarget()) {
BlockPos startPos = context.getStartPos(); if (!maid.blockPosition().equals(context.getTargetPos())) {
BlockPos blockPos = maid.blockPosition(); BlockPos startPos = context.getStartPos();
context.setStartTarget(new BlockPos(blockPos.getX(), startPos.getY(), blockPos.getZ()), blockPos); BlockPos blockPos = maid.blockPosition();
context.setStartTarget(new BlockPos(blockPos.getX(), startPos.getY(), blockPos.getZ()), blockPos);
}
MemoryUtil.setCurrent(maid, CurrentWork.BLOCKUP_DESTROY);
} }
MemoryUtil.clearTarget(maid); MemoryUtil.clearTarget(maid);
} }

View File

@@ -1,6 +1,5 @@
package studio.fantasyit.maid_useful_task.behavior; package studio.fantasyit.maid_useful_task.behavior;
import com.github.tartaricacid.touhoulittlemaid.entity.ai.brain.task.MaidCheckRateTask;
import com.github.tartaricacid.touhoulittlemaid.entity.passive.EntityMaid; import com.github.tartaricacid.touhoulittlemaid.entity.passive.EntityMaid;
import com.github.tartaricacid.touhoulittlemaid.init.InitEntities; import com.github.tartaricacid.touhoulittlemaid.init.InitEntities;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
@@ -13,12 +12,11 @@ import net.minecraft.world.entity.ai.memory.MemoryModuleType;
import net.minecraft.world.entity.ai.memory.MemoryStatus; import net.minecraft.world.entity.ai.memory.MemoryStatus;
import oshi.util.tuples.Pair; import oshi.util.tuples.Pair;
import studio.fantasyit.maid_useful_task.memory.BlockUpContext; import studio.fantasyit.maid_useful_task.memory.BlockUpContext;
import studio.fantasyit.maid_useful_task.memory.TaskRateLimitToken; import studio.fantasyit.maid_useful_task.memory.CurrentWork;
import studio.fantasyit.maid_useful_task.task.IMaidBlockUpTask; import studio.fantasyit.maid_useful_task.task.IMaidBlockUpTask;
import studio.fantasyit.maid_useful_task.util.MaidUtils;
import studio.fantasyit.maid_useful_task.util.MemoryUtil; import studio.fantasyit.maid_useful_task.util.MemoryUtil;
import java.util.Map;
public class BlockUpScheduleBehavior extends Behavior<EntityMaid> { public class BlockUpScheduleBehavior extends Behavior<EntityMaid> {
public BlockUpScheduleBehavior() { public BlockUpScheduleBehavior() {
super(ImmutableMap.of(MemoryModuleType.WALK_TARGET, MemoryStatus.VALUE_ABSENT, InitEntities.TARGET_POS.get(), MemoryStatus.VALUE_ABSENT)); super(ImmutableMap.of(MemoryModuleType.WALK_TARGET, MemoryStatus.VALUE_ABSENT, InitEntities.TARGET_POS.get(), MemoryStatus.VALUE_ABSENT));
@@ -26,7 +24,10 @@ public class BlockUpScheduleBehavior extends Behavior<EntityMaid> {
@Override @Override
protected boolean checkExtraStartConditions(ServerLevel p_22538_, EntityMaid p_22539_) { protected boolean checkExtraStartConditions(ServerLevel p_22538_, EntityMaid p_22539_) {
if (MemoryUtil.getRateLimitToken(p_22539_).isFor(TaskRateLimitToken.Level.L3)) { if (!switch (MemoryUtil.getCurrent(p_22539_)) {
case BLOCKUP_UP, BLOCKUP_DOWN, BLOCKUP_DESTROY, IDLE -> true;
default -> false;
}) {
return false; return false;
} }
return super.checkExtraStartConditions(p_22538_, p_22539_); return super.checkExtraStartConditions(p_22538_, p_22539_);
@@ -37,23 +38,33 @@ public class BlockUpScheduleBehavior extends Behavior<EntityMaid> {
BlockUpContext context = MemoryUtil.getBlockUpContext(maid); BlockUpContext context = MemoryUtil.getBlockUpContext(maid);
IMaidBlockUpTask task = (IMaidBlockUpTask) maid.getTask(); IMaidBlockUpTask task = (IMaidBlockUpTask) maid.getTask();
if (context.hasTarget()) { if (context.hasTarget()) {
if (context.getStatus() != BlockUpContext.STATUS.IDLE && MemoryUtil.getTargetPos(maid) == null) { if (context.getStatus() != BlockUpContext.STATUS.UP && !context.isOnLine(maid.blockPosition())) {
context.clearStartTarget(); context.clearStartTarget();
MemoryUtil.setCurrent(maid, CurrentWork.IDLE);
} else if (context.getStatus() != BlockUpContext.STATUS.IDLE && MemoryUtil.getTargetPos(maid) == null) {
if (context.getStatus() == BlockUpContext.STATUS.DOWN) {
MemoryUtil.setTarget(maid, context.getTargetPos(), 0.5f);
MemoryUtil.setCurrent(maid, CurrentWork.BLOCKUP_DOWN);
} else {
MemoryUtil.setTarget(maid, context.getStartPos(), 0.5f);
MemoryUtil.setCurrent(maid, CurrentWork.BLOCKUP_UP);
}
} else if (!context.isOnLine(maid.blockPosition()) || context.getStartPos().equals(context.getTargetPos())) { } else if (!context.isOnLine(maid.blockPosition()) || context.getStartPos().equals(context.getTargetPos())) {
context.clearStartTarget(); context.clearStartTarget();
} else if (context.getStatus() == BlockUpContext.STATUS.IDLE && !context.isTarget(maid.blockPosition()) && context.isOnLine(maid.blockPosition())) { MemoryUtil.setCurrent(maid, CurrentWork.IDLE);
context.setStartTarget(context.getStartPos(), maid.blockPosition());
} else if (context.getStatus() == BlockUpContext.STATUS.IDLE && !task.stillValid(maid, maid.blockPosition())) { } else if (context.getStatus() == BlockUpContext.STATUS.IDLE && !task.stillValid(maid, maid.blockPosition())) {
maid.getBrain().setMemory(InitEntities.TARGET_POS.get(), new BlockPosTracker(context.getTargetPos())); maid.getBrain().setMemory(InitEntities.TARGET_POS.get(), new BlockPosTracker(context.getTargetPos()));
context.setStatus(BlockUpContext.STATUS.DOWN); context.setStatus(BlockUpContext.STATUS.DOWN);
MemoryUtil.setCurrent(maid, CurrentWork.BLOCKUP_DOWN);
} }
} else { } else {
Pair<BlockPos, BlockPos> targetPosBlockUp = task.findTargetPosBlockUp(maid, maid.blockPosition()); Pair<BlockPos, BlockPos> targetPosBlockUp = task.findTargetPosBlockUp(maid, MaidUtils.getMaidRestrictCenter(maid), task.countMaxUsableBlockItems(maid));
if (targetPosBlockUp != null) { if (targetPosBlockUp != null) {
context.setStartTarget(targetPosBlockUp.getA(), targetPosBlockUp.getB()); context.setStartTarget(targetPosBlockUp.getA(), targetPosBlockUp.getB());
maid.getBrain().setMemory(InitEntities.TARGET_POS.get(), new BlockPosTracker(targetPosBlockUp.getA())); maid.getBrain().setMemory(InitEntities.TARGET_POS.get(), new BlockPosTracker(targetPosBlockUp.getA()));
BehaviorUtils.setWalkAndLookTargetMemories(maid, targetPosBlockUp.getA(), 0.5f, 0); BehaviorUtils.setWalkAndLookTargetMemories(maid, targetPosBlockUp.getA(), 0.5f, 0);
context.setStatus(BlockUpContext.STATUS.UP); context.setStatus(BlockUpContext.STATUS.UP);
MemoryUtil.setCurrent(maid, CurrentWork.BLOCKUP_UP);
} }
} }
} }

View File

@@ -10,9 +10,11 @@ import net.minecraft.world.entity.ai.memory.MemoryStatus;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import studio.fantasyit.maid_useful_task.memory.BlockTargetMemory; import studio.fantasyit.maid_useful_task.memory.BlockTargetMemory;
import studio.fantasyit.maid_useful_task.memory.CurrentWork;
import studio.fantasyit.maid_useful_task.registry.MemoryModuleRegistry; import studio.fantasyit.maid_useful_task.registry.MemoryModuleRegistry;
import studio.fantasyit.maid_useful_task.task.IMaidBlockDestroyTask; import studio.fantasyit.maid_useful_task.task.IMaidBlockDestroyTask;
import studio.fantasyit.maid_useful_task.util.Conditions; import studio.fantasyit.maid_useful_task.util.Conditions;
import studio.fantasyit.maid_useful_task.util.MaidUtils;
import studio.fantasyit.maid_useful_task.util.MemoryUtil; import studio.fantasyit.maid_useful_task.util.MemoryUtil;
import studio.fantasyit.maid_useful_task.util.WrappedMaidFakePlayer; import studio.fantasyit.maid_useful_task.util.WrappedMaidFakePlayer;
@@ -32,7 +34,9 @@ public class DestoryBlockBehavior extends Behavior<EntityMaid> {
@Override @Override
protected boolean checkExtraStartConditions(@NotNull ServerLevel worldIn, @NotNull EntityMaid maid) { protected boolean checkExtraStartConditions(@NotNull ServerLevel worldIn, @NotNull EntityMaid maid) {
return Conditions.hasReachedValidTargetOrReset(maid,1); if (!Conditions.isCurrent(maid, CurrentWork.DESTROY) && !Conditions.isCurrent(maid, CurrentWork.BLOCKUP_DESTROY))
return false;
return Conditions.hasReachedValidTargetOrReset(maid, 1);
} }
@@ -48,7 +52,7 @@ public class DestoryBlockBehavior extends Behavior<EntityMaid> {
super.start(p_22540_, maid, p_22542_); super.start(p_22540_, maid, p_22542_);
BlockTargetMemory blockTargetMemory = MemoryUtil.getDestroyTargetMemory(maid); BlockTargetMemory blockTargetMemory = MemoryUtil.getDestroyTargetMemory(maid);
if (blockTargetMemory != null) { if (blockTargetMemory != null) {
blockPosSet =new ArrayList<>(blockTargetMemory.getBlockPosSet()); blockPosSet = new ArrayList<>(blockTargetMemory.getBlockPosSet());
blockPosSet.sort((o1, o2) -> (int) (o1.distSqr(maid.blockPosition()) - o2.distSqr(maid.blockPosition()))); blockPosSet.sort((o1, o2) -> (int) (o1.distSqr(maid.blockPosition()) - o2.distSqr(maid.blockPosition())));
} }
index = 0; index = 0;
@@ -87,14 +91,13 @@ public class DestoryBlockBehavior extends Behavior<EntityMaid> {
} }
private void tickDestroyProgress(EntityMaid maid) { private void tickDestroyProgress(EntityMaid maid) {
float speed = fakePlayer.getMainHandItem().getDestroySpeed(targetBlockState) / fakePlayer.getDigSpeed(targetBlockState, targetPos) / 30; float speed = MaidUtils.getDestroyProgressDelta(maid, targetPos);
MemoryUtil.setLookAt(maid, targetPos); MemoryUtil.setLookAt(maid, targetPos);
if (task.availableToGetDrop(maid, fakePlayer, targetPos, targetBlockState)) { if (speed != 0.0f && task.availableToGetDrop(maid, fakePlayer, targetPos, targetBlockState)) {
maid.swing(InteractionHand.MAIN_HAND); maid.swing(InteractionHand.MAIN_HAND);
destroyProgress += speed; destroyProgress += speed;
if (destroyProgress >= 1f) { if (destroyProgress >= 1f) {
maid.getMainHandItem().hurt(1, maid.getRandom(), fakePlayer); task.tryDestroyBlock(maid, targetPos);
task.tryDestroyBlock(maid,targetPos);
destroyProgress = 0f; destroyProgress = 0f;
targetPos = null; targetPos = null;
targetBlockState = null; targetBlockState = null;
@@ -110,6 +113,7 @@ public class DestoryBlockBehavior extends Behavior<EntityMaid> {
super.stop(p_22548_, p_22549_, p_22550_); super.stop(p_22548_, p_22549_, p_22550_);
MemoryUtil.clearDestroyTargetMemory(p_22549_); MemoryUtil.clearDestroyTargetMemory(p_22549_);
MemoryUtil.clearTarget(p_22549_); MemoryUtil.clearTarget(p_22549_);
MemoryUtil.setCurrent(p_22549_, CurrentWork.IDLE);
} }
@Override @Override

View File

@@ -1,13 +1,12 @@
package studio.fantasyit.maid_useful_task.behavior; package studio.fantasyit.maid_useful_task.behavior;
import com.github.tartaricacid.touhoulittlemaid.entity.ai.brain.task.MaidMoveToBlockTask;
import com.github.tartaricacid.touhoulittlemaid.entity.passive.EntityMaid; import com.github.tartaricacid.touhoulittlemaid.entity.passive.EntityMaid;
import com.github.tartaricacid.touhoulittlemaid.entity.passive.MaidPathFindingBFS; import com.github.tartaricacid.touhoulittlemaid.entity.passive.MaidPathFindingBFS;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import studio.fantasyit.maid_useful_task.memory.TaskRateLimitToken; import studio.fantasyit.maid_useful_task.memory.CurrentWork;
import studio.fantasyit.maid_useful_task.task.IMaidBlockDestroyTask; import studio.fantasyit.maid_useful_task.task.IMaidBlockDestroyTask;
import studio.fantasyit.maid_useful_task.util.Conditions; import studio.fantasyit.maid_useful_task.util.Conditions;
import studio.fantasyit.maid_useful_task.util.MemoryUtil; import studio.fantasyit.maid_useful_task.util.MemoryUtil;
@@ -26,16 +25,17 @@ public class DestoryBlockMoveBehavior extends MaidCenterMoveToBlockTask {
@Override @Override
protected boolean checkExtraStartConditions(ServerLevel p_22538_, EntityMaid p_22539_) { protected boolean checkExtraStartConditions(ServerLevel p_22538_, EntityMaid maid) {
if (MemoryUtil.getRateLimitToken(p_22539_).isFor(TaskRateLimitToken.Level.L1)) { if (!Conditions.isCurrent(maid, CurrentWork.IDLE) && !Conditions.isCurrent(maid, CurrentWork.BLOCKUP_DESTROY))
return false; return false;
} return super.checkExtraStartConditions(p_22538_, maid);
return super.checkExtraStartConditions(p_22538_, p_22539_);
} }
@Override @Override
protected void start(@NotNull ServerLevel p_22540_, @NotNull EntityMaid maid, long p_22542_) { protected void start(@NotNull ServerLevel p_22540_, @NotNull EntityMaid maid, long p_22542_) {
super.start(p_22540_, maid, p_22542_); super.start(p_22540_, maid, p_22542_);
if (maid.hasRestriction())
this.setSearchRange((int) maid.getRestrictRadius());
task = (IMaidBlockDestroyTask) maid.getTask(); task = (IMaidBlockDestroyTask) maid.getTask();
task.tryTakeOutTool(maid); task.tryTakeOutTool(maid);
searchForDestination(p_22540_, maid); searchForDestination(p_22540_, maid);
@@ -43,11 +43,14 @@ public class DestoryBlockMoveBehavior extends MaidCenterMoveToBlockTask {
if (target != null && blockPosSet != null) { if (target != null && blockPosSet != null) {
blockPosSet.addAll(task.getTryDestroyBlockListBesidesStart(targetPos, target, maid)); blockPosSet.addAll(task.getTryDestroyBlockListBesidesStart(targetPos, target, maid));
MemoryUtil.setDestroyTargetMemory(maid, blockPosSet); MemoryUtil.setDestroyTargetMemory(maid, blockPosSet);
if (Conditions.isCurrent(maid, CurrentWork.IDLE))
MemoryUtil.setCurrent(maid, CurrentWork.DESTROY);
} }
} }
@Override @Override
protected boolean shouldMoveTo(@NotNull ServerLevel serverLevel, @NotNull EntityMaid entityMaid, @NotNull BlockPos blockPos) { protected boolean shouldMoveTo(@NotNull ServerLevel serverLevel, @NotNull EntityMaid entityMaid, @NotNull BlockPos blockPos) {
if (!task.shouldDestroyBlock(entityMaid, blockPos)) return false; if (!task.shouldDestroyBlock(entityMaid, blockPos.immutable())) return false;
targetPos = blockPos.immutable(); targetPos = blockPos.immutable();
if (blockPos instanceof BlockPos.MutableBlockPos mb) { if (blockPos instanceof BlockPos.MutableBlockPos mb) {
for (int dx = 0; dx < task.reachDistance(); dx = dx <= 0 ? 1 - dx : -dx) { for (int dx = 0; dx < task.reachDistance(); dx = dx <= 0 ? 1 - dx : -dx) {
@@ -75,7 +78,10 @@ public class DestoryBlockMoveBehavior extends MaidCenterMoveToBlockTask {
@Override @Override
protected @NotNull MaidPathFindingBFS getOrCreateArrivalMap(@NotNull ServerLevel worldIn, @NotNull EntityMaid maid) { protected @NotNull MaidPathFindingBFS getOrCreateArrivalMap(@NotNull ServerLevel worldIn, @NotNull EntityMaid maid) {
if (this.pathfindingBFS == null) if (this.pathfindingBFS == null)
this.pathfindingBFS = new MaidPathFindingBFS(maid.getNavigation().getNodeEvaluator(), worldIn, maid, 14); if(maid.hasRestriction())
this.pathfindingBFS = new MaidPathFindingBFS(maid.getNavigation().getNodeEvaluator(), worldIn, maid, 14, (int) maid.getRestrictRadius());
else
this.pathfindingBFS = new MaidPathFindingBFS(maid.getNavigation().getNodeEvaluator(), worldIn, maid, 14);
return this.pathfindingBFS; return this.pathfindingBFS;
} }
@@ -84,4 +90,4 @@ public class DestoryBlockMoveBehavior extends MaidCenterMoveToBlockTask {
super.clearCurrentArrivalMap(pathFinding); super.clearCurrentArrivalMap(pathFinding);
this.pathfindingBFS = null; this.pathfindingBFS = null;
} }
} }

View File

@@ -13,6 +13,7 @@ import net.minecraft.world.entity.ai.behavior.BehaviorUtils;
import net.minecraft.world.entity.ai.behavior.BlockPosTracker; import net.minecraft.world.entity.ai.behavior.BlockPosTracker;
import net.minecraft.world.entity.ai.memory.MemoryModuleType; import net.minecraft.world.entity.ai.memory.MemoryModuleType;
import net.minecraft.world.entity.ai.memory.MemoryStatus; import net.minecraft.world.entity.ai.memory.MemoryStatus;
import studio.fantasyit.maid_useful_task.util.MaidUtils;
/** /**
* From https://github.com/TartaricAcid/TouhouLittleMaid * From https://github.com/TartaricAcid/TouhouLittleMaid
@@ -23,7 +24,7 @@ abstract public class MaidCenterMoveToBlockTask extends Behavior<EntityMaid> {
private static final int MAX_DELAY_TIME = 120; private static final int MAX_DELAY_TIME = 120;
private final float movementSpeed; private final float movementSpeed;
private final int verticalSearchRange; private final int verticalSearchRange;
private final int searchRange; private int searchRange;
protected int verticalSearchStart; protected int verticalSearchStart;
public MaidCenterMoveToBlockTask(float movementSpeed) { public MaidCenterMoveToBlockTask(float movementSpeed) {
@@ -33,26 +34,29 @@ abstract public class MaidCenterMoveToBlockTask extends Behavior<EntityMaid> {
public MaidCenterMoveToBlockTask(float movementSpeed, int verticalSearchRange) { public MaidCenterMoveToBlockTask(float movementSpeed, int verticalSearchRange) {
this(movementSpeed, verticalSearchRange, 7); this(movementSpeed, verticalSearchRange, 7);
} }
public MaidCenterMoveToBlockTask(float movementSpeed, int verticalSearchRange,int searchRange) {
public MaidCenterMoveToBlockTask(float movementSpeed, int verticalSearchRange, int defaultSearchRange) {
super(ImmutableMap.of(MemoryModuleType.WALK_TARGET, MemoryStatus.VALUE_ABSENT, InitEntities.TARGET_POS.get(), MemoryStatus.VALUE_ABSENT)); super(ImmutableMap.of(MemoryModuleType.WALK_TARGET, MemoryStatus.VALUE_ABSENT, InitEntities.TARGET_POS.get(), MemoryStatus.VALUE_ABSENT));
this.movementSpeed = movementSpeed; this.movementSpeed = movementSpeed;
this.verticalSearchRange = verticalSearchRange; this.verticalSearchRange = verticalSearchRange;
this.searchRange = searchRange; this.searchRange = defaultSearchRange;
}
public void setSearchRange(int searchRange) {
this.searchRange = searchRange;
} }
protected final void searchForDestination(ServerLevel worldIn, EntityMaid maid) { protected final void searchForDestination(ServerLevel worldIn, EntityMaid maid) {
MaidPathFindingBFS pathFinding = this.getOrCreateArrivalMap(worldIn, maid); MaidPathFindingBFS pathFinding = this.getOrCreateArrivalMap(worldIn, maid);
BlockPos centrePos = this.getWorkSearchPos(maid); BlockPos centrePos = this.getWorkSearchPos(maid);
BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos(); BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos();
for(int y = this.verticalSearchStart; y <= this.verticalSearchRange; y = y > 0 ? -y : 1 - y) { for (int y = this.verticalSearchStart; y <= this.verticalSearchRange; y = y > 0 ? -y : 1 - y) {
for(int i = 0; i < searchRange; ++i) { for (int i = 0; i < searchRange; ++i) {
for(int x = 0; x <= i; x = x > 0 ? -x : 1 - x) { for (int x = 0; x <= i; x = x > 0 ? -x : 1 - x) {
for(int z = x < i && x > -i ? i : 0; z <= i; z = z > 0 ? -z : 1 - z) { for (int z = x < i && x > -i ? i : 0; z <= i; z = z > 0 ? -z : 1 - z) {
mutableBlockPos.setWithOffset(centrePos, x, y - 1, z); mutableBlockPos.setWithOffset(centrePos, x, y - 1, z);
if (maid.isWithinRestriction(mutableBlockPos) && this.shouldMoveTo(worldIn, maid, mutableBlockPos) && this.checkPathReach(maid, pathFinding, mutableBlockPos) && this.checkOwnerPos(maid, mutableBlockPos)) { if (this.shouldMoveTo(worldIn, maid, mutableBlockPos) && this.checkPathReach(maid, pathFinding, mutableBlockPos) && this.checkOwnerPos(maid, mutableBlockPos)) {
BehaviorUtils.setWalkAndLookTargetMemories(maid, mutableBlockPos, this.movementSpeed, 0); BehaviorUtils.setWalkAndLookTargetMemories(maid, mutableBlockPos, this.movementSpeed, 0);
maid.getBrain().setMemory((MemoryModuleType)InitEntities.TARGET_POS.get(), new BlockPosTracker(mutableBlockPos)); maid.getBrain().setMemory((MemoryModuleType) InitEntities.TARGET_POS.get(), new BlockPosTracker(mutableBlockPos));
this.clearCurrentArrivalMap(pathFinding); this.clearCurrentArrivalMap(pathFinding);
return; return;
} }
@@ -73,7 +77,7 @@ abstract public class MaidCenterMoveToBlockTask extends Behavior<EntityMaid> {
} }
private BlockPos getWorkSearchPos(EntityMaid maid) { private BlockPos getWorkSearchPos(EntityMaid maid) {
return maid.blockPosition(); return MaidUtils.getMaidRestrictCenter(maid);
} }
private boolean checkOwnerPos(EntityMaid maid, BlockPos mutableBlockPos) { private boolean checkOwnerPos(EntityMaid maid, BlockPos mutableBlockPos) {
@@ -86,7 +90,9 @@ abstract public class MaidCenterMoveToBlockTask extends Behavior<EntityMaid> {
protected abstract boolean shouldMoveTo(ServerLevel var1, EntityMaid var2, BlockPos var3); protected abstract boolean shouldMoveTo(ServerLevel var1, EntityMaid var2, BlockPos var3);
/** @deprecated */ /**
* @deprecated
*/
@Deprecated( @Deprecated(
forRemoval = true forRemoval = true
) )

View File

@@ -7,6 +7,7 @@ import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.ai.behavior.Behavior; import net.minecraft.world.entity.ai.behavior.Behavior;
import net.minecraft.world.entity.ai.memory.MemoryStatus; import net.minecraft.world.entity.ai.memory.MemoryStatus;
import studio.fantasyit.maid_useful_task.memory.CurrentWork;
import studio.fantasyit.maid_useful_task.registry.MemoryModuleRegistry; import studio.fantasyit.maid_useful_task.registry.MemoryModuleRegistry;
import studio.fantasyit.maid_useful_task.task.IMaidBlockPlaceTask; import studio.fantasyit.maid_useful_task.task.IMaidBlockPlaceTask;
import studio.fantasyit.maid_useful_task.util.Conditions; import studio.fantasyit.maid_useful_task.util.Conditions;
@@ -24,8 +25,9 @@ public class PlaceBlockBehavior extends Behavior<EntityMaid> {
} }
@Override @Override
protected boolean checkExtraStartConditions(ServerLevel p_22538_, EntityMaid p_22539_) { protected boolean checkExtraStartConditions(ServerLevel p_22538_, EntityMaid maid) {
return Conditions.hasReachedValidTargetOrReset(p_22539_); MemoryUtil.setCurrent(maid, CurrentWork.PLACE);
return Conditions.hasReachedValidTargetOrReset(maid);
} }
@Override @Override
@@ -59,5 +61,6 @@ public class PlaceBlockBehavior extends Behavior<EntityMaid> {
super.stop(p_22548_, p_22549_, p_22550_); super.stop(p_22548_, p_22549_, p_22550_);
MemoryUtil.clearPlaceTarget(p_22549_); MemoryUtil.clearPlaceTarget(p_22549_);
MemoryUtil.clearTarget(p_22549_); MemoryUtil.clearTarget(p_22549_);
MemoryUtil.setCurrent(p_22549_, CurrentWork.IDLE);
} }
} }

View File

@@ -1,6 +1,5 @@
package studio.fantasyit.maid_useful_task.behavior; package studio.fantasyit.maid_useful_task.behavior;
import com.github.tartaricacid.touhoulittlemaid.entity.ai.brain.task.MaidMoveToBlockTask;
import com.github.tartaricacid.touhoulittlemaid.entity.passive.EntityMaid; import com.github.tartaricacid.touhoulittlemaid.entity.passive.EntityMaid;
import com.github.tartaricacid.touhoulittlemaid.entity.passive.MaidPathFindingBFS; import com.github.tartaricacid.touhoulittlemaid.entity.passive.MaidPathFindingBFS;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
@@ -10,7 +9,7 @@ import net.minecraft.world.item.ItemStack;
import net.minecraftforge.items.wrapper.CombinedInvWrapper; import net.minecraftforge.items.wrapper.CombinedInvWrapper;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import studio.fantasyit.maid_useful_task.memory.TaskRateLimitToken; import studio.fantasyit.maid_useful_task.memory.CurrentWork;
import studio.fantasyit.maid_useful_task.task.IMaidBlockPlaceTask; import studio.fantasyit.maid_useful_task.task.IMaidBlockPlaceTask;
import studio.fantasyit.maid_useful_task.util.Conditions; import studio.fantasyit.maid_useful_task.util.Conditions;
import studio.fantasyit.maid_useful_task.util.MemoryUtil; import studio.fantasyit.maid_useful_task.util.MemoryUtil;
@@ -30,16 +29,16 @@ public class PlaceBlockMoveBehavior extends MaidCenterMoveToBlockTask {
@Override @Override
protected boolean checkExtraStartConditions(ServerLevel p_22538_, EntityMaid p_22539_) { protected boolean checkExtraStartConditions(ServerLevel p_22538_, EntityMaid maid) {
if (MemoryUtil.getRateLimitToken(p_22539_).isFor(TaskRateLimitToken.Level.L2)) { if (!Conditions.isCurrent(maid, CurrentWork.IDLE)) return false;
return false; return super.checkExtraStartConditions(p_22538_, maid);
}
return super.checkExtraStartConditions(p_22538_, p_22539_);
} }
@Override @Override
protected void start(ServerLevel p_22540_, EntityMaid maid, long p_22542_) { protected void start(ServerLevel p_22540_, EntityMaid maid, long p_22542_) {
super.start(p_22540_, maid, p_22542_); super.start(p_22540_, maid, p_22542_);
if (maid.hasRestriction())
this.setSearchRange((int) maid.getRestrictRadius());
task = (IMaidBlockPlaceTask) maid.getTask(); task = (IMaidBlockPlaceTask) maid.getTask();
CombinedInvWrapper inv = maid.getAvailableInv(true); CombinedInvWrapper inv = maid.getAvailableInv(true);
List<ItemStack> markedVis = new ArrayList<>(); List<ItemStack> markedVis = new ArrayList<>();
@@ -52,6 +51,7 @@ public class PlaceBlockMoveBehavior extends MaidCenterMoveToBlockTask {
@Nullable BlockPos target = MemoryUtil.getTargetPos(maid); @Nullable BlockPos target = MemoryUtil.getTargetPos(maid);
if (target != null) { if (target != null) {
MemoryUtil.setPlaceTarget(maid, targetPos); MemoryUtil.setPlaceTarget(maid, targetPos);
MemoryUtil.setCurrent(maid, CurrentWork.PLACE);
inv.setStackInSlot(finalI, maid.getMainHandItem()); inv.setStackInSlot(finalI, maid.getMainHandItem());
maid.setItemInHand(InteractionHand.MAIN_HAND, targetItem); maid.setItemInHand(InteractionHand.MAIN_HAND, targetItem);
return; return;
@@ -62,7 +62,8 @@ public class PlaceBlockMoveBehavior extends MaidCenterMoveToBlockTask {
@Override @Override
protected boolean shouldMoveTo(ServerLevel serverLevel, EntityMaid entityMaid, BlockPos blockPos) { protected boolean shouldMoveTo(ServerLevel serverLevel, EntityMaid entityMaid, BlockPos blockPos) {
if (!task.shouldPlacePos(entityMaid, targetItem, blockPos)) return false; if (!task.shouldPlacePos(entityMaid, targetItem, blockPos.immutable())) return false;
if (!entityMaid.isWithinRestriction(blockPos)) return false;
targetPos = blockPos.immutable(); targetPos = blockPos.immutable();
if (blockPos instanceof BlockPos.MutableBlockPos mb) { if (blockPos instanceof BlockPos.MutableBlockPos mb) {
final int[] dv = {0, 1, -1}; final int[] dv = {0, 1, -1};
@@ -87,7 +88,10 @@ public class PlaceBlockMoveBehavior extends MaidCenterMoveToBlockTask {
@Override @Override
protected @NotNull MaidPathFindingBFS getOrCreateArrivalMap(@NotNull ServerLevel worldIn, @NotNull EntityMaid maid) { protected @NotNull MaidPathFindingBFS getOrCreateArrivalMap(@NotNull ServerLevel worldIn, @NotNull EntityMaid maid) {
if (this.pathfindingBFS == null) if (this.pathfindingBFS == null)
this.pathfindingBFS = new MaidPathFindingBFS(maid.getNavigation().getNodeEvaluator(), worldIn, maid, 10); if (maid.hasRestriction())
this.pathfindingBFS = new MaidPathFindingBFS(maid.getNavigation().getNodeEvaluator(), worldIn, maid, 14, (int) maid.getRestrictRadius());
else
this.pathfindingBFS = new MaidPathFindingBFS(maid.getNavigation().getNodeEvaluator(), worldIn, maid, 14);
return this.pathfindingBFS; return this.pathfindingBFS;
} }

View File

@@ -0,0 +1,24 @@
package studio.fantasyit.maid_useful_task.behavior;
import com.github.tartaricacid.touhoulittlemaid.entity.ai.brain.task.MaidCheckRateTask;
import com.github.tartaricacid.touhoulittlemaid.entity.passive.EntityMaid;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.ai.memory.MemoryStatus;
import studio.fantasyit.maid_useful_task.registry.MemoryModuleRegistry;
import studio.fantasyit.maid_useful_task.util.MemoryUtil;
import java.util.Map;
public class UpdateValidationMemoryBehavior extends MaidCheckRateTask {
public UpdateValidationMemoryBehavior() {
super(Map.of(MemoryModuleRegistry.BLOCK_VALIDATION.get(), MemoryStatus.VALUE_PRESENT));
this.setMaxCheckRate(600);
}
@Override
protected void start(ServerLevel p_22540_, EntityMaid p_22541_, long p_22542_) {
//Hardcoded range?
MemoryUtil.getBlockValidationMemory(p_22541_).clearFaraway(p_22541_.blockPosition(), 72);
MemoryUtil.getBlockValidationMemory(p_22541_).clearIf(pos -> p_22540_.getBlockState(pos).isAir());
}
}

View File

@@ -0,0 +1,75 @@
package studio.fantasyit.maid_useful_task.memory;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.core.BlockPos;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Predicate;
public class BlockValidationMemory {
public static final Codec<BlockValidationMemory> CODEC = RecordCodecBuilder.create(instance -> instance.group(
Codec.list(BlockPos.CODEC).fieldOf("validList").forGetter(BlockValidationMemory::getValidList),
Codec.list(BlockPos.CODEC).fieldOf("invalidList").forGetter(BlockValidationMemory::getInvalidList)
).apply(instance, BlockValidationMemory::new)
);
private final Set<BlockPos> validSet = new HashSet<>();
private final Set<BlockPos> invalidSet = new HashSet<>();
public BlockValidationMemory() {
}
public BlockValidationMemory(List<BlockPos> validList, List<BlockPos> invalidList) {
validSet.addAll(validList);
invalidSet.addAll(invalidList);
}
public List<BlockPos> getValidList() {
return List.copyOf(validSet);
}
public List<BlockPos> getInvalidList() {
return List.copyOf(invalidSet);
}
public void setValid(BlockPos blockPos) {
validSet.add(blockPos);
invalidSet.remove(blockPos);
}
public void setInvalid(BlockPos blockPos) {
invalidSet.add(blockPos);
validSet.remove(blockPos);
}
public void remove(BlockPos blockPos) {
validSet.remove(blockPos);
invalidSet.remove(blockPos);
}
public boolean isValid(BlockPos blockPos, boolean defaultValue) {
if (validSet.contains(blockPos)) {
return true;
}
if (invalidSet.contains(blockPos)) {
return false;
}
return defaultValue;
}
public boolean hasRecord(BlockPos blockPos) {
return validSet.contains(blockPos) || invalidSet.contains(blockPos);
}
public void clearFaraway(BlockPos blockPos, int range) {
clearIf(pos->pos.distSqr(blockPos) > range * range);
}
public void clearIf(Predicate<BlockPos> o) {
validSet.removeIf(o);
invalidSet.removeIf(o);
}
}

View File

@@ -0,0 +1,10 @@
package studio.fantasyit.maid_useful_task.memory;
public enum CurrentWork {
IDLE,
PLACE,
DESTROY,
BLOCKUP_UP,
BLOCKUP_DOWN,
BLOCKUP_DESTROY
}

View File

@@ -6,13 +6,15 @@ 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 studio.fantasyit.maid_useful_task.memory.CurrentWork;
import studio.fantasyit.maid_useful_task.util.Conditions;
import studio.fantasyit.maid_useful_task.util.MemoryUtil; import studio.fantasyit.maid_useful_task.util.MemoryUtil;
@Mixin(EntityMaid.class) @Mixin(EntityMaid.class)
public abstract class MaidCheckPickupItem { public abstract class MaidCheckPickupItem {
@Inject(method = "pickupItem", at = @At("HEAD"), cancellable = true, remap = false) @Inject(method = "pickupItem", at = @At("HEAD"), cancellable = true, remap = false)
public void maid_storage_manager$pickupItem(ItemEntity entityItem, boolean simulate, CallbackInfoReturnable<Boolean> cir) { public void maid_storage_manager$pickupItem(ItemEntity entityItem, boolean simulate, CallbackInfoReturnable<Boolean> cir) {
if (MemoryUtil.getBlockUpContext((EntityMaid) (Object) this).hasTarget()) { if (!Conditions.isCurrent((EntityMaid) (Object) this, CurrentWork.IDLE)) {
cir.setReturnValue(false); cir.setReturnValue(false);
} }
} }

View File

@@ -16,12 +16,13 @@ abstract public class MaidMoveControlMixin {
@Final @Final
private EntityMaid maid; private EntityMaid maid;
@Inject(method = "tick", at = @At("HEAD"), remap = false, cancellable = true) @Inject(method = "tick", at = @At("HEAD"), cancellable = true)
public void tick(CallbackInfo ci) { public void tick(CallbackInfo ci) {
if (MemoryUtil.getBlockUpContext(this.maid).hasTarget()) { if (switch (MemoryUtil.getCurrent(maid)) {
if (MemoryUtil.getBlockUpContext(this.maid).isOnLine(this.maid.blockPosition())) { case BLOCKUP_DESTROY, BLOCKUP_DOWN -> true;
ci.cancel(); default -> false;
} }) {
ci.cancel();
} }
} }
} }

View File

@@ -7,13 +7,16 @@ 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 studio.fantasyit.maid_useful_task.memory.CurrentWork;
import studio.fantasyit.maid_useful_task.util.Conditions;
import studio.fantasyit.maid_useful_task.util.MemoryUtil; import studio.fantasyit.maid_useful_task.util.MemoryUtil;
@Mixin(MaidRunOne.class) @Mixin(MaidRunOne.class)
abstract public class MaidRunOneMixin { abstract public class MaidRunOneMixin {
@Inject(method = "tryStart(Lnet/minecraft/server/level/ServerLevel;Lcom/github/tartaricacid/touhoulittlemaid/entity/passive/EntityMaid;J)Z", at = @At("HEAD"), cancellable = true, remap = false) @Inject(method = "tryStart(Lnet/minecraft/server/level/ServerLevel;Lcom/github/tartaricacid/touhoulittlemaid/entity/passive/EntityMaid;J)Z", at = @At("HEAD"), cancellable = true, remap = false)
public void runOne(ServerLevel pLevel, EntityMaid maid, long pGameTime, CallbackInfoReturnable<Boolean> cir) { public void runOne(ServerLevel pLevel, EntityMaid maid, long pGameTime, CallbackInfoReturnable<Boolean> cir) {
if (MemoryUtil.getDestroyTargetMemory(maid) != null || MemoryUtil.getPlaceTarget(maid) != null || MemoryUtil.getBlockUpContext(maid).hasTarget()) if (!Conditions.isCurrent(maid, CurrentWork.IDLE)) {
cir.setReturnValue(false); cir.setReturnValue(false);
}
} }
} }

View File

@@ -7,9 +7,8 @@ import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.RegistryObject; import net.minecraftforge.registries.RegistryObject;
import studio.fantasyit.maid_useful_task.MaidUsefulTask; import studio.fantasyit.maid_useful_task.MaidUsefulTask;
import studio.fantasyit.maid_useful_task.memory.BlockTargetMemory; import studio.fantasyit.maid_useful_task.memory.*;
import studio.fantasyit.maid_useful_task.memory.BlockUpContext; import studio.fantasyit.maid_useful_task.util.WrappedMaidFakePlayer;
import studio.fantasyit.maid_useful_task.memory.TaskRateLimitToken;
import java.util.Optional; import java.util.Optional;
@@ -22,8 +21,9 @@ public class MemoryModuleRegistry {
= REGISTER.register("place_target", () -> new MemoryModuleType<>(Optional.empty())); = REGISTER.register("place_target", () -> new MemoryModuleType<>(Optional.empty()));
public static final RegistryObject<MemoryModuleType<BlockUpContext>> BLOCK_UP_TARGET public static final RegistryObject<MemoryModuleType<BlockUpContext>> BLOCK_UP_TARGET
= REGISTER.register("block_up", () -> new MemoryModuleType<>(Optional.of(BlockUpContext.CODEC))); = REGISTER.register("block_up", () -> new MemoryModuleType<>(Optional.of(BlockUpContext.CODEC)));
public static final RegistryObject<MemoryModuleType<TaskRateLimitToken>> RATE_LIMIT_TOKEN public static final RegistryObject<MemoryModuleType<BlockValidationMemory>> BLOCK_VALIDATION
= REGISTER.register("task_rate_limit", () -> new MemoryModuleType<>(Optional.empty())); = REGISTER.register("block_validation", () -> new MemoryModuleType<>(Optional.of(BlockValidationMemory.CODEC)));
public static final RegistryObject<MemoryModuleType<CurrentWork>> CURRENT_WORK = REGISTER.register("current_work", () -> new MemoryModuleType<>(Optional.empty()));
public static void register(IEventBus eventBus) { public static void register(IEventBus eventBus) {
REGISTER.register(eventBus); REGISTER.register(eventBus);

View File

@@ -3,12 +3,14 @@ package studio.fantasyit.maid_useful_task.task;
import com.github.tartaricacid.touhoulittlemaid.api.task.IMaidTask; import com.github.tartaricacid.touhoulittlemaid.api.task.IMaidTask;
import com.github.tartaricacid.touhoulittlemaid.entity.passive.EntityMaid; import com.github.tartaricacid.touhoulittlemaid.entity.passive.EntityMaid;
import com.github.tartaricacid.touhoulittlemaid.entity.passive.MaidPathFindingBFS; import com.github.tartaricacid.touhoulittlemaid.entity.passive.MaidPathFindingBFS;
import com.github.tartaricacid.touhoulittlemaid.util.CenterOffsetBlockPosSet;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionHand;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraftforge.items.wrapper.CombinedInvWrapper; import net.minecraftforge.items.wrapper.CombinedInvWrapper;
import oshi.util.tuples.Pair; import oshi.util.tuples.Pair;
import studio.fantasyit.maid_useful_task.util.MaidUtils;
import studio.fantasyit.maid_useful_task.util.PosUtils; import studio.fantasyit.maid_useful_task.util.PosUtils;
public interface IMaidBlockUpTask { public interface IMaidBlockUpTask {
@@ -27,7 +29,6 @@ public interface IMaidBlockUpTask {
for (int dz = 0; dz < touchLimit(); dz = dz <= 0 ? 1 - dz : -dz) { for (int dz = 0; dz < touchLimit(); dz = dz <= 0 ? 1 - dz : -dz) {
for (int dy = 0; dy < verticalDistance(); dy++) { for (int dy = 0; dy < verticalDistance(); dy++) {
BlockPos targetPos = startPos.offset(dx, dy, dz); BlockPos targetPos = startPos.offset(dx, dy, dz);
if (maid.hasRestriction() && !maid.isWithinRestriction(targetPos)) break;
if (isFindingBlock(maid, targetPos, startPos)) { if (isFindingBlock(maid, targetPos, startPos)) {
return true; return true;
} }
@@ -37,55 +38,75 @@ public interface IMaidBlockUpTask {
return false; return false;
} }
default Pair<BlockPos, BlockPos> findTargetPosBlockUp(EntityMaid maid, BlockPos center) { default Pair<BlockPos, BlockPos> findTargetPosBlockUp(EntityMaid maid, BlockPos center, int maxUp) {
ServerLevel level = (ServerLevel) maid.level(); ServerLevel level = (ServerLevel) maid.level();
MaidPathFindingBFS pathFindingBFS = new MaidPathFindingBFS(maid.getNavigation().getNodeEvaluator(), level, maid); int maxHeight = verticalOffset() + verticalDistance();
for (int dx = 0; dx < scanRange(); dx = dx <= 0 ? 1 - dx : -dx) { CenterOffsetBlockPosSet notAvailable = new CenterOffsetBlockPosSet(scanRange(maid), scanRange(maid) + maxHeight / 2 + 1, scanRange(maid), center.getX(), center.getY() + maxHeight / 2, center.getZ());
for (int dz = 0; dz < scanRange(); dz = dz <= 0 ? 1 - dz : -dz) { MaidPathFindingBFS pathFindingBFS = new MaidPathFindingBFS(maid.getNavigation().getNodeEvaluator(), level, maid, 7, scanRange(maid));
BlockPos.MutableBlockPos mb = center.offset(dx, 0, dz).mutable(); for (int dx = 0; dx < scanRange(maid); dx = dx <= 0 ? 1 - dx : -dx) {
while (level.getBlockState(mb).canBeReplaced()) mb.move(0, -1, 0); for (int dz = 0; dz < scanRange(maid); dz = dz <= 0 ? 1 - dz : -dz) {
while (!level.getBlockState(mb).canBeReplaced()) mb.move(0, 1, 0); //计算地面的位置
if (!PosUtils.isFourSideAir(level, mb)) continue; BlockPos.MutableBlockPos ground = center.offset(dx, 0, dz).mutable();
if (!pathFindingBFS.canPathReach(mb)) continue; while (level.getBlockState(ground).canBeReplaced()) ground.move(0, -1, 0);
while (!level.getBlockState(ground).canBeReplaced()) ground.move(0, 1, 0);
if (notAvailable.isVis(ground)) continue;
//地面基本判断
if (!PosUtils.isFourSideAir(level, ground.immutable())) continue;
if (!pathFindingBFS.canPathReach(ground)) continue;
boolean valid = true; boolean valid = true;
for (int dy = 0; dy < verticalOffset(); dy++) { for (int dy = 0; dy < verticalOffset(); dy++) {
BlockPos targetPos = center.offset(dx, dy, dz); BlockPos targetPos = ground.above(dy);
if (!level.getBlockState(targetPos).canBeReplaced()) { if (!level.getBlockState(targetPos).canBeReplaced()) {
valid = false; valid = false;
break; break;
} }
} }
for (int dy = verticalDistance(); dy < verticalDistance() + 2; dy++) { for (int dy = verticalOffset(); dy < verticalOffset() + 2; dy++) {
BlockPos targetPos = center.offset(dx, dy, dz); BlockPos targetPos = ground.above(dy);
if (!level.getBlockState(targetPos).isAir()) { if (!level.getBlockState(targetPos).isAir()) {
valid = false; valid = false;
break; break;
} }
} }
if (!valid) if (!valid) {
notAvailable.markVis(ground.immutable());
continue; continue;
int touchLimit = touchLimit() + 1;
boolean continuous = true;
BlockPos standPos = center.offset(dx, verticalOffset(), dz);
for (int dy = verticalOffset(); dy < verticalDistance() + verticalOffset(); dy++) {
BlockPos targetPos = center.offset(dx, dy, dz);
if (maid.hasRestriction() && !maid.isWithinRestriction(targetPos)) break;
if (isFindingBlock(maid, targetPos, standPos)) {
return new Pair<>(mb, standPos);
}
//头顶一格是不是空气,不是:不连续空间(不能继续垫了,那么需要计算触及范围
if (!level.getBlockState(standPos.above().above()).isAir()) {
continuous = false;
}
if (!continuous) {
touchLimit--;
} else {
standPos = standPos.above();
}
if (touchLimit <= 0)
break;
} }
//竖直方向触及
for (int sdx = 0; sdx < 2; sdx = sdx <= 0 ? 1 - sdx : -sdx)
for (int sdz = 0; sdz < 2; sdz = sdz <= 0 ? 1 - sdz : -sdz) {
int touchLimit = touchLimit() + 1;
boolean continuous = true;
BlockPos standPos = ground.above(verticalOffset()).offset(sdx, 0, sdz);
if (standPos.getY() - ground.getY() > maxUp)
continue;
for (int dy = verticalOffset(); dy < verticalDistance() + verticalOffset(); dy++) {
BlockPos targetPos = ground.offset(sdx, dy, sdz);
if (targetPos.distSqr(standPos) > touchLimit * touchLimit) break;
if (maid.hasRestriction() && !maid.isWithinRestriction(standPos)) break;
if (isFindingBlock(maid, targetPos, standPos)) {
return new Pair<>(ground.immutable(), standPos);
}
//头顶一格是不是空气,不是:不连续空间(不能继续垫了,那么需要计算触及范围
if (continuous) {
if (!level.getBlockState(standPos.above().above()).isAir()) {
continuous = false;
} else if (maid.hasRestriction() && !maid.isWithinRestriction(standPos.above())) {
continuous = false;
}
}
if (!continuous) {
touchLimit--;
} else {
standPos = standPos.above();
if (standPos.getY() - ground.getY() > maxUp)
break;
}
if (touchLimit <= 0)
break;
}
}
} }
} }
return null; return null;
@@ -97,7 +118,7 @@ public interface IMaidBlockUpTask {
for (int i = 0; i < inv.getSlots(); i++) { for (int i = 0; i < inv.getSlots(); i++) {
ItemStack stack = inv.getStackInSlot(i); ItemStack stack = inv.getStackInSlot(i);
if (isValidItemStack(maid, stack)) { if (isValidItemStack(maid, stack)) {
count++; count += stack.getCount();
} }
} }
return count; return count;
@@ -141,11 +162,19 @@ public interface IMaidBlockUpTask {
return 15; return 15;
} }
default int scanRange() { default int scanRange(EntityMaid maid) {
return 10; return maid.hasRestriction() ? (int) maid.getRestrictRadius() : 15;
} }
default int touchLimit() { default int touchLimit() {
return 7; return 7;
} }
default boolean tryPlaceBlockUp(EntityMaid maid, BlockPos targetPos) {
return MaidUtils.placeBlock(maid, targetPos);
}
default boolean tryDestroyBlockUp(EntityMaid maid, BlockPos targetPos) {
return MaidUtils.destroyBlock(maid, targetPos);
}
} }

View File

@@ -20,10 +20,15 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import studio.fantasyit.maid_useful_task.MaidUsefulTask; import studio.fantasyit.maid_useful_task.MaidUsefulTask;
import studio.fantasyit.maid_useful_task.behavior.*; import studio.fantasyit.maid_useful_task.behavior.*;
import studio.fantasyit.maid_useful_task.memory.BlockValidationMemory;
import studio.fantasyit.maid_useful_task.util.MaidUtils;
import studio.fantasyit.maid_useful_task.util.MemoryUtil;
import studio.fantasyit.maid_useful_task.util.WrappedMaidFakePlayer; import studio.fantasyit.maid_useful_task.util.WrappedMaidFakePlayer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
public class MaidTreeTask implements IMaidTask, IMaidBlockPlaceTask, IMaidBlockDestroyTask, IMaidBlockUpTask { public class MaidTreeTask implements IMaidTask, IMaidBlockPlaceTask, IMaidBlockDestroyTask, IMaidBlockUpTask {
@Override @Override
@@ -49,12 +54,22 @@ public class MaidTreeTask implements IMaidTask, IMaidBlockPlaceTask, IMaidBlockD
@Override @Override
public boolean shouldDestroyBlock(EntityMaid maid, BlockPos pos) { public boolean shouldDestroyBlock(EntityMaid maid, BlockPos pos) {
if (MemoryUtil.getBlockUpContext(maid).hasTarget()) {
if (pos.getY() < maid.getBlockY() && pos.getX() == maid.getBlockX() && pos.getZ() == maid.getBlockZ()) {
return false;
}
}
BlockState blockState = maid.level().getBlockState(pos); BlockState blockState = maid.level().getBlockState(pos);
return blockState.is(BlockTags.LOGS) && isValidNatureTree(maid, pos); return blockState.is(BlockTags.LOGS) && isValidNatureTree(maid, pos);
} }
@Override @Override
public boolean mayDestroy(EntityMaid maid, BlockPos pos) { public boolean mayDestroy(EntityMaid maid, BlockPos pos) {
if (MemoryUtil.getBlockUpContext(maid).hasTarget()) {
if (pos.getY() < maid.getBlockY() && pos.getX() == maid.getBlockX() && pos.getZ() == maid.getBlockZ()) {
return false;
}
}
BlockState blockState = maid.level().getBlockState(pos); BlockState blockState = maid.level().getBlockState(pos);
if (blockState.is(BlockTags.LEAVES)) { if (blockState.is(BlockTags.LEAVES)) {
return true; return true;
@@ -133,34 +148,56 @@ public class MaidTreeTask implements IMaidTask, IMaidBlockPlaceTask, IMaidBlockD
return IMaidBlockDestroyTask.super.availableToGetDrop(maid, fakePlayer, pos, targetBlockState); return IMaidBlockDestroyTask.super.availableToGetDrop(maid, fakePlayer, pos, targetBlockState);
} }
protected boolean isValidNatureTree(EntityMaid maid, BlockPos startPos) { protected boolean isValidNatureTree(EntityMaid maid, BlockPos startPos) {
return isValidNatureTree(maid, startPos, new HashSet<>());
}
protected boolean isValidNatureTree(EntityMaid maid, BlockPos startPos, Set<BlockPos> visited) {
BlockValidationMemory validationMemory = MemoryUtil.getBlockValidationMemory(maid);
if (validationMemory.hasRecord(startPos))
return validationMemory.isValid(startPos, false);
if (visited.contains(startPos))
return false;
visited.add(startPos);
boolean valid = false;
final int[] dv = {0, 1, -1}; final int[] dv = {0, 1, -1};
for (int dx : dv) { for (int dx : dv) {
for (int dz : dv) { for (int dz : dv) {
for (int dy = 0; dy < 6; dy++) { for (int dy : dv) {
BlockState blockState = maid.level().getBlockState(startPos.offset(dx, dy, dz)); BlockPos offset = startPos.offset(dx, dy, dz);
BlockState blockState = maid.level().getBlockState(offset);
if (blockState.is(BlockTags.LEAVES) && !blockState.getValue(LeavesBlock.PERSISTENT)) { if (blockState.is(BlockTags.LEAVES) && !blockState.getValue(LeavesBlock.PERSISTENT)) {
return true; valid = true;
}
if (blockState.is(BlockTags.LOGS) && isValidNatureTree(maid, offset, visited)) {
valid = true;
} }
} }
} }
} }
return false; if (valid)
validationMemory.setValid(startPos);
else
validationMemory.setInvalid(startPos);
return valid;
} }
@Override @Override
public List<Pair<Integer, BehaviorControl<? super EntityMaid>>> createBrainTasks(EntityMaid entityMaid) { public List<Pair<Integer, BehaviorControl<? super EntityMaid>>> createBrainTasks(EntityMaid entityMaid) {
ArrayList<Pair<Integer, BehaviorControl<? super EntityMaid>>> list = new ArrayList<>(); ArrayList<Pair<Integer, BehaviorControl<? super EntityMaid>>> list = new ArrayList<>();
list.add(Pair.of(6, new LoopWithTokenBehavior()));
list.add(Pair.of(5, new DestoryBlockBehavior())); list.add(Pair.of(1, new DestoryBlockBehavior()));
list.add(Pair.of(4, new DestoryBlockMoveBehavior())); list.add(Pair.of(1, new DestoryBlockMoveBehavior()));
list.add(Pair.of(2, new BlockUpScheduleBehavior()));
list.add(Pair.of(2, new BlockUpPlaceBehavior()));
list.add(Pair.of(2, new BlockUpDestroyBehavior()));
list.add(Pair.of(3, new PlaceBlockBehavior())); list.add(Pair.of(3, new PlaceBlockBehavior()));
list.add(Pair.of(2, new PlaceBlockMoveBehavior())); list.add(Pair.of(3, new PlaceBlockMoveBehavior()));
list.add(Pair.of(1, new BlockUpScheduleBehavior())); list.add(Pair.of(4, new UpdateValidationMemoryBehavior()));
list.add(Pair.of(0, new BlockUpPlaceBehavior()));
list.add(Pair.of(0, new BlockUpDestroyBehavior()));
return list; return list;
} }
@@ -181,4 +218,27 @@ public class MaidTreeTask implements IMaidTask, IMaidBlockPlaceTask, IMaidBlockD
return false; return false;
return maid.level().getBlockState(target).is(BlockTags.LOGS) && isValidNatureTree(maid, target); return maid.level().getBlockState(target).is(BlockTags.LOGS) && isValidNatureTree(maid, target);
} }
@Override
public boolean tryDestroyBlockUp(EntityMaid maid, BlockPos targetPos) {
return tryDestroyBlock(maid, targetPos);
}
@Override
public boolean tryPlaceBlock(EntityMaid maid, BlockPos pos) {
if (IMaidBlockPlaceTask.super.tryPlaceBlock(maid, pos)) {
MemoryUtil.getBlockValidationMemory(maid).setValid(pos);
return true;
}
return false;
}
@Override
public boolean tryDestroyBlock(EntityMaid maid, BlockPos blockPos) {
if (MaidUtils.destroyBlock(maid, blockPos)) {
MemoryUtil.getBlockValidationMemory(maid).remove(blockPos);
return true;
}
return false;
}
} }

View File

@@ -7,6 +7,7 @@ import net.minecraft.world.entity.ai.Brain;
import net.minecraft.world.entity.ai.memory.MemoryModuleType; import net.minecraft.world.entity.ai.memory.MemoryModuleType;
import net.minecraft.world.entity.ai.memory.WalkTarget; import net.minecraft.world.entity.ai.memory.WalkTarget;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import studio.fantasyit.maid_useful_task.memory.CurrentWork;
import studio.fantasyit.maid_useful_task.registry.MemoryModuleRegistry; import studio.fantasyit.maid_useful_task.registry.MemoryModuleRegistry;
import java.util.Optional; import java.util.Optional;
@@ -24,6 +25,7 @@ public class Conditions {
Optional<WalkTarget> walkTarget = brain.getMemory(MemoryModuleType.WALK_TARGET); Optional<WalkTarget> walkTarget = brain.getMemory(MemoryModuleType.WALK_TARGET);
if (walkTarget.isEmpty() || !walkTarget.get().getTarget().currentPosition().equals(targetV3d)) { if (walkTarget.isEmpty() || !walkTarget.get().getTarget().currentPosition().equals(targetV3d)) {
brain.eraseMemory(InitEntities.TARGET_POS.get()); brain.eraseMemory(InitEntities.TARGET_POS.get());
MemoryUtil.setCurrent(maid, CurrentWork.IDLE);
} }
return false; return false;
} }
@@ -41,10 +43,12 @@ public class Conditions {
public static boolean isGlobalValidTarget(EntityMaid maid, BlockPos pos, BlockPos targetPos) { public static boolean isGlobalValidTarget(EntityMaid maid, BlockPos pos, BlockPos targetPos) {
if (MemoryUtil.getBlockUpContext(maid).hasTarget()) { if (MemoryUtil.getBlockUpContext(maid).hasTarget()) {
if (targetPos.getY() < maid.getBlockY() && targetPos.getX() == maid.getBlockX() && targetPos.getZ() == maid.getBlockZ())
return false;
return MemoryUtil.getBlockUpContext(maid).isTarget(pos); return MemoryUtil.getBlockUpContext(maid).isTarget(pos);
} }
return true; return true;
} }
public static boolean isCurrent(EntityMaid maid, CurrentWork currentWork) {
return MemoryUtil.getCurrent(maid) == currentWork;
}
} }

View File

@@ -37,7 +37,27 @@ public class MaidUtils {
} }
} }
} }
public static boolean destroyBlock(EntityMaid maid, BlockPos blockPos){
public static float getDestroyProgressDelta(EntityMaid maid, BlockPos blockPos) {
WrappedMaidFakePlayer fakePlayer = WrappedMaidFakePlayer.get(maid);
BlockState blockState = maid.level().getBlockState(blockPos);
return blockState.getDestroyProgress(fakePlayer, maid.level(), blockPos);
}
public static BlockPos getMaidRestrictCenter(EntityMaid maid) {
if (MemoryUtil.getBlockUpContext(maid).hasTarget()) {
return MemoryUtil.getBlockUpContext(maid).getTargetPos();
}
if (maid.hasRestriction())
return maid.getRestrictCenter();
return maid.blockPosition();
}
public static boolean destroyBlock(EntityMaid maid, BlockPos blockPos) {
WrappedMaidFakePlayer fakePlayer = WrappedMaidFakePlayer.get(maid);
maid.getMainHandItem().hurtAndBreak(1, fakePlayer, (p_186374_) -> {
p_186374_.broadcastBreakEvent(InteractionHand.MAIN_HAND);
});
ServerLevel level = (ServerLevel) maid.level(); ServerLevel level = (ServerLevel) maid.level();
BlockState blockState = level.getBlockState(blockPos); BlockState blockState = level.getBlockState(blockPos);
if (blockState.isAir()) { if (blockState.isAir()) {
@@ -62,7 +82,7 @@ public class MaidUtils {
} }
public static boolean placeBlock(EntityMaid maid, BlockPos pos) { public static boolean placeBlock(EntityMaid maid, BlockPos pos) {
Player fakePlayer = WrappedMaidFakePlayer.get(maid); WrappedMaidFakePlayer fakePlayer = WrappedMaidFakePlayer.get(maid);
BlockHitResult result = null; BlockHitResult result = null;
ClipContext rayTraceContext = new ClipContext(maid.getPosition(0).add(0, maid.getEyeHeight(), 0), ClipContext rayTraceContext = new ClipContext(maid.getPosition(0).add(0, maid.getEyeHeight(), 0),
pos.getCenter(), pos.getCenter(),

View File

@@ -5,13 +5,12 @@ import com.github.tartaricacid.touhoulittlemaid.init.InitEntities;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.ai.Brain; import net.minecraft.world.entity.ai.Brain;
import net.minecraft.world.entity.ai.behavior.BehaviorUtils;
import net.minecraft.world.entity.ai.behavior.BlockPosTracker; import net.minecraft.world.entity.ai.behavior.BlockPosTracker;
import net.minecraft.world.entity.ai.behavior.PositionTracker; import net.minecraft.world.entity.ai.behavior.PositionTracker;
import net.minecraft.world.entity.ai.memory.MemoryModuleType; import net.minecraft.world.entity.ai.memory.MemoryModuleType;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import studio.fantasyit.maid_useful_task.memory.BlockTargetMemory; import studio.fantasyit.maid_useful_task.memory.*;
import studio.fantasyit.maid_useful_task.memory.BlockUpContext;
import studio.fantasyit.maid_useful_task.memory.TaskRateLimitToken;
import studio.fantasyit.maid_useful_task.registry.MemoryModuleRegistry; import studio.fantasyit.maid_useful_task.registry.MemoryModuleRegistry;
import java.util.List; import java.util.List;
@@ -62,12 +61,23 @@ public class MemoryUtil {
} }
return brain.getMemory(MemoryModuleRegistry.BLOCK_UP_TARGET.get()).get(); return brain.getMemory(MemoryModuleRegistry.BLOCK_UP_TARGET.get()).get();
} }
public static TaskRateLimitToken getRateLimitToken(EntityMaid maid){ public static BlockValidationMemory getBlockValidationMemory(EntityMaid maid){
Brain<EntityMaid> brain = maid.getBrain(); Brain<EntityMaid> brain = maid.getBrain();
if(!brain.hasMemoryValue(MemoryModuleRegistry.RATE_LIMIT_TOKEN.get())){ if(!brain.hasMemoryValue(MemoryModuleRegistry.BLOCK_VALIDATION.get())){
brain.setMemory(MemoryModuleRegistry.RATE_LIMIT_TOKEN.get(), new TaskRateLimitToken()); brain.setMemory(MemoryModuleRegistry.BLOCK_VALIDATION.get(), new BlockValidationMemory());
} }
return brain.getMemory(MemoryModuleRegistry.RATE_LIMIT_TOKEN.get()).get(); return brain.getMemory(MemoryModuleRegistry.BLOCK_VALIDATION.get()).get();
} }
public static void setTarget(EntityMaid maid, BlockPos targetPos,float speed) {
maid.getBrain().setMemory(InitEntities.TARGET_POS.get(), new BlockPosTracker(targetPos));
BehaviorUtils.setWalkAndLookTargetMemories(maid, targetPos, speed, 0);
}
public static CurrentWork getCurrent(EntityMaid maid){
return maid.getBrain().getMemory(MemoryModuleRegistry.CURRENT_WORK.get()).orElse(CurrentWork.IDLE);
}
public static void setCurrent(EntityMaid maid, CurrentWork currentWork){
maid.getBrain().setMemory(MemoryModuleRegistry.CURRENT_WORK.get(), currentWork);
}
} }

View File

@@ -3,9 +3,13 @@ package studio.fantasyit.maid_useful_task.util;
import com.github.tartaricacid.touhoulittlemaid.entity.passive.EntityMaid; import com.github.tartaricacid.touhoulittlemaid.entity.passive.EntityMaid;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.nbt.ListTag;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.tags.TagKey; import net.minecraft.tags.TagKey;
import net.minecraft.world.Container;
import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionHand;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.effect.MobEffect; import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
@@ -13,6 +17,9 @@ import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.HumanoidArm; import net.minecraft.world.entity.HumanoidArm;
import net.minecraft.world.entity.RelativeMovement; import net.minecraft.world.entity.RelativeMovement;
import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.player.StackedContents;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
@@ -20,6 +27,9 @@ import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import net.minecraftforge.common.util.FakePlayer; import net.minecraftforge.common.util.FakePlayer;
import net.minecraftforge.items.wrapper.CombinedInvWrapper;
import net.minecraftforge.items.wrapper.PlayerInvWrapper;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.Collection; import java.util.Collection;
@@ -27,8 +37,28 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Predicate;
public class WrappedMaidFakePlayer extends FakePlayer { public class WrappedMaidFakePlayer extends FakePlayer {
public static class WrappedMaidInventory extends Inventory {
private final EntityMaid maid;
public WrappedMaidInventory(EntityMaid p_35983_, WrappedMaidFakePlayer fakePlayer) {
super(fakePlayer);
this.maid = p_35983_;
}
@Override
public @NotNull ItemStack getSelected() {
return maid.getMainHandItem();
}
@Override
public float getDestroySpeed(BlockState p_36021_) {
return maid.getMainHandItem().getDestroySpeed(p_36021_);
}
}
private static ConcurrentHashMap<UUID, WrappedMaidFakePlayer> cache = new ConcurrentHashMap<>(); private static ConcurrentHashMap<UUID, WrappedMaidFakePlayer> cache = new ConcurrentHashMap<>();
private final EntityMaid maid; private final EntityMaid maid;
@@ -50,6 +80,7 @@ public class WrappedMaidFakePlayer extends FakePlayer {
private WrappedMaidFakePlayer(EntityMaid maid) { private WrappedMaidFakePlayer(EntityMaid maid) {
super((ServerLevel) maid.level(), new GameProfile(UUID.randomUUID(), maid.getName().getString())); super((ServerLevel) maid.level(), new GameProfile(UUID.randomUUID(), maid.getName().getString()));
this.maid = maid; this.maid = maid;
this.inventory = new WrappedMaidInventory(maid, this);
} }
@Override @Override

View File

@@ -1 +1,2 @@
public net.minecraft.world.level.BlockGetter m_151361_(Lnet/minecraft/world/phys/Vec3;Lnet/minecraft/world/phys/Vec3;Ljava/lang/Object;Ljava/util/function/BiFunction;Ljava/util/function/Function;)Ljava/lang/Object; public net.minecraft.world.level.BlockGetter m_151361_(Lnet/minecraft/world/phys/Vec3;Lnet/minecraft/world/phys/Vec3;Ljava/lang/Object;Ljava/util/function/BiFunction;Ljava/util/function/Function;)Ljava/lang/Object;
public-f net.minecraft.world.entity.player.Player f_36093_