From 071617bfc571cd85ccf5469936a3dce171d350e4 Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Thu, 5 Aug 2021 20:03:50 -0400 Subject: [PATCH] Tile & Entity Matter --- .../com/volmit/iris/core/nms/INMSBinding.java | 2 + .../iris/core/nms/v17_1/NMSBinding17_1.java | 5 + .../volmit/iris/util/matter/MatterEntity.java | 5 +- .../iris/util/matter/MatterEntityGroup.java | 29 +++++ .../volmit/iris/util/matter/MatterSlice.java | 14 ++- .../iris/util/matter/slices/BlockMatter.java | 5 +- .../iris/util/matter/slices/EntityMatter.java | 110 ++++++++++++++++-- .../iris/util/matter/slices/TileMatter.java | 21 +++- 8 files changed, 177 insertions(+), 14 deletions(-) create mode 100644 src/main/java/com/volmit/iris/util/matter/MatterEntityGroup.java diff --git a/src/main/java/com/volmit/iris/core/nms/INMSBinding.java b/src/main/java/com/volmit/iris/core/nms/INMSBinding.java index 218f3ba28..6d96606b8 100644 --- a/src/main/java/com/volmit/iris/core/nms/INMSBinding.java +++ b/src/main/java/com/volmit/iris/core/nms/INMSBinding.java @@ -28,6 +28,8 @@ import org.bukkit.entity.Entity; import org.bukkit.generator.ChunkGenerator; public interface INMSBinding { + boolean hasTile(Location l); + CompoundTag serializeTile(Location location); void deserializeTile(CompoundTag s, Location newPosition); diff --git a/src/main/java/com/volmit/iris/core/nms/v17_1/NMSBinding17_1.java b/src/main/java/com/volmit/iris/core/nms/v17_1/NMSBinding17_1.java index a9619286c..132ddb4a8 100644 --- a/src/main/java/com/volmit/iris/core/nms/v17_1/NMSBinding17_1.java +++ b/src/main/java/com/volmit/iris/core/nms/v17_1/NMSBinding17_1.java @@ -72,6 +72,11 @@ public class NMSBinding17_1 implements INMSBinding { return null; } + @Override + public boolean hasTile(Location l) { + return ((CraftWorld)l.getWorld()).getHandle().getTileEntity(new BlockPosition(l.getBlockX(), l.getBlockY(), l.getBlockZ()), false) != null; + } + @Override public CompoundTag serializeTile(Location location) { TileEntity e = ((CraftWorld)location.getWorld()).getHandle().getTileEntity(new BlockPosition(location.getBlockX(), location.getBlockY(), location.getBlockZ()), true); diff --git a/src/main/java/com/volmit/iris/util/matter/MatterEntity.java b/src/main/java/com/volmit/iris/util/matter/MatterEntity.java index 925087376..b5a5db8c9 100644 --- a/src/main/java/com/volmit/iris/util/matter/MatterEntity.java +++ b/src/main/java/com/volmit/iris/util/matter/MatterEntity.java @@ -25,5 +25,8 @@ import lombok.Data; @Data @AllArgsConstructor public class MatterEntity { - private final CompoundTag tileData; + private final double xOff; + private final double yOff; + private final double zOff; + private final CompoundTag entityData; } diff --git a/src/main/java/com/volmit/iris/util/matter/MatterEntityGroup.java b/src/main/java/com/volmit/iris/util/matter/MatterEntityGroup.java new file mode 100644 index 000000000..96a21216a --- /dev/null +++ b/src/main/java/com/volmit/iris/util/matter/MatterEntityGroup.java @@ -0,0 +1,29 @@ +/* + * 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.KList; +import com.volmit.iris.util.nbt.tag.CompoundTag; +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +public class MatterEntityGroup { + private final KList entities = new KList<>(); +} 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 119201304..02ba46ea5 100644 --- a/src/main/java/com/volmit/iris/util/matter/MatterSlice.java +++ b/src/main/java/com/volmit/iris/util/matter/MatterSlice.java @@ -65,7 +65,12 @@ public interface MatterSlice extends Hunk { 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); + T g = get(i - x, j - y, k - z); + + if(g != null) + { + injector.writeMatter(w, g, i, j, k); + } } } } @@ -83,7 +88,12 @@ public interface MatterSlice extends Hunk { 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)); + T v = ejector.readMatter(w, i, j, k); + + if(v != null) + { + set(i - x, j - y, k - z, v); + } } } } 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 64f18c46d..08907a686 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 @@ -39,7 +39,10 @@ public class BlockMatter extends RawMatter { 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(World.class, (w, x, y, z) -> { + BlockData d = w.getBlockAt(x, y, z).getBlockData(); + return d.getMaterial().isAir() ? null : d; + }); registerReader(ParallaxWorld.class, ParallaxAccess::getBlock); } diff --git a/src/main/java/com/volmit/iris/util/matter/slices/EntityMatter.java b/src/main/java/com/volmit/iris/util/matter/slices/EntityMatter.java index 0c004bb97..3815c6701 100644 --- a/src/main/java/com/volmit/iris/util/matter/slices/EntityMatter.java +++ b/src/main/java/com/volmit/iris/util/matter/slices/EntityMatter.java @@ -18,33 +18,125 @@ package com.volmit.iris.util.matter.slices; -import com.volmit.iris.util.matter.MatterEntity; -import com.volmit.iris.util.matter.MatterTile; -import com.volmit.iris.util.matter.Sliced; +import com.volmit.iris.core.nms.INMS; +import com.volmit.iris.engine.object.basic.IrisPosition; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.collection.KMap; +import com.volmit.iris.util.data.Varint; +import com.volmit.iris.util.matter.*; import com.volmit.iris.util.nbt.io.NBTUtil; import com.volmit.iris.util.nbt.tag.CompoundTag; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Entity; +import org.bukkit.util.BoundingBox; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; @Sliced -public class EntityMatter extends RawMatter { +public class EntityMatter extends RawMatter { + private transient KMap> entityCache = new KMap<>(); + public EntityMatter() { this(1, 1, 1); + registerWriter(World.class, ((w, d, x, y, z) -> { + for(MatterEntity i : d.getEntities()) + { + Location realPosition = new Location(w, x+i.getXOff(), y+i.getYOff(), z+i.getZOff()); + INMS.get().deserializeEntity(i.getEntityData(), realPosition); + } + })); + registerReader(World.class, (w, x, y, z) -> { + IrisPosition pos = new IrisPosition(x,y,z); + KList entities = entityCache.get(pos); + MatterEntityGroup g = new MatterEntityGroup(); + if(entities != null) + { + for(Entity i : entities) + { + g.getEntities().add(new MatterEntity( + Math.abs(i.getLocation().getX()) - Math.abs(i.getLocation().getBlockX()), + Math.abs(i.getLocation().getY()) - Math.abs(i.getLocation().getBlockY()), + Math.abs(i.getLocation().getZ()) - Math.abs(i.getLocation().getBlockZ()), + INMS.get().serializeEntity(i) + )); + } + + return g; + } + + return null; + }); } public EntityMatter(int width, int height, int depth) { - super(width, height, depth, MatterEntity.class); + super(width, height, depth, MatterEntityGroup.class); } @Override - public void writeNode(MatterEntity b, DataOutputStream dos) throws IOException { - NBTUtil.write(b.getTileData(), dos, false); + public synchronized boolean readFrom(W w, int x, int y, int z) { + if(!(w instanceof World)) + { + return super.readFrom(w, x, y, z); + } + + MatterReader ejector = (MatterReader) readFrom(getClass(w)); + + if (ejector == null) { + return false; + } + + entityCache = new KMap<>(); + + for(Entity i : ((World) w).getNearbyEntities(new BoundingBox(x, y, z, x + getWidth(), y + getHeight(), z + getHeight()))) + { + entityCache.compute(new IrisPosition(i.getLocation()), + (k, v) -> v == null ? new KList<>() : v).add(i); + } + + for(IrisPosition i : entityCache.keySet()) + { + MatterEntityGroup g = ejector.readMatter(w, i.getX(), i.getY(), i.getZ()); + + if(g != null) + { + set(i.getX() - x, i.getY() - y, i.getZ() - z, g); + } + } + + entityCache.clear(); + + return true; } @Override - public MatterEntity readNode(DataInputStream din) throws IOException { - return new MatterEntity((CompoundTag) NBTUtil.read(din, false).getTag()); + public void writeNode(MatterEntityGroup b, DataOutputStream dos) throws IOException { + Varint.writeUnsignedVarInt(b.getEntities().size(), dos); + for(MatterEntity i : b.getEntities()) + { + dos.writeByte((int)(i.getXOff() * 255) + Byte.MIN_VALUE); + dos.writeByte((int)(i.getYOff() * 255) + Byte.MIN_VALUE); + dos.writeByte((int)(i.getZOff() * 255) + Byte.MIN_VALUE); + NBTUtil.write(i.getEntityData(), dos, false); + } + } + + @Override + public MatterEntityGroup readNode(DataInputStream din) throws IOException { + MatterEntityGroup g = new MatterEntityGroup(); + int c = Varint.readUnsignedVarInt(din); + + while(c-- > 0) + { + g.getEntities().add(new MatterEntity( + ((int)din.readByte() - Byte.MIN_VALUE) / 255F, + ((int)din.readByte() - Byte.MIN_VALUE) / 255F, + ((int)din.readByte() - Byte.MIN_VALUE) / 255F, + (CompoundTag) NBTUtil.read(din, false).getTag())); + } + + return g; } } diff --git a/src/main/java/com/volmit/iris/util/matter/slices/TileMatter.java b/src/main/java/com/volmit/iris/util/matter/slices/TileMatter.java index 420046826..2db9ab1c2 100644 --- a/src/main/java/com/volmit/iris/util/matter/slices/TileMatter.java +++ b/src/main/java/com/volmit/iris/util/matter/slices/TileMatter.java @@ -18,10 +18,15 @@ package com.volmit.iris.util.matter.slices; +import com.volmit.iris.core.nms.INMS; +import com.volmit.iris.engine.parallax.ParallaxAccess; +import com.volmit.iris.engine.parallax.ParallaxWorld; import com.volmit.iris.util.matter.MatterTile; import com.volmit.iris.util.matter.Sliced; import com.volmit.iris.util.nbt.io.NBTUtil; import com.volmit.iris.util.nbt.tag.CompoundTag; +import org.bukkit.Location; +import org.bukkit.World; import java.io.DataInputStream; import java.io.DataOutputStream; @@ -31,6 +36,21 @@ import java.io.IOException; public class TileMatter extends RawMatter { public TileMatter() { this(1, 1, 1); + registerWriter(World.class, ((w, d, x, y, z) -> INMS.get().deserializeTile(d.getTileData(), new Location(w, x, y, z)))); + registerReader(World.class, (w, x, y, z) -> { + Location l = new Location(w, x, y, z); + if(INMS.get().hasTile(l)) + { + CompoundTag tag = INMS.get().serializeTile(l); + + if(tag != null) + { + return new MatterTile(tag); + } + } + + return null; + }); } public TileMatter(int width, int height, int depth) { @@ -40,7 +60,6 @@ public class TileMatter extends RawMatter { @Override public void writeNode(MatterTile b, DataOutputStream dos) throws IOException { NBTUtil.write(b.getTileData(), dos, false); - } @Override