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")) { } else if (args[0].toLowerCase().equals("origin")) {
Point2 playerLoc = new Point2(player.getLocation().getBlockX(), player.getLocation().getBlockZ()); 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 { } else {
return false; return false;
} }
@ -77,17 +77,17 @@ public class HighlightCommand implements CommandRunnable {
World world = player.getWorld(); World world = player.getWorld();
WorldInfo worldInfo = islandsurvivalcraft.getWorldInfoManager().retrieve(world.getName()); WorldInfo worldInfo = islandsurvivalcraft.getWorldInfoManager().retrieve(world.getName());
Location playerLocation = player.getLocation(); Location playerLocation = player.getLocation();
int playerX = playerLocation.getBlockX(), playerY = playerLocation.getBlockY(), playerZ = playerLocation.getBlockZ(); double playerX = playerLocation.getX(), playerY = playerLocation.getY(), playerZ = playerLocation.getZ();
Point2 playerCoords = new Point2(playerX, playerZ); Point2 playerCoords = new Point2(playerLocation.getBlockX(), playerLocation.getBlockZ());
IslandInformation islandInfo = worldInfo.getIslandInfoManager().getIslandInformation(playerCoords); IslandInformation islandInfo = worldInfo.getIslandInfoManager().getIslandInformation(playerCoords, true);
if (islandInfo != null) { if (islandInfo != null) {
Set<Point2> islandBorder = islandInfo.getEdgeCoordinates(); Set<Point2> islandBorder = islandInfo.getEdgeCoordinates();
for (Point2 current : islandBorder) { for (Point2 current : islandBorder) {
spawnParticle(false, true, world, current.x, playerY, current.y, EDGE_DUST_OPTIONS); spawnParticle(false, true, world, current.x, playerY, current.y, EDGE_DUST_OPTIONS);
} }
Point2 islandOrigin = islandInfo.getIslandOrigin(); Point2 islandOrigin = islandInfo.getIslandOrigin();
int xDirection = GeneralUtilities.addMagnitude(Math.max(Math.min(1, islandOrigin.x - playerX), -1), 1) + playerX; double xDirection = GeneralUtilities.addMagnitude(Math.max(Math.min(1, islandOrigin.x - playerCoords.x), -1), 1) + playerX;
int yDirection = GeneralUtilities.addMagnitude(Math.max(Math.min(1, islandOrigin.y - playerZ), -1), 1) + playerZ; 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(false, false, world, xDirection, playerY + 1, yDirection, ORIGIN_DUST_OPTIONS);
spawnParticle(true, true, world, islandOrigin.x, playerY, islandOrigin.y, 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.Event.Result;
import org.bukkit.event.block.Action; import org.bukkit.event.block.Action;
import org.bukkit.event.inventory.CraftItemEvent; 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.PlayerInteractEvent;
import org.bukkit.event.player.PlayerItemHeldEvent; import org.bukkit.event.player.PlayerItemHeldEvent;
import org.bukkit.event.player.PlayerJoinEvent; 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"); namespacedKey = new NamespacedKey(islandSurvivalCraft, "island_map");
ItemStack resultItem = new ItemStack(getBaseItems()[0], 1); ItemStack resultItem = new ItemStack(getBaseItems()[0], 1);
ItemMeta metadata = resultItem.getItemMeta(); ItemMeta metadata = resultItem.getItemMeta();
metadata.setDisplayName(ChatColor.RESET + getName()); metadata.setDisplayName(getName());
metadata.setLocalizedName(getName()); metadata.setLocalizedName(getName());
metadata.getPersistentDataContainer().set(getNamespacedKey(), getIdentifier(), getIdentifier().getID()); metadata.getPersistentDataContainer().set(getNamespacedKey(), getIdentifier(), getIdentifier().getID());
metadata.setLore(lore); metadata.setLore(lore);
@ -74,20 +74,16 @@ public class IslandMapItem extends MapRenderer implements VariedItem {
byte baseColorVal = canvas.getBasePixel(x, y); byte baseColorVal = canvas.getBasePixel(x, y);
Color baseColor = MapPalette.getColor(baseColorVal); Color baseColor = MapPalette.getColor(baseColorVal);
Point2 pCoords = new Point2(actualX, actualZ); Point2 pCoords = new Point2(actualX, actualZ);
IslandInformation info = islandInformationManager.getIslandInformation(pCoords); IslandInformation info = islandInformationManager.getIslandInformation(pCoords, false);
if (baseColorVal != 0) { 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)); 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));
} }
} }
} }
} }
} }
}
@Override @Override
public Recipe getRecipe() { public Recipe getRecipe() {
@ -96,7 +92,7 @@ public class IslandMapItem extends MapRenderer implements VariedItem {
@Override @Override
public String getName() { public String getName() {
return ChatColor.GREEN + "Island Map"; return "Island Map";
} }
@Override @Override
@ -112,7 +108,7 @@ public class IslandMapItem extends MapRenderer implements VariedItem {
@Override @Override
public boolean onItemCrafted(ItemStack item, HumanEntity crafter) { public boolean onItemCrafted(ItemStack item, HumanEntity crafter) {
if (item.getType() != Material.FILLED_MAP) return false; if (item.getType() != Material.FILLED_MAP) return false;
Bukkit.getScheduler().runTask(islandSurvivalCraft, () -> { Bukkit.getScheduler().scheduleSyncDelayedTask(islandSurvivalCraft, () -> {
initializeInstanceOfItem(item); initializeInstanceOfItem(item);
}); });
return false; return false;
@ -139,7 +135,7 @@ public class IslandMapItem extends MapRenderer implements VariedItem {
if (item.getType() != Material.MAP) return false; if (item.getType() != Material.MAP) return false;
ItemStack freshMap = new ItemStack(Material.FILLED_MAP, 1); ItemStack freshMap = new ItemStack(Material.FILLED_MAP, 1);
MapMeta mapMeta = (MapMeta) freshMap.getItemMeta(); MapMeta mapMeta = (MapMeta) freshMap.getItemMeta();
mapMeta.setDisplayName(ChatColor.RESET + getName()); mapMeta.setDisplayName(getName());
mapMeta.setLore(lore); mapMeta.setLore(lore);
mapMeta.getPersistentDataContainer().set(getNamespacedKey(), getIdentifier(), getIdentifier().getID()); mapMeta.getPersistentDataContainer().set(getNamespacedKey(), getIdentifier(), getIdentifier().getID());
MapView mapView = Bukkit.createMap(clicker.getWorld()); MapView mapView = Bukkit.createMap(clicker.getWorld());

View File

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