diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandJigsaw.java b/core/src/main/java/com/volmit/iris/core/commands/CommandJigsaw.java index 70e8e2ae3..710184027 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandJigsaw.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandJigsaw.java @@ -21,6 +21,7 @@ package com.volmit.iris.core.commands; import com.volmit.iris.Iris; import com.volmit.iris.core.edit.JigsawEditor; import com.volmit.iris.core.loader.IrisData; +import com.volmit.iris.engine.framework.placer.WorldObjectPlacer; import com.volmit.iris.engine.jigsaw.PlannedStructure; import com.volmit.iris.engine.object.IrisJigsawPiece; import com.volmit.iris.engine.object.IrisJigsawStructure; @@ -56,10 +57,16 @@ public class CommandJigsaw implements DecreeExecutor { IrisJigsawStructure structure ) { PrecisionStopwatch p = PrecisionStopwatch.start(); - PlannedStructure ps = new PlannedStructure(structure, new IrisPosition(player().getLocation()), new RNG()); - VolmitSender sender = sender(); - sender.sendMessage(C.GREEN + "Generated " + ps.getPieces().size() + " pieces in " + Form.duration(p.getMilliseconds(), 2)); - ps.place(world(), failed -> sender.sendMessage(failed ? C.GREEN + "Placed the structure!" : C.RED + "Failed to place the structure!")); + try { + var world = world(); + WorldObjectPlacer placer = new WorldObjectPlacer(world); + PlannedStructure ps = new PlannedStructure(structure, new IrisPosition(player().getLocation().add(0, world.getMinHeight(), 0)), new RNG()); + VolmitSender sender = sender(); + sender.sendMessage(C.GREEN + "Generated " + ps.getPieces().size() + " pieces in " + Form.duration(p.getMilliseconds(), 2)); + ps.place(placer, failed -> sender.sendMessage(failed ? C.GREEN + "Placed the structure!" : C.RED + "Failed to place the structure!")); + } catch (IllegalArgumentException e) { + sender().sendMessage(C.RED + "Failed to place the structure: " + e.getMessage()); + } } @Decree(description = "Create a jigsaw piece") diff --git a/core/src/main/java/com/volmit/iris/engine/framework/placer/WorldObjectPlacer.java b/core/src/main/java/com/volmit/iris/engine/framework/placer/WorldObjectPlacer.java new file mode 100644 index 000000000..16968eee5 --- /dev/null +++ b/core/src/main/java/com/volmit/iris/engine/framework/placer/WorldObjectPlacer.java @@ -0,0 +1,127 @@ +package com.volmit.iris.engine.framework.placer; + +import com.volmit.iris.Iris; +import com.volmit.iris.core.loader.IrisData; +import com.volmit.iris.core.tools.IrisToolbelt; +import com.volmit.iris.engine.data.cache.Cache; +import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.framework.IrisLootEvent; +import com.volmit.iris.engine.mantle.EngineMantle; +import com.volmit.iris.engine.object.IObjectPlacer; +import com.volmit.iris.engine.object.InventorySlotType; +import com.volmit.iris.engine.object.IrisLootTable; +import com.volmit.iris.engine.object.TileData; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.data.B; +import com.volmit.iris.util.math.RNG; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.block.TileState; +import org.bukkit.block.data.BlockData; +import org.bukkit.inventory.InventoryHolder; + +@Getter +@EqualsAndHashCode(exclude = {"engine", "mantle"}) +public class WorldObjectPlacer implements IObjectPlacer { + private final World world; + private final Engine engine; + private final EngineMantle mantle; + + public WorldObjectPlacer(World world) { + var a = IrisToolbelt.access(world); + if (a == null || a.getEngine() == null) throw new IllegalStateException(world.getName() + " is not an Iris World!"); + this.world = world; + this.engine = a.getEngine(); + this.mantle = engine.getMantle(); + } + + @Override + public int getHighest(int x, int z, IrisData data) { + return mantle.getHighest(x, z, data); + } + + @Override + public int getHighest(int x, int z, IrisData data, boolean ignoreFluid) { + return mantle.getHighest(x, z, data, ignoreFluid); + } + + @Override + public void set(int x, int y, int z, BlockData d) { + Block block = world.getBlockAt(x, y + world.getMinHeight(), z); + + if (y <= world.getMinHeight() || block.getType() == Material.BEDROCK) return; + InventorySlotType slot = null; + if (B.isStorageChest(d)) { + slot = InventorySlotType.STORAGE; + } + + if (slot != null) { + RNG rx = new RNG(Cache.key(x, z)); + KList tables = engine.getLootTables(rx, block); + + try { + Bukkit.getPluginManager().callEvent(new IrisLootEvent(engine, block, slot, tables)); + + if (!tables.isEmpty()){ + Iris.debug("IrisLootEvent has been accessed"); + } + + if (tables.isEmpty()) + return; + InventoryHolder m = (InventoryHolder) block.getState(); + engine.addItems(false, m.getInventory(), rx, tables, slot, x, y, z, 15); + } catch (Throwable e) { + Iris.reportError(e); + } + } + + block.setBlockData(d); + } + + @Override + public BlockData get(int x, int y, int z) { + return world.getBlockAt(x, y + world.getMinHeight(), z).getBlockData(); + } + + @Override + public boolean isPreventingDecay() { + return mantle.isPreventingDecay(); + } + + @Override + public boolean isCarved(int x, int y, int z) { + return mantle.isCarved(x, y, z); + } + + @Override + public boolean isSolid(int x, int y, int z) { + return world.getBlockAt(x, y + world.getMinHeight(), z).getType().isSolid(); + } + + @Override + public boolean isUnderwater(int x, int z) { + return mantle.isUnderwater(x, z); + } + + @Override + public int getFluidHeight() { + return mantle.getFluidHeight(); + } + + @Override + public boolean isDebugSmartBore() { + return mantle.isDebugSmartBore(); + } + + @Override + public void setTile(int xx, int yy, int zz, TileData tile) { + BlockState state = world.getBlockAt(xx, yy + world.getMinHeight(), zz).getState(); + tile.toBukkitTry(state); + state.update(); + } +} diff --git a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedPiece.java b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedPiece.java index cf0ef0dc0..862674f8b 100644 --- a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedPiece.java +++ b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedPiece.java @@ -20,24 +20,11 @@ package com.volmit.iris.engine.jigsaw; import com.volmit.iris.Iris; import com.volmit.iris.core.loader.IrisData; -import com.volmit.iris.core.tools.IrisToolbelt; -import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.object.*; -import com.volmit.iris.engine.platform.PlatformChunkGenerator; import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.context.IrisContext; import com.volmit.iris.util.math.AxisAlignedBB; -import com.volmit.iris.util.math.BlockPosition; -import com.volmit.iris.util.math.RNG; import lombok.Data; import lombok.EqualsAndHashCode; -import org.bukkit.Material; -import org.bukkit.World; -import org.bukkit.block.Block; -import org.bukkit.block.BlockState; -import org.bukkit.block.TileState; -import org.bukkit.block.data.BlockData; -import org.bukkit.inventory.InventoryHolder; import org.bukkit.util.BlockVector; import java.util.ArrayList; @@ -175,103 +162,4 @@ public class PlannedPiece { public boolean isFull() { return connected.size() >= piece.getConnectors().size() || isDead(); } - - public boolean place(World world) { - PlatformChunkGenerator a = IrisToolbelt.access(world); - - int minY = 0; - if (a != null) { - minY = a.getEngine().getMinHeight(); - - if (!a.getEngine().getDimension().isBedrock()) - minY--; //If the dimension has no bedrock, allow it to go a block lower - } - Engine engine = a != null ? a.getEngine() : IrisContext.get().getEngine(); - - getPiece().getPlacementOptions().setTranslate(new IrisObjectTranslate()); - getPiece().getPlacementOptions().getRotation().setEnabled(false); - getPiece().getPlacementOptions().setRotateTowardsSlope(false); - int finalMinY = minY; - RNG rng = getStructure().getRng().nextParallelRNG(37555); - - // TODO: REAL CLASSES!!!!!!! - return getObject().place(position.getX() + getObject().getCenter().getBlockX(), position.getY() + getObject().getCenter().getBlockY(), position.getZ() + getObject().getCenter().getBlockZ(), new IObjectPlacer() { - @Override - public int getHighest(int x, int z, IrisData data) { - return position.getY(); - } - - @Override - public int getHighest(int x, int z, IrisData data, boolean ignoreFluid) { - return position.getY(); - } - - @Override - public void set(int x, int y, int z, BlockData d) { - Block block = world.getBlockAt(x, y, z); - - //Prevent blocks being set in or bellow bedrock - if (y <= finalMinY || block.getType() == Material.BEDROCK) return; - - block.setBlockData(d); - - if (a != null && getPiece().getPlacementOptions().getLoot().isNotEmpty() && - block.getState() instanceof InventoryHolder) { - - IrisLootTable table = getPiece().getPlacementOptions().getTable(block.getBlockData(), getData()); - if (table == null) return; - engine.addItems(false, ((InventoryHolder) block.getState()).getInventory(), - rng.nextParallelRNG(BlockPosition.toLong(x, y, z)), - new KList<>(table), InventorySlotType.STORAGE, x, y, z, 15); - } - } - - @Override - public BlockData get(int x, int y, int z) { - return world.getBlockAt(x, y, z).getBlockData(); - } - - @Override - public boolean isPreventingDecay() { - return false; - } - - @Override - public boolean isCarved(int x, int y, int z) { - return false; - } - - @Override - public boolean isSolid(int x, int y, int z) { - return world.getBlockAt(x, y, z).getType().isSolid(); - } - - @Override - public boolean isUnderwater(int x, int z) { - return false; - } - - @Override - public int getFluidHeight() { - return 0; - } - - @Override - public boolean isDebugSmartBore() { - return false; - } - - @Override - public void setTile(int xx, int yy, int zz, TileData tile) { - BlockState state = world.getBlockAt(xx, yy, zz).getState(); - tile.toBukkitTry(state); - state.update(); - } - - @Override - public Engine getEngine() { - return engine; - } - }, piece.getPlacementOptions(), rng, getData().getEngine() == null ? engine.getData() : getData()) != -1; - } } diff --git a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java index 18c03bd9b..846ba406a 100644 --- a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java +++ b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java @@ -21,9 +21,8 @@ package com.volmit.iris.engine.jigsaw; import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap; import com.volmit.iris.Iris; import com.volmit.iris.core.loader.IrisData; -import com.volmit.iris.core.tools.IrisToolbelt; -import com.volmit.iris.engine.data.cache.Cache; import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.framework.placer.WorldObjectPlacer; import com.volmit.iris.engine.object.*; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.mantle.Mantle; @@ -34,12 +33,6 @@ import com.volmit.iris.util.matter.slices.container.JigsawStructuresContainer; import com.volmit.iris.util.scheduling.J; import lombok.Data; import org.bukkit.Axis; -import org.bukkit.Material; -import org.bukkit.World; -import org.bukkit.block.Block; -import org.bukkit.block.BlockState; -import org.bukkit.block.TileState; -import org.bukkit.block.data.BlockData; import java.util.function.Consumer; @@ -119,7 +112,6 @@ public class PlannedStructure { int sz = (v.getD() / 2); int xx = i.getPosition().getX() + sx; int zz = i.getPosition().getZ() + sz; - RNG rngf = new RNG(Cache.key(xx, zz)); int offset = i.getPosition().getY() - startHeight; int height; @@ -147,83 +139,8 @@ public class PlannedStructure { }, null, getData().getEngine() != null ? getData() : eng.getData()) != -1; } - public void place(World world, Consumer consumer) { - var a = IrisToolbelt.access(world); - if (a == null || a.getEngine() == null) { - consumer.accept(null); - return; - } - var engine = a.getEngine(); - var engineMantle = engine.getMantle(); - var placer = new IObjectPlacer() { - @Override - public int getHighest(int x, int z, IrisData data) { - return engineMantle.getHighest(x, z, data); - } - - @Override - public int getHighest(int x, int z, IrisData data, boolean ignoreFluid) { - return engineMantle.getHighest(x, z, data, ignoreFluid); - } - - @Override - public void set(int x, int y, int z, BlockData d) { - Block block = world.getBlockAt(x, y + world.getMinHeight(), z); - - //Prevent blocks being set in or bellow bedrock - if (y <= world.getMinHeight() || block.getType() == Material.BEDROCK) return; - - block.setBlockData(d); - } - - @Override - public BlockData get(int x, int y, int z) { - return world.getBlockAt(x, y + world.getMinHeight(), z).getBlockData(); - } - - @Override - public boolean isPreventingDecay() { - return engineMantle.isPreventingDecay(); - } - - @Override - public boolean isCarved(int x, int y, int z) { - return engineMantle.isCarved(x, y, z); - } - - @Override - public boolean isSolid(int x, int y, int z) { - return world.getBlockAt(x, y + world.getMinHeight(), z).getType().isSolid(); - } - - @Override - public boolean isUnderwater(int x, int z) { - return engineMantle.isUnderwater(x, z); - } - - @Override - public int getFluidHeight() { - return engineMantle.getFluidHeight(); - } - - @Override - public boolean isDebugSmartBore() { - return engineMantle.isDebugSmartBore(); - } - - @Override - public void setTile(int xx, int yy, int zz, TileData tile) { - BlockState state = world.getBlockAt(xx, yy + world.getMinHeight(), zz).getState(); - tile.toBukkitTry(state); - state.update(); - } - - @Override - public Engine getEngine() { - return engine; - } - }; - J.s(() -> consumer.accept(place(placer, engineMantle.getMantle(), engine))); + public void place(WorldObjectPlacer placer, Consumer consumer) { + J.s(() -> consumer.accept(place(placer, placer.getMantle().getMantle(), placer.getEngine()))); } private void generateOutwards() {