mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-07-18 18:23:06 +00:00
Mantle & Debugging
This commit is contained in:
parent
771cb45b49
commit
803dfed9f7
@ -524,7 +524,41 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
msg(C.LIGHT_PURPLE + string);
|
try
|
||||||
|
{
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
catch(Throwable e)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String[] cc = e.getStackTrace()[1].getClassName().split("\\Q.\\E");
|
||||||
|
|
||||||
|
if(cc.length > 5)
|
||||||
|
{
|
||||||
|
debug(cc[3] + "/" + cc[4] + "/" + cc[cc.length-1], e.getStackTrace()[1].getLineNumber(), string);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
debug(cc[3] + "/" + cc[4], e.getStackTrace()[1].getLineNumber(), string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
catch(Throwable ex)
|
||||||
|
{
|
||||||
|
debug("Origin", -1, string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void debug(String category, int line, String string) {
|
||||||
|
if (!IrisSettings.get().getGeneral().isDebug()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg("<gradient:#095fe0:#a848db>" + category + " <#bf3b76>" + line + "<reset> " + C.LIGHT_PURPLE + string.replaceAll("\\Q<\\E", "[").replaceAll("\\Q>\\E", "]"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void verbose(String string) {
|
public static void verbose(String string) {
|
||||||
|
@ -228,24 +228,10 @@ public class IrisEngine extends BlockPopulator implements Engine {
|
|||||||
}
|
}
|
||||||
case ISLANDS -> {
|
case ISLANDS -> {
|
||||||
getFramework().getTerrainActuator().actuate(x, z, vblocks, multicore);
|
getFramework().getTerrainActuator().actuate(x, z, vblocks, multicore);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getMetrics().getTotal().put(p.getMilliseconds());
|
getMetrics().getTotal().put(p.getMilliseconds());
|
||||||
|
|
||||||
if (IrisSettings.get().getGeneral().isDebug()) {
|
|
||||||
KList<String> v = new KList<>();
|
|
||||||
KMap<String, Double> g = getMetrics().pull();
|
|
||||||
|
|
||||||
for (String i : g.sortKNumber()) {
|
|
||||||
if (g.get(i) != null) {
|
|
||||||
v.add(C.RESET + "" + C.LIGHT_PURPLE + i + ": " + C.UNDERLINE + C.BLUE + Form.duration(g.get(i), 0) + C.RESET + C.GRAY + "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Iris.debug(v.toString(", "));
|
|
||||||
}
|
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Iris.reportError(e);
|
Iris.reportError(e);
|
||||||
fail("Failed to generate " + x + ", " + z, e);
|
fail("Failed to generate " + x + ", " + z, e);
|
||||||
@ -258,7 +244,9 @@ public class IrisEngine extends BlockPopulator implements Engine {
|
|||||||
f.getParentFile().mkdirs();
|
f.getParentFile().mkdirs();
|
||||||
try {
|
try {
|
||||||
IO.writeAll(f, new Gson().toJson(getEngineData()));
|
IO.writeAll(f, new Gson().toJson(getEngineData()));
|
||||||
|
Iris.debug("Saved Engine Data");
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
Iris.error("Failed to save Engine Data");
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,6 +114,7 @@ public class ParallaxWorld implements ParallaxAccess {
|
|||||||
|
|
||||||
if (lr != null) {
|
if (lr != null) {
|
||||||
v += lr.unload();
|
v += lr.unload();
|
||||||
|
Iris.debug("Unloaded Parallax Region " + C.RED + x + " " + z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,6 +129,7 @@ public class ParallaxWorld implements ParallaxAccess {
|
|||||||
|
|
||||||
ParallaxRegion v = new ParallaxRegion(burst, height, folder, x, z);
|
ParallaxRegion v = new ParallaxRegion(burst, height, folder, x, z);
|
||||||
loadedRegions.put(key(x, z), v);
|
loadedRegions.put(key(x, z), v);
|
||||||
|
Iris.debug("Loaded Parallax Region " + C.RED + x + " " + z);
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
@ -61,6 +61,14 @@ public interface Hunk<T> {
|
|||||||
return new HunkView<T>(src);
|
return new HunkView<T>(src);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default boolean isMapped() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default int getEntryCount() {
|
||||||
|
return getWidth() * getHeight() * getDepth();
|
||||||
|
}
|
||||||
|
|
||||||
static <A, B> Hunk<B> convertedReadView(Hunk<A> src, Function<A, B> reader) {
|
static <A, B> Hunk<B> convertedReadView(Hunk<A> src, Function<A, B> reader) {
|
||||||
return new FunctionalHunkView<A, B>(src, reader, null);
|
return new FunctionalHunkView<A, B>(src, reader, null);
|
||||||
}
|
}
|
||||||
@ -1059,6 +1067,45 @@ public interface Hunk<T> {
|
|||||||
setRaw(x, y, z, t);
|
setRaw(x, y, z, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a hunk that is optimized for specific uses
|
||||||
|
* @param w width
|
||||||
|
* @param h height
|
||||||
|
* @param d depth
|
||||||
|
* @param type the class type
|
||||||
|
* @param packed if the hunk is generally more than 50% full (non-null nodes)
|
||||||
|
* @param concurrent if this hunk must be thread safe
|
||||||
|
* @param <T> the type
|
||||||
|
* @return the hunk
|
||||||
|
*/
|
||||||
|
static <T> Hunk<T> newHunk(int w, int h, int d, Class<T> type, boolean packed, boolean concurrent)
|
||||||
|
{
|
||||||
|
if(type.equals(Double.class))
|
||||||
|
{
|
||||||
|
return concurrent ?
|
||||||
|
packed ? (Hunk<T>) newAtomicDoubleHunk(w,h,d) : newMappedHunk(w,h,d)
|
||||||
|
: packed ? newArrayHunk(w,h,d) : newMappedHunkSynced(w,h,d);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(type.equals(Integer.class))
|
||||||
|
{
|
||||||
|
return concurrent ?
|
||||||
|
packed ? (Hunk<T>) newAtomicIntegerHunk(w,h,d) : newMappedHunk(w,h,d)
|
||||||
|
: packed ? newArrayHunk(w,h,d) : newMappedHunkSynced(w,h,d);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(type.equals(Long.class))
|
||||||
|
{
|
||||||
|
return concurrent ?
|
||||||
|
packed ? (Hunk<T>) newAtomicLongHunk(w,h,d) : newMappedHunk(w,h,d)
|
||||||
|
: packed ? newArrayHunk(w,h,d) : newMappedHunkSynced(w,h,d);
|
||||||
|
}
|
||||||
|
|
||||||
|
return concurrent ?
|
||||||
|
packed ? newAtomicHunk(w,h,d) : newMappedHunk(w,h,d)
|
||||||
|
: packed ? newArrayHunk(w,h,d) : newMappedHunkSynced(w,h,d);
|
||||||
|
}
|
||||||
|
|
||||||
default void setIfExists(int x, int y, int z, T t) {
|
default void setIfExists(int x, int y, int z, T t) {
|
||||||
if (x < 0 || x >= getWidth() || y < 0 || y >= getHeight() || z < 0 || z >= getDepth()) {
|
if (x < 0 || x >= getWidth() || y < 0 || y >= getHeight() || z < 0 || z >= getDepth()) {
|
||||||
return;
|
return;
|
||||||
|
24
src/main/java/com/volmit/iris/util/hunk/HunkFactory.java
Normal file
24
src/main/java/com/volmit/iris/util/hunk/HunkFactory.java
Normal file
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.volmit.iris.util.hunk;
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface HunkFactory {
|
||||||
|
<T> Hunk<T> create(int w, int h, int d);
|
||||||
|
}
|
@ -20,6 +20,7 @@ package com.volmit.iris.util.hunk.storage;
|
|||||||
|
|
||||||
import com.volmit.iris.engine.data.cache.Cache;
|
import com.volmit.iris.engine.data.cache.Cache;
|
||||||
import com.volmit.iris.util.hunk.Hunk;
|
import com.volmit.iris.util.hunk.Hunk;
|
||||||
|
import com.volmit.iris.util.hunk.HunkFactory;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
@ -43,6 +43,10 @@ public class MappedHunk<T> extends StorageHunk<T> implements Hunk<T> {
|
|||||||
return data.size();
|
return data.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isMapped() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isEmpty()
|
public boolean isEmpty()
|
||||||
{
|
{
|
||||||
return data.isEmpty();
|
return data.isEmpty();
|
||||||
|
107
src/main/java/com/volmit/iris/util/mantle/Mantle.java
Normal file
107
src/main/java/com/volmit/iris/util/mantle/Mantle.java
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
* 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.mantle;
|
||||||
|
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.engine.data.cache.Cache;
|
||||||
|
import com.volmit.iris.util.collection.KMap;
|
||||||
|
import com.volmit.iris.util.documentation.RegionCoordinates;
|
||||||
|
import com.volmit.iris.util.format.C;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class Mantle
|
||||||
|
{
|
||||||
|
private final File dataFolder;
|
||||||
|
private final int worldHeight;
|
||||||
|
private final Map<Long, MantleRegion> loadedRegions;
|
||||||
|
|
||||||
|
public Mantle(File dataFolder, int worldHeight)
|
||||||
|
{
|
||||||
|
this.dataFolder = dataFolder;
|
||||||
|
this.worldHeight = worldHeight;
|
||||||
|
dataFolder.mkdirs();
|
||||||
|
loadedRegions = new KMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@RegionCoordinates
|
||||||
|
public MantleRegion get(int x, int z)
|
||||||
|
{
|
||||||
|
Long k = key(x, z);
|
||||||
|
MantleRegion region = loadedRegions.get(k);
|
||||||
|
|
||||||
|
if(region != null)
|
||||||
|
{
|
||||||
|
return region;
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized (loadedRegions)
|
||||||
|
{
|
||||||
|
// Ensure we are the first loading thread
|
||||||
|
region = loadedRegions.get(k);
|
||||||
|
|
||||||
|
if(region != null)
|
||||||
|
{
|
||||||
|
return region;
|
||||||
|
}
|
||||||
|
|
||||||
|
File file = fileForRegion(x, z);
|
||||||
|
|
||||||
|
if(file.exists())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
FileInputStream fin = new FileInputStream(file);
|
||||||
|
DataInputStream din = new DataInputStream(fin);
|
||||||
|
region = new MantleRegion(worldHeight, din);
|
||||||
|
din.close();
|
||||||
|
Iris.debug("Loaded Mantle Region " + C.RED + x + " " + z + C.DARK_AQUA + " " + file.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
catch(Throwable e)
|
||||||
|
{
|
||||||
|
Iris.error("Failed to read Mantle Region " + file.getAbsolutePath() + " creating a new chunk instead.");
|
||||||
|
Iris.reportError(e);
|
||||||
|
e.printStackTrace();
|
||||||
|
region = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(region != null)
|
||||||
|
{
|
||||||
|
return region;
|
||||||
|
}
|
||||||
|
|
||||||
|
Iris.debug("Created new Mantle Region " + C.RED + x + " " + z);
|
||||||
|
return new MantleRegion(worldHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private File fileForRegion(int x, int z) {
|
||||||
|
return new File("m." + x + "." + z + ".mtl");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long key(int x, int z)
|
||||||
|
{
|
||||||
|
return Cache.key(x, z);
|
||||||
|
}
|
||||||
|
}
|
112
src/main/java/com/volmit/iris/util/mantle/MantleChunk.java
Normal file
112
src/main/java/com/volmit/iris/util/mantle/MantleChunk.java
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
/*
|
||||||
|
* 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.mantle;
|
||||||
|
|
||||||
|
import com.volmit.iris.engine.data.chunk.MCATerrainChunk;
|
||||||
|
import com.volmit.iris.util.data.Varint;
|
||||||
|
import com.volmit.iris.util.documentation.ChunkCoordinates;
|
||||||
|
import com.volmit.iris.util.nbt.mca.Section;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.atomic.AtomicReferenceArray;
|
||||||
|
|
||||||
|
public class MantleChunk {
|
||||||
|
private final AtomicReferenceArray<MantleMatter> sections;
|
||||||
|
|
||||||
|
@ChunkCoordinates
|
||||||
|
public MantleChunk(int sectionHeight)
|
||||||
|
{
|
||||||
|
sections = new AtomicReferenceArray<>(sectionHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MantleChunk(int sectionHeight, DataInputStream din) throws IOException, ClassNotFoundException {
|
||||||
|
this(sectionHeight);
|
||||||
|
int s = Varint.readUnsignedVarInt(din);
|
||||||
|
|
||||||
|
for(int i = 0; i < s; i++)
|
||||||
|
{
|
||||||
|
if(din.readBoolean())
|
||||||
|
{
|
||||||
|
sections.set(i, MantleMatter.read(din));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ChunkCoordinates
|
||||||
|
public boolean exists(int section)
|
||||||
|
{
|
||||||
|
return get(section) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ChunkCoordinates
|
||||||
|
public MantleMatter get(int section)
|
||||||
|
{
|
||||||
|
return sections.get(section);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear()
|
||||||
|
{
|
||||||
|
for(int i = 0; i < sections.length(); i++)
|
||||||
|
{
|
||||||
|
delete(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ChunkCoordinates
|
||||||
|
public void delete(int section)
|
||||||
|
{
|
||||||
|
sections.set(section, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ChunkCoordinates
|
||||||
|
public MantleMatter getOrCreate(int section)
|
||||||
|
{
|
||||||
|
MantleMatter matter = get(section);
|
||||||
|
|
||||||
|
if(matter == null)
|
||||||
|
{
|
||||||
|
matter = new MantleMatter(16, 16, 16);
|
||||||
|
sections.set(section, matter);
|
||||||
|
}
|
||||||
|
|
||||||
|
return matter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(DataOutputStream dos) throws IOException {
|
||||||
|
Varint.writeUnsignedVarInt(sections.length(), dos);
|
||||||
|
|
||||||
|
for(int i = 0; i < sections.length(); i++)
|
||||||
|
{
|
||||||
|
if(exists(i))
|
||||||
|
{
|
||||||
|
dos.writeBoolean(true);
|
||||||
|
MantleMatter matter = get(i);
|
||||||
|
matter.writeDos(dos);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dos.writeBoolean(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
69
src/main/java/com/volmit/iris/util/mantle/MantleMatter.java
Normal file
69
src/main/java/com/volmit/iris/util/mantle/MantleMatter.java
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* 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.mantle;
|
||||||
|
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.util.collection.KMap;
|
||||||
|
import com.volmit.iris.util.matter.IrisMatter;
|
||||||
|
import com.volmit.iris.util.matter.Matter;
|
||||||
|
import com.volmit.iris.util.matter.MatterSlice;
|
||||||
|
import com.volmit.iris.util.matter.Sliced;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class MantleMatter extends IrisMatter
|
||||||
|
{
|
||||||
|
protected static final KMap<Class<?>, MatterSlice<?>> slicers = buildSlicers();
|
||||||
|
|
||||||
|
public MantleMatter(int width, int height, int depth) {
|
||||||
|
super(width, height, depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MantleMatter read(DataInputStream din) throws IOException, ClassNotFoundException {
|
||||||
|
return (MantleMatter) Matter.read(din, (b) -> new MantleMatter(b.getX(), b.getY(), b.getZ()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> MatterSlice<T> createSlice(Class<T> type, Matter m) {
|
||||||
|
MatterSlice<?> slice = slicers.get(type);
|
||||||
|
|
||||||
|
if (slice == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
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<Class<?>, MatterSlice<?>> buildSlicers() {
|
||||||
|
KMap<Class<?>, MatterSlice<?>> c = new KMap<>();
|
||||||
|
for (Object i : Iris.initialize("com.volmit.iris.util.mantle.slices", Sliced.class)) {
|
||||||
|
MatterSlice<?> s = (MatterSlice<?>) i;
|
||||||
|
c.put(s.getType(), s);
|
||||||
|
}
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
}
|
107
src/main/java/com/volmit/iris/util/mantle/MantleRegion.java
Normal file
107
src/main/java/com/volmit/iris/util/mantle/MantleRegion.java
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
* 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.mantle;
|
||||||
|
|
||||||
|
import com.volmit.iris.util.documentation.ChunkCoordinates;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.atomic.AtomicReferenceArray;
|
||||||
|
|
||||||
|
public class MantleRegion {
|
||||||
|
private final int sectionHeight;
|
||||||
|
private final AtomicReferenceArray<MantleChunk> chunks;
|
||||||
|
|
||||||
|
public MantleRegion(int worldHeight)
|
||||||
|
{
|
||||||
|
this.sectionHeight = worldHeight >> 4;
|
||||||
|
this.chunks = new AtomicReferenceArray<>(1024);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MantleRegion(int worldHeight, DataInputStream din) throws IOException, ClassNotFoundException {
|
||||||
|
this(worldHeight);
|
||||||
|
|
||||||
|
for(int i = 0; i < chunks.length(); i++)
|
||||||
|
{
|
||||||
|
if(din.readBoolean())
|
||||||
|
{
|
||||||
|
chunks.set(i, new MantleChunk(sectionHeight, din));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ChunkCoordinates
|
||||||
|
public boolean exists(int x, int z)
|
||||||
|
{
|
||||||
|
return get(x, z) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ChunkCoordinates
|
||||||
|
public MantleChunk get(int x, int z)
|
||||||
|
{
|
||||||
|
return chunks.get(index(x, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear()
|
||||||
|
{
|
||||||
|
for(int i = 0; i < chunks.length(); i++)
|
||||||
|
{
|
||||||
|
chunks.set(i, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ChunkCoordinates
|
||||||
|
public void delete(int x, int z)
|
||||||
|
{
|
||||||
|
chunks.set(index(x, z), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ChunkCoordinates
|
||||||
|
public MantleChunk getOrCreate(int x, int z)
|
||||||
|
{
|
||||||
|
MantleChunk chunk = get(x, z);
|
||||||
|
|
||||||
|
if(chunk == null)
|
||||||
|
{
|
||||||
|
chunk = new MantleChunk(sectionHeight);
|
||||||
|
chunks.set(index(x, z), chunk);
|
||||||
|
}
|
||||||
|
|
||||||
|
return chunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ChunkCoordinates
|
||||||
|
private int index(int x, int z) {
|
||||||
|
return (x & 0x1F) + (z & 0x1F) * 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(DataOutputStream dos) throws IOException {
|
||||||
|
for(int i = 0; i < chunks.length(); i++)
|
||||||
|
{
|
||||||
|
MantleChunk chunk = chunks.get(i);
|
||||||
|
dos.writeBoolean(chunk != null);
|
||||||
|
|
||||||
|
if(chunk != null)
|
||||||
|
{
|
||||||
|
chunk.write(dos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* 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.mantle.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.matter.slices.RawMatter;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.block.data.BlockData;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@Sliced
|
||||||
|
public class MantleBlockMatter extends RawMatter<BlockData> {
|
||||||
|
public MantleBlockMatter() {
|
||||||
|
this(1, 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MantleBlockMatter(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) -> {
|
||||||
|
BlockData d = w.getBlockAt(x, y, z).getBlockData();
|
||||||
|
return d.getMaterial().isAir() ? null : d;
|
||||||
|
});
|
||||||
|
registerReader(ParallaxWorld.class, ParallaxAccess::getBlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeNode(BlockData b, DataOutputStream dos) throws IOException {
|
||||||
|
dos.writeUTF(b.getAsString(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockData readNode(DataInputStream din) throws IOException {
|
||||||
|
return B.get(din.readUTF());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* 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.mantle.slices;
|
||||||
|
|
||||||
|
import com.volmit.iris.util.collection.KMap;
|
||||||
|
import com.volmit.iris.util.hunk.storage.ArrayHunk;
|
||||||
|
import com.volmit.iris.util.hunk.storage.AtomicHunk;
|
||||||
|
import com.volmit.iris.util.hunk.storage.MappedHunk;
|
||||||
|
import com.volmit.iris.util.matter.MatterReader;
|
||||||
|
import com.volmit.iris.util.matter.MatterSlice;
|
||||||
|
import com.volmit.iris.util.matter.MatterWriter;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public abstract class RawMantleMatter<T> extends AtomicHunk<T> implements MatterSlice<T> {
|
||||||
|
@Getter
|
||||||
|
private final Class<T> type;
|
||||||
|
protected final KMap<Class<?>, MatterWriter<?, T>> writers;
|
||||||
|
protected final KMap<Class<?>, MatterReader<?, T>> readers;
|
||||||
|
|
||||||
|
public RawMantleMatter(int width, int height, int depth, Class<T> type) {
|
||||||
|
super(width, height, depth);
|
||||||
|
writers = new KMap<>();
|
||||||
|
readers = new KMap<>();
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected <W> void registerWriter(Class<W> mediumType, MatterWriter<W, T> injector) {
|
||||||
|
writers.put(mediumType, injector);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected <W> void registerReader(Class<W> mediumType, MatterReader<W, T> injector) {
|
||||||
|
readers.put(mediumType, injector);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <W> MatterWriter<W, T> writeInto(Class<W> mediumType) {
|
||||||
|
return (MatterWriter<W, T>) writers.get(mediumType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <W> MatterReader<W, T> readFrom(Class<W> mediumType) {
|
||||||
|
return (MatterReader<W, T>) readers.get(mediumType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public abstract void writeNode(T b, DataOutputStream dos) throws IOException;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public abstract T readNode(DataInputStream din) throws IOException;
|
||||||
|
}
|
@ -24,6 +24,7 @@ import com.volmit.iris.util.data.Varint;
|
|||||||
import com.volmit.iris.util.hunk.Hunk;
|
import com.volmit.iris.util.hunk.Hunk;
|
||||||
import com.volmit.iris.util.math.BlockPosition;
|
import com.volmit.iris.util.math.BlockPosition;
|
||||||
|
|
||||||
|
import javax.xml.crypto.Data;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -87,7 +88,7 @@ public interface Matter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a slice from the given type
|
* Create a slice from the given type (full is false)
|
||||||
*
|
*
|
||||||
* @param type the type class
|
* @param type the type class
|
||||||
* @param matter the matter this slice will go into (size provider)
|
* @param matter the matter this slice will go into (size provider)
|
||||||
@ -248,7 +249,7 @@ public interface Matter {
|
|||||||
Set<Class<?>> drop = null;
|
Set<Class<?>> drop = null;
|
||||||
|
|
||||||
for (Class<?> i : getSliceTypes()) {
|
for (Class<?> i : getSliceTypes()) {
|
||||||
if (getSlice(i).getCount() == 0) {
|
if (getSlice(i).getEntryCount() == 0) {
|
||||||
if (drop == null) {
|
if (drop == null) {
|
||||||
drop = new KSet<>();
|
drop = new KSet<>();
|
||||||
}
|
}
|
||||||
@ -272,8 +273,11 @@ public interface Matter {
|
|||||||
* @throws IOException shit happens yo
|
* @throws IOException shit happens yo
|
||||||
*/
|
*/
|
||||||
default void write(OutputStream out) throws IOException {
|
default void write(OutputStream out) throws IOException {
|
||||||
|
writeDos(new DataOutputStream(out));
|
||||||
|
}
|
||||||
|
|
||||||
|
default void writeDos(DataOutputStream dos) throws IOException {
|
||||||
trimSlices();
|
trimSlices();
|
||||||
DataOutputStream dos = new DataOutputStream(out);
|
|
||||||
Varint.writeUnsignedVarInt(getWidth(), dos);
|
Varint.writeUnsignedVarInt(getWidth(), dos);
|
||||||
Varint.writeUnsignedVarInt(getHeight(), dos);
|
Varint.writeUnsignedVarInt(getHeight(), dos);
|
||||||
Varint.writeUnsignedVarInt(getDepth(), dos);
|
Varint.writeUnsignedVarInt(getDepth(), dos);
|
||||||
@ -283,8 +287,6 @@ public interface Matter {
|
|||||||
for (Class<?> i : getSliceTypes()) {
|
for (Class<?> i : getSliceTypes()) {
|
||||||
getSlice(i).write(dos);
|
getSlice(i).write(dos);
|
||||||
}
|
}
|
||||||
|
|
||||||
dos.flush();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Matter read(File f) throws IOException, ClassNotFoundException {
|
static Matter read(File f) throws IOException, ClassNotFoundException {
|
||||||
@ -339,7 +341,7 @@ public interface Matter {
|
|||||||
|
|
||||||
for(MatterSlice<?> i : getSliceMap().values())
|
for(MatterSlice<?> i : getSliceMap().values())
|
||||||
{
|
{
|
||||||
m+= i.getCount();
|
m+= i.getEntryCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
return m;
|
return m;
|
||||||
|
@ -99,14 +99,6 @@ public interface MatterSlice<T> extends Hunk<T> {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// BlockMatter<T>
|
|
||||||
// RawMatter<T> ex MappedHunk<T>
|
|
||||||
// IMatterSlice<T> ex Hunk<T>
|
|
||||||
|
|
||||||
default int getCount() {
|
|
||||||
return ((MappedHunk<?>) this).getEntryCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean canWrite(Class<?> mediumType) {
|
default boolean canWrite(Class<?> mediumType) {
|
||||||
return writeInto(mediumType) != null;
|
return writeInto(mediumType) != null;
|
||||||
}
|
}
|
||||||
@ -122,18 +114,29 @@ public interface MatterSlice<T> extends Hunk<T> {
|
|||||||
MatterPalette<T> palette = new MatterPalette<T>(this);
|
MatterPalette<T> palette = new MatterPalette<T>(this);
|
||||||
iterateSync((x, y, z, b) -> palette.assign(b));
|
iterateSync((x, y, z, b) -> palette.assign(b));
|
||||||
palette.writePalette(dos);
|
palette.writePalette(dos);
|
||||||
Varint.writeUnsignedVarInt(getCount(), dos);
|
dos.writeBoolean(isMapped());
|
||||||
|
|
||||||
|
if(isMapped())
|
||||||
|
{
|
||||||
|
Varint.writeUnsignedVarInt(getEntryCount(), dos);
|
||||||
iterateSyncIO((x, y, z, b) -> {
|
iterateSyncIO((x, y, z, b) -> {
|
||||||
Varint.writeUnsignedVarInt(Cache.to1D(x, y, z, w, h), dos);
|
Varint.writeUnsignedVarInt(Cache.to1D(x, y, z, w, h), dos);
|
||||||
palette.writeNode(b, dos);
|
palette.writeNode(b, dos);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
iterateSyncIO((x, y, z, b) -> palette.writeNode(b, dos));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
default void read(DataInputStream din) throws IOException {
|
default void read(DataInputStream din) throws IOException {
|
||||||
int w = getWidth();
|
int w = getWidth();
|
||||||
int h = getHeight();
|
int h = getHeight();
|
||||||
|
|
||||||
MatterPalette<T> palette = new MatterPalette<T>(this, din);
|
MatterPalette<T> palette = new MatterPalette<T>(this, din);
|
||||||
|
if(din.readBoolean())
|
||||||
|
{
|
||||||
int nodes = Varint.readUnsignedVarInt(din);
|
int nodes = Varint.readUnsignedVarInt(din);
|
||||||
int[] pos;
|
int[] pos;
|
||||||
|
|
||||||
@ -143,6 +146,12 @@ public interface MatterSlice<T> extends Hunk<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
iterateSyncIO((x, y, z, b) -> setRaw(x, y, z, palette.readNode(din)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
default void rotateSliceInto(Matter n, double x, double y, double z) {
|
default void rotateSliceInto(Matter n, double x, double y, double z) {
|
||||||
rotate(x, y, z, (_x, _y, _z) -> n.slice(getType()));
|
rotate(x, y, z, (_x, _y, _z) -> n.slice(getType()));
|
||||||
}
|
}
|
||||||
|
@ -38,12 +38,10 @@ public class BlockMatter extends RawMatter<BlockData> {
|
|||||||
public BlockMatter(int width, int height, int depth) {
|
public BlockMatter(int width, int height, int depth) {
|
||||||
super(width, height, depth, BlockData.class);
|
super(width, height, depth, BlockData.class);
|
||||||
registerWriter(World.class, ((w, d, x, y, z) -> w.getBlockAt(x, y, z).setBlockData(d)));
|
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) -> {
|
registerReader(World.class, (w, x, y, z) -> {
|
||||||
BlockData d = w.getBlockAt(x, y, z).getBlockData();
|
BlockData d = w.getBlockAt(x, y, z).getBlockData();
|
||||||
return d.getMaterial().isAir() ? null : d;
|
return d.getMaterial().isAir() ? null : d;
|
||||||
});
|
});
|
||||||
registerReader(ParallaxWorld.class, ParallaxAccess::getBlock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
x
Reference in New Issue
Block a user