Skip to content

Commit

Permalink
(Fixes #83) Improve grave placement algorithm
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
ginsm committed Oct 23, 2023
1 parent ad536f1 commit 62cfc60
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 13 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}

Expand Down
11 changes: 7 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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! :)
### 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).
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
38 changes: 33 additions & 5 deletions src/main/java/me/mgin/graves/block/utility/PlaceGrave.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,28 @@ 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);
}

// Place the grave
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.
*
Expand Down Expand Up @@ -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;
}

/**
Expand Down

0 comments on commit 62cfc60

Please sign in to comment.