diff --git a/src/main/java/com/volmit/iris/util/collection/StateList.java b/src/main/java/com/volmit/iris/util/collection/StateList.java
new file mode 100644
index 000000000..62490d7f2
--- /dev/null
+++ b/src/main/java/com/volmit/iris/util/collection/StateList.java
@@ -0,0 +1,126 @@
+/*
+ * 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.collection;
+
+public class StateList
+{
+ private final KList states;
+
+ public StateList(String... states)
+ {
+ this.states = new KList(states);
+
+ if(getBits() > 64)
+ {
+ throw new RuntimeException("StateLists cannot exceed 64 bits! You are trying to use " + getBits() + " bits!");
+ }
+ }
+
+ public StateList(Enum>... states)
+ {
+ this.states = new KList>().convert(Enum::name);
+
+ if(getBits() > 64)
+ {
+ throw new RuntimeException("StateLists cannot exceed 64 bits! You are trying to use " + getBits() + " bits!");
+ }
+ }
+
+ public long max()
+ {
+ return (long) (Math.pow(2, getBits()) - 1);
+ }
+
+ public KList getEnabled(long list)
+ {
+ KList f = new KList<>();
+
+ for(String i : states)
+ {
+ if(is(list, i))
+ {
+ f.add(i);
+ }
+ }
+
+ return f;
+ }
+
+ public long of(String... enabledStates)
+ {
+ long b = 0;
+
+ for(String i : enabledStates)
+ {
+ b |= getBit(i);
+ }
+
+ return b;
+ }
+
+ public long set(long list, String state, boolean enabled)
+ {
+ long bit = getBit(state);
+ boolean is = is(list, state);
+
+ if(enabled && !is)
+ {
+ return list | bit;
+ }
+
+ else if(!enabled && is)
+ {
+ return list ^ bit;
+ }
+
+ return list;
+ }
+
+ public boolean is(long list, String state)
+ {
+ long bit = getBit(state);
+
+ return bit > 0 && (list & bit) == bit;
+ }
+
+ public boolean hasBit(String state)
+ {
+ return getBit(state) > 0;
+ }
+
+ public long getBit(String state)
+ {
+ return getBit(states.indexOf(state));
+ }
+
+ public long getBit(int index)
+ {
+ return (long) (index < 0 ? -1 : Math.pow(2, index));
+ }
+
+ public int getBytes()
+ {
+ return getBits() == 0 ? 0 : ((getBits() >> 2) + 1);
+ }
+
+ public int getBits()
+ {
+ return states.size();
+ }
+}
diff --git a/src/main/java/com/volmit/iris/util/mantle/Mantle.java b/src/main/java/com/volmit/iris/util/mantle/Mantle.java
index f2026c452..f607a530d 100644
--- a/src/main/java/com/volmit/iris/util/mantle/Mantle.java
+++ b/src/main/java/com/volmit/iris/util/mantle/Mantle.java
@@ -23,6 +23,7 @@ import com.volmit.iris.engine.data.cache.Cache;
import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.collection.KSet;
import com.volmit.iris.util.documentation.BlockCoordinates;
+import com.volmit.iris.util.documentation.ChunkCoordinates;
import com.volmit.iris.util.documentation.RegionCoordinates;
import com.volmit.iris.util.format.C;
import com.volmit.iris.util.format.Form;
@@ -77,6 +78,48 @@ public class Mantle {
Iris.debug("Opened The Mantle " + C.DARK_AQUA + dataFolder.getAbsolutePath());
}
+ @ChunkCoordinates
+ public void raiseFlag(int x, int z, MantleFlag flag, Runnable r)
+ {
+ if(!hasFlag(x, z, flag))
+ {
+ flag(x, z, flag, true);
+ r.run();
+ }
+ }
+
+ @ChunkCoordinates
+ public void lowerFlag(int x, int z, MantleFlag flag, Runnable r)
+ {
+ if(hasFlag(x, z, flag))
+ {
+ flag(x, z, flag, false);
+ r.run();
+ }
+ }
+
+ @ChunkCoordinates
+ public void flag(int x, int z, MantleFlag flag, boolean flagged)
+ {
+ try {
+ get(x >> 5, z >> 5).get().get(x & 31, z & 31).flag(flag, flagged);
+ } catch (InterruptedException | ExecutionException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @ChunkCoordinates
+ public boolean hasFlag(int x, int z, MantleFlag flag)
+ {
+ try {
+ get(x >> 5, z >> 5).get().get(x & 31, z & 31).isFlagged(flag);
+ } catch (InterruptedException | ExecutionException e) {
+ e.printStackTrace();
+ }
+
+ return false;
+ }
+
/**
* Set data T at the given block position. This method will attempt to find a
* Tectonic Plate either by loading it or creating a new one. This method uses
diff --git a/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java b/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java
index ebbd93916..28fd95243 100644
--- a/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java
+++ b/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java
@@ -19,6 +19,8 @@
package com.volmit.iris.util.mantle;
import com.volmit.iris.util.collection.KSet;
+import com.volmit.iris.util.collection.StateList;
+import com.volmit.iris.util.data.Varint;
import com.volmit.iris.util.documentation.ChunkCoordinates;
import com.volmit.iris.util.matter.IrisMatter;
import com.volmit.iris.util.matter.Matter;
@@ -26,6 +28,7 @@ import com.volmit.iris.util.matter.Matter;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
+import java.util.concurrent.atomic.AtomicIntegerArray;
import java.util.concurrent.atomic.AtomicReferenceArray;
/**
@@ -33,7 +36,8 @@ import java.util.concurrent.atomic.AtomicReferenceArray;
* Mantle Chunks are fully atomic & thread safe
*/
public class MantleChunk {
- private final KSet flags;
+ private static final StateList state = MantleFlag.getStateList();
+ private final AtomicIntegerArray flags;
private final AtomicReferenceArray sections;
/**
@@ -44,7 +48,7 @@ public class MantleChunk {
@ChunkCoordinates
public MantleChunk(int sectionHeight) {
sections = new AtomicReferenceArray<>(sectionHeight);
- flags = new KSet<>();
+ flags = new AtomicIntegerArray(MantleFlag.values().length);
}
/**
@@ -58,10 +62,10 @@ public class MantleChunk {
public MantleChunk(int sectionHeight, DataInputStream din) throws IOException, ClassNotFoundException {
this(sectionHeight);
int s = din.readByte();
- int f = din.readByte();
- for (int i = 0; i < f; i++) {
- flags.add(din.readUTF());
+ for(String i : state.getEnabled(Varint.readUnsignedVarLong(din)))
+ {
+ flags.set(MantleFlag.valueOf(i).ordinal(), 1);
}
for (int i = 0; i < s; i++) {
@@ -71,16 +75,12 @@ public class MantleChunk {
}
}
- public void flag(String s, boolean f) {
- if (f) {
- flags.add(s);
- } else {
- flags.remove(s);
- }
+ public void flag(MantleFlag flag, boolean f) {
+ flags.set(flag.ordinal(), f ? 1 : 0);
}
- public boolean isFlagged(String s) {
- return flags.contains(s);
+ public boolean isFlagged(MantleFlag flag) {
+ return flags.get(flags.get(flag.ordinal())) == 1;
}
/**
@@ -150,12 +150,14 @@ public class MantleChunk {
*/
public void write(DataOutputStream dos) throws IOException {
dos.writeByte(sections.length());
- dos.writeByte(flags.size());
+ long data = 0;
- for (String i : flags) {
- dos.writeUTF(i);
+ for (int i = 0; i < flags.length(); i++) {
+ state.set(data, MantleFlag.values()[i].name(), flags.get(i) == 1);
}
+ Varint.writeUnsignedVarLong(data, dos);
+
for (int i = 0; i < sections.length(); i++) {
if (exists(i)) {
dos.writeBoolean(true);
diff --git a/src/main/java/com/volmit/iris/util/mantle/MantleFlag.java b/src/main/java/com/volmit/iris/util/mantle/MantleFlag.java
new file mode 100644
index 000000000..128773092
--- /dev/null
+++ b/src/main/java/com/volmit/iris/util/mantle/MantleFlag.java
@@ -0,0 +1,33 @@
+/*
+ * 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.mantle;
+
+import com.volmit.iris.util.collection.StateList;
+
+public enum MantleFlag {
+ OBJECT,
+ VACUUM,
+ JIGSAW,
+ FEATURE
+ ;
+ static StateList getStateList()
+ {
+ return new StateList(MantleFlag.values());
+ }
+}