From 62cfc60d4e59d11588130617dde5e78f6c8eb7a5 Mon Sep 17 00:00:00 2001 From: Ginsm Date: Sat, 30 Sep 2023 01:55:45 -0400 Subject: [PATCH] (Fixes #83) Improve grave placement algorithm The new algorithm will try and find an 'ideal' spot to place the grave when you die inside of a block (kelp, fences, stairs, path block, etc). An 'ideal' spot would be either in a liquid block or air. --- .github/workflows/publish.yml | 4 +- CHANGELOG.md | 11 ++++-- gradle.properties | 4 +- .../mgin/graves/block/utility/PlaceGrave.java | 38 ++++++++++++++++--- 4 files changed, 44 insertions(+), 13 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 8a940e65..4dd85f94 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -4,8 +4,8 @@ on: [ workflow_dispatch ] env: JAVA_VERSION: 17 - VERSION: 1.20.1-3.2.1 - RELEASE_NAME: Forgotten Graves 1.20.1-3.2.1 + VERSION: 1.20.1-3.2.3 + RELEASE_NAME: Forgotten Graves 1.20.1-3.2.3 MODRINTH_TOKEN: ${{ secrets.PUBLISH_MODRINTH_TOKEN }} CURSEFORGE_TOKEN: ${{ secrets.PUBLISH_CURSEFORGE_TOKEN }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 72e3b08f..02c09bfc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,9 @@ -## 1.20.1-3.2.1 +## 1.20.1-3.2.2 -### Added -- Added `ru_ru` and `es_mx` translations; please feel free to let me know about any mistakes. +### Updated +- Cloth config's version has been updated to the latest version (v11.1.106). + +## 1.20.1-3.2.3 -Thanks a bunch, mpustovoi, for the Russian translation! :) \ No newline at end of file +### Added +- The grave placement search algorithm has been improved to try and find more 'ideal' placement locations (i.e. in a liquid or air, rather than another block). \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 715a5739..3c25a9bc 100755 --- a/gradle.properties +++ b/gradle.properties @@ -8,12 +8,12 @@ loader_version=0.14.22 fabric_version=0.83.1+1.20.1 # Mod Properties -mod_version=1.20.1-3.2.1 +mod_version=1.20.1-3.2.3 maven_group=me.mgin archives_base_name=forgottengraves # Dependencies -cloth_config_version=11.0.99 +cloth_config_version=11.1.106 # Optional Dependencies mod_menu_version=7.0.1 diff --git a/src/main/java/me/mgin/graves/block/utility/PlaceGrave.java b/src/main/java/me/mgin/graves/block/utility/PlaceGrave.java index 92898c27..a247989b 100755 --- a/src/main/java/me/mgin/graves/block/utility/PlaceGrave.java +++ b/src/main/java/me/mgin/graves/block/utility/PlaceGrave.java @@ -53,8 +53,8 @@ public static void place(World world, Vec3d vecPos, PlayerEntity player) { pos = sinkDownwards(world, belowPos, pos.getY() - (minY + 7), player); } - // Try and find a new valid position - if (!canPlaceGrave(world, block, initialPos)) { + // Try and find a new valid, ideal position + if (!canPlaceGrave(world, block, initialPos) || !isLiquidOrAir(world, initialPos)) { pos = searchOutwards(world, pos, player); } @@ -62,6 +62,19 @@ public static void place(World world, Vec3d vecPos, PlayerEntity player) { spawnGrave(world, pos, player); } + /** + * Checks to see if the block is an liquid or air. This is useful to prevent breaking blocks that aren't + * standard 1x1 collision blocks (fences, path blocks, etc). + * + * @param world World + * @param pos BlockPos + * @return boolean + */ + private static boolean isLiquidOrAir(World world, BlockPos pos) { + BlockState state = world.getBlockState(pos); + return state.isAir() || state.isLiquid(); + } + /** * Ensures that graves only spawn inside the world boundaries. * @@ -158,23 +171,38 @@ private static boolean canPlaceGrave(World world, Block block, BlockPos pos) { * @return BlockPos */ private static BlockPos searchOutwards(World world, BlockPos pos, PlayerEntity player) { + // This is used to find an 'ideal' spot; an ideal spot is either liquid or air. + BlockPos firstNonIdeal = null; + boolean idealBlockFound = false; + for (BlockPos newPos : BlockPos.iterateOutwards(pos, 10, 10, 10)) { Block block = world.getBlockState(newPos).getBlock(); if (canPlaceGrave(world, block, newPos)) { BlockPos belowPos = new BlockPos(newPos.getX(), newPos.getY() - 1, newPos.getZ()); + // This always ends up with an ideal spot; simply return result of sinkDownwards if (graveShouldSink(world, belowPos, player)) { pos = sinkDownwards(world, belowPos, pos.getY() - (minY + 7), player); break; } - pos = newPos; - break; + // Ensure the position is an ideal spot, if so, set and break loop + idealBlockFound = isLiquidOrAir(world, newPos); + if (idealBlockFound) { + pos = newPos; + break; + } + + // Assign the first non-ideal spot; this spot can still be placed but will end up breaking + // replacing another block. This is a fallback. + if (firstNonIdeal == null) { + firstNonIdeal = newPos; + } } } - return pos; + return idealBlockFound ? pos : firstNonIdeal; } /**