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.Mob;
|
||||||
import net.minecraft.world.entity.ai.navigation.GroundPathNavigation;
|
import net.minecraft.world.entity.ai.navigation.GroundPathNavigation;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.pathfinder.BlockPathTypes;
|
||||||
import net.minecraft.world.level.pathfinder.PathFinder;
|
import net.minecraft.world.level.pathfinder.PathFinder;
|
||||||
|
|
||||||
public class ElliePathNavigation extends GroundPathNavigation {
|
public class ElliePathNavigation extends GroundPathNavigation {
|
||||||
@@ -13,8 +14,18 @@ public class ElliePathNavigation extends GroundPathNavigation {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected PathFinder createPathFinder(int maxVisitedNodes) {
|
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();
|
EllieNodeEvaluator evaluator = new EllieNodeEvaluator();
|
||||||
evaluator.setCanPassDoors(true);
|
evaluator.setCanPassDoors(true);
|
||||||
|
evaluator.setCanOpenDoors(true);
|
||||||
this.nodeEvaluator = evaluator;
|
this.nodeEvaluator = evaluator;
|
||||||
return new PathFinder(evaluator, maxVisitedNodes);
|
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.BedBlock;
|
||||||
import net.minecraft.world.level.block.DoorBlock;
|
import net.minecraft.world.level.block.DoorBlock;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
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 net.minecraft.world.phys.Vec3;
|
||||||
|
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
@@ -86,8 +88,24 @@ public class EllieSleepGoal extends Goal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void tryOpenDoor() {
|
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++) {
|
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);
|
BlockState state = ellie.level().getBlockState(checkPos);
|
||||||
if (state.getBlock() instanceof DoorBlock) {
|
if (state.getBlock() instanceof DoorBlock) {
|
||||||
if (!state.getValue(DoorBlock.OPEN)) {
|
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.server.level.ServerLevel;
|
||||||
import net.minecraft.world.level.pathfinder.Node;
|
import net.minecraft.world.level.pathfinder.Node;
|
||||||
import net.minecraft.world.level.pathfinder.Path;
|
import net.minecraft.world.level.pathfinder.Path;
|
||||||
|
import net.minecraft.world.level.pathfinder.BlockPathTypes;
|
||||||
import net.minecraftforge.network.PacketDistributor;
|
import net.minecraftforge.network.PacketDistributor;
|
||||||
import me.sashegdev.fabled_hearts.network.DebugSyncPacket;
|
import me.sashegdev.fabled_hearts.network.DebugSyncPacket;
|
||||||
import me.sashegdev.fabled_hearts.network.ModNetworking;
|
import me.sashegdev.fabled_hearts.network.ModNetworking;
|
||||||
@@ -189,7 +190,10 @@ public class EllieEntity extends Animal implements GeoEntity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean wasCrouching = getPose() == Pose.CROUCHING;
|
boolean wasCrouching = getPose() == Pose.CROUCHING;
|
||||||
if (wasCrouching) {
|
|
||||||
|
if (lowCeiling) {
|
||||||
|
crouchTimer = Math.max(crouchTimer, 20);
|
||||||
|
} else if (wasCrouching) {
|
||||||
crouchTimer = Math.max(0, crouchTimer - 1);
|
crouchTimer = Math.max(0, crouchTimer - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,7 +203,6 @@ public class EllieEntity extends Animal implements GeoEntity {
|
|||||||
} else if (lowCeiling) {
|
} else if (lowCeiling) {
|
||||||
if (onGround() || wasCrouching) {
|
if (onGround() || wasCrouching) {
|
||||||
setPose(Pose.CROUCHING);
|
setPose(Pose.CROUCHING);
|
||||||
crouchTimer = 20;
|
|
||||||
}
|
}
|
||||||
} else if (wasCrouching && crouchTimer > 0) {
|
} else if (wasCrouching && crouchTimer > 0) {
|
||||||
setPose(Pose.CROUCHING);
|
setPose(Pose.CROUCHING);
|
||||||
@@ -280,13 +283,8 @@ public class EllieEntity extends Animal implements GeoEntity {
|
|||||||
if (isSpaceLow(pos)) return true;
|
if (isSpaceLow(pos)) return true;
|
||||||
if (isMoving() && navigation.isInProgress()) {
|
if (isMoving() && navigation.isInProgress()) {
|
||||||
Direction dir = getDirection();
|
Direction dir = getDirection();
|
||||||
Direction left = dir.getCounterClockWise();
|
for (int i = 1; i <= 2; i++) {
|
||||||
Direction right = dir.getClockWise();
|
if (isSpaceLow(pos.relative(dir, i))) return true;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -371,13 +369,13 @@ public class EllieEntity extends Animal implements GeoEntity {
|
|||||||
? pos
|
? pos
|
||||||
: pos.relative(facing);
|
: pos.relative(facing);
|
||||||
|
|
||||||
float yRot = facing.getOpposite().toYRot();
|
setPose(Pose.SLEEPING);
|
||||||
setPos(headPos.getX() + 0.5, headPos.getY() + 0.5625, headPos.getZ() + 0.5);
|
setPos(headPos.getX() + 0.5, headPos.getY() + 0.5625, headPos.getZ() + 0.5);
|
||||||
|
float yRot = facing.getOpposite().toYRot();
|
||||||
setYRot(yRot);
|
setYRot(yRot);
|
||||||
yRotO = yRot;
|
yRotO = yRot;
|
||||||
setYHeadRot(yRot);
|
setYHeadRot(yRot);
|
||||||
setSleeping(true);
|
setSleeping(true);
|
||||||
setPose(Pose.SLEEPING);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void wakeUp() {
|
public void wakeUp() {
|
||||||
@@ -390,8 +388,26 @@ public class EllieEntity extends Animal implements GeoEntity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void openDoorInFront() {
|
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++) {
|
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);
|
BlockState state = level().getBlockState(checkPos);
|
||||||
if (state.getBlock() instanceof DoorBlock) {
|
if (state.getBlock() instanceof DoorBlock) {
|
||||||
if (!state.getValue(DoorBlock.OPEN)) {
|
if (!state.getValue(DoorBlock.OPEN)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user