mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-10-26 14:00:26 +00:00
Headless Classload
This commit is contained in:
1 parent
e1196b0364
commit
a3d7269a99
22 files changed
+695
-624
No files matched your search
@@ -23,6 +23,7 @@ import art.arcane.iris.platform.bukkit.BukkitPlatform;
|
|||||||
import art.arcane.iris.core.service.ObjectStudioSaveService;
|
import art.arcane.iris.core.service.ObjectStudioSaveService;
|
||||||
import art.arcane.iris.engine.framework.Engine;
|
import art.arcane.iris.engine.framework.Engine;
|
||||||
import art.arcane.iris.engine.framework.IrisStructureLocator;
|
import art.arcane.iris.engine.framework.IrisStructureLocator;
|
||||||
|
import art.arcane.iris.engine.platform.EngineBukkitOps;
|
||||||
import art.arcane.iris.engine.framework.StructureReachability;
|
import art.arcane.iris.engine.framework.StructureReachability;
|
||||||
import art.arcane.iris.engine.object.IrisBiome;
|
import art.arcane.iris.engine.object.IrisBiome;
|
||||||
import art.arcane.iris.engine.object.IrisRegion;
|
import art.arcane.iris.engine.object.IrisRegion;
|
||||||
@@ -57,7 +58,7 @@ public class CommandFind implements DirectorExecutor {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
e.gotoBiome(biome, player(), teleport);
|
EngineBukkitOps.gotoBiome(e, biome, player(), teleport);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Director(description = "Find a region")
|
@Director(description = "Find a region")
|
||||||
@@ -74,7 +75,7 @@ public class CommandFind implements DirectorExecutor {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
e.gotoRegion(region, player(), teleport);
|
EngineBukkitOps.gotoRegion(e, region, player(), teleport);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Director(description = "Find a point of interest.")
|
@Director(description = "Find a point of interest.")
|
||||||
@@ -90,7 +91,7 @@ public class CommandFind implements DirectorExecutor {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
e.gotoPOI(type, player(), teleport);
|
EngineBukkitOps.gotoPOI(e, type, player(), teleport);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Director(description = "Find a structure (a vanilla key like minecraft:village_plains or minecraft:stronghold, or an imported iris structure key)")
|
@Director(description = "Find a structure (a vanilla key like minecraft:village_plains or minecraft:stronghold, or an imported iris structure key)")
|
||||||
@@ -106,7 +107,7 @@ public class CommandFind implements DirectorExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (IrisStructureLocator.isPlaced(e, structure)) {
|
if (IrisStructureLocator.isPlaced(e, structure)) {
|
||||||
e.gotoStructure(structure, player(), true);
|
EngineBukkitOps.gotoStructure(e, structure, player(), true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,7 +181,7 @@ public class CommandFind implements DirectorExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (e.hasObjectPlacement(object)) {
|
if (e.hasObjectPlacement(object)) {
|
||||||
e.gotoObject(object, player(), teleport);
|
EngineBukkitOps.gotoObject(e, object, player(), teleport);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-3
@@ -32,6 +32,7 @@ import art.arcane.iris.core.structure.StructureImporter;
|
|||||||
import art.arcane.iris.core.tools.IrisToolbelt;
|
import art.arcane.iris.core.tools.IrisToolbelt;
|
||||||
import art.arcane.iris.engine.framework.Engine;
|
import art.arcane.iris.engine.framework.Engine;
|
||||||
import art.arcane.iris.engine.object.*;
|
import art.arcane.iris.engine.object.*;
|
||||||
|
import art.arcane.iris.engine.platform.EngineBukkitOps;
|
||||||
import art.arcane.iris.engine.platform.PlatformChunkGenerator;
|
import art.arcane.iris.engine.platform.PlatformChunkGenerator;
|
||||||
import art.arcane.volmlib.util.collection.KList;
|
import art.arcane.volmlib.util.collection.KList;
|
||||||
import art.arcane.volmlib.util.collection.KMap;
|
import art.arcane.volmlib.util.collection.KMap;
|
||||||
@@ -246,11 +247,11 @@ public class CommandStudio implements DirectorExecutor {
|
|||||||
) {
|
) {
|
||||||
if (noStudio()) return;
|
if (noStudio()) return;
|
||||||
|
|
||||||
KList<IrisLootTable> tables = engine().getLootTables(RNG.r, player().getLocation().getBlock());
|
KList<IrisLootTable> tables = EngineBukkitOps.getLootTables(engine(), RNG.r, player().getLocation().getBlock());
|
||||||
Inventory inv = Bukkit.createInventory(null, 27 * 2);
|
Inventory inv = Bukkit.createInventory(null, 27 * 2);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
engine().addItems(true, inv, RNG.r, tables, InventorySlotType.STORAGE, player().getWorld(), player().getLocation().getBlockX(), player().getLocation().getBlockY(), player().getLocation().getBlockZ(), 1);
|
EngineBukkitOps.addItems(engine(), true, inv, RNG.r, tables, InventorySlotType.STORAGE, player().getWorld(), player().getLocation().getBlockX(), player().getLocation().getBlockY(), player().getLocation().getBlockZ(), 1);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Iris.reportError(e);
|
Iris.reportError(e);
|
||||||
sender().sendMessage(C.RED + "Cannot add items to virtual inventory because of: " + e.getMessage());
|
sender().sendMessage(C.RED + "Cannot add items to virtual inventory because of: " + e.getMessage());
|
||||||
@@ -277,7 +278,7 @@ public class CommandStudio implements DirectorExecutor {
|
|||||||
inv.clear();
|
inv.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
engine.addItems(true, inv, new RNG(RNG.r.imax()), tables, InventorySlotType.STORAGE, player.getWorld(), player.getLocation().getBlockX(), player.getLocation().getBlockY(), player.getLocation().getBlockZ(), 1);
|
EngineBukkitOps.addItems(engine, true, inv, new RNG(RNG.r.imax()), tables, InventorySlotType.STORAGE, player.getWorld(), player.getLocation().getBlockX(), player.getLocation().getBlockY(), player.getLocation().getBlockZ(), 1);
|
||||||
}, fast ? 5 : 35));
|
}, fast ? 5 : 35));
|
||||||
|
|
||||||
sender().sendMessage(C.GREEN + "Opening inventory now!");
|
sender().sendMessage(C.GREEN + "Opening inventory now!");
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import art.arcane.iris.core.edit.BlockSignal;
|
|||||||
import art.arcane.iris.core.nms.INMS;
|
import art.arcane.iris.core.nms.INMS;
|
||||||
import art.arcane.iris.core.tools.IrisToolbelt;
|
import art.arcane.iris.core.tools.IrisToolbelt;
|
||||||
import art.arcane.iris.engine.framework.Engine;
|
import art.arcane.iris.engine.framework.Engine;
|
||||||
|
import art.arcane.iris.engine.platform.EngineBukkitOps;
|
||||||
import art.arcane.iris.engine.object.IrisBiome;
|
import art.arcane.iris.engine.object.IrisBiome;
|
||||||
import art.arcane.iris.engine.object.IrisRegion;
|
import art.arcane.iris.engine.object.IrisRegion;
|
||||||
import art.arcane.iris.util.common.director.DirectorExecutor;
|
import art.arcane.iris.util.common.director.DirectorExecutor;
|
||||||
@@ -96,7 +97,7 @@ public class CommandWhat implements DirectorExecutor {
|
|||||||
public void region() {
|
public void region() {
|
||||||
try {
|
try {
|
||||||
Chunk chunk = world().getChunkAt(player().getLocation().getBlockZ() / 16, player().getLocation().getBlockZ() / 16);
|
Chunk chunk = world().getChunkAt(player().getLocation().getBlockZ() / 16, player().getLocation().getBlockZ() / 16);
|
||||||
IrisRegion r = engine().getRegion(chunk);
|
IrisRegion r = EngineBukkitOps.getRegion(engine(), chunk);
|
||||||
sender().sendMessage("IRegion: " + r.getLoadKey() + " (" + r.getName() + ")");
|
sender().sendMessage("IRegion: " + r.getLoadKey() + " (" + r.getName() + ")");
|
||||||
|
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
|
|||||||
+4
-3
@@ -21,6 +21,7 @@ package art.arcane.iris.core.link;
|
|||||||
import art.arcane.iris.Iris;
|
import art.arcane.iris.Iris;
|
||||||
import art.arcane.iris.core.tools.IrisToolbelt;
|
import art.arcane.iris.core.tools.IrisToolbelt;
|
||||||
import art.arcane.iris.engine.object.IrisBiome;
|
import art.arcane.iris.engine.object.IrisBiome;
|
||||||
|
import art.arcane.iris.engine.platform.EngineBukkitOps;
|
||||||
import art.arcane.iris.engine.platform.PlatformChunkGenerator;
|
import art.arcane.iris.engine.platform.PlatformChunkGenerator;
|
||||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
@@ -73,15 +74,15 @@ public class IrisPapiExpansion extends PlaceholderExpansion {
|
|||||||
}
|
}
|
||||||
} else if (p.equalsIgnoreCase("region_name")) {
|
} else if (p.equalsIgnoreCase("region_name")) {
|
||||||
if (a != null) {
|
if (a != null) {
|
||||||
return a.getEngine().getRegion(l).getName();
|
return EngineBukkitOps.getRegion(a.getEngine(), l).getName();
|
||||||
}
|
}
|
||||||
} else if (p.equalsIgnoreCase("region_id")) {
|
} else if (p.equalsIgnoreCase("region_id")) {
|
||||||
if (a != null) {
|
if (a != null) {
|
||||||
return a.getEngine().getRegion(l).getLoadKey();
|
return EngineBukkitOps.getRegion(a.getEngine(), l).getLoadKey();
|
||||||
}
|
}
|
||||||
} else if (p.equalsIgnoreCase("region_file")) {
|
} else if (p.equalsIgnoreCase("region_file")) {
|
||||||
if (a != null) {
|
if (a != null) {
|
||||||
return a.getEngine().getRegion(l).getLoadFile().getPath();
|
return EngineBukkitOps.getRegion(a.getEngine(), l).getLoadFile().getPath();
|
||||||
}
|
}
|
||||||
} else if (p.equalsIgnoreCase("terrain_slope")) {
|
} else if (p.equalsIgnoreCase("terrain_slope")) {
|
||||||
if (a != null) {
|
if (a != null) {
|
||||||
|
|||||||
@@ -51,7 +51,6 @@ art/arcane/iris/core/runtime/ChunkClearer.java
|
|||||||
art/arcane/iris/core/runtime/ChunkJobReporter.java
|
art/arcane/iris/core/runtime/ChunkJobReporter.java
|
||||||
art/arcane/iris/core/runtime/GoldenHashScanner.java
|
art/arcane/iris/core/runtime/GoldenHashScanner.java
|
||||||
art/arcane/iris/core/runtime/InPlaceChunkRegenerator.java
|
art/arcane/iris/core/runtime/InPlaceChunkRegenerator.java
|
||||||
art/arcane/iris/core/runtime/ObjectStudioLayout.java
|
|
||||||
art/arcane/iris/core/runtime/PaperLikeRuntimeControlBackend.java
|
art/arcane/iris/core/runtime/PaperLikeRuntimeControlBackend.java
|
||||||
art/arcane/iris/core/runtime/StudioOpenCoordinator.java
|
art/arcane/iris/core/runtime/StudioOpenCoordinator.java
|
||||||
art/arcane/iris/core/runtime/WorldRuntimeControlBackend.java
|
art/arcane/iris/core/runtime/WorldRuntimeControlBackend.java
|
||||||
@@ -83,12 +82,10 @@ art/arcane/iris/engine/actuator/IrisBiomeActuator.java
|
|||||||
art/arcane/iris/engine/data/chunk/LinkedTerrainChunk.java
|
art/arcane/iris/engine/data/chunk/LinkedTerrainChunk.java
|
||||||
art/arcane/iris/engine/data/chunk/TerrainChunk.java
|
art/arcane/iris/engine/data/chunk/TerrainChunk.java
|
||||||
art/arcane/iris/engine/decorator/DecoratorCore.java
|
art/arcane/iris/engine/decorator/DecoratorCore.java
|
||||||
art/arcane/iris/engine/framework/BlockUpdater.java
|
|
||||||
art/arcane/iris/engine/framework/Engine.java
|
art/arcane/iris/engine/framework/Engine.java
|
||||||
art/arcane/iris/engine/framework/EngineAssignedWorldManager.java
|
art/arcane/iris/engine/framework/EngineAssignedWorldManager.java
|
||||||
art/arcane/iris/engine/framework/EnginePlayer.java
|
art/arcane/iris/engine/framework/EnginePlayer.java
|
||||||
art/arcane/iris/engine/framework/EngineWorldManager.java
|
art/arcane/iris/engine/framework/EngineWorldManager.java
|
||||||
art/arcane/iris/engine/framework/LootProvider.java
|
|
||||||
art/arcane/iris/engine/framework/placer/WorldObjectPlacer.java
|
art/arcane/iris/engine/framework/placer/WorldObjectPlacer.java
|
||||||
art/arcane/iris/engine/mantle/EngineMantle.java
|
art/arcane/iris/engine/mantle/EngineMantle.java
|
||||||
art/arcane/iris/engine/mantle/MantleWriter.java
|
art/arcane/iris/engine/mantle/MantleWriter.java
|
||||||
@@ -123,7 +120,6 @@ art/arcane/iris/engine/object/IrisLootTable.java
|
|||||||
art/arcane/iris/engine/object/IrisObject.java
|
art/arcane/iris/engine/object/IrisObject.java
|
||||||
art/arcane/iris/engine/object/IrisObjectPlacement.java
|
art/arcane/iris/engine/object/IrisObjectPlacement.java
|
||||||
art/arcane/iris/engine/object/IrisObjectRotation.java
|
art/arcane/iris/engine/object/IrisObjectRotation.java
|
||||||
art/arcane/iris/engine/object/IrisObjectTranslate.java
|
|
||||||
art/arcane/iris/engine/object/IrisPotionEffect.java
|
art/arcane/iris/engine/object/IrisPotionEffect.java
|
||||||
art/arcane/iris/engine/object/IrisProceduralBlocks.java
|
art/arcane/iris/engine/object/IrisProceduralBlocks.java
|
||||||
art/arcane/iris/engine/object/IrisSurface.java
|
art/arcane/iris/engine/object/IrisSurface.java
|
||||||
@@ -151,6 +147,7 @@ art/arcane/iris/engine/object/tree/TreePlausibility.java
|
|||||||
art/arcane/iris/engine/platform/BukkitChunkGenerator.java
|
art/arcane/iris/engine/platform/BukkitChunkGenerator.java
|
||||||
art/arcane/iris/engine/platform/DummyBiomeProvider.java
|
art/arcane/iris/engine/platform/DummyBiomeProvider.java
|
||||||
art/arcane/iris/engine/platform/DummyChunkGenerator.java
|
art/arcane/iris/engine/platform/DummyChunkGenerator.java
|
||||||
|
art/arcane/iris/engine/platform/EngineBukkitOps.java
|
||||||
art/arcane/iris/engine/platform/studio/generators/ObjectStudioGenerator.java
|
art/arcane/iris/engine/platform/studio/generators/ObjectStudioGenerator.java
|
||||||
art/arcane/iris/platform/bukkit/BukkitBiome.java
|
art/arcane/iris/platform/bukkit/BukkitBiome.java
|
||||||
art/arcane/iris/platform/bukkit/BukkitBlockResolution.java
|
art/arcane/iris/platform/bukkit/BukkitBlockResolution.java
|
||||||
@@ -162,7 +159,6 @@ art/arcane/iris/platform/bukkit/BukkitRegistries.java
|
|||||||
art/arcane/iris/platform/bukkit/BukkitScheduler.java
|
art/arcane/iris/platform/bukkit/BukkitScheduler.java
|
||||||
art/arcane/iris/platform/bukkit/BukkitWorld.java
|
art/arcane/iris/platform/bukkit/BukkitWorld.java
|
||||||
art/arcane/iris/util/common/data/IrisCustomData.java
|
art/arcane/iris/util/common/data/IrisCustomData.java
|
||||||
art/arcane/iris/util/common/data/VectorMap.java
|
|
||||||
art/arcane/iris/util/common/data/registry/Attributes.java
|
art/arcane/iris/util/common/data/registry/Attributes.java
|
||||||
art/arcane/iris/util/common/data/registry/KeyedRegistry.java
|
art/arcane/iris/util/common/data/registry/KeyedRegistry.java
|
||||||
art/arcane/iris/util/common/data/registry/Materials.java
|
art/arcane/iris/util/common/data/registry/Materials.java
|
||||||
@@ -183,7 +179,6 @@ art/arcane/iris/util/common/inventorygui/Window.java
|
|||||||
art/arcane/iris/util/common/inventorygui/WindowResolution.java
|
art/arcane/iris/util/common/inventorygui/WindowResolution.java
|
||||||
art/arcane/iris/util/common/math/AxisAlignedBB.java
|
art/arcane/iris/util/common/math/AxisAlignedBB.java
|
||||||
art/arcane/iris/util/common/math/Direction.java
|
art/arcane/iris/util/common/math/Direction.java
|
||||||
art/arcane/iris/util/common/math/Vector3i.java
|
|
||||||
art/arcane/iris/util/common/math/VectorMath.java
|
art/arcane/iris/util/common/math/VectorMath.java
|
||||||
art/arcane/iris/util/common/misc/Bindings.java
|
art/arcane/iris/util/common/misc/Bindings.java
|
||||||
art/arcane/iris/util/common/nbt/mca/Chunk.java
|
art/arcane/iris/util/common/nbt/mca/Chunk.java
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ package art.arcane.iris.core.runtime;
|
|||||||
import art.arcane.iris.spi.IrisLogging;
|
import art.arcane.iris.spi.IrisLogging;
|
||||||
import art.arcane.iris.core.nms.INMS;
|
import art.arcane.iris.core.nms.INMS;
|
||||||
import art.arcane.iris.engine.data.chunk.TerrainChunk;
|
import art.arcane.iris.engine.data.chunk.TerrainChunk;
|
||||||
|
import art.arcane.iris.engine.platform.EngineBukkitOps;
|
||||||
import art.arcane.iris.engine.framework.Engine;
|
import art.arcane.iris.engine.framework.Engine;
|
||||||
import art.arcane.iris.engine.mantle.EngineMantle;
|
import art.arcane.iris.engine.mantle.EngineMantle;
|
||||||
import art.arcane.iris.spi.PlatformBiome;
|
import art.arcane.iris.spi.PlatformBiome;
|
||||||
@@ -175,7 +176,7 @@ public final class InPlaceChunkRegenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
engine.updateChunk(chunk);
|
EngineBukkitOps.updateChunk(engine, chunk);
|
||||||
world.refreshChunk(chunkX, chunkZ);
|
world.refreshChunk(chunkX, chunkZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import art.arcane.iris.core.tools.IrisToolbelt;
|
|||||||
import art.arcane.iris.engine.data.cache.Cache;
|
import art.arcane.iris.engine.data.cache.Cache;
|
||||||
import art.arcane.iris.engine.framework.Engine;
|
import art.arcane.iris.engine.framework.Engine;
|
||||||
import art.arcane.iris.engine.framework.EngineAssignedWorldManager;
|
import art.arcane.iris.engine.framework.EngineAssignedWorldManager;
|
||||||
|
import art.arcane.iris.engine.platform.EngineBukkitOps;
|
||||||
import art.arcane.iris.engine.object.*;
|
import art.arcane.iris.engine.object.*;
|
||||||
import art.arcane.iris.spi.IrisLogging;
|
import art.arcane.iris.spi.IrisLogging;
|
||||||
import art.arcane.volmlib.util.collection.KList;
|
import art.arcane.volmlib.util.collection.KList;
|
||||||
@@ -281,7 +282,7 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
|
|||||||
warmupMantleChunkAsync(chunkX, chunkZ);
|
warmupMantleChunkAsync(chunkX, chunkZ);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
getEngine().updateChunk(chunk);
|
EngineBukkitOps.updateChunk(getEngine(), chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isEntitySpawningEnabledForCurrentWorld()) {
|
if (!isEntitySpawningEnabledForCurrentWorld()) {
|
||||||
@@ -585,7 +586,7 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
|
|||||||
Predicate<IrisSpawner> filter = i -> i.canSpawn(getEngine(), c.getX(), c.getZ());
|
Predicate<IrisSpawner> filter = i -> i.canSpawn(getEngine(), c.getX(), c.getZ());
|
||||||
ChunkCounter counter = new ChunkCounter(c.getEntities());
|
ChunkCounter counter = new ChunkCounter(c.getEntities());
|
||||||
|
|
||||||
IrisBiome biome = getEngine().getSurfaceBiome(c);
|
IrisBiome biome = EngineBukkitOps.getSurfaceBiome(getEngine(), c);
|
||||||
IrisEntitySpawn v = spawnRandomly(Stream.concat(getData().getSpawnerLoader()
|
IrisEntitySpawn v = spawnRandomly(Stream.concat(getData().getSpawnerLoader()
|
||||||
.loadAll(getDimension().getEntitySpawners())
|
.loadAll(getDimension().getEntitySpawners())
|
||||||
.shuffleCopy(RNG.r)
|
.shuffleCopy(RNG.r)
|
||||||
@@ -978,11 +979,11 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
|
|||||||
});
|
});
|
||||||
|
|
||||||
KList<ItemStack> d = new KList<>();
|
KList<ItemStack> d = new KList<>();
|
||||||
IrisBiome b = getEngine().getBiome(e.getBlock().getLocation().clone().subtract(0, getEngine().getWorld().minHeight(), 0));
|
IrisBiome b = EngineBukkitOps.getBiome(getEngine(), e.getBlock().getLocation().clone().subtract(0, getEngine().getWorld().minHeight(), 0));
|
||||||
List<IrisBlockDrops> dropProviders = filterDrops(b.getBlockDrops(), e, getData());
|
List<IrisBlockDrops> dropProviders = filterDrops(b.getBlockDrops(), e, getData());
|
||||||
|
|
||||||
if (dropProviders.stream().noneMatch(IrisBlockDrops::isSkipParents)) {
|
if (dropProviders.stream().noneMatch(IrisBlockDrops::isSkipParents)) {
|
||||||
IrisRegion r = getEngine().getRegion(e.getBlock().getLocation());
|
IrisRegion r = EngineBukkitOps.getRegion(getEngine(), e.getBlock().getLocation());
|
||||||
dropProviders.addAll(filterDrops(r.getBlockDrops(), e, getData()));
|
dropProviders.addAll(filterDrops(r.getBlockDrops(), e, getData()));
|
||||||
dropProviders.addAll(filterDrops(getEngine().getDimension().getBlockDrops(), e, getData()));
|
dropProviders.addAll(filterDrops(getEngine().getDimension().getBlockDrops(), e, getData()));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,16 +19,8 @@
|
|||||||
package art.arcane.iris.engine.framework;
|
package art.arcane.iris.engine.framework;
|
||||||
|
|
||||||
import art.arcane.iris.spi.PlatformBlockState;
|
import art.arcane.iris.spi.PlatformBlockState;
|
||||||
import art.arcane.volmlib.util.mantle.runtime.MantleChunk;
|
|
||||||
import art.arcane.volmlib.util.math.RNG;
|
|
||||||
import art.arcane.volmlib.util.matter.Matter;
|
|
||||||
import org.bukkit.Chunk;
|
|
||||||
|
|
||||||
public interface BlockUpdater {
|
public interface BlockUpdater {
|
||||||
|
|
||||||
void catchBlockUpdates(int x, int y, int z, PlatformBlockState data);
|
void catchBlockUpdates(int x, int y, int z, PlatformBlockState data);
|
||||||
|
|
||||||
void updateChunk(Chunk c);
|
|
||||||
|
|
||||||
void update(int x, int y, int z, Chunk c, MantleChunk<Matter> mc, RNG rf);
|
|
||||||
}
|
}
|
||||||
@@ -20,30 +20,23 @@ package art.arcane.iris.engine.framework;
|
|||||||
|
|
||||||
import art.arcane.iris.platform.bukkit.BukkitBlockResolution;
|
import art.arcane.iris.platform.bukkit.BukkitBlockResolution;
|
||||||
|
|
||||||
import art.arcane.iris.spi.IrisServices;
|
|
||||||
import art.arcane.iris.core.IrisSettings;
|
import art.arcane.iris.core.IrisSettings;
|
||||||
import art.arcane.iris.core.events.IrisLootEvent;
|
|
||||||
import art.arcane.iris.engine.framework.render.RenderType;
|
import art.arcane.iris.engine.framework.render.RenderType;
|
||||||
import art.arcane.iris.engine.framework.render.Renderer;
|
import art.arcane.iris.engine.framework.render.Renderer;
|
||||||
import art.arcane.iris.core.gui.PregeneratorJob;
|
import art.arcane.iris.core.gui.PregeneratorJob;
|
||||||
import art.arcane.iris.core.link.Identifier;
|
|
||||||
import art.arcane.iris.core.loader.IrisData;
|
import art.arcane.iris.core.loader.IrisData;
|
||||||
import art.arcane.iris.core.loader.IrisRegistrant;
|
import art.arcane.iris.core.loader.IrisRegistrant;
|
||||||
import art.arcane.iris.core.nms.container.BlockPos;
|
import art.arcane.iris.core.nms.container.BlockPos;
|
||||||
import art.arcane.iris.core.nms.container.Pair;
|
import art.arcane.iris.core.nms.container.Pair;
|
||||||
import art.arcane.iris.core.service.ExternalDataSVC;
|
|
||||||
import art.arcane.iris.core.tools.IrisToolbelt;
|
import art.arcane.iris.core.tools.IrisToolbelt;
|
||||||
import art.arcane.iris.engine.IrisComplex;
|
import art.arcane.iris.engine.IrisComplex;
|
||||||
import art.arcane.iris.engine.UpperDimensionContext;
|
import art.arcane.iris.engine.UpperDimensionContext;
|
||||||
import art.arcane.iris.engine.data.cache.Cache;
|
|
||||||
import art.arcane.iris.engine.data.chunk.TerrainChunk;
|
import art.arcane.iris.engine.data.chunk.TerrainChunk;
|
||||||
import art.arcane.iris.engine.mantle.EngineMantle;
|
import art.arcane.iris.engine.mantle.EngineMantle;
|
||||||
import art.arcane.iris.engine.object.*;
|
import art.arcane.iris.engine.object.*;
|
||||||
import art.arcane.iris.platform.bukkit.BukkitBlockState;
|
|
||||||
import art.arcane.iris.spi.IrisLogging;
|
import art.arcane.iris.spi.IrisLogging;
|
||||||
import art.arcane.iris.spi.PlatformBiome;
|
import art.arcane.iris.spi.PlatformBiome;
|
||||||
import art.arcane.iris.spi.PlatformBlockState;
|
import art.arcane.iris.spi.PlatformBlockState;
|
||||||
import art.arcane.iris.util.project.matter.TileWrapper;
|
|
||||||
import art.arcane.volmlib.util.collection.KList;
|
import art.arcane.volmlib.util.collection.KList;
|
||||||
import art.arcane.volmlib.util.collection.KMap;
|
import art.arcane.volmlib.util.collection.KMap;
|
||||||
import art.arcane.iris.util.project.context.ChunkContext;
|
import art.arcane.iris.util.project.context.ChunkContext;
|
||||||
@@ -52,48 +45,30 @@ import art.arcane.iris.util.common.data.DataProvider;
|
|||||||
import art.arcane.iris.util.common.data.IrisCustomData;
|
import art.arcane.iris.util.common.data.IrisCustomData;
|
||||||
import art.arcane.volmlib.util.documentation.BlockCoordinates;
|
import art.arcane.volmlib.util.documentation.BlockCoordinates;
|
||||||
import art.arcane.volmlib.util.documentation.ChunkCoordinates;
|
import art.arcane.volmlib.util.documentation.ChunkCoordinates;
|
||||||
import art.arcane.iris.util.common.format.C;
|
|
||||||
import art.arcane.volmlib.util.function.Function2;
|
import art.arcane.volmlib.util.function.Function2;
|
||||||
import art.arcane.iris.util.project.hunk.Hunk;
|
import art.arcane.iris.util.project.hunk.Hunk;
|
||||||
import art.arcane.volmlib.util.mantle.runtime.MantleChunk;
|
import art.arcane.volmlib.util.mantle.runtime.MantleChunk;
|
||||||
import art.arcane.volmlib.util.mantle.flag.MantleFlag;
|
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.M;
|
||||||
import art.arcane.volmlib.util.math.Position2;
|
|
||||||
import art.arcane.volmlib.util.math.RNG;
|
import art.arcane.volmlib.util.math.RNG;
|
||||||
import art.arcane.volmlib.util.matter.Matter;
|
import art.arcane.volmlib.util.matter.Matter;
|
||||||
import art.arcane.volmlib.util.matter.MatterCavern;
|
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.BurstExecutor;
|
||||||
import art.arcane.iris.util.common.parallel.MultiBurst;
|
import art.arcane.iris.util.common.parallel.MultiBurst;
|
||||||
import art.arcane.iris.util.common.plugin.VolmitSender;
|
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.iris.util.common.reflect.W;
|
||||||
import art.arcane.volmlib.util.scheduling.ChronoLatch;
|
import art.arcane.volmlib.util.scheduling.ChronoLatch;
|
||||||
import art.arcane.iris.util.common.scheduling.J;
|
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 art.arcane.iris.util.project.stream.ProceduralStream;
|
||||||
import io.papermc.lib.PaperLib;
|
import org.bukkit.World;
|
||||||
import org.bukkit.*;
|
|
||||||
import org.bukkit.block.Block;
|
|
||||||
import org.bukkit.block.BlockFace;
|
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.Inventory;
|
|
||||||
import org.bukkit.inventory.InventoryHolder;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
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.AtomicBoolean;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
@@ -339,243 +314,6 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
|
|||||||
|
|
||||||
void blockUpdatedMetric();
|
void blockUpdatedMetric();
|
||||||
|
|
||||||
@ChunkCoordinates
|
|
||||||
@Override
|
|
||||||
default void updateChunk(Chunk c) {
|
|
||||||
for (int x = -1; x <= 1; x++) {
|
|
||||||
for (int z = -1; z <= 1; z++) {
|
|
||||||
if (c.getWorld().isChunkLoaded(c.getX() + x, c.getZ() + z))
|
|
||||||
continue;
|
|
||||||
var msg = "Chunk %s, %s [%s, %s] is not loaded".formatted(c.getX() + x, c.getZ() + z, x, z);
|
|
||||||
IrisLogging.debug(msg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var mantle = getMantle().getMantle();
|
|
||||||
if (!mantle.isLoaded(c)) {
|
|
||||||
var msg = "Mantle Chunk " + c.getX() + "," + c.getZ() + " is not loaded";
|
|
||||||
IrisLogging.debug(msg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!J.isFolia() && !J.isPrimaryThread()) {
|
|
||||||
CompletableFuture<?> scheduled = J.sfut(() -> updateChunk(c));
|
|
||||||
if (scheduled != null) {
|
|
||||||
try {
|
|
||||||
scheduled.join();
|
|
||||||
} catch (Throwable e) {
|
|
||||||
IrisLogging.reportError(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var chunk = mantle.getChunk(c).use();
|
|
||||||
try {
|
|
||||||
Runnable tileTask = () -> {
|
|
||||||
chunk.iterate(TileWrapper.class, (x, y, z, v) -> {
|
|
||||||
Block block = c.getBlock(x & 15, y + getWorld().minHeight(), z & 15);
|
|
||||||
if (!TileData.setTileState(block, v.getData())) {
|
|
||||||
NamespacedKey blockTypeKey = KeyedType.getKey(block.getType());
|
|
||||||
NamespacedKey tileTypeKey = KeyedType.getKey(v.getData().getMaterial());
|
|
||||||
String blockType = blockTypeKey == null ? block.getType().name() : blockTypeKey.toString();
|
|
||||||
String tileType = tileTypeKey == null ? v.getData().getMaterial().name() : tileTypeKey.toString();
|
|
||||||
IrisLogging.warn("Failed to set tile entity data at [%d %d %d | %s] for tile %s!", block.getX(), block.getY(), block.getZ(), blockType, tileType);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
Runnable customTask = () -> {
|
|
||||||
chunk.iterate(Identifier.class, (x, y, z, v) -> {
|
|
||||||
IrisServices.get(ExternalDataSVC.class).processUpdate(this, c.getBlock(x & 15, y + getWorld().minHeight(), z & 15), v);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
Runnable updateTask = () -> {
|
|
||||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
|
||||||
int[][] grid = new int[16][16];
|
|
||||||
for (int x = 0; x < 16; x++) {
|
|
||||||
for (int z = 0; z < 16; z++) {
|
|
||||||
grid[x][z] = Integer.MIN_VALUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RNG rng = new RNG(Cache.key(c.getX(), c.getZ()));
|
|
||||||
chunk.iterate(MatterCavern.class, (x, yf, z, v) -> {
|
|
||||||
int y = yf + getWorld().minHeight();
|
|
||||||
x &= 15;
|
|
||||||
z &= 15;
|
|
||||||
Block block = c.getBlock(x, y, z);
|
|
||||||
if (!BukkitBlockResolution.isFluid(block.getBlockData())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
boolean u = BukkitBlockResolution.isAir(block.getRelative(BlockFace.DOWN).getBlockData())
|
|
||||||
|| BukkitBlockResolution.isAir(block.getRelative(BlockFace.WEST).getBlockData())
|
|
||||||
|| BukkitBlockResolution.isAir(block.getRelative(BlockFace.EAST).getBlockData())
|
|
||||||
|| BukkitBlockResolution.isAir(block.getRelative(BlockFace.SOUTH).getBlockData())
|
|
||||||
|| BukkitBlockResolution.isAir(block.getRelative(BlockFace.NORTH).getBlockData());
|
|
||||||
|
|
||||||
if (u) grid[x][z] = Math.max(grid[x][z], y);
|
|
||||||
});
|
|
||||||
|
|
||||||
for (int x = 0; x < 16; x++) {
|
|
||||||
for (int z = 0; z < 16; z++) {
|
|
||||||
if (grid[x][z] == Integer.MIN_VALUE) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
update(x, grid[x][z], z, c, chunk, rng);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
chunk.iterate(MatterUpdate.class, (x, yf, z, v) -> {
|
|
||||||
int y = yf + getWorld().minHeight();
|
|
||||||
if (v != null && v.isUpdate()) {
|
|
||||||
update(x, y, z, c, chunk, rng);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
chunk.deleteSlices(MatterUpdate.class);
|
|
||||||
getMetrics().getUpdates().put(p.getMilliseconds());
|
|
||||||
};
|
|
||||||
|
|
||||||
if (shouldRunChunkUpdateInline(c)) {
|
|
||||||
chunk.raiseFlagUnchecked(MantleFlag.ETCHED, () -> {
|
|
||||||
chunk.raiseFlagUnchecked(MantleFlag.TILE, tileTask);
|
|
||||||
chunk.raiseFlagUnchecked(MantleFlag.CUSTOM, customTask);
|
|
||||||
chunk.raiseFlagUnchecked(MantleFlag.UPDATE, updateTask);
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Semaphore semaphore = new Semaphore(1024);
|
|
||||||
chunk.raiseFlagUnchecked(MantleFlag.ETCHED, () -> {
|
|
||||||
chunk.raiseFlagUnchecked(MantleFlag.TILE, run(semaphore, c, tileTask, 0));
|
|
||||||
chunk.raiseFlagUnchecked(MantleFlag.CUSTOM, run(semaphore, c, customTask, 0));
|
|
||||||
chunk.raiseFlagUnchecked(MantleFlag.UPDATE, run(semaphore, c, updateTask, RNG.r.i(1, 20)));
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
semaphore.acquire(1024);
|
|
||||||
} catch (InterruptedException ex) {
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
IrisLogging.reportError(ex);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
chunk.release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean shouldRunChunkUpdateInline(Chunk chunk) {
|
|
||||||
if (chunk == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!J.isFolia()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return J.isOwnedByCurrentRegion(chunk.getWorld(), chunk.getX(), chunk.getZ());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Runnable run(Semaphore semaphore, Chunk contextChunk, Runnable runnable, int delay) {
|
|
||||||
return () -> {
|
|
||||||
try {
|
|
||||||
semaphore.acquire();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
int effectiveDelay = J.isFolia() ? 0 : delay;
|
|
||||||
boolean scheduled = J.runRegion(contextChunk.getWorld(), contextChunk.getX(), contextChunk.getZ(), () -> {
|
|
||||||
try {
|
|
||||||
runnable.run();
|
|
||||||
} finally {
|
|
||||||
semaphore.release();
|
|
||||||
}
|
|
||||||
}, effectiveDelay);
|
|
||||||
|
|
||||||
if (!scheduled) {
|
|
||||||
try {
|
|
||||||
if (J.isPrimaryThread()) {
|
|
||||||
runnable.run();
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
semaphore.release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@BlockCoordinates
|
|
||||||
@Override
|
|
||||||
|
|
||||||
default void update(int x, int y, int z, Chunk c, MantleChunk<Matter> mc, RNG rf) {
|
|
||||||
Block block = c.getBlock(x, y, z);
|
|
||||||
BlockData data = block.getBlockData();
|
|
||||||
blockUpdatedMetric();
|
|
||||||
if (BukkitBlockResolution.isStorage(data)) {
|
|
||||||
RNG rx = rf.nextParallelRNG(BlockPosition.toLong(x, y, z));
|
|
||||||
InventorySlotType slot = null;
|
|
||||||
|
|
||||||
if (BukkitBlockResolution.isStorageChest(data)) {
|
|
||||||
slot = InventorySlotType.STORAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (slot != null) {
|
|
||||||
KList<IrisLootTable> tables = getLootTables(rx, block, mc);
|
|
||||||
|
|
||||||
try {
|
|
||||||
Bukkit.getPluginManager().callEvent(new IrisLootEvent(this, block, slot, tables));
|
|
||||||
if (tables.isEmpty()) return;
|
|
||||||
InventoryHolder m = (InventoryHolder) block.getState();
|
|
||||||
addItems(false, m.getInventory(), rx, tables, slot, c.getWorld(), x, y, z, 15);
|
|
||||||
|
|
||||||
} catch (Throwable e) {
|
|
||||||
IrisLogging.reportError(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
block.setType(Material.AIR, false);
|
|
||||||
block.setBlockData(data, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
default void scramble(Inventory inventory, RNG rng) {
|
|
||||||
org.bukkit.inventory.ItemStack[] items = inventory.getContents();
|
|
||||||
org.bukkit.inventory.ItemStack[] nitems = new org.bukkit.inventory.ItemStack[inventory.getSize()];
|
|
||||||
System.arraycopy(items, 0, nitems, 0, items.length);
|
|
||||||
boolean packedFull = false;
|
|
||||||
|
|
||||||
splitting:
|
|
||||||
for (int i = 0; i < nitems.length; i++) {
|
|
||||||
ItemStack is = nitems[i];
|
|
||||||
|
|
||||||
if (is != null && is.getAmount() > 1 && !packedFull) {
|
|
||||||
for (int j = 0; j < nitems.length; j++) {
|
|
||||||
if (nitems[j] == null) {
|
|
||||||
int take = rng.nextInt(is.getAmount());
|
|
||||||
take = take == 0 ? 1 : take;
|
|
||||||
is.setAmount(is.getAmount() - take);
|
|
||||||
nitems[j] = is.clone();
|
|
||||||
nitems[j].setAmount(take);
|
|
||||||
continue splitting;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
packedFull = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = nitems.length; i > 1; i--) {
|
|
||||||
int j = rng.nextInt(i);
|
|
||||||
ItemStack tmp = nitems[i - 1];
|
|
||||||
nitems[i - 1] = nitems[j];
|
|
||||||
nitems[j] = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
inventory.setContents(nitems);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default void injectTables(KList<IrisLootTable> list, IrisLootReference r, boolean fallback) {
|
default void injectTables(KList<IrisLootTable> list, IrisLootReference r, boolean fallback) {
|
||||||
if (r.getMode().equals(IrisLootMode.FALLBACK) && !fallback)
|
if (r.getMode().equals(IrisLootMode.FALLBACK) && !fallback)
|
||||||
@@ -588,101 +326,6 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
|
|||||||
list.addAll(r.getLootTables(getComplex()));
|
list.addAll(r.getLootTables(getComplex()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@BlockCoordinates
|
|
||||||
@Override
|
|
||||||
default KList<IrisLootTable> getLootTables(RNG rng, Block b) {
|
|
||||||
MantleChunk<Matter> mc = getMantle().getMantle().getChunk(b.getChunk()).use();
|
|
||||||
try {
|
|
||||||
return getLootTables(rng, b, mc);
|
|
||||||
} finally {
|
|
||||||
mc.release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@BlockCoordinates
|
|
||||||
default KList<IrisLootTable> getLootTables(RNG rng, Block b, MantleChunk<Matter> mc) {
|
|
||||||
int rx = b.getX();
|
|
||||||
int rz = b.getZ();
|
|
||||||
int ry = b.getY() - getWorld().minHeight();
|
|
||||||
double he = getComplex().getHeightStream().get(rx, rz);
|
|
||||||
KList<IrisLootTable> tables = new KList<>();
|
|
||||||
|
|
||||||
PlacedObject po = getObjectPlacement(rx, ry, rz, mc);
|
|
||||||
if (po != null && po.getPlacement() != null) {
|
|
||||||
if (BukkitBlockResolution.isStorageChest(b.getBlockData())) {
|
|
||||||
IrisLootTable table = po.getPlacement().getTable(BukkitBlockState.of(b.getBlockData()), getData());
|
|
||||||
if (table != null) {
|
|
||||||
tables.add(table);
|
|
||||||
if (po.getPlacement().isOverrideGlobalLoot()) {
|
|
||||||
return new KList<>(table);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IrisRegion region = getComplex().getRegionStream().get(rx, rz);
|
|
||||||
IrisBiome biomeSurface = getComplex().getTrueBiomeStream().get(rx, rz);
|
|
||||||
IrisBiome biomeUnder = ry < he ? getCaveBiome(rx, ry, rz) : biomeSurface;
|
|
||||||
|
|
||||||
double multiplier = 1D * getDimension().getLoot().getMultiplier() * region.getLoot().getMultiplier() * biomeSurface.getLoot().getMultiplier() * biomeUnder.getLoot().getMultiplier();
|
|
||||||
boolean fallback = tables.isEmpty();
|
|
||||||
injectTables(tables, getDimension().getLoot(), fallback);
|
|
||||||
injectTables(tables, region.getLoot(), fallback);
|
|
||||||
injectTables(tables, biomeSurface.getLoot(), fallback);
|
|
||||||
injectTables(tables, biomeUnder.getLoot(), fallback);
|
|
||||||
|
|
||||||
if (tables.isNotEmpty()) {
|
|
||||||
int target = (int) Math.round(tables.size() * multiplier);
|
|
||||||
|
|
||||||
while (tables.size() < target && tables.isNotEmpty()) {
|
|
||||||
tables.add(tables.get(rng.i(tables.size() - 1)));
|
|
||||||
}
|
|
||||||
|
|
||||||
while (tables.size() > target && tables.isNotEmpty()) {
|
|
||||||
tables.remove(rng.i(tables.size() - 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return tables;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
default void addItems(boolean debug, Inventory inv, RNG rng, KList<IrisLootTable> tables, InventorySlotType slot, World world, int x, int y, int z, int mgf) {
|
|
||||||
KList<ItemStack> items = new KList<>();
|
|
||||||
|
|
||||||
for (IrisLootTable i : tables) {
|
|
||||||
if (i == null)
|
|
||||||
continue;
|
|
||||||
items.addAll(i.getLoot(debug, rng, slot, world, x, y, z));
|
|
||||||
}
|
|
||||||
if (IrisLootEvent.callLootEvent(items, inv, world, x, y, z))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (PaperLib.isPaper() && getWorld().hasRealWorld()) {
|
|
||||||
PaperLib.getChunkAtAsync(getWorld().realWorld(), x >> 4, z >> 4).thenAccept((c) -> {
|
|
||||||
Runnable r = () -> {
|
|
||||||
for (ItemStack i : items) {
|
|
||||||
inv.addItem(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
scramble(inv, rng);
|
|
||||||
};
|
|
||||||
|
|
||||||
if (Bukkit.isPrimaryThread()) {
|
|
||||||
r.run();
|
|
||||||
} else {
|
|
||||||
J.s(r);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
for (ItemStack i : items) {
|
|
||||||
inv.addItem(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
scramble(inv, rng);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EngineEffects getEffects();
|
EngineEffects getEffects();
|
||||||
|
|
||||||
default MultiBurst burst() {
|
default MultiBurst burst() {
|
||||||
@@ -693,16 +336,6 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
|
|||||||
burst().lazy(() -> getMantle().trim(10));
|
burst().lazy(() -> getMantle().trim(10));
|
||||||
}
|
}
|
||||||
|
|
||||||
@BlockCoordinates
|
|
||||||
default IrisBiome getBiome(Location l) {
|
|
||||||
return getBiome(l.getBlockX(), l.getBlockY() - getWorld().minHeight(), l.getBlockZ());
|
|
||||||
}
|
|
||||||
|
|
||||||
@BlockCoordinates
|
|
||||||
default IrisRegion getRegion(Location l) {
|
|
||||||
return getRegion(l.getBlockX(), l.getBlockZ());
|
|
||||||
}
|
|
||||||
|
|
||||||
IrisBiome getFocus();
|
IrisBiome getFocus();
|
||||||
|
|
||||||
IrisRegion getFocusRegion();
|
IrisRegion getFocusRegion();
|
||||||
@@ -710,14 +343,6 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
|
|||||||
|
|
||||||
IrisEngineData getEngineData();
|
IrisEngineData getEngineData();
|
||||||
|
|
||||||
default IrisBiome getSurfaceBiome(Chunk c) {
|
|
||||||
return getSurfaceBiome((c.getX() << 4) + 8, (c.getZ() << 4) + 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
default IrisRegion getRegion(Chunk c) {
|
|
||||||
return getRegion((c.getX() << 4) + 8, (c.getZ() << 4) + 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
default KList<IrisBiome> getAllBiomes() {
|
default KList<IrisBiome> getAllBiomes() {
|
||||||
KMap<String, IrisBiome> v = new KMap<>();
|
KMap<String, IrisBiome> v = new KMap<>();
|
||||||
|
|
||||||
@@ -981,107 +606,6 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
|
|||||||
|
|
||||||
int getCacheID();
|
int getCacheID();
|
||||||
|
|
||||||
default IrisBiome getBiomeOrMantle(Location l) {
|
|
||||||
return getBiomeOrMantle(l.getBlockX(), l.getBlockY(), l.getBlockZ());
|
|
||||||
}
|
|
||||||
|
|
||||||
default void gotoBiome(IrisBiome biome, Player player, boolean teleport) {
|
|
||||||
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 -> {
|
|
||||||
IrisLogging.reportError(throwable);
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} catch (Throwable throwable) {
|
|
||||||
IrisLogging.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) {
|
|
||||||
IrisLogging.reportError(throwable);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
default void gotoObject(String s, Player player, boolean teleport) {
|
|
||||||
find(Locator.object(s), player, teleport, "Object " + s);
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean hasObjectPlacement(String objectKey) {
|
default boolean hasObjectPlacement(String objectKey) {
|
||||||
String normalizedObjectKey = normalizeObjectPlacementKey(objectKey);
|
String normalizedObjectKey = normalizeObjectPlacementKey(objectKey);
|
||||||
if (normalizedObjectKey.isBlank()) {
|
if (normalizedObjectKey.isBlank()) {
|
||||||
@@ -1100,23 +624,6 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
|
|||||||
return !regionKeys.isEmpty();
|
return !regionKeys.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
default void gotoRegion(IrisRegion r, Player player, boolean teleport) {
|
|
||||||
if (!getDimension().getRegions().contains(r.getLoadKey())) {
|
|
||||||
player.sendMessage(C.RED + r.getName() + " is not defined in the dimension!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
find(Locator.region(r.getLoadKey()), player, teleport, "Region " + r.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
default void gotoPOI(String type, Player p, boolean teleport) {
|
|
||||||
find(Locator.poi(type), p, teleport, "POI " + type);
|
|
||||||
}
|
|
||||||
|
|
||||||
default void gotoStructure(String key, Player player, boolean teleport) {
|
|
||||||
find(Locator.structure(key), player, teleport, "Structure " + key);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean containsObjectPlacement(KList<IrisObjectPlacement> placements, String normalizedObjectKey) {
|
private static boolean containsObjectPlacement(KList<IrisObjectPlacement> placements, String normalizedObjectKey) {
|
||||||
if (placements == null || placements.isEmpty() || normalizedObjectKey.isBlank()) {
|
if (placements == null || placements.isEmpty() || normalizedObjectKey.isBlank()) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
package art.arcane.iris.engine.framework;
|
package art.arcane.iris.engine.framework;
|
||||||
|
|
||||||
import art.arcane.iris.core.IrisSettings;
|
import art.arcane.iris.core.IrisSettings;
|
||||||
|
import art.arcane.iris.engine.platform.EngineBukkitOps;
|
||||||
import art.arcane.iris.engine.object.IrisBiome;
|
import art.arcane.iris.engine.object.IrisBiome;
|
||||||
import art.arcane.iris.engine.object.IrisEffect;
|
import art.arcane.iris.engine.object.IrisEffect;
|
||||||
import art.arcane.iris.engine.object.IrisRegion;
|
import art.arcane.iris.engine.object.IrisRegion;
|
||||||
@@ -87,8 +88,8 @@ public class EnginePlayer {
|
|||||||
if (ticksSinceLastSample() > 55 && current.distanceSquared(lastLocation) > 9 * 9) {
|
if (ticksSinceLastSample() > 55 && current.distanceSquared(lastLocation) > 9 * 9) {
|
||||||
lastLocation = current;
|
lastLocation = current;
|
||||||
lastSample = M.ms();
|
lastSample = M.ms();
|
||||||
biome = engine.getBiome(current);
|
biome = EngineBukkitOps.getBiome(engine, current);
|
||||||
region = engine.getRegion(current);
|
region = EngineBukkitOps.getRegion(engine, current);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
|
|||||||
@@ -18,21 +18,10 @@
|
|||||||
|
|
||||||
package art.arcane.iris.engine.framework;
|
package art.arcane.iris.engine.framework;
|
||||||
|
|
||||||
import art.arcane.iris.engine.object.InventorySlotType;
|
|
||||||
import art.arcane.iris.engine.object.IrisLootReference;
|
import art.arcane.iris.engine.object.IrisLootReference;
|
||||||
import art.arcane.iris.engine.object.IrisLootTable;
|
import art.arcane.iris.engine.object.IrisLootTable;
|
||||||
import art.arcane.volmlib.util.collection.KList;
|
import art.arcane.volmlib.util.collection.KList;
|
||||||
import art.arcane.volmlib.util.math.RNG;
|
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.block.Block;
|
|
||||||
import org.bukkit.inventory.Inventory;
|
|
||||||
|
|
||||||
public interface LootProvider {
|
public interface LootProvider {
|
||||||
void scramble(Inventory inventory, RNG rng);
|
|
||||||
|
|
||||||
void injectTables(KList<IrisLootTable> list, IrisLootReference r, boolean fallback);
|
void injectTables(KList<IrisLootTable> list, IrisLootReference r, boolean fallback);
|
||||||
|
|
||||||
KList<IrisLootTable> getLootTables(RNG rng, Block b);
|
|
||||||
|
|
||||||
void addItems(boolean debug, Inventory inv, RNG rng, KList<IrisLootTable> tables, InventorySlotType slot, World world, int x, int y, int z, int mgf);
|
|
||||||
}
|
}
|
||||||
@@ -8,6 +8,7 @@ import art.arcane.iris.engine.data.cache.Cache;
|
|||||||
import art.arcane.iris.engine.framework.Engine;
|
import art.arcane.iris.engine.framework.Engine;
|
||||||
import art.arcane.iris.core.events.IrisLootEvent;
|
import art.arcane.iris.core.events.IrisLootEvent;
|
||||||
import art.arcane.iris.engine.mantle.EngineMantle;
|
import art.arcane.iris.engine.mantle.EngineMantle;
|
||||||
|
import art.arcane.iris.engine.platform.EngineBukkitOps;
|
||||||
import art.arcane.iris.engine.object.IObjectPlacer;
|
import art.arcane.iris.engine.object.IObjectPlacer;
|
||||||
import art.arcane.iris.engine.object.InventorySlotType;
|
import art.arcane.iris.engine.object.InventorySlotType;
|
||||||
import art.arcane.iris.engine.object.IrisLootTable;
|
import art.arcane.iris.engine.object.IrisLootTable;
|
||||||
@@ -71,7 +72,7 @@ public class WorldObjectPlacer implements IObjectPlacer {
|
|||||||
|
|
||||||
if (slot != null) {
|
if (slot != null) {
|
||||||
RNG rx = new RNG(Cache.key(x, z));
|
RNG rx = new RNG(Cache.key(x, z));
|
||||||
KList<IrisLootTable> tables = engine.getLootTables(rx, block);
|
KList<IrisLootTable> tables = EngineBukkitOps.getLootTables(engine, rx, block);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Bukkit.getPluginManager().callEvent(new IrisLootEvent(engine, block, slot, tables));
|
Bukkit.getPluginManager().callEvent(new IrisLootEvent(engine, block, slot, tables));
|
||||||
@@ -83,7 +84,7 @@ public class WorldObjectPlacer implements IObjectPlacer {
|
|||||||
if (tables.isEmpty())
|
if (tables.isEmpty())
|
||||||
return;
|
return;
|
||||||
InventoryHolder m = (InventoryHolder) block.getState();
|
InventoryHolder m = (InventoryHolder) block.getState();
|
||||||
engine.addItems(false, m.getInventory(), rx, tables, slot, world, x, y, z, 15);
|
EngineBukkitOps.addItems(engine, false, m.getInventory(), rx, tables, slot, world, x, y, z, 15);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
IrisLogging.reportError(e);
|
IrisLogging.reportError(e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -179,6 +179,12 @@ public class IrisEffect {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final class BukkitFx {
|
||||||
|
private static void run(Player p, Runnable r) {
|
||||||
|
J.runEntity(p, r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void apply(Player p, Engine g) {
|
public void apply(Player p, Engine g) {
|
||||||
if (!canTick()) {
|
if (!canTick()) {
|
||||||
return;
|
return;
|
||||||
@@ -188,7 +194,7 @@ public class IrisEffect {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
J.runEntity(p, () -> {
|
BukkitFx.run(p, () -> {
|
||||||
if (sound != null) {
|
if (sound != null) {
|
||||||
Location part = p.getLocation().clone().add(RNG.r.i(-soundDistance, soundDistance), RNG.r.i(-soundDistance, soundDistance), RNG.r.i(-soundDistance, soundDistance));
|
Location part = p.getLocation().clone().add(RNG.r.i(-soundDistance, soundDistance), RNG.r.i(-soundDistance, soundDistance), RNG.r.i(-soundDistance, soundDistance));
|
||||||
p.playSound(part, getSound(), (float) volume, (float) RNG.r.d(minPitch, maxPitch));
|
p.playSound(part, getSound(), (float) volume, (float) RNG.r.d(minPitch, maxPitch));
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import art.arcane.iris.core.link.Identifier;
|
|||||||
import art.arcane.iris.core.loader.IrisRegistrant;
|
import art.arcane.iris.core.loader.IrisRegistrant;
|
||||||
import art.arcane.iris.core.service.ExternalDataSVC;
|
import art.arcane.iris.core.service.ExternalDataSVC;
|
||||||
import art.arcane.iris.engine.framework.Engine;
|
import art.arcane.iris.engine.framework.Engine;
|
||||||
|
import art.arcane.iris.engine.platform.EngineBukkitOps;
|
||||||
import art.arcane.iris.engine.object.annotations.*;
|
import art.arcane.iris.engine.object.annotations.*;
|
||||||
import art.arcane.iris.platform.bukkit.BukkitPlatform;
|
import art.arcane.iris.platform.bukkit.BukkitPlatform;
|
||||||
import art.arcane.iris.platform.bukkit.BukkitWorld;
|
import art.arcane.iris.platform.bukkit.BukkitWorld;
|
||||||
@@ -247,34 +248,7 @@ public class IrisEntity extends IrisRegistrant {
|
|||||||
Lootable l = (Lootable) e;
|
Lootable l = (Lootable) e;
|
||||||
|
|
||||||
if (getLoot().getTables().isNotEmpty()) {
|
if (getLoot().getTables().isNotEmpty()) {
|
||||||
Location finalAt = at;
|
BukkitOps.bindLoot(this, gen, l, at, rng);
|
||||||
l.setLootTable(new LootTable() {
|
|
||||||
@Override
|
|
||||||
public NamespacedKey getKey() {
|
|
||||||
return new NamespacedKey("iris", "loot-" + IrisEntity.this.hashCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<ItemStack> populateLoot(Random random, LootContext context) {
|
|
||||||
KList<ItemStack> items = new KList<>();
|
|
||||||
|
|
||||||
for (String fi : getLoot().getTables()) {
|
|
||||||
IrisLootTable i = gen.getData().getLootLoader().load(fi);
|
|
||||||
items.addAll(i.getLoot(gen.isStudio(), rng.nextParallelRNG(345911), InventorySlotType.STORAGE, finalAt.getWorld(), finalAt.getBlockX(), finalAt.getBlockY(), finalAt.getBlockZ()));
|
|
||||||
}
|
|
||||||
|
|
||||||
return items;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void fillInventory(Inventory inventory, Random random, LootContext context) {
|
|
||||||
for (ItemStack i : populateLoot(random, context)) {
|
|
||||||
inventory.addItem(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
gen.scramble(inventory, rng);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -326,7 +300,7 @@ public class IrisEntity extends IrisRegistrant {
|
|||||||
if (e instanceof Villager) {
|
if (e instanceof Villager) {
|
||||||
Villager villager = (Villager) e;
|
Villager villager = (Villager) e;
|
||||||
villager.setRemoveWhenFarAway(false);
|
villager.setRemoveWhenFarAway(false);
|
||||||
J.runEntity(villager, () -> villager.setPersistent(true), 1);
|
BukkitOps.persistVillager(villager);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e instanceof Mob) {
|
if (e instanceof Mob) {
|
||||||
@@ -458,6 +432,42 @@ public class IrisEntity extends IrisRegistrant {
|
|||||||
return specialType != null && !specialType.equals("");
|
return specialType != null && !specialType.equals("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final class BukkitOps {
|
||||||
|
private static void persistVillager(Villager villager) {
|
||||||
|
J.runEntity(villager, () -> villager.setPersistent(true), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void bindLoot(IrisEntity entity, Engine gen, Lootable l, Location finalAt, RNG rng) {
|
||||||
|
l.setLootTable(new LootTable() {
|
||||||
|
@Override
|
||||||
|
public NamespacedKey getKey() {
|
||||||
|
return new NamespacedKey("iris", "loot-" + entity.hashCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<ItemStack> populateLoot(Random random, LootContext context) {
|
||||||
|
KList<ItemStack> items = new KList<>();
|
||||||
|
|
||||||
|
for (String fi : entity.getLoot().getTables()) {
|
||||||
|
IrisLootTable i = gen.getData().getLootLoader().load(fi);
|
||||||
|
items.addAll(i.getLoot(gen.isStudio(), rng.nextParallelRNG(345911), InventorySlotType.STORAGE, finalAt.getWorld(), finalAt.getBlockX(), finalAt.getBlockY(), finalAt.getBlockZ()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fillInventory(Inventory inventory, Random random, LootContext context) {
|
||||||
|
for (ItemStack i : populateLoot(random, context)) {
|
||||||
|
inventory.addItem(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
EngineBukkitOps.scramble(gen, inventory, rng);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getFolderName() {
|
public String getFolderName() {
|
||||||
return "entities";
|
return "entities";
|
||||||
|
|||||||
@@ -1059,8 +1059,8 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (placer.isPreventingDecay() && ((BlockData) data.nativeHandle()) instanceof Leaves && !((Leaves) ((BlockData) data.nativeHandle())).isPersistent()) {
|
if (placer.isPreventingDecay() && ((BlockData) data.nativeHandle()) instanceof Leaves && !((Leaves) ((BlockData) data.nativeHandle())).isPersistent()) {
|
||||||
Leaves leaves = (Leaves) ((BlockData) data.nativeHandle()).clone();
|
BlockData leaves = ((BlockData) data.nativeHandle()).clone();
|
||||||
leaves.setPersistent(true);
|
((Leaves) leaves).setPersistent(true);
|
||||||
data = BukkitBlockState.of(leaves);
|
data = BukkitBlockState.of(leaves);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1119,13 +1119,14 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (((BlockData) data.nativeHandle()) instanceof Waterlogged && shouldAutoWaterlogBlock(placer, config, yv, xx, yy, zz)) {
|
if (((BlockData) data.nativeHandle()) instanceof Waterlogged && shouldAutoWaterlogBlock(placer, config, yv, xx, yy, zz)) {
|
||||||
Waterlogged waterlogged = (Waterlogged) ((BlockData) data.nativeHandle()).clone();
|
BlockData waterlogged = ((BlockData) data.nativeHandle()).clone();
|
||||||
waterlogged.setWaterlogged(true);
|
((Waterlogged) waterlogged).setWaterlogged(true);
|
||||||
data = BukkitBlockState.of(waterlogged);
|
data = BukkitBlockState.of(waterlogged);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BukkitBlockResolution.isVineBlock((BlockData) data.nativeHandle())) {
|
if (BukkitBlockResolution.isVineBlock((BlockData) data.nativeHandle())) {
|
||||||
MultipleFacing f = (MultipleFacing) ((BlockData) data.nativeHandle()).clone();
|
BlockData fData = ((BlockData) data.nativeHandle()).clone();
|
||||||
|
MultipleFacing f = (MultipleFacing) fData;
|
||||||
boolean facesChanged = false;
|
boolean facesChanged = false;
|
||||||
for (BlockFace face : f.getAllowedFaces()) {
|
for (BlockFace face : f.getAllowedFaces()) {
|
||||||
PlatformBlockState facingState = placer.get(xx + face.getModX(), yy + face.getModY(), zz + face.getModZ());
|
PlatformBlockState facingState = placer.get(xx + face.getModX(), yy + face.getModY(), zz + face.getModZ());
|
||||||
@@ -1136,7 +1137,7 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (facesChanged) {
|
if (facesChanged) {
|
||||||
data = BukkitBlockState.of(f);
|
data = BukkitBlockState.of(fData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1344,8 +1345,8 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
int highest = placer.getHighest(xx, zz, getLoader(), true);
|
int highest = placer.getHighest(xx, zz, getLoader(), true);
|
||||||
|
|
||||||
if (((BlockData) d.nativeHandle()) instanceof Waterlogged && shouldAutoWaterlogBlock(placer, config, yv, xx, highest, zz)) {
|
if (((BlockData) d.nativeHandle()) instanceof Waterlogged && shouldAutoWaterlogBlock(placer, config, yv, xx, highest, zz)) {
|
||||||
Waterlogged waterlogged = (Waterlogged) ((BlockData) d.nativeHandle()).clone();
|
BlockData waterlogged = ((BlockData) d.nativeHandle()).clone();
|
||||||
waterlogged.setWaterlogged(true);
|
((Waterlogged) waterlogged).setWaterlogged(true);
|
||||||
d = BukkitBlockState.of(waterlogged);
|
d = BukkitBlockState.of(waterlogged);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1385,7 +1386,8 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (BukkitBlockResolution.isVineBlock((BlockData) d.nativeHandle())) {
|
if (BukkitBlockResolution.isVineBlock((BlockData) d.nativeHandle())) {
|
||||||
MultipleFacing f = (MultipleFacing) ((BlockData) d.nativeHandle()).clone();
|
BlockData fData = ((BlockData) d.nativeHandle()).clone();
|
||||||
|
MultipleFacing f = (MultipleFacing) fData;
|
||||||
boolean facesChanged = false;
|
boolean facesChanged = false;
|
||||||
for (BlockFace face : f.getAllowedFaces()) {
|
for (BlockFace face : f.getAllowedFaces()) {
|
||||||
PlatformBlockState facingState = placer.get(xx + face.getModX(), j + face.getModY(), zz + face.getModZ());
|
PlatformBlockState facingState = placer.get(xx + face.getModX(), j + face.getModY(), zz + face.getModZ());
|
||||||
@@ -1396,7 +1398,7 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (facesChanged) {
|
if (facesChanged) {
|
||||||
d = BukkitBlockState.of(f);
|
d = BukkitBlockState.of(fData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
placer.set(xx, j, zz, d);
|
placer.set(xx, j, zz, d);
|
||||||
|
|||||||
@@ -47,7 +47,9 @@ import java.util.Map;
|
|||||||
@Desc("Configures rotation for iris")
|
@Desc("Configures rotation for iris")
|
||||||
@Data
|
@Data
|
||||||
public class IrisObjectRotation {
|
public class IrisObjectRotation {
|
||||||
private static final List<BlockFace> WALL_FACES = List.of(BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST);
|
private static final class Faces {
|
||||||
|
private static final List<BlockFace> WALL_FACES = List.of(BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST);
|
||||||
|
}
|
||||||
|
|
||||||
@Desc("If this rotator is enabled or not")
|
@Desc("If this rotator is enabled or not")
|
||||||
private boolean enabled = true;
|
private boolean enabled = true;
|
||||||
@@ -332,17 +334,17 @@ public class IrisObjectRotation {
|
|||||||
} else if (d instanceof Wall wall) {
|
} else if (d instanceof Wall wall) {
|
||||||
KMap<BlockFace, Wall.Height> faces = new KMap<>();
|
KMap<BlockFace, Wall.Height> faces = new KMap<>();
|
||||||
|
|
||||||
for (BlockFace i : WALL_FACES) {
|
for (BlockFace i : Faces.WALL_FACES) {
|
||||||
Wall.Height h = wall.getHeight(i);
|
Wall.Height h = wall.getHeight(i);
|
||||||
IrisBlockVector bv = new IrisBlockVector(i.getModX(), i.getModY(), i.getModZ());
|
IrisBlockVector bv = new IrisBlockVector(i.getModX(), i.getModY(), i.getModZ());
|
||||||
bv = rotate(bv.clone(), spinx, spiny, spinz);
|
bv = rotate(bv.clone(), spinx, spiny, spinz);
|
||||||
BlockFace r = getFace(bv);
|
BlockFace r = getFace(bv);
|
||||||
if (WALL_FACES.contains(r)) {
|
if (Faces.WALL_FACES.contains(r)) {
|
||||||
faces.put(r, h);
|
faces.put(r, h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (BlockFace i : WALL_FACES) {
|
for (BlockFace i : Faces.WALL_FACES) {
|
||||||
wall.setHeight(i, faces.getOrDefault(i, Wall.Height.NONE));
|
wall.setHeight(i, faces.getOrDefault(i, Wall.Height.NONE));
|
||||||
}
|
}
|
||||||
} else if (d instanceof RedstoneWire wire) {
|
} else if (d instanceof RedstoneWire wire) {
|
||||||
|
|||||||
@@ -36,18 +36,12 @@ import java.util.stream.StreamSupport;
|
|||||||
@ToString
|
@ToString
|
||||||
@EqualsAndHashCode(callSuper = false)
|
@EqualsAndHashCode(callSuper = false)
|
||||||
public class LegacyTileData extends TileData {
|
public class LegacyTileData extends TileData {
|
||||||
private static final Map<Integer, Pair<Builder, IOFunction<DataInputStream, Handler>>> legacy = Map.of(
|
|
||||||
0, new Pair<>(SignHandler::fromBukkit, SignHandler::new),
|
|
||||||
1, new Pair<>(SpawnerHandler::fromBukkit, SpawnerHandler::new),
|
|
||||||
2, new Pair<>(BannerHandler::fromBukkit, BannerHandler::new),
|
|
||||||
3, new Pair<>(LootableHandler::fromBukkit, LootableHandler::new));
|
|
||||||
private static final AtomicCache<Tag<Material>> SIGNS = new AtomicCache<>();
|
|
||||||
private final int id;
|
private final int id;
|
||||||
private final Handler handler;
|
private final Handler handler;
|
||||||
|
|
||||||
public LegacyTileData(DataInputStream in) throws IOException {
|
public LegacyTileData(DataInputStream in) throws IOException {
|
||||||
id = in.readShort();
|
id = in.readShort();
|
||||||
var factory = legacy.get(id);
|
Pair<Builder, IOFunction<DataInputStream, Handler>> factory = Handlers.LEGACY.get(id);
|
||||||
if (factory == null)
|
if (factory == null)
|
||||||
throw new IOException("Unknown tile type: " + id);
|
throw new IOException("Unknown tile type: " + id);
|
||||||
handler = factory.getB().apply(in);
|
handler = factory.getB().apply(in);
|
||||||
@@ -60,16 +54,24 @@ public class LegacyTileData extends TileData {
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static LegacyTileData fromBukkit(@NonNull BlockState tileState) {
|
public static LegacyTileData fromBukkit(@NonNull BlockState tileState) {
|
||||||
var type = tileState.getType();
|
Material type = tileState.getType();
|
||||||
for (var id : legacy.keySet()) {
|
for (Integer id : Handlers.LEGACY.keySet()) {
|
||||||
var factory = legacy.get(id);
|
Pair<Builder, IOFunction<DataInputStream, Handler>> factory = Handlers.LEGACY.get(id);
|
||||||
var handler = factory.getA().apply(tileState, type);
|
Handler handler = factory.getA().apply(tileState, type);
|
||||||
if (handler != null)
|
if (handler != null)
|
||||||
return new LegacyTileData(id, handler);
|
return new LegacyTileData(id, handler);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final class Handlers {
|
||||||
|
private static final Map<Integer, Pair<Builder, IOFunction<DataInputStream, Handler>>> LEGACY = Map.of(
|
||||||
|
0, new Pair<>(SignHandler::fromBukkit, SignHandler::new),
|
||||||
|
1, new Pair<>(SpawnerHandler::fromBukkit, SpawnerHandler::new),
|
||||||
|
2, new Pair<>(BannerHandler::fromBukkit, BannerHandler::new),
|
||||||
|
3, new Pair<>(LootableHandler::fromBukkit, LootableHandler::new));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NonNull KMap<String, Object> getProperties() {
|
public @NonNull KMap<String, Object> getProperties() {
|
||||||
return new KMap<>();
|
return new KMap<>();
|
||||||
@@ -411,34 +413,42 @@ public class LegacyTileData extends TileData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static Tag<Material> signsTag() {
|
private static Tag<Material> signsTag() {
|
||||||
return SIGNS.aquire(() -> {
|
return SignTags.get();
|
||||||
var signs = Bukkit.getTag("blocks", NamespacedKey.minecraft("all_signs"), Material.class);
|
}
|
||||||
if (signs != null)
|
|
||||||
return signs;
|
private static final class SignTags {
|
||||||
return new Tag<>() {
|
private static final AtomicCache<Tag<Material>> SIGNS = new AtomicCache<>();
|
||||||
@Override
|
|
||||||
public boolean isTagged(@NotNull Material item) {
|
private static Tag<Material> get() {
|
||||||
NamespacedKey key = KeyedType.getKey(item);
|
return SIGNS.aquire(() -> {
|
||||||
if (key != null) {
|
Tag<Material> signs = Bukkit.getTag("blocks", NamespacedKey.minecraft("all_signs"), Material.class);
|
||||||
return key.getKey().endsWith("_sign");
|
if (signs != null)
|
||||||
|
return signs;
|
||||||
|
return new Tag<>() {
|
||||||
|
@Override
|
||||||
|
public boolean isTagged(@NotNull Material item) {
|
||||||
|
NamespacedKey key = KeyedType.getKey(item);
|
||||||
|
if (key != null) {
|
||||||
|
return key.getKey().endsWith("_sign");
|
||||||
|
}
|
||||||
|
return item.name().toLowerCase(Locale.ROOT).endsWith("_sign");
|
||||||
}
|
}
|
||||||
return item.name().toLowerCase(Locale.ROOT).endsWith("_sign");
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Set<Material> getValues() {
|
public Set<Material> getValues() {
|
||||||
return StreamSupport.stream(Registry.MATERIAL.spliterator(), false)
|
return StreamSupport.stream(Registry.MATERIAL.spliterator(), false)
|
||||||
.filter(this::isTagged)
|
.filter(this::isTagged)
|
||||||
.collect(Collectors.toUnmodifiableSet());
|
.collect(Collectors.toUnmodifiableSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public NamespacedKey getKey() {
|
public NamespacedKey getKey() {
|
||||||
return NamespacedKey.minecraft("all_signs");
|
return NamespacedKey.minecraft("all_signs");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,539 @@
|
|||||||
|
/*
|
||||||
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package art.arcane.iris.engine.platform;
|
||||||
|
|
||||||
|
import art.arcane.iris.core.events.IrisLootEvent;
|
||||||
|
import art.arcane.iris.core.link.Identifier;
|
||||||
|
import art.arcane.iris.core.service.ExternalDataSVC;
|
||||||
|
import art.arcane.iris.core.tools.IrisToolbelt;
|
||||||
|
import art.arcane.iris.engine.data.cache.Cache;
|
||||||
|
import art.arcane.iris.engine.framework.Engine;
|
||||||
|
import art.arcane.iris.engine.framework.Locator;
|
||||||
|
import art.arcane.iris.engine.framework.PlacedObject;
|
||||||
|
import art.arcane.iris.engine.framework.WrongEngineBroException;
|
||||||
|
import art.arcane.iris.engine.object.InventorySlotType;
|
||||||
|
import art.arcane.iris.engine.object.IrisBiome;
|
||||||
|
import art.arcane.iris.engine.object.IrisLootTable;
|
||||||
|
import art.arcane.iris.engine.object.IrisRegion;
|
||||||
|
import art.arcane.iris.engine.object.TileData;
|
||||||
|
import art.arcane.iris.platform.bukkit.BukkitBlockResolution;
|
||||||
|
import art.arcane.iris.platform.bukkit.BukkitBlockState;
|
||||||
|
import art.arcane.iris.spi.IrisLogging;
|
||||||
|
import art.arcane.iris.spi.IrisServices;
|
||||||
|
import art.arcane.iris.util.common.format.C;
|
||||||
|
import art.arcane.iris.util.common.plugin.VolmitSender;
|
||||||
|
import art.arcane.iris.util.common.reflect.KeyedType;
|
||||||
|
import art.arcane.iris.util.common.scheduling.J;
|
||||||
|
import art.arcane.iris.util.common.scheduling.jobs.SingleJob;
|
||||||
|
import art.arcane.iris.util.project.matter.TileWrapper;
|
||||||
|
import art.arcane.volmlib.util.collection.KList;
|
||||||
|
import art.arcane.volmlib.util.format.Form;
|
||||||
|
import art.arcane.volmlib.util.mantle.flag.MantleFlag;
|
||||||
|
import art.arcane.volmlib.util.mantle.runtime.Mantle;
|
||||||
|
import art.arcane.volmlib.util.mantle.runtime.MantleChunk;
|
||||||
|
import art.arcane.volmlib.util.math.BlockPosition;
|
||||||
|
import art.arcane.volmlib.util.math.M;
|
||||||
|
import art.arcane.volmlib.util.math.Position2;
|
||||||
|
import art.arcane.volmlib.util.math.RNG;
|
||||||
|
import art.arcane.volmlib.util.matter.Matter;
|
||||||
|
import art.arcane.volmlib.util.matter.MatterCavern;
|
||||||
|
import art.arcane.volmlib.util.matter.MatterUpdate;
|
||||||
|
import art.arcane.volmlib.util.scheduling.PrecisionStopwatch;
|
||||||
|
import io.papermc.lib.PaperLib;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Chunk;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.block.BlockFace;
|
||||||
|
import org.bukkit.block.data.BlockData;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.Inventory;
|
||||||
|
import org.bukkit.inventory.InventoryHolder;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
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.AtomicLong;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
public final class EngineBukkitOps {
|
||||||
|
private EngineBukkitOps() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void updateChunk(Engine engine, Chunk c) {
|
||||||
|
for (int x = -1; x <= 1; x++) {
|
||||||
|
for (int z = -1; z <= 1; z++) {
|
||||||
|
if (c.getWorld().isChunkLoaded(c.getX() + x, c.getZ() + z))
|
||||||
|
continue;
|
||||||
|
String msg = "Chunk %s, %s [%s, %s] is not loaded".formatted(c.getX() + x, c.getZ() + z, x, z);
|
||||||
|
IrisLogging.debug(msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Mantle<Matter> mantle = engine.getMantle().getMantle();
|
||||||
|
if (!mantle.isLoaded(c)) {
|
||||||
|
String msg = "Mantle Chunk " + c.getX() + "," + c.getZ() + " is not loaded";
|
||||||
|
IrisLogging.debug(msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!J.isFolia() && !J.isPrimaryThread()) {
|
||||||
|
CompletableFuture<?> scheduled = J.sfut(() -> updateChunk(engine, c));
|
||||||
|
if (scheduled != null) {
|
||||||
|
try {
|
||||||
|
scheduled.join();
|
||||||
|
} catch (Throwable e) {
|
||||||
|
IrisLogging.reportError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MantleChunk<Matter> chunk = mantle.getChunk(c).use();
|
||||||
|
try {
|
||||||
|
Runnable tileTask = () -> {
|
||||||
|
chunk.iterate(TileWrapper.class, (x, y, z, v) -> {
|
||||||
|
Block block = c.getBlock(x & 15, y + engine.getWorld().minHeight(), z & 15);
|
||||||
|
if (!TileData.setTileState(block, v.getData())) {
|
||||||
|
NamespacedKey blockTypeKey = KeyedType.getKey(block.getType());
|
||||||
|
NamespacedKey tileTypeKey = KeyedType.getKey(v.getData().getMaterial());
|
||||||
|
String blockType = blockTypeKey == null ? block.getType().name() : blockTypeKey.toString();
|
||||||
|
String tileType = tileTypeKey == null ? v.getData().getMaterial().name() : tileTypeKey.toString();
|
||||||
|
IrisLogging.warn("Failed to set tile entity data at [%d %d %d | %s] for tile %s!", block.getX(), block.getY(), block.getZ(), blockType, tileType);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Runnable customTask = () -> {
|
||||||
|
chunk.iterate(Identifier.class, (x, y, z, v) -> {
|
||||||
|
IrisServices.get(ExternalDataSVC.class).processUpdate(engine, c.getBlock(x & 15, y + engine.getWorld().minHeight(), z & 15), v);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Runnable updateTask = () -> {
|
||||||
|
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||||
|
int[][] grid = new int[16][16];
|
||||||
|
for (int x = 0; x < 16; x++) {
|
||||||
|
for (int z = 0; z < 16; z++) {
|
||||||
|
grid[x][z] = Integer.MIN_VALUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RNG rng = new RNG(Cache.key(c.getX(), c.getZ()));
|
||||||
|
chunk.iterate(MatterCavern.class, (x, yf, z, v) -> {
|
||||||
|
int y = yf + engine.getWorld().minHeight();
|
||||||
|
x &= 15;
|
||||||
|
z &= 15;
|
||||||
|
Block block = c.getBlock(x, y, z);
|
||||||
|
if (!BukkitBlockResolution.isFluid(block.getBlockData())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
boolean u = BukkitBlockResolution.isAir(block.getRelative(BlockFace.DOWN).getBlockData())
|
||||||
|
|| BukkitBlockResolution.isAir(block.getRelative(BlockFace.WEST).getBlockData())
|
||||||
|
|| BukkitBlockResolution.isAir(block.getRelative(BlockFace.EAST).getBlockData())
|
||||||
|
|| BukkitBlockResolution.isAir(block.getRelative(BlockFace.SOUTH).getBlockData())
|
||||||
|
|| BukkitBlockResolution.isAir(block.getRelative(BlockFace.NORTH).getBlockData());
|
||||||
|
|
||||||
|
if (u) grid[x][z] = Math.max(grid[x][z], y);
|
||||||
|
});
|
||||||
|
|
||||||
|
for (int x = 0; x < 16; x++) {
|
||||||
|
for (int z = 0; z < 16; z++) {
|
||||||
|
if (grid[x][z] == Integer.MIN_VALUE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
update(engine, x, grid[x][z], z, c, chunk, rng);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
chunk.iterate(MatterUpdate.class, (x, yf, z, v) -> {
|
||||||
|
int y = yf + engine.getWorld().minHeight();
|
||||||
|
if (v != null && v.isUpdate()) {
|
||||||
|
update(engine, x, y, z, c, chunk, rng);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
chunk.deleteSlices(MatterUpdate.class);
|
||||||
|
engine.getMetrics().getUpdates().put(p.getMilliseconds());
|
||||||
|
};
|
||||||
|
|
||||||
|
if (shouldRunChunkUpdateInline(c)) {
|
||||||
|
chunk.raiseFlagUnchecked(MantleFlag.ETCHED, () -> {
|
||||||
|
chunk.raiseFlagUnchecked(MantleFlag.TILE, tileTask);
|
||||||
|
chunk.raiseFlagUnchecked(MantleFlag.CUSTOM, customTask);
|
||||||
|
chunk.raiseFlagUnchecked(MantleFlag.UPDATE, updateTask);
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Semaphore semaphore = new Semaphore(1024);
|
||||||
|
chunk.raiseFlagUnchecked(MantleFlag.ETCHED, () -> {
|
||||||
|
chunk.raiseFlagUnchecked(MantleFlag.TILE, run(semaphore, c, tileTask, 0));
|
||||||
|
chunk.raiseFlagUnchecked(MantleFlag.CUSTOM, run(semaphore, c, customTask, 0));
|
||||||
|
chunk.raiseFlagUnchecked(MantleFlag.UPDATE, run(semaphore, c, updateTask, RNG.r.i(1, 20)));
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
semaphore.acquire(1024);
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
IrisLogging.reportError(ex);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
chunk.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean shouldRunChunkUpdateInline(Chunk chunk) {
|
||||||
|
if (chunk == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!J.isFolia()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return J.isOwnedByCurrentRegion(chunk.getWorld(), chunk.getX(), chunk.getZ());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Runnable run(Semaphore semaphore, Chunk contextChunk, Runnable runnable, int delay) {
|
||||||
|
return () -> {
|
||||||
|
try {
|
||||||
|
semaphore.acquire();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
int effectiveDelay = J.isFolia() ? 0 : delay;
|
||||||
|
boolean scheduled = J.runRegion(contextChunk.getWorld(), contextChunk.getX(), contextChunk.getZ(), () -> {
|
||||||
|
try {
|
||||||
|
runnable.run();
|
||||||
|
} finally {
|
||||||
|
semaphore.release();
|
||||||
|
}
|
||||||
|
}, effectiveDelay);
|
||||||
|
|
||||||
|
if (!scheduled) {
|
||||||
|
try {
|
||||||
|
if (J.isPrimaryThread()) {
|
||||||
|
runnable.run();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
semaphore.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void update(Engine engine, int x, int y, int z, Chunk c, MantleChunk<Matter> mc, RNG rf) {
|
||||||
|
Block block = c.getBlock(x, y, z);
|
||||||
|
BlockData data = block.getBlockData();
|
||||||
|
engine.blockUpdatedMetric();
|
||||||
|
if (BukkitBlockResolution.isStorage(data)) {
|
||||||
|
RNG rx = rf.nextParallelRNG(BlockPosition.toLong(x, y, z));
|
||||||
|
InventorySlotType slot = null;
|
||||||
|
|
||||||
|
if (BukkitBlockResolution.isStorageChest(data)) {
|
||||||
|
slot = InventorySlotType.STORAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (slot != null) {
|
||||||
|
KList<IrisLootTable> tables = getLootTables(engine, rx, block, mc);
|
||||||
|
|
||||||
|
try {
|
||||||
|
Bukkit.getPluginManager().callEvent(new IrisLootEvent(engine, block, slot, tables));
|
||||||
|
if (tables.isEmpty()) return;
|
||||||
|
InventoryHolder m = (InventoryHolder) block.getState();
|
||||||
|
addItems(engine, false, m.getInventory(), rx, tables, slot, c.getWorld(), x, y, z, 15);
|
||||||
|
|
||||||
|
} catch (Throwable e) {
|
||||||
|
IrisLogging.reportError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
block.setType(Material.AIR, false);
|
||||||
|
block.setBlockData(data, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void scramble(Engine engine, Inventory inventory, RNG rng) {
|
||||||
|
org.bukkit.inventory.ItemStack[] items = inventory.getContents();
|
||||||
|
org.bukkit.inventory.ItemStack[] nitems = new org.bukkit.inventory.ItemStack[inventory.getSize()];
|
||||||
|
System.arraycopy(items, 0, nitems, 0, items.length);
|
||||||
|
boolean packedFull = false;
|
||||||
|
|
||||||
|
splitting:
|
||||||
|
for (int i = 0; i < nitems.length; i++) {
|
||||||
|
ItemStack is = nitems[i];
|
||||||
|
|
||||||
|
if (is != null && is.getAmount() > 1 && !packedFull) {
|
||||||
|
for (int j = 0; j < nitems.length; j++) {
|
||||||
|
if (nitems[j] == null) {
|
||||||
|
int take = rng.nextInt(is.getAmount());
|
||||||
|
take = take == 0 ? 1 : take;
|
||||||
|
is.setAmount(is.getAmount() - take);
|
||||||
|
nitems[j] = is.clone();
|
||||||
|
nitems[j].setAmount(take);
|
||||||
|
continue splitting;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
packedFull = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = nitems.length; i > 1; i--) {
|
||||||
|
int j = rng.nextInt(i);
|
||||||
|
ItemStack tmp = nitems[i - 1];
|
||||||
|
nitems[i - 1] = nitems[j];
|
||||||
|
nitems[j] = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
inventory.setContents(nitems);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static KList<IrisLootTable> getLootTables(Engine engine, RNG rng, Block b) {
|
||||||
|
MantleChunk<Matter> mc = engine.getMantle().getMantle().getChunk(b.getChunk()).use();
|
||||||
|
try {
|
||||||
|
return getLootTables(engine, rng, b, mc);
|
||||||
|
} finally {
|
||||||
|
mc.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static KList<IrisLootTable> getLootTables(Engine engine, RNG rng, Block b, MantleChunk<Matter> mc) {
|
||||||
|
int rx = b.getX();
|
||||||
|
int rz = b.getZ();
|
||||||
|
int ry = b.getY() - engine.getWorld().minHeight();
|
||||||
|
double he = engine.getComplex().getHeightStream().get(rx, rz);
|
||||||
|
KList<IrisLootTable> tables = new KList<>();
|
||||||
|
|
||||||
|
PlacedObject po = engine.getObjectPlacement(rx, ry, rz, mc);
|
||||||
|
if (po != null && po.getPlacement() != null) {
|
||||||
|
if (BukkitBlockResolution.isStorageChest(b.getBlockData())) {
|
||||||
|
IrisLootTable table = po.getPlacement().getTable(BukkitBlockState.of(b.getBlockData()), engine.getData());
|
||||||
|
if (table != null) {
|
||||||
|
tables.add(table);
|
||||||
|
if (po.getPlacement().isOverrideGlobalLoot()) {
|
||||||
|
return new KList<>(table);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IrisRegion region = engine.getComplex().getRegionStream().get(rx, rz);
|
||||||
|
IrisBiome biomeSurface = engine.getComplex().getTrueBiomeStream().get(rx, rz);
|
||||||
|
IrisBiome biomeUnder = ry < he ? engine.getCaveBiome(rx, ry, rz) : biomeSurface;
|
||||||
|
|
||||||
|
double multiplier = 1D * engine.getDimension().getLoot().getMultiplier() * region.getLoot().getMultiplier() * biomeSurface.getLoot().getMultiplier() * biomeUnder.getLoot().getMultiplier();
|
||||||
|
boolean fallback = tables.isEmpty();
|
||||||
|
engine.injectTables(tables, engine.getDimension().getLoot(), fallback);
|
||||||
|
engine.injectTables(tables, region.getLoot(), fallback);
|
||||||
|
engine.injectTables(tables, biomeSurface.getLoot(), fallback);
|
||||||
|
engine.injectTables(tables, biomeUnder.getLoot(), fallback);
|
||||||
|
|
||||||
|
if (tables.isNotEmpty()) {
|
||||||
|
int target = (int) Math.round(tables.size() * multiplier);
|
||||||
|
|
||||||
|
while (tables.size() < target && tables.isNotEmpty()) {
|
||||||
|
tables.add(tables.get(rng.i(tables.size() - 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
while (tables.size() > target && tables.isNotEmpty()) {
|
||||||
|
tables.remove(rng.i(tables.size() - 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tables;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void addItems(Engine engine, boolean debug, Inventory inv, RNG rng, KList<IrisLootTable> tables, InventorySlotType slot, World world, int x, int y, int z, int mgf) {
|
||||||
|
KList<ItemStack> items = new KList<>();
|
||||||
|
|
||||||
|
for (IrisLootTable i : tables) {
|
||||||
|
if (i == null)
|
||||||
|
continue;
|
||||||
|
items.addAll(i.getLoot(debug, rng, slot, world, x, y, z));
|
||||||
|
}
|
||||||
|
if (IrisLootEvent.callLootEvent(items, inv, world, x, y, z))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (PaperLib.isPaper() && engine.getWorld().hasRealWorld()) {
|
||||||
|
PaperLib.getChunkAtAsync(engine.getWorld().realWorld(), x >> 4, z >> 4).thenAccept((c) -> {
|
||||||
|
Runnable r = () -> {
|
||||||
|
for (ItemStack i : items) {
|
||||||
|
inv.addItem(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
scramble(engine, inv, rng);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (Bukkit.isPrimaryThread()) {
|
||||||
|
r.run();
|
||||||
|
} else {
|
||||||
|
J.s(r);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
for (ItemStack i : items) {
|
||||||
|
inv.addItem(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
scramble(engine, inv, rng);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IrisBiome getBiome(Engine engine, Location l) {
|
||||||
|
return engine.getBiome(l.getBlockX(), l.getBlockY() - engine.getWorld().minHeight(), l.getBlockZ());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IrisRegion getRegion(Engine engine, Location l) {
|
||||||
|
return engine.getRegion(l.getBlockX(), l.getBlockZ());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IrisBiome getBiomeOrMantle(Engine engine, Location l) {
|
||||||
|
return engine.getBiomeOrMantle(l.getBlockX(), l.getBlockY(), l.getBlockZ());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IrisBiome getSurfaceBiome(Engine engine, Chunk c) {
|
||||||
|
return engine.getSurfaceBiome((c.getX() << 4) + 8, (c.getZ() << 4) + 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IrisRegion getRegion(Engine engine, Chunk c) {
|
||||||
|
return engine.getRegion((c.getX() << 4) + 8, (c.getZ() << 4) + 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void gotoBiome(Engine engine, IrisBiome biome, Player player, boolean teleport) {
|
||||||
|
find(Locator.surfaceBiome(biome.getLoadKey()), player, teleport, "Biome " + biome.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void gotoObject(Engine engine, String s, Player player, boolean teleport) {
|
||||||
|
find(Locator.object(s), player, teleport, "Object " + s);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void gotoRegion(Engine engine, IrisRegion r, Player player, boolean teleport) {
|
||||||
|
if (!engine.getDimension().getRegions().contains(r.getLoadKey())) {
|
||||||
|
player.sendMessage(C.RED + r.getName() + " is not defined in the dimension!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
find(Locator.region(r.getLoadKey()), player, teleport, "Region " + r.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void gotoPOI(Engine engine, String type, Player p, boolean teleport) {
|
||||||
|
find(Locator.poi(type), p, teleport, "POI " + type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void gotoStructure(Engine engine, String key, Player player, boolean teleport) {
|
||||||
|
find(Locator.structure(key), player, teleport, "Structure " + key);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 -> {
|
||||||
|
IrisLogging.reportError(throwable);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (Throwable throwable) {
|
||||||
|
IrisLogging.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) {
|
||||||
|
IrisLogging.reportError(throwable);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-1
@@ -20,6 +20,7 @@ package art.arcane.iris.util.common.director.context;
|
|||||||
|
|
||||||
import art.arcane.iris.core.tools.IrisToolbelt;
|
import art.arcane.iris.core.tools.IrisToolbelt;
|
||||||
import art.arcane.iris.engine.object.IrisBiome;
|
import art.arcane.iris.engine.object.IrisBiome;
|
||||||
|
import art.arcane.iris.engine.platform.EngineBukkitOps;
|
||||||
import art.arcane.iris.util.common.director.DirectorContextHandler;
|
import art.arcane.iris.util.common.director.DirectorContextHandler;
|
||||||
import art.arcane.iris.util.common.plugin.VolmitSender;
|
import art.arcane.iris.util.common.plugin.VolmitSender;
|
||||||
|
|
||||||
@@ -32,7 +33,7 @@ public class BiomeContextHandler implements DirectorContextHandler<IrisBiome> {
|
|||||||
if (sender.isPlayer()
|
if (sender.isPlayer()
|
||||||
&& IrisToolbelt.isIrisWorld(sender.player().getWorld())
|
&& IrisToolbelt.isIrisWorld(sender.player().getWorld())
|
||||||
&& IrisToolbelt.access(sender.player().getWorld()).getEngine() != null) {
|
&& IrisToolbelt.access(sender.player().getWorld()).getEngine() != null) {
|
||||||
return IrisToolbelt.access(sender.player().getWorld()).getEngine().getBiomeOrMantle(sender.player().getLocation());
|
return EngineBukkitOps.getBiomeOrMantle(IrisToolbelt.access(sender.player().getWorld()).getEngine(), sender.player().getLocation());
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
+2
-1
@@ -21,6 +21,7 @@ package art.arcane.iris.util.common.director.context;
|
|||||||
import art.arcane.iris.core.tools.IrisToolbelt;
|
import art.arcane.iris.core.tools.IrisToolbelt;
|
||||||
import art.arcane.iris.engine.framework.Engine;
|
import art.arcane.iris.engine.framework.Engine;
|
||||||
import art.arcane.iris.engine.object.IrisGenerator;
|
import art.arcane.iris.engine.object.IrisGenerator;
|
||||||
|
import art.arcane.iris.engine.platform.EngineBukkitOps;
|
||||||
import art.arcane.iris.util.common.director.DirectorContextHandler;
|
import art.arcane.iris.util.common.director.DirectorContextHandler;
|
||||||
import art.arcane.iris.util.common.plugin.VolmitSender;
|
import art.arcane.iris.util.common.plugin.VolmitSender;
|
||||||
|
|
||||||
@@ -36,7 +37,7 @@ public class GeneratorContextHandler implements DirectorContextHandler<IrisGener
|
|||||||
&& IrisToolbelt.isIrisWorld(sender.player().getWorld())
|
&& IrisToolbelt.isIrisWorld(sender.player().getWorld())
|
||||||
&& IrisToolbelt.access(sender.player().getWorld()).getEngine() != null) {
|
&& IrisToolbelt.access(sender.player().getWorld()).getEngine() != null) {
|
||||||
Engine engine = IrisToolbelt.access(sender.player().getWorld()).getEngine();
|
Engine engine = IrisToolbelt.access(sender.player().getWorld()).getEngine();
|
||||||
return engine.getData().getGeneratorLoader().load(engine.getBiome(sender.player().getLocation()).getGenerators().getRandom().getGenerator());
|
return engine.getData().getGeneratorLoader().load(EngineBukkitOps.getBiome(engine, sender.player().getLocation()).getGenerators().getRandom().getGenerator());
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
+2
-1
@@ -20,6 +20,7 @@ package art.arcane.iris.util.common.director.context;
|
|||||||
|
|
||||||
import art.arcane.iris.core.tools.IrisToolbelt;
|
import art.arcane.iris.core.tools.IrisToolbelt;
|
||||||
import art.arcane.iris.engine.object.IrisRegion;
|
import art.arcane.iris.engine.object.IrisRegion;
|
||||||
|
import art.arcane.iris.engine.platform.EngineBukkitOps;
|
||||||
import art.arcane.iris.util.common.director.DirectorContextHandler;
|
import art.arcane.iris.util.common.director.DirectorContextHandler;
|
||||||
import art.arcane.iris.util.common.plugin.VolmitSender;
|
import art.arcane.iris.util.common.plugin.VolmitSender;
|
||||||
|
|
||||||
@@ -32,7 +33,7 @@ public class RegionContextHandler implements DirectorContextHandler<IrisRegion>
|
|||||||
if (sender.isPlayer()
|
if (sender.isPlayer()
|
||||||
&& IrisToolbelt.isIrisWorld(sender.player().getWorld())
|
&& IrisToolbelt.isIrisWorld(sender.player().getWorld())
|
||||||
&& IrisToolbelt.access(sender.player().getWorld()).getEngine() != null) {
|
&& IrisToolbelt.access(sender.player().getWorld()).getEngine() != null) {
|
||||||
return IrisToolbelt.access(sender.player().getWorld()).getEngine().getRegion(sender.player().getLocation());
|
return EngineBukkitOps.getRegion(IrisToolbelt.access(sender.player().getWorld()).getEngine(), sender.player().getLocation());
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -47,6 +47,11 @@ public final class ClassloadProbe {
|
|||||||
"art.arcane.iris.util.common.misc.Bindings",
|
"art.arcane.iris.util.common.misc.Bindings",
|
||||||
"art.arcane.iris.util.common.misc.SlimJar",
|
"art.arcane.iris.util.common.misc.SlimJar",
|
||||||
"art.arcane.iris.util.common.misc.ServerProperties",
|
"art.arcane.iris.util.common.misc.ServerProperties",
|
||||||
|
"art.arcane.iris.util.common.data.IrisCustomData",
|
||||||
|
"art.arcane.iris.engine.IrisWorldManager",
|
||||||
|
"art.arcane.iris.engine.framework.EngineAssignedWorldManager",
|
||||||
|
"art.arcane.iris.engine.object.StudioMode",
|
||||||
|
"art.arcane.iris.engine.framework.placer.WorldObjectPlacer",
|
||||||
};
|
};
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
public static void main(String[] args) throws IOException {
|
||||||
@@ -87,6 +92,9 @@ public final class ClassloadProbe {
|
|||||||
Class.forName(name, true, ClassloadProbe.class.getClassLoader());
|
Class.forName(name, true, ClassloadProbe.class.getClassLoader());
|
||||||
loaded++;
|
loaded++;
|
||||||
} catch (Throwable failure) {
|
} catch (Throwable failure) {
|
||||||
|
if (System.getenv("PROBE_TRACE") != null && name.contains(System.getenv("PROBE_TRACE"))) {
|
||||||
|
failure.printStackTrace(System.out);
|
||||||
|
}
|
||||||
String cause = rootCause(failure);
|
String cause = rootCause(failure);
|
||||||
if (critical) {
|
if (critical) {
|
||||||
criticalFailures.put(name, cause);
|
criticalFailures.put(name, cause);
|
||||||
|
|||||||
Reference in new issue
Block a user