Fix crouch timer, bed collision on sleep, and pathfinding: better node evaluator maluses, path-aware door opening
This commit is contained in:
@@ -3,6 +3,7 @@ package me.sashegdev.fabled_hearts.ai;
|
||||
import net.minecraft.world.entity.Mob;
|
||||
import net.minecraft.world.entity.ai.navigation.GroundPathNavigation;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.pathfinder.BlockPathTypes;
|
||||
import net.minecraft.world.level.pathfinder.PathFinder;
|
||||
|
||||
public class ElliePathNavigation extends GroundPathNavigation {
|
||||
@@ -13,8 +14,18 @@ public class ElliePathNavigation extends GroundPathNavigation {
|
||||
|
||||
@Override
|
||||
protected PathFinder createPathFinder(int maxVisitedNodes) {
|
||||
mob.setPathfindingMalus(BlockPathTypes.DOOR_WOOD_CLOSED, 2.0F);
|
||||
mob.setPathfindingMalus(BlockPathTypes.DOOR_IRON_CLOSED, 5.0F);
|
||||
mob.setPathfindingMalus(BlockPathTypes.DANGER_FIRE, -1.0F);
|
||||
mob.setPathfindingMalus(BlockPathTypes.DAMAGE_FIRE, -1.0F);
|
||||
mob.setPathfindingMalus(BlockPathTypes.LAVA, -1.0F);
|
||||
mob.setPathfindingMalus(BlockPathTypes.WATER, 3.0F);
|
||||
mob.setPathfindingMalus(BlockPathTypes.WATER_BORDER, 1.0F);
|
||||
mob.setPathfindingMalus(BlockPathTypes.FENCE, -1.0F);
|
||||
|
||||
EllieNodeEvaluator evaluator = new EllieNodeEvaluator();
|
||||
evaluator.setCanPassDoors(true);
|
||||
evaluator.setCanOpenDoors(true);
|
||||
this.nodeEvaluator = evaluator;
|
||||
return new PathFinder(evaluator, maxVisitedNodes);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ 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.level.pathfinder.Node;
|
||||
import net.minecraft.world.level.pathfinder.Path;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
import java.util.EnumSet;
|
||||
@@ -86,8 +88,24 @@ public class EllieSleepGoal extends Goal {
|
||||
}
|
||||
|
||||
private void tryOpenDoor() {
|
||||
Path path = ellie.getNavigation().getPath();
|
||||
BlockPos entityPos = ellie.blockPosition();
|
||||
if (path != null) {
|
||||
for (int i = 0; i < Math.min(4, path.getNodeCount()); i++) {
|
||||
Node node = path.getNode(i);
|
||||
BlockPos checkPos = new BlockPos(node.x, node.y, node.z);
|
||||
if (checkPos.distSqr(entityPos) > 9) break;
|
||||
BlockState state = ellie.level().getBlockState(checkPos);
|
||||
if (state.getBlock() instanceof DoorBlock) {
|
||||
if (!state.getValue(DoorBlock.OPEN)) {
|
||||
ellie.level().setBlock(checkPos, state.setValue(DoorBlock.OPEN, true), 3);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 3; i++) {
|
||||
BlockPos checkPos = ellie.blockPosition().relative(ellie.getDirection(), i);
|
||||
BlockPos checkPos = entityPos.relative(ellie.getDirection(), i);
|
||||
BlockState state = ellie.level().getBlockState(checkPos);
|
||||
if (state.getBlock() instanceof DoorBlock) {
|
||||
if (!state.getValue(DoorBlock.OPEN)) {
|
||||
|
||||
@@ -32,6 +32,7 @@ import net.minecraft.world.level.block.state.properties.BedPart;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.level.pathfinder.Node;
|
||||
import net.minecraft.world.level.pathfinder.Path;
|
||||
import net.minecraft.world.level.pathfinder.BlockPathTypes;
|
||||
import net.minecraftforge.network.PacketDistributor;
|
||||
import me.sashegdev.fabled_hearts.network.DebugSyncPacket;
|
||||
import me.sashegdev.fabled_hearts.network.ModNetworking;
|
||||
@@ -189,7 +190,10 @@ public class EllieEntity extends Animal implements GeoEntity {
|
||||
}
|
||||
|
||||
boolean wasCrouching = getPose() == Pose.CROUCHING;
|
||||
if (wasCrouching) {
|
||||
|
||||
if (lowCeiling) {
|
||||
crouchTimer = Math.max(crouchTimer, 20);
|
||||
} else if (wasCrouching) {
|
||||
crouchTimer = Math.max(0, crouchTimer - 1);
|
||||
}
|
||||
|
||||
@@ -199,7 +203,6 @@ public class EllieEntity extends Animal implements GeoEntity {
|
||||
} else if (lowCeiling) {
|
||||
if (onGround() || wasCrouching) {
|
||||
setPose(Pose.CROUCHING);
|
||||
crouchTimer = 20;
|
||||
}
|
||||
} else if (wasCrouching && crouchTimer > 0) {
|
||||
setPose(Pose.CROUCHING);
|
||||
@@ -280,13 +283,8 @@ public class EllieEntity extends Animal implements GeoEntity {
|
||||
if (isSpaceLow(pos)) return true;
|
||||
if (isMoving() && navigation.isInProgress()) {
|
||||
Direction dir = getDirection();
|
||||
Direction left = dir.getCounterClockWise();
|
||||
Direction right = dir.getClockWise();
|
||||
for (int i = 1; i <= 3; i++) {
|
||||
BlockPos ahead = pos.relative(dir, i);
|
||||
if (isSpaceLow(ahead)) return true;
|
||||
if (isSpaceLow(ahead.relative(left, 1))) return true;
|
||||
if (isSpaceLow(ahead.relative(right, 1))) return true;
|
||||
for (int i = 1; i <= 2; i++) {
|
||||
if (isSpaceLow(pos.relative(dir, i))) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -371,13 +369,13 @@ public class EllieEntity extends Animal implements GeoEntity {
|
||||
? pos
|
||||
: pos.relative(facing);
|
||||
|
||||
float yRot = facing.getOpposite().toYRot();
|
||||
setPose(Pose.SLEEPING);
|
||||
setPos(headPos.getX() + 0.5, headPos.getY() + 0.5625, headPos.getZ() + 0.5);
|
||||
float yRot = facing.getOpposite().toYRot();
|
||||
setYRot(yRot);
|
||||
yRotO = yRot;
|
||||
setYHeadRot(yRot);
|
||||
setSleeping(true);
|
||||
setPose(Pose.SLEEPING);
|
||||
}
|
||||
|
||||
public void wakeUp() {
|
||||
@@ -390,8 +388,26 @@ public class EllieEntity extends Animal implements GeoEntity {
|
||||
}
|
||||
|
||||
public void openDoorInFront() {
|
||||
Path path = navigation.getPath();
|
||||
BlockPos entityPos = blockPosition();
|
||||
if (path != null) {
|
||||
for (int i = 0; i < Math.min(4, path.getNodeCount()); i++) {
|
||||
Node node = path.getNode(i);
|
||||
BlockPos checkPos = new BlockPos(node.x, node.y, node.z);
|
||||
if (checkPos.distSqr(entityPos) > 9) break;
|
||||
BlockState state = level().getBlockState(checkPos);
|
||||
if (state.getBlock() instanceof DoorBlock) {
|
||||
if (!state.getValue(DoorBlock.OPEN)) {
|
||||
level().setBlock(checkPos, state.setValue(DoorBlock.OPEN, true), 3);
|
||||
lastOpenedDoor = checkPos;
|
||||
doorCloseTimer = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 3; i++) {
|
||||
BlockPos checkPos = blockPosition().relative(getDirection(), 2 + i);
|
||||
BlockPos checkPos = entityPos.relative(getDirection(), 2 + i);
|
||||
BlockState state = level().getBlockState(checkPos);
|
||||
if (state.getBlock() instanceof DoorBlock) {
|
||||
if (!state.getValue(DoorBlock.OPEN)) {
|
||||
|
||||
Reference in New Issue
Block a user