diff --git a/src/main/java/dev/cammiescorner/arcanuscontinuum/common/components/level/PocketDimensionComponent.java b/src/main/java/dev/cammiescorner/arcanuscontinuum/common/components/level/PocketDimensionComponent.java index 86e8ecd..79e6edf 100644 --- a/src/main/java/dev/cammiescorner/arcanuscontinuum/common/components/level/PocketDimensionComponent.java +++ b/src/main/java/dev/cammiescorner/arcanuscontinuum/common/components/level/PocketDimensionComponent.java @@ -16,15 +16,11 @@ import net.minecraft.nbt.NbtList; import net.minecraft.registry.RegistryKey; import net.minecraft.registry.RegistryKeys; -import net.minecraft.server.MinecraftServer; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.Identifier; import net.minecraft.util.Pair; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Box; -import net.minecraft.util.math.Direction; -import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.*; import net.minecraft.world.TeleportTarget; import net.minecraft.world.World; import net.minecraft.world.WorldProperties; @@ -51,7 +47,7 @@ public void readFromNbt(NbtCompound tag) { existingPlots.clear(); exitSpot.clear(); - for(int i = 0; i < plotNbtList.size(); i++) { + for (int i = 0; i < plotNbtList.size(); i++) { NbtCompound entry = plotNbtList.getCompound(i); existingPlots.put( entry.getUuid("OwnerUuid"), @@ -59,14 +55,14 @@ public void readFromNbt(NbtCompound tag) { ); } - for(int i = 0; i < exitNbtList.size(); i++) { + for (int i = 0; i < exitNbtList.size(); i++) { NbtCompound entry = exitNbtList.getCompound(i); exitSpot.put( - entry.getUuid("EntityId"), - new Pair<>( - RegistryKey.of(RegistryKeys.WORLD, new Identifier(entry.getString("WorldKey"))), + entry.getUuid("EntityId"), + new Pair<>( + RegistryKey.of(RegistryKeys.WORLD, new Identifier(entry.getString("WorldKey"))), new Vec3d(entry.getDouble("X"), entry.getDouble("Y"), entry.getDouble("Z")) - ) + ) ); } } @@ -102,36 +98,61 @@ public void writeToNbt(NbtCompound tag) { tag.put("ExitSpots", exitNbtList); } - public void teleportToPocketDimension(PlayerEntity ownerOfPocket, Entity entity) { - if(!entity.getWorld().isClient()) { - if(!existingPlots.containsKey(ownerOfPocket.getUuid())) - generateNewPlot(ownerOfPocket); + private static boolean chunksExist(Box plot, PlayerEntity owner, ServerWorld pocketDim) { + var chunkManager = pocketDim.getChunkManager(); + + var passed = BlockPos.stream(plot) + .map(ChunkPos::new).distinct() + .map(cPos -> chunkManager.getWorldChunk(cPos.x, cPos.z, false)) + .noneMatch(Objects::isNull); + if (!passed) { + Arcanus.LOGGER.warn("Pocket dimension plot for player {} failed integrity check! regenerating...", owner.getGameProfile().getName()); + } + + return passed; + } + + public void teleportToPocketDimension(PlayerEntity ownerOfPocket, Entity entity) { + if (!entity.getWorld().isClient()) { ServerWorld pocketDim = entity.getServer().getWorld(POCKET_DIM); + if (pocketDim != null) { + Box plot = existingPlots.get(ownerOfPocket.getUuid()); + if (plot == null || !chunksExist(plot, ownerOfPocket, pocketDim)) { + generateNewPlot(ownerOfPocket, pocketDim); + } + plot = existingPlots.get(ownerOfPocket.getUuid()); - if(pocketDim != null) - QuiltDimensions.teleport(entity, pocketDim, new TeleportTarget(existingPlots.get(ownerOfPocket.getUuid()).getCenter().subtract(0, 11, 0), Vec3d.ZERO, entity.getYaw(), entity.getPitch())); + QuiltDimensions.teleport(entity, pocketDim, new TeleportTarget(plot.getCenter().subtract(0, 11, 0), Vec3d.ZERO, entity.getYaw(), entity.getPitch())); + } } } public void teleportOutOfPocketDimension(ServerPlayerEntity player) { - if(!player.getWorld().isClient() && player.getWorld().getRegistryKey() == POCKET_DIM) { + if (!player.getWorld().isClient() && player.getWorld().getRegistryKey() == POCKET_DIM) { Optional> entry = existingPlots.entrySet().stream().filter(entry1 -> entry1.getValue().intersects(player.getBoundingBox())).findFirst(); - if(entry.isPresent()) { + if (entry.isPresent()) { UUID ownerId = entry.get().getKey(); Pair, Vec3d> pair = exitSpot.get(ownerId); - if(pair == null) - pair = new Pair<>(World.OVERWORLD, Vec3d.ofBottomCenter(player.getServer().getOverworld().getSpawnPos())); + ServerWorld targetWorld; + Vec3d targetPos; + + if (pair == null || (targetWorld = player.getServer().getWorld(pair.getLeft())) == null) { + targetWorld = player.getServer().getOverworld(); + targetPos = Vec3d.ofBottomCenter(targetWorld.getSpawnPos()); + } else { + targetPos = pair.getRight(); + } ArcanusComponents.setPortalCoolDown(player, 200); - QuiltDimensions.teleport(player, player.getServer().getWorld(pair.getLeft()), new TeleportTarget(pair.getRight(), Vec3d.ZERO, player.getYaw(), player.getPitch())); + QuiltDimensions.teleport(player, targetWorld, new TeleportTarget(targetPos, Vec3d.ZERO, player.getYaw(), player.getPitch())); } } } - public void generateNewPlot(PlayerEntity player) { + public void generateNewPlot(PlayerEntity player, ServerWorld pocketDim) { int pocketWidth = Math.round(ArcanusConfig.UtilityEffects.SpatialRiftEffectProperties.pocketWidth / 2f) + 1; int pocketHeight = Math.round(ArcanusConfig.UtilityEffects.SpatialRiftEffectProperties.pocketHeight / 2f) + 1; @@ -139,62 +160,56 @@ public void generateNewPlot(PlayerEntity player) { Box box = new Box(-pocketWidth, -pocketHeight, -pocketWidth, pocketWidth, pocketHeight, pocketWidth); }; - while(existingPlots.entrySet().stream().anyMatch(entry -> entry.getValue().intersects(boxContainer.box.expand(38)))) + while (existingPlots.entrySet().stream().anyMatch(entry -> entry.getValue().intersects(boxContainer.box.expand(38)))) boxContainer.box = boxContainer.box.offset(random.nextInt(-468748, 468749) * 64, random.nextInt(-3, 4) * 64, random.nextInt(-468748, 468749) * 64); existingPlots.put(player.getUuid(), boxContainer.box); - MinecraftServer server = player.getServer(); - - if(server != null) { - ServerWorld pocketDim = server.getWorld(POCKET_DIM); - - if(pocketDim != null) { - for(BlockPos pos : BlockPos.iterate((int) Math.round(boxContainer.box.minX), (int) Math.round(boxContainer.box.minY), (int) Math.round(boxContainer.box.minZ), (int) Math.round(boxContainer.box.maxX - 1), (int) Math.round(boxContainer.box.maxY - 1), (int) Math.round(boxContainer.box.maxZ - 1))) { - if(pos.getX() > boxContainer.box.minX && pos.getX() < boxContainer.box.maxX - 1 && pos.getY() > boxContainer.box.minY && pos.getY() < boxContainer.box.maxY - 1 && pos.getZ() > boxContainer.box.minZ && pos.getZ() < boxContainer.box.maxZ - 1) - continue; + for (BlockPos pos : BlockPos.iterate((int) Math.round(boxContainer.box.minX), (int) Math.round(boxContainer.box.minY), (int) Math.round(boxContainer.box.minZ), (int) Math.round(boxContainer.box.maxX - 1), (int) Math.round(boxContainer.box.maxY - 1), (int) Math.round(boxContainer.box.maxZ - 1))) { + if (pos.getX() > boxContainer.box.minX && pos.getX() < boxContainer.box.maxX - 1 && pos.getY() > boxContainer.box.minY && pos.getY() < boxContainer.box.maxY - 1 && pos.getZ() > boxContainer.box.minZ && pos.getZ() < boxContainer.box.maxZ - 1) + continue; - pocketDim.setBlockState(pos, ArcanusBlocks.UNBREAKABLE_MAGIC_BLOCK.get().getDefaultState()); + pocketDim.setBlockState(pos, ArcanusBlocks.UNBREAKABLE_MAGIC_BLOCK.get().getDefaultState()); - if(pocketDim.getBlockEntity(pos) instanceof MagicBlockEntity magicBlock) - magicBlock.setColour(Arcanus.getMagicColour(player.getGameProfile().getId())); - } + if (pocketDim.getBlockEntity(pos) instanceof MagicBlockEntity magicBlock) + magicBlock.setColour(Arcanus.getMagicColour(player.getGameProfile().getId())); + } - for(int x = 0; x < 4; x++) { - for(int z = 0; z < 4; z++) { - BlockPos pos = new BlockPos((int) Math.round(boxContainer.box.getCenter().getX()) + (x - 2), (int) Math.round(boxContainer.box.minY), (int) Math.round(boxContainer.box.getCenter().getZ()) + (z - 2)); - - if(x == 0) { - switch(z) { - case 0 -> pocketDim.setBlockState(pos, ArcanusBlocks.SPATIAL_RIFT_EXIT_EDGE.get().getDefaultState().with(SpatialRiftExitEdgeBlock.CORNER, true)); - case 1, 2 -> pocketDim.setBlockState(pos, ArcanusBlocks.SPATIAL_RIFT_EXIT_EDGE.get().getDefaultState().with(SpatialRiftExitEdgeBlock.FACING, Direction.WEST)); - case 3 -> pocketDim.setBlockState(pos, ArcanusBlocks.SPATIAL_RIFT_EXIT_EDGE.get().getDefaultState().with(SpatialRiftExitEdgeBlock.FACING, Direction.WEST).with(SpatialRiftExitEdgeBlock.CORNER, true)); - } - } - else if(x == 3) { - switch(z) { - case 0 -> pocketDim.setBlockState(pos, ArcanusBlocks.SPATIAL_RIFT_EXIT_EDGE.get().getDefaultState().with(SpatialRiftExitEdgeBlock.FACING, Direction.EAST).with(SpatialRiftExitEdgeBlock.CORNER, true)); - case 1, 2 -> pocketDim.setBlockState(pos, ArcanusBlocks.SPATIAL_RIFT_EXIT_EDGE.get().getDefaultState().with(SpatialRiftExitEdgeBlock.FACING, Direction.EAST)); - case 3 -> pocketDim.setBlockState(pos, ArcanusBlocks.SPATIAL_RIFT_EXIT_EDGE.get().getDefaultState().with(SpatialRiftExitEdgeBlock.FACING, Direction.SOUTH).with(SpatialRiftExitEdgeBlock.CORNER, true)); - } - } - else if(z == 0) { - pocketDim.setBlockState(pos, ArcanusBlocks.SPATIAL_RIFT_EXIT_EDGE.get().getDefaultState().with(SpatialRiftExitEdgeBlock.FACING, Direction.NORTH)); - } - else if(z == 3) { - pocketDim.setBlockState(pos, ArcanusBlocks.SPATIAL_RIFT_EXIT_EDGE.get().getDefaultState().with(SpatialRiftExitEdgeBlock.FACING, Direction.SOUTH)); - } - else { - pocketDim.setBlockState(pos, ArcanusBlocks.SPATIAL_RIFT_EXIT.get().getDefaultState().with(SpatialRiftExitBlock.ACTIVE, x == 1 && z == 1)); - - if(pocketDim.getBlockEntity(pos) instanceof SpatialRiftExitBlockEntity exitBlockEntity) - exitBlockEntity.setColour(Arcanus.getMagicColour(player.getGameProfile().getId())); - } - - if(pocketDim.getBlockEntity(pos) instanceof MagicBlockEntity magicBlock) - magicBlock.setColour(Arcanus.getMagicColour(player.getGameProfile().getId())); + for (int x = 0; x < 4; x++) { + for (int z = 0; z < 4; z++) { + BlockPos pos = new BlockPos((int) Math.round(boxContainer.box.getCenter().getX()) + (x - 2), (int) Math.round(boxContainer.box.minY), (int) Math.round(boxContainer.box.getCenter().getZ()) + (z - 2)); + + if (x == 0) { + switch (z) { + case 0 -> + pocketDim.setBlockState(pos, ArcanusBlocks.SPATIAL_RIFT_EXIT_EDGE.get().getDefaultState().with(SpatialRiftExitEdgeBlock.CORNER, true)); + case 1, 2 -> + pocketDim.setBlockState(pos, ArcanusBlocks.SPATIAL_RIFT_EXIT_EDGE.get().getDefaultState().with(SpatialRiftExitEdgeBlock.FACING, Direction.WEST)); + case 3 -> + pocketDim.setBlockState(pos, ArcanusBlocks.SPATIAL_RIFT_EXIT_EDGE.get().getDefaultState().with(SpatialRiftExitEdgeBlock.FACING, Direction.WEST).with(SpatialRiftExitEdgeBlock.CORNER, true)); } + } else if (x == 3) { + switch (z) { + case 0 -> + pocketDim.setBlockState(pos, ArcanusBlocks.SPATIAL_RIFT_EXIT_EDGE.get().getDefaultState().with(SpatialRiftExitEdgeBlock.FACING, Direction.EAST).with(SpatialRiftExitEdgeBlock.CORNER, true)); + case 1, 2 -> + pocketDim.setBlockState(pos, ArcanusBlocks.SPATIAL_RIFT_EXIT_EDGE.get().getDefaultState().with(SpatialRiftExitEdgeBlock.FACING, Direction.EAST)); + case 3 -> + pocketDim.setBlockState(pos, ArcanusBlocks.SPATIAL_RIFT_EXIT_EDGE.get().getDefaultState().with(SpatialRiftExitEdgeBlock.FACING, Direction.SOUTH).with(SpatialRiftExitEdgeBlock.CORNER, true)); + } + } else if (z == 0) { + pocketDim.setBlockState(pos, ArcanusBlocks.SPATIAL_RIFT_EXIT_EDGE.get().getDefaultState().with(SpatialRiftExitEdgeBlock.FACING, Direction.NORTH)); + } else if (z == 3) { + pocketDim.setBlockState(pos, ArcanusBlocks.SPATIAL_RIFT_EXIT_EDGE.get().getDefaultState().with(SpatialRiftExitEdgeBlock.FACING, Direction.SOUTH)); + } else { + pocketDim.setBlockState(pos, ArcanusBlocks.SPATIAL_RIFT_EXIT.get().getDefaultState().with(SpatialRiftExitBlock.ACTIVE, x == 1 && z == 1)); + + if (pocketDim.getBlockEntity(pos) instanceof SpatialRiftExitBlockEntity exitBlockEntity) + exitBlockEntity.setColour(Arcanus.getMagicColour(player.getGameProfile().getId())); } + + if (pocketDim.getBlockEntity(pos) instanceof MagicBlockEntity magicBlock) + magicBlock.setColour(Arcanus.getMagicColour(player.getGameProfile().getId())); } } } diff --git a/src/main/java/dev/cammiescorner/arcanuscontinuum/common/registry/ArcanusCommands.java b/src/main/java/dev/cammiescorner/arcanuscontinuum/common/registry/ArcanusCommands.java index 87cbcc5..80db9da 100644 --- a/src/main/java/dev/cammiescorner/arcanuscontinuum/common/registry/ArcanusCommands.java +++ b/src/main/java/dev/cammiescorner/arcanuscontinuum/common/registry/ArcanusCommands.java @@ -5,9 +5,9 @@ import com.mojang.brigadier.arguments.IntegerArgumentType; import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.exceptions.CommandSyntaxException; +import dev.cammiescorner.arcanuscontinuum.common.components.level.PocketDimensionComponent; import net.minecraft.command.CommandBuildContext; import net.minecraft.command.argument.EntityArgumentType; -import net.minecraft.entity.player.PlayerEntity; import net.minecraft.server.command.CommandManager; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.network.ServerPlayerEntity; @@ -59,7 +59,7 @@ public static int setLevel(CommandContext context, ServerPl private static class RegenPocketCommand { public static int regeneratePocket(CommandContext context, ServerPlayerEntity player) throws CommandSyntaxException { - context.getSource().getWorld().getProperties().getComponent(ArcanusComponents.POCKET_DIMENSION_COMPONENT).generateNewPlot(player); + context.getSource().getWorld().getProperties().getComponent(ArcanusComponents.POCKET_DIMENSION_COMPONENT).generateNewPlot(player, context.getSource().getServer().getWorld(PocketDimensionComponent.POCKET_DIM)); context.getSource().sendFeedback(() -> Text.literal(String.format("Regenerated %s's pocket dimension", player.getEntityName())), false); return Command.SINGLE_SUCCESS;