diff --git a/src/main/java/mekanism/common/capabilities/item/CursedTransporterItemHandler.java b/src/main/java/mekanism/common/capabilities/item/CursedTransporterItemHandler.java index efc16da96a2..5eb0deb67f5 100644 --- a/src/main/java/mekanism/common/capabilities/item/CursedTransporterItemHandler.java +++ b/src/main/java/mekanism/common/capabilities/item/CursedTransporterItemHandler.java @@ -28,10 +28,10 @@ public class CursedTransporterItemHandler implements IItemHandler { private final Set seenExecutedStacks = Collections.newSetFromMap(new IdentityHashMap<>()); private final LogisticalTransporterBase transporter; private final LongSupplier currentTickSupplier; - private final BlockPos fromPos; + private final long fromPos; private long lastTick; - public CursedTransporterItemHandler(LogisticalTransporterBase transporter, BlockPos fromPos, LongSupplier currentTickSupplier) { + public CursedTransporterItemHandler(LogisticalTransporterBase transporter, long fromPos, LongSupplier currentTickSupplier) { this.transporter = transporter; this.fromPos = fromPos; this.currentTickSupplier = currentTickSupplier; diff --git a/src/main/java/mekanism/common/content/network/InventoryNetwork.java b/src/main/java/mekanism/common/content/network/InventoryNetwork.java index 5d88ac6feff..acfe90d5482 100644 --- a/src/main/java/mekanism/common/content/network/InventoryNetwork.java +++ b/src/main/java/mekanism/common/content/network/InventoryNetwork.java @@ -46,15 +46,16 @@ public List calculateAcceptors(TransitRequest request, Transporter Map> additionalFlowingStacks, LogisticalTransporterBase start) { List toReturn = new ArrayList<>(); for (Long2ObjectMap.Entry> entry : acceptorCache.getAcceptorEntrySet()) { - BlockPos pos = BlockPos.of(entry.getLongKey()); - if (!pos.equals(stack.homeLocation)) { - BlockEntity acceptor = WorldUtils.getTileEntity(getWorld(), chunkMap, pos); + long pos = entry.getLongKey(); + if (pos != stack.homeLocation) { + BlockPos blockPos = BlockPos.of(pos); + BlockEntity acceptor = WorldUtils.getTileEntity(getWorld(), chunkMap, blockPos); Map dataMap = new HashMap<>(); - GlobalPos position = GlobalPos.of(getWorld().dimension(), pos); + GlobalPos position = GlobalPos.of(getWorld().dimension(), blockPos); for (Map.Entry acceptorEntry : entry.getValue().entrySet()) { IItemHandler handler = acceptorEntry.getValue(); Direction side = acceptorEntry.getKey(); - PathfinderCache.CachedPath cachedPath = PathfinderCache.getSingleCache(start, pos, side); + PathfinderCache.CachedPath cachedPath = PathfinderCache.getSingleCache(start, blockPos, side); if (cachedPath != null && !TransporterPathfinder.checkPath(this, cachedPath.path(), stack)) { continue;//invalid path, no need to simulate } @@ -77,7 +78,7 @@ public List calculateAcceptors(TransitRequest request, Transporter AcceptorData data = dataMap.get(response); if (data == null) { //If we don't, add a new acceptor data for the response and position with side - data = new AcceptorData(pos, response, opposite); + data = new AcceptorData(blockPos, response, opposite); dataMap.put(response, data); toReturn.add(data); //Note: In theory this shouldn't cause any issues if some exposed slots overlap but are for diff --git a/src/main/java/mekanism/common/content/network/transmitter/LogisticalTransporterBase.java b/src/main/java/mekanism/common/content/network/transmitter/LogisticalTransporterBase.java index 3f6849cace4..39e4e3f90cc 100644 --- a/src/main/java/mekanism/common/content/network/transmitter/LogisticalTransporterBase.java +++ b/src/main/java/mekanism/common/content/network/transmitter/LogisticalTransporterBase.java @@ -173,7 +173,7 @@ public void onUpdateServer() { } } if (!transit.isEmpty()) { - BlockPos pos = getBlockPos(); + long pos = getWorldPositionLong(); InventoryNetwork network = getTransmitterNetwork(); //Update stack positions IntSet deletes = new IntOpenHashSet(); @@ -200,11 +200,11 @@ public void onUpdateServer() { if (stack.progress >= 100) { long prevSet = Long.MAX_VALUE; if (stack.hasPath()) { - int currentIndex = stack.getPath().indexOf(pos.asLong()); - if (currentIndex == 0) { //Necessary for transition reasons, not sure why + if (stack.getPath().getLong(0) == pos) { //Necessary for transition reasons, not sure why deletes.add(stackId); continue; } + int currentIndex = stack.getPath().indexOf(pos); long next = stack.getPath().getLong(currentIndex - 1); if (next != Long.MAX_VALUE) { if (!stack.isFinal(this)) { @@ -269,7 +269,7 @@ public void onUpdateServer() { if (nextPos == Long.MAX_VALUE) { tryRecalculate = true; } else { - Direction nextSide = stack.getSide(pos, nextPos); + Direction nextSide = stack.getSide(getWorldPositionLong(), nextPos); LogisticalTransporterBase nextTransmitter = network.getTransmitter(nextPos); if (nextTransmitter == null && stack.getPathType().noTarget() && stack.getPath().size() == 2) { //If there is no next transmitter, and it was an idle path, assume that we are idling @@ -424,9 +424,7 @@ private boolean recalculate(int stackId, TransporterStack stack, long from) { //Only add to needsSync if true is being returned; otherwise it gets added to deletes needsSync.put(stackId, stack); - if (from != Long.MAX_VALUE) { - stack.originalLocation = BlockPos.of(from); - } + stack.originalLocation = from; return true; } @@ -445,7 +443,7 @@ private TransitResponse insert(@Nullable BE outputter, int min, boolean doEmit, PathCalculator pathCalculator) { Direction from = WorldUtils.sideDifference(getBlockPos(), outputterPos); if (from != null && canReceiveFrom(from.getOpposite())) { - TransporterStack stack = createInsertStack(outputterPos.immutable(), color); + TransporterStack stack = createInsertStack(outputterPos.asLong(), color); if (stack.canInsertToTransporterNN(this, from, outputter)) { return updateTransit(doEmit, stack, pathCalculator.calculate(stack, request, outputter, this, min, doEmit)); } @@ -453,17 +451,17 @@ private TransitResponse insert(@Nullable BE outputter, return request.getEmptyResponse(); } - public TransitResponse insertUnchecked(BlockPos outputterPos, TransitRequest request, @Nullable EnumColor color, boolean doEmit, int min) { + public TransitResponse insertUnchecked(long outputterPos, TransitRequest request, @Nullable EnumColor color, boolean doEmit, int min) { TransporterStack stack = createInsertStack(outputterPos, color); return updateTransit(doEmit, stack, stack.recalculatePath(request, this, min, doEmit)); } public TransitResponse insertUnchecked(BE outputter, TransitRequest request, @Nullable EnumColor color, boolean doEmit, int min, PathCalculator pathCalculator) { - TransporterStack stack = createInsertStack(outputter.getBlockPos(), color); + TransporterStack stack = createInsertStack(outputter.getBlockPos().asLong(), color); return updateTransit(doEmit, stack, pathCalculator.calculate(stack, request, outputter, this, min, doEmit)); } - public TransporterStack createInsertStack(BlockPos outputterCoord, @Nullable EnumColor color) { + public TransporterStack createInsertStack(long outputterCoord, @Nullable EnumColor color) { TransporterStack stack = new TransporterStack(); stack.originalLocation = outputterCoord; stack.homeLocation = outputterCoord; @@ -478,7 +476,7 @@ private TransitResponse updateTransit(boolean doEmit, TransporterStack stack, Tr if (doEmit) { int stackId = nextId++; addStack(stackId, stack); - PacketUtils.sendToAllTracking(PacketTransporterSync.create(getBlockPos(), stackId, stack), getTransmitterTile()); + PacketUtils.sendToAllTracking(PacketTransporterSync.create(getWorldPositionLong(), stackId, stack), getTransmitterTile()); getTransmitterTile().markForSave(); } } diff --git a/src/main/java/mekanism/common/content/transporter/TransporterPathfinder.java b/src/main/java/mekanism/common/content/transporter/TransporterPathfinder.java index 73440aea979..164b5584dd0 100644 --- a/src/main/java/mekanism/common/content/transporter/TransporterPathfinder.java +++ b/src/main/java/mekanism/common/content/transporter/TransporterPathfinder.java @@ -173,16 +173,16 @@ public static IdlePathData getIdlePath(LogisticalTransporterBase start, Transpor if (network == null) { return null; } - if (stack.homeLocation != null) { + if (stack.homeLocation != Long.MAX_VALUE) { Long2ObjectMap chunkMap = new Long2ObjectOpenHashMap<>(); //We are idling use the base stack - Pathfinder p = new Pathfinder(network, start.getLevel(), stack.homeLocation, start.getBlockPos(), stack, stack.itemStack, + Pathfinder p = new Pathfinder(network, start.getLevel(), BlockPos.of(stack.homeLocation), start.getBlockPos(), stack, stack.itemStack, (level, pos, tile, s, resp, side) -> TransporterUtils.canInsert(level, pos, tile, s.color, resp, side, true)); p.find(chunkMap); if (p.hasPath()) { return new IdlePathData(p.getPath(), Path.HOME); } - stack.homeLocation = null; + stack.homeLocation = Long.MAX_VALUE; } IdlePath d = new IdlePath(network, start.getBlockPos(), stack); diff --git a/src/main/java/mekanism/common/content/transporter/TransporterStack.java b/src/main/java/mekanism/common/content/transporter/TransporterStack.java index 456f6522b73..445c17af846 100644 --- a/src/main/java/mekanism/common/content/transporter/TransporterStack.java +++ b/src/main/java/mekanism/common/content/transporter/TransporterStack.java @@ -19,12 +19,10 @@ import mekanism.common.lib.inventory.TransitRequest.TransitResponse; import mekanism.common.util.NBTUtils; import mekanism.common.util.WorldUtils; -import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.GlobalPos; import net.minecraft.core.HolderLookup; import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.NbtUtils; import net.minecraft.nbt.Tag; import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.codec.ByteBufCodecs; @@ -44,7 +42,7 @@ public class TransporterStack { public static StreamCodec STREAM_CODEC = NeoForgeStreamCodecs.composite( EnumColor.OPTIONAL_STREAM_CODEC, stack -> Optional.ofNullable(stack.color), ByteBufCodecs.VAR_INT, stack -> stack.progress, - BlockPos.STREAM_CODEC, stack -> stack.originalLocation, + ByteBufCodecs.VAR_LONG, stack -> stack.originalLocation, Path.STREAM_CODEC, TransporterStack::getPathType, ByteBufCodecs.optional(ByteBufCodecs.VAR_LONG), stack -> stack.clientNext == Long.MAX_VALUE ? Optional.empty() : Optional.of(stack.clientNext), ByteBufCodecs.optional(ByteBufCodecs.VAR_LONG), stack -> stack.clientPrev == Long.MAX_VALUE ? Optional.empty() : Optional.of(stack.clientPrev), @@ -71,10 +69,14 @@ public class TransporterStack { public boolean initiatedPath = false; public Direction idleDir = null; - public BlockPos originalLocation; - public BlockPos homeLocation; + + //packed BlockPos-es + public long originalLocation = Long.MAX_VALUE; + public long homeLocation = Long.MAX_VALUE; private long clientNext = Long.MAX_VALUE; private long clientPrev = Long.MAX_VALUE; + // + @Nullable private Path pathType; private LongList pathToTarget = new LongArrayList(); @@ -96,7 +98,7 @@ public void writeToUpdateTag(HolderLookup.Provider provider, LogisticalTransport NBTUtils.writeEnum(updateTag, SerializationConstants.COLOR, color); } updateTag.putInt(SerializationConstants.PROGRESS, progress); - updateTag.put(SerializationConstants.ORIGINAL_LOCATION, NbtUtils.writeBlockPos(originalLocation)); + updateTag.putLong(SerializationConstants.ORIGINAL_LOCATION, originalLocation); NBTUtils.writeEnum(updateTag, SerializationConstants.PATH_TYPE, getPathType()); long next = getNext(transporter); if (next != Long.MAX_VALUE) { @@ -114,7 +116,7 @@ public void writeToUpdateTag(HolderLookup.Provider provider, LogisticalTransport public void readFromUpdateTag(HolderLookup.Provider provider, CompoundTag updateTag) { this.color = NBTUtils.getEnum(updateTag, SerializationConstants.COLOR, EnumColor.BY_ID); progress = updateTag.getInt(SerializationConstants.PROGRESS); - NBTUtils.setBlockPosIfPresent(updateTag, SerializationConstants.ORIGINAL_LOCATION, coord -> originalLocation = coord); + NBTUtils.setLongIfPresent(updateTag, SerializationConstants.ORIGINAL_LOCATION, coord -> originalLocation = coord); NBTUtils.setEnumIfPresent(updateTag, SerializationConstants.PATH_TYPE, Path.BY_ID, type -> pathType = type); //todo is backcompat needed? @@ -137,13 +139,13 @@ public void write(HolderLookup.Provider provider, CompoundTag nbtTags) { } nbtTags.putInt(SerializationConstants.PROGRESS, progress); - nbtTags.put(SerializationConstants.ORIGINAL_LOCATION, NbtUtils.writeBlockPos(originalLocation)); + nbtTags.putLong(SerializationConstants.ORIGINAL_LOCATION, originalLocation); if (idleDir != null) { NBTUtils.writeEnum(nbtTags, SerializationConstants.IDLE_DIR, idleDir); } - if (homeLocation != null) { - nbtTags.put(SerializationConstants.HOME_LOCATION, NbtUtils.writeBlockPos(homeLocation)); + if (homeLocation != Long.MAX_VALUE) { + nbtTags.putLong(SerializationConstants.HOME_LOCATION, homeLocation); } if (pathType != null) { NBTUtils.writeEnum(nbtTags, SerializationConstants.PATH_TYPE, pathType); @@ -156,12 +158,15 @@ public void write(HolderLookup.Provider provider, CompoundTag nbtTags) { public void read(HolderLookup.Provider provider, CompoundTag nbtTags) { this.color = NBTUtils.getEnum(nbtTags, SerializationConstants.COLOR, EnumColor.BY_ID); progress = nbtTags.getInt(SerializationConstants.PROGRESS); - NBTUtils.setBlockPosIfPresent(nbtTags, SerializationConstants.ORIGINAL_LOCATION, coord -> originalLocation = coord); + NBTUtils.setBlockPosIfPresent(nbtTags, SerializationConstants.ORIGINAL_LOCATION, coord -> originalLocation = coord.asLong());//TODO 1.22 remove backcompat + NBTUtils.setLongIfPresent(nbtTags, SerializationConstants.ORIGINAL_LOCATION, coord -> originalLocation = coord); NBTUtils.setEnumIfPresent(nbtTags, SerializationConstants.IDLE_DIR, Direction::from3DDataValue, dir -> idleDir = dir); - NBTUtils.setBlockPosIfPresent(nbtTags, SerializationConstants.HOME_LOCATION, coord -> homeLocation = coord); + NBTUtils.setBlockPosIfPresent(nbtTags, SerializationConstants.HOME_LOCATION, coord -> homeLocation = coord.asLong());//TODO 1.22 remove backcompat + NBTUtils.setLongIfPresent(nbtTags, SerializationConstants.HOME_LOCATION, coord -> homeLocation = coord); NBTUtils.setEnumIfPresent(nbtTags, SerializationConstants.PATH_TYPE, Path.BY_ID, type -> pathType = type); - if (nbtTags.contains(SerializationConstants.ITEM_OVERSIZED)) { - itemStack = SerializerHelper.parseOversized(provider, nbtTags.get(SerializationConstants.ITEM_OVERSIZED)).orElse(ItemStack.EMPTY); + Tag oversizedTag = nbtTags.get(SerializationConstants.ITEM_OVERSIZED); + if (oversizedTag != null) { + itemStack = SerializerHelper.parseOversized(provider, oversizedTag).orElse(ItemStack.EMPTY); } else if (nbtTags.contains(SerializationConstants.ITEM, Tag.TAG_COMPOUND)) {//TODO - 1.22: Remove this legacy way of loading data itemStack = ItemStack.parseOptional(provider, nbtTags.getCompound(SerializationConstants.ITEM)); } else {//TODO - 1.22: Remove this legacy way of loading data @@ -248,7 +253,7 @@ public boolean calculateIdle(LogisticalTransporterBase transporter) { idleDir = null; } setPath(transporter.getLevel(), newPath.path(), newPath.type(), true); - originalLocation = transporter.getBlockPos(); + originalLocation = transporter.getWorldPositionLong(); initiatedPath = true; return true; } @@ -258,18 +263,18 @@ public boolean isFinal(LogisticalTransporterBase transporter) { } //TODO - 1.20.5: Re-evaluate this method - public TransporterStack updateForPos(BlockPos pos) { + public TransporterStack updateForPos(long pos) { clientNext = getNext(pos); - clientPrev = getPrev(pos.asLong()); + clientPrev = getPrev(pos); return this; } public long getNext(LogisticalTransporterBase transporter) { - return transporter.isRemote() ? clientNext : getNext(transporter.getBlockPos()); + return transporter.isRemote() ? clientNext : getNext(transporter.getWorldPositionLong()); } - private long getNext(BlockPos pos) { - int index = pathToTarget.indexOf(pos.asLong()) - 1; + private long getNext(long pos) { + int index = pathToTarget.indexOf(pos) - 1; if (index < 0) { return Long.MAX_VALUE; } @@ -285,7 +290,7 @@ private long getPrev(long pos) { if (index < pathToTarget.size()) { return pathToTarget.getLong(index); } - return originalLocation.asLong(); + return originalLocation; } public Direction getSide(LogisticalTransporterBase transporter) { @@ -308,10 +313,10 @@ public Direction getSide(LogisticalTransporterBase transporter) { return side == null ? Direction.DOWN : side; } - public Direction getSide(BlockPos pos, long target) { + public Direction getSide(long pos, long target) { Direction side = null; if (target != Long.MAX_VALUE) { - side = WorldUtils.sideDifference(target, pos.asLong()); + side = WorldUtils.sideDifference(target, pos); } //TODO: See getSide(Transporter) for why we null check and then return down return side == null ? Direction.DOWN : side; diff --git a/src/main/java/mekanism/common/network/PacketUtils.java b/src/main/java/mekanism/common/network/PacketUtils.java index ee42bccc6da..4fb1b821d48 100644 --- a/src/main/java/mekanism/common/network/PacketUtils.java +++ b/src/main/java/mekanism/common/network/PacketUtils.java @@ -113,6 +113,11 @@ public static BlockEntity blockEntity(IPayloadContext context, BlockPos pos) { return WorldUtils.getTileEntity(context.player().level(), pos); } + @Nullable + public static BlockEntity blockEntity(IPayloadContext context, long pos) { + return WorldUtils.getTileEntity(context.player().level(), pos); + } + /** * Send this message to the server. * diff --git a/src/main/java/mekanism/common/network/to_client/transmitter/PacketTransporterBatch.java b/src/main/java/mekanism/common/network/to_client/transmitter/PacketTransporterBatch.java index e82ed0d526a..23294054d28 100644 --- a/src/main/java/mekanism/common/network/to_client/transmitter/PacketTransporterBatch.java +++ b/src/main/java/mekanism/common/network/to_client/transmitter/PacketTransporterBatch.java @@ -10,7 +10,6 @@ import mekanism.common.network.IMekanismPacket; import mekanism.common.network.PacketUtils; import mekanism.common.tile.transmitter.TileEntityLogisticalTransporterBase; -import net.minecraft.core.BlockPos; import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; @@ -18,17 +17,17 @@ import net.neoforged.neoforge.network.handling.IPayloadContext; import org.jetbrains.annotations.NotNull; -public record PacketTransporterBatch(BlockPos pos, IntSet deletes, Int2ObjectMap updates) implements IMekanismPacket { +public record PacketTransporterBatch(long pos, IntSet deletes, Int2ObjectMap updates) implements IMekanismPacket { public static final CustomPacketPayload.Type TYPE = new CustomPacketPayload.Type<>(Mekanism.rl("transporter_batch")); public static final StreamCodec STREAM_CODEC = StreamCodec.composite( - BlockPos.STREAM_CODEC, PacketTransporterBatch::pos, + ByteBufCodecs.VAR_LONG, PacketTransporterBatch::pos, ByteBufCodecs.VAR_INT.apply(ByteBufCodecs.collection(IntOpenHashSet::new)), PacketTransporterBatch::deletes, ByteBufCodecs.map(Int2ObjectOpenHashMap::new, ByteBufCodecs.VAR_INT, TransporterStack.STREAM_CODEC), PacketTransporterBatch::updates, PacketTransporterBatch::new ); - public static PacketTransporterBatch create(BlockPos pos, IntSet deletes, Int2ObjectMap updates) { + public static PacketTransporterBatch create(long pos, IntSet deletes, Int2ObjectMap updates) { for (TransporterStack stack : updates.values()) { stack.updateForPos(pos); } diff --git a/src/main/java/mekanism/common/network/to_client/transmitter/PacketTransporterSync.java b/src/main/java/mekanism/common/network/to_client/transmitter/PacketTransporterSync.java index 796f771f1f9..c4f3584e7bd 100644 --- a/src/main/java/mekanism/common/network/to_client/transmitter/PacketTransporterSync.java +++ b/src/main/java/mekanism/common/network/to_client/transmitter/PacketTransporterSync.java @@ -5,7 +5,6 @@ import mekanism.common.network.IMekanismPacket; import mekanism.common.network.PacketUtils; import mekanism.common.tile.transmitter.TileEntityLogisticalTransporterBase; -import net.minecraft.core.BlockPos; import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; @@ -13,17 +12,17 @@ import net.neoforged.neoforge.network.handling.IPayloadContext; import org.jetbrains.annotations.NotNull; -public record PacketTransporterSync(BlockPos pos, int stackId, TransporterStack stack) implements IMekanismPacket { +public record PacketTransporterSync(long pos, int stackId, TransporterStack stack) implements IMekanismPacket { public static final CustomPacketPayload.Type TYPE = new CustomPacketPayload.Type<>(Mekanism.rl("transporter_sync")); public static final StreamCodec STREAM_CODEC = StreamCodec.composite( - BlockPos.STREAM_CODEC, PacketTransporterSync::pos, + ByteBufCodecs.VAR_LONG, PacketTransporterSync::pos, ByteBufCodecs.VAR_INT, PacketTransporterSync::stackId, TransporterStack.STREAM_CODEC, PacketTransporterSync::stack, PacketTransporterSync::new ); - public static PacketTransporterSync create(BlockPos pos, int stackId, TransporterStack stack) { + public static PacketTransporterSync create(long pos, int stackId, TransporterStack stack) { return new PacketTransporterSync(pos, stackId, stack.updateForPos(pos)); } diff --git a/src/main/java/mekanism/common/tile/transmitter/TileEntityLogisticalTransporterBase.java b/src/main/java/mekanism/common/tile/transmitter/TileEntityLogisticalTransporterBase.java index 4af8fd38c42..31f724f5474 100644 --- a/src/main/java/mekanism/common/tile/transmitter/TileEntityLogisticalTransporterBase.java +++ b/src/main/java/mekanism/common/tile/transmitter/TileEntityLogisticalTransporterBase.java @@ -13,6 +13,7 @@ import mekanism.common.content.transporter.TransporterStack; import mekanism.common.lib.transmitter.ConnectionType; import mekanism.common.util.TransporterUtils; +import mekanism.common.util.WorldUtils; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.world.level.Level; @@ -106,7 +107,7 @@ public T resolve(BlockCapability capability, @Nullab if (transporter.exposesInsertCap(side)) { CursedTransporterItemHandler cached = cursedHandlers.get(side); if (cached == null) { - cached = new CursedTransporterItemHandler(transporter, worldPosition.relative(side), () -> level == null ? -1 : level.getGameTime()); + cached = new CursedTransporterItemHandler(transporter, WorldUtils.relativePos(getWorldPositionLong(), side), () -> level == null ? -1 : level.getGameTime()); cursedHandlers.put(side, cached); } handlers.put(side, cached); diff --git a/src/main/java/mekanism/common/util/WorldUtils.java b/src/main/java/mekanism/common/util/WorldUtils.java index 4683c9b62f5..91048f9093a 100644 --- a/src/main/java/mekanism/common/util/WorldUtils.java +++ b/src/main/java/mekanism/common/util/WorldUtils.java @@ -29,7 +29,6 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.context.BlockPlaceContext; -import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.GameRules; @@ -69,6 +68,19 @@ public static boolean isChunkLoaded(@Nullable LevelReader world, @NotNull BlockP return isChunkLoaded(world, SectionPos.blockToSectionCoord(pos.getX()), SectionPos.blockToSectionCoord(pos.getZ())); } + /** + * Checks if the chunk at the given position is loaded but does not validate the position is in bounds of the world. + * + * @param world world + * @param pos packed block position + * + * @see #isBlockLoaded(BlockGetter, BlockPos) + */ + @Contract("null, _ -> false") + public static boolean isChunkLoaded(@Nullable LevelReader world, long pos) { + return isChunkLoaded(world, SectionPos.blockToSectionCoord(BlockPos.getX(pos)), SectionPos.blockToSectionCoord(BlockPos.getZ(pos))); + } + /** * Checks if the chunk at the given position is loaded. * @@ -124,6 +136,41 @@ public static boolean isBlockLoaded(@Nullable BlockGetter world, @NotNull BlockP return true; } + private static boolean isInWorldBound(BlockGetter world, long pos) { + return !world.isOutsideBuildHeight(BlockPos.getY(pos)) && isInWorldBoundsHorizontal(pos); + } + + private static boolean isInWorldBoundsHorizontal(long pos) { + int x = BlockPos.getX(pos); + int z = BlockPos.getZ(pos); + return x >= -30000000 && z >= -30000000 && x < 30000000 && z < 30000000; + } + + /** + * Checks if a position is in bounds of the world, and is loaded + * + * @param world world + * @param pos packed block position + * + * @return True if the position is loaded or the given world is of a superclass of IWorldReader that does not have a concept of being loaded. + * + * @implNote the checks for world bound don't account for a mod changing the default 30,000,000 limit, but surely that's rare... + */ + @Contract("null, _ -> false") + public static boolean isBlockLoaded(@Nullable BlockGetter world, long pos) { + if (world == null) { + return false; + } else if (world instanceof LevelReader reader) { + if (reader instanceof Level level && !isInWorldBound(level, pos)) { + return false; + } + //TODO: If any cases come up where things are behaving oddly due to the change from reader.hasChunkAt(pos) + // re-evaluate this and if the specific case is being handled properly + return isChunkLoaded(reader, pos); + } + return true; + } + /** * Checks if a position is in bounds of the world * @@ -296,6 +343,24 @@ public static T getTileEntity(@NotNull Class clazz, @ return getTileEntity(clazz, getChunkForPos(world, chunkMap, pos), pos, logWrongType); } + /** + * Gets a tile entity if the location is loaded + * + * @param world world + * @param pos position + * + * @return tile entity if found, null if either not found or not loaded + */ + @Nullable + @Contract("null, _ -> null") + public static BlockEntity getTileEntity(@Nullable BlockGetter world, long pos) { + if (!isBlockLoaded(world, pos)) { + //If the world is null, or it is a world reader and the block is not loaded, return null + return null; + } + return world.getBlockEntity(BlockPos.of(pos)); + } + /** * Gets a tile entity if the location is loaded *