fix passable and replacable checks for snow in cached chunks, fixes #87

This commit is contained in:
Leijurv 2018-08-25 08:44:33 -07:00
parent db6453fae0
commit 342bb8616c
No known key found for this signature in database
GPG Key ID: 44A3EA646EADAC6A
4 changed files with 39 additions and 8 deletions

View File

@ -112,7 +112,6 @@ public final class ChunkPacker implements Helper {
if (MovementHelper.avoidWalkingInto(block)) { if (MovementHelper.avoidWalkingInto(block)) {
return PathingBlockType.AVOID; return PathingBlockType.AVOID;
} }
// We used to do an AABB check here // We used to do an AABB check here
// however, this failed in the nether when you were near a nether fortress // however, this failed in the nether when you were near a nether fortress
// because fences check their adjacent blocks in the world for their fence connection status to determine AABB shape // because fences check their adjacent blocks in the world for their fence connection status to determine AABB shape

View File

@ -33,6 +33,7 @@ import net.minecraft.item.ItemStack;
import net.minecraft.util.NonNullList; import net.minecraft.util.NonNullList;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.chunk.EmptyChunk;
import java.util.Optional; import java.util.Optional;
@ -75,16 +76,48 @@ public interface MovementHelper extends ActionCosts, Helper {
|| block instanceof BlockEndPortal) {//you can't actually walk through a lilypad from the side, and you shouldn't walk through fire || block instanceof BlockEndPortal) {//you can't actually walk through a lilypad from the side, and you shouldn't walk through fire
return false; return false;
} }
if (block instanceof BlockDoor) {
if (block == Blocks.IRON_DOOR) {
return false;
}
return true; // we can just open the door
}
if (block instanceof BlockSnow || block instanceof BlockFenceGate || block instanceof BlockTrapDoor) {
// we've already checked doors
// so the only remaining dynamic isPassables are snow, fence gate, and trapdoor
// if they're cached as a top block, we don't know their metadata
// default to true (mostly because it would otherwise make long distance pathing through snowy biomes impossible)
if (mc.world.getChunk(pos) instanceof EmptyChunk) {
return true;
}
}
IBlockState up = BlockStateInterface.get(pos.up()); IBlockState up = BlockStateInterface.get(pos.up());
if (BlockStateInterface.isFlowing(state) || up.getBlock() instanceof BlockLiquid || up.getBlock() instanceof BlockLilyPad) { if (BlockStateInterface.isFlowing(state) || up.getBlock() instanceof BlockLiquid || up.getBlock() instanceof BlockLilyPad) {
return false; // Don't walk through flowing liquids return false; // Don't walk through flowing liquids
} }
if (block instanceof BlockDoor && !Blocks.IRON_DOOR.equals(block)) {
return true; // we can just open the door
}
return block.isPassable(mc.world, pos); return block.isPassable(mc.world, pos);
} }
static boolean isReplacable(BlockPos pos, IBlockState state) {
// for MovementTraverse and MovementAscend
// block double plant defaults to true when the block doesn't match, so don't need to check that case
// all other overrides just return true or false
// the only case to deal with is snow
/*
* public boolean isReplaceable(IBlockAccess worldIn, BlockPos pos)
* {
* return ((Integer)worldIn.getBlockState(pos).getValue(LAYERS)).intValue() == 1;
* }
*/
if (state.getBlock() instanceof BlockSnow) {
// as before, default to true (mostly because it would otherwise make long distance pathing through snowy biomes impossible)
if (mc.world.getChunk(pos) instanceof EmptyChunk) {
return true;
}
}
return state.getBlock().isReplaceable(mc.world, pos);
}
static boolean isDoorPassable(BlockPos doorPos, BlockPos playerPos) { static boolean isDoorPassable(BlockPos doorPos, BlockPos playerPos) {
IBlockState door = BlockStateInterface.get(doorPos); IBlockState door = BlockStateInterface.get(doorPos);
if (!(door.getBlock() instanceof BlockDoor)) { if (!(door.getBlock() instanceof BlockDoor)) {

View File

@ -74,11 +74,10 @@ public class MovementAscend extends Movement {
protected double calculateCost(CalculationContext context) { protected double calculateCost(CalculationContext context) {
IBlockState toPlace = BlockStateInterface.get(positionsToPlace[0]); IBlockState toPlace = BlockStateInterface.get(positionsToPlace[0]);
if (!MovementHelper.canWalkOn(positionsToPlace[0], toPlace)) { if (!MovementHelper.canWalkOn(positionsToPlace[0], toPlace)) {
if (!BlockStateInterface.isAir(toPlace) && !BlockStateInterface.isWater(toPlace.getBlock())) { if (!context.hasThrowaway()) {
// TODO replace this check with isReplacable or similar
return COST_INF; return COST_INF;
} }
if (!context.hasThrowaway()) { if (!BlockStateInterface.isAir(toPlace) && !BlockStateInterface.isWater(toPlace.getBlock()) && !MovementHelper.isReplacable(positionsToPlace[0], toPlace)) {
return COST_INF; return COST_INF;
} }
for (BlockPos against1 : against) { for (BlockPos against1 : against) {

View File

@ -107,7 +107,7 @@ public class MovementTraverse extends Movement {
return COST_INF; return COST_INF;
} }
IBlockState pp0 = BlockStateInterface.get(positionsToPlace[0]); IBlockState pp0 = BlockStateInterface.get(positionsToPlace[0]);
if (pp0.getBlock().equals(Blocks.AIR) || (!BlockStateInterface.isWater(pp0.getBlock()) && pp0.getBlock().isReplaceable(Minecraft.getMinecraft().world, positionsToPlace[0]))) { if (pp0.getBlock().equals(Blocks.AIR) || (!BlockStateInterface.isWater(pp0.getBlock()) && MovementHelper.isReplacable(positionsToPlace[0], pp0))) {
if (!context.hasThrowaway()) { if (!context.hasThrowaway()) {
return COST_INF; return COST_INF;
} }