Engine Slimming

This commit is contained in:
Brian Neumann-Fopiano
2026-06-11 15:09:57 -04:00
parent 3063801a3a
commit c9929e0880
28 changed files with 226 additions and 268 deletions
-11
View File
@@ -107,20 +107,12 @@ art/arcane/iris/engine/decorator/IrisCeilingDecorator.java
art/arcane/iris/engine/framework/BlockUpdater.java
art/arcane/iris/engine/framework/Engine.java
art/arcane/iris/engine/framework/EngineAssignedWorldManager.java
art/arcane/iris/engine/framework/EngineComponent.java
art/arcane/iris/engine/framework/EngineDecorator.java
art/arcane/iris/engine/framework/EngineMode.java
art/arcane/iris/engine/framework/EnginePlayer.java
art/arcane/iris/engine/framework/EngineWorldManager.java
art/arcane/iris/engine/framework/Locator.java
art/arcane/iris/engine/framework/LootProvider.java
art/arcane/iris/engine/framework/placer/WorldObjectPlacer.java
art/arcane/iris/engine/framework/PregeneratedData.java
art/arcane/iris/engine/framework/StructureAssembler.java
art/arcane/iris/engine/IrisComplex.java
art/arcane/iris/engine/IrisEngine.java
art/arcane/iris/engine/IrisEngineEffects.java
art/arcane/iris/engine/IrisEngineMantle.java
art/arcane/iris/engine/IrisWorldManager.java
art/arcane/iris/engine/mantle/components/MantleFloatingObjectComponent.java
art/arcane/iris/engine/mantle/components/MantleObjectComponent.java
@@ -169,10 +161,8 @@ art/arcane/iris/engine/object/IrisObjectLoot.java
art/arcane/iris/engine/object/IrisObjectPlacement.java
art/arcane/iris/engine/object/IrisObjectRotation.java
art/arcane/iris/engine/object/IrisObjectTranslate.java
art/arcane/iris/engine/object/IrisPosition.java
art/arcane/iris/engine/object/IrisPotionEffect.java
art/arcane/iris/engine/object/IrisProceduralBlocks.java
art/arcane/iris/engine/object/IrisSpawner.java
art/arcane/iris/engine/object/IrisSurface.java
art/arcane/iris/engine/object/IrisTree.java
art/arcane/iris/engine/object/IrisVanillaLootTable.java
@@ -191,7 +181,6 @@ art/arcane/iris/engine/object/tree/TreePlausibility.java
art/arcane/iris/engine/platform/BukkitChunkGenerator.java
art/arcane/iris/engine/platform/DummyBiomeProvider.java
art/arcane/iris/engine/platform/DummyChunkGenerator.java
art/arcane/iris/engine/platform/PlatformChunkGenerator.java
art/arcane/iris/engine/platform/studio/generators/BiomeBuffetGenerator.java
art/arcane/iris/engine/platform/studio/generators/ObjectStudioGenerator.java
art/arcane/iris/Iris.java
@@ -18,6 +18,7 @@
package art.arcane.iris.core.commands;
import art.arcane.iris.platform.bukkit.BukkitPlatform;
import art.arcane.iris.Iris;
import art.arcane.iris.core.edit.BlockSignal;
import art.arcane.iris.core.nms.INMS;
@@ -159,7 +160,7 @@ public class CommandWhat implements DirectorExecutor {
for (int xxx = c.getX() - 4; xxx <= c.getX() + 4; xxx++) {
for (int zzz = c.getZ() - 4; zzz <= c.getZ() + 4; zzz++) {
IrisToolbelt.access(c.getWorld()).getEngine().getMantle().findMarkers(xxx, zzz, new MatterMarker(marker))
.convert((i) -> i.toLocation(c.getWorld())).forEach((i) -> {
.convert((i) -> BukkitPlatform.toLocation(i, c.getWorld())).forEach((i) -> {
BlockSignal.of(i.getWorld(), i.getBlockX(), i.getBlockY(), i.getBlockZ(), 100);
v.incrementAndGet();
});
@@ -7,6 +7,7 @@ import art.arcane.iris.core.lifecycle.ServerFamily;
import art.arcane.iris.core.lifecycle.WorldLifecycleService;
import art.arcane.iris.core.service.BoardSVC;
import art.arcane.iris.core.tools.IrisToolbelt;
import art.arcane.iris.engine.platform.BukkitChunkGenerator;
import art.arcane.iris.engine.platform.PlatformChunkGenerator;
import art.arcane.iris.util.common.format.C;
import art.arcane.iris.util.common.scheduling.J;
@@ -202,8 +203,8 @@ public final class WorldRuntimeControlService {
return null;
}
if (provider != null && provider.isStudio()) {
Location initialSpawn = provider.getInitialSpawnLocation(world);
if (provider != null && provider.isStudio() && provider instanceof BukkitChunkGenerator bukkitProvider) {
Location initialSpawn = bukkitProvider.getInitialSpawnLocation(world);
if (initialSpawn != null) {
return initialSpawn.clone();
}
@@ -31,6 +31,7 @@ import art.arcane.iris.core.pregenerator.methods.HybridPregenMethod;
import art.arcane.iris.core.service.StudioSVC;
import art.arcane.iris.engine.framework.Engine;
import art.arcane.iris.engine.object.IrisDimension;
import art.arcane.iris.engine.platform.BukkitChunkGenerator;
import art.arcane.iris.engine.platform.PlatformChunkGenerator;
import art.arcane.iris.util.common.scheduling.J;
import art.arcane.iris.util.common.plugin.VolmitSender;
@@ -170,7 +171,9 @@ public class IrisToolbelt {
}
if (world.getGenerator() instanceof PlatformChunkGenerator f) {
f.touch(world);
if (f instanceof BukkitChunkGenerator bukkit) {
bukkit.touch(world);
}
return true;
}
@@ -204,7 +207,9 @@ public class IrisToolbelt {
if (activeProvider != null) {
World activeWorld = activeProvider.getTarget().getWorld().realWorld();
if (activeWorld != null && activeWorld.getName().equals(world.getName())) {
activeProvider.touch(world);
if (activeProvider instanceof BukkitChunkGenerator bukkit) {
bukkit.touch(world);
}
return activeProvider;
}
}
@@ -38,7 +38,8 @@ import art.arcane.iris.engine.data.cache.AtomicCache;
import art.arcane.iris.engine.framework.*;
import art.arcane.iris.engine.mantle.EngineMantle;
import art.arcane.iris.engine.object.*;
import art.arcane.iris.platform.bukkit.BukkitBlockState;
import art.arcane.iris.util.common.data.B;
import art.arcane.iris.util.common.plugin.VolmitSender;
import art.arcane.iris.spi.PlatformBiome;
import art.arcane.iris.spi.PlatformBlockState;
import art.arcane.volmlib.util.atomics.AtomicRollingSequence;
@@ -60,9 +61,6 @@ import art.arcane.volmlib.util.scheduling.PrecisionStopwatch;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import java.io.File;
import java.io.IOException;
@@ -515,7 +513,7 @@ public class IrisEngine implements Engine {
return buds.get();
}
public void printMetrics(CommandSender sender) {
public void printMetrics(VolmitSender sender) {
KMap<String, Double> totals = new KMap<>();
KMap<String, Double> weights = new KMap<>();
double masterWallClock = wallClock.getAverage();
@@ -665,9 +663,10 @@ public class IrisEngine implements Engine {
Hunk<PlatformBlockState> blocks = vblocks.listen((xx, y, zz, t) -> catchBlockUpdates(x + xx, y, z + zz, t));
if (getDimension().isDebugChunkCrossSections() && ((x >> 4) % getDimension().getDebugCrossSectionsMod() == 0 || (z >> 4) % getDimension().getDebugCrossSectionsMod() == 0)) {
PlatformBlockState crossSection = B.getState("CRYING_OBSIDIAN");
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
blocks.set(i, 0, j, BukkitBlockState.of(Material.CRYING_OBSIDIAN.createBlockData()));
blocks.set(i, 0, j, crossSection);
}
}
} else {
@@ -675,8 +674,7 @@ public class IrisEngine implements Engine {
activeMode.generate(x, z, blocks, vbiomes, multicore);
}
World realWorld = getWorld().realWorld();
boolean skipRealFlag = J.isFolia() && realWorld != null && IrisToolbelt.isWorldMaintenanceBypassingMantleStages(realWorld);
boolean skipRealFlag = J.isFolia() && getWorld().hasRealWorld() && IrisToolbelt.isWorldMaintenanceBypassingMantleStages(getWorld().realWorld());
if (!skipRealFlag) {
getMantle().getMantle().flag(x >> 4, z >> 4, MantleFlag.REAL, true);
}
@@ -49,12 +49,10 @@ import art.arcane.iris.util.common.format.C;
import art.arcane.volmlib.util.matter.IrisMatter;
import art.arcane.volmlib.util.matter.Matter;
import art.arcane.volmlib.util.matter.MatterSlice;
import art.arcane.iris.platform.bukkit.BukkitPlatform;
import art.arcane.iris.util.common.parallel.HyperLock;
import art.arcane.iris.util.common.parallel.MultiBurst;
import lombok.*;
import org.bukkit.World;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Entity;
import java.io.File;
import java.io.IOException;
@@ -230,19 +228,7 @@ public class IrisEngineMantle implements EngineMantle {
@Override
public Class<?> classifyValue(Object value) {
if (value instanceof World) {
return World.class;
}
if (value instanceof BlockData) {
return BlockData.class;
}
if (value instanceof Entity) {
return Entity.class;
}
return value.getClass();
return BukkitPlatform.classifyMantleValue(value);
}
@Override
@@ -56,6 +56,7 @@ import art.arcane.iris.util.project.hunk.Hunk;
import art.arcane.volmlib.util.mantle.runtime.MantleChunk;
import art.arcane.volmlib.util.mantle.flag.MantleFlag;
import art.arcane.volmlib.util.math.BlockPosition;
import art.arcane.volmlib.util.format.Form;
import art.arcane.volmlib.util.math.M;
import art.arcane.volmlib.util.math.Position2;
import art.arcane.volmlib.util.math.RNG;
@@ -64,10 +65,12 @@ import art.arcane.volmlib.util.matter.MatterCavern;
import art.arcane.volmlib.util.matter.MatterUpdate;
import art.arcane.iris.util.common.parallel.BurstExecutor;
import art.arcane.iris.util.common.parallel.MultiBurst;
import art.arcane.iris.util.common.plugin.VolmitSender;
import art.arcane.iris.util.common.reflect.KeyedType;
import art.arcane.iris.util.common.reflect.W;
import art.arcane.volmlib.util.scheduling.ChronoLatch;
import art.arcane.iris.util.common.scheduling.J;
import art.arcane.iris.util.common.scheduling.jobs.SingleJob;
import art.arcane.volmlib.util.scheduling.PrecisionStopwatch;
import art.arcane.iris.util.project.stream.ProceduralStream;
import io.papermc.lib.PaperLib;
@@ -75,7 +78,6 @@ import org.bukkit.*;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.BlockData;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
@@ -86,7 +88,9 @@ import java.awt.Color;
import java.util.Locale;
import java.util.Set;
import java.util.UUID;
import java.lang.reflect.Method;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
@@ -106,7 +110,7 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
int getBlockUpdatesPerSecond();
void printMetrics(CommandSender sender);
void printMetrics(VolmitSender sender);
EngineMantle getMantle();
@@ -980,11 +984,100 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
}
default void gotoBiome(IrisBiome biome, Player player, boolean teleport) {
Locator.surfaceBiome(biome.getLoadKey()).find(player, teleport, "Biome " + biome.getName());
find(Locator.surfaceBiome(biome.getLoadKey()), player, teleport, "Biome " + biome.getName());
}
private static void find(Locator<?> locator, Player player, boolean teleport, String message) {
find(locator, player, 120_000, location -> {
if (location == null) {
player.sendMessage(C.RED + "Could not find " + message + " within search range.");
return;
}
if (teleport) {
J.runEntity(player, () -> teleportAsyncSafely(player, location));
player.sendMessage(C.GREEN + "Teleporting to " + message + "...");
} else {
player.sendMessage(C.GREEN + message + " at: " + location.getBlockX() + " " + location.getBlockY() + " " + location.getBlockZ());
}
});
}
private static void find(Locator<?> locator, Player player, long timeout, Consumer<Location> consumer) {
AtomicLong checks = new AtomicLong();
long ms = M.ms();
new SingleJob("Searching", () -> {
try {
World world = player.getWorld();
Engine engine = IrisToolbelt.access(world).getEngine();
Position2 at = locator.find(engine, new Position2(player.getLocation().getBlockX() >> 4, player.getLocation().getBlockZ() >> 4), timeout, checks::set).get();
if (at != null) {
int bx = (at.getX() << 4) + 8;
int bz = (at.getZ() << 4) + 8;
consumer.accept(new Location(world, bx,
world.getHighestBlockYAt(bx, bz) + 2,
bz));
} else {
consumer.accept(null);
}
} catch (WrongEngineBroException | InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}) {
@Override
public String getName() {
return "Searched " + Form.f(checks.get()) + " Chunks";
}
@Override
public int getTotalWork() {
return (int) timeout;
}
@Override
public int getWorkCompleted() {
return (int) Math.min(M.ms() - ms, timeout - 1);
}
}.execute(new VolmitSender(player));
}
private static void teleportAsyncSafely(Player player, Location location) {
if (player == null || location == null) {
return;
}
if (invokeNativeTeleportAsync(player, location)) {
return;
}
try {
CompletableFuture<Boolean> teleportFuture = PaperLib.teleportAsync(player, location);
if (teleportFuture != null) {
teleportFuture.exceptionally(throwable -> {
Iris.reportError(throwable);
return false;
});
}
} catch (Throwable throwable) {
Iris.reportError(throwable);
}
}
private static boolean invokeNativeTeleportAsync(Player player, Location location) {
try {
Method teleportAsyncMethod = player.getClass().getMethod("teleportAsync", Location.class);
teleportAsyncMethod.invoke(player, location);
return true;
} catch (NoSuchMethodException ignored) {
return false;
} catch (Throwable throwable) {
Iris.reportError(throwable);
return false;
}
}
default void gotoObject(String s, Player player, boolean teleport) {
Locator.object(s).find(player, teleport, "Object " + s);
find(Locator.object(s), player, teleport, "Object " + s);
}
default boolean hasObjectPlacement(String objectKey) {
@@ -1011,15 +1104,15 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
return;
}
Locator.region(r.getLoadKey()).find(player, teleport, "Region " + r.getName());
find(Locator.region(r.getLoadKey()), player, teleport, "Region " + r.getName());
}
default void gotoPOI(String type, Player p, boolean teleport) {
Locator.poi(type).find(p, teleport, "POI " + type);
find(Locator.poi(type), p, teleport, "POI " + type);
}
default void gotoStructure(String key, Player player, boolean teleport) {
Locator.structure(key).find(player, teleport, "Structure " + key);
find(Locator.structure(key), player, teleport, "Structure " + key);
}
private static boolean containsObjectPlacement(KList<IrisObjectPlacement> placements, String normalizedObjectKey) {
@@ -22,9 +22,9 @@ import art.arcane.iris.Iris;
import art.arcane.iris.core.loader.IrisData;
import art.arcane.iris.engine.IrisComplex;
import art.arcane.iris.engine.object.IrisDimension;
import art.arcane.iris.platform.bukkit.BukkitPlatform;
import art.arcane.volmlib.util.math.RollingSequence;
import art.arcane.iris.util.common.parallel.MultiBurst;
import org.bukkit.event.Listener;
public interface EngineComponent {
Engine getEngine();
@@ -39,9 +39,7 @@ public interface EngineComponent {
default void close() {
try {
if (this instanceof Listener) {
Iris.instance.unregisterListener((Listener) this);
}
BukkitPlatform.unregisterListener(this);
} catch (Throwable e) {
Iris.reportError(e);
@@ -23,7 +23,6 @@ import art.arcane.iris.spi.PlatformBlockState;
import art.arcane.iris.util.common.data.B;
import art.arcane.volmlib.util.documentation.BlockCoordinates;
import art.arcane.iris.util.project.hunk.Hunk;
import org.bukkit.block.data.BlockData;
public interface EngineDecorator extends EngineComponent {
@@ -41,6 +40,6 @@ public interface EngineDecorator extends EngineComponent {
return false;
}
return B.canPlaceOnto(((BlockData) decorant.nativeHandle()).getMaterial(), ((BlockData) atop.nativeHandle()).getMaterial());
return B.canPlaceOnto(decorant, atop);
}
}
@@ -74,11 +74,8 @@ public interface EngineMode extends Staged {
default void generate(int x, int z, Hunk<PlatformBlockState> blocks, Hunk<PlatformBiome> biomes, boolean multicore) {
IrisContext context = IrisContext.getOr(getEngine());
boolean cacheContext = true;
if (J.isFolia()) {
org.bukkit.World world = getEngine().getWorld().realWorld();
if (world != null && shouldDisableContextCacheForMaintenance(world)) {
cacheContext = false;
}
if (J.isFolia() && getEngine().getWorld().hasRealWorld() && shouldDisableContextCacheForMaintenance()) {
cacheContext = false;
}
ChunkContext.PrefillPlan prefillPlan = cacheContext ? ChunkContext.PrefillPlan.NO_CAVE : ChunkContext.PrefillPlan.NONE;
ChunkContext ctx = new ChunkContext(x, z, getComplex(), context.getGenerationSessionId(), cacheContext, prefillPlan, getEngine().getMetrics());
@@ -94,14 +91,14 @@ public interface EngineMode extends Staged {
return maintenanceActive && !pregeneratorTargetsWorld;
}
private boolean shouldDisableContextCacheForMaintenance(org.bukkit.World world) {
boolean maintenanceActive = IrisToolbelt.isWorldMaintenanceActive(world);
private boolean shouldDisableContextCacheForMaintenance() {
boolean maintenanceActive = IrisToolbelt.isWorldMaintenanceActive(getEngine().getWorld().realWorld());
if (!maintenanceActive) {
return false;
}
PregeneratorJob pregeneratorJob = PregeneratorJob.getInstance();
boolean pregeneratorTargetsWorld = pregeneratorJob != null && pregeneratorJob.targetsWorld(world);
boolean pregeneratorTargetsWorld = pregeneratorJob != null && pregeneratorJob.targetsWorld(getEngine().getWorld().realWorld());
return shouldDisableContextCacheForMaintenance(maintenanceActive, pregeneratorTargetsWorld);
}
}
@@ -18,41 +18,25 @@
package art.arcane.iris.engine.framework;
import art.arcane.iris.Iris;
import art.arcane.iris.core.IrisSettings;
import art.arcane.iris.core.nms.container.BlockPos;
import art.arcane.iris.core.nms.container.Pair;
import art.arcane.iris.core.tools.IrisToolbelt;
import art.arcane.iris.engine.object.IrisBiome;
import art.arcane.iris.engine.object.IrisObject;
import art.arcane.iris.engine.object.IrisRegion;
import art.arcane.iris.util.project.context.IrisContext;
import art.arcane.iris.util.project.context.ChunkContext;
import art.arcane.iris.util.common.format.C;
import art.arcane.volmlib.util.format.Form;
import art.arcane.volmlib.util.math.M;
import art.arcane.volmlib.util.math.Position2;
import art.arcane.volmlib.util.math.Spiraler;
import art.arcane.volmlib.util.matter.MatterCavern;
import art.arcane.iris.util.common.parallel.BurstExecutor;
import art.arcane.iris.util.common.parallel.MultiBurst;
import art.arcane.iris.util.common.plugin.VolmitSender;
import art.arcane.iris.util.common.scheduling.J;
import art.arcane.volmlib.util.scheduling.PrecisionStopwatch;
import art.arcane.iris.util.common.scheduling.jobs.SingleJob;
import io.papermc.lib.PaperLib;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Player;
import java.lang.reflect.Method;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
@@ -117,64 +101,6 @@ public interface Locator<T> {
boolean matches(Engine engine, Position2 chunk);
default void find(Player player, boolean teleport, String message) {
find(player, 120_000, location -> {
if (location == null) {
player.sendMessage(C.RED + "Could not find " + message + " within search range.");
return;
}
if (teleport) {
J.runEntity(player, () -> teleportAsyncSafely(player, location));
player.sendMessage(C.GREEN + "Teleporting to " + message + "...");
} else {
player.sendMessage(C.GREEN + message + " at: " + location.getBlockX() + " " + location.getBlockY() + " " + location.getBlockZ());
}
});
}
default void find(Player player, Consumer<Location> consumer) {
find(player, 120_000, consumer);
}
default void find(Player player, long timeout, Consumer<Location> consumer) {
AtomicLong checks = new AtomicLong();
long ms = M.ms();
new SingleJob("Searching", () -> {
try {
World world = player.getWorld();
Engine engine = IrisToolbelt.access(world).getEngine();
Position2 at = find(engine, new Position2(player.getLocation().getBlockX() >> 4, player.getLocation().getBlockZ() >> 4), timeout, checks::set).get();
if (at != null) {
int bx = (at.getX() << 4) + 8;
int bz = (at.getZ() << 4) + 8;
consumer.accept(new Location(world, bx,
world.getHighestBlockYAt(bx, bz) + 2,
bz));
} else {
consumer.accept(null);
}
} catch (WrongEngineBroException | InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}) {
@Override
public String getName() {
return "Searched " + Form.f(checks.get()) + " Chunks";
}
@Override
public int getTotalWork() {
return (int) timeout;
}
@Override
public int getWorkCompleted() {
return (int) Math.min(M.ms() - ms, timeout - 1);
}
}.execute(new VolmitSender(player));
}
default Future<Position2> find(Engine engine, Position2 pos, long timeout, Consumer<Integer> checks) throws WrongEngineBroException {
if (engine.isClosed()) {
throw new WrongEngineBroException();
@@ -226,39 +152,4 @@ public interface Locator<T> {
return null;
});
}
static void teleportAsyncSafely(Player player, Location location) {
if (player == null || location == null) {
return;
}
if (invokeNativeTeleportAsync(player, location)) {
return;
}
try {
CompletableFuture<Boolean> teleportFuture = PaperLib.teleportAsync(player, location);
if (teleportFuture != null) {
teleportFuture.exceptionally(throwable -> {
Iris.reportError(throwable);
return false;
});
}
} catch (Throwable throwable) {
Iris.reportError(throwable);
}
}
static boolean invokeNativeTeleportAsync(Player player, Location location) {
try {
Method teleportAsyncMethod = player.getClass().getMethod("teleportAsync", Location.class);
teleportAsyncMethod.invoke(player, location);
return true;
} catch (NoSuchMethodException ignored) {
return false;
} catch (Throwable throwable) {
Iris.reportError(throwable);
return false;
}
}
}
@@ -24,7 +24,6 @@ import art.arcane.iris.spi.PlatformBlockState;
import art.arcane.iris.util.common.data.B;
import art.arcane.iris.util.project.hunk.Hunk;
import lombok.Data;
import org.bukkit.block.data.BlockData;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -56,7 +55,7 @@ public class PregeneratedData {
});
if (postMod.get()) {
return () -> Hunk.view(tc).insertSoftly(0, 0, 0, post, (b) -> b == null || B.isAirOrFluid((BlockData) b.nativeHandle()));
return () -> Hunk.view(tc).insertSoftly(0, 0, 0, post, (b) -> b == null || B.isAirOrFluid(b));
}
return () -> {
@@ -30,8 +30,8 @@ import art.arcane.iris.engine.object.IrisObjectRotation;
import art.arcane.iris.engine.object.IrisStructure;
import art.arcane.iris.engine.object.JigsawJoint;
import art.arcane.volmlib.util.collection.KList;
import art.arcane.iris.engine.object.IrisPosition;
import art.arcane.volmlib.util.math.RNG;
import org.bukkit.util.BlockVector;
import java.util.ArrayDeque;
import java.util.Deque;
@@ -126,23 +126,23 @@ public final class StructureAssembler {
IrisDirection needed = c.facing.reverse();
for (int yDeg : rotationCandidates(cb.getJoint(), rng)) {
IrisObjectRotation rot = IrisObjectRotation.of(0, yDeg, 0);
IrisDirection rotatedFace = rotateDirection(rot, cb.getDirection());
IrisDirection rotatedFace = rot.rotate(cb.getDirection());
if (rotatedFace != needed) {
continue;
}
BlockVector centerB = centerOf(object);
BlockVector crB = new BlockVector(
cb.getPosition().getX() - centerB.getBlockX(),
cb.getPosition().getY() - centerB.getBlockY(),
cb.getPosition().getZ() - centerB.getBlockZ());
BlockVector rcrB = rot.rotate(crB.clone(), 0, 0, 0);
IrisPosition center = centerOf(object);
IrisPosition cr = new IrisPosition(
cb.getPosition().getX() - center.getX(),
cb.getPosition().getY() - center.getY(),
cb.getPosition().getZ() - center.getZ());
IrisPosition rcr = rot.rotate(cr, 0, 0, 0);
int wcx = c.wx + c.facing.toVector().getBlockX();
int wcy = c.wy + c.facing.toVector().getBlockY();
int wcz = c.wz + c.facing.toVector().getBlockZ();
int px = wcx - rcrB.getBlockX();
int py = wcy - rcrB.getBlockY();
int pz = wcz - rcrB.getBlockZ();
int px = wcx - rcr.getX();
int py = wcy - rcr.getY();
int pz = wcz - rcr.getZ();
PlacedStructurePiece candidate = build(piece, object, px, py, pz, rot);
if (!withinRadius(candidate) || collides(placed, candidate)) {
@@ -158,30 +158,30 @@ public final class StructureAssembler {
}
private void enqueueConnectors(Deque<OpenConnector> open, PlacedStructurePiece p, IrisObject object, int depth, IrisJigsawConnector skip) {
BlockVector center = centerOf(object);
IrisPosition center = centerOf(object);
for (IrisJigsawConnector con : p.getPiece().getConnectors()) {
if (con == skip) {
continue;
}
BlockVector cr = new BlockVector(
con.getPosition().getX() - center.getBlockX(),
con.getPosition().getY() - center.getBlockY(),
con.getPosition().getZ() - center.getBlockZ());
BlockVector rcr = p.getRotation().rotate(cr.clone(), 0, 0, 0);
IrisDirection facing = rotateDirection(p.getRotation(), con.getDirection());
IrisPosition cr = new IrisPosition(
con.getPosition().getX() - center.getX(),
con.getPosition().getY() - center.getY(),
con.getPosition().getZ() - center.getZ());
IrisPosition rcr = p.getRotation().rotate(cr, 0, 0, 0);
IrisDirection facing = p.getRotation().rotate(con.getDirection());
open.add(new OpenConnector(
p.getX() + rcr.getBlockX(),
p.getY() + rcr.getBlockY(),
p.getZ() + rcr.getBlockZ(),
p.getX() + rcr.getX(),
p.getY() + rcr.getY(),
p.getZ() + rcr.getZ(),
facing, con.getPool(), con.getName(), con.getTargetName(), con.getJoint(), depth));
}
}
private PlacedStructurePiece build(IrisJigsawPiece piece, IrisObject object, int x, int y, int z, IrisObjectRotation rot) {
BlockVector rotated = rot.rotate(new BlockVector(object.getW(), object.getH(), object.getD()), 0, 0, 0);
int rw = Math.abs(rotated.getBlockX());
int rh = Math.abs(rotated.getBlockY());
int rd = Math.abs(rotated.getBlockZ());
IrisPosition rotated = rot.rotate(new IrisPosition(object.getW(), object.getH(), object.getD()), 0, 0, 0);
int rw = Math.abs(rotated.getX());
int rh = Math.abs(rotated.getY());
int rd = Math.abs(rotated.getZ());
int hx = rw / 2;
int hy = rh / 2;
int hz = rd / 2;
@@ -217,14 +217,8 @@ public final class StructureAssembler {
return shuffled;
}
private IrisDirection rotateDirection(IrisObjectRotation rot, IrisDirection direction) {
BlockVector v = direction.toVector().toBlockVector();
BlockVector r = rot.rotate(v.clone(), 0, 0, 0);
return IrisDirection.getDirection(r);
}
private BlockVector centerOf(IrisObject object) {
return new BlockVector(object.getW() / 2, object.getH() / 2, object.getD() / 2);
private IrisPosition centerOf(IrisObject object) {
return new IrisPosition(object.getW() / 2, object.getH() / 2, object.getD() / 2);
}
private IrisJigsawPiece pickPiece(IrisJigsawPool pool, RNG rng) {
@@ -47,7 +47,6 @@ import art.arcane.iris.util.common.parallel.MultiBurst;
import art.arcane.iris.util.common.scheduling.J;
import art.arcane.iris.platform.bukkit.BukkitBlockState;
import art.arcane.iris.spi.PlatformBlockState;
import org.bukkit.World;
import org.bukkit.block.data.BlockData;
import org.jetbrains.annotations.UnmodifiableView;
@@ -86,11 +85,8 @@ public interface EngineMantle extends MatterGenerator {
@ChunkCoordinates
default KList<IrisPosition> findMarkers(int x, int z, MatterMarker marker) {
KList<IrisPosition> p = new KList<>();
if (J.isFolia()) {
World world = getEngine().getWorld().realWorld();
if (world != null && J.isOwnedByCurrentRegion(world, x, z)) {
return p;
}
if (J.isFolia() && getEngine().getWorld().hasRealWorld() && J.isOwnedByCurrentRegion(getEngine().getWorld().realWorld(), x, z)) {
return p;
}
getMantle().iterateChunk(x, z, MatterMarker.class, (xx, yy, zz, mm) -> {
@@ -1,5 +1,6 @@
package art.arcane.iris.engine.object;
import art.arcane.iris.platform.bukkit.BukkitPlatform;
import art.arcane.iris.engine.framework.Engine;
import org.bukkit.block.data.BlockData;
import art.arcane.iris.engine.object.annotations.*;
@@ -45,7 +46,7 @@ public class IrisCaveShape {
var rotated = new KSet<IrisPosition>();
engine.getData().getObjectLoader().load(object).getBlocks().forEach((vector, data) -> {
if (((BlockData) data.nativeHandle()).getMaterial().isAir()) return;
rotated.add(new IrisPosition(objectRotation.rotate(vector, pos.getX(), pos.getY(), pos.getZ())));
rotated.add(BukkitPlatform.positionOf(objectRotation.rotate(vector, pos.getX(), pos.getY(), pos.getZ())));
});
return rotated;
});
@@ -18,6 +18,7 @@
package art.arcane.iris.engine.object;
import art.arcane.iris.platform.bukkit.BukkitPlatform;
import art.arcane.iris.Iris;
import art.arcane.iris.core.nms.INMS;
import art.arcane.iris.engine.data.cache.AtomicCache;
@@ -82,7 +83,7 @@ public class IrisEntitySpawn implements IRare {
yield new Location(c.getWorld(), x, h + 1, z);
}
yield gen.getMantle().findMarkers(c.getX(), c.getZ(), MarkerMatter.CAVE_FLOOR)
.convert((i) -> i.toLocation(c.getWorld()).add(0, 1, 0)).getRandom(rng);
.convert((i) -> BukkitPlatform.toLocation(i, c.getWorld()).add(0, 1, 0)).getRandom(rng);
}
case UNDERWATER, BEACH -> new Location(c.getWorld(), x, rng.i(h + 1, hf), z);
};
@@ -126,7 +127,7 @@ public class IrisEntitySpawn implements IRare {
}
for (int id = 0; id < spawns; id++) {
Location l = c.toLocation(world).add(0, 1, 0);
Location l = BukkitPlatform.toLocation(c, world).add(0, 1, 0);
if (referenceSpawner.getAllowedLightLevels().getMin() > 0 || referenceSpawner.getAllowedLightLevels().getMax() < 15) {
if (referenceSpawner.getAllowedLightLevels().contains(l.getBlock().getLightLevel())) {
@@ -18,6 +18,7 @@
package art.arcane.iris.engine.object;
import art.arcane.iris.platform.bukkit.BukkitPlatform;
import art.arcane.iris.Iris;
import art.arcane.iris.core.loader.IrisData;
import art.arcane.iris.core.loader.IrisRegistrant;
@@ -137,8 +138,8 @@ public class IrisObject extends IrisRegistrant {
public static AxisAlignedBB getAABBFor(BlockVector size) {
BlockVector center = new BlockVector(size.getX() / 2, size.getY() / 2, size.getZ() / 2);
return new AxisAlignedBB(new IrisPosition(new BlockVector(0, 0, 0).subtract(center).toBlockVector()),
new IrisPosition(new BlockVector(size.getX() - 1, size.getY() - 1, size.getZ() - 1).subtract(center).toBlockVector()));
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 {
@@ -18,6 +18,7 @@
package art.arcane.iris.engine.object;
import art.arcane.iris.platform.bukkit.BukkitPlatform;
import art.arcane.iris.Iris;
import art.arcane.iris.engine.object.annotations.Desc;
import art.arcane.iris.engine.object.annotations.Snippet;
@@ -387,7 +388,7 @@ public class IrisObjectRotation {
}
public IrisPosition rotate(IrisPosition b, int spinx, int spiny, int spinz) {
return new IrisPosition(rotate(new BlockVector(b.getX(), b.getY(), b.getZ()), spinx, spiny, spinz));
return BukkitPlatform.positionOf(rotate(new BlockVector(b.getX(), b.getY(), b.getZ()), spinx, spiny, spinz));
}
public BlockVector rotate(BlockVector b, int spinx, int spiny, int spinz) {
@@ -24,10 +24,6 @@ import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.util.BlockVector;
import org.bukkit.util.Vector;
@Snippet("position-3d")
@Accessors(chain = true)
@@ -45,18 +41,6 @@ public class IrisPosition {
@Desc("The z position")
private int z = 0;
public IrisPosition(BlockVector bv) {
this(bv.getBlockX(), bv.getBlockY(), bv.getBlockZ());
}
public IrisPosition(Location l) {
this(l.getBlockX(), l.getBlockY(), l.getBlockZ());
}
public IrisPosition(Vector v) {
this(v.getBlockX(), v.getBlockY(), v.getBlockZ());
}
public IrisPosition(double x, double y, double z) {
this((int) x, (int) y, (int) z);
}
@@ -70,10 +54,6 @@ public class IrisPosition {
return new IrisPosition(x - relativePosition.x, y - relativePosition.y, z - relativePosition.z);
}
public Location toLocation(World world) {
return new Location(world, x, y, z);
}
public IrisPosition copy() {
return new IrisPosition(x, y, z);
}
@@ -86,8 +66,4 @@ public class IrisPosition {
public boolean isLongerThan(IrisPosition s, int maxLength) {
return Math.abs(Math.pow(s.x - x, 2) + Math.pow(s.y - y, 2) + Math.pow(s.z - z, 2)) > maxLength * maxLength;
}
public Vector toVector() {
return new Vector(x, y, z);
}
}
@@ -32,7 +32,6 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.bukkit.World;
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@@ -91,13 +90,12 @@ public class IrisSpawner extends IrisRegistrant {
};
}
public boolean isValid(World world) {
PlatformWorld platformWorld = new BukkitWorld(world);
return timeBlock.isWithin(platformWorld) && weather.is(platformWorld);
public boolean isValid(PlatformWorld world) {
return timeBlock.isWithin(world) && weather.is(world);
}
public boolean canSpawn(Engine engine) {
if (!isValid(engine.getWorld().realWorld()))
if (!isValid(new BukkitWorld(engine.getWorld().realWorld())))
return false;
var rate = getMaximumRate();
@@ -164,7 +164,6 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
return getInitialSpawnLocation(world);
}
@Override
public Location getInitialSpawnLocation(World world) {
int minY = world.getMinHeight() + 1;
int maxY = world.getMaxHeight() - 2;
@@ -397,7 +396,6 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
return future;
}
@Override
public void touch(World world) {
getEngine(world);
}
@@ -23,8 +23,6 @@ import art.arcane.iris.engine.framework.Engine;
import art.arcane.iris.engine.framework.EngineTarget;
import art.arcane.iris.engine.framework.Hotloadable;
import art.arcane.iris.util.common.data.DataProvider;
import org.bukkit.Location;
import org.bukkit.World;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -55,10 +53,5 @@ public interface PlatformChunkGenerator extends Hotloadable, DataProvider {
return false;
}
void touch(World world);
CompletableFuture<Integer> getSpawnChunks();
@Nullable
Location getInitialSpawnLocation(World world);
}
@@ -20,6 +20,7 @@ package art.arcane.iris.platform.bukkit;
import art.arcane.iris.Iris;
import art.arcane.iris.core.nms.INMS;
import art.arcane.iris.engine.object.IrisPosition;
import art.arcane.iris.spi.IrisPlatform;
import art.arcane.iris.spi.LogLevel;
import art.arcane.iris.spi.PlatformCapabilities;
@@ -27,6 +28,12 @@ import art.arcane.iris.spi.PlatformRegistries;
import art.arcane.iris.spi.PlatformScheduler;
import art.arcane.iris.util.common.scheduling.J;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Entity;
import org.bukkit.event.Listener;
import org.bukkit.util.Vector;
import java.io.File;
@@ -38,6 +45,40 @@ public final class BukkitPlatform implements IrisPlatform {
private final BukkitScheduler scheduler = new BukkitScheduler();
private final PlatformCapabilities capabilities = new BukkitCapabilities();
public static Class<?> classifyMantleValue(Object value) {
if (value instanceof World) {
return World.class;
}
if (value instanceof BlockData) {
return BlockData.class;
}
if (value instanceof Entity) {
return Entity.class;
}
return value.getClass();
}
public static void unregisterListener(Object candidate) {
if (candidate instanceof Listener listener) {
Iris.instance.unregisterListener(listener);
}
}
public static IrisPosition positionOf(Location location) {
return new IrisPosition(location.getBlockX(), location.getBlockY(), location.getBlockZ());
}
public static IrisPosition positionOf(Vector vector) {
return new IrisPosition(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ());
}
public static Location toLocation(IrisPosition position, World world) {
return new Location(world, position.getX(), position.getY(), position.getZ());
}
@Override
public String platformName() {
return "bukkit";
@@ -148,6 +148,10 @@ public class B {
return BASE.canPlaceOnto(mat, onto);
}
public static boolean canPlaceOnto(art.arcane.iris.spi.PlatformBlockState mat, art.arcane.iris.spi.PlatformBlockState onto) {
return BASE.canPlaceOnto(((BlockData) mat.nativeHandle()).getMaterial(), ((BlockData) onto.nativeHandle()).getMaterial());
}
public static boolean isFoliagePlantable(BlockData d) {
return BASE.isFoliagePlantable(d);
}
@@ -241,6 +245,10 @@ public class B {
return BASE.isAirOrFluid(d);
}
public static boolean isAirOrFluid(art.arcane.iris.spi.PlatformBlockState state) {
return BASE.isAirOrFluid((BlockData) state.nativeHandle());
}
public static boolean isAir(BlockData d) {
return BASE.isAir(d);
}
@@ -18,6 +18,7 @@
package art.arcane.iris.util.common.math;
import art.arcane.iris.platform.bukkit.BukkitPlatform;
import art.arcane.volmlib.util.math.AlignedPoint;
import art.arcane.iris.engine.object.IrisPosition;
import art.arcane.volmlib.util.data.Cuboid;
@@ -87,6 +88,6 @@ public class AxisAlignedBB {
}
public Cuboid toCuboid(World world) {
return new Cuboid(min().toLocation(world), max().toLocation(world));
return new Cuboid(BukkitPlatform.toLocation(min(), world), BukkitPlatform.toLocation(max(), world));
}
}
@@ -18,6 +18,7 @@
package art.arcane.iris.util.project.matter.slices;
import art.arcane.iris.platform.bukkit.BukkitPlatform;
import art.arcane.iris.core.nms.INMS;
import art.arcane.iris.engine.object.IrisPosition;
import art.arcane.volmlib.util.collection.KList;
@@ -111,7 +112,7 @@ public class EntityMatter extends RawMatter<MatterEntityGroup> {
entityCache = new KMap<>();
for (Entity i : ((World) w).getNearbyEntities(new BoundingBox(x, y, z, x + getWidth(), y + getHeight(), z + getHeight()))) {
entityCache.computeIfAbsent(new IrisPosition(i.getLocation()),
entityCache.computeIfAbsent(BukkitPlatform.positionOf(i.getLocation()),
k -> new KList<>()).add(i);
}
@@ -5,7 +5,6 @@ import art.arcane.iris.core.nms.INMSBinding;
import art.arcane.iris.engine.framework.Engine;
import art.arcane.iris.engine.framework.EngineTarget;
import art.arcane.iris.engine.platform.PlatformChunkGenerator;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.generator.ChunkGenerator;
import org.junit.Test;
@@ -114,20 +113,11 @@ public class WorldLifecycleRuntimeLevelStemTest {
return true;
}
@Override
public void touch(World world) {
}
@Override
public CompletableFuture<Integer> getSpawnChunks() {
return CompletableFuture.completedFuture(0);
}
@Override
public Location getInitialSpawnLocation(World world) {
return null;
}
@Override
public void hotload() {
}
@@ -1,5 +1,6 @@
package art.arcane.iris.core.runtime;
import art.arcane.iris.engine.platform.BukkitChunkGenerator;
import art.arcane.iris.engine.platform.PlatformChunkGenerator;
import org.bukkit.HeightMap;
import org.bukkit.Location;
@@ -18,7 +19,7 @@ public class WorldRuntimeControlServiceSafeEntryTest {
@Test
public void resolvesStudioEntryAnchorFromGeneratorInsteadOfMutableWorldSpawn() {
World world = mock(World.class);
PlatformChunkGenerator provider = mock(PlatformChunkGenerator.class);
BukkitChunkGenerator provider = mock(BukkitChunkGenerator.class);
Location initialSpawn = new Location(world, 0.5D, 96D, 0.5D);
Location mutableWorldSpawn = new Location(world, 128.5D, 80D, -64.5D);