AnnotatedNBT

This commit is contained in:
Runemoro 2017-12-28 23:46:29 -05:00
parent 2e5217a17c
commit 7dacc56bd7
41 changed files with 937 additions and 595 deletions

35
AnnotatedNBT/build.gradle Normal file
View file

@ -0,0 +1,35 @@
buildscript {
repositories {
jcenter()
maven { url = "http://files.minecraftforge.net/maven" }
}
dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'
}
}
plugins {
id 'io.franzbecker.gradle-lombok'
id 'java'
}
apply plugin: 'net.minecraftforge.gradle.forge'
apply plugin: 'java'
group 'org.dimdev.annotatednbt'
version '1.0'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
}
minecraft {
version = "1.12.2-14.23.1.2555"
mappings = "snapshot_20171007"
}

View file

@ -0,0 +1,47 @@
package org.dimdev.ddutils.nbt;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.Collections;
public class IndentedPrintWriter extends PrintWriter { // TODO: verify indentation using a marking system when passing?
private int indent = 0;
private boolean startOfLine;
public IndentedPrintWriter(Writer out) {
super(out);
}
public void indent(int n) {
if (indent + n < 0) throw new IllegalArgumentException("Can't set indentation to less than 0!");
indent += n;
}
public void unindent(int n) {
indent(-n);
}
public void indent() {
indent(4);
}
public void unindent() {
indent(-4);
}
@Override
public void print(String s) {
if (startOfLine) {
super.print(String.join("", Collections.nCopies(indent, " ")));
}
super.print(s);
startOfLine = false;
}
@Override
public void println() {
super.println();
startOfLine = true;
}
}

View file

@ -0,0 +1,32 @@
package org.dimdev.ddutils.nbt;
import net.minecraft.nbt.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public final class NBTUtils {
public static NBTTagCompound writeToNBT(Object obj, NBTTagCompound nbt) {
try {
Class<?> callingClass = Class.forName(new Exception().getStackTrace()[1].getClassName());
Class<?> nbtWriter = Class.forName(callingClass.getPackage().getName() + "." + callingClass.getSimpleName() + "NBTWriter");
Method write = nbtWriter.getMethod("writeToNBT", callingClass, NBTTagCompound.class);
write.invoke(null, obj, nbt);
return nbt;
} catch (ClassNotFoundException|NoSuchMethodException|IllegalAccessException|InvocationTargetException e) {
throw new RuntimeException(e);
}
}
public static void readFromNBT(Object obj, NBTTagCompound nbt) {
try {
Class<?> callingClass = Class.forName(new Exception().getStackTrace()[1].getClassName());
Class<?> nbtWriter = Class.forName(callingClass.getPackage().getName() + "." + callingClass.getSimpleName() + "NBTWriter");
Method read = nbtWriter.getMethod("readFromNBT", callingClass, NBTTagCompound.class);
read.invoke(null, obj, nbt);
} catch (ClassNotFoundException|NoSuchMethodException|IllegalAccessException|InvocationTargetException e) {
throw new RuntimeException(e);
}
}
}

View file

@ -0,0 +1,12 @@
package org.dimdev.ddutils.nbt;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE, ElementType.FIELD}) // TODO: split annotation, error when set on field but not containing class
@Retention(RetentionPolicy.RUNTIME)
public @interface SavedToNBT {
}

View file

@ -0,0 +1,628 @@
package org.dimdev.ddutils.nbt;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.*;
import javax.lang.model.type.*;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
import javax.tools.JavaFileObject;
import java.io.IOException;
import java.util.*;
@SupportedAnnotationTypes("org.dimdev.ddutils.nbt.SavedToNBT")
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class SavedToNBTProcessor extends AbstractProcessor {
private static final String BOOLEAN = "java.lang.Boolean";
private static final String BYTE = "java.lang.Byte";
private static final String SHORT = "java.lang.Short";
private static final String INTEGER = "java.lang.Integer";
private static final String LONG = "java.lang.Long";
private static final String CHAR = "java.lang.Char";
private static final String FLOAT = "java.lang.Float";
private static final String DOUBLE = "java.lang.Double";
private static final String STRING = "java.lang.String";
private static final String COLLECTION = "java.util.Collection"; // TODO: Allow storing any Iterable?
private static final String MAP = "java.util.Map";
private static final String MAP_ENTRY = "java.util.Map.Entry";
private static final String NBT_STORABLE = "org.dimdev.ddutils.nbt.INBTStorable";
private static final String VEC_3I = "net.minecraft.util.math.Vec3i";
private static final String LOCATION = "org.dimdev.ddutils.Location";
private static final String VIRTUAL_LOCATION = "org.dimdev.dimdoors.shared.VirtualLocation";
private static final String UUID = "java.util.UUID";
private Map<String, Integer> varCounter = new HashMap<>();
@SuppressWarnings("StringConcatenationInsideStringBufferAppend")
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { // TODO: generics, inheritance, different exception for error type
roundEnv.getElementsAnnotatedWith(SavedToNBT.class);
for (Element element : roundEnv.getElementsAnnotatedWith(SavedToNBT.class)) {
if (element.getKind() != ElementKind.CLASS) continue;
TypeElement classElement = (TypeElement) element;
Element enclosingElement = classElement;
while (!(enclosingElement instanceof PackageElement)) {
enclosingElement = enclosingElement.getEnclosingElement();
}
PackageElement packageElement = (PackageElement) enclosingElement;
JavaFileObject jfo;
IndentedPrintWriter w;
try {
jfo = processingEnv.getFiler().createSourceFile(packageElement.getQualifiedName() + "."+ classElement.getSimpleName() + "NBTWriter");
w = new IndentedPrintWriter(jfo.openWriter());
} catch (IOException e) {
throw new RuntimeException(e);
}
String type = classElement.getSimpleName().toString();
List<VariableElement> savedFields = new ArrayList<>();
for (Element enclosedElement : classElement.getEnclosedElements()) {
if (enclosedElement.getKind() == ElementKind.FIELD && enclosedElement.getAnnotationsByType(SavedToNBT.class).length > 0) {
savedFields.add((VariableElement) enclosedElement);
}
}
w.println("package " + packageElement.getQualifiedName() + ";");
w.println();
w.println("import net.minecraft.nbt.*;");
w.println();
w.println("public final class " + type + "NBTWriter {");
w.println();
w.indent();
w.print("public static void writeToNBT(" + classElement.getQualifiedName() + " obj, NBTTagCompound nbt) {");
w.indent();
for (VariableElement field : savedFields) {
w.println();
writeFieldWriteCode(w, field.asType(), field.getSimpleName().toString());
}
varCounter.clear();
if (savedFields.size() == 0) w.println();
w.unindent();
w.println("}");
w.println();
w.println("@SuppressWarnings({\"OverlyStrongTypeCast\", \"RedundantSuppression\"})"); // We want the cast to fail if it's ther wrong type
w.print("public static void readFromNBT(" + classElement.getQualifiedName() + " obj, NBTTagCompound nbt) {");
w.indent();
for (VariableElement field : savedFields) {
w.println();
writeFieldReadCode(w, field.asType(), field.getSimpleName().toString());
}
varCounter.clear();
if (savedFields.size() == 0) w.println();
w.unindent();
w.println("}");
w.unindent();
w.println("}");
w.close();
}
return true;
}
// Writing
// This tries to write using a .set method, and creates and fills a tag only if necessary
private void writeFieldWriteCode(IndentedPrintWriter w, TypeMirror type, String name) { // TODO: store boxed primitives and boxed primitive collections as primitives
w.println("// Write field " + type + " " + name);
switch (type.getKind()) {
case BOOLEAN:
w.println("nbt.setBoolean(\"" + name + "\", obj." + name + ");");
break;
case BYTE:
w.println("nbt.setByte(\"" + name + "\", obj." + name + ");");
break;
case SHORT:
w.println("nbt.setShort(\"" + name + "\", obj." + name + ");");
break;
case INT:
w.println("nbt.setInteger(\"" + name + "\", obj." + name + ");");
break;
case LONG:
w.println("nbt.setLong(\"" + name + "\", obj." + name + ");");
break;
case CHAR:
w.println("nbt.setInteger(\"" + name + "\", (int) obj." + name + ");"); // TODO: use short?
break;
case FLOAT:
w.println("nbt.setFloat(\"" + name + "\", obj." + name + ");");
break;
case DOUBLE:
w.println("nbt.setDouble(\"" + name + "\", obj." + name + ");");
break;
case ARRAY:
TypeMirror componentType = ((ArrayType) type).getComponentType();
if (componentType.getKind() == TypeKind.BYTE) { // TODO: store boolean array as byte array
w.println("nbt.setByteArray(\"" + name + "\", obj." + name + ");");
} else if (componentType.getKind() == TypeKind.INT) {
w.println("nbt.setIntArray(\"" + name + "\", obj." + name + ");");
} else {
makeNBTObject(w, type, "obj." + name, newVar("tag")); // TODO: name should depend on field name
w.println("nbt.setTag(\"" + name + "\", " + var("tag") + ");");
}
break;
case DECLARED:
DeclaredType declaredType = (DeclaredType) type;
Types tu = processingEnv.getTypeUtils();
Elements eu = processingEnv.getElementUtils();
switch (declaredType.toString()) {
// <editor-fold> TODO: less code duplication
case BOOLEAN:
w.println("nbt.setBoolean(\"" + name + "\", obj." + name + ");");
break;
case BYTE:
w.println("nbt.setByte(\"" + name + "\", obj." + name + ");");
break;
case SHORT:
w.println("nbt.setShort(\"" + name + "\", obj." + name + ");");
break;
case INTEGER:
w.println("nbt.setInteger(\"" + name + "\", obj." + name + ");");
break;
case LONG:
w.println("nbt.setLong(\"" + name + "\", obj." + name + ");");
break;
case CHAR:
w.println("nbt.setInteger(\"" + name + "\", (int) obj." + name + ");"); // TODO: use short?
break;
case FLOAT:
w.println("nbt.setFloat(\"" + name + "\", obj." + name + ");");
break;
case DOUBLE:
w.println("nbt.setDouble(\"" + name + "\", obj." + name + ");");
break;
// </editor-fold>
case STRING:
w.println("nbt.setString(\"" + name + "\", obj." + name + ");");
break;
case UUID:
w.println("nbt.setUUID(\"" + name + "\", obj." + name + ");");
break;
default:
w.println("if (obj." + name + " != null) {");
w.indent();
if (tu.isAssignable(type, eu.getTypeElement(NBT_STORABLE).asType())) {
w.println("if (obj." + name + " != null) nbt.setTag(\"" + name + "\", obj." + name + ".writeToNBT(new NBTTagCompound()));");
} else {
makeNBTObject(w, type, "obj." + name, newVar("tag")); // TODO: name should depend on field name
w.println("nbt.setTag(\"" + name + "\", " + var("tag") + ");");
}
w.unindent();
w.println("}");
break;
}
break;
default:
makeNBTObject(w, type, "obj." + name, newVar("tag")); // TODO: name should depend on field name
w.println("nbt.setTag(\"" + name + "\", " + var("tag") + ");");
break;
}
}
private void makeNBTObject(IndentedPrintWriter w, TypeMirror type, String from, String nbt) {
switch (type.getKind()) {
case BOOLEAN:
w.println("NBTTagByte " + nbt + " = new NBTTagByte((byte) (" + from + " ? 1 : 0));");
break;
case BYTE:
w.println("NBTTagByte " + nbt + " = new NBTTagByte(" + from + ");");
break;
case SHORT:
w.println("NBTTagShort " + nbt + " = new NBTTagShort(" + from + ");");
break;
case INT:
w.println("NBTTagInt " + nbt + " = new NBTTagInt(" + from + ");");
break;
case LONG:
w.println("NBTTagLong " + nbt + " = new NBTTagLong(" + from + ");");
break;
case CHAR:
w.println("NBTTagInt " + nbt + " = new NBTTagInt((int) " + from + ");");
break;
case FLOAT:
w.println("NBTTagFloat " + nbt + " = new NBTTagFloat(" + from + ");");
break;
case DOUBLE:
w.println("NBTTagDouble " + nbt + " = new NBTTagDouble(" + from + ");");
break;
case ARRAY:
TypeMirror componentType = ((ArrayType) type).getComponentType();
if (componentType.getKind() == TypeKind.BYTE) {
w.println("NBTTagByteArray " + nbt + " = new NBTTagByteArray(" + from + ");");
} else if (componentType.getKind() == TypeKind.INT) {
w.println("NBTTagIntArray " + nbt + " = new NBTTagIntArray(" + from + ");");
} else {
writeIterable(w, componentType, from, nbt);
}
break;
case DECLARED:
DeclaredType declaredType = (DeclaredType) type;
switch (declaredType.toString()) {
// <editor-fold> TODO: less code duplication
case BOOLEAN:
w.println("NBTTagByte " + nbt + " = new NBTTagByte((byte) (" + from + " ? 1 : 0));");
break;
case BYTE:
w.println("NBTTagByte " + nbt + " = new NBTTagByte(" + from + ");");
break;
case SHORT:
w.println("NBTTagShort " + nbt + " = new NBTTagShort(" + from + ");");
break;
case INTEGER:
w.println("NBTTagInt " + nbt + " = new NBTTagInt(" + from + ");");
break;
case LONG:
w.println("NBTTagLong " + nbt + " = new NBTTagLong(" + from + ");");
break;
case CHAR:
w.println("NBTTagInt " + nbt + " = new NBTTagInt((int) " + from + ");");
break;
case FLOAT:
w.println("NBTTagFloat " + nbt + " = new NBTTagFloat(" + from + ");");
break;
case DOUBLE:
w.println("NBTTagDouble " + nbt + " = new NBTTagDouble(" + from + ");");
break;
// </editor-fold>
case STRING:
w.println("NBTTagString " + nbt + " = new NBTTagString(" + from + ");");
break;
default:
Types types = processingEnv.getTypeUtils();
Elements elements = processingEnv.getElementUtils();
if (types.isAssignable(type, types.erasure(elements.getTypeElement(COLLECTION).asType()))) {
List<? extends TypeMirror> typeArguments = ((DeclaredType) type).getTypeArguments();
if (typeArguments.size() != 1) throw new RuntimeException("Missing type arguments for " + type);
TypeMirror elementType = typeArguments.get(0);
writeIterable(w, elementType, from, nbt);
} else if (types.isAssignable(type, types.erasure(elements.getTypeElement(MAP).asType()))) {
List<? extends TypeMirror> typeArguments = ((DeclaredType) type).getTypeArguments();
if (typeArguments.size() != 2) throw new RuntimeException("Missing type arguments for " + type);
TypeMirror entryType = types.getDeclaredType(elements.getTypeElement(MAP_ENTRY),
typeArguments.get(0), typeArguments.get(1));
writeIterable(w, entryType, from + ".entrySet()", nbt);
} else if (types.isAssignable(type, types.erasure(elements.getTypeElement(MAP_ENTRY).asType()))) {
w.println("NBTTagCompound " + nbt + " = new NBTTagCompound();");
List<? extends TypeMirror> typeArguments = ((DeclaredType) type).getTypeArguments();
if (typeArguments.size() != 2) throw new RuntimeException("Missing type arguments for " + type);
makeNBTObject(w, typeArguments.get(0), from + ".getKey()", newVar("key")); // TODO: configurable key name
w.println(nbt + ".setTag(\"" + var("key") + "\", " + var("key") + ");");
makeNBTObject(w, typeArguments.get(1), from + ".getValue()", newVar("value"));
w.println(nbt + ".setTag(\"" + var("value") + "\", " + var("value") + ");");
varGone("key");
varGone("value");
} else if (types.isAssignable(type, elements.getTypeElement(NBT_STORABLE).asType())) {
w.println("NBTTagCompound " + nbt + " = " + from + ".writeToNBT(new NBTTagCompound());");
} else if (types.isAssignable(type, elements.getTypeElement(VEC_3I).asType())) {
w.println("NBTTagCompound " + nbt + " = new NBTTagCompound();");
w.println(nbt + ".setInteger(\"x\", " + from + ".getX());");
w.println(nbt + ".setInteger(\"y\", " + from + ".getY());");
w.println(nbt + ".setInteger(\"z\", " + from + ".getZ());");
} else if (types.isAssignable(type, elements.getTypeElement(LOCATION).asType())) {
w.println("NBTTagCompound " + nbt + " = new NBTTagCompound();");
w.println(nbt + ".setInteger(\"dim\", " + from + ".getDim());");
w.println(nbt + ".setInteger(\"x\", " + from + ".getX());");
w.println(nbt + ".setInteger(\"y\", " + from + ".getY());");
w.println(nbt + ".setInteger(\"z\", " + from + ".getZ());");
} else if (types.isAssignable(type, elements.getTypeElement(VIRTUAL_LOCATION).asType())) {
w.println("NBTTagCompound " + nbt + " = new NBTTagCompound();");
w.println(nbt + ".setInteger(\"dim\", " + from + ".getDim());");
w.println(nbt + ".setInteger(\"x\", " + from + ".getX());");
w.println(nbt + ".setInteger(\"y\", " + from + ".getY());");
w.println(nbt + ".setInteger(\"z\", " + from + ".getZ());");
w.println(nbt + ".setInteger(\"depth\", " + from + ".getDepth());");
} else if (((DeclaredType) type).asElement().getKind() == ElementKind.ENUM) {
w.println("NBTTagInt " + nbt + " = new NBTTagInt(" + from + ".ordinal());");
} else {
throw new RuntimeException("Unsupported type " + type + " for variable " + from + "!");
}
}
break;
default:
throw new RuntimeException("Unsupported type kind " + type + " for variable " + from + "!");
}
}
private void writeIterable(IndentedPrintWriter w, TypeMirror componentType, String from, String nbt) {
w.println("NBTTagList " + nbt + " = new NBTTagList();");
w.println("for (" + componentType + " " + newVar("element") + " : " + from + ") {"); // TODO: no java.lang or java.util
w.indent();
makeNBTObject(w, componentType, var("element"), newVar("elementNBT")); // TODO: single line if possible
w.println(nbt + ".appendTag(" + var("elementNBT") + ");");
varGone("element");
varGone("elementNBT");
w.unindent();
w.println("}");
}
// Reading
private void writeFieldReadCode(IndentedPrintWriter w, TypeMirror type, String name) {
w.println("// Read field " + type + " " + name);
switch (type.getKind()) {
case BOOLEAN:
w.println("obj." + name + " = nbt.getBoolean(\"" + name + "\");");
break;
case BYTE:
w.println("obj." + name + " = nbt.getByte(\"" + name + "\");");
break;
case SHORT:
w.println("obj." + name + " = nbt.getShort(\"" + name + "\");");
break;
case INT:
w.println("obj." + name + " = nbt.getInteger(\"" + name + "\");");
break;
case LONG:
w.println("obj." + name + " = nbt.getLong(\"" + name + "\");");
break;
case CHAR:
w.println("obj." + name + " = (char) nbt.getInteger(\"" + name + "\");");
break;
case FLOAT:
w.println("obj." + name + " = nbt.getFloat(\"" + name + "\");");
break;
case DOUBLE:
w.println("obj." + name + " = nbt.getDouble(\"" + name + "\");");
break;
case ARRAY:
TypeMirror componentType = ((ArrayType) type).getComponentType();
if (componentType.getKind() == TypeKind.BYTE) { // TODO: store boolean array as byte array
w.println("obj." + name + " = nbt.getByteArray(\"" + name + "\");");
} else if (componentType.getKind() == TypeKind.INT) {
w.println("obj." + name + " = nbt.getIntArray(\"" + name + "\");");
} else {
w.println("NBTBase " + newVar("tag") + " = nbt.getTag(\"" + name + "\");");
readNBTObject(w, type, newVar("arr"), var("tag")); // TODO: name should depend on field name
w.println("obj." + name + " = " + var("arr") + ";");
}
break;
case DECLARED:
DeclaredType declaredType = (DeclaredType) type;
Types tu = processingEnv.getTypeUtils();
Elements eu = processingEnv.getElementUtils();
switch (declaredType.toString()) {
// <editor-fold> TODO: less code duplication
case BOOLEAN:
w.println("obj." + name + " = nbt.getBoolean(\"" + name + "\");");
break;
case BYTE:
w.println("obj." + name + " = nbt.getByte(\"" + name + "\");");
break;
case SHORT:
w.println("obj." + name + " = nbt.getShort(\"" + name + "\");");
break;
case INTEGER:
w.println("obj." + name + " = nbt.getInteger(\"" + name + "\");");
break;
case LONG:
w.println("obj." + name + " = nbt.getLong(\"" + name + "\");");
break;
case CHAR:
w.println("obj." + name + " = (char) nbt.getInteger(\"" + name + "\");");
break;
case FLOAT:
w.println("obj." + name + " = nbt.getFloat(\"" + name + "\");");
break;
case DOUBLE:
w.println("obj." + name + " = nbt.getDouble(\"" + name + "\");");
break;
// </editor-fold>
case STRING:
w.println("obj." + name + " = nbt.getString(\"" + name + "\");");
break;
case UUID: // TODO: non top-level UUIDs
w.println("obj." + name + " = nbt.getUUID(\"" + name + "\");");
break;
default:
if (tu.isAssignable(type, eu.getTypeElement(NBT_STORABLE).asType())) {
w.println("if (nbt.hasKey(\"" + name + "\")) {");
w.indent();
w.println("obj." + name + " = new " + type + "();");
w.println("obj." + name + ".readFromNBT(nbt.getCompoundTag(\"" + name + "\"));");
w.unindent();
w.println("}");
} else {
w.println("if (nbt.hasKey(\"" + name + "\")) {");
w.indent();
w.println("NBTBase " + newVar("tag") + " = nbt.getTag(\"" + name + "\");");
readNBTObject(w, type, newVar("arr"), var("tag")); // TODO: name should depend on field name
w.println("obj." + name + " = " + var("arr") + ";");
w.unindent();
w.println("}");
}
break;
}
break;
default:
w.println("NBTBase " + newVar("tag") + " = nbt.getTag(\"" + name + "\");");
readNBTObject(w, type, newVar("arr"), var("tag")); // TODO: name should depend on field name
w.println("obj." + name + " = " + var("arr") + ";");
break;
}
}
private void readNBTObject(IndentedPrintWriter w, TypeMirror type, String to, String nbt) {
switch (type.getKind()) {
case BOOLEAN:
w.println(type + " " + to + " = ((NBTTagByte) " + nbt + ").getByte() == 1;");
break;
case BYTE:
w.println(type + " " + to + " = ((NBTTagByte) " + nbt + ").getByte();");
break;
case SHORT:
w.println(type + " " + to + " = ((NBTTagShort) " + nbt + ").getShort();");
break;
case INT:
w.println(type + " " + to + " = ((NBTTagInt) " + nbt + ").getInt();");
break;
case LONG:
w.println(type + " " + to + " = ((NBTTagLong) " + nbt + ").getLong();");
break;
case CHAR:
w.println(type + " " + to + " = (char) ((NBTTagInt) " + nbt + ").getInt();");
break;
case FLOAT:
w.println(type + " " + to + " = ((NBTTagFloat) " + nbt + ").getFloat();");
break;
case DOUBLE:
w.println(type + " " + to + " = ((NBTTagDouble) " + nbt + ").getDouble();");
break;
case ARRAY:
TypeMirror componentType = ((ArrayType) type).getComponentType();
if (componentType.getKind() == TypeKind.BYTE) {
w.println(type + " " + to + " = ((NBTTagByteArray) " + nbt + ").getByteArray();");
} else if (componentType.getKind() == TypeKind.INT) {
w.println(type + " " + to + " = ((NBTTagIntArray) " + nbt + ").getIntArray();");
} else {
if (componentType.getKind() == TypeKind.ARRAY) { // TODO: better array creation
w.println(type + " " + to + " = (" + type + ") new Object[((NBTTagList) " + nbt + ").tagCount()];");
} else {
w.println(type + " " + to + " = new " + componentType + "[((NBTTagList) " + nbt + ").tagCount()];");
}
String i = newVar("i"); // TODO: this is a workaround for not being able to varGone the variable
w.println("int " + i + " = 0;");
w.println("for (NBTBase " + newVar("elementNBT") + " : (NBTTagList) " + nbt + ") {");
w.indent();
readNBTObject(w, componentType, newVar("element"), var("elementNBT")); // TODO: single line if possible
w.println(to + "[" + i + "++] = " + var("element") + ";");
varGone("element");
varGone("elementNBT");
w.unindent();
w.println("}");
}
break;
case DECLARED:
DeclaredType declaredType = (DeclaredType) type;
switch (declaredType.toString()) {
// <editor-fold> TODO: less code duplication
case BOOLEAN:
w.println(type + " " + to + " = ((NBTTagByte) " + nbt + ").getByte() == 1;");
break;
case BYTE:
w.println(type + " " + to + " = ((NBTTagByte) " + nbt + ").getByte();");
break;
case SHORT:
w.println(type + " " + to + " = ((NBTTagShort) " + nbt + ").getShort();");
break;
case INTEGER:
w.println(type + " " + to + " = ((NBTTagInt) " + nbt + ").getInt();");
break;
case LONG:
w.println(type + " " + to + " = ((NBTTagLong) " + nbt + ").getLong();");
break;
case CHAR:
w.println(type + " " + to + " = (char) ((NBTTagInt) " + nbt + ").getInt();");
break;
case FLOAT:
w.println(type + " " + to + " = ((NBTTagFloat) " + nbt + ").getFloat();");
break;
case DOUBLE:
w.println(type + " " + to + " = ((NBTTagDouble) " + nbt + ").getDouble();");
break;
// </editor-fold>
case STRING:
w.println(type + " " + to + " = ((NBTTagString) " + nbt + ").getString();");
break;
default:
Types types = processingEnv.getTypeUtils();
Elements elements = processingEnv.getElementUtils();
if (types.isAssignable(type, types.erasure(elements.getTypeElement(COLLECTION).asType()))) {
List<? extends TypeMirror> typeArguments = ((DeclaredType) type).getTypeArguments();
if (typeArguments.size() != 1) throw new RuntimeException("Missing type arguments for " + type);
TypeMirror elementType = typeArguments.get(0);
w.println(type + " " + to + " = " + makeContainer(type) + ";");
w.println("for (NBTBase " + newVar("elementNBT") + " : (NBTTagList) " + nbt + ") {");
w.indent();
readNBTObject(w, elementType, newVar("element"), var("elementNBT")); // TODO: single line if possible
w.println(to + ".add(" + var("element") + ");");
varGone("element");
varGone("elementNBT");
w.unindent();
w.println("}");
} else if (types.isAssignable(type, types.erasure(elements.getTypeElement(MAP).asType()))) {
List<? extends TypeMirror> typeArguments = ((DeclaredType) type).getTypeArguments();
if (typeArguments.size() != 2) throw new RuntimeException("Missing type arguments for " + type);
w.println(type + " " + to + " = " + makeContainer(type) + ";");
w.println("for (NBTBase " + newVar("elementNBT") + " : (NBTTagList) " + nbt + ") {");
w.indent();
readNBTObject(w, typeArguments.get(0), newVar("key"), "((NBTTagCompound) " + var("elementNBT") + ").getTag(\"key\")");
readNBTObject(w, typeArguments.get(1), newVar("value"), "((NBTTagCompound) " + var("elementNBT") + ").getTag(\"value\")");
w.println(to + ".put(" + var("key") + ", " + var("value") + ");");
varGone("key");
varGone("value");
varGone("elementNBT");
w.unindent();
w.println("}");
} else if (types.isAssignable(type, elements.getTypeElement(NBT_STORABLE).asType())) {
w.println(type + " " + to + " = new " + type + "();");
w.println(to + ".readFromNBT((NBTTagCompound) " + nbt + ");");
} else if (types.isAssignable(type, elements.getTypeElement(VEC_3I).asType())) {
w.println(type + " " + to + " = new " + type + "("
+ "((NBTTagCompound) "+ nbt + ").getInteger(\"x\"), "
+ "((NBTTagCompound) "+ nbt + ").getInteger(\"y\"), "
+ "((NBTTagCompound) "+ nbt + ").getInteger(\"z\")" + ");");
} else if (types.isAssignable(type, elements.getTypeElement(LOCATION).asType())) {
w.println(type + " " + to + " = new " + type + "("
+ "((NBTTagCompound) "+ nbt + ").getInteger(\"dim\"), "
+ "((NBTTagCompound) "+ nbt + ").getInteger(\"x\"), "
+ "((NBTTagCompound) "+ nbt + ").getInteger(\"y\"), "
+ "((NBTTagCompound) "+ nbt + ").getInteger(\"z\")" + ");");
} else if (types.isAssignable(type, elements.getTypeElement(VIRTUAL_LOCATION).asType())) {
w.println(type + " " + to + " = new " + type + "("
+ "((NBTTagCompound) "+ nbt + ").getInteger(\"dim\"), "
+ "((NBTTagCompound) "+ nbt + ").getInteger(\"x\"), "
+ "((NBTTagCompound) "+ nbt + ").getInteger(\"y\"), "
+ "((NBTTagCompound) "+ nbt + ").getInteger(\"z\"), "
+ "((NBTTagCompound) "+ nbt + ").getInteger(\"depth\")" + ");");
} else if (((DeclaredType) type).asElement().getKind() == ElementKind.ENUM) {
w.println(type + " " + to + " = " + type + ".values()[((NBTTagInt) " + nbt + ").getInt()" + "];");
} else {
throw new RuntimeException("Unsupported type " + type + " for variable " + to + "!");
}
}
break;
default:
throw new RuntimeException("Unsupported type kind for type " + type + " for variable " + to + "!");
}
}
private Object makeContainer(TypeMirror type) {
Types types = processingEnv.getTypeUtils();
Elements elements = processingEnv.getElementUtils();
if (types.isAssignable(types.erasure(elements.getTypeElement("java.util.List").asType()), type)) {
return "new java.util.ArrayList<>()";
} else if (types.isAssignable(types.erasure(elements.getTypeElement("java.util.Set").asType()), type)) {
return "new java.util.HashSet<>()";
} else if (types.isAssignable(types.erasure(elements.getTypeElement("java.util.Map").asType()), type)) {
return "new java.util.HashMap<>()";
} else if (types.isAssignable(types.erasure(elements.getTypeElement("com.google.common.collect.BiMap").asType()), type)) {
return "com.google.common.collect.HashBiMap.create()";
} else if (types.isAssignable(types.erasure(elements.getTypeElement("com.google.common.collect.Multiset").asType()), type)) {
return "com.google.common.collect.HashMultiset.create()";
} else { // TODO: check that it can be instantiated, don't use generic params
return "new " + type + "()";
}
}
private String newVar(String name) {
varCounter.put(name, varCounter.getOrDefault(name, -1) + 1);
return var(name);
}
private void varGone(String name) {
if (varCounter.get(name) < 0) throw new IllegalStateException("Can't set variable to negative index!");
varCounter.put(name, varCounter.get(name) - 1);
}
private String var(String name) {
if (varCounter.get(name) == 0) {
return name;
} else {
return name + varCounter.get(name);
}
}
}

View file

@ -0,0 +1 @@
org.dimdev.ddutils.nbt.SavedToNBTProcessor

View file

@ -16,7 +16,7 @@ plugins {
apply plugin: 'net.minecraftforge.gradle.forge'
//Only edit below this line, the above code adds and enables the nessasary things for Forge to be setup.
ext.modversion = "3.0.0-b1"
ext.modversion = "3.0.0-b2"
ext.mcversion = "1.12.2"
ext.forgeversion = "14.23.1.2555"
//spongeSchematicVersion = "1"
@ -29,6 +29,10 @@ jar.archiveName = "dimdoors.jar" // Constant name for travis
sourceCompatibility = targetCompatibility = "1.8" // Need this here so eclipse task generates correctly.
compileJava {
sourceCompatibility = targetCompatibility = "1.8"
options.compilerArgs += [
//"-proc:only", // TODO: have generated code available for debugging
"-processor", "org.dimdev.ddutils.nbt.SavedToNBTProcessor,lombok.launch.AnnotationProcessorHider\$AnnotationProcessor"
]
}
minecraft {
@ -47,6 +51,7 @@ configurations {
dependencies {
embed 'com.flowpowered:flow-math:1.0.3'
compile project(':AnnotatedNBT')
}
jar {
@ -61,7 +66,6 @@ processResources {
// replace stuff in mcmod.info, nothing else
from(sourceSets.main.resources.srcDirs) {
include 'mcmod.info'
// replace version and mcversion
expand 'version':project.version, 'mcversion':project.minecraft.version
}

2
settings.gradle Normal file
View file

@ -0,0 +1,2 @@
include 'AnnotatedNBT'

View file

@ -67,24 +67,6 @@ public class Location implements Serializable {
return new Location(world, blockPos);
}
public static NBTTagCompound writeToNBT(Location location) {
NBTTagCompound locationNBT = new NBTTagCompound();
locationNBT.setInteger("worldID", location.dim);
locationNBT.setInteger("x", location.pos.getX());
locationNBT.setInteger("y", location.pos.getY());
locationNBT.setInteger("z", location.pos.getZ());
return locationNBT;
}
public static Location readFromNBT(NBTTagCompound locationNBT) {
int worldID = locationNBT.getInteger("worldID");
int x = locationNBT.getInteger("x");
int y = locationNBT.getInteger("y");
int z = locationNBT.getInteger("z");
BlockPos blockPos = new BlockPos(x, y, z);
return new Location(worldID, blockPos);
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Location)) {

View file

@ -0,0 +1,44 @@
package org.dimdev.ddutils.nbt;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3i;
import org.dimdev.ddutils.Location;
import org.dimdev.dimdoors.shared.pockets.Pocket;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@SavedToNBT
public final class NBTTest {
@SavedToNBT public boolean a;
@SavedToNBT public byte b;
@SavedToNBT public short c;
@SavedToNBT public int d;
@SavedToNBT public long e;
@SavedToNBT public char f;
@SavedToNBT public float g;
@SavedToNBT public double h;
@SavedToNBT public byte[] i;
@SavedToNBT public int[] j;
@SavedToNBT public boolean[] k;
@SavedToNBT public byte[] l;
@SavedToNBT public short[] m;
@SavedToNBT public int[] n;
@SavedToNBT public long[] o;
@SavedToNBT public float[] p;
@SavedToNBT public double[] q;
@SavedToNBT public byte[][] r;
@SavedToNBT public int[][] s;
@SavedToNBT public String str;
@SavedToNBT public Vec3i vec3i;
@SavedToNBT public BlockPos blockPos;
@SavedToNBT public Location location;
@SavedToNBT public String[] strArr;
@SavedToNBT public String[][] strArrArr;
//@SavedToNBT public String[][][][][][][][][][][][][][][] test;
@SavedToNBT public Pocket nbtStorable;
@SavedToNBT public List<Integer> list = new ArrayList<>();
@SavedToNBT public Map<String, Integer> map;
@SavedToNBT public Map<Map<List<String>, int[]>, Map<Pocket, List<Pocket>>> test2;
}

View file

@ -1,47 +0,0 @@
package org.dimdev.ddutils.nbt;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.math.Vec3i;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
public final class NBTUtils {
public static <T extends Map<String, Integer>> T readMapStringInteger(NBTTagCompound nbt, T map) {
for (String str : nbt.getKeySet()) {
map.put(str, nbt.getInteger(str));
}
return map;
}
public static NBTTagCompound writeMapStringInteger(Map<String, Integer> map) {
NBTTagCompound tagCompound = new NBTTagCompound();
for (String str : map.keySet()) {
tagCompound.setInteger(str, map.get(str));
}
return tagCompound;
}
public static <T extends INBTStorable> T readNBTStorable(T obj, NBTTagCompound nbt) {
obj.readFromNBT(nbt);
return obj;
}
public static Vec3i readVec3i(NBTTagCompound nbt) {
return new Vec3i(nbt.getInteger("x"), nbt.getInteger("y"), nbt.getInteger("z"));
}
public static NBTTagCompound writeVec3i(Vec3i vec) {
NBTTagCompound nbt = new NBTTagCompound();
nbt.setInteger("x", vec.getX());
nbt.setInteger("y", vec.getY());
nbt.setInteger("z", vec.getZ());
return nbt;
}
}

View file

@ -1,5 +1,6 @@
package org.dimdev.dimdoors.shared;
import org.dimdev.ddutils.nbt.INBTStorable;
import org.dimdev.dimdoors.shared.pockets.Pocket;
import org.dimdev.dimdoors.shared.pockets.PocketRegistry;
import org.dimdev.ddutils.Location;
@ -33,25 +34,6 @@ public class VirtualLocation { // TODO: use BlockPos/Location
public int getY() { return location.getY(); }
public int getZ() { return location.getZ(); }
public static VirtualLocation readFromNBT(NBTTagCompound nbt) {
int dim = nbt.getInteger("dim");
int x = nbt.getInteger("x");
int y = nbt.getInteger("y");
int z = nbt.getInteger("z");
int depth = nbt.getInteger("depth");
return new VirtualLocation(dim, x, y, z, depth);
}
public NBTTagCompound writeToNBT() {
NBTTagCompound nbt = new NBTTagCompound();
nbt.setInteger("dim", location.getDim());
nbt.setInteger("x", location.getPos().getX());
nbt.setInteger("y", location.getPos().getY());
nbt.setInteger("z", location.getPos().getZ());
nbt.setInteger("depth", depth);
return nbt;
}
public static VirtualLocation fromLocation(Location location) { // TODO: reverse function too
VirtualLocation virtualLocation = null;
if (DimDoorDimensions.isPocketDimension(location.getDim())) {

View file

@ -1,6 +1,8 @@
package org.dimdev.dimdoors.shared.pockets;
import org.dimdev.ddutils.nbt.INBTStorable;
import org.dimdev.ddutils.nbt.NBTUtils;
import org.dimdev.ddutils.nbt.SavedToNBT;
import org.dimdev.dimdoors.shared.VirtualLocation;
import org.dimdev.dimdoors.shared.rifts.*;
import org.dimdev.dimdoors.shared.tileentities.TileEntityEntranceRift;
@ -15,15 +17,15 @@ import net.minecraft.nbt.*;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
public class Pocket implements INBTStorable{ // TODO: better visibilities
@SavedToNBT public class Pocket implements INBTStorable { // TODO: better visibilities
@Getter private int id;
@Getter private int x; // Grid x TODO: rename to gridX and gridY
@Getter private int z; // Grid y
@Getter @Setter private int size; // In chunks TODO: non chunk-based size, better bounds such as minX, minZ, maxX, maxZ, etc.
@Getter @Setter private VirtualLocation virtualLocation; // The non-pocket dimension from which this dungeon was created
@Getter @Setter Location entrance;
@Getter List<Location> riftLocations;
@SavedToNBT @Getter /*package-private*/ int id;
@SavedToNBT @Getter /*package-private*/ int x; // Grid x TODO: rename to gridX and gridY
@SavedToNBT @Getter /*package-private*/ int z; // Grid y
@SavedToNBT @Getter @Setter /*package-private*/ int size; // In chunks TODO: non chunk-based size, better bounds such as minX, minZ, maxX, maxZ, etc.
@SavedToNBT @Getter @Setter /*package-private*/ VirtualLocation virtualLocation; // The non-pocket dimension from which this dungeon was created
@SavedToNBT @Getter @Setter /*package-private*/ Location entrance;
@SavedToNBT @Getter /*package-private*/ List<Location> riftLocations;
@Getter int dimID; // Not saved
@ -37,39 +39,9 @@ public class Pocket implements INBTStorable{ // TODO: better visibilities
riftLocations = new ArrayList<>();
}
@Override
public /*static Pocket*/ void readFromNBT(NBTTagCompound nbt) {
id = nbt.getInteger("id");
x = nbt.getInteger("x");
z = nbt.getInteger("z");
size = nbt.getInteger("size");
if (nbt.hasKey("virtualLocation")) virtualLocation = VirtualLocation.readFromNBT(nbt.getCompoundTag("virtualLocation"));
if (nbt.hasKey("entrance")) entrance = Location.readFromNBT(nbt.getCompoundTag("entrance"));
riftLocations = new ArrayList<>();
NBTTagList riftLocationsNBT = (NBTTagList) nbt.getTag("riftLocations");
for (NBTBase riftLocationNBT : riftLocationsNBT) {
riftLocations.add(Location.readFromNBT((NBTTagCompound) riftLocationNBT));
}
}
@Override
public /*static*/ NBTTagCompound writeToNBT(NBTTagCompound nbt) {
nbt.setInteger("id", id);
nbt.setInteger("x", x);
nbt.setInteger("z", z);
nbt.setInteger("size", size);
if (virtualLocation != null) nbt.setTag("virtualLocation", virtualLocation.writeToNBT());
if (entrance != null) nbt.setTag("entrance", Location.writeToNBT(entrance));
NBTTagList riftLocationsNBT = new NBTTagList();
for (Location loc : riftLocations) {
riftLocationsNBT.appendTag(Location.writeToNBT(loc));
}
nbt.setTag("riftLocations", riftLocationsNBT);
return nbt;
}
// TODO: make these static?
@Override public void readFromNBT(NBTTagCompound nbt) { NBTUtils.readFromNBT(this, nbt); }
@Override public NBTTagCompound writeToNBT(NBTTagCompound nbt) { return NBTUtils.writeToNBT(this, nbt); }
boolean isInBounds(BlockPos pos) {
// pocket bounds

View file

@ -2,6 +2,7 @@ package org.dimdev.dimdoors.shared.pockets;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import org.dimdev.ddutils.nbt.SavedToNBT;
import org.dimdev.dimdoors.shared.DDConfig;
import org.dimdev.ddutils.math.GridUtils;
import org.dimdev.dimdoors.DimDoors;
@ -21,18 +22,18 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.storage.MapStorage;
import net.minecraft.world.storage.WorldSavedData;
public class PocketRegistry extends WorldSavedData { // TODO: unregister pocket entrances, private pocket entrances/exits
@SavedToNBT public class PocketRegistry extends WorldSavedData { // TODO: unregister pocket entrances, private pocket entrances/exits
private static final String DATA_NAME = DimDoors.MODID + "_pockets";
@Getter private static final int DATA_VERSION = 0; // IMPORTANT: Update this and upgradeRegistry when making changes.
@Getter private int gridSize; // Determines how much pockets in their dimension are spaced
@Getter private int maxPocketSize;
@Getter private int privatePocketSize;
@Getter private int publicPocketSize;
private BiMap<String, Integer> privatePocketMap; // Player UUID -> Pocket ID, in pocket dim only
@Getter private Map<Integer, Pocket> pockets; // TODO: remove getter?
@Getter private int nextID;
@SavedToNBT @Getter /*package-private*/ int gridSize; // Determines how much pockets in their dimension are spaced
@SavedToNBT @Getter /*package-private*/ int maxPocketSize;
@SavedToNBT @Getter /*package-private*/ int privatePocketSize;
@SavedToNBT @Getter /*package-private*/ int publicPocketSize;
@SavedToNBT /*package-private*/ BiMap<String, Integer> privatePocketMap; // Player UUID -> Pocket ID, in pocket dim only
@SavedToNBT @Getter /*package-private*/ Map<Integer, Pocket> pockets; // TODO: remove getter?
@SavedToNBT @Getter /*package-private*/ int nextID;
@Getter private int dimID;
@ -82,24 +83,7 @@ public class PocketRegistry extends WorldSavedData { // TODO: unregister pocket
throw new RuntimeException("Couldn't upgrade registry"); // TODO: better exceptions
}
}
gridSize = nbt.getInteger("gridSize");
maxPocketSize = nbt.getInteger("maxPocketSize");
privatePocketSize = nbt.getInteger("privatePocketSize");
publicPocketSize = nbt.getInteger("publicPocketSize");
privatePocketMap = NBTUtils.readMapStringInteger(nbt.getCompoundTag("privatePocketMap"), HashBiMap.create());
nextID = nbt.getInteger("nextID");
pockets = new HashMap<>();
NBTTagList pocketsNBT = (NBTTagList) nbt.getTag("pockets");
for (NBTBase pocketNBT : pocketsNBT) { // TODO: convert to map to be able to skip IDs efficiently
NBTTagCompound pocketNBTC = (NBTTagCompound) pocketNBT;
pockets.put(pocketNBTC.getInteger("id"), NBTUtils.readNBTStorable(new Pocket(), (NBTTagCompound) pocketNBT));
}
for (Pocket pocket : pockets.values()) {
pocket.dimID = dimID;
}
NBTUtils.readFromNBT(this, nbt);
}
@SuppressWarnings("unused")
@ -122,24 +106,7 @@ public class PocketRegistry extends WorldSavedData { // TODO: unregister pocket
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
nbt.setInteger("version", DATA_VERSION);
nbt.setInteger("gridSize", gridSize);
nbt.setInteger("maxPocketSize", maxPocketSize);
nbt.setInteger("privatePocketSize", privatePocketSize);
nbt.setInteger("publicPocketSize", publicPocketSize);
nbt.setTag("privatePocketMap", NBTUtils.writeMapStringInteger(privatePocketMap));
nbt.setInteger("nextID", nextID);
NBTTagList pocketsNBT = new NBTTagList();
for (Map.Entry<Integer, Pocket> pocketEntry : pockets.entrySet()) {
if (pocketEntry.getValue() == null) continue;
NBTTagCompound pocketNBT = (NBTTagCompound) pocketEntry.getValue().writeToNBT(new NBTTagCompound());
pocketNBT.setInteger("id", pocketEntry.getKey()); // TODO: store separately?
pocketsNBT.appendTag(pocketNBT);
}
nbt.setTag("pockets", pocketsNBT);
return nbt;
return NBTUtils.writeToNBT(this, nbt);
}
/**

View file

@ -1,5 +1,7 @@
package org.dimdev.dimdoors.shared.rifts;
import org.dimdev.ddutils.nbt.NBTUtils;
import org.dimdev.ddutils.nbt.SavedToNBT;
import org.dimdev.dimdoors.shared.VirtualLocation;
import org.dimdev.ddutils.Location;
import org.dimdev.ddutils.math.MathUtils;
@ -17,19 +19,19 @@ import java.util.Map;
import java.util.UUID;
@Getter @AllArgsConstructor @Builder(toBuilder = true) @ToString
public class AvailableLinkDestination extends RiftDestination { // TODO
private float newDungeonRiftProbability;
private float depthPenalization; // TODO: these make the equation assymetric
private float distancePenalization;
private float closenessPenalization;
@SavedToNBT public class AvailableLinkDestination extends RiftDestination { // TODO
@SavedToNBT /*package-private*/ float newDungeonRiftProbability;
@SavedToNBT /*package-private*/ float depthPenalization; // TODO: these make the equation assymetric
@SavedToNBT /*package-private*/ float distancePenalization;
@SavedToNBT /*package-private*/ float closenessPenalization;
private boolean dungeonRiftsOnly;
private boolean overworldRifts;
private boolean unstable;
private float nonFloatingRiftWeight;
private float floatingRiftWeight;
@SavedToNBT /*package-private*/ boolean dungeonRiftsOnly;
@SavedToNBT /*package-private*/ boolean overworldRifts;
@SavedToNBT /*package-private*/ boolean unstable;
@SavedToNBT /*package-private*/ float nonFloatingRiftWeight;
@SavedToNBT /*package-private*/ float floatingRiftWeight;
private boolean noLinkBack;
@SavedToNBT /*package-private*/ boolean noLinkBack;
// private int maxLinks;
@Builder.Default private UUID uuid = UUID.randomUUID();
@ -37,40 +39,8 @@ public class AvailableLinkDestination extends RiftDestination { // TODO
AvailableLinkDestination() {}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
newDungeonRiftProbability = nbt.getFloat("newDungeonRiftProbability");
depthPenalization = nbt.getFloat("depthPenalization");
distancePenalization = nbt.getFloat("distancePenalization");
closenessPenalization = nbt.getFloat("closenessPenalization");
dungeonRiftsOnly = nbt.getBoolean("dungeonRiftsOnly");
overworldRifts = nbt.getBoolean("overworldRifts");
unstable = nbt.getBoolean("unstable");
noLinkBack = nbt.getBoolean("noLinkBack");
nonFloatingRiftWeight = nbt.getFloat("nonFloatingRiftWeight");
floatingRiftWeight = nbt.getFloat("floatingRiftWeight");
// maxLinks = nbt.getInteger("maxLinks");
uuid = nbt.getUniqueId("uuid");
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
nbt = super.writeToNBT(nbt);
nbt.setFloat("newDungeonRiftProbability", newDungeonRiftProbability);
nbt.setFloat("depthPenalization", depthPenalization);
nbt.setFloat("distancePenalization", distancePenalization);
nbt.setFloat("closenessPenalization", closenessPenalization);
nbt.setBoolean("dungeonRiftsOnly", dungeonRiftsOnly);
nbt.setBoolean("overworldRifts", overworldRifts);
nbt.setBoolean("unstable", unstable);
nbt.setBoolean("noLinkBack", noLinkBack);
nbt.setFloat("nonFloatingRiftWeight", nonFloatingRiftWeight);
nbt.setFloat("floatingRiftWeight", floatingRiftWeight);
// nbt.setInteger("maxLinks", maxLinks);
nbt.setUniqueId("uuid", uuid);
return nbt;
}
@Override public void readFromNBT(NBTTagCompound nbt) { super.readFromNBT(nbt); NBTUtils.readFromNBT(this, nbt); }
@Override public NBTTagCompound writeToNBT(NBTTagCompound nbt) { nbt = super.writeToNBT(nbt); return NBTUtils.writeToNBT(this, nbt); }
@Override
public boolean teleport(TileEntityRift rift, Entity entity) {

View file

@ -7,25 +7,17 @@ import lombok.Getter;
import lombok.ToString;
import net.minecraft.entity.Entity;
import net.minecraft.nbt.NBTTagCompound;
import org.dimdev.ddutils.nbt.NBTUtils;
import org.dimdev.ddutils.nbt.SavedToNBT;
@Getter @AllArgsConstructor @Builder(toBuilder = true) @ToString
public class GlobalDestination extends RiftDestination { // TODO: location directly in nbt like minecraft?
private Location loc;
@SavedToNBT public class GlobalDestination extends RiftDestination { // TODO: location directly in nbt like minecraft?
@SavedToNBT @Getter /*package-private*/ Location loc;
public GlobalDestination() {}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
loc = Location.readFromNBT(nbt.getCompoundTag("loc"));
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
nbt = super.writeToNBT(nbt);
nbt.setTag("loc", Location.writeToNBT(loc));
return nbt;
}
@Override public void readFromNBT(NBTTagCompound nbt) { super.readFromNBT(nbt); NBTUtils.readFromNBT(this, nbt); }
@Override public NBTTagCompound writeToNBT(NBTTagCompound nbt) { nbt = super.writeToNBT(nbt); return NBTUtils.writeToNBT(this, nbt); }
@Override
public boolean teleport(TileEntityRift rift, Entity entity) {

View file

@ -9,25 +9,16 @@ import lombok.ToString;
import net.minecraft.entity.Entity;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.math.BlockPos;
import org.dimdev.ddutils.nbt.SavedToNBT;
@Getter @AllArgsConstructor @Builder(toBuilder = true) @ToString
public class LocalDestination extends RiftDestination { // TODO: use BlockPos
private BlockPos pos;
@SavedToNBT public class LocalDestination extends RiftDestination { // TODO: use BlockPos
@SavedToNBT /*package-private*/ BlockPos pos;
public LocalDestination() {}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
pos = new BlockPos(NBTUtils.readVec3i(nbt.getCompoundTag("pos")));
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
nbt = super.writeToNBT(nbt);
nbt.setTag("pos", NBTUtils.writeVec3i(pos));
return nbt;
}
@Override public void readFromNBT(NBTTagCompound nbt) { super.readFromNBT(nbt); NBTUtils.readFromNBT(this, nbt); }
@Override public NBTTagCompound writeToNBT(NBTTagCompound nbt) { nbt = super.writeToNBT(nbt); return NBTUtils.writeToNBT(this, nbt); }
@Override
public boolean teleport(TileEntityRift rift, Entity entity) {

View file

@ -1,5 +1,7 @@
package org.dimdev.dimdoors.shared.rifts;
import org.dimdev.ddutils.nbt.NBTUtils;
import org.dimdev.ddutils.nbt.SavedToNBT;
import org.dimdev.dimdoors.DimDoors;
import lombok.AllArgsConstructor;
import lombok.Builder;
@ -15,54 +17,15 @@ import java.util.LinkedList;
import java.util.List;
@Getter @AllArgsConstructor @Builder(toBuilder = true) @ToString
public class PocketEntranceDestination extends RiftDestination {
private float weight;
@SuppressWarnings({"UnusedAssignment", "RedundantSuppression"}) @Builder.Default private List<WeightedRiftDestination> ifDestinations = new LinkedList<>(); // TODO addIfDestination method in builder
@SuppressWarnings({"UnusedAssignment", "RedundantSuppression"}) @Builder.Default private List<WeightedRiftDestination> otherwiseDestinations = new LinkedList<>(); // TODO addOtherwiseDestination method in builder
@SavedToNBT public class PocketEntranceDestination extends RiftDestination {
@SavedToNBT /*package-private*/ float weight;
@SavedToNBT @SuppressWarnings({"UnusedAssignment", "RedundantSuppression"}) @Builder.Default /*package-private*/ List<WeightedRiftDestination> ifDestinations = new LinkedList<>(); // TODO addIfDestination method in builder
@SavedToNBT @SuppressWarnings({"UnusedAssignment", "RedundantSuppression"}) @Builder.Default /*package-private*/ List<WeightedRiftDestination> otherwiseDestinations = new LinkedList<>(); // TODO addOtherwiseDestination method in builder
public PocketEntranceDestination() {}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
weight = nbt.getFloat("weight");
ifDestinations = new LinkedList<>();
NBTTagList ifDestinationsNBT = (NBTTagList) nbt.getTag("ifDestinations");
for (NBTBase ifDestinationNBT : ifDestinationsNBT) {
WeightedRiftDestination ifDestination = new WeightedRiftDestination();
ifDestination.readFromNBT((NBTTagCompound) ifDestinationNBT);
ifDestinations.add(ifDestination);
}
otherwiseDestinations = new LinkedList<>();
NBTTagList otherwiseDestinationsNBT = (NBTTagList) nbt.getTag("otherwiseDestinations");
for (NBTBase otherwiseDestinationNBT : otherwiseDestinationsNBT) {
WeightedRiftDestination otherwiseDestination = new WeightedRiftDestination();
otherwiseDestination.readFromNBT((NBTTagCompound) otherwiseDestinationNBT);
otherwiseDestinations.add(otherwiseDestination);
}
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
nbt = super.writeToNBT(nbt);
nbt.setFloat("weight", weight);
NBTTagList ifDestinationsNBT = new NBTTagList();
for (WeightedRiftDestination ifDestination : ifDestinations) {
ifDestinationsNBT.appendTag(ifDestination.writeToNBT(new NBTTagCompound()));
}
nbt.setTag("ifDestinations", ifDestinationsNBT);
NBTTagList otherwiseDestinationsNBT = new NBTTagList();
for (WeightedRiftDestination otherwiseDestination : otherwiseDestinations) {
otherwiseDestinationsNBT.appendTag(otherwiseDestination.writeToNBT(new NBTTagCompound()));
}
nbt.setTag("otherwiseDestinations", otherwiseDestinationsNBT);
return nbt;
}
@Override public void readFromNBT(NBTTagCompound nbt) { super.readFromNBT(nbt); NBTUtils.readFromNBT(this, nbt); }
@Override public NBTTagCompound writeToNBT(NBTTagCompound nbt) { nbt = super.writeToNBT(nbt); return NBTUtils.writeToNBT(this, nbt); }
@Override
public boolean teleport(TileEntityRift rift, Entity entity) {

View file

@ -9,25 +9,16 @@ import lombok.ToString;
import net.minecraft.entity.Entity;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.math.Vec3i;
import org.dimdev.ddutils.nbt.SavedToNBT;
@Getter @AllArgsConstructor @Builder(toBuilder = true) @ToString
public class RelativeDestination extends RiftDestination { // TODO: use Vec3i
private Vec3i offset;
@SavedToNBT public class RelativeDestination extends RiftDestination { // TODO: use Vec3i
@SavedToNBT /*package-private*/ Vec3i offset;
public RelativeDestination() {}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
offset = NBTUtils.readVec3i(nbt.getCompoundTag("offset"));
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
nbt = super.writeToNBT(nbt);
nbt.setTag("offset", NBTUtils.writeVec3i(offset));
return nbt;
}
@Override public void readFromNBT(NBTTagCompound nbt) { super.readFromNBT(nbt); NBTUtils.readFromNBT(this, nbt); }
@Override public NBTTagCompound writeToNBT(NBTTagCompound nbt) { nbt = super.writeToNBT(nbt); return NBTUtils.writeToNBT(this, nbt); }
@Override
public boolean teleport(TileEntityRift rift, Entity entity) {

View file

@ -7,6 +7,7 @@ import org.dimdev.ddutils.nbt.INBTStorable;
import net.minecraft.entity.Entity;
import net.minecraft.nbt.NBTTagCompound;
import lombok.*; // Don't change import order! (Gradle bug): https://stackoverflow.com/questions/26557133/
import org.dimdev.ddutils.nbt.SavedToNBT;
import java.lang.reflect.InvocationTargetException;

View file

@ -2,6 +2,8 @@ package org.dimdev.dimdoors.shared.rifts;
import com.google.common.collect.ConcurrentHashMultiset;
import com.google.common.collect.Multiset;
import org.dimdev.ddutils.nbt.NBTUtils;
import org.dimdev.ddutils.nbt.SavedToNBT;
import org.dimdev.dimdoors.shared.world.DimDoorDimensions;
import org.dimdev.ddutils.nbt.INBTStorable; // Don't change imports order! (Gradle bug): https://stackoverflow.com/questions/26557133/
import org.dimdev.ddutils.Location;
@ -21,48 +23,36 @@ import net.minecraftforge.common.DimensionManager;
import java.util.*;
public class RiftRegistry extends WorldSavedData {
@SavedToNBT public class RiftRegistry extends WorldSavedData {
private static final String DATA_NAME = DimDoors.MODID + "_rifts";
@Getter private static final int DATA_VERSION = 0; // IMPORTANT: Update this and upgradeRegistry when making changes.
@Getter private final Map<Location, RiftInfo> rifts = new HashMap<>(); // TODO: store relative locations too (better location class supporting relative, etc)
@Getter private final Map<String, Location> privatePocketEntrances = new HashMap<>(); // Player UUID -> last rift used to exit pocket TODO: split into PrivatePocketRiftRegistry subclass
@Getter private final Map<String, List<Location>> privatePocketEntranceLists = new HashMap<>(); // Player UUID -> private pocket entrances TODO: split into PrivatePocketRiftRegistry subclass
@Getter private final Map<String, Location> privatePocketExits = new HashMap<>(); // Player UUID -> last rift used to enter pocket
@Getter private final Map<String, Location> overworldRifts = new HashMap<>();
@SavedToNBT @Getter /*package-private*/ /*final*/ Map<Location, RiftInfo> rifts = new HashMap<>(); // TODO: store relative locations too (better location class supporting relative, etc)
@SavedToNBT @Getter /*package-private*/ /*final*/ Map<String, Location> privatePocketEntrances = new HashMap<>(); // Player UUID -> last rift used to exit pocket TODO: split into PrivatePocketRiftRegistry subclass
@SavedToNBT @Getter /*package-private*/ /*final*/ Map<String, List<Location>> privatePocketEntranceLists = new HashMap<>(); // Player UUID -> private pocket entrances TODO: split into PrivatePocketRiftRegistry subclass
@SavedToNBT @Getter /*package-private*/ /*final*/ Map<String, Location> privatePocketExits = new HashMap<>(); // Player UUID -> last rift used to enter pocket
@SavedToNBT @Getter /*package-private*/ /*final*/ Map<String, Location> overworldRifts = new HashMap<>();
@Getter private int dim;
private World world;
@AllArgsConstructor @EqualsAndHashCode @Builder(toBuilder = true)
public static class RiftInfo implements INBTStorable {
@SavedToNBT public static class RiftInfo implements INBTStorable {
// IntelliJ warnings are wrong, Builder needs these initializers!
@SuppressWarnings({"UnusedAssignment", "RedundantSuppression"}) @Builder.Default @Getter private Set<AvailableLinkInfo> availableLinks = new HashSet<>(); // TODO: multiset?
@SuppressWarnings({"UnusedAssignment", "RedundantSuppression"}) @Builder.Default @Getter private Multiset<Location> sources = ConcurrentHashMultiset.create();
@SuppressWarnings({"UnusedAssignment", "RedundantSuppression"}) @Builder.Default @Getter private Multiset<Location> destinations = ConcurrentHashMultiset.create();
@SavedToNBT @SuppressWarnings({"UnusedAssignment", "RedundantSuppression"}) @Builder.Default @Getter /*package-private*/ Set<AvailableLinkInfo> availableLinks = new HashSet<>(); // TODO: multiset?
@SavedToNBT @SuppressWarnings({"UnusedAssignment", "RedundantSuppression"}) @Builder.Default @Getter /*package-private*/ Multiset<Location> sources = ConcurrentHashMultiset.create();
@SavedToNBT @SuppressWarnings({"UnusedAssignment", "RedundantSuppression"}) @Builder.Default @Getter /*package-private*/ Multiset<Location> destinations = ConcurrentHashMultiset.create();
@AllArgsConstructor @NoArgsConstructor @EqualsAndHashCode @Builder(toBuilder = true)
public static class AvailableLinkInfo implements INBTStorable {
@Getter @Setter private float weight;
@Getter private VirtualLocation virtualLocation;
@Getter @Wither private Location location;
@Getter private UUID uuid;
@SavedToNBT @Getter @Setter /*package-private*/ float weight;
@SavedToNBT @Getter /*package-private*/ VirtualLocation virtualLocation;
@SavedToNBT @Getter @Wither /*package-private*/ Location location;
@SavedToNBT @Getter /*package-private*/ UUID uuid;
@Override
public void readFromNBT(NBTTagCompound nbt) {
weight = nbt.getFloat("weight");
virtualLocation = VirtualLocation.readFromNBT(nbt.getCompoundTag("virtualLocation"));
uuid = nbt.getUniqueId("uuid");
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
nbt.setFloat("weight", weight);
nbt.setTag("virtualLocation", virtualLocation.writeToNBT());
nbt.setUniqueId("uuid", uuid);
return nbt;
}
@Override public void readFromNBT(NBTTagCompound nbt) { NBTUtils.readFromNBT(this, nbt); }
@Override public NBTTagCompound writeToNBT(NBTTagCompound nbt) { return NBTUtils.writeToNBT(this, nbt); }
}
public RiftInfo() {
@ -71,48 +61,8 @@ public class RiftRegistry extends WorldSavedData {
destinations = ConcurrentHashMultiset.create();
}
@Override
public void readFromNBT(NBTTagCompound nbt) {
NBTTagList availableLinksNBT = (NBTTagList) nbt.getTag("availableLinks"); // TODO: figure out why this is sometimes null
for (NBTBase availableLinkNBT : availableLinksNBT) {
AvailableLinkInfo link = new AvailableLinkInfo();
link.readFromNBT((NBTTagCompound) availableLinkNBT);
availableLinks.add(link);
}
NBTTagList sourcesNBT = (NBTTagList) nbt.getTag("sources");
for (NBTBase sourceNBT : sourcesNBT) {
sources.add(Location.readFromNBT((NBTTagCompound) sourceNBT));
}
NBTTagList destinationsNBT = (NBTTagList) nbt.getTag("destinations");
for (NBTBase destinationNBT : destinationsNBT) {
destinations.add(Location.readFromNBT((NBTTagCompound) destinationNBT));
}
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
NBTTagList availableLinksNBT = new NBTTagList();
for (AvailableLinkInfo availableLink : availableLinks) {
availableLinksNBT.appendTag(availableLink.writeToNBT(new NBTTagCompound()));
}
nbt.setTag("availableLinks", availableLinksNBT);
NBTTagList sourcesNBT = new NBTTagList();
for (Location source : sources) {
sourcesNBT.appendTag(Location.writeToNBT(source));
}
nbt.setTag("sources", sourcesNBT);
NBTTagList destinationsNBT = new NBTTagList();
for (Location destination : destinations) {
destinationsNBT.appendTag(Location.writeToNBT(destination));
}
nbt.setTag("destinations", sourcesNBT);
return nbt;
}
@Override public void readFromNBT(NBTTagCompound nbt) { NBTUtils.readFromNBT(this, nbt); }
@Override public NBTTagCompound writeToNBT(NBTTagCompound nbt) { return NBTUtils.writeToNBT(this, nbt); }
}
public RiftRegistry() {
@ -154,50 +104,7 @@ public class RiftRegistry extends WorldSavedData {
}
}
NBTTagList riftsNBT = (NBTTagList) nbt.getTag("rifts");
for (NBTBase riftNBT : riftsNBT) {
NBTTagCompound riftNBTC = (NBTTagCompound) riftNBT;
Location location = Location.readFromNBT(riftNBTC.getCompoundTag("location"));
RiftInfo riftInfo = new RiftInfo();
riftInfo.readFromNBT(riftNBTC);
rifts.put(location, riftInfo);
}
NBTTagList privatePocketEntrancesNBT = (NBTTagList) nbt.getTag("privatePocketEntrances");
for (NBTBase privatePocketEntranceNBT : privatePocketEntrancesNBT) { // TODO: move to NBTUtils
NBTTagCompound privatePocketEntranceNBTC = (NBTTagCompound) privatePocketEntranceNBT;
String uuid = privatePocketEntranceNBTC.getString("uuid");
Location rift = Location.readFromNBT(privatePocketEntranceNBTC.getCompoundTag("location"));
privatePocketEntrances.put(uuid, rift);
}
NBTTagList privatePocketEntranceListsNBT = (NBTTagList) nbt.getTag("privatePocketEntranceLists");
for (NBTBase privatePocketEntranceListNBT : privatePocketEntranceListsNBT) { // TODO: move to NBTUtils
NBTTagCompound privatePocketEntranceListNBTC = (NBTTagCompound) privatePocketEntranceListNBT;
String uuid = privatePocketEntranceListNBTC.getString("uuid");
NBTTagList entrancesNBT = (NBTTagList) privatePocketEntranceListNBTC.getTag("locationList");
for (NBTBase entranceNBT : entrancesNBT) {
NBTTagCompound entranceNBTC = (NBTTagCompound) entranceNBT;
Location rift = Location.readFromNBT(entranceNBTC);
privatePocketEntranceLists.get(uuid).add(rift);
}
}
NBTTagList privatePocketExitsNBT = (NBTTagList) nbt.getTag("privatePocketExits");
for (NBTBase privatePocketExitNBT : privatePocketExitsNBT) { // TODO: move to NBTUtils
NBTTagCompound privatePocketExitNBTC = (NBTTagCompound) privatePocketExitNBT;
String uuid = privatePocketExitNBTC.getString("uuid");
Location rift = Location.readFromNBT(privatePocketExitNBTC.getCompoundTag("location"));
privatePocketExits.put(uuid, rift);
}
NBTTagList overworldRiftsNBT = (NBTTagList) nbt.getTag("overworldRifts");
for (NBTBase overworldRiftNBT : overworldRiftsNBT) { // TODO: move to NBTUtils
NBTTagCompound overworldRiftNBTC = (NBTTagCompound) overworldRiftNBT;
String uuid = overworldRiftNBTC.getString("uuid");
Location rift = Location.readFromNBT(overworldRiftNBTC.getCompoundTag("location"));
overworldRifts.put(uuid, rift);
}
NBTUtils.readFromNBT(this, nbt);
}
private static boolean upgradeRegistry(@SuppressWarnings("unused") NBTTagCompound nbt, int oldVersion) {
@ -219,61 +126,7 @@ public class RiftRegistry extends WorldSavedData {
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
nbt.setInteger("version", DATA_VERSION);
NBTTagList riftsNBT = new NBTTagList();
for (HashMap.Entry<Location, RiftInfo> rift : rifts.entrySet()) {
NBTTagCompound riftNBT = new NBTTagCompound();
riftNBT.setTag("location", Location.writeToNBT(rift.getKey()));
riftNBT = rift.getValue().writeToNBT(riftNBT);
riftsNBT.appendTag(riftNBT);
}
nbt.setTag("rifts", riftsNBT);
NBTTagList privatePocketEntrancesNBT = new NBTTagList();
for (HashMap.Entry<String, Location> privatePocketEntrance : privatePocketEntrances.entrySet()) { // TODO: move to NBTUtils
if (privatePocketEntrance.getValue() == null) continue;
NBTTagCompound privatePocketEntranceNBT = new NBTTagCompound();
privatePocketEntranceNBT.setString("uuid", privatePocketEntrance.getKey());
privatePocketEntranceNBT.setTag("location", Location.writeToNBT(privatePocketEntrance.getValue()));
privatePocketEntrancesNBT.appendTag(privatePocketEntranceNBT);
}
nbt.setTag("privatePocketEntrances", privatePocketEntrancesNBT);
NBTTagList privatePocketEntranceListsNBT = new NBTTagList();
for (HashMap.Entry<String, List<Location>> privatePocketEntranceList : privatePocketEntranceLists.entrySet()) { // TODO: move to NBTUtils
if (privatePocketEntranceList.getValue() == null) continue;
NBTTagCompound privatePocketEntranceListNBT = new NBTTagCompound();
privatePocketEntranceListNBT.setString("uuid", privatePocketEntranceList.getKey());
NBTTagList entranceListNBT = new NBTTagList();
for (Location entrance : privatePocketEntranceList.getValue()) {
entranceListNBT.appendTag(Location.writeToNBT(entrance));
}
privatePocketEntranceListNBT.setTag("locationList", entranceListNBT);
privatePocketEntranceListsNBT.appendTag(privatePocketEntranceListNBT);
}
nbt.setTag("privatePocketEntranceLists", privatePocketEntranceListsNBT);
NBTTagList privatePocketExitsNBT = new NBTTagList();
for (HashMap.Entry<String, Location> privatePocketExit : privatePocketExits.entrySet()) { // TODO: move to NBTUtils
if (privatePocketExit.getValue() == null) continue;
NBTTagCompound privatePocketExitNBT = new NBTTagCompound();
privatePocketExitNBT.setString("uuid", privatePocketExit.getKey());
privatePocketExitNBT.setTag("location", Location.writeToNBT(privatePocketExit.getValue()));
privatePocketExitsNBT.appendTag(privatePocketExitNBT);
}
nbt.setTag("privatePocketExits", privatePocketExitsNBT);
NBTTagList overworldRiftsNBT = new NBTTagList();
for (HashMap.Entry<String, Location> overworldRift : overworldRifts.entrySet()) {
if (overworldRift.getValue() == null) continue;
NBTTagCompound overworldRiftNBT = new NBTTagCompound();
overworldRiftNBT.setString("uuid", overworldRift.getKey());
overworldRiftNBT.setTag("location", Location.writeToNBT(overworldRift.getValue()));
overworldRiftsNBT.appendTag(overworldRiftNBT);
}
nbt.setTag("overworldRifts", overworldRiftsNBT);
return nbt;
return NBTUtils.writeToNBT(this, nbt);
}
public static RiftInfo getRiftInfo(Location rift) {

View file

@ -1,5 +1,7 @@
package org.dimdev.dimdoors.shared.rifts;
import org.dimdev.ddutils.nbt.NBTUtils;
import org.dimdev.ddutils.nbt.SavedToNBT;
import org.dimdev.dimdoors.DimDoors;
import org.dimdev.dimdoors.shared.VirtualLocation;
import org.dimdev.dimdoors.shared.pockets.Pocket;
@ -29,16 +31,16 @@ import net.minecraftforge.fml.relauncher.SideOnly;
import javax.annotation.Nonnull;
import java.util.*;
public abstract class TileEntityRift extends TileEntity implements ITickable { // TODO: implement ITeleportSource and ITeleportDestination
@SavedToNBT public abstract class TileEntityRift extends TileEntity implements ITickable { // TODO: implement ITeleportSource and ITeleportDestination
@Getter protected VirtualLocation virtualLocation;
@Nonnull @Getter protected List<WeightedRiftDestination> destinations; // Not using a set because we can have duplicate destinations. Maybe use Multiset from Guava?
@Getter protected boolean makeDestinationPermanent;
@Getter protected boolean preserveRotation;
@Getter protected float yaw;
@Getter protected float pitch;
@Getter protected boolean alwaysDelete; // Delete the rift when an entrances rift is broken even if the state was changed or destinations link there.
@Getter protected float chaosWeight;
@SavedToNBT@Getter protected VirtualLocation virtualLocation;
@SavedToNBT @Nonnull @Getter protected List<WeightedRiftDestination> destinations; // Not using a set because we can have duplicate destinations. Maybe use Multiset from Guava?
@SavedToNBT @Getter protected boolean makeDestinationPermanent;
@SavedToNBT @Getter protected boolean preserveRotation;
@SavedToNBT @Getter protected float yaw;
@SavedToNBT @Getter protected float pitch;
@SavedToNBT @Getter protected boolean alwaysDelete; // Delete the rift when an entrances rift is broken even if the state was changed or destinations link there.
@SavedToNBT @Getter protected float chaosWeight;
// TODO: option to convert to door on teleportTo?
protected boolean riftStateChanged; // not saved
@ -64,49 +66,10 @@ public abstract class TileEntityRift extends TileEntity implements ITickable { /
markDirty();
}
// Reading/writing to NBT
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
if (nbt.hasKey("virtualLocation")) virtualLocation = VirtualLocation.readFromNBT(nbt.getCompoundTag("virtualLocation"));
NBTTagList destinationsNBT = (NBTTagList) nbt.getTag("destinations");
destinations = new ArrayList<>();
if (destinationsNBT != null) for (NBTBase destinationNBT : destinationsNBT) {
WeightedRiftDestination destination = new WeightedRiftDestination();
destination.readFromNBT((NBTTagCompound) destinationNBT);
destinations.add(destination);
}
makeDestinationPermanent = nbt.getBoolean("makeDestinationPermanent");
preserveRotation = nbt.getBoolean("preserveRotation");
yaw = nbt.getFloat("yaw");
pitch = nbt.getFloat("pitch");
alwaysDelete = nbt.getBoolean("alwaysDelete");
chaosWeight = nbt.getFloat("chaosWeight");
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
super.writeToNBT(nbt);
if (virtualLocation != null) nbt.setTag("virtualLocation", virtualLocation.writeToNBT());
NBTTagList destinationsNBT = new NBTTagList();
for (WeightedRiftDestination destination : destinations) {
destinationsNBT.appendTag(destination.writeToNBT(new NBTTagCompound()));
}
nbt.setTag("destinations", destinationsNBT);
nbt.setBoolean("makeDestinationPermanent", makeDestinationPermanent);
nbt.setBoolean("preserveRotation", preserveRotation);
nbt.setFloat("yaw", yaw);
nbt.setFloat("pitch", pitch);
nbt.setBoolean("alwaysDelete", alwaysDelete);
nbt.setFloat("chaosWeight", chaosWeight);
return nbt;
@Override public void readFromNBT(NBTTagCompound nbt) { super.readFromNBT(nbt); NBTUtils.readFromNBT(this, nbt); }
@Override public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
nbt = super.writeToNBT(nbt);
return NBTUtils.writeToNBT(this, nbt);
}
@Override

View file

@ -1,5 +1,7 @@
package org.dimdev.dimdoors.shared.tileentities;
import org.dimdev.ddutils.nbt.NBTUtils;
import org.dimdev.ddutils.nbt.SavedToNBT;
import org.dimdev.dimdoors.shared.rifts.TileEntityRift;
import org.dimdev.ddutils.Location;
import org.dimdev.ddutils.render.RGBA;
@ -12,20 +14,20 @@ import net.minecraft.util.EnumFacing;
import java.util.Random;
// TODO: merge horizontal and vertical entrances' render code into one, and support custom sizes
public class TileEntityEntranceRift extends TileEntityRift {
@Getter private boolean placeRiftOnBreak = false;
@Getter private boolean closeAfterPassThrough = false;
@Getter public boolean shouldRender = true;
@Getter public byte lockStatus = 0;
@SavedToNBT public class TileEntityEntranceRift extends TileEntityRift {
@SavedToNBT @Getter /*package-private*/ boolean placeRiftOnBreak = false;
@SavedToNBT @Getter /*package-private*/ boolean closeAfterPassThrough = false;
@SavedToNBT @Getter public boolean shouldRender = true;
@SavedToNBT @Getter public byte lockStatus = 0;
// Set by the block, not saved and not synced to the client
public EnumFacing orientation;
public int tpOffset = 1; // TODO: float?
public double extendUp = 0.5; // Use += to set these. TODO: @SideOnly client?
public double extendDown = 0.5;
public double extendLeft = 0.5;
public double extendRight = 0.5;
public double pushIn = 0.01; // TODO: set to 0, and set on door
@SavedToNBT public EnumFacing orientation;
@SavedToNBT public int tpOffset = 1; // TODO: float?
@SavedToNBT public double extendUp = 0.5; // Use += to set these. TODO: @SideOnly client?
@SavedToNBT public double extendDown = 0.5;
@SavedToNBT public double extendLeft = 0.5;
@SavedToNBT public double extendRight = 0.5;
@SavedToNBT public double pushIn = 0.01; // TODO: set to 0, and set on door
@Override
public void copyFrom(TileEntityRift oldRift) {
@ -37,38 +39,10 @@ public class TileEntityEntranceRift extends TileEntityRift {
placeRiftOnBreak = true;
}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
placeRiftOnBreak = nbt.getBoolean("placeRiftOnBreak");
closeAfterPassThrough = nbt.getBoolean("closeAfterPassThrough");
shouldRender = nbt.getBoolean("shouldRender");
lockStatus = nbt.getByte("lockStatus");
orientation = EnumFacing.byName(nbt.getString("orientation")); // TODO: avoid having to save these and generate on load based on blockstate
tpOffset = nbt.getInteger("tpOffset");
extendUp = nbt.getDouble("extendUp");
extendDown = nbt.getDouble("extendDown");
extendLeft = nbt.getDouble("extendLeft");
extendRight = nbt.getDouble("extendRight");
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
super.writeToNBT(nbt);
nbt.setBoolean("placeRiftOnBreak", placeRiftOnBreak);
nbt.setBoolean("closeAfterPassThrough", closeAfterPassThrough);
nbt.setBoolean("shouldRender", shouldRender);
nbt.setByte("lockStatus", lockStatus);
if (orientation != null) nbt.setString("orientation", orientation.getName()); // TODO: why is this sometimes null on generated transient entrances?
nbt.setInteger("tpOffset", tpOffset);
nbt.setDouble("extendUp", extendUp);
nbt.setDouble("extendDown", extendDown);
nbt.setDouble("extendLeft", extendLeft);
nbt.setDouble("extendRight", extendRight);
return nbt;
@Override public void readFromNBT(NBTTagCompound nbt) { super.readFromNBT(nbt); NBTUtils.readFromNBT(this, nbt); }
@Override public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
nbt = super.writeToNBT(nbt);
return NBTUtils.writeToNBT(this, nbt);
}
@Override

View file

@ -1,5 +1,7 @@
package org.dimdev.dimdoors.shared.tileentities;
import org.dimdev.ddutils.nbt.NBTUtils;
import org.dimdev.ddutils.nbt.SavedToNBT;
import org.dimdev.dimdoors.shared.blocks.ModBlocks;
import java.util.List;
import java.util.Random;
@ -12,7 +14,7 @@ import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.ITickable;
import net.minecraft.util.math.AxisAlignedBB;
public class TileEntityFloatingRift extends TileEntityRift implements ITickable {
@SavedToNBT public class TileEntityFloatingRift extends TileEntityRift implements ITickable {
private static final int ENDERMAN_SPAWNING_CHANCE = 1;
private static final int MAX_ENDERMAN_SPAWNING_CHANCE = 32;
@ -20,15 +22,13 @@ public class TileEntityFloatingRift extends TileEntityRift implements ITickable
private static final int MAX_HOSTILE_ENDERMAN_CHANCE = 3;
private static final int UPDATE_PERIOD = 200; //10 seconds
public boolean placingDoorOnRift = false; //to track whether a Rift is getting broken because it is replaced by a door (do not unregister in this case) or because it is being broken another way (do unregister in this case)
private static final Random random = new Random();
//Need to be saved:
private int updateTimer;
public boolean shouldClose = false; // TODO
public int spawnedEndermenID = 0;
public float growth = 0;
@SavedToNBT /*package-private*/ int updateTimer;
@SavedToNBT public boolean shouldClose = false; // TODO
@SavedToNBT public int spawnedEndermenID = 0;
@SavedToNBT public float growth = 0;
public TileEntityFloatingRift() {
updateTimer = random.nextInt(UPDATE_PERIOD);
@ -105,25 +105,8 @@ public class TileEntityFloatingRift extends TileEntityRift implements ITickable
return pass == 1;
}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
updateTimer = nbt.getInteger("updateTimer");
shouldClose = nbt.getBoolean("shouldClose");
spawnedEndermenID = nbt.getInteger("spawnedEndermenID");
growth = nbt.getFloat("growth");
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
super.writeToNBT(nbt);
nbt.setInteger("updateTimer", updateTimer);
nbt.setBoolean("shouldClose", shouldClose);
nbt.setInteger("spawnedEndermenID", spawnedEndermenID);
nbt.setFloat("growth", growth);
return nbt;
}
@Override public void readFromNBT(NBTTagCompound nbt) { super.readFromNBT(nbt); NBTUtils.readFromNBT(this, nbt); }
@Override public NBTTagCompound writeToNBT(NBTTagCompound nbt) { nbt = super.writeToNBT(nbt); return NBTUtils.writeToNBT(this, nbt); }
@Override
public boolean isFloating() {