minecraft-src/net/minecraft/world/entity/ai/goal/DoorInteractGoal.java
2025-07-04 03:15:13 +03:00

106 lines
3.1 KiB
Java

package net.minecraft.world.entity.ai.goal;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.ai.navigation.GroundPathNavigation;
import net.minecraft.world.entity.ai.util.GoalUtils;
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;
public abstract class DoorInteractGoal extends Goal {
protected Mob mob;
protected BlockPos doorPos = BlockPos.ZERO;
protected boolean hasDoor;
private boolean passed;
private float doorOpenDirX;
private float doorOpenDirZ;
public DoorInteractGoal(Mob mob) {
this.mob = mob;
if (!GoalUtils.hasGroundPathNavigation(mob)) {
throw new IllegalArgumentException("Unsupported mob type for DoorInteractGoal");
}
}
protected boolean isOpen() {
if (!this.hasDoor) {
return false;
} else {
BlockState blockState = this.mob.level().getBlockState(this.doorPos);
if (!(blockState.getBlock() instanceof DoorBlock)) {
this.hasDoor = false;
return false;
} else {
return (Boolean)blockState.getValue(DoorBlock.OPEN);
}
}
}
protected void setOpen(boolean open) {
if (this.hasDoor) {
BlockState blockState = this.mob.level().getBlockState(this.doorPos);
if (blockState.getBlock() instanceof DoorBlock) {
((DoorBlock)blockState.getBlock()).setOpen(this.mob, this.mob.level(), blockState, this.doorPos, open);
}
}
}
@Override
public boolean canUse() {
if (!GoalUtils.hasGroundPathNavigation(this.mob)) {
return false;
} else if (!this.mob.horizontalCollision) {
return false;
} else {
GroundPathNavigation groundPathNavigation = (GroundPathNavigation)this.mob.getNavigation();
Path path = groundPathNavigation.getPath();
if (path != null && !path.isDone()) {
for (int i = 0; i < Math.min(path.getNextNodeIndex() + 2, path.getNodeCount()); i++) {
Node node = path.getNode(i);
this.doorPos = new BlockPos(node.x, node.y + 1, node.z);
if (!(this.mob.distanceToSqr(this.doorPos.getX(), this.mob.getY(), this.doorPos.getZ()) > 2.25)) {
this.hasDoor = DoorBlock.isWoodenDoor(this.mob.level(), this.doorPos);
if (this.hasDoor) {
return true;
}
}
}
this.doorPos = this.mob.blockPosition().above();
this.hasDoor = DoorBlock.isWoodenDoor(this.mob.level(), this.doorPos);
return this.hasDoor;
} else {
return false;
}
}
}
@Override
public boolean canContinueToUse() {
return !this.passed;
}
@Override
public void start() {
this.passed = false;
this.doorOpenDirX = (float)(this.doorPos.getX() + 0.5 - this.mob.getX());
this.doorOpenDirZ = (float)(this.doorPos.getZ() + 0.5 - this.mob.getZ());
}
@Override
public boolean requiresUpdateEveryTick() {
return true;
}
@Override
public void tick() {
float f = (float)(this.doorPos.getX() + 0.5 - this.mob.getX());
float g = (float)(this.doorPos.getZ() + 0.5 - this.mob.getZ());
float h = this.doorOpenDirX * f + this.doorOpenDirZ * g;
if (h < 0.0F) {
this.passed = true;
}
}
}