Skip to content

Commit

Permalink
Graves will no longer overwrite other graves when dying in exact same…
Browse files Browse the repository at this point in the history
… places outside the world
  • Loading branch information
B1n-ry committed Oct 11, 2024
1 parent 122626a commit 8e966d3
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 41 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
78 changes: 38 additions & 40 deletions src/main/java/com/b1n_ry/yigd/components/GraveComponent.java
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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++) {
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 8e966d3

Please sign in to comment.