From 8acab4479751258691fdaa1cdb4fdc524a21c368 Mon Sep 17 00:00:00 2001 From: MidnightTale Date: Mon, 3 Aug 2026 16:46:04 +0700 Subject: [PATCH] fix: detect vertical falling blocks entering end portals --- .gitignore | 1 + .../foliaflow/watcher/PortalWatcher.java | 57 +++++++++++++------ 2 files changed, 42 insertions(+), 16 deletions(-) diff --git a/.gitignore b/.gitignore index 3c37caf..cdb5be5 100644 --- a/.gitignore +++ b/.gitignore @@ -116,3 +116,4 @@ run/ # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) !gradle-wrapper.jar +niri-rpc/ diff --git a/src/main/java/xyz/hynse/foliaflow/watcher/PortalWatcher.java b/src/main/java/xyz/hynse/foliaflow/watcher/PortalWatcher.java index 22d26ec..581b07b 100644 --- a/src/main/java/xyz/hynse/foliaflow/watcher/PortalWatcher.java +++ b/src/main/java/xyz/hynse/foliaflow/watcher/PortalWatcher.java @@ -9,6 +9,7 @@ import org.bukkit.entity.FallingBlock; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.entity.EntityChangeBlockEvent; +import org.bukkit.event.entity.EntityPortalEnterEvent; import org.bukkit.util.Vector; import xyz.hynse.foliaflow.FoliaFlow; @@ -18,31 +19,55 @@ import static xyz.hynse.foliaflow.util.VelocityUtil.getBlockMovingTo; public class PortalWatcher implements Listener { + private static final String DUPE_TAG = "foliaflow_dupe"; + @EventHandler public void onFallingBlockToBlock(EntityChangeBlockEvent e){ if(e.getEntityType() != EntityType.FALLING_BLOCK) return; Entity entity = e.getEntity(); + if(entity.getScoreboardTags().contains(DUPE_TAG)) return; Location loc = entity.getLocation(); Vector vel = entity.getVelocity(); Block movingTo = getBlockMovingTo(loc, vel); if(movingTo.getType() == Material.END_PORTAL){ - Location spawnLoc = movingTo.getLocation(); - spawnLoc.add(0.5, FoliaFlow.spawnHeight, 0.5); - - FallingBlock dummy = loc.getWorld().spawnFallingBlock(spawnLoc, ((FallingBlock) entity).getBlockData()); - Vector dummyVel = vel.clone(); - dummyVel.multiply(FoliaFlow.horizontalCoefficient); - dummyVel.setY(vel.getY() * FoliaFlow.verticalCoefficient); - dummy.setVelocity(dummyVel); - - SchedulerUtil.runLaterEntity(dummy, FoliaFlow.instance, () -> { - // Portal teleportation is a bit below vanilla, so we teleport it above - dummy.teleportAsync(dummy.getLocation().add(0, FoliaFlow.TeleportOffset, 0)); - dummy.setVelocity(dummyVel); - }, - 2 - ); + spawnDupe(entity, movingTo, false); } } + + @EventHandler + public void onPortalEnter(EntityPortalEnterEvent e){ + if(e.getEntityType() != EntityType.FALLING_BLOCK) return; + Entity entity = e.getEntity(); + if(entity.getScoreboardTags().contains(DUPE_TAG)) return; + Block portal = e.getLocation().getBlock(); + + if(portal.getType() == Material.END_PORTAL && portal.getRelative(0, -1, 0).getType().name().endsWith("_FENCE")){ + spawnDupe(entity, portal, true); + } + } + + private void spawnDupe(Entity entity, Block portal, boolean passThrough){ + Location spawnLoc = portal.getLocation(); + spawnLoc.add(0.5, FoliaFlow.spawnHeight, 0.5); + + FallingBlock dummy = entity.getWorld().spawnFallingBlock(spawnLoc, ((FallingBlock) entity).getBlockData()); + dummy.addScoreboardTag(DUPE_TAG); + Vector dummyVel = entity.getVelocity().clone(); + dummyVel.multiply(FoliaFlow.horizontalCoefficient); + if(passThrough){ + dummyVel.setY(entity.getVelocity().getY()); + } else { + dummyVel.setY(entity.getVelocity().getY() * FoliaFlow.verticalCoefficient); + } + dummy.setVelocity(dummyVel); + + SchedulerUtil.runLaterEntity(dummy, FoliaFlow.instance, () -> { + // Portal teleportation is a bit below vanilla, so we teleport it above + dummy.teleportAsync(dummy.getLocation().add(0, FoliaFlow.TeleportOffset, 0)); + dummy.setVelocity(dummyVel); + }, + 2 + ); + } }