From 294a5e39a6c6f3cddca0a405f511250bf4b3394a Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Thu, 5 Aug 2021 01:11:48 -0400 Subject: [PATCH] Data formats Matter --- .../com/volmit/iris/core/WandManager.java | 37 ++++ .../command/object/CommandIrisObject.java | 6 + .../object/CommandIrisObjectPasteMatter.java | 174 ++++++++++++++++++ .../object/CommandIrisObjectSaveMatter.java | 108 +++++++++++ .../iris/engine/jigsaw/PlannedPiece.java | 3 + .../iris/engine/jigsaw/PlannedStructure.java | 5 + .../java/com/volmit/iris/util/hunk/Hunk.java | 1 + .../iris/util/hunk/storage/MappedHunk.java | 5 + .../volmit/iris/util/matter/IrisMatter.java | 11 +- .../com/volmit/iris/util/matter/Matter.java | 24 +++ .../volmit/iris/util/matter/MatterHunk.java | 82 --------- .../volmit/iris/util/matter/MatterReader.java | 24 +++ .../volmit/iris/util/matter/MatterSlice.java | 93 +++++++++- .../volmit/iris/util/matter/MatterWriter.java | 24 +++ .../iris/util/matter/slices/BlockMatter.java | 12 +- .../iris/util/matter/slices/RawMatter.java | 31 +++- 16 files changed, 546 insertions(+), 94 deletions(-) create mode 100644 src/main/java/com/volmit/iris/core/command/object/CommandIrisObjectPasteMatter.java create mode 100644 src/main/java/com/volmit/iris/core/command/object/CommandIrisObjectSaveMatter.java delete mode 100644 src/main/java/com/volmit/iris/util/matter/MatterHunk.java create mode 100644 src/main/java/com/volmit/iris/util/matter/MatterReader.java create mode 100644 src/main/java/com/volmit/iris/util/matter/MatterWriter.java 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 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 "); + sender.sendMessage("I.e. /iris o save overworld some-tree/tree1"); + return true; + } + + try { + boolean overwrite = false; + + for (String i : args) { + if (i.equals("-o")) { + overwrite = true; + break; + } + } + + Player p = sender.player(); + ItemStack wand = p.getInventory().getItemInMainHand(); + IrisMatter o = WandManager.createSchematic(p, wand); + File file = Iris.proj.getWorkspaceFile(args[0], "objects", args[1] + ".iob"); + + if (file.exists()) { + if (!overwrite) { + sender.sendMessage("File Exists. Overwrite by adding -o"); + return true; + } + } + + o.write(file); + sender.sendMessage("Saved " + args[1]); + p.getWorld().playSound(p.getLocation(), Sound.BLOCK_ENCHANTMENT_TABLE_USE, 1f, 1.5f); + } catch (Throwable e) { + Iris.reportError(e); + sender.sendMessage("Failed to save " + args[1] + ". Are you holding your wand?"); + + e.printStackTrace(); + } + + return true; + } + + @Override + protected String getArgsUsage() { + return "[project] [name]"; + } +} diff --git a/src/main/java/com/volmit/iris/engine/jigsaw/PlannedPiece.java b/src/main/java/com/volmit/iris/engine/jigsaw/PlannedPiece.java index 6eb18a61c..954b1a030 100644 --- a/src/main/java/com/volmit/iris/engine/jigsaw/PlannedPiece.java +++ b/src/main/java/com/volmit/iris/engine/jigsaw/PlannedPiece.java @@ -18,6 +18,7 @@ package com.volmit.iris.engine.jigsaw; +import com.volmit.iris.Iris; import com.volmit.iris.core.project.loader.IrisData; import com.volmit.iris.core.tools.IrisWorlds; import com.volmit.iris.engine.framework.Engine; @@ -30,6 +31,7 @@ import com.volmit.iris.engine.object.loot.IrisLootTable; import com.volmit.iris.engine.object.meta.InventorySlotType; import com.volmit.iris.engine.object.objects.IrisObject; import com.volmit.iris.engine.object.objects.IrisObjectRotation; +import com.volmit.iris.engine.object.objects.IrisObjectTranslate; import com.volmit.iris.engine.object.tile.TileData; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.math.AxisAlignedBB; @@ -159,6 +161,7 @@ public class PlannedPiece { minY--; //If the dimension has no bedrock, allow it to go a block lower } + getPiece().getPlacementOptions().setTranslate(new IrisObjectTranslate()); getPiece().getPlacementOptions().setRotation(rotation); int finalMinY = minY; RNG rng = getStructure().getRng().nextParallelRNG(37555); diff --git a/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java b/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java index 0cc946770..5bbc252a3 100644 --- a/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java +++ b/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java @@ -74,6 +74,11 @@ public class PlannedStructure { } generateTerminators(); + + for(PlannedPiece i : pieces) + { + Iris.debug("Place: " + i.getObject().getLoadKey() + " at @ relative " + i.getPosition().toString()); + } } public KList place(IObjectPlacer placer, EngineParallaxManager e) { diff --git a/src/main/java/com/volmit/iris/util/hunk/Hunk.java b/src/main/java/com/volmit/iris/util/hunk/Hunk.java index 1d8ecc118..f3d877ebd 100644 --- a/src/main/java/com/volmit/iris/util/hunk/Hunk.java +++ b/src/main/java/com/volmit/iris/util/hunk/Hunk.java @@ -18,6 +18,7 @@ package com.volmit.iris.util.hunk; +import com.volmit.iris.Iris; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.function.*; import com.volmit.iris.util.hunk.io.HunkIOAdapter; diff --git a/src/main/java/com/volmit/iris/util/hunk/storage/MappedHunk.java b/src/main/java/com/volmit/iris/util/hunk/storage/MappedHunk.java index 85e726a5e..4af768d55 100644 --- a/src/main/java/com/volmit/iris/util/hunk/storage/MappedHunk.java +++ b/src/main/java/com/volmit/iris/util/hunk/storage/MappedHunk.java @@ -18,6 +18,7 @@ package com.volmit.iris.util.hunk.storage; +import com.volmit.iris.Iris; import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.function.Consumer4; import com.volmit.iris.util.hunk.Hunk; @@ -37,6 +38,10 @@ public class MappedHunk extends StorageHunk implements Hunk { data = new KMap<>(); } + public int getEntryCount() { + return data.size(); + } + @Override public void setRaw(int x, int y, int z, T t) { if (t == null) { diff --git a/src/main/java/com/volmit/iris/util/matter/IrisMatter.java b/src/main/java/com/volmit/iris/util/matter/IrisMatter.java index 071cc21fe..37d769955 100644 --- a/src/main/java/com/volmit/iris/util/matter/IrisMatter.java +++ b/src/main/java/com/volmit/iris/util/matter/IrisMatter.java @@ -22,6 +22,8 @@ import com.volmit.iris.Iris; import com.volmit.iris.util.collection.KMap; import lombok.Getter; +import java.lang.reflect.InvocationTargetException; + public class IrisMatter implements Matter { private static final KMap, MatterSlice> slicers = buildSlicers(); @@ -45,6 +47,7 @@ public class IrisMatter implements Matter { this.height = height; this.depth = depth; this.header = new MatterHeader(); + this.sliceMap = new KMap<>(); } @Override @@ -55,7 +58,13 @@ public class IrisMatter implements Matter { return null; } - return (MatterSlice) slice; + try { + return slice.getClass().getConstructor(int.class, int.class, int.class).newInstance(getWidth(), getHeight(), getDepth()); + } catch (Throwable e) { + e.printStackTrace(); + } + + return null; } private static KMap, MatterSlice> buildSlicers() { diff --git a/src/main/java/com/volmit/iris/util/matter/Matter.java b/src/main/java/com/volmit/iris/util/matter/Matter.java index 35cfb335d..dc4ebb29e 100644 --- a/src/main/java/com/volmit/iris/util/matter/Matter.java +++ b/src/main/java/com/volmit/iris/util/matter/Matter.java @@ -25,6 +25,8 @@ import java.io.*; import java.util.Map; import java.util.Set; import java.util.function.Function; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; /** * When Red Matter isn't enough @@ -208,6 +210,14 @@ public interface Matter { */ Map, MatterSlice> getSliceMap(); + default void write(File f) throws IOException + { + FileOutputStream out = new FileOutputStream(f); + GZIPOutputStream gzo = new GZIPOutputStream(out); + write(gzo); + gzo.close(); + } + /** * Writes the data to the output stream. The data will be flushed to the provided output * stream however the provided stream will NOT BE CLOSED, so be sure to actually close it @@ -231,6 +241,20 @@ public interface Matter { dos.flush(); } + static Matter read(File f) throws IOException, ClassNotFoundException + { + FileInputStream in = new FileInputStream(f); + GZIPInputStream gzi = new GZIPInputStream(in); + Matter m = read(gzi); + gzi.close(); + return m; + } + + static Matter read(InputStream in) throws IOException, ClassNotFoundException + { + return read(in, (b) -> new IrisMatter(b.getX(), b.getY(), b.getZ())); + } + /** * Reads the input stream into a matter object using a matter factory. * Does not close the input stream. Be a man, close it yourself. diff --git a/src/main/java/com/volmit/iris/util/matter/MatterHunk.java b/src/main/java/com/volmit/iris/util/matter/MatterHunk.java deleted file mode 100644 index ef3a5d2e5..000000000 --- a/src/main/java/com/volmit/iris/util/matter/MatterHunk.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * 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.util.matter; - -import com.volmit.iris.util.collection.KMap; -import com.volmit.iris.util.function.Consumer4; -import com.volmit.iris.util.hunk.Hunk; -import com.volmit.iris.util.hunk.storage.StorageHunk; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.util.Map; - -@SuppressWarnings({"DefaultAnnotationParam", "Lombok"}) -@Data -@EqualsAndHashCode(callSuper = false) -public class MatterHunk extends StorageHunk implements Hunk { - private final Map data; - - public MatterHunk(int w, int h, int d) { - super(w, h, d); - data = new KMap<>(); - } - - public int getCount() { - return data.size(); - } - - @Override - public void setRaw(int x, int y, int z, T t) { - if (t == null) { - data.remove(index(x, y, z)); - return; - } - - data.put(index(x, y, z), t); - } - - private Integer index(int x, int y, int z) { - return (z * getWidth() * getHeight()) + (y * getWidth()) + x; - } - - @Override - public synchronized Hunk iterateSync(Consumer4 c) { - int idx, z; - - for (Map.Entry g : data.entrySet()) { - idx = g.getKey(); - z = idx / (getWidth() * getHeight()); - idx -= (z * getWidth() * getHeight()); - c.accept(idx % getWidth(), idx / getWidth(), z, g.getValue()); - } - - return this; - } - - @Override - public void empty(T b) { - data.clear(); - } - - @Override - public T getRaw(int x, int y, int z) { - return data.get(index(x, y, z)); - } -} \ No newline at end of file diff --git a/src/main/java/com/volmit/iris/util/matter/MatterReader.java b/src/main/java/com/volmit/iris/util/matter/MatterReader.java new file mode 100644 index 000000000..b7b31bbf1 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/matter/MatterReader.java @@ -0,0 +1,24 @@ +/* + * 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.util.matter; + +@FunctionalInterface +public interface MatterReader { + T readMatter(W w, int x, int y, int z); +} diff --git a/src/main/java/com/volmit/iris/util/matter/MatterSlice.java b/src/main/java/com/volmit/iris/util/matter/MatterSlice.java index a6906fbd9..b3156d44b 100644 --- a/src/main/java/com/volmit/iris/util/matter/MatterSlice.java +++ b/src/main/java/com/volmit/iris/util/matter/MatterSlice.java @@ -18,9 +18,13 @@ package com.volmit.iris.util.matter; +import com.volmit.iris.Iris; import com.volmit.iris.engine.data.cache.Cache; import com.volmit.iris.util.data.Varint; import com.volmit.iris.util.hunk.Hunk; +import com.volmit.iris.util.hunk.storage.MappedHunk; +import org.bukkit.World; +import org.bukkit.block.data.BlockData; import java.io.DataInputStream; import java.io.DataOutputStream; @@ -33,6 +37,90 @@ public interface MatterSlice extends Hunk { T readNode(DataInputStream din) throws IOException; + MatterWriter writeInto(Class mediumType); + + MatterReader readFrom(Class mediumType); + + default Class getClass(Object w) + { + Class c = w.getClass(); + + if(w instanceof World) + { + c = World.class; + }else if(w instanceof BlockData) + { + c = BlockData.class; + } + + return c; + } + + default boolean writeInto(W w, int x, int y, int z) + { + MatterWriter injector = (MatterWriter) writeInto(getClass(w)); + + if(injector == null) + { + return false; + } + + for(int i = x; i < x + getWidth(); i++) + { + for(int j = y; j < y + getHeight(); j++) + { + for(int k = z; k < z + getDepth(); k++) + { + injector.writeMatter(w, get(i - x, j - y, k - z), i, j, k); + } + } + } + + return true; + } + + default boolean readFrom(W w, int x, int y, int z) + { + MatterReader ejector = (MatterReader) readFrom(getClass(w)); + + if(ejector == null) + { + return false; + } + + for(int i = x; i < x + getWidth(); i++) + { + for(int j = y; j < y + getHeight(); j++) + { + for(int k = z; k < z + getDepth(); k++) + { + set(i - x, j - y, k - z, ejector.readMatter(w, i, j, k)); + } + } + } + + return true; + } + + // BlockMatter + // RawMatter ex MappedHunk + // IMatterSlice ex Hunk + + default int getCount() + { + return ((MappedHunk)this).getEntryCount(); + } + + default boolean canWrite(Class mediumType) + { + return writeInto(mediumType) != null; + } + + default boolean canRead(Class mediumType) + { + return readFrom(mediumType) != null; + } + default void write(DataOutputStream dos) throws IOException { int w = getWidth(); int h = getHeight(); @@ -40,9 +128,9 @@ public interface MatterSlice extends Hunk { MatterPalette palette = new MatterPalette(this); iterateSync((x, y, z, b) -> palette.assign(b)); palette.writePalette(dos); - Varint.writeUnsignedVarInt(((MatterHunk) this).getCount(), dos); + Varint.writeUnsignedVarInt(getCount(), dos); iterateSyncIO((x, y, z, b) -> { - Varint.writeUnsignedVarInt((z * w * h) + (y * w) + x, dos); + Varint.writeUnsignedVarInt(Cache.to1D(x, y, z, w, h), dos); palette.writeNode(b, dos); }); } @@ -51,7 +139,6 @@ public interface MatterSlice extends Hunk { int w = getWidth(); int h = getHeight(); - // canonical is read in parent MatterPalette palette = new MatterPalette(this, din); int nodes = Varint.readUnsignedVarInt(din); int[] pos; diff --git a/src/main/java/com/volmit/iris/util/matter/MatterWriter.java b/src/main/java/com/volmit/iris/util/matter/MatterWriter.java new file mode 100644 index 000000000..415f21c64 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/matter/MatterWriter.java @@ -0,0 +1,24 @@ +/* + * 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.util.matter; + +@FunctionalInterface +public interface MatterWriter { + void writeMatter(W w, T d, int x, int y, int z); +} diff --git a/src/main/java/com/volmit/iris/util/matter/slices/BlockMatter.java b/src/main/java/com/volmit/iris/util/matter/slices/BlockMatter.java index c1be8facf..2c1ce0169 100644 --- a/src/main/java/com/volmit/iris/util/matter/slices/BlockMatter.java +++ b/src/main/java/com/volmit/iris/util/matter/slices/BlockMatter.java @@ -18,10 +18,14 @@ package com.volmit.iris.util.matter.slices; +import com.volmit.iris.engine.parallax.ParallaxAccess; +import com.volmit.iris.engine.parallax.ParallaxWorld; +import com.volmit.iris.util.data.B; import com.volmit.iris.util.matter.Sliced; import com.volmit.iris.util.nbt.io.NBTUtil; import com.volmit.iris.util.nbt.mca.NBTWorld; import com.volmit.iris.util.nbt.tag.CompoundTag; +import org.bukkit.World; import org.bukkit.block.data.BlockData; import java.io.DataInputStream; @@ -36,15 +40,19 @@ public class BlockMatter extends RawMatter { public BlockMatter(int width, int height, int depth) { super(width, height, depth, BlockData.class); + registerWriter(World.class, ((w, d, x, y, z) -> w.getBlockAt(x,y,z).setBlockData(d))); + registerWriter(ParallaxWorld.class, (w, d, x, y, z) -> w.setBlock(x,y,z,d)); + registerReader(World.class, (w, x, y, z) -> w.getBlockAt(x,y,z).getBlockData()); + registerReader(ParallaxWorld.class, ParallaxAccess::getBlock); } @Override public void writeNode(BlockData b, DataOutputStream dos) throws IOException { - NBTUtil.write(NBTWorld.getCompound(b), dos, false); + dos.writeUTF(b.getAsString(true)); } @Override public BlockData readNode(DataInputStream din) throws IOException { - return NBTWorld.getBlockData((CompoundTag) NBTUtil.read(din, false).getTag()); + return B.get(din.readUTF()); } } diff --git a/src/main/java/com/volmit/iris/util/matter/slices/RawMatter.java b/src/main/java/com/volmit/iris/util/matter/slices/RawMatter.java index 05dbe373b..90c3e0446 100644 --- a/src/main/java/com/volmit/iris/util/matter/slices/RawMatter.java +++ b/src/main/java/com/volmit/iris/util/matter/slices/RawMatter.java @@ -18,7 +18,10 @@ package com.volmit.iris.util.matter.slices; -import com.volmit.iris.util.matter.MatterHunk; +import com.volmit.iris.util.collection.KMap; +import com.volmit.iris.util.hunk.storage.MappedHunk; +import com.volmit.iris.util.matter.MatterReader; +import com.volmit.iris.util.matter.MatterWriter; import com.volmit.iris.util.matter.MatterSlice; import lombok.Getter; @@ -26,23 +29,39 @@ import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; -public abstract class RawMatter extends MatterHunk implements MatterSlice { +public abstract class RawMatter extends MappedHunk implements MatterSlice { @Getter private final Class type; + private final KMap, MatterWriter> injectors; + private final KMap, MatterReader> ejectors; public RawMatter(int width, int height, int depth, Class type) { super(width, height, depth); + injectors = new KMap<>(); + ejectors = new KMap<>(); this.type = type; } - @Override - public void setRaw(int x, int y, int z, T t) { + protected void registerWriter(Class mediumType, MatterWriter injector) + { + injectors.put(mediumType, injector); + } + protected void registerReader(Class mediumType, MatterReader injector) + { + ejectors.put(mediumType, injector); } @Override - public T getRaw(int x, int y, int z) { - return null; + public MatterWriter writeInto(Class mediumType) + { + return (MatterWriter) injectors.get(mediumType); + } + + @Override + public MatterReader readFrom(Class mediumType) + { + return (MatterReader) ejectors.get(mediumType); } @Override