Mantle flagging

This commit is contained in:
Daniel Mills 2021-08-09 09:06:45 -04:00
parent 0d8cb7393c
commit 4ee31db7a0
4 changed files with 220 additions and 16 deletions

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
package com.volmit.iris.util.collection;
public class StateList
{
private final KList<String> states;
public StateList(String... states)
{
this.states = new KList<String>(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<Enum<?>>().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<String> getEnabled(long list)
{
KList<String> 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();
}
}

View File

@ -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.KMap;
import com.volmit.iris.util.collection.KSet; import com.volmit.iris.util.collection.KSet;
import com.volmit.iris.util.documentation.BlockCoordinates; 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.documentation.RegionCoordinates;
import com.volmit.iris.util.format.C; import com.volmit.iris.util.format.C;
import com.volmit.iris.util.format.Form; import com.volmit.iris.util.format.Form;
@ -77,6 +78,48 @@ public class Mantle {
Iris.debug("Opened The Mantle " + C.DARK_AQUA + dataFolder.getAbsolutePath()); 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 * 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 * Tectonic Plate either by loading it or creating a new one. This method uses

View File

@ -19,6 +19,8 @@
package com.volmit.iris.util.mantle; package com.volmit.iris.util.mantle;
import com.volmit.iris.util.collection.KSet; 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.documentation.ChunkCoordinates;
import com.volmit.iris.util.matter.IrisMatter; import com.volmit.iris.util.matter.IrisMatter;
import com.volmit.iris.util.matter.Matter; 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.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.concurrent.atomic.AtomicIntegerArray;
import java.util.concurrent.atomic.AtomicReferenceArray; import java.util.concurrent.atomic.AtomicReferenceArray;
/** /**
@ -33,7 +36,8 @@ import java.util.concurrent.atomic.AtomicReferenceArray;
* Mantle Chunks are fully atomic & thread safe * Mantle Chunks are fully atomic & thread safe
*/ */
public class MantleChunk { public class MantleChunk {
private final KSet<String> flags; private static final StateList state = MantleFlag.getStateList();
private final AtomicIntegerArray flags;
private final AtomicReferenceArray<Matter> sections; private final AtomicReferenceArray<Matter> sections;
/** /**
@ -44,7 +48,7 @@ public class MantleChunk {
@ChunkCoordinates @ChunkCoordinates
public MantleChunk(int sectionHeight) { public MantleChunk(int sectionHeight) {
sections = new AtomicReferenceArray<>(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 { public MantleChunk(int sectionHeight, DataInputStream din) throws IOException, ClassNotFoundException {
this(sectionHeight); this(sectionHeight);
int s = din.readByte(); int s = din.readByte();
int f = din.readByte();
for (int i = 0; i < f; i++) { for(String i : state.getEnabled(Varint.readUnsignedVarLong(din)))
flags.add(din.readUTF()); {
flags.set(MantleFlag.valueOf(i).ordinal(), 1);
} }
for (int i = 0; i < s; i++) { for (int i = 0; i < s; i++) {
@ -71,16 +75,12 @@ public class MantleChunk {
} }
} }
public void flag(String s, boolean f) { public void flag(MantleFlag flag, boolean f) {
if (f) { flags.set(flag.ordinal(), f ? 1 : 0);
flags.add(s);
} else {
flags.remove(s);
}
} }
public boolean isFlagged(String s) { public boolean isFlagged(MantleFlag flag) {
return flags.contains(s); return flags.get(flags.get(flag.ordinal())) == 1;
} }
/** /**
@ -150,12 +150,14 @@ public class MantleChunk {
*/ */
public void write(DataOutputStream dos) throws IOException { public void write(DataOutputStream dos) throws IOException {
dos.writeByte(sections.length()); dos.writeByte(sections.length());
dos.writeByte(flags.size()); long data = 0;
for (String i : flags) { for (int i = 0; i < flags.length(); i++) {
dos.writeUTF(i); state.set(data, MantleFlag.values()[i].name(), flags.get(i) == 1);
} }
Varint.writeUnsignedVarLong(data, dos);
for (int i = 0; i < sections.length(); i++) { for (int i = 0; i < sections.length(); i++) {
if (exists(i)) { if (exists(i)) {
dos.writeBoolean(true); dos.writeBoolean(true);

View File

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