diff --git a/modules/Movecraft/src/main/java/net/countercraft/movecraft/async/rotation/RotationTask.java b/modules/Movecraft/src/main/java/net/countercraft/movecraft/async/rotation/RotationTask.java index ff2553f1b..22a7032bd 100644 --- a/modules/Movecraft/src/main/java/net/countercraft/movecraft/async/rotation/RotationTask.java +++ b/modules/Movecraft/src/main/java/net/countercraft/movecraft/async/rotation/RotationTask.java @@ -117,6 +117,15 @@ protected void execute() { MovecraftLocation newLocation = MathUtils.rotateVec(rotation,originalLocation.subtract(originPoint)).add(originPoint); newHitBox.add(newLocation); + //Prevent piston bug + if (originalLocation.toBukkit(getCraft().getWorld()).getBlock().getType().equals(Material.MOVING_PISTON)) { + failed = true; + failMessage = (String.format(I18nSupport.getInternationalisedString("Translation - Failed Craft is obstructed") + + " @ %d,%d,%d,%s", originalLocation.getX(), originalLocation.getY(), originalLocation.getZ(), + originalLocation.toBukkit(craft.getWorld()).getBlock().getType())); + break; + } + Material oldMaterial = originalLocation.toBukkit(w).getBlock().getType(); //prevent chests collision if (Tags.CHESTS.contains(oldMaterial) && !checkChests(oldMaterial, newLocation)) { diff --git a/modules/Movecraft/src/main/java/net/countercraft/movecraft/async/translation/TranslationTask.java b/modules/Movecraft/src/main/java/net/countercraft/movecraft/async/translation/TranslationTask.java index 78732983c..6f3729a68 100644 --- a/modules/Movecraft/src/main/java/net/countercraft/movecraft/async/translation/TranslationTask.java +++ b/modules/Movecraft/src/main/java/net/countercraft/movecraft/async/translation/TranslationTask.java @@ -243,6 +243,12 @@ else if (world.equals(craft.getWorld()) newHitBox.add(newLocation); continue; } + //Prevent piston bug + if (oldLocation.toBukkit(world).getBlock().getType().equals(Material.MOVING_PISTON)) + fail(String.format(I18nSupport.getInternationalisedString("Translation - Failed Craft is obstructed") + + " @ %d,%d,%d,%s", oldLocation.getX(), oldLocation.getY(), oldLocation.getZ(), + oldLocation.toBukkit(craft.getWorld()).getBlock().getType())); + final Material testMaterial = newLocation.toBukkit(world).getBlock().getType(); if (Tags.CHESTS.contains(testMaterial) && checkChests(testMaterial, newLocation)) { diff --git a/modules/v1_18_R2/src/main/java/net/countercraft/movecraft/compat/v1_18_R2/IWorldHandler.java b/modules/v1_18_R2/src/main/java/net/countercraft/movecraft/compat/v1_18_R2/IWorldHandler.java index 21ce8941d..7a3273961 100644 --- a/modules/v1_18_R2/src/main/java/net/countercraft/movecraft/compat/v1_18_R2/IWorldHandler.java +++ b/modules/v1_18_R2/src/main/java/net/countercraft/movecraft/compat/v1_18_R2/IWorldHandler.java @@ -19,7 +19,9 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.LevelChunkSection; +import net.minecraft.world.ticks.LevelChunkTicks; import net.minecraft.world.ticks.ScheduledTick; +import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.data.BlockData; @@ -37,6 +39,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.function.Predicate; @SuppressWarnings("unused") public class IWorldHandler extends WorldHandler { @@ -72,15 +75,21 @@ public void rotateCraft(@NotNull Craft craft, @NotNull MovecraftLocation originP //******************************************* ServerLevel nativeWorld = ((CraftWorld) craft.getWorld()).getHandle(); List tiles = new ArrayList<>(); + List ticks = new ArrayList<>(); //get the tiles for (BlockPos position : rotatedPositions.keySet()) { - //BlockEntity tile = nativeWorld.removeBlockEntity(position); + BlockEntity tile = removeBlockEntity(nativeWorld, position); - if (tile == null) - continue; -// tile.a(ROTATION[rotation.ordinal()]); + if (tile != null) + tiles.add(new TileHolder(tile, position)); + //get the nextTick to move with the tile - tiles.add(new TileHolder(tile, tickProvider.getNextTick(nativeWorld, position), position)); + ScheduledTick tickHere = tickProvider.getNextTick(nativeWorld, position); + if (tickHere != null) { + ((LevelChunkTicks) nativeWorld.getChunkAt(position).getBlockTicks()).removeIf( + (Predicate) scheduledTick -> scheduledTick.equals(tickHere)); + ticks.add(new TickHolder(tickHere, position)); + } } //******************************************* @@ -107,10 +116,10 @@ public void rotateCraft(@NotNull Craft craft, @NotNull MovecraftLocation originP //TODO: go by chunks for (TileHolder tileHolder : tiles) { moveBlockEntity(nativeWorld, rotatedPositions.get(tileHolder.getTilePosition()), tileHolder.getTile()); - if (tileHolder.getNextTick() == null) - continue; + } + for (TickHolder tickHolder : ticks) { final long currentTime = nativeWorld.M.getGameTime(); - nativeWorld.getBlockTicks().schedule(new ScheduledTick<>((Block) tileHolder.getNextTick().type(), rotatedPositions.get(tileHolder.getNextTick().pos()), tileHolder.getNextTick().triggerTick() - currentTime, tileHolder.getNextTick().priority(), tileHolder.getNextTick().subTickOrder())); + nativeWorld.getBlockTicks().schedule(new ScheduledTick<>((Block) tickHolder.getTick().type(), rotatedPositions.get(tickHolder.getTick().pos()), tickHolder.getTick().triggerTick() - currentTime, tickHolder.getTick().priority(), tickHolder.getTick().subTickOrder())); } //******************************************* @@ -139,6 +148,7 @@ public void translateCraft(@NotNull Craft craft, @NotNull MovecraftLocation disp //* Step two: Get the tiles * //******************************************* List tiles = new ArrayList<>(); + List ticks = new ArrayList<>(); //get the tiles for (int i = 0, positionsSize = positions.size(); i < positionsSize; i++) { BlockPos position = positions.get(i); @@ -146,13 +156,16 @@ public void translateCraft(@NotNull Craft craft, @NotNull MovecraftLocation disp continue; //BlockEntity tile = nativeWorld.removeBlockEntity(position); BlockEntity tile = removeBlockEntity(oldNativeWorld, position); - if (tile == null) - continue; - //get the nextTick to move with the tile + if (tile != null) + tiles.add(new TileHolder(tile, position)); - //nativeWorld.capturedTileEntities.remove(position); - //nativeWorld.getChunkAtWorldCoords(position).getTileEntities().remove(position); - tiles.add(new TileHolder(tile, tickProvider.getNextTick(oldNativeWorld, position), position)); + //get the nextTick to move with the tile + ScheduledTick tickHere = tickProvider.getNextTick(oldNativeWorld, position); + if (tickHere != null) { + ((LevelChunkTicks) nativeWorld.getChunkAt(position).getBlockTicks()).removeIf( + (Predicate) scheduledTick -> scheduledTick.equals(tickHere)); + ticks.add(new TickHolder(tickHere, position)); + } } //******************************************* @@ -181,10 +194,11 @@ public void translateCraft(@NotNull Craft craft, @NotNull MovecraftLocation disp for (int i = 0, tilesSize = tiles.size(); i < tilesSize; i++) { TileHolder tileHolder = tiles.get(i); moveBlockEntity(nativeWorld, tileHolder.getTilePosition().offset(translateVector), tileHolder.getTile()); - if (tileHolder.getNextTick() == null) - continue; + } + for (int i = 0, tickSize = ticks.size(); i < tickSize; i++) { + TickHolder tickHolder = ticks.get(i); final long currentTime = nativeWorld.getGameTime(); - nativeWorld.getBlockTicks().schedule(new ScheduledTick<>((Block) tileHolder.getNextTick().type(), tileHolder.getTilePosition().offset(translateVector), tileHolder.getNextTick().triggerTick() - currentTime, tileHolder.getNextTick().priority(), tileHolder.getNextTick().subTickOrder())); + nativeWorld.getBlockTicks().schedule(new ScheduledTick<>((Block) tickHolder.getTick().type(), tickHolder.getTickPosition().offset(translateVector), tickHolder.getTick().triggerTick() - currentTime, tickHolder.getTick().priority(), tickHolder.getTick().subTickOrder())); } //******************************************* //* Step five: Destroy the leftovers * @@ -301,14 +315,11 @@ private void moveBlockEntity(@NotNull Level nativeWorld, @NotNull BlockPos newPo private static class TileHolder { @NotNull private final BlockEntity tile; - @Nullable - private final ScheduledTick nextTick; @NotNull private final BlockPos tilePosition; - public TileHolder(@NotNull BlockEntity tile, @Nullable ScheduledTick nextTick, @NotNull BlockPos tilePosition) { + public TileHolder(@NotNull BlockEntity tile, @NotNull BlockPos tilePosition) { this.tile = tile; - this.nextTick = nextTick; this.tilePosition = tilePosition; } @@ -318,14 +329,32 @@ public BlockEntity getTile() { return tile; } - @Nullable - public ScheduledTick getNextTick() { - return nextTick; - } - @NotNull public BlockPos getTilePosition() { return tilePosition; } } + + private static class TickHolder { + @NotNull + private final ScheduledTick tick; + @NotNull + private final BlockPos tickPosition; + + public TickHolder(@NotNull ScheduledTick tick, @NotNull BlockPos tilePosition) { + this.tick = tick; + this.tickPosition = tilePosition; + } + + + @NotNull + public ScheduledTick getTick() { + return tick; + } + + @NotNull + public BlockPos getTickPosition() { + return tickPosition; + } + } } \ No newline at end of file diff --git a/modules/v1_18_R2/src/main/java/net/countercraft/movecraft/compat/v1_18_R2/NextTickProvider.java b/modules/v1_18_R2/src/main/java/net/countercraft/movecraft/compat/v1_18_R2/NextTickProvider.java index 1021ce210..d0951ad6b 100644 --- a/modules/v1_18_R2/src/main/java/net/countercraft/movecraft/compat/v1_18_R2/NextTickProvider.java +++ b/modules/v1_18_R2/src/main/java/net/countercraft/movecraft/compat/v1_18_R2/NextTickProvider.java @@ -4,39 +4,39 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.levelgen.structure.BoundingBox; +import net.minecraft.world.ticks.LevelChunkTicks; import net.minecraft.world.ticks.LevelTicks; import net.minecraft.world.ticks.ScheduledTick; +import org.bukkit.Bukkit; +import org.bukkit.World; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.lang.reflect.Field; import java.util.List; import java.util.Queue; +import java.util.stream.Stream; public class NextTickProvider { @Nullable public ScheduledTick getNextTick(@NotNull ServerLevel world, @NotNull BlockPos position){ - LevelTicks tickList = world.getBlockTicks(); + LevelChunkTicks tickList = (LevelChunkTicks) world + .getChunk(position) + .getBlockTicks(); + var box = BoundingBox.encapsulatingPositions(List.of(position)); - if(box.isEmpty()){ - return null; - } - Queue> toRunThisTick; - try { - Field toRunThisTickField = LevelTicks.class.getDeclaredField("g"); - toRunThisTickField.setAccessible(true); - toRunThisTick = (Queue>) toRunThisTickField.get(tickList); - } catch (NoSuchFieldException | IllegalAccessException e) { - e.printStackTrace(); + if(box.isEmpty()) { return null; } - for (var iter = toRunThisTick.iterator(); iter.hasNext(); ) { + + Stream> ticks = tickList.getAll(); + + for (var iter = ticks.iterator(); iter.hasNext(); ) { var next = iter.next(); if (!next.pos().equals(position)) { continue; } - iter.remove(); return next; } return null;