diff --git a/core/src/main/java/mc/core/GameLoop.java b/core/src/main/java/mc/core/GameLoop.java index da9cc1c..06fc0a1 100644 --- a/core/src/main/java/mc/core/GameLoop.java +++ b/core/src/main/java/mc/core/GameLoop.java @@ -10,6 +10,7 @@ import lombok.extern.slf4j.Slf4j; import mc.core.events.CS_PlayerMoveEvent; import mc.core.events.EventBusGetter; import mc.core.events.SC_ChunkLoadEvent; +import mc.core.events.SC_ChunkUnloadEvent; import mc.core.player.PlayerManager; import mc.core.time.TimeProcessor; import mc.core.utils.CompactedCoords; @@ -17,6 +18,8 @@ import mc.core.world.World; import mc.core.world.chunk.Chunk; import org.springframework.beans.factory.annotation.Autowired; +import java.util.Iterator; + @Slf4j public class GameLoop extends Thread { private final TpsWatcher TPS_WATCHER = TpsWatcher.getInstance(); @@ -48,22 +51,37 @@ public class GameLoop extends Thread { @Subscribe public void playerMoveEventHandler(CS_PlayerMoveEvent event) { log.trace("(GameLoop) playerMoveEventHandler()"); - event.getPlayer().getLocation().setXYZ(event.getNewLocation()); - Chunk chunk = event.getNewLocation().getChunk(); // Next chunk - int ncX = chunk.getX(); - int ncZ = chunk.getZ(); - chunk = event.getPlayer().getLocation().getChunk(); // Current chunk + Chunk chunk; + chunk = event.getOldLocation().getChunk(); // Old chunk int ccX = chunk.getX(); int ccZ = chunk.getZ(); + chunk = event.getNewLocation().getChunk(); // Next chunk + int ncX = chunk.getX(); + int ncZ = chunk.getZ(); - if (event.isRecalcChunk() || (ncX != ccX && ncZ != ccZ)) { - final int viewDistance = event.getPlayer().getSettings().getViewDistance(); + if (event.isRecalcChunk() || (ncX != ccX || ncZ != ccZ)) { + final int viewDistance = event.getPlayer().getSettings().getViewDistance() + 1; int cMinX = chunk.getX() - viewDistance; int cMaxX = chunk.getX() + viewDistance; int cMinZ = chunk.getZ() - viewDistance; int cMaxZ = chunk.getZ() + viewDistance; + SC_ChunkUnloadEvent eventChunkUnload = new SC_ChunkUnloadEvent(event.getPlayer()); + Iterator itr = event.getPlayer().getLoadedChunks().iterator(); + while(itr.hasNext()) { + int compressXZ = itr.next(); + int[] xz = CompactedCoords.uncompressXZ(compressXZ); + if (xz[0] > cMaxX || xz[0] < cMinX || xz[1] > cMaxZ || xz[1] < cMinZ) { + eventChunkUnload.getNeedUnloadChunks().add(compressXZ); + itr.remove(); + } + } + + if (!eventChunkUnload.getNeedUnloadChunks().isEmpty()) { + EventBusGetter.INSTANCE.post(eventChunkUnload); + } + SC_ChunkLoadEvent eventChunkLoad = new SC_ChunkLoadEvent(event.getPlayer()); for (int cZ = cMinZ; cZ <= cMaxZ; cZ++) { for (int cX = cMinX; cX <= cMaxX; cX++) { @@ -71,6 +89,7 @@ public class GameLoop extends Thread { if (!event.getPlayer().getLoadedChunks().contains(compressXZ)) { if (!event.getPlayer().getLoadedChunks().contains(compressXZ)) { eventChunkLoad.getNeedLoadChunks().add(compressXZ); + event.getPlayer().getLoadedChunks().add(compressXZ); } } } @@ -81,6 +100,8 @@ public class GameLoop extends Thread { } } + event.getPlayer().getLocation().setXYZ(event.getNewLocation()); + // TODO отсылать клиенту только(!) для корректировки позиции // SC_PlayerMoveEvent nextEvent = new SC_PlayerMoveEvent(event.getPlayer()); // nextEvent.setNewLocation(event.getNewLocation()); diff --git a/core/src/main/java/mc/core/events/SC_ChunkUnloadEvent.java b/core/src/main/java/mc/core/events/SC_ChunkUnloadEvent.java new file mode 100644 index 0000000..397cbac --- /dev/null +++ b/core/src/main/java/mc/core/events/SC_ChunkUnloadEvent.java @@ -0,0 +1,16 @@ +package mc.core.events; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import mc.core.player.Player; + +import java.util.ArrayList; +import java.util.List; + +@RequiredArgsConstructor +public class SC_ChunkUnloadEvent extends EventBase { + @Getter + private final Player player; + @Getter + private List needUnloadChunks = new ArrayList<>(); +} diff --git a/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/PlayerEventListener.java b/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/PlayerEventListener.java index 63415cd..75a0978 100644 --- a/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/PlayerEventListener.java +++ b/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/PlayerEventListener.java @@ -3,10 +3,12 @@ package mc.core.network.proto_1_12_2.netty; import com.google.common.eventbus.Subscribe; import lombok.extern.slf4j.Slf4j; import mc.core.events.SC_ChunkLoadEvent; +import mc.core.events.SC_ChunkUnloadEvent; import mc.core.events.SC_PlayerMoveEvent; import mc.core.network.proto_1_12_2.TeleportManager; import mc.core.network.proto_1_12_2.packets.ChunkDataPacket; import mc.core.network.proto_1_12_2.packets.PlayerPositionAndLookPacket; +import mc.core.network.proto_1_12_2.packets.UnloadChunkPacket; import mc.core.utils.CompactedCoords; import mc.core.world.chunk.Chunk; import mc.core.world.chunk.ChunkSection; @@ -26,8 +28,6 @@ class PlayerEventListener { @Subscribe public void playerChunkLoadHandler(SC_ChunkLoadEvent event) { - log.debug("(SC) playerChunkLoadHandler()"); - for(Integer compressXZ : event.getNeedLoadChunks()) { int[] xz = CompactedCoords.uncompressXZ(compressXZ); Chunk chunk = event.getPlayer().getLocation().getWorld().getChunk(xz[0], xz[1]); @@ -43,4 +43,19 @@ class PlayerEventListener { event.getPlayer().getChannel().flush(); } + + @Subscribe + public void playerChunkUnloadHandler(SC_ChunkUnloadEvent event) { + for(Integer compressXZ : event.getNeedUnloadChunks()) { + int[] xz = CompactedCoords.uncompressXZ(compressXZ); + + UnloadChunkPacket packet = new UnloadChunkPacket(); + packet.setX(xz[0]); + packet.setZ(xz[1]); + + event.getPlayer().getChannel().write(packet); + } + + event.getPlayer().getChannel().flush(); + } }