Skip to content

Commit

Permalink
1.21 implementation
Browse files Browse the repository at this point in the history
The same code should hopefully work for 1.21
  • Loading branch information
drfiveminusmint committed Aug 18, 2024
1 parent d300504 commit 15c2837
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -32,6 +33,7 @@

import java.lang.reflect.Field;
import java.util.*;
import java.util.function.Predicate;

@SuppressWarnings("unused")
public class IWorldHandler extends WorldHandler {
Expand Down Expand Up @@ -67,15 +69,21 @@ public void rotateCraft(@NotNull Craft craft, @NotNull MovecraftLocation originP
//*******************************************
ServerLevel nativeWorld = ((CraftWorld) craft.getWorld()).getHandle();
List<TileHolder> tiles = new ArrayList<>();
List<TickHolder> 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 -> scheduledTick.equals(tickHere));
ticks.add(new TickHolder(tickHere, position));
}
}

//*******************************************
Expand All @@ -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()));
}

//*******************************************
Expand Down Expand Up @@ -134,21 +146,24 @@ public void translateCraft(@NotNull Craft craft, @NotNull MovecraftLocation disp
//* Step two: Get the tiles *
//*******************************************
List<TileHolder> tiles = new ArrayList<>();
List<TickHolder> ticks = new ArrayList<>();
//get the tiles
for (int i = 0, positionsSize = positions.size(); i < positionsSize; i++) {
BlockPos position = positions.get(i);
if (oldNativeWorld.getBlockState(position) == Blocks.AIR.defaultBlockState())
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 -> scheduledTick.equals(tickHere));
ticks.add(new TickHolder(tickHere, position));
}
}
//*******************************************
//* Step three: Translate all the blocks *
Expand All @@ -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 *
Expand Down Expand Up @@ -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;
}

Expand All @@ -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;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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<Block> tickList = world.getBlockTicks();
LevelChunkTicks<Block> tickList = (LevelChunkTicks<Block>) world
.getChunk(position)
.getBlockTicks();

var box = BoundingBox.encapsulatingPositions(List.of(position));
if(box.isEmpty()){
return null;
}
Queue<ScheduledTick<?>> toRunThisTick;
try {
Field toRunThisTickField = LevelTicks.class.getDeclaredField("g"); // g is obfuscated toRunThisTick
toRunThisTickField.setAccessible(true);
toRunThisTick = (Queue<ScheduledTick<?>>) toRunThisTickField.get(tickList);
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
return null;
}
for (var iter = toRunThisTick.iterator(); iter.hasNext(); ) {

Stream<ScheduledTick<Block>> 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;
Expand Down

0 comments on commit 15c2837

Please sign in to comment.