Vector Currency

This commit is contained in:
Brian Neumann-Fopiano
2026-06-11 20:00:17 -04:00
parent 4c462ba78a
commit e1196b0364
38 changed files with 1096 additions and 344 deletions
@@ -661,8 +661,9 @@ public class CommandObject implements DirectorExecutor {
Iris.service(ObjectSVC.class).addChanges(futureChanges);
if (edit) {
ItemStack newWand = WandSVC.createWand(block.clone().subtract(o.getCenter()).add(o.getW() - 1,
o.getH() + o.getCenter().clone().getY() - 1, o.getD() - 1), block.clone().subtract(o.getCenter().clone().setY(0)));
Vector center = new Vector(o.getCenter().getX(), o.getCenter().getY(), o.getCenter().getZ());
ItemStack newWand = WandSVC.createWand(block.clone().subtract(center).add(o.getW() - 1,
o.getH() + center.getY() - 1, o.getD() - 1), block.clone().subtract(center.clone().setY(0)));
if (WandSVC.isWand(wand)) {
wand = newWand;
player().getInventory().setItemInMainHand(wand);
@@ -783,7 +783,7 @@ public class CommandStudio implements DirectorExecutor {
}
File ff = g.getData().getObjectLoader().findFile(i);
BlockVector sz = IrisObject.sampleSize(ff);
art.arcane.iris.util.common.math.IrisBlockVector sz = IrisObject.sampleSize(ff);
nn3 = i + ": size=[" + sz.getBlockX() + "," + sz.getBlockY() + "," + sz.getBlockZ() + "] location=[" + ff.getPath() + "]";
stop.add(i);
} catch (Throwable e) {
@@ -23,7 +23,7 @@ import art.arcane.iris.core.loader.IrisData;
import art.arcane.iris.engine.object.IrisObject;
import art.arcane.volmlib.util.json.JSONArray;
import art.arcane.volmlib.util.json.JSONObject;
import org.bukkit.util.BlockVector;
import art.arcane.iris.util.common.math.IrisBlockVector;
import java.io.File;
import java.nio.file.Files;
@@ -96,7 +96,7 @@ public final class ObjectStudioLayout {
if (file == null) {
continue;
}
BlockVector size;
IrisBlockVector size;
try {
size = IrisObject.sampleSize(file);
} catch (Throwable e) {
@@ -29,7 +29,7 @@ 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;
import org.bukkit.util.BlockVector;
import art.arcane.iris.util.common.math.IrisBlockVector;
import java.util.ArrayDeque;
import java.util.ArrayList;
@@ -92,8 +92,8 @@ 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<BlockVector, PlatformBlockState> entry : blocks) {
BlockVector pos = entry.getKey();
for (Map.Entry<IrisBlockVector, PlatformBlockState> entry : blocks) {
IrisBlockVector pos = entry.getKey();
BlockData data = (BlockData) entry.getValue().nativeHandle();
long key = packKey(pos);
positions.put(key, data);
@@ -653,7 +653,7 @@ public final class TreePlausibilizer {
return Tag.LEAVES.isTagged(data.getMaterial()) || data instanceof Leaves;
}
private static long packKey(BlockVector pos) {
private static long packKey(IrisBlockVector pos) {
return packXYZ(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ());
}
@@ -671,9 +671,9 @@ public final class TreePlausibilizer {
return new int[]{x, y, z};
}
private static BlockVector unpackKey(long key) {
private static IrisBlockVector unpackKey(long key) {
int[] xyz = unpack(key);
return new BlockVector(xyz[0], xyz[1], xyz[2]);
return new IrisBlockVector(xyz[0], xyz[1], xyz[2]);
}
private record LogInsertion(long key, BlockData data) {
@@ -230,7 +230,7 @@ final class DecoratorCore {
}
if (bd.nativeHandle() instanceof PointedDripstone) {
bd = BukkitBlockState.of(dripstoneBlock(stack, i, BlockFace.UP));
bd = dripstoneBlock(stack, i, BlockFace.UP);
}
data.set(x, height + 1 + i, z, bd);
@@ -264,7 +264,7 @@ final class DecoratorCore {
: decorator.pickBlockData(rng, irisData, realX, realZ);
if (bd != null && bd.nativeHandle() instanceof PointedDripstone) {
bd = BukkitBlockState.of(dripstoneBlock(stack, i, BlockFace.DOWN));
bd = dripstoneBlock(stack, i, BlockFace.DOWN);
}
if (opts.caveSkipFluid && BukkitBlockResolution.isFluid(unwrap(data.get(x, h, z)))) {
@@ -340,7 +340,8 @@ final class DecoratorCore {
if (!BukkitBlockResolution.isVineBlock(rawB)) {
return b;
}
MultipleFacing data = (MultipleFacing) rawB.clone();
BlockData cloned = rawB.clone();
MultipleFacing data = (MultipleFacing) cloned;
data.getFaces().forEach(f -> data.setFace(f, false));
boolean found = false;
@@ -385,7 +386,7 @@ final class DecoratorCore {
data.setFace(fallback, true);
}
}
return BukkitBlockState.of(data);
return BukkitBlockState.of(cloned);
}
static boolean canGoOn(PlatformBlockState decorator, PlatformBlockState surface) {
@@ -407,28 +408,26 @@ final class DecoratorCore {
return stack;
}
// Lazily populated on first dripstone decoration — avoids Bukkit API at class-load time.
// Index: 0=TIP, 1=FRUSTUM, 2=BASE. Race on init is benign (only allocation cost, not correctness).
private static volatile BlockData[] dripstoneUp;
private static volatile BlockData[] dripstoneDown;
private static volatile PlatformBlockState[] dripstoneUp;
private static volatile PlatformBlockState[] dripstoneDown;
private static BlockData[] buildDripstoneArr(BlockFace direction) {
private static PlatformBlockState[] buildDripstoneArr(BlockFace direction) {
PointedDripstone.Thickness[] order = {
PointedDripstone.Thickness.TIP,
PointedDripstone.Thickness.FRUSTUM,
PointedDripstone.Thickness.BASE
};
BlockData[] arr = new BlockData[3];
PlatformBlockState[] arr = new PlatformBlockState[3];
for (int k = 0; k < 3; k++) {
BlockData bd = Material.POINTED_DRIPSTONE.createBlockData();
((PointedDripstone) bd).setThickness(order[k]);
((PointedDripstone) bd).setVerticalDirection(direction);
arr[k] = bd;
arr[k] = BukkitBlockState.of(bd);
}
return arr;
}
private static BlockData dripstoneBlock(int stack, int i, BlockFace direction) {
private static PlatformBlockState dripstoneBlock(int stack, int i, BlockFace direction) {
int thIdx;
if (i == stack - 1) {
thIdx = 0;
@@ -40,6 +40,7 @@ import art.arcane.iris.engine.object.IrisObjectTranslate;
import art.arcane.iris.engine.object.ObjectPlaceMode;
import art.arcane.iris.spi.IrisLogging;
import art.arcane.iris.util.common.data.IrisCustomData;
import art.arcane.iris.util.common.math.IrisBlockVector;
import art.arcane.iris.util.project.context.ChunkContext;
import art.arcane.volmlib.util.collection.KList;
import art.arcane.volmlib.util.documentation.ChunkCoordinates;
@@ -48,7 +49,6 @@ 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;
import java.io.File;
import java.util.HashSet;
@@ -384,7 +384,7 @@ public class MantleFloatingObjectComponent extends IrisMantleComponent {
}
private static boolean isFootprintFlatBottom(FloatingObjectFootprint fp, IrisObjectRotation rotation, int pickedXf, int pickedZf, int pickBottomY, FloatingIslandSample[] samples, int tolerance) {
BlockVector anchor = invertedFootprintAnchor(fp, rotation);
IrisBlockVector anchor = invertedFootprintAnchor(fp, rotation);
int checked = 0;
boolean touchedChunkEdge = false;
long[] cells = fp.footprintXZ();
@@ -392,7 +392,7 @@ public class MantleFloatingObjectComponent extends IrisMantleComponent {
long encoded = cells[i];
int kx = (int) (encoded >> 32);
int kz = (int) (encoded & 0xFFFFFFFFL);
BlockVector cell = rotation.rotate(new BlockVector(kx, 0, kz), 0, 0, 0);
IrisBlockVector cell = rotation.rotate(new IrisBlockVector(kx, 0, kz), 0, 0, 0);
int colXf = pickedXf + cell.getBlockX() - anchor.getBlockX();
int colZf = pickedZf + cell.getBlockZ() - anchor.getBlockZ();
if (colXf < 0 || colXf >= 16 || colZf < 0 || colZf >= 16) {
@@ -439,12 +439,12 @@ public class MantleFloatingObjectComponent extends IrisMantleComponent {
return minZ + pickedZf - invertedFootprintAnchor(fp, rotation).getBlockZ();
}
private static BlockVector invertedFootprintAnchor(FloatingObjectFootprint fp, IrisObjectRotation rotation) {
return rotation.rotate(new BlockVector(fp.getTallestKx(), 0, fp.getTallestKz()), 0, 0, 0);
private static IrisBlockVector invertedFootprintAnchor(FloatingObjectFootprint fp, IrisObjectRotation rotation) {
return rotation.rotate(new IrisBlockVector(fp.getTallestKx(), 0, fp.getTallestKz()), 0, 0, 0);
}
private static BlockVector invertedSolidAnchor(FloatingObjectFootprint fp, IrisObjectRotation rotation) {
return rotation.rotate(new BlockVector(fp.getTallestKx(), fp.getLowestSolidKeyY(), fp.getTallestKz()), 0, 0, 0);
private static IrisBlockVector invertedSolidAnchor(FloatingObjectFootprint fp, IrisObjectRotation rotation) {
return rotation.rotate(new IrisBlockVector(fp.getTallestKx(), fp.getLowestSolidKeyY(), fp.getTallestKz()), 0, 0, 0);
}
private static boolean shouldWritePlacementMarker(IObjectPlacer placer, PlatformBlockState state, int x, int y, int z) {
@@ -568,7 +568,7 @@ public class MantleFloatingObjectComponent extends IrisMantleComponent {
if (f == null) {
continue;
}
BlockVector sz = IrisObject.sampleSize(f);
IrisBlockVector sz = IrisObject.sampleSize(f);
int extent = Math.max(sz.getBlockX(), sz.getBlockZ());
if (extent > maxObjectExtent) {
maxObjectExtent = extent;
@@ -49,7 +49,7 @@ 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 art.arcane.iris.util.common.math.IrisBlockVector;
import org.bukkit.block.data.BlockData;
import java.io.IOException;
@@ -1597,7 +1597,7 @@ public class MantleObjectComponent extends IrisMantleComponent {
}
}
KMap<String, BlockVector> sizeCache = new KMap<>();
KMap<String, IrisBlockVector> sizeCache = new KMap<>();
for (String i : objects) {
updateRadiusBounds(sizeCache, xg, zg, i, 1D);
}
@@ -1635,14 +1635,14 @@ public class MantleObjectComponent extends IrisMantleComponent {
}
private void updateRadiusBounds(
KMap<String, BlockVector> sizeCache,
KMap<String, IrisBlockVector> sizeCache,
AtomicInteger xg,
AtomicInteger zg,
String objectKey,
double scale
) {
try {
BlockVector bv = loadObjectSize(sizeCache, objectKey);
IrisBlockVector bv = loadObjectSize(sizeCache, objectKey);
if (bv == null) {
throw new RuntimeException();
}
@@ -1663,7 +1663,7 @@ public class MantleObjectComponent extends IrisMantleComponent {
}
private void updateVacuumRadiusBounds(
KMap<String, BlockVector> sizeCache,
KMap<String, IrisBlockVector> sizeCache,
AtomicInteger xg,
AtomicInteger zg,
IrisObjectPlacement placement
@@ -1676,7 +1676,7 @@ public class MantleObjectComponent extends IrisMantleComponent {
double scale = placement.getScale() != null ? Math.max(1D, placement.getScale().getMaxScale()) : 1D;
for (String objectKey : placement.getPlace()) {
try {
BlockVector bv = loadObjectSize(sizeCache, objectKey);
IrisBlockVector bv = loadObjectSize(sizeCache, objectKey);
if (bv == null) {
continue;
}
@@ -1691,7 +1691,7 @@ public class MantleObjectComponent extends IrisMantleComponent {
}
}
private BlockVector loadObjectSize(KMap<String, BlockVector> sizeCache, String objectKey) {
private IrisBlockVector loadObjectSize(KMap<String, IrisBlockVector> sizeCache, String objectKey) {
return sizeCache.computeIfAbsent(objectKey, k -> {
try {
return IrisObject.sampleSize(getData().getObjectLoader().findFile(objectKey));
@@ -35,7 +35,6 @@ 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<PlatformBlockState> {
private final RNG rng;
@@ -125,7 +124,7 @@ public class IrisDepositModifier extends EngineAssignedModifier<PlatformBlockSta
IrisDimension dimension = getDimension();
for (BlockVector j : clump.getBlocks().keys()) {
for (art.arcane.iris.util.common.math.IrisBlockVector j : clump.getBlocks().keys()) {
int nx = j.getBlockX() + x;
int ny = j.getBlockY() + y;
int nz = j.getBlockZ() + z;
@@ -28,55 +28,62 @@ import art.arcane.iris.util.project.hunk.Hunk;
import art.arcane.iris.util.common.parallel.BurstExecutor;
import art.arcane.volmlib.util.scheduling.PrecisionStopwatch;
import art.arcane.iris.spi.PlatformBlockState;
import org.bukkit.Material;
import org.bukkit.block.data.Bisected;
import org.bukkit.block.data.BlockData;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
public class IrisPerfectionModifier extends EngineAssignedModifier<PlatformBlockState> {
private static final PlatformBlockState AIR = B.getState("AIR");
private static final PlatformBlockState WATER = B.getState("WATER");
private static final Map<Material, PlatformBlockState> ORE_BASES = buildOreBases();
private static final class States {
private static final PlatformBlockState AIR = B.getState("AIR");
private static final PlatformBlockState WATER = B.getState("WATER");
private static final Map<String, PlatformBlockState> ORE_BASES = buildOreBases();
}
public IrisPerfectionModifier(Engine engine) {
super(engine, "Perfection");
}
private static Map<Material, PlatformBlockState> buildOreBases() {
Map<Material, PlatformBlockState> map = new EnumMap<>(Material.class);
private static Map<String, PlatformBlockState> buildOreBases() {
Map<String, PlatformBlockState> map = new HashMap<>();
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);
map.put(Material.GOLD_ORE, stone);
map.put(Material.REDSTONE_ORE, stone);
map.put(Material.LAPIS_ORE, stone);
map.put(Material.DIAMOND_ORE, stone);
map.put(Material.EMERALD_ORE, stone);
map.put(Material.DEEPSLATE_COAL_ORE, deepslate);
map.put(Material.DEEPSLATE_COPPER_ORE, deepslate);
map.put(Material.DEEPSLATE_IRON_ORE, deepslate);
map.put(Material.DEEPSLATE_GOLD_ORE, deepslate);
map.put(Material.DEEPSLATE_REDSTONE_ORE, deepslate);
map.put(Material.DEEPSLATE_LAPIS_ORE, deepslate);
map.put(Material.DEEPSLATE_DIAMOND_ORE, deepslate);
map.put(Material.DEEPSLATE_EMERALD_ORE, deepslate);
map.put(Material.NETHER_GOLD_ORE, netherrack);
map.put(Material.NETHER_QUARTZ_ORE, netherrack);
map.put(Material.ANCIENT_DEBRIS, netherrack);
map.put(Material.GILDED_BLACKSTONE, blackstone);
map.put("minecraft:coal_ore", stone);
map.put("minecraft:copper_ore", stone);
map.put("minecraft:iron_ore", stone);
map.put("minecraft:gold_ore", stone);
map.put("minecraft:redstone_ore", stone);
map.put("minecraft:lapis_ore", stone);
map.put("minecraft:diamond_ore", stone);
map.put("minecraft:emerald_ore", stone);
map.put("minecraft:deepslate_coal_ore", deepslate);
map.put("minecraft:deepslate_copper_ore", deepslate);
map.put("minecraft:deepslate_iron_ore", deepslate);
map.put("minecraft:deepslate_gold_ore", deepslate);
map.put("minecraft:deepslate_redstone_ore", deepslate);
map.put("minecraft:deepslate_lapis_ore", deepslate);
map.put("minecraft:deepslate_diamond_ore", deepslate);
map.put("minecraft:deepslate_emerald_ore", deepslate);
map.put("minecraft:nether_gold_ore", netherrack);
map.put("minecraft:nether_quartz_ore", netherrack);
map.put("minecraft:ancient_debris", netherrack);
map.put("minecraft:gilded_blackstone", blackstone);
return map;
}
private static String baseKey(PlatformBlockState state) {
String key = state.key();
int bracket = key.indexOf('[');
return bracket < 0 ? key : key.substring(0, bracket);
}
@Override
public void onModify(int x, int z, Hunk<PlatformBlockState> output, boolean multicore, ChunkContext context) {
PrecisionStopwatch p = PrecisionStopwatch.start();
@@ -147,11 +154,11 @@ public class IrisPerfectionModifier extends EngineAssignedModifier<PlatformBlock
if (remove) {
changed.set(true);
changes.getAndIncrement();
output.set(finalI, k, j, AIR);
output.set(finalI, k, j, States.AIR);
if (remove2) {
changes.getAndIncrement();
output.set(finalI, k - 1, j, AIR);
output.set(finalI, k - 1, j, States.AIR);
}
}
}
@@ -176,7 +183,7 @@ public class IrisPerfectionModifier extends EngineAssignedModifier<PlatformBlock
if (block == null) {
continue;
}
PlatformBlockState base = ORE_BASES.get(((BlockData) block.nativeHandle()).getMaterial());
PlatformBlockState base = States.ORE_BASES.get(baseKey(block));
if (base != null) {
output.set(finalI, k, j, base);
}
@@ -41,8 +41,11 @@ import org.bukkit.block.data.type.Slab;
import java.util.concurrent.atomic.AtomicInteger;
public class IrisPostModifier extends EngineAssignedModifier<PlatformBlockState> {
private static final PlatformBlockState AIR = B.getState("AIR");
private static final PlatformBlockState WATER = B.getState("WATER");
private static final class States {
private static final PlatformBlockState AIR = B.getState("AIR");
private static final PlatformBlockState WATER = B.getState("WATER");
}
private final RNG rng;
public IrisPostModifier(Engine engine) {
@@ -87,7 +90,7 @@ public class IrisPostModifier extends EngineAssignedModifier<PlatformBlockState>
g += hd < h - 1 ? 1 : 0;
if (g == 4 && isAir(x, h - 1, z, currentPostX, currentPostZ, currentData)) {
setPostBlock(x, h, z, AIR, currentPostX, currentPostZ, currentData);
setPostBlock(x, h, z, States.AIR, currentPostX, currentPostZ, currentData);
for (int i = h - 1; i > 0; i--) {
if (!isAir(x, i, z, currentPostX, currentPostZ, currentData)) {
@@ -207,7 +210,8 @@ public class IrisPostModifier extends EngineAssignedModifier<PlatformBlockState>
BlockData b = (BlockData) getPostBlock(x, h, z, currentPostX, currentPostZ, currentData).nativeHandle();
if (b instanceof Waterlogged) {
Waterlogged ww = (Waterlogged) b.clone();
BlockData cloned = b.clone();
Waterlogged ww = (Waterlogged) cloned;
boolean w = false;
if (h <= getDimension().getFluidHeight() + 1) {
@@ -220,11 +224,11 @@ public class IrisPostModifier extends EngineAssignedModifier<PlatformBlockState>
if (w != ww.isWaterlogged()) {
ww.setWaterlogged(w);
setPostBlock(x, h, z, BukkitBlockState.of(ww), currentPostX, currentPostZ, currentData);
setPostBlock(x, h, z, BukkitBlockState.of(cloned), 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))) {
setPostBlock(x, h, z, WATER, currentPostX, currentPostZ, currentData);
setPostBlock(x, h, z, States.WATER, currentPostX, currentPostZ, currentData);
}
}
@@ -232,7 +236,8 @@ public class IrisPostModifier extends EngineAssignedModifier<PlatformBlockState>
b = (BlockData) getPostBlock(x, h + 1, z, currentPostX, currentPostZ, currentData).nativeHandle();
if (BukkitBlockResolution.isVineBlock(b) && b instanceof MultipleFacing) {
MultipleFacing f = (MultipleFacing) b.clone();
BlockData cloned = b.clone();
MultipleFacing f = (MultipleFacing) cloned;
int finalH = h + 1;
f.getAllowedFaces().forEach(face -> {
@@ -240,7 +245,7 @@ public class IrisPostModifier extends EngineAssignedModifier<PlatformBlockState>
f.setFace(face, !BukkitBlockResolution.isAir(d) && !BukkitBlockResolution.isVineBlock(d));
});
if (!f.equals(b)) {
setPostBlock(x, h + 1, z, BukkitBlockState.of(f), currentPostX, currentPostZ, currentData);
setPostBlock(x, h + 1, z, BukkitBlockState.of(cloned), currentPostX, currentPostZ, currentData);
}
}
@@ -248,7 +253,7 @@ public class IrisPostModifier extends EngineAssignedModifier<PlatformBlockState>
Material onto = ((BlockData) getPostBlock(x, h, z, currentPostX, currentPostZ, currentData).nativeHandle()).getMaterial();
if (!BukkitBlockResolution.canPlaceOnto(b.getMaterial(), onto) && !BukkitBlockResolution.isDecorant(b)) {
setPostBlock(x, h + 1, z, AIR, currentPostX, currentPostZ, currentData);
setPostBlock(x, h + 1, z, States.AIR, currentPostX, currentPostZ, currentData);
}
}
}
@@ -312,6 +317,6 @@ public class IrisPostModifier extends EngineAssignedModifier<PlatformBlockState>
public PlatformBlockState getPostBlock(int x, int y, int z, int cpx, int cpz, Hunk<PlatformBlockState> h) {
PlatformBlockState b = h.getClosest(x & 15, y, z & 15);
return b == null ? AIR : b;
return b == null ? States.AIR : b;
}
}
@@ -43,9 +43,7 @@ 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 java.awt.*;
@@ -58,7 +56,10 @@ import java.util.EnumMap;
@Data
@EqualsAndHashCode(callSuper = false)
public class IrisBiome extends IrisRegistrant implements IRare {
private static final PlatformBlockState BARRIER = BukkitBlockState.of(Material.BARRIER.createBlockData());
private static final class States {
private static final PlatformBlockState BARRIER = B.getState("BARRIER");
}
private final transient AtomicCache<KMap<String, IrisBiomeGeneratorLink>> genCache = new AtomicCache<>();
private final transient AtomicCache<KMap<String, Integer>> genCacheMax = new AtomicCache<>();
private final transient AtomicCache<KMap<String, Integer>> genCacheMin = new AtomicCache<>();
@@ -445,7 +446,7 @@ public class IrisBiome extends IrisRegistrant implements IRare {
if (dim.isExplodeBiomePalettes()) {
for (int j = 0; j < dim.getExplodeBiomePaletteSize(); j++) {
data.add(BARRIER);
data.add(States.BARRIER);
if (data.size() >= maxDepth) {
break;
@@ -491,7 +492,7 @@ public class IrisBiome extends IrisRegistrant implements IRare {
if (dim.isExplodeBiomePalettes()) {
for (int j = 0; j < dim.getExplodeBiomePaletteSize(); j++) {
data.add(BARRIER);
data.add(States.BARRIER);
if (data.size() >= maxDepth) {
break;
@@ -1,7 +1,7 @@
package art.arcane.iris.engine.object;
import art.arcane.iris.platform.bukkit.BukkitPlatform;
import art.arcane.iris.engine.framework.Engine;
import art.arcane.iris.util.common.math.IrisBlockVector;
import art.arcane.iris.engine.object.annotations.*;
import art.arcane.volmlib.util.collection.KMap;
import art.arcane.volmlib.util.collection.KSet;
@@ -45,7 +45,8 @@ public class IrisCaveShape {
var rotated = new KSet<IrisPosition>();
engine.getData().getObjectLoader().load(object).getBlocks().forEach((vector, data) -> {
if (data.isAir()) return;
rotated.add(BukkitPlatform.positionOf(objectRotation.rotate(vector, pos.getX(), pos.getY(), pos.getZ())));
IrisBlockVector rot = objectRotation.rotate(vector, pos.getX(), pos.getY(), pos.getZ());
rotated.add(new IrisPosition(rot.getBlockX(), rot.getBlockY(), rot.getBlockZ()));
});
return rotated;
});
@@ -22,6 +22,8 @@ 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.util.common.math.IrisBlockVector;
import art.arcane.iris.util.common.math.Vector3i;
import art.arcane.volmlib.util.collection.KList;
import art.arcane.volmlib.util.collection.KSet;
import art.arcane.volmlib.util.math.BlockPosition;
@@ -113,7 +115,8 @@ public class IrisDepositGenerator {
int s = rngv.i(minSize, maxSize + 1);
if (s == 1) {
IrisObject o = new IrisObject(1, 1, 1);
o.getBlocks().put(o.getCenter(), nextBlock(rngv, rdata));
Vector3i center = o.getCenter();
o.getBlocks().put(new IrisBlockVector(center.getX(), center.getY(), center.getZ()), nextBlock(rngv, rdata));
return o;
}
@@ -21,7 +21,6 @@ package art.arcane.iris.engine.object;
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.platform.bukkit.BukkitPlatform;
import art.arcane.iris.spi.IrisLogging;
import art.arcane.iris.spi.PlatformBlockState;
@@ -49,7 +48,6 @@ 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;
@@ -70,8 +68,6 @@ import java.util.Map;
@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<Position2> parallaxSize = new AtomicCache<>();
private final transient AtomicCache<CNG> rockLayerGenerator = new AtomicCache<>();
private final transient AtomicCache<CNG> fluidLayerGenerator = new AtomicCache<>();
@@ -20,7 +20,6 @@ package art.arcane.iris.engine.object;
import art.arcane.iris.platform.bukkit.BukkitBlockResolution;
import art.arcane.iris.platform.bukkit.BukkitPlatform;
import art.arcane.iris.core.loader.IrisData;
import art.arcane.iris.core.loader.IrisRegistrant;
import art.arcane.iris.engine.data.cache.AtomicCache;
@@ -66,8 +65,6 @@ import org.bukkit.block.data.Waterlogged;
import org.bukkit.block.data.type.Leaves;
import org.bukkit.block.data.type.Slab;
import org.bukkit.block.data.type.Stairs;
import org.bukkit.util.BlockVector;
import org.bukkit.util.Vector;
import java.io.*;
import java.util.*;
@@ -82,10 +79,12 @@ import java.util.stream.StreamSupport;
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
public class IrisObject extends IrisRegistrant {
protected static final Vector HALF = new Vector(0.5, 0.5, 0.5);
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 IrisVector HALF = new IrisVector(0.5, 0.5, 0.5);
static final class States {
static final PlatformBlockState AIR = B.getState("CAVE_AIR");
static final PlatformBlockState STONE = B.getState("STONE");
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;
@@ -134,24 +133,22 @@ public class IrisObject extends IrisRegistrant {
this(0, 0, 0);
}
public static BlockVector getCenterForSize(BlockVector size) {
return new BlockVector(size.getX() / 2, size.getY() / 2, size.getZ() / 2);
public static AxisAlignedBB getAABBFor(IrisBlockVector size) {
IrisBlockVector center = new IrisBlockVector(size.getX() / 2, size.getY() / 2, size.getZ() / 2);
IrisVector min = new IrisBlockVector(0, 0, 0).subtract(center);
IrisVector max = new IrisBlockVector(size.getX() - 1, size.getY() - 1, size.getZ() - 1).subtract(center);
return new AxisAlignedBB(new IrisPosition(min.getBlockX(), min.getBlockY(), min.getBlockZ()),
new IrisPosition(max.getBlockX(), max.getBlockY(), max.getBlockZ()));
}
public static AxisAlignedBB getAABBFor(BlockVector size) {
BlockVector center = new BlockVector(size.getX() / 2, size.getY() / 2, size.getZ() / 2);
return new AxisAlignedBB(BukkitPlatform.positionOf(new BlockVector(0, 0, 0).subtract(center).toBlockVector()),
BukkitPlatform.positionOf(new BlockVector(size.getX() - 1, size.getY() - 1, size.getZ() - 1).subtract(center).toBlockVector()));
}
public static BlockVector sampleSize(File file) throws IOException {
public static IrisBlockVector sampleSize(File file) throws IOException {
try (DataInputStream din = new DataInputStream(new FileInputStream(file))) {
return new BlockVector(din.readInt(), din.readInt(), din.readInt());
return new IrisBlockVector(din.readInt(), din.readInt(), din.readInt());
}
}
private static List<BlockVector> blocksBetweenTwoPoints(Vector loc1, Vector loc2) {
List<BlockVector> locations = new ArrayList<>();
private static List<IrisBlockVector> blocksBetweenTwoPoints(IrisVector loc1, IrisVector loc2) {
List<IrisBlockVector> locations = new ArrayList<>();
int topBlockX = Math.max(loc1.getBlockX(), loc2.getBlockX());
int bottomBlockX = Math.min(loc1.getBlockX(), loc2.getBlockX());
int topBlockY = Math.max(loc1.getBlockY(), loc2.getBlockY());
@@ -162,7 +159,7 @@ public class IrisObject extends IrisRegistrant {
for (int x = bottomBlockX; x <= topBlockX; x++) {
for (int z = bottomBlockZ; z <= topBlockZ; z++) {
for (int y = bottomBlockY; y <= topBlockY; y++) {
locations.add(new BlockVector(x, y, z));
locations.add(new IrisBlockVector(x, y, z));
}
}
}
@@ -181,7 +178,7 @@ public class IrisObject extends IrisRegistrant {
}
public AxisAlignedBB getAABB() {
return aabb.aquire(() -> getAABBFor(new BlockVector(w, h, d)));
return aabb.aquire(() -> getAABBFor(new IrisBlockVector(w, h, d)));
}
public void ensureSmartBored(boolean debug) {
@@ -190,7 +187,7 @@ public class IrisObject extends IrisRegistrant {
}
PrecisionStopwatch p = PrecisionStopwatch.start();
PlatformBlockState vair = debug ? VAIR_DEBUG : VAIR;
PlatformBlockState vair = debug ? VAIR_DEBUG : States.VAIR;
writeLock.lock();
AtomicInteger applied = new AtomicInteger();
if (blocks.isEmpty()) {
@@ -200,10 +197,10 @@ public class IrisObject extends IrisRegistrant {
return;
}
BlockVector max = new BlockVector(Double.MIN_VALUE, Double.MIN_VALUE, Double.MIN_VALUE);
BlockVector min = new BlockVector(Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE);
IrisBlockVector max = new IrisBlockVector(Double.MIN_VALUE, Double.MIN_VALUE, Double.MIN_VALUE);
IrisBlockVector min = new IrisBlockVector(Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE);
for (BlockVector i : blocks.keys()) {
for (IrisBlockVector i : blocks.keys()) {
max.setX(Math.max(i.getX(), max.getX()));
min.setX(Math.min(i.getX(), min.getX()));
max.setY(Math.max(i.getY(), max.getY()));
@@ -223,7 +220,7 @@ public class IrisObject extends IrisRegistrant {
int end = Integer.MIN_VALUE;
for (int ray = min.getBlockX(); ray <= max.getBlockX(); ray++) {
if (blocks.containsKey(new Vector3i(ray, finalRayY, rayZ))) {
if (blocks.containsKey(new IrisBlockVector(ray, finalRayY, rayZ))) {
start = Math.min(ray, start);
end = Math.max(ray, end);
}
@@ -231,7 +228,7 @@ public class IrisObject extends IrisRegistrant {
if (start != Integer.MAX_VALUE && end != Integer.MIN_VALUE) {
for (int i = start; i <= end; i++) {
Vector3i v = new Vector3i(i, finalRayY, rayZ);
IrisBlockVector v = new IrisBlockVector(i, finalRayY, rayZ);
if (!vair.equals(blocks.get(v))) {
blocks.computeIfAbsent(v, (vv) -> vair);
@@ -252,7 +249,7 @@ public class IrisObject extends IrisRegistrant {
int end = Integer.MIN_VALUE;
for (int ray = min.getBlockY(); ray <= max.getBlockY(); ray++) {
if (blocks.containsKey(new Vector3i(finalRayX, ray, rayZ))) {
if (blocks.containsKey(new IrisBlockVector(finalRayX, ray, rayZ))) {
start = Math.min(ray, start);
end = Math.max(ray, end);
}
@@ -260,7 +257,7 @@ public class IrisObject extends IrisRegistrant {
if (start != Integer.MAX_VALUE && end != Integer.MIN_VALUE) {
for (int i = start; i <= end; i++) {
Vector3i v = new Vector3i(finalRayX, i, rayZ);
IrisBlockVector v = new IrisBlockVector(finalRayX, i, rayZ);
if (!vair.equals(blocks.get(v))) {
blocks.computeIfAbsent(v, (vv) -> vair);
@@ -281,7 +278,7 @@ public class IrisObject extends IrisRegistrant {
int end = Integer.MIN_VALUE;
for (int ray = min.getBlockZ(); ray <= max.getBlockZ(); ray++) {
if (blocks.containsKey(new Vector3i(finalRayX, rayY, ray))) {
if (blocks.containsKey(new IrisBlockVector(finalRayX, rayY, ray))) {
start = Math.min(ray, start);
end = Math.max(ray, end);
}
@@ -289,7 +286,7 @@ public class IrisObject extends IrisRegistrant {
if (start != Integer.MAX_VALUE && end != Integer.MIN_VALUE) {
for (int i = start; i <= end; i++) {
Vector3i v = new Vector3i(finalRayX, rayY, i);
IrisBlockVector v = new IrisBlockVector(finalRayX, rayY, i);
if (!vair.equals(blocks.get(v))) {
blocks.computeIfAbsent(v, (vv) -> vair);
@@ -329,7 +326,7 @@ public class IrisObject extends IrisRegistrant {
int s = din.readInt();
for (int i = 0; i < s; i++) {
Vector3i pos = new Vector3i(din.readShort(), din.readShort(), din.readShort());
IrisBlockVector pos = new IrisBlockVector(din.readShort(), din.readShort(), din.readShort());
BlockData data = BukkitBlockResolution.get(din.readUTF());
if (isStructureMarker(data)) {
continue;
@@ -344,7 +341,7 @@ public class IrisObject extends IrisRegistrant {
int size = din.readInt();
for (int i = 0; i < size; i++) {
states.put(new Vector3i(din.readShort(), din.readShort(), din.readShort()), TileData.read(din));
states.put(new IrisBlockVector(din.readShort(), din.readShort(), din.readShort()), TileData.read(din));
}
} catch (Throwable e) {
IrisLogging.reportError(e);
@@ -371,7 +368,7 @@ public class IrisObject extends IrisRegistrant {
s = din.readInt();
for (i = 0; i < s; i++) {
Vector3i pos = new Vector3i(din.readShort(), din.readShort(), din.readShort());
IrisBlockVector pos = new IrisBlockVector(din.readShort(), din.readShort(), din.readShort());
BlockData data = BukkitBlockResolution.get(palette.get(din.readShort()));
if (isStructureMarker(data)) {
continue;
@@ -382,7 +379,7 @@ public class IrisObject extends IrisRegistrant {
s = din.readInt();
for (i = 0; i < s; i++) {
states.put(new Vector3i(din.readShort(), din.readShort(), din.readShort()), TileData.read(din));
states.put(new IrisBlockVector(din.readShort(), din.readShort(), din.readShort()), TileData.read(din));
}
}
@@ -550,10 +547,10 @@ public class IrisObject extends IrisRegistrant {
public void shrinkwrap() {
if (blocks.isEmpty()) return;
BlockVector min = new BlockVector(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE);
BlockVector max = new BlockVector(Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE);
IrisBlockVector min = new IrisBlockVector(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE);
IrisBlockVector max = new IrisBlockVector(Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE);
for (BlockVector i : blocks.keys()) {
for (IrisBlockVector i : blocks.keys()) {
min.setX(Math.min(min.getX(), i.getX()));
min.setY(Math.min(min.getY(), i.getY()));
min.setZ(Math.min(min.getZ(), i.getZ()));
@@ -577,14 +574,15 @@ public class IrisObject extends IrisRegistrant {
VectorMap<PlatformBlockState> b = new VectorMap<>();
VectorMap<TileData> s = new VectorMap<>();
IrisBlockVector shift = new IrisBlockVector(offset.getX(), offset.getY(), offset.getZ());
blocks.forEach((vector, data) -> {
vector.add(offset);
vector.add(shift);
b.put(vector, data);
});
states.forEach((vector, data) -> {
vector.add(offset);
vector.add(shift);
s.put(vector, data);
});
@@ -604,16 +602,16 @@ public class IrisObject extends IrisRegistrant {
states = dx;
}
public Vector3i getSigned(int x, int y, int z) {
public IrisBlockVector getSigned(int x, int y, int z) {
if (x >= w || y >= h || z >= d) {
throw new RuntimeException(x + " " + y + " " + z + " exceeds limit of " + w + " " + h + " " + d);
}
return (Vector3i) new Vector3i(x, y, z).subtract(center);
return new IrisBlockVector(x - center.getX(), y - center.getY(), z - center.getZ());
}
public void setUnsigned(int x, int y, int z, PlatformBlockState block) {
Vector3i v = getSigned(x, y, z);
IrisBlockVector v = getSigned(x, y, z);
if (block == null) {
blocks.remove(v);
@@ -624,7 +622,7 @@ public class IrisObject extends IrisRegistrant {
}
public void setUnsignedTile(int x, int y, int z, TileData tile) {
Vector3i v = getSigned(x, y, z);
IrisBlockVector v = getSigned(x, y, z);
if (tile == null) {
states.remove(v);
@@ -634,7 +632,7 @@ public class IrisObject extends IrisRegistrant {
}
public void setUnsigned(int x, int y, int z, Block block, boolean legacy) {
Vector3i v = getSigned(x, y, z);
IrisBlockVector v = getSigned(x, y, z);
if (block == null) {
blocks.remove(v);
@@ -738,8 +736,8 @@ public class IrisObject extends IrisRegistrant {
int spinx = rng.imax() / 1000;
int spiny = rng.imax() / 1000;
int spinz = rng.imax() / 1000;
int rty = config.getRotation().rotate(new BlockVector(0, getCenter().getBlockY(), 0), spinx, spiny, spinz).getBlockY();
int ty = config.getTranslate().translate(new BlockVector(0, getCenter().getBlockY(), 0), config.getRotation(), spinx, spiny, spinz).getBlockY();
int rty = config.getRotation().rotate(new IrisBlockVector(0, getCenter().getBlockY(), 0), spinx, spiny, spinz).getBlockY();
int ty = config.getTranslate().translate(new IrisBlockVector(0, getCenter().getBlockY(), 0), config.getRotation(), spinx, spiny, spinz).getBlockY();
int y = -1;
int xx, zz;
int yrand = config.getTranslate().getYRandom();
@@ -764,8 +762,8 @@ public class IrisObject extends IrisRegistrant {
}
}
} else if (config.getMode().equals(ObjectPlaceMode.MAX_HEIGHT) || config.getMode().equals(ObjectPlaceMode.STILT)) {
BlockVector offset = new BlockVector(config.getTranslate().getX(), config.getTranslate().getY(), config.getTranslate().getZ());
BlockVector rotatedDimensions = config.getRotation().rotate(new BlockVector(getW(), getH(), getD()), spinx, spiny, spinz).clone();
IrisBlockVector offset = new IrisBlockVector(config.getTranslate().getX(), config.getTranslate().getY(), config.getTranslate().getZ());
IrisBlockVector rotatedDimensions = config.getRotation().rotate(new IrisBlockVector(getW(), getH(), getD()), spinx, spiny, spinz).clone();
int xLength = (rotatedDimensions.getBlockX() / 2) + offset.getBlockX();
int minX = Math.min(x - xLength, x + xLength);
int maxX = Math.max(x - xLength, x + xLength);
@@ -786,8 +784,8 @@ public class IrisObject extends IrisRegistrant {
}
}
} else if (config.getMode().equals(ObjectPlaceMode.FAST_MAX_HEIGHT) || config.getMode().equals(ObjectPlaceMode.FAST_STILT)) {
BlockVector offset = new BlockVector(config.getTranslate().getX(), config.getTranslate().getY(), config.getTranslate().getZ());
BlockVector rotatedDimensions = config.getRotation().rotate(new BlockVector(getW(), getH(), getD()), spinx, spiny, spinz).clone();
IrisBlockVector offset = new IrisBlockVector(config.getTranslate().getX(), config.getTranslate().getY(), config.getTranslate().getZ());
IrisBlockVector rotatedDimensions = config.getRotation().rotate(new IrisBlockVector(getW(), getH(), getD()), spinx, spiny, spinz).clone();
int xRadius = (rotatedDimensions.getBlockX() / 2);
int xLength = xRadius + offset.getBlockX();
@@ -813,8 +811,8 @@ public class IrisObject extends IrisRegistrant {
}
} else if (config.getMode().equals(ObjectPlaceMode.MIN_HEIGHT) || config.getMode() == ObjectPlaceMode.MIN_STILT) {
y = rdata.getEngine().getHeight() + 1;
BlockVector offset = new BlockVector(config.getTranslate().getX(), config.getTranslate().getY(), config.getTranslate().getZ());
BlockVector rotatedDimensions = config.getRotation().rotate(new BlockVector(getW(), getH(), getD()), spinx, spiny, spinz).clone();
IrisBlockVector offset = new IrisBlockVector(config.getTranslate().getX(), config.getTranslate().getY(), config.getTranslate().getZ());
IrisBlockVector rotatedDimensions = config.getRotation().rotate(new IrisBlockVector(getW(), getH(), getD()), spinx, spiny, spinz).clone();
int xLength = (rotatedDimensions.getBlockX() / 2) + offset.getBlockX();
int minX = Math.min(x - xLength, x + xLength);
@@ -838,8 +836,8 @@ public class IrisObject extends IrisRegistrant {
}
} else if (config.getMode().equals(ObjectPlaceMode.FAST_MIN_HEIGHT) || config.getMode() == ObjectPlaceMode.FAST_MIN_STILT) {
y = rdata.getEngine().getHeight() + 1;
BlockVector offset = new BlockVector(config.getTranslate().getX(), config.getTranslate().getY(), config.getTranslate().getZ());
BlockVector rotatedDimensions = config.getRotation().rotate(new BlockVector(getW(), getH(), getD()), spinx, spiny, spinz).clone();
IrisBlockVector offset = new IrisBlockVector(config.getTranslate().getX(), config.getTranslate().getY(), config.getTranslate().getZ());
IrisBlockVector rotatedDimensions = config.getRotation().rotate(new IrisBlockVector(getW(), getH(), getD()), spinx, spiny, spinz).clone();
int xRadius = (rotatedDimensions.getBlockX() / 2);
int xLength = xRadius + offset.getBlockX();
@@ -943,7 +941,7 @@ public class IrisObject extends IrisRegistrant {
if (!config.isForcePlace() && !rawStructurePiece && (!config.getAllowedCollisions().isEmpty() || !config.getForbiddenCollisions().isEmpty())) {
Engine engine = rdata.getEngine();
BlockVector offset = new BlockVector(config.getTranslate().getX(), config.getTranslate().getY(), config.getTranslate().getZ());
IrisBlockVector offset = new IrisBlockVector(config.getTranslate().getX(), config.getTranslate().getY(), config.getTranslate().getZ());
for (int i = x - Math.floorDiv(w, 2) + (int) offset.getX(); i <= x + Math.floorDiv(w, 2) - (w % 2 == 0 ? 1 : 0) + (int) offset.getX(); i++) {
for (int j = y - Math.floorDiv(h, 2) + (int) offset.getY(); j <= y + Math.floorDiv(h, 2) - (h % 2 == 0 ? 1 : 0) + (int) offset.getY(); j++) {
for (int k = z - Math.floorDiv(d, 2) + (int) offset.getZ(); k <= z + Math.floorDiv(d, 2) - (d % 2 == 0 ? 1 : 0) + (int) offset.getX(); k++) {
@@ -963,11 +961,11 @@ public class IrisObject extends IrisRegistrant {
}
if (config.isBore()) {
BlockVector offset = new BlockVector(config.getTranslate().getX(), config.getTranslate().getY(), config.getTranslate().getZ());
IrisBlockVector offset = new IrisBlockVector(config.getTranslate().getX(), config.getTranslate().getY(), config.getTranslate().getZ());
for (int i = x - Math.floorDiv(w, 2) + (int) offset.getX(); i <= x + Math.floorDiv(w, 2) - (w % 2 == 0 ? 1 : 0) + (int) offset.getX(); i++) {
for (int j = y - Math.floorDiv(h, 2) - config.getBoreExtendMinY() + (int) offset.getY(); j <= y + Math.floorDiv(h, 2) + config.getBoreExtendMaxY() - (h % 2 == 0 ? 1 : 0) + (int) offset.getY(); j++) {
for (int k = z - Math.floorDiv(d, 2) + (int) offset.getZ(); k <= z + Math.floorDiv(d, 2) - (d % 2 == 0 ? 1 : 0) + (int) offset.getX(); k++) {
placer.set(i, j, k, AIR);
placer.set(i, j, k, States.AIR);
}
}
}
@@ -980,7 +978,7 @@ public class IrisObject extends IrisRegistrant {
y += yrand;
readLock.lock();
KMap<BlockVector, String> markers = null;
KMap<IrisBlockVector, String> markers = null;
try {
if (config.getMarkers().isNotEmpty() && placer.getEngine() != null) {
@@ -996,7 +994,7 @@ public class IrisObject extends IrisRegistrant {
}
int max = j.getMaximumMarkers();
for (BlockVector i : list.shuffle()) {
for (IrisBlockVector i : list.shuffle()) {
if (max <= 0) {
break;
}
@@ -1011,8 +1009,8 @@ public class IrisObject extends IrisRegistrant {
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)));
boolean a = !blocks.containsKey((IrisBlockVector) i.clone().add(new IrisBlockVector(0, 1, 0)));
boolean fff = !blocks.containsKey((IrisBlockVector) i.clone().add(new IrisBlockVector(0, 2, 0)));
if (!marker.isEmptyAbove() || (a && fff)) {
markers.put(i, j.getMarker());
@@ -1035,15 +1033,15 @@ public class IrisObject extends IrisRegistrant {
} catch (Throwable e) {
IrisLogging.reportError(e);
IrisLogging.warn("Failed to read block node " + g.getBlockX() + "," + g.getBlockY() + "," + g.getBlockZ() + " in object " + getLoadKey() + " (cme)");
d = AIR;
d = States.AIR;
}
if (d == null) {
IrisLogging.warn("Failed to read block node " + g.getBlockX() + "," + g.getBlockY() + "," + g.getBlockZ() + " in object " + getLoadKey() + " (null)");
d = AIR;
d = States.AIR;
}
BlockVector i = g.clone();
IrisBlockVector i = g.clone();
PlatformBlockState data = d;
i = config.getRotation().rotate(i.clone(), spinx, spiny, spinz).clone();
if (ceilingHang) {
@@ -1184,8 +1182,8 @@ public class IrisObject extends IrisRegistrant {
double erodeMaxDist = 1;
if (eroding) {
int centroidCount = 0;
for (BlockVector g : blocks.keys()) {
BlockVector rot = config.getRotation().rotate(g.clone(), spinx, spiny, spinz).clone();
for (IrisBlockVector g : blocks.keys()) {
IrisBlockVector 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) {
PlatformBlockState bd = blocks.get(g);
@@ -1200,8 +1198,8 @@ public class IrisObject extends IrisRegistrant {
erodeCentroidX /= centroidCount;
erodeCentroidZ /= centroidCount;
}
for (BlockVector g : blocks.keys()) {
BlockVector rot = config.getRotation().rotate(g.clone(), spinx, spiny, spinz).clone();
for (IrisBlockVector g : blocks.keys()) {
IrisBlockVector 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) {
PlatformBlockState bd = blocks.get(g);
@@ -1217,19 +1215,19 @@ public class IrisObject extends IrisRegistrant {
}
}
for (BlockVector g : blocks.keys()) {
for (IrisBlockVector g : blocks.keys()) {
PlatformBlockState sourceData;
try {
sourceData = blocks.get(g);
} catch (Throwable e) {
IrisLogging.reportError(e);
IrisLogging.warn("Failed to read block node " + g.getBlockX() + "," + g.getBlockY() + "," + g.getBlockZ() + " in object " + getLoadKey() + " (stilt cme)");
sourceData = AIR;
sourceData = States.AIR;
}
if (sourceData == null) {
IrisLogging.warn("Failed to read block node " + g.getBlockX() + "," + g.getBlockY() + "," + g.getBlockZ() + " in object " + getLoadKey() + " (stilt null)");
sourceData = AIR;
sourceData = States.AIR;
}
if (!shouldStilt(sourceData)) {
@@ -1246,7 +1244,7 @@ public class IrisObject extends IrisRegistrant {
}
}
BlockVector i = g.clone();
IrisBlockVector i = g.clone();
i = config.getRotation().rotate(i.clone(), spinx, spiny, spinz).clone();
if (ceilingHang) {
i.setY(-i.getBlockY());
@@ -1410,7 +1408,7 @@ public class IrisObject extends IrisRegistrant {
}
if (vacuuming && vacuumLowest != Integer.MAX_VALUE && placer.getEngine() != null) {
BlockVector rotDim = config.getRotation().rotate(new BlockVector(getW(), getH(), getD()), spinx, spiny, spinz).clone();
IrisBlockVector rotDim = config.getRotation().rotate(new IrisBlockVector(getW(), getH(), getD()), spinx, spiny, spinz).clone();
int lowX = IrisObjectVacuum.footprintLow(rotDim.getBlockX());
int highX = IrisObjectVacuum.footprintHigh(rotDim.getBlockX());
int lowZ = IrisObjectVacuum.footprintLow(rotDim.getBlockZ());
@@ -1500,7 +1498,7 @@ public class IrisObject extends IrisRegistrant {
if (targetY > origY) {
PlatformBlockState fill = complex != null ? complex.getRockStream().get(cx, cz) : null;
if (fill == null || BukkitBlockResolution.isAir((BlockData) fill.nativeHandle())) {
fill = STONE;
fill = States.STONE;
}
for (int yy = origY + 1; yy <= targetY; yy++) {
placer.set(cx, yy, cz, fill);
@@ -1509,7 +1507,7 @@ public class IrisObject extends IrisRegistrant {
boolean inside = IrisObjectVacuum.outset(dx, lowX, highX) == 0 && IrisObjectVacuum.outset(dz, lowZ, highZ) == 0;
int carveFloor = IrisObjectVacuum.carveFloorY(targetY, topY, inside);
for (int yy = origY; yy >= carveFloor; yy--) {
placer.set(cx, yy, cz, AIR);
placer.set(cx, yy, cz, States.AIR);
}
}
}
@@ -1527,7 +1525,7 @@ public class IrisObject extends IrisRegistrant {
}
private boolean lacksFootprintSupport(IObjectPlacer placer, IrisObjectPlacement config, int x, int y, int z, int spinx, int spiny, int spinz) {
BlockVector rot = config.getRotation().rotate(new BlockVector(getW(), getH(), getD()), spinx, spiny, spinz).clone();
IrisBlockVector rot = config.getRotation().rotate(new IrisBlockVector(getW(), getH(), getD()), spinx, spiny, spinz).clone();
int halfW = Math.max(0, Math.abs(rot.getBlockX()) / 2);
int halfD = Math.max(0, Math.abs(rot.getBlockZ()) / 2);
if (halfW == 0 && halfD == 0) {
@@ -1603,7 +1601,7 @@ public class IrisObject extends IrisRegistrant {
readLock.lock();
for (var entry : blocks) {
var i = entry.getKey();
Block b = at.clone().add(0, getCenter().getY(), 0).add(i).getBlock();
Block b = at.clone().add(0, getCenter().getY(), 0).add(i.getX(), i.getY(), i.getZ()).getBlock();
b.setBlockData((BlockData) Objects.requireNonNull(entry.getValue()).nativeHandle(), false);
if (states.containsKey(i)) {
@@ -1618,7 +1616,7 @@ public class IrisObject extends IrisRegistrant {
readLock.lock();
for (var entry : blocks) {
var i = entry.getKey();
Block b = at.clone().add(getCenter().getX(), getCenter().getY(), getCenter().getZ()).add(i).getBlock();
Block b = at.clone().add(getCenter().getX(), getCenter().getY(), getCenter().getZ()).add(i.getX(), i.getY(), i.getZ()).getBlock();
b.setBlockData((BlockData) Objects.requireNonNull(entry.getValue()).nativeHandle(), false);
if (states.containsKey(i)) {
@@ -1630,8 +1628,8 @@ 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((BlockData) AIR.nativeHandle(), false);
for (IrisBlockVector i : blocks.keys()) {
at.clone().add(getCenter().getX(), getCenter().getY(), getCenter().getZ()).add(i.getX(), i.getY(), i.getZ()).getBlock().setBlockData((BlockData) States.AIR.nativeHandle(), false);
}
readLock.unlock();
}
@@ -1640,7 +1638,7 @@ public class IrisObject extends IrisRegistrant {
if (interpolation == null) {
interpolation = IrisObjectPlacementScaleInterpolator.NONE;
}
Vector sm1 = new Vector(scale - 1, scale - 1, scale - 1);
IrisVector sm1 = new IrisVector(scale - 1, scale - 1, scale - 1);
scale = Math.max(0.001, Math.min(50, scale));
if (scale < 1) {
scale = scale - 0.0001;
@@ -1650,7 +1648,7 @@ public class IrisObject extends IrisRegistrant {
IrisPosition l2 = getAABB().min();
VectorMap<PlatformBlockState> placeBlock = new VectorMap<>();
Vector center = getCenter();
IrisVector center = new IrisVector(getCenter().getX(), getCenter().getY(), getCenter().getZ());
if (getH() == 2) {
center = center.setY(center.getBlockY() + 0.5);
}
@@ -1675,9 +1673,9 @@ public class IrisObject extends IrisRegistrant {
readLock.unlock();
for (var entry : placeBlock) {
BlockVector v = entry.getKey();
IrisBlockVector v = entry.getKey();
if (scale > 1) {
for (BlockVector vec : blocksBetweenTwoPoints(v.clone().add(center), v.clone().add(center).add(sm1))) {
for (IrisBlockVector vec : blocksBetweenTwoPoints(v.clone().add(center), v.clone().add(center).add(sm1))) {
oo.blocks.put(vec, entry.getValue());
}
} else {
@@ -1700,14 +1698,14 @@ public class IrisObject extends IrisRegistrant {
writeLock.lock();
VectorMap<PlatformBlockState> v = blocks;
VectorMap<PlatformBlockState> b = new VectorMap<>();
BlockVector min = getAABB().minbv();
BlockVector max = getAABB().maxbv();
IrisPosition min = getAABB().min();
IrisPosition max = getAABB().max();
for (int x = min.getBlockX(); x <= max.getBlockX(); x++) {
for (int y = min.getBlockY(); y <= max.getBlockY(); y++) {
for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) {
for (int x = min.getX(); x <= max.getX(); x++) {
for (int y = min.getY(); y <= max.getY(); y++) {
for (int z = min.getZ(); z <= max.getZ(); z++) {
if (IrisInterpolation.getTrilinear(x, y, z, rad, (xx, yy, zz) -> {
PlatformBlockState data = v.get(new BlockVector((int) xx, (int) yy, (int) zz));
PlatformBlockState data = v.get(new IrisBlockVector((int) xx, (int) yy, (int) zz));
if (data == null || ((BlockData) data.nativeHandle()).getMaterial().isAir()) {
return 0;
@@ -1715,9 +1713,9 @@ public class IrisObject extends IrisRegistrant {
return 1;
}) >= 0.5) {
b.put(new BlockVector(x, y, z), nearestBlockData(x, y, z));
b.put(new IrisBlockVector(x, y, z), nearestBlockData(x, y, z));
} else {
b.put(new BlockVector(x, y, z), AIR);
b.put(new IrisBlockVector(x, y, z), States.AIR);
}
}
}
@@ -1731,14 +1729,14 @@ public class IrisObject extends IrisRegistrant {
writeLock.lock();
VectorMap<PlatformBlockState> v = blocks;
VectorMap<PlatformBlockState> b = new VectorMap<>();
BlockVector min = getAABB().minbv();
BlockVector max = getAABB().maxbv();
IrisPosition min = getAABB().min();
IrisPosition max = getAABB().max();
for (int x = min.getBlockX(); x <= max.getBlockX(); x++) {
for (int y = min.getBlockY(); y <= max.getBlockY(); y++) {
for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) {
for (int x = min.getX(); x <= max.getX(); x++) {
for (int y = min.getY(); y <= max.getY(); y++) {
for (int z = min.getZ(); z <= max.getZ(); z++) {
if (IrisInterpolation.getTricubic(x, y, z, rad, (xx, yy, zz) -> {
PlatformBlockState data = v.get(new BlockVector((int) xx, (int) yy, (int) zz));
PlatformBlockState data = v.get(new IrisBlockVector((int) xx, (int) yy, (int) zz));
if (data == null || ((BlockData) data.nativeHandle()).getMaterial().isAir()) {
return 0;
@@ -1746,9 +1744,9 @@ public class IrisObject extends IrisRegistrant {
return 1;
}) >= 0.5) {
b.put(new BlockVector(x, y, z), nearestBlockData(x, y, z));
b.put(new IrisBlockVector(x, y, z), nearestBlockData(x, y, z));
} else {
b.put(new BlockVector(x, y, z), AIR);
b.put(new IrisBlockVector(x, y, z), States.AIR);
}
}
}
@@ -1766,14 +1764,14 @@ public class IrisObject extends IrisRegistrant {
writeLock.lock();
VectorMap<PlatformBlockState> v = blocks;
VectorMap<PlatformBlockState> b = new VectorMap<>();
BlockVector min = getAABB().minbv();
BlockVector max = getAABB().maxbv();
IrisPosition min = getAABB().min();
IrisPosition max = getAABB().max();
for (int x = min.getBlockX(); x <= max.getBlockX(); x++) {
for (int y = min.getBlockY(); y <= max.getBlockY(); y++) {
for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) {
for (int x = min.getX(); x <= max.getX(); x++) {
for (int y = min.getY(); y <= max.getY(); y++) {
for (int z = min.getZ(); z <= max.getZ(); z++) {
if (IrisInterpolation.getTrihermite(x, y, z, rad, (xx, yy, zz) -> {
PlatformBlockState data = v.get(new BlockVector((int) xx, (int) yy, (int) zz));
PlatformBlockState data = v.get(new IrisBlockVector((int) xx, (int) yy, (int) zz));
if (data == null || ((BlockData) data.nativeHandle()).getMaterial().isAir()) {
return 0;
@@ -1781,9 +1779,9 @@ public class IrisObject extends IrisRegistrant {
return 1;
}, tension, bias) >= 0.5) {
b.put(new BlockVector(x, y, z), nearestBlockData(x, y, z));
b.put(new IrisBlockVector(x, y, z), nearestBlockData(x, y, z));
} else {
b.put(new BlockVector(x, y, z), AIR);
b.put(new IrisBlockVector(x, y, z), States.AIR);
}
}
}
@@ -1794,7 +1792,7 @@ public class IrisObject extends IrisRegistrant {
}
private PlatformBlockState nearestBlockData(int x, int y, int z) {
BlockVector vv = new BlockVector(x, y, z);
IrisBlockVector vv = new IrisBlockVector(x, y, z);
readLock.lock();
PlatformBlockState r = blocks.get(vv);
@@ -18,12 +18,12 @@
package art.arcane.iris.engine.object;
import art.arcane.iris.platform.bukkit.BukkitPlatform;
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.IrisLogging;
import art.arcane.iris.spi.PlatformBlockState;
import art.arcane.iris.util.common.math.IrisBlockVector;
import art.arcane.volmlib.util.collection.KList;
import art.arcane.volmlib.util.collection.KMap;
import lombok.AllArgsConstructor;
@@ -35,7 +35,6 @@ import org.bukkit.block.BlockFace;
import org.bukkit.block.data.*;
import org.bukkit.block.data.type.RedstoneWire;
import org.bukkit.block.data.type.Wall;
import org.bukkit.util.BlockVector;
import java.util.HashMap;
import java.util.List;
@@ -136,13 +135,25 @@ public class IrisObjectRotation {
return e.rotateCopy(this);
}
public BlockVector rotate(BlockVector direction) {
public IrisBlockVector rotate(IrisBlockVector direction) {
return rotate(direction, 0, 0, 0);
}
public IrisDirection rotate(IrisDirection direction) {
BlockVector v = rotate(direction.toVector().toBlockVector());
return IrisDirection.closest(v);
IrisBlockVector v = rotate(new IrisBlockVector(direction.x(), direction.y(), direction.z()));
double m = Double.MAX_VALUE;
IrisDirection s = null;
for (IrisDirection i : IrisDirection.values()) {
double g = new IrisBlockVector(i.x(), i.y(), i.z()).distance(v);
if (g < m) {
m = g;
s = i;
}
}
return s;
}
public double getRotation(int spin, IrisAxisRotationClamp clamp) {
@@ -157,7 +168,7 @@ public class IrisObjectRotation {
return clamp.getRadians(spin);
}
public BlockFace getFace(BlockVector v) {
public BlockFace getFace(IrisBlockVector v) {
int x = (int) Math.round(v.getX());
int y = (int) Math.round(v.getY());
int z = (int) Math.round(v.getZ());
@@ -189,7 +200,7 @@ public class IrisObjectRotation {
return BlockFace.SOUTH;
}
public BlockFace getHexFace(BlockVector v) {
public BlockFace getHexFace(IrisBlockVector v) {
int x = v.getBlockX();
int y = v.getBlockY();
int z = v.getBlockZ();
@@ -271,7 +282,7 @@ public class IrisObjectRotation {
if (d instanceof Directional g) {
BlockFace f = g.getFacing();
BlockVector bv = new BlockVector(f.getModX(), f.getModY(), f.getModZ());
IrisBlockVector bv = new IrisBlockVector(f.getModX(), f.getModY(), f.getModZ());
bv = rotate(bv.clone(), spinx, spiny, spinz);
BlockFace t = getFace(bv);
@@ -283,7 +294,7 @@ public class IrisObjectRotation {
} else if (d instanceof Rotatable g) {
BlockFace f = g.getRotation();
BlockVector bv = new BlockVector(f.getModX(), 0, f.getModZ());
IrisBlockVector bv = new IrisBlockVector(f.getModX(), 0, f.getModZ());
bv = rotate(bv.clone(), spinx, spiny, spinz);
BlockFace face = getHexFace(bv);
@@ -291,7 +302,7 @@ public class IrisObjectRotation {
} else if (d instanceof Orientable g) {
BlockFace f = getFace(g.getAxis());
BlockVector bv = new BlockVector(f.getModX(), f.getModY(), f.getModZ());
IrisBlockVector bv = new IrisBlockVector(f.getModX(), f.getModY(), f.getModZ());
bv = rotate(bv.clone(), spinx, spiny, spinz);
Axis a = getAxis(bv);
@@ -302,7 +313,7 @@ public class IrisObjectRotation {
List<BlockFace> faces = new KList<>();
for (BlockFace i : g.getFaces()) {
BlockVector bv = new BlockVector(i.getModX(), i.getModY(), i.getModZ());
IrisBlockVector bv = new IrisBlockVector(i.getModX(), i.getModY(), i.getModZ());
bv = rotate(bv.clone(), spinx, spiny, spinz);
BlockFace r = getFace(bv);
@@ -323,7 +334,7 @@ public class IrisObjectRotation {
for (BlockFace i : WALL_FACES) {
Wall.Height h = wall.getHeight(i);
BlockVector bv = new BlockVector(i.getModX(), i.getModY(), i.getModZ());
IrisBlockVector bv = new IrisBlockVector(i.getModX(), i.getModY(), i.getModZ());
bv = rotate(bv.clone(), spinx, spiny, spinz);
BlockFace r = getFace(bv);
if (WALL_FACES.contains(r)) {
@@ -340,7 +351,7 @@ public class IrisObjectRotation {
var allowed = wire.getAllowedFaces();
for (BlockFace i : allowed) {
RedstoneWire.Connection connection = wire.getFace(i);
BlockVector bv = new BlockVector(i.getModX(), i.getModY(), i.getModZ());
IrisBlockVector bv = new IrisBlockVector(i.getModX(), i.getModY(), i.getModZ());
bv = rotate(bv.clone(), spinx, spiny, spinz);
BlockFace r = getFace(bv);
if (allowed.contains(r))
@@ -359,7 +370,7 @@ public class IrisObjectRotation {
return d;
}
public Axis getAxis(BlockVector v) {
public Axis getAxis(IrisBlockVector v) {
if (Math.abs(v.getBlockX()) > Math.max(Math.abs(v.getBlockY()), Math.abs(v.getBlockZ()))) {
return Axis.X;
}
@@ -388,15 +399,16 @@ public class IrisObjectRotation {
}
public IrisPosition rotate(IrisPosition b, int spinx, int spiny, int spinz) {
return BukkitPlatform.positionOf(rotate(new BlockVector(b.getX(), b.getY(), b.getZ()), spinx, spiny, spinz));
IrisBlockVector v = rotate(new IrisBlockVector(b.getX(), b.getY(), b.getZ()), spinx, spiny, spinz);
return new IrisPosition(v.getBlockX(), v.getBlockY(), v.getBlockZ());
}
public BlockVector rotate(BlockVector b, int spinx, int spiny, int spinz) {
public IrisBlockVector rotate(IrisBlockVector b, int spinx, int spiny, int spinz) {
if (!canRotate()) {
return b;
}
BlockVector v = b.clone();
IrisBlockVector v = b.clone();
if (canRotateX()) {
if (getXAxis().isLocked()) {
@@ -19,11 +19,11 @@
package art.arcane.iris.engine.object;
import art.arcane.iris.engine.object.annotations.*;
import art.arcane.iris.util.common.math.IrisBlockVector;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.bukkit.util.BlockVector;
@Snippet("object-translator")
@Accessors(chain = true)
@@ -57,17 +57,17 @@ public class IrisObjectTranslate {
return x != 0 || y != 0 || z != 0;
}
public BlockVector translate(BlockVector i) {
public IrisBlockVector translate(IrisBlockVector i) {
if (canTranslate()) {
return (BlockVector) i.clone().add(new BlockVector(x, y, z));
return (IrisBlockVector) i.clone().add(new IrisBlockVector(x, y, z));
}
return i;
}
public BlockVector translate(BlockVector clone, IrisObjectRotation rotation, int sx, int sy, int sz) {
public IrisBlockVector translate(IrisBlockVector clone, IrisObjectRotation rotation, int sx, int sy, int sz) {
if (canTranslate()) {
return (BlockVector) clone.clone().add(rotation.rotate(new BlockVector(x, y, z), sx, sy, sz));
return (IrisBlockVector) clone.clone().add(rotation.rotate(new IrisBlockVector(x, y, z), sx, sy, sz));
}
return clone;
@@ -23,6 +23,7 @@ import art.arcane.iris.platform.bukkit.BukkitBlockResolution;
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.math.IrisBlockVector;
import art.arcane.iris.util.common.math.Vector3i;
import art.arcane.volmlib.util.math.RNG;
import org.bukkit.block.data.BlockData;
@@ -88,7 +89,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), BukkitBlockState.of(entry.getValue()));
object.getBlocks().put(new IrisBlockVector(nx, ny, nz), BukkitBlockState.of(entry.getValue()));
}
return object;
@@ -22,7 +22,7 @@ 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.iris.util.common.math.IrisBlockVector;
import art.arcane.volmlib.util.math.RNG;
import org.bukkit.block.data.BlockData;
@@ -119,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), BukkitBlockState.of(entry.getValue()));
object.getBlocks().put(new IrisBlockVector(nx, ny, nz), BukkitBlockState.of(entry.getValue()));
}
return object;
@@ -37,7 +37,7 @@ 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.util.BlockVector;
import art.arcane.iris.util.common.math.IrisBlockVector;
import java.io.File;
import java.util.LinkedHashMap;
@@ -198,8 +198,8 @@ public class ObjectStudioGenerator extends EnginedStudioGenerator {
int originY = cell.originY();
int originZ = cell.originZ();
for (Map.Entry<BlockVector, PlatformBlockState> entry : blocks) {
BlockVector signed = entry.getKey();
for (Map.Entry<IrisBlockVector, PlatformBlockState> entry : blocks) {
IrisBlockVector signed = entry.getKey();
int worldX = originX + signed.getBlockX() + centerX;
int worldY = originY + signed.getBlockY() + centerY;
int worldZ = originZ + signed.getBlockZ() + centerZ;
@@ -257,7 +257,7 @@ public class ObjectStudioGenerator extends EnginedStudioGenerator {
}
int cellCount = layout.cells().size();
BlockVector worldExtent = computeExtent(layout);
IrisBlockVector worldExtent = computeExtent(layout);
IrisLogging.info("Object Studio layout built: %d cells from %d pack(s), extent %d x %d blocks",
cellCount, sources.size(), worldExtent.getBlockX(), worldExtent.getBlockZ());
}
@@ -280,13 +280,13 @@ public class ObjectStudioGenerator extends EnginedStudioGenerator {
return new File(new File(worldFolder, ".iris"), "object-studio-layout.json");
}
private static BlockVector computeExtent(ObjectStudioLayout layout) {
private static IrisBlockVector computeExtent(ObjectStudioLayout layout) {
int maxX = 0;
int maxZ = 0;
for (GridCell cell : layout.cells()) {
maxX = Math.max(maxX, cell.originX() + cell.w());
maxZ = Math.max(maxZ, cell.originZ() + cell.d());
}
return new BlockVector(maxX, 0, maxZ);
return new IrisBlockVector(maxX, 0, maxZ);
}
}
@@ -2,7 +2,7 @@ package art.arcane.iris.util.common.data;
import art.arcane.volmlib.util.collection.KMap;
import lombok.NonNull;
import org.bukkit.util.BlockVector;
import art.arcane.iris.util.common.math.IrisBlockVector;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -11,7 +11,7 @@ import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Function;
public class VectorMap<T> implements Iterable<Map.Entry<BlockVector, T>> {
public class VectorMap<T> implements Iterable<Map.Entry<IrisBlockVector, T>> {
private final Map<Key, Map<Key, T>> map = new KMap<>();
public int size() {
@@ -22,7 +22,7 @@ public class VectorMap<T> implements Iterable<Map.Entry<BlockVector, T>> {
return map.values().stream().allMatch(Map::isEmpty);
}
public boolean containsKey(@NonNull BlockVector vector) {
public boolean containsKey(@NonNull IrisBlockVector vector) {
var chunk = map.get(chunk(vector));
return chunk != null && chunk.containsKey(relative(vector));
}
@@ -31,22 +31,22 @@ public class VectorMap<T> implements Iterable<Map.Entry<BlockVector, T>> {
return map.values().stream().anyMatch(m -> m.containsValue(value));
}
public @Nullable T get(@NonNull BlockVector vector) {
public @Nullable T get(@NonNull IrisBlockVector vector) {
var chunk = map.get(chunk(vector));
return chunk == null ? null : chunk.get(relative(vector));
}
public @Nullable T put(@NonNull BlockVector vector, @NonNull T value) {
public @Nullable T put(@NonNull IrisBlockVector vector, @NonNull T value) {
return map.computeIfAbsent(chunk(vector), k -> new KMap<>())
.put(relative(vector), value);
}
public @Nullable T computeIfAbsent(@NonNull BlockVector vector, @NonNull Function<@NonNull BlockVector, @NonNull T> mappingFunction) {
public @Nullable T computeIfAbsent(@NonNull IrisBlockVector vector, @NonNull Function<@NonNull IrisBlockVector, @NonNull T> mappingFunction) {
return map.computeIfAbsent(chunk(vector), k -> new KMap<>())
.computeIfAbsent(relative(vector), $ -> mappingFunction.apply(vector));
}
public @Nullable T remove(@NonNull BlockVector vector) {
public @Nullable T remove(@NonNull IrisBlockVector vector) {
var chunk = map.get(chunk(vector));
return chunk == null ? null : chunk.remove(relative(vector));
}
@@ -59,7 +59,7 @@ public class VectorMap<T> implements Iterable<Map.Entry<BlockVector, T>> {
map.clear();
}
public void forEach(@NonNull BiConsumer<@NonNull BlockVector, @NonNull T> consumer) {
public void forEach(@NonNull BiConsumer<@NonNull IrisBlockVector, @NonNull T> consumer) {
map.forEach((chunk, values) -> {
int rX = chunk.x << 10;
int rY = chunk.y << 10;
@@ -72,11 +72,11 @@ public class VectorMap<T> implements Iterable<Map.Entry<BlockVector, T>> {
});
}
private static Key chunk(BlockVector vector) {
private static Key chunk(IrisBlockVector vector) {
return new Key(vector.getBlockX() >> 10, vector.getBlockY() >> 10, vector.getBlockZ() >> 10);
}
private static Key relative(BlockVector vector) {
private static Key relative(IrisBlockVector vector) {
return new Key(vector.getBlockX() & 0x3FF, vector.getBlockY() & 0x3FF, vector.getBlockZ() & 0x3FF);
}
@@ -93,7 +93,7 @@ public class VectorMap<T> implements Iterable<Map.Entry<BlockVector, T>> {
return new ValueIterator();
}
public class EntryIterator implements Iterator<Map.Entry<BlockVector, T>> {
public class EntryIterator implements Iterator<Map.Entry<IrisBlockVector, T>> {
private final Iterator<Map.Entry<Key, Map<Key, T>>> chunkIterator = map.entrySet().iterator();
private Iterator<Map.Entry<Key, T>> relativeIterator;
private int rX, rY, rZ;
@@ -104,7 +104,7 @@ public class VectorMap<T> implements Iterable<Map.Entry<BlockVector, T>> {
}
@Override
public Map.Entry<BlockVector, T> next() {
public Map.Entry<IrisBlockVector, T> next() {
if (relativeIterator == null || !relativeIterator.hasNext()) {
if (!chunkIterator.hasNext()) throw new IllegalStateException("No more elements");
var chunk = chunkIterator.next();
@@ -125,7 +125,7 @@ public class VectorMap<T> implements Iterable<Map.Entry<BlockVector, T>> {
}
}
public class KeyIterator implements Iterator<BlockVector>, Iterable<BlockVector> {
public class KeyIterator implements Iterator<IrisBlockVector>, Iterable<IrisBlockVector> {
private final Iterator<Map.Entry<Key, Map<Key, T>>> chunkIterator = map.entrySet().iterator();
private Iterator<Key> relativeIterator;
private int rX, rY, rZ;
@@ -136,7 +136,7 @@ public class VectorMap<T> implements Iterable<Map.Entry<BlockVector, T>> {
}
@Override
public BlockVector next() {
public IrisBlockVector next() {
if (relativeIterator == null || !relativeIterator.hasNext()) {
var chunk = chunkIterator.next();
rX = chunk.getKey().x << 10;
@@ -155,7 +155,7 @@ public class VectorMap<T> implements Iterable<Map.Entry<BlockVector, T>> {
}
@Override
public @NotNull Iterator<BlockVector> iterator() {
public @NotNull Iterator<IrisBlockVector> iterator() {
return this;
}
}
@@ -202,8 +202,8 @@ public class VectorMap<T> implements Iterable<Map.Entry<BlockVector, T>> {
this.hashCode = (x << 20) | (y << 10) | z;
}
private BlockVector resolve(int rX, int rY, int rZ) {
return new BlockVector(rX + x, rY + y, rZ + z);
private IrisBlockVector resolve(int rX, int rY, int rZ) {
return new IrisBlockVector(rX + x, rY + y, rZ + z);
}
@Override
@@ -260,9 +260,7 @@ public enum C {
@SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
private final static Map<Integer, C> BY_ID = new HashMap<>();
private final static Map<Character, C> BY_CHAR = new HashMap<>();
private final static Map<DyeColor, C> dyeChatMap = new HashMap<>();
private final static Map<C, String> chatHexMap = new HashMap<>();
private final static Map<DyeColor, String> dyeHexMap = new HashMap<>();
static {
chatHexMap.put(C.BLACK, "#000000");
@@ -282,38 +280,6 @@ public enum C {
chatHexMap.put(C.LIGHT_PURPLE, "#FF55FF");
chatHexMap.put(C.YELLOW, "#FFFF55");
chatHexMap.put(C.WHITE, "#FFFFFF");
dyeChatMap.put(DyeColor.BLACK, C.DARK_GRAY);
dyeChatMap.put(DyeColor.BLUE, C.DARK_BLUE);
dyeChatMap.put(DyeColor.BROWN, C.GOLD);
dyeChatMap.put(DyeColor.CYAN, C.AQUA);
dyeChatMap.put(DyeColor.GRAY, C.GRAY);
dyeChatMap.put(DyeColor.GREEN, C.DARK_GREEN);
dyeChatMap.put(DyeColor.LIGHT_BLUE, C.BLUE);
dyeChatMap.put(DyeColor.LIME, C.GREEN);
dyeChatMap.put(DyeColor.MAGENTA, C.LIGHT_PURPLE);
dyeChatMap.put(DyeColor.ORANGE, C.GOLD);
dyeChatMap.put(DyeColor.PINK, C.LIGHT_PURPLE);
dyeChatMap.put(DyeColor.PURPLE, C.DARK_PURPLE);
dyeChatMap.put(DyeColor.RED, C.RED);
dyeChatMap.put(DyeColor.LIGHT_GRAY, C.GRAY);
dyeChatMap.put(DyeColor.WHITE, C.WHITE);
dyeChatMap.put(DyeColor.YELLOW, C.YELLOW);
dyeHexMap.put(DyeColor.BLACK, "#181414");
dyeHexMap.put(DyeColor.BLUE, "#253193");
dyeHexMap.put(DyeColor.BROWN, "#56331c");
dyeHexMap.put(DyeColor.CYAN, "#267191");
dyeHexMap.put(DyeColor.GRAY, "#414141");
dyeHexMap.put(DyeColor.GREEN, "#364b18");
dyeHexMap.put(DyeColor.LIGHT_BLUE, "#6387d2");
dyeHexMap.put(DyeColor.LIME, "#39ba2e");
dyeHexMap.put(DyeColor.MAGENTA, "#be49c9");
dyeHexMap.put(DyeColor.ORANGE, "#ea7e35");
dyeHexMap.put(DyeColor.PINK, "#d98199");
dyeHexMap.put(DyeColor.PURPLE, "#7e34bf");
dyeHexMap.put(DyeColor.RED, "#9e2b27");
dyeHexMap.put(DyeColor.LIGHT_GRAY, "#a0a7a7");
dyeHexMap.put(DyeColor.WHITE, "#a4a4a4");
dyeHexMap.put(DyeColor.YELLOW, "#c2b51c");
}
static {
@@ -323,6 +289,46 @@ public enum C {
}
}
private static final class DyeMaps {
private static final Map<DyeColor, C> CHAT = new HashMap<>();
private static final Map<DyeColor, String> HEX = new HashMap<>();
static {
CHAT.put(DyeColor.BLACK, C.DARK_GRAY);
CHAT.put(DyeColor.BLUE, C.DARK_BLUE);
CHAT.put(DyeColor.BROWN, C.GOLD);
CHAT.put(DyeColor.CYAN, C.AQUA);
CHAT.put(DyeColor.GRAY, C.GRAY);
CHAT.put(DyeColor.GREEN, C.DARK_GREEN);
CHAT.put(DyeColor.LIGHT_BLUE, C.BLUE);
CHAT.put(DyeColor.LIME, C.GREEN);
CHAT.put(DyeColor.MAGENTA, C.LIGHT_PURPLE);
CHAT.put(DyeColor.ORANGE, C.GOLD);
CHAT.put(DyeColor.PINK, C.LIGHT_PURPLE);
CHAT.put(DyeColor.PURPLE, C.DARK_PURPLE);
CHAT.put(DyeColor.RED, C.RED);
CHAT.put(DyeColor.LIGHT_GRAY, C.GRAY);
CHAT.put(DyeColor.WHITE, C.WHITE);
CHAT.put(DyeColor.YELLOW, C.YELLOW);
HEX.put(DyeColor.BLACK, "#181414");
HEX.put(DyeColor.BLUE, "#253193");
HEX.put(DyeColor.BROWN, "#56331c");
HEX.put(DyeColor.CYAN, "#267191");
HEX.put(DyeColor.GRAY, "#414141");
HEX.put(DyeColor.GREEN, "#364b18");
HEX.put(DyeColor.LIGHT_BLUE, "#6387d2");
HEX.put(DyeColor.LIME, "#39ba2e");
HEX.put(DyeColor.MAGENTA, "#be49c9");
HEX.put(DyeColor.ORANGE, "#ea7e35");
HEX.put(DyeColor.PINK, "#d98199");
HEX.put(DyeColor.PURPLE, "#7e34bf");
HEX.put(DyeColor.RED, "#9e2b27");
HEX.put(DyeColor.LIGHT_GRAY, "#a0a7a7");
HEX.put(DyeColor.WHITE, "#a4a4a4");
HEX.put(DyeColor.YELLOW, "#c2b51c");
}
}
private final int intCode;
private final char code;
private final String token;
@@ -511,15 +517,15 @@ public enum C {
* @return the color
*/
public static C dyeToChat(DyeColor dclr) {
if (dyeChatMap.containsKey(dclr)) {
return dyeChatMap.get(dclr);
if (DyeMaps.CHAT.containsKey(dclr)) {
return DyeMaps.CHAT.get(dclr);
}
return C.MAGIC;
}
public static DyeColor chatToDye(ChatColor color) {
for (Map.Entry<DyeColor, C> entry : dyeChatMap.entrySet()) {
for (Map.Entry<DyeColor, C> entry : DyeMaps.CHAT.entrySet()) {
if (entry.getValue().toString().equals(color.toString())) {
return entry.getKey();
}
@@ -538,8 +544,8 @@ public enum C {
}
public static String dyeToHex(DyeColor clr) {
if (dyeHexMap.containsKey(clr)) {
return dyeHexMap.get(clr);
if (DyeMaps.HEX.containsKey(clr)) {
return DyeMaps.HEX.get(clr);
}
return "#000000";
@@ -592,7 +598,7 @@ public enum C {
str.append("</table>");
str.append("<table><tr><td>Dye Color</td><td>Color</td></tr>");
for (Map.Entry<DyeColor, String> e : dyeHexMap.entrySet()) {
for (Map.Entry<DyeColor, String> e : DyeMaps.HEX.entrySet()) {
str.append(String.format("<tr><td style='color: %2$s;'>%1$s</td>" + "<td style='color: %2$s;'>Test String</td></tr>", e.getKey().name(), e.getValue()));
}
@@ -0,0 +1,34 @@
package art.arcane.iris.util.common.math;
public class IrisBlockVector extends IrisVector {
public IrisBlockVector() {
super();
}
public IrisBlockVector(int x, int y, int z) {
super(x, y, z);
}
public IrisBlockVector(double x, double y, double z) {
super(x, y, z);
}
@Override
public IrisBlockVector clone() {
return (IrisBlockVector) super.clone();
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof IrisBlockVector other)) {
return false;
}
return (int) other.getX() == (int) this.x && (int) other.getY() == (int) this.y && (int) other.getZ() == (int) this.z;
}
@Override
public int hashCode() {
return (Integer.hashCode((int) x) >> 13) ^ (Integer.hashCode((int) y) >> 7) ^ Integer.hashCode((int) z);
}
}
@@ -0,0 +1,163 @@
package art.arcane.iris.util.common.math;
public class IrisVector implements Cloneable {
private static final double EPSILON = 0.000001;
protected double x;
protected double y;
protected double z;
public IrisVector() {
this.x = 0;
this.y = 0;
this.z = 0;
}
public IrisVector(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
public IrisVector(double x, double y, double z) {
this.x = x;
this.y = y;
this.z = z;
}
public double getX() {
return x;
}
public double getY() {
return y;
}
public double getZ() {
return z;
}
public int getBlockX() {
return floor(x);
}
public int getBlockY() {
return floor(y);
}
public int getBlockZ() {
return floor(z);
}
public IrisVector setX(double x) {
this.x = x;
return this;
}
public IrisVector setY(double y) {
this.y = y;
return this;
}
public IrisVector setZ(double z) {
this.z = z;
return this;
}
public IrisVector add(IrisVector vec) {
x += vec.x;
y += vec.y;
z += vec.z;
return this;
}
public IrisVector subtract(IrisVector vec) {
x -= vec.x;
y -= vec.y;
z -= vec.z;
return this;
}
public IrisVector multiply(double m) {
x *= m;
y *= m;
z *= m;
return this;
}
public double distance(IrisVector o) {
return Math.sqrt(square(x - o.x) + square(y - o.y) + square(z - o.z));
}
public double distanceSquared(IrisVector o) {
return square(x - o.x) + square(y - o.y) + square(z - o.z);
}
public IrisVector rotateAroundX(double angle) {
double angleCos = Math.cos(angle);
double angleSin = Math.sin(angle);
double y = angleCos * this.y - angleSin * this.z;
double z = angleSin * this.y + angleCos * this.z;
return setY(y).setZ(z);
}
public IrisVector rotateAroundY(double angle) {
double angleCos = Math.cos(angle);
double angleSin = Math.sin(angle);
double x = angleCos * this.x + angleSin * this.z;
double z = -angleSin * this.x + angleCos * this.z;
return setX(x).setZ(z);
}
public IrisVector rotateAroundZ(double angle) {
double angleCos = Math.cos(angle);
double angleSin = Math.sin(angle);
double x = angleCos * this.x - angleSin * this.y;
double y = angleSin * this.x + angleCos * this.y;
return setX(x).setY(y);
}
public IrisBlockVector toBlockVector() {
return new IrisBlockVector(x, y, z);
}
@Override
public IrisVector clone() {
try {
return (IrisVector) super.clone();
} catch (CloneNotSupportedException e) {
throw new Error(e);
}
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof IrisVector other)) {
return false;
}
return Math.abs(x - other.x) < EPSILON && Math.abs(y - other.y) < EPSILON && Math.abs(z - other.z) < EPSILON && this.getClass().equals(obj.getClass());
}
@Override
public int hashCode() {
int hash = 7;
hash = 79 * hash + (int) (Double.doubleToLongBits(this.x) ^ (Double.doubleToLongBits(this.x) >>> 32));
hash = 79 * hash + (int) (Double.doubleToLongBits(this.y) ^ (Double.doubleToLongBits(this.y) >>> 32));
hash = 79 * hash + (int) (Double.doubleToLongBits(this.z) ^ (Double.doubleToLongBits(this.z) >>> 32));
return hash;
}
@Override
public String toString() {
return x + "," + y + "," + z;
}
protected static int floor(double num) {
int floor = (int) num;
return floor == num ? floor : floor - (int) (Double.doubleToRawLongBits(num) >>> 63);
}
private static double square(double num) {
return num * num;
}
}
@@ -1,26 +1,65 @@
package art.arcane.iris.util.common.math;
import org.bukkit.util.BlockVector;
import org.bukkit.util.Vector;
import org.jetbrains.annotations.NotNull;
public class Vector3i implements Cloneable {
private final int x;
private final int y;
private final int z;
public class Vector3i extends BlockVector {
public Vector3i(int x, int y, int z) {
super(x, y, z);
this.x = x;
this.y = y;
this.z = z;
}
public Vector3i(Vector vec) {
super(vec);
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getZ() {
return z;
}
public int getBlockX() {
return x;
}
public int getBlockY() {
return y;
}
public int getBlockZ() {
return z;
}
@NotNull
@Override
public Vector3i clone() {
return (Vector3i) super.clone();
try {
return (Vector3i) super.clone();
} catch (CloneNotSupportedException e) {
throw new Error(e);
}
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Vector3i other)) {
return false;
}
return x == other.x && y == other.y && z == other.z;
}
@Override
public int hashCode() {
return (int) x ^ ((int) z << 12) ^ ((int) y << 24);
return x ^ (z << 12) ^ (y << 24);
}
@Override
public String toString() {
return x + "," + y + "," + z;
}
}
@@ -45,7 +45,7 @@ public class Bindings {
var settings = IrisSettings.get().getSentry();
if (settings.disableAutoReporting || Sentry.isEnabled() || Boolean.getBoolean("iris.suppressReporting")) return;
IrisLogging.info("Enabling Sentry for anonymous error reporting. You can disable this in the settings.");
IrisLogging.info("Your server ID is: " + ServerID.ID);
IrisLogging.info("Your server ID is: " + ServerID.getId());
Sentry.init(options -> {
options.setDsn("http://4cdbb9ac953306529947f4ca1e8e6b26@sentry.volmit.com:8080/2");
@@ -41,20 +41,23 @@ import java.util.Map;
import java.util.Locale;
public class NBTWorld {
private static final BlockData AIR = BukkitBlockResolution.get("AIR");
private static final NBTWorldSupport.BlockStateCodec<BlockData> BLOCK_STATE_CODEC = NBTWorldSupport.blockStateCodec(
blockStateString -> BukkitBlockResolution.getOrNull(blockStateString, true),
BukkitBlockResolution::getAir,
blockData -> blockData.getAsString(true),
blockData -> {
NamespacedKey key = KeyedType.getKey(blockData.getMaterial());
if (key == null) {
return "minecraft:" + blockData.getMaterial().name().toLowerCase(Locale.ROOT);
private static final class Holder {
private static final BlockData AIR = BukkitBlockResolution.get("AIR");
private static final NBTWorldSupport.BlockStateCodec<BlockData> BLOCK_STATE_CODEC = NBTWorldSupport.blockStateCodec(
blockStateString -> BukkitBlockResolution.getOrNull(blockStateString, true),
BukkitBlockResolution::getAir,
blockData -> blockData.getAsString(true),
blockData -> {
NamespacedKey key = KeyedType.getKey(blockData.getMaterial());
if (key == null) {
return "minecraft:" + blockData.getMaterial().name().toLowerCase(Locale.ROOT);
}
return key.getNamespace() + ":" + key.getKey();
}
return key.getNamespace() + ":" + key.getKey();
}
);
private static final Map<Biome, Integer> biomeIds = computeBiomeIDs();
);
private static final Map<Biome, Integer> BIOME_IDS = computeBiomeIDs();
}
private final HyperLock hyperLock = new HyperLock();
private final MCAWorldStoreSupport<MCAFile> regionStore;
private final MCAWorldRuntimeSupport<MCAFile, Chunk, Section> worldRuntime;
@@ -124,11 +127,11 @@ public class NBTWorld {
}
public static BlockData getBlockData(CompoundTag tag) {
return BLOCK_STATE_CODEC.decode(tag);
return Holder.BLOCK_STATE_CODEC.decode(tag);
}
public static CompoundTag getCompound(BlockData bd) {
return BLOCK_STATE_CODEC.encode(bd);
return Holder.BLOCK_STATE_CODEC.encode(bd);
}
private static Map<Biome, Integer> computeBiomeIDs() {
@@ -193,7 +196,7 @@ public class NBTWorld {
CompoundTag tag = worldRuntime.getBlockStateTag(x, y, z);
if (tag == null) {
return AIR;
return Holder.AIR;
}
return getBlockData(tag);
@@ -201,7 +204,7 @@ public class NBTWorld {
IrisLogging.reportError(e);
}
return AIR;
return Holder.AIR;
}
public void setBlockData(int x, int y, int z, BlockData data) {
@@ -209,11 +212,11 @@ public class NBTWorld {
}
public int getBiomeId(Biome b) {
return biomeIds.get(b);
return Holder.BIOME_IDS.get(b);
}
public void setBiome(int x, int y, int z, Biome biome) {
worldRuntime.setBiomeId(x, y, z, biomeIds.get(biome));
worldRuntime.setBiomeId(x, y, z, Holder.BIOME_IDS.get(biome));
}
public Section getChunkSection(int x, int y, int z) {
@@ -102,7 +102,10 @@ public class ChunkContext {
return false;
}
String threadName = Thread.currentThread().getName();
return prefillAsyncEligible(Thread.currentThread().getName());
}
static boolean prefillAsyncEligible(String threadName) {
return threadName != null && threadName.startsWith("Iris ");
}
@@ -18,16 +18,18 @@
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.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<PlatformBlockState> {
private static final PlatformBlockState AIR = BukkitBlockState.of(Material.AIR.createBlockData());
private static final class States {
private static final PlatformBlockState AIR = B.getState("AIR");
}
private final ChunkData chunk;
public ChunkDataHunkHolder(ChunkData chunk) {
@@ -54,7 +56,7 @@ public class ChunkDataHunkHolder extends AtomicHunk<PlatformBlockState> {
public PlatformBlockState getRaw(int x, int y, int z) {
PlatformBlockState b = super.getRaw(x, y, z);
return b != null ? b : AIR;
return b != null ? b : States.AIR;
}
public void apply() {
@@ -29,12 +29,10 @@ import org.bukkit.generator.ChunkGenerator.ChunkData;
@SuppressWarnings("ClassCanBeRecord")
public class ChunkDataHunkView implements Hunk<PlatformBlockState> {
private static final BlockData AIR = BukkitBlockResolution.getAir();
private final art.arcane.volmlib.util.hunk.view.ChunkDataHunkView view;
public ChunkDataHunkView(ChunkData chunk) {
this.view = new art.arcane.volmlib.util.hunk.view.ChunkDataHunkView(chunk, AIR, (data) -> data instanceof IrisCustomData d ? d.getBase() : data);
this.view = new art.arcane.volmlib.util.hunk.view.ChunkDataHunkView(chunk, BukkitBlockResolution.getAir(), (data) -> data instanceof IrisCustomData d ? d.getBase() : data);
}
@Override
@@ -28,7 +28,7 @@ import art.arcane.iris.util.project.matter.slices.TileMatter;
import art.arcane.volmlib.util.matter.IrisMatter;
import art.arcane.volmlib.util.matter.Matter;
import org.bukkit.block.data.BlockData;
import org.bukkit.util.BlockVector;
import art.arcane.iris.util.common.math.IrisBlockVector;
import java.io.File;
@@ -54,16 +54,16 @@ public final class IrisMatterSupport {
ensureRegistered();
object.clean();
object.shrinkwrap();
BlockVector min = new BlockVector();
IrisBlockVector min = new IrisBlockVector();
Matter matter = new IrisMatter(Math.max(object.getW(), 1) + 1, Math.max(object.getH(), 1) + 1, Math.max(object.getD(), 1) + 1);
for (BlockVector i : object.getBlocks().keys()) {
for (IrisBlockVector i : object.getBlocks().keys()) {
min.setX(Math.min(min.getX(), i.getX()));
min.setY(Math.min(min.getY(), i.getY()));
min.setZ(Math.min(min.getZ(), i.getZ()));
}
for (BlockVector i : object.getBlocks().keys()) {
for (IrisBlockVector i : object.getBlocks().keys()) {
matter.slice(BlockData.class).set(i.getBlockX() - min.getBlockX(), i.getBlockY() - min.getBlockY(), i.getBlockZ() - min.getBlockZ(), (BlockData) object.getBlocks().get(i).nativeHandle());
}
@@ -12,11 +12,17 @@ import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class ServerID {
public static final String ID = calculate();
private static final class Holder {
private static final String ID = calculate();
}
public static String getId() {
return Holder.ID;
}
public static User asUser() {
User u = new User();
u.setId(ID);
u.setId(Holder.ID);
return u;
}
@@ -1,6 +1,6 @@
package art.arcane.iris.engine.object;
import org.bukkit.util.BlockVector;
import art.arcane.iris.util.common.math.IrisBlockVector;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
@@ -28,8 +28,8 @@ public class IrisObjectRotationFlipTest {
@Test
public void xFlip180WithY_zeroYaw_stillUsesFixedYRotation() {
IrisObjectRotation rot = IrisObjectRotation.xFlip180WithY(0);
BlockVector v = new BlockVector(1, 2, 3);
BlockVector result = rot.rotate(v, 117, 253, 91);
IrisBlockVector v = new IrisBlockVector(1, 2, 3);
IrisBlockVector result = rot.rotate(v, 117, 253, 91);
assertTrue(rot.canRotateY());
assertEquals(1, result.getBlockX());
assertEquals(-2, result.getBlockY());
@@ -39,8 +39,8 @@ public class IrisObjectRotationFlipTest {
@Test
public void xFlip180WithY_ninetyYaw_rotatesMirroredFootprint() {
IrisObjectRotation rot = IrisObjectRotation.xFlip180WithY(90);
BlockVector v = new BlockVector(2, 5, 3);
BlockVector result = rot.rotate(v, 0, 0, 0);
IrisBlockVector v = new IrisBlockVector(2, 5, 3);
IrisBlockVector result = rot.rotate(v, 0, 0, 0);
assertEquals(-3, result.getBlockX());
assertEquals(-5, result.getBlockY());
assertEquals(-2, result.getBlockZ());
@@ -49,8 +49,8 @@ public class IrisObjectRotationFlipTest {
@Test
public void xFlip180_rotateVector_negatesYandZ() {
IrisObjectRotation rot = IrisObjectRotation.xFlip180();
BlockVector v = new BlockVector(1, 2, 3);
BlockVector result = rot.rotate(v, 0, 0, 0);
IrisBlockVector v = new IrisBlockVector(1, 2, 3);
IrisBlockVector result = rot.rotate(v, 0, 0, 0);
assertEquals(1, result.getBlockX());
assertEquals(-2, result.getBlockY());
assertEquals(-3, result.getBlockZ());
@@ -59,8 +59,8 @@ public class IrisObjectRotationFlipTest {
@Test
public void xFlip180_rotateNegativeVector_negatesYandZ() {
IrisObjectRotation rot = IrisObjectRotation.xFlip180();
BlockVector v = new BlockVector(-3, -5, -7);
BlockVector result = rot.rotate(v, 0, 0, 0);
IrisBlockVector v = new IrisBlockVector(-3, -5, -7);
IrisBlockVector result = rot.rotate(v, 0, 0, 0);
assertEquals(-3, result.getBlockX());
assertEquals(5, result.getBlockY());
assertEquals(7, result.getBlockZ());
@@ -172,7 +172,7 @@ public class ChunkContextPrefillPlanTest {
return thread;
});
try {
Future<Boolean> future = executor.submit(() -> ChunkContext.shouldPrefillAsync(2));
Future<Boolean> future = executor.submit(() -> ChunkContext.prefillAsyncEligible(Thread.currentThread().getName()));
boolean actual = future.get(10, TimeUnit.SECONDS);
if (expected) {
assertTrue(actual);
+37
View File
@@ -0,0 +1,37 @@
plugins {
id 'application'
}
group = 'art.arcane'
version = rootProject.version
application {
mainClass = 'art.arcane.iris.probe.ClassloadProbe'
}
dependencies {
implementation(project(':core'))
runtimeOnly(libs.paralithic)
runtimeOnly(libs.gson)
runtimeOnly(libs.lru)
runtimeOnly(libs.kotlin.coroutines)
runtimeOnly(libs.commons.io)
runtimeOnly(libs.commons.lang)
runtimeOnly(libs.commons.lang3)
runtimeOnly(libs.commons.math3)
runtimeOnly(libs.fastutil)
runtimeOnly(libs.caffeine)
runtimeOnly(libs.lz4)
runtimeOnly(libs.zip)
runtimeOnly('com.google.guava:guava:33.4.0-jre')
runtimeOnly(libs.sentry)
runtimeOnly(libs.oshi)
runtimeOnly(libs.byteBuddy.core)
runtimeOnly(libs.byteBuddy.agent)
}
tasks.named('run', JavaExec).configure {
args(project(':core').layout.buildDirectory.dir('classes/java/main').get().asFile.absolutePath)
jvmArgs('--add-modules', 'jdk.incubator.vector')
dependsOn(':core:compileJava')
}
@@ -0,0 +1,137 @@
/*
* Iris is a World Generator for Minecraft Servers
* Copyright (c) 2026 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 <https://www.gnu.org/licenses/>.
*/
package art.arcane.iris.probe;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.TreeMap;
import java.util.stream.Stream;
public final class ClassloadProbe {
private static final String[] CRITICAL_PREFIXES = {
"art.arcane.iris.engine.",
"art.arcane.iris.util.",
"art.arcane.iris.core.loader.",
"art.arcane.iris.spi.",
};
private static final String[] EXEMPT_PREFIXES = {
"art.arcane.iris.platform.bukkit.",
"art.arcane.iris.engine.platform.",
"art.arcane.iris.util.common.plugin.",
"art.arcane.iris.util.common.inventorygui.",
"art.arcane.iris.util.common.director.",
"art.arcane.iris.util.common.data.registry.",
};
private static final String[] EXEMPT_CLASSES = {
"art.arcane.iris.util.common.misc.Bindings",
"art.arcane.iris.util.common.misc.SlimJar",
"art.arcane.iris.util.common.misc.ServerProperties",
};
public static void main(String[] args) throws IOException {
art.arcane.iris.spi.IrisPlatforms.bind(new StubPlatform());
boolean bukkitPresent = true;
try {
Class.forName("org.bukkit.Bukkit", false, ClassloadProbe.class.getClassLoader());
} catch (ClassNotFoundException absent) {
bukkitPresent = false;
}
System.out.println("[probe] org.bukkit on classpath: " + bukkitPresent);
Path classesRoot = Path.of(args[0]);
List<String> names = new ArrayList<>();
try (Stream<Path> walk = Files.walk(classesRoot)) {
walk.filter(p -> p.toString().endsWith(".class"))
.forEach(p -> {
String rel = classesRoot.relativize(p).toString();
String name = rel.substring(0, rel.length() - 6).replace('/', '.');
if (name.contains("$")) {
return;
}
names.add(name);
});
}
names.sort(String::compareTo);
TreeMap<String, String> criticalFailures = new TreeMap<>();
TreeMap<String, String> otherFailures = new TreeMap<>();
int loaded = 0;
int criticalTotal = 0;
for (String name : names) {
boolean critical = matchesAny(name, CRITICAL_PREFIXES) && !matchesAny(name, EXEMPT_PREFIXES) && !exactAny(name);
if (critical) {
criticalTotal++;
}
try {
Class.forName(name, true, ClassloadProbe.class.getClassLoader());
loaded++;
} catch (Throwable failure) {
String cause = rootCause(failure);
if (critical) {
criticalFailures.put(name, cause);
} else {
otherFailures.put(name, cause);
}
}
}
System.out.println("[probe] classes scanned: " + names.size() + ", initialized OK: " + loaded);
System.out.println("[probe] critical set: " + criticalTotal + ", critical failures: " + criticalFailures.size());
criticalFailures.forEach((name, cause) -> System.out.println(" CRITICAL " + name + " -> " + cause));
System.out.println("[probe] non-critical failures: " + otherFailures.size());
otherFailures.forEach((name, cause) -> System.out.println(" other " + name + " -> " + cause));
if (!criticalFailures.isEmpty()) {
System.out.println("[probe] RESULT: FAIL");
System.exit(1);
}
System.out.println("[probe] RESULT: PASS");
}
private static boolean exactAny(String name) {
for (String exempt : EXEMPT_CLASSES) {
if (name.equals(exempt)) {
return true;
}
}
return false;
}
private static boolean matchesAny(String name, String[] prefixes) {
for (String prefix : prefixes) {
if (name.startsWith(prefix)) {
return true;
}
}
return false;
}
private static String rootCause(Throwable failure) {
Throwable cause = failure;
while (cause.getCause() != null && cause.getCause() != cause) {
cause = cause.getCause();
}
return cause.getClass().getSimpleName() + ": " + cause.getMessage();
}
}
@@ -0,0 +1,300 @@
/*
* Iris is a World Generator for Minecraft Servers
* Copyright (c) 2026 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 <https://www.gnu.org/licenses/>.
*/
package art.arcane.iris.probe;
import art.arcane.iris.spi.IrisPlatform;
import art.arcane.iris.spi.LogLevel;
import art.arcane.iris.spi.PlatformBiome;
import art.arcane.iris.spi.PlatformBiomeWriter;
import art.arcane.iris.spi.PlatformBlockState;
import art.arcane.iris.spi.PlatformCapabilities;
import art.arcane.iris.spi.PlatformEntityType;
import art.arcane.iris.spi.PlatformItem;
import art.arcane.iris.spi.PlatformRegistries;
import art.arcane.iris.spi.PlatformScheduler;
import art.arcane.iris.spi.PlatformStructureHooks;
import java.io.File;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
public final class StubPlatform implements IrisPlatform {
private final StubRegistries registries = new StubRegistries();
private static final class StubBlockState implements PlatformBlockState {
private static final ConcurrentHashMap<String, StubBlockState> CACHE = new ConcurrentHashMap<>();
private final String key;
private StubBlockState(String key) {
this.key = key;
}
static StubBlockState of(String key) {
return CACHE.computeIfAbsent(key, StubBlockState::new);
}
@Override
public String key() {
return key;
}
@Override
public String namespace() {
int colon = key.indexOf(':');
return colon >= 0 ? key.substring(0, colon) : "minecraft";
}
@Override
public boolean isAir() {
return key.endsWith("air");
}
@Override
public boolean isSolid() {
return !isAir();
}
@Override
public boolean isFluid() {
return false;
}
@Override
public boolean isWater() {
return false;
}
@Override
public boolean isWaterLogged() {
return false;
}
@Override
public boolean isLit() {
return false;
}
@Override
public boolean isUpdatable() {
return false;
}
@Override
public boolean isFoliage() {
return false;
}
@Override
public boolean isFoliagePlantable() {
return false;
}
@Override
public boolean isDecorant() {
return false;
}
@Override
public boolean isStorage() {
return false;
}
@Override
public boolean isStorageChest() {
return false;
}
@Override
public boolean isOre() {
return false;
}
@Override
public boolean isDeepSlate() {
return false;
}
@Override
public boolean isVineBlock() {
return false;
}
@Override
public boolean canPlaceOnto(PlatformBlockState onto) {
return true;
}
@Override
public boolean matches(PlatformBlockState state) {
return equals(state);
}
@Override
public boolean hasTileEntity() {
return false;
}
@Override
public PlatformBlockState withProperty(String name, String value) {
return this;
}
@Override
public Object nativeHandle() {
return key;
}
}
private static final class StubRegistries implements PlatformRegistries {
@Override
public PlatformBlockState block(String key) {
return StubBlockState.of(key);
}
@Override
public PlatformBlockState blockOrNull(String key) {
return StubBlockState.of(key);
}
@Override
public PlatformBlockState blockOrNull(String key, boolean warn) {
return StubBlockState.of(key);
}
@Override
public PlatformBlockState air() {
return StubBlockState.of("minecraft:air");
}
@Override
public PlatformBlockState deepSlateOre(PlatformBlockState block, PlatformBlockState ore) {
return ore;
}
@Override
public PlatformBiome biome(String key) {
return null;
}
@Override
public PlatformItem item(String key) {
return null;
}
@Override
public PlatformEntityType entity(String key) {
return null;
}
@Override
public List<String> blockKeys() {
return List.of();
}
@Override
public List<String> biomeKeys() {
return List.of();
}
@Override
public List<String> structureKeys() {
return List.of();
}
}
@Override
public String platformName() {
return "probe";
}
@Override
public String minecraftVersion() {
return "probe";
}
@Override
public PlatformRegistries registries() {
return registries;
}
@Override
public PlatformScheduler scheduler() {
return null;
}
@Override
public PlatformCapabilities capabilities() {
return null;
}
@Override
public PlatformStructureHooks structureHooks() {
return null;
}
@Override
public PlatformBiomeWriter biomeWriter() {
return null;
}
@Override
public File dataFolder() {
return new File(System.getProperty("java.io.tmpdir"), "iris-probe");
}
@Override
public File dataFile(String... path) {
return new File(dataFolder(), String.join(File.separator, path));
}
@Override
public File pluginJar() {
return new File(dataFolder(), "probe.jar");
}
@Override
public int irisVersionNumber() {
return 0;
}
@Override
public int minecraftVersionNumber() {
return 0;
}
@Override
public void callEvent(Object event) {
}
@Override
public void dispatchConsoleCommand(String command) {
}
@Override
public void log(LogLevel level, String message) {
}
@Override
public void msg(String message) {
}
@Override
public void reportError(Throwable error) {
}
}
+1
View File
@@ -69,6 +69,7 @@ if (useLocalVolmLib && localVolmLibDirectory != null) {
}
include(':core', ':core:agent')
include(':probe')
include(':spi')
include(':adapters:bukkit:plugin')
include(':adapters:bukkit:nms:v1_21_R7')