Fix AI: simplify crouching, rewrite EllieSleepGoal, clean up idle anim

- checkLowCeiling: only check current position (no path/node scanning)
- Crouch height: 1.0 (fits in 1-block gaps without suffocation)
- EllieSleepGoal: remove hurtTime from canUse, simplify canContinueToUse
- IdleAnimationGoal: no longer stops navigation on start
- Also: register FollowPlayerGoal, bed memory improvements
This commit is contained in:
2026-06-09 23:32:35 +03:00
parent 31a21f2f45
commit 15a31b1aec
3 changed files with 17 additions and 43 deletions
@@ -3,6 +3,7 @@ package me.sashegdev.fabled_hearts.ai;
import me.sashegdev.fabled_hearts.entity.ellie.EllieEntity;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.ai.goal.Goal;
import net.minecraft.world.level.block.BedBlock;
import net.minecraft.world.level.block.DoorBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec3;
@@ -26,9 +27,8 @@ public class EllieSleepGoal extends Goal {
@Override
public boolean canUse() {
if (!ellie.level().isNight() && !ellie.isTired()) return false;
if (ellie.isSleeping()) return false;
if (ellie.hurtTime > 0) return false;
if (!ellie.level().isNight() && !ellie.isTired()) return false;
bedPos = findBed();
return bedPos != null;
@@ -46,9 +46,6 @@ public class EllieSleepGoal extends Goal {
public void start() {
claimed = false;
if (bedPos != null) {
if (ellie.isSpaceLow(bedPos)) {
ellie.setPose(net.minecraft.world.entity.Pose.CROUCHING);
}
ellie.getNavigation().moveTo(bedPos.getX() + 0.5, bedPos.getY(), bedPos.getZ() + 0.5, 0.6);
}
}
@@ -57,7 +54,6 @@ public class EllieSleepGoal extends Goal {
public void tick() {
if (bedPos == null) return;
// Open doors in path
tryOpenDoor();
double distSqr = ellie.distanceToSqr(Vec3.atCenterOf(bedPos));
@@ -69,10 +65,11 @@ public class EllieSleepGoal extends Goal {
claimed = ellie.occupyBed(bedPos);
}
if (claimed) {
if (!ellie.isSleeping()) {
ellie.setBedSleepPos(bedPos);
}
if (claimed && !ellie.isSleeping()) {
ellie.setBedSleepPos(bedPos);
}
if (ellie.isSleeping()) {
sleepTimer++;
}
} else {
@@ -83,7 +80,6 @@ public class EllieSleepGoal extends Goal {
}
private void tryOpenDoor() {
BlockPos inFront = ellie.blockPosition().relative(ellie.getDirection());
for (int i = 0; i < 3; i++) {
BlockPos checkPos = ellie.blockPosition().relative(ellie.getDirection(), i);
BlockState state = ellie.level().getBlockState(checkPos);
@@ -108,14 +104,16 @@ public class EllieSleepGoal extends Goal {
@Override
public boolean canContinueToUse() {
if (ellie.hurtTime > 0) return false;
if (ellie.isSleeping()) {
if (sleepTimer >= MAX_SLEEP_TICKS) return false;
if (bedPos != null && !ellie.level().getBlockState(bedPos).isBed(ellie.level(), bedPos, null)) {
return false;
if (bedPos != null) {
BlockState state = ellie.level().getBlockState(bedPos);
if (!state.isBed(ellie.level(), bedPos, null)) return false;
}
return true;
}
if (bedPos == null) return false;
if (ellie.hurtTime > 10) return false;
if (!ellie.level().isNight() && !ellie.isTired()) return false;
return true;
}
@@ -145,8 +143,8 @@ public class EllieSleepGoal extends Goal {
private boolean isFreeBed(BlockPos pos) {
BlockState state = ellie.level().getBlockState(pos);
if (!state.isBed(ellie.level(), pos, null)) return false;
if (state.hasProperty(DoorBlock.OPEN) && state.getValue(DoorBlock.OPEN)) return false;
return !state.getValue(net.minecraft.world.level.block.BedBlock.OCCUPIED);
if (!(state.getBlock() instanceof BedBlock)) return false;
if (state.getValue(BedBlock.OCCUPIED)) return false;
return true;
}
}