From a21073f95d63a6807254ba8477d229b6a39cea24 Mon Sep 17 00:00:00 2001 From: CreepyCre Date: Fri, 29 Oct 2021 14:50:03 +0200 Subject: [PATCH] fix VirtualLocation#getTopPos crash when querying empty column --- .../dimdoors/item/DimensionalEraserItem.java | 4 ++-- .../dimdoors/rift/targets/EscapeTarget.java | 2 +- .../dimdoors/rift/targets/LimboTarget.java | 4 ++-- .../world/pocket/VirtualLocation.java | 19 +++++++++---------- 4 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/main/java/org/dimdev/dimdoors/item/DimensionalEraserItem.java b/src/main/java/org/dimdev/dimdoors/item/DimensionalEraserItem.java index acfebac8..e81dcc69 100644 --- a/src/main/java/org/dimdev/dimdoors/item/DimensionalEraserItem.java +++ b/src/main/java/org/dimdev/dimdoors/item/DimensionalEraserItem.java @@ -36,10 +36,10 @@ public class DimensionalEraserItem extends Item { if (hit != null && hit.getType() == HitResult.Type.ENTITY) { if(((EntityHitResult) hit).getEntity() instanceof ServerPlayerEntity) { BlockPos teleportPos = ((EntityHitResult) hit).getEntity().getBlockPos(); - while(ModDimensions.LIMBO_DIMENSION.getBlockState(VirtualLocation.getTopPos(ModDimensions.LIMBO_DIMENSION, teleportPos)).getBlock() == ModBlocks.ETERNAL_FLUID) { + while(ModDimensions.LIMBO_DIMENSION.getBlockState(VirtualLocation.getTopPos(ModDimensions.LIMBO_DIMENSION, teleportPos.getX(), teleportPos.getZ())).getBlock() == ModBlocks.ETERNAL_FLUID) { teleportPos = teleportPos.add(1, 0, 1); } - TeleportUtil.teleport(((EntityHitResult) hit).getEntity(), ModDimensions.LIMBO_DIMENSION, teleportPos.add(0, 255-((EntityHitResult) hit).getEntity().getBlockY(), 0), entityEulerAngle(((EntityHitResult) hit).getEntity()), ((EntityHitResult) hit).getEntity().getVelocity()); + TeleportUtil.teleport(((EntityHitResult) hit).getEntity(), ModDimensions.LIMBO_DIMENSION, teleportPos.withY(255), entityEulerAngle(((EntityHitResult) hit).getEntity()), ((EntityHitResult) hit).getEntity().getVelocity()); } ((EntityHitResult) hit).getEntity().remove(Entity.RemovalReason.KILLED); diff --git a/src/main/java/org/dimdev/dimdoors/rift/targets/EscapeTarget.java b/src/main/java/org/dimdev/dimdoors/rift/targets/EscapeTarget.java index 26df4374..606e9baa 100644 --- a/src/main/java/org/dimdev/dimdoors/rift/targets/EscapeTarget.java +++ b/src/main/java/org/dimdev/dimdoors/rift/targets/EscapeTarget.java @@ -100,7 +100,7 @@ public class EscapeTarget extends VirtualTarget implements EntityTarget { // TOD entity = TeleportUtil.teleport(entity, location.getWorld(), location.getBlockPos(), relativeAngle, relativeVelocity); entity.fallDistance = 0; Random random = new Random(); - BlockPos.iterateOutwards(location.pos.add(0, -4, 0), 3, 2, 3).forEach((pos1 -> { + BlockPos.iterateOutwards(location.pos.add(0, -3, 0), 3, 2, 3).forEach((pos1 -> { if (random.nextFloat() < (1 / ((float) location.pos.getSquaredDistance(pos1))) * DimensionalDoorsInitializer.getConfig().getLimboConfig().limboBlocksCorruptingOverworldAmount) { Block block = location.getWorld().getBlockState(pos1).getBlock(); if (UnravelUtil.unravelBlocksMap.containsKey(block)) diff --git a/src/main/java/org/dimdev/dimdoors/rift/targets/LimboTarget.java b/src/main/java/org/dimdev/dimdoors/rift/targets/LimboTarget.java index 5dd928f5..5730634e 100644 --- a/src/main/java/org/dimdev/dimdoors/rift/targets/LimboTarget.java +++ b/src/main/java/org/dimdev/dimdoors/rift/targets/LimboTarget.java @@ -24,10 +24,10 @@ public class LimboTarget extends VirtualTarget implements EntityTarget { @Override public boolean receiveEntity(Entity entity, Vec3d relativePos, EulerAngle relativeAngle, Vec3d relativeVelocity) { BlockPos teleportPos = entity.getBlockPos(); - while(ModDimensions.LIMBO_DIMENSION.getBlockState(VirtualLocation.getTopPos(ModDimensions.LIMBO_DIMENSION, teleportPos)).getBlock() == ModBlocks.ETERNAL_FLUID) { + while(ModDimensions.LIMBO_DIMENSION.getBlockState(VirtualLocation.getTopPos(ModDimensions.LIMBO_DIMENSION, teleportPos.getX(), teleportPos.getZ())).getBlock() == ModBlocks.ETERNAL_FLUID) { teleportPos = teleportPos.add(1, 0, 1); } - TeleportUtil.teleport(entity, ModDimensions.LIMBO_DIMENSION, teleportPos.add(0, 255-entity.getBlockY(), 0), relativeAngle, relativeVelocity); + TeleportUtil.teleport(entity, ModDimensions.LIMBO_DIMENSION, teleportPos.withY(255), relativeAngle, relativeVelocity); return true; } diff --git a/src/main/java/org/dimdev/dimdoors/world/pocket/VirtualLocation.java b/src/main/java/org/dimdev/dimdoors/world/pocket/VirtualLocation.java index 0454a0df..3c11aa6c 100644 --- a/src/main/java/org/dimdev/dimdoors/world/pocket/VirtualLocation.java +++ b/src/main/java/org/dimdev/dimdoors/world/pocket/VirtualLocation.java @@ -3,6 +3,9 @@ package org.dimdev.dimdoors.world.pocket; import com.google.common.base.MoreObjects; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.util.math.ChunkPos; +import net.minecraft.util.math.ChunkSectionPos; +import net.minecraft.world.chunk.Chunk; import org.dimdev.dimdoors.DimensionalDoorsInitializer; import org.dimdev.dimdoors.world.level.registry.DimensionalRegistry; import org.dimdev.dimdoors.api.util.Location; @@ -90,18 +93,14 @@ public class VirtualLocation { int newX = (int) (this.x + spread * 2 * (Math.random() - 0.5)); int newZ = (int) (this.z + spread * 2 * (Math.random() - 0.5)); //BlockPos pos = world.getTopPosition(Heightmap.Type.WORLD_SURFACE, new BlockPos(newX, 1, newZ)); - BlockPos pos = getTopPos(world, new BlockPos(newX, 255, newZ)); + BlockPos pos = getTopPos(world, newX, newZ).up(); return new Location(world, pos); } - public static BlockPos getTopPos(World world, BlockPos pos) { - while(world.getBlockState(pos).isAir()) { - pos = pos.down(); - } - while(world.getBlockState(pos).isSolidBlock(world, pos)) { - pos = pos.up(); - } - pos = pos.up(2); - return pos; + + public static BlockPos getTopPos(World world, int x, int z) { + int topHeight = world.getChunk(ChunkSectionPos.getSectionCoord(x), ChunkSectionPos.getSectionCoord(z)) // guarantees WorldChunk + .sampleHeightmap(Heightmap.Type.MOTION_BLOCKING_NO_LEAVES, x, z); + return new BlockPos(x, topHeight, z); } public RegistryKey getWorld() {