diff --git a/core/src/main/java/net/pl3x/map/core/registry/RendererRegistry.java b/core/src/main/java/net/pl3x/map/core/registry/RendererRegistry.java index b2ebb122c..ebf33e6c7 100644 --- a/core/src/main/java/net/pl3x/map/core/registry/RendererRegistry.java +++ b/core/src/main/java/net/pl3x/map/core/registry/RendererRegistry.java @@ -29,6 +29,7 @@ import net.pl3x.map.core.renderer.BlockInfoRenderer; import net.pl3x.map.core.renderer.FlowerMapRenderer; import net.pl3x.map.core.renderer.InhabitedRenderer; +import net.pl3x.map.core.renderer.NetherRoofRenderer; import net.pl3x.map.core.renderer.NightRenderer; import net.pl3x.map.core.renderer.Renderer; import net.pl3x.map.core.renderer.VanillaRenderer; @@ -45,6 +46,7 @@ public class RendererRegistry extends Registry { public static final String NIGHT = "night"; public static final String VANILLA = "vanilla"; public static final String VINTAGE_STORY = "vintage_story"; + public static final String NETHER_ROOF = "nether_roof"; public void register() { register(BASIC, new Renderer.Builder(BASIC, "Basic", BasicRenderer.class)); @@ -55,6 +57,7 @@ public void register() { register(NIGHT, new Renderer.Builder(NIGHT, "Night", NightRenderer.class)); register(VANILLA, new Renderer.Builder(VANILLA, "Vanilla", VanillaRenderer.class)); register(VINTAGE_STORY, new Renderer.Builder(VINTAGE_STORY, "VintageStory", VintageStoryRenderer.class)); + register(NETHER_ROOF, new Renderer.Builder(NETHER_ROOF, "NetherRoof", NetherRoofRenderer.class)); } public @NotNull Renderer createRenderer(@NotNull RegionScanTask task, Renderer.@NotNull Builder builder) { diff --git a/core/src/main/java/net/pl3x/map/core/renderer/NetherRoofRenderer.java b/core/src/main/java/net/pl3x/map/core/renderer/NetherRoofRenderer.java new file mode 100644 index 000000000..fca124143 --- /dev/null +++ b/core/src/main/java/net/pl3x/map/core/renderer/NetherRoofRenderer.java @@ -0,0 +1,135 @@ +/* + * MIT License + * + * Copyright (c) 2020-2023 William Blake Galbreath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package net.pl3x.map.core.renderer; + +import net.pl3x.map.core.Pl3xMap; +import net.pl3x.map.core.renderer.heightmap.Heightmap; +import net.pl3x.map.core.renderer.task.RegionScanTask; +import net.pl3x.map.core.util.Colors; +import net.pl3x.map.core.world.BlockState; +import net.pl3x.map.core.world.Chunk; +import net.pl3x.map.core.world.EmptyChunk; +import net.pl3x.map.core.world.Region; +import org.jetbrains.annotations.NotNull; + +public class NetherRoofRenderer extends Renderer { + private final Heightmap heightmap; + + public NetherRoofRenderer(@NotNull RegionScanTask task, @NotNull Builder builder) { + super(task, builder); + this.heightmap = Pl3xMap.api().getHeightmapRegistry().get("old_school"); + } + + @Override + public @NotNull Heightmap getHeightmap() { + return this.heightmap; + } + + @Override + public void scanData(@NotNull Region region) { + int startX = region.getX() << 9; + int startZ = region.getZ() << 9; + + for (int pixelX = 0; pixelX < 512; pixelX++) { + int blockX = startX + pixelX; + double lastBlockY = 0.0D; + for (int pixelZ = -1; pixelZ < 512; pixelZ++) { + int blockZ = startZ + pixelZ; + + if (!getWorld().visibleBlock(blockX, blockZ)) { + continue; + } + + Pl3xMap.api().getRegionProcessor().checkPaused(); + + Chunk chunk = region.getWorld().getChunk(region, blockX >> 4, blockZ >> 4); + if (chunk instanceof EmptyChunk) { + continue; + } + + int blockY = chunk.noHeightmap() ? getWorld().getMaxBuildHeight() : chunk.getWorldSurfaceY(blockX, blockZ) + 1; + int fluidY = 0; + BlockState blockstate; + BlockState fluidstate = null; + + // iterate down until we find a renderable block + do { + blockY -= 1; + blockstate = chunk.getBlockState(blockX, blockY, blockZ); + if (blockstate.getBlock().isFluid()) { + if (fluidstate == null) { + // get fluid information for the top fluid block + fluidY = blockY; + fluidstate = blockstate; + } + continue; + } + + // test if block is renderable. we ignore blocks with black color + if (blockstate.getBlock().vanilla() > 0) { + break; + } + } while (blockY > getWorld().getMinBuildHeight()); + + if (pixelZ >= 0) { + int color; + int brightness; + if (fluidstate != null) { + color = fluidstate.getBlock().vanilla(); + double heightDiff = (double) (fluidY - blockY) * 0.1D + (double) (pixelX + pixelZ & 1) * 0.2D; + if (heightDiff < 0.5D) { + brightness = 0x00; + } else if (heightDiff > 0.9D) { + brightness = 0x44; + } else { + brightness = 0x22; + } + } else { + color = blockstate.getBlock().vanilla(); + double heightDiff = (blockY - lastBlockY) * 4.0D / (double) (1 + 4) + ((double) (pixelX + pixelZ & 1) - 0.5D) * 0.4D; + if (heightDiff > 0.6D) { + brightness = 0x00; + } else if (heightDiff < -0.6D) { + brightness = 0x44; + } else { + brightness = 0x22; + } + } + + getTileImage().setPixel(pixelX, pixelZ, Colors.blend(brightness << 24, Colors.setAlpha(0xFF, color))); + } + + if (blockstate.getBlock().isFlat()) { + blockY--; + } + + lastBlockY = blockY; + } + } + } + + @Override + public void scanBlock(@NotNull Region region, @NotNull Chunk chunk, Chunk.@NotNull BlockData data, int blockX, int blockZ) { + } +} diff --git a/core/src/main/java/net/pl3x/map/core/renderer/task/RegionProcessor.java b/core/src/main/java/net/pl3x/map/core/renderer/task/RegionProcessor.java index fe3a85def..22134a2d6 100644 --- a/core/src/main/java/net/pl3x/map/core/renderer/task/RegionProcessor.java +++ b/core/src/main/java/net/pl3x/map/core/renderer/task/RegionProcessor.java @@ -141,6 +141,8 @@ private void run() { try { while (!this.ticketsToScan.isEmpty()) { Ticket ticket = this.ticketsToScan.poll(); + if (ticket == null) break; + Collection set = this.regionsToScan.getOrDefault(ticket.world, new HashSet<>()); set.add(ticket.region); this.regionsToScan.put(ticket.world, set); diff --git a/webmap/public/images/icon/nether_roof.png b/webmap/public/images/icon/nether_roof.png new file mode 100644 index 000000000..958e2379c Binary files /dev/null and b/webmap/public/images/icon/nether_roof.png differ