diff --git a/src/main/java/com/volmit/iris/core/WandManager.java b/src/main/java/com/volmit/iris/core/WandManager.java
index a0896ed58..1416e1146 100644
--- a/src/main/java/com/volmit/iris/core/WandManager.java
+++ b/src/main/java/com/volmit/iris/core/WandManager.java
@@ -24,10 +24,13 @@ import com.volmit.iris.engine.object.objects.IrisObject;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.data.Cuboid;
import com.volmit.iris.util.format.C;
+import com.volmit.iris.util.hunk.storage.MappedHunk;
import com.volmit.iris.util.math.M;
+import com.volmit.iris.util.matter.IrisMatter;
import com.volmit.iris.util.plugin.VolmitSender;
import org.bukkit.*;
import org.bukkit.block.Block;
+import org.bukkit.block.data.BlockData;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@@ -224,6 +227,40 @@ public class WandManager implements Listener {
return null;
}
+ /**
+ * Creates an Iris Object from the 2 coordinates selected with a wand
+ *
+ * @param wand The wand itemstack
+ * @return The new object
+ */
+ public static IrisMatter createSchematic(Player p, ItemStack wand) {
+ if (!isWand(wand)) {
+ return null;
+ }
+
+ try {
+ Location[] f = getCuboid(wand);
+ Cuboid c = new Cuboid(f[0], f[1]);
+ IrisMatter s = new IrisMatter(c.getSizeX(), c.getSizeY(), c.getSizeZ());
+ Iris.info(s.getWidth() + " " + s.getHeight() + " " + s.getDepth());
+ s.getHeader().setAuthor(p.getName());
+ s.slice(BlockData.class)
+ .readFrom(c.getWorld(),
+ c.getLowerNE().getBlockX(),
+ c.getLowerNE().getBlockY(), c.getLowerNE().getBlockZ());
+
+ Iris.info("Slices: " + s.getSliceMap().size());
+ Iris.info("Entries " + s.getSlice(BlockData.class).getCount());
+
+ return s;
+ } catch (Throwable e) {
+ e.printStackTrace();
+ Iris.reportError(e);
+ }
+
+ return null;
+ }
+
/**
* Converts a user friendly location string to an actual Location
*
diff --git a/src/main/java/com/volmit/iris/core/command/object/CommandIrisObject.java b/src/main/java/com/volmit/iris/core/command/object/CommandIrisObject.java
index 11a4cdaff..9f05494d1 100644
--- a/src/main/java/com/volmit/iris/core/command/object/CommandIrisObject.java
+++ b/src/main/java/com/volmit/iris/core/command/object/CommandIrisObject.java
@@ -32,6 +32,12 @@ public class CommandIrisObject extends MortarCommand {
@Command
private CommandIrisObjectDust dust;
+ @Command
+ private CommandIrisObjectPasteMatter mpaste;
+
+ @Command
+ private CommandIrisObjectSaveMatter msave;
+
@Command
private CommandIrisObjectXPY xpy;
diff --git a/src/main/java/com/volmit/iris/core/command/object/CommandIrisObjectPasteMatter.java b/src/main/java/com/volmit/iris/core/command/object/CommandIrisObjectPasteMatter.java
new file mode 100644
index 000000000..1fcb43752
--- /dev/null
+++ b/src/main/java/com/volmit/iris/core/command/object/CommandIrisObjectPasteMatter.java
@@ -0,0 +1,174 @@
+/*
+ * Iris is a World Generator for Minecraft Bukkit Servers
+ * Copyright (c) 2021 Arcane Arts (Volmit Software)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.volmit.iris.core.command.object;
+
+import com.volmit.iris.Iris;
+import com.volmit.iris.core.IrisSettings;
+import com.volmit.iris.core.ProjectManager;
+import com.volmit.iris.core.WandManager;
+import com.volmit.iris.core.project.loader.IrisData;
+import com.volmit.iris.core.tools.IrisWorlds;
+import com.volmit.iris.engine.object.common.IObjectPlacer;
+import com.volmit.iris.engine.object.objects.IrisObject;
+import com.volmit.iris.engine.object.objects.IrisObjectPlacement;
+import com.volmit.iris.engine.object.objects.IrisObjectPlacementScaleInterpolator;
+import com.volmit.iris.engine.object.objects.IrisObjectRotation;
+import com.volmit.iris.engine.object.tile.TileData;
+import com.volmit.iris.util.collection.KList;
+import com.volmit.iris.util.math.RNG;
+import com.volmit.iris.util.matter.IrisMatter;
+import com.volmit.iris.util.matter.Matter;
+import com.volmit.iris.util.plugin.MortarCommand;
+import com.volmit.iris.util.plugin.VolmitSender;
+import org.bukkit.*;
+import org.bukkit.block.Block;
+import org.bukkit.block.BlockState;
+import org.bukkit.block.TileState;
+import org.bukkit.block.data.BlockData;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+public class CommandIrisObjectPasteMatter extends MortarCommand {
+
+ public CommandIrisObjectPasteMatter() {
+ super("mpaste");
+ requiresPermission(Iris.perm);
+ setCategory("Object");
+ setDescription("Paste an object");
+ }
+
+ @Override
+ public void addTabOptions(VolmitSender sender, String[] args, KList list) {
+ if ((args.length == 0 || args.length == 1) && sender.isPlayer() && IrisWorlds.isIrisWorld(sender.player().getWorld())) {
+ IrisData data = IrisWorlds.access(sender.player().getWorld()).getData();
+ if (data == null) {
+ sender.sendMessage("Tab complete options only work for objects while in an Iris world.");
+ } else if (args.length == 0) {
+ list.add(data.getObjectLoader().getPossibleKeys());
+ } else {
+ list.add(data.getObjectLoader().getPossibleKeys(args[0]));
+ }
+ }
+ }
+
+ @Override
+ public boolean handle(VolmitSender sender, String[] args) {
+ if (!IrisSettings.get().isStudio()) {
+ sender.sendMessage("To use Iris Studio Objects, please enable studio in Iris/settings.json");
+ return true;
+ }
+
+ if (!sender.isPlayer()) {
+ sender.sendMessage("Only players can spawn objects with this command");
+ return true;
+ }
+
+ if (args.length == 0) {
+ sender.sendMessage("Please specify the name of of the object want to paste");
+ return true;
+ }
+
+ Player p = sender.player();
+ File f = new File(args[0]);
+ try {
+ Matter matter = Matter.read(f);
+ matter.slice(BlockData.class)
+ .writeInto(p.getWorld(), p.getLocation().getBlockX(), p.getLocation().getBlockY(), p.getLocation().getBlockZ());
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+
+ return true;
+ }
+
+ @Override
+ protected String getArgsUsage() {
+ return "[name] [-edit] [-rotate [angle]] [-scale [num] [method]]";
+ }
+
+ public static IObjectPlacer createPlacer(Player player, World world, Map futureBlockChanges) {
+
+ return new IObjectPlacer() {
+ @Override
+ public int getHighest(int x, int z, IrisData data) {
+ return world.getHighestBlockYAt(x, z);
+ }
+
+ @Override
+ public int getHighest(int x, int z, IrisData data, boolean ignoreFluid) {
+ return world.getHighestBlockYAt(x, z, ignoreFluid ? HeightMap.OCEAN_FLOOR : HeightMap.MOTION_BLOCKING);
+ }
+
+ @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 <= world.getMinHeight() || block.getType() == Material.BEDROCK) return;
+
+ futureBlockChanges.put(block, block.getBlockData());
+
+ block.setBlockData(d);
+ }
+
+ @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 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 63;
+ }
+
+ @Override
+ public boolean isDebugSmartBore() {
+ return false;
+ }
+
+ @Override
+ public void setTile(int xx, int yy, int zz, TileData extends TileState> tile) {
+ BlockState state = world.getBlockAt(xx, yy, zz).getState();
+ tile.toBukkitTry(state);
+ state.update();
+ }
+ };
+ }
+}
diff --git a/src/main/java/com/volmit/iris/core/command/object/CommandIrisObjectSaveMatter.java b/src/main/java/com/volmit/iris/core/command/object/CommandIrisObjectSaveMatter.java
new file mode 100644
index 000000000..1f24a7ccd
--- /dev/null
+++ b/src/main/java/com/volmit/iris/core/command/object/CommandIrisObjectSaveMatter.java
@@ -0,0 +1,108 @@
+/*
+ * Iris is a World Generator for Minecraft Bukkit Servers
+ * Copyright (c) 2021 Arcane Arts (Volmit Software)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.volmit.iris.core.command.object;
+
+import com.volmit.iris.Iris;
+import com.volmit.iris.core.IrisSettings;
+import com.volmit.iris.core.WandManager;
+import com.volmit.iris.engine.object.objects.IrisObject;
+import com.volmit.iris.util.collection.KList;
+import com.volmit.iris.util.format.Form;
+import com.volmit.iris.util.matter.IrisMatter;
+import com.volmit.iris.util.plugin.MortarCommand;
+import com.volmit.iris.util.plugin.VolmitSender;
+import com.volmit.iris.util.scheduling.PrecisionStopwatch;
+import org.bukkit.Sound;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
+
+import java.io.File;
+
+public class CommandIrisObjectSaveMatter extends MortarCommand {
+ public CommandIrisObjectSaveMatter() {
+ super("msave");
+ requiresPermission(Iris.perm);
+ setCategory("Object");
+ setDescription("Save an object");
+ }
+
+
+ @Override
+ public void addTabOptions(VolmitSender sender, String[] args, KList list) {
+
+ }
+
+ @Override
+ public boolean handle(VolmitSender sender, String[] args) {
+ if (!IrisSettings.get().isStudio()) {
+ sender.sendMessage("To use Iris Studio Objects, please enable studio in Iris/settings.json");
+ return true;
+ }
+
+ if (!sender.isPlayer()) {
+ sender.sendMessage("You don't have a wand");
+ return true;
+ }
+
+ if (args.length < 2) {
+ sender.sendMessage("/iris o save