diff --git a/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/IWorldHandler.java b/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/IWorldHandler.java index d7405bfdf..4a48783c8 100644 --- a/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/IWorldHandler.java +++ b/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/IWorldHandler.java @@ -19,6 +19,7 @@ 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; @@ -32,6 +33,7 @@ import java.lang.reflect.Field; import java.util.*; +import java.util.function.Predicate; @SuppressWarnings("unused") public class IWorldHandler extends WorldHandler { @@ -67,15 +69,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)); + } } //******************************************* @@ -100,12 +108,16 @@ public void rotateCraft(@NotNull Craft craft, @NotNull MovecraftLocation originP //* Step four: replace all the tiles * //******************************************* //TODO: go by chunks - for (TileHolder tileHolder : tiles) { + 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.serverLevelData.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())); } //******************************************* @@ -134,6 +146,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); @@ -141,14 +154,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 - - //nativeWorld.capturedTileEntities.remove(position); - //nativeWorld.getChunkAtWorldCoords(position).getTileEntities().remove(position); - tiles.add(new TileHolder(tile, tickProvider.getNextTick(oldNativeWorld, position), position)); + if (tile != null) + tiles.add(new TileHolder(tile,position)); + //get the nextTick to move with the tile + 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)); + } } //******************************************* //* Step three: Translate all the blocks * @@ -173,13 +188,11 @@ public void translateCraft(@NotNull Craft craft, @NotNull MovecraftLocation disp //* Step four: replace all the tiles * //******************************************* //TODO: go by chunks - for (int i = 0, tilesSize = tiles.size(); i < tilesSize; i++) { - TileHolder tileHolder = tiles.get(i); + for (TileHolder tileHolder : tiles) moveBlockEntity(nativeWorld, tileHolder.getTilePosition().offset(translateVector), tileHolder.getTile()); - if (tileHolder.getNextTick() == null) - continue; + for (TickHolder tickHolder : ticks) { 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 * @@ -291,14 +304,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; } @@ -308,14 +318,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/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/NextTickProvider.java b/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/NextTickProvider.java index c29d9ddce..b5898f390 100644 --- a/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/NextTickProvider.java +++ b/v1_21/src/main/java/net/countercraft/movecraft/compat/v1_21/NextTickProvider.java @@ -4,39 +4,34 @@ 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.LevelTicks; +import net.minecraft.world.ticks.LevelChunkTicks; import net.minecraft.world.ticks.ScheduledTick; 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"); // g is obfuscated toRunThisTick - toRunThisTickField.setAccessible(true); - toRunThisTick = (Queue>) toRunThisTickField.get(tickList); - } catch (NoSuchFieldException | IllegalAccessException e) { - e.printStackTrace(); - 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;