From 1c9f9d92bbe34652530ec5abeb0779fb103754b8 Mon Sep 17 00:00:00 2001 From: Brian Neumann-Fopiano Date: Thu, 11 Jun 2026 14:18:13 -0400 Subject: [PATCH] Neutral Pipeline --- .../iris/core/commands/CommandObject.java | 11 +- .../iris/core/runtime/GoldenHashScanner.java | 41 +- .../core/runtime/InPlaceChunkRegenerator.java | 10 +- .../art/arcane/iris/core/service/TreeSVC.java | 11 +- .../core/structure/StructureImporter.java | 2 +- .../iris/core/structure/VillageImporter.java | 2 +- .../arcane/iris/core/tools/IrisConverter.java | 2 +- .../iris/core/tools/TreePlausibilizer.java | 14 +- .../art/arcane/iris/engine/IrisComplex.java | 14 +- .../art/arcane/iris/engine/IrisEngine.java | 11 +- .../iris/engine/UpperDimensionContext.java | 10 +- .../engine/actuator/IrisBiomeActuator.java | 5 +- .../engine/actuator/IrisDecorantActuator.java | 19 +- .../actuator/IrisTerrainNormalActuator.java | 51 +- .../engine/data/chunk/LinkedTerrainChunk.java | 23 +- .../iris/engine/data/chunk/TerrainChunk.java | 14 +- .../iris/engine/decorator/DecoratorCore.java | 119 +- .../engine/decorator/FloatingDecorator.java | 4 +- .../decorator/IrisCeilingDecorator.java | 10 +- .../decorator/IrisSeaFloorDecorator.java | 4 +- .../decorator/IrisSeaSurfaceDecorator.java | 4 +- .../decorator/IrisShoreLineDecorator.java | 4 +- .../decorator/IrisSurfaceDecorator.java | 4 +- .../iris/engine/framework/BlockUpdater.java | 4 +- .../arcane/iris/engine/framework/Engine.java | 15 +- .../engine/framework/EngineDecorator.java | 11 +- .../iris/engine/framework/EngineMode.java | 6 +- .../iris/engine/framework/EngineStage.java | 6 +- .../engine/framework/PregeneratedData.java | 15 +- .../placer/HeightmapObjectPlacer.java | 6 +- .../framework/placer/WorldObjectPlacer.java | 9 +- .../iris/engine/mantle/EngineMantle.java | 14 +- .../iris/engine/mantle/MantleWriter.java | 14 +- .../mantle/components/IslandObjectPlacer.java | 7 +- .../MantleFloatingObjectComponent.java | 9 +- .../components/MantleObjectComponent.java | 19 +- .../engine/modifier/IrisCarveModifier.java | 71 +- .../engine/modifier/IrisCustomModifier.java | 13 +- .../engine/modifier/IrisDepositModifier.java | 38 +- .../IrisFloatingChildBiomeModifier.java | 55 +- .../modifier/IrisPerfectionModifier.java | 60 +- .../engine/modifier/IrisPostModifier.java | 98 +- .../engine/object/BlockDataMergeSupport.java | 7 +- .../engine/object/DecayControlPlacer.java | 6 +- .../object/FloatingObjectFootprint.java | 5 +- .../iris/engine/object/IObjectLoot.java | 4 +- .../iris/engine/object/IObjectPlacer.java | 6 +- .../iris/engine/object/IPostBlockAccess.java | 6 +- .../arcane/iris/engine/object/IrisBiome.java | 37 +- .../engine/object/IrisBiomePaletteLayer.java | 12 +- .../iris/engine/object/IrisBlockData.java | 19 +- .../iris/engine/object/IrisBlockDrops.java | 7 +- .../iris/engine/object/IrisCaveShape.java | 3 +- .../iris/engine/object/IrisDecorator.java | 50 +- .../engine/object/IrisDepositGenerator.java | 12 +- .../engine/object/IrisDepositVariant.java | 7 +- .../iris/engine/object/IrisDimension.java | 1263 +++++++++-------- .../engine/object/IrisMaterialPalette.java | 12 +- .../arcane/iris/engine/object/IrisObject.java | 199 +-- .../iris/engine/object/IrisObjectLoot.java | 16 +- .../iris/engine/object/IrisObjectMarker.java | 10 +- .../engine/object/IrisObjectPlacement.java | 12 +- .../iris/engine/object/IrisObjectReplace.java | 14 +- .../engine/object/IrisObjectRotation.java | 12 + .../engine/object/IrisObjectVanillaLoot.java | 10 +- .../iris/engine/object/IrisOreGenerator.java | 4 +- .../engine/object/IrisProceduralBlocks.java | 8 +- .../arcane/iris/engine/object/IrisRegion.java | 12 +- .../formation/FormationBlockResolver.java | 7 +- .../object/tree/ProceduralTreeGenerator.java | 3 +- .../engine/object/tree/TreeBlockResolver.java | 9 +- .../engine/platform/BukkitChunkGenerator.java | 5 +- .../generators/BiomeBuffetGenerator.java | 5 +- .../generators/ObjectStudioGenerator.java | 27 +- .../bukkit/BukkitChunkWriteTarget.java | 6 +- .../util/project/context/ChunkContext.java | 10 +- .../arcane/iris/util/project/hunk/Hunk.java | 14 +- .../project/hunk/view/ChunkBiomeHunkView.java | 8 +- .../hunk/view/ChunkDataHunkHolder.java | 14 +- .../project/hunk/view/ChunkDataHunkView.java | 59 +- .../util/project/hunk/view/ChunkHunkView.java | 8 +- .../hunk/view/TerrainChunkBiomeHunkView.java | 8 +- .../project/matter/IrisMatterSupport.java | 2 +- .../stream/interpolation/Interpolated.java | 4 +- .../IrisRuntimeSchedulerModeRoutingTest.java | 15 +- .../InPlaceChunkRegeneratorDiffTest.java | 5 + .../engine/IrisComplexImplodeParityTest.java | 15 +- .../IrisCaveCarver3DNearParityTest.java | 14 +- ...risDimensionCarvingResolverParityTest.java | 15 +- ...atingChildBiomesCarvingResolutionTest.java | 15 +- .../object/IrisObjectBlockDataMergeTest.java | 12 + .../bukkit/BukkitSpiConformanceTest.java | 3 +- .../context/ChunkContextPrefillPlanTest.java | 2 + .../project/noise/CNGInjectorParityTest.java | 15 +- 94 files changed, 1592 insertions(+), 1320 deletions(-) diff --git a/core/src/main/java/art/arcane/iris/core/commands/CommandObject.java b/core/src/main/java/art/arcane/iris/core/commands/CommandObject.java index 81bc2410b..0550a421b 100644 --- a/core/src/main/java/art/arcane/iris/core/commands/CommandObject.java +++ b/core/src/main/java/art/arcane/iris/core/commands/CommandObject.java @@ -32,6 +32,8 @@ import art.arcane.iris.core.tools.PlausibilizeMode; import art.arcane.iris.core.tools.TreePlausibilizer; import art.arcane.iris.engine.framework.Engine; import art.arcane.iris.engine.object.*; +import art.arcane.iris.platform.bukkit.BukkitBlockState; +import art.arcane.iris.spi.PlatformBlockState; import art.arcane.volmlib.util.data.Cuboid; import art.arcane.iris.util.common.data.IrisCustomData; import art.arcane.iris.util.common.data.registry.Materials; @@ -174,7 +176,8 @@ public class CommandObject implements DirectorExecutor { } @Override - public void set(int x, int y, int z, BlockData d) { + public void set(int x, int y, int z, PlatformBlockState s) { + BlockData d = (BlockData) s.nativeHandle(); Block block = world.getBlockAt(x, y, z); //Prevent blocks being set in or bellow bedrock @@ -189,8 +192,8 @@ public class CommandObject implements DirectorExecutor { } @Override - public BlockData get(int x, int y, int z) { - return world.getBlockAt(x, y, z).getBlockData(); + public PlatformBlockState get(int x, int y, int z) { + return BukkitBlockState.of(world.getBlockAt(x, y, z).getBlockData()); } @Override @@ -259,7 +262,7 @@ public class CommandObject implements DirectorExecutor { Map amounts = new HashMap<>(); Map materials = new HashMap<>(); while (queue.hasNext()) { - BlockData block = queue.next(); + BlockData block = (BlockData) queue.next().nativeHandle(); //unsorted.put(block.getMaterial(), block); diff --git a/core/src/main/java/art/arcane/iris/core/runtime/GoldenHashScanner.java b/core/src/main/java/art/arcane/iris/core/runtime/GoldenHashScanner.java index 186b75cd8..480b9009c 100644 --- a/core/src/main/java/art/arcane/iris/core/runtime/GoldenHashScanner.java +++ b/core/src/main/java/art/arcane/iris/core/runtime/GoldenHashScanner.java @@ -22,14 +22,14 @@ import art.arcane.iris.Iris; import art.arcane.iris.engine.data.chunk.TerrainChunk; import art.arcane.iris.engine.framework.Engine; import art.arcane.iris.engine.mantle.EngineMantle; +import art.arcane.iris.spi.PlatformBiome; +import art.arcane.iris.spi.PlatformBlockState; import art.arcane.iris.util.common.format.C; import art.arcane.iris.util.common.parallel.MultiBurst; import art.arcane.iris.util.common.plugin.VolmitSender; import art.arcane.volmlib.util.mantle.runtime.Mantle; import org.bukkit.Bukkit; import org.bukkit.World; -import org.bukkit.block.Biome; -import org.bukkit.block.data.BlockData; import java.io.File; import java.io.IOException; @@ -184,14 +184,14 @@ public final class GoldenHashScanner { MessageDigest biomeDigest = sha256(); int minY = buffer.getMinHeight(); int maxY = buffer.getMaxHeight(); - IdentityHashMap blockCache = new IdentityHashMap<>(); - Map biomeCache = new HashMap<>(); + IdentityHashMap blockCache = new IdentityHashMap<>(); + Map biomeCache = new HashMap<>(); for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { for (int y = minY; y < maxY; y++) { - BlockData data = buffer.getBlockData(x, y, z); - byte[] bytes = blockCache.computeIfAbsent(data, d -> (d.getAsString() + "\n").getBytes(StandardCharsets.UTF_8)); + PlatformBlockState data = buffer.getBlockData(x, y, z); + byte[] bytes = blockCache.computeIfAbsent(data, (PlatformBlockState d) -> (d.key() + "\n").getBytes(StandardCharsets.UTF_8)); blockDigest.update(bytes); } } @@ -200,10 +200,10 @@ public final class GoldenHashScanner { for (int x = 0; x < 16; x += BIOME_STEP) { for (int z = 0; z < 16; z += BIOME_STEP) { for (int y = minY; y < maxY; y += BIOME_STEP) { - Biome biome = buffer.getBiome(x, y, z); + PlatformBiome biome = buffer.getBiome(x, y, z); byte[] bytes = biome == null ? NULL_BIOME - : biomeCache.computeIfAbsent(biome, b -> (biomeKey(b) + "\n").getBytes(StandardCharsets.UTF_8)); + : biomeCache.computeIfAbsent(biome, (PlatformBiome b) -> (b.key() + "\n").getBytes(StandardCharsets.UTF_8)); biomeDigest.update(bytes); } } @@ -319,8 +319,8 @@ public final class GoldenHashScanner { for (int x = 0; x < 16 && diffs.size() < 50; x++) { for (int z = 0; z < 16 && diffs.size() < 50; z++) { for (int y = minY; y < maxY && diffs.size() < 50; y++) { - String a = first.getBlockData(x, y, z).getAsString(); - String b = second.getBlockData(x, y, z).getAsString(); + String a = first.getBlockData(x, y, z).key(); + String b = second.getBlockData(x, y, z).key(); if (!a.equals(b)) { diffs.add(x + " " + y + " " + z + " | " + a + " | " + b); } @@ -341,8 +341,8 @@ public final class GoldenHashScanner { for (int x = 0; x < 16 && mantleDiffs.size() < 80; x++) { for (int z = 0; z < 16 && mantleDiffs.size() < 80; z++) { for (int y = minY; y < maxY && mantleDiffs.size() < 80; y++) { - String a = first.getBlockData(x, y, z).getAsString(); - String b = reset.getBlockData(x, y, z).getAsString(); + String a = first.getBlockData(x, y, z).key(); + String b = reset.getBlockData(x, y, z).key(); if (!a.equals(b)) { mantleDiffs.add(x + " " + y + " " + z + " | scan: " + a + " | mantle-reset: " + b); } @@ -360,7 +360,7 @@ public final class GoldenHashScanner { for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { for (int y = minY; y < maxY; y++) { - String state = first.getBlockData(x, y, z).getAsString(); + String state = first.getBlockData(x, y, z).key(); if (!state.equals("minecraft:air") && !state.equals("minecraft:cave_air") && !state.equals("minecraft:void_air")) { report.add(x + " " + y + " " + z + " " + state); } @@ -402,7 +402,7 @@ public final class GoldenHashScanner { for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { for (int y = minY; y < maxY; y++) { - String state = buffer.getBlockData(x, y, z).getAsString(); + String state = buffer.getBlockData(x, y, z).key(); if (!state.equals("minecraft:air") && !state.equals("minecraft:cave_air") && !state.equals("minecraft:void_air")) { out.add(x + " " + y + " " + z + " " + state); } @@ -412,19 +412,6 @@ public final class GoldenHashScanner { Files.write(new File(dir, chunkX + "_" + chunkZ + ".txt").toPath(), out, StandardCharsets.UTF_8); } - private static String biomeKey(Biome biome) { - for (String method : new String[]{"getKeyOrNull", "getKeyOrThrow", "getKey"}) { - try { - Object key = Biome.class.getMethod(method).invoke(biome); - if (key != null) { - return key.toString(); - } - } catch (Throwable ignored) { - } - } - return biome.toString(); - } - private static String shortHash(String hex) { return hex.substring(0, 12); } diff --git a/core/src/main/java/art/arcane/iris/core/runtime/InPlaceChunkRegenerator.java b/core/src/main/java/art/arcane/iris/core/runtime/InPlaceChunkRegenerator.java index b9482647b..4390fe21e 100644 --- a/core/src/main/java/art/arcane/iris/core/runtime/InPlaceChunkRegenerator.java +++ b/core/src/main/java/art/arcane/iris/core/runtime/InPlaceChunkRegenerator.java @@ -23,6 +23,7 @@ import art.arcane.iris.core.nms.INMS; import art.arcane.iris.engine.data.chunk.TerrainChunk; import art.arcane.iris.engine.framework.Engine; import art.arcane.iris.engine.mantle.EngineMantle; +import art.arcane.iris.spi.PlatformBiome; import art.arcane.iris.util.common.parallel.MultiBurst; import art.arcane.iris.util.common.plugin.VolmitSender; import art.arcane.iris.util.common.scheduling.J; @@ -163,9 +164,12 @@ public final class InPlaceChunkRegenerator { for (int x = 0; x < 16; x += BIOME_STEP) { for (int z = 0; z < 16; z += BIOME_STEP) { for (int y = minHeight; y < maxHeight; y += BIOME_STEP) { - Biome biome = buffer.getBiome(x, y, z); - if (biome != null && world.getBiome(baseX + x, y, baseZ + z) != biome) { - world.setBiome(baseX + x, y, baseZ + z, biome); + PlatformBiome biome = buffer.getBiome(x, y, z); + if (biome != null) { + Biome bukkitBiome = (Biome) biome.nativeHandle(); + if (world.getBiome(baseX + x, y, baseZ + z) != bukkitBiome) { + world.setBiome(baseX + x, y, baseZ + z, bukkitBiome); + } } } } diff --git a/core/src/main/java/art/arcane/iris/core/service/TreeSVC.java b/core/src/main/java/art/arcane/iris/core/service/TreeSVC.java index de739408f..9a41572ab 100644 --- a/core/src/main/java/art/arcane/iris/core/service/TreeSVC.java +++ b/core/src/main/java/art/arcane/iris/core/service/TreeSVC.java @@ -24,6 +24,8 @@ import art.arcane.iris.core.tools.IrisToolbelt; import art.arcane.iris.engine.framework.Engine; import art.arcane.iris.engine.object.*; import art.arcane.iris.engine.platform.PlatformChunkGenerator; +import art.arcane.iris.platform.bukkit.BukkitBlockState; +import art.arcane.iris.spi.PlatformBlockState; import art.arcane.volmlib.util.collection.KList; import art.arcane.volmlib.util.collection.KMap; import art.arcane.volmlib.util.data.Cuboid; @@ -139,7 +141,8 @@ public class TreeSVC implements IrisService { } @Override - public void set(int x, int y, int z, BlockData d) { + public void set(int x, int y, int z, PlatformBlockState s) { + BlockData d = (BlockData) s.nativeHandle(); Block b = event.getWorld().getBlockAt(x, y, z); BlockState state = b.getState(); if (d instanceof IrisCustomData data) @@ -150,8 +153,8 @@ public class TreeSVC implements IrisService { } @Override - public BlockData get(int x, int y, int z) { - return event.getWorld().getBlockAt(x, y, z).getBlockData(); + public PlatformBlockState get(int x, int y, int z) { + return BukkitBlockState.of(event.getWorld().getBlockAt(x, y, z).getBlockData()); } @Override @@ -166,7 +169,7 @@ public class TreeSVC implements IrisService { @Override public boolean isSolid(int x, int y, int z) { - return get(x, y, z).getMaterial().isSolid(); + return event.getWorld().getBlockAt(x, y, z).getBlockData().getMaterial().isSolid(); } @Override diff --git a/core/src/main/java/art/arcane/iris/core/structure/StructureImporter.java b/core/src/main/java/art/arcane/iris/core/structure/StructureImporter.java index 03ee1d0ea..0a7bc7d56 100644 --- a/core/src/main/java/art/arcane/iris/core/structure/StructureImporter.java +++ b/core/src/main/java/art/arcane/iris/core/structure/StructureImporter.java @@ -135,7 +135,7 @@ public final class StructureImporter { } else if (mat == Material.STRUCTURE_BLOCK) { continue; } - object.setUnsigned(x, y, z, blockData); + object.setUnsigned(x, y, z, art.arcane.iris.platform.bukkit.BukkitBlockState.of(blockData)); count++; if (!structural) { LegacyTileData tile = captureTile(block); diff --git a/core/src/main/java/art/arcane/iris/core/structure/VillageImporter.java b/core/src/main/java/art/arcane/iris/core/structure/VillageImporter.java index a98aa5014..646d1b278 100644 --- a/core/src/main/java/art/arcane/iris/core/structure/VillageImporter.java +++ b/core/src/main/java/art/arcane/iris/core/structure/VillageImporter.java @@ -616,7 +616,7 @@ public final class VillageImporter { File objectFile = new File(data.getDataFolder(), "objects/" + pieceName + ".iob"); objectFile.getParentFile().mkdirs(); IrisObject object = new IrisObject(1, 1, 1); - object.setUnsigned(0, 0, 0, Material.AIR.createBlockData()); + object.setUnsigned(0, 0, 0, art.arcane.iris.platform.bukkit.BukkitBlockState.of(Material.AIR.createBlockData())); object.write(objectFile); return true; } catch (Throwable e) { diff --git a/core/src/main/java/art/arcane/iris/core/tools/IrisConverter.java b/core/src/main/java/art/arcane/iris/core/tools/IrisConverter.java index 47221723e..83eab0f2f 100644 --- a/core/src/main/java/art/arcane/iris/core/tools/IrisConverter.java +++ b/core/src/main/java/art/arcane/iris/core/tools/IrisConverter.java @@ -93,7 +93,7 @@ public class IrisConverter { int blockIndex = isBytes ? din.read() & 0xFF : Varint.readUnsignedVarInt(din); BlockData bd = blockmap.get(blockIndex); if (!bd.getMaterial().isAir()) { - object.setUnsigned(w, h, d, bd); + object.setUnsigned(w, h, d, art.arcane.iris.platform.bukkit.BukkitBlockState.of(bd)); } v.getAndAdd(1); } diff --git a/core/src/main/java/art/arcane/iris/core/tools/TreePlausibilizer.java b/core/src/main/java/art/arcane/iris/core/tools/TreePlausibilizer.java index f4091bd2f..f3cfb70f4 100644 --- a/core/src/main/java/art/arcane/iris/core/tools/TreePlausibilizer.java +++ b/core/src/main/java/art/arcane/iris/core/tools/TreePlausibilizer.java @@ -23,6 +23,8 @@ import art.arcane.iris.util.common.data.B; import art.arcane.iris.util.common.data.VectorMap; import org.bukkit.Axis; import org.bukkit.Tag; +import art.arcane.iris.platform.bukkit.BukkitBlockState; +import art.arcane.iris.spi.PlatformBlockState; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.Orientable; import org.bukkit.block.data.type.Leaves; @@ -79,7 +81,7 @@ public final class TreePlausibilizer { boolean normalize = mode == PlausibilizeMode.NORMALIZE; boolean smoke = mode == PlausibilizeMode.SMOKE; boolean foliageOverature = mode == PlausibilizeMode.FOLIAGE_OVERATURE; - VectorMap blocks = obj.getBlocks(); + VectorMap blocks = obj.getBlocks(); Map positions = new HashMap<>(blocks.size() * 2); Set logPositions = new HashSet<>(); Set originalLeafPositions = new HashSet<>(); @@ -89,9 +91,9 @@ public final class TreePlausibilizer { int minX = Integer.MAX_VALUE, minY = Integer.MAX_VALUE, minZ = Integer.MAX_VALUE; int maxX = Integer.MIN_VALUE, maxY = Integer.MIN_VALUE, maxZ = Integer.MIN_VALUE; - for (Map.Entry entry : blocks) { + for (Map.Entry entry : blocks) { BlockVector pos = entry.getKey(); - BlockData data = entry.getValue(); + BlockData data = (BlockData) entry.getValue().nativeHandle(); long key = packKey(pos); positions.put(key, data); int x = pos.getBlockX(); @@ -235,13 +237,13 @@ public final class TreePlausibilizer { blocks.remove(unpackKey(key)); } for (LeafAddition addition : leafAdds) { - blocks.put(unpackKey(addition.key()), addition.data()); + blocks.put(unpackKey(addition.key()), BukkitBlockState.of(addition.data())); } for (LogInsertion insertion : inserts) { - blocks.put(unpackKey(insertion.key()), insertion.data()); + blocks.put(unpackKey(insertion.key()), BukkitBlockState.of(insertion.data())); } for (LeafRewrite rewrite : normalizeRewrites) { - blocks.put(unpackKey(rewrite.key()), rewrite.data()); + blocks.put(unpackKey(rewrite.key()), BukkitBlockState.of(rewrite.data())); } } diff --git a/core/src/main/java/art/arcane/iris/engine/IrisComplex.java b/core/src/main/java/art/arcane/iris/engine/IrisComplex.java index b2c63c158..e929c735a 100644 --- a/core/src/main/java/art/arcane/iris/engine/IrisComplex.java +++ b/core/src/main/java/art/arcane/iris/engine/IrisComplex.java @@ -24,6 +24,9 @@ import art.arcane.iris.core.loader.IrisData; import art.arcane.iris.engine.data.cache.Cache; import art.arcane.iris.engine.framework.Engine; import art.arcane.iris.engine.object.*; +import art.arcane.iris.platform.bukkit.BukkitBiome; +import art.arcane.iris.spi.PlatformBiome; +import art.arcane.iris.spi.PlatformBlockState; import art.arcane.volmlib.util.collection.KList; import art.arcane.iris.util.project.context.IrisContext; import art.arcane.iris.util.common.data.DataProvider; @@ -37,7 +40,6 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import org.bukkit.Material; -import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; import java.io.File; @@ -68,7 +70,7 @@ public class IrisComplex implements DataProvider { private ProceduralStream baseBiomeStream; private ProceduralStream baseBiomeIDStream; private ProceduralStream trueBiomeStream; - private ProceduralStream trueBiomeDerivativeStream; + private ProceduralStream trueBiomeDerivativeStream; private ProceduralStream heightStream; private ProceduralStream roundedHeighteightStream; private ProceduralStream maxHeightStream; @@ -83,8 +85,8 @@ public class IrisComplex implements DataProvider { private ProceduralStream seaSurfaceDecoration; private ProceduralStream seaFloorDecoration; private ProceduralStream shoreSurfaceDecoration; - private ProceduralStream rockStream; - private ProceduralStream fluidStream; + private ProceduralStream rockStream; + private ProceduralStream fluidStream; private IrisBiome focusBiome; private IrisRegion focusRegion; private Map> generatorBounds; @@ -216,7 +218,7 @@ public class IrisComplex implements DataProvider { regionStream.contextInjecting((c, xx, zz) -> IrisContext.getOr(engine).getChunkContext().getRegion().get(xx, zz)).get(x, z), x, z, fluidHeight)) .cache2D("trueBiomeStream", engine, cacheSize).waste("True Biome Stream"); trueBiomeDerivativeStream = trueBiomeStream.contextInjecting((c, x, z) -> IrisContext.getOr(engine).getChunkContext().getBiome().get(x, z)) - .convert(IrisBiome::getDerivative).cache2D("trueBiomeDerivativeStream", engine, cacheSize).waste("True Biome Derivative Stream"); + .convert((b) -> (PlatformBiome) BukkitBiome.of(b.getDerivative())).cache2D("trueBiomeDerivativeStream", engine, cacheSize).waste("True Biome Derivative Stream"); heightFluidStream = heightStream.contextInjecting((c, x, z) -> IrisContext.getOr(engine).getChunkContext().getHeight().getDouble(x, z)) .max(fluidHeight).cache2DDouble("heightFluidStream", engine, cacheSize).waste("Height Fluid Stream"); maxHeightStream = ProceduralStream.ofDouble((x, z) -> height).waste("Max Height Stream"); @@ -287,7 +289,7 @@ public class IrisComplex implements DataProvider { continue; } - BlockData block = i.getBlockData(b, rngc, x, z, data); + PlatformBlockState block = i.getBlockData(b, rngc, x, z, data); if (block != null) { return i; diff --git a/core/src/main/java/art/arcane/iris/engine/IrisEngine.java b/core/src/main/java/art/arcane/iris/engine/IrisEngine.java index 39fe0f686..fa0b56f7d 100644 --- a/core/src/main/java/art/arcane/iris/engine/IrisEngine.java +++ b/core/src/main/java/art/arcane/iris/engine/IrisEngine.java @@ -38,6 +38,9 @@ import art.arcane.iris.engine.data.cache.AtomicCache; import art.arcane.iris.engine.framework.*; import art.arcane.iris.engine.mantle.EngineMantle; import art.arcane.iris.engine.object.*; +import art.arcane.iris.platform.bukkit.BukkitBlockState; +import art.arcane.iris.spi.PlatformBiome; +import art.arcane.iris.spi.PlatformBlockState; import art.arcane.volmlib.util.atomics.AtomicRollingSequence; import art.arcane.volmlib.util.collection.KMap; import art.arcane.iris.util.project.context.ChunkContext; @@ -59,8 +62,6 @@ import lombok.EqualsAndHashCode; import lombok.ToString; import org.bukkit.Material; import org.bukkit.World; -import org.bukkit.block.Biome; -import org.bukkit.block.data.BlockData; import org.bukkit.command.CommandSender; import java.io.File; @@ -651,7 +652,7 @@ public class IrisEngine implements Engine { @BlockCoordinates @Override - public void generate(int x, int z, Hunk vblocks, Hunk vbiomes, boolean multicore) throws WrongEngineBroException { + public void generate(int x, int z, Hunk vblocks, Hunk vbiomes, boolean multicore) throws WrongEngineBroException { if (closing.get() || closed) { throw new GenerationSessionException("Generation session is closed for world \"" + getWorld().name() + "\".", true); } @@ -661,12 +662,12 @@ public class IrisEngine implements Engine { context.setGenerationSessionId(lease.sessionId()); getEngineData().getStatistics().generatedChunk(); PrecisionStopwatch p = PrecisionStopwatch.start(); - Hunk blocks = vblocks.listen((xx, y, zz, t) -> catchBlockUpdates(x + xx, y, z + zz, t)); + Hunk blocks = vblocks.listen((xx, y, zz, t) -> catchBlockUpdates(x + xx, y, z + zz, t)); if (getDimension().isDebugChunkCrossSections() && ((x >> 4) % getDimension().getDebugCrossSectionsMod() == 0 || (z >> 4) % getDimension().getDebugCrossSectionsMod() == 0)) { for (int i = 0; i < 16; i++) { for (int j = 0; j < 16; j++) { - blocks.set(i, 0, j, Material.CRYING_OBSIDIAN.createBlockData()); + blocks.set(i, 0, j, BukkitBlockState.of(Material.CRYING_OBSIDIAN.createBlockData())); } } } else { diff --git a/core/src/main/java/art/arcane/iris/engine/UpperDimensionContext.java b/core/src/main/java/art/arcane/iris/engine/UpperDimensionContext.java index 803eb1afd..e1f142791 100644 --- a/core/src/main/java/art/arcane/iris/engine/UpperDimensionContext.java +++ b/core/src/main/java/art/arcane/iris/engine/UpperDimensionContext.java @@ -12,9 +12,9 @@ import art.arcane.iris.util.common.data.DataProvider; import art.arcane.volmlib.util.math.M; import art.arcane.volmlib.util.math.RNG; import art.arcane.iris.util.project.interpolation.IrisInterpolation.NoiseBounds; +import art.arcane.iris.spi.PlatformBlockState; import art.arcane.iris.util.project.stream.ProceduralStream; import art.arcane.iris.util.project.stream.interpolation.Interpolated; -import org.bukkit.block.data.BlockData; import java.util.*; @@ -26,14 +26,14 @@ public class UpperDimensionContext implements DataProvider { private final ProceduralStream heightStream; private final ProceduralStream biomeStream; private final ProceduralStream regionStream; - private final ProceduralStream rockStream; + private final ProceduralStream rockStream; private final boolean selfReferencing; private UpperDimensionContext(IrisDimension dimension, IrisData data, int chunkHeight, ProceduralStream heightStream, ProceduralStream biomeStream, ProceduralStream regionStream, - ProceduralStream rockStream, + ProceduralStream rockStream, boolean selfReferencing) { this.dimension = dimension; this.data = data; @@ -227,7 +227,7 @@ public class UpperDimensionContext implements DataProvider { return Math.max(Math.min(interpolatedHeight + fluidHeight + overlayStream.get(x, z), chunkHeight), 0); }, Interpolated.DOUBLE); - ProceduralStream rockStream = upperDim.getRockPalette() + ProceduralStream rockStream = upperDim.getRockPalette() .getLayerGenerator(rng.nextParallelRNG(45), upperData).stream() .select(upperDim.getRockPalette().getBlockData(upperData)); @@ -256,7 +256,7 @@ public class UpperDimensionContext implements DataProvider { return regionStream == null ? null : regionStream.get((double) x, (double) z); } - public BlockData getRockBlock(int x, int z) { + public PlatformBlockState getRockBlock(int x, int z) { return rockStream.get((double) x, (double) z); } diff --git a/core/src/main/java/art/arcane/iris/engine/actuator/IrisBiomeActuator.java b/core/src/main/java/art/arcane/iris/engine/actuator/IrisBiomeActuator.java index 93344ab9d..9fed0ae86 100644 --- a/core/src/main/java/art/arcane/iris/engine/actuator/IrisBiomeActuator.java +++ b/core/src/main/java/art/arcane/iris/engine/actuator/IrisBiomeActuator.java @@ -31,9 +31,10 @@ import art.arcane.volmlib.util.matter.MatterBiomeInject; import art.arcane.volmlib.util.matter.slices.BiomeInjectMatter; import art.arcane.volmlib.util.scheduling.ChronoLatch; import art.arcane.volmlib.util.scheduling.PrecisionStopwatch; +import art.arcane.iris.spi.PlatformBiome; import org.bukkit.block.Biome; -public class IrisBiomeActuator extends EngineAssignedActuator { +public class IrisBiomeActuator extends EngineAssignedActuator { private final RNG rng; private final ChronoLatch cl = new ChronoLatch(5000); @@ -44,7 +45,7 @@ public class IrisBiomeActuator extends EngineAssignedActuator { @BlockCoordinates @Override - public void onActuate(int x, int z, Hunk h, boolean multicore, ChunkContext context) { + public void onActuate(int x, int z, Hunk h, boolean multicore, ChunkContext context) { try { PrecisionStopwatch p = PrecisionStopwatch.start(); for (int xf = 0; xf < h.getWidth(); xf++) { diff --git a/core/src/main/java/art/arcane/iris/engine/actuator/IrisDecorantActuator.java b/core/src/main/java/art/arcane/iris/engine/actuator/IrisDecorantActuator.java index e3faa6154..98bbe9b33 100644 --- a/core/src/main/java/art/arcane/iris/engine/actuator/IrisDecorantActuator.java +++ b/core/src/main/java/art/arcane/iris/engine/actuator/IrisDecorantActuator.java @@ -29,14 +29,21 @@ import art.arcane.volmlib.util.documentation.BlockCoordinates; import art.arcane.iris.util.project.hunk.Hunk; import art.arcane.volmlib.util.math.RNG; import art.arcane.volmlib.util.scheduling.PrecisionStopwatch; +import art.arcane.iris.spi.PlatformBlockState; import lombok.Getter; import org.bukkit.Material; import org.bukkit.block.data.BlockData; import java.util.function.Predicate; -public class IrisDecorantActuator extends EngineAssignedActuator { - private static final Predicate PREDICATE_SOLID = (b) -> b != null && !b.getMaterial().isAir() && !b.getMaterial().equals(Material.WATER) && !b.getMaterial().equals(Material.LAVA); +public class IrisDecorantActuator extends EngineAssignedActuator { + private static final Predicate PREDICATE_SOLID = (s) -> { + if (s == null) { + return false; + } + BlockData b = (BlockData) s.nativeHandle(); + return !b.getMaterial().isAir() && !b.getMaterial().equals(Material.WATER) && !b.getMaterial().equals(Material.LAVA); + }; private final RNG rng; @Getter private final EngineDecorator surfaceDecorator; @@ -63,7 +70,7 @@ public class IrisDecorantActuator extends EngineAssignedActuator { @BlockCoordinates @Override - public void onActuate(int x, int z, Hunk output, boolean multicore, ChunkContext context) { + public void onActuate(int x, int z, Hunk output, boolean multicore, ChunkContext context) { if (!getEngine().getDimension().isDecorate()) { return; } @@ -89,7 +96,7 @@ public class IrisDecorantActuator extends EngineAssignedActuator { } if (height < getDimension().getFluidHeight() && PREDICATE_SOLID.test(output.get(i, height, j)) - && height + 1 < output.getHeight() && B.isWater(output.get(i, height + 1, j))) { + && height + 1 < output.getHeight() && B.isWater(unwrap(output.get(i, height + 1, j)))) { getSeaSurfaceDecorator().decorate(i, j, realX, Math.round(i + 1), Math.round(x + i - 1), realZ, Math.round(z + j + 1), Math.round(z + j - 1), @@ -135,4 +142,8 @@ public class IrisDecorantActuator extends EngineAssignedActuator { private boolean shouldRayDecorate() { return false; // TODO CAVES } + + private static BlockData unwrap(PlatformBlockState state) { + return state == null ? null : (BlockData) state.nativeHandle(); + } } diff --git a/core/src/main/java/art/arcane/iris/engine/actuator/IrisTerrainNormalActuator.java b/core/src/main/java/art/arcane/iris/engine/actuator/IrisTerrainNormalActuator.java index 0b70ebdf2..790445067 100644 --- a/core/src/main/java/art/arcane/iris/engine/actuator/IrisTerrainNormalActuator.java +++ b/core/src/main/java/art/arcane/iris/engine/actuator/IrisTerrainNormalActuator.java @@ -33,16 +33,17 @@ import art.arcane.volmlib.util.documentation.BlockCoordinates; import art.arcane.iris.util.project.hunk.Hunk; import art.arcane.volmlib.util.math.RNG; import art.arcane.volmlib.util.scheduling.PrecisionStopwatch; +import art.arcane.iris.platform.bukkit.BukkitBlockState; +import art.arcane.iris.spi.PlatformBlockState; import lombok.Getter; import org.bukkit.Material; -import org.bukkit.block.data.BlockData; -public class IrisTerrainNormalActuator extends EngineAssignedActuator { - private static final BlockData AIR = Material.AIR.createBlockData(); - private static final BlockData BEDROCK = Material.BEDROCK.createBlockData(); - private static final BlockData LAVA = Material.LAVA.createBlockData(); - private static final BlockData GLASS = Material.GLASS.createBlockData(); - private static final BlockData CAVE_AIR = Material.CAVE_AIR.createBlockData(); +public class IrisTerrainNormalActuator extends EngineAssignedActuator { + private static final PlatformBlockState AIR = BukkitBlockState.of(Material.AIR.createBlockData()); + private static final PlatformBlockState BEDROCK = BukkitBlockState.of(Material.BEDROCK.createBlockData()); + private static final PlatformBlockState LAVA = BukkitBlockState.of(Material.LAVA.createBlockData()); + private static final PlatformBlockState GLASS = BukkitBlockState.of(Material.GLASS.createBlockData()); + private static final PlatformBlockState CAVE_AIR = BukkitBlockState.of(Material.CAVE_AIR.createBlockData()); @Getter private final RNG rng; @Getter @@ -55,7 +56,7 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator @BlockCoordinates @Override - public void onActuate(int x, int z, Hunk h, boolean multicore, ChunkContext context) { + public void onActuate(int x, int z, Hunk h, boolean multicore, ChunkContext context) { PrecisionStopwatch p = PrecisionStopwatch.start(); for (int xf = 0; xf < h.getWidth(); xf++) { @@ -78,12 +79,12 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator * @param h the blockdata */ @BlockCoordinates - public void terrainSliver(int x, int z, int xf, Hunk h, ChunkContext context) { + public void terrainSliver(int x, int z, int xf, Hunk h, ChunkContext context) { terrainSliverOptimized(x, z, xf, h, context); } @BlockCoordinates - private void terrainSliverLegacy(int x, int z, int xf, Hunk h, ChunkContext context) { + private void terrainSliverLegacy(int x, int z, int xf, Hunk h, ChunkContext context) { int zf, realX, realZ, hf, he; IrisBiome biome; IrisRegion region; @@ -101,8 +102,8 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator continue; } - KList blocks = null; - KList fblocks = null; + KList blocks = null; + KList fblocks = null; int depth, fdepth; for (int i = hf; i >= 0; i--) { if (i >= h.getHeight()) { @@ -117,7 +118,7 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator } } - BlockData ore = biome.generateOres(realX, i, realZ, rng, getData(), true); + PlatformBlockState ore = biome.generateOres(realX, i, realZ, rng, getData(), true); ore = ore == null ? region.generateOres(realX, i, realZ, rng, getData(), true) : ore; ore = ore == null ? getDimension().generateOres(realX, i, realZ, rng, getData(), true) : ore; if (ore != null) { @@ -179,9 +180,9 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator if (upperSurfaceY < chunkHeight - 1) { IrisBiome upperBiome = upperContext.getUpperBiome(realX, realZ); - BlockData upperRock = upperContext.getRockBlock(realX, realZ); + PlatformBlockState upperRock = upperContext.getRockBlock(realX, realZ); int upperThickness = chunkHeight - 1 - upperSurfaceY; - KList upperBlocks = upperBiome != null + KList upperBlocks = upperBiome != null ? upperBiome.generateLayers(upperContext.getDimension(), realX, realZ, rng, upperThickness, upperThickness, upperContext.getData(), getComplex()) @@ -205,7 +206,7 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator } @BlockCoordinates - private void terrainSliverOptimized(int x, int z, int xf, Hunk h, ChunkContext context) { + private void terrainSliverOptimized(int x, int z, int xf, Hunk h, ChunkContext context) { int chunkHeight = h.getHeight(); int chunkDepth = h.getDepth(); IrisDimension dimension = getDimension(); @@ -218,8 +219,8 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator boolean hideOres = dimension.isHideOresForHiddenOre(); ChunkedDataCache biomeCache = context.getBiome(); ChunkedDataCache regionCache = context.getRegion(); - ChunkedDataCache fluidCache = context.getFluid(); - ChunkedDataCache rockCache = context.getRock(); + ChunkedDataCache fluidCache = context.getFluid(); + ChunkedDataCache rockCache = context.getRock(); int realX = xf + x; UpperDimensionContext upperContext = getEngine().getUpperContext(); @@ -234,12 +235,12 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator } int topY = Math.min(hf, chunkHeight - 1); - BlockData fluid = fluidCache.get(xf, zf); - BlockData rock = rockCache.get(xf, zf); + PlatformBlockState fluid = fluidCache.get(xf, zf); + PlatformBlockState rock = rockCache.get(xf, zf); boolean hasSurfaceOres = !hideOres && (biome.hasSurfaceOres() || region.hasSurfaceOres() || dimension.hasSurfaceOres()); boolean hasUndergroundOres = !hideOres && (biome.hasUndergroundOres() || region.hasUndergroundOres() || dimension.hasUndergroundOres()); - KList blocks = null; - KList fblocks = null; + KList blocks = null; + KList fblocks = null; for (int i = topY; i >= 0; i--) { if (i == 0 && bedrockEnabled) { @@ -248,7 +249,7 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator continue; } - BlockData ore = null; + PlatformBlockState ore = null; if (hasSurfaceOres) { ore = biome.generateSurfaceOres(realX, i, realZ, localRng, data); ore = ore == null ? region.generateSurfaceOres(realX, i, realZ, localRng, data) : ore; @@ -305,9 +306,9 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator if (upperSurfaceY < chunkHeight - 1) { IrisBiome upperBiome = upperContext.getUpperBiome(realX, realZ); - BlockData upperRock = upperContext.getRockBlock(realX, realZ); + PlatformBlockState upperRock = upperContext.getRockBlock(realX, realZ); int upperThickness = chunkHeight - 1 - upperSurfaceY; - KList upperBlocks = upperBiome != null + KList upperBlocks = upperBiome != null ? upperBiome.generateLayers(upperContext.getDimension(), realX, realZ, localRng, upperThickness, upperThickness, upperContext.getData(), complex) diff --git a/core/src/main/java/art/arcane/iris/engine/data/chunk/LinkedTerrainChunk.java b/core/src/main/java/art/arcane/iris/engine/data/chunk/LinkedTerrainChunk.java index 1e3928166..5bf5fec02 100644 --- a/core/src/main/java/art/arcane/iris/engine/data/chunk/LinkedTerrainChunk.java +++ b/core/src/main/java/art/arcane/iris/engine/data/chunk/LinkedTerrainChunk.java @@ -18,6 +18,10 @@ package art.arcane.iris.engine.data.chunk; +import art.arcane.iris.platform.bukkit.BukkitBiome; +import art.arcane.iris.platform.bukkit.BukkitBlockState; +import art.arcane.iris.spi.PlatformBiome; +import art.arcane.iris.spi.PlatformBlockState; import art.arcane.iris.util.common.data.IrisCustomData; import org.bukkit.Bukkit; import org.bukkit.World; @@ -46,15 +50,15 @@ public class LinkedTerrainChunk implements TerrainChunk { } @Override - public Biome getBiome(int x, int y, int z) { + public PlatformBiome getBiome(int x, int y, int z) { int index = biomeIndex(x, y, z); Biome biome = biomes[index]; - return biome == null ? Biome.PLAINS : biome; + return BukkitBiome.of(biome == null ? Biome.PLAINS : biome); } @Override - public void setBiome(int x, int y, int z, Biome bio) { - biomes[biomeIndex(x, y, z)] = bio; + public void setBiome(int x, int y, int z, PlatformBiome bio) { + biomes[biomeIndex(x, y, z)] = (Biome) bio.nativeHandle(); } @Override @@ -68,7 +72,8 @@ public class LinkedTerrainChunk implements TerrainChunk { } @Override - public synchronized void setBlock(int x, int y, int z, BlockData blockData) { + public synchronized void setBlock(int x, int y, int z, PlatformBlockState state) { + BlockData blockData = (BlockData) state.nativeHandle(); if (blockData instanceof IrisCustomData data) { blockData = data.getBase(); } @@ -76,13 +81,13 @@ public class LinkedTerrainChunk implements TerrainChunk { } @Override - public synchronized void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, BlockData blockData) { - rawChunkData.setRegion(xMin, yMin, zMin, xMax, yMax, zMax, blockData); + public synchronized void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, PlatformBlockState state) { + rawChunkData.setRegion(xMin, yMin, zMin, xMax, yMax, zMax, (BlockData) state.nativeHandle()); } @Override - public BlockData getBlockData(int x, int y, int z) { - return rawChunkData.getBlockData(x, y, z); + public PlatformBlockState getBlockData(int x, int y, int z) { + return BukkitBlockState.of(rawChunkData.getBlockData(x, y, z)); } @Override diff --git a/core/src/main/java/art/arcane/iris/engine/data/chunk/TerrainChunk.java b/core/src/main/java/art/arcane/iris/engine/data/chunk/TerrainChunk.java index 8961b8db3..c4992d6fd 100644 --- a/core/src/main/java/art/arcane/iris/engine/data/chunk/TerrainChunk.java +++ b/core/src/main/java/art/arcane/iris/engine/data/chunk/TerrainChunk.java @@ -18,9 +18,9 @@ package art.arcane.iris.engine.data.chunk; +import art.arcane.iris.spi.PlatformBiome; +import art.arcane.iris.spi.PlatformBlockState; import org.bukkit.World; -import org.bukkit.block.Biome; -import org.bukkit.block.data.BlockData; import org.bukkit.generator.ChunkGenerator.ChunkData; public interface TerrainChunk { @@ -32,13 +32,13 @@ public interface TerrainChunk { return new LinkedTerrainChunk(raw); } - Biome getBiome(int x, int y, int z); + PlatformBiome getBiome(int x, int y, int z); - void setBiome(int x, int y, int z, Biome bio); + void setBiome(int x, int y, int z, PlatformBiome bio); int getMinHeight(); int getMaxHeight(); - void setBlock(int x, int y, int z, BlockData blockData); - void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, BlockData blockData); - BlockData getBlockData(int x, int y, int z); + void setBlock(int x, int y, int z, PlatformBlockState blockData); + void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, PlatformBlockState blockData); + PlatformBlockState getBlockData(int x, int y, int z); ChunkData getChunkData(); } diff --git a/core/src/main/java/art/arcane/iris/engine/decorator/DecoratorCore.java b/core/src/main/java/art/arcane/iris/engine/decorator/DecoratorCore.java index 414fdb5ea..aea7e6928 100644 --- a/core/src/main/java/art/arcane/iris/engine/decorator/DecoratorCore.java +++ b/core/src/main/java/art/arcane/iris/engine/decorator/DecoratorCore.java @@ -24,6 +24,8 @@ import art.arcane.iris.engine.mantle.EngineMantle; import art.arcane.iris.engine.object.IrisBiome; import art.arcane.iris.engine.object.IrisDecorationPart; import art.arcane.iris.engine.object.IrisDecorator; +import art.arcane.iris.platform.bukkit.BukkitBlockState; +import art.arcane.iris.spi.PlatformBlockState; import art.arcane.iris.util.common.data.B; import art.arcane.iris.util.project.hunk.Hunk; import art.arcane.volmlib.util.math.RNG; @@ -89,38 +91,40 @@ final class DecoratorCore { } static void placeSingleUp(IrisDecorator decorator, int x, int z, - int realX, int height, int realZ, Hunk data, + int realX, int height, int realZ, Hunk data, RNG rng, IrisData irisData, boolean caveSkipFluid, EngineMantle mantle) { - BlockData bd = decorator.pickBlockData(rng, irisData, realX, realZ); + PlatformBlockState bd = decorator.pickBlockData(rng, irisData, realX, realZ); if (bd == null) { return; } - if (bd instanceof Bisected) { - BlockData top = bd.clone(); + BlockData rawBd = (BlockData) bd.nativeHandle(); + if (rawBd instanceof Bisected) { + BlockData top = rawBd.clone(); ((Bisected) top).setHalf(Bisected.Half.TOP); try { - if (!caveSkipFluid || !B.isFluid(data.get(x, height + 2, z))) { - data.set(x, height + 2, z, top); + if (!caveSkipFluid || !B.isFluid(unwrap(data.get(x, height + 2, z)))) { + data.set(x, height + 2, z, BukkitBlockState.of(top)); } } catch (Throwable e) { Iris.reportError(e); } - bd = bd.clone(); - ((Bisected) bd).setHalf(Bisected.Half.BOTTOM); + BlockData bottom = rawBd.clone(); + ((Bisected) bottom).setHalf(Bisected.Half.BOTTOM); + bd = BukkitBlockState.of(bottom); } - if (B.isAir(data.get(x, height + 1, z))) { + if (B.isAir(unwrap(data.get(x, height + 1, z)))) { data.set(x, height + 1, z, fixFacesForHunk(bd, data, x, z, realX, height + 1, realZ, mantle)); } } static void placeSurfaceSingle(IrisDecorator decorator, int x, int z, int realX, int height, int realZ, - Hunk data, RNG rng, IrisData irisData, + Hunk data, RNG rng, IrisData irisData, boolean underwater, boolean caveSkipFluid, EngineMantle mantle) { - BlockData bdx = data.get(x, height, z); - BlockData bd = decorator.pickBlockData(rng, irisData, realX, realZ); + PlatformBlockState bdx = data.get(x, height, z); + PlatformBlockState bd = decorator.pickBlockData(rng, irisData, realX, realZ); if (!underwater && !canGoOn(bd, bdx) && !decorator.isForcePlace() && decorator.getForceBlock() == null) { @@ -128,7 +132,7 @@ final class DecoratorCore { } if (decorator.getForceBlock() != null) { - if (caveSkipFluid && B.isFluid(bdx)) { + if (caveSkipFluid && B.isFluid(unwrap(bdx))) { return; } data.set(x, height, z, fixFacesForHunk( @@ -147,29 +151,31 @@ final class DecoratorCore { } } - if (bd instanceof Bisected) { - BlockData top = bd.clone(); + BlockData rawBd = bd == null ? null : (BlockData) bd.nativeHandle(); + if (rawBd instanceof Bisected) { + BlockData top = rawBd.clone(); ((Bisected) top).setHalf(Bisected.Half.TOP); try { - if (!caveSkipFluid || !B.isFluid(data.get(x, height + 2, z))) { - data.set(x, height + 2, z, top); + if (!caveSkipFluid || !B.isFluid(unwrap(data.get(x, height + 2, z)))) { + data.set(x, height + 2, z, BukkitBlockState.of(top)); } } catch (Throwable e) { Iris.reportError(e); } - bd = bd.clone(); - ((Bisected) bd).setHalf(Bisected.Half.BOTTOM); + BlockData bottom = rawBd.clone(); + ((Bisected) bottom).setHalf(Bisected.Half.BOTTOM); + bd = BukkitBlockState.of(bottom); } - if (B.isAir(data.get(x, height + 1, z))) { + if (B.isAir(unwrap(data.get(x, height + 1, z)))) { data.set(x, height + 1, z, fixFacesForHunk(bd, data, x, z, realX, height + 1, realZ, mantle)); } } static void placeSingleAt(IrisDecorator decorator, int x, int z, - int realX, int height, int realZ, Hunk data, + int realX, int height, int realZ, Hunk data, RNG rng, IrisData irisData, boolean applyFixFaces, EngineMantle mantle) { - BlockData bd = decorator.pickBlockData(rng, irisData, realX, realZ); + PlatformBlockState bd = decorator.pickBlockData(rng, irisData, realX, realZ); if (bd == null) { return; } @@ -180,7 +186,7 @@ final class DecoratorCore { } static void placeStackUp(IrisDecorator decorator, int x, int z, int realX, int realZ, - int height, int max, Hunk data, + int height, int max, Hunk data, RNG rng, IrisData irisData, PlaceOpts opts) { int effectiveMax = max; if (opts.underwater && height < opts.fluidHeight) { @@ -190,19 +196,19 @@ final class DecoratorCore { int stack = computeStack(decorator, rng, realX, realZ, irisData, effectiveMax); if (stack == 1) { - if (opts.caveSkipFluid && B.isFluid(data.get(x, height, z))) { + if (opts.caveSkipFluid && B.isFluid(unwrap(data.get(x, height, z)))) { return; } data.set(x, height, z, decorator.pickBlockDataTop(rng, irisData, realX, realZ)); return; } - BlockData bdx = data.get(x, height, z); + PlatformBlockState bdx = data.get(x, height, z); for (int i = 0; i < stack; i++) { int h = height + i; double threshold = ((double) i) / (stack - 1); - BlockData bd = threshold >= decorator.getTopThreshold() + PlatformBlockState bd = threshold >= decorator.getTopThreshold() ? decorator.pickBlockDataTop(rng, irisData, realX, realZ) : decorator.pickBlockData(rng, irisData, realX, realZ); @@ -218,12 +224,12 @@ final class DecoratorCore { break; } - if (opts.caveSkipFluid && B.isFluid(data.get(x, height + 1 + i, z))) { + if (opts.caveSkipFluid && B.isFluid(unwrap(data.get(x, height + 1 + i, z)))) { break; } - if (bd instanceof PointedDripstone) { - bd = dripstoneBlock(stack, i, BlockFace.UP); + if (bd.nativeHandle() instanceof PointedDripstone) { + bd = BukkitBlockState.of(dripstoneBlock(stack, i, BlockFace.UP)); } data.set(x, height + 1 + i, z, bd); @@ -231,12 +237,12 @@ final class DecoratorCore { } static void placeStackDown(IrisDecorator decorator, int x, int z, int realX, int realZ, - int height, int minHeight, Hunk data, + int height, int minHeight, Hunk data, RNG rng, IrisData irisData, int max, PlaceOpts opts, EngineMantle mantle) { int stack = computeStack(decorator, rng, realX, realZ, irisData, max); if (stack == 1) { - if (opts.caveSkipFluid && B.isFluid(data.get(x, height, z))) { + if (opts.caveSkipFluid && B.isFluid(unwrap(data.get(x, height, z)))) { return; } data.set(x, height, z, fixFacesForHunk( @@ -252,15 +258,15 @@ final class DecoratorCore { } double threshold = ((double) i) / (double) (stack - 1); - BlockData bd = threshold >= decorator.getTopThreshold() + PlatformBlockState bd = threshold >= decorator.getTopThreshold() ? decorator.pickBlockDataTop(rng, irisData, realX, realZ) : decorator.pickBlockData(rng, irisData, realX, realZ); - if (bd instanceof PointedDripstone) { - bd = dripstoneBlock(stack, i, BlockFace.DOWN); + if (bd != null && bd.nativeHandle() instanceof PointedDripstone) { + bd = BukkitBlockState.of(dripstoneBlock(stack, i, BlockFace.DOWN)); } - if (opts.caveSkipFluid && B.isFluid(data.get(x, h, z))) { + if (opts.caveSkipFluid && B.isFluid(unwrap(data.get(x, h, z)))) { break; } data.set(x, h, z, fixFacesForHunk(bd, data, x, z, realX, h, realZ, mantle)); @@ -269,25 +275,27 @@ final class DecoratorCore { static void placeFloatingSimple(IrisDecorator decorator, int xf, int zf, int realX, int realZ, - int height, int max, Hunk data, + int height, int max, Hunk data, RNG rng, IrisData irisData) { - BlockData bd = decorator.pickBlockData(rng, irisData, realX, realZ); + PlatformBlockState bd = decorator.pickBlockData(rng, irisData, realX, realZ); if (bd == null) { return; } - if (bd instanceof Bisected) { - BlockData top = bd.clone(); + BlockData rawBd = (BlockData) bd.nativeHandle(); + if (rawBd instanceof Bisected) { + BlockData top = rawBd.clone(); ((Bisected) top).setHalf(Bisected.Half.TOP); try { if (max > 2) { - data.set(xf, height + 2, zf, top); + data.set(xf, height + 2, zf, BukkitBlockState.of(top)); } } catch (Throwable e) { Iris.reportError(e); } - bd = bd.clone(); - ((Bisected) bd).setHalf(Bisected.Half.BOTTOM); + BlockData bottom = rawBd.clone(); + ((Bisected) bottom).setHalf(Bisected.Half.BOTTOM); + bd = BukkitBlockState.of(bottom); } if (max > 1) { @@ -297,7 +305,7 @@ final class DecoratorCore { static int placeFloatingStacked(IrisDecorator decorator, int xf, int zf, int realX, int realZ, - int height, int max, Hunk data, + int height, int max, Hunk data, RNG rng, IrisData irisData) { int stack = decorator.getHeight(rng, realX, realZ, irisData); if (decorator.isScaleStack()) { @@ -313,7 +321,7 @@ final class DecoratorCore { break; } double threshold = stack == 1 ? 0.0 : ((double) i) / (stack - 1); - BlockData bd = threshold >= decorator.getTopThreshold() + PlatformBlockState bd = threshold >= decorator.getTopThreshold() ? decorator.pickBlockDataTop(rng, irisData, realX, realZ) : decorator.pickBlockData(rng, irisData, realX, realZ); if (bd == null) { @@ -325,12 +333,13 @@ final class DecoratorCore { return placed; } - static BlockData fixFacesForHunk(BlockData b, Hunk hunk, int rX, int rZ, - int x, int y, int z, EngineMantle mantle) { - if (!B.isVineBlock(b)) { + static PlatformBlockState fixFacesForHunk(PlatformBlockState b, Hunk hunk, int rX, int rZ, + int x, int y, int z, EngineMantle mantle) { + BlockData rawB = unwrap(b); + if (!B.isVineBlock(rawB)) { return b; } - MultipleFacing data = (MultipleFacing) b.clone(); + MultipleFacing data = (MultipleFacing) rawB.clone(); data.getFaces().forEach(f -> data.setFace(f, false)); boolean found = false; @@ -345,7 +354,7 @@ final class DecoratorCore { r = mantle.getMantle().get(x + f.getModX(), yy, z + f.getModZ(), BlockData.class); } if (r == null) { - r = EngineMantle.AIR; + r = (BlockData) EngineMantle.AIR.nativeHandle(); } if (r.isFaceSturdy(f.getOppositeFace(), BlockSupport.FULL)) { if (data.getAllowedFaces().contains(f)) { @@ -361,7 +370,7 @@ final class DecoratorCore { continue; } - r = hunk.get(xx, yy, zz); + r = unwrap(hunk.get(xx, yy, zz)); if (r.isFaceSturdy(f.getOppositeFace(), BlockSupport.FULL)) { if (data.getAllowedFaces().contains(f)) { found = true; @@ -375,11 +384,15 @@ final class DecoratorCore { data.setFace(fallback, true); } } - return data; + return BukkitBlockState.of(data); } - static boolean canGoOn(BlockData decorator, BlockData surface) { - return surface.isFaceSturdy(BlockFace.UP, BlockSupport.FULL); + static boolean canGoOn(PlatformBlockState decorator, PlatformBlockState surface) { + return ((BlockData) surface.nativeHandle()).isFaceSturdy(BlockFace.UP, BlockSupport.FULL); + } + + private static BlockData unwrap(PlatformBlockState state) { + return state == null ? null : (BlockData) state.nativeHandle(); } private static int computeStack(IrisDecorator decorator, RNG rng, double realX, double realZ, diff --git a/core/src/main/java/art/arcane/iris/engine/decorator/FloatingDecorator.java b/core/src/main/java/art/arcane/iris/engine/decorator/FloatingDecorator.java index c66372ac8..760fed42b 100644 --- a/core/src/main/java/art/arcane/iris/engine/decorator/FloatingDecorator.java +++ b/core/src/main/java/art/arcane/iris/engine/decorator/FloatingDecorator.java @@ -24,7 +24,7 @@ import art.arcane.iris.engine.object.IrisDecorationPart; import art.arcane.iris.engine.object.IrisDecorator; import art.arcane.iris.util.project.hunk.Hunk; import art.arcane.volmlib.util.math.RNG; -import org.bukkit.block.data.BlockData; +import art.arcane.iris.spi.PlatformBlockState; /* * Floating island decoration path. Bypasses all canGoOn, slope, whitelist, and blacklist @@ -35,7 +35,7 @@ public class FloatingDecorator { public static int decorateColumn(Engine engine, IrisBiome target, IrisDecorationPart part, int xf, int zf, int realX, int realZ, - int height, int max, Hunk data, RNG rng, + int height, int max, Hunk data, RNG rng, Runnable candidatesNullCallback) { RNG gRNG = new RNG(DecoratorCore.partSeed(engine.getSeedManager().getDecorator(), part)); IrisDecorator decorator = DecoratorCore.pickDecorator(target, part, gRNG, rng, engine.getData(), realX, realZ); diff --git a/core/src/main/java/art/arcane/iris/engine/decorator/IrisCeilingDecorator.java b/core/src/main/java/art/arcane/iris/engine/decorator/IrisCeilingDecorator.java index 39fd497c4..897e88620 100644 --- a/core/src/main/java/art/arcane/iris/engine/decorator/IrisCeilingDecorator.java +++ b/core/src/main/java/art/arcane/iris/engine/decorator/IrisCeilingDecorator.java @@ -27,6 +27,7 @@ import art.arcane.iris.util.common.data.B; import art.arcane.iris.util.project.hunk.Hunk; import art.arcane.volmlib.util.documentation.BlockCoordinates; import art.arcane.volmlib.util.math.RNG; +import art.arcane.iris.spi.PlatformBlockState; import org.bukkit.block.data.BlockData; public class IrisCeilingDecorator extends IrisEngineDecorator { @@ -40,7 +41,7 @@ public class IrisCeilingDecorator extends IrisEngineDecorator { @BlockCoordinates @Override public void decorate(int x, int z, int realX, int realX1, int realX_1, int realZ, int realZ1, int realZ_1, - Hunk data, IrisBiome biome, int height, int max) { + Hunk data, IrisBiome biome, int height, int max) { boolean caveSkipFluid = biome.getInferredType() == InferredType.CAVE; RNG rng = getRNG(realX, realZ); IrisDecorator decorator = DecoratorCore.pickDecorator(biome, getPart(), partRNG, rng, getData(), realX, realZ); @@ -50,8 +51,11 @@ public class IrisCeilingDecorator extends IrisEngineDecorator { } if (!decorator.isStacking()) { - if (caveSkipFluid && B.isFluid(data.get(x, height, z))) { - return; + if (caveSkipFluid) { + PlatformBlockState state = data.get(x, height, z); + if (B.isFluid(state == null ? null : (BlockData) state.nativeHandle())) { + return; + } } DecoratorCore.placeSingleAt(decorator, x, z, realX, height, realZ, data, rng, getData(), true, getEngine().getMantle()); return; diff --git a/core/src/main/java/art/arcane/iris/engine/decorator/IrisSeaFloorDecorator.java b/core/src/main/java/art/arcane/iris/engine/decorator/IrisSeaFloorDecorator.java index c929e162b..5a9c63894 100644 --- a/core/src/main/java/art/arcane/iris/engine/decorator/IrisSeaFloorDecorator.java +++ b/core/src/main/java/art/arcane/iris/engine/decorator/IrisSeaFloorDecorator.java @@ -25,7 +25,7 @@ import art.arcane.iris.engine.object.IrisDecorator; import art.arcane.iris.util.project.hunk.Hunk; import art.arcane.volmlib.util.documentation.BlockCoordinates; import art.arcane.volmlib.util.math.RNG; -import org.bukkit.block.data.BlockData; +import art.arcane.iris.spi.PlatformBlockState; public class IrisSeaFloorDecorator extends IrisEngineDecorator { private final RNG partRNG; @@ -38,7 +38,7 @@ public class IrisSeaFloorDecorator extends IrisEngineDecorator { @BlockCoordinates @Override public void decorate(int x, int z, int realX, int realX1, int realX_1, int realZ, int realZ1, int realZ_1, - Hunk data, IrisBiome biome, int height, int max) { + Hunk data, IrisBiome biome, int height, int max) { RNG rng = getRNG(realX, realZ); IrisDecorator decorator = DecoratorCore.pickDecorator(biome, getPart(), partRNG, rng, getData(), realX, realZ); diff --git a/core/src/main/java/art/arcane/iris/engine/decorator/IrisSeaSurfaceDecorator.java b/core/src/main/java/art/arcane/iris/engine/decorator/IrisSeaSurfaceDecorator.java index c82145768..5968cb894 100644 --- a/core/src/main/java/art/arcane/iris/engine/decorator/IrisSeaSurfaceDecorator.java +++ b/core/src/main/java/art/arcane/iris/engine/decorator/IrisSeaSurfaceDecorator.java @@ -25,7 +25,7 @@ import art.arcane.iris.engine.object.IrisDecorator; import art.arcane.iris.util.project.hunk.Hunk; import art.arcane.volmlib.util.documentation.BlockCoordinates; import art.arcane.volmlib.util.math.RNG; -import org.bukkit.block.data.BlockData; +import art.arcane.iris.spi.PlatformBlockState; public class IrisSeaSurfaceDecorator extends IrisEngineDecorator { private final RNG partRNG; @@ -38,7 +38,7 @@ public class IrisSeaSurfaceDecorator extends IrisEngineDecorator { @BlockCoordinates @Override public void decorate(int x, int z, int realX, int realX1, int realX_1, int realZ, int realZ1, int realZ_1, - Hunk data, IrisBiome biome, int height, int max) { + Hunk data, IrisBiome biome, int height, int max) { RNG rng = getRNG(realX, realZ); IrisDecorator decorator = DecoratorCore.pickDecorator(biome, getPart(), partRNG, rng, getData(), realX, realZ); diff --git a/core/src/main/java/art/arcane/iris/engine/decorator/IrisShoreLineDecorator.java b/core/src/main/java/art/arcane/iris/engine/decorator/IrisShoreLineDecorator.java index 38e6fdeea..d045b12b0 100644 --- a/core/src/main/java/art/arcane/iris/engine/decorator/IrisShoreLineDecorator.java +++ b/core/src/main/java/art/arcane/iris/engine/decorator/IrisShoreLineDecorator.java @@ -26,7 +26,7 @@ import art.arcane.iris.util.project.hunk.Hunk; import art.arcane.iris.util.project.stream.ProceduralStream; import art.arcane.volmlib.util.documentation.BlockCoordinates; import art.arcane.volmlib.util.math.RNG; -import org.bukkit.block.data.BlockData; +import art.arcane.iris.spi.PlatformBlockState; public class IrisShoreLineDecorator extends IrisEngineDecorator { private final RNG partRNG; @@ -39,7 +39,7 @@ public class IrisShoreLineDecorator extends IrisEngineDecorator { @BlockCoordinates @Override public void decorate(int x, int z, int realX, int realX1, int realX_1, int realZ, int realZ1, int realZ_1, - Hunk data, IrisBiome biome, int height, int max) { + Hunk data, IrisBiome biome, int height, int max) { if (height != getDimension().getFluidHeight()) { return; } diff --git a/core/src/main/java/art/arcane/iris/engine/decorator/IrisSurfaceDecorator.java b/core/src/main/java/art/arcane/iris/engine/decorator/IrisSurfaceDecorator.java index abe2a098b..534f1317e 100644 --- a/core/src/main/java/art/arcane/iris/engine/decorator/IrisSurfaceDecorator.java +++ b/core/src/main/java/art/arcane/iris/engine/decorator/IrisSurfaceDecorator.java @@ -26,7 +26,7 @@ import art.arcane.iris.engine.object.IrisDecorator; import art.arcane.iris.util.project.hunk.Hunk; import art.arcane.volmlib.util.documentation.BlockCoordinates; import art.arcane.volmlib.util.math.RNG; -import org.bukkit.block.data.BlockData; +import art.arcane.iris.spi.PlatformBlockState; public class IrisSurfaceDecorator extends IrisEngineDecorator { private final RNG partRNG; @@ -51,7 +51,7 @@ public class IrisSurfaceDecorator extends IrisEngineDecorator { @BlockCoordinates @Override public void decorate(int x, int z, int realX, int realX1, int realX_1, int realZ, int realZ1, int realZ_1, - Hunk data, IrisBiome biome, int height, int max) { + Hunk data, IrisBiome biome, int height, int max) { int fluidHeight = getDimension().getFluidHeight(); if (biome.getInferredType().equals(InferredType.SHORE) && height < fluidHeight) { return; diff --git a/core/src/main/java/art/arcane/iris/engine/framework/BlockUpdater.java b/core/src/main/java/art/arcane/iris/engine/framework/BlockUpdater.java index 33dcaea10..7d6d1aa03 100644 --- a/core/src/main/java/art/arcane/iris/engine/framework/BlockUpdater.java +++ b/core/src/main/java/art/arcane/iris/engine/framework/BlockUpdater.java @@ -18,15 +18,15 @@ package art.arcane.iris.engine.framework; +import art.arcane.iris.spi.PlatformBlockState; import art.arcane.volmlib.util.mantle.runtime.MantleChunk; import art.arcane.volmlib.util.math.RNG; import art.arcane.volmlib.util.matter.Matter; import org.bukkit.Chunk; -import org.bukkit.block.data.BlockData; public interface BlockUpdater { - void catchBlockUpdates(int x, int y, int z, BlockData data); + void catchBlockUpdates(int x, int y, int z, PlatformBlockState data); void updateChunk(Chunk c); diff --git a/core/src/main/java/art/arcane/iris/engine/framework/Engine.java b/core/src/main/java/art/arcane/iris/engine/framework/Engine.java index 791c5627f..d7763109f 100644 --- a/core/src/main/java/art/arcane/iris/engine/framework/Engine.java +++ b/core/src/main/java/art/arcane/iris/engine/framework/Engine.java @@ -37,6 +37,9 @@ import art.arcane.iris.engine.data.cache.Cache; import art.arcane.iris.engine.data.chunk.TerrainChunk; import art.arcane.iris.engine.mantle.EngineMantle; import art.arcane.iris.engine.object.*; +import art.arcane.iris.platform.bukkit.BukkitBlockState; +import art.arcane.iris.spi.PlatformBiome; +import art.arcane.iris.spi.PlatformBlockState; import art.arcane.iris.util.project.matter.TileWrapper; import art.arcane.volmlib.util.collection.KList; import art.arcane.volmlib.util.collection.KMap; @@ -69,7 +72,6 @@ import art.arcane.volmlib.util.scheduling.PrecisionStopwatch; import art.arcane.iris.util.project.stream.ProceduralStream; import io.papermc.lib.PaperLib; import org.bukkit.*; -import org.bukkit.block.Biome; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.block.data.BlockData; @@ -178,7 +180,7 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat } @BlockCoordinates - void generate(int x, int z, Hunk blocks, Hunk biomes, boolean multicore) throws WrongEngineBroException; + void generate(int x, int z, Hunk blocks, Hunk biomes, boolean multicore) throws WrongEngineBroException; EngineMetrics getMetrics(); @@ -315,15 +317,16 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat @BlockCoordinates @Override - default void catchBlockUpdates(int x, int y, int z, BlockData data) { + default void catchBlockUpdates(int x, int y, int z, PlatformBlockState data) { if (data == null) { return; } - if (B.isUpdatable(data)) { + BlockData blockData = (BlockData) data.nativeHandle(); + if (B.isUpdatable(blockData)) { getMantle().updateBlock(x, y, z); } - if (data instanceof IrisCustomData) { + if (blockData instanceof IrisCustomData) { getMantle().getMantle().flag(x >> 4, z >> 4, MantleFlag.CUSTOM_ACTIVE, true); } } @@ -601,7 +604,7 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat PlacedObject po = getObjectPlacement(rx, ry, rz, mc); if (po != null && po.getPlacement() != null) { if (B.isStorageChest(b.getBlockData())) { - IrisLootTable table = po.getPlacement().getTable(b.getBlockData(), getData()); + IrisLootTable table = po.getPlacement().getTable(BukkitBlockState.of(b.getBlockData()), getData()); if (table != null) { tables.add(table); if (po.getPlacement().isOverrideGlobalLoot()) { diff --git a/core/src/main/java/art/arcane/iris/engine/framework/EngineDecorator.java b/core/src/main/java/art/arcane/iris/engine/framework/EngineDecorator.java index aa5ebd9c5..3c3fb10f3 100644 --- a/core/src/main/java/art/arcane/iris/engine/framework/EngineDecorator.java +++ b/core/src/main/java/art/arcane/iris/engine/framework/EngineDecorator.java @@ -19,6 +19,7 @@ package art.arcane.iris.engine.framework; import art.arcane.iris.engine.object.IrisBiome; +import art.arcane.iris.spi.PlatformBlockState; import art.arcane.iris.util.common.data.B; import art.arcane.volmlib.util.documentation.BlockCoordinates; import art.arcane.iris.util.project.hunk.Hunk; @@ -27,19 +28,19 @@ import org.bukkit.block.data.BlockData; public interface EngineDecorator extends EngineComponent { @BlockCoordinates - void decorate(int x, int z, int realX, int realX1, int realX_1, int realZ, int realZ1, int realZ_1, Hunk data, IrisBiome biome, int height, int max); + void decorate(int x, int z, int realX, int realX1, int realX_1, int realZ, int realZ1, int realZ_1, Hunk data, IrisBiome biome, int height, int max); @BlockCoordinates - default void decorate(int x, int z, int realX, int realZ, Hunk data, IrisBiome biome, int height, int max) { + default void decorate(int x, int z, int realX, int realZ, Hunk data, IrisBiome biome, int height, int max) { decorate(x, z, realX, realX, realX, realZ, realZ, realZ, data, biome, height, max); } @SuppressWarnings("BooleanMethodIsAlwaysInverted") - default boolean canGoOn(BlockData decorant, BlockData atop) { - if (atop == null || B.isAir(atop)) { + default boolean canGoOn(PlatformBlockState decorant, PlatformBlockState atop) { + if (atop == null || atop.isAir()) { return false; } - return B.canPlaceOnto(decorant.getMaterial(), atop.getMaterial()); + return B.canPlaceOnto(((BlockData) decorant.nativeHandle()).getMaterial(), ((BlockData) atop.nativeHandle()).getMaterial()); } } diff --git a/core/src/main/java/art/arcane/iris/engine/framework/EngineMode.java b/core/src/main/java/art/arcane/iris/engine/framework/EngineMode.java index c82705632..4f0f575d9 100644 --- a/core/src/main/java/art/arcane/iris/engine/framework/EngineMode.java +++ b/core/src/main/java/art/arcane/iris/engine/framework/EngineMode.java @@ -29,9 +29,9 @@ import art.arcane.iris.util.project.hunk.Hunk; import art.arcane.volmlib.util.math.RollingSequence; import art.arcane.iris.util.common.parallel.BurstExecutor; import art.arcane.iris.util.common.parallel.MultiBurst; +import art.arcane.iris.spi.PlatformBiome; +import art.arcane.iris.spi.PlatformBlockState; import art.arcane.iris.util.common.scheduling.J; -import org.bukkit.block.Biome; -import org.bukkit.block.data.BlockData; public interface EngineMode extends Staged { RollingSequence r = new RollingSequence(64); @@ -71,7 +71,7 @@ public interface EngineMode extends Staged { } @BlockCoordinates - default void generate(int x, int z, Hunk blocks, Hunk biomes, boolean multicore) { + default void generate(int x, int z, Hunk blocks, Hunk biomes, boolean multicore) { IrisContext context = IrisContext.getOr(getEngine()); boolean cacheContext = true; if (J.isFolia()) { diff --git a/core/src/main/java/art/arcane/iris/engine/framework/EngineStage.java b/core/src/main/java/art/arcane/iris/engine/framework/EngineStage.java index aba9e22eb..1f7735288 100644 --- a/core/src/main/java/art/arcane/iris/engine/framework/EngineStage.java +++ b/core/src/main/java/art/arcane/iris/engine/framework/EngineStage.java @@ -18,15 +18,15 @@ package art.arcane.iris.engine.framework; +import art.arcane.iris.spi.PlatformBiome; +import art.arcane.iris.spi.PlatformBlockState; import art.arcane.iris.util.project.context.ChunkContext; import art.arcane.volmlib.util.documentation.BlockCoordinates; import art.arcane.iris.util.project.hunk.Hunk; -import org.bukkit.block.Biome; -import org.bukkit.block.data.BlockData; public interface EngineStage { @BlockCoordinates - void generate(int x, int z, Hunk blocks, Hunk biomes, boolean multicore, ChunkContext context); + void generate(int x, int z, Hunk blocks, Hunk biomes, boolean multicore, ChunkContext context); default void close() { if (this instanceof EngineComponent c) { diff --git a/core/src/main/java/art/arcane/iris/engine/framework/PregeneratedData.java b/core/src/main/java/art/arcane/iris/engine/framework/PregeneratedData.java index dfee059e3..5ba70919d 100644 --- a/core/src/main/java/art/arcane/iris/engine/framework/PregeneratedData.java +++ b/core/src/main/java/art/arcane/iris/engine/framework/PregeneratedData.java @@ -19,26 +19,27 @@ package art.arcane.iris.engine.framework; import art.arcane.iris.engine.data.chunk.TerrainChunk; +import art.arcane.iris.spi.PlatformBiome; +import art.arcane.iris.spi.PlatformBlockState; import art.arcane.iris.util.common.data.B; import art.arcane.iris.util.project.hunk.Hunk; import lombok.Data; -import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; import java.util.concurrent.atomic.AtomicBoolean; @Data public class PregeneratedData { - private final Hunk blocks; - private final Hunk post; - private final Hunk biomes; + private final Hunk blocks; + private final Hunk post; + private final Hunk biomes; private final AtomicBoolean postMod; public PregeneratedData(int height) { postMod = new AtomicBoolean(false); blocks = Hunk.newAtomicHunk(16, height, 16); biomes = Hunk.newAtomicHunk(16, height, 16); - Hunk p = Hunk.newMappedHunkSynced(16, height, 16); + Hunk p = Hunk.newMappedHunkSynced(16, height, 16); post = p.trackWrite(postMod); } @@ -48,14 +49,14 @@ public class PregeneratedData { tc.setBlock(x, y, z, b); } - Biome bf = biomes.get(x, y, z); + PlatformBiome bf = biomes.get(x, y, z); if (bf != null) { tc.setBiome(x, y, z, bf); } }); if (postMod.get()) { - return () -> Hunk.view(tc).insertSoftly(0, 0, 0, post, (b) -> b == null || B.isAirOrFluid(b)); + return () -> Hunk.view(tc).insertSoftly(0, 0, 0, post, (b) -> b == null || B.isAirOrFluid((BlockData) b.nativeHandle())); } return () -> { diff --git a/core/src/main/java/art/arcane/iris/engine/framework/placer/HeightmapObjectPlacer.java b/core/src/main/java/art/arcane/iris/engine/framework/placer/HeightmapObjectPlacer.java index 7e183f180..20663484e 100644 --- a/core/src/main/java/art/arcane/iris/engine/framework/placer/HeightmapObjectPlacer.java +++ b/core/src/main/java/art/arcane/iris/engine/framework/placer/HeightmapObjectPlacer.java @@ -23,8 +23,8 @@ import art.arcane.iris.engine.framework.Engine; import art.arcane.iris.engine.object.IObjectPlacer; import art.arcane.iris.engine.object.IrisObjectPlacement; import art.arcane.iris.engine.object.TileData; +import art.arcane.iris.spi.PlatformBlockState; import art.arcane.volmlib.util.math.RNG; -import org.bukkit.block.data.BlockData; public class HeightmapObjectPlacer implements IObjectPlacer { private final long s; @@ -45,11 +45,11 @@ public class HeightmapObjectPlacer implements IObjectPlacer { return (int) Math.round(config.getHeightmap().getNoise(this.s, param1Int1, param1Int2, data)); } - public void set(int param1Int1, int param1Int2, int param1Int3, BlockData param1BlockData) { + public void set(int param1Int1, int param1Int2, int param1Int3, PlatformBlockState param1BlockData) { oplacer.set(param1Int1, param1Int2, param1Int3, param1BlockData); } - public BlockData get(int param1Int1, int param1Int2, int param1Int3) { + public PlatformBlockState get(int param1Int1, int param1Int2, int param1Int3) { return oplacer.get(param1Int1, param1Int2, param1Int3); } diff --git a/core/src/main/java/art/arcane/iris/engine/framework/placer/WorldObjectPlacer.java b/core/src/main/java/art/arcane/iris/engine/framework/placer/WorldObjectPlacer.java index fbc67d2cc..c5f10b7db 100644 --- a/core/src/main/java/art/arcane/iris/engine/framework/placer/WorldObjectPlacer.java +++ b/core/src/main/java/art/arcane/iris/engine/framework/placer/WorldObjectPlacer.java @@ -11,6 +11,8 @@ import art.arcane.iris.engine.object.IObjectPlacer; import art.arcane.iris.engine.object.InventorySlotType; import art.arcane.iris.engine.object.IrisLootTable; import art.arcane.iris.engine.object.TileData; +import art.arcane.iris.platform.bukkit.BukkitBlockState; +import art.arcane.iris.spi.PlatformBlockState; import art.arcane.volmlib.util.collection.KList; import art.arcane.iris.util.common.data.B; import art.arcane.iris.util.common.data.IrisCustomData; @@ -51,7 +53,8 @@ public class WorldObjectPlacer implements IObjectPlacer { } @Override - public void set(int x, int y, int z, BlockData d) { + public void set(int x, int y, int z, PlatformBlockState state) { + BlockData d = (BlockData) state.nativeHandle(); Block block = world.getBlockAt(x, y + world.getMinHeight(), z); if (y <= world.getMinHeight() || block.getType() == Material.BEDROCK) return; @@ -87,8 +90,8 @@ public class WorldObjectPlacer implements IObjectPlacer { } @Override - public BlockData get(int x, int y, int z) { - return world.getBlockAt(x, y + world.getMinHeight(), z).getBlockData(); + public PlatformBlockState get(int x, int y, int z) { + return BukkitBlockState.of(world.getBlockAt(x, y + world.getMinHeight(), z).getBlockData()); } @Override diff --git a/core/src/main/java/art/arcane/iris/engine/mantle/EngineMantle.java b/core/src/main/java/art/arcane/iris/engine/mantle/EngineMantle.java index ed54db7af..a194f7d2c 100644 --- a/core/src/main/java/art/arcane/iris/engine/mantle/EngineMantle.java +++ b/core/src/main/java/art/arcane/iris/engine/mantle/EngineMantle.java @@ -45,6 +45,8 @@ import art.arcane.volmlib.util.matter.Matter; import art.arcane.volmlib.util.matter.slices.UpdateMatter; import art.arcane.iris.util.common.parallel.MultiBurst; import art.arcane.iris.util.common.scheduling.J; +import art.arcane.iris.platform.bukkit.BukkitBlockState; +import art.arcane.iris.spi.PlatformBlockState; import org.bukkit.World; import org.bukkit.block.data.BlockData; import org.jetbrains.annotations.UnmodifiableView; @@ -54,7 +56,7 @@ import java.util.Map; import java.util.concurrent.TimeUnit; public interface EngineMantle extends MatterGenerator { - BlockData AIR = B.get("AIR"); + PlatformBlockState AIR = B.getState("AIR"); Mantle getMantle(); @@ -120,11 +122,11 @@ public interface EngineMantle extends MatterGenerator { return getMantle().get(x, h, z, MatterCavern.class) != null; } - default BlockData get(int x, int y, int z) { + default PlatformBlockState get(int x, int y, int z) { BlockData block = getMantle().get(x, y, z, BlockData.class); if (block == null) return AIR; - return block; + return BukkitBlockState.of(block); } default boolean isPreventingDecay() { @@ -187,7 +189,7 @@ public interface EngineMantle extends MatterGenerator { } @ChunkCoordinates - default void insertMatter(int x, int z, Class t, Hunk blocks, boolean multicore) { + default void insertMatter(int x, int z, Class t, Hunk blocks, boolean multicore) { if (!getEngine().getDimension().isUseMantle()) { return; } @@ -214,11 +216,11 @@ public interface EngineMantle extends MatterGenerator { chunk.iterate(t, (lx, y, lz, value) -> { int colIdx = (lx << 4) | (lz & 15); if (y < upperYs[colIdx]) { - blocks.set(lx, y, lz, value); + blocks.set(lx, y, lz, BukkitBlockState.of(value)); } }); } else { - chunk.iterate(t, blocks::set); + chunk.iterate(t, (lx, y, lz, value) -> blocks.set(lx, y, lz, BukkitBlockState.of(value))); } } finally { chunk.release(); diff --git a/core/src/main/java/art/arcane/iris/engine/mantle/MantleWriter.java b/core/src/main/java/art/arcane/iris/engine/mantle/MantleWriter.java index 03a3e81d8..11dec4f2a 100644 --- a/core/src/main/java/art/arcane/iris/engine/mantle/MantleWriter.java +++ b/core/src/main/java/art/arcane/iris/engine/mantle/MantleWriter.java @@ -45,6 +45,8 @@ import art.arcane.iris.util.project.noise.CNG; import art.arcane.iris.util.common.scheduling.J; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import lombok.Data; +import art.arcane.iris.platform.bukkit.BukkitBlockState; +import art.arcane.iris.spi.PlatformBlockState; import org.bukkit.block.data.BlockData; import org.bukkit.util.Vector; @@ -266,7 +268,11 @@ public class MantleWriter implements IObjectPlacer, AutoCloseable { } @Override - public void set(int x, int y, int z, BlockData d) { + public void set(int x, int y, int z, PlatformBlockState s) { + if (s == null) { + return; + } + BlockData d = (BlockData) s.nativeHandle(); if (d instanceof IrisCustomData data) { setData(x, y, z, data.getBase()); setData(x, y, z, data.getCustom()); @@ -274,11 +280,11 @@ public class MantleWriter implements IObjectPlacer, AutoCloseable { } @Override - public BlockData get(int x, int y, int z) { + public PlatformBlockState get(int x, int y, int z) { BlockData block = getData(x, y, z, BlockData.class); if (block == null) return AIR; - return block; + return BukkitBlockState.of(block); } @Override @@ -293,7 +299,7 @@ public class MantleWriter implements IObjectPlacer, AutoCloseable { @Override public boolean isSolid(int x, int y, int z) { - return B.isSolid(get(x, y, z)); + return B.isSolid((BlockData) get(x, y, z).nativeHandle()); } @Override diff --git a/core/src/main/java/art/arcane/iris/engine/mantle/components/IslandObjectPlacer.java b/core/src/main/java/art/arcane/iris/engine/mantle/components/IslandObjectPlacer.java index e9c98975c..6d25bb80c 100644 --- a/core/src/main/java/art/arcane/iris/engine/mantle/components/IslandObjectPlacer.java +++ b/core/src/main/java/art/arcane/iris/engine/mantle/components/IslandObjectPlacer.java @@ -24,8 +24,7 @@ import art.arcane.iris.engine.mantle.MantleWriter; import art.arcane.iris.engine.object.FloatingIslandSample; import art.arcane.iris.engine.object.IObjectPlacer; import art.arcane.iris.engine.object.TileData; -import art.arcane.iris.util.common.data.B; -import org.bukkit.block.data.BlockData; +import art.arcane.iris.spi.PlatformBlockState; import org.jetbrains.annotations.Nullable; public class IslandObjectPlacer implements IObjectPlacer { @@ -205,7 +204,7 @@ public class IslandObjectPlacer implements IObjectPlacer { } @Override - public void set(int x, int y, int z, BlockData d) { + public void set(int x, int y, int z, PlatformBlockState d) { if (shouldSkipAirColumn(x, y, z)) { return; } @@ -213,7 +212,7 @@ public class IslandObjectPlacer implements IObjectPlacer { } @Override - public BlockData get(int x, int y, int z) { + public PlatformBlockState get(int x, int y, int z) { return wrapped.get(x, y, z); } diff --git a/core/src/main/java/art/arcane/iris/engine/mantle/components/MantleFloatingObjectComponent.java b/core/src/main/java/art/arcane/iris/engine/mantle/components/MantleFloatingObjectComponent.java index 1971926af..9de45d6eb 100644 --- a/core/src/main/java/art/arcane/iris/engine/mantle/components/MantleFloatingObjectComponent.java +++ b/core/src/main/java/art/arcane/iris/engine/mantle/components/MantleFloatingObjectComponent.java @@ -44,6 +44,7 @@ import art.arcane.volmlib.util.collection.KList; import art.arcane.volmlib.util.documentation.ChunkCoordinates; import art.arcane.volmlib.util.mantle.flag.ReservedFlag; import art.arcane.volmlib.util.math.RNG; +import art.arcane.iris.spi.PlatformBlockState; import org.bukkit.Material; import org.bukkit.block.data.BlockData; import org.bukkit.util.BlockVector; @@ -445,11 +446,13 @@ public class MantleFloatingObjectComponent extends IrisMantleComponent { return rotation.rotate(new BlockVector(fp.getTallestKx(), fp.getLowestSolidKeyY(), fp.getTallestKz()), 0, 0, 0); } - private static boolean shouldWritePlacementMarker(IObjectPlacer placer, BlockData data, int x, int y, int z) { - if (data == null) { + private static boolean shouldWritePlacementMarker(IObjectPlacer placer, PlatformBlockState state, int x, int y, int z) { + if (state == null) { return false; } - BlockData existing = placer.get(x, y, z); + BlockData data = (BlockData) state.nativeHandle(); + PlatformBlockState existingState = placer.get(x, y, z); + BlockData existing = existingState == null ? null : (BlockData) existingState.nativeHandle(); boolean wouldReplace = existing != null && B.isSolid(existing) && B.isVineBlock(data); boolean placesBlock = !data.getMaterial().equals(Material.AIR) && !data.getMaterial().equals(Material.CAVE_AIR) && !wouldReplace; return data instanceof IrisCustomData || placesBlock; diff --git a/core/src/main/java/art/arcane/iris/engine/mantle/components/MantleObjectComponent.java b/core/src/main/java/art/arcane/iris/engine/mantle/components/MantleObjectComponent.java index 062049e56..f59d2e0dc 100644 --- a/core/src/main/java/art/arcane/iris/engine/mantle/components/MantleObjectComponent.java +++ b/core/src/main/java/art/arcane/iris/engine/mantle/components/MantleObjectComponent.java @@ -47,6 +47,7 @@ import art.arcane.iris.util.project.noise.CNG; import art.arcane.iris.util.project.noise.NoiseType; import it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; +import art.arcane.iris.spi.PlatformBlockState; import org.bukkit.util.BlockVector; import org.bukkit.block.data.BlockData; @@ -484,7 +485,7 @@ public class MantleObjectComponent extends IrisMantleComponent { if (marker != null) { writer.setData(b.getX(), b.getY(), b.getZ(), marker); } - if (effectivePlacement.isDolphinTarget() && effectivePlacement.isUnderwater() && B.isStorageChest(data)) { + if (effectivePlacement.isDolphinTarget() && effectivePlacement.isUnderwater() && B.isStorageChest(unwrap(data))) { writer.setData(b.getX(), b.getY(), b.getZ(), MatterStructurePOI.BURIED_TREASURE); } }, null, getData()); @@ -499,7 +500,7 @@ public class MantleObjectComponent extends IrisMantleComponent { if (marker != null) { writer.setData(b.getX(), b.getY(), b.getZ(), marker); } - if (effectivePlacement.isDolphinTarget() && effectivePlacement.isUnderwater() && B.isStorageChest(data)) { + if (effectivePlacement.isDolphinTarget() && effectivePlacement.isUnderwater() && B.isStorageChest(unwrap(data))) { writer.setData(b.getX(), b.getY(), b.getZ(), MatterStructurePOI.BURIED_TREASURE); } }, null, getData()); @@ -511,7 +512,7 @@ public class MantleObjectComponent extends IrisMantleComponent { if (marker != null) { writer.setData(b.getX(), b.getY(), b.getZ(), marker); } - if (effectivePlacement.isDolphinTarget() && effectivePlacement.isUnderwater() && B.isStorageChest(data)) { + if (effectivePlacement.isDolphinTarget() && effectivePlacement.isUnderwater() && B.isStorageChest(unwrap(data))) { writer.setData(b.getX(), b.getY(), b.getZ(), MatterStructurePOI.BURIED_TREASURE); } }, null, getData()); @@ -700,7 +701,7 @@ public class MantleObjectComponent extends IrisMantleComponent { if (marker != null) { writer.setData(b.getX(), b.getY(), b.getZ(), marker); } - if (effectivePlacement.isDolphinTarget() && effectivePlacement.isUnderwater() && B.isStorageChest(data)) { + if (effectivePlacement.isDolphinTarget() && effectivePlacement.isUnderwater() && B.isStorageChest(unwrap(data))) { writer.setData(b.getX(), b.getY(), b.getZ(), MatterStructurePOI.BURIED_TREASURE); } }, null, getData()); @@ -880,7 +881,7 @@ public class MantleObjectComponent extends IrisMantleComponent { if (marker != null) { writer.setData(b.getX(), b.getY(), b.getZ(), marker); } - if (placement.isDolphinTarget() && placement.isUnderwater() && B.isStorageChest(data)) { + if (placement.isDolphinTarget() && placement.isUnderwater() && B.isStorageChest(unwrap(data))) { writer.setData(b.getX(), b.getY(), b.getZ(), MatterStructurePOI.BURIED_TREASURE); } }, null, getData()); @@ -1037,7 +1038,7 @@ public class MantleObjectComponent extends IrisMantleComponent { } @Override - public void set(int x, int y, int z, BlockData d) { + public void set(int x, int y, int z, PlatformBlockState d) { if (y >= maxY) { return; } @@ -1045,7 +1046,7 @@ public class MantleObjectComponent extends IrisMantleComponent { } @Override - public BlockData get(int x, int y, int z) { + public PlatformBlockState get(int x, int y, int z) { return delegate.get(x, y, z); } @@ -1300,6 +1301,10 @@ public class MantleObjectComponent extends IrisMantleComponent { && IrisSettings.get().getGeneral().isDebug(); } + private static BlockData unwrap(PlatformBlockState state) { + return state == null ? null : (BlockData) state.nativeHandle(); + } + private record ObjectPlacementSummary( int biomeSurfacePlacersChecked, int biomeSurfacePlacersTriggered, diff --git a/core/src/main/java/art/arcane/iris/engine/modifier/IrisCarveModifier.java b/core/src/main/java/art/arcane/iris/engine/modifier/IrisCarveModifier.java index 3602620ad..1974cf6ac 100644 --- a/core/src/main/java/art/arcane/iris/engine/modifier/IrisCarveModifier.java +++ b/core/src/main/java/art/arcane/iris/engine/modifier/IrisCarveModifier.java @@ -44,6 +44,8 @@ import art.arcane.volmlib.util.matter.slices.MarkerMatter; import art.arcane.volmlib.util.scheduling.PrecisionStopwatch; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import lombok.Data; +import art.arcane.iris.platform.bukkit.BukkitBlockState; +import art.arcane.iris.spi.PlatformBlockState; import org.bukkit.Material; import org.bukkit.block.data.BlockData; @@ -51,14 +53,14 @@ import java.util.Arrays; import java.util.HashMap; import java.util.Map; -public class IrisCarveModifier extends EngineAssignedModifier { +public class IrisCarveModifier extends EngineAssignedModifier { private static final ThreadLocal SCRATCH = ThreadLocal.withInitial(CarveScratch::new); private static final int CAVE_BIOME_BLEND_RADIUS = 3; private static final int CAVE_BIOME_BLEND_CENTER_WEIGHT = 4; private static final int CAVE_BIOME_BLEND_TOTAL_WEIGHT = 8; private final RNG rng; - private final BlockData AIR = Material.CAVE_AIR.createBlockData(); - private final BlockData LAVA = Material.LAVA.createBlockData(); + private final PlatformBlockState AIR = BukkitBlockState.of(Material.CAVE_AIR.createBlockData()); + private final PlatformBlockState LAVA = BukkitBlockState.of(Material.LAVA.createBlockData()); private final IrisDecorantActuator decorant; public IrisCarveModifier(Engine engine) { @@ -69,7 +71,7 @@ public class IrisCarveModifier extends EngineAssignedModifier { @Override @ChunkCoordinates - public void onModify(int x, int z, Hunk output, boolean multicore, ChunkContext context) { + public void onModify(int x, int z, Hunk output, boolean multicore, ChunkContext context) { PrecisionStopwatch p = PrecisionStopwatch.start(); Mantle mantle = getEngine().getMantle().getMantle(); IrisDimensionCarvingResolver.State resolverState = new IrisDimensionCarvingResolver.State(); @@ -120,9 +122,10 @@ public class IrisCarveModifier extends EngineAssignedModifier { return; } - BlockData current = output.getRaw(rx, yy, rz); + PlatformBlockState current = output.getRaw(rx, yy, rz); + BlockData currentRaw = current == null ? null : (BlockData) current.nativeHandle(); - if (B.isFluid(current)) { + if (B.isFluid(currentRaw)) { return; } @@ -144,7 +147,7 @@ public class IrisCarveModifier extends EngineAssignedModifier { walls.put(rx - 1, yy, rz, c); } - if (current.getMaterial().isAir()) { + if (currentRaw.getMaterial().isAir()) { return; } @@ -175,10 +178,10 @@ public class IrisCarveModifier extends EngineAssignedModifier { if (biome != null) { biome.setInferredType(InferredType.CAVE); - BlockData data = biome.getWall().get(rng, worldX, yy, worldZ, getData()); + PlatformBlockState data = biome.getWall().get(rng, worldX, yy, worldZ, getData()); int columnIndex = PowerOfTwoCoordinates.packLocal16(rx, rz); - if (data != null && B.isSolid(output.getRaw(rx, yy, rz)) && yy < surfaceHeights[columnIndex]) { + if (data != null && B.isSolid(unwrap(output.getRaw(rx, yy, rz))) && yy < surfaceHeights[columnIndex]) { output.setRaw(rx, yy, rz, data); } } @@ -288,7 +291,7 @@ public class IrisCarveModifier extends EngineAssignedModifier { } private void processColumnFromMask( - Hunk output, + Hunk output, MantleChunk mc, Mantle mantle, ColumnMask columnMask, @@ -342,7 +345,7 @@ public class IrisCarveModifier extends EngineAssignedModifier { } private void processBoundaryColumnFromMask( - Hunk output, + Hunk output, ColumnMask boundaryMask, MatterCavern cavern, int columnIndex, @@ -380,7 +383,7 @@ public class IrisCarveModifier extends EngineAssignedModifier { } private void paintBoundaryZone( - Hunk output, + Hunk output, MatterCavern cavern, int rx, int rz, @@ -404,7 +407,7 @@ public class IrisCarveModifier extends EngineAssignedModifier { biome.setInferredType(InferredType.CAVE); - KList floorLayers = biome.generateLayers(getDimension(), worldX, worldZ, rng, 3, zoneFloor, getData(), getComplex()); + KList floorLayers = biome.generateLayers(getDimension(), worldX, worldZ, rng, 3, zoneFloor, getData(), getComplex()); for (int i = 0; i < zoneFloor - 1; i++) { if (!floorLayers.hasIndex(i)) { break; @@ -415,14 +418,14 @@ public class IrisCarveModifier extends EngineAssignedModifier { break; } - BlockData down = output.getRaw(rx, fy, rz); + BlockData down = unwrap(output.getRaw(rx, fy, rz)); if (!B.isSolid(down)) { break; } - BlockData layer = floorLayers.get(i); + PlatformBlockState layer = floorLayers.get(i); if (B.isOre(down)) { - output.setRaw(rx, fy, rz, B.toDeepSlateOre(down, layer)); + output.setRaw(rx, fy, rz, BukkitBlockState.of(B.toDeepSlateOre(down, unwrap(layer)))); continue; } @@ -430,21 +433,21 @@ public class IrisCarveModifier extends EngineAssignedModifier { } int worldMaxY = getEngine().getWorld().maxHeight() - getEngine().getWorld().minHeight(); - KList ceilingLayers = biome.generateCeilingLayers(getDimension(), worldX, worldZ, rng, 3, zoneCeiling, getData(), getComplex()); + KList ceilingLayers = biome.generateCeilingLayers(getDimension(), worldX, worldZ, rng, 3, zoneCeiling, getData(), getComplex()); for (int i = 0; i < ceilingLayers.size(); i++) { int cy = zoneCeiling + i + 1; if (cy >= worldMaxY) { break; } - BlockData up = output.getRaw(rx, cy, rz); + BlockData up = unwrap(output.getRaw(rx, cy, rz)); if (!B.isSolid(up)) { continue; } - BlockData layer = ceilingLayers.get(i); + PlatformBlockState layer = ceilingLayers.get(i); if (B.isOre(up)) { - output.setRaw(rx, cy, rz, B.toDeepSlateOre(up, layer)); + output.setRaw(rx, cy, rz, BukkitBlockState.of(B.toDeepSlateOre(up, unwrap(layer)))); continue; } @@ -452,16 +455,16 @@ public class IrisCarveModifier extends EngineAssignedModifier { } } - private void processZone(Hunk output, MantleChunk mc, Mantle mantle, CaveZone zone, int rx, int rz, int xx, int zz, IrisDimensionCarvingResolver.State resolverState, Long2ObjectOpenHashMap caveBiomeCache) { + private void processZone(Hunk output, MantleChunk mc, Mantle mantle, CaveZone zone, int rx, int rz, int xx, int zz, IrisDimensionCarvingResolver.State resolverState, Long2ObjectOpenHashMap caveBiomeCache) { int center = (zone.floor + zone.ceiling) / 2; int maxY = output.getHeight(); String customBiome = ""; - if (zone.ceiling + 1 < maxY && B.isDecorant(output.getRaw(rx, zone.ceiling + 1, rz))) { + if (zone.ceiling + 1 < maxY && B.isDecorant(unwrap(output.getRaw(rx, zone.ceiling + 1, rz)))) { output.setRaw(rx, zone.ceiling + 1, rz, AIR); } - if (B.isDecorant(output.getRaw(rx, zone.ceiling, rz))) { + if (B.isDecorant(unwrap(output.getRaw(rx, zone.ceiling, rz)))) { output.setRaw(rx, zone.ceiling, rz, AIR); } @@ -493,7 +496,7 @@ public class IrisCarveModifier extends EngineAssignedModifier { biome.setInferredType(InferredType.CAVE); - KList blocks = biome.generateLayers(getDimension(), xx, zz, rng, 3, zone.floor, getData(), getComplex()); + KList blocks = biome.generateLayers(getDimension(), xx, zz, rng, 3, zone.floor, getData(), getComplex()); for (int i = 0; i < zone.floor - 1; i++) { if (!blocks.hasIndex(i)) { @@ -501,15 +504,15 @@ public class IrisCarveModifier extends EngineAssignedModifier { } int y = zone.floor - i - 1; - BlockData b = blocks.get(i); - BlockData down = output.getRaw(rx, y, rz); + PlatformBlockState b = blocks.get(i); + BlockData down = unwrap(output.getRaw(rx, y, rz)); if (!B.isSolid(down)) { continue; } if (B.isOre(down)) { - output.setRaw(rx, y, rz, B.toDeepSlateOre(down, b)); + output.setRaw(rx, y, rz, BukkitBlockState.of(B.toDeepSlateOre(down, unwrap(b)))); continue; } @@ -524,15 +527,15 @@ public class IrisCarveModifier extends EngineAssignedModifier { break; } - BlockData b = blocks.get(i); - BlockData up = output.getRaw(rx, cy, rz); + PlatformBlockState b = blocks.get(i); + BlockData up = unwrap(output.getRaw(rx, cy, rz)); if (!B.isSolid(up)) { continue; } if (B.isOre(up)) { - output.setRaw(rx, cy, rz, B.toDeepSlateOre(up, b)); + output.setRaw(rx, cy, rz, BukkitBlockState.of(B.toDeepSlateOre(up, unwrap(b)))); continue; } @@ -540,9 +543,9 @@ public class IrisCarveModifier extends EngineAssignedModifier { } for (IrisDecorator decorator : biome.getDecorators()) { - if (decorator.getPartOf().equals(IrisDecorationPart.NONE) && zone.getFloor() > 0 && B.isSolid(output.getRaw(rx, zone.getFloor() - 1, rz))) { + if (decorator.getPartOf().equals(IrisDecorationPart.NONE) && zone.getFloor() > 0 && B.isSolid(unwrap(output.getRaw(rx, zone.getFloor() - 1, rz)))) { decorant.getSurfaceDecorator().decorate(rx, rz, xx, xx, xx, zz, zz, zz, output, biome, zone.getFloor() - 1, zone.airThickness()); - } else if (decorator.getPartOf().equals(IrisDecorationPart.CEILING) && zone.getCeiling() + 1 < maxY && B.isSolid(output.getRaw(rx, zone.getCeiling() + 1, rz))) { + } else if (decorator.getPartOf().equals(IrisDecorationPart.CEILING) && zone.getCeiling() + 1 < maxY && B.isSolid(unwrap(output.getRaw(rx, zone.getCeiling() + 1, rz)))) { decorant.getCeilingDecorator().decorate(rx, rz, xx, xx, xx, zz, zz, zz, output, biome, zone.getCeiling(), zone.airThickness()); } } @@ -594,6 +597,10 @@ public class IrisCarveModifier extends EngineAssignedModifier { return resolvedBiome; } + private static BlockData unwrap(PlatformBlockState state) { + return state == null ? null : (BlockData) state.nativeHandle(); + } + private IrisBiome resolveCustomBiome(Map customBiomeCache, String customBiome) { if (customBiomeCache.containsKey(customBiome)) { return customBiomeCache.get(customBiome); diff --git a/core/src/main/java/art/arcane/iris/engine/modifier/IrisCustomModifier.java b/core/src/main/java/art/arcane/iris/engine/modifier/IrisCustomModifier.java index 30cc7b88c..94316f756 100644 --- a/core/src/main/java/art/arcane/iris/engine/modifier/IrisCustomModifier.java +++ b/core/src/main/java/art/arcane/iris/engine/modifier/IrisCustomModifier.java @@ -8,13 +8,14 @@ import art.arcane.iris.util.project.hunk.Hunk; import art.arcane.volmlib.util.mantle.flag.MantleFlag; import art.arcane.iris.util.common.parallel.BurstExecutor; import art.arcane.iris.util.common.parallel.MultiBurst; -import org.bukkit.block.data.BlockData; -public class IrisCustomModifier extends EngineAssignedModifier { +import art.arcane.iris.platform.bukkit.BukkitBlockState; +import art.arcane.iris.spi.PlatformBlockState; +public class IrisCustomModifier extends EngineAssignedModifier { public IrisCustomModifier(Engine engine) { super(engine, "Custom"); } @Override - public void onModify(int x, int z, Hunk output, boolean multicore, ChunkContext context) { + public void onModify(int x, int z, Hunk output, boolean multicore, ChunkContext context) { var mc = getEngine().getMantle().getMantle().getChunk(x >> 4, z >> 4); if (!mc.isFlagged(MantleFlag.CUSTOM_ACTIVE)) return; mc.use(); @@ -26,13 +27,13 @@ public class IrisCustomModifier extends EngineAssignedModifier { burst.queue(() -> { for (int rX = 0; rX < output.getWidth(); rX++) { for (int rZ = 0; rZ < output.getDepth(); rZ++) { - BlockData b = output.get(rX, finalY, rZ); - if (!(b instanceof IrisCustomData d)) continue; + PlatformBlockState b = output.get(rX, finalY, rZ); + if (b == null || !(b.nativeHandle() instanceof IrisCustomData d)) continue; mc.getOrCreate(finalY >> 4) .slice(Identifier.class) .set(rX, finalY & 15, rZ, d.getCustom()); - output.set(rX, finalY, rZ, d.getBase()); + output.set(rX, finalY, rZ, BukkitBlockState.of(d.getBase())); } } }); diff --git a/core/src/main/java/art/arcane/iris/engine/modifier/IrisDepositModifier.java b/core/src/main/java/art/arcane/iris/engine/modifier/IrisDepositModifier.java index 26df4ed46..310ef8e26 100644 --- a/core/src/main/java/art/arcane/iris/engine/modifier/IrisDepositModifier.java +++ b/core/src/main/java/art/arcane/iris/engine/modifier/IrisDepositModifier.java @@ -30,11 +30,13 @@ import art.arcane.volmlib.util.math.RNG; import art.arcane.volmlib.util.matter.MatterCavern; import art.arcane.iris.util.common.parallel.BurstExecutor; import art.arcane.volmlib.util.scheduling.PrecisionStopwatch; +import art.arcane.iris.platform.bukkit.BukkitBlockState; +import art.arcane.iris.spi.PlatformBlockState; import org.bukkit.Material; import org.bukkit.block.data.BlockData; import org.bukkit.util.BlockVector; -public class IrisDepositModifier extends EngineAssignedModifier { +public class IrisDepositModifier extends EngineAssignedModifier { private final RNG rng; public IrisDepositModifier(Engine engine) { @@ -43,13 +45,13 @@ public class IrisDepositModifier extends EngineAssignedModifier { } @Override - public void onModify(int x, int z, Hunk output, boolean multicore, ChunkContext context) { + public void onModify(int x, int z, Hunk output, boolean multicore, ChunkContext context) { PrecisionStopwatch p = PrecisionStopwatch.start(); generateDeposits(output, Math.floorDiv(x, 16), Math.floorDiv(z, 16), multicore, context); getEngine().getMetrics().getDeposit().put(p.getMilliseconds()); } - public void generateDeposits(Hunk terrain, int x, int z, boolean multicore, ChunkContext context) { + public void generateDeposits(Hunk terrain, int x, int z, boolean multicore, ChunkContext context) { IrisRegion region = context.getRegion().get(7, 7); IrisBiome biome = context.getBiome().get(7, 7); BurstExecutor burst = burst().burst(multicore); @@ -78,11 +80,11 @@ public class IrisDepositModifier extends EngineAssignedModifier { } } - public void generate(IrisDepositGenerator k, MantleChunk chunk, Hunk data, RNG rng, int cx, int cz, boolean safe, ChunkContext context) { + public void generate(IrisDepositGenerator k, MantleChunk chunk, Hunk data, RNG rng, int cx, int cz, boolean safe, ChunkContext context) { generate(k, chunk, data, rng, cx, cz, safe, null, context); } - public void generate(IrisDepositGenerator k, MantleChunk chunk, Hunk data, RNG rng, int cx, int cz, boolean safe, HeightMap he, ChunkContext context) { + public void generate(IrisDepositGenerator k, MantleChunk chunk, Hunk data, RNG rng, int cx, int cz, boolean safe, HeightMap he, ChunkContext context) { if (k.getSpawnChance() < rng.d()) return; @@ -130,29 +132,29 @@ public class IrisDepositModifier extends EngineAssignedModifier { if (ny > height || nx > 15 || nx < 0 || ny > getEngine().getHeight() || ny < 0 || nz < 0 || nz > 15) { continue; } - if (!k.isReplaceBedrock() && data.get(nx, ny, nz).getMaterial() == Material.BEDROCK) { + if (!k.isReplaceBedrock() && ((BlockData) data.get(nx, ny, nz).nativeHandle()).getMaterial() == Material.BEDROCK) { continue; } if (chunk.get(nx, ny, nz, MatterCavern.class) == null) { - BlockData ore = clump.getBlocks().get(j); - BlockData remapped = resolveDepositVariant(cx, cz, nx, ny, nz, ore, dimension, context); - BlockData finalBlock = remapped != null + PlatformBlockState ore = clump.getBlocks().get(j); + PlatformBlockState remapped = resolveDepositVariant(cx, cz, nx, ny, nz, ore, dimension, context); + PlatformBlockState finalBlock = remapped != null ? remapped - : B.toDeepSlateOre(data.get(nx, ny, nz), ore); + : BukkitBlockState.of(B.toDeepSlateOre(unwrap(data.get(nx, ny, nz)), unwrap(ore))); data.set(nx, ny, nz, finalBlock); } } } } - private BlockData resolveDepositVariant(int cx, int cz, int nx, int ny, int nz, BlockData ore, IrisDimension dimension, ChunkContext context) { + private PlatformBlockState resolveDepositVariant(int cx, int cz, int nx, int ny, int nz, PlatformBlockState ore, IrisDimension dimension, ChunkContext context) { int worldX = (cx << 4) + nx; int worldZ = (cz << 4) + nz; IrisBiome biome = getEngine().getBiome(worldX, ny, worldZ); if (biome != null) { - BlockData match = matchDepositVariant(biome.getDepositVariants(), ore, ny); + PlatformBlockState match = matchDepositVariant(biome.getDepositVariants(), ore, ny); if (match != null) { return match; } @@ -160,14 +162,14 @@ public class IrisDepositModifier extends EngineAssignedModifier { IrisRegion region = context.getRegion().get(nx, nz); if (region != null) { - BlockData match = matchDepositVariant(region.getDepositVariants(), ore, ny); + PlatformBlockState match = matchDepositVariant(region.getDepositVariants(), ore, ny); if (match != null) { return match; } } if (dimension != null) { - BlockData match = matchDepositVariant(dimension.getDepositVariants(), ore, ny); + PlatformBlockState match = matchDepositVariant(dimension.getDepositVariants(), ore, ny); if (match != null) { return match; } @@ -176,7 +178,7 @@ public class IrisDepositModifier extends EngineAssignedModifier { return null; } - private BlockData matchDepositVariant(java.util.List variants, BlockData ore, int y) { + private PlatformBlockState matchDepositVariant(java.util.List variants, PlatformBlockState ore, int y) { if (variants == null || variants.isEmpty()) { return null; } @@ -186,7 +188,7 @@ public class IrisDepositModifier extends EngineAssignedModifier { continue; } - BlockData swapped = variant.remapOrNull(ore, getData()); + PlatformBlockState swapped = variant.remapOrNull(ore, getData()); if (swapped != null) { return swapped; } @@ -194,4 +196,8 @@ public class IrisDepositModifier extends EngineAssignedModifier { return null; } + + private static BlockData unwrap(PlatformBlockState state) { + return state == null ? null : (BlockData) state.nativeHandle(); + } } diff --git a/core/src/main/java/art/arcane/iris/engine/modifier/IrisFloatingChildBiomeModifier.java b/core/src/main/java/art/arcane/iris/engine/modifier/IrisFloatingChildBiomeModifier.java index 982f0d61f..63c5644e7 100644 --- a/core/src/main/java/art/arcane/iris/engine/modifier/IrisFloatingChildBiomeModifier.java +++ b/core/src/main/java/art/arcane/iris/engine/modifier/IrisFloatingChildBiomeModifier.java @@ -46,6 +46,8 @@ import art.arcane.volmlib.util.math.RNG; import art.arcane.volmlib.util.matter.MatterBiomeInject; import art.arcane.volmlib.util.matter.slices.BiomeInjectMatter; import art.arcane.volmlib.util.scheduling.PrecisionStopwatch; +import art.arcane.iris.platform.bukkit.BukkitBlockState; +import art.arcane.iris.spi.PlatformBlockState; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; @@ -53,22 +55,22 @@ import java.util.IdentityHashMap; import static art.arcane.iris.engine.mantle.EngineMantle.AIR; -public class IrisFloatingChildBiomeModifier extends EngineAssignedModifier { +public class IrisFloatingChildBiomeModifier extends EngineAssignedModifier { public static final long FLOATING_BASE_SEED_SALT = 0x5EED_F107_00F1B10CL; private static final Runnable NOOP_DECORATION_MISS = () -> { }; private final RNG rng; private final EngineDecorator seaSurfaceDecorator; - private static KList generateBottomPaletteLayers(IrisFloatingChildBiomes entry, IrisDimension dimension, double wx, double wz, RNG random, int paletteDepth, IrisData data, IrisComplex complex) { + private static KList generateBottomPaletteLayers(IrisFloatingChildBiomes entry, IrisDimension dimension, double wx, double wz, RNG random, int paletteDepth, IrisData data, IrisComplex complex) { if (entry == null || entry.getBottomPaletteMode() != FloatingBottomPaletteMode.CUSTOM || entry.getBottomPalette() == null || entry.getBottomPalette().isEmpty()) { return null; } return generatePaletteLayers(dimension, entry.getBottomPalette(), wx, wz, random.nextParallelRNG(0xB0770B), paletteDepth, data, complex); } - private static KList generatePaletteLayers(IrisDimension dimension, KList layers, double wx, double wz, RNG random, int maxDepth, IrisData data, IrisComplex complex) { - KList generated = new KList<>(); + private static KList generatePaletteLayers(IrisDimension dimension, KList layers, double wx, double wz, RNG random, int maxDepth, IrisData data, IrisComplex complex) { + KList generated = new KList<>(); if (layers == null || layers.isEmpty() || maxDepth <= 0) { return generated; } @@ -109,7 +111,7 @@ public class IrisFloatingChildBiomeModifier extends EngineAssignedModifier topBlocks, KList bottomBlocks, int topDepth, int bottomDepth, BlockData fallbackSolid) { + private static PlatformBlockState selectPaletteBlock(IrisFloatingChildBiomes entry, KList topBlocks, KList bottomBlocks, int topDepth, int bottomDepth, PlatformBlockState fallbackSolid) { FloatingBottomPaletteMode mode = entry == null || entry.getBottomPaletteMode() == null ? FloatingBottomPaletteMode.DEPTH : entry.getBottomPaletteMode(); if (mode == FloatingBottomPaletteMode.MIRROR_TOP) { return paletteBlock(topBlocks, Math.min(topDepth, bottomDepth), fallbackSolid); @@ -167,11 +169,11 @@ public class IrisFloatingChildBiomeModifier extends EngineAssignedModifier blocks, int depth, BlockData fallbackSolid) { + private static PlatformBlockState paletteBlock(KList blocks, int depth, PlatformBlockState fallbackSolid) { if (blocks == null || blocks.isEmpty()) { return fallbackSolid; } - BlockData block = blocks.hasIndex(depth) ? blocks.get(depth) : blocks.getLast(); + PlatformBlockState block = blocks.hasIndex(depth) ? blocks.get(depth) : blocks.getLast(); return block == null ? fallbackSolid : block; } @@ -179,20 +181,20 @@ public class IrisFloatingChildBiomeModifier extends EngineAssignedModifier topBlocks = target == null ? null : target.generateLayers(dimension, wx, wz, layerRng, paletteDepth, paletteDepth, data, complex); + KList topBlocks = target == null ? null : target.generateLayers(dimension, wx, wz, layerRng, paletteDepth, paletteDepth, data, complex); if (topBlocks == null || topBlocks.isEmpty()) { topBlocks = parent.generateLayers(dimension, wx, wz, layerRng, paletteDepth, paletteDepth, data, complex); } - KList bottomBlocks = generateBottomPaletteLayers(entry, dimension, wx, wz, layerRng, paletteDepth, data, complex); - return new PaletteContext(topBlocks, bottomBlocks, B.get("minecraft:stone")); + KList bottomBlocks = generateBottomPaletteLayers(entry, dimension, wx, wz, layerRng, paletteDepth, data, complex); + return new PaletteContext(topBlocks, bottomBlocks, B.getState("minecraft:stone")); } private static final class PaletteContext { - private final KList topBlocks; - private final KList bottomBlocks; - private final BlockData fallbackSolid; + private final KList topBlocks; + private final KList bottomBlocks; + private final PlatformBlockState fallbackSolid; - private PaletteContext(KList topBlocks, KList bottomBlocks, BlockData fallbackSolid) { + private PaletteContext(KList topBlocks, KList bottomBlocks, PlatformBlockState fallbackSolid) { this.topBlocks = topBlocks; this.bottomBlocks = bottomBlocks; this.fallbackSolid = fallbackSolid; @@ -206,7 +208,7 @@ public class IrisFloatingChildBiomeModifier extends EngineAssignedModifier output, boolean multicore, ChunkContext context) { + public void onModify(int x, int z, Hunk output, boolean multicore, ChunkContext context) { PrecisionStopwatch p = PrecisionStopwatch.start(); int chunkHeight = output.getHeight(); IrisData data = getData(); @@ -248,7 +250,7 @@ public class IrisFloatingChildBiomeModifier extends EngineAssignedModifier 0) { - BlockData fluid = B.get(entry.getFluidBlock()); - if (fluid == null) { - fluid = B.get("minecraft:water"); + BlockData rawFluid = B.get(entry.getFluidBlock()); + if (rawFluid == null) { + rawFluid = B.get("minecraft:water"); } + PlatformBlockState fluid = BukkitBlockState.of(rawFluid); int fluidCap = Math.min(sample.thickness - 1, localFluidHeight); for (int k = 1; k <= fluidCap; k++) { if (sample.solidMask[k]) { @@ -291,7 +294,7 @@ public class IrisFloatingChildBiomeModifier extends EngineAssignedModifier output, boolean multicore, ChunkContext context) { + public void decorateColumns(int x, int z, Hunk output, boolean multicore, ChunkContext context) { int chunkHeight = output.getHeight(); IrisData data = getData(); IrisComplex complex = getComplex(); @@ -319,8 +322,8 @@ public class IrisFloatingChildBiomeModifier extends EngineAssignedModifier 0 && fluidTopY + 1 < chunkHeight && B.isAir(output.get(xf, fluidTopY + 1, zf))) { + if (fluidTopY > 0 && fluidTopY + 1 < chunkHeight && B.isAir(unwrap(output.get(xf, fluidTopY + 1, zf)))) { try { seaSurfaceDecorator.decorate(xf, zf, wx, wx + 1, wx - 1, wz, wz + 1, wz - 1, output, target, fluidTopY, chunkHeight); } catch (Throwable e) { @@ -393,6 +396,10 @@ public class IrisFloatingChildBiomeModifier extends EngineAssignedModifier { - private static final BlockData AIR = B.get("AIR"); - private static final BlockData WATER = B.get("WATER"); - private static final Map ORE_BASES = buildOreBases(); +public class IrisPerfectionModifier extends EngineAssignedModifier { + private static final PlatformBlockState AIR = B.getState("AIR"); + private static final PlatformBlockState WATER = B.getState("WATER"); + private static final Map ORE_BASES = buildOreBases(); public IrisPerfectionModifier(Engine engine) { super(engine, "Perfection"); } - private static Map buildOreBases() { - Map map = new EnumMap<>(Material.class); - BlockData stone = B.get("STONE"); - BlockData deepslate = B.get("DEEPSLATE"); - BlockData netherrack = B.get("NETHERRACK"); - BlockData blackstone = B.get("BLACKSTONE"); + private static Map buildOreBases() { + Map map = new EnumMap<>(Material.class); + PlatformBlockState stone = B.getState("STONE"); + PlatformBlockState deepslate = B.getState("DEEPSLATE"); + PlatformBlockState netherrack = B.getState("NETHERRACK"); + PlatformBlockState blackstone = B.getState("BLACKSTONE"); map.put(Material.COAL_ORE, stone); map.put(Material.COPPER_ORE, stone); map.put(Material.IRON_ORE, stone); @@ -75,7 +76,7 @@ public class IrisPerfectionModifier extends EngineAssignedModifier { } @Override - public void onModify(int x, int z, Hunk output, boolean multicore, ChunkContext context) { + public void onModify(int x, int z, Hunk output, boolean multicore, ChunkContext context) { PrecisionStopwatch p = PrecisionStopwatch.start(); if (getDimension().isHideOresForHiddenOre()) { hideOres(output, multicore); @@ -100,8 +101,9 @@ public class IrisPerfectionModifier extends EngineAssignedModifier { surfaces.add(top); for (int k = top; k >= 0; k--) { - BlockData b = output.get(finalI, k, j); - boolean now = b != null && !(B.isAir(b) || B.isFluid(b)); + PlatformBlockState b = output.get(finalI, k, j); + BlockData rawB = unwrap(b); + boolean now = b != null && !(B.isAir(rawB) || B.isFluid(rawB)); if (now != inside) { inside = now; @@ -115,7 +117,7 @@ public class IrisPerfectionModifier extends EngineAssignedModifier { } for (int k : surfaces) { - BlockData tip = output.get(finalI, k, j); + PlatformBlockState tip = output.get(finalI, k, j); if (tip == null) { continue; @@ -124,15 +126,16 @@ public class IrisPerfectionModifier extends EngineAssignedModifier { boolean remove = false; boolean remove2 = false; - if (B.isDecorant(tip)) { - BlockData bel = output.get(finalI, k - 1, j); + BlockData rawTip = (BlockData) tip.nativeHandle(); + if (B.isDecorant(rawTip)) { + BlockData bel = unwrap(output.get(finalI, k - 1, j)); if (bel == null) { remove = true; - } else if (!B.canPlaceOnto(tip.getMaterial(), bel.getMaterial())) { + } else if (!B.canPlaceOnto(rawTip.getMaterial(), bel.getMaterial())) { remove = true; } else if (bel instanceof Bisected) { - BlockData bb = output.get(finalI, k - 2, j); + BlockData bb = unwrap(output.get(finalI, k - 2, j)); if (bb == null || !B.canPlaceOnto(bel.getMaterial(), bb.getMaterial())) { remove = true; remove2 = true; @@ -159,7 +162,7 @@ public class IrisPerfectionModifier extends EngineAssignedModifier { getEngine().getMetrics().getPerfection().put(p.getMilliseconds()); } - private void hideOres(Hunk output, boolean multicore) { + private void hideOres(Hunk output, boolean multicore) { BurstExecutor burst = burst().burst(multicore); int height = output.getHeight(); for (int i = 0; i < 16; i++) { @@ -167,11 +170,11 @@ public class IrisPerfectionModifier extends EngineAssignedModifier { burst.queue(() -> { for (int j = 0; j < 16; j++) { for (int k = height - 1; k >= 0; k--) { - BlockData block = output.get(finalI, k, j); + PlatformBlockState block = output.get(finalI, k, j); if (block == null) { continue; } - BlockData base = ORE_BASES.get(block.getMaterial()); + PlatformBlockState base = ORE_BASES.get(((BlockData) block.nativeHandle()).getMaterial()); if (base != null) { output.set(finalI, k, j, base); } @@ -182,15 +185,22 @@ public class IrisPerfectionModifier extends EngineAssignedModifier { burst.complete(); } - private int getHeight(Hunk output, int x, int z) { + private int getHeight(Hunk output, int x, int z) { for (int i = output.getHeight() - 1; i >= 0; i--) { - BlockData b = output.get(x, i, z); + PlatformBlockState b = output.get(x, i, z); - if (b != null && !B.isAir(b) && !B.isFluid(b)) { - return i; + if (b != null) { + BlockData rawB = (BlockData) b.nativeHandle(); + if (!B.isAir(rawB) && !B.isFluid(rawB)) { + return i; + } } } return 0; } + + private static BlockData unwrap(PlatformBlockState state) { + return state == null ? null : (BlockData) state.nativeHandle(); + } } diff --git a/core/src/main/java/art/arcane/iris/engine/modifier/IrisPostModifier.java b/core/src/main/java/art/arcane/iris/engine/modifier/IrisPostModifier.java index 1b0fdc309..843b3bdc6 100644 --- a/core/src/main/java/art/arcane/iris/engine/modifier/IrisPostModifier.java +++ b/core/src/main/java/art/arcane/iris/engine/modifier/IrisPostModifier.java @@ -27,6 +27,8 @@ import art.arcane.iris.util.common.data.B; import art.arcane.iris.util.project.hunk.Hunk; import art.arcane.volmlib.util.math.RNG; import art.arcane.volmlib.util.scheduling.PrecisionStopwatch; +import art.arcane.iris.platform.bukkit.BukkitBlockState; +import art.arcane.iris.spi.PlatformBlockState; import org.bukkit.Material; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.Levelled; @@ -36,9 +38,9 @@ import org.bukkit.block.data.type.Slab; import java.util.concurrent.atomic.AtomicInteger; -public class IrisPostModifier extends EngineAssignedModifier { - private static final BlockData AIR = B.get("AIR"); - private static final BlockData WATER = B.get("WATER"); +public class IrisPostModifier extends EngineAssignedModifier { + private static final PlatformBlockState AIR = B.getState("AIR"); + private static final PlatformBlockState WATER = B.getState("WATER"); private final RNG rng; public IrisPostModifier(Engine engine) { @@ -47,11 +49,11 @@ public class IrisPostModifier extends EngineAssignedModifier { } @Override - public void onModify(int x, int z, Hunk output, boolean multicore, ChunkContext context) { + public void onModify(int x, int z, Hunk output, boolean multicore, ChunkContext context) { PrecisionStopwatch p = PrecisionStopwatch.start(); AtomicInteger i = new AtomicInteger(); AtomicInteger j = new AtomicInteger(); - Hunk sync = output.synchronize(); + Hunk sync = output.synchronize(); for (i.set(0); i.get() < output.getWidth(); i.getAndIncrement()) { for (j.set(0); j.get() < output.getDepth(); j.getAndIncrement()) { int ii = i.get(); @@ -63,7 +65,7 @@ public class IrisPostModifier extends EngineAssignedModifier { getEngine().getMetrics().getPost().put(p.getMilliseconds()); } - private void post(int currentPostX, int currentPostZ, Hunk currentData, int x, int z, ChunkContext context) { + private void post(int currentPostX, int currentPostZ, Hunk currentData, int x, int z, ChunkContext context) { int h = getEngine().getMantle().trueHeight(x, z); int ha = getEngine().getMantle().trueHeight(x + 1, z); int hb = getEngine().getMantle().trueHeight(x, z + 1); @@ -101,13 +103,14 @@ public class IrisPostModifier extends EngineAssignedModifier { g += hd == h - 1 ? 1 : 0; if (g >= 4) { - BlockData bc = getPostBlock(x, h, z, currentPostX, currentPostZ, currentData); - BlockData b = getPostBlock(x, h + 1, z, currentPostX, currentPostZ, currentData); - Material m = bc.getMaterial(); + PlatformBlockState bcState = getPostBlock(x, h, z, currentPostX, currentPostZ, currentData); + PlatformBlockState bState = getPostBlock(x, h + 1, z, currentPostX, currentPostZ, currentData); + BlockData b = (BlockData) bState.nativeHandle(); + Material m = ((BlockData) bcState.nativeHandle()).getMaterial(); if ((b.getMaterial().isOccluding() && b.getMaterial().isSolid())) { if (m.isSolid()) { - setPostBlock(x, h, z, b, currentPostX, currentPostZ, currentData); + setPostBlock(x, h, z, bState, currentPostX, currentPostZ, currentData); h--; } } @@ -120,10 +123,10 @@ public class IrisPostModifier extends EngineAssignedModifier { g += hd == h + 1 ? 1 : 0; if (g >= 4) { - BlockData ba = getPostBlock(x, ha, z, currentPostX, currentPostZ, currentData); - BlockData bb = getPostBlock(x, hb, z, currentPostX, currentPostZ, currentData); - BlockData bc = getPostBlock(x, hc, z, currentPostX, currentPostZ, currentData); - BlockData bd = getPostBlock(x, hd, z, currentPostX, currentPostZ, currentData); + BlockData ba = (BlockData) getPostBlock(x, ha, z, currentPostX, currentPostZ, currentData).nativeHandle(); + BlockData bb = (BlockData) getPostBlock(x, hb, z, currentPostX, currentPostZ, currentData).nativeHandle(); + BlockData bc = (BlockData) getPostBlock(x, hc, z, currentPostX, currentPostZ, currentData).nativeHandle(); + BlockData bd = (BlockData) getPostBlock(x, hd, z, currentPostX, currentPostZ, currentData).nativeHandle(); g = 0; g = B.isSolid(ba) ? g + 1 : g; g = B.isSolid(bb) ? g + 1 : g; @@ -147,7 +150,7 @@ public class IrisPostModifier extends EngineAssignedModifier { int max = Math.abs(Math.max(h - ha, Math.max(h - hb, Math.max(h - hc, h - hd)))); for (int i = h; i > h - max; i--) { - BlockData d = biome.getWall().get(rng, x + i, i + h, z + i, getData()); + PlatformBlockState d = biome.getWall().get(rng, x + i, i + h, z + i, getData()); if (d != null) { if (isAirOrWater(x, i, z, currentPostX, currentPostZ, currentData)) { @@ -176,12 +179,13 @@ public class IrisPostModifier extends EngineAssignedModifier { //@done { IrisSlopeClip sc = biome.getSlab().getSlopeCondition(); - BlockData d = sc.isValid(getComplex().getSlopeStream().get(x, z)) ? biome.getSlab().get(rng, x, h, z, getData()) : null; + PlatformBlockState d = sc.isValid(getComplex().getSlopeStream().get(x, z)) ? biome.getSlab().get(rng, x, h, z, getData()) : null; if (d != null) { - boolean cancel = B.isAir(d); + BlockData rawD = (BlockData) d.nativeHandle(); + boolean cancel = B.isAir(rawD); - if (d.getMaterial().equals(Material.SNOW) && h + 1 <= getDimension().getFluidHeight()) { + if (rawD.getMaterial().equals(Material.SNOW) && h + 1 <= getDimension().getFluidHeight()) { cancel = true; } @@ -198,7 +202,7 @@ public class IrisPostModifier extends EngineAssignedModifier { } // Waterlogging - BlockData b = getPostBlock(x, h, z, currentPostX, currentPostZ, currentData); + BlockData b = (BlockData) getPostBlock(x, h, z, currentPostX, currentPostZ, currentData).nativeHandle(); if (b instanceof Waterlogged) { Waterlogged ww = (Waterlogged) b.clone(); @@ -214,7 +218,7 @@ public class IrisPostModifier extends EngineAssignedModifier { if (w != ww.isWaterlogged()) { ww.setWaterlogged(w); - setPostBlock(x, h, z, ww, currentPostX, currentPostZ, currentData); + setPostBlock(x, h, z, BukkitBlockState.of(ww), currentPostX, currentPostZ, currentData); } } else if (b.getMaterial().equals(Material.AIR) && h <= getDimension().getFluidHeight()) { if ((isWaterOrWaterlogged(x + 1, h, z, currentPostX, currentPostZ, currentData) || isWaterOrWaterlogged(x - 1, h, z, currentPostX, currentPostZ, currentData) || isWaterOrWaterlogged(x, h, z + 1, currentPostX, currentPostZ, currentData) || isWaterOrWaterlogged(x, h, z - 1, currentPostX, currentPostZ, currentData))) { @@ -223,23 +227,23 @@ public class IrisPostModifier extends EngineAssignedModifier { } // Foliage - b = getPostBlock(x, h + 1, z, currentPostX, currentPostZ, currentData); + b = (BlockData) getPostBlock(x, h + 1, z, currentPostX, currentPostZ, currentData).nativeHandle(); if (B.isVineBlock(b) && b instanceof MultipleFacing) { MultipleFacing f = (MultipleFacing) b.clone(); int finalH = h + 1; f.getAllowedFaces().forEach(face -> { - BlockData d = getPostBlock(x + face.getModX(), finalH + face.getModY(), z + face.getModZ(), currentPostX, currentPostZ, currentData); + BlockData d = (BlockData) getPostBlock(x + face.getModX(), finalH + face.getModY(), z + face.getModZ(), currentPostX, currentPostZ, currentData).nativeHandle(); f.setFace(face, !B.isAir(d) && !B.isVineBlock(d)); }); if (!f.equals(b)) { - setPostBlock(x, h + 1, z, f, currentPostX, currentPostZ, currentData); + setPostBlock(x, h + 1, z, BukkitBlockState.of(f), currentPostX, currentPostZ, currentData); } } if (B.isFoliage(b) || b.getMaterial().equals(Material.DEAD_BUSH)) { - Material onto = getPostBlock(x, h, z, currentPostX, currentPostZ, currentData).getMaterial(); + Material onto = ((BlockData) getPostBlock(x, h, z, currentPostX, currentPostZ, currentData).nativeHandle()).getMaterial(); if (!B.canPlaceOnto(b.getMaterial(), onto) && !B.isDecorant(b)) { setPostBlock(x, h + 1, z, AIR, currentPostX, currentPostZ, currentData); @@ -247,64 +251,64 @@ public class IrisPostModifier extends EngineAssignedModifier { } } - public boolean isAir(int x, int y, int z, int currentPostX, int currentPostZ, Hunk currentData) { - BlockData d = getPostBlock(x, y, z, currentPostX, currentPostZ, currentData); + public boolean isAir(int x, int y, int z, int currentPostX, int currentPostZ, Hunk currentData) { + BlockData d = (BlockData) getPostBlock(x, y, z, currentPostX, currentPostZ, currentData).nativeHandle(); return d.getMaterial().equals(Material.AIR) || d.getMaterial().equals(Material.CAVE_AIR); } - public boolean hasGravity(int x, int y, int z, int currentPostX, int currentPostZ, Hunk currentData) { - BlockData d = getPostBlock(x, y, z, currentPostX, currentPostZ, currentData); + public boolean hasGravity(int x, int y, int z, int currentPostX, int currentPostZ, Hunk currentData) { + BlockData d = (BlockData) getPostBlock(x, y, z, currentPostX, currentPostZ, currentData).nativeHandle(); return d.getMaterial().equals(Material.SAND) || d.getMaterial().equals(Material.RED_SAND) || d.getMaterial().equals(Material.BLACK_CONCRETE_POWDER) || d.getMaterial().equals(Material.BLUE_CONCRETE_POWDER) || d.getMaterial().equals(Material.BROWN_CONCRETE_POWDER) || d.getMaterial().equals(Material.CYAN_CONCRETE_POWDER) || d.getMaterial().equals(Material.GRAY_CONCRETE_POWDER) || d.getMaterial().equals(Material.GREEN_CONCRETE_POWDER) || d.getMaterial().equals(Material.LIGHT_BLUE_CONCRETE_POWDER) || d.getMaterial().equals(Material.LIGHT_GRAY_CONCRETE_POWDER) || d.getMaterial().equals(Material.LIME_CONCRETE_POWDER) || d.getMaterial().equals(Material.MAGENTA_CONCRETE_POWDER) || d.getMaterial().equals(Material.ORANGE_CONCRETE_POWDER) || d.getMaterial().equals(Material.PINK_CONCRETE_POWDER) || d.getMaterial().equals(Material.PURPLE_CONCRETE_POWDER) || d.getMaterial().equals(Material.RED_CONCRETE_POWDER) || d.getMaterial().equals(Material.WHITE_CONCRETE_POWDER) || d.getMaterial().equals(Material.YELLOW_CONCRETE_POWDER); } - public boolean isSolid(int x, int y, int z, int currentPostX, int currentPostZ, Hunk currentData) { - BlockData d = getPostBlock(x, y, z, currentPostX, currentPostZ, currentData); + public boolean isSolid(int x, int y, int z, int currentPostX, int currentPostZ, Hunk currentData) { + BlockData d = (BlockData) getPostBlock(x, y, z, currentPostX, currentPostZ, currentData).nativeHandle(); return d.getMaterial().isSolid() && !B.isVineBlock(d); } - public boolean isSolidNonSlab(int x, int y, int z, int currentPostX, int currentPostZ, Hunk currentData) { - BlockData d = getPostBlock(x, y, z, currentPostX, currentPostZ, currentData); + public boolean isSolidNonSlab(int x, int y, int z, int currentPostX, int currentPostZ, Hunk currentData) { + BlockData d = (BlockData) getPostBlock(x, y, z, currentPostX, currentPostZ, currentData).nativeHandle(); return d.getMaterial().isSolid() && !(d instanceof Slab); } - public boolean isAirOrWater(int x, int y, int z, int currentPostX, int currentPostZ, Hunk currentData) { - BlockData d = getPostBlock(x, y, z, currentPostX, currentPostZ, currentData); + public boolean isAirOrWater(int x, int y, int z, int currentPostX, int currentPostZ, Hunk currentData) { + BlockData d = (BlockData) getPostBlock(x, y, z, currentPostX, currentPostZ, currentData).nativeHandle(); return d.getMaterial().equals(Material.WATER) || d.getMaterial().equals(Material.AIR) || d.getMaterial().equals(Material.CAVE_AIR); } - public boolean isSlab(int x, int y, int z, int currentPostX, int currentPostZ, Hunk currentData) { - BlockData d = getPostBlock(x, y, z, currentPostX, currentPostZ, currentData); + public boolean isSlab(int x, int y, int z, int currentPostX, int currentPostZ, Hunk currentData) { + BlockData d = (BlockData) getPostBlock(x, y, z, currentPostX, currentPostZ, currentData).nativeHandle(); return d instanceof Slab; } - public boolean isSnowLayer(int x, int y, int z, int currentPostX, int currentPostZ, Hunk currentData) { - BlockData d = getPostBlock(x, y, z, currentPostX, currentPostZ, currentData); + public boolean isSnowLayer(int x, int y, int z, int currentPostX, int currentPostZ, Hunk currentData) { + BlockData d = (BlockData) getPostBlock(x, y, z, currentPostX, currentPostZ, currentData).nativeHandle(); return d.getMaterial().equals(Material.SNOW); } - public boolean isWater(int x, int y, int z, int currentPostX, int currentPostZ, Hunk currentData) { - BlockData d = getPostBlock(x, y, z, currentPostX, currentPostZ, currentData); + public boolean isWater(int x, int y, int z, int currentPostX, int currentPostZ, Hunk currentData) { + BlockData d = (BlockData) getPostBlock(x, y, z, currentPostX, currentPostZ, currentData).nativeHandle(); return d.getMaterial().equals(Material.WATER); } - public boolean isWaterOrWaterlogged(int x, int y, int z, int currentPostX, int currentPostZ, Hunk currentData) { - BlockData d = getPostBlock(x, y, z, currentPostX, currentPostZ, currentData); + public boolean isWaterOrWaterlogged(int x, int y, int z, int currentPostX, int currentPostZ, Hunk currentData) { + BlockData d = (BlockData) getPostBlock(x, y, z, currentPostX, currentPostZ, currentData).nativeHandle(); return d.getMaterial().equals(Material.WATER) || (d instanceof Waterlogged && ((Waterlogged) d).isWaterlogged()); } - public boolean isLiquid(int x, int y, int z, int currentPostX, int currentPostZ, Hunk currentData) { - BlockData d = getPostBlock(x, y, z, currentPostX, currentPostZ, currentData); + public boolean isLiquid(int x, int y, int z, int currentPostX, int currentPostZ, Hunk currentData) { + BlockData d = (BlockData) getPostBlock(x, y, z, currentPostX, currentPostZ, currentData).nativeHandle(); return d instanceof Levelled; } - public void setPostBlock(int x, int y, int z, BlockData d, int currentPostX, int currentPostZ, Hunk currentData) { + public void setPostBlock(int x, int y, int z, PlatformBlockState d, int currentPostX, int currentPostZ, Hunk currentData) { if (y < currentData.getHeight()) { currentData.set(x & 15, y, z & 15, d); } } - public BlockData getPostBlock(int x, int y, int z, int cpx, int cpz, Hunk h) { - BlockData b = h.getClosest(x & 15, y, z & 15); + public PlatformBlockState getPostBlock(int x, int y, int z, int cpx, int cpz, Hunk h) { + PlatformBlockState b = h.getClosest(x & 15, y, z & 15); return b == null ? AIR : b; } diff --git a/core/src/main/java/art/arcane/iris/engine/object/BlockDataMergeSupport.java b/core/src/main/java/art/arcane/iris/engine/object/BlockDataMergeSupport.java index 6e33ebf53..f2f7de9dd 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/BlockDataMergeSupport.java +++ b/core/src/main/java/art/arcane/iris/engine/object/BlockDataMergeSupport.java @@ -1,5 +1,7 @@ package art.arcane.iris.engine.object; +import art.arcane.iris.platform.bukkit.BukkitBlockState; +import art.arcane.iris.spi.PlatformBlockState; import art.arcane.iris.util.common.data.B; import org.bukkit.block.data.BlockData; @@ -9,8 +11,9 @@ final class BlockDataMergeSupport { private BlockDataMergeSupport() { } - static BlockData merge(BlockData base, BlockData update) { - return merge(base, update, B::get); + static PlatformBlockState merge(PlatformBlockState base, PlatformBlockState update) { + BlockData merged = merge((BlockData) base.nativeHandle(), (BlockData) update.nativeHandle(), B::get); + return merged == null ? null : BukkitBlockState.of(merged); } static BlockData merge(BlockData base, BlockData update, Function resolver) { diff --git a/core/src/main/java/art/arcane/iris/engine/object/DecayControlPlacer.java b/core/src/main/java/art/arcane/iris/engine/object/DecayControlPlacer.java index 50f630adb..2c132a6f9 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/DecayControlPlacer.java +++ b/core/src/main/java/art/arcane/iris/engine/object/DecayControlPlacer.java @@ -20,7 +20,7 @@ package art.arcane.iris.engine.object; import art.arcane.iris.core.loader.IrisData; import art.arcane.iris.engine.framework.Engine; -import org.bukkit.block.data.BlockData; +import art.arcane.iris.spi.PlatformBlockState; import org.jetbrains.annotations.Nullable; public class DecayControlPlacer implements IObjectPlacer { @@ -41,12 +41,12 @@ public class DecayControlPlacer implements IObjectPlacer { } @Override - public void set(int x, int y, int z, BlockData d) { + public void set(int x, int y, int z, PlatformBlockState d) { delegate.set(x, y, z, d); } @Override - public BlockData get(int x, int y, int z) { + public PlatformBlockState get(int x, int y, int z) { return delegate.get(x, y, z); } diff --git a/core/src/main/java/art/arcane/iris/engine/object/FloatingObjectFootprint.java b/core/src/main/java/art/arcane/iris/engine/object/FloatingObjectFootprint.java index db91cf6d4..3b57bd8b3 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/FloatingObjectFootprint.java +++ b/core/src/main/java/art/arcane/iris/engine/object/FloatingObjectFootprint.java @@ -18,6 +18,7 @@ package art.arcane.iris.engine.object; +import art.arcane.iris.spi.PlatformBlockState; import art.arcane.iris.util.common.data.B; import org.bukkit.block.data.BlockData; import org.bukkit.util.BlockVector; @@ -68,8 +69,8 @@ public class FloatingObjectFootprint { int[] globalHighestKx = {0}; int[] globalHighestKz = {0}; - obj.getBlocks().forEach((BlockVector key, BlockData bd) -> { - if (!B.isSolid(bd)) { + obj.getBlocks().forEach((BlockVector key, PlatformBlockState bd) -> { + if (!B.isSolid((BlockData) bd.nativeHandle())) { return; } int kx = key.getBlockX(); diff --git a/core/src/main/java/art/arcane/iris/engine/object/IObjectLoot.java b/core/src/main/java/art/arcane/iris/engine/object/IObjectLoot.java index c12f805b3..6f7b64e1a 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/IObjectLoot.java +++ b/core/src/main/java/art/arcane/iris/engine/object/IObjectLoot.java @@ -1,12 +1,12 @@ package art.arcane.iris.engine.object; import art.arcane.iris.core.loader.IrisData; +import art.arcane.iris.spi.PlatformBlockState; import art.arcane.volmlib.util.collection.KList; -import org.bukkit.block.data.BlockData; public interface IObjectLoot { KList getFilter(); - KList getFilter(IrisData manager); + KList getFilter(IrisData manager); boolean isExact(); String getName(); int getWeight(); diff --git a/core/src/main/java/art/arcane/iris/engine/object/IObjectPlacer.java b/core/src/main/java/art/arcane/iris/engine/object/IObjectPlacer.java index d1b494aba..82d62cb98 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/IObjectPlacer.java +++ b/core/src/main/java/art/arcane/iris/engine/object/IObjectPlacer.java @@ -20,7 +20,7 @@ package art.arcane.iris.engine.object; import art.arcane.iris.core.loader.IrisData; import art.arcane.iris.engine.framework.Engine; -import org.bukkit.block.data.BlockData; +import art.arcane.iris.spi.PlatformBlockState; import org.jetbrains.annotations.Nullable; public interface IObjectPlacer { @@ -28,9 +28,9 @@ public interface IObjectPlacer { int getHighest(int x, int z, IrisData data, boolean ignoreFluid); - void set(int x, int y, int z, BlockData d); + void set(int x, int y, int z, PlatformBlockState d); - BlockData get(int x, int y, int z); + PlatformBlockState get(int x, int y, int z); boolean isPreventingDecay(); diff --git a/core/src/main/java/art/arcane/iris/engine/object/IPostBlockAccess.java b/core/src/main/java/art/arcane/iris/engine/object/IPostBlockAccess.java index 939cac7d8..d1c50bc1f 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/IPostBlockAccess.java +++ b/core/src/main/java/art/arcane/iris/engine/object/IPostBlockAccess.java @@ -18,14 +18,14 @@ package art.arcane.iris.engine.object; +import art.arcane.iris.spi.PlatformBlockState; import art.arcane.volmlib.util.collection.KList; -import org.bukkit.block.data.BlockData; import org.bukkit.generator.ChunkGenerator.ChunkData; public interface IPostBlockAccess { - BlockData getPostBlock(int x, int y, int z, int currentPostX, int currentPostZ, ChunkData currentData); + PlatformBlockState getPostBlock(int x, int y, int z, int currentPostX, int currentPostZ, ChunkData currentData); - void setPostBlock(int x, int y, int z, BlockData d, int currentPostX, int currentPostZ, ChunkData currentData); + void setPostBlock(int x, int y, int z, PlatformBlockState d, int currentPostX, int currentPostZ, ChunkData currentData); int highestTerrainOrFluidBlock(int x, int z); diff --git a/core/src/main/java/art/arcane/iris/engine/object/IrisBiome.java b/core/src/main/java/art/arcane/iris/engine/object/IrisBiome.java index c9d0fcd21..c520c3820 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/IrisBiome.java +++ b/core/src/main/java/art/arcane/iris/engine/object/IrisBiome.java @@ -43,9 +43,10 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; +import art.arcane.iris.platform.bukkit.BukkitBlockState; +import art.arcane.iris.spi.PlatformBlockState; import org.bukkit.Material; import org.bukkit.block.Biome; -import org.bukkit.block.data.BlockData; import java.awt.*; import java.util.EnumMap; @@ -57,7 +58,7 @@ import java.util.EnumMap; @Data @EqualsAndHashCode(callSuper = false) public class IrisBiome extends IrisRegistrant implements IRare { - private static final BlockData BARRIER = Material.BARRIER.createBlockData(); + private static final PlatformBlockState BARRIER = BukkitBlockState.of(Material.BARRIER.createBlockData()); private final transient AtomicCache> genCache = new AtomicCache<>(); private final transient AtomicCache> genCacheMax = new AtomicCache<>(); private final transient AtomicCache> genCacheMin = new AtomicCache<>(); @@ -189,16 +190,16 @@ public class IrisBiome extends IrisRegistrant implements IRare { @ArrayType(type = IrisOreGenerator.class, min = 1) private KList ores = new KList<>(); - public BlockData generateOres(int x, int y, int z, RNG rng, IrisData data, boolean surface) { + public PlatformBlockState generateOres(int x, int y, int z, RNG rng, IrisData data, boolean surface) { KList localOres = surface ? getSurfaceOres() : getUndergroundOres(); return generateOres(localOres, x, y, z, rng, data); } - public BlockData generateSurfaceOres(int x, int y, int z, RNG rng, IrisData data) { + public PlatformBlockState generateSurfaceOres(int x, int y, int z, RNG rng, IrisData data) { return generateOres(getSurfaceOres(), x, y, z, rng, data); } - public BlockData generateUndergroundOres(int x, int y, int z, RNG rng, IrisData data) { + public PlatformBlockState generateUndergroundOres(int x, int y, int z, RNG rng, IrisData data) { return generateOres(getUndergroundOres(), x, y, z, rng, data); } @@ -210,7 +211,7 @@ public class IrisBiome extends IrisRegistrant implements IRare { return !getUndergroundOres().isEmpty(); } - private BlockData generateOres(KList localOres, int x, int y, int z, RNG rng, IrisData data) { + private PlatformBlockState generateOres(KList localOres, int x, int y, int z, RNG rng, IrisData data) { if (localOres.isEmpty()) { return null; } @@ -218,7 +219,7 @@ public class IrisBiome extends IrisRegistrant implements IRare { int oreCount = localOres.size(); for (int oreIndex = 0; oreIndex < oreCount; oreIndex++) { IrisOreGenerator oreGenerator = localOres.get(oreIndex); - BlockData ore = oreGenerator.generate(x, y, z, rng, data); + PlatformBlockState ore = oreGenerator.generate(x, y, z, rng, data); if (ore != null) { return ore; } @@ -398,12 +399,12 @@ public class IrisBiome extends IrisRegistrant implements IRare { return childrenCell.aquire(() -> getChildStyle().create(random.nextParallelRNG(sig * 2137), getLoader()).bake().scale(scale).bake()); } - public KList generateLayers(IrisDimension dim, double wx, double wz, RNG random, int maxDepth, int height, IrisData rdata, IrisComplex complex) { + public KList generateLayers(IrisDimension dim, double wx, double wz, RNG random, int maxDepth, int height, IrisData rdata, IrisComplex complex) { if (isLockLayers()) { return generateLockedLayers(wx, wz, random, maxDepth, height, rdata, complex); } - KList data = new KList<>(); + KList data = new KList<>(); if (maxDepth <= 0) { return data; @@ -456,8 +457,8 @@ public class IrisBiome extends IrisRegistrant implements IRare { return data; } - public KList generateCeilingLayers(IrisDimension dim, double wx, double wz, RNG random, int maxDepth, int height, IrisData rdata, IrisComplex complex) { - KList data = new KList<>(); + public KList generateCeilingLayers(IrisDimension dim, double wx, double wz, RNG random, int maxDepth, int height, IrisData rdata, IrisComplex complex) { + KList data = new KList<>(); if (maxDepth <= 0) { return data; @@ -502,9 +503,9 @@ public class IrisBiome extends IrisRegistrant implements IRare { return data; } - public KList generateLockedLayers(double wx, double wz, RNG random, int maxDepthf, int height, IrisData rdata, IrisComplex complex) { - KList data = new KList<>(); - KList real = new KList<>(); + public KList generateLockedLayers(double wx, double wz, RNG random, int maxDepthf, int height, IrisData rdata, IrisComplex complex) { + KList data = new KList<>(); + KList real = new KList<>(); int maxDepth = Math.min(maxDepthf, getLockLayersMax()); if (maxDepth <= 0) { return data; @@ -583,8 +584,8 @@ public class IrisBiome extends IrisRegistrant implements IRare { }); } - public KList generateSeaLayers(double wx, double wz, RNG random, int maxDepth, IrisData rdata) { - KList data = new KList<>(); + public KList generateSeaLayers(double wx, double wz, RNG random, int maxDepth, IrisData rdata) { + KList data = new KList<>(); for (int i = 0; i < seaLayers.size(); i++) { CNG hgen = getLayerSeaHeightGenerators(random, rdata).get(i); @@ -733,9 +734,9 @@ public class IrisBiome extends IrisRegistrant implements IRare { return getBiomeGenerator(rng).fit(biomeScatter, x, y, z); } - public BlockData getSurfaceBlock(int x, int z, RNG rng, IrisData idm) { + public PlatformBlockState getSurfaceBlock(int x, int z, RNG rng, IrisData idm) { if (getLayers().isEmpty()) { - return B.get("AIR"); + return B.getState("AIR"); } return getLayers().get(0).get(rng, x, 0, z, idm); diff --git a/core/src/main/java/art/arcane/iris/engine/object/IrisBiomePaletteLayer.java b/core/src/main/java/art/arcane/iris/engine/object/IrisBiomePaletteLayer.java index 11992e8f6..0262bf44e 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/IrisBiomePaletteLayer.java +++ b/core/src/main/java/art/arcane/iris/engine/object/IrisBiomePaletteLayer.java @@ -27,8 +27,8 @@ import art.arcane.iris.util.project.noise.CNG; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import art.arcane.iris.spi.PlatformBlockState; import lombok.experimental.Accessors; -import org.bukkit.block.data.BlockData; @Snippet("biome-palette") @Accessors(chain = true) @@ -37,7 +37,7 @@ import org.bukkit.block.data.BlockData; @Desc("A layer of surface / subsurface material in biomes") @Data public class IrisBiomePaletteLayer { - private final transient AtomicCache> blockData = new AtomicCache<>(); + private final transient AtomicCache> blockData = new AtomicCache<>(); private final transient AtomicCache layerGenerator = new AtomicCache<>(); private final transient AtomicCache heightGenerator = new AtomicCache<>(); @Desc("The style of noise") @@ -68,7 +68,7 @@ public class IrisBiomePaletteLayer { return heightGenerator.aquire(() -> CNG.signature(rng.nextParallelRNG(minHeight * maxHeight + getBlockData(data).size()))); } - public BlockData get(RNG rng, double x, double y, double z, IrisData data) { + public PlatformBlockState get(RNG rng, double x, double y, double z, IrisData data) { if (getBlockData(data).isEmpty()) { return null; } @@ -97,12 +97,12 @@ public class IrisBiomePaletteLayer { return palette; } - public KList getBlockData(IrisData data) { + public KList getBlockData(IrisData data) { return blockData.aquire(() -> { - KList blockData = new KList<>(); + KList blockData = new KList<>(); for (IrisBlockData ix : palette) { - BlockData bx = ix.getBlockData(data); + PlatformBlockState bx = ix.getBlockData(data); if (bx != null) { for (int i = 0; i < ix.getWeight(); i++) { blockData.add(bx); diff --git a/core/src/main/java/art/arcane/iris/engine/object/IrisBlockData.java b/core/src/main/java/art/arcane/iris/engine/object/IrisBlockData.java index dc596face..edaa492b8 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/IrisBlockData.java +++ b/core/src/main/java/art/arcane/iris/engine/object/IrisBlockData.java @@ -25,6 +25,8 @@ import art.arcane.iris.core.loader.IrisRegistrant; import art.arcane.iris.core.nms.INMS; import art.arcane.iris.engine.data.cache.AtomicCache; import art.arcane.iris.engine.object.annotations.*; +import art.arcane.iris.platform.bukkit.BukkitBlockState; +import art.arcane.iris.spi.PlatformBlockState; import art.arcane.volmlib.util.collection.KList; import art.arcane.volmlib.util.collection.KMap; import art.arcane.iris.util.common.data.B; @@ -47,7 +49,7 @@ import java.util.Map; @Data @EqualsAndHashCode(callSuper = false) public class IrisBlockData extends IrisRegistrant { - private final transient AtomicCache blockdata = new AtomicCache<>(); + private final transient AtomicCache blockdata = new AtomicCache<>(); private final transient AtomicCache realProperties = new AtomicCache<>(); @RegistryListBlockType @Required @@ -139,7 +141,7 @@ public class IrisBlockData extends IrisRegistrant { return computeProperties(getData()); } - public BlockData getBlockData(IrisData data) { + public PlatformBlockState getBlockData(IrisData data) { return blockdata.aquire(() -> { BlockData b = null; @@ -147,7 +149,8 @@ public class IrisBlockData extends IrisRegistrant { IrisBlockData customData = data.getBlockLoader().load(getBlock(), false); if (customData != null) { - b = customData.getBlockData(data); + PlatformBlockState customState = customData.getBlockData(data); + b = customState == null ? null : (BlockData) customState.nativeHandle(); if (b != null) { b = b.clone(); @@ -173,11 +176,11 @@ public class IrisBlockData extends IrisRegistrant { BlockData bx = B.get(sx); if (bx != null) { - return bx; + return BukkitBlockState.of(bx); } if (b != null) { - return b; + return BukkitBlockState.of(b); } } } @@ -190,20 +193,20 @@ public class IrisBlockData extends IrisRegistrant { } if (b != null) { - return b; + return BukkitBlockState.of(b); } if (backup != null) { return backup.getBlockData(data); } - return B.get("AIR"); + return B.getState("AIR"); }); } public TileData tryGetTile(IrisData data) { //TODO Do like a registry thing with the tile data registry. Also update the parsing of data to include **block** entities. - var type = getBlockData(data).getMaterial(); + Material type = ((BlockData) getBlockData(data).nativeHandle()).getMaterial(); if (type == Material.SPAWNER && this.data.containsKey("entitySpawn")) { String id = (String) this.data.get("entitySpawn"); if (tileData == null) tileData = new KMap<>(); diff --git a/core/src/main/java/art/arcane/iris/engine/object/IrisBlockDrops.java b/core/src/main/java/art/arcane/iris/engine/object/IrisBlockDrops.java index 72e26cb67..907a1e5ef 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/IrisBlockDrops.java +++ b/core/src/main/java/art/arcane/iris/engine/object/IrisBlockDrops.java @@ -29,6 +29,7 @@ import art.arcane.volmlib.util.math.RNG; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import art.arcane.iris.spi.PlatformBlockState; import lombok.experimental.Accessors; import org.bukkit.block.data.BlockData; import org.bukkit.inventory.ItemStack; @@ -60,10 +61,10 @@ public class IrisBlockDrops { KList b = new KList<>(); for (IrisBlockData i : getBlocks()) { - BlockData dd = i.getBlockData(rdata); + PlatformBlockState state = i.getBlockData(rdata); - if (dd != null) { - b.add(dd); + if (state != null) { + b.add((BlockData) state.nativeHandle()); } } diff --git a/core/src/main/java/art/arcane/iris/engine/object/IrisCaveShape.java b/core/src/main/java/art/arcane/iris/engine/object/IrisCaveShape.java index 4a845f853..304533ee8 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/IrisCaveShape.java +++ b/core/src/main/java/art/arcane/iris/engine/object/IrisCaveShape.java @@ -1,6 +1,7 @@ package art.arcane.iris.engine.object; import art.arcane.iris.engine.framework.Engine; +import org.bukkit.block.data.BlockData; import art.arcane.iris.engine.object.annotations.*; import art.arcane.volmlib.util.collection.KMap; import art.arcane.volmlib.util.collection.KSet; @@ -43,7 +44,7 @@ public class IrisCaveShape { return cache.computeIfAbsent(randomRotation(rng), pos -> { var rotated = new KSet(); engine.getData().getObjectLoader().load(object).getBlocks().forEach((vector, data) -> { - if (data.getMaterial().isAir()) return; + if (((BlockData) data.nativeHandle()).getMaterial().isAir()) return; rotated.add(new IrisPosition(objectRotation.rotate(vector, pos.getX(), pos.getY(), pos.getZ()))); }); return rotated; diff --git a/core/src/main/java/art/arcane/iris/engine/object/IrisDecorator.java b/core/src/main/java/art/arcane/iris/engine/object/IrisDecorator.java index 95c6a7012..3fb20f438 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/IrisDecorator.java +++ b/core/src/main/java/art/arcane/iris/engine/object/IrisDecorator.java @@ -28,8 +28,8 @@ import art.arcane.iris.util.project.noise.CNG; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import art.arcane.iris.spi.PlatformBlockState; import lombok.experimental.Accessors; -import org.bukkit.block.data.BlockData; @Snippet("decorator") @Accessors(chain = true) @@ -41,10 +41,10 @@ public class IrisDecorator { private final transient AtomicCache layerGenerator = new AtomicCache<>(); private final transient AtomicCache varianceGenerator = new AtomicCache<>(); private final transient AtomicCache heightGenerator = new AtomicCache<>(); - private final transient AtomicCache> blockData = new AtomicCache<>(); - private final transient AtomicCache> blockDataTops = new AtomicCache<>(); - private final transient AtomicCache blockDataArray = new AtomicCache<>(); - private final transient AtomicCache blockDataTopsArray = new AtomicCache<>(); + private final transient AtomicCache> blockData = new AtomicCache<>(); + private final transient AtomicCache> blockDataTops = new AtomicCache<>(); + private final transient AtomicCache blockDataArray = new AtomicCache<>(); + private final transient AtomicCache blockDataTopsArray = new AtomicCache<>(); @Desc("The varience dispersion is used when multiple blocks are put in the palette. Scatter scrambles them, Wispy shows streak-looking varience") private IrisGeneratorStyle variance = NoiseStyle.STATIC.style(); @Desc("Forcefully place this decorant anywhere it is supposed to go even if it should not go on a specific surface block. For example, you could force tallgrass to place on top of stone by using this.") @@ -145,7 +145,7 @@ public class IrisDecorator { return getGenerator(rng, data).fitDouble(0D, 1D, xx, zz) <= chance; } - public BlockData getBlockData(IrisBiome b, RNG rng, double x, double z, IrisData data) { + public PlatformBlockState getBlockData(IrisBiome b, RNG rng, double x, double z, IrisData data) { if (!passesChanceGate(rng, x, z, data)) { return null; } @@ -155,7 +155,7 @@ public class IrisDecorator { return getVarianceGenerator(rng, data).fit(getBlockData(data), z, x); } - public BlockData getBlockData100(IrisBiome b, RNG rng, double x, double y, double z, IrisData data) { + public PlatformBlockState getBlockData100(IrisBiome b, RNG rng, double x, double y, double z, IrisData data) { if (getBlockData(data).isEmpty()) { Iris.warn("Empty Block Data for " + b.getName()); return null; @@ -175,10 +175,10 @@ public class IrisDecorator { return getBlockData(data).get(0); } - return getVarianceGenerator(rng, data).fit(getBlockData(data), z, y, x).clone(); //X and Z must be switched + return getVarianceGenerator(rng, data).fit(getBlockData(data), z, y, x); //X and Z must be switched } - public BlockData getBlockDataForTop(IrisBiome b, RNG rng, double x, double y, double z, IrisData data) { + public PlatformBlockState getBlockDataForTop(IrisBiome b, RNG rng, double x, double y, double z, IrisData data) { if (getBlockDataTops(data).isEmpty()) { return getBlockData100(b, rng, x, y, z, data); } @@ -197,12 +197,12 @@ public class IrisDecorator { return null; } - public KList getBlockData(IrisData data) { + public KList getBlockData(IrisData data) { return blockData.aquire(() -> { - KList blockData = new KList<>(); + KList blockData = new KList<>(); for (IrisBlockData i : palette) { - BlockData bx = i.getBlockData(data); + PlatformBlockState bx = i.getBlockData(data); if (bx != null) { for (int n = 0; n < i.getWeight(); n++) { blockData.add(bx); @@ -214,12 +214,12 @@ public class IrisDecorator { }); } - public KList getBlockDataTops(IrisData data) { + public KList getBlockDataTops(IrisData data) { return blockDataTops.aquire(() -> { - KList blockDataTops = new KList<>(); + KList blockDataTops = new KList<>(); for (IrisBlockData i : topPalette) { - BlockData bx = i.getBlockData(data); + PlatformBlockState bx = i.getBlockData(data); if (bx != null) { for (int n = 0; n < i.getWeight(); n++) { blockDataTops.add(bx); @@ -231,22 +231,22 @@ public class IrisDecorator { }); } - public BlockData[] getBlockDataArray(IrisData data) { + public PlatformBlockState[] getBlockDataArray(IrisData data) { return blockDataArray.aquire(() -> { - KList list = getBlockData(data); - return list.toArray(new BlockData[0]); + KList list = getBlockData(data); + return list.toArray(new PlatformBlockState[0]); }); } - public BlockData[] getBlockDataTopsArray(IrisData data) { + public PlatformBlockState[] getBlockDataTopsArray(IrisData data) { return blockDataTopsArray.aquire(() -> { - KList list = getBlockDataTops(data); - return list.toArray(new BlockData[0]); + KList list = getBlockDataTops(data); + return list.toArray(new PlatformBlockState[0]); }); } - public BlockData pickBlockData(RNG rng, IrisData data, double x, double z) { - BlockData[] arr = getBlockDataArray(data); + public PlatformBlockState pickBlockData(RNG rng, IrisData data, double x, double z) { + PlatformBlockState[] arr = getBlockDataArray(data); if (arr.length == 0) { return null; } @@ -256,8 +256,8 @@ public class IrisDecorator { return arr[Math.abs((int) getVarianceGenerator(rng, data).fit(0, arr.length - 1, z, x))]; } - public BlockData pickBlockDataTop(RNG rng, IrisData data, double x, double z) { - BlockData[] arr = getBlockDataTopsArray(data); + public PlatformBlockState pickBlockDataTop(RNG rng, IrisData data, double x, double z) { + PlatformBlockState[] arr = getBlockDataTopsArray(data); if (arr.length == 0) { return pickBlockData(rng, data, x, z); } diff --git a/core/src/main/java/art/arcane/iris/engine/object/IrisDepositGenerator.java b/core/src/main/java/art/arcane/iris/engine/object/IrisDepositGenerator.java index cc1742217..dae7cc05a 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/IrisDepositGenerator.java +++ b/core/src/main/java/art/arcane/iris/engine/object/IrisDepositGenerator.java @@ -29,8 +29,8 @@ import art.arcane.volmlib.util.math.RNG; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import art.arcane.iris.spi.PlatformBlockState; import lombok.experimental.Accessors; -import org.bukkit.block.data.BlockData; @Snippet("deposit") @Accessors(chain = true) @@ -40,7 +40,7 @@ import org.bukkit.block.data.BlockData; @Data public class IrisDepositGenerator { private final transient AtomicCache> objects = new AtomicCache<>(); - private final transient AtomicCache> blockData = new AtomicCache<>(); + private final transient AtomicCache> blockData = new AtomicCache<>(); @Required @MinNumber(0) @MaxNumber(8192) // TODO: WARNING HEIGHT @@ -156,17 +156,17 @@ public class IrisDepositGenerator { return o; } - private BlockData nextBlock(RNG rngv, IrisData rdata) { + private PlatformBlockState nextBlock(RNG rngv, IrisData rdata) { return getBlockData(rdata).get(rngv.i(0, getBlockData(rdata).size())); } - public KList getBlockData(IrisData rdata) { + public KList getBlockData(IrisData rdata) { return blockData.aquire(() -> { - KList blockData = new KList<>(); + KList blockData = new KList<>(); for (IrisBlockData ix : palette) { - BlockData bx = ix.getBlockData(rdata); + PlatformBlockState bx = ix.getBlockData(rdata); if (bx != null) { blockData.add(bx); diff --git a/core/src/main/java/art/arcane/iris/engine/object/IrisDepositVariant.java b/core/src/main/java/art/arcane/iris/engine/object/IrisDepositVariant.java index a956392ea..85997ce16 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/IrisDepositVariant.java +++ b/core/src/main/java/art/arcane/iris/engine/object/IrisDepositVariant.java @@ -30,6 +30,8 @@ import art.arcane.volmlib.util.collection.KMap; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import art.arcane.iris.platform.bukkit.BukkitBlockState; +import art.arcane.iris.spi.PlatformBlockState; import lombok.experimental.Accessors; import org.bukkit.Material; import org.bukkit.block.data.BlockData; @@ -59,13 +61,14 @@ public class IrisDepositVariant { @Desc("Source block id (for example `minecraft:iron_ore`) -> replacement block id (for example `minecraft:deepslate_iron_ore`). Any block id the data loader resolves is accepted, including external/mod blocks. Source match is by material only, so block properties on the source key are ignored.") private KMap remap = new KMap<>(); - public BlockData remapOrNull(BlockData ore, IrisData rdata) { + public PlatformBlockState remapOrNull(PlatformBlockState ore, IrisData rdata) { if (ore == null || remap == null || remap.isEmpty()) { return null; } KMap map = resolved.aquire(() -> buildResolved(rdata)); - return map.get(ore.getMaterial()); + BlockData target = map.get(((BlockData) ore.nativeHandle()).getMaterial()); + return target == null ? null : BukkitBlockState.of(target); } private KMap buildResolved(IrisData rdata) { diff --git a/core/src/main/java/art/arcane/iris/engine/object/IrisDimension.java b/core/src/main/java/art/arcane/iris/engine/object/IrisDimension.java index d6ad1664d..6ea6c9192 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/IrisDimension.java +++ b/core/src/main/java/art/arcane/iris/engine/object/IrisDimension.java @@ -1,631 +1,632 @@ -/* - * Iris is a World Generator for Minecraft Bukkit Servers - * Copyright (c) 2022 Arcane Arts (Volmit Software) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package art.arcane.iris.engine.object; - -import art.arcane.iris.Iris; -import art.arcane.iris.core.IrisSettings; -import art.arcane.iris.core.ServerConfigurator.DimensionHeight; -import art.arcane.iris.core.loader.IrisData; -import art.arcane.iris.core.loader.IrisRegistrant; -import art.arcane.iris.core.nms.INMS; -import art.arcane.iris.core.nms.datapack.IDataFixer; -import art.arcane.iris.core.nms.datapack.IDataFixer.Dimension; -import art.arcane.iris.engine.data.cache.AtomicCache; -import art.arcane.iris.engine.object.annotations.*; -import art.arcane.iris.engine.object.annotations.functions.ComponentFlagFunction; -import com.google.gson.annotations.SerializedName; -import art.arcane.volmlib.util.collection.KList; -import art.arcane.volmlib.util.collection.KMap; -import art.arcane.volmlib.util.collection.KSet; -import art.arcane.iris.util.common.data.DataProvider; -import art.arcane.volmlib.util.io.IO; -import art.arcane.volmlib.util.json.JSONArray; -import art.arcane.volmlib.util.json.JSONObject; -import art.arcane.volmlib.util.mantle.flag.MantleFlag; -import art.arcane.volmlib.util.math.Position2; -import art.arcane.volmlib.util.math.RNG; -import art.arcane.iris.util.project.noise.CNG; -import art.arcane.iris.util.common.plugin.VolmitSender; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; -import lombok.experimental.Accessors; -import org.bukkit.Material; -import org.bukkit.NamespacedKey; -import org.bukkit.World.Environment; -import org.bukkit.block.Biome; -import org.bukkit.block.data.BlockData; - -import java.io.*; -import java.nio.file.AtomicMoveNotSupportedException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardCopyOption; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; - -@Accessors(chain = true) -@AllArgsConstructor -@NoArgsConstructor -@Desc("Represents a dimension") -@Data -@EqualsAndHashCode(callSuper = false) -public class IrisDimension extends IrisRegistrant { - public static final BlockData STONE = Material.STONE.createBlockData(); - public static final BlockData WATER = Material.WATER.createBlockData(); - private final transient AtomicCache parallaxSize = new AtomicCache<>(); - private final transient AtomicCache rockLayerGenerator = new AtomicCache<>(); - private final transient AtomicCache fluidLayerGenerator = new AtomicCache<>(); - private final transient AtomicCache coordFracture = new AtomicCache<>(); - private final transient AtomicCache sinr = new AtomicCache<>(); - private final transient AtomicCache cosr = new AtomicCache<>(); - private final transient AtomicCache rad = new AtomicCache<>(); - private final transient AtomicCache featuresUsed = new AtomicCache<>(); - private final transient AtomicCache> carvingEntryIndex = new AtomicCache<>(); - private final transient AtomicCache> surfaceOreCache = new AtomicCache<>(); - private final transient AtomicCache> undergroundOreCache = new AtomicCache<>(); - @MinNumber(2) - @Required - @Desc("The human readable name of this dimension") - private String name = "A Dimension"; - @MinNumber(1) - @MaxNumber(2032) - @Desc("Maximum height at which players can be teleported to through gameplay.") - private int logicalHeight = 256; - @Desc("If set to true, Iris will remove chunks to allow visualizing cross sections of chunks easily") - private boolean debugChunkCrossSections = false; - @Desc("Vertically split up the biome palettes with 3 air blocks in between to visualize them") - private boolean explodeBiomePalettes = false; - @Desc("Studio Mode for testing different parts of the world") - private StudioMode studioMode = StudioMode.NORMAL; - @MinNumber(1) - @MaxNumber(16) - @Desc("Customize the palette height explosion") - private int explodeBiomePaletteSize = 3; - @MinNumber(2) - @MaxNumber(16) - @Desc("Every X/Z % debugCrossSectionsMod == 0 cuts the chunk") - private int debugCrossSectionsMod = 3; - @Desc("Tree growth override settings") - private IrisTreeSettings treeSettings = new IrisTreeSettings(); - @Desc("Spawn Entities in this dimension over time. Iris will continually replenish these mobs just like vanilla does.") - @ArrayType(min = 1, type = String.class) - @RegistryListResource(IrisSpawner.class) - private KList entitySpawners = new KList<>(); - @Desc("Reference loot tables in this area") - private IrisLootReference loot = new IrisLootReference(); - @MinNumber(0) - @Desc("The version of this dimension. Changing this will stop users from accidentally upgrading (and breaking their worlds).") - private int version = 1; - @ArrayType(min = 1, type = IrisBlockDrops.class) - @Desc("Define custom block drops for this dimension") - private KList blockDrops = new KList<>(); - @Desc("Should bedrock be generated or not.") - private boolean bedrock = true; - @MinNumber(0) - @MaxNumber(1) - @Desc("The land chance. Up to 1.0 for total land or 0.0 for total sea") - private double landChance = 0.625; - @Desc("The placement style of regions") - private IrisGeneratorStyle regionStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style(); - @Desc("The placement style of land/sea") - private IrisGeneratorStyle continentalStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style(); - @Desc("The placement style of biomes") - private IrisGeneratorStyle landBiomeStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style(); - @Desc("The placement style of biomes") - private IrisGeneratorStyle shoreBiomeStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style(); - @Desc("The placement style of biomes") - private IrisGeneratorStyle seaBiomeStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style(); - @Desc("The placement style of biomes") - private IrisGeneratorStyle caveBiomeStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style(); - @Desc("Instead of filling objects with air, fills them with cobweb so you can see them") - private boolean debugSmartBore = false; - @Desc("Generate decorations or not") - private boolean decorate = true; - @Desc("When true, every ore block the generator would place (terrain ores, deposits, ores inside objects) is replaced with its base material such as stone, deepslate or netherrack, so drop-control plugins like HiddenOre can manage ore rewards themselves") - private boolean hideOresForHiddenOre = false; - @Desc("Use post processing or not") - private boolean postProcessing = true; - @Desc("Add slabs in post processing") - private boolean postProcessingSlabs = true; - @Desc("Add painted walls in post processing") - private boolean postProcessingWalls = true; - @Desc("Enable or disable all carving for this dimension") - private boolean carvingEnabled = true; - @ArrayType(type = IrisDimensionCarvingEntry.class, min = 1) - @Desc("Dimension-level cave biome carving overrides with absolute world Y ranges") - private KList carving = new KList<>(); - @Desc("Profile-driven 3D cave configuration") - private IrisCaveProfile caveProfile = new IrisCaveProfile(); - @Desc("Configuration of fluid bodies such as rivers & lakes") - private IrisFluidBodies fluidBodies = new IrisFluidBodies(); - @Desc("forceConvertTo320Height") - private Boolean forceConvertTo320Height = false; - @Desc("The world environment") - private Environment environment = Environment.NORMAL; - @RegistryListResource(IrisRegion.class) - @Required - @ArrayType(min = 1, type = String.class) - @Desc("Define all of the regions to include in this dimension. Dimensions -> Regions -> Biomes -> Objects etc") - private KList regions = new KList<>(); - @Required - @MinNumber(0) - @MaxNumber(1024) - @Desc("The fluid height for this dimension") - private int fluidHeight = 63; - @Desc("Define the min and max Y bounds of this dimension. Please keep in mind that Iris internally generates from 0 to (max - min). \n\nFor example at -64 to 320, Iris is internally generating to 0 to 384, then on outputting chunks, it shifts it down by the min height (64 blocks). The default is -64 to 320. \n\nThe fluid height is placed at (fluid height + min height). So a fluid height of 63 would actually show up in the world at 1.") - private IrisRange dimensionHeight = new IrisRange(-64, 320); - @Desc("Define options for this dimension") - private IrisDimensionTypeOptions dimensionOptions = new IrisDimensionTypeOptions(); - @Desc("When true, sets the dimension's ambient light to maximum, making all blocks fully lit regardless of light level.") - private boolean fullbright = false; - @RegistryListResource(IrisDimension.class) - @Desc("When set, generates the referenced dimension's terrain upside-down at the world ceiling, creating a nether-like canopy. Use the dimension's load key (e.g., 'overworld'). Set to 'none' to disable.") - private String upperDimension = "none"; - @MinNumber(0) - @MaxNumber(256) - @Desc("Minimum air gap in blocks between the lower terrain surface and the upper terrain surface.") - private int upperDimensionGap = 32; - @Desc("When true, cave carving will cut through the upper dimension terrain. When false, the upper terrain is a solid untouched mass.") - private boolean upperDimensionCarving = false; - @Desc("When true, objects from the mantle (structures, trees, etc.) can be placed in the upper dimension terrain zone. When false, the upper terrain is protected from object placement.") - private boolean upperDimensionObjects = false; - @Desc("When true, upper-dimension objects force-place regardless of placement restrictions (slope, underwater, clamp, collisions, carving). Normal dimension objects always place first; upper objects place second and may clip or occlude lower-dimension placements when this is enabled.") - private boolean upperObjectsForcePlace = false; - @RegistryListResource(IrisBiome.class) - @Desc("Keep this either undefined or empty. Setting any biome name into this will force iris to only generate the specified biome. Great for testing.") - private String focus = ""; - @RegistryListResource(IrisRegion.class) - @Desc("Keep this either undefined or empty. Setting any region name into this will force iris to only generate the specified region. Great for testing.") - private String focusRegion = ""; - @MinNumber(0.0001) - @MaxNumber(512) - @Desc("Zoom in or out the biome size. Higher = bigger biomes") - private double biomeZoom = 1D; - @MinNumber(0) - @MaxNumber(360) - @Desc("You can rotate the input coordinates by an angle. This can make terrain appear more natural (less sharp corners and lines). This literally rotates the entire dimension by an angle. Hint: Try 12 degrees or something not on a 90 or 45 degree angle.") - private double dimensionAngleDeg = 0; - @Required - @Desc("Define the mode of this dimension (required!)") - private IrisDimensionMode mode = new IrisDimensionMode(); - @MinNumber(0) - @MaxNumber(8192) - @Desc("Coordinate fracturing applies noise to the input coordinates. This creates the 'iris swirls' and wavy features. The distance pushes these waves further into places they shouldnt be. This is a block value multiplier.") - private double coordFractureDistance = 20; - @MinNumber(0.0001) - @MaxNumber(512) - @Desc("Coordinate fracturing zoom. Higher = less frequent warping, Lower = more frequent and rapid warping / swirls.") - private double coordFractureZoom = 8; - @MinNumber(0.0001) - @MaxNumber(512) - @Desc("This zooms in the land space") - private double landZoom = 1; - @MinNumber(0.0001) - @MaxNumber(512) - @Desc("This zooms oceanic biomes") - private double seaZoom = 1; - @MinNumber(0.0001) - @MaxNumber(512) - @Desc("Zoom in continents") - private double continentZoom = 1; - @MinNumber(0.0001) - @MaxNumber(512) - @Desc("Change the size of regions") - private double regionZoom = 1; - @Desc("Disable this to stop placing objects, entities, features & updates") - private boolean useMantle = true; - @Desc("Prevent Leaf decay as if placed in creative mode") - private boolean preventLeafDecay = false; - @ArrayType(min = 1, type = IrisDepositGenerator.class) - @Desc("Define global deposit generators") - private KList deposits = new KList<>(); - @ArrayType(min = 1, type = IrisDepositVariant.class) - @Desc("Dimension-wide deposit ore remap rules. Each entry declares a vertical band and a source->replacement block id map. Applied after biome and region rules; first matching dimension rule wins.") - private KList depositVariants = new KList<>(); - @ArrayType(min = 1, type = IrisShapedGeneratorStyle.class) - @Desc("Overlay additional noise on top of the interoplated terrain.") - private KList overlayNoise = new KList<>(); - @MinNumber(0.0001) - @MaxNumber(512) - @Desc("The rock zoom mostly for zooming in on a wispy palette") - private double rockZoom = 5; - @Desc("The palette of blocks for 'stone'") - private IrisMaterialPalette rockPalette = new IrisMaterialPalette().qclear().qadd("stone"); - @Desc("The palette of blocks for 'water'") - private IrisMaterialPalette fluidPalette = new IrisMaterialPalette().qclear().qadd("water"); - @Desc("Prevent cartographers to generate explorer maps (Iris worlds only)\nONLY TOUCH IF YOUR SERVER CRASHES WHILE GENERATING EXPLORER MAPS") - private boolean disableExplorerMaps = false; - @Desc("Collection of ores to be generated") - @ArrayType(type = IrisOreGenerator.class, min = 1) - private KList ores = new KList<>(); - @Desc("Dimension-wide Iris structure placements, independent of biome/region placements") - @ArrayType(type = IrisStructurePlacement.class, min = 1) - private KList structures = new KList<>(); - @Desc("Controls native vanilla & ingested datapack structure generation for this dimension. Defaults to ALL_ON. The 'disabled'/'enabled' lists autocomplete every live vanilla and ingested datapack structure key.") - private IrisImportedStructureControl importedStructures = new IrisImportedStructureControl(); - @ArrayType(type = String.class, min = 1) - @Desc("External datapack imports for this dimension. List Modrinth datapack page URLs ('https://modrinth.com/datapack/' resolves the latest datapack version, or a specific '.../version/' link pins a version) or a direct .zip URL. Run '/iris datapack ingest' (or '/iris ingest') to download/update them and install them into the world's datapacks folder. Once ingested, their structures behave exactly like vanilla jigsaw structures. To REPLACE a vanilla structure with an imported one, add a 'structures' placement (route IRIS_PLACED) referencing the imported structure key (which carries the matching 'vanillaSource', e.g. 'minecraft:stronghold'): its vanilla counterpart is then automatically suppressed, so it never double-generates - no 'importedStructures.disabled' entry needed. Use 'importedStructures.disabled' only to turn a vanilla structure OFF entirely when you are NOT placing a replacement, or place any imported structure key arbitrarily through a 'structures' placement.") - private KList datapackImports = new KList<>(); - @MinNumber(0) - @MaxNumber(318) - @Desc("The Subterrain Fluid Layer Height") - private int caveLavaHeight = 8; - @RegistryListFunction(ComponentFlagFunction.class) - @ArrayType(type = String.class) - @Desc("Collection of disabled components") - private KList disabledComponents = new KList<>(); - - public int getMaxHeight() { - return (int) getDimensionHeight().getMax(); - } - - public int getMinHeight() { - return (int) getDimensionHeight().getMin(); - } - - public Map getCarvingEntryIndex() { - return carvingEntryIndex.aquire(() -> { - Map index = new HashMap<>(); - KList entries = getCarving(); - if (entries == null || entries.isEmpty()) { - return index; - } - - for (IrisDimensionCarvingEntry entry : entries) { - if (entry == null) { - continue; - } - - String entryId = entry.getId(); - if (entryId == null || entryId.isBlank()) { - continue; - } - - index.put(entryId.trim(), entry); - } - - return index; - }); - } - - public void setCarving(KList carving) { - this.carving = carving == null ? new KList<>() : carving; - carvingEntryIndex.reset(); - } - - public BlockData generateOres(int x, int y, int z, RNG rng, IrisData data, boolean surface) { - KList localOres = surface ? getSurfaceOres() : getUndergroundOres(); - return generateOres(localOres, x, y, z, rng, data); - } - - public BlockData generateSurfaceOres(int x, int y, int z, RNG rng, IrisData data) { - return generateOres(getSurfaceOres(), x, y, z, rng, data); - } - - public BlockData generateUndergroundOres(int x, int y, int z, RNG rng, IrisData data) { - return generateOres(getUndergroundOres(), x, y, z, rng, data); - } - - public boolean hasSurfaceOres() { - return !getSurfaceOres().isEmpty(); - } - - public boolean hasUndergroundOres() { - return !getUndergroundOres().isEmpty(); - } - - private BlockData generateOres(KList localOres, int x, int y, int z, RNG rng, IrisData data) { - if (localOres.isEmpty()) { - return null; - } - - int oreCount = localOres.size(); - for (int oreIndex = 0; oreIndex < oreCount; oreIndex++) { - IrisOreGenerator oreGenerator = localOres.get(oreIndex); - BlockData ore = oreGenerator.generate(x, y, z, rng, data); - if (ore != null) { - return ore; - } - } - return null; - } - - public void setOres(KList ores) { - this.ores = ores == null ? new KList<>() : ores; - surfaceOreCache.reset(); - undergroundOreCache.reset(); - } - - private KList getSurfaceOres() { - return getOres(true); - } - - private KList getUndergroundOres() { - return getOres(false); - } - - private KList getOres(boolean surface) { - AtomicCache> oreCache = surface ? surfaceOreCache : undergroundOreCache; - return oreCache.aquire(() -> { - KList filtered = new KList<>(); - KList localOres = ores; - int oreCount = localOres.size(); - for (int oreIndex = 0; oreIndex < oreCount; oreIndex++) { - IrisOreGenerator oreGenerator = localOres.get(oreIndex); - if (oreGenerator.isGenerateSurface() == surface) { - filtered.add(oreGenerator); - } - } - - return filtered; - }); - } - - public int getFluidHeight() { - return fluidHeight - (int) dimensionHeight.getMin(); - } - - public CNG getCoordFracture(RNG rng, int signature) { - return coordFracture.aquire(() -> - { - CNG coordFracture = CNG.signature(rng.nextParallelRNG(signature)); - coordFracture.scale(0.012 / coordFractureZoom); - return coordFracture; - }); - } - - public double getDimensionAngle() { - return rad.aquire(() -> Math.toRadians(dimensionAngleDeg)); - } - - public Environment getEnvironment() { - return environment; - } - - public boolean hasFocusRegion() { - return !focusRegion.equals(""); - } - - public String getFocusRegion() { - return focusRegion; - } - - public double sinRotate() { - return sinr.aquire(() -> Math.sin(getDimensionAngle())); - } - - public double cosRotate() { - return cosr.aquire(() -> Math.cos(getDimensionAngle())); - } - - public KList getAllRegions(DataProvider g) { - KList r = new KList<>(); - - for (String i : getRegions()) { - r.add(g.getData().getRegionLoader().load(i)); - } - - return r; - } - - public KList getAllAnyRegions() { - KList r = new KList<>(); - - for (String i : getRegions()) { - r.add(IrisData.loadAnyRegion(i, getLoader())); - } - - return r; - } - - public KList getAllBiomes(DataProvider g) { - return g.getData().getBiomeLoader().loadAll(g.getData().getBiomeLoader().getPossibleKeys()); - } - - public KList getAllAnyBiomes() { - KList r = new KList<>(); - - for (IrisRegion i : getAllAnyRegions()) { - if (i == null) { - continue; - } - - r.addAll(i.getAllAnyBiomes()); - } - - return r; - } - - public IrisGeneratorStyle getBiomeStyle(InferredType type) { - switch (type) { - case CAVE: - return caveBiomeStyle; - case LAND: - return landBiomeStyle; - case SEA: - return seaBiomeStyle; - case SHORE: - return shoreBiomeStyle; - default: - break; - } - - return landBiomeStyle; - } - - public void installBiomes(IDataFixer fixer, DataProvider data, KList folders, KSet biomes) { - String namespace = getLoadKey().toLowerCase(Locale.ROOT); - - for (IrisBiome irisBiome : getAllBiomes(data)) { - if (!irisBiome.isCustom()) { - continue; - } - - for (IrisBiomeCustom customBiome : irisBiome.getCustomDerivitives()) { - String customBiomeId = customBiome.getId(); - String json = customBiome.generateJson(fixer); - - synchronized (biomes) { - if (!biomes.add(customBiomeId)) { - Iris.verbose("Duplicate Data Pack Biome: " + getLoadKey() + "/" + customBiomeId); - continue; - } - } - - for (File datapacks : folders) { - File output = new File(datapacks, "iris/data/" + namespace + "/worldgen/biome/" + customBiomeId + ".json"); - - Iris.verbose(" Installing Data Pack Biome: " + output.getPath()); - output.getParentFile().mkdirs(); - try { - IO.writeAll(output, json); - } catch (IOException e) { - Iris.reportError(e); - e.printStackTrace(); - } - } - } - } - } - - public Dimension getBaseDimension() { - return switch (getEnvironment()) { - case NETHER -> Dimension.NETHER; - case THE_END -> Dimension.END; - default -> Dimension.OVERWORLD; - }; - } - - public String getDimensionTypeKey() { - return sanitizeDimensionTypeKeyValue(getLoadKey()); - } - - public static String sanitizeDimensionTypeKeyValue(String value) { - if (value == null || value.isBlank()) { - return "dimension"; - } - - String sanitized = value.trim().toLowerCase(Locale.ROOT).replace("\\", "/"); - sanitized = sanitized.replaceAll("[^a-z0-9_\\-./]", "_"); - sanitized = sanitized.replaceAll("/+", "/"); - sanitized = sanitized.replaceAll("^/+", ""); - sanitized = sanitized.replaceAll("/+$", ""); - if (sanitized.contains("..")) { - sanitized = sanitized.replace("..", "_"); - } - - sanitized = sanitized.replace("/", "_"); - return sanitized.isBlank() ? "dimension" : sanitized; - } - - public IrisDimensionType getDimensionType() { - IrisDimensionTypeOptions options = getDimensionOptions(); - if (fullbright) { - options = options.copy().ambientLight(1.0f); - } - return new IrisDimensionType(getBaseDimension(), options, getLogicalHeight(), getMaxHeight() - getMinHeight(), getMinHeight()); - } - - public boolean hasUpperDimension() { - return upperDimension != null && !upperDimension.isEmpty() && !upperDimension.equalsIgnoreCase("none"); - } - - public void installDimensionType(IDataFixer fixer, KList folders) { - IrisDimensionType type = getDimensionType(); - String json = type.toJson(fixer); - String dimensionTypeKey = getDimensionTypeKey(); - - Iris.verbose(" Installing Data Pack Dimension Type: \"iris:" + dimensionTypeKey + '"'); - for (File datapacks : folders) { - File output = new File(datapacks, "iris/data/iris/dimension_type/" + dimensionTypeKey + ".json"); - output.getParentFile().mkdirs(); - try { - IO.writeAll(output, json); - } catch (IOException e) { - Iris.reportError(e); - e.printStackTrace(); - } - } - } - - @Override - public String getFolderName() { - return "dimensions"; - } - - @Override - public String getTypeName() { - return "Dimension"; - } - - @Override - public void scanForErrors(JSONObject p, VolmitSender sender) { - - } - - public static void writeShared(KList folders, DimensionHeight height) { - Iris.verbose(" Installing Data Pack Vanilla Dimension Types"); - String[] jsonStrings = height.jsonStrings(); - for (File datapacks : folders) { - write(datapacks, "overworld", jsonStrings[0]); - write(datapacks, "the_nether", jsonStrings[1]); - write(datapacks, "the_end", jsonStrings[2]); - } - - String raw = """ - { - "pack": { - "description": "Iris Data Pack. This pack contains all installed Iris Packs' resources.", - "pack_format": {}, - "min_format": {}, - "max_format": {} - } - } - """.replace("{}", INMS.get().getDataVersion().getPackFormat() + ""); - - for (File datapacks : folders) { - File mcm = new File(datapacks, "iris/pack.mcmeta"); - try { - IO.writeAll(mcm, raw); - } catch (IOException e) { - Iris.reportError(e); - e.printStackTrace(); - } - Iris.verbose(" Installing Data Pack MCMeta: " + mcm.getPath()); - } - } - - private static void write(File datapacks, String type, String json) { - if (json == null) return; - File dimTypeVanilla = new File(datapacks, "iris/data/minecraft/dimension_type/" + type + ".json"); - - if (IrisSettings.get().getGeneral().adjustVanillaHeight || dimTypeVanilla.exists()) { - dimTypeVanilla.getParentFile().mkdirs(); - try { - IO.writeAll(dimTypeVanilla, json); - } catch (IOException e) { - Iris.reportError(e); - e.printStackTrace(); - } - } - } -} +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2022 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package art.arcane.iris.engine.object; + +import art.arcane.iris.Iris; +import art.arcane.iris.core.IrisSettings; +import art.arcane.iris.core.ServerConfigurator.DimensionHeight; +import art.arcane.iris.core.loader.IrisData; +import art.arcane.iris.platform.bukkit.BukkitBlockState; +import art.arcane.iris.spi.PlatformBlockState; +import art.arcane.iris.core.loader.IrisRegistrant; +import art.arcane.iris.core.nms.INMS; +import art.arcane.iris.core.nms.datapack.IDataFixer; +import art.arcane.iris.core.nms.datapack.IDataFixer.Dimension; +import art.arcane.iris.engine.data.cache.AtomicCache; +import art.arcane.iris.engine.object.annotations.*; +import art.arcane.iris.engine.object.annotations.functions.ComponentFlagFunction; +import com.google.gson.annotations.SerializedName; +import art.arcane.volmlib.util.collection.KList; +import art.arcane.volmlib.util.collection.KMap; +import art.arcane.volmlib.util.collection.KSet; +import art.arcane.iris.util.common.data.DataProvider; +import art.arcane.volmlib.util.io.IO; +import art.arcane.volmlib.util.json.JSONArray; +import art.arcane.volmlib.util.json.JSONObject; +import art.arcane.volmlib.util.mantle.flag.MantleFlag; +import art.arcane.volmlib.util.math.Position2; +import art.arcane.volmlib.util.math.RNG; +import art.arcane.iris.util.project.noise.CNG; +import art.arcane.iris.util.common.plugin.VolmitSender; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; +import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.World.Environment; +import org.bukkit.block.Biome; + +import java.io.*; +import java.nio.file.AtomicMoveNotSupportedException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +@Accessors(chain = true) +@AllArgsConstructor +@NoArgsConstructor +@Desc("Represents a dimension") +@Data +@EqualsAndHashCode(callSuper = false) +public class IrisDimension extends IrisRegistrant { + public static final PlatformBlockState STONE = BukkitBlockState.of(Material.STONE.createBlockData()); + public static final PlatformBlockState WATER = BukkitBlockState.of(Material.WATER.createBlockData()); + private final transient AtomicCache parallaxSize = new AtomicCache<>(); + private final transient AtomicCache rockLayerGenerator = new AtomicCache<>(); + private final transient AtomicCache fluidLayerGenerator = new AtomicCache<>(); + private final transient AtomicCache coordFracture = new AtomicCache<>(); + private final transient AtomicCache sinr = new AtomicCache<>(); + private final transient AtomicCache cosr = new AtomicCache<>(); + private final transient AtomicCache rad = new AtomicCache<>(); + private final transient AtomicCache featuresUsed = new AtomicCache<>(); + private final transient AtomicCache> carvingEntryIndex = new AtomicCache<>(); + private final transient AtomicCache> surfaceOreCache = new AtomicCache<>(); + private final transient AtomicCache> undergroundOreCache = new AtomicCache<>(); + @MinNumber(2) + @Required + @Desc("The human readable name of this dimension") + private String name = "A Dimension"; + @MinNumber(1) + @MaxNumber(2032) + @Desc("Maximum height at which players can be teleported to through gameplay.") + private int logicalHeight = 256; + @Desc("If set to true, Iris will remove chunks to allow visualizing cross sections of chunks easily") + private boolean debugChunkCrossSections = false; + @Desc("Vertically split up the biome palettes with 3 air blocks in between to visualize them") + private boolean explodeBiomePalettes = false; + @Desc("Studio Mode for testing different parts of the world") + private StudioMode studioMode = StudioMode.NORMAL; + @MinNumber(1) + @MaxNumber(16) + @Desc("Customize the palette height explosion") + private int explodeBiomePaletteSize = 3; + @MinNumber(2) + @MaxNumber(16) + @Desc("Every X/Z % debugCrossSectionsMod == 0 cuts the chunk") + private int debugCrossSectionsMod = 3; + @Desc("Tree growth override settings") + private IrisTreeSettings treeSettings = new IrisTreeSettings(); + @Desc("Spawn Entities in this dimension over time. Iris will continually replenish these mobs just like vanilla does.") + @ArrayType(min = 1, type = String.class) + @RegistryListResource(IrisSpawner.class) + private KList entitySpawners = new KList<>(); + @Desc("Reference loot tables in this area") + private IrisLootReference loot = new IrisLootReference(); + @MinNumber(0) + @Desc("The version of this dimension. Changing this will stop users from accidentally upgrading (and breaking their worlds).") + private int version = 1; + @ArrayType(min = 1, type = IrisBlockDrops.class) + @Desc("Define custom block drops for this dimension") + private KList blockDrops = new KList<>(); + @Desc("Should bedrock be generated or not.") + private boolean bedrock = true; + @MinNumber(0) + @MaxNumber(1) + @Desc("The land chance. Up to 1.0 for total land or 0.0 for total sea") + private double landChance = 0.625; + @Desc("The placement style of regions") + private IrisGeneratorStyle regionStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style(); + @Desc("The placement style of land/sea") + private IrisGeneratorStyle continentalStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style(); + @Desc("The placement style of biomes") + private IrisGeneratorStyle landBiomeStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style(); + @Desc("The placement style of biomes") + private IrisGeneratorStyle shoreBiomeStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style(); + @Desc("The placement style of biomes") + private IrisGeneratorStyle seaBiomeStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style(); + @Desc("The placement style of biomes") + private IrisGeneratorStyle caveBiomeStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style(); + @Desc("Instead of filling objects with air, fills them with cobweb so you can see them") + private boolean debugSmartBore = false; + @Desc("Generate decorations or not") + private boolean decorate = true; + @Desc("When true, every ore block the generator would place (terrain ores, deposits, ores inside objects) is replaced with its base material such as stone, deepslate or netherrack, so drop-control plugins like HiddenOre can manage ore rewards themselves") + private boolean hideOresForHiddenOre = false; + @Desc("Use post processing or not") + private boolean postProcessing = true; + @Desc("Add slabs in post processing") + private boolean postProcessingSlabs = true; + @Desc("Add painted walls in post processing") + private boolean postProcessingWalls = true; + @Desc("Enable or disable all carving for this dimension") + private boolean carvingEnabled = true; + @ArrayType(type = IrisDimensionCarvingEntry.class, min = 1) + @Desc("Dimension-level cave biome carving overrides with absolute world Y ranges") + private KList carving = new KList<>(); + @Desc("Profile-driven 3D cave configuration") + private IrisCaveProfile caveProfile = new IrisCaveProfile(); + @Desc("Configuration of fluid bodies such as rivers & lakes") + private IrisFluidBodies fluidBodies = new IrisFluidBodies(); + @Desc("forceConvertTo320Height") + private Boolean forceConvertTo320Height = false; + @Desc("The world environment") + private Environment environment = Environment.NORMAL; + @RegistryListResource(IrisRegion.class) + @Required + @ArrayType(min = 1, type = String.class) + @Desc("Define all of the regions to include in this dimension. Dimensions -> Regions -> Biomes -> Objects etc") + private KList regions = new KList<>(); + @Required + @MinNumber(0) + @MaxNumber(1024) + @Desc("The fluid height for this dimension") + private int fluidHeight = 63; + @Desc("Define the min and max Y bounds of this dimension. Please keep in mind that Iris internally generates from 0 to (max - min). \n\nFor example at -64 to 320, Iris is internally generating to 0 to 384, then on outputting chunks, it shifts it down by the min height (64 blocks). The default is -64 to 320. \n\nThe fluid height is placed at (fluid height + min height). So a fluid height of 63 would actually show up in the world at 1.") + private IrisRange dimensionHeight = new IrisRange(-64, 320); + @Desc("Define options for this dimension") + private IrisDimensionTypeOptions dimensionOptions = new IrisDimensionTypeOptions(); + @Desc("When true, sets the dimension's ambient light to maximum, making all blocks fully lit regardless of light level.") + private boolean fullbright = false; + @RegistryListResource(IrisDimension.class) + @Desc("When set, generates the referenced dimension's terrain upside-down at the world ceiling, creating a nether-like canopy. Use the dimension's load key (e.g., 'overworld'). Set to 'none' to disable.") + private String upperDimension = "none"; + @MinNumber(0) + @MaxNumber(256) + @Desc("Minimum air gap in blocks between the lower terrain surface and the upper terrain surface.") + private int upperDimensionGap = 32; + @Desc("When true, cave carving will cut through the upper dimension terrain. When false, the upper terrain is a solid untouched mass.") + private boolean upperDimensionCarving = false; + @Desc("When true, objects from the mantle (structures, trees, etc.) can be placed in the upper dimension terrain zone. When false, the upper terrain is protected from object placement.") + private boolean upperDimensionObjects = false; + @Desc("When true, upper-dimension objects force-place regardless of placement restrictions (slope, underwater, clamp, collisions, carving). Normal dimension objects always place first; upper objects place second and may clip or occlude lower-dimension placements when this is enabled.") + private boolean upperObjectsForcePlace = false; + @RegistryListResource(IrisBiome.class) + @Desc("Keep this either undefined or empty. Setting any biome name into this will force iris to only generate the specified biome. Great for testing.") + private String focus = ""; + @RegistryListResource(IrisRegion.class) + @Desc("Keep this either undefined or empty. Setting any region name into this will force iris to only generate the specified region. Great for testing.") + private String focusRegion = ""; + @MinNumber(0.0001) + @MaxNumber(512) + @Desc("Zoom in or out the biome size. Higher = bigger biomes") + private double biomeZoom = 1D; + @MinNumber(0) + @MaxNumber(360) + @Desc("You can rotate the input coordinates by an angle. This can make terrain appear more natural (less sharp corners and lines). This literally rotates the entire dimension by an angle. Hint: Try 12 degrees or something not on a 90 or 45 degree angle.") + private double dimensionAngleDeg = 0; + @Required + @Desc("Define the mode of this dimension (required!)") + private IrisDimensionMode mode = new IrisDimensionMode(); + @MinNumber(0) + @MaxNumber(8192) + @Desc("Coordinate fracturing applies noise to the input coordinates. This creates the 'iris swirls' and wavy features. The distance pushes these waves further into places they shouldnt be. This is a block value multiplier.") + private double coordFractureDistance = 20; + @MinNumber(0.0001) + @MaxNumber(512) + @Desc("Coordinate fracturing zoom. Higher = less frequent warping, Lower = more frequent and rapid warping / swirls.") + private double coordFractureZoom = 8; + @MinNumber(0.0001) + @MaxNumber(512) + @Desc("This zooms in the land space") + private double landZoom = 1; + @MinNumber(0.0001) + @MaxNumber(512) + @Desc("This zooms oceanic biomes") + private double seaZoom = 1; + @MinNumber(0.0001) + @MaxNumber(512) + @Desc("Zoom in continents") + private double continentZoom = 1; + @MinNumber(0.0001) + @MaxNumber(512) + @Desc("Change the size of regions") + private double regionZoom = 1; + @Desc("Disable this to stop placing objects, entities, features & updates") + private boolean useMantle = true; + @Desc("Prevent Leaf decay as if placed in creative mode") + private boolean preventLeafDecay = false; + @ArrayType(min = 1, type = IrisDepositGenerator.class) + @Desc("Define global deposit generators") + private KList deposits = new KList<>(); + @ArrayType(min = 1, type = IrisDepositVariant.class) + @Desc("Dimension-wide deposit ore remap rules. Each entry declares a vertical band and a source->replacement block id map. Applied after biome and region rules; first matching dimension rule wins.") + private KList depositVariants = new KList<>(); + @ArrayType(min = 1, type = IrisShapedGeneratorStyle.class) + @Desc("Overlay additional noise on top of the interoplated terrain.") + private KList overlayNoise = new KList<>(); + @MinNumber(0.0001) + @MaxNumber(512) + @Desc("The rock zoom mostly for zooming in on a wispy palette") + private double rockZoom = 5; + @Desc("The palette of blocks for 'stone'") + private IrisMaterialPalette rockPalette = new IrisMaterialPalette().qclear().qadd("stone"); + @Desc("The palette of blocks for 'water'") + private IrisMaterialPalette fluidPalette = new IrisMaterialPalette().qclear().qadd("water"); + @Desc("Prevent cartographers to generate explorer maps (Iris worlds only)\nONLY TOUCH IF YOUR SERVER CRASHES WHILE GENERATING EXPLORER MAPS") + private boolean disableExplorerMaps = false; + @Desc("Collection of ores to be generated") + @ArrayType(type = IrisOreGenerator.class, min = 1) + private KList ores = new KList<>(); + @Desc("Dimension-wide Iris structure placements, independent of biome/region placements") + @ArrayType(type = IrisStructurePlacement.class, min = 1) + private KList structures = new KList<>(); + @Desc("Controls native vanilla & ingested datapack structure generation for this dimension. Defaults to ALL_ON. The 'disabled'/'enabled' lists autocomplete every live vanilla and ingested datapack structure key.") + private IrisImportedStructureControl importedStructures = new IrisImportedStructureControl(); + @ArrayType(type = String.class, min = 1) + @Desc("External datapack imports for this dimension. List Modrinth datapack page URLs ('https://modrinth.com/datapack/' resolves the latest datapack version, or a specific '.../version/' link pins a version) or a direct .zip URL. Run '/iris datapack ingest' (or '/iris ingest') to download/update them and install them into the world's datapacks folder. Once ingested, their structures behave exactly like vanilla jigsaw structures. To REPLACE a vanilla structure with an imported one, add a 'structures' placement (route IRIS_PLACED) referencing the imported structure key (which carries the matching 'vanillaSource', e.g. 'minecraft:stronghold'): its vanilla counterpart is then automatically suppressed, so it never double-generates - no 'importedStructures.disabled' entry needed. Use 'importedStructures.disabled' only to turn a vanilla structure OFF entirely when you are NOT placing a replacement, or place any imported structure key arbitrarily through a 'structures' placement.") + private KList datapackImports = new KList<>(); + @MinNumber(0) + @MaxNumber(318) + @Desc("The Subterrain Fluid Layer Height") + private int caveLavaHeight = 8; + @RegistryListFunction(ComponentFlagFunction.class) + @ArrayType(type = String.class) + @Desc("Collection of disabled components") + private KList disabledComponents = new KList<>(); + + public int getMaxHeight() { + return (int) getDimensionHeight().getMax(); + } + + public int getMinHeight() { + return (int) getDimensionHeight().getMin(); + } + + public Map getCarvingEntryIndex() { + return carvingEntryIndex.aquire(() -> { + Map index = new HashMap<>(); + KList entries = getCarving(); + if (entries == null || entries.isEmpty()) { + return index; + } + + for (IrisDimensionCarvingEntry entry : entries) { + if (entry == null) { + continue; + } + + String entryId = entry.getId(); + if (entryId == null || entryId.isBlank()) { + continue; + } + + index.put(entryId.trim(), entry); + } + + return index; + }); + } + + public void setCarving(KList carving) { + this.carving = carving == null ? new KList<>() : carving; + carvingEntryIndex.reset(); + } + + public PlatformBlockState generateOres(int x, int y, int z, RNG rng, IrisData data, boolean surface) { + KList localOres = surface ? getSurfaceOres() : getUndergroundOres(); + return generateOres(localOres, x, y, z, rng, data); + } + + public PlatformBlockState generateSurfaceOres(int x, int y, int z, RNG rng, IrisData data) { + return generateOres(getSurfaceOres(), x, y, z, rng, data); + } + + public PlatformBlockState generateUndergroundOres(int x, int y, int z, RNG rng, IrisData data) { + return generateOres(getUndergroundOres(), x, y, z, rng, data); + } + + public boolean hasSurfaceOres() { + return !getSurfaceOres().isEmpty(); + } + + public boolean hasUndergroundOres() { + return !getUndergroundOres().isEmpty(); + } + + private PlatformBlockState generateOres(KList localOres, int x, int y, int z, RNG rng, IrisData data) { + if (localOres.isEmpty()) { + return null; + } + + int oreCount = localOres.size(); + for (int oreIndex = 0; oreIndex < oreCount; oreIndex++) { + IrisOreGenerator oreGenerator = localOres.get(oreIndex); + PlatformBlockState ore = oreGenerator.generate(x, y, z, rng, data); + if (ore != null) { + return ore; + } + } + return null; + } + + public void setOres(KList ores) { + this.ores = ores == null ? new KList<>() : ores; + surfaceOreCache.reset(); + undergroundOreCache.reset(); + } + + private KList getSurfaceOres() { + return getOres(true); + } + + private KList getUndergroundOres() { + return getOres(false); + } + + private KList getOres(boolean surface) { + AtomicCache> oreCache = surface ? surfaceOreCache : undergroundOreCache; + return oreCache.aquire(() -> { + KList filtered = new KList<>(); + KList localOres = ores; + int oreCount = localOres.size(); + for (int oreIndex = 0; oreIndex < oreCount; oreIndex++) { + IrisOreGenerator oreGenerator = localOres.get(oreIndex); + if (oreGenerator.isGenerateSurface() == surface) { + filtered.add(oreGenerator); + } + } + + return filtered; + }); + } + + public int getFluidHeight() { + return fluidHeight - (int) dimensionHeight.getMin(); + } + + public CNG getCoordFracture(RNG rng, int signature) { + return coordFracture.aquire(() -> + { + CNG coordFracture = CNG.signature(rng.nextParallelRNG(signature)); + coordFracture.scale(0.012 / coordFractureZoom); + return coordFracture; + }); + } + + public double getDimensionAngle() { + return rad.aquire(() -> Math.toRadians(dimensionAngleDeg)); + } + + public Environment getEnvironment() { + return environment; + } + + public boolean hasFocusRegion() { + return !focusRegion.equals(""); + } + + public String getFocusRegion() { + return focusRegion; + } + + public double sinRotate() { + return sinr.aquire(() -> Math.sin(getDimensionAngle())); + } + + public double cosRotate() { + return cosr.aquire(() -> Math.cos(getDimensionAngle())); + } + + public KList getAllRegions(DataProvider g) { + KList r = new KList<>(); + + for (String i : getRegions()) { + r.add(g.getData().getRegionLoader().load(i)); + } + + return r; + } + + public KList getAllAnyRegions() { + KList r = new KList<>(); + + for (String i : getRegions()) { + r.add(IrisData.loadAnyRegion(i, getLoader())); + } + + return r; + } + + public KList getAllBiomes(DataProvider g) { + return g.getData().getBiomeLoader().loadAll(g.getData().getBiomeLoader().getPossibleKeys()); + } + + public KList getAllAnyBiomes() { + KList r = new KList<>(); + + for (IrisRegion i : getAllAnyRegions()) { + if (i == null) { + continue; + } + + r.addAll(i.getAllAnyBiomes()); + } + + return r; + } + + public IrisGeneratorStyle getBiomeStyle(InferredType type) { + switch (type) { + case CAVE: + return caveBiomeStyle; + case LAND: + return landBiomeStyle; + case SEA: + return seaBiomeStyle; + case SHORE: + return shoreBiomeStyle; + default: + break; + } + + return landBiomeStyle; + } + + public void installBiomes(IDataFixer fixer, DataProvider data, KList folders, KSet biomes) { + String namespace = getLoadKey().toLowerCase(Locale.ROOT); + + for (IrisBiome irisBiome : getAllBiomes(data)) { + if (!irisBiome.isCustom()) { + continue; + } + + for (IrisBiomeCustom customBiome : irisBiome.getCustomDerivitives()) { + String customBiomeId = customBiome.getId(); + String json = customBiome.generateJson(fixer); + + synchronized (biomes) { + if (!biomes.add(customBiomeId)) { + Iris.verbose("Duplicate Data Pack Biome: " + getLoadKey() + "/" + customBiomeId); + continue; + } + } + + for (File datapacks : folders) { + File output = new File(datapacks, "iris/data/" + namespace + "/worldgen/biome/" + customBiomeId + ".json"); + + Iris.verbose(" Installing Data Pack Biome: " + output.getPath()); + output.getParentFile().mkdirs(); + try { + IO.writeAll(output, json); + } catch (IOException e) { + Iris.reportError(e); + e.printStackTrace(); + } + } + } + } + } + + public Dimension getBaseDimension() { + return switch (getEnvironment()) { + case NETHER -> Dimension.NETHER; + case THE_END -> Dimension.END; + default -> Dimension.OVERWORLD; + }; + } + + public String getDimensionTypeKey() { + return sanitizeDimensionTypeKeyValue(getLoadKey()); + } + + public static String sanitizeDimensionTypeKeyValue(String value) { + if (value == null || value.isBlank()) { + return "dimension"; + } + + String sanitized = value.trim().toLowerCase(Locale.ROOT).replace("\\", "/"); + sanitized = sanitized.replaceAll("[^a-z0-9_\\-./]", "_"); + sanitized = sanitized.replaceAll("/+", "/"); + sanitized = sanitized.replaceAll("^/+", ""); + sanitized = sanitized.replaceAll("/+$", ""); + if (sanitized.contains("..")) { + sanitized = sanitized.replace("..", "_"); + } + + sanitized = sanitized.replace("/", "_"); + return sanitized.isBlank() ? "dimension" : sanitized; + } + + public IrisDimensionType getDimensionType() { + IrisDimensionTypeOptions options = getDimensionOptions(); + if (fullbright) { + options = options.copy().ambientLight(1.0f); + } + return new IrisDimensionType(getBaseDimension(), options, getLogicalHeight(), getMaxHeight() - getMinHeight(), getMinHeight()); + } + + public boolean hasUpperDimension() { + return upperDimension != null && !upperDimension.isEmpty() && !upperDimension.equalsIgnoreCase("none"); + } + + public void installDimensionType(IDataFixer fixer, KList folders) { + IrisDimensionType type = getDimensionType(); + String json = type.toJson(fixer); + String dimensionTypeKey = getDimensionTypeKey(); + + Iris.verbose(" Installing Data Pack Dimension Type: \"iris:" + dimensionTypeKey + '"'); + for (File datapacks : folders) { + File output = new File(datapacks, "iris/data/iris/dimension_type/" + dimensionTypeKey + ".json"); + output.getParentFile().mkdirs(); + try { + IO.writeAll(output, json); + } catch (IOException e) { + Iris.reportError(e); + e.printStackTrace(); + } + } + } + + @Override + public String getFolderName() { + return "dimensions"; + } + + @Override + public String getTypeName() { + return "Dimension"; + } + + @Override + public void scanForErrors(JSONObject p, VolmitSender sender) { + + } + + public static void writeShared(KList folders, DimensionHeight height) { + Iris.verbose(" Installing Data Pack Vanilla Dimension Types"); + String[] jsonStrings = height.jsonStrings(); + for (File datapacks : folders) { + write(datapacks, "overworld", jsonStrings[0]); + write(datapacks, "the_nether", jsonStrings[1]); + write(datapacks, "the_end", jsonStrings[2]); + } + + String raw = """ + { + "pack": { + "description": "Iris Data Pack. This pack contains all installed Iris Packs' resources.", + "pack_format": {}, + "min_format": {}, + "max_format": {} + } + } + """.replace("{}", INMS.get().getDataVersion().getPackFormat() + ""); + + for (File datapacks : folders) { + File mcm = new File(datapacks, "iris/pack.mcmeta"); + try { + IO.writeAll(mcm, raw); + } catch (IOException e) { + Iris.reportError(e); + e.printStackTrace(); + } + Iris.verbose(" Installing Data Pack MCMeta: " + mcm.getPath()); + } + } + + private static void write(File datapacks, String type, String json) { + if (json == null) return; + File dimTypeVanilla = new File(datapacks, "iris/data/minecraft/dimension_type/" + type + ".json"); + + if (IrisSettings.get().getGeneral().adjustVanillaHeight || dimTypeVanilla.exists()) { + dimTypeVanilla.getParentFile().mkdirs(); + try { + IO.writeAll(dimTypeVanilla, json); + } catch (IOException e) { + Iris.reportError(e); + e.printStackTrace(); + } + } + } +} diff --git a/core/src/main/java/art/arcane/iris/engine/object/IrisMaterialPalette.java b/core/src/main/java/art/arcane/iris/engine/object/IrisMaterialPalette.java index 73b737880..8814746d6 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/IrisMaterialPalette.java +++ b/core/src/main/java/art/arcane/iris/engine/object/IrisMaterialPalette.java @@ -27,8 +27,8 @@ import art.arcane.iris.util.project.noise.CNG; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import art.arcane.iris.spi.PlatformBlockState; import lombok.experimental.Accessors; -import org.bukkit.block.data.BlockData; import java.util.Optional; @@ -39,7 +39,7 @@ import java.util.Optional; @Desc("A palette of materials") @Data public class IrisMaterialPalette { - private final transient AtomicCache> blockData = new AtomicCache<>(); + private final transient AtomicCache> blockData = new AtomicCache<>(); private final transient AtomicCache layerGenerator = new AtomicCache<>(); private final transient AtomicCache heightGenerator = new AtomicCache<>(); @Desc("The style of noise") @@ -52,7 +52,7 @@ public class IrisMaterialPalette { @Desc("The palette of blocks to be used in this layer") private KList palette = new KList().qadd(new IrisBlockData("STONE")); - public BlockData get(RNG rng, double x, double y, double z, IrisData rdata) { + public PlatformBlockState get(RNG rng, double x, double y, double z, IrisData rdata) { if (getBlockData(rdata).isEmpty()) { return null; } @@ -100,12 +100,12 @@ public class IrisMaterialPalette { return this; } - public KList getBlockData(IrisData rdata) { + public KList getBlockData(IrisData rdata) { return blockData.aquire(() -> { - KList blockData = new KList<>(); + KList blockData = new KList<>(); for (IrisBlockData ix : palette) { - BlockData bx = ix.getBlockData(rdata); + PlatformBlockState bx = ix.getBlockData(rdata); if (bx != null) { for (int i = 0; i < ix.getWeight(); i++) { blockData.add(bx); diff --git a/core/src/main/java/art/arcane/iris/engine/object/IrisObject.java b/core/src/main/java/art/arcane/iris/engine/object/IrisObject.java index 976ea3797..cef745e3b 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/IrisObject.java +++ b/core/src/main/java/art/arcane/iris/engine/object/IrisObject.java @@ -25,6 +25,8 @@ import art.arcane.iris.engine.data.cache.AtomicCache; import art.arcane.iris.engine.framework.Engine; import art.arcane.iris.engine.framework.PlacedObject; import art.arcane.iris.engine.framework.placer.HeightmapObjectPlacer; +import art.arcane.iris.platform.bukkit.BukkitBlockState; +import art.arcane.iris.spi.PlatformBlockState; import art.arcane.volmlib.util.collection.KList; import art.arcane.volmlib.util.collection.KMap; import art.arcane.iris.util.project.context.IrisContext; @@ -78,11 +80,11 @@ import java.util.stream.StreamSupport; @EqualsAndHashCode(callSuper = false) public class IrisObject extends IrisRegistrant { protected static final Vector HALF = new Vector(0.5, 0.5, 0.5); - protected static final BlockData AIR = B.get("CAVE_AIR"); - protected static final BlockData STONE = B.get("STONE"); - protected static final BlockData VAIR = B.get("VOID_AIR"); - protected static final BlockData VAIR_DEBUG = B.get("COBWEB"); - protected static final BlockData[] SNOW_LAYERS = new BlockData[]{B.get("minecraft:snow[layers=1]"), B.get("minecraft:snow[layers=2]"), B.get("minecraft:snow[layers=3]"), B.get("minecraft:snow[layers=4]"), B.get("minecraft:snow[layers=5]"), B.get("minecraft:snow[layers=6]"), B.get("minecraft:snow[layers=7]"), B.get("minecraft:snow[layers=8]")}; + protected static final PlatformBlockState AIR = B.getState("CAVE_AIR"); + protected static final PlatformBlockState STONE = B.getState("STONE"); + protected static final PlatformBlockState VAIR = B.getState("VOID_AIR"); + protected static final PlatformBlockState VAIR_DEBUG = B.getState("COBWEB"); + protected static final PlatformBlockState[] SNOW_LAYERS = new PlatformBlockState[]{B.getState("minecraft:snow[layers=1]"), B.getState("minecraft:snow[layers=2]"), B.getState("minecraft:snow[layers=3]"), B.getState("minecraft:snow[layers=4]"), B.getState("minecraft:snow[layers=5]"), B.getState("minecraft:snow[layers=6]"), B.getState("minecraft:snow[layers=7]"), B.getState("minecraft:snow[layers=8]")}; private static final long IMPLAUSIBLE_BEDROCK_WARN_THROTTLE_MS = 5000L; private static final long VACUUM_WAVE_SEED = 7392113L; private static final java.util.concurrent.ConcurrentHashMap IMPLAUSIBLE_BEDROCK_WARNS = new java.util.concurrent.ConcurrentHashMap<>(); @@ -94,7 +96,7 @@ public class IrisObject extends IrisRegistrant { @Setter protected transient AtomicCache aabb = new AtomicCache<>(); @Getter - private VectorMap blocks; + private VectorMap blocks; @Getter private VectorMap states; @Getter @@ -164,7 +166,8 @@ public class IrisObject extends IrisRegistrant { return locations; } - private static boolean shouldStilt(BlockData data) { + private static boolean shouldStilt(PlatformBlockState state) { + BlockData data = (BlockData) state.nativeHandle(); if (!data.getMaterial().isOccluding()) { return false; } @@ -184,7 +187,7 @@ public class IrisObject extends IrisRegistrant { } PrecisionStopwatch p = PrecisionStopwatch.start(); - BlockData vair = debug ? VAIR_DEBUG : VAIR; + PlatformBlockState vair = debug ? VAIR_DEBUG : VAIR; writeLock.lock(); AtomicInteger applied = new AtomicInteger(); if (blocks.isEmpty()) { @@ -308,7 +311,7 @@ public class IrisObject extends IrisRegistrant { o.setLoadFile(getLoadFile()); o.setCenter(getCenter().clone()); - blocks.forEach((i, v) -> o.blocks.put(i.clone(), v.clone())); + blocks.forEach((i, v) -> o.blocks.put(i.clone(), v)); states.forEach((i, v) -> o.states.put(i.clone(), v.clone())); return o; @@ -328,7 +331,7 @@ public class IrisObject extends IrisRegistrant { if (isStructureMarker(data)) { continue; } - blocks.put(pos, data); + blocks.put(pos, data == null ? null : BukkitBlockState.of(data)); } if (din.available() == 0) @@ -370,7 +373,7 @@ public class IrisObject extends IrisRegistrant { if (isStructureMarker(data)) { continue; } - blocks.put(pos, data); + blocks.put(pos, data == null ? null : BukkitBlockState.of(data)); } s = din.readInt(); @@ -396,8 +399,8 @@ public class IrisObject extends IrisRegistrant { dos.writeUTF("Iris V2 IOB;"); KList palette = new KList<>(); - for (BlockData i : blocks.values()) { - palette.addIfMissing(i.getAsString()); + for (PlatformBlockState i : blocks.values()) { + palette.addIfMissing(i.key()); } dos.writeShort(palette.size()); @@ -413,7 +416,7 @@ public class IrisObject extends IrisRegistrant { dos.writeShort(i.getBlockX()); dos.writeShort(i.getBlockY()); dos.writeShort(i.getBlockZ()); - dos.writeShort(palette.indexOf(entry.getValue().getAsString())); + dos.writeShort(palette.indexOf(entry.getValue().key())); } dos.writeInt(states.size()); @@ -449,8 +452,8 @@ public class IrisObject extends IrisRegistrant { KList palette = new KList<>(); - for (BlockData i : blocks.values()) { - palette.addIfMissing(i.getAsString()); + for (PlatformBlockState i : blocks.values()) { + palette.addIfMissing(i.key()); ++c; } total -= blocks.size() - palette.size(); @@ -469,7 +472,7 @@ public class IrisObject extends IrisRegistrant { dos.writeShort(i.getBlockX()); dos.writeShort(i.getBlockY()); dos.writeShort(i.getBlockZ()); - dos.writeShort(palette.indexOf(entry.getValue().getAsString())); + dos.writeShort(palette.indexOf(entry.getValue().key())); ++c; } @@ -569,7 +572,7 @@ public class IrisObject extends IrisRegistrant { if (offset.getBlockX() == 0 && offset.getBlockY() == 0 && offset.getBlockZ() == 0) return; - VectorMap b = new VectorMap<>(); + VectorMap b = new VectorMap<>(); VectorMap s = new VectorMap<>(); blocks.forEach((vector, data) -> { @@ -588,7 +591,7 @@ public class IrisObject extends IrisRegistrant { } public void clean() { - VectorMap d = new VectorMap<>(); + VectorMap d = new VectorMap<>(); d.putAll(blocks); VectorMap dx = new VectorMap<>(); @@ -606,7 +609,7 @@ public class IrisObject extends IrisRegistrant { return (Vector3i) new Vector3i(x, y, z).subtract(center); } - public void setUnsigned(int x, int y, int z, BlockData block) { + public void setUnsigned(int x, int y, int z, PlatformBlockState block) { Vector3i v = getSigned(x, y, z); if (block == null) { @@ -635,7 +638,7 @@ public class IrisObject extends IrisRegistrant { states.remove(v); } else { BlockData data = block.getBlockData(); - blocks.put(v, data); + blocks.put(v, BukkitBlockState.of(data)); TileData state = TileData.getTileState(block, legacy); if (state != null) { Iris.debug("Saved State " + v); @@ -660,7 +663,7 @@ public class IrisObject extends IrisRegistrant { return place(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), placer, config, rng, rdata); } - public int place(int x, int yv, int z, IObjectPlacer oplacer, IrisObjectPlacement config, RNG rng, BiConsumer listener, CarveResult c, IrisData rdata) { + public int place(int x, int yv, int z, IObjectPlacer oplacer, IrisObjectPlacement config, RNG rng, BiConsumer listener, CarveResult c, IrisData rdata) { IObjectPlacer placer = (config.getHeightmap() != null) ? new HeightmapObjectPlacer(oplacer.getEngine() == null ? IrisContext.get().getEngine() : oplacer.getEngine(), rng, x, yv, z, config, oplacer) : oplacer; if (rdata != null) { @@ -996,14 +999,16 @@ public class IrisObject extends IrisRegistrant { break; } - BlockData data = blocks.get(i); + PlatformBlockState data = blocks.get(i); + BlockData rawData = data == null ? null : (BlockData) data.nativeHandle(); - for (BlockData k : j.getMark(rdata)) { + for (PlatformBlockState k : j.getMark(rdata)) { if (max <= 0) { break; } - if (j.isExact() ? k.matches(data) : k.getMaterial().equals(data.getMaterial())) { + BlockData rawMark = (BlockData) k.nativeHandle(); + if (j.isExact() ? rawMark.matches(rawData) : rawMark.getMaterial().equals(rawData.getMaterial())) { boolean a = !blocks.containsKey((BlockVector) i.clone().add(new BlockVector(0, 1, 0))); boolean fff = !blocks.containsKey((BlockVector) i.clone().add(new BlockVector(0, 2, 0))); @@ -1019,7 +1024,7 @@ public class IrisObject extends IrisRegistrant { for (var entry : blocks) { var g = entry.getKey(); - BlockData d; + PlatformBlockState d; TileData tile = null; try { @@ -1037,7 +1042,7 @@ public class IrisObject extends IrisRegistrant { } BlockVector i = g.clone(); - BlockData data = d.clone(); + PlatformBlockState data = d; i = config.getRotation().rotate(i.clone(), spinx, spiny, spinz).clone(); if (ceilingHang) { i.setY(-i.getBlockY()); @@ -1053,19 +1058,22 @@ public class IrisObject extends IrisRegistrant { } } - if (placer.isPreventingDecay() && (data) instanceof Leaves && !((Leaves) (data)).isPersistent()) { - Leaves leaves = (Leaves) data.clone(); + if (placer.isPreventingDecay() && ((BlockData) data.nativeHandle()) instanceof Leaves && !((Leaves) ((BlockData) data.nativeHandle())).isPersistent()) { + Leaves leaves = (Leaves) ((BlockData) data.nativeHandle()).clone(); leaves.setPersistent(true); - data = leaves; + data = BukkitBlockState.of(leaves); } for (IrisObjectReplace j : config.getEdit()) { if (rng.chance(j.getChance())) { - for (BlockData k : j.getFind(rdata)) { - if (j.isExact() ? k.matches(data) : k.getMaterial().equals(data.getMaterial())) { - BlockData newData = j.getReplace(rng, i.getX() + x, i.getY() + y, i.getZ() + z, rdata).clone(); + for (PlatformBlockState k : j.getFind(rdata)) { + BlockData rawFind = (BlockData) k.nativeHandle(); + BlockData rawData = (BlockData) data.nativeHandle(); + if (j.isExact() ? rawFind.matches(rawData) : rawFind.getMaterial().equals(rawData.getMaterial())) { + PlatformBlockState newData = j.getReplace(rng, i.getX() + x, i.getY() + y, i.getZ() + z, rdata); + BlockData rawNew = (BlockData) newData.nativeHandle(); - if (newData.getMaterial() == data.getMaterial() && !(newData instanceof IrisCustomData || data instanceof IrisCustomData)) + if (rawNew.getMaterial() == rawData.getMaterial() && !(rawNew instanceof IrisCustomData || rawData instanceof IrisCustomData)) data = BlockDataMergeSupport.merge(data, newData); else data = newData; @@ -1090,7 +1098,7 @@ public class IrisObject extends IrisRegistrant { zz += config.warp(rng, i.getZ() + z, i.getY() + y, i.getX() + x, getLoader()); } - if (yv < 0 && (config.getMode().equals(ObjectPlaceMode.PAINT)) && !B.isVineBlock(data)) { + if (yv < 0 && (config.getMode().equals(ObjectPlaceMode.PAINT)) && !B.isVineBlock((BlockData) data.nativeHandle())) { yy = (int) Math.round(i.getY()) + Math.floorDiv(h, 2) + placer.getHighest(xx, zz, getLoader(), config.isUnderwater()); } @@ -1110,24 +1118,25 @@ public class IrisObject extends IrisRegistrant { continue; } - if (data instanceof Waterlogged && shouldAutoWaterlogBlock(placer, config, yv, xx, yy, zz)) { - Waterlogged waterlogged = (Waterlogged) data.clone(); + if (((BlockData) data.nativeHandle()) instanceof Waterlogged && shouldAutoWaterlogBlock(placer, config, yv, xx, yy, zz)) { + Waterlogged waterlogged = (Waterlogged) ((BlockData) data.nativeHandle()).clone(); waterlogged.setWaterlogged(true); - data = waterlogged; + data = BukkitBlockState.of(waterlogged); } - if (B.isVineBlock(data)) { - MultipleFacing f = (MultipleFacing) data.clone(); + if (B.isVineBlock((BlockData) data.nativeHandle())) { + MultipleFacing f = (MultipleFacing) ((BlockData) data.nativeHandle()).clone(); boolean facesChanged = false; for (BlockFace face : f.getAllowedFaces()) { - BlockData facingBlock = placer.get(xx + face.getModX(), yy + face.getModY(), zz + face.getModZ()); + PlatformBlockState facingState = placer.get(xx + face.getModX(), yy + face.getModY(), zz + face.getModZ()); + BlockData facingBlock = facingState == null ? null : (BlockData) facingState.nativeHandle(); if (B.isSolid(facingBlock) && !B.isVineBlock(facingBlock)) { f.setFace(face, true); facesChanged = true; } } if (facesChanged) { - data = f; + data = BukkitBlockState.of(f); } } @@ -1139,10 +1148,13 @@ public class IrisObject extends IrisRegistrant { placer.getEngine().getMantle().getMantle().set(xx, yy, zz, new MatterMarker(markers.get(g))); } - boolean wouldReplace = B.isSolid(placer.get(xx, yy, zz)) && B.isVineBlock(data); - boolean place = !data.getMaterial().equals(Material.AIR) && !data.getMaterial().equals(Material.CAVE_AIR) && !wouldReplace; + PlatformBlockState existingState = placer.get(xx, yy, zz); + BlockData existingRaw = existingState == null ? null : (BlockData) existingState.nativeHandle(); + BlockData rawData = (BlockData) data.nativeHandle(); + boolean wouldReplace = B.isSolid(existingRaw) && B.isVineBlock(rawData); + boolean place = !rawData.getMaterial().equals(Material.AIR) && !rawData.getMaterial().equals(Material.CAVE_AIR) && !wouldReplace; - if (data instanceof IrisCustomData || place) { + if (rawData instanceof IrisCustomData || place) { placer.set(xx, yy, zz, data); if (tile != null) { placer.setTile(xx, yy, zz, tile); @@ -1174,7 +1186,7 @@ public class IrisObject extends IrisRegistrant { BlockVector rot = config.getRotation().rotate(g.clone(), spinx, spiny, spinz).clone(); rot = config.getTranslate().translate(rot.clone(), config.getRotation(), spinx, spiny, spinz).clone(); if (rot.getBlockY() == lowest) { - BlockData bd = blocks.get(g); + PlatformBlockState bd = blocks.get(g); if (bd != null && shouldStilt(bd)) { erodeCentroidX += rot.getX(); erodeCentroidZ += rot.getZ(); @@ -1190,7 +1202,7 @@ public class IrisObject extends IrisRegistrant { BlockVector rot = config.getRotation().rotate(g.clone(), spinx, spiny, spinz).clone(); rot = config.getTranslate().translate(rot.clone(), config.getRotation(), spinx, spiny, spinz).clone(); if (rot.getBlockY() == lowest) { - BlockData bd = blocks.get(g); + PlatformBlockState bd = blocks.get(g); if (bd != null && shouldStilt(bd)) { double dx = rot.getX() - erodeCentroidX; double dz = rot.getZ() - erodeCentroidZ; @@ -1204,7 +1216,7 @@ public class IrisObject extends IrisRegistrant { } for (BlockVector g : blocks.keys()) { - BlockData sourceData; + PlatformBlockState sourceData; try { sourceData = blocks.get(g); } catch (Throwable e) { @@ -1222,13 +1234,13 @@ public class IrisObject extends IrisRegistrant { continue; } - BlockData d = sourceData; + PlatformBlockState d = sourceData; if (settings != null && settings.getPalette() != null) { d = config.getStiltSettings().getPalette().get(rng, x, y, z, rdata); } else { - Material mat = d.getMaterial(); + Material mat = ((BlockData) d.nativeHandle()).getMaterial(); if (mat == Material.GRASS_BLOCK || mat == Material.MYCELIUM || mat == Material.PODZOL || mat == Material.DIRT_PATH) { - d = Material.DIRT.createBlockData(); + d = BukkitBlockState.of(Material.DIRT.createBlockData()); } } @@ -1246,11 +1258,13 @@ public class IrisObject extends IrisRegistrant { for (IrisObjectReplace j : config.getEdit()) { if (rng.chance(j.getChance())) { - for (BlockData k : j.getFind(rdata)) { - if (j.isExact() ? k.matches(d) : k.getMaterial().equals(d.getMaterial())) { - BlockData newData = j.getReplace(rng, i.getX() + x, i.getY() + y, i.getZ() + z, rdata).clone(); + for (PlatformBlockState k : j.getFind(rdata)) { + BlockData rawFind = (BlockData) k.nativeHandle(); + BlockData rawD = d == null ? null : (BlockData) d.nativeHandle(); + if (j.isExact() ? rawFind.matches(rawD) : rawFind.getMaterial().equals(rawD.getMaterial())) { + PlatformBlockState newData = j.getReplace(rng, i.getX() + x, i.getY() + y, i.getZ() + z, rdata); - if (newData.getMaterial() == d.getMaterial()) { + if (((BlockData) newData.nativeHandle()).getMaterial() == rawD.getMaterial()) { d = BlockDataMergeSupport.merge(d, newData); } else { d = newData; @@ -1260,7 +1274,7 @@ public class IrisObject extends IrisRegistrant { } } - if (d == null || !d.getMaterial().isOccluding()) + if (d == null || !((BlockData) d.nativeHandle()).getMaterial().isOccluding()) continue; xx = x + (int) Math.round(i.getX()); @@ -1329,10 +1343,10 @@ public class IrisObject extends IrisRegistrant { int highest = placer.getHighest(xx, zz, getLoader(), true); - if (d instanceof Waterlogged && shouldAutoWaterlogBlock(placer, config, yv, xx, highest, zz)) { - Waterlogged waterlogged = (Waterlogged) d.clone(); + if (((BlockData) d.nativeHandle()) instanceof Waterlogged && shouldAutoWaterlogBlock(placer, config, yv, xx, highest, zz)) { + Waterlogged waterlogged = (Waterlogged) ((BlockData) d.nativeHandle()).clone(); waterlogged.setWaterlogged(true); - d = waterlogged; + d = BukkitBlockState.of(waterlogged); } int lowerBound = highest - 1; @@ -1353,7 +1367,8 @@ public class IrisObject extends IrisRegistrant { } for (int j = lowest + y; j > lowerBound; j--) { - if (B.isFluid(placer.get(xx, j, zz))) { + PlatformBlockState fluidState = placer.get(xx, j, zz); + if (B.isFluid(fluidState == null ? null : (BlockData) fluidState.nativeHandle())) { break; } if (eroding) { @@ -1369,18 +1384,19 @@ public class IrisObject extends IrisRegistrant { } } - if (B.isVineBlock(d)) { - MultipleFacing f = (MultipleFacing) d.clone(); + if (B.isVineBlock((BlockData) d.nativeHandle())) { + MultipleFacing f = (MultipleFacing) ((BlockData) d.nativeHandle()).clone(); boolean facesChanged = false; for (BlockFace face : f.getAllowedFaces()) { - BlockData facingBlock = placer.get(xx + face.getModX(), j + face.getModY(), zz + face.getModZ()); + PlatformBlockState facingState = placer.get(xx + face.getModX(), j + face.getModY(), zz + face.getModZ()); + BlockData facingBlock = facingState == null ? null : (BlockData) facingState.nativeHandle(); if (B.isSolid(facingBlock) && !B.isVineBlock(facingBlock)) { f.setFace(face, true); facesChanged = true; } } if (facesChanged) { - d = f; + d = BukkitBlockState.of(f); } } placer.set(xx, j, zz, d); @@ -1480,8 +1496,8 @@ public class IrisObject extends IrisRegistrant { } targetY = Math.max(worldMin + 1, Math.min(worldMax, targetY)); if (targetY > origY) { - BlockData fill = complex != null ? complex.getRockStream().get(cx, cz) : null; - if (fill == null || B.isAir(fill)) { + PlatformBlockState fill = complex != null ? complex.getRockStream().get(cx, cz) : null; + if (fill == null || B.isAir((BlockData) fill.nativeHandle())) { fill = STONE; } for (int yy = origY + 1; yy <= targetY; yy++) { @@ -1546,12 +1562,13 @@ public class IrisObject extends IrisRegistrant { return false; } - BlockData existing = placer.get(x, y, z); + PlatformBlockState existing = placer.get(x, y, z); if (existing == null) { return false; } - return B.isWater(existing) || B.isWaterLogged(existing); + BlockData raw = (BlockData) existing.nativeHandle(); + return B.isWater(raw) || B.isWaterLogged(raw); } public IrisObject rotateCopy(IrisObjectRotation rt) { @@ -1562,7 +1579,7 @@ public class IrisObject extends IrisRegistrant { public void rotate(IrisObjectRotation r, int spinx, int spiny, int spinz) { writeLock.lock(); - VectorMap d = new VectorMap<>(); + VectorMap d = new VectorMap<>(); for (var entry : blocks) { d.put(r.rotate(entry.getKey(), spinx, spiny, spinz), r.rotate(entry.getValue(), spinx, spiny, spinz)); @@ -1585,7 +1602,7 @@ public class IrisObject extends IrisRegistrant { for (var entry : blocks) { var i = entry.getKey(); Block b = at.clone().add(0, getCenter().getY(), 0).add(i).getBlock(); - b.setBlockData(Objects.requireNonNull(entry.getValue()), false); + b.setBlockData((BlockData) Objects.requireNonNull(entry.getValue()).nativeHandle(), false); if (states.containsKey(i)) { Iris.info(Objects.requireNonNull(states.get(i)).toString()); @@ -1600,7 +1617,7 @@ public class IrisObject extends IrisRegistrant { for (var entry : blocks) { var i = entry.getKey(); Block b = at.clone().add(getCenter().getX(), getCenter().getY(), getCenter().getZ()).add(i).getBlock(); - b.setBlockData(Objects.requireNonNull(entry.getValue()), false); + b.setBlockData((BlockData) Objects.requireNonNull(entry.getValue()).nativeHandle(), false); if (states.containsKey(i)) { Objects.requireNonNull(states.get(i)).toBukkitTry(b); @@ -1612,7 +1629,7 @@ public class IrisObject extends IrisRegistrant { public void unplaceCenterY(Location at) { readLock.lock(); for (BlockVector i : blocks.keys()) { - at.clone().add(getCenter().getX(), getCenter().getY(), getCenter().getZ()).add(i).getBlock().setBlockData(AIR, false); + at.clone().add(getCenter().getX(), getCenter().getY(), getCenter().getZ()).add(i).getBlock().setBlockData((BlockData) AIR.nativeHandle(), false); } readLock.unlock(); } @@ -1629,7 +1646,7 @@ public class IrisObject extends IrisRegistrant { IrisPosition l1 = getAABB().max(); IrisPosition l2 = getAABB().min(); - VectorMap placeBlock = new VectorMap<>(); + VectorMap placeBlock = new VectorMap<>(); Vector center = getCenter(); if (getH() == 2) { @@ -1649,7 +1666,7 @@ public class IrisObject extends IrisRegistrant { readLock.lock(); for (var entry : blocks) { - BlockData bd = entry.getValue(); + PlatformBlockState bd = entry.getValue(); placeBlock.put(entry.getKey().clone().add(HALF).subtract(center) .multiply(scale).add(sm1).toBlockVector(), bd); } @@ -1679,8 +1696,8 @@ public class IrisObject extends IrisRegistrant { public void trilinear(int rad) { writeLock.lock(); - VectorMap v = blocks; - VectorMap b = new VectorMap<>(); + VectorMap v = blocks; + VectorMap b = new VectorMap<>(); BlockVector min = getAABB().minbv(); BlockVector max = getAABB().maxbv(); @@ -1688,9 +1705,9 @@ public class IrisObject extends IrisRegistrant { for (int y = min.getBlockY(); y <= max.getBlockY(); y++) { for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) { if (IrisInterpolation.getTrilinear(x, y, z, rad, (xx, yy, zz) -> { - BlockData data = v.get(new BlockVector((int) xx, (int) yy, (int) zz)); + PlatformBlockState data = v.get(new BlockVector((int) xx, (int) yy, (int) zz)); - if (data == null || data.getMaterial().isAir()) { + if (data == null || ((BlockData) data.nativeHandle()).getMaterial().isAir()) { return 0; } @@ -1710,8 +1727,8 @@ public class IrisObject extends IrisRegistrant { public void tricubic(int rad) { writeLock.lock(); - VectorMap v = blocks; - VectorMap b = new VectorMap<>(); + VectorMap v = blocks; + VectorMap b = new VectorMap<>(); BlockVector min = getAABB().minbv(); BlockVector max = getAABB().maxbv(); @@ -1719,9 +1736,9 @@ public class IrisObject extends IrisRegistrant { for (int y = min.getBlockY(); y <= max.getBlockY(); y++) { for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) { if (IrisInterpolation.getTricubic(x, y, z, rad, (xx, yy, zz) -> { - BlockData data = v.get(new BlockVector((int) xx, (int) yy, (int) zz)); + PlatformBlockState data = v.get(new BlockVector((int) xx, (int) yy, (int) zz)); - if (data == null || data.getMaterial().isAir()) { + if (data == null || ((BlockData) data.nativeHandle()).getMaterial().isAir()) { return 0; } @@ -1745,8 +1762,8 @@ public class IrisObject extends IrisRegistrant { public void trihermite(int rad, double tension, double bias) { writeLock.lock(); - VectorMap v = blocks; - VectorMap b = new VectorMap<>(); + VectorMap v = blocks; + VectorMap b = new VectorMap<>(); BlockVector min = getAABB().minbv(); BlockVector max = getAABB().maxbv(); @@ -1754,9 +1771,9 @@ public class IrisObject extends IrisRegistrant { for (int y = min.getBlockY(); y <= max.getBlockY(); y++) { for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) { if (IrisInterpolation.getTrihermite(x, y, z, rad, (xx, yy, zz) -> { - BlockData data = v.get(new BlockVector((int) xx, (int) yy, (int) zz)); + PlatformBlockState data = v.get(new BlockVector((int) xx, (int) yy, (int) zz)); - if (data == null || data.getMaterial().isAir()) { + if (data == null || ((BlockData) data.nativeHandle()).getMaterial().isAir()) { return 0; } @@ -1774,21 +1791,21 @@ public class IrisObject extends IrisRegistrant { writeLock.unlock(); } - private BlockData nearestBlockData(int x, int y, int z) { + private PlatformBlockState nearestBlockData(int x, int y, int z) { BlockVector vv = new BlockVector(x, y, z); readLock.lock(); - BlockData r = blocks.get(vv); + PlatformBlockState r = blocks.get(vv); - if (r != null && !r.getMaterial().isAir()) { + if (r != null && !((BlockData) r.nativeHandle()).getMaterial().isAir()) { return r; } double d = Double.MAX_VALUE; for (var entry : blocks) { - BlockData dat = entry.getValue(); + PlatformBlockState dat = entry.getValue(); - if (dat.getMaterial().isAir()) { + if (((BlockData) dat.nativeHandle()).getMaterial().isAir()) { continue; } diff --git a/core/src/main/java/art/arcane/iris/engine/object/IrisObjectLoot.java b/core/src/main/java/art/arcane/iris/engine/object/IrisObjectLoot.java index 166152a3c..90c17622b 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/IrisObjectLoot.java +++ b/core/src/main/java/art/arcane/iris/engine/object/IrisObjectLoot.java @@ -25,6 +25,7 @@ import art.arcane.volmlib.util.collection.KList; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import art.arcane.iris.spi.PlatformBlockState; import lombok.experimental.Accessors; import org.bukkit.block.data.BlockData; @@ -35,7 +36,7 @@ import org.bukkit.block.data.BlockData; @Desc("Represents loot within this object") @Data public class IrisObjectLoot implements IObjectLoot { - private final transient AtomicCache> filterCache = new AtomicCache<>(); + private final transient AtomicCache> filterCache = new AtomicCache<>(); @ArrayType(min = 1, type = IrisBlockData.class) @Desc("The list of blocks this loot table should apply to") private KList filter = new KList<>(); @@ -48,13 +49,13 @@ public class IrisObjectLoot implements IObjectLoot { @Desc("The weight of this loot table being chosen") private int weight = 1; - public KList getFilter(IrisData rdata) { + public KList getFilter(IrisData rdata) { return filterCache.aquire(() -> { - KList b = new KList<>(); + KList b = new KList<>(); for (IrisBlockData i : filter) { - BlockData bx = i.getBlockData(rdata); + PlatformBlockState bx = i.getBlockData(rdata); if (bx != null) { b.add(bx); @@ -65,9 +66,10 @@ public class IrisObjectLoot implements IObjectLoot { }); } - public boolean matchesFilter(IrisData manager, BlockData data) { - for (BlockData filterData : getFilter(manager)) { - if (filterData.matches(data)) return true; + public boolean matchesFilter(IrisData manager, PlatformBlockState data) { + BlockData raw = (BlockData) data.nativeHandle(); + for (PlatformBlockState filterState : getFilter(manager)) { + if (((BlockData) filterState.nativeHandle()).matches(raw)) return true; } return false; } diff --git a/core/src/main/java/art/arcane/iris/engine/object/IrisObjectMarker.java b/core/src/main/java/art/arcane/iris/engine/object/IrisObjectMarker.java index f547a3878..6842826fd 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/IrisObjectMarker.java +++ b/core/src/main/java/art/arcane/iris/engine/object/IrisObjectMarker.java @@ -25,8 +25,8 @@ import art.arcane.volmlib.util.collection.KList; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import art.arcane.iris.spi.PlatformBlockState; import lombok.experimental.Accessors; -import org.bukkit.block.data.BlockData; @Snippet("object-marker") @Accessors(chain = true) @@ -35,7 +35,7 @@ import org.bukkit.block.data.BlockData; @Desc("Find blocks to mark") @Data public class IrisObjectMarker { - private final transient AtomicCache> findData = new AtomicCache<>(); + private final transient AtomicCache> findData = new AtomicCache<>(); @ArrayType(min = 1, type = IrisBlockData.class) @Required @Desc("Find block types to mark") @@ -51,13 +51,13 @@ public class IrisObjectMarker { @Desc("The marker to add") private String marker; - public KList getMark(IrisData rdata) { + public KList getMark(IrisData rdata) { return findData.aquire(() -> { - KList b = new KList<>(); + KList b = new KList<>(); for (IrisBlockData i : mark) { - BlockData bx = i.getBlockData(rdata); + PlatformBlockState bx = i.getBlockData(rdata); if (bx != null) { b.add(bx); diff --git a/core/src/main/java/art/arcane/iris/engine/object/IrisObjectPlacement.java b/core/src/main/java/art/arcane/iris/engine/object/IrisObjectPlacement.java index 67f6e68b8..799983b39 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/IrisObjectPlacement.java +++ b/core/src/main/java/art/arcane/iris/engine/object/IrisObjectPlacement.java @@ -23,6 +23,7 @@ import art.arcane.iris.core.loader.IrisData; import art.arcane.iris.engine.data.cache.AtomicCache; import art.arcane.iris.engine.framework.Engine; import art.arcane.iris.engine.object.annotations.*; +import art.arcane.iris.spi.PlatformBlockState; import art.arcane.volmlib.util.collection.KList; import art.arcane.volmlib.util.collection.KMap; import art.arcane.iris.util.common.data.B; @@ -275,7 +276,8 @@ public class IrisObjectPlacement { tc.global.put(table, loot.getWeight()); } else if (!loot.isExact()) //Table is meant to be by type { - for (BlockData filterData : loot.getFilter(manager)) { + for (PlatformBlockState filterState : loot.getFilter(manager)) { + BlockData filterData = (BlockData) filterState.nativeHandle(); if (!tc.basic.containsKey(filterData.getMaterial())) { tc.basic.put(filterData.getMaterial(), new WeightedRandom<>()); } @@ -284,7 +286,8 @@ public class IrisObjectPlacement { } } else //Filter is exact { - for (BlockData filterData : loot.getFilter(manager)) { + for (PlatformBlockState filterState : loot.getFilter(manager)) { + BlockData filterData = (BlockData) filterState.nativeHandle(); if (!tc.exact.containsKey(filterData.getMaterial())) { tc.exact.put(filterData.getMaterial(), new KMap<>()); } @@ -311,12 +314,13 @@ public class IrisObjectPlacement { /** * Gets the loot table that should be used for the block * - * @param data The block data of the block + * @param state The block state of the block * @param dataManager Iris Data Manager * @return The loot table it should use. */ - public IrisLootTable getTable(BlockData data, IrisData dataManager) { + public IrisLootTable getTable(PlatformBlockState state, IrisData dataManager) { TableCache cache = getCache(dataManager); + BlockData data = (BlockData) state.nativeHandle(); if (B.isStorageChest(data)) { IrisLootTable picked = null; if (cache.exact.containsKey(data.getMaterial()) && cache.exact.get(data.getMaterial()).containsKey(data)) { diff --git a/core/src/main/java/art/arcane/iris/engine/object/IrisObjectReplace.java b/core/src/main/java/art/arcane/iris/engine/object/IrisObjectReplace.java index 56b4f27e0..85075adc7 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/IrisObjectReplace.java +++ b/core/src/main/java/art/arcane/iris/engine/object/IrisObjectReplace.java @@ -27,8 +27,8 @@ import art.arcane.iris.util.project.noise.CNG; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import art.arcane.iris.spi.PlatformBlockState; import lombok.experimental.Accessors; -import org.bukkit.block.data.BlockData; @Snippet("object-block-replacer") @Accessors(chain = true) @@ -38,8 +38,8 @@ import org.bukkit.block.data.BlockData; @Data public class IrisObjectReplace { private final transient AtomicCache replaceGen = new AtomicCache<>(); - private final transient AtomicCache> findData = new AtomicCache<>(); - private final transient AtomicCache> replaceData = new AtomicCache<>(); + private final transient AtomicCache> findData = new AtomicCache<>(); + private final transient AtomicCache> replaceData = new AtomicCache<>(); @ArrayType(min = 1, type = IrisBlockData.class) @Required @Desc("Find this block") @@ -54,13 +54,13 @@ public class IrisObjectReplace { @Desc("Modifies the chance the block is replaced") private float chance = 1; - public KList getFind(IrisData rdata) { + public KList getFind(IrisData rdata) { return findData.aquire(() -> { - KList b = new KList<>(); + KList b = new KList<>(); for (IrisBlockData i : find) { - BlockData bx = i.getBlockData(rdata); + PlatformBlockState bx = i.getBlockData(rdata); if (bx != null) { b.add(bx); @@ -71,7 +71,7 @@ public class IrisObjectReplace { }); } - public BlockData getReplace(RNG seed, double x, double y, double z, IrisData rdata) { + public PlatformBlockState getReplace(RNG seed, double x, double y, double z, IrisData rdata) { return getReplace().get(seed, x, y, z, rdata); } } diff --git a/core/src/main/java/art/arcane/iris/engine/object/IrisObjectRotation.java b/core/src/main/java/art/arcane/iris/engine/object/IrisObjectRotation.java index 280c1ad39..120e8cd83 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/IrisObjectRotation.java +++ b/core/src/main/java/art/arcane/iris/engine/object/IrisObjectRotation.java @@ -21,6 +21,8 @@ package art.arcane.iris.engine.object; import art.arcane.iris.Iris; import art.arcane.iris.engine.object.annotations.Desc; import art.arcane.iris.engine.object.annotations.Snippet; +import art.arcane.iris.platform.bukkit.BukkitBlockState; +import art.arcane.iris.spi.PlatformBlockState; import art.arcane.volmlib.util.collection.KList; import art.arcane.volmlib.util.collection.KMap; import lombok.AllArgsConstructor; @@ -245,6 +247,16 @@ public class IrisObjectRotation { } + public PlatformBlockState rotate(PlatformBlockState state, int spinx, int spiny, int spinz) { + if (state == null) { + return null; + } + + BlockData raw = ((BlockData) state.nativeHandle()).clone(); + BlockData rotated = rotate(raw, spinx, spiny, spinz); + return rotated == null ? null : BukkitBlockState.of(rotated); + } + public BlockData rotate(BlockData dd, int spinxx, int spinyy, int spinzz) { BlockData d = dd; try { diff --git a/core/src/main/java/art/arcane/iris/engine/object/IrisObjectVanillaLoot.java b/core/src/main/java/art/arcane/iris/engine/object/IrisObjectVanillaLoot.java index e5b820ab9..65c651d04 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/IrisObjectVanillaLoot.java +++ b/core/src/main/java/art/arcane/iris/engine/object/IrisObjectVanillaLoot.java @@ -8,8 +8,8 @@ import art.arcane.volmlib.util.collection.KList; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import art.arcane.iris.spi.PlatformBlockState; import lombok.experimental.Accessors; -import org.bukkit.block.data.BlockData; @Snippet("object-vanilla-loot") @Accessors(chain = true) @@ -18,7 +18,7 @@ import org.bukkit.block.data.BlockData; @Desc("Represents vanilla loot within this object") @Data public class IrisObjectVanillaLoot implements IObjectLoot { - private final transient AtomicCache> filterCache = new AtomicCache<>(); + private final transient AtomicCache> filterCache = new AtomicCache<>(); @ArrayType(min = 1, type = IrisBlockData.class) @Desc("The list of blocks this loot table should apply to") private KList filter = new KList<>(); @@ -31,13 +31,13 @@ public class IrisObjectVanillaLoot implements IObjectLoot { @Desc("The weight of this loot table being chosen") private int weight = 1; - public KList getFilter(IrisData rdata) { + public KList getFilter(IrisData rdata) { return filterCache.aquire(() -> { - KList b = new KList<>(); + KList b = new KList<>(); for (IrisBlockData i : filter) { - BlockData bx = i.getBlockData(rdata); + PlatformBlockState bx = i.getBlockData(rdata); if (bx != null) { b.add(bx); diff --git a/core/src/main/java/art/arcane/iris/engine/object/IrisOreGenerator.java b/core/src/main/java/art/arcane/iris/engine/object/IrisOreGenerator.java index 98e2a6881..12a227810 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/IrisOreGenerator.java +++ b/core/src/main/java/art/arcane/iris/engine/object/IrisOreGenerator.java @@ -26,8 +26,8 @@ import art.arcane.iris.util.project.noise.CNG; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import art.arcane.iris.spi.PlatformBlockState; import lombok.experimental.Accessors; -import org.bukkit.block.data.BlockData; @Accessors(chain = true) @NoArgsConstructor @@ -53,7 +53,7 @@ public class IrisOreGenerator { palette.getLayerGenerator(rng, data); } - public BlockData generate(int x, int y, int z, RNG rng, IrisData data) { + public PlatformBlockState generate(int x, int y, int z, RNG rng, IrisData data) { if (palette.getPalette().isEmpty()) { return null; } diff --git a/core/src/main/java/art/arcane/iris/engine/object/IrisProceduralBlocks.java b/core/src/main/java/art/arcane/iris/engine/object/IrisProceduralBlocks.java index 0b0adc78e..a848295fe 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/IrisProceduralBlocks.java +++ b/core/src/main/java/art/arcane/iris/engine/object/IrisProceduralBlocks.java @@ -19,6 +19,8 @@ package art.arcane.iris.engine.object; import art.arcane.iris.core.loader.IrisData; +import art.arcane.iris.platform.bukkit.BukkitBlockState; +import art.arcane.iris.spi.PlatformBlockState; import art.arcane.iris.util.common.data.B; import art.arcane.iris.util.common.math.Vector3i; import art.arcane.volmlib.util.math.RNG; @@ -42,8 +44,8 @@ public final class IrisProceduralBlocks { public static BlockData resolve(String block, IrisMaterialPalette palette, IrisData data, int x, int y, int z, RNG paletteRng) { if (paletteSet(palette)) { - BlockData bd = palette.get(paletteRng, x, y, z, data); - return bd == null ? null : bd.clone(); + PlatformBlockState state = palette.get(paletteRng, x, y, z, data); + return state == null ? null : ((BlockData) state.nativeHandle()).clone(); } if (block != null && !block.isEmpty()) { BlockData bd = B.getOrNull(block, false); @@ -85,7 +87,7 @@ public final class IrisProceduralBlocks { int nx = v.getBlockX() - minX - cx; int ny = v.getBlockY() - cy + 1; int nz = v.getBlockZ() - minZ - cz; - object.getBlocks().put(new Vector3i(nx, ny, nz), entry.getValue()); + object.getBlocks().put(new Vector3i(nx, ny, nz), BukkitBlockState.of(entry.getValue())); } return object; diff --git a/core/src/main/java/art/arcane/iris/engine/object/IrisRegion.java b/core/src/main/java/art/arcane/iris/engine/object/IrisRegion.java index f42029d0f..0803ba363 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/IrisRegion.java +++ b/core/src/main/java/art/arcane/iris/engine/object/IrisRegion.java @@ -21,6 +21,7 @@ package art.arcane.iris.engine.object; import art.arcane.iris.Iris; import art.arcane.iris.core.gui.components.RenderType; import art.arcane.iris.core.loader.IrisData; +import art.arcane.iris.spi.PlatformBlockState; import art.arcane.iris.core.loader.IrisRegistrant; import art.arcane.iris.engine.data.cache.AtomicCache; import art.arcane.iris.engine.object.annotations.*; @@ -40,7 +41,6 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; -import org.bukkit.block.data.BlockData; import java.awt.*; import java.util.Random; @@ -157,16 +157,16 @@ public class IrisRegion extends IrisRegistrant implements IRare { @ArrayType(type = IrisOreGenerator.class, min = 1) private KList ores = new KList<>(); - public BlockData generateOres(int x, int y, int z, RNG rng, IrisData data, boolean surface) { + public PlatformBlockState generateOres(int x, int y, int z, RNG rng, IrisData data, boolean surface) { KList localOres = surface ? getSurfaceOres() : getUndergroundOres(); return generateOres(localOres, x, y, z, rng, data); } - public BlockData generateSurfaceOres(int x, int y, int z, RNG rng, IrisData data) { + public PlatformBlockState generateSurfaceOres(int x, int y, int z, RNG rng, IrisData data) { return generateOres(getSurfaceOres(), x, y, z, rng, data); } - public BlockData generateUndergroundOres(int x, int y, int z, RNG rng, IrisData data) { + public PlatformBlockState generateUndergroundOres(int x, int y, int z, RNG rng, IrisData data) { return generateOres(getUndergroundOres(), x, y, z, rng, data); } @@ -178,7 +178,7 @@ public class IrisRegion extends IrisRegistrant implements IRare { return !getUndergroundOres().isEmpty(); } - private BlockData generateOres(KList localOres, int x, int y, int z, RNG rng, IrisData data) { + private PlatformBlockState generateOres(KList localOres, int x, int y, int z, RNG rng, IrisData data) { if (localOres.isEmpty()) { return null; } @@ -186,7 +186,7 @@ public class IrisRegion extends IrisRegistrant implements IRare { int oreCount = localOres.size(); for (int oreIndex = 0; oreIndex < oreCount; oreIndex++) { IrisOreGenerator oreGenerator = localOres.get(oreIndex); - BlockData ore = oreGenerator.generate(x, y, z, rng, data); + PlatformBlockState ore = oreGenerator.generate(x, y, z, rng, data); if (ore != null) { return ore; } diff --git a/core/src/main/java/art/arcane/iris/engine/object/formation/FormationBlockResolver.java b/core/src/main/java/art/arcane/iris/engine/object/formation/FormationBlockResolver.java index f500c5843..4eb0e426c 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/formation/FormationBlockResolver.java +++ b/core/src/main/java/art/arcane/iris/engine/object/formation/FormationBlockResolver.java @@ -22,6 +22,7 @@ import art.arcane.iris.core.loader.IrisData; import art.arcane.iris.engine.object.IrisFormation; import art.arcane.iris.engine.object.IrisMaterialPalette; import art.arcane.iris.engine.object.IrisProceduralBlocks; +import art.arcane.iris.spi.PlatformBlockState; import art.arcane.iris.util.common.math.Vector3i; import art.arcane.volmlib.util.math.RNG; import org.bukkit.block.data.BlockData; @@ -47,9 +48,9 @@ public final class FormationBlockResolver { IrisMaterialPalette strata = f.getStrataPalette(); int thickness = Math.max(1, f.getStrataThickness()); int band = Math.floorDiv(y, thickness); - BlockData strataBlock = strata.get(new RNG(f.getSeed() + (band * 31L)), x, band, z, data); - if (strataBlock != null) { - return strataBlock.clone(); + PlatformBlockState strataState = strata.get(new RNG(f.getSeed() + (band * 31L)), x, band, z, data); + if (strataState != null) { + return ((BlockData) strataState.nativeHandle()).clone(); } } diff --git a/core/src/main/java/art/arcane/iris/engine/object/tree/ProceduralTreeGenerator.java b/core/src/main/java/art/arcane/iris/engine/object/tree/ProceduralTreeGenerator.java index d89c6e501..75c51d811 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/tree/ProceduralTreeGenerator.java +++ b/core/src/main/java/art/arcane/iris/engine/object/tree/ProceduralTreeGenerator.java @@ -21,6 +21,7 @@ package art.arcane.iris.engine.object.tree; import art.arcane.iris.core.loader.IrisData; import art.arcane.iris.engine.object.IrisObject; import art.arcane.iris.engine.object.IrisProceduralTree; +import art.arcane.iris.platform.bukkit.BukkitBlockState; import art.arcane.iris.util.common.math.Vector3i; import art.arcane.volmlib.util.math.RNG; import org.bukkit.block.data.BlockData; @@ -118,7 +119,7 @@ public final class ProceduralTreeGenerator { int nx = v.x() - minX - cx; int ny = v.y() - cy + 1; int nz = v.z() - minZ - cz; - object.getBlocks().put(new Vector3i(nx, ny, nz), entry.getValue()); + object.getBlocks().put(new Vector3i(nx, ny, nz), BukkitBlockState.of(entry.getValue())); } return object; diff --git a/core/src/main/java/art/arcane/iris/engine/object/tree/TreeBlockResolver.java b/core/src/main/java/art/arcane/iris/engine/object/tree/TreeBlockResolver.java index 19035b812..f77d1c334 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/tree/TreeBlockResolver.java +++ b/core/src/main/java/art/arcane/iris/engine/object/tree/TreeBlockResolver.java @@ -22,6 +22,7 @@ import art.arcane.iris.core.loader.IrisData; import art.arcane.iris.engine.object.IrisMaterialPalette; import art.arcane.iris.engine.object.IrisProceduralTree; import art.arcane.iris.engine.object.IrisTreeDecorator; +import art.arcane.iris.spi.PlatformBlockState; import art.arcane.iris.util.common.data.B; import art.arcane.volmlib.util.math.RNG; import org.bukkit.Axis; @@ -100,8 +101,8 @@ public final class TreeBlockResolver { private static BlockData resolveSecondaryLeaf(IrisProceduralTree tree, IrisData data, TreeBlockCanvas.Vec pos, RNG paletteRng, RNG posRng) { if (TreeTrunkBuilder.paletteSet(tree.getSecondaryLeavesPalette())) { - BlockData bd = tree.getSecondaryLeavesPalette().get(paletteRng, pos.x(), pos.y(), pos.z(), data); - return bd == null ? null : bd.clone(); + PlatformBlockState state = tree.getSecondaryLeavesPalette().get(paletteRng, pos.x(), pos.y(), pos.z(), data); + return state == null ? null : ((BlockData) state.nativeHandle()).clone(); } if (tree.getWeightedSecondaryLeaves() != null && !tree.getWeightedSecondaryLeaves().isEmpty()) { String picked = pickWeighted(tree, posRng); @@ -134,8 +135,8 @@ public final class TreeBlockResolver { private static BlockData resolveBlock(String block, IrisMaterialPalette palette, IrisData data, TreeBlockCanvas.Vec pos, RNG paletteRng) { if (TreeTrunkBuilder.paletteSet(palette)) { - BlockData bd = palette.get(paletteRng, pos.x(), pos.y(), pos.z(), data); - return bd == null ? null : bd.clone(); + PlatformBlockState state = palette.get(paletteRng, pos.x(), pos.y(), pos.z(), data); + return state == null ? null : ((BlockData) state.nativeHandle()).clone(); } if (block != null && !block.isEmpty()) { return cloneOrNull(B.getOrNull(block, false)); diff --git a/core/src/main/java/art/arcane/iris/engine/platform/BukkitChunkGenerator.java b/core/src/main/java/art/arcane/iris/engine/platform/BukkitChunkGenerator.java index e2a93a498..3521e19f3 100644 --- a/core/src/main/java/art/arcane/iris/engine/platform/BukkitChunkGenerator.java +++ b/core/src/main/java/art/arcane/iris/engine/platform/BukkitChunkGenerator.java @@ -37,6 +37,7 @@ import art.arcane.iris.engine.object.VanillaStructureMode; import art.arcane.iris.engine.object.IrisWorld; import art.arcane.iris.engine.object.StudioMode; import art.arcane.iris.engine.platform.studio.StudioGenerator; +import art.arcane.iris.spi.PlatformBiome; import art.arcane.volmlib.util.collection.KList; import art.arcane.iris.util.project.hunk.Hunk; import art.arcane.iris.util.project.hunk.view.ChunkDataHunkHolder; @@ -49,8 +50,6 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.Setter; import org.bukkit.*; -import org.bukkit.block.Biome; -import org.bukkit.block.data.BlockData; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; @@ -419,7 +418,7 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun studioGenerator.generateChunk(engine, tc, x, z); } else { ChunkDataHunkHolder blocks = new ChunkDataHunkHolder(d); - Hunk biomes = Hunk.viewBiomes(tc); + Hunk biomes = Hunk.viewBiomes(tc); boolean useMulticore = studio && !J.isFolia(); engine.generate(x << 4, z << 4, blocks, biomes, useMulticore); blocks.apply(); diff --git a/core/src/main/java/art/arcane/iris/engine/platform/studio/generators/BiomeBuffetGenerator.java b/core/src/main/java/art/arcane/iris/engine/platform/studio/generators/BiomeBuffetGenerator.java index 9fb6733e3..2695f7ae5 100644 --- a/core/src/main/java/art/arcane/iris/engine/platform/studio/generators/BiomeBuffetGenerator.java +++ b/core/src/main/java/art/arcane/iris/engine/platform/studio/generators/BiomeBuffetGenerator.java @@ -24,13 +24,14 @@ import art.arcane.iris.engine.framework.Engine; import art.arcane.iris.engine.framework.WrongEngineBroException; import art.arcane.iris.engine.object.IrisBiome; import art.arcane.iris.engine.platform.studio.EnginedStudioGenerator; +import art.arcane.iris.platform.bukkit.BukkitBlockState; +import art.arcane.iris.spi.PlatformBlockState; import org.bukkit.Material; -import org.bukkit.block.data.BlockData; import java.util.Objects; public class BiomeBuffetGenerator extends EnginedStudioGenerator { - private static final BlockData FLOOR = Material.BARRIER.createBlockData(); + private static final PlatformBlockState FLOOR = BukkitBlockState.of(Material.BARRIER.createBlockData()); private final IrisBiome[] biomes; private final int width; private final int biomeSize; diff --git a/core/src/main/java/art/arcane/iris/engine/platform/studio/generators/ObjectStudioGenerator.java b/core/src/main/java/art/arcane/iris/engine/platform/studio/generators/ObjectStudioGenerator.java index e5bc77c55..eb6a3bc32 100644 --- a/core/src/main/java/art/arcane/iris/engine/platform/studio/generators/ObjectStudioGenerator.java +++ b/core/src/main/java/art/arcane/iris/engine/platform/studio/generators/ObjectStudioGenerator.java @@ -29,11 +29,14 @@ import art.arcane.iris.engine.framework.Engine; import art.arcane.iris.engine.framework.WrongEngineBroException; import art.arcane.iris.engine.object.IrisObject; import art.arcane.iris.engine.platform.studio.EnginedStudioGenerator; +import art.arcane.iris.platform.bukkit.BukkitBiome; +import art.arcane.iris.platform.bukkit.BukkitBlockState; +import art.arcane.iris.spi.PlatformBiome; +import art.arcane.iris.spi.PlatformBlockState; import art.arcane.iris.util.common.data.VectorMap; import art.arcane.iris.util.common.math.Vector3i; import org.bukkit.Material; import org.bukkit.block.Biome; -import org.bukkit.block.data.BlockData; import org.bukkit.util.BlockVector; import java.io.File; @@ -44,15 +47,15 @@ import java.util.concurrent.atomic.AtomicBoolean; public class ObjectStudioGenerator extends EnginedStudioGenerator { public static final int DEFAULT_PADDING = 2; - private static final BlockData FLOOR = Material.POLISHED_DEEPSLATE.createBlockData(); - private static final BlockData FRAME = Material.SMOOTH_QUARTZ.createBlockData(); - private static final BlockData MARKER = Material.END_ROD.createBlockData(); - private static final Biome DEFAULT_BIOME = Biome.PLAINS; + private static final PlatformBlockState FLOOR = BukkitBlockState.of(Material.POLISHED_DEEPSLATE.createBlockData()); + private static final PlatformBlockState FRAME = BukkitBlockState.of(Material.SMOOTH_QUARTZ.createBlockData()); + private static final PlatformBlockState MARKER = BukkitBlockState.of(Material.END_ROD.createBlockData()); + private static final PlatformBiome DEFAULT_BIOME = BukkitBiome.of(Biome.PLAINS); private final int padding; - private final BlockData floor; - private final BlockData frame; - private final BlockData marker; + private final PlatformBlockState floor; + private final PlatformBlockState frame; + private final PlatformBlockState marker; private final AtomicBoolean layoutBuilt = new AtomicBoolean(false); private final Object layoutLock = new Object(); private final Map objectCache = new ConcurrentHashMap<>(); @@ -63,7 +66,7 @@ public class ObjectStudioGenerator extends EnginedStudioGenerator { this(engine, DEFAULT_PADDING, FLOOR, FRAME, MARKER); } - public ObjectStudioGenerator(Engine engine, int padding, BlockData floor, BlockData frame, BlockData marker) { + public ObjectStudioGenerator(Engine engine, int padding, PlatformBlockState floor, PlatformBlockState frame, PlatformBlockState marker) { super(engine); this.padding = padding; this.floor = floor; @@ -183,7 +186,7 @@ public class ObjectStudioGenerator extends EnginedStudioGenerator { } private void placeSlice(IrisObject object, GridCell cell, TerrainChunk tc, int chunkWorldX, int chunkWorldZ, int minHeight, int maxHeight) { - VectorMap blocks = object.getBlocks(); + VectorMap blocks = object.getBlocks(); if (blocks == null || blocks.isEmpty()) return; Vector3i center = object.getCenter(); @@ -195,7 +198,7 @@ public class ObjectStudioGenerator extends EnginedStudioGenerator { int originY = cell.originY(); int originZ = cell.originZ(); - for (Map.Entry entry : blocks) { + for (Map.Entry entry : blocks) { BlockVector signed = entry.getKey(); int worldX = originX + signed.getBlockX() + centerX; int worldY = originY + signed.getBlockY() + centerY; @@ -205,7 +208,7 @@ public class ObjectStudioGenerator extends EnginedStudioGenerator { if (worldZ < chunkWorldZ || worldZ > chunkWorldZ + 15) continue; if (worldY < minHeight || worldY >= maxHeight) continue; - BlockData data = entry.getValue(); + PlatformBlockState data = entry.getValue(); if (data == null) continue; tc.setBlock(worldX - chunkWorldX, worldY, worldZ - chunkWorldZ, data); diff --git a/core/src/main/java/art/arcane/iris/platform/bukkit/BukkitChunkWriteTarget.java b/core/src/main/java/art/arcane/iris/platform/bukkit/BukkitChunkWriteTarget.java index 3b33890df..adad6a64b 100644 --- a/core/src/main/java/art/arcane/iris/platform/bukkit/BukkitChunkWriteTarget.java +++ b/core/src/main/java/art/arcane/iris/platform/bukkit/BukkitChunkWriteTarget.java @@ -22,8 +22,6 @@ import art.arcane.iris.engine.data.chunk.TerrainChunk; import art.arcane.iris.spi.ChunkWriteTarget; import art.arcane.iris.spi.PlatformBiome; import art.arcane.iris.spi.PlatformBlockState; -import org.bukkit.block.Biome; -import org.bukkit.block.data.BlockData; /** * Bukkit adapter for the hot-path chunk write surface backed by TerrainChunk. @@ -37,12 +35,12 @@ public final class BukkitChunkWriteTarget implements ChunkWriteTarget { @Override public void setBlock(int x, int y, int z, PlatformBlockState state) { - terrain.setBlock(x, y, z, (BlockData) state.nativeHandle()); + terrain.setBlock(x, y, z, state); } @Override public void setBiome(int x, int y, int z, PlatformBiome biome) { - terrain.setBiome(x, y, z, (Biome) biome.nativeHandle()); + terrain.setBiome(x, y, z, biome); } @Override diff --git a/core/src/main/java/art/arcane/iris/util/project/context/ChunkContext.java b/core/src/main/java/art/arcane/iris/util/project/context/ChunkContext.java index 5facff86b..73d92cb69 100644 --- a/core/src/main/java/art/arcane/iris/util/project/context/ChunkContext.java +++ b/core/src/main/java/art/arcane/iris/util/project/context/ChunkContext.java @@ -5,8 +5,8 @@ import art.arcane.iris.engine.IrisComplex; import art.arcane.iris.engine.framework.EngineMetrics; import art.arcane.iris.engine.object.IrisBiome; import art.arcane.iris.engine.object.IrisRegion; +import art.arcane.iris.spi.PlatformBlockState; import art.arcane.iris.util.common.parallel.MultiBurst; -import org.bukkit.block.data.BlockData; import java.util.ArrayList; import java.util.List; @@ -21,8 +21,8 @@ public class ChunkContext { private final int[] roundedHeight; private final ChunkedDataCache biome; private final ChunkedDataCache cave; - private final ChunkedDataCache rock; - private final ChunkedDataCache fluid; + private final ChunkedDataCache rock; + private final ChunkedDataCache fluid; private final ChunkedDataCache region; public ChunkContext(int x, int z, IrisComplex complex) { @@ -138,11 +138,11 @@ public class ChunkContext { return cave; } - public ChunkedDataCache getRock() { + public ChunkedDataCache getRock() { return rock; } - public ChunkedDataCache getFluid() { + public ChunkedDataCache getFluid() { return fluid; } diff --git a/core/src/main/java/art/arcane/iris/util/project/hunk/Hunk.java b/core/src/main/java/art/arcane/iris/util/project/hunk/Hunk.java index e7448c849..b34e86ec7 100644 --- a/core/src/main/java/art/arcane/iris/util/project/hunk/Hunk.java +++ b/core/src/main/java/art/arcane/iris/util/project/hunk/Hunk.java @@ -35,10 +35,10 @@ import art.arcane.iris.util.project.interpolation.InterpolationMethod3D; import art.arcane.iris.util.project.interpolation.IrisInterpolation; import art.arcane.volmlib.util.math.BlockPosition; import art.arcane.iris.util.common.parallel.MultiBurst; +import art.arcane.iris.spi.PlatformBiome; +import art.arcane.iris.spi.PlatformBlockState; import art.arcane.iris.util.project.stream.interpolation.Interpolated; import org.bukkit.Chunk; -import org.bukkit.block.Biome; -import org.bukkit.block.data.BlockData; import org.bukkit.generator.ChunkGenerator.ChunkData; import java.io.IOException; @@ -98,23 +98,23 @@ public interface Hunk extends HunkLike { return adapt(new art.arcane.volmlib.util.hunk.view.FringedHunkView<>(unwrap(i), unwrap(o))); } - static Hunk view(TerrainChunk src) { + static Hunk view(TerrainChunk src) { return new ChunkDataHunkView(src.getChunkData()); } - static Hunk viewBiomes(TerrainChunk src) { + static Hunk viewBiomes(TerrainChunk src) { return new TerrainChunkBiomeHunkView(src); } - static Hunk view(ChunkData src) { + static Hunk view(ChunkData src) { return new ChunkDataHunkView(src); } - static Hunk viewBlocks(Chunk src) { + static Hunk viewBlocks(Chunk src) { return new ChunkHunkView(src); } - static Hunk viewBiomes(Chunk src) { + static Hunk viewBiomes(Chunk src) { return new ChunkBiomeHunkView(src); } diff --git a/core/src/main/java/art/arcane/iris/util/project/hunk/view/ChunkBiomeHunkView.java b/core/src/main/java/art/arcane/iris/util/project/hunk/view/ChunkBiomeHunkView.java index 8bf0dc67c..fc8836ce2 100644 --- a/core/src/main/java/art/arcane/iris/util/project/hunk/view/ChunkBiomeHunkView.java +++ b/core/src/main/java/art/arcane/iris/util/project/hunk/view/ChunkBiomeHunkView.java @@ -20,16 +20,18 @@ package art.arcane.iris.util.project.hunk.view; import art.arcane.iris.Iris; import art.arcane.iris.core.service.EditSVC; +import art.arcane.iris.platform.bukkit.BukkitBiome; +import art.arcane.iris.spi.PlatformBiome; import art.arcane.iris.util.project.hunk.Hunk; import org.bukkit.Chunk; import org.bukkit.block.Biome; @SuppressWarnings("ClassCanBeRecord") -public class ChunkBiomeHunkView extends art.arcane.volmlib.util.hunk.view.ChunkWorldHunkView implements Hunk { +public class ChunkBiomeHunkView extends art.arcane.volmlib.util.hunk.view.ChunkWorldHunkView implements Hunk { public ChunkBiomeHunkView(Chunk chunk) { super(chunk, chunk.getWorld().getMaxHeight(), - (wx, y, wz, t) -> Iris.service(EditSVC.class).setBiome(chunk.getWorld(), wx, y, wz, t), - (wx, y, wz) -> Iris.service(EditSVC.class).getBiome(chunk.getWorld(), wx, y, wz)); + (wx, y, wz, t) -> Iris.service(EditSVC.class).setBiome(chunk.getWorld(), wx, y, wz, (Biome) t.nativeHandle()), + (wx, y, wz) -> BukkitBiome.of(Iris.service(EditSVC.class).getBiome(chunk.getWorld(), wx, y, wz))); } } diff --git a/core/src/main/java/art/arcane/iris/util/project/hunk/view/ChunkDataHunkHolder.java b/core/src/main/java/art/arcane/iris/util/project/hunk/view/ChunkDataHunkHolder.java index 0513a688d..7fccad5d0 100644 --- a/core/src/main/java/art/arcane/iris/util/project/hunk/view/ChunkDataHunkHolder.java +++ b/core/src/main/java/art/arcane/iris/util/project/hunk/view/ChunkDataHunkHolder.java @@ -18,14 +18,16 @@ package art.arcane.iris.util.project.hunk.view; +import art.arcane.iris.platform.bukkit.BukkitBlockState; +import art.arcane.iris.spi.PlatformBlockState; import art.arcane.iris.util.project.hunk.storage.AtomicHunk; import org.bukkit.Material; import org.bukkit.block.data.BlockData; import org.bukkit.generator.ChunkGenerator.ChunkData; @SuppressWarnings("ClassCanBeRecord") -public class ChunkDataHunkHolder extends AtomicHunk { - private static final BlockData AIR = Material.AIR.createBlockData(); +public class ChunkDataHunkHolder extends AtomicHunk { + private static final PlatformBlockState AIR = BukkitBlockState.of(Material.AIR.createBlockData()); private final ChunkData chunk; public ChunkDataHunkHolder(ChunkData chunk) { @@ -49,8 +51,8 @@ public class ChunkDataHunkHolder extends AtomicHunk { } @Override - public BlockData getRaw(int x, int y, int z) { - BlockData b = super.getRaw(x, y, z); + public PlatformBlockState getRaw(int x, int y, int z) { + PlatformBlockState b = super.getRaw(x, y, z); return b != null ? b : AIR; } @@ -59,10 +61,10 @@ public class ChunkDataHunkHolder extends AtomicHunk { for (int i = 0; i < getHeight(); i++) { for (int j = 0; j < getWidth(); j++) { for (int k = 0; k < getDepth(); k++) { - BlockData b = super.getRaw(j, i, k); + PlatformBlockState b = super.getRaw(j, i, k); if (b != null) { - chunk.setBlock(j, i + chunk.getMinHeight(), k, b); + chunk.setBlock(j, i + chunk.getMinHeight(), k, (BlockData) b.nativeHandle()); } } } diff --git a/core/src/main/java/art/arcane/iris/util/project/hunk/view/ChunkDataHunkView.java b/core/src/main/java/art/arcane/iris/util/project/hunk/view/ChunkDataHunkView.java index 2ef27c924..09e8122df 100644 --- a/core/src/main/java/art/arcane/iris/util/project/hunk/view/ChunkDataHunkView.java +++ b/core/src/main/java/art/arcane/iris/util/project/hunk/view/ChunkDataHunkView.java @@ -18,6 +18,8 @@ package art.arcane.iris.util.project.hunk.view; +import art.arcane.iris.platform.bukkit.BukkitBlockState; +import art.arcane.iris.spi.PlatformBlockState; import art.arcane.iris.util.common.data.B; import art.arcane.iris.util.common.data.IrisCustomData; import art.arcane.iris.util.project.hunk.Hunk; @@ -25,23 +27,64 @@ import org.bukkit.block.data.BlockData; import org.bukkit.generator.ChunkGenerator.ChunkData; @SuppressWarnings("ClassCanBeRecord") -public class ChunkDataHunkView extends art.arcane.volmlib.util.hunk.view.ChunkDataHunkView implements Hunk { +public class ChunkDataHunkView implements Hunk { private static final BlockData AIR = B.getAir(); + private final art.arcane.volmlib.util.hunk.view.ChunkDataHunkView view; + public ChunkDataHunkView(ChunkData chunk) { - super(chunk, AIR, (data) -> data instanceof IrisCustomData d ? d.getBase() : data); + this.view = new art.arcane.volmlib.util.hunk.view.ChunkDataHunkView(chunk, AIR, (data) -> data instanceof IrisCustomData d ? d.getBase() : data); } @Override - public void set(int x1, int y1, int z1, int x2, int y2, int z2, BlockData t) { - setRegion(x1, y1, z1, x2, y2, z2, t); + public int getWidth() { + return view.getWidth(); } - public BlockData get(int x, int y, int z) { - return super.get(x, y, z); + @Override + public int getDepth() { + return view.getDepth(); } - public void set(int x, int y, int z, BlockData t) { - super.set(x, y, z, t); + @Override + public int getHeight() { + return view.getHeight(); + } + + @Override + public void set(int x1, int y1, int z1, int x2, int y2, int z2, PlatformBlockState t) { + if (t == null) { + return; + } + + view.setRegion(x1, y1, z1, x2, y2, z2, (BlockData) t.nativeHandle()); + } + + @Override + public PlatformBlockState get(int x, int y, int z) { + return BukkitBlockState.of(view.get(x, y, z)); + } + + @Override + public void set(int x, int y, int z, PlatformBlockState t) { + if (t == null) { + return; + } + + view.set(x, y, z, (BlockData) t.nativeHandle()); + } + + @Override + public void setRaw(int x, int y, int z, PlatformBlockState t) { + if (t == null) { + return; + } + + view.setRaw(x, y, z, (BlockData) t.nativeHandle()); + } + + @Override + public PlatformBlockState getRaw(int x, int y, int z) { + return BukkitBlockState.of(view.getRaw(x, y, z)); } } diff --git a/core/src/main/java/art/arcane/iris/util/project/hunk/view/ChunkHunkView.java b/core/src/main/java/art/arcane/iris/util/project/hunk/view/ChunkHunkView.java index 68fb9b51e..91c14a35e 100644 --- a/core/src/main/java/art/arcane/iris/util/project/hunk/view/ChunkHunkView.java +++ b/core/src/main/java/art/arcane/iris/util/project/hunk/view/ChunkHunkView.java @@ -20,16 +20,18 @@ package art.arcane.iris.util.project.hunk.view; import art.arcane.iris.Iris; import art.arcane.iris.core.service.EditSVC; +import art.arcane.iris.platform.bukkit.BukkitBlockState; +import art.arcane.iris.spi.PlatformBlockState; import art.arcane.iris.util.project.hunk.Hunk; import org.bukkit.Chunk; import org.bukkit.block.data.BlockData; @SuppressWarnings("ClassCanBeRecord") -public class ChunkHunkView extends art.arcane.volmlib.util.hunk.view.ChunkWorldHunkView implements Hunk { +public class ChunkHunkView extends art.arcane.volmlib.util.hunk.view.ChunkWorldHunkView implements Hunk { public ChunkHunkView(Chunk chunk) { super(chunk, chunk.getWorld().getMaxHeight(), - (wx, y, wz, t) -> Iris.service(EditSVC.class).set(chunk.getWorld(), wx, y, wz, t), - (wx, y, wz) -> Iris.service(EditSVC.class).get(chunk.getWorld(), wx, y, wz)); + (wx, y, wz, t) -> Iris.service(EditSVC.class).set(chunk.getWorld(), wx, y, wz, (BlockData) t.nativeHandle()), + (wx, y, wz) -> BukkitBlockState.of(Iris.service(EditSVC.class).get(chunk.getWorld(), wx, y, wz))); } } diff --git a/core/src/main/java/art/arcane/iris/util/project/hunk/view/TerrainChunkBiomeHunkView.java b/core/src/main/java/art/arcane/iris/util/project/hunk/view/TerrainChunkBiomeHunkView.java index 9ad5a6ed6..c92a5ac57 100644 --- a/core/src/main/java/art/arcane/iris/util/project/hunk/view/TerrainChunkBiomeHunkView.java +++ b/core/src/main/java/art/arcane/iris/util/project/hunk/view/TerrainChunkBiomeHunkView.java @@ -19,11 +19,11 @@ package art.arcane.iris.util.project.hunk.view; import art.arcane.iris.engine.data.chunk.TerrainChunk; +import art.arcane.iris.spi.PlatformBiome; import art.arcane.iris.util.project.hunk.Hunk; import art.arcane.iris.util.project.hunk.storage.StorageHunk; -import org.bukkit.block.Biome; -public class TerrainChunkBiomeHunkView extends StorageHunk implements Hunk { +public class TerrainChunkBiomeHunkView extends StorageHunk implements Hunk { private final TerrainChunk chunk; public TerrainChunkBiomeHunkView(TerrainChunk chunk) { @@ -32,12 +32,12 @@ public class TerrainChunkBiomeHunkView extends StorageHunk implements Hun } @Override - public void setRaw(int x, int y, int z, Biome biome) { + public void setRaw(int x, int y, int z, PlatformBiome biome) { chunk.setBiome(x, y + chunk.getMinHeight(), z, biome); } @Override - public Biome getRaw(int x, int y, int z) { + public PlatformBiome getRaw(int x, int y, int z) { return chunk.getBiome(x, y + chunk.getMinHeight(), z); } } diff --git a/core/src/main/java/art/arcane/iris/util/project/matter/IrisMatterSupport.java b/core/src/main/java/art/arcane/iris/util/project/matter/IrisMatterSupport.java index c7f3bb928..04c5e5bf9 100644 --- a/core/src/main/java/art/arcane/iris/util/project/matter/IrisMatterSupport.java +++ b/core/src/main/java/art/arcane/iris/util/project/matter/IrisMatterSupport.java @@ -64,7 +64,7 @@ public final class IrisMatterSupport { } for (BlockVector i : object.getBlocks().keys()) { - matter.slice(BlockData.class).set(i.getBlockX() - min.getBlockX(), i.getBlockY() - min.getBlockY(), i.getBlockZ() - min.getBlockZ(), object.getBlocks().get(i)); + matter.slice(BlockData.class).set(i.getBlockX() - min.getBlockX(), i.getBlockY() - min.getBlockY(), i.getBlockZ() - min.getBlockZ(), (BlockData) object.getBlocks().get(i).nativeHandle()); } return matter; diff --git a/core/src/main/java/art/arcane/iris/util/project/stream/interpolation/Interpolated.java b/core/src/main/java/art/arcane/iris/util/project/stream/interpolation/Interpolated.java index 19717a72a..1050f1828 100644 --- a/core/src/main/java/art/arcane/iris/util/project/stream/interpolation/Interpolated.java +++ b/core/src/main/java/art/arcane/iris/util/project/stream/interpolation/Interpolated.java @@ -20,16 +20,16 @@ package art.arcane.iris.util.project.stream.interpolation; import art.arcane.iris.Iris; import art.arcane.iris.engine.object.CaveResult; +import art.arcane.iris.spi.PlatformBlockState; import art.arcane.volmlib.util.collection.KList; import art.arcane.volmlib.util.math.RNG; import art.arcane.iris.util.project.stream.ProceduralStream; -import org.bukkit.block.data.BlockData; import java.util.UUID; import java.util.function.Function; public interface Interpolated { - Interpolated BLOCK_DATA = of((t) -> 0D, (t) -> null); + Interpolated BLOCK_DATA = of((t) -> 0D, (t) -> null); Interpolated> CAVE_RESULTS = of((t) -> 0D, (t) -> null); Interpolated RNG = of((t) -> 0D, (t) -> null); Interpolated DOUBLE = of((t) -> t, (t) -> t); diff --git a/core/src/test/java/art/arcane/iris/core/IrisRuntimeSchedulerModeRoutingTest.java b/core/src/test/java/art/arcane/iris/core/IrisRuntimeSchedulerModeRoutingTest.java index 44d17c23e..37ff046f6 100644 --- a/core/src/test/java/art/arcane/iris/core/IrisRuntimeSchedulerModeRoutingTest.java +++ b/core/src/test/java/art/arcane/iris/core/IrisRuntimeSchedulerModeRoutingTest.java @@ -5,13 +5,16 @@ import org.bukkit.Material; import org.bukkit.Server; import org.bukkit.block.data.BlockData; import org.junit.Test; +import org.mockito.invocation.InvocationOnMock; +import java.util.Locale; import java.util.logging.Logger; import static org.junit.Assert.assertEquals; import static org.junit.Assume.assumeTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mockingDetails; @@ -74,12 +77,18 @@ public class IrisRuntimeSchedulerModeRoutingTest { assumeTrue(server != null && mockingDetails(server).isMock()); - BlockData emptyBlockData = mock(BlockData.class); doReturn(Logger.getLogger("IrisTest")).when(server).getLogger(); doReturn(name).when(server).getName(); doReturn(version).when(server).getVersion(); doReturn(version).when(server).getBukkitVersion(); - doReturn(emptyBlockData).when(server).createBlockData(any(Material.class)); - doReturn(emptyBlockData).when(server).createBlockData(anyString()); + doAnswer((InvocationOnMock invocation) -> namedBlockData(invocation.getArgument(0, Material.class).name().toLowerCase(Locale.ROOT))).when(server).createBlockData(any(Material.class)); + doAnswer((InvocationOnMock invocation) -> namedBlockData(invocation.getArgument(0, String.class))).when(server).createBlockData(anyString()); + } + + private static BlockData namedBlockData(String key) { + String canonical = key.indexOf(':') >= 0 ? key : "minecraft:" + key; + BlockData data = mock(BlockData.class); + doReturn(canonical).when(data).getAsString(); + return data; } } diff --git a/core/src/test/java/art/arcane/iris/core/runtime/InPlaceChunkRegeneratorDiffTest.java b/core/src/test/java/art/arcane/iris/core/runtime/InPlaceChunkRegeneratorDiffTest.java index ee96518e5..fc25ecd94 100644 --- a/core/src/test/java/art/arcane/iris/core/runtime/InPlaceChunkRegeneratorDiffTest.java +++ b/core/src/test/java/art/arcane/iris/core/runtime/InPlaceChunkRegeneratorDiffTest.java @@ -23,6 +23,7 @@ public class InPlaceChunkRegeneratorDiffTest { @Test public void applyBlockDiffsSkipsAllWritesWhenChunkMatchesBuffer() { BlockData stone = mock(BlockData.class); + when(stone.getAsString()).thenReturn("minecraft:stone"); ChunkSnapshot snapshot = mock(ChunkSnapshot.class); when(snapshot.getBlockType(anyInt(), anyInt(), anyInt())).thenReturn(Material.STONE); when(snapshot.getBlockData(anyInt(), anyInt(), anyInt())).thenReturn(stone); @@ -43,7 +44,9 @@ public class InPlaceChunkRegeneratorDiffTest { @Test public void applyBlockDiffsWritesOnlyMaterialChanges() { BlockData stone = mock(BlockData.class); + when(stone.getAsString()).thenReturn("minecraft:stone"); BlockData dirt = mock(BlockData.class); + when(dirt.getAsString()).thenReturn("minecraft:dirt"); ChunkSnapshot snapshot = mock(ChunkSnapshot.class); when(snapshot.getBlockType(anyInt(), anyInt(), anyInt())).thenReturn(Material.STONE); when(snapshot.getBlockData(anyInt(), anyInt(), anyInt())).thenReturn(stone); @@ -68,7 +71,9 @@ public class InPlaceChunkRegeneratorDiffTest { @Test public void applyBlockDiffsWritesWhenMaterialMatchesButStateDiffers() { BlockData liveStairs = mock(BlockData.class); + when(liveStairs.getAsString()).thenReturn("minecraft:oak_stairs[facing=north]"); BlockData rotatedStairs = mock(BlockData.class); + when(rotatedStairs.getAsString()).thenReturn("minecraft:oak_stairs[facing=east]"); ChunkSnapshot snapshot = mock(ChunkSnapshot.class); when(snapshot.getBlockType(anyInt(), anyInt(), anyInt())).thenReturn(Material.OAK_STAIRS); when(snapshot.getBlockData(anyInt(), anyInt(), anyInt())).thenReturn(liveStairs); diff --git a/core/src/test/java/art/arcane/iris/engine/IrisComplexImplodeParityTest.java b/core/src/test/java/art/arcane/iris/engine/IrisComplexImplodeParityTest.java index 4f7a38b8b..fbf4b448a 100644 --- a/core/src/test/java/art/arcane/iris/engine/IrisComplexImplodeParityTest.java +++ b/core/src/test/java/art/arcane/iris/engine/IrisComplexImplodeParityTest.java @@ -10,16 +10,19 @@ import org.bukkit.Server; import org.bukkit.block.data.BlockData; import org.junit.BeforeClass; import org.junit.Test; +import org.mockito.invocation.InvocationOnMock; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import java.util.logging.Logger; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; @@ -31,13 +34,12 @@ public class IrisComplexImplodeParityTest { public static void setup() throws Exception { if (Bukkit.getServer() == null) { Server server = mock(Server.class); - BlockData emptyBlockData = mock(BlockData.class); doReturn(Logger.getLogger("IrisTest")).when(server).getLogger(); doReturn("IrisTestServer").when(server).getName(); doReturn("1.0").when(server).getVersion(); doReturn("1.0").when(server).getBukkitVersion(); - doReturn(emptyBlockData).when(server).createBlockData(any(Material.class)); - doReturn(emptyBlockData).when(server).createBlockData(anyString()); + doAnswer((InvocationOnMock invocation) -> namedBlockData(invocation.getArgument(0, Material.class).name().toLowerCase(Locale.ROOT))).when(server).createBlockData(any(Material.class)); + doAnswer((InvocationOnMock invocation) -> namedBlockData(invocation.getArgument(0, String.class))).when(server).createBlockData(anyString()); Bukkit.setServer(server); } @@ -48,6 +50,13 @@ public class IrisComplexImplodeParityTest { childSelectionSelectMethod.setAccessible(true); } + private static BlockData namedBlockData(String key) { + String canonical = key.indexOf(':') >= 0 ? key : "minecraft:" + key; + BlockData data = mock(BlockData.class); + doReturn(canonical).when(data).getAsString(); + return data; + } + @Test public void selectionPlanMatchesLegacyFitRarityAcrossSeedAndCoordinateGrid() throws Exception { List> scenarios = buildScenarios(); diff --git a/core/src/test/java/art/arcane/iris/engine/mantle/components/IrisCaveCarver3DNearParityTest.java b/core/src/test/java/art/arcane/iris/engine/mantle/components/IrisCaveCarver3DNearParityTest.java index 1b13fabd1..3a92a88a7 100644 --- a/core/src/test/java/art/arcane/iris/engine/mantle/components/IrisCaveCarver3DNearParityTest.java +++ b/core/src/test/java/art/arcane/iris/engine/mantle/components/IrisCaveCarver3DNearParityTest.java @@ -27,12 +27,14 @@ import org.bukkit.Server; import org.bukkit.block.data.BlockData; import org.junit.BeforeClass; import org.junit.Test; +import org.mockito.invocation.InvocationOnMock; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; +import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.logging.Logger; @@ -61,13 +63,12 @@ public class IrisCaveCarver3DNearParityTest { public static void setupBukkit() throws Exception { if (Bukkit.getServer() == null) { Server server = mock(Server.class); - BlockData emptyBlockData = mock(BlockData.class); doReturn(Logger.getLogger("IrisTest")).when(server).getLogger(); doReturn("IrisTestServer").when(server).getName(); doReturn("1.0").when(server).getVersion(); doReturn("1.0").when(server).getBukkitVersion(); - doReturn(emptyBlockData).when(server).createBlockData(any(Material.class)); - doReturn(emptyBlockData).when(server).createBlockData(anyString()); + doAnswer((InvocationOnMock invocation) -> namedBlockData(invocation.getArgument(0, Material.class).name().toLowerCase(Locale.ROOT))).when(server).createBlockData(any(Material.class)); + doAnswer((InvocationOnMock invocation) -> namedBlockData(invocation.getArgument(0, String.class))).when(server).createBlockData(anyString()); Bukkit.setServer(server); } @@ -91,6 +92,13 @@ public class IrisCaveCarver3DNearParityTest { carveForcedAirField.setAccessible(true); } + private static BlockData namedBlockData(String key) { + String canonical = key.indexOf(':') >= 0 ? key : "minecraft:" + key; + BlockData data = mock(BlockData.class); + doReturn(canonical).when(data).getAsString(); + return data; + } + @Test public void carvedCellDistributionStableAcrossEquivalentCarvers() { Engine engine = createEngine(128, 92); diff --git a/core/src/test/java/art/arcane/iris/engine/object/IrisDimensionCarvingResolverParityTest.java b/core/src/test/java/art/arcane/iris/engine/object/IrisDimensionCarvingResolverParityTest.java index 67cf1974c..b1027059b 100644 --- a/core/src/test/java/art/arcane/iris/engine/object/IrisDimensionCarvingResolverParityTest.java +++ b/core/src/test/java/art/arcane/iris/engine/object/IrisDimensionCarvingResolverParityTest.java @@ -12,9 +12,11 @@ import org.bukkit.Server; import org.bukkit.block.data.BlockData; import org.junit.BeforeClass; import org.junit.Test; +import org.mockito.invocation.InvocationOnMock; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.logging.Logger; @@ -23,6 +25,7 @@ import static org.mockito.Answers.CALLS_REAL_METHODS; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; @@ -37,16 +40,22 @@ public class IrisDimensionCarvingResolverParityTest { } Server server = mock(Server.class); - BlockData emptyBlockData = mock(BlockData.class); doReturn(Logger.getLogger("IrisTest")).when(server).getLogger(); doReturn("IrisTestServer").when(server).getName(); doReturn("1.0").when(server).getVersion(); doReturn("1.0").when(server).getBukkitVersion(); - doReturn(emptyBlockData).when(server).createBlockData(any(Material.class)); - doReturn(emptyBlockData).when(server).createBlockData(anyString()); + doAnswer((InvocationOnMock invocation) -> namedBlockData(invocation.getArgument(0, Material.class).name().toLowerCase(Locale.ROOT))).when(server).createBlockData(any(Material.class)); + doAnswer((InvocationOnMock invocation) -> namedBlockData(invocation.getArgument(0, String.class))).when(server).createBlockData(anyString()); Bukkit.setServer(server); } + private static BlockData namedBlockData(String key) { + String canonical = key.indexOf(':') >= 0 ? key : "minecraft:" + key; + BlockData data = mock(BlockData.class); + doReturn(canonical).when(data).getAsString(); + return data; + } + @Test public void resolverStatefulOverloadsMatchLegacyResolverAcrossSampleGrid() { Fixture fixture = createFixture(); diff --git a/core/src/test/java/art/arcane/iris/engine/object/IrisFloatingChildBiomesCarvingResolutionTest.java b/core/src/test/java/art/arcane/iris/engine/object/IrisFloatingChildBiomesCarvingResolutionTest.java index 93c6ba87b..9e3a01c82 100644 --- a/core/src/test/java/art/arcane/iris/engine/object/IrisFloatingChildBiomesCarvingResolutionTest.java +++ b/core/src/test/java/art/arcane/iris/engine/object/IrisFloatingChildBiomesCarvingResolutionTest.java @@ -10,14 +10,17 @@ import org.bukkit.Server; import org.bukkit.block.data.BlockData; import org.junit.BeforeClass; import org.junit.Test; +import org.mockito.invocation.InvocationOnMock; import java.util.HashMap; +import java.util.Locale; import java.util.Map; import java.util.logging.Logger; import static org.junit.Assert.assertSame; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; @@ -29,16 +32,22 @@ public class IrisFloatingChildBiomesCarvingResolutionTest { } Server server = mock(Server.class); - BlockData emptyBlockData = mock(BlockData.class); doReturn(Logger.getLogger("IrisTest")).when(server).getLogger(); doReturn("IrisTestServer").when(server).getName(); doReturn("1.0").when(server).getVersion(); doReturn("1.0").when(server).getBukkitVersion(); - doReturn(emptyBlockData).when(server).createBlockData(any(Material.class)); - doReturn(emptyBlockData).when(server).createBlockData(anyString()); + doAnswer((InvocationOnMock invocation) -> namedBlockData(invocation.getArgument(0, Material.class).name().toLowerCase(Locale.ROOT))).when(server).createBlockData(any(Material.class)); + doAnswer((InvocationOnMock invocation) -> namedBlockData(invocation.getArgument(0, String.class))).when(server).createBlockData(anyString()); Bukkit.setServer(server); } + private static BlockData namedBlockData(String key) { + String canonical = key.indexOf(':') >= 0 ? key : "minecraft:" + key; + BlockData data = mock(BlockData.class); + doReturn(canonical).when(data).getAsString(); + return data; + } + @Test public void resolveCarvingBiome_loadsBiomeKeyWhenEntryIdMissing() { IrisBiome biome = mock(IrisBiome.class); diff --git a/core/src/test/java/art/arcane/iris/engine/object/IrisObjectBlockDataMergeTest.java b/core/src/test/java/art/arcane/iris/engine/object/IrisObjectBlockDataMergeTest.java index 53e68e7c7..cdddacdd7 100644 --- a/core/src/test/java/art/arcane/iris/engine/object/IrisObjectBlockDataMergeTest.java +++ b/core/src/test/java/art/arcane/iris/engine/object/IrisObjectBlockDataMergeTest.java @@ -29,6 +29,11 @@ public class IrisObjectBlockDataMergeTest { doThrow(new IllegalArgumentException("Block data not created via string parsing")).when(base).merge(update); doReturn("minecraft:oak_log[axis=x]").when(base).getAsString(false); doReturn("minecraft:oak_log[axis=y]").when(update).getAsString(false); + doReturn("minecraft:oak_log[axis=x]").when(base).getAsString(); + doReturn("minecraft:oak_log[axis=y]").when(update).getAsString(); + doReturn("minecraft:oak_log[axis=x]").when(parsedBase).getAsString(); + doReturn("minecraft:oak_log[axis=y]").when(parsedUpdate).getAsString(); + doReturn("minecraft:oak_log[axis=y]").when(merged).getAsString(); doReturn(merged).when(parsedBase).merge(parsedUpdate); BlockData result = BlockDataMergeSupport.merge(base, update, resolver); @@ -50,6 +55,10 @@ public class IrisObjectBlockDataMergeTest { doThrow(new IllegalArgumentException("Block data not created via string parsing")).when(base).merge(update); doReturn("minecraft:stone").when(base).getAsString(false); doReturn("minecraft:stone[waterlogged=true]").when(update).getAsString(false); + doReturn("minecraft:stone").when(base).getAsString(); + doReturn("minecraft:stone[waterlogged=true]").when(update).getAsString(); + doReturn("minecraft:stone").when(parsedBase).getAsString(); + doReturn("minecraft:stone[waterlogged=true]").when(parsedUpdate).getAsString(); doThrow(new IllegalArgumentException("normalized merge failed")).when(parsedBase).merge(parsedUpdate); BlockData result = BlockDataMergeSupport.merge(base, update, resolver); @@ -65,6 +74,9 @@ public class IrisObjectBlockDataMergeTest { doReturn(Material.STONE).when(base).getMaterial(); doReturn(Material.STONE).when(update).getMaterial(); + doReturn("minecraft:stone").when(base).getAsString(); + doReturn("minecraft:stone[waterlogged=true]").when(update).getAsString(); + doReturn("minecraft:stone[waterlogged=true]").when(merged).getAsString(); doReturn(merged).when(base).merge(update); BlockData result = BlockDataMergeSupport.merge(base, update, key -> null); diff --git a/core/src/test/java/art/arcane/iris/platform/bukkit/BukkitSpiConformanceTest.java b/core/src/test/java/art/arcane/iris/platform/bukkit/BukkitSpiConformanceTest.java index 3c20b63e6..1bcd441f1 100644 --- a/core/src/test/java/art/arcane/iris/platform/bukkit/BukkitSpiConformanceTest.java +++ b/core/src/test/java/art/arcane/iris/platform/bukkit/BukkitSpiConformanceTest.java @@ -29,6 +29,7 @@ import org.junit.BeforeClass; import org.junit.Test; import org.mockito.invocation.InvocationOnMock; +import java.util.Locale; import java.util.logging.Logger; import static org.junit.Assert.assertEquals; @@ -52,7 +53,7 @@ public class BukkitSpiConformanceTest { doReturn("IrisTestServer").when(server).getName(); doReturn("1.0").when(server).getVersion(); doReturn("1.0").when(server).getBukkitVersion(); - doReturn(mock(BlockData.class)).when(server).createBlockData(any(Material.class)); + doAnswer((InvocationOnMock invocation) -> blockData("minecraft:" + invocation.getArgument(0, Material.class).name().toLowerCase(Locale.ROOT))).when(server).createBlockData(any(Material.class)); Bukkit.setServer(server); } doAnswer((InvocationOnMock invocation) -> blockData(invocation.getArgument(0))).when(server).createBlockData(anyString()); diff --git a/core/src/test/java/art/arcane/iris/util/project/context/ChunkContextPrefillPlanTest.java b/core/src/test/java/art/arcane/iris/util/project/context/ChunkContextPrefillPlanTest.java index 74f39f629..548e184b7 100644 --- a/core/src/test/java/art/arcane/iris/util/project/context/ChunkContextPrefillPlanTest.java +++ b/core/src/test/java/art/arcane/iris/util/project/context/ChunkContextPrefillPlanTest.java @@ -133,6 +133,7 @@ public class ChunkContextPrefillPlanTest { @SuppressWarnings("unchecked") ProceduralStream rockStream = mock(ProceduralStream.class); BlockData rock = mock(BlockData.class); + doReturn("minecraft:stone").when(rock).getAsString(); doAnswer(invocation -> { rockCalls.incrementAndGet(); return rock; @@ -141,6 +142,7 @@ public class ChunkContextPrefillPlanTest { @SuppressWarnings("unchecked") ProceduralStream fluidStream = mock(ProceduralStream.class); BlockData fluid = mock(BlockData.class); + doReturn("minecraft:water").when(fluid).getAsString(); doAnswer(invocation -> { fluidCalls.incrementAndGet(); return fluid; diff --git a/core/src/test/java/art/arcane/iris/util/project/noise/CNGInjectorParityTest.java b/core/src/test/java/art/arcane/iris/util/project/noise/CNGInjectorParityTest.java index 12d7b59d2..874688db1 100644 --- a/core/src/test/java/art/arcane/iris/util/project/noise/CNGInjectorParityTest.java +++ b/core/src/test/java/art/arcane/iris/util/project/noise/CNGInjectorParityTest.java @@ -8,14 +8,17 @@ import org.bukkit.Server; import org.bukkit.block.data.BlockData; import org.junit.BeforeClass; import org.junit.Test; +import org.mockito.invocation.InvocationOnMock; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import java.util.logging.Logger; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; @@ -27,16 +30,22 @@ public class CNGInjectorParityTest { } Server server = mock(Server.class); - BlockData emptyBlockData = mock(BlockData.class); doReturn(Logger.getLogger("IrisTest")).when(server).getLogger(); doReturn("IrisTestServer").when(server).getName(); doReturn("1.0").when(server).getVersion(); doReturn("1.0").when(server).getBukkitVersion(); - doReturn(emptyBlockData).when(server).createBlockData(any(Material.class)); - doReturn(emptyBlockData).when(server).createBlockData(anyString()); + doAnswer((InvocationOnMock invocation) -> namedBlockData(invocation.getArgument(0, Material.class).name().toLowerCase(Locale.ROOT))).when(server).createBlockData(any(Material.class)); + doAnswer((InvocationOnMock invocation) -> namedBlockData(invocation.getArgument(0, String.class))).when(server).createBlockData(anyString()); Bukkit.setServer(server); } + private static BlockData namedBlockData(String key) { + String canonical = key.indexOf(':') >= 0 ? key : "minecraft:" + key; + BlockData data = mock(BlockData.class); + doReturn(canonical).when(data).getAsString(); + return data; + } + @Test public void builtInInjectorsMatchLegacyCombineFor1D() { List injectors = builtInInjectors();