fix: detect vertical falling blocks entering end portals

This commit is contained in:
MidnightTale 2026-08-03 16:46:04 +07:00
commit 8acab44797
2 changed files with 42 additions and 16 deletions

1
.gitignore vendored
View file

@ -116,3 +116,4 @@ run/
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
!gradle-wrapper.jar !gradle-wrapper.jar
niri-rpc/

View file

@ -9,6 +9,7 @@ import org.bukkit.entity.FallingBlock;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityChangeBlockEvent; import org.bukkit.event.entity.EntityChangeBlockEvent;
import org.bukkit.event.entity.EntityPortalEnterEvent;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import xyz.hynse.foliaflow.FoliaFlow; import xyz.hynse.foliaflow.FoliaFlow;
@ -18,31 +19,55 @@ import static xyz.hynse.foliaflow.util.VelocityUtil.getBlockMovingTo;
public class PortalWatcher implements Listener { public class PortalWatcher implements Listener {
private static final String DUPE_TAG = "foliaflow_dupe";
@EventHandler @EventHandler
public void onFallingBlockToBlock(EntityChangeBlockEvent e){ public void onFallingBlockToBlock(EntityChangeBlockEvent e){
if(e.getEntityType() != EntityType.FALLING_BLOCK) return; if(e.getEntityType() != EntityType.FALLING_BLOCK) return;
Entity entity = e.getEntity(); Entity entity = e.getEntity();
if(entity.getScoreboardTags().contains(DUPE_TAG)) return;
Location loc = entity.getLocation(); Location loc = entity.getLocation();
Vector vel = entity.getVelocity(); Vector vel = entity.getVelocity();
Block movingTo = getBlockMovingTo(loc, vel); Block movingTo = getBlockMovingTo(loc, vel);
if(movingTo.getType() == Material.END_PORTAL){ if(movingTo.getType() == Material.END_PORTAL){
Location spawnLoc = movingTo.getLocation(); spawnDupe(entity, movingTo, false);
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
);
} }
} }
@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
);
}
} }