Fix isPassable crash

This commit is contained in:
Brady 2019-10-22 15:58:10 -05:00
parent 6341f9fcb4
commit 43ab4f7d3b
No known key found for this signature in database
GPG Key ID: 73A788379A197567
4 changed files with 31 additions and 23 deletions

View File

@ -35,6 +35,7 @@ import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.IBlockAccess;
import java.util.Optional;
@ -132,27 +133,29 @@ public interface MovementHelper extends ActionCosts, Helper {
}
return block == Blocks.WATER || block == Blocks.FLOWING_WATER;
}
// every block that overrides isPassable with anything more complicated than a "return true;" or "return false;"
// has already been accounted for above
// therefore it's safe to not construct a blockpos from our x, y, z ints and instead just pass null
return block.isPassable(null, BlockPos.ORIGIN);
return block.isPassable(bsi.world, bsi.isPassableBlockPos.setPos(x, y, z));
}
/**
* canWalkThrough but also won't impede movement at all. so not including doors or fence gates (we'd have to right click),
* not including water, and not including ladders or vines or cobwebs (they slow us down)
*
* @param context Calculation context to provide block state lookup
* @param x The block's x position
* @param y The block's y position
* @param z The block's z position
* @param bsi Block State Interface to provide block state lookup
* @param x The block's x position
* @param y The block's y position
* @param z The block's z position
* @return Whether or not the block at the specified position
*/
static boolean fullyPassable(CalculationContext context, int x, int y, int z) {
return fullyPassable(context.get(x, y, z));
static boolean fullyPassable(BlockStateInterface bsi, int x, int y, int z) {
return fullyPassable(bsi.world, bsi.isPassableBlockPos.setPos(x, y, z), bsi.get0(x, y, z));
}
static boolean fullyPassable(IBlockState state) {
static boolean fullyPassable(IPlayerContext ctx, BlockPos pos) {
return fullyPassable(ctx.world(), pos, ctx.world().getBlockState(pos));
}
static boolean fullyPassable(IBlockAccess world, BlockPos pos, IBlockState state) {
Block block = state.getBlock();
if (block == Blocks.AIR) { // early return for most common case
return true;
@ -174,7 +177,7 @@ public interface MovementHelper extends ActionCosts, Helper {
return false;
}
// door, fence gate, liquid, trapdoor have been accounted for, nothing else uses the world or pos parameters
return block.isPassable(null, null);
return block.isPassable(world, pos);
}
static boolean isReplaceable(int x, int y, int z, IBlockState state, BlockStateInterface bsi) {

View File

@ -69,7 +69,7 @@ public class MovementParkour extends Movement {
int xDiff = dir.getXOffset();
int zDiff = dir.getZOffset();
if (!MovementHelper.fullyPassable(context, x + xDiff, y, z + zDiff)) {
if (!MovementHelper.fullyPassable(context.bsi, x + xDiff, y, z + zDiff)) {
// most common case at the top -- the adjacent block isn't air
return;
}
@ -81,13 +81,13 @@ public class MovementParkour extends Movement {
if (MovementHelper.avoidWalkingInto(adj.getBlock()) && adj.getBlock() != Blocks.WATER && adj.getBlock() != Blocks.FLOWING_WATER) { // magma sucks
return;
}
if (!MovementHelper.fullyPassable(context, x + xDiff, y + 1, z + zDiff)) {
if (!MovementHelper.fullyPassable(context.bsi, x + xDiff, y + 1, z + zDiff)) {
return;
}
if (!MovementHelper.fullyPassable(context, x + xDiff, y + 2, z + zDiff)) {
if (!MovementHelper.fullyPassable(context.bsi, x + xDiff, y + 2, z + zDiff)) {
return;
}
if (!MovementHelper.fullyPassable(context, x, y + 2, z)) {
if (!MovementHelper.fullyPassable(context.bsi, x, y + 2, z)) {
return;
}
IBlockState standingOn = context.get(x, y - 1, z);
@ -107,14 +107,14 @@ public class MovementParkour extends Movement {
for (int i = 2; i <= maxJump; i++) {
int destX = x + xDiff * i;
int destZ = z + zDiff * i;
if (!MovementHelper.fullyPassable(context, destX, y + 1, destZ)) {
if (!MovementHelper.fullyPassable(context.bsi, destX, y + 1, destZ)) {
return;
}
if (!MovementHelper.fullyPassable(context, destX, y + 2, destZ)) {
if (!MovementHelper.fullyPassable(context.bsi, destX, y + 2, destZ)) {
return;
}
IBlockState destInto = context.bsi.get0(destX, y, destZ);
if (!MovementHelper.fullyPassable(destInto)) {
if (!MovementHelper.fullyPassable(context.bsi.world, context.bsi.isPassableBlockPos.setPos(destX, y, destZ), destInto)) {
if (i <= 3 && context.allowParkourAscend && context.canSprint && MovementHelper.canWalkOn(context.bsi, destX, y, destZ, destInto) && checkOvershootSafety(context.bsi, destX + xDiff, y + 1, destZ + zDiff)) {
res.x = destX;
res.y = y + 1;
@ -134,7 +134,7 @@ public class MovementParkour extends Movement {
}
return;
}
if (!MovementHelper.fullyPassable(context, destX, y + 3, destZ)) {
if (!MovementHelper.fullyPassable(context.bsi, destX, y + 3, destZ)) {
return;
}
}

View File

@ -466,7 +466,7 @@ public class PathExecutor implements IPathExecutor, Helper {
}
for (int y = next.getDest().y; y <= movement.getSrc().y + 1; y++) {
BlockPos chk = new BlockPos(next.getDest().x, y, next.getDest().z);
if (!MovementHelper.fullyPassable(ctx.world().getBlockState(chk))) {
if (!MovementHelper.fullyPassable(ctx, chk)) {
break outer;
}
}
@ -491,7 +491,7 @@ public class PathExecutor implements IPathExecutor, Helper {
}
// we are centered
BlockPos headBonk = current.getSrc().subtract(current.getDirection()).up(2);
if (MovementHelper.fullyPassable(ctx.world().getBlockState(headBonk))) {
if (MovementHelper.fullyPassable(ctx, headBonk)) {
return true;
}
// wait 0.3
@ -524,7 +524,7 @@ public class PathExecutor implements IPathExecutor, Helper {
if (x == 1) {
chk = chk.add(current.getDirection());
}
if (!MovementHelper.fullyPassable(ctx.world().getBlockState(chk))) {
if (!MovementHelper.fullyPassable(ctx, chk)) {
return false;
}
}

View File

@ -30,6 +30,7 @@ import net.minecraft.client.Minecraft;
import net.minecraft.init.Blocks;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
@ -42,6 +43,8 @@ public class BlockStateInterface {
private final Long2ObjectMap<Chunk> loadedChunks;
private final WorldData worldData;
public final IBlockAccess world;
public final BlockPos.MutableBlockPos isPassableBlockPos;
private Chunk prev = null;
private CachedRegion prevCached = null;
@ -59,6 +62,7 @@ public class BlockStateInterface {
}
public BlockStateInterface(World world, WorldData worldData, boolean copyLoadedChunks) {
this.world = world;
this.worldData = worldData;
Long2ObjectMap<Chunk> worldLoaded = ((IChunkProviderClient) world.getChunkProvider()).loadedChunks();
if (copyLoadedChunks) {
@ -70,6 +74,7 @@ public class BlockStateInterface {
if (!Minecraft.getMinecraft().isCallingFromMinecraftThread()) {
throw new IllegalStateException();
}
this.isPassableBlockPos = new BlockPos.MutableBlockPos();
}
public boolean worldContainsLoadedChunk(int blockX, int blockZ) {