From 8e966d3257cbc3fd57b4382325cd092510a12884 Mon Sep 17 00:00:00 2001 From: B1n_ry Date: Fri, 11 Oct 2024 13:46:59 +0200 Subject: [PATCH] Graves will no longer overwrite other graves when dying in exact same places outside the world --- CHANGELOG.md | 4 + gradle.properties | 2 +- .../yigd/components/GraveComponent.java | 78 +++++++++---------- .../yigd/events/YigdServerEventHandler.java | 4 + 4 files changed, 47 insertions(+), 41 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d5d5b6..f109ec1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # You're in Grave Danger 2.4.11 +### Fixes +* Graves will no longer overwrite other graves when dying in exact same places +outside the world + --- # You're in Grave Danger 2.4.10 diff --git a/gradle.properties b/gradle.properties index 70fdda4..753066b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -33,7 +33,7 @@ org.gradle.parallel=true # inventorio_version=GX7qPAzO travelers_backpack_version=1.21-10.0.6 # numismatic_version=0.2.14+1.20.3 -# apoli_version=2.12.0-alpha.4+mc.1.20.4 +# apoli_version=2.12.0-alpha.12+mc.1.21.x # origins_version=v1.12.10 # levelz_version=1.4.13+1.20.1 # beans_backpacks_version=bsSV8DuI diff --git a/src/main/java/com/b1n_ry/yigd/components/GraveComponent.java b/src/main/java/com/b1n_ry/yigd/components/GraveComponent.java index 4d11d70..1f911e0 100644 --- a/src/main/java/com/b1n_ry/yigd/components/GraveComponent.java +++ b/src/main/java/com/b1n_ry/yigd/components/GraveComponent.java @@ -202,11 +202,41 @@ public DirectionalPos findGravePos(Direction defaultDirection) { return new DirectionalPos(this.pos, defaultDirection); } + YigdConfig config = YigdConfig.getConfig(); + int y = this.pos.getY(); + int lowerAcceptableY = config.graveConfig.lowestGraveY + this.world.getBottomY(); + if (config.graveConfig.generateGraveInVoid && this.pos.getY() <= lowerAcceptableY) { + y = lowerAcceptableY; + } + int topY = this.world.getTopY() - 1; // Can't actually place blocks at top Y + if (y > topY) { + y = topY; + } + + int x = this.pos.getX(); + int z = this.pos.getZ(); + if (config.graveConfig.generateOnlyWithinBorder) { + WorldBorder border = this.world.getWorldBorder(); + if (!border.contains(x, z)) { + x = (int) Math.max(x, border.getBoundWest()); + x = (int) Math.min(x, border.getBoundEast()); + + z = (int) Math.max(z, border.getBoundNorth()); + z = (int) Math.min(z, border.getBoundSouth()); + } + } + + this.pos = new BlockPos(x, y, z); + + // Makes sure the grave is not broken/replaced by portal, or the dragon egg + if (this.world.getRegistryKey().equals(World.END)) { + if (Math.abs(this.pos.getX()) + Math.abs(this.pos.getZ()) < 25 && this.world.getBlockState(this.pos.down()).isOf(Blocks.BEDROCK)) + this.pos = this.pos.up(); + } DirectionalPos graveyardPos = this.findPosInGraveyard(defaultDirection); if (graveyardPos != null) return graveyardPos; - YigdConfig config = YigdConfig.getConfig(); YigdConfig.GraveConfig.Range generationMaxDistance = config.graveConfig.generationMaxDistance; if (config.graveConfig.tryGenerateOnGround) { @@ -218,6 +248,8 @@ public DirectionalPos findGravePos(Direction defaultDirection) { } } + DeathInfoManager.INSTANCE.markDirty(); // The "this" object is (at least should be) located inside DeathInfoManager.INSTANCE + // Loop should ABSOLUTELY NOT loop 50 times, but in case some stupid ass person (maybe me lol) doesn't return true by default // in canGenerate when i reaches some value (maybe 4) there is a cap at least, so the loop won't continue forever and freeze the game for (int i = 0; i < 50; i++) { @@ -269,50 +301,16 @@ private DirectionalPos findPosInGraveyard(Direction defaultDirection) { /** * Called to place down a grave block. Should only be called from server - * @param attemptedPos Where the grave should try to be placed + * * @param state Which block should be placed * @return Weather or not the grave was placed */ - public boolean tryPlaceGraveAt(BlockPos attemptedPos, BlockState state) { + public boolean tryPlaceGrave(BlockState state) { if (this.world == null) { Yigd.LOGGER.error("GraveComponent tried to place grave without knowing the ServerWorld"); return false; } - YigdConfig.GraveConfig config = YigdConfig.getConfig().graveConfig; - int y = attemptedPos.getY(); - int lowerAcceptableY = config.lowestGraveY + this.world.getBottomY(); - if (config.generateGraveInVoid && attemptedPos.getY() <= lowerAcceptableY) { - y = lowerAcceptableY; - } - int topY = this.world.getTopY() - 1; // Can't actually place blocks at top Y - if (y > topY) { - y = topY; - } - - int x = attemptedPos.getX(); - int z = attemptedPos.getZ(); - if (config.generateOnlyWithinBorder) { - WorldBorder border = this.world.getWorldBorder(); - if (!border.contains(x, z)) { - x = (int) Math.max(x, border.getBoundWest()); - x = (int) Math.min(x, border.getBoundEast()); - - z = (int) Math.max(z, border.getBoundNorth()); - z = (int) Math.min(z, border.getBoundSouth()); - } - } - - this.pos = new BlockPos(x, y, z); - - // Makes sure the grave is not broken/replaced by portal, or the dragon egg - if (this.world.getRegistryKey().equals(World.END)) { - if (Math.abs(attemptedPos.getX()) + Math.abs(attemptedPos.getZ()) < 25 && this.world.getBlockState(attemptedPos.down()).isOf(Blocks.BEDROCK)) - this.pos = this.pos.up(); - } - - DeathInfoManager.INSTANCE.markDirty(); // The "this" object is (at least should be) located inside DeathInfoManager.INSTANCE - this.placeBlockUnder(); return this.world.setBlockState(this.pos, state); } @@ -341,12 +339,12 @@ public void placeAndLoad(Direction direction, DeathContext context, BlockPos pos Yigd.END_OF_TICK.add(() -> { BlockState previousState = world.getBlockState(pos); - boolean placed = this.tryPlaceGraveAt(pos, graveBlock); + boolean placed = this.tryPlaceGrave(graveBlock); BlockPos placedPos = this.getPos(); if (!placed) { - Yigd.LOGGER.error("Failed to generate grave at X: %d, Y: %d, Z: %d, %s. Grave block placement failed".formatted( - placedPos.getX(), placedPos.getY(), placedPos.getZ(), world.getRegistryKey().getValue())); + Yigd.LOGGER.error("Failed to generate grave at X: {}, Y: {}, Z: {}, {}. Grave block placement failed", + placedPos.getX(), placedPos.getY(), placedPos.getZ(), world.getRegistryKey().getValue()); Yigd.LOGGER.info("Dropping items on ground instead of in grave"); context.player().sendMessage(Text.translatable("text.yigd.message.grave_generation_error")); this.getInventoryComponent().dropGraveItems(world, Vec3d.of(placedPos)); diff --git a/src/main/java/com/b1n_ry/yigd/events/YigdServerEventHandler.java b/src/main/java/com/b1n_ry/yigd/events/YigdServerEventHandler.java index 0ac1c61..83e60a3 100644 --- a/src/main/java/com/b1n_ry/yigd/events/YigdServerEventHandler.java +++ b/src/main/java/com/b1n_ry/yigd/events/YigdServerEventHandler.java @@ -210,6 +210,10 @@ public static void registerEventCallbacks() { (grave, currentUnder) -> YigdConfig.getConfig().graveConfig.blockUnderGrave.enabled && currentUnder.isIn(YigdTags.REPLACE_SOFT_WHITELIST)); GraveGenerationEvent.EVENT.register((world, pos, nthTry) -> { + if (world.isOutOfHeightLimit(pos) || !world.getWorldBorder().contains(pos)) { + return false; + } + BlockState state = world.getBlockState(pos); YigdConfig.GraveConfig config = YigdConfig.getConfig().graveConfig; if (world.getBlockEntity(pos) != null) // Block entities should NOT be replaced by graves