Tile & Entity Matter

This commit is contained in:
Daniel Mills 2021-08-05 20:03:50 -04:00
parent 8a079c98cc
commit 071617bfc5
8 changed files with 177 additions and 14 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
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<MatterEntity> entities = new KList<>();
}

View File

@ -65,7 +65,12 @@ public interface MatterSlice<T> extends Hunk<T> {
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<T> extends Hunk<T> {
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);
}
}
}
}

View File

@ -39,7 +39,10 @@ public class BlockMatter extends RawMatter<BlockData> {
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);
}

View File

@ -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<MatterEntity> {
public class EntityMatter extends RawMatter<MatterEntityGroup> {
private transient KMap<IrisPosition, KList<Entity>> 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<Entity> 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 <W> boolean readFrom(W w, int x, int y, int z) {
if(!(w instanceof World))
{
return super.readFrom(w, x, y, z);
}
MatterReader<W, MatterEntityGroup> ejector = (MatterReader<W, MatterEntityGroup>) 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;
}
}

View File

@ -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<MatterTile> {
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<MatterTile> {
@Override
public void writeNode(MatterTile b, DataOutputStream dos) throws IOException {
NBTUtil.write(b.getTileData(), dos, false);
}
@Override