Changed chunk island information load structure.

This commit is contained in:
Harrison Deng 2020-05-16 15:45:44 -05:00
parent e2f476cd82
commit 3514434fbb
4 changed files with 51 additions and 49 deletions

View File

@ -55,7 +55,7 @@ public class HighlightCommand implements CommandRunnable {
}
} else if (args[0].toLowerCase().equals("origin")) {
Point2 playerLoc = new Point2(player.getLocation().getBlockX(), player.getLocation().getBlockZ());
sender.sendMessage("Current island's origin point: " + islandSurvivalCraft.getWorldInfoManager().retrieve(player.getWorld().getName()).getIslandInfoManager().getIslandInformation(playerLoc).getIslandOrigin());
sender.sendMessage("Current island's origin point: " + islandSurvivalCraft.getWorldInfoManager().retrieve(player.getWorld().getName()).getIslandInfoManager().getIslandInformation(playerLoc, true).getIslandOrigin());
} else {
return false;
}
@ -77,17 +77,17 @@ public class HighlightCommand implements CommandRunnable {
World world = player.getWorld();
WorldInfo worldInfo = islandsurvivalcraft.getWorldInfoManager().retrieve(world.getName());
Location playerLocation = player.getLocation();
int playerX = playerLocation.getBlockX(), playerY = playerLocation.getBlockY(), playerZ = playerLocation.getBlockZ();
Point2 playerCoords = new Point2(playerX, playerZ);
IslandInformation islandInfo = worldInfo.getIslandInfoManager().getIslandInformation(playerCoords);
double playerX = playerLocation.getX(), playerY = playerLocation.getY(), playerZ = playerLocation.getZ();
Point2 playerCoords = new Point2(playerLocation.getBlockX(), playerLocation.getBlockZ());
IslandInformation islandInfo = worldInfo.getIslandInfoManager().getIslandInformation(playerCoords, true);
if (islandInfo != null) {
Set<Point2> islandBorder = islandInfo.getEdgeCoordinates();
for (Point2 current : islandBorder) {
spawnParticle(false, true, world, current.x, playerY, current.y, EDGE_DUST_OPTIONS);
}
Point2 islandOrigin = islandInfo.getIslandOrigin();
int xDirection = GeneralUtilities.addMagnitude(Math.max(Math.min(1, islandOrigin.x - playerX), -1), 1) + playerX;
int yDirection = GeneralUtilities.addMagnitude(Math.max(Math.min(1, islandOrigin.y - playerZ), -1), 1) + playerZ;
double xDirection = GeneralUtilities.addMagnitude(Math.max(Math.min(1, islandOrigin.x - playerCoords.x), -1), 1) + playerX;
double yDirection = GeneralUtilities.addMagnitude(Math.max(Math.min(1, islandOrigin.y - playerCoords.y), -1), 1) + playerZ;
spawnParticle(false, false, world, xDirection, playerY + 1, yDirection, ORIGIN_DUST_OPTIONS);
spawnParticle(true, true, world, islandOrigin.x, playerY, islandOrigin.y, ORIGIN_DUST_OPTIONS);
}

View File

@ -13,9 +13,6 @@ import org.bukkit.event.Listener;
import org.bukkit.event.Event.Result;
import org.bukkit.event.block.Action;
import org.bukkit.event.inventory.CraftItemEvent;
import org.bukkit.event.inventory.InventoryEvent;
import org.bukkit.event.inventory.InventoryMoveItemEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerItemHeldEvent;
import org.bukkit.event.player.PlayerJoinEvent;

View File

@ -51,7 +51,7 @@ public class IslandMapItem extends MapRenderer implements VariedItem {
namespacedKey = new NamespacedKey(islandSurvivalCraft, "island_map");
ItemStack resultItem = new ItemStack(getBaseItems()[0], 1);
ItemMeta metadata = resultItem.getItemMeta();
metadata.setDisplayName(ChatColor.RESET + getName());
metadata.setDisplayName(getName());
metadata.setLocalizedName(getName());
metadata.getPersistentDataContainer().set(getNamespacedKey(), getIdentifier(), getIdentifier().getID());
metadata.setLore(lore);
@ -74,15 +74,11 @@ public class IslandMapItem extends MapRenderer implements VariedItem {
byte baseColorVal = canvas.getBasePixel(x, y);
Color baseColor = MapPalette.getColor(baseColorVal);
Point2 pCoords = new Point2(actualX, actualZ);
IslandInformation info = islandInformationManager.getIslandInformation(pCoords);
IslandInformation info = islandInformationManager.getIslandInformation(pCoords, false);
if (baseColorVal != 0) {
if (info != null && pCoords.distance(new Point2(player.getLocation().getBlockX(), player.getLocation().getBlockZ())) < 32) {
if (info != null && pCoords.distance(new Point2(player.getLocation().getBlockX(), player.getLocation().getBlockZ())) < 128) {
Color mixed = new Color((int) Math.min(255, baseColor.getRed() * 1.5f), (int) Math.min(255, baseColor.getGreen() * 0.7f), (int) Math.min(255, baseColor.getBlue() * 0.44f));
if (info.isEdgeOfIsland(pCoords)) {
canvas.setPixel(x, y, MapPalette.matchColor(255, 120, 70));
} else {
canvas.setPixel(x, y, MapPalette.matchColor(mixed));
}
canvas.setPixel(x, y, MapPalette.matchColor(mixed));
}
}
}
@ -96,7 +92,7 @@ public class IslandMapItem extends MapRenderer implements VariedItem {
@Override
public String getName() {
return ChatColor.GREEN + "Island Map";
return "Island Map";
}
@Override
@ -112,7 +108,7 @@ public class IslandMapItem extends MapRenderer implements VariedItem {
@Override
public boolean onItemCrafted(ItemStack item, HumanEntity crafter) {
if (item.getType() != Material.FILLED_MAP) return false;
Bukkit.getScheduler().runTask(islandSurvivalCraft, () -> {
Bukkit.getScheduler().scheduleSyncDelayedTask(islandSurvivalCraft, () -> {
initializeInstanceOfItem(item);
});
return false;
@ -139,7 +135,7 @@ public class IslandMapItem extends MapRenderer implements VariedItem {
if (item.getType() != Material.MAP) return false;
ItemStack freshMap = new ItemStack(Material.FILLED_MAP, 1);
MapMeta mapMeta = (MapMeta) freshMap.getItemMeta();
mapMeta.setDisplayName(ChatColor.RESET + getName());
mapMeta.setDisplayName(getName());
mapMeta.setLore(lore);
mapMeta.getPersistentDataContainer().set(getNamespacedKey(), getIdentifier(), getIdentifier().getID());
MapView mapView = Bukkit.createMap(clicker.getWorld());

View File

@ -1,6 +1,7 @@
package ca.recrown.islandsurvivalcraft.world.Information;
import java.util.HashSet;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
@ -14,7 +15,7 @@ import ca.recrown.islandsurvivalcraft.world.IslandWorldMap;
public class IslandInformationManager {
private final IslandWorldMap islandMap;
private final ExecutorService executors = Executors.newFixedThreadPool(2, new ThreadFactory() {
private final ExecutorService executors = Executors.newFixedThreadPool(1, new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r);
@ -22,31 +23,37 @@ public class IslandInformationManager {
return thread;
}
});
private final ConcurrentHashMap<Point2, Future<Void>> building = new ConcurrentHashMap<>();
private final ConcurrentHashMap<Point2, Future<HashSet<IslandInformation>>> building = new ConcurrentHashMap<>();
private final ConcurrentHashMap<Point2, HashSet<IslandInformation>> islandSets = new ConcurrentHashMap<>();
public IslandInformationManager(IslandWorldMap islandWorldMap) {
this.islandMap = islandWorldMap;
}
public void loadChunkIslandInformation(Point2 chunkCoords) {
Point2[] surrounding = new Point2[4];
surrounding[0] = chunkCoords.shift(1, 0);
surrounding[1] = chunkCoords.shift(-1, 0);
surrounding[2] = chunkCoords.shift(0, -1);
surrounding[3] = chunkCoords.shift(0, 1);
public HashSet<IslandInformation> loadChunkIslandInformation(Point2 chunkCoords) {
HashSet<IslandInformation> result = new HashSet<>();
Point2[] surroundings = new Point2[4];
surroundings[0] = chunkCoords.shift(1, 0);
surroundings[1] = chunkCoords.shift(-1, 0);
surroundings[2] = chunkCoords.shift(0, -1);
surroundings[3] = chunkCoords.shift(0, 1);
HashSet<Point2> checkedCoordinates = new HashSet<>();
for (Point2 chunk : surrounding) {
HashSet<IslandInformation> chunkIslandSet = islandSets.computeIfAbsent(chunk, (p) -> new HashSet<>());
for (IslandInformation islandInformation : chunkIslandSet) {
if (islandInformation.isIslandInChunk(chunkCoords)) {
checkedCoordinates.addAll(islandInformation.getIslandCoordinates());
for (Point2 surrounding : surroundings) {
if (Thread.currentThread().isInterrupted()) return null;
HashSet<IslandInformation> chunkIslandSet = islandSets.get(surrounding);
if (chunkIslandSet != null) {
for (IslandInformation islandInformation : chunkIslandSet) {
if (islandInformation.isIslandInChunk(chunkCoords)) {
checkedCoordinates.addAll(islandInformation.getIslandCoordinates());
result.add(islandInformation);
}
}
}
}
for (int x = 0; x < GeneralUtilities.CHUNK_SIZE; x++) {
for (int z = 0; z < GeneralUtilities.CHUNK_SIZE; z++) {
if (Thread.currentThread().isInterrupted()) return null;
int worldX = chunkCoords.x * GeneralUtilities.CHUNK_SIZE + x;
int worldZ = chunkCoords.y * GeneralUtilities.CHUNK_SIZE + z;
if (islandMap.isIsland(worldX, worldZ)) {
@ -60,48 +67,50 @@ public class IslandInformationManager {
});
if (origin != null) {
IslandInformation islandInfo = infoBuilder.build(origin);
for (Point2 chunk : infoBuilder.getChunksUsed()) {
islandSets.computeIfAbsent(chunk, (p) -> new HashSet<>()).add(islandInfo);
}
result.add(islandInfo);
}
}
}
}
return result;
}
public void loadChunkIslandInformationAsync(Point2 chunkCoords) {
building.put(chunkCoords, executors.submit(() -> {
loadChunkIslandInformation(chunkCoords);
return null;
}));
CompletableFuture<HashSet<IslandInformation>> completableFuture = new CompletableFuture<>();
executors.execute(() -> {
completableFuture.complete(loadChunkIslandInformation(chunkCoords));
});
building.put(chunkCoords, completableFuture);
completableFuture.thenAccept((p) -> {
if (Thread.currentThread().isInterrupted()) return;
islandSets.put(chunkCoords, p);
building.remove(chunkCoords);
});
}
public void unloadChunkIslandInformation(Point2 chunkCoords) {
if (building.containsKey(chunkCoords)) building.remove(chunkCoords).cancel(true);
islandSets.remove(chunkCoords);
building.remove(chunkCoords);
}
public HashSet<IslandInformation> getChunkIslandInformationSet(Point2 chunkCoords, boolean checkBuilding) {
public HashSet<IslandInformation> getChunkIslandInformationSet(Point2 chunkCoords, boolean checkLoading) {
if (!islandSets.containsKey(chunkCoords)) {
if (checkBuilding && building.containsKey(chunkCoords)) {
if (checkLoading && building.containsKey(chunkCoords)) {
try {
building.get(chunkCoords).get();
} catch (InterruptedException | ExecutionException e) {
}
}
}
building.remove(chunkCoords);
return islandSets.get(chunkCoords);
}
public IslandInformation getIslandInformation(Point2 coords) {
HashSet<IslandInformation> chunkIslandSet = getChunkIslandInformationSet(GeneralUtilities.worldToChunkCoordinates(coords), true);
try {
public IslandInformation getIslandInformation(Point2 coords, boolean checkLoading) {
HashSet<IslandInformation> chunkIslandSet = getChunkIslandInformationSet(GeneralUtilities.worldToChunkCoordinates(coords), checkLoading);
if (chunkIslandSet != null) {
for (IslandInformation islandInformation : chunkIslandSet) {
if (islandInformation.isWithinIsland(coords)) return islandInformation;
}
} catch (NullPointerException e) {
}
return null;
}