diff --git a/core/src/main/java/mc/core/Direction.java b/core/src/main/java/mc/core/Direction.java new file mode 100644 index 0000000..74e4630 --- /dev/null +++ b/core/src/main/java/mc/core/Direction.java @@ -0,0 +1,8 @@ +package mc.core; + +public enum Direction { + NORTH, + EAST, + WEST, + SOUTH +} diff --git a/generated_world/src/main/java/mc/world/generated_world/world/RegionManager.java b/generated_world/src/main/java/mc/world/generated_world/world/RegionManager.java new file mode 100644 index 0000000..0cc0ef4 --- /dev/null +++ b/generated_world/src/main/java/mc/world/generated_world/world/RegionManager.java @@ -0,0 +1,143 @@ +package mc.world.generated_world.world; + +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import mc.core.Direction; +import mc.core.world.Region; +import mc.core.world.World; +import mc.core.world.WorldGenerator; +import mc.world.generated_world.serialization.RegionReaderWriter; +import org.springframework.beans.factory.annotation.Autowired; + +import java.io.File; +import java.io.IOException; +import java.text.MessageFormat; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import static mc.world.generated_world.WorldConstants.REGION_FILE_NAME_TEMPLATE; + +/* +* NORTH +* +* EAST WEST +* +* SOUTH +* +* + ----> X +* | +* | +* | +* V Z +*/ +@Slf4j +public class RegionManager { + private final World world; + private int pointX = -1; + private int pointZ = -1; + private int sizeX = 2; + private int sizeZ = 2; + private Region[][] regions = new Region[sizeX][sizeZ]; + private final Lock regionSaveLock = new ReentrantLock(); + @Autowired + private RegionReaderWriter regionReaderWriter; + @Autowired + private WorldGenerator worldGenerator; + @Setter + private boolean autoSaveRegionAfterGenerating = true; + + + public RegionManager(World world) { + this.world = world; + } + + public void setRegion (Region region) { + int x = region.getX(); + int z = region.getZ(); + + try { + regionSaveLock.lock(); + regions[x - pointX][z - pointZ] = region; + } finally { + regionSaveLock.unlock(); + } + } + + private void checkCoordsInCache (int x, int z) { + if (x < pointX) { + addLines(Direction.EAST, pointX - x); + } else if (x > pointX + sizeX) { + addLines(Direction.WEST, x - (pointX + sizeX)); + } else if (z < pointZ) { + addLines(Direction.NORTH, pointZ - z); + } else if (z > pointZ + sizeZ) { + addLines(Direction.SOUTH, z - (pointZ + sizeZ)); + } + } + + public Region getRegion (int x, int z) { + checkCoordsInCache(x, z); + Region region; + if (regions[x - pointX][z - pointZ] == null) { + File file = new File(new File("worlds", world.getWorldId().toString()), MessageFormat.format(REGION_FILE_NAME_TEMPLATE, x, z)); + if (!file.exists()) { + region = worldGenerator.generateRegion(x, z, world); + if (autoSaveRegionAfterGenerating) { + try { + regionReaderWriter.write(region); + } catch (IOException e) { + log.error("Error occurred while saving region data"); + } + } + } else { + try { + region = regionReaderWriter.read(x, z, world); + } catch (IOException e) { + log.error("Error occurred while loading region"); + region = null; + } + } + setRegion(region); + } else { + region = regions[x - pointX][z - pointZ]; + } + return region; + } + + private void addLines (Direction direction, int amount) { + int addBeforeX = 0; + int addAfterX = 0; + int addBeforeZ = 0; + int addAfterZ = 0; + switch (direction) { + case NORTH: + addBeforeZ = amount; + break; + case EAST: + addBeforeX = amount; + break; + case WEST: + addAfterX = amount; + break; + case SOUTH: + addAfterZ = amount; + break; + } + try { + int tempSizeX = sizeX + addAfterX + addBeforeX; + int tempSizeZ = sizeZ + addAfterZ + addBeforeZ; + Region[][] temp = new Region[tempSizeX][tempSizeZ]; + for (int x = 0; x < sizeX; x ++) { + System.arraycopy(regions[x], 0, temp[x + addBeforeX], addBeforeZ, sizeZ); + } + + this.sizeX = tempSizeX; + this.sizeZ = tempSizeZ; + this.pointX = pointX - addBeforeX; + this.pointZ = pointZ - addBeforeZ; + } finally { + regionSaveLock.unlock(); + } + } + +}