From 66945d29835c90a46ef576abbdf4ee2b27d09f7e Mon Sep 17 00:00:00 2001 From: Alex4386 Date: Tue, 25 Jun 2024 03:00:32 +0900 Subject: [PATCH] fix: landslide --- .../typhon/volcano/VolcanoComposition.java | 2 +- .../volcano/landslide/VolcanoLandslide.java | 121 ++++++++++++------ .../volcano/lavaflow/VolcanoLavaFlow.java | 10 +- 3 files changed, 90 insertions(+), 43 deletions(-) diff --git a/src/main/java/me/alex4386/plugin/typhon/volcano/VolcanoComposition.java b/src/main/java/me/alex4386/plugin/typhon/volcano/VolcanoComposition.java index 71547fe..b9cc92d 100644 --- a/src/main/java/me/alex4386/plugin/typhon/volcano/VolcanoComposition.java +++ b/src/main/java/me/alex4386/plugin/typhon/volcano/VolcanoComposition.java @@ -23,7 +23,7 @@ public static Material getBombRock(double silicateLevel, double distanceScale) { double scaled = distanceScale * redScoriaPercentage; double s = random.nextDouble(); - System.out.println("redScoriaPercentage: "+redScoriaPercentage+", distanceScale:"+distanceScale+", Scaled: " + scaled); + //System.out.println("redScoriaPercentage: "+redScoriaPercentage+", distanceScale:"+distanceScale+", Scaled: " + scaled); if (s < scaled) { return Material.COBBLED_DEEPSLATE; diff --git a/src/main/java/me/alex4386/plugin/typhon/volcano/landslide/VolcanoLandslide.java b/src/main/java/me/alex4386/plugin/typhon/volcano/landslide/VolcanoLandslide.java index 9543985..9c5cf47 100644 --- a/src/main/java/me/alex4386/plugin/typhon/volcano/landslide/VolcanoLandslide.java +++ b/src/main/java/me/alex4386/plugin/typhon/volcano/landslide/VolcanoLandslide.java @@ -1,6 +1,7 @@ package me.alex4386.plugin.typhon.volcano.landslide; import me.alex4386.plugin.typhon.TyphonPlugin; +import me.alex4386.plugin.typhon.TyphonScheduler; import me.alex4386.plugin.typhon.TyphonSounds; import me.alex4386.plugin.typhon.TyphonUtils; import me.alex4386.plugin.typhon.volcano.utils.VolcanoMath; @@ -10,17 +11,15 @@ import org.bukkit.block.BlockFace; import org.bukkit.util.Vector; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; +import java.util.*; public class VolcanoLandslide { public VolcanoVent vent; public double landslideAngle = 0; public int initSummitY = Integer.MIN_VALUE; - public Iterator blockIterator = null - ; + public Map> iteratorPerChunk = null; + public int landslideTimer = -1; public VolcanoLandslide(VolcanoVent vent) { @@ -37,58 +36,91 @@ public void shutdown() { public void registerTask() { if (this.landslideTimer < 0) { - this.landslideTimer = Bukkit.getScheduler().scheduleSyncRepeatingTask(TyphonPlugin.plugin, this::runTask, 0, 1); + this.landslideTimer = TyphonScheduler.registerGlobalTask( + this::runTask, 1 + ); } } public void unregisterTask() { if (this.landslideTimer >= 0) { - Bukkit.getScheduler().cancelTask(this.landslideTimer); + TyphonScheduler.unregisterTask(this.landslideTimer); this.landslideTimer = -1; } } public void clear() { - this.blockIterator = null; + this.iteratorPerChunk = null; this.initSummitY = Integer.MIN_VALUE; this.landslideAngle = 0; } public void runTask() { - if (this.blockIterator == null) return; - - Block randomSrc = null; + if (this.iteratorPerChunk == null) return; + if (this.iteratorPerChunk.isEmpty()) { + this.clear(); + return; + } - int count = 5 + (int) (Math.random() * 10); - for (int i = 0; i < count; i++) { - if (!this.blockIterator.hasNext()) { - break; + for (Chunk chunk : this.iteratorPerChunk.keySet()) { + if (this.iteratorPerChunk.get(chunk) == null || !this.iteratorPerChunk.get(chunk).hasNext()) { + this.iteratorPerChunk.remove(chunk); + continue; } + TyphonScheduler.run(chunk, () -> this.runChunk(chunk)); + } + + if (Math.random() < 0.1) { + TyphonSounds.DISTANT_EXPLOSION.play(this.vent.location, SoundCategory.BLOCKS, 2f, 1f); + } - Block block = this.blockIterator.next(); + this.runPyroclasticFlow(); + } - if (randomSrc == null) randomSrc = block; - else if (Math.random() < 0.1) randomSrc = block; + public void runChunk(Chunk chunk) { + Iterator iterator = this.iteratorPerChunk.get(chunk); + if (iterator == null) return; + int count = 0; + while (iterator.hasNext() && count < 100) { + Block block = iterator.next(); this.runCollapse(block); + count++; } - if (Math.random() < 0.1 && randomSrc != null) { - TyphonSounds.DISTANT_EXPLOSION.play(randomSrc.getLocation(), SoundCategory.BLOCKS, 2f, 1f); - } - - this.runPyroclasticFlow(); - if (!this.blockIterator.hasNext()) { - this.blockIterator = null; + if (!iterator.hasNext()) { + this.iteratorPerChunk.remove(chunk); } } public void start() { if (!this.isConfigured()) return; - if (this.blockIterator == null) { - this.blockIterator = this.getTargetBlocks().iterator(); + if (this.iteratorPerChunk == null) { + this.generateIterator(); + } + } + + public void generateIterator() { + List blocks = this.getTargetBlocks(); + Map> blocksPerChunk = new HashMap<>(); + + for (Block block : blocks) { + Chunk chunk = block.getChunk(); + if (!blocksPerChunk.containsKey(chunk)) { + blocksPerChunk.put(chunk, new ArrayList<>()); + } + + blocksPerChunk.get(chunk).add(block); + } + + Map> iteratorPerChunk = new HashMap<>(); + for (Chunk chunk : blocksPerChunk.keySet()) { + List blockList = blocksPerChunk.get(chunk); + iteratorPerChunk.put(chunk, blockList.iterator()); } + + this.iteratorPerChunk = iteratorPerChunk; } public boolean isConfigured() { @@ -97,7 +129,9 @@ public boolean isConfigured() { public void configure() { this.initSummitY = (int) (this.vent.getSummitBlock().getY() + (this.vent.getRadius() / Math.sqrt(3))); - this.landslideAngle = Math.random() * Math.PI * 2; + if (this.landslideAngle == 0) { + this.landslideAngle = Math.random() * Math.PI * 2; + } } public void setLandslideAngle(double angle) { @@ -123,12 +157,12 @@ public double getRimY(double x) { } public int getFloorY(double x) { - if (x < 0 && x > -this.getRadius()) { + if (x < 0) { return (int) (this.getRimSummitY() - this.getRadius() - x); } int zeroY = this.getRimSummitY() - this.getRadius(); - double offset = ((1.0 / 16.0) * x); + double offset = ((1.0 / 12.0) * x); return (int) Math.round(zeroY - offset); } @@ -186,25 +220,25 @@ public double getLandslideVolume() { } public List getTargetBlocks() { - List blocks = VolcanoMath.getCircle(this.vent.location.getBlock(), this.getRadius()); + double radius = this.getRadius() * 1.25; + + Set blocks = new HashSet<>(VolcanoMath.getCircle(this.vent.location.getBlock(), (int) radius)); double cos = Math.cos(this.landslideAngle); double sin = Math.sin(this.landslideAngle); int length = this.getRadius() * 8; - for (int x = 0; x < length; x++) { - for (int z = -this.getRadius(); z < this.getRadius(); z++) { + for (double x = 0; x < length; x += 0.5) { + for (double z = -radius; z < radius; z += 0.5) { double rotatedX = x * cos - z * sin; double rotatedZ = x * sin + z * cos; Block block = this.vent.location.getBlock().getRelative((int) rotatedX, 0, (int) rotatedZ); - if (!blocks.contains(block)) { - blocks.add(block); - } + blocks.add(block); } } - return blocks; + return blocks.stream().toList(); } public void runCollapse(Block block) { @@ -212,12 +246,14 @@ public void runCollapse(Block block) { Vector vector = this.getVector(block.getLocation()); int y = this.getY(vector); - int currentY = TyphonUtils.getHighestRocklikes(block).getY(); + Block topBlock = TyphonUtils.getHighestRocklikes(block); + int currentY = topBlock.getY(); + System.out.println("Drilling down from " + currentY + " to " + y); if (currentY < y) return; for (int i = currentY; i > y; i--) { - Block targetBlock = block.getRelative(0, i - currentY, 0); - if (targetBlock.getType().isSolid()) { + Block targetBlock = topBlock.getRelative(0, i - currentY, 0); + if (!targetBlock.getType().isAir()) { Material material = i <= world.getSeaLevel() ? world.isUltraWarm() ? Material.LAVA : Material.WATER : Material.AIR; @@ -243,7 +279,10 @@ public Block getPyroclasticFlowSource() { double x = xOffset * cos - zOffset * sin; double z = xOffset * sin + zOffset * cos; - return TyphonUtils.getHighestRocklikes(this.vent.location.clone().add(x, 0, z).getBlock()).getRelative(BlockFace.UP); + Block baseBlock = this.vent.location.clone().add(x, 255, z).getBlock(); + baseBlock = TyphonUtils.getHighestRocklikes(baseBlock); + + return TyphonUtils.getHighestRocklikes(baseBlock).getRelative(BlockFace.UP); } } diff --git a/src/main/java/me/alex4386/plugin/typhon/volcano/lavaflow/VolcanoLavaFlow.java b/src/main/java/me/alex4386/plugin/typhon/volcano/lavaflow/VolcanoLavaFlow.java index 023bf39..56d5cfb 100644 --- a/src/main/java/me/alex4386/plugin/typhon/volcano/lavaflow/VolcanoLavaFlow.java +++ b/src/main/java/me/alex4386/plugin/typhon/volcano/lavaflow/VolcanoLavaFlow.java @@ -102,6 +102,10 @@ public void setLavaInflux(int currentLavaInflux) { } public void queueBlockUpdate(Block block, Material material) { + if (this.queueScheduleId == -1) { + this.registerQueueUpdate(); + } + Chunk chunk = block.getChunk(); if (!blockUpdateQueues.containsKey(chunk)) { blockUpdateQueues.put(chunk, new LinkedList<>()); @@ -210,6 +214,10 @@ public void registerTask() { }, 1L); } + this.registerQueueUpdate(); + } + + public void registerQueueUpdate() { if (queueScheduleId == -1) { this.vent.volcano.logger.log( VolcanoLogClass.LAVA_FLOW, @@ -1225,7 +1233,7 @@ public double getDistanceRatio(Location dest) { double distanceFromVent = Math.max(0, Math.min(distance - radius, coneHeight)); double scaledDistance = distanceFromVent / coneHeight; - System.out.println("coneHeight: "+coneHeight+", distance: "+distance+", radius: "+radius+", distanceFromVent: "+distanceFromVent+", scaledDistance: "+scaledDistance); + //System.out.println("coneHeight: "+coneHeight+", distance: "+distance+", radius: "+radius+", distanceFromVent: "+distanceFromVent+", scaledDistance: "+scaledDistance); return Math.min(Math.pow(scaledDistance, 2), 1); }