diff --git a/.gitignore b/.gitignore
index f230c07b3c..e9a73fdffd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,6 +18,7 @@ logs/
/annotations/out/
/net/build/
/tools/build/
+/core/build/
/tests/build/
/server/build/
changelog
@@ -43,6 +44,7 @@ changelog
*.gif
/core/assets/saves/
/out/
+/core/assets-raw/fontgen/out/
version.properties
diff --git a/android/build.gradle b/android/build.gradle
index e82a957ba5..6d9c072a58 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -29,12 +29,10 @@ dependencies{
implementation arcModule("backends:backend-android")
implementation 'com.jakewharton.android.repackaged:dalvik-dx:9.0.0_r3'
- natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-armeabi"
natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-armeabi-v7a"
natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-arm64-v8a"
natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-x86"
natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-x86_64"
- natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-armeabi"
natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-armeabi-v7a"
natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-arm64-v8a"
natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-x86"
@@ -119,7 +117,6 @@ android{
// the natives configuration, and extracts them to the proper libs/ folders
// so they get packed with the APK.
task copyAndroidNatives(){
- file("libs/armeabi/").mkdirs()
file("libs/armeabi-v7a/").mkdirs()
file("libs/arm64-v8a/").mkdirs()
file("libs/x86_64/").mkdirs()
@@ -129,7 +126,6 @@ task copyAndroidNatives(){
def outputDir = null
if(jar.name.endsWith("natives-arm64-v8a.jar")) outputDir = file("libs/arm64-v8a")
if(jar.name.endsWith("natives-armeabi-v7a.jar")) outputDir = file("libs/armeabi-v7a")
- if(jar.name.endsWith("natives-armeabi.jar")) outputDir = file("libs/armeabi")
if(jar.name.endsWith("natives-x86_64.jar")) outputDir = file("libs/x86_64")
if(jar.name.endsWith("natives-x86.jar")) outputDir = file("libs/x86")
if(outputDir != null){
diff --git a/android/src/mindustry/android/AndroidLauncher.java b/android/src/mindustry/android/AndroidLauncher.java
index ffaadcf470..1c233438ff 100644
--- a/android/src/mindustry/android/AndroidLauncher.java
+++ b/android/src/mindustry/android/AndroidLauncher.java
@@ -144,7 +144,6 @@ public class AndroidLauncher extends AndroidApplication{
}, new AndroidApplicationConfiguration(){{
useImmersiveMode = true;
- depth = 0;
hideStatusBar = true;
errorHandler = CrashSender::log;
}});
diff --git a/annotations/build.gradle b/annotations/build.gradle
index d894ed0abf..d87bfffb22 100644
--- a/annotations/build.gradle
+++ b/annotations/build.gradle
@@ -2,5 +2,4 @@ apply plugin: "java"
sourceCompatibility = 1.8
sourceSets.main.java.srcDirs = ["src/main/java/"]
-sourceSets.main.resources.srcDirs = ["src/main/resources/"]
-
+sourceSets.main.resources.srcDirs = ["src/main/resources/"]
\ No newline at end of file
diff --git a/annotations/src/main/java/mindustry/annotations/Annotations.java b/annotations/src/main/java/mindustry/annotations/Annotations.java
index 6441cacf2f..95bd2b2a4a 100644
--- a/annotations/src/main/java/mindustry/annotations/Annotations.java
+++ b/annotations/src/main/java/mindustry/annotations/Annotations.java
@@ -5,11 +5,56 @@ import java.lang.annotation.*;
public class Annotations{
//region entity interfaces
+ public enum DrawLayer{
+ floor,
+ floorOver,
+ groundShadows,
+ groundUnder,
+ ground,
+ flyingShadows,
+ flying,
+ bullets,
+ effects,
+ overlays,
+ names,
+ weather
+ }
+
+ /** Indicates that a method overrides other methods. */
+ @Target({ElementType.METHOD})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Replace{
+ }
+
+ /** Indicates that a component field is imported from other components. */
+ @Target({ElementType.FIELD})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Import{
+ }
+
+ /** Indicates that a component field is read-only. */
+ @Target({ElementType.FIELD, ElementType.METHOD})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ReadOnly{
+ }
+
/** Indicates multiple inheritance on a component type. */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
- public @interface Depends{
- Class[] value();
+ public @interface Component{
+ }
+
+ /** Indicates that a method is implemented by the annotation processor. */
+ @Target(ElementType.METHOD)
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface InternalImpl{
+ }
+
+ /** Indicates priority of a method in an entity. Methods with higher priority are done last. */
+ @Target(ElementType.METHOD)
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface MethodPriority{
+ float value();
}
/** Indicates that a component def is present on all entities. */
@@ -18,11 +63,28 @@ public class Annotations{
public @interface BaseComponent{
}
+ /** Creates a group that only examines entities that have all the components listed. */
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface GroupDef{
+ Class[] value();
+ Class[] collide() default {};
+ boolean spatial() default false;
+ boolean mapping() default false;
+ }
+
/** Indicates an entity definition. */
- @Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface EntityDef{
+ /** List of component interfaces */
Class[] value();
+ /** Whether the class is final */
+ boolean isFinal() default true;
+ /** If true, entities are recycled. */
+ boolean pooled() default false;
+ /** Whether to serialize (makes the serialize method return this value) */
+ boolean serialize() default true;
+ /** Whether to generate IO code */
+ boolean genio() default true;
}
/** Indicates an internal interface for entity components. */
@@ -153,26 +215,9 @@ public class Annotations{
PacketPriority priority() default PacketPriority.normal;
}
- /**
- * Specifies that this method will be used to write classes of the type returned by {@link #value()}.
- * This method must return void and have two parameters, the first being of type {@link java.nio.ByteBuffer} and the second
- * being the type returned by {@link #value()}.
- */
- @Target(ElementType.METHOD)
+ @Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
- public @interface WriteClass{
- Class> value();
- }
-
- /**
- * Specifies that this method will be used to read classes of the type returned by {@link #value()}.
- * This method must return the type returned by {@link #value()},
- * and have one parameter, being of type {@link java.nio.ByteBuffer}.
- */
- @Target(ElementType.METHOD)
- @Retention(RetentionPolicy.SOURCE)
- public @interface ReadClass{
- Class> value();
+ public @interface TypeIOHandler{
}
//endregion
diff --git a/annotations/src/main/java/mindustry/annotations/BaseProcessor.java b/annotations/src/main/java/mindustry/annotations/BaseProcessor.java
index 57d3be2d9c..37cbff235f 100644
--- a/annotations/src/main/java/mindustry/annotations/BaseProcessor.java
+++ b/annotations/src/main/java/mindustry/annotations/BaseProcessor.java
@@ -1,7 +1,9 @@
package mindustry.annotations;
-import arc.struct.*;
+import arc.files.*;
+import arc.struct.Array;
import arc.util.*;
+import arc.util.Log.*;
import com.squareup.javapoet.*;
import com.sun.source.util.*;
import mindustry.annotations.util.*;
@@ -9,11 +11,13 @@ import mindustry.annotations.util.*;
import javax.annotation.processing.*;
import javax.lang.model.*;
import javax.lang.model.element.*;
+import javax.lang.model.type.*;
import javax.lang.model.util.*;
import javax.tools.Diagnostic.*;
import javax.tools.*;
import java.io.*;
import java.lang.annotation.*;
+import java.lang.reflect.*;
import java.util.*;
@SupportedSourceVersion(SourceVersion.RELEASE_8)
@@ -30,6 +34,7 @@ public abstract class BaseProcessor extends AbstractProcessor{
protected int round;
protected int rounds = 1;
protected RoundEnvironment env;
+ protected Fi rootDirectory;
public static String getMethodName(Element element){
return ((TypeElement)element.getEnclosingElement()).getQualifiedName().toString() + "." + element.getSimpleName();
@@ -40,6 +45,74 @@ public abstract class BaseProcessor extends AbstractProcessor{
|| type.equals("long") || type.equals("float") || type.equals("double") || type.equals("char");
}
+ public static boolean instanceOf(String type, String other){
+ TypeElement a = elementu.getTypeElement(type);
+ TypeElement b = elementu.getTypeElement(other);
+ return a != null && b != null && typeu.isSubtype(a.asType(), b.asType());
+ }
+
+ public static String getDefault(String value){
+ switch(value){
+ case "float":
+ case "double":
+ case "int":
+ case "long":
+ case "short":
+ case "char":
+ case "byte":
+ return "0";
+ case "boolean":
+ return "false";
+ default:
+ return "null";
+ }
+ }
+
+ //in bytes
+ public static int typeSize(String kind){
+ switch(kind){
+ case "boolean":
+ case "byte":
+ return 1;
+ case "short":
+ return 2;
+ case "float":
+ case "char":
+ case "int":
+ return 4;
+ case "long":
+ return 8;
+ default:
+ throw new IllegalArgumentException("Invalid primitive type: " + kind + "");
+ }
+ }
+
+ public static String simpleName(String str){
+ return str.contains(".") ? str.substring(str.lastIndexOf('.') + 1) : str;
+ }
+
+ public static TypeName tname(String name) throws Exception{
+ Constructor cons = TypeName.class.getDeclaredConstructor(String.class);
+ cons.setAccessible(true);
+ return cons.newInstance(name);
+ }
+
+ public static TypeName tname(Class> c){
+ return ClassName.get(c).box();
+ }
+
+ public static TypeVariableName getTVN(TypeParameterElement element) {
+ String name = element.getSimpleName().toString();
+ List extends TypeMirror> boundsMirrors = element.getBounds();
+
+ List boundsTypeNames = new ArrayList<>();
+ for (TypeMirror typeMirror : boundsMirrors) {
+ boundsTypeNames.add(TypeName.get(typeMirror));
+ }
+
+ return TypeVariableName.get(name, boundsTypeNames.toArray(new TypeName[0]));
+ }
+
public static void write(TypeSpec.Builder builder) throws Exception{
write(builder, null);
}
@@ -70,6 +143,10 @@ public abstract class BaseProcessor extends AbstractProcessor{
}
}
+ public Array elements(Class extends Annotation> type){
+ return Array.with(env.getElementsAnnotatedWith(type)).map(Selement::new);
+ }
+
public Array types(Class extends Annotation> type){
return Array.with(env.getElementsAnnotatedWith(type)).select(e -> e instanceof TypeElement)
.map(e -> new Stype((TypeElement)e));
@@ -85,12 +162,12 @@ public abstract class BaseProcessor extends AbstractProcessor{
.map(e -> new Smethod((ExecutableElement)e));
}
- public void err(String message){
+ public static void err(String message){
messager.printMessage(Kind.ERROR, message);
Log.err("[CODEGEN ERROR] " +message);
}
- public void err(String message, Element elem){
+ public static void err(String message, Element elem){
messager.printMessage(Kind.ERROR, message, elem);
Log.err("[CODEGEN ERROR] " + message + ": " + elem);
}
@@ -108,15 +185,32 @@ public abstract class BaseProcessor extends AbstractProcessor{
elementu = env.getElementUtils();
filer = env.getFiler();
messager = env.getMessager();
+
+ Log.setLogLevel(LogLevel.info);
+
+ if(System.getProperty("debug") != null){
+ Log.setLogLevel(LogLevel.debug);
+ }
}
@Override
public boolean process(Set extends TypeElement> annotations, RoundEnvironment roundEnv){
if(round++ >= rounds) return false; //only process 1 round
+ if(rootDirectory == null){
+ try{
+ String path = Fi.get(filer.getResource(StandardLocation.CLASS_OUTPUT, "no", "no")
+ .toUri().toURL().toString().substring(OS.isWindows ? 6 : "file:".length()))
+ .parent().parent().parent().parent().parent().parent().parent().toString().replace("%20", " ");
+ rootDirectory = Fi.get(path);
+ }catch(IOException e){
+ throw new RuntimeException(e);
+ }
+ }
+
this.env = roundEnv;
try{
process(roundEnv);
- }catch(Exception e){
+ }catch(Throwable e){
e.printStackTrace();
throw new RuntimeException(e);
}
diff --git a/annotations/src/main/java/mindustry/annotations/entity/EntityIO.java b/annotations/src/main/java/mindustry/annotations/entity/EntityIO.java
new file mode 100644
index 0000000000..93b07ace1a
--- /dev/null
+++ b/annotations/src/main/java/mindustry/annotations/entity/EntityIO.java
@@ -0,0 +1,185 @@
+package mindustry.annotations.entity;
+
+import arc.files.*;
+import arc.struct.*;
+import arc.util.serialization.*;
+import com.squareup.javapoet.*;
+import mindustry.annotations.Annotations.*;
+import mindustry.annotations.*;
+import mindustry.annotations.util.TypeIOResolver.*;
+
+import javax.lang.model.element.*;
+
+import static mindustry.annotations.BaseProcessor.instanceOf;
+
+public class EntityIO{
+ final static Json json = new Json();
+
+ final ClassSerializer serializer;
+ final String name;
+ final TypeSpec.Builder type;
+ final Fi directory;
+ final Array revisions = new Array<>();
+
+ boolean write;
+ MethodSpec.Builder method;
+ ObjectSet presentFields = new ObjectSet<>();
+
+ EntityIO(String name, TypeSpec.Builder type, ClassSerializer serializer, Fi directory){
+ this.directory = directory;
+ this.type = type;
+ this.serializer = serializer;
+ this.name = name;
+
+ directory.mkdirs();
+
+ //load old revisions
+ for(Fi fi : directory.list()){
+ revisions.add(json.fromJson(Revision.class, fi));
+ }
+
+ //next revision to be used
+ int nextRevision = revisions.isEmpty() ? 0 : revisions.max(r -> r.version).version + 1;
+
+ //resolve preferred field order based on fields that fit
+ Array fields = Array.with(type.fieldSpecs).select(spec ->
+ !spec.hasModifier(Modifier.TRANSIENT) &&
+ !spec.hasModifier(Modifier.STATIC) &&
+ !spec.hasModifier(Modifier.FINAL) &&
+ (spec.type.isPrimitive() || serializer.has(spec.type.toString())));
+
+ //sort to keep order
+ fields.sortComparing(f -> f.name);
+
+ //keep track of fields present in the entity
+ presentFields.addAll(fields.map(f -> f.name));
+
+ //add new revision if it doesn't match or there are no revisions
+ if(revisions.isEmpty() || !revisions.peek().equal(fields)){
+ revisions.add(new Revision(nextRevision, fields.map(f -> new RevisionField(f.name, f.type.toString(), f.type.isPrimitive() ? BaseProcessor.typeSize(f.type.toString()) : -1))));
+ //write revision
+ directory.child(nextRevision + ".json").writeString(json.toJson(revisions.peek()));
+ }
+ }
+
+ void write(MethodSpec.Builder method, boolean write) throws Exception{
+ this.method = method;
+ this.write = write;
+
+ //subclasses *have* to call this method
+ method.addAnnotation(CallSuper.class);
+
+ if(write){
+ //write short revision
+ st("write.s($L)", revisions.peek().version);
+ //write uses most recent revision
+ for(RevisionField field : revisions.peek().fields){
+ io(field.type, "this." + field.name);
+ }
+ }else{
+ //read revision
+ st("short REV = read.s()");
+
+ for(int i = 0; i < revisions.size; i++){
+ //check for the right revision
+ Revision rev = revisions.get(i);
+ if(i == 0){
+ cont("if(REV == $L)", rev.version);
+ }else{
+ ncont("else if(REV == $L)", rev.version);
+ }
+
+ //add code for reading revision
+ for(RevisionField field : rev.fields){
+ //if the field doesn't exist, the result will be an empty string, it won't get assigned
+ io(field.type, presentFields.contains(field.name) ? "this." + field.name + " = " : "");
+ }
+ }
+
+ //throw exception on illegal revisions
+ ncont("else");
+ st("throw new IllegalArgumentException(\"Unknown revision '\" + REV + \"' for entity type '" + name + "'\")");
+ econt();
+ }
+ }
+
+ private void io(String type, String field) throws Exception{
+ if(BaseProcessor.isPrimitive(type)){
+ s(type.equals("boolean") ? "bool" : type.charAt(0) + "", field);
+ }else if(instanceOf(type, "mindustry.ctype.Content")){
+ if(write){
+ s("s", field + ".id");
+ }else{
+ st(field + "mindustry.Vars.content.getByID(mindustry.ctype.ContentType.$L, read.s())", BaseProcessor.simpleName(type).toLowerCase().replace("type", ""));
+ }
+ }else if(serializer.writers.containsKey(type) && write){
+ st("$L(write, $L)", serializer.writers.get(type), field);
+ }else if(serializer.readers.containsKey(type) && !write){
+ st("$L$L(read)", field, serializer.readers.get(type));
+ }
+ }
+
+ private void cont(String text, Object... fmt){
+ method.beginControlFlow(text, fmt);
+ }
+
+ private void econt(){
+ method.endControlFlow();
+ }
+
+ private void ncont(String text, Object... fmt){
+ method.nextControlFlow(text, fmt);
+ }
+
+ private void st(String text, Object... args){
+ method.addStatement(text, args);
+ }
+
+ private void s(String type, String field){
+ if(write){
+ method.addStatement("write.$L($L)", type, field);
+ }else{
+ method.addStatement("$Lread.$L()", field, type);
+ }
+ }
+
+ public static class Revision{
+ int version;
+ Array fields;
+
+ Revision(int version, Array fields){
+ this.version = version;
+ this.fields = fields;
+ }
+
+ Revision(){}
+
+ /** @return whether these two revisions are compatible */
+ boolean equal(Array specs){
+ if(fields.size != specs.size) return false;
+
+ for(int i = 0; i < fields.size; i++){
+ RevisionField field = fields.get(i);
+ FieldSpec spec = specs.get(i);
+ //TODO when making fields, their primitive size may be overwritten by an annotation; check for that
+ if(!(field.type.equals(spec.type.toString()) && (!spec.type.isPrimitive() || BaseProcessor.typeSize(spec.type.toString()) == field.size))){
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+
+ public static class RevisionField{
+ String name, type;
+ int size; //in bytes
+
+ RevisionField(String name, String type, int size){
+ this.name = name;
+ this.size = size;
+ this.type = type;
+ }
+
+ RevisionField(){}
+ }
+}
diff --git a/annotations/src/main/java/mindustry/annotations/entity/EntityProcess.java b/annotations/src/main/java/mindustry/annotations/entity/EntityProcess.java
new file mode 100644
index 0000000000..3e072d2fa8
--- /dev/null
+++ b/annotations/src/main/java/mindustry/annotations/entity/EntityProcess.java
@@ -0,0 +1,762 @@
+package mindustry.annotations.entity;
+
+import arc.*;
+import arc.files.*;
+import arc.func.*;
+import arc.struct.*;
+import arc.util.*;
+import arc.util.io.*;
+import arc.util.pooling.Pool.*;
+import arc.util.pooling.*;
+import com.squareup.javapoet.*;
+import com.squareup.javapoet.TypeSpec.*;
+import com.sun.source.tree.*;
+import mindustry.annotations.Annotations.*;
+import mindustry.annotations.*;
+import mindustry.annotations.util.*;
+import mindustry.annotations.util.TypeIOResolver.*;
+
+import javax.annotation.processing.*;
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+import java.lang.annotation.*;
+
+@SupportedAnnotationTypes({
+"mindustry.annotations.Annotations.EntityDef",
+"mindustry.annotations.Annotations.GroupDef",
+"mindustry.annotations.Annotations.EntityInterface",
+"mindustry.annotations.Annotations.BaseComponent",
+"mindustry.annotations.Annotations.TypeIOHandler"
+})
+public class EntityProcess extends BaseProcessor{
+ Array definitions = new Array<>();
+ Array groupDefs = new Array<>();
+ Array baseComponents;
+ ObjectMap componentNames = new ObjectMap<>();
+ ObjectMap> componentDependencies = new ObjectMap<>();
+ ObjectMap> defComponents = new ObjectMap<>();
+ ObjectMap varInitializers = new ObjectMap<>();
+ ObjectMap methodBlocks = new ObjectMap<>();
+ ObjectSet imports = new ObjectSet<>();
+ Array allGroups = new Array<>();
+ Array allDefs = new Array<>();
+ Array allInterfaces = new Array<>();
+ ClassSerializer serializer;
+
+ {
+ rounds = 3;
+ }
+
+ @Override
+ public void process(RoundEnvironment env) throws Exception{
+ allGroups.addAll(elements(GroupDef.class));
+ allDefs.addAll(elements(EntityDef.class));
+ allInterfaces.addAll(types(EntityInterface.class));
+
+ //round 1: generate component interfaces
+ if(round == 1){
+ serializer = TypeIOResolver.resolve(this);
+ baseComponents = types(BaseComponent.class);
+ Array allComponents = types(Component.class);
+
+ //store code
+ for(Stype component : allComponents){
+ for(Svar f : component.fields()){
+ VariableTree tree = f.tree();
+
+ //add initializer if it exists
+ if(tree.getInitializer() != null){
+ String init = tree.getInitializer().toString();
+ varInitializers.put(f, init);
+ }
+ }
+
+ for(Smethod elem : component.methods()){
+ if(elem.is(Modifier.ABSTRACT) || elem.is(Modifier.NATIVE)) continue;
+ //get all statements in the method, store them
+ methodBlocks.put(elem, elem.tree().getBody().toString());
+ }
+ }
+
+ //store components
+ for(Stype type : allComponents){
+ componentNames.put(type.name(), type);
+ }
+
+ //add component imports
+ for(Stype comp : allComponents){
+ imports.addAll(getImports(comp.e));
+ }
+
+ //create component interfaces
+ for(Stype component : allComponents){
+ TypeSpec.Builder inter = TypeSpec.interfaceBuilder(interfaceName(component))
+ .addModifiers(Modifier.PUBLIC).addAnnotation(EntityInterface.class);
+
+ //implement extra interfaces these components may have, e.g. position
+ for(Stype extraInterface : component.interfaces().select(i -> !isCompInterface(i))){
+ //javapoet completely chokes on this if I add `addSuperInterface` or create the type name with TypeName.get
+ inter.superinterfaces.add(tname(extraInterface.fullName()));
+ }
+
+ //implement super interfaces
+ Array depends = getDependencies(component);
+ for(Stype type : depends){
+ inter.addSuperinterface(ClassName.get(packageName, interfaceName(type)));
+ }
+
+ ObjectSet signatures = new ObjectSet<>();
+
+ //add utility methods to interface
+ for(Smethod method : component.methods()){
+ //skip private methods, those are for internal use.
+ if(method.isAny(Modifier.PRIVATE, Modifier.STATIC)) continue;
+
+ //keep track of signatures used to prevent dupes
+ signatures.add(method.e.toString());
+
+ inter.addMethod(MethodSpec.methodBuilder(method.name())
+ .addExceptions(method.thrownt())
+ .addTypeVariables(method.typeVariables().map(TypeVariableName::get))
+ .returns(method.ret().toString().equals("void") ? TypeName.VOID : method.retn())
+ .addParameters(method.params().map(v -> ParameterSpec.builder(v.tname(), v.name())
+ .build())).addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT).build());
+ }
+
+ for(Svar field : component.fields().select(e -> !e.is(Modifier.STATIC) && !e.is(Modifier.PRIVATE) && !e.has(Import.class))){
+ String cname = field.name();
+
+ //getter
+ if(!signatures.contains(cname + "()")){
+ inter.addMethod(MethodSpec.methodBuilder(cname).addModifiers(Modifier.ABSTRACT, Modifier.PUBLIC)
+ .addAnnotations(Array.with(field.annotations()).select(a -> a.toString().contains("Null")).map(AnnotationSpec::get))
+ .returns(field.tname()).build());
+ }
+
+ //setter
+ if(!field.is(Modifier.FINAL) && !signatures.contains(cname + "(" + field.mirror().toString() + ")") &&
+ !field.annotations().contains(f -> f.toString().equals("@mindustry.annotations.Annotations.ReadOnly"))){
+ inter.addMethod(MethodSpec.methodBuilder(cname).addModifiers(Modifier.ABSTRACT, Modifier.PUBLIC)
+ .addParameter(ParameterSpec.builder(field.tname(), field.name())
+ .addAnnotations(Array.with(field.annotations())
+ .select(a -> a.toString().contains("Null")).map(AnnotationSpec::get)).build()).build());
+ }
+ }
+
+ write(inter);
+
+ //LOGGING
+
+ Log.debug("&gGenerating interface for " + component.name());
+
+ for(TypeName tn : inter.superinterfaces){
+ Log.debug("&g> &lbextends {0}", simpleName(tn.toString()));
+ }
+
+ //log methods generated
+ for(MethodSpec spec : inter.methodSpecs){
+ Log.debug("&g> > &c{0} {1}({2})", simpleName(spec.returnType.toString()), spec.name, Array.with(spec.parameters).toString(", ", p -> simpleName(p.type.toString()) + " " + p.name));
+ }
+
+ Log.debug("");
+ }
+
+ //generate special render layer interfaces
+ for(DrawLayer layer : DrawLayer.values()){
+ //create the DrawLayer interface that entities need to implement
+ String name = "DrawLayer" + Strings.capitalize(layer.name()) + "c";
+ TypeSpec.Builder inter = TypeSpec.interfaceBuilder(name)
+ .addSuperinterface(tname(packageName + ".Entityc"))
+ .addSuperinterface(tname(packageName + ".Drawc"))
+ .addModifiers(Modifier.PUBLIC).addAnnotation(EntityInterface.class);
+ inter.addMethod(MethodSpec.methodBuilder("draw" + Strings.capitalize(layer.name())).addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT).build());
+ write(inter);
+ }
+ }else if(round == 2){ //round 2: get component classes and generate interfaces for them
+
+ //parse groups
+ for(Selement> group : allGroups){
+ GroupDef an = group.annotation(GroupDef.class);
+ Array types = types(an, GroupDef::value).map(this::interfaceToComp);
+ Array collides = types(an, GroupDef::collide);
+ groupDefs.add(new GroupDefinition(group.name(), ClassName.bestGuess(packageName + "." + interfaceName(types.first())), types, an.spatial(), an.mapping(), collides));
+ }
+
+ //add special generated groups
+ for(DrawLayer layer : DrawLayer.values()){
+ String name = "DrawLayer" + Strings.capitalize(layer.name()) + "c";
+ //create group definition with no components directly
+ GroupDefinition def = new GroupDefinition(layer.name(), ClassName.bestGuess(packageName + "." + name), Array.with(), false, false, new Array<>(0));
+ //add manual inclusions of entities to be added to this group
+ def.manualInclusions.addAll(allDefs.select(s -> allComponents(s).contains(comp -> comp.interfaces().contains(in -> in.name().equals(name)))));
+ groupDefs.add(def);
+ }
+
+ ObjectMap usedNames = new ObjectMap<>();
+ ObjectMap> extraNames = new ObjectMap<>();
+
+ //look at each definition
+ for(Selement> type : allDefs){
+ EntityDef ann = type.annotation(EntityDef.class);
+ boolean isFinal = ann.isFinal();
+
+ if(type.isType() && (!type.name().endsWith("Def") && !type.name().endsWith("Comp"))){
+ err("All entity def names must end with 'Def'/'Comp'", type.e);
+ }
+
+ String name = type.isType() ?
+ type.name().replace("Def", "Entity").replace("Comp", "Entity") :
+ createName(type);
+
+ //skip double classes
+ if(usedNames.containsKey(name)){
+ extraNames.getOr(usedNames.get(name), ObjectSet::new).add(type.name());
+ continue;
+ }
+
+ usedNames.put(name, type);
+ extraNames.getOr(type, ObjectSet::new).add(name);
+ if(!type.isType()){
+ extraNames.getOr(type, ObjectSet::new).add(type.name());
+ }
+
+ TypeSpec.Builder builder = TypeSpec.classBuilder(name).addModifiers(Modifier.PUBLIC);
+ if(isFinal) builder.addModifiers(Modifier.FINAL);
+
+ Array components = allComponents(type);
+ Array groups = groupDefs.select(g -> (!g.components.isEmpty() && !g.components.contains(s -> !components.contains(s))) || g.manualInclusions.contains(type));
+ ObjectMap> methods = new ObjectMap<>();
+ ObjectMap specVariables = new ObjectMap<>();
+ ObjectSet usedFields = new ObjectSet<>();
+
+ //add serialize() boolean
+ builder.addMethod(MethodSpec.methodBuilder("serialize").addModifiers(Modifier.PUBLIC, Modifier.FINAL).returns(boolean.class).addStatement("return " + ann.serialize()).build());
+
+ //add all components
+ for(Stype comp : components){
+
+ //write fields to the class; ignoring transient ones
+ Array fields = comp.fields().select(f -> !f.has(Import.class));
+ for(Svar f : fields){
+ if(!usedFields.add(f.name())){
+ err("Field '" + f.name() + "' of component '" + comp.name() + "' re-defines a field in entity '" + type.name() + "'");
+ continue;
+ }
+
+ FieldSpec.Builder fbuilder = FieldSpec.builder(f.tname(), f.name());
+ //keep statics/finals
+ if(f.is(Modifier.STATIC)){
+ fbuilder.addModifiers(Modifier.STATIC);
+ if(f.is(Modifier.FINAL)) fbuilder.addModifiers(Modifier.FINAL);
+ }
+ //add transient modifier for serialization
+ if(f.is(Modifier.TRANSIENT)){
+ fbuilder.addModifiers(Modifier.TRANSIENT);
+ }
+ //add initializer if it exists
+ if(varInitializers.containsKey(f)){
+ fbuilder.initializer(varInitializers.get(f));
+ }
+
+ if(!isFinal) fbuilder.addModifiers(Modifier.PROTECTED);
+ fbuilder.addAnnotations(f.annotations().map(AnnotationSpec::get));
+ builder.addField(fbuilder.build());
+ specVariables.put(builder.fieldSpecs.get(builder.fieldSpecs.size() - 1), f);
+ }
+
+ //get all utility methods from components
+ for(Smethod elem : comp.methods()){
+ methods.getOr(elem.toString(), Array::new).add(elem);
+ }
+ }
+
+ //override toString method
+ builder.addMethod(MethodSpec.methodBuilder("toString")
+ .addAnnotation(Override.class)
+ .returns(String.class)
+ .addModifiers(Modifier.PUBLIC)
+ .addStatement("return $S + $L", name + "#", "id").build());
+
+ EntityIO io = new EntityIO(type.name(), builder, serializer, rootDirectory.child("annotations/src/main/resources/revisions").child(name));
+
+ //add all methods from components
+ for(ObjectMap.Entry> entry : methods){
+ if(entry.value.contains(m -> m.has(Replace.class))){
+ //check replacements
+ if(entry.value.count(m -> m.has(Replace.class)) > 1){
+ err("Type " + type + " has multiple components replacing method " + entry.key + ".");
+ }
+ Smethod base = entry.value.find(m -> m.has(Replace.class));
+ entry.value.clear();
+ entry.value.add(base);
+ }
+
+ //check multi return
+ if(entry.value.count(m -> !m.isAny(Modifier.NATIVE, Modifier.ABSTRACT) && !m.isVoid()) > 1){
+ err("Type " + type + " has multiple components implementing non-void method " + entry.key + ".");
+ }
+
+ entry.value.sort(Structs.comps(Structs.comparingFloat(m -> m.has(MethodPriority.class) ? m.annotation(MethodPriority.class).value() : 0), Structs.comparing(Selement::name)));
+
+ //representative method
+ Smethod first = entry.value.first();
+
+ //skip internal impl
+ if(first.has(InternalImpl.class)){
+ continue;
+ }
+
+ //build method using same params/returns
+ MethodSpec.Builder mbuilder = MethodSpec.methodBuilder(first.name()).addModifiers(first.is(Modifier.PRIVATE) ? Modifier.PRIVATE : Modifier.PUBLIC);
+ if(isFinal) mbuilder.addModifiers(Modifier.FINAL);
+ if(first.is(Modifier.STATIC)) mbuilder.addModifiers(Modifier.STATIC);
+ mbuilder.addTypeVariables(first.typeVariables().map(TypeVariableName::get));
+ mbuilder.returns(first.retn());
+ mbuilder.addExceptions(first.thrownt());
+
+ for(Svar var : first.params()){
+ mbuilder.addParameter(var.tname(), var.name());
+ }
+
+ //only write the block if it's a void method with several entries
+ boolean writeBlock = first.ret().toString().equals("void") && entry.value.size > 1;
+
+ if((entry.value.first().is(Modifier.ABSTRACT) || entry.value.first().is(Modifier.NATIVE)) && entry.value.size == 1 && !entry.value.first().has(InternalImpl.class)){
+ err(entry.value.first().up().getSimpleName() + "#" + entry.value.first() + " is an abstract method and must be implemented in some component", type);
+ }
+
+ //SPECIAL CASE: inject group add/remove code
+ if(first.name().equals("add") || first.name().equals("remove")){
+ mbuilder.addStatement("if(added == $L) return", first.name().equals("add"));
+
+ for(GroupDefinition def : groups){
+ //remove/add from each group, assume imported
+ mbuilder.addStatement("Groups.$L.$L(this)", def.name, first.name());
+ }
+ }
+
+ //SPECIAL CASE: I/O code
+ //note that serialization is generated even for non-serializing entities for manual usage
+ if((first.name().equals("read") || first.name().equals("write")) && ann.genio()){
+ io.write(mbuilder, first.name().equals("write"));
+ }
+
+ for(Smethod elem : entry.value){
+ if(elem.is(Modifier.ABSTRACT) || elem.is(Modifier.NATIVE) || !methodBlocks.containsKey(elem)) continue;
+
+ //get all statements in the method, copy them over
+ String str = methodBlocks.get(elem);
+ //name for code blocks in the methods
+ String blockName = elem.up().getSimpleName().toString().toLowerCase().replace("comp", "");
+
+ //skip empty blocks
+ if(str.replace("{", "").replace("\n", "").replace("}", "").replace("\t", "").replace(" ", "").isEmpty()){
+ continue;
+ }
+
+ //wrap scope to prevent variable leakage
+ if(writeBlock){
+ //replace return; with block break
+ str = str.replace("return;", "break " + blockName + ";");
+ mbuilder.addCode(blockName + ": {\n");
+ }
+
+ //trim block
+ str = str.substring(2, str.length() - 1);
+
+ //make sure to remove braces here
+ mbuilder.addCode(str);
+
+ //end scope
+ if(writeBlock) mbuilder.addCode("}\n");
+ }
+
+ //add free code to remove methods - always at the end
+ //this only gets called next frame.
+ if(first.name().equals("remove") && ann.pooled()){
+ mbuilder.addStatement("$T.app.post(() -> $T.free(this))", Core.class, Pools.class);
+ }
+
+ builder.addMethod(mbuilder.build());
+ }
+
+ //add pool reset method and implement Poolable
+ if(ann.pooled()){
+ builder.addSuperinterface(Poolable.class);
+ //implement reset()
+ MethodSpec.Builder resetBuilder = MethodSpec.methodBuilder("reset").addModifiers(Modifier.PUBLIC);
+ for(FieldSpec spec : builder.fieldSpecs){
+ Svar variable = specVariables.get(spec);
+ if(variable.isAny(Modifier.STATIC, Modifier.FINAL)) continue;
+
+ if(spec.type.isPrimitive()){
+ //set to primitive default
+ resetBuilder.addStatement("$L = $L", spec.name, varInitializers.containsKey(variable) ? varInitializers.get(variable) : getDefault(spec.type.toString()));
+ }else{
+ //set to default null
+ if(!varInitializers.containsKey(variable)){
+ resetBuilder.addStatement("$L = null", spec.name);
+ } //else... TODO reset if poolable
+ }
+ }
+
+ builder.addMethod(resetBuilder.build());
+ }
+
+ //make constructor private
+ builder.addMethod(MethodSpec.constructorBuilder().addModifiers(Modifier.PROTECTED).build());
+
+ //add create() method
+ builder.addMethod(MethodSpec.methodBuilder("create").addModifiers(Modifier.PUBLIC, Modifier.STATIC)
+ .returns(tname(packageName + "." + name))
+ .addStatement(ann.pooled() ? "return Pools.obtain($L.class, " +name +"::new)" : "return new $L()", name).build());
+
+ definitions.add(new EntityDefinition(packageName + "." + name, builder, type, components, groups));
+ }
+
+ //generate groups
+ TypeSpec.Builder groupsBuilder = TypeSpec.classBuilder("Groups").addModifiers(Modifier.PUBLIC);
+ MethodSpec.Builder groupInit = MethodSpec.methodBuilder("init").addModifiers(Modifier.PUBLIC, Modifier.STATIC);
+ for(GroupDefinition group : groupDefs){
+ //Stype ctype = group.components.first();
+ //class names for interface/group
+ ClassName itype = group.baseType;
+ ClassName groupc = ClassName.bestGuess("mindustry.entities.EntityGroup");
+
+ //add field...
+ groupsBuilder.addField(ParameterizedTypeName.get(
+ ClassName.bestGuess("mindustry.entities.EntityGroup"), itype), group.name, Modifier.PUBLIC, Modifier.STATIC);
+
+ groupInit.addStatement("$L = new $T<>($L.class, $L, $L)", group.name, groupc, itype, group.spatial, group.mapping);
+ }
+
+ //write the groups
+ groupsBuilder.addMethod(groupInit.build());
+
+ //add method for resizing all necessary groups
+ MethodSpec.Builder groupResize = MethodSpec.methodBuilder("resize")
+ .addParameter(TypeName.FLOAT, "x").addParameter(TypeName.FLOAT, "y").addParameter(TypeName.FLOAT, "w").addParameter(TypeName.FLOAT, "h")
+ .addModifiers(Modifier.PUBLIC, Modifier.STATIC);
+
+ MethodSpec.Builder groupUpdate = MethodSpec.methodBuilder("update")
+ .addModifiers(Modifier.PUBLIC, Modifier.STATIC);
+
+ //method resize
+ for(GroupDefinition group : groupDefs){
+ if(group.spatial){
+ groupResize.addStatement("$L.resize(x, y, w, h)", group.name);
+ groupUpdate.addStatement("$L.updatePhysics()", group.name);
+ }
+ }
+
+ groupUpdate.addStatement("all.update()");
+
+ for(GroupDefinition group : groupDefs){
+ for(Stype collide : group.collides){
+ groupUpdate.addStatement("$L.collide($L)", group.name, collide.name());
+ }
+ }
+
+ for(DrawLayer layer : DrawLayer.values()){
+ MethodSpec.Builder groupDraw = MethodSpec.methodBuilder("draw" + Strings.capitalize(layer.name()))
+ .addModifiers(Modifier.PUBLIC, Modifier.STATIC);
+ groupDraw.addStatement("$L.draw($L::$L)", layer.name(), "DrawLayer" + Strings.capitalize(layer.name()) + "c", "draw" + Strings.capitalize(layer.name()));
+ groupsBuilder.addMethod(groupDraw.build());
+ }
+
+ groupsBuilder.addMethod(groupResize.build());
+ groupsBuilder.addMethod(groupUpdate.build());
+
+ write(groupsBuilder);
+
+ //load map of sync IDs
+ StringMap map = new StringMap();
+ Fi idProps = rootDirectory.child("annotations/src/main/resources/classids.properties");
+ if(!idProps.exists()) idProps.writeString("");
+ PropertiesUtils.load(map, idProps.reader());
+ //next ID to be used in generation
+ Integer max = map.values().toArray().map(Integer::parseInt).max(i -> i);
+ int maxID = max == null ? 0 : max + 1;
+
+ //assign IDs
+ definitions.sort(Structs.comparing(t -> t.base.toString()));
+ for(EntityDefinition def : definitions){
+ String name = def.base.fullName();
+ if(map.containsKey(name)){
+ def.classID = map.getInt(name);
+ }else{
+ def.classID = maxID++;
+ map.put(name, def.classID + "");
+ }
+ }
+
+ OrderedMap res = new OrderedMap<>();
+ res.putAll(map);
+ res.orderedKeys().sort();
+
+ //write assigned IDs
+ PropertiesUtils.store(res, idProps.writer(false), "Maps entity names to IDs. Autogenerated.");
+
+ //build mapping class for sync IDs
+ TypeSpec.Builder idBuilder = TypeSpec.classBuilder("EntityMapping").addModifiers(Modifier.PUBLIC)
+ .addField(FieldSpec.builder(TypeName.get(Prov[].class), "idMap", Modifier.PRIVATE, Modifier.STATIC).initializer("new Prov[256]").build())
+ .addField(FieldSpec.builder(ParameterizedTypeName.get(ClassName.get(ObjectMap.class),
+ tname(String.class), tname(Prov.class)),
+ "nameMap", Modifier.PRIVATE, Modifier.STATIC).initializer("new ObjectMap<>()").build())
+ .addMethod(MethodSpec.methodBuilder("map").addModifiers(Modifier.PUBLIC, Modifier.STATIC)
+ .returns(TypeName.get(Prov.class)).addParameter(int.class, "id").addStatement("return idMap[id]").build())
+ .addMethod(MethodSpec.methodBuilder("map").addModifiers(Modifier.PUBLIC, Modifier.STATIC)
+ .returns(TypeName.get(Prov.class)).addParameter(String.class, "name").addStatement("return nameMap.get(name)").build());
+
+ CodeBlock.Builder idStore = CodeBlock.builder();
+
+ //store the mappings
+ for(EntityDefinition def : definitions){
+ //store mapping
+ idStore.addStatement("idMap[$L] = $L::new", def.classID, def.name);
+ extraNames.get(def.base).each(extra -> {
+ idStore.addStatement("nameMap.put($S, $L::new)", extra, def.name);
+ });
+
+ //return mapping
+ def.builder.addMethod(MethodSpec.methodBuilder("classId").addAnnotation(Override.class)
+ .returns(int.class).addModifiers(Modifier.PUBLIC).addStatement("return " + def.classID).build());
+ }
+
+
+ idBuilder.addStaticBlock(idStore.build());
+
+ write(idBuilder);
+ }else{
+ //round 3: generate actual classes and implement interfaces
+
+ //implement each definition
+ for(EntityDefinition def : definitions){
+
+ //get interface for each component
+ for(Stype comp : def.components){
+
+ //implement the interface
+ Stype inter = allInterfaces.find(i -> i.name().equals(interfaceName(comp)));
+ if(inter == null){
+ err("Failed to generate interface for", comp);
+ return;
+ }
+
+ def.builder.addSuperinterface(inter.tname());
+
+ //generate getter/setter for each method
+ for(Smethod method : inter.methods()){
+ String var = method.name();
+ FieldSpec field = Array.with(def.builder.fieldSpecs).find(f -> f.name.equals(var));
+ //make sure it's a real variable AND that the component doesn't already implement it with custom logic
+ if(field == null || comp.methods().contains(m -> m.simpleString().equals(method.simpleString()))) continue;
+
+ //getter
+ if(!method.isVoid()){
+ def.builder.addMethod(MethodSpec.overriding(method.e).addStatement("return " + var).addModifiers(Modifier.FINAL).build());
+ }
+
+ //setter
+ if(method.isVoid() && !Array.with(field.annotations).contains(f -> f.type.toString().equals("@mindustry.annotations.Annotations.ReadOnly"))){
+ def.builder.addMethod(MethodSpec.overriding(method.e).addModifiers(Modifier.FINAL).addStatement("this." + var + " = " + var).build());
+ }
+ }
+ }
+
+ write(def.builder, imports.asArray());
+ }
+
+ //store nulls
+ TypeSpec.Builder nullsBuilder = TypeSpec.classBuilder("Nulls").addModifiers(Modifier.PUBLIC).addModifiers(Modifier.FINAL);
+
+ //create mock types of all components
+ for(Stype interf : allInterfaces){
+ //indirect interfaces to implement methods for
+ Array dependencies = interf.allInterfaces().and(interf);
+ Array methods = dependencies.flatMap(Stype::methods);
+ methods.sortComparing(Object::toString);
+
+ //used method signatures
+ ObjectSet signatures = new ObjectSet<>();
+
+ //create null builder
+ String baseName = interf.name().substring(0, interf.name().length() - 1);
+ String className = "Null" + baseName;
+ TypeSpec.Builder nullBuilder = TypeSpec.classBuilder(className)
+ .addModifiers(Modifier.FINAL);
+
+ nullBuilder.addSuperinterface(interf.tname());
+
+ for(Smethod method : methods){
+ String signature = method.toString();
+ if(signatures.contains(signature)) continue;
+
+ Stype compType = interfaceToComp(method.type());
+ MethodSpec.Builder builder = MethodSpec.overriding(method.e).addModifiers(Modifier.PUBLIC, Modifier.FINAL);
+
+ if(!method.isVoid()){
+ if(method.name().equals("isNull")){
+ builder.addStatement("return true");
+ }else if(method.name().equals("id")){
+ builder.addStatement("return -1");
+ }else{
+ Svar variable = compType == null || method.params().size > 0 ? null : compType.fields().find(v -> v.name().equals(method.name()));
+ if(variable == null || !varInitializers.containsKey(variable)){
+ builder.addStatement("return " + getDefault(method.ret().toString()));
+ }else{
+ String init = varInitializers.get(variable);
+ builder.addStatement("return " + (init.equals("{}") ? "new " + variable.mirror().toString() : "") + init);
+ }
+ }
+ }
+
+ nullBuilder.addMethod(builder.build());
+
+ signatures.add(signature);
+ }
+
+ nullsBuilder.addField(FieldSpec.builder(interf.cname(), Strings.camelize(baseName)).initializer("new " + className + "()").addModifiers(Modifier.FINAL, Modifier.STATIC, Modifier.PUBLIC).build());
+
+ write(nullBuilder);
+ }
+
+ write(nullsBuilder);
+ }
+ }
+
+ Array getImports(Element elem){
+ return Array.with(trees.getPath(elem).getCompilationUnit().getImports()).map(Object::toString);
+ }
+
+ /** @return interface for a component type */
+ String interfaceName(Stype comp){
+ String suffix = "Comp";
+ if(!comp.name().endsWith(suffix)){
+ err("All components must have names that end with 'Comp'", comp.e);
+ }
+ return comp.name().substring(0, comp.name().length() - suffix.length()) + "c";
+ }
+
+ /** @return all components that a entity def has */
+ Array allComponents(Selement> type){
+ if(!defComponents.containsKey(type)){
+ //get base defs
+ Array components = types(type.annotation(EntityDef.class), EntityDef::value).map(this::interfaceToComp);
+ ObjectSet out = new ObjectSet<>();
+ for(Stype comp : components){
+ //get dependencies for each def, add them
+ out.add(comp);
+ out.addAll(getDependencies(comp));
+ }
+
+ defComponents.put(type, out.asArray());
+ }
+
+ return defComponents.get(type);
+ }
+
+ Array getDependencies(Stype component){
+ if(!componentDependencies.containsKey(component)){
+ ObjectSet out = new ObjectSet<>();
+ //add base component interfaces
+ out.addAll(component.interfaces().select(this::isCompInterface).map(this::interfaceToComp));
+ //remove self interface
+ out.remove(component);
+
+ //out now contains the base dependencies; finish constructing the tree
+ ObjectSet result = new ObjectSet<>();
+ for(Stype type : out){
+ result.add(type);
+ result.addAll(getDependencies(type));
+ }
+
+ if(component.annotation(BaseComponent.class) == null){
+ result.addAll(baseComponents);
+ }
+
+ //remove it again just in case
+ out.remove(component);
+ componentDependencies.put(component, result.asArray());
+ }
+
+ return componentDependencies.get(component);
+ }
+
+ boolean isCompInterface(Stype type){
+ return interfaceToComp(type) != null;
+ }
+
+ Stype interfaceToComp(Stype type){
+ String name = type.name().substring(0, type.name().length() - 1) + "Comp";
+ return componentNames.get(name);
+ }
+
+ String createName(Selement> elem){
+ Array comps = types(elem.annotation(EntityDef.class), EntityDef::value).map(this::interfaceToComp);;
+ comps.sortComparing(Selement::name);
+ return comps.toString("", s -> s.name().replace("Comp", "")) + "Entity";
+ }
+
+ boolean isComponent(Stype type){
+ return type.annotation(Component.class) != null;
+ }
+
+ Array types(T t, Cons consumer){
+ try{
+ consumer.get(t);
+ }catch(MirroredTypesException e){
+ return Array.with(e.getTypeMirrors()).map(Stype::of);
+ }
+ throw new IllegalArgumentException("Missing types.");
+ }
+
+ class GroupDefinition{
+ final String name;
+ final ClassName baseType;
+ final Array components;
+ final Array collides;
+ final boolean spatial, mapping;
+ final ObjectSet manualInclusions = new ObjectSet<>();
+
+ public GroupDefinition(String name, ClassName bestType, Array components, boolean spatial, boolean mapping, Array collides){
+ this.baseType = bestType;
+ this.components = components;
+ this.name = name;
+ this.spatial = spatial;
+ this.mapping = mapping;
+ this.collides = collides;
+ }
+
+ @Override
+ public String toString(){
+ return name;
+ }
+ }
+
+ class EntityDefinition{
+ final Array groups;
+ final Array components;
+ final TypeSpec.Builder builder;
+ final Selement base;
+ final String name;
+ int classID;
+
+ public EntityDefinition(String name, Builder builder, Selement base, Array components, Array groups){
+ this.builder = builder;
+ this.name = name;
+ this.base = base;
+ this.groups = groups;
+ this.components = components;
+ }
+
+ @Override
+ public String toString(){
+ return "Definition{" +
+ "groups=" + groups +
+ "components=" + components +
+ ", base=" + base +
+ '}';
+ }
+ }
+}
diff --git a/annotations/src/main/java/mindustry/annotations/impl/AssetsProcess.java b/annotations/src/main/java/mindustry/annotations/impl/AssetsProcess.java
index 2f2234027c..fc83ce3e3b 100644
--- a/annotations/src/main/java/mindustry/annotations/impl/AssetsProcess.java
+++ b/annotations/src/main/java/mindustry/annotations/impl/AssetsProcess.java
@@ -5,29 +5,21 @@ import arc.scene.style.*;
import arc.struct.*;
import arc.util.serialization.*;
import com.squareup.javapoet.*;
-import mindustry.annotations.*;
import mindustry.annotations.Annotations.*;
+import mindustry.annotations.*;
import javax.annotation.processing.*;
import javax.lang.model.*;
import javax.lang.model.element.*;
-import javax.tools.Diagnostic.*;
-import javax.tools.*;
import java.util.*;
@SupportedAnnotationTypes("mindustry.annotations.Annotations.StyleDefaults")
public class AssetsProcess extends BaseProcessor{
- private String path;
@Override
public void process(RoundEnvironment env) throws Exception{
- path = Fi.get(BaseProcessor.filer.createResource(StandardLocation.CLASS_OUTPUT, "no", "no")
- .toUri().toURL().toString().substring(System.getProperty("os.name").contains("Windows") ? 6 : "file:".length()))
- .parent().parent().parent().parent().parent().parent().toString();
- path = path.replace("%20", " ");
-
- processSounds("Sounds", path + "/assets/sounds", "arc.audio.Sound");
- processSounds("Musics", path + "/assets/music", "arc.audio.Music");
+ processSounds("Sounds", rootDirectory + "/core/assets/sounds", "arc.audio.Sound");
+ processSounds("Musics", rootDirectory + "/core/assets/music", "arc.audio.Music");
processUI(env.getElementsAnnotatedWith(StyleDefaults.class));
}
@@ -38,8 +30,8 @@ public class AssetsProcess extends BaseProcessor{
MethodSpec.Builder load = MethodSpec.methodBuilder("load").addModifiers(Modifier.PUBLIC, Modifier.STATIC);
MethodSpec.Builder loadStyles = MethodSpec.methodBuilder("loadStyles").addModifiers(Modifier.PUBLIC, Modifier.STATIC);
MethodSpec.Builder icload = MethodSpec.methodBuilder("load").addModifiers(Modifier.PUBLIC, Modifier.STATIC);
- String resources = path + "/assets-raw/sprites/ui";
- Jval icons = Jval.read(Fi.get(path + "/assets-raw/fontgen/config.json").readString());
+ String resources = rootDirectory + "/core/assets-raw/sprites/ui";
+ Jval icons = Jval.read(Fi.get(rootDirectory + "/core/assets-raw/fontgen/config.json").readString());
ictype.addField(FieldSpec.builder(ParameterizedTypeName.get(ObjectMap.class, String.class, TextureRegionDrawable.class),
"icons", Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL).initializer("new ObjectMap<>()").build());
@@ -105,7 +97,7 @@ public class AssetsProcess extends BaseProcessor{
String name = p.nameWithoutExtension();
if(names.contains(name)){
- BaseProcessor.messager.printMessage(Kind.ERROR, "Duplicate file name: " + p.toString() + "!");
+ BaseProcessor.err("Duplicate file name: " + p.toString() + "!");
}else{
names.add(name);
}
diff --git a/annotations/src/main/java/mindustry/annotations/impl/StructProcess.java b/annotations/src/main/java/mindustry/annotations/impl/StructProcess.java
index b27871d63d..7eadedb856 100644
--- a/annotations/src/main/java/mindustry/annotations/impl/StructProcess.java
+++ b/annotations/src/main/java/mindustry/annotations/impl/StructProcess.java
@@ -29,7 +29,7 @@ public class StructProcess extends BaseProcessor{
for(TypeElement elem : elements){
if(!elem.getSimpleName().toString().endsWith("Struct")){
- BaseProcessor.messager.printMessage(Kind.ERROR, "All classes annotated with @Struct must have their class names end in 'Struct'.", elem);
+ BaseProcessor.err("All classes annotated with @Struct must have their class names end in 'Struct'.", elem);
continue;
}
@@ -45,7 +45,7 @@ public class StructProcess extends BaseProcessor{
int structTotalSize = (structSize <= 8 ? 8 : structSize <= 16 ? 16 : structSize <= 32 ? 32 : 64);
if(variables.size() == 0){
- BaseProcessor.messager.printMessage(Kind.ERROR, "making a struct with no fields is utterly pointles.", elem);
+ BaseProcessor.err("making a struct with no fields is utterly pointles.", elem);
continue;
}
@@ -133,7 +133,7 @@ public class StructProcess extends BaseProcessor{
JavaFile.builder(packageName, classBuilder.build()).build().writeTo(BaseProcessor.filer);
}catch(IllegalArgumentException e){
e.printStackTrace();
- BaseProcessor.messager.printMessage(Kind.ERROR, e.getMessage(), elem);
+ BaseProcessor.err(e.getMessage(), elem);
}
}
diff --git a/annotations/src/main/java/mindustry/annotations/remote/IOFinder.java b/annotations/src/main/java/mindustry/annotations/remote/IOFinder.java
deleted file mode 100644
index 16384f241a..0000000000
--- a/annotations/src/main/java/mindustry/annotations/remote/IOFinder.java
+++ /dev/null
@@ -1,91 +0,0 @@
-package mindustry.annotations.remote;
-
-import mindustry.annotations.*;
-import mindustry.annotations.Annotations.ReadClass;
-import mindustry.annotations.Annotations.WriteClass;
-
-import javax.annotation.processing.RoundEnvironment;
-import javax.lang.model.element.Element;
-import javax.lang.model.type.MirroredTypeException;
-import javax.tools.Diagnostic.Kind;
-import java.util.HashMap;
-import java.util.Set;
-
-/**
- * This class finds reader and writer methods annotated by the {@link WriteClass}
- * and {@link ReadClass} annotations.
- */
-public class IOFinder{
-
- /**
- * Finds all class serializers for all types and returns them. Logs errors when necessary.
- * Maps fully qualified class names to their serializers.
- */
- public HashMap findSerializers(RoundEnvironment env){
- HashMap result = new HashMap<>();
-
- //get methods with the types
- Set extends Element> writers = env.getElementsAnnotatedWith(WriteClass.class);
- Set extends Element> readers = env.getElementsAnnotatedWith(ReadClass.class);
-
- //look for writers first
- for(Element writer : writers){
- WriteClass writean = writer.getAnnotation(WriteClass.class);
- String typeName = getValue(writean);
-
- //make sure there's only one read method
- if(readers.stream().filter(elem -> getValue(elem.getAnnotation(ReadClass.class)).equals(typeName)).count() > 1){
- BaseProcessor.messager.printMessage(Kind.ERROR, "Multiple writer methods for type '" + typeName + "'", writer);
- }
-
- //make sure there's only one write method
- long count = readers.stream().filter(elem -> getValue(elem.getAnnotation(ReadClass.class)).equals(typeName)).count();
- if(count == 0){
- BaseProcessor.messager.printMessage(Kind.ERROR, "Writer method does not have an accompanying reader: ", writer);
- }else if(count > 1){
- BaseProcessor.messager.printMessage(Kind.ERROR, "Writer method has multiple reader for type: ", writer);
- }
-
- Element reader = readers.stream().filter(elem -> getValue(elem.getAnnotation(ReadClass.class)).equals(typeName)).findFirst().get();
-
- //add to result list
- result.put(typeName, new ClassSerializer(BaseProcessor.getMethodName(reader), BaseProcessor.getMethodName(writer), typeName));
- }
-
- return result;
- }
-
- private String getValue(WriteClass write){
- try{
- Class> type = write.value();
- return type.getName();
- }catch(MirroredTypeException e){
- return e.getTypeMirror().toString();
- }
- }
-
- private String getValue(ReadClass read){
- try{
- Class> type = read.value();
- return type.getName();
- }catch(MirroredTypeException e){
- return e.getTypeMirror().toString();
- }
- }
-
- /** Information about read/write methods for a specific class type. */
- public static class ClassSerializer{
- /** Fully qualified method name of the reader. */
- public final String readMethod;
- /** Fully qualified method name of the writer. */
- public final String writeMethod;
- /** Fully qualified class type name. */
- public final String classType;
-
- public ClassSerializer(String readMethod, String writeMethod, String classType){
- this.readMethod = readMethod;
- this.writeMethod = writeMethod;
- this.classType = classType;
- }
- }
-}
diff --git a/annotations/src/main/java/mindustry/annotations/remote/RemoteProcess.java b/annotations/src/main/java/mindustry/annotations/remote/RemoteProcess.java
index 8abd0b82b8..9a00d12bfe 100644
--- a/annotations/src/main/java/mindustry/annotations/remote/RemoteProcess.java
+++ b/annotations/src/main/java/mindustry/annotations/remote/RemoteProcess.java
@@ -3,11 +3,11 @@ package mindustry.annotations.remote;
import com.squareup.javapoet.*;
import mindustry.annotations.*;
import mindustry.annotations.Annotations.*;
-import mindustry.annotations.remote.IOFinder.*;
+import mindustry.annotations.util.*;
+import mindustry.annotations.util.TypeIOResolver.*;
import javax.annotation.processing.*;
import javax.lang.model.element.*;
-import javax.tools.Diagnostic.*;
import java.util.*;
import java.util.stream.*;
@@ -15,8 +15,7 @@ import java.util.stream.*;
/** The annotation processor for generating remote method call code. */
@SupportedAnnotationTypes({
"mindustry.annotations.Annotations.Remote",
-"mindustry.annotations.Annotations.WriteClass",
-"mindustry.annotations.Annotations.ReadClass",
+"mindustry.annotations.Annotations.TypeIOHandler"
})
public class RemoteProcess extends BaseProcessor{
/** Maximum size of each event packet. */
@@ -32,7 +31,7 @@ public class RemoteProcess extends BaseProcessor{
private static final String callLocation = "Call";
//class serializers
- private HashMap serializers;
+ private ClassSerializer serializer;
//all elements with the Remote annotation
private Set extends Element> elements;
//map of all classes to generate by name
@@ -51,7 +50,7 @@ public class RemoteProcess extends BaseProcessor{
//round 1: find all annotations, generate *writers*
if(round == 1){
//get serializers
- serializers = new IOFinder().findSerializers(roundEnv);
+ serializer = TypeIOResolver.resolve(this);
//last method ID used
int lastMethodID = 0;
//find all elements with the Remote annotation
@@ -72,12 +71,12 @@ public class RemoteProcess extends BaseProcessor{
//check for static
if(!element.getModifiers().contains(Modifier.STATIC) || !element.getModifiers().contains(Modifier.PUBLIC)){
- BaseProcessor.messager.printMessage(Kind.ERROR, "All @Remote methods must be public and static: ", element);
+ err("All @Remote methods must be public and static: ", element);
}
//can't generate none methods
if(annotation.targets() == Loc.none){
- BaseProcessor.messager.printMessage(Kind.ERROR, "A @Remote method's targets() cannot be equal to 'none':", element);
+ err("A @Remote method's targets() cannot be equal to 'none':", element);
}
//get and create class entry if needed
@@ -98,12 +97,12 @@ public class RemoteProcess extends BaseProcessor{
}
//create read/write generators
- RemoteWriteGenerator writegen = new RemoteWriteGenerator(serializers);
+ RemoteWriteGenerator writegen = new RemoteWriteGenerator(serializer);
//generate the methods to invoke (write)
writegen.generateFor(classes, packageName);
}else if(round == 2){ //round 2: generate all *readers*
- RemoteReadGenerator readgen = new RemoteReadGenerator(serializers);
+ RemoteReadGenerator readgen = new RemoteReadGenerator(serializer);
//generate server readers
readgen.generateFor(methods.stream().filter(method -> method.where.isClient).collect(Collectors.toList()), readServerName, packageName, true);
diff --git a/annotations/src/main/java/mindustry/annotations/remote/RemoteReadGenerator.java b/annotations/src/main/java/mindustry/annotations/remote/RemoteReadGenerator.java
index 211d807067..2c228e5a9e 100644
--- a/annotations/src/main/java/mindustry/annotations/remote/RemoteReadGenerator.java
+++ b/annotations/src/main/java/mindustry/annotations/remote/RemoteReadGenerator.java
@@ -1,24 +1,21 @@
package mindustry.annotations.remote;
+import arc.util.io.*;
import com.squareup.javapoet.*;
import mindustry.annotations.*;
-import mindustry.annotations.remote.IOFinder.ClassSerializer;
+import mindustry.annotations.util.TypeIOResolver.*;
+import javax.lang.model.element.Modifier;
import javax.lang.model.element.*;
-import javax.tools.Diagnostic.Kind;
-import java.io.IOException;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.nio.ByteBuffer;
-import java.util.HashMap;
-import java.util.List;
+import java.lang.reflect.*;
+import java.util.*;
/** Generates code for reading remote invoke packets on the client and server. */
public class RemoteReadGenerator{
- private final HashMap serializers;
+ private final ClassSerializer serializers;
/** Creates a read generator that uses the supplied serializer setup. */
- public RemoteReadGenerator(HashMap serializers){
+ public RemoteReadGenerator(ClassSerializer serializers){
this.serializers = serializers;
}
@@ -29,8 +26,7 @@ public class RemoteReadGenerator{
* @param packageName Full target package name.
* @param needsPlayer Whether this read method requires a reference to the player sender.
*/
- public void generateFor(List entries, String className, String packageName, boolean needsPlayer)
- throws IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchMethodException, IOException{
+ public void generateFor(List entries, String className, String packageName, boolean needsPlayer) throws Exception{
TypeSpec.Builder classBuilder = TypeSpec.classBuilder(className).addModifiers(Modifier.PUBLIC);
classBuilder.addJavadoc(RemoteProcess.autogenWarning);
@@ -38,7 +34,7 @@ public class RemoteReadGenerator{
//create main method builder
MethodSpec.Builder readMethod = MethodSpec.methodBuilder("readPacket")
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
- .addParameter(ByteBuffer.class, "buffer") //buffer to read form
+ .addParameter(Reads.class, "read") //buffer to read form
.addParameter(int.class, "id") //ID of method type to read
.returns(void.class);
@@ -48,7 +44,7 @@ public class RemoteReadGenerator{
Constructor cons = TypeName.class.getDeclaredConstructor(String.class);
cons.setAccessible(true);
- TypeName playerType = cons.newInstance("mindustry.entities.type.Player");
+ TypeName playerType = cons.newInstance("mindustry.gen.Playerc");
//add player parameter
readMethod.addParameter(playerType, "player");
}
@@ -80,26 +76,22 @@ public class RemoteReadGenerator{
//name of parameter
String varName = var.getSimpleName().toString();
//captialized version of type name for reading primitives
- String capName = typeName.equals("byte") ? "" : Character.toUpperCase(typeName.charAt(0)) + typeName.substring(1);
+ String pname = typeName.equals("boolean") ? "bool" : typeName.charAt(0) + "";
//write primitives automatically
if(BaseProcessor.isPrimitive(typeName)){
- if(typeName.equals("boolean")){
- readBlock.addStatement("boolean " + varName + " = buffer.get() == 1");
- }else{
- readBlock.addStatement(typeName + " " + varName + " = buffer.get" + capName + "()");
- }
+ readBlock.addStatement("$L $L = read.$L()", typeName, varName, pname);
}else{
//else, try and find a serializer
- ClassSerializer ser = serializers.get(typeName);
+ String ser = serializers.readers.get(typeName, SerializerResolver.locate(entry.element, var.asType(), false));
if(ser == null){ //make sure a serializer exists!
- BaseProcessor.messager.printMessage(Kind.ERROR, "No @ReadClass method to read class type: '" + typeName + "'", var);
+ BaseProcessor.err("No read method to read class type '" + typeName + "' in method " + entry.targetMethod + "; " + serializers.readers, var);
return;
}
//add statement for reading it
- readBlock.addStatement(typeName + " " + varName + " = " + ser.readMethod + "(buffer)");
+ readBlock.addStatement(typeName + " " + varName + " = " + ser + "(read)");
}
//append variable name to string builder
@@ -119,7 +111,7 @@ public class RemoteReadGenerator{
if(entry.forward && entry.where.isServer && needsPlayer){
//call forwarded method
readBlock.addStatement(packageName + "." + entry.className + "." + entry.element.getSimpleName() +
- "__forward(player.con" + (varResult.length() == 0 ? "" : ", ") + varResult.toString() + ")");
+ "__forward(player.con()" + (varResult.length() == 0 ? "" : ", ") + varResult.toString() + ")");
}
readBlock.nextControlFlow("catch (java.lang.Exception e)");
diff --git a/annotations/src/main/java/mindustry/annotations/remote/RemoteWriteGenerator.java b/annotations/src/main/java/mindustry/annotations/remote/RemoteWriteGenerator.java
index 10d822dd59..df6e5afcdb 100644
--- a/annotations/src/main/java/mindustry/annotations/remote/RemoteWriteGenerator.java
+++ b/annotations/src/main/java/mindustry/annotations/remote/RemoteWriteGenerator.java
@@ -1,23 +1,22 @@
package mindustry.annotations.remote;
+import arc.struct.*;
+import arc.util.io.*;
import com.squareup.javapoet.*;
+import mindustry.annotations.Annotations.*;
import mindustry.annotations.*;
-import mindustry.annotations.Annotations.Loc;
-import mindustry.annotations.remote.IOFinder.ClassSerializer;
+import mindustry.annotations.util.TypeIOResolver.*;
import javax.lang.model.element.*;
-import javax.tools.Diagnostic.Kind;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.HashMap;
-import java.util.List;
+import java.io.*;
+import java.util.*;
/** Generates code for writing remote invoke packets on the client and server. */
public class RemoteWriteGenerator{
- private final HashMap serializers;
+ private final ClassSerializer serializers;
/** Creates a write generator that uses the supplied serializer setup. */
- public RemoteWriteGenerator(HashMap serializers){
+ public RemoteWriteGenerator(ClassSerializer serializers){
this.serializers = serializers;
}
@@ -30,8 +29,12 @@ public class RemoteWriteGenerator{
classBuilder.addJavadoc(RemoteProcess.autogenWarning);
//add temporary write buffer
- classBuilder.addField(FieldSpec.builder(ByteBuffer.class, "TEMP_BUFFER", Modifier.STATIC, Modifier.PRIVATE, Modifier.FINAL)
- .initializer("ByteBuffer.allocate($1L)", RemoteProcess.maxPacketSize).build());
+ classBuilder.addField(FieldSpec.builder(ReusableByteOutStream.class, "OUT", Modifier.STATIC, Modifier.PRIVATE, Modifier.FINAL)
+ .initializer("new ReusableByteOutStream($L)", RemoteProcess.maxPacketSize).build());
+
+ //add writer for that buffer
+ classBuilder.addField(FieldSpec.builder(Writes.class, "WRITE", Modifier.STATIC, Modifier.PRIVATE, Modifier.FINAL)
+ .initializer("new Writes(new $T(OUT))", DataOutputStream.class).build());
//go through each method entry in this class
for(MethodEntry methodEntry : entry.methods){
@@ -74,12 +77,12 @@ public class RemoteWriteGenerator{
//validate client methods to make sure
if(methodEntry.where.isClient){
if(elem.getParameters().isEmpty()){
- BaseProcessor.messager.printMessage(Kind.ERROR, "Client invoke methods must have a first parameter of type Player.", elem);
+ BaseProcessor.err("Client invoke methods must have a first parameter of type Player", elem);
return;
}
- if(!elem.getParameters().get(0).asType().toString().equals("mindustry.entities.type.Player")){
- BaseProcessor.messager.printMessage(Kind.ERROR, "Client invoke methods should have a first parameter of type Player.", elem);
+ if(!elem.getParameters().get(0).asType().toString().equals("Playerc")){
+ BaseProcessor.err("Client invoke methods should have a first parameter of type Playerc", elem);
return;
}
}
@@ -129,14 +132,14 @@ public class RemoteWriteGenerator{
//add statement to create packet from pool
method.addStatement("$1N packet = $2N.obtain($1N.class, $1N::new)", "mindustry.net.Packets.InvokePacket", "arc.util.pooling.Pools");
- //assign buffer
- method.addStatement("packet.writeBuffer = TEMP_BUFFER");
//assign priority
method.addStatement("packet.priority = (byte)" + methodEntry.priority.ordinal());
//assign method ID
method.addStatement("packet.type = (byte)" + methodEntry.id);
- //rewind buffer
- method.addStatement("TEMP_BUFFER.position(0)");
+ //reset stream
+ method.addStatement("OUT.reset()");
+
+ method.addTypeVariables(Array.with(elem.getTypeParameters()).map(BaseProcessor::getTVN));
for(int i = 0; i < elem.getParameters().size(); i++){
//first argument is skipped as it is always the player caller
@@ -146,8 +149,12 @@ public class RemoteWriteGenerator{
VariableElement var = elem.getParameters().get(i);
- //add parameter to method
- method.addParameter(TypeName.get(var.asType()), var.getSimpleName().toString());
+ try{
+ //add parameter to method
+ method.addParameter(TypeName.get(var.asType()), var.getSimpleName().toString());
+ }catch(Throwable t){
+ throw new RuntimeException("Error parsing method " + methodEntry.targetMethod);
+ }
//name of parameter
String varName = var.getSimpleName().toString();
@@ -164,23 +171,18 @@ public class RemoteWriteGenerator{
}
if(BaseProcessor.isPrimitive(typeName)){ //check if it's a primitive, and if so write it
- if(typeName.equals("boolean")){ //booleans are special
- method.addStatement("TEMP_BUFFER.put(" + varName + " ? (byte)1 : 0)");
- }else{
- method.addStatement("TEMP_BUFFER.put" +
- capName + "(" + varName + ")");
- }
+ method.addStatement("WRITE.$L($L)", typeName.equals("boolean") ? "bool" : typeName.charAt(0) + "", varName);
}else{
//else, try and find a serializer
- ClassSerializer ser = serializers.get(typeName);
+ String ser = serializers.writers.get(typeName, SerializerResolver.locate(elem, var.asType(), true));
if(ser == null){ //make sure a serializer exists!
- BaseProcessor.messager.printMessage(Kind.ERROR, "No @WriteClass method to write class type: '" + typeName + "'", var);
+ BaseProcessor.err("No @WriteClass method to write class type: '" + typeName + "'", var);
return;
}
//add statement for writing it
- method.addStatement(ser.writeMethod + "(TEMP_BUFFER, " + varName + ")");
+ method.addStatement(ser + "(WRITE, " + varName + ")");
}
if(writePlayerSkipCheck){ //write end check
@@ -188,8 +190,10 @@ public class RemoteWriteGenerator{
}
}
+ //assign packet bytes
+ method.addStatement("packet.bytes = OUT.getBytes()");
//assign packet length
- method.addStatement("packet.writeLength = TEMP_BUFFER.position()");
+ method.addStatement("packet.length = OUT.size()");
String sendString;
diff --git a/annotations/src/main/java/mindustry/annotations/remote/SerializerResolver.java b/annotations/src/main/java/mindustry/annotations/remote/SerializerResolver.java
new file mode 100644
index 0000000000..6431bfea49
--- /dev/null
+++ b/annotations/src/main/java/mindustry/annotations/remote/SerializerResolver.java
@@ -0,0 +1,22 @@
+package mindustry.annotations.remote;
+
+import arc.struct.*;
+
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+
+public class SerializerResolver{
+
+ public static String locate(ExecutableElement elem, TypeMirror mirror, boolean write){
+ //generic type
+ if((mirror.toString().equals("T") && Array.with(elem.getTypeParameters().get(0).getBounds()).contains(SerializerResolver::isEntity)) ||
+ isEntity(mirror)){
+ return write ? "mindustry.io.TypeIO.writeEntity" : "mindustry.io.TypeIO.readEntity";
+ }
+ return null;
+ }
+
+ private static boolean isEntity(TypeMirror mirror){
+ return !mirror.toString().contains(".") && mirror.toString().endsWith("c");
+ }
+}
diff --git a/annotations/src/main/java/mindustry/annotations/util/AnnotationProxyMaker.java b/annotations/src/main/java/mindustry/annotations/util/AnnotationProxyMaker.java
new file mode 100644
index 0000000000..352c684e74
--- /dev/null
+++ b/annotations/src/main/java/mindustry/annotations/util/AnnotationProxyMaker.java
@@ -0,0 +1,287 @@
+package mindustry.annotations.util;
+
+import com.sun.tools.javac.code.*;
+import com.sun.tools.javac.code.Attribute.Array;
+import com.sun.tools.javac.code.Attribute.Enum;
+import com.sun.tools.javac.code.Attribute.Error;
+import com.sun.tools.javac.code.Attribute.Visitor;
+import com.sun.tools.javac.code.Attribute.*;
+import com.sun.tools.javac.code.Type;
+import com.sun.tools.javac.code.Symbol.*;
+import com.sun.tools.javac.code.Type.ArrayType;
+import com.sun.tools.javac.util.List;
+import com.sun.tools.javac.util.*;
+import sun.reflect.annotation.*;
+
+import javax.lang.model.type.*;
+import java.io.*;
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.Map.*;
+import java.lang.Class;
+
+//replaces the standard Java AnnotationProxyMaker with one that doesn't crash
+//thanks, oracle.
+@SuppressWarnings({"sunapi", "unchecked"})
+public class AnnotationProxyMaker{
+ private final Compound anno;
+ private final Class extends Annotation> annoType;
+
+ private AnnotationProxyMaker(Compound var1, Class extends Annotation> var2){
+ this.anno = var1;
+ this.annoType = var2;
+ }
+
+ public static A generateAnnotation(Compound var0, Class var1){
+ AnnotationProxyMaker var2 = new AnnotationProxyMaker(var0, var1);
+ return (A)var1.cast(var2.generateAnnotation());
+ }
+
+ private Annotation generateAnnotation(){
+ return AnnotationParser.annotationForMap(this.annoType, this.getAllReflectedValues());
+ }
+
+ private Map getAllReflectedValues(){
+ LinkedHashMap var1 = new LinkedHashMap();
+ Iterator var2 = this.getAllValues().entrySet().iterator();
+
+ while(var2.hasNext()){
+ Entry var3 = (Entry)var2.next();
+ MethodSymbol var4 = (MethodSymbol)var3.getKey();
+ Object var5 = this.generateValue(var4, (Attribute)var3.getValue());
+ if(var5 != null){
+ var1.put(var4.name.toString(), var5);
+ }
+ }
+
+ return var1;
+ }
+
+ private Map getAllValues(){
+ LinkedHashMap var1 = new LinkedHashMap();
+ ClassSymbol var2 = (ClassSymbol)this.anno.type.tsym;
+
+ for(com.sun.tools.javac.code.Scope.Entry var3 = var2.members().elems; var3 != null; var3 = var3.sibling){
+ if(var3.sym.kind == 16){
+ MethodSymbol var4 = (MethodSymbol)var3.sym;
+ Attribute var5 = var4.getDefaultValue();
+ if(var5 != null){
+ var1.put(var4, var5);
+ }
+ }
+ }
+
+ Iterator var6 = this.anno.values.iterator();
+
+ while(var6.hasNext()){
+ Pair var7 = (Pair)var6.next();
+ var1.put(var7.fst, var7.snd);
+ }
+
+ return var1;
+ }
+
+ private Object generateValue(MethodSymbol var1, Attribute var2){
+ AnnotationProxyMaker.ValueVisitor var3 = new AnnotationProxyMaker.ValueVisitor(var1);
+ return var3.getValue(var2);
+ }
+
+ private static final class MirroredTypesExceptionProxy extends ExceptionProxy{
+ static final long serialVersionUID = 269L;
+ private transient List types;
+ private final String typeStrings;
+
+ MirroredTypesExceptionProxy(List var1){
+ this.types = var1;
+ this.typeStrings = var1.toString();
+ }
+
+ public String toString(){
+ return this.typeStrings;
+ }
+
+ public int hashCode(){
+ return (this.types != null ? this.types : this.typeStrings).hashCode();
+ }
+
+ public boolean equals(Object var1){
+ return this.types != null && var1 instanceof AnnotationProxyMaker.MirroredTypesExceptionProxy && this.types.equals(((AnnotationProxyMaker.MirroredTypesExceptionProxy)var1).types);
+ }
+
+ protected RuntimeException generateException(){
+ return new MirroredTypesException(this.types);
+ }
+
+ private void readObject(ObjectInputStream var1) throws IOException, ClassNotFoundException{
+ var1.defaultReadObject();
+ this.types = null;
+ }
+ }
+
+ private static final class MirroredTypeExceptionProxy extends ExceptionProxy{
+ static final long serialVersionUID = 269L;
+ private transient TypeMirror type;
+ private final String typeString;
+
+ MirroredTypeExceptionProxy(TypeMirror var1){
+ this.type = var1;
+ this.typeString = var1.toString();
+ }
+
+ public String toString(){
+ return this.typeString;
+ }
+
+ public int hashCode(){
+ return (this.type != null ? this.type : this.typeString).hashCode();
+ }
+
+ public boolean equals(Object var1){
+ return this.type != null && var1 instanceof AnnotationProxyMaker.MirroredTypeExceptionProxy && this.type.equals(((AnnotationProxyMaker.MirroredTypeExceptionProxy)var1).type);
+ }
+
+ protected RuntimeException generateException(){
+ return new MirroredTypeException(this.type);
+ }
+
+ private void readObject(ObjectInputStream var1) throws IOException, ClassNotFoundException{
+ var1.defaultReadObject();
+ this.type = null;
+ }
+ }
+
+ private class ValueVisitor implements Visitor{
+ private MethodSymbol meth;
+ private Class> returnClass;
+ private Object value;
+
+ ValueVisitor(MethodSymbol var2){
+ this.meth = var2;
+ }
+
+ Object getValue(Attribute var1){
+ Method var2;
+ try{
+ var2 = AnnotationProxyMaker.this.annoType.getMethod(this.meth.name.toString());
+ }catch(NoSuchMethodException var4){
+ return null;
+ }
+
+ this.returnClass = var2.getReturnType();
+ var1.accept(this);
+ if(!(this.value instanceof ExceptionProxy) && !AnnotationType.invocationHandlerReturnType(this.returnClass).isInstance(this.value)){
+ this.typeMismatch(var2, var1);
+ }
+
+ return this.value;
+ }
+
+ public void visitConstant(Constant var1){
+ this.value = var1.getValue();
+ }
+
+ public void visitClass(com.sun.tools.javac.code.Attribute.Class var1){
+ this.value = new AnnotationProxyMaker.MirroredTypeExceptionProxy(var1.classType);
+ }
+
+ public void visitArray(Array var1){
+ Name var2 = ((ArrayType)var1.type).elemtype.tsym.getQualifiedName();
+ int var6;
+ if(var2.equals(var2.table.names.java_lang_Class)){
+ ListBuffer var14 = new ListBuffer();
+ Attribute[] var15 = var1.values;
+ int var16 = var15.length;
+
+ for(var6 = 0; var6 < var16; ++var6){
+ Attribute var7 = var15[var6];
+ Type var8 = var7 instanceof UnresolvedClass ? ((UnresolvedClass)var7).classType : ((com.sun.tools.javac.code.Attribute.Class)var7).classType;
+ var14.append(var8);
+ }
+
+ this.value = new AnnotationProxyMaker.MirroredTypesExceptionProxy(var14.toList());
+ }else{
+ int var3 = var1.values.length;
+ Class var4 = this.returnClass;
+ this.returnClass = this.returnClass.getComponentType();
+
+ try{
+ Object var5 = java.lang.reflect.Array.newInstance(this.returnClass, var3);
+
+ for(var6 = 0; var6 < var3; ++var6){
+ var1.values[var6].accept(this);
+ if(this.value == null || this.value instanceof ExceptionProxy){
+ return;
+ }
+
+ try{
+ java.lang.reflect.Array.set(var5, var6, this.value);
+ }catch(IllegalArgumentException var12){
+ this.value = null;
+ return;
+ }
+ }
+
+ this.value = var5;
+ }finally{
+ this.returnClass = var4;
+ }
+ }
+ }
+
+ public void visitEnum(Enum var1){
+ if(this.returnClass.isEnum()){
+ String var2 = var1.value.toString();
+
+ try{
+ this.value = java.lang.Enum.valueOf((Class)this.returnClass, var2);
+ }catch(IllegalArgumentException var4){
+ this.value = new EnumConstantNotPresentExceptionProxy((Class)this.returnClass, var2);
+ }
+ }else{
+ this.value = null;
+ }
+
+ }
+
+ public void visitCompound(Compound var1){
+ try{
+ Class var2 = this.returnClass.asSubclass(Annotation.class);
+ this.value = AnnotationProxyMaker.generateAnnotation(var1, var2);
+ }catch(ClassCastException var3){
+ this.value = null;
+ }
+
+ }
+
+ public void visitError(Error var1){
+ if(var1 instanceof UnresolvedClass){
+ this.value = new AnnotationProxyMaker.MirroredTypeExceptionProxy(((UnresolvedClass)var1).classType);
+ }else{
+ this.value = null;
+ }
+
+ }
+
+ private void typeMismatch(Method var1, final Attribute var2){
+ class AnnotationTypeMismatchExceptionProxy extends ExceptionProxy{
+ static final long serialVersionUID = 269L;
+ final transient Method method;
+
+ AnnotationTypeMismatchExceptionProxy(Method var2x){
+ this.method = var2x;
+ }
+
+ public String toString(){
+ return "";
+ }
+
+ protected RuntimeException generateException(){
+ return new AnnotationTypeMismatchException(this.method, var2.type.toString());
+ }
+ }
+
+ this.value = new AnnotationTypeMismatchExceptionProxy(var1);
+ }
+ }
+}
diff --git a/annotations/src/main/java/mindustry/annotations/util/Selement.java b/annotations/src/main/java/mindustry/annotations/util/Selement.java
index d7e458a20e..def6b001e9 100644
--- a/annotations/src/main/java/mindustry/annotations/util/Selement.java
+++ b/annotations/src/main/java/mindustry/annotations/util/Selement.java
@@ -1,10 +1,15 @@
package mindustry.annotations.util;
+import arc.struct.Array;
import com.squareup.javapoet.*;
+import com.sun.tools.javac.code.Attribute.*;
import mindustry.annotations.*;
import javax.lang.model.element.*;
import javax.lang.model.type.*;
+import java.lang.Class;
+import java.lang.annotation.*;
+import java.lang.reflect.*;
public class Selement{
public final T e;
@@ -13,6 +18,57 @@ public class Selement{
this.e = e;
}
+ public Array> enclosed(){
+ return Array.with(e.getEnclosedElements()).map(Selement::new);
+ }
+
+ public String fullName(){
+ return e.toString();
+ }
+
+ public Stype asType(){
+ return new Stype((TypeElement)e);
+ }
+
+ public Svar asVar(){
+ return new Svar((VariableElement)e);
+ }
+
+ public Smethod asMethod(){
+ return new Smethod((ExecutableElement)e);
+ }
+
+ public boolean isVar(){
+ return e instanceof VariableElement;
+ }
+
+ public boolean isType(){
+ return e instanceof TypeElement;
+ }
+
+ public boolean isMethod(){
+ return e instanceof ExecutableElement;
+ }
+
+ public Array extends AnnotationMirror> annotations(){
+ return Array.with(e.getAnnotationMirrors());
+ }
+
+ public A annotation(Class annotation){
+ try{
+ Method m = com.sun.tools.javac.code.AnnoConstruct.class.getDeclaredMethod("getAttribute", Class.class);
+ m.setAccessible(true);
+ Compound compound = (Compound)m.invoke(e, annotation);
+ return compound == null ? null : AnnotationProxyMaker.generateAnnotation(compound, annotation);
+ }catch(Exception e){
+ throw new RuntimeException(e);
+ }
+ }
+
+ public boolean has(Class annotation){
+ return annotation(annotation) != null;
+ }
+
public Element up(){
return e.getEnclosingElement();
}
@@ -45,6 +101,6 @@ public class Selement{
@Override
public boolean equals(Object o){
- return o != null && o.getClass() == getClass() && ((Selement)o).e.equals(e);
+ return o != null && o.getClass() == getClass() && e == ((Selement)o).e;
}
}
diff --git a/annotations/src/main/java/mindustry/annotations/util/Smethod.java b/annotations/src/main/java/mindustry/annotations/util/Smethod.java
index b9687dd728..9eedb5bb7e 100644
--- a/annotations/src/main/java/mindustry/annotations/util/Smethod.java
+++ b/annotations/src/main/java/mindustry/annotations/util/Smethod.java
@@ -14,10 +14,21 @@ public class Smethod extends Selement{
super(executableElement);
}
+ public boolean isAny(Modifier... mod){
+ for(Modifier m : mod){
+ if(is(m)) return true;
+ }
+ return false;
+ }
+
public boolean is(Modifier mod){
return e.getModifiers().contains(mod);
}
+ public Stype type(){
+ return new Stype((TypeElement)up());
+ }
+
public Array thrown(){
return Array.with(e.getThrownTypes()).as(TypeMirror.class);
}
@@ -34,6 +45,10 @@ public class Smethod extends Selement{
return Array.with(e.getParameters()).map(Svar::new);
}
+ public boolean isVoid(){
+ return ret().toString().equals("void");
+ }
+
public TypeMirror ret(){
return e.getReturnType();
}
@@ -45,4 +60,8 @@ public class Smethod extends Selement{
public MethodTree tree(){
return BaseProcessor.trees.getTree(e);
}
+
+ public String simpleString(){
+ return name() + "(" + params().toString(", ", p -> BaseProcessor.simpleName(p.mirror().toString())) + ")";
+ }
}
diff --git a/annotations/src/main/java/mindustry/annotations/util/Stype.java b/annotations/src/main/java/mindustry/annotations/util/Stype.java
index 99b9b9f781..2582ae2fbb 100644
--- a/annotations/src/main/java/mindustry/annotations/util/Stype.java
+++ b/annotations/src/main/java/mindustry/annotations/util/Stype.java
@@ -5,7 +5,6 @@ import mindustry.annotations.*;
import javax.lang.model.element.*;
import javax.lang.model.type.*;
-import java.lang.annotation.*;
public class Stype extends Selement{
@@ -17,28 +16,30 @@ public class Stype extends Selement{
return new Stype((TypeElement)BaseProcessor.typeu.asElement(mirror));
}
+ public String fullName(){
+ return mirror().toString();
+ }
+
public Array interfaces(){
return Array.with(e.getInterfaces()).map(Stype::of);
}
+ public Array allInterfaces(){
+ return interfaces().flatMap(s -> s.allInterfaces().and(s)).distinct();
+ }
+
public Array superclasses(){
- Array out = new Array<>();
- Stype sup = superclass();
- while(!sup.name().equals("Object")){
- out.add(sup);
- sup = sup.superclass();
- }
- return out;
+ return Array.with(BaseProcessor.typeu.directSupertypes(mirror())).map(Stype::of);
+ }
+
+ public Array allSuperclasses(){
+ return superclasses().flatMap(s -> s.allSuperclasses().and(s)).distinct();
}
public Stype superclass(){
return new Stype((TypeElement)BaseProcessor.typeu.asElement(BaseProcessor.typeu.directSupertypes(mirror()).get(0)));
}
- public A annotation(Class annotation){
- return e.getAnnotation(annotation);
- }
-
public Array fields(){
return Array.with(e.getEnclosedElements()).select(e -> e instanceof VariableElement).map(e -> new Svar((VariableElement)e));
}
diff --git a/annotations/src/main/java/mindustry/annotations/util/Svar.java b/annotations/src/main/java/mindustry/annotations/util/Svar.java
index cf58d7a6f5..6f307e8bc9 100644
--- a/annotations/src/main/java/mindustry/annotations/util/Svar.java
+++ b/annotations/src/main/java/mindustry/annotations/util/Svar.java
@@ -11,6 +11,13 @@ public class Svar extends Selement{
super(e);
}
+ public boolean isAny(Modifier... mods){
+ for(Modifier m : mods){
+ if(is(m)) return true;
+ }
+ return false;
+ }
+
public boolean is(Modifier mod){
return e.getModifiers().contains(mod);
}
diff --git a/annotations/src/main/java/mindustry/annotations/util/TypeIOResolver.java b/annotations/src/main/java/mindustry/annotations/util/TypeIOResolver.java
new file mode 100644
index 0000000000..d0359ba51c
--- /dev/null
+++ b/annotations/src/main/java/mindustry/annotations/util/TypeIOResolver.java
@@ -0,0 +1,53 @@
+package mindustry.annotations.util;
+
+import arc.struct.*;
+import mindustry.annotations.Annotations.*;
+import mindustry.annotations.*;
+
+import javax.lang.model.element.*;
+
+/**
+ * This class finds reader and writer methods.
+ */
+public class TypeIOResolver{
+
+ /**
+ * Finds all class serializers for all types and returns them. Logs errors when necessary.
+ * Maps fully qualified class names to their serializers.
+ */
+ public static ClassSerializer resolve(BaseProcessor processor){
+ ClassSerializer out = new ClassSerializer(new ObjectMap<>(), new ObjectMap<>());
+ for(Stype type : processor.types(TypeIOHandler.class)){
+ //look at all TypeIOHandler methods
+ Array methods = type.methods();
+ for(Smethod meth : methods){
+ if(meth.is(Modifier.PUBLIC) && meth.is(Modifier.STATIC)){
+ Array params = meth.params();
+ //2 params, second one is type, first is writer
+ if(params.size == 2 && params.first().tname().toString().equals("arc.util.io.Writes")){
+ out.writers.put(params.get(1).tname().toString(), type.fullName() + "." + meth.name());
+ }else if(params.size == 1 && params.first().tname().toString().equals("arc.util.io.Reads") && !meth.isVoid()){
+ //1 param, one is reader, returns type
+ out.readers.put(meth.retn().toString(), type.fullName() + "." + meth.name());
+ }
+ }
+ }
+ }
+
+ return out;
+ }
+
+ /** Information about read/write methods for class types. */
+ public static class ClassSerializer{
+ public final ObjectMap writers, readers;
+
+ public ClassSerializer(ObjectMap writers, ObjectMap readers){
+ this.writers = writers;
+ this.readers = readers;
+ }
+
+ public boolean has(String type){
+ return writers.containsKey(type) && readers.containsKey(type);
+ }
+ }
+}
diff --git a/annotations/src/main/resources/classids.properties b/annotations/src/main/resources/classids.properties
new file mode 100644
index 0000000000..ed82e2bef1
--- /dev/null
+++ b/annotations/src/main/resources/classids.properties
@@ -0,0 +1,17 @@
+#Maps entity names to IDs. Autogenerated.
+
+dagger=0
+draug=10
+mindustry.entities.def.BulletComp=1
+mindustry.entities.def.DecalComp=2
+mindustry.entities.def.FireComp=3
+mindustry.entities.def.GroundEffectComp=4
+mindustry.entities.def.PlayerComp=5
+mindustry.entities.def.PuddleComp=6
+mindustry.entities.def.StandardEffectComp=7
+mindustry.entities.def.TileComp=8
+mindustry.type.Weather.WeatherComp=13
+phantom=11
+spirit=12
+vanguard=9
+wraith=14
\ No newline at end of file
diff --git a/annotations/src/main/resources/revisions/BuilderUnitEntity/0.json b/annotations/src/main/resources/revisions/BuilderUnitEntity/0.json
new file mode 100644
index 0000000000..a3e717b9b7
--- /dev/null
+++ b/annotations/src/main/resources/revisions/BuilderUnitEntity/0.json
@@ -0,0 +1 @@
+{fields:[{name:drownTime,type:float,size:4},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:rotation,type:float,size:4},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
\ No newline at end of file
diff --git a/annotations/src/main/resources/revisions/BulletEntity/0.json b/annotations/src/main/resources/revisions/BulletEntity/0.json
new file mode 100644
index 0000000000..576dffb934
--- /dev/null
+++ b/annotations/src/main/resources/revisions/BulletEntity/0.json
@@ -0,0 +1 @@
+{fields:[{name:damage,type:float,size:4},{name:data,type:java.lang.Object,size:-1},{name:lifetime,type:float,size:4},{name:team,type:mindustry.game.Team,size:-1},{name:time,type:float,size:4},{name:type,type:mindustry.entities.bullet.BulletType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
\ No newline at end of file
diff --git a/annotations/src/main/resources/revisions/DecalEntity/0.json b/annotations/src/main/resources/revisions/DecalEntity/0.json
new file mode 100644
index 0000000000..b8d564d18c
--- /dev/null
+++ b/annotations/src/main/resources/revisions/DecalEntity/0.json
@@ -0,0 +1 @@
+{fields:[{name:color,type:arc.graphics.Color,size:-1},{name:lifetime,type:float,size:4},{name:rotation,type:float,size:4},{name:time,type:float,size:4},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
\ No newline at end of file
diff --git a/annotations/src/main/resources/revisions/FireEntity/0.json b/annotations/src/main/resources/revisions/FireEntity/0.json
new file mode 100644
index 0000000000..a5423a835b
--- /dev/null
+++ b/annotations/src/main/resources/revisions/FireEntity/0.json
@@ -0,0 +1 @@
+{fields:[{name:baseFlammability,type:float,size:4},{name:block,type:mindustry.world.Block,size:-1},{name:lifetime,type:float,size:4},{name:puddleFlammability,type:float,size:4},{name:tile,type:mindustry.world.Tile,size:-1},{name:time,type:float,size:4},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
\ No newline at end of file
diff --git a/annotations/src/main/resources/revisions/GroundEffectEntity/0.json b/annotations/src/main/resources/revisions/GroundEffectEntity/0.json
new file mode 100644
index 0000000000..4e23d76400
--- /dev/null
+++ b/annotations/src/main/resources/revisions/GroundEffectEntity/0.json
@@ -0,0 +1 @@
+{fields:[{name:color,type:arc.graphics.Color,size:-1},{name:data,type:java.lang.Object,size:-1},{name:lifetime,type:float,size:4},{name:offsetX,type:float,size:4},{name:offsetY,type:float,size:4},{name:rotation,type:float,size:4},{name:time,type:float,size:4},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
\ No newline at end of file
diff --git a/annotations/src/main/resources/revisions/LegsUnitEntity/0.json b/annotations/src/main/resources/revisions/LegsUnitEntity/0.json
new file mode 100644
index 0000000000..8946f13fa4
--- /dev/null
+++ b/annotations/src/main/resources/revisions/LegsUnitEntity/0.json
@@ -0,0 +1 @@
+{fields:[{name:baseRotation,type:float,size:4},{name:drownTime,type:float,size:4},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:rotation,type:float,size:4},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
\ No newline at end of file
diff --git a/annotations/src/main/resources/revisions/MinerUnitEntity/0.json b/annotations/src/main/resources/revisions/MinerUnitEntity/0.json
new file mode 100644
index 0000000000..d8ae40cd01
--- /dev/null
+++ b/annotations/src/main/resources/revisions/MinerUnitEntity/0.json
@@ -0,0 +1 @@
+{fields:[{name:drownTime,type:float,size:4},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:mineTile,type:mindustry.world.Tile,size:-1},{name:rotation,type:float,size:4},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
\ No newline at end of file
diff --git a/annotations/src/main/resources/revisions/PlayerEntity/0.json b/annotations/src/main/resources/revisions/PlayerEntity/0.json
new file mode 100644
index 0000000000..5b9d12787d
--- /dev/null
+++ b/annotations/src/main/resources/revisions/PlayerEntity/0.json
@@ -0,0 +1 @@
+{fields:[{name:admin,type:boolean,size:1},{name:color,type:arc.graphics.Color,size:-1},{name:lastText,type:java.lang.String,size:-1},{name:mouseX,type:float,size:4},{name:mouseY,type:float,size:4},{name:name,type:java.lang.String,size:-1},{name:team,type:mindustry.game.Team,size:-1},{name:textFadeTime,type:float,size:4},{name:typing,type:boolean,size:1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
\ No newline at end of file
diff --git a/annotations/src/main/resources/revisions/PuddleEntity/0.json b/annotations/src/main/resources/revisions/PuddleEntity/0.json
new file mode 100644
index 0000000000..09114ed8ea
--- /dev/null
+++ b/annotations/src/main/resources/revisions/PuddleEntity/0.json
@@ -0,0 +1 @@
+{fields:[{name:accepting,type:float,size:4},{name:amount,type:float,size:4},{name:generation,type:int,size:4},{name:lastRipple,type:float,size:4},{name:liquid,type:mindustry.type.Liquid,size:-1},{name:tile,type:mindustry.world.Tile,size:-1},{name:updateTime,type:float,size:4},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
\ No newline at end of file
diff --git a/annotations/src/main/resources/revisions/StandardEffectEntity/0.json b/annotations/src/main/resources/revisions/StandardEffectEntity/0.json
new file mode 100644
index 0000000000..4e23d76400
--- /dev/null
+++ b/annotations/src/main/resources/revisions/StandardEffectEntity/0.json
@@ -0,0 +1 @@
+{fields:[{name:color,type:arc.graphics.Color,size:-1},{name:data,type:java.lang.Object,size:-1},{name:lifetime,type:float,size:4},{name:offsetX,type:float,size:4},{name:offsetY,type:float,size:4},{name:rotation,type:float,size:4},{name:time,type:float,size:4},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
\ No newline at end of file
diff --git a/annotations/src/main/resources/revisions/TileEntity/0.json b/annotations/src/main/resources/revisions/TileEntity/0.json
new file mode 100644
index 0000000000..2e02b6b8d2
--- /dev/null
+++ b/annotations/src/main/resources/revisions/TileEntity/0.json
@@ -0,0 +1 @@
+{fields:[{name:health,type:float,size:4},{name:team,type:mindustry.game.Team,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
\ No newline at end of file
diff --git a/annotations/src/main/resources/revisions/UnitEntity/0.json b/annotations/src/main/resources/revisions/UnitEntity/0.json
new file mode 100644
index 0000000000..a3e717b9b7
--- /dev/null
+++ b/annotations/src/main/resources/revisions/UnitEntity/0.json
@@ -0,0 +1 @@
+{fields:[{name:drownTime,type:float,size:4},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:rotation,type:float,size:4},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
\ No newline at end of file
diff --git a/annotations/src/main/resources/revisions/UnitWaterMoveEntity/0.json b/annotations/src/main/resources/revisions/UnitWaterMoveEntity/0.json
new file mode 100644
index 0000000000..a3e717b9b7
--- /dev/null
+++ b/annotations/src/main/resources/revisions/UnitWaterMoveEntity/0.json
@@ -0,0 +1 @@
+{fields:[{name:drownTime,type:float,size:4},{name:elevation,type:float,size:4},{name:health,type:float,size:4},{name:rotation,type:float,size:4},{name:team,type:mindustry.game.Team,size:-1},{name:type,type:mindustry.type.UnitType,size:-1},{name:x,type:float,size:4},{name:y,type:float,size:4}]}
\ No newline at end of file
diff --git a/annotations/src/main/resources/revisions/WeatherEntity/0.json b/annotations/src/main/resources/revisions/WeatherEntity/0.json
new file mode 100644
index 0000000000..9a76fbe28e
--- /dev/null
+++ b/annotations/src/main/resources/revisions/WeatherEntity/0.json
@@ -0,0 +1 @@
+{fields:[{name:x,type:float,size:4},{name:y,type:float,size:4}]}
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 113ef06226..ac9cd0ffaf 100644
--- a/build.gradle
+++ b/build.gradle
@@ -163,6 +163,9 @@ allprojects{
project(":desktop"){
apply plugin: "java"
+ compileJava.options.fork = true
+ compileJava.options.compilerArgs += ["-XDignore.symbol.file"]
+
dependencies{
compile project(":core")
@@ -249,8 +252,10 @@ project(":core"){
compile "org.lz4:lz4-java:1.4.1"
compile arcModule("arc-core")
compile arcModule("extensions:freetype")
+ compile arcModule("extensions:g3d")
+ compile arcModule("extensions:fx")
compile arcModule("extensions:arcnet")
- compile "org.mozilla:rhino:1.7.11"
+ compile "org.mozilla:rhino-runtime:1.7.12"
if(localArc() && debugged()) compile arcModule("extensions:recorder")
compileOnly project(":annotations")
@@ -294,7 +299,7 @@ project(":tools"){
compile "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-desktop"
compile "org.reflections:reflections:0.9.12"
- compile arcModule("backends:backend-sdl")
+ compile arcModule("backends:backend-headless")
}
}
diff --git a/core/assets-raw/sprites/blocks/distribution/cross.png b/core/assets-raw/sprites/blocks/distribution/cross.png
new file mode 100644
index 0000000000..0d9dea8538
Binary files /dev/null and b/core/assets-raw/sprites/blocks/distribution/cross.png differ
diff --git a/core/assets-raw/sprites/blocks/distribution/mass-conveyor-edge.png b/core/assets-raw/sprites/blocks/distribution/mass-conveyor-edge.png
new file mode 100644
index 0000000000..5360903433
Binary files /dev/null and b/core/assets-raw/sprites/blocks/distribution/mass-conveyor-edge.png differ
diff --git a/core/assets-raw/sprites/blocks/distribution/mass-conveyor-top.png b/core/assets-raw/sprites/blocks/distribution/mass-conveyor-top.png
new file mode 100644
index 0000000000..8ecc636e9e
Binary files /dev/null and b/core/assets-raw/sprites/blocks/distribution/mass-conveyor-top.png differ
diff --git a/core/assets-raw/sprites/blocks/distribution/mass-conveyor.png b/core/assets-raw/sprites/blocks/distribution/mass-conveyor.png
new file mode 100644
index 0000000000..8615a84382
Binary files /dev/null and b/core/assets-raw/sprites/blocks/distribution/mass-conveyor.png differ
diff --git a/core/assets-raw/sprites/blocks/environment/cliff.png b/core/assets-raw/sprites/blocks/environment/cliff.png
new file mode 100644
index 0000000000..9d76c62084
Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/cliff.png differ
diff --git a/core/assets-raw/sprites/blocks/environment/deepwater.png b/core/assets-raw/sprites/blocks/environment/deepwater.png
index 200485d6ad..f441f06ff9 100644
Binary files a/core/assets-raw/sprites/blocks/environment/deepwater.png and b/core/assets-raw/sprites/blocks/environment/deepwater.png differ
diff --git a/core/assets-raw/sprites/blocks/environment/slag.png b/core/assets-raw/sprites/blocks/environment/slag.png
new file mode 100644
index 0000000000..1467a11fa5
Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/slag.png differ
diff --git a/core/assets-raw/sprites/blocks/environment/tainted-water.png b/core/assets-raw/sprites/blocks/environment/tainted-water.png
index 021c5ac7b6..330aca5f14 100644
Binary files a/core/assets-raw/sprites/blocks/environment/tainted-water.png and b/core/assets-raw/sprites/blocks/environment/tainted-water.png differ
diff --git a/core/assets-raw/sprites/blocks/environment/water.png b/core/assets-raw/sprites/blocks/environment/water.png
index 474987f0e9..cb56267f9d 100644
Binary files a/core/assets-raw/sprites/blocks/environment/water.png and b/core/assets-raw/sprites/blocks/environment/water.png differ
diff --git a/core/assets-raw/sprites/blocks/extra/rubble-3-1.png b/core/assets-raw/sprites/blocks/extra/rubble-3-1.png
deleted file mode 100644
index 83853df7a2..0000000000
Binary files a/core/assets-raw/sprites/blocks/extra/rubble-3-1.png and /dev/null differ
diff --git a/core/assets-raw/sprites/blocks/extra/rubble-4-1.png b/core/assets-raw/sprites/blocks/extra/rubble-4-1.png
deleted file mode 100644
index f937d25c8e..0000000000
Binary files a/core/assets-raw/sprites/blocks/extra/rubble-4-1.png and /dev/null differ
diff --git a/core/assets-raw/sprites/blocks/extra/rubble-5-1.png b/core/assets-raw/sprites/blocks/extra/rubble-5-1.png
deleted file mode 100644
index 822e4b777b..0000000000
Binary files a/core/assets-raw/sprites/blocks/extra/rubble-5-1.png and /dev/null differ
diff --git a/core/assets-raw/sprites/blocks/extra/rubble-6-1.png b/core/assets-raw/sprites/blocks/extra/rubble-6-1.png
deleted file mode 100644
index 3260f4b32d..0000000000
Binary files a/core/assets-raw/sprites/blocks/extra/rubble-6-1.png and /dev/null differ
diff --git a/core/assets-raw/sprites/blocks/extra/rubble-7-1.png b/core/assets-raw/sprites/blocks/extra/rubble-7-1.png
deleted file mode 100644
index 525ca3da1f..0000000000
Binary files a/core/assets-raw/sprites/blocks/extra/rubble-7-1.png and /dev/null differ
diff --git a/core/assets-raw/sprites/blocks/extra/rubble-8-1.png b/core/assets-raw/sprites/blocks/extra/rubble-8-1.png
deleted file mode 100644
index 680e65aa48..0000000000
Binary files a/core/assets-raw/sprites/blocks/extra/rubble-8-1.png and /dev/null differ
diff --git a/core/assets-raw/sprites/blocks/mechs/alpha-mech-pad.png b/core/assets-raw/sprites/blocks/mechs/alpha-mech-pad.png
new file mode 100644
index 0000000000..e5a90abb4b
Binary files /dev/null and b/core/assets-raw/sprites/blocks/mechs/alpha-mech-pad.png differ
diff --git a/core/assets-raw/sprites/blocks/mechs/dart-mech-pad.png b/core/assets-raw/sprites/blocks/mechs/dart-ship-pad.png
similarity index 100%
rename from core/assets-raw/sprites/blocks/mechs/dart-mech-pad.png
rename to core/assets-raw/sprites/blocks/mechs/dart-ship-pad.png
diff --git a/core/assets-raw/sprites/blocks/units/ground-factory-top.png b/core/assets-raw/sprites/blocks/units/ground-factory-top.png
new file mode 100644
index 0000000000..bfa0af2088
Binary files /dev/null and b/core/assets-raw/sprites/blocks/units/ground-factory-top.png differ
diff --git a/core/assets-raw/sprites/blocks/units/ground-factory.png b/core/assets-raw/sprites/blocks/units/ground-factory.png
new file mode 100644
index 0000000000..5bf4b32783
Binary files /dev/null and b/core/assets-raw/sprites/blocks/units/ground-factory.png differ
diff --git a/core/assets-raw/sprites/effects/bullet-back.png b/core/assets-raw/sprites/effects/bullet-back.png
index d5dccee0d7..007c025017 100644
Binary files a/core/assets-raw/sprites/effects/bullet-back.png and b/core/assets-raw/sprites/effects/bullet-back.png differ
diff --git a/core/assets-raw/sprites/effects/bullet.png b/core/assets-raw/sprites/effects/bullet.png
index 0b5dd8e8ac..c242e21ab0 100644
Binary files a/core/assets-raw/sprites/effects/bullet.png and b/core/assets-raw/sprites/effects/bullet.png differ
diff --git a/core/assets-raw/sprites/effects/missile-back.png b/core/assets-raw/sprites/effects/missile-back.png
index 0aa9893a33..cbd578de24 100644
Binary files a/core/assets-raw/sprites/effects/missile-back.png and b/core/assets-raw/sprites/effects/missile-back.png differ
diff --git a/core/assets-raw/sprites/effects/missile.png b/core/assets-raw/sprites/effects/missile.png
index 9f9f3831c3..5937fc06e0 100644
Binary files a/core/assets-raw/sprites/effects/missile.png and b/core/assets-raw/sprites/effects/missile.png differ
diff --git a/core/assets-raw/sprites/effects/particle.png b/core/assets-raw/sprites/effects/particle.png
new file mode 100644
index 0000000000..dabcbab9a9
Binary files /dev/null and b/core/assets-raw/sprites/effects/particle.png differ
diff --git a/core/assets-raw/sprites/effects/scorch1.png b/core/assets-raw/sprites/effects/scorch1.png
deleted file mode 100644
index 9044dc696c..0000000000
Binary files a/core/assets-raw/sprites/effects/scorch1.png and /dev/null differ
diff --git a/core/assets-raw/sprites/effects/scorch2.png b/core/assets-raw/sprites/effects/scorch2.png
deleted file mode 100644
index e5f2f11105..0000000000
Binary files a/core/assets-raw/sprites/effects/scorch2.png and /dev/null differ
diff --git a/core/assets-raw/sprites/effects/scorch3.png b/core/assets-raw/sprites/effects/scorch3.png
deleted file mode 100644
index 555ca5f288..0000000000
Binary files a/core/assets-raw/sprites/effects/scorch3.png and /dev/null differ
diff --git a/core/assets-raw/sprites/effects/scorch4.png b/core/assets-raw/sprites/effects/scorch4.png
deleted file mode 100644
index 981a1c8ac4..0000000000
Binary files a/core/assets-raw/sprites/effects/scorch4.png and /dev/null differ
diff --git a/core/assets-raw/sprites/effects/scorch5.png b/core/assets-raw/sprites/effects/scorch5.png
deleted file mode 100644
index 0a8d1e2ef2..0000000000
Binary files a/core/assets-raw/sprites/effects/scorch5.png and /dev/null differ
diff --git a/core/assets-raw/sprites/effects/shell-back.png b/core/assets-raw/sprites/effects/shell-back.png
index 2702b8f463..20a6ed6bb5 100644
Binary files a/core/assets-raw/sprites/effects/shell-back.png and b/core/assets-raw/sprites/effects/shell-back.png differ
diff --git a/core/assets-raw/sprites/effects/shell.png b/core/assets-raw/sprites/effects/shell.png
index 72969437f9..0818272a40 100644
Binary files a/core/assets-raw/sprites/effects/shell.png and b/core/assets-raw/sprites/effects/shell.png differ
diff --git a/core/assets-raw/sprites/effects/shot.png b/core/assets-raw/sprites/effects/shot.png
deleted file mode 100644
index 98a45162f4..0000000000
Binary files a/core/assets-raw/sprites/effects/shot.png and /dev/null differ
diff --git a/core/assets-raw/sprites/effects/transfer-arrow.png b/core/assets-raw/sprites/effects/transfer-arrow.png
index 16d71b0c5e..5faa4ae6c7 100644
Binary files a/core/assets-raw/sprites/effects/transfer-arrow.png and b/core/assets-raw/sprites/effects/transfer-arrow.png differ
diff --git a/core/assets-raw/sprites/effects/transfer-end.png b/core/assets-raw/sprites/effects/transfer-end.png
deleted file mode 100644
index 8579ff179e..0000000000
Binary files a/core/assets-raw/sprites/effects/transfer-end.png and /dev/null differ
diff --git a/core/assets-raw/sprites/mechs/mechs/alpha-mech-base.png b/core/assets-raw/sprites/mechs/mechs/alpha-mech-base.png
deleted file mode 100644
index 703f86e430..0000000000
Binary files a/core/assets-raw/sprites/mechs/mechs/alpha-mech-base.png and /dev/null differ
diff --git a/core/assets-raw/sprites/mechs/mechs/alpha-mech-leg.png b/core/assets-raw/sprites/mechs/mechs/alpha-mech-leg.png
deleted file mode 100644
index d60217a0bc..0000000000
Binary files a/core/assets-raw/sprites/mechs/mechs/alpha-mech-leg.png and /dev/null differ
diff --git a/core/assets-raw/sprites/mechs/mechs/alpha-mech.png b/core/assets-raw/sprites/mechs/mechs/alpha-mech.png
deleted file mode 100644
index 4cf40e53ec..0000000000
Binary files a/core/assets-raw/sprites/mechs/mechs/alpha-mech.png and /dev/null differ
diff --git a/core/assets-raw/sprites/mechs/ships/dart-ship.png b/core/assets-raw/sprites/mechs/ships/dart-ship.png
deleted file mode 100644
index a97796180e..0000000000
Binary files a/core/assets-raw/sprites/mechs/ships/dart-ship.png and /dev/null differ
diff --git a/core/assets-raw/sprites/rubble/pack.json b/core/assets-raw/sprites/rubble/pack.json
new file mode 100644
index 0000000000..2612f17acc
--- /dev/null
+++ b/core/assets-raw/sprites/rubble/pack.json
@@ -0,0 +1,8 @@
+{
+ duplicatePadding: true,
+ combineSubdirectories: true,
+ flattenPaths: true,
+ maxWidth: 2048,
+ maxHeight: 2048,
+ fast: true
+}
diff --git a/core/assets-raw/sprites/blocks/extra/rubble-1-0.png b/core/assets-raw/sprites/rubble/rubble-1-0.png
similarity index 100%
rename from core/assets-raw/sprites/blocks/extra/rubble-1-0.png
rename to core/assets-raw/sprites/rubble/rubble-1-0.png
diff --git a/core/assets-raw/sprites/blocks/extra/rubble-1-1.png b/core/assets-raw/sprites/rubble/rubble-1-1.png
similarity index 100%
rename from core/assets-raw/sprites/blocks/extra/rubble-1-1.png
rename to core/assets-raw/sprites/rubble/rubble-1-1.png
diff --git a/core/assets-raw/sprites/blocks/extra/rubble-2-0.png b/core/assets-raw/sprites/rubble/rubble-2-0.png
similarity index 100%
rename from core/assets-raw/sprites/blocks/extra/rubble-2-0.png
rename to core/assets-raw/sprites/rubble/rubble-2-0.png
diff --git a/core/assets-raw/sprites/blocks/extra/rubble-2-1.png b/core/assets-raw/sprites/rubble/rubble-2-1.png
similarity index 100%
rename from core/assets-raw/sprites/blocks/extra/rubble-2-1.png
rename to core/assets-raw/sprites/rubble/rubble-2-1.png
diff --git a/core/assets-raw/sprites/blocks/extra/rubble-3-0.png b/core/assets-raw/sprites/rubble/rubble-3-0.png
similarity index 100%
rename from core/assets-raw/sprites/blocks/extra/rubble-3-0.png
rename to core/assets-raw/sprites/rubble/rubble-3-0.png
diff --git a/core/assets-raw/sprites/blocks/extra/rubble-4-0.png b/core/assets-raw/sprites/rubble/rubble-4-0.png
similarity index 100%
rename from core/assets-raw/sprites/blocks/extra/rubble-4-0.png
rename to core/assets-raw/sprites/rubble/rubble-4-0.png
diff --git a/core/assets-raw/sprites/blocks/extra/rubble-5-0.png b/core/assets-raw/sprites/rubble/rubble-5-0.png
similarity index 100%
rename from core/assets-raw/sprites/blocks/extra/rubble-5-0.png
rename to core/assets-raw/sprites/rubble/rubble-5-0.png
diff --git a/core/assets-raw/sprites/blocks/extra/rubble-6-0.png b/core/assets-raw/sprites/rubble/rubble-6-0.png
similarity index 100%
rename from core/assets-raw/sprites/blocks/extra/rubble-6-0.png
rename to core/assets-raw/sprites/rubble/rubble-6-0.png
diff --git a/core/assets-raw/sprites/blocks/extra/rubble-7-0.png b/core/assets-raw/sprites/rubble/rubble-7-0.png
similarity index 100%
rename from core/assets-raw/sprites/blocks/extra/rubble-7-0.png
rename to core/assets-raw/sprites/rubble/rubble-7-0.png
diff --git a/core/assets-raw/sprites/blocks/extra/rubble-8-0.png b/core/assets-raw/sprites/rubble/rubble-8-0.png
similarity index 100%
rename from core/assets-raw/sprites/blocks/extra/rubble-8-0.png
rename to core/assets-raw/sprites/rubble/rubble-8-0.png
diff --git a/core/assets-raw/sprites/units/alpha-base.png b/core/assets-raw/sprites/units/alpha-base.png
new file mode 100644
index 0000000000..61fb31cf47
Binary files /dev/null and b/core/assets-raw/sprites/units/alpha-base.png differ
diff --git a/core/assets-raw/sprites/units/alpha-leg.png b/core/assets-raw/sprites/units/alpha-leg.png
new file mode 100644
index 0000000000..3be6f210e2
Binary files /dev/null and b/core/assets-raw/sprites/units/alpha-leg.png differ
diff --git a/core/assets-raw/sprites/units/alpha.png b/core/assets-raw/sprites/units/alpha.png
new file mode 100644
index 0000000000..a01baf8e22
Binary files /dev/null and b/core/assets-raw/sprites/units/alpha.png differ
diff --git a/core/assets-raw/sprites/units/dart.png b/core/assets-raw/sprites/units/dart.png
new file mode 100644
index 0000000000..12f4d9c924
Binary files /dev/null and b/core/assets-raw/sprites/units/dart.png differ
diff --git a/core/assets-raw/sprites/mechs/mechs/delta-mech-base.png b/core/assets-raw/sprites/units/delta-base.png
similarity index 100%
rename from core/assets-raw/sprites/mechs/mechs/delta-mech-base.png
rename to core/assets-raw/sprites/units/delta-base.png
diff --git a/core/assets-raw/sprites/mechs/mechs/delta-mech-leg.png b/core/assets-raw/sprites/units/delta-leg.png
similarity index 100%
rename from core/assets-raw/sprites/mechs/mechs/delta-mech-leg.png
rename to core/assets-raw/sprites/units/delta-leg.png
diff --git a/core/assets-raw/sprites/mechs/mechs/delta-mech.png b/core/assets-raw/sprites/units/delta.png
similarity index 100%
rename from core/assets-raw/sprites/mechs/mechs/delta-mech.png
rename to core/assets-raw/sprites/units/delta.png
diff --git a/core/assets-raw/sprites/mechs/ships/glaive-ship.png b/core/assets-raw/sprites/units/glaive.png
similarity index 100%
rename from core/assets-raw/sprites/mechs/ships/glaive-ship.png
rename to core/assets-raw/sprites/units/glaive.png
diff --git a/core/assets-raw/sprites/mechs/ships/javelin-ship-shield.png b/core/assets-raw/sprites/units/javelin-shield.png
similarity index 100%
rename from core/assets-raw/sprites/mechs/ships/javelin-ship-shield.png
rename to core/assets-raw/sprites/units/javelin-shield.png
diff --git a/core/assets-raw/sprites/mechs/ships/javelin-ship.png b/core/assets-raw/sprites/units/javelin.png
similarity index 100%
rename from core/assets-raw/sprites/mechs/ships/javelin-ship.png
rename to core/assets-raw/sprites/units/javelin.png
diff --git a/core/assets-raw/sprites/mechs/mechs/omega-mech-armor.png b/core/assets-raw/sprites/units/omega-armor.png
similarity index 100%
rename from core/assets-raw/sprites/mechs/mechs/omega-mech-armor.png
rename to core/assets-raw/sprites/units/omega-armor.png
diff --git a/core/assets-raw/sprites/mechs/mechs/omega-mech-base.png b/core/assets-raw/sprites/units/omega-base.png
similarity index 100%
rename from core/assets-raw/sprites/mechs/mechs/omega-mech-base.png
rename to core/assets-raw/sprites/units/omega-base.png
diff --git a/core/assets-raw/sprites/mechs/mechs/omega-mech-leg.png b/core/assets-raw/sprites/units/omega-leg.png
similarity index 100%
rename from core/assets-raw/sprites/mechs/mechs/omega-mech-leg.png
rename to core/assets-raw/sprites/units/omega-leg.png
diff --git a/core/assets-raw/sprites/mechs/mechs/omega-mech.png b/core/assets-raw/sprites/units/omega.png
similarity index 100%
rename from core/assets-raw/sprites/mechs/mechs/omega-mech.png
rename to core/assets-raw/sprites/units/omega.png
diff --git a/core/assets-raw/sprites/units/reaper.png b/core/assets-raw/sprites/units/reaper.png
index 168919a427..22d5f468c7 100644
Binary files a/core/assets-raw/sprites/units/reaper.png and b/core/assets-raw/sprites/units/reaper.png differ
diff --git a/core/assets-raw/sprites/mechs/mechs/tau-mech-base.png b/core/assets-raw/sprites/units/tau-base.png
similarity index 100%
rename from core/assets-raw/sprites/mechs/mechs/tau-mech-base.png
rename to core/assets-raw/sprites/units/tau-base.png
diff --git a/core/assets-raw/sprites/mechs/mechs/tau-mech-leg.png b/core/assets-raw/sprites/units/tau-leg.png
similarity index 100%
rename from core/assets-raw/sprites/mechs/mechs/tau-mech-leg.png
rename to core/assets-raw/sprites/units/tau-leg.png
diff --git a/core/assets-raw/sprites/mechs/mechs/tau-mech.png b/core/assets-raw/sprites/units/tau.png
similarity index 100%
rename from core/assets-raw/sprites/mechs/mechs/tau-mech.png
rename to core/assets-raw/sprites/units/tau.png
diff --git a/core/assets-raw/sprites/mechs/ships/trident-ship.png b/core/assets-raw/sprites/units/trident.png
similarity index 100%
rename from core/assets-raw/sprites/mechs/ships/trident-ship.png
rename to core/assets-raw/sprites/units/trident.png
diff --git a/core/assets-raw/sprites/units/vanguard.png b/core/assets-raw/sprites/units/vanguard.png
new file mode 100644
index 0000000000..f4ac2a3210
Binary files /dev/null and b/core/assets-raw/sprites/units/vanguard.png differ
diff --git a/core/assets-raw/sprites/weapons/shockgun-equip.png b/core/assets-raw/sprites/weapons/shockgun-equip.png
index 3f024a6865..6e1993212b 100644
Binary files a/core/assets-raw/sprites/weapons/shockgun-equip.png and b/core/assets-raw/sprites/weapons/shockgun-equip.png differ
diff --git a/core/assets-raw/sprites/weapons/vanguard-blaster-equip.png b/core/assets-raw/sprites/weapons/vanguard-blaster-equip.png
new file mode 100644
index 0000000000..7d1e246dd4
Binary files /dev/null and b/core/assets-raw/sprites/weapons/vanguard-blaster-equip.png differ
diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties
index 69e65a3ca2..0fed5ad244 100644
--- a/core/assets/bundles/bundle.properties
+++ b/core/assets/bundles/bundle.properties
@@ -105,11 +105,13 @@ mods = Mods
mods.none = [LIGHT_GRAY]No mods found!
mods.guide = Modding Guide
mods.report = Report Bug
-mods.openfolder = Open Mod Folder
+mods.openfolder = Open Folder
+mods.reload = Reload
mod.display = [gray]Mod:[orange] {0}
mod.enabled = [lightgray]Enabled
mod.disabled = [scarlet]Disabled
mod.disable = Disable
+mod.content = Content:
mod.delete.error = Unable to delete mod. File may be in use.
mod.requiresversion = [scarlet]Requires min game version: [accent]{0}
mod.missingdependencies = [scarlet]Missing dependencies: {0}
@@ -121,14 +123,15 @@ mod.enable = Enable
mod.requiresrestart = The game will now close to apply the mod changes.
mod.reloadrequired = [scarlet]Reload Required
mod.import = Import Mod
-mod.import.github = Import GitHub Mod
+mod.import.file = Import File
+mod.import.github = Import From GitHub
mod.item.remove = This item is part of the[accent] '{0}'[] mod. To remove it, uninstall that mod.
mod.remove.confirm = This mod will be deleted.
mod.author = [LIGHT_GRAY]Author:[] {0}
mod.missing = This save contains mods that you have recently updated or no longer have installed. Save corruption may occur. Are you sure you want to load it?\n[lightgray]Mods:\n{0}
mod.preview.missing = Before publishing this mod in the workshop, you must add an image preview.\nPlace an image named[accent] preview.png[] into the mod's folder and try again.
mod.folder.missing = Only mods in folder form can be published on the workshop.\nTo convert any mod into a folder, simply unzip its file into a folder and delete the old zip, then restart your game or reload your mods.
-mod.scripts.unsupported = Your device does not support mod scripts. Some mods will not function correctly.
+mod.scripts.disable = Your device does not support mods with scripts. You must disable these mods to play the game.
about.button = About
name = Name:
@@ -265,8 +268,6 @@ data.openfolder = Open Data Folder
data.exported = Data exported.
data.invalid = This isn't valid game data.
data.import.confirm = Importing external data will overwrite[scarlet] all[] your current game data.\n[accent]This cannot be undone![]\n\nOnce the data is imported, your game will exit immediately.
-classic.export = Export Classic Data
-classic.export.text = [accent]Mindustry[] has just had a major update.\nClassic (v3.5 build 40) save or map data has been detected. Would you like to export these saves to your phone's home folder, for use in the Mindustry Classic app?
quit.confirm = Are you sure you want to quit?
quit.confirm.tutorial = Are you sure you know what you're doing?\nThe tutorial can be re-taken in[accent] Settings->Game->Re-Take Tutorial.[]
loading = [accent]Loading...
@@ -367,13 +368,13 @@ editor.importmap = Import Map
editor.importmap.description = Import an already existing map
editor.importfile = Import File
editor.importfile.description = Import an external map file
-editor.importimage = Import Legacy Map
+editor.importimage = Import Image File
editor.importimage.description = Import an external map image file
editor.export = Export...
editor.exportfile = Export File
editor.exportfile.description = Export a map file
editor.exportimage = Export Terrain Image
-editor.exportimage.description = Export a map image file
+editor.exportimage.description = Export an image file containing only basic terrain
editor.loadimage = Import Terrain
editor.saveimage = Export Terrain
editor.unsaved = [scarlet]You have unsaved changes![]\nAre you sure you want to exit?
@@ -402,6 +403,8 @@ toolmode.drawteams.description = Draw teams instead of blocks.
filters.empty = [lightgray]No filters! Add one with the button below.
filter.distort = Distort
filter.noise = Noise
+filter.enemyspawn = Enemy Spawn Select
+filter.corespawn = Core Select
filter.median = Median
filter.oremedian = Ore Median
filter.blend = Blend
@@ -421,6 +424,7 @@ filter.option.circle-scale = Circle Scale
filter.option.octaves = Octaves
filter.option.falloff = Falloff
filter.option.angle = Angle
+filter.option.amount = Amount
filter.option.block = Block
filter.option.floor = Floor
filter.option.flooronto = Target Floor
@@ -539,6 +543,7 @@ no = No
info.title = Info
error.title = [crimson]An error has occured
error.crashtitle = An error has occured
+unit.nobuild = [scarlet]Unit can't build
blocks.input = Input
blocks.output = Output
blocks.booster = Booster
@@ -633,6 +638,7 @@ setting.shadows.name = Shadows
setting.blockreplace.name = Automatic Block Suggestions
setting.linear.name = Linear Filtering
setting.hints.name = Hints
+setting.flow.name = Display Resource Flow Rate[scarlet] (experimental)
setting.buildautopause.name = Auto-Pause Building
setting.animatedwater.name = Animated Water
setting.animatedshields.name = Animated Shields
@@ -655,6 +661,7 @@ setting.difficulty.name = Difficulty:
setting.screenshake.name = Screen Shake
setting.effects.name = Display Effects
setting.destroyedblocks.name = Display Destroyed Blocks
+setting.blockstatus.name = Display Block Status
setting.conveyorpathfinding.name = Conveyor Placement Pathfinding
setting.coreselect.name = Allow Schematic Cores
setting.sensitivity.name = Controller Sensitivity
@@ -702,6 +709,7 @@ keybind.press = Press a key...
keybind.press.axis = Press an axis or key...
keybind.screenshot.name = Map Screenshot
keybind.toggle_power_lines.name = Toggle Power Lasers
+keybind.toggle_block_status.name = Toggle Block Statuses
keybind.move_x.name = Move X
keybind.move_y.name = Move Y
keybind.mouse_move.name = Follow Mouse
@@ -860,6 +868,7 @@ liquid.temperature = [lightgray]Temperature: {0}
block.sand-boulder.name = Sand Boulder
block.grass.name = Grass
+block.slag.name = Slag
block.salt.name = Salt
block.saltrocks.name = Salt Rocks
block.pebbles.name = Pebbles
@@ -985,7 +994,8 @@ block.pneumatic-drill.name = Pneumatic Drill
block.laser-drill.name = Laser Drill
block.water-extractor.name = Water Extractor
block.cultivator.name = Cultivator
-block.dart-mech-pad.name = Alpha Mech Pad
+block.dart-ship-pad.name = Dart Ship Pad
+block.alpha-mech-pad.name = Alpha Mech Pad
block.delta-mech-pad.name = Delta Mech Pad
block.javelin-ship-pad.name = Javelin Ship Pad
block.trident-ship-pad.name = Trident Ship Pad
@@ -1183,7 +1193,7 @@ block.force-projector.description = Creates a hexagonal force field around itsel
block.shock-mine.description = Damages enemies stepping on the mine. Nearly invisible to the enemy.
block.conveyor.description = Basic item transport block. Moves items forward and automatically deposits them into blocks. Rotatable.
block.titanium-conveyor.description = Advanced item transport block. Moves items faster than standard conveyors.
-block.plastanium-conveyor.description = The \uf822 moves items in batches.\nOnly accepts items at the back.\nLoads & unloads on all 3 sides.
+block.plastanium-conveyor.description = The \uf81c moves items in batches.\nOnly accepts items at the back.\nLoads & unloads on all 3 sides.
block.junction.description = Acts as a bridge for two crossing conveyor belts. Useful in situations with two different conveyors carrying different materials to different locations.
block.bridge-conveyor.description = Advanced item transport block. Allows transporting items over up to 3 tiles of any terrain or building.
block.phase-conveyor.description = Advanced item transport block. Uses power to teleport items to a connected phase conveyor over several tiles.
@@ -1261,7 +1271,6 @@ block.crawler-factory.description = Produces fast self-destructing swarm units.
block.titan-factory.description = Produces advanced, armored ground units.
block.fortress-factory.description = Produces heavy artillery ground units.
block.repair-point.description = Continuously heals the closest damaged unit in its vicinity.
-block.dart-mech-pad.description = Provides transformation into a basic attack mech.\nUse by tapping while standing on it.
block.delta-mech-pad.description = Provides transformation into a lightly armored hit-and-run attack mech.\nUse by tapping while standing on it.
block.tau-mech-pad.description = Provides transformation into an advanced support mech.\nUse by tapping while standing on it.
block.omega-mech-pad.description = Provides transformation into a heavily-armored missile mech.\nUse by tapping while standing on it.
diff --git a/core/assets/bundles/bundle_uk_UA.properties b/core/assets/bundles/bundle_uk_UA.properties
index 4740c2b768..ddbab934d8 100644
--- a/core/assets/bundles/bundle_uk_UA.properties
+++ b/core/assets/bundles/bundle_uk_UA.properties
@@ -266,8 +266,6 @@ data.openfolder = Відкрити теку з даними
data.exported = Дані вивантажено.
data.invalid = Це не дійсні ігрові дані.
data.import.confirm = Вивантаження зовнішніх даних перезапише[scarlet] ВСІ[] ваші поточні ігрові дані.\n[accent]Це неможливо скасувати![]\n\nЩойно дані імпортуються, гра негайно закриється.
-classic.export = Вивантажити класичні дані
-classic.export.text = [accent]Mindustry[] отримала суттєве оновлення.\nБуло виявлено класичні файли збереження (версія 3.5 збірка 40), або дані мапи. Ви хочете експортувати ці дані в домашню теку телефону, для використання у застосунку Mindustry Classic?
quit.confirm = Ви дійсно хочете вийти?
quit.confirm.tutorial = Ви впевнені, що знаєте що робите?\nНавчання можна пройти наново[accent] Налаштування->Гра->Пройти навчання ще раз.[]
loading = [accent]Завантаження…
@@ -368,13 +366,13 @@ editor.importmap = Імпортувати мапу
editor.importmap.description = Імпортувати вже наявну мапу
editor.importfile = Імпортувати файл
editor.importfile.description = Імпортувати зовнішній файл мапи
-editor.importimage = Імпортувати застаріле зображення
+editor.importimage = Імпортувати зображення
editor.importimage.description = Імпорт із зображенням місцевості
editor.export = Експорт…
editor.exportfile = Експортувати файл
editor.exportfile.description = Експортувати файл мапи
editor.exportimage = Експорт зображення місцевості
-editor.exportimage.description = Експорт файлу з зображенням мапи
+editor.exportimage.description = Експортувати файл, який містить основний рельєф місцевості.
editor.loadimage = Завантажити\nзображення
editor.saveimage = Зберегти\nзображення
editor.unsaved = [scarlet]У вас є незбережені зміни![]\nВи впевнені, що хочете вийти?
@@ -403,6 +401,8 @@ toolmode.drawteams.description = Змінює належність\nблока
filters.empty = [lightgray]Немає фільтрів! Додайте хоча б один за допомогою кнопки нижче.
filter.distort = Спотворення
filter.noise = Шум
+filter.enemyspawn = Вибір точки появи ворогів
+filter.corespawn = Вибір ядра
filter.median = Медіана
filter.oremedian = Рудна медіана
filter.blend = Змішування
@@ -540,6 +540,7 @@ no = Ні
info.title = Інформація
error.title = [crimson]Виникла помилка
error.crashtitle = Виникла помилка
+unit.nobuild = [scarlet]Ця одиниця не може будувати
blocks.input = Ввід
blocks.output = Вивід
blocks.booster = Прискорювач
@@ -669,7 +670,7 @@ setting.borderlesswindow.name = Вікно без полів[lightgray] (мож
setting.fps.name = Показувати FPS і затримку до сервера
setting.blockselectkeys.name = Показувати клавіші вибору блока
setting.vsync.name = Вертикальна синхронізація
-setting.pixelate.name = Пікселізація[lightgray] (вимикає анімації)
+setting.pixelate.name = Пікселізація
setting.minimap.name = Показувати мінімапу
setting.position.name = Показувати координати гравця
setting.musicvol.name = Гучність музики
@@ -1261,8 +1262,7 @@ block.crawler-factory.description = Виробляє швидких одиниц
block.titan-factory.description = Виробляє поліпшених наземних одиниць.
block.fortress-factory.description = Виробляє важкоартилерійних наземних одиниць.
block.repair-point.description = Безперервно лікує найближчу пошкоджену бойову одиницю.
-block.dart-mech-pad.description = Забезпечує перетворення в основний атакуючий мех.\nДля використання натисніть на нього, коли стоїте на ньому.
-block.delta-mech-pad.description = Забезпечує перетворення в легко броньований атакуючий мех.\nДля використання натисніть на нього, коли стоїте на ньому.
+block.delta-mech-pad.description = Забезпечує перетворення в легкоброньований атакуючий мех.\nДля використання натисніть на нього, коли стоїте на ньому.
block.tau-mech-pad.description = Забезпечує перетворення в поліпшений мех підтримки.\nДля використання натисніть на нього, коли стоїте на ньому.
block.omega-mech-pad.description = Забезпечує перетворення в тяжко броньований ракетний мех.\nДля використання натисніть на нього, коли стоїте на ньому.
block.javelin-ship-pad.description = Забезпечує перетворення в швидкий, легко броньований перехоплювач.\nДля використання натисніть на нього, коли стоїте на ньому.
diff --git a/core/assets/cubemaps/stars/back.png b/core/assets/cubemaps/stars/back.png
new file mode 100644
index 0000000000..05f3375811
Binary files /dev/null and b/core/assets/cubemaps/stars/back.png differ
diff --git a/core/assets/cubemaps/stars/bottom.png b/core/assets/cubemaps/stars/bottom.png
new file mode 100644
index 0000000000..bfcded64e3
Binary files /dev/null and b/core/assets/cubemaps/stars/bottom.png differ
diff --git a/core/assets/cubemaps/stars/front.png b/core/assets/cubemaps/stars/front.png
new file mode 100644
index 0000000000..8e9dbcd437
Binary files /dev/null and b/core/assets/cubemaps/stars/front.png differ
diff --git a/core/assets/cubemaps/stars/left.png b/core/assets/cubemaps/stars/left.png
new file mode 100644
index 0000000000..f99a70ab1b
Binary files /dev/null and b/core/assets/cubemaps/stars/left.png differ
diff --git a/core/assets/cubemaps/stars/right.png b/core/assets/cubemaps/stars/right.png
new file mode 100644
index 0000000000..f1c6f5c807
Binary files /dev/null and b/core/assets/cubemaps/stars/right.png differ
diff --git a/core/assets/cubemaps/stars/top.png b/core/assets/cubemaps/stars/top.png
new file mode 100644
index 0000000000..078e1a3d3f
Binary files /dev/null and b/core/assets/cubemaps/stars/top.png differ
diff --git a/core/assets/icons/icons.properties b/core/assets/icons/icons.properties
index 1407e53c39..8885e7623d 100755
--- a/core/assets/icons/icons.properties
+++ b/core/assets/icons/icons.properties
@@ -218,5 +218,13 @@
63526=oil|liquid-oil-icon
63525=cryofluid|liquid-cryofluid-icon
63524=underflow-gate|block-underflow-gate-medium
-63523=plastanium-conveyor|block-plastanium-conveyor-medium
-63522=crater|crater
+63523=dart-ship-pad|block-dart-ship-pad-medium
+63522=alpha-mech-pad|block-alpha-mech-pad-medium
+63521=cliff|block-cliff-medium
+63520=legacy-mech-pad|block-legacy-mech-pad-medium
+63519=ground-factory|block-ground-factory-medium
+63518=legacy-unit-factory|block-legacy-unit-factory-medium
+63517=mass-conveyor|block-mass-conveyor-medium
+63516=crater|crater
+63515=plastanium-conveyor|block-plastanium-conveyor-medium
+63514=legacy-command-center|block-legacy-command-center-medium
diff --git a/core/assets/music/land.ogg b/core/assets/music/land.ogg
new file mode 100644
index 0000000000..800b253656
Binary files /dev/null and b/core/assets/music/land.ogg differ
diff --git a/core/assets/planets/TODO.dat b/core/assets/planets/TODO.dat
new file mode 100644
index 0000000000..0c6f13e210
Binary files /dev/null and b/core/assets/planets/TODO.dat differ
diff --git a/core/assets/planets/colors.png b/core/assets/planets/colors.png
new file mode 100644
index 0000000000..5efd5d38e0
Binary files /dev/null and b/core/assets/planets/colors.png differ
diff --git a/core/assets/shaders/atmosphere.frag b/core/assets/shaders/atmosphere.frag
new file mode 100644
index 0000000000..fee422e5b6
--- /dev/null
+++ b/core/assets/shaders/atmosphere.frag
@@ -0,0 +1,123 @@
+#ifdef GL_ES
+precision mediump float;
+precision mediump int;
+#endif
+
+const float PI = 3.14159265359;
+const float MAX = 10000.0;
+
+const float PEAK = 0.1;
+const float FLARE = 0.0025;
+const float INTENSITY = 14.3;
+const float G_M = -0.85;
+
+#define SCATTER_OUT 3
+#define SCATTER_IN 3
+
+const int numOutScatter = SCATTER_OUT;
+const float fNumOutScatter = float(SCATTER_OUT);
+const int numInScatter = SCATTER_IN;
+const float fNumInScatter = float(SCATTER_IN);
+
+varying vec4 v_position;
+varying mat4 v_model;
+
+uniform float u_innerRadius;
+uniform float u_outerRadius;
+uniform vec3 u_color;
+uniform vec2 u_resolution;
+uniform float u_time;
+uniform vec3 u_campos;
+uniform vec3 u_rcampos;
+uniform mat4 u_invproj;
+uniform vec3 u_light;
+
+vec2 rayIntersection(vec3 p, vec3 dir, float radius) {
+ float b = dot(p, dir);
+ float c = dot(p, p) - radius * radius;
+
+ float d = b * b - c;
+ if (d < 0.0) {
+ return vec2(MAX, -MAX);
+ }
+ d = sqrt(d);
+
+ float near = -b - d;
+ float far = -b + d;
+
+ return vec2(near, far);
+}
+
+float miePhase(float g, float c, float cc) {
+ float gg = g * g;
+
+ float a = (1.0 - gg) * (1.0 + cc);
+
+ float b = 1.0 + gg - 2.0 * g * c;
+ b *= sqrt(b);
+ b *= 2.0 + gg;
+
+ return 1.5 * a / b;
+}
+
+float rayleighPhase(float cc) {
+ return 0.75 * (1.0 + cc);
+}
+
+float density(vec3 p) {
+ return exp(-(length(p) - u_innerRadius) * (4.0 / (u_outerRadius - u_innerRadius)));
+}
+
+float optic(vec3 p, vec3 q) {
+ vec3 step = (q - p) / fNumOutScatter;
+ vec3 v = p + step * 0.5;
+
+ float sum = 0.0;
+ for (int i = 0; i < numOutScatter; i++) {
+ sum += density(v);
+ v += step;
+ }
+ sum *= length(step)*(1.0 / (u_outerRadius - u_innerRadius));
+ return sum;
+}
+
+vec3 inScatter(vec3 o, vec3 dir, vec2 e, vec3 l) {
+ float len = (e.y - e.x) / fNumInScatter;
+ vec3 step = dir * len;
+ vec3 p = o + dir * e.x;
+ vec3 v = p + dir * (len * 0.5);
+
+ vec3 sum = vec3(0.0);
+ for(int i = 0; i < numInScatter; i++){
+ vec2 f = rayIntersection(v, l, u_outerRadius);
+ vec3 u = v + l * f.y;
+ float n = (optic(p, v) + optic(v, u))*(PI * 4.0);
+
+ sum += density(v) * exp(-n * (PEAK * u_color + FLARE));
+ v += step;
+ }
+ sum *= len * (1.0 / (u_outerRadius - u_innerRadius));
+ float c = dot(dir, -l);
+ float cc = c * c;
+ return sum * (PEAK * u_color * rayleighPhase(cc) + FLARE * miePhase(G_M, c, cc)) * INTENSITY;
+}
+
+vec3 rayDirection(){
+ vec4 ray = v_model*v_position - vec4(u_campos, 1.0);
+ return normalize(vec3(ray));
+}
+
+void main(){
+ vec3 dir = rayDirection();
+ vec3 eye = u_rcampos;
+
+ vec3 l = u_light;
+
+ vec2 e = rayIntersection(eye, dir, u_outerRadius);
+ vec2 f = rayIntersection(eye, dir, u_innerRadius);
+ e.y = min(e.y, f.x);
+
+ vec3 result = inScatter(eye, dir, e, l);
+
+ gl_FragColor = vec4(result, 1.0);
+}
\ No newline at end of file
diff --git a/core/assets/shaders/atmosphere.vert b/core/assets/shaders/atmosphere.vert
new file mode 100644
index 0000000000..6899e0f0f4
--- /dev/null
+++ b/core/assets/shaders/atmosphere.vert
@@ -0,0 +1,13 @@
+attribute vec4 a_position;
+
+varying vec4 v_position;
+varying mat4 v_model;
+
+uniform mat4 u_model;
+uniform mat4 u_projection;
+
+void main(){
+ v_position = a_position;
+ v_model = u_model;
+ gl_Position = u_projection*u_model*a_position;
+}
\ No newline at end of file
diff --git a/core/assets/shaders/blockbuild.fragment.glsl b/core/assets/shaders/blockbuild.frag
similarity index 100%
rename from core/assets/shaders/blockbuild.fragment.glsl
rename to core/assets/shaders/blockbuild.frag
diff --git a/core/assets/shaders/cubemap.frag b/core/assets/shaders/cubemap.frag
new file mode 100644
index 0000000000..893384f120
--- /dev/null
+++ b/core/assets/shaders/cubemap.frag
@@ -0,0 +1,11 @@
+#ifdef GL_ES
+precision mediump float;
+#endif
+
+varying vec3 v_texCoords;
+
+uniform samplerCube u_cubemap;
+
+void main(){
+ gl_FragColor = textureCube(u_cubemap, v_texCoords);
+}
\ No newline at end of file
diff --git a/core/assets/shaders/cubemap.vert b/core/assets/shaders/cubemap.vert
new file mode 100644
index 0000000000..546cec8f46
--- /dev/null
+++ b/core/assets/shaders/cubemap.vert
@@ -0,0 +1,12 @@
+attribute vec3 a_position;
+
+varying vec3 v_texCoords;
+
+uniform mat4 u_proj;
+
+const float SCALE = 50.0;
+
+void main(){
+ v_texCoords = a_position;
+ gl_Position = u_proj * vec4(a_position * SCALE, 1.0);
+}
\ No newline at end of file
diff --git a/core/assets/shaders/default.vertex.glsl b/core/assets/shaders/default.vert
similarity index 100%
rename from core/assets/shaders/default.vertex.glsl
rename to core/assets/shaders/default.vert
diff --git a/core/assets/shaders/fog.fragment.glsl b/core/assets/shaders/fog.frag
similarity index 100%
rename from core/assets/shaders/fog.fragment.glsl
rename to core/assets/shaders/fog.frag
diff --git a/core/assets/shaders/light.fragment.glsl b/core/assets/shaders/light.frag
similarity index 100%
rename from core/assets/shaders/light.fragment.glsl
rename to core/assets/shaders/light.frag
diff --git a/core/assets/shaders/menu.fragment.glsl b/core/assets/shaders/menu.frag
similarity index 100%
rename from core/assets/shaders/menu.fragment.glsl
rename to core/assets/shaders/menu.frag
diff --git a/core/assets/shaders/planet.frag b/core/assets/shaders/planet.frag
new file mode 100755
index 0000000000..fbd1548992
--- /dev/null
+++ b/core/assets/shaders/planet.frag
@@ -0,0 +1,9 @@
+#ifdef GL_ES
+precision mediump float;
+#endif
+
+varying vec4 v_col;
+
+void main(){
+ gl_FragColor = v_col;
+}
diff --git a/core/assets/shaders/planet.vert b/core/assets/shaders/planet.vert
new file mode 100755
index 0000000000..f500af0ecf
--- /dev/null
+++ b/core/assets/shaders/planet.vert
@@ -0,0 +1,25 @@
+attribute vec4 a_position;
+attribute vec3 a_normal;
+attribute vec4 a_color;
+
+uniform mat4 u_proj;
+uniform mat4 u_trans;
+uniform vec3 u_lightdir;
+uniform vec3 u_camdir;
+uniform vec3 u_ambientColor;
+
+varying vec4 v_col;
+
+const vec3 diffuse = vec3(0);
+const float shinefalloff = 4.0;
+const float shinelen = 0.2;
+
+void main(){
+ vec3 norc = u_ambientColor * (diffuse + vec3(clamp((dot(a_normal, u_lightdir) + 1.0) / 2.0, 0.0, 1.0)));
+ float shinedot = max((-dot(u_camdir, a_normal) - (1.0 - shinelen)) / shinelen, 0.0);
+ float shinyness = (1.0 - a_color.a) * pow(shinedot, shinefalloff);
+ vec4 baseCol = vec4(a_color.rgb, 1.0);
+
+ v_col = mix(baseCol * vec4(norc, 1.0), vec4(1.0), shinyness * norc.r);
+ gl_Position = u_proj * u_trans * a_position;
+}
diff --git a/core/assets/shaders/planetgrid.frag b/core/assets/shaders/planetgrid.frag
new file mode 100644
index 0000000000..ccdf82998a
--- /dev/null
+++ b/core/assets/shaders/planetgrid.frag
@@ -0,0 +1,14 @@
+#ifdef GL_ES
+precision mediump float;
+#endif
+
+varying vec4 v_col;
+varying vec4 v_position;
+
+uniform vec3 u_mouse;
+
+const vec4 shadow = vec4(0, 0, 0, 0);
+
+void main(){
+ gl_FragColor = mix(v_col, shadow, distance(u_mouse, v_position.xyz));
+}
diff --git a/core/assets/shaders/planetgrid.vert b/core/assets/shaders/planetgrid.vert
new file mode 100644
index 0000000000..5dd54ffebc
--- /dev/null
+++ b/core/assets/shaders/planetgrid.vert
@@ -0,0 +1,14 @@
+attribute vec4 a_position;
+attribute vec4 a_color;
+
+uniform mat4 u_proj;
+uniform mat4 u_trans;
+
+varying vec4 v_col;
+varying vec4 v_position;
+
+void main() {
+ gl_Position = u_proj * u_trans * a_position;
+ v_col = a_color;
+ v_position = a_position;
+}
diff --git a/core/assets/shaders/shadow.fragment.glsl b/core/assets/shaders/shadow.frag
similarity index 100%
rename from core/assets/shaders/shadow.fragment.glsl
rename to core/assets/shaders/shadow.frag
diff --git a/core/assets/shaders/shield.fragment.glsl b/core/assets/shaders/shield.frag
similarity index 100%
rename from core/assets/shaders/shield.fragment.glsl
rename to core/assets/shaders/shield.frag
diff --git a/core/assets/shaders/slag.frag b/core/assets/shaders/slag.frag
new file mode 100755
index 0000000000..50bdcfd879
--- /dev/null
+++ b/core/assets/shaders/slag.frag
@@ -0,0 +1,36 @@
+#ifdef GL_ES
+precision highp float;
+precision mediump int;
+#endif
+
+//shades of slag
+#define S2 vec3(100.0, 93.0, 49.0) / 100.0
+#define S1 vec3(100.0, 60.0, 25.0) / 100.0
+#define NSCALE 280.0 / 2.0
+
+uniform sampler2D u_texture;
+uniform sampler2D u_noise;
+
+uniform vec2 u_campos;
+uniform vec2 u_resolution;
+uniform float u_time;
+
+varying vec4 v_color;
+varying vec2 v_texCoord;
+
+void main(){
+ vec2 c = v_texCoord.xy;
+ vec2 coords = vec2(c.x * u_resolution.x + u_campos.x, c.y * u_resolution.y + u_campos.y);
+
+ float btime = u_time / 4000.0;
+ float noise = (texture2D(u_noise, (coords) / NSCALE + vec2(btime) * vec2(-0.9, 0.8)).r + texture2D(u_noise, (coords) / NSCALE + vec2(btime * 1.1) * vec2(0.8, -1.0)).r) / 2.0;
+ vec3 color = texture2D(u_texture, c).rgb;
+
+ if(noise > 0.6){
+ color = S2;
+ }else if(noise > 0.54){
+ color = S1;
+ }
+
+ gl_FragColor = vec4(color.rgb, 1.0);
+}
\ No newline at end of file
diff --git a/core/assets/shaders/snow.frag b/core/assets/shaders/snow.frag
new file mode 100644
index 0000000000..b17cc756e0
--- /dev/null
+++ b/core/assets/shaders/snow.frag
@@ -0,0 +1,45 @@
+#define LIGHT
+
+#ifdef LIGHT
+ #define LAYERS 30.
+ #define DEPTH .5
+ #define WIDTH .3
+ #define SPEED .6
+ #define SIZE 0.2
+#else
+ #define LAYERS 200.
+ #define DEPTH .1
+ #define WIDTH .8
+ #define SPEED 1.5
+ #define SIZE 1.0
+#endif
+
+varying vec2 v_texCoords;
+
+uniform vec2 u_pos;
+uniform vec2 u_resolution;
+uniform float u_time;
+uniform sampler2D u_texture0;
+
+void main(){
+ gl_FragColor = texture2D(u_texture0, v_texCoords);
+
+ vec2 uv = (v_texCoords * u_resolution + u_pos) / 1000.0;
+ const mat3 p = mat3(
+ 13.3231, 23.5112, 21.7112,
+ 21.1212, 28.7312, 11.9312,
+ 21.8112, 14.7212, 61.3934
+ );
+ float dof = 5.*sin(u_time*.1);
+
+ //TODO this is very slow
+ for(float i=0.0; i 0.54 && noise < 0.58)){
+ color *= 0.6;
+ }
+
+ gl_FragColor = vec4(color.rgb, 1.0);
+}
\ No newline at end of file
diff --git a/core/assets/shaders/tar.fragment.glsl b/core/assets/shaders/tar.fragment.glsl
deleted file mode 100644
index bdbd49c4b3..0000000000
--- a/core/assets/shaders/tar.fragment.glsl
+++ /dev/null
@@ -1,71 +0,0 @@
-#ifdef GL_ES
-precision highp float;
-precision mediump int;
-#endif
-
-uniform sampler2D u_texture;
-
-uniform vec2 camerapos;
-uniform vec2 screensize;
-uniform float time;
-
-varying vec4 v_color;
-varying vec2 v_texCoord;
-
-vec3 permute(vec3 x) { return mod(((x*34.0)+1.0)*x, 289.0); }
-
-float snoise(vec2 v){
- const vec4 C = vec4(0.211324865405187, 0.366025403784439,
- -0.577350269189626, 0.024390243902439);
- vec2 i = floor(v + dot(v, C.yy) );
- vec2 x0 = v - i + dot(i, C.xx);
- vec2 i1;
- i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
- vec4 x12 = x0.xyxy + C.xxzz;
- x12.xy -= i1;
- i = mod(i, 289.0);
- vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 ))
- + i.x + vec3(0.0, i1.x, 1.0 ));
- vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy),
- dot(x12.zw,x12.zw)), 0.0);
- m = m*m ;
- m = m*m ;
- vec3 x = 2.0 * fract(p * C.www) - 1.0;
- vec3 h = abs(x) - 0.5;
- vec3 ox = floor(x + 0.5);
- vec3 a0 = x - ox;
- m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h );
- vec3 g;
- g.x = a0.x * x0.x + h.x * x0.y;
- g.yz = a0.yz * x12.xz + h.yz * x12.yw;
- return 130.0 * dot(m, g);
-}
-
-void main() {
-
- vec2 c = v_texCoord.xy;
- vec4 color = texture2D(u_texture, c);
-
- vec2 v = vec2(1.0/screensize.x, 1.0/screensize.y);
- vec2 coords = vec2(c.x / v.x + camerapos.x, c.y / v.y + camerapos.y);
-
- float stime = time / 5.0;
-
- float mscl = 30.0;
- float mth = 5.0;
-
- if(color.r > 0.01){
- color = texture2D(u_texture, c + vec2(sin(stime/3.0 + coords.y/0.75) * v.x, 0.0)) * vec4(0.9, 0.9, 1, 1.0);
-
- float n1 = snoise(coords / 22.0 + vec2(-time) / 540.0);
- float n2 = snoise((coords + vec2(632.0)) / 8.0 + vec2(0.0, time) / 510.0);
-
- float r = (n1 + n2) / 2.0;
-
- if(r < -0.3 && r > -0.6){
- color *= 1.4;
- }
- }
-
- gl_FragColor = color;
-}
\ No newline at end of file
diff --git a/core/assets/shaders/unitbuild.fragment.glsl b/core/assets/shaders/unitbuild.frag
similarity index 100%
rename from core/assets/shaders/unitbuild.fragment.glsl
rename to core/assets/shaders/unitbuild.frag
diff --git a/core/assets/shaders/water.frag b/core/assets/shaders/water.frag
new file mode 100644
index 0000000000..1d2b67f889
--- /dev/null
+++ b/core/assets/shaders/water.frag
@@ -0,0 +1,41 @@
+#ifdef GL_ES
+precision highp float;
+precision mediump int;
+#endif
+
+uniform sampler2D u_texture;
+
+uniform vec2 u_campos;
+uniform vec2 u_resolution;
+uniform float u_time;
+
+varying vec4 v_color;
+varying vec2 v_texCoord;
+
+const float mscl = 40.0;
+const float mth = 7.0;
+
+void main(){
+
+ vec2 c = v_texCoord.xy;
+
+ vec2 v = vec2(1.0/u_resolution.x, 1.0/u_resolution.y);
+ vec2 coords = vec2(c.x / v.x + u_campos.x, c.y / v.y + u_campos.y);
+
+ float stime = u_time / 5.0;
+
+ vec3 color = texture2D(u_texture, c + vec2(sin(stime/3.0 + coords.y/0.75) * v.x, 0.0)).rgb * vec3(0.9, 0.9, 1);
+
+ float tester = mod((coords.x + coords.y*1.1 + sin(stime / 8.0 + coords.x/5.0 - coords.y/100.0)*2.0) +
+ sin(stime / 20.0 + coords.y/3.0) * 1.0 +
+ sin(stime / 10.0 - coords.y/2.0) * 2.0 +
+ sin(stime / 7.0 + coords.y/1.0) * 0.5 +
+ sin(coords.x / 3.0 + coords.y / 2.0) +
+ sin(stime / 20.0 + coords.x/4.0) * 1.0, mscl);
+
+ if(tester < mth){
+ color *= 1.2;
+ }
+
+ gl_FragColor = vec4(color.rgb, 1.0);
+}
\ No newline at end of file
diff --git a/core/assets/shaders/water.fragment.glsl b/core/assets/shaders/water.fragment.glsl
deleted file mode 100644
index bd3e2103e6..0000000000
--- a/core/assets/shaders/water.fragment.glsl
+++ /dev/null
@@ -1,77 +0,0 @@
-#ifdef GL_ES
-precision highp float;
-precision mediump int;
-#endif
-
-uniform sampler2D u_texture;
-
-uniform vec2 camerapos;
-uniform vec2 screensize;
-uniform float time;
-
-varying vec4 v_color;
-varying vec2 v_texCoord;
-
-vec3 permute(vec3 x) { return mod(((x*34.0)+1.0)*x, 289.0); }
-
-float snoise(vec2 v){
- const vec4 C = vec4(0.211324865405187, 0.366025403784439,
- -0.577350269189626, 0.024390243902439);
- vec2 i = floor(v + dot(v, C.yy) );
- vec2 x0 = v - i + dot(i, C.xx);
- vec2 i1;
- i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
- vec4 x12 = x0.xyxy + C.xxzz;
- x12.xy -= i1;
- i = mod(i, 289.0);
- vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 ))
- + i.x + vec3(0.0, i1.x, 1.0 ));
- vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy),
- dot(x12.zw,x12.zw)), 0.0);
- m = m*m ;
- m = m*m ;
- vec3 x = 2.0 * fract(p * C.www) - 1.0;
- vec3 h = abs(x) - 0.5;
- vec3 ox = floor(x + 0.5);
- vec3 a0 = x - ox;
- m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h );
- vec3 g;
- g.x = a0.x * x0.x + h.x * x0.y;
- g.yz = a0.yz * x12.xz + h.yz * x12.yw;
- return 130.0 * dot(m, g);
-}
-
-void main() {
-
- vec2 c = v_texCoord.xy;
- vec4 color = texture2D(u_texture, c) * v_color;
-
- vec2 v = vec2(1.0/screensize.x, 1.0/screensize.y);
- vec2 coords = vec2(c.x / v.x + camerapos.x, c.y / v.y + camerapos.y);
-
- float stime = time / 5.0;
-
- float mscl = 30.0;
- float mth = 5.0;
-
- color = texture2D(u_texture, c + vec2(sin(stime/3.0 + coords.y/0.75) * v.x, 0.0)) * vec4(0.9, 0.9, 1, 1.0);
- color.a = 1.0;
-
- float n1 = snoise(coords / 40.0 + vec2(time) / 200.0);
- float n2 = snoise((coords + vec2(632.0)) / 25.0 + vec2(0.0, -time) / 190.0);
-
- float r = (n1 + n2) * 3.0;
- float tester = mod(float(int(coords.x + coords.y*1.1 + sin(stime / 8.0 + coords.x/5.0 - coords.y/100.0)*2.0)) +
- sin(stime / 20.0 + coords.y/3.0) * 1.0 +
- sin(stime / 10.0 + coords.y/2.0) * 2.0 +
- sin(stime / 7.0 + coords.y/1.0) * 0.5 +
- sin(coords.x + coords.y) +
- sin(stime / 20.0 + coords.x/4.0) * 1.0, mscl) + r;
-
- if(tester < mth){
- color *= 1.2;
- color.a = 1.0;
- }
-
- gl_FragColor = color;
-}
\ No newline at end of file
diff --git a/core/assets/sprites/backgrounds/planet-zero.png b/core/assets/sprites/backgrounds/planet-zero.png
deleted file mode 100644
index b1e13f744c..0000000000
Binary files a/core/assets/sprites/backgrounds/planet-zero.png and /dev/null differ
diff --git a/core/assets/sprites/backgrounds/stars.png b/core/assets/sprites/backgrounds/stars.png
deleted file mode 100644
index 41a8fadb7b..0000000000
Binary files a/core/assets/sprites/backgrounds/stars.png and /dev/null differ
diff --git a/core/assets/sprites/block_colors.png b/core/assets/sprites/block_colors.png
index 9438eab4d9..ed88955a45 100644
Binary files a/core/assets/sprites/block_colors.png and b/core/assets/sprites/block_colors.png differ
diff --git a/core/assets/sprites/noise.png b/core/assets/sprites/noise.png
new file mode 100644
index 0000000000..0c19e36bfa
Binary files /dev/null and b/core/assets/sprites/noise.png differ
diff --git a/core/assets/sprites/sprites.atlas b/core/assets/sprites/sprites.atlas
index 9e6cc7c0f1..138224f476 100644
--- a/core/assets/sprites/sprites.atlas
+++ b/core/assets/sprites/sprites.atlas
@@ -6,5852 +6,5572 @@ filter: Nearest,Nearest
repeat: none
force-projector-top
rotate: false
- xy: 619, 241
+ xy: 1447, 1333
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
mend-projector-top
rotate: false
- xy: 1011, 463
+ xy: 719, 534
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
mender-top
rotate: false
- xy: 1421, 414
+ xy: 1832, 795
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
overdrive-projector-top
rotate: false
- xy: 1011, 397
+ xy: 719, 468
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
shock-mine
rotate: false
- xy: 1489, 236
+ xy: 1558, 777
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
bridge-arrow
rotate: false
- xy: 1251, 330
+ xy: 1145, 489
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
bridge-conveyor-bridge
rotate: false
- xy: 1301, 822
+ xy: 1077, 387
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
bridge-conveyor-end
rotate: false
- xy: 1335, 828
+ xy: 1111, 421
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
center
rotate: false
- xy: 1285, 788
+ xy: 1145, 455
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
armored-conveyor-0-0
rotate: false
- xy: 873, 30
+ xy: 383, 965
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-armored-conveyor-full
rotate: false
- xy: 873, 30
+ xy: 383, 965
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
armored-conveyor-0-1
rotate: false
- xy: 1397, 1212
+ xy: 1, 4
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
armored-conveyor-0-2
rotate: false
- xy: 1158, 998
+ xy: 521, 317
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
armored-conveyor-0-3
rotate: false
- xy: 1301, 856
+ xy: 555, 317
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
armored-conveyor-1-0
rotate: false
- xy: 890, 850
+ xy: 1673, 991
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
armored-conveyor-1-1
rotate: false
- xy: 389, 14
+ xy: 1757, 1033
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
armored-conveyor-1-2
rotate: false
- xy: 423, 9
+ xy: 163, 708
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
armored-conveyor-1-3
rotate: false
- xy: 457, 9
+ xy: 1013, 1422
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
armored-conveyor-2-0
rotate: false
- xy: 491, 9
+ xy: 35, 4
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
armored-conveyor-2-1
rotate: false
- xy: 525, 9
+ xy: 589, 317
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
armored-conveyor-2-2
rotate: false
- xy: 559, 9
+ xy: 1707, 991
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
armored-conveyor-2-3
rotate: false
- xy: 593, 9
+ xy: 1791, 1033
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
armored-conveyor-3-0
rotate: false
- xy: 627, 11
+ xy: 69, 4
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
armored-conveyor-3-1
rotate: false
- xy: 661, 11
+ xy: 623, 317
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
armored-conveyor-3-2
rotate: false
- xy: 1408, 1178
+ xy: 657, 317
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
armored-conveyor-3-3
rotate: false
- xy: 1408, 1144
+ xy: 555, 283
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
armored-conveyor-4-0
rotate: false
- xy: 1408, 1110
+ xy: 555, 249
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
armored-conveyor-4-1
rotate: false
- xy: 1408, 1076
+ xy: 589, 283
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
armored-conveyor-4-2
rotate: false
- xy: 1408, 1042
+ xy: 623, 283
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
armored-conveyor-4-3
rotate: false
- xy: 1408, 1008
+ xy: 589, 249
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
conveyor-0-1
rotate: false
- xy: 1285, 278
+ xy: 1179, 353
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
conveyor-0-2
rotate: false
- xy: 1285, 244
+ xy: 1179, 319
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
conveyor-0-3
rotate: false
- xy: 1319, 788
+ xy: 1009, 285
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
conveyor-1-0
rotate: false
- xy: 1319, 754
+ xy: 1043, 285
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
conveyor-1-1
rotate: false
- xy: 1319, 720
+ xy: 1077, 285
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
conveyor-1-2
rotate: false
- xy: 1319, 686
+ xy: 1111, 285
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
conveyor-1-3
rotate: false
- xy: 1319, 652
+ xy: 1145, 285
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
conveyor-2-0
rotate: false
- xy: 1319, 618
+ xy: 1179, 285
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
conveyor-2-1
rotate: false
- xy: 1319, 584
+ xy: 545, 1279
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
conveyor-2-2
rotate: false
- xy: 1319, 550
+ xy: 691, 302
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
conveyor-2-3
rotate: false
- xy: 1319, 516
+ xy: 725, 302
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
conveyor-3-0
rotate: false
- xy: 1319, 482
+ xy: 691, 268
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
conveyor-3-1
rotate: false
- xy: 1319, 448
+ xy: 759, 302
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
conveyor-3-2
rotate: false
- xy: 1319, 414
+ xy: 725, 268
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
conveyor-3-3
rotate: false
- xy: 1319, 380
+ xy: 793, 302
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
conveyor-4-0
rotate: false
- xy: 1319, 346
+ xy: 759, 268
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
conveyor-4-1
rotate: false
- xy: 1319, 312
+ xy: 827, 302
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
conveyor-4-2
rotate: false
- xy: 1319, 278
+ xy: 793, 268
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
conveyor-4-3
rotate: false
- xy: 1319, 244
+ xy: 861, 302
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
plastanium-conveyor-0-0
rotate: false
- xy: 1387, 192
+ xy: 1218, 769
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
plastanium-conveyor-1-0
rotate: false
- xy: 1421, 176
+ xy: 1218, 735
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
plastanium-conveyor-2-0
rotate: false
- xy: 1455, 746
+ xy: 1252, 769
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
plastanium-conveyor-3-0
rotate: false
- xy: 1455, 712
+ xy: 1218, 701
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
plastanium-conveyor-4-0
rotate: false
- xy: 1489, 746
+ xy: 1252, 735
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
plastanium-conveyor-5-0
rotate: false
- xy: 1455, 678
+ xy: 1218, 667
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
plastanium-conveyor-6-0
rotate: false
- xy: 1489, 712
+ xy: 1252, 701
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
plastanium-conveyor-7-0
rotate: false
- xy: 1455, 644
+ xy: 1252, 667
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
titanium-conveyor-0-1
rotate: false
- xy: 1455, 168
+ xy: 1456, 675
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
titanium-conveyor-0-2
rotate: false
- xy: 1489, 168
+ xy: 1490, 709
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
titanium-conveyor-0-3
rotate: false
- xy: 1523, 746
+ xy: 1524, 743
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
titanium-conveyor-1-0
rotate: false
- xy: 1523, 712
+ xy: 1490, 675
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
titanium-conveyor-1-1
rotate: false
- xy: 1523, 678
+ xy: 1524, 709
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
titanium-conveyor-1-2
rotate: false
- xy: 1523, 644
+ xy: 1558, 743
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
titanium-conveyor-1-3
rotate: false
- xy: 1523, 610
+ xy: 1524, 675
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
titanium-conveyor-2-0
rotate: false
- xy: 1523, 576
+ xy: 1558, 709
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
titanium-conveyor-2-1
rotate: false
- xy: 1523, 542
+ xy: 1558, 675
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
titanium-conveyor-2-2
rotate: false
- xy: 1523, 508
+ xy: 1592, 751
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
titanium-conveyor-2-3
rotate: false
- xy: 1523, 474
+ xy: 1592, 717
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
titanium-conveyor-3-0
rotate: false
- xy: 1523, 440
+ xy: 1592, 683
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
titanium-conveyor-3-1
rotate: false
- xy: 1523, 406
+ xy: 1218, 633
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
titanium-conveyor-3-2
rotate: false
- xy: 1523, 372
+ xy: 1252, 633
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
titanium-conveyor-3-3
rotate: false
- xy: 1523, 338
+ xy: 1286, 641
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
titanium-conveyor-4-0
rotate: false
- xy: 1523, 304
+ xy: 1320, 641
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
titanium-conveyor-4-1
rotate: false
- xy: 1523, 270
+ xy: 1354, 641
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
titanium-conveyor-4-2
rotate: false
- xy: 1523, 236
+ xy: 1388, 641
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
titanium-conveyor-4-3
rotate: false
- xy: 1523, 202
+ xy: 1422, 641
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
+cross
+ rotate: false
+ xy: 895, 297
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+mass-conveyor-edge
+ rotate: false
+ xy: 583, 1373
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+mass-conveyor-top
+ rotate: false
+ xy: 681, 1373
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
mass-driver-base
rotate: false
- xy: 758, 848
+ xy: 877, 1358
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
phase-conveyor-arrow
rotate: false
- xy: 1421, 278
+ xy: 1866, 761
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
phase-conveyor-bridge
rotate: false
- xy: 1421, 244
+ xy: 1218, 803
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
phase-conveyor-end
rotate: false
- xy: 1421, 210
+ xy: 1252, 803
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
underflow-gate
rotate: false
- xy: 1369, 158
+ xy: 1490, 641
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
blast-drill
rotate: false
- xy: 204, 992
+ xy: 1676, 1919
size: 128, 128
orig: 128, 128
offset: 0, 0
index: -1
blast-drill-rim
rotate: false
- xy: 334, 992
+ xy: 1, 38
size: 128, 128
orig: 128, 128
offset: 0, 0
index: -1
blast-drill-rotator
rotate: false
- xy: 477, 1370
+ xy: 1806, 1919
size: 128, 128
orig: 128, 128
offset: 0, 0
index: -1
blast-drill-top
rotate: false
- xy: 413, 1240
+ xy: 825, 1716
size: 128, 128
orig: 128, 128
offset: 0, 0
index: -1
drill-top
rotate: false
- xy: 988, 925
+ xy: 732, 864
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
turbine-generator-liquid
rotate: false
- xy: 988, 925
+ xy: 732, 864
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
laser-drill
rotate: false
- xy: 717, 533
+ xy: 423, 413
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
laser-drill-rim
rotate: false
- xy: 717, 435
+ xy: 423, 315
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
laser-drill-rotator
rotate: false
- xy: 717, 337
+ xy: 457, 217
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
laser-drill-top
rotate: false
- xy: 717, 239
+ xy: 1839, 1267
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
mechanical-drill
rotate: false
- xy: 1077, 661
+ xy: 798, 666
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
mechanical-drill-rotator
rotate: false
- xy: 1011, 529
+ xy: 864, 666
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
mechanical-drill-top
rotate: false
- xy: 1077, 595
+ xy: 719, 600
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
oil-extractor
rotate: false
- xy: 749, 750
+ xy: 583, 1275
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
oil-extractor-liquid
rotate: false
- xy: 815, 652
+ xy: 681, 1275
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
oil-extractor-rotator
rotate: false
- xy: 815, 554
+ xy: 779, 1260
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
oil-extractor-top
rotate: false
- xy: 815, 456
+ xy: 877, 1260
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
pneumatic-drill
rotate: false
- xy: 1119, 331
+ xy: 785, 402
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
pneumatic-drill-rotator
rotate: false
- xy: 1119, 265
+ xy: 851, 468
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
pneumatic-drill-top
rotate: false
- xy: 1119, 199
+ xy: 851, 402
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
water-extractor
rotate: false
- xy: 1201, 1430
+ xy: 1403, 1103
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
water-extractor-liquid
rotate: false
- xy: 1201, 1364
+ xy: 1469, 1169
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
water-extractor-rotator
rotate: false
- xy: 1135, 1298
+ xy: 1403, 1037
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
water-extractor-top
rotate: false
- xy: 1267, 1430
+ xy: 1469, 1103
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
block-border
rotate: false
- xy: 1370, 938
+ xy: 1688, 923
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-middle
rotate: false
- xy: 1548, 1296
+ xy: 1150, 795
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-select
rotate: false
- xy: 1853, 1262
+ xy: 1077, 557
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
conduit-liquid
rotate: false
- xy: 1285, 550
+ xy: 1077, 319
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
place-arrow
rotate: false
- xy: 815, 358
+ xy: 1073, 1317
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
-rubble-1-0
- rotate: false
- xy: 1111, 67
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-rubble-1-1
- rotate: false
- xy: 1111, 1
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-rubble-2-0
- rotate: false
- xy: 1003, 1387
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-rubble-2-1
- rotate: false
- xy: 1003, 1321
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-rubble-3-0
- rotate: false
- xy: 815, 64
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-rubble-3-1
- rotate: false
- xy: 815, 64
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-rubble-4-0
- rotate: false
- xy: 1059, 1496
- size: 128, 128
- orig: 128, 128
- offset: 0, 0
- index: -1
-rubble-4-1
- rotate: false
- xy: 1059, 1496
- size: 128, 128
- orig: 128, 128
- offset: 0, 0
- index: -1
-rubble-5-0
- rotate: false
- xy: 1876, 1886
- size: 160, 160
- orig: 160, 160
- offset: 0, 0
- index: -1
-rubble-5-1
- rotate: false
- xy: 1876, 1886
- size: 160, 160
- orig: 160, 160
- offset: 0, 0
- index: -1
-rubble-6-0
- rotate: false
- xy: 1, 749
- size: 192, 192
- orig: 192, 192
- offset: 0, 0
- index: -1
-rubble-6-1
- rotate: false
- xy: 1, 749
- size: 192, 192
- orig: 192, 192
- offset: 0, 0
- index: -1
-rubble-7-0
- rotate: false
- xy: 323, 1500
- size: 224, 224
- orig: 224, 224
- offset: 0, 0
- index: -1
-rubble-7-1
- rotate: false
- xy: 323, 1500
- size: 224, 224
- orig: 224, 224
- offset: 0, 0
- index: -1
-rubble-8-0
- rotate: false
- xy: 1, 1146
- size: 256, 256
- orig: 256, 256
- offset: 0, 0
- index: -1
-rubble-8-1
- rotate: false
- xy: 1, 1146
- size: 256, 256
- orig: 256, 256
- offset: 0, 0
- index: -1
bridge-conduit-arrow
rotate: false
- xy: 1251, 296
+ xy: 1179, 523
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
bridge-conveyor-arrow
rotate: false
- xy: 1251, 296
+ xy: 1179, 523
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
bridge-conduit-bridge
rotate: false
- xy: 1251, 262
+ xy: 1009, 319
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
bridge-conduit-end
rotate: false
- xy: 1251, 228
+ xy: 1043, 353
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
conduit-bottom
rotate: false
- xy: 1285, 720
+ xy: 1043, 319
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
conduit-bottom-0
rotate: false
- xy: 1285, 686
+ xy: 1077, 353
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
conduit-bottom-1
rotate: false
- xy: 1285, 652
+ xy: 1111, 387
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
conduit-bottom-2
rotate: false
- xy: 1285, 618
+ xy: 1145, 421
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
conduit-bottom-3
rotate: false
- xy: 1285, 618
+ xy: 1145, 421
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
conduit-bottom-4
rotate: false
- xy: 1285, 618
+ xy: 1145, 421
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
conduit-bottom-6
rotate: false
- xy: 1285, 618
+ xy: 1145, 421
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
conduit-bottom-5
rotate: false
- xy: 1285, 584
+ xy: 1179, 455
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
conduit-top-0
rotate: false
- xy: 1285, 516
+ xy: 1111, 353
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
conduit-top-1
rotate: false
- xy: 1285, 482
+ xy: 1145, 387
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
conduit-top-2
rotate: false
- xy: 1285, 448
+ xy: 1179, 421
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
conduit-top-3
rotate: false
- xy: 1285, 414
+ xy: 1111, 319
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
pulse-conduit-top-3
rotate: false
- xy: 1285, 414
+ xy: 1111, 319
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
conduit-top-4
rotate: false
- xy: 1285, 380
+ xy: 1145, 353
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
conduit-top-5
rotate: false
- xy: 1285, 346
+ xy: 1179, 387
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
conduit-top-6
rotate: false
- xy: 1285, 312
+ xy: 1145, 319
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
liquid-overflow-gate
rotate: false
- xy: 1421, 720
+ xy: 1832, 829
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
liquid-overflow-gate-top
rotate: false
- xy: 1421, 686
+ xy: 1866, 829
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
liquid-router-bottom
rotate: false
- xy: 1421, 652
+ xy: 1594, 785
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
liquid-router-liquid
rotate: false
- xy: 1421, 618
+ xy: 1628, 786
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
liquid-router-top
rotate: false
- xy: 1421, 584
+ xy: 1662, 787
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
liquid-tank-bottom
rotate: false
- xy: 717, 141
+ xy: 1937, 1267
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
liquid-tank-liquid
rotate: false
- xy: 717, 43
+ xy: 523, 119
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
liquid-tank-top
rotate: false
- xy: 1939, 1528
+ xy: 523, 21
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
phase-conduit-arrow
rotate: false
- xy: 1421, 380
+ xy: 1866, 795
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
phase-conduit-bridge
rotate: false
- xy: 1421, 346
+ xy: 1798, 761
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
phase-conduit-end
rotate: false
- xy: 1421, 312
+ xy: 1832, 761
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
plated-conduit-cap
rotate: false
- xy: 1489, 678
+ xy: 1286, 777
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
plated-conduit-top-0
rotate: false
- xy: 1455, 610
+ xy: 1320, 777
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
plated-conduit-top-1
rotate: false
- xy: 1489, 644
+ xy: 1286, 743
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
plated-conduit-top-2
rotate: false
- xy: 1455, 576
+ xy: 1354, 777
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
plated-conduit-top-3
rotate: false
- xy: 1489, 610
+ xy: 1286, 709
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
plated-conduit-top-4
rotate: false
- xy: 1455, 542
+ xy: 1320, 743
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
plated-conduit-top-5
rotate: false
- xy: 1489, 576
+ xy: 1388, 777
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
plated-conduit-top-6
rotate: false
- xy: 1455, 508
+ xy: 1286, 675
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
pulse-conduit-top-0
rotate: false
- xy: 1455, 474
+ xy: 1354, 743
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
pulse-conduit-top-1
rotate: false
- xy: 1489, 508
+ xy: 1422, 777
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
pulse-conduit-top-2
rotate: false
- xy: 1455, 440
+ xy: 1320, 675
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
pulse-conduit-top-4
rotate: false
- xy: 1489, 474
+ xy: 1354, 709
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
pulse-conduit-top-5
rotate: false
- xy: 1455, 406
+ xy: 1388, 743
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
pulse-conduit-top-6
rotate: false
- xy: 1489, 440
+ xy: 1456, 777
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
-battery
+alpha-mech-pad
rotate: false
- xy: 1336, 964
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-battery-full
- rotate: false
- xy: 1336, 964
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-battery-large
- rotate: false
- xy: 527, 1142
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-block-battery-large-full
- rotate: false
- xy: 527, 1142
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-battery-large-top
- rotate: false
- xy: 1547, 1528
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-battery-top
- rotate: false
- xy: 1336, 930
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-combustion-generator-top
- rotate: false
- xy: 1285, 754
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-differential-generator-liquid
- rotate: false
- xy: 619, 631
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-differential-generator-top
- rotate: false
- xy: 619, 533
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-diode-arrow
- rotate: false
- xy: 1335, 176
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-illuminator-top
- rotate: false
- xy: 1335, 40
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-impact-reactor
- rotate: false
- xy: 1586, 1756
- size: 128, 128
- orig: 128, 128
- offset: 0, 0
- index: -1
-impact-reactor-bottom
- rotate: false
- xy: 1716, 1756
- size: 128, 128
- orig: 128, 128
- offset: 0, 0
- index: -1
-impact-reactor-light
- rotate: false
- xy: 1846, 1756
- size: 128, 128
- orig: 128, 128
- offset: 0, 0
- index: -1
-impact-reactor-plasma-0
- rotate: false
- xy: 929, 1585
- size: 128, 128
- orig: 128, 128
- offset: 0, 0
- index: -1
-impact-reactor-plasma-1
- rotate: false
- xy: 1059, 1626
- size: 128, 128
- orig: 128, 128
- offset: 0, 0
- index: -1
-impact-reactor-plasma-2
- rotate: false
- xy: 1189, 1626
- size: 128, 128
- orig: 128, 128
- offset: 0, 0
- index: -1
-impact-reactor-plasma-3
- rotate: false
- xy: 1319, 1626
- size: 128, 128
- orig: 128, 128
- offset: 0, 0
- index: -1
-power-source
- rotate: false
- xy: 1489, 542
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-rtg-generator-top
- rotate: false
- xy: 1489, 338
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-thorium-reactor-center
- rotate: false
- xy: 913, 554
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-thorium-reactor-lights
- rotate: false
- xy: 913, 456
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-turbine-generator-top
- rotate: false
- xy: 1069, 1364
+ xy: 477, 1285
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
-alloy-smelter
+dart-ship-pad
rotate: false
- xy: 1, 3
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-block-alloy-smelter-full
- rotate: false
- xy: 1, 3
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-alloy-smelter-top
- rotate: false
- xy: 1449, 1528
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-blast-mixer
- rotate: false
- xy: 549, 1512
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-blast-mixer-full
- rotate: false
- xy: 549, 1512
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-cryofluidmixer-bottom
- rotate: false
- xy: 937, 1255
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-cryofluidmixer-liquid
- rotate: false
- xy: 921, 1189
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-cryofluidmixer-top
- rotate: false
- xy: 987, 1189
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-cultivator
- rotate: false
- xy: 960, 1123
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-cultivator-middle
- rotate: false
- xy: 960, 1057
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-cultivator-top
- rotate: false
- xy: 960, 991
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-kiln-top
- rotate: false
- xy: 1011, 661
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-silicon-smelter-top
- rotate: false
- xy: 1011, 661
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-phase-weaver
- rotate: false
- xy: 1077, 397
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-phase-weaver-bottom
- rotate: false
- xy: 1053, 331
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-phase-weaver-weave
- rotate: false
- xy: 1053, 265
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-plastanium-compressor-top
- rotate: false
- xy: 1053, 199
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-pulverizer
- rotate: false
- xy: 1455, 372
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-pulverizer-rotator
- rotate: false
- xy: 1489, 406
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-pump-liquid
- rotate: false
- xy: 1455, 338
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-separator-liquid
- rotate: false
- xy: 1143, 661
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-separator-spinner
- rotate: false
- xy: 1143, 595
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-spore-press
- rotate: false
- xy: 1143, 463
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-spore-press-frame0
- rotate: false
- xy: 1143, 397
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-spore-press-frame1
- rotate: false
- xy: 1185, 331
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-spore-press-frame2
- rotate: false
- xy: 1185, 265
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-spore-press-liquid
- rotate: false
- xy: 1185, 199
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-spore-press-top
- rotate: false
- xy: 1177, 133
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-unloader-center
- rotate: false
- xy: 1369, 124
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-arc-heat
- rotate: false
- xy: 856, 850
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-1
- rotate: false
- xy: 1336, 896
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-2
- rotate: false
- xy: 913, 144
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-3
- rotate: false
- xy: 1645, 1528
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-block-4
- rotate: false
- xy: 543, 1240
- size: 128, 128
- orig: 128, 128
- offset: 0, 0
- index: -1
-hail-heat
- rotate: false
- xy: 887, 1592
- size: 40, 40
- orig: 40, 40
- offset: 0, 0
- index: -1
-lancer-heat
- rotate: false
- xy: 1011, 595
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-meltdown-heat
- rotate: false
- xy: 1579, 1626
- size: 128, 128
- orig: 128, 128
- offset: 0, 0
- index: -1
-ripple-heat
- rotate: false
- xy: 815, 162
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-salvo-heat
- rotate: false
- xy: 1053, 1189
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-salvo-panel-left
- rotate: false
- xy: 1092, 1123
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-salvo-panel-right
- rotate: false
- xy: 1092, 1057
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-scorch-heat
- rotate: false
- xy: 1489, 304
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-wave-liquid
- rotate: false
- xy: 1201, 1298
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-crawler-factory
- rotate: false
- xy: 937, 1387
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-dagger-factory
- rotate: false
- xy: 937, 1387
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-draug-factory
- rotate: false
- xy: 937, 1387
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-phantom-factory
- rotate: false
- xy: 937, 1387
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-spirit-factory
- rotate: false
- xy: 937, 1387
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-wraith-factory
- rotate: false
- xy: 937, 1387
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-crawler-factory-top
- rotate: false
- xy: 937, 1321
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-dagger-factory-top
- rotate: false
- xy: 1026, 1123
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-draug-factory-top
- rotate: false
- xy: 1026, 991
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-fortress-factory
- rotate: false
- xy: 619, 143
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-fortress-factory-top
- rotate: false
- xy: 619, 45
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-ghoul-factory-top
- rotate: false
- xy: 619, 45
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-titan-factory-top
- rotate: false
- xy: 619, 45
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-ghoul-factory
- rotate: false
- xy: 717, 631
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-phantom-factory-top
- rotate: false
- xy: 1077, 463
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-rally-point
- rotate: false
- xy: 1111, 133
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-repair-point-base
- rotate: false
- xy: 1455, 304
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-revenant-factory
- rotate: false
- xy: 1709, 1626
- size: 128, 128
- orig: 128, 128
- offset: 0, 0
- index: -1
-revenant-factory-top
- rotate: false
- xy: 1839, 1626
- size: 128, 128
- orig: 128, 128
- offset: 0, 0
- index: -1
-spirit-factory-top
- rotate: false
- xy: 1143, 529
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-titan-factory
- rotate: false
- xy: 913, 358
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-wraith-factory-top
- rotate: false
- xy: 1333, 1430
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-door-large-open
- rotate: false
- xy: 1026, 1057
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-door-open
- rotate: false
- xy: 1335, 142
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-insulator-wall
- rotate: false
- xy: 1335, 6
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-insulator-wall-large
- rotate: false
- xy: 1011, 727
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-scrap-wall-huge2
- rotate: false
- xy: 847, 750
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-scrap-wall-huge3
- rotate: false
- xy: 913, 652
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-scrap-wall-large1
- rotate: false
- xy: 1120, 925
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-scrap-wall-large2
- rotate: false
- xy: 1120, 859
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-scrap-wall-large3
- rotate: false
- xy: 1143, 793
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-scrap-wall-large4
- rotate: false
- xy: 1143, 727
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-scrap-wall2
- rotate: false
- xy: 1455, 236
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-scrap-wall3
- rotate: false
- xy: 1489, 270
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-scrap-wall4
- rotate: false
- xy: 1455, 202
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-scrap-wall5
- rotate: false
- xy: 1455, 202
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-bullet
- rotate: false
- xy: 1293, 1252
- size: 52, 52
- orig: 52, 52
- offset: 0, 0
- index: -1
-bullet-back
- rotate: false
- xy: 1293, 1198
- size: 52, 52
- orig: 52, 52
- offset: 0, 0
- index: -1
-casing
- rotate: false
- xy: 2038, 2030
- size: 8, 16
- orig: 8, 16
- offset: 0, 0
- index: -1
-circle-end
- rotate: false
- xy: 464, 925
- size: 100, 199
- orig: 100, 199
- offset: 0, 0
- index: -1
-circle-mid
- rotate: false
- xy: 1557, 595
- size: 1, 199
- orig: 1, 199
- offset: 0, 0
- index: -1
-circle-shadow
- rotate: false
- xy: 863, 1845
- size: 201, 201
- orig: 201, 201
- offset: 0, 0
- index: -1
-error
- rotate: false
- xy: 1398, 1346
- size: 48, 48
- orig: 48, 48
- offset: 0, 0
- index: -1
-laser
- rotate: false
- xy: 1053, 1535
- size: 4, 48
- orig: 4, 48
- offset: 0, 0
- index: -1
-laser-end
- rotate: false
- xy: 913, 284
- size: 72, 72
- orig: 72, 72
- offset: 0, 0
- index: -1
-minelaser
- rotate: false
- xy: 1053, 1485
- size: 4, 48
- orig: 4, 48
- offset: 0, 0
- index: -1
-minelaser-end
- rotate: false
- xy: 549, 1578
- size: 72, 72
- orig: 72, 72
- offset: 0, 0
- index: -1
-missile
- rotate: false
- xy: 863, 1807
- size: 36, 36
- orig: 36, 36
- offset: 0, 0
- index: -1
-missile-back
- rotate: false
- xy: 921, 1151
- size: 36, 36
- orig: 36, 36
- offset: 0, 0
- index: -1
-scale_marker
- rotate: false
- xy: 723, 1142
- size: 4, 4
- orig: 4, 4
- offset: 0, 0
- index: -1
-scorch1
- rotate: false
- xy: 1369, 22
- size: 28, 100
- orig: 28, 100
- offset: 0, 0
- index: -1
-scorch2
- rotate: false
- xy: 1540, 848
- size: 28, 100
- orig: 28, 100
- offset: 0, 0
- index: -1
-scorch3
- rotate: false
- xy: 1399, 22
- size: 28, 100
- orig: 28, 100
- offset: 0, 0
- index: -1
-scorch4
- rotate: false
- xy: 1544, 1120
- size: 28, 100
- orig: 28, 100
- offset: 0, 0
- index: -1
-scorch5
- rotate: false
- xy: 1544, 1018
- size: 28, 100
- orig: 28, 100
- offset: 0, 0
- index: -1
-shell
- rotate: false
- xy: 1011, 359
- size: 36, 36
- orig: 36, 36
- offset: 0, 0
- index: -1
-shell-back
- rotate: false
- xy: 1053, 161
- size: 36, 36
- orig: 36, 36
- offset: 0, 0
- index: -1
-shot
- rotate: false
- xy: 1489, 202
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-transfer
- rotate: false
- xy: 907, 14
- size: 4, 48
- orig: 4, 48
- offset: 0, 0
- index: -1
-transfer-arrow
- rotate: false
- xy: 1523, 168
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-transfer-end
- rotate: false
- xy: 913, 210
- size: 72, 72
- orig: 72, 72
- offset: 0, 0
- index: -1
-white
- rotate: false
- xy: 1204, 885
- size: 3, 3
- orig: 3, 3
- offset: 0, 0
- index: -1
-arc
- rotate: false
- xy: 389, 48
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-arc-full
- rotate: false
- xy: 1370, 972
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-blast-drill-full
- rotate: false
- xy: 799, 1676
- size: 128, 128
- orig: 128, 128
- offset: 0, 0
- index: -1
-block-bridge-conduit-full
- rotate: false
- xy: 1370, 904
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-bridge-conduit
- rotate: false
- xy: 1370, 904
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-bridge-conveyor-full
- rotate: false
- xy: 1442, 1196
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-bridge-conveyor
- rotate: false
- xy: 1442, 1196
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-char-full
- rotate: false
- xy: 1442, 1162
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-cliffs-full
- rotate: false
- xy: 1442, 1128
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-coal-centrifuge-full
- rotate: false
- xy: 913, 78
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-coal-centrifuge
- rotate: false
- xy: 913, 78
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-combustion-generator-full
- rotate: false
- xy: 1442, 1094
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-combustion-generator
- rotate: false
- xy: 1442, 1094
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-command-center-full
- rotate: false
- xy: 1976, 1820
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-command-center
- rotate: false
- xy: 1976, 1820
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-conduit-full
- rotate: false
- xy: 1442, 1060
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-container-full
- rotate: false
- xy: 1976, 1754
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-container
- rotate: false
- xy: 1976, 1754
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-conveyor-full
- rotate: false
- xy: 1442, 1026
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-conveyor-0-0
- rotate: false
- xy: 1442, 1026
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-copper-wall-full
- rotate: false
- xy: 1442, 992
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-copper-wall
- rotate: false
- xy: 1442, 992
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-copper-wall-large-full
- rotate: false
- xy: 1969, 1688
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-copper-wall-large
- rotate: false
- xy: 1969, 1688
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-core-foundation-full
- rotate: false
- xy: 929, 1715
- size: 128, 128
- orig: 128, 128
- offset: 0, 0
- index: -1
-core-foundation
- rotate: false
- xy: 929, 1715
- size: 128, 128
- orig: 128, 128
- offset: 0, 0
- index: -1
-block-core-nucleus-full
- rotate: false
- xy: 1066, 1886
- size: 160, 160
- orig: 160, 160
- offset: 0, 0
- index: -1
-core-nucleus
- rotate: false
- xy: 1066, 1886
- size: 160, 160
- orig: 160, 160
- offset: 0, 0
- index: -1
-block-core-shard-full
- rotate: false
- xy: 1743, 1528
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-core-shard
- rotate: false
- xy: 1743, 1528
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-block-craters-full
- rotate: false
- xy: 1408, 974
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-crawler-factory-full
- rotate: false
- xy: 623, 1614
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-cryofluidmixer-full
- rotate: false
- xy: 689, 1614
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-cultivator-full
- rotate: false
- xy: 623, 1548
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-cyclone-full
- rotate: false
- xy: 1841, 1528
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-block-dagger-factory-full
- rotate: false
- xy: 689, 1548
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-dark-metal-full
- rotate: false
- xy: 1404, 940
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-dark-panel-1-full
- rotate: false
- xy: 1404, 906
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-dark-panel-2-full
- rotate: false
- xy: 1442, 958
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-dark-panel-3-full
- rotate: false
- xy: 1438, 924
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-dark-panel-4-full
- rotate: false
- xy: 1438, 890
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-dark-panel-5-full
- rotate: false
- xy: 1404, 872
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-dark-panel-6-full
- rotate: false
- xy: 1370, 870
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-darksand-full
- rotate: false
- xy: 1336, 862
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-darksand-tainted-water-full
- rotate: false
- xy: 1438, 856
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-darksand-water-full
- rotate: false
- xy: 1404, 838
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-dart-mech-pad-full
- rotate: false
- xy: 615, 1482
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-dart-mech-pad
- rotate: false
- xy: 615, 1482
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-deepwater-full
- rotate: false
- xy: 1370, 836
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-delta-mech-pad-full
- rotate: false
- xy: 681, 1482
+ xy: 743, 996
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
delta-mech-pad
rotate: false
- xy: 681, 1482
+ xy: 809, 996
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
-block-differential-generator-full
- rotate: false
- xy: 464, 827
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-differential-generator
- rotate: false
- xy: 464, 827
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-block-diode-full
- rotate: false
- xy: 1438, 822
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-diode
- rotate: false
- xy: 1438, 822
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-distributor-full
- rotate: false
- xy: 607, 1416
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-distributor
- rotate: false
- xy: 607, 1416
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-door-full
- rotate: false
- xy: 1404, 804
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-door
- rotate: false
- xy: 1404, 804
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-door-large-full
- rotate: false
- xy: 673, 1416
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-door-large
- rotate: false
- xy: 673, 1416
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-draug-factory-full
- rotate: false
- xy: 987, 292
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-dunerocks-full
- rotate: false
- xy: 1438, 788
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-duo-full
- rotate: false
- xy: 1476, 1188
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-force-projector-full
- rotate: false
- xy: 455, 729
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-force-projector
- rotate: false
- xy: 455, 729
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-block-fortress-factory-full
- rotate: false
- xy: 423, 631
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-block-fuse-full
- rotate: false
- xy: 423, 533
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-block-ghoul-factory-full
- rotate: false
- xy: 423, 435
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-block-glaive-ship-pad-full
- rotate: false
- xy: 423, 337
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
glaive-ship-pad
rotate: false
- xy: 423, 337
+ xy: 423, 609
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
-block-graphite-press-full
- rotate: false
- xy: 987, 226
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-graphite-press
- rotate: false
- xy: 987, 226
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-grass-full
- rotate: false
- xy: 1476, 1154
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-hail-full
- rotate: false
- xy: 1510, 1188
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-holostone-full
- rotate: false
- xy: 1476, 1120
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-hotrock-full
- rotate: false
- xy: 1510, 1154
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-ice-full
- rotate: false
- xy: 1476, 1086
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-ice-snow-full
- rotate: false
- xy: 1510, 1120
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-icerocks-full
- rotate: false
- xy: 1476, 1052
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-ignarock-full
- rotate: false
- xy: 1510, 1086
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-illuminator-full
- rotate: false
- xy: 1476, 1018
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-illuminator
- rotate: false
- xy: 1476, 1018
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-impact-reactor-full
- rotate: false
- xy: 204, 862
- size: 128, 128
- orig: 128, 128
- offset: 0, 0
- index: -1
-block-incinerator-full
- rotate: false
- xy: 1510, 1052
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-incinerator
- rotate: false
- xy: 1510, 1052
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-inverted-sorter-full
- rotate: false
- xy: 1476, 984
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-inverted-sorter
- rotate: false
- xy: 1476, 984
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-item-source-full
- rotate: false
- xy: 1510, 1018
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-item-source
- rotate: false
- xy: 1510, 1018
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-item-void-full
- rotate: false
- xy: 1510, 984
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-item-void
- rotate: false
- xy: 1510, 984
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-javelin-ship-pad-full
- rotate: false
- xy: 755, 1610
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
javelin-ship-pad
rotate: false
- xy: 755, 1610
+ xy: 798, 732
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
-block-junction-full
- rotate: false
- xy: 1476, 950
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-junction
- rotate: false
- xy: 1476, 950
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-kiln-full
- rotate: false
- xy: 821, 1610
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-kiln
- rotate: false
- xy: 821, 1610
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-lancer-full
- rotate: false
- xy: 755, 1544
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-laser-drill-full
- rotate: false
- xy: 423, 239
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-block-launch-pad-full
- rotate: false
- xy: 423, 141
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-launch-pad
- rotate: false
- xy: 423, 141
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-block-launch-pad-large-full
- rotate: false
- xy: 334, 862
- size: 128, 128
- orig: 128, 128
- offset: 0, 0
- index: -1
-launch-pad-large
- rotate: false
- xy: 334, 862
- size: 128, 128
- orig: 128, 128
- offset: 0, 0
- index: -1
-block-liquid-junction-full
- rotate: false
- xy: 1510, 950
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-liquid-junction
- rotate: false
- xy: 1510, 950
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-liquid-router-full
- rotate: false
- xy: 1472, 916
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-liquid-source-full
- rotate: false
- xy: 1472, 882
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-liquid-source
- rotate: false
- xy: 1472, 882
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-liquid-tank-full
- rotate: false
- xy: 423, 43
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-block-liquid-void-full
- rotate: false
- xy: 1506, 916
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-liquid-void
- rotate: false
- xy: 1506, 916
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-magmarock-full
- rotate: false
- xy: 1472, 848
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-mass-driver-full
- rotate: false
- xy: 625, 1142
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-block-mechanical-drill-full
- rotate: false
- xy: 821, 1544
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-mechanical-pump-full
- rotate: false
- xy: 1506, 882
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-mechanical-pump
- rotate: false
- xy: 1506, 882
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-meltdown-full
- rotate: false
- xy: 195, 732
- size: 128, 128
- orig: 128, 128
- offset: 0, 0
- index: -1
-block-melter-full
- rotate: false
- xy: 1472, 814
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-melter
- rotate: false
- xy: 1472, 814
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-mend-projector-full
- rotate: false
- xy: 747, 1478
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-mend-projector
- rotate: false
- xy: 747, 1478
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-mender-full
- rotate: false
- xy: 1506, 848
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-mender
- rotate: false
- xy: 1506, 848
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-message-full
- rotate: false
- xy: 1506, 814
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-message
- rotate: false
- xy: 1506, 814
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-metal-floor-2-full
- rotate: false
- xy: 1472, 780
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-metal-floor-3-full
- rotate: false
- xy: 1506, 780
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-metal-floor-5-full
- rotate: false
- xy: 695, 9
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-metal-floor-damaged-full
- rotate: false
- xy: 729, 9
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-metal-floor-full
- rotate: false
- xy: 763, 9
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-moss-full
- rotate: false
- xy: 1582, 1296
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-multi-press-full
- rotate: false
- xy: 566, 1044
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-multi-press
- rotate: false
- xy: 566, 1044
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-block-oil-extractor-full
- rotate: false
- xy: 566, 946
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-block-omega-mech-pad-full
- rotate: false
- xy: 664, 1044
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
omega-mech-pad
rotate: false
- xy: 664, 1044
+ xy: 975, 1317
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
-block-ore-coal-full
- rotate: false
- xy: 1616, 1296
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-ore-copper-full
- rotate: false
- xy: 1650, 1296
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-ore-lead-full
- rotate: false
- xy: 1684, 1296
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-ore-scrap-full
- rotate: false
- xy: 1718, 1296
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-ore-thorium-full
- rotate: false
- xy: 1752, 1296
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-ore-titanium-full
- rotate: false
- xy: 1786, 1296
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-overdrive-projector-full
- rotate: false
- xy: 813, 1478
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-overdrive-projector
- rotate: false
- xy: 813, 1478
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-overflow-gate-full
- rotate: false
- xy: 1820, 1296
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-overflow-gate
- rotate: false
- xy: 1820, 1296
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-pebbles-full
- rotate: false
- xy: 1854, 1296
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-phantom-factory-full
- rotate: false
- xy: 739, 1412
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-phase-conduit-full
- rotate: false
- xy: 1888, 1296
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-phase-conduit
- rotate: false
- xy: 1888, 1296
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-phase-conveyor-full
- rotate: false
- xy: 1922, 1296
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-phase-conveyor
- rotate: false
- xy: 1922, 1296
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-phase-wall-full
- rotate: false
- xy: 1956, 1296
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-phase-wall
- rotate: false
- xy: 1956, 1296
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-phase-wall-large-full
- rotate: false
- xy: 805, 1412
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-phase-wall-large
- rotate: false
- xy: 805, 1412
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-phase-weaver-full
- rotate: false
- xy: 673, 1350
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-pine-full
- rotate: false
- xy: 1158, 1082
- size: 48, 48
- orig: 48, 48
- offset: 0, 0
- index: -1
-block-plastanium-compressor-full
- rotate: false
- xy: 673, 1284
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-plastanium-compressor
- rotate: false
- xy: 673, 1284
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-plastanium-conveyor-full
- rotate: false
- xy: 1990, 1296
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-plastanium-wall-full
- rotate: false
- xy: 1547, 1262
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-plastanium-wall
- rotate: false
- xy: 1547, 1262
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-plastanium-wall-large-full
- rotate: false
- xy: 739, 1346
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-plastanium-wall-large
- rotate: false
- xy: 739, 1346
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-plated-conduit-full
- rotate: false
- xy: 1547, 1228
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-pneumatic-drill-full
- rotate: false
- xy: 805, 1346
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-power-node-full
- rotate: false
- xy: 1581, 1262
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-power-node
- rotate: false
- xy: 1581, 1262
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-power-node-large-full
- rotate: false
- xy: 739, 1280
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-power-node-large
- rotate: false
- xy: 739, 1280
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-power-source-full
- rotate: false
- xy: 1581, 1228
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-power-void-full
- rotate: false
- xy: 1615, 1262
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-power-void
- rotate: false
- xy: 1615, 1262
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-pulse-conduit-full
- rotate: false
- xy: 1615, 1228
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-pulverizer-full
- rotate: false
- xy: 1649, 1262
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-pyratite-mixer-full
- rotate: false
- xy: 805, 1280
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-pyratite-mixer
- rotate: false
- xy: 805, 1280
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-repair-point-full
- rotate: false
- xy: 1649, 1228
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-revenant-factory-full
- rotate: false
- xy: 325, 732
- size: 128, 128
- orig: 128, 128
- offset: 0, 0
- index: -1
-block-ripple-full
- rotate: false
- xy: 664, 946
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-block-rock-full
- rotate: false
- xy: 1208, 1140
- size: 48, 48
- orig: 48, 48
- offset: 0, 0
- index: -1
-block-rocks-full
- rotate: false
- xy: 1683, 1262
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-rotary-pump-full
- rotate: false
- xy: 987, 160
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-rotary-pump
- rotate: false
- xy: 987, 160
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-router-full
- rotate: false
- xy: 1683, 1228
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-router
- rotate: false
- xy: 1683, 1228
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-rtg-generator-full
- rotate: false
- xy: 979, 94
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-rtg-generator
- rotate: false
- xy: 979, 94
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-salt-full
- rotate: false
- xy: 1717, 1262
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-saltrocks-full
- rotate: false
- xy: 1717, 1228
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-salvo-full
- rotate: false
- xy: 979, 28
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-sand-boulder-full
- rotate: false
- xy: 1751, 1262
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-sand-full
- rotate: false
- xy: 1751, 1228
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-sand-water-full
- rotate: false
- xy: 1785, 1262
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-sandrocks-full
- rotate: false
- xy: 1785, 1228
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-scatter-full
- rotate: false
- xy: 913, 12
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-scorch-full
- rotate: false
- xy: 1819, 1262
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-scrap-wall-full
- rotate: false
- xy: 1819, 1228
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-scrap-wall1
- rotate: false
- xy: 1819, 1228
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-scrap-wall-gigantic-full
- rotate: false
- xy: 163, 602
- size: 128, 128
- orig: 128, 128
- offset: 0, 0
- index: -1
-scrap-wall-gigantic
- rotate: false
- xy: 163, 602
- size: 128, 128
- orig: 128, 128
- offset: 0, 0
- index: -1
-block-scrap-wall-huge-full
- rotate: false
- xy: 1449, 1430
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-scrap-wall-huge1
- rotate: false
- xy: 1449, 1430
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-block-scrap-wall-large-full
- rotate: false
- xy: 723, 1214
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-separator-full
- rotate: false
- xy: 723, 1148
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-separator
- rotate: false
- xy: 723, 1148
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-shale-boulder-full
- rotate: false
- xy: 1853, 1228
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-shale-full
- rotate: false
- xy: 1887, 1262
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-shalerocks-full
- rotate: false
- xy: 1887, 1228
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-shock-mine-full
- rotate: false
- xy: 1921, 1262
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-shrubs-full
- rotate: false
- xy: 1921, 1228
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-silicon-smelter-full
- rotate: false
- xy: 789, 1214
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-silicon-smelter
- rotate: false
- xy: 789, 1214
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-snow-full
- rotate: false
- xy: 1955, 1262
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-snow-pine-full
- rotate: false
- xy: 1158, 1032
- size: 48, 48
- orig: 48, 48
- offset: 0, 0
- index: -1
-block-snowrock-full
- rotate: false
- xy: 1208, 1090
- size: 48, 48
- orig: 48, 48
- offset: 0, 0
- index: -1
-block-snowrocks-full
- rotate: false
- xy: 1955, 1228
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-solar-panel-full
- rotate: false
- xy: 1989, 1262
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-solar-panel
- rotate: false
- xy: 1989, 1262
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-solar-panel-large-full
- rotate: false
- xy: 1547, 1430
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-solar-panel-large
- rotate: false
- xy: 1547, 1430
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-block-sorter-full
- rotate: false
- xy: 1989, 1228
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-sorter
- rotate: false
- xy: 1989, 1228
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-spawn-full
- rotate: false
- xy: 1251, 806
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-spectre-full
- rotate: false
- xy: 163, 472
- size: 128, 128
- orig: 128, 128
- offset: 0, 0
- index: -1
-block-spirit-factory-full
- rotate: false
- xy: 789, 1148
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-spore-cluster-full
- rotate: false
- xy: 887, 1634
- size: 40, 40
- orig: 40, 40
- offset: 0, 0
- index: -1
-block-spore-moss-full
- rotate: false
- xy: 1251, 772
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-spore-pine-full
- rotate: false
- xy: 1208, 1040
- size: 48, 48
- orig: 48, 48
- offset: 0, 0
- index: -1
-block-spore-press-full
- rotate: false
- xy: 762, 1082
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-sporerocks-full
- rotate: false
- xy: 1251, 738
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-stone-full
- rotate: false
- xy: 1251, 704
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-surge-tower-full
- rotate: false
- xy: 762, 1016
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-surge-tower
- rotate: false
- xy: 762, 1016
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-surge-wall-full
- rotate: false
- xy: 1251, 670
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-surge-wall
- rotate: false
- xy: 1251, 670
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-surge-wall-large-full
- rotate: false
- xy: 762, 950
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-surge-wall-large
- rotate: false
- xy: 762, 950
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-swarmer-full
- rotate: false
- xy: 828, 1082
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-tainted-water-full
- rotate: false
- xy: 1251, 636
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-tar-full
- rotate: false
- xy: 1251, 602
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-tau-mech-pad-full
- rotate: false
- xy: 828, 1016
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
tau-mech-pad
rotate: false
- xy: 828, 1016
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-tendrils-full
- rotate: false
- xy: 1251, 568
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-thermal-generator-full
- rotate: false
- xy: 828, 950
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-thermal-generator
- rotate: false
- xy: 828, 950
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-thermal-pump-full
- rotate: false
- xy: 1645, 1430
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-thermal-pump
- rotate: false
- xy: 1645, 1430
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-block-thorium-reactor-full
- rotate: false
- xy: 1743, 1430
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-thorium-reactor
- rotate: false
- xy: 1743, 1430
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-block-thorium-wall-full
- rotate: false
- xy: 1251, 534
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-thorium-wall
- rotate: false
- xy: 1251, 534
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-thorium-wall-large-full
- rotate: false
- xy: 856, 884
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-thorium-wall-large
- rotate: false
- xy: 856, 884
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-thruster-full
- rotate: false
- xy: 293, 602
- size: 128, 128
- orig: 128, 128
- offset: 0, 0
- index: -1
-thruster
- rotate: false
- xy: 293, 602
- size: 128, 128
- orig: 128, 128
- offset: 0, 0
- index: -1
-block-titan-factory-full
- rotate: false
- xy: 1841, 1430
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-block-titanium-conveyor-full
- rotate: false
- xy: 1251, 500
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-titanium-conveyor-0-0
- rotate: false
- xy: 1251, 500
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-titanium-wall-full
- rotate: false
- xy: 1251, 466
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-titanium-wall
- rotate: false
- xy: 1251, 466
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-titanium-wall-large-full
- rotate: false
- xy: 855, 1214
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-titanium-wall-large
- rotate: false
- xy: 855, 1214
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-block-trident-ship-pad-full
- rotate: false
- xy: 855, 1148
+ xy: 1337, 1169
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
trident-ship-pad
rotate: false
- xy: 855, 1148
+ xy: 1403, 1169
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+battery
+ rotate: false
+ xy: 657, 283
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-battery-full
+ rotate: false
+ xy: 657, 283
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+battery-large
+ rotate: false
+ xy: 1291, 1529
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+block-battery-large-full
+ rotate: false
+ xy: 1291, 1529
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+battery-large-top
+ rotate: false
+ xy: 1389, 1529
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+battery-top
+ rotate: false
+ xy: 623, 249
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+combustion-generator-top
+ rotate: false
+ xy: 1179, 489
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+differential-generator-liquid
+ rotate: false
+ xy: 1251, 1333
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+differential-generator-top
+ rotate: false
+ xy: 1349, 1333
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+diode-arrow
+ rotate: false
+ xy: 929, 297
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+illuminator-top
+ rotate: false
+ xy: 895, 229
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+impact-reactor
+ rotate: false
+ xy: 1215, 1627
+ size: 128, 128
+ orig: 128, 128
+ offset: 0, 0
+ index: -1
+impact-reactor-bottom
+ rotate: false
+ xy: 1345, 1627
+ size: 128, 128
+ orig: 128, 128
+ offset: 0, 0
+ index: -1
+impact-reactor-light
+ rotate: false
+ xy: 1475, 1627
+ size: 128, 128
+ orig: 128, 128
+ offset: 0, 0
+ index: -1
+impact-reactor-plasma-0
+ rotate: false
+ xy: 1605, 1627
+ size: 128, 128
+ orig: 128, 128
+ offset: 0, 0
+ index: -1
+impact-reactor-plasma-1
+ rotate: false
+ xy: 1735, 1659
+ size: 128, 128
+ orig: 128, 128
+ offset: 0, 0
+ index: -1
+impact-reactor-plasma-2
+ rotate: false
+ xy: 1865, 1659
+ size: 128, 128
+ orig: 128, 128
+ offset: 0, 0
+ index: -1
+impact-reactor-plasma-3
+ rotate: false
+ xy: 293, 575
+ size: 128, 128
+ orig: 128, 128
+ offset: 0, 0
+ index: -1
+power-source
+ rotate: false
+ xy: 1320, 709
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+rtg-generator-top
+ rotate: false
+ xy: 1422, 709
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+thorium-reactor-center
+ rotate: false
+ xy: 1367, 1235
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+thorium-reactor-lights
+ rotate: false
+ xy: 1465, 1235
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+turbine-generator-top
+ rotate: false
+ xy: 1337, 1037
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+alloy-smelter
+ rotate: false
+ xy: 1936, 1951
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+block-alloy-smelter-full
+ rotate: false
+ xy: 1936, 1951
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+alloy-smelter-top
+ rotate: false
+ xy: 1193, 1529
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+blast-mixer
+ rotate: false
+ xy: 583, 1499
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+block-blast-mixer-full
+ rotate: false
+ xy: 583, 1499
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+cryofluidmixer-bottom
+ rotate: false
+ xy: 809, 1194
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+cryofluidmixer-liquid
+ rotate: false
+ xy: 743, 1062
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+cryofluidmixer-top
+ rotate: false
+ xy: 809, 1128
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+cultivator
+ rotate: false
+ xy: 875, 1194
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+cultivator-middle
+ rotate: false
+ xy: 809, 1062
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+cultivator-top
+ rotate: false
+ xy: 875, 1128
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+kiln-top
+ rotate: false
+ xy: 864, 798
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+silicon-smelter-top
+ rotate: false
+ xy: 864, 798
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+phase-weaver
+ rotate: false
+ xy: 851, 600
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+phase-weaver-bottom
+ rotate: false
+ xy: 719, 402
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+phase-weaver-weave
+ rotate: false
+ xy: 785, 468
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+plastanium-compressor-top
+ rotate: false
+ xy: 851, 534
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+pulverizer
+ rotate: false
+ xy: 1354, 675
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+pulverizer-rotator
+ rotate: false
+ xy: 1388, 709
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+pump-liquid
+ rotate: false
+ xy: 1422, 743
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+separator-liquid
+ rotate: false
+ xy: 1073, 1087
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+separator-spinner
+ rotate: false
+ xy: 1073, 1021
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+spore-press
+ rotate: false
+ xy: 1139, 1087
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+spore-press-frame0
+ rotate: false
+ xy: 1139, 1021
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+spore-press-frame1
+ rotate: false
+ xy: 1205, 1169
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+spore-press-frame2
+ rotate: false
+ xy: 1205, 1103
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+spore-press-liquid
+ rotate: false
+ xy: 1271, 1169
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+spore-press-top
+ rotate: false
+ xy: 1205, 1037
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+unloader-center
+ rotate: false
+ xy: 1524, 641
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+arc-heat
+ rotate: false
+ xy: 941, 1226
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-1
+ rotate: false
+ xy: 657, 249
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-2
+ rotate: false
+ xy: 479, 1219
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+block-3
+ rotate: false
+ xy: 1487, 1529
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+block-4
+ rotate: false
+ xy: 819, 1586
+ size: 128, 128
+ orig: 128, 128
+ offset: 0, 0
+ index: -1
+hail-heat
+ rotate: false
+ xy: 1288, 845
+ size: 40, 40
+ orig: 40, 40
+ offset: 0, 0
+ index: -1
+lancer-heat
+ rotate: false
+ xy: 732, 666
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+meltdown-heat
+ rotate: false
+ xy: 293, 315
+ size: 128, 128
+ orig: 128, 128
+ offset: 0, 0
+ index: -1
+ripple-heat
+ rotate: false
+ xy: 1073, 1219
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+salvo-heat
+ rotate: false
+ xy: 851, 336
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+salvo-panel-left
+ rotate: false
+ xy: 941, 1153
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+salvo-panel-right
+ rotate: false
+ xy: 941, 1087
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+scorch-heat
+ rotate: false
+ xy: 1524, 777
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+wave-liquid
+ rotate: false
+ xy: 1469, 1037
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+command-center
+ rotate: false
+ xy: 521, 417
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+crawler-factory
+ rotate: false
+ xy: 743, 1194
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+dagger-factory
+ rotate: false
+ xy: 743, 1194
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+draug-factory
+ rotate: false
+ xy: 743, 1194
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+phantom-factory
+ rotate: false
+ xy: 743, 1194
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+spirit-factory
+ rotate: false
+ xy: 743, 1194
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+wraith-factory
+ rotate: false
+ xy: 743, 1194
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+crawler-factory-top
+ rotate: false
+ xy: 743, 1128
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+dagger-factory-top
+ rotate: false
+ xy: 875, 1062
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+draug-factory-top
+ rotate: false
+ xy: 732, 930
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+fortress-factory
+ rotate: false
+ xy: 1545, 1333
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+fortress-factory-top
+ rotate: false
+ xy: 1643, 1333
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+ghoul-factory-top
+ rotate: false
+ xy: 1643, 1333
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+ground-factory-top
+ rotate: false
+ xy: 1643, 1333
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+titan-factory-top
+ rotate: false
+ xy: 1643, 1333
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+ghoul-factory
+ rotate: false
+ xy: 436, 707
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+ground-factory
+ rotate: false
+ xy: 423, 511
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+phantom-factory-top
+ rotate: false
+ xy: 785, 534
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+rally-point
+ rotate: false
+ xy: 719, 336
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+repair-point-base
+ rotate: false
+ xy: 1388, 675
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+revenant-factory
+ rotate: false
+ xy: 665, 1471
+ size: 128, 128
+ orig: 128, 128
+ offset: 0, 0
+ index: -1
+revenant-factory-top
+ rotate: false
+ xy: 795, 1456
+ size: 128, 128
+ orig: 128, 128
+ offset: 0, 0
+ index: -1
+spirit-factory-top
+ rotate: false
+ xy: 1139, 1153
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+titan-factory
+ rotate: false
+ xy: 1563, 1235
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+wraith-factory-top
+ rotate: false
+ xy: 1535, 1103
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+door-large-open
+ rotate: false
+ xy: 875, 996
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+door-open
+ rotate: false
+ xy: 895, 263
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+insulator-wall
+ rotate: false
+ xy: 929, 229
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+insulator-wall-large
+ rotate: false
+ xy: 864, 864
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+scrap-wall-huge2
+ rotate: false
+ xy: 1171, 1235
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+scrap-wall-huge3
+ rotate: false
+ xy: 1269, 1235
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+scrap-wall-large1
+ rotate: false
+ xy: 941, 1021
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+scrap-wall-large2
+ rotate: false
+ xy: 1007, 1087
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+scrap-wall-large3
+ rotate: false
+ xy: 1073, 1153
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+scrap-wall-large4
+ rotate: false
+ xy: 1007, 1021
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+scrap-wall2
+ rotate: false
+ xy: 1422, 675
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+scrap-wall3
+ rotate: false
+ xy: 1456, 709
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+scrap-wall4
+ rotate: false
+ xy: 1490, 743
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+scrap-wall5
+ rotate: false
+ xy: 1490, 743
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+bullet
+ rotate: false
+ xy: 1995, 1897
+ size: 52, 52
+ orig: 52, 52
+ offset: 0, 0
+ index: -1
+bullet-back
+ rotate: false
+ xy: 1995, 1843
+ size: 52, 52
+ orig: 52, 52
+ offset: 0, 0
+ index: -1
+casing
+ rotate: false
+ xy: 204, 965
+ size: 8, 16
+ orig: 8, 16
+ offset: 0, 0
+ index: -1
+circle-end
+ rotate: false
+ xy: 334, 764
+ size: 100, 199
+ orig: 100, 199
+ offset: 0, 0
+ index: -1
+circle-mid
+ rotate: false
+ xy: 2045, 1642
+ size: 1, 199
+ orig: 1, 199
+ offset: 0, 0
+ index: -1
+circle-shadow
+ rotate: false
+ xy: 1, 780
+ size: 201, 201
+ orig: 201, 201
+ offset: 0, 0
+ index: -1
+error
+ rotate: false
+ xy: 930, 647
+ size: 48, 48
+ orig: 48, 48
+ offset: 0, 0
+ index: -1
+laser
+ rotate: false
+ xy: 1079, 1666
+ size: 4, 48
+ orig: 4, 48
+ offset: 0, 0
+ index: -1
+laser-end
+ rotate: false
+ xy: 1661, 1259
+ size: 72, 72
+ orig: 72, 72
+ offset: 0, 0
+ index: -1
+minelaser
+ rotate: false
+ xy: 1245, 1365
+ size: 4, 48
+ orig: 4, 48
+ offset: 0, 0
+ index: -1
+minelaser-end
+ rotate: false
+ xy: 1735, 1259
+ size: 72, 72
+ orig: 72, 72
+ offset: 0, 0
+ index: -1
+missile
+ rotate: false
+ xy: 1028, 1849
+ size: 36, 36
+ orig: 36, 36
+ offset: 0, 0
+ index: -1
+missile-back
+ rotate: false
+ xy: 163, 742
+ size: 36, 36
+ orig: 36, 36
+ offset: 0, 0
+ index: -1
+particle
+ rotate: false
+ xy: 1715, 1025
+ size: 40, 40
+ orig: 40, 40
+ offset: 0, 0
+ index: -1
+scale_marker
+ rotate: false
+ xy: 819, 1721
+ size: 4, 4
+ orig: 4, 4
+ offset: 0, 0
+ index: -1
+shell
+ rotate: false
+ xy: 975, 1418
+ size: 36, 36
+ orig: 36, 36
+ offset: 0, 0
+ index: -1
+shell-back
+ rotate: false
+ xy: 543, 1313
+ size: 36, 36
+ orig: 36, 36
+ offset: 0, 0
+ index: -1
+transfer
+ rotate: false
+ xy: 1073, 1536
+ size: 4, 48
+ orig: 4, 48
+ offset: 0, 0
+ index: -1
+transfer-arrow
+ rotate: false
+ xy: 1456, 641
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+white
+ rotate: false
+ xy: 895, 331
+ size: 3, 3
+ orig: 3, 3
+ offset: 0, 0
+ index: -1
+arc
+ rotate: false
+ xy: 349, 965
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-arc-full
+ rotate: false
+ xy: 1688, 957
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-blast-drill-full
+ rotate: false
+ xy: 219, 1095
+ size: 128, 128
+ orig: 128, 128
+ offset: 0, 0
+ index: -1
+block-bridge-conduit-full
+ rotate: false
+ xy: 1688, 889
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+bridge-conduit
+ rotate: false
+ xy: 1688, 889
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-bridge-conveyor-full
+ rotate: false
+ xy: 1722, 957
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+bridge-conveyor
+ rotate: false
+ xy: 1722, 957
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-char-full
+ rotate: false
+ xy: 1722, 923
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-cliff-full
+ rotate: false
+ xy: 1722, 889
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-cliffs-full
+ rotate: false
+ xy: 1741, 991
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-coal-centrifuge-full
+ rotate: false
+ xy: 479, 1153
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+coal-centrifuge
+ rotate: false
+ xy: 479, 1153
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+block-combustion-generator-full
+ rotate: false
+ xy: 1775, 999
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+combustion-generator
+ rotate: false
+ xy: 1775, 999
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-conduit-full
+ rotate: false
+ xy: 1756, 957
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-container-full
+ rotate: false
+ xy: 479, 1087
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+container
+ rotate: false
+ xy: 479, 1087
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+block-conveyor-full
+ rotate: false
+ xy: 1756, 923
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+conveyor-0-0
+ rotate: false
+ xy: 1756, 923
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-copper-wall-full
+ rotate: false
+ xy: 1756, 889
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+copper-wall
+ rotate: false
+ xy: 1756, 889
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-copper-wall-large-full
+ rotate: false
+ xy: 479, 1021
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+copper-wall-large
+ rotate: false
+ xy: 479, 1021
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+block-core-foundation-full
+ rotate: false
+ xy: 219, 965
+ size: 128, 128
+ orig: 128, 128
+ offset: 0, 0
+ index: -1
+core-foundation
+ rotate: false
+ xy: 219, 965
+ size: 128, 128
+ orig: 128, 128
+ offset: 0, 0
+ index: -1
+block-core-nucleus-full
+ rotate: false
+ xy: 323, 1385
+ size: 160, 160
+ orig: 160, 160
+ offset: 0, 0
+ index: -1
+core-nucleus
+ rotate: false
+ xy: 323, 1385
+ size: 160, 160
+ orig: 160, 160
+ offset: 0, 0
+ index: -1
+block-core-shard-full
+ rotate: false
+ xy: 1585, 1529
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+core-shard
+ rotate: false
+ xy: 1585, 1529
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+block-craters-full
+ rotate: false
+ xy: 1809, 999
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-cryofluidmixer-full
+ rotate: false
+ xy: 131, 4
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+block-cultivator-full
+ rotate: false
+ xy: 545, 1209
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+block-cyclone-full
+ rotate: false
+ xy: 1683, 1529
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+block-dark-metal-full
+ rotate: false
+ xy: 1790, 965
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-dark-panel-1-full
+ rotate: false
+ xy: 1790, 931
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-dark-panel-2-full
+ rotate: false
+ xy: 1790, 897
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-dark-panel-3-full
+ rotate: false
+ xy: 1825, 1033
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-dark-panel-4-full
+ rotate: false
+ xy: 1824, 965
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-dark-panel-5-full
+ rotate: false
+ xy: 1824, 931
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-dark-panel-6-full
+ rotate: false
+ xy: 1824, 897
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-darksand-full
+ rotate: false
+ xy: 1843, 999
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-darksand-tainted-water-full
+ rotate: false
+ xy: 1858, 965
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-darksand-water-full
+ rotate: false
+ xy: 1858, 931
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-deepwater-full
+ rotate: false
+ xy: 1858, 897
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-differential-generator-full
+ rotate: false
+ xy: 1781, 1561
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+differential-generator
+ rotate: false
+ xy: 1781, 1561
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+block-diode-full
+ rotate: false
+ xy: 1038, 829
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+diode
+ rotate: false
+ xy: 1038, 829
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-distributor-full
+ rotate: false
+ xy: 611, 1209
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+distributor
+ rotate: false
+ xy: 611, 1209
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+block-door-full
+ rotate: false
+ xy: 1072, 829
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+door
+ rotate: false
+ xy: 1072, 829
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-door-large-full
+ rotate: false
+ xy: 545, 1143
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+door-large
+ rotate: false
+ xy: 545, 1143
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+block-dunerocks-full
+ rotate: false
+ xy: 1106, 829
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-duo-full
+ rotate: false
+ xy: 1140, 829
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-force-projector-full
+ rotate: false
+ xy: 1879, 1561
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+force-projector
+ rotate: false
+ xy: 1879, 1561
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+block-fuse-full
+ rotate: false
+ xy: 1055, 1415
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+block-graphite-press-full
+ rotate: false
+ xy: 677, 1209
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+graphite-press
+ rotate: false
+ xy: 677, 1209
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+block-grass-full
+ rotate: false
+ xy: 1174, 829
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-ground-factory-full
+ rotate: false
+ xy: 1153, 1415
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+block-hail-full
+ rotate: false
+ xy: 1288, 811
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-holostone-full
+ rotate: false
+ xy: 1322, 811
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-hotrock-full
+ rotate: false
+ xy: 1356, 811
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-ice-full
+ rotate: false
+ xy: 1390, 811
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-ice-snow-full
+ rotate: false
+ xy: 1424, 811
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-icerocks-full
+ rotate: false
+ xy: 1458, 811
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-ignarock-full
+ rotate: false
+ xy: 1492, 811
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-illuminator-full
+ rotate: false
+ xy: 1526, 811
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+illuminator
+ rotate: false
+ xy: 1526, 811
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-impact-reactor-full
+ rotate: false
+ xy: 204, 835
+ size: 128, 128
+ orig: 128, 128
+ offset: 0, 0
+ index: -1
+block-incinerator-full
+ rotate: false
+ xy: 1560, 811
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+incinerator
+ rotate: false
+ xy: 1560, 811
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-inverted-sorter-full
+ rotate: false
+ xy: 1790, 863
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+inverted-sorter
+ rotate: false
+ xy: 1790, 863
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-item-source-full
+ rotate: false
+ xy: 1824, 863
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+item-source
+ rotate: false
+ xy: 1824, 863
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-item-void-full
+ rotate: false
+ xy: 1858, 863
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+item-void
+ rotate: false
+ xy: 1858, 863
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-junction-full
+ rotate: false
+ xy: 980, 813
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+junction
+ rotate: false
+ xy: 980, 813
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-kiln-full
+ rotate: false
+ xy: 611, 1143
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+kiln
+ rotate: false
+ xy: 611, 1143
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+block-lancer-full
+ rotate: false
+ xy: 545, 1077
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+block-laser-drill-full
+ rotate: false
+ xy: 1251, 1431
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+block-launch-pad-full
+ rotate: false
+ xy: 1349, 1431
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+launch-pad
+ rotate: false
+ xy: 1349, 1431
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+block-launch-pad-large-full
+ rotate: false
+ xy: 349, 1129
+ size: 128, 128
+ orig: 128, 128
+ offset: 0, 0
+ index: -1
+launch-pad-large
+ rotate: false
+ xy: 349, 1129
+ size: 128, 128
+ orig: 128, 128
+ offset: 0, 0
+ index: -1
+block-liquid-junction-full
+ rotate: false
+ xy: 980, 779
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+liquid-junction
+ rotate: false
+ xy: 980, 779
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-liquid-router-full
+ rotate: false
+ xy: 980, 745
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-liquid-source-full
+ rotate: false
+ xy: 980, 711
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+liquid-source
+ rotate: false
+ xy: 980, 711
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-liquid-tank-full
+ rotate: false
+ xy: 1447, 1431
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+block-liquid-void-full
+ rotate: false
+ xy: 980, 677
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+liquid-void
+ rotate: false
+ xy: 980, 677
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-magmarock-full
+ rotate: false
+ xy: 1014, 795
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-mass-conveyor-full
+ rotate: false
+ xy: 1545, 1431
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+mass-conveyor
+ rotate: false
+ xy: 1545, 1431
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+block-mass-driver-full
+ rotate: false
+ xy: 1643, 1431
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+block-mechanical-drill-full
+ rotate: false
+ xy: 677, 1143
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+block-mechanical-pump-full
+ rotate: false
+ xy: 1048, 795
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+mechanical-pump
+ rotate: false
+ xy: 1048, 795
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-meltdown-full
+ rotate: false
+ xy: 349, 999
+ size: 128, 128
+ orig: 128, 128
+ offset: 0, 0
+ index: -1
+block-melter-full
+ rotate: false
+ xy: 1014, 761
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+melter
+ rotate: false
+ xy: 1014, 761
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-mend-projector-full
+ rotate: false
+ xy: 611, 1077
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+mend-projector
+ rotate: false
+ xy: 611, 1077
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+block-mender-full
+ rotate: false
+ xy: 1082, 795
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+mender
+ rotate: false
+ xy: 1082, 795
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-message-full
+ rotate: false
+ xy: 1014, 727
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+message
+ rotate: false
+ xy: 1014, 727
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-metal-floor-2-full
+ rotate: false
+ xy: 1048, 761
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-metal-floor-3-full
+ rotate: false
+ xy: 1116, 795
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-metal-floor-5-full
+ rotate: false
+ xy: 1014, 693
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-metal-floor-damaged-full
+ rotate: false
+ xy: 1048, 727
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-metal-floor-full
+ rotate: false
+ xy: 1082, 761
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-moss-full
+ rotate: false
+ xy: 1048, 693
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-multi-press-full
+ rotate: false
+ xy: 1741, 1431
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+multi-press
+ rotate: false
+ xy: 1741, 1431
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+block-oil-extractor-full
+ rotate: false
+ xy: 1839, 1463
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+block-ore-coal-full
+ rotate: false
+ xy: 1082, 727
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-ore-copper-full
+ rotate: false
+ xy: 1116, 761
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-ore-lead-full
+ rotate: false
+ xy: 1082, 693
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-ore-scrap-full
+ rotate: false
+ xy: 1116, 727
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-ore-thorium-full
+ rotate: false
+ xy: 1150, 761
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-ore-titanium-full
+ rotate: false
+ xy: 1116, 693
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-overdrive-projector-full
+ rotate: false
+ xy: 677, 1077
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+overdrive-projector
+ rotate: false
+ xy: 677, 1077
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+block-overflow-gate-full
+ rotate: false
+ xy: 1150, 727
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+overflow-gate
+ rotate: false
+ xy: 1150, 727
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-pebbles-full
+ rotate: false
+ xy: 1150, 693
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-phase-conduit-full
+ rotate: false
+ xy: 1184, 795
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+phase-conduit
+ rotate: false
+ xy: 1184, 795
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-phase-conveyor-full
+ rotate: false
+ xy: 1184, 761
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+phase-conveyor
+ rotate: false
+ xy: 1184, 761
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-phase-wall-full
+ rotate: false
+ xy: 1184, 727
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+phase-wall
+ rotate: false
+ xy: 1184, 727
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-phase-wall-large-full
+ rotate: false
+ xy: 545, 1011
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+phase-wall-large
+ rotate: false
+ xy: 545, 1011
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+block-phase-weaver-full
+ rotate: false
+ xy: 611, 1011
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+block-pine-full
+ rotate: false
+ xy: 930, 747
+ size: 48, 48
+ orig: 48, 48
+ offset: 0, 0
+ index: -1
+block-plastanium-compressor-full
+ rotate: false
+ xy: 677, 1011
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+plastanium-compressor
+ rotate: false
+ xy: 677, 1011
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+block-plastanium-conveyor-full
+ rotate: false
+ xy: 1184, 693
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-plastanium-wall-full
+ rotate: false
+ xy: 1014, 659
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+plastanium-wall
+ rotate: false
+ xy: 1014, 659
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-plastanium-wall-large-full
+ rotate: false
+ xy: 534, 945
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+plastanium-wall-large
+ rotate: false
+ xy: 534, 945
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+block-plated-conduit-full
+ rotate: false
+ xy: 1048, 659
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-pneumatic-drill-full
+ rotate: false
+ xy: 534, 879
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+block-power-node-full
+ rotate: false
+ xy: 1082, 659
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+power-node
+ rotate: false
+ xy: 1082, 659
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-power-node-large-full
+ rotate: false
+ xy: 600, 945
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+power-node-large
+ rotate: false
+ xy: 600, 945
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+block-power-source-full
+ rotate: false
+ xy: 1116, 659
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-power-void-full
+ rotate: false
+ xy: 1150, 659
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+power-void
+ rotate: false
+ xy: 1150, 659
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-pulse-conduit-full
+ rotate: false
+ xy: 1184, 659
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-pulverizer-full
+ rotate: false
+ xy: 1009, 625
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-pyratite-mixer-full
+ rotate: false
+ xy: 534, 813
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+pyratite-mixer
+ rotate: false
+ xy: 534, 813
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+block-repair-point-full
+ rotate: false
+ xy: 1009, 591
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-ripple-full
+ rotate: false
+ xy: 1937, 1463
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+block-rock-full
+ rotate: false
+ xy: 1995, 1743
+ size: 48, 48
+ orig: 48, 48
+ offset: 0, 0
+ index: -1
+block-rocks-full
+ rotate: false
+ xy: 1043, 625
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-rotary-pump-full
+ rotate: false
+ xy: 666, 945
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+rotary-pump
+ rotate: false
+ xy: 666, 945
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+block-router-full
+ rotate: false
+ xy: 1009, 557
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+router
+ rotate: false
+ xy: 1009, 557
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-rtg-generator-full
+ rotate: false
+ xy: 600, 879
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+rtg-generator
+ rotate: false
+ xy: 600, 879
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+block-salt-full
+ rotate: false
+ xy: 1043, 591
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-saltrocks-full
+ rotate: false
+ xy: 1077, 625
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-salvo-full
+ rotate: false
+ xy: 534, 747
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+block-sand-boulder-full
+ rotate: false
+ xy: 1009, 523
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-sand-full
+ rotate: false
+ xy: 1043, 557
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-sand-water-full
+ rotate: false
+ xy: 1077, 591
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-sandrocks-full
+ rotate: false
+ xy: 1111, 625
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-scatter-full
+ rotate: false
+ xy: 666, 879
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+block-scorch-full
+ rotate: false
+ xy: 1009, 489
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-scrap-wall-full
+ rotate: false
+ xy: 1043, 523
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+scrap-wall1
+ rotate: false
+ xy: 1043, 523
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-scrap-wall-gigantic-full
+ rotate: false
+ xy: 955, 1716
+ size: 128, 128
+ orig: 128, 128
+ offset: 0, 0
+ index: -1
+scrap-wall-gigantic
+ rotate: false
+ xy: 955, 1716
+ size: 128, 128
+ orig: 128, 128
+ offset: 0, 0
+ index: -1
+block-scrap-wall-huge-full
+ rotate: false
+ xy: 1839, 1365
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+scrap-wall-huge1
+ rotate: false
+ xy: 1839, 1365
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+block-scrap-wall-large-full
+ rotate: false
+ xy: 600, 813
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+block-separator-full
+ rotate: false
+ xy: 666, 813
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+separator
+ rotate: false
+ xy: 666, 813
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+block-shale-boulder-full
+ rotate: false
+ xy: 1111, 591
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-shale-full
+ rotate: false
+ xy: 1145, 625
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-shalerocks-full
+ rotate: false
+ xy: 1009, 455
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-shock-mine-full
+ rotate: false
+ xy: 1043, 489
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-shrubs-full
+ rotate: false
+ xy: 1077, 523
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-silicon-smelter-full
+ rotate: false
+ xy: 600, 747
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+silicon-smelter
+ rotate: false
+ xy: 600, 747
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+block-slag-full
+ rotate: false
+ xy: 1111, 557
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-snow-full
+ rotate: false
+ xy: 1145, 591
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-snow-pine-full
+ rotate: false
+ xy: 1038, 863
+ size: 48, 48
+ orig: 48, 48
+ offset: 0, 0
+ index: -1
+block-snowrock-full
+ rotate: false
+ xy: 1088, 913
+ size: 48, 48
+ orig: 48, 48
+ offset: 0, 0
+ index: -1
+block-snowrocks-full
+ rotate: false
+ xy: 1179, 625
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-solar-panel-full
+ rotate: false
+ xy: 1009, 421
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+solar-panel
+ rotate: false
+ xy: 1009, 421
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-solar-panel-large-full
+ rotate: false
+ xy: 1937, 1365
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+solar-panel-large
+ rotate: false
+ xy: 1937, 1365
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+block-sorter-full
+ rotate: false
+ xy: 1043, 455
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+sorter
+ rotate: false
+ xy: 1043, 455
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-spawn-full
+ rotate: false
+ xy: 1077, 489
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-spectre-full
+ rotate: false
+ xy: 949, 1586
+ size: 128, 128
+ orig: 128, 128
+ offset: 0, 0
+ index: -1
+block-spore-cluster-full
+ rotate: false
+ xy: 392, 722
+ size: 40, 40
+ orig: 40, 40
+ offset: 0, 0
+ index: -1
+block-spore-moss-full
+ rotate: false
+ xy: 1111, 523
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-spore-pine-full
+ rotate: false
+ xy: 930, 697
+ size: 48, 48
+ orig: 48, 48
+ offset: 0, 0
+ index: -1
+block-spore-press-full
+ rotate: false
+ xy: 666, 747
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+block-sporerocks-full
+ rotate: false
+ xy: 1145, 557
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-stone-full
+ rotate: false
+ xy: 1179, 591
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-surge-tower-full
+ rotate: false
+ xy: 534, 681
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+surge-tower
+ rotate: false
+ xy: 534, 681
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+block-surge-wall-full
+ rotate: false
+ xy: 1009, 387
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+surge-wall
+ rotate: false
+ xy: 1009, 387
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-surge-wall-large-full
+ rotate: false
+ xy: 600, 681
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+surge-wall-large
+ rotate: false
+ xy: 600, 681
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+block-swarmer-full
+ rotate: false
+ xy: 666, 681
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+block-tainted-water-full
+ rotate: false
+ xy: 1043, 421
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-tar-full
+ rotate: false
+ xy: 1077, 455
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-tendrils-full
+ rotate: false
+ xy: 1111, 489
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-thermal-generator-full
+ rotate: false
+ xy: 521, 615
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+thermal-generator
+ rotate: false
+ xy: 521, 615
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+block-thermal-pump-full
+ rotate: false
+ xy: 131, 70
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+thermal-pump
+ rotate: false
+ xy: 131, 70
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+block-thorium-reactor-full
+ rotate: false
+ xy: 163, 217
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+thorium-reactor
+ rotate: false
+ xy: 163, 217
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+block-thorium-wall-full
+ rotate: false
+ xy: 1145, 523
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+thorium-wall
+ rotate: false
+ xy: 1145, 523
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-thorium-wall-large-full
+ rotate: false
+ xy: 521, 549
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+thorium-wall-large
+ rotate: false
+ xy: 521, 549
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+block-thruster-full
+ rotate: false
+ xy: 1085, 1757
+ size: 128, 128
+ orig: 128, 128
+ offset: 0, 0
+ index: -1
+thruster
+ rotate: false
+ xy: 1085, 1757
+ size: 128, 128
+ orig: 128, 128
+ offset: 0, 0
+ index: -1
+block-titanium-conveyor-full
+ rotate: false
+ xy: 1179, 557
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+titanium-conveyor-0-0
+ rotate: false
+ xy: 1179, 557
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-titanium-wall-full
+ rotate: false
+ xy: 1009, 353
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+titanium-wall
+ rotate: false
+ xy: 1009, 353
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-titanium-wall-large-full
+ rotate: false
+ xy: 587, 615
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+titanium-wall-large
+ rotate: false
+ xy: 587, 615
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
block-turbine-generator-full
rotate: false
- xy: 894, 1082
+ xy: 521, 483
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
turbine-generator
rotate: false
- xy: 894, 1082
+ xy: 521, 483
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
block-underflow-gate-full
rotate: false
- xy: 1251, 432
+ xy: 1043, 387
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-unloader-full
rotate: false
- xy: 1251, 398
+ xy: 1077, 421
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
unloader
rotate: false
- xy: 1251, 398
+ xy: 1077, 421
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-vault-full
rotate: false
- xy: 521, 631
+ xy: 261, 217
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
vault
rotate: false
- xy: 521, 631
+ xy: 261, 217
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
block-water-extractor-full
rotate: false
- xy: 894, 1016
+ xy: 653, 615
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
block-water-full
rotate: false
- xy: 1251, 364
+ xy: 1111, 455
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-wave-full
rotate: false
- xy: 894, 950
+ xy: 587, 549
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
block-white-tree-dead-full
rotate: false
- xy: 1, 1726
+ xy: 1, 1225
size: 320, 320
orig: 320, 320
offset: 0, 0
index: -1
block-white-tree-full
rotate: false
- xy: 1, 1404
+ xy: 503, 1727
size: 320, 320
orig: 320, 320
offset: 0, 0
index: -1
-block-wraith-factory-full
- rotate: false
- xy: 922, 884
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
cracks-1-0
rotate: false
- xy: 1285, 210
+ xy: 827, 268
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
cracks-1-1
rotate: false
- xy: 1319, 210
+ xy: 861, 268
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
cracks-1-2
rotate: false
- xy: 1301, 176
+ xy: 691, 234
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
cracks-1-3
rotate: false
- xy: 1301, 142
+ xy: 725, 234
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
cracks-1-4
rotate: false
- xy: 1301, 108
+ xy: 759, 234
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
cracks-1-5
rotate: false
- xy: 1301, 74
+ xy: 793, 234
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
cracks-1-6
rotate: false
- xy: 1301, 40
+ xy: 827, 234
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
cracks-1-7
rotate: false
- xy: 1301, 6
+ xy: 861, 234
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
cracks-2-0
rotate: false
- xy: 1045, 94
+ xy: 653, 549
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
cracks-2-1
rotate: false
- xy: 1045, 28
+ xy: 587, 483
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
cracks-2-2
rotate: false
- xy: 879, 1478
+ xy: 521, 351
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
cracks-2-3
rotate: false
- xy: 871, 1412
+ xy: 653, 483
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
cracks-2-4
rotate: false
- xy: 871, 1346
+ xy: 587, 417
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
cracks-2-5
rotate: false
- xy: 871, 1280
+ xy: 653, 417
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
cracks-2-6
rotate: false
- xy: 945, 1519
+ xy: 587, 351
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
cracks-2-7
rotate: false
- xy: 945, 1453
+ xy: 653, 351
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
cracks-3-0
rotate: false
- xy: 521, 533
+ xy: 359, 217
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
cracks-3-1
rotate: false
- xy: 521, 435
+ xy: 229, 119
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
cracks-3-2
rotate: false
- xy: 521, 337
+ xy: 327, 119
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
cracks-3-3
rotate: false
- xy: 521, 239
+ xy: 229, 21
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
cracks-3-4
rotate: false
- xy: 521, 141
+ xy: 327, 21
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
cracks-3-5
rotate: false
- xy: 521, 43
+ xy: 425, 119
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
cracks-3-6
rotate: false
- xy: 553, 729
+ xy: 425, 21
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
cracks-3-7
rotate: false
- xy: 562, 827
+ xy: 485, 1449
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
cracks-4-0
rotate: false
- xy: 293, 342
+ xy: 1605, 1757
size: 128, 128
orig: 128, 128
offset: 0, 0
index: -1
cracks-4-1
rotate: false
- xy: 293, 212
+ xy: 1735, 1789
size: 128, 128
orig: 128, 128
offset: 0, 0
index: -1
cracks-4-2
rotate: false
- xy: 163, 82
+ xy: 1865, 1789
size: 128, 128
orig: 128, 128
offset: 0, 0
index: -1
cracks-4-3
rotate: false
- xy: 293, 82
+ xy: 204, 705
size: 128, 128
orig: 128, 128
offset: 0, 0
index: -1
cracks-4-4
rotate: false
- xy: 1066, 1756
+ xy: 163, 575
size: 128, 128
orig: 128, 128
offset: 0, 0
index: -1
cracks-4-5
rotate: false
- xy: 1196, 1756
+ xy: 163, 445
size: 128, 128
orig: 128, 128
offset: 0, 0
index: -1
cracks-4-6
rotate: false
- xy: 1326, 1756
+ xy: 163, 315
size: 128, 128
orig: 128, 128
offset: 0, 0
index: -1
cracks-4-7
rotate: false
- xy: 1456, 1756
+ xy: 1085, 1627
size: 128, 128
orig: 128, 128
offset: 0, 0
index: -1
cracks-5-0
rotate: false
- xy: 1, 587
+ xy: 503, 1565
size: 160, 160
orig: 160, 160
offset: 0, 0
index: -1
cracks-5-1
rotate: false
- xy: 1228, 1886
+ xy: 1028, 1887
size: 160, 160
orig: 160, 160
offset: 0, 0
index: -1
cracks-5-2
rotate: false
- xy: 1, 425
+ xy: 1, 618
size: 160, 160
orig: 160, 160
offset: 0, 0
index: -1
cracks-5-3
rotate: false
- xy: 1390, 1886
+ xy: 1190, 1887
size: 160, 160
orig: 160, 160
offset: 0, 0
index: -1
cracks-5-4
rotate: false
- xy: 1, 263
+ xy: 1, 456
size: 160, 160
orig: 160, 160
offset: 0, 0
index: -1
cracks-5-5
rotate: false
- xy: 1552, 1886
+ xy: 1352, 1887
size: 160, 160
orig: 160, 160
offset: 0, 0
index: -1
cracks-5-6
rotate: false
- xy: 1, 101
+ xy: 1, 294
size: 160, 160
orig: 160, 160
offset: 0, 0
index: -1
cracks-5-7
rotate: false
- xy: 1714, 1886
+ xy: 1514, 1887
size: 160, 160
orig: 160, 160
offset: 0, 0
index: -1
cyclone
rotate: false
- xy: 660, 848
+ xy: 485, 1351
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
duo
rotate: false
- xy: 1335, 108
+ xy: 929, 263
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
fuse
rotate: false
- xy: 651, 729
+ xy: 1741, 1333
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
hail
rotate: false
- xy: 1335, 74
+ xy: 963, 277
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-blast-compound-large
rotate: false
- xy: 887, 1550
+ xy: 1330, 845
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
item-blast-compound-medium
rotate: false
- xy: 1353, 760
+ xy: 997, 251
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-blast-compound-small
rotate: false
- xy: 2023, 1270
+ xy: 323, 1233
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
item-blast-compound-tiny
rotate: false
- xy: 797, 25
+ xy: 503, 1547
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
item-blast-compound-xlarge
rotate: false
- xy: 1598, 1330
+ xy: 917, 381
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
item-coal-large
rotate: false
- xy: 607, 1374
+ xy: 1372, 845
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
item-coal-medium
rotate: false
- xy: 1353, 692
+ xy: 1065, 251
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-coal-small
rotate: false
- xy: 2023, 1244
+ xy: 1676, 1893
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
item-coal-tiny
rotate: false
- xy: 1403, 174
+ xy: 521, 1547
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
item-coal-xlarge
rotate: false
- xy: 1648, 1330
+ xy: 917, 331
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
item-copper-large
rotate: false
- xy: 673, 1242
+ xy: 1414, 845
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
item-copper-medium
rotate: false
- xy: 1353, 624
+ xy: 1133, 251
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-copper-small
rotate: false
- xy: 2023, 1218
+ xy: 1735, 1633
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
item-copper-tiny
rotate: false
- xy: 797, 7
+ xy: 539, 1547
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
item-copper-xlarge
rotate: false
- xy: 1698, 1330
+ xy: 1188, 921
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
item-graphite-large
rotate: false
- xy: 945, 751
+ xy: 1456, 845
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
item-graphite-medium
rotate: false
- xy: 1353, 556
+ xy: 963, 209
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-graphite-small
rotate: false
- xy: 259, 1378
+ xy: 1781, 1535
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
item-graphite-tiny
rotate: false
- xy: 1369, 198
+ xy: 557, 1547
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
item-graphite-xlarge
rotate: false
- xy: 1748, 1330
+ xy: 1188, 871
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
item-lead-large
rotate: false
- xy: 1011, 1543
+ xy: 1498, 845
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
item-lead-medium
rotate: false
- xy: 1353, 488
+ xy: 1031, 217
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-lead-small
rotate: false
- xy: 960, 965
+ xy: 583, 1473
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
item-lead-tiny
rotate: false
- xy: 204, 1128
+ xy: 1055, 1568
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
item-lead-xlarge
rotate: false
- xy: 1798, 1330
+ xy: 1238, 937
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
item-metaglass-large
rotate: false
- xy: 1069, 1256
+ xy: 1540, 845
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
item-metaglass-medium
rotate: false
- xy: 1353, 420
+ xy: 1099, 217
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-metaglass-small
rotate: false
- xy: 901, 1819
+ xy: 197, 44
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
item-metaglass-tiny
rotate: false
- xy: 566, 928
+ xy: 479, 1003
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
item-metaglass-xlarge
rotate: false
- xy: 1848, 1330
+ xy: 1238, 887
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
item-phase-fabric-large
rotate: false
- xy: 1209, 798
+ xy: 155, 175
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
item-phase-fabric-medium
rotate: false
- xy: 1353, 352
+ xy: 1167, 217
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-phase-fabric-small
rotate: false
- xy: 1251, 202
+ xy: 1936, 1925
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
item-phase-fabric-tiny
rotate: false
- xy: 660, 830
+ xy: 2027, 1625
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
item-phase-fabric-xlarge
rotate: false
- xy: 1898, 1330
+ xy: 1288, 937
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
item-plastanium-large
rotate: false
- xy: 1259, 848
+ xy: 967, 605
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
item-plastanium-medium
rotate: false
- xy: 1353, 284
+ xy: 1201, 217
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-plastanium-small
rotate: false
- xy: 1540, 822
+ xy: 1977, 1567
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
item-plastanium-tiny
rotate: false
- xy: 749, 732
+ xy: 1066, 1869
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
item-plastanium-xlarge
rotate: false
- xy: 1948, 1330
+ xy: 1288, 887
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
item-pyratite-large
rotate: false
- xy: 1011, 1501
+ xy: 967, 563
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
item-pyratite-medium
rotate: false
- xy: 1353, 216
+ xy: 1031, 183
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-pyratite-small
rotate: false
- xy: 1544, 992
+ xy: 1809, 1307
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
item-pyratite-tiny
rotate: false
- xy: 623, 1708
+ xy: 417, 981
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
item-pyratite-xlarge
rotate: false
- xy: 1998, 1330
+ xy: 1338, 937
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
item-sand-large
rotate: false
- xy: 1209, 756
+ xy: 967, 521
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
item-sand-medium
rotate: false
- xy: 1387, 736
+ xy: 1099, 183
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-sand-small
rotate: false
- xy: 285, 1378
+ xy: 197, 191
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
item-sand-tiny
rotate: false
- xy: 1269, 1222
+ xy: 1761, 1641
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
item-sand-xlarge
rotate: false
- xy: 1347, 1256
+ xy: 1338, 887
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
item-scrap-large
rotate: false
- xy: 1011, 1459
+ xy: 967, 479
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
item-scrap-medium
rotate: false
- xy: 1387, 668
+ xy: 1167, 183
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-scrap-small
rotate: false
- xy: 1540, 796
+ xy: 103, 12
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
item-scrap-tiny
rotate: false
- xy: 1186, 872
+ xy: 2003, 1575
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
item-scrap-xlarge
rotate: false
- xy: 1347, 1206
+ xy: 1388, 937
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
item-silicon-large
rotate: false
- xy: 1209, 714
+ xy: 967, 437
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
item-silicon-medium
rotate: false
- xy: 1387, 600
+ xy: 1582, 853
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-silicon-small
rotate: false
- xy: 1544, 966
+ xy: 980, 651
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
item-silicon-tiny
rotate: false
- xy: 649, 1398
+ xy: 581, 231
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
item-silicon-xlarge
rotate: false
- xy: 1258, 1140
+ xy: 1388, 887
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
item-spore-pod-large
rotate: false
- xy: 1209, 672
+ xy: 967, 395
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
item-spore-pod-medium
rotate: false
- xy: 1387, 532
+ xy: 1650, 855
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-spore-pod-small
rotate: false
- xy: 873, 4
+ xy: 555, 223
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
item-spore-pod-tiny
rotate: false
- xy: 987, 775
+ xy: 1809, 1263
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
item-spore-pod-xlarge
rotate: false
- xy: 1258, 1090
+ xy: 1438, 937
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
item-surge-alloy-large
rotate: false
- xy: 1209, 630
+ xy: 967, 353
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
item-surge-alloy-medium
rotate: false
- xy: 1387, 464
+ xy: 1718, 855
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-surge-alloy-small
rotate: false
- xy: 1574, 1202
+ xy: 1558, 649
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
item-surge-alloy-tiny
rotate: false
- xy: 1091, 181
+ xy: 1055, 1550
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
item-surge-alloy-xlarge
rotate: false
- xy: 1258, 1040
+ xy: 1438, 887
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
item-thorium-large
rotate: false
- xy: 1209, 588
+ xy: 967, 311
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
item-thorium-medium
rotate: false
- xy: 1387, 396
+ xy: 1594, 819
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-thorium-small
rotate: false
- xy: 1574, 1176
+ xy: 1702, 1893
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
item-thorium-tiny
rotate: false
- xy: 924, 866
+ xy: 497, 1003
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
item-thorium-xlarge
rotate: false
- xy: 1308, 1148
+ xy: 1488, 937
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
item-titanium-large
rotate: false
- xy: 1209, 546
+ xy: 1659, 1067
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
item-titanium-medium
rotate: false
- xy: 1387, 328
+ xy: 1662, 821
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-titanium-small
rotate: false
- xy: 1600, 1202
+ xy: 1807, 1535
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
item-titanium-tiny
rotate: false
- xy: 924, 848
+ xy: 2027, 1607
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
item-titanium-xlarge
rotate: false
- xy: 1308, 1098
+ xy: 1488, 887
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
lancer
rotate: false
- xy: 1077, 727
+ xy: 864, 732
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
liquid-cryofluid-large
rotate: false
- xy: 1209, 504
+ xy: 1701, 1067
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
liquid-cryofluid-medium
rotate: false
- xy: 1387, 260
+ xy: 1730, 821
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
liquid-cryofluid-small
rotate: false
- xy: 1574, 1150
+ xy: 609, 1473
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
liquid-cryofluid-tiny
rotate: false
- xy: 1209, 402
+ xy: 1066, 1851
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
liquid-cryofluid-xlarge
rotate: false
- xy: 1358, 1056
+ xy: 1573, 988
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
liquid-oil-large
rotate: false
- xy: 1209, 462
+ xy: 1743, 1067
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
liquid-oil-medium
rotate: false
- xy: 1421, 754
+ xy: 1798, 829
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
liquid-oil-small
rotate: false
- xy: 1600, 1176
+ xy: 197, 18
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
liquid-oil-tiny
rotate: false
- xy: 2024, 1312
+ xy: 599, 231
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
liquid-oil-xlarge
rotate: false
- xy: 1397, 1296
+ xy: 1623, 989
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
liquid-slag-large
rotate: false
- xy: 1209, 420
+ xy: 1785, 1067
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
liquid-slag-medium
rotate: false
- xy: 1421, 516
+ xy: 1730, 787
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
liquid-slag-small
rotate: false
- xy: 1626, 1202
+ xy: 1962, 1925
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
liquid-slag-tiny
rotate: false
- xy: 1600, 1158
+ xy: 1055, 1532
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
liquid-slag-xlarge
rotate: false
- xy: 1397, 1246
+ xy: 1588, 938
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
liquid-water-large
rotate: false
- xy: 99, 1
+ xy: 1673, 1025
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
liquid-water-medium
rotate: false
- xy: 1421, 448
+ xy: 1798, 795
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
liquid-water-small
rotate: false
- xy: 1574, 1124
+ xy: 1809, 1281
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
liquid-water-tiny
rotate: false
- xy: 1626, 1184
+ xy: 515, 1003
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
liquid-water-xlarge
rotate: false
- xy: 1447, 1280
+ xy: 1588, 888
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
mass-driver
rotate: false
- xy: 1939, 1430
+ xy: 779, 1358
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
-mech-alpha-mech-full
- rotate: false
- xy: 1497, 1272
- size: 48, 48
- orig: 48, 48
- offset: 0, 0
- index: -1
-mech-dart-ship-full
- rotate: false
- xy: 1447, 1230
- size: 48, 48
- orig: 48, 48
- offset: 0, 0
- index: -1
-mech-delta-mech-full
- rotate: false
- xy: 1497, 1222
- size: 48, 48
- orig: 48, 48
- offset: 0, 0
- index: -1
-mech-glaive-ship-full
- rotate: false
- xy: 1969, 1630
- size: 56, 56
- orig: 56, 56
- offset: 0, 0
- index: -1
-mech-javelin-ship-full
- rotate: false
- xy: 1208, 990
- size: 48, 48
- orig: 48, 48
- offset: 0, 0
- index: -1
-mech-omega-mech-full
- rotate: false
- xy: 1243, 3
- size: 56, 56
- orig: 56, 56
- offset: 0, 0
- index: -1
-mech-tau-mech-full
- rotate: false
- xy: 1267, 1306
- size: 56, 56
- orig: 56, 56
- offset: 0, 0
- index: -1
-mech-trident-ship-full
- rotate: false
- xy: 157, 24
- size: 56, 56
- orig: 56, 56
- offset: 0, 0
- index: -1
meltdown
rotate: false
- xy: 1449, 1626
+ xy: 293, 445
size: 128, 128
orig: 128, 128
offset: 0, 0
index: -1
repair-point
rotate: false
- xy: 1489, 372
+ xy: 1490, 777
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
ripple
rotate: false
- xy: 815, 260
+ xy: 975, 1219
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
salvo
rotate: false
- xy: 1003, 1255
+ xy: 785, 336
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
scatter
rotate: false
- xy: 1092, 991
+ xy: 1007, 1153
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
scorch
rotate: false
- xy: 1455, 270
+ xy: 1456, 743
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
spectre
rotate: false
- xy: 1189, 1496
+ xy: 925, 1456
size: 128, 128
orig: 128, 128
offset: 0, 0
index: -1
swarmer
rotate: false
- xy: 1177, 67
+ xy: 1271, 1103
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
-unit-chaos-array-full
- rotate: false
- xy: 1319, 1496
- size: 128, 128
- orig: 128, 128
- offset: 0, 0
- index: -1
-unit-crawler-full
- rotate: false
- xy: 1286, 940
- size: 48, 48
- orig: 48, 48
- offset: 0, 0
- index: -1
unit-dagger-full
rotate: false
- xy: 1286, 890
+ xy: 1709, 1109
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
-unit-eradicator-full
+unit-vanguard-full
rotate: false
- xy: 259, 1122
- size: 152, 124
- orig: 152, 124
- offset: 0, 0
- index: -1
-unit-eruptor-full
- rotate: false
- xy: 1135, 1430
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-unit-fortress-full
- rotate: false
- xy: 1069, 1298
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-unit-titan-full
- rotate: false
- xy: 1135, 1364
- size: 64, 64
- orig: 64, 64
+ xy: 1761, 1209
+ size: 48, 48
+ orig: 48, 48
offset: 0, 0
index: -1
wave
rotate: false
- xy: 1267, 1364
+ xy: 1535, 1169
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
item-blast-compound
rotate: false
- xy: 1353, 794
+ xy: 963, 243
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-coal
rotate: false
- xy: 1353, 726
+ xy: 1031, 251
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-copper
rotate: false
- xy: 1353, 658
+ xy: 1099, 251
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-graphite
rotate: false
- xy: 1353, 590
+ xy: 1167, 251
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-lead
rotate: false
- xy: 1353, 522
+ xy: 997, 217
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-metaglass
rotate: false
- xy: 1353, 454
+ xy: 1065, 217
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-phase-fabric
rotate: false
- xy: 1353, 386
+ xy: 1133, 217
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-plastanium
rotate: false
- xy: 1353, 318
+ xy: 1201, 251
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-pyratite
rotate: false
- xy: 1353, 250
+ xy: 997, 183
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-sand
rotate: false
- xy: 1387, 770
+ xy: 1065, 183
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-scrap
rotate: false
- xy: 1387, 702
+ xy: 1133, 183
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-silicon
rotate: false
- xy: 1387, 634
+ xy: 1201, 183
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-spore-pod
rotate: false
- xy: 1387, 566
+ xy: 1616, 854
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-surge-alloy
rotate: false
- xy: 1387, 498
+ xy: 1684, 855
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-thorium
rotate: false
- xy: 1387, 430
+ xy: 1752, 855
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-titanium
rotate: false
- xy: 1387, 362
+ xy: 1628, 820
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
liquid-cryofluid
rotate: false
- xy: 1387, 294
+ xy: 1696, 821
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
liquid-oil
rotate: false
- xy: 1387, 226
+ xy: 1764, 821
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
liquid-slag
rotate: false
- xy: 1421, 550
+ xy: 1696, 787
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
liquid-water
rotate: false
- xy: 1421, 482
+ xy: 1764, 787
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
-alpha-mech
- rotate: false
- xy: 1399, 1446
- size: 48, 48
- orig: 48, 48
- offset: 0, 0
- index: -1
-alpha-mech-base
- rotate: false
- xy: 1119, 1190
- size: 48, 48
- orig: 48, 48
- offset: 0, 0
- index: -1
-alpha-mech-leg
- rotate: false
- xy: 1169, 1190
- size: 48, 48
- orig: 48, 48
- offset: 0, 0
- index: -1
-delta-mech
- rotate: false
- xy: 1849, 1380
- size: 48, 48
- orig: 48, 48
- offset: 0, 0
- index: -1
-delta-mech-base
- rotate: false
- xy: 1899, 1380
- size: 48, 48
- orig: 48, 48
- offset: 0, 0
- index: -1
-delta-mech-leg
- rotate: false
- xy: 1949, 1380
- size: 48, 48
- orig: 48, 48
- offset: 0, 0
- index: -1
-omega-mech
- rotate: false
- xy: 215, 24
- size: 56, 56
- orig: 56, 56
- offset: 0, 0
- index: -1
-omega-mech-armor
- rotate: false
- xy: 1077, 529
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-omega-mech-base
- rotate: false
- xy: 273, 24
- size: 56, 56
- orig: 56, 56
- offset: 0, 0
- index: -1
-omega-mech-leg
- rotate: false
- xy: 331, 24
- size: 56, 56
- orig: 56, 56
- offset: 0, 0
- index: -1
-tau-mech
- rotate: false
- xy: 1177, 1240
- size: 56, 56
- orig: 56, 56
- offset: 0, 0
- index: -1
-tau-mech-base
- rotate: false
- xy: 1236, 940
- size: 48, 48
- orig: 48, 48
- offset: 0, 0
- index: -1
-tau-mech-leg
- rotate: false
- xy: 1236, 890
- size: 48, 48
- orig: 48, 48
- offset: 0, 0
- index: -1
-dart-ship
- rotate: false
- xy: 1799, 1380
- size: 48, 48
- orig: 48, 48
- offset: 0, 0
- index: -1
-glaive-ship
- rotate: false
- xy: 99, 43
- size: 56, 56
- orig: 56, 56
- offset: 0, 0
- index: -1
-javelin-ship
- rotate: false
- xy: 1308, 1048
- size: 48, 48
- orig: 48, 48
- offset: 0, 0
- index: -1
-javelin-ship-shield
- rotate: false
- xy: 1358, 1156
- size: 48, 48
- orig: 48, 48
- offset: 0, 0
- index: -1
-trident-ship
- rotate: false
- xy: 1235, 1240
- size: 56, 56
- orig: 56, 56
- offset: 0, 0
- index: -1
blank
rotate: false
- xy: 423, 729
+ xy: 1, 1
size: 1, 1
orig: 1, 1
offset: 0, 0
index: -1
circle
rotate: false
- xy: 1, 943
+ xy: 825, 1846
size: 201, 201
orig: 201, 201
offset: 0, 0
index: -1
shape-3
rotate: false
- xy: 1333, 1365
+ xy: 1535, 1038
size: 63, 63
orig: 63, 63
offset: 0, 0
index: -1
+alpha
+ rotate: false
+ xy: 988, 913
+ size: 48, 48
+ orig: 48, 48
+ offset: 0, 0
+ index: -1
+alpha-base
+ rotate: false
+ xy: 930, 797
+ size: 48, 48
+ orig: 48, 48
+ offset: 0, 0
+ index: -1
+alpha-leg
+ rotate: false
+ xy: 1995, 1793
+ size: 48, 48
+ orig: 48, 48
+ offset: 0, 0
+ index: -1
chaos-array
rotate: false
- xy: 163, 342
+ xy: 1215, 1757
size: 128, 128
orig: 128, 128
offset: 0, 0
index: -1
chaos-array-base
rotate: false
- xy: 293, 472
+ xy: 1345, 1757
size: 128, 128
orig: 128, 128
offset: 0, 0
index: -1
chaos-array-leg
rotate: false
- xy: 163, 212
+ xy: 1475, 1757
size: 128, 128
orig: 128, 128
offset: 0, 0
index: -1
crawler
rotate: false
- xy: 1499, 1380
+ xy: 1138, 913
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
crawler-base
rotate: false
- xy: 1549, 1380
+ xy: 1138, 863
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
crawler-leg
rotate: false
- xy: 1599, 1380
+ xy: 1995, 1643
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
dagger
rotate: false
- xy: 1649, 1380
+ xy: 1173, 971
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
dagger-base
rotate: false
- xy: 1699, 1380
+ xy: 1223, 987
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
dagger-leg
rotate: false
- xy: 1749, 1380
+ xy: 1273, 987
+ size: 48, 48
+ orig: 48, 48
+ offset: 0, 0
+ index: -1
+dart
+ rotate: false
+ xy: 1323, 987
+ size: 48, 48
+ orig: 48, 48
+ offset: 0, 0
+ index: -1
+delta
+ rotate: false
+ xy: 1373, 987
+ size: 48, 48
+ orig: 48, 48
+ offset: 0, 0
+ index: -1
+delta-base
+ rotate: false
+ xy: 1423, 987
+ size: 48, 48
+ orig: 48, 48
+ offset: 0, 0
+ index: -1
+delta-leg
+ rotate: false
+ xy: 1473, 987
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
draug
rotate: false
- xy: 1999, 1380
+ xy: 1977, 1593
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
eradicator
rotate: false
- xy: 323, 1374
+ xy: 323, 1259
size: 152, 124
orig: 152, 124
offset: 0, 0
index: -1
eradicator-base
rotate: false
- xy: 645, 1680
+ xy: 665, 1601
size: 152, 124
orig: 152, 124
offset: 0, 0
index: -1
eradicator-leg
rotate: false
- xy: 259, 1248
+ xy: 1, 168
size: 152, 124
orig: 152, 124
offset: 0, 0
index: -1
eruptor
rotate: false
- xy: 988, 859
+ xy: 798, 930
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
eruptor-base
rotate: false
- xy: 1054, 925
+ xy: 732, 798
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
eruptor-leg
rotate: false
- xy: 1054, 859
+ xy: 798, 864
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
fortress
rotate: false
- xy: 945, 793
+ xy: 864, 930
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
fortress-base
rotate: false
- xy: 1011, 793
+ xy: 732, 732
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
titan-base
rotate: false
- xy: 1011, 793
+ xy: 732, 732
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
fortress-leg
rotate: false
- xy: 1077, 793
+ xy: 798, 798
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
ghoul
rotate: false
- xy: 549, 1652
+ xy: 1171, 1341
size: 72, 72
orig: 72, 72
offset: 0, 0
index: -1
+glaive
+ rotate: false
+ xy: 334, 706
+ size: 56, 56
+ orig: 56, 56
+ offset: 0, 0
+ index: -1
+javelin
+ rotate: false
+ xy: 1523, 987
+ size: 48, 48
+ orig: 48, 48
+ offset: 0, 0
+ index: -1
+javelin-shield
+ rotate: false
+ xy: 1538, 937
+ size: 48, 48
+ orig: 48, 48
+ offset: 0, 0
+ index: -1
lich
rotate: false
- xy: 645, 1806
+ xy: 1, 983
size: 216, 240
orig: 216, 240
offset: 0, 0
index: -1
+omega
+ rotate: false
+ xy: 1600, 1039
+ size: 56, 56
+ orig: 56, 56
+ offset: 0, 0
+ index: -1
+omega-armor
+ rotate: false
+ xy: 785, 600
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+omega-base
+ rotate: false
+ xy: 941, 963
+ size: 56, 56
+ orig: 56, 56
+ offset: 0, 0
+ index: -1
+omega-leg
+ rotate: false
+ xy: 999, 963
+ size: 56, 56
+ orig: 56, 56
+ offset: 0, 0
+ index: -1
phantom
rotate: false
- xy: 815, 6
+ xy: 1057, 963
size: 56, 56
orig: 56, 56
offset: 0, 0
index: -1
power-cell
rotate: false
- xy: 1119, 1240
+ xy: 1115, 963
size: 56, 56
orig: 56, 56
offset: 0, 0
index: -1
reaper
rotate: false
- xy: 323, 1726
- size: 320, 320
- orig: 320, 320
+ xy: 1, 1547
+ size: 500, 500
+ orig: 500, 500
offset: 0, 0
index: -1
revenant
rotate: false
- xy: 413, 1126
+ xy: 1079, 1513
size: 112, 112
orig: 112, 112
offset: 0, 0
index: -1
spirit
rotate: false
- xy: 1186, 940
+ xy: 1711, 1209
+ size: 48, 48
+ orig: 48, 48
+ offset: 0, 0
+ index: -1
+tau
+ rotate: false
+ xy: 930, 905
+ size: 56, 56
+ orig: 56, 56
+ offset: 0, 0
+ index: -1
+tau-base
+ rotate: false
+ xy: 1659, 1109
+ size: 48, 48
+ orig: 48, 48
+ offset: 0, 0
+ index: -1
+tau-leg
+ rotate: false
+ xy: 1709, 1159
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
titan
rotate: false
- xy: 1177, 1
+ xy: 1271, 1037
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
titan-leg
rotate: false
- xy: 1069, 1430
+ xy: 1337, 1103
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
+trident
+ rotate: false
+ xy: 930, 847
+ size: 56, 56
+ orig: 56, 56
+ offset: 0, 0
+ index: -1
+vanguard
+ rotate: false
+ xy: 1759, 1159
+ size: 48, 48
+ orig: 48, 48
+ offset: 0, 0
+ index: -1
wraith
rotate: false
- xy: 1209, 840
+ xy: 1238, 837
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
artillery-equip
rotate: false
- xy: 1158, 1132
+ xy: 988, 855
size: 48, 56
orig: 48, 56
offset: 0, 0
index: -1
blaster-equip
rotate: false
- xy: 1219, 1190
+ xy: 1038, 913
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
bomber-equip
rotate: false
- xy: 1399, 1396
+ xy: 1995, 1693
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
missiles-equip
rotate: false
- xy: 1399, 1396
+ xy: 1995, 1693
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
chain-blaster-equip
rotate: false
- xy: 1449, 1380
+ xy: 1088, 863
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
chaos-equip
rotate: false
- xy: 1243, 61
+ xy: 1601, 1097
size: 56, 136
orig: 56, 136
offset: 0, 0
index: -1
eradication-equip
rotate: false
- xy: 619, 339
+ xy: 436, 805
size: 96, 192
orig: 96, 192
offset: 0, 0
index: -1
eruption-equip
rotate: false
- xy: 1325, 1306
+ xy: 917, 589
size: 48, 56
orig: 48, 56
offset: 0, 0
index: -1
flakgun-equip
rotate: false
- xy: 1448, 1330
+ xy: 917, 539
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
flamethrower-equip
rotate: false
- xy: 1498, 1322
+ xy: 917, 481
size: 48, 56
orig: 48, 56
offset: 0, 0
index: -1
heal-blaster-equip
rotate: false
- xy: 1548, 1330
+ xy: 917, 431
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
lich-missiles-equip
rotate: false
- xy: 1358, 1106
+ xy: 1538, 887
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
reaper-gun-equip
rotate: false
- xy: 1258, 990
+ xy: 1638, 939
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
revenant-missiles-equip
rotate: false
- xy: 1308, 998
+ xy: 1638, 889
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
shockgun-equip
rotate: false
- xy: 1358, 1006
+ xy: 1661, 1209
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
swarmer-equip
rotate: false
- xy: 1186, 890
+ xy: 1659, 1159
+ size: 48, 48
+ orig: 48, 48
+ offset: 0, 0
+ index: -1
+vanguard-blaster-equip
+ rotate: false
+ xy: 1759, 1109
size: 48, 48
orig: 48, 48
offset: 0, 0
@@ -5864,112 +5584,119 @@ filter: Nearest,Nearest
repeat: none
char1
rotate: false
- xy: 1825, 479
+ xy: 589, 107
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
char2
rotate: false
- xy: 315, 59
+ xy: 415, 59
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
char3
rotate: false
- xy: 349, 59
+ xy: 449, 59
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+cliff
+ rotate: false
+ xy: 483, 59
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
cliffs1
rotate: false
- xy: 1859, 479
+ xy: 517, 59
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
coal1
rotate: false
- xy: 383, 59
+ xy: 551, 59
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
coal2
rotate: false
- xy: 1893, 479
+ xy: 1429, 217
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
coal3
rotate: false
- xy: 417, 59
+ xy: 1495, 283
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
copper1
rotate: false
- xy: 1927, 479
+ xy: 1593, 381
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
copper2
rotate: false
- xy: 451, 59
+ xy: 1463, 217
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
copper3
rotate: false
- xy: 1961, 479
+ xy: 1593, 347
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
craters1
rotate: false
- xy: 485, 59
+ xy: 645, 185
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
craters2
rotate: false
- xy: 1995, 479
+ xy: 679, 185
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
craters3
rotate: false
- xy: 519, 59
+ xy: 713, 185
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
craters4
rotate: false
- xy: 553, 59
+ xy: 747, 185
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
craters5
rotate: false
- xy: 1429, 217
+ xy: 781, 185
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
craters6
rotate: false
- xy: 1495, 283
+ xy: 815, 185
size: 32, 32
orig: 32, 32
offset: 0, 0
@@ -5983,21 +5710,21 @@ dark-metal-large
index: -1
dark-metal1
rotate: false
- xy: 1627, 347
+ xy: 849, 185
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
dark-metal2
rotate: false
- xy: 1463, 217
+ xy: 883, 185
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
dark-panel-1
rotate: false
- xy: 645, 185
+ xy: 917, 185
size: 32, 32
orig: 32, 32
offset: 0, 0
@@ -6011,7 +5738,7 @@ dark-panel-1-edge
index: -1
dark-panel-2
rotate: false
- xy: 679, 185
+ xy: 951, 185
size: 32, 32
orig: 32, 32
offset: 0, 0
@@ -6025,7 +5752,7 @@ dark-panel-2-edge
index: -1
dark-panel-3
rotate: false
- xy: 713, 185
+ xy: 985, 185
size: 32, 32
orig: 32, 32
offset: 0, 0
@@ -6039,7 +5766,7 @@ dark-panel-3-edge
index: -1
dark-panel-4
rotate: false
- xy: 747, 185
+ xy: 1019, 185
size: 32, 32
orig: 32, 32
offset: 0, 0
@@ -6053,7 +5780,7 @@ dark-panel-4-edge
index: -1
dark-panel-5
rotate: false
- xy: 781, 185
+ xy: 1053, 185
size: 32, 32
orig: 32, 32
offset: 0, 0
@@ -6067,7 +5794,7 @@ dark-panel-5-edge
index: -1
dark-panel-6
rotate: false
- xy: 815, 185
+ xy: 1087, 185
size: 32, 32
orig: 32, 32
offset: 0, 0
@@ -6088,7 +5815,7 @@ darksand-edge
index: -1
darksand-tainted-water
rotate: false
- xy: 951, 185
+ xy: 1223, 185
size: 32, 32
orig: 32, 32
offset: 0, 0
@@ -6100,9 +5827,30 @@ darksand-tainted-water-edge
orig: 96, 96
offset: 0, 0
index: -1
+darksand-tainted-water1
+ rotate: false
+ xy: 1257, 185
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+darksand-tainted-water2
+ rotate: false
+ xy: 1291, 185
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+darksand-tainted-water3
+ rotate: false
+ xy: 1325, 185
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
darksand-water
rotate: false
- xy: 985, 185
+ xy: 1359, 185
size: 32, 32
orig: 32, 32
offset: 0, 0
@@ -6114,30 +5862,51 @@ darksand-water-edge
orig: 96, 96
offset: 0, 0
index: -1
+darksand-water1
+ rotate: false
+ xy: 1393, 185
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+darksand-water2
+ rotate: false
+ xy: 1427, 183
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+darksand-water3
+ rotate: false
+ xy: 1461, 183
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
darksand1
rotate: false
- xy: 849, 185
+ xy: 1121, 185
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
darksand2
rotate: false
- xy: 883, 185
+ xy: 1155, 185
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
darksand3
rotate: false
- xy: 917, 185
+ xy: 1189, 185
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
deepwater
rotate: false
- xy: 1019, 185
+ xy: 639, 151
size: 32, 32
orig: 32, 32
offset: 0, 0
@@ -6151,28 +5920,28 @@ deepwater-edge
index: -1
dunerocks-large
rotate: false
- xy: 1527, 447
+ xy: 1429, 251
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
dunerocks1
rotate: false
- xy: 1053, 185
+ xy: 673, 151
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
dunerocks2
rotate: false
- xy: 1087, 185
+ xy: 707, 151
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
edge
rotate: false
- xy: 1121, 185
+ xy: 741, 151
size: 32, 32
orig: 32, 32
offset: 0, 0
@@ -6186,7 +5955,7 @@ edge-stencil
index: -1
edgier
rotate: false
- xy: 1155, 185
+ xy: 775, 151
size: 32, 32
orig: 32, 32
offset: 0, 0
@@ -6200,21 +5969,21 @@ grass-edge
index: -1
grass1
rotate: false
- xy: 1189, 185
+ xy: 809, 151
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
grass2
rotate: false
- xy: 1223, 185
+ xy: 843, 151
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
grass3
rotate: false
- xy: 1257, 185
+ xy: 877, 151
size: 32, 32
orig: 32, 32
offset: 0, 0
@@ -6228,42 +5997,42 @@ holostone-edge
index: -1
holostone1
rotate: false
- xy: 1291, 185
+ xy: 911, 151
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
holostone2
rotate: false
- xy: 1325, 185
+ xy: 945, 151
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
holostone3
rotate: false
- xy: 1359, 185
+ xy: 979, 151
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
hotrock1
rotate: false
- xy: 1393, 185
+ xy: 1013, 151
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
hotrock2
rotate: false
- xy: 1427, 183
+ xy: 1047, 151
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
hotrock3
rotate: false
- xy: 1461, 183
+ xy: 1081, 151
size: 32, 32
orig: 32, 32
offset: 0, 0
@@ -6284,63 +6053,63 @@ ice-snow-edge
index: -1
ice-snow1
rotate: false
- xy: 741, 151
+ xy: 1217, 151
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
ice-snow2
rotate: false
- xy: 775, 151
+ xy: 1251, 151
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
ice-snow3
rotate: false
- xy: 809, 151
+ xy: 1285, 151
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
ice1
rotate: false
- xy: 639, 151
+ xy: 1115, 151
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
ice2
rotate: false
- xy: 673, 151
+ xy: 1149, 151
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
ice3
rotate: false
- xy: 707, 151
+ xy: 1183, 151
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
icerocks-large
rotate: false
- xy: 1429, 251
+ xy: 1527, 349
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
icerocks1
rotate: false
- xy: 843, 151
+ xy: 1319, 151
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
icerocks2
rotate: false
- xy: 877, 151
+ xy: 1353, 151
size: 32, 32
orig: 32, 32
offset: 0, 0
@@ -6354,77 +6123,77 @@ ignarock-edge
index: -1
ignarock1
rotate: false
- xy: 911, 151
+ xy: 1387, 151
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
ignarock2
rotate: false
- xy: 945, 151
+ xy: 1421, 149
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
ignarock3
rotate: false
- xy: 979, 151
+ xy: 1455, 149
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
lead1
rotate: false
- xy: 1013, 151
+ xy: 391, 9
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
lead2
rotate: false
- xy: 1047, 151
+ xy: 425, 25
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
lead3
rotate: false
- xy: 1081, 151
+ xy: 459, 25
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
magmarock1
rotate: false
- xy: 1115, 151
+ xy: 493, 25
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
magmarock2
rotate: false
- xy: 1149, 151
+ xy: 527, 25
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
magmarock3
rotate: false
- xy: 1183, 151
+ xy: 561, 25
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
metal-floor
rotate: false
- xy: 1217, 151
+ xy: 1889, 429
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
metal-floor-2
rotate: false
- xy: 1251, 151
+ xy: 1923, 429
size: 32, 32
orig: 32, 32
offset: 0, 0
@@ -6438,7 +6207,7 @@ metal-floor-2-edge
index: -1
metal-floor-3
rotate: false
- xy: 1285, 151
+ xy: 1957, 429
size: 32, 32
orig: 32, 32
offset: 0, 0
@@ -6452,7 +6221,7 @@ metal-floor-3-edge
index: -1
metal-floor-5
rotate: false
- xy: 1319, 151
+ xy: 1991, 429
size: 32, 32
orig: 32, 32
offset: 0, 0
@@ -6473,21 +6242,21 @@ metal-floor-damaged-edge
index: -1
metal-floor-damaged1
rotate: false
- xy: 1353, 151
+ xy: 623, 107
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
metal-floor-damaged2
rotate: false
- xy: 1387, 151
+ xy: 657, 117
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
metal-floor-damaged3
rotate: false
- xy: 1421, 149
+ xy: 691, 117
size: 32, 32
orig: 32, 32
offset: 0, 0
@@ -6508,168 +6277,168 @@ moss-edge
index: -1
moss1
rotate: false
- xy: 1455, 149
+ xy: 725, 117
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
moss2
rotate: false
- xy: 1529, 297
+ xy: 759, 117
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
moss3
rotate: false
- xy: 1563, 297
+ xy: 793, 117
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
ore-coal1
rotate: false
- xy: 1597, 297
+ xy: 827, 117
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
ore-coal2
rotate: false
- xy: 349, 25
+ xy: 861, 117
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
ore-coal3
rotate: false
- xy: 383, 25
+ xy: 895, 117
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
ore-copper1
rotate: false
- xy: 417, 25
+ xy: 929, 117
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
ore-copper2
rotate: false
- xy: 451, 25
+ xy: 963, 117
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
ore-copper3
rotate: false
- xy: 485, 25
+ xy: 997, 117
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
ore-lead1
rotate: false
- xy: 519, 25
+ xy: 1031, 117
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
ore-lead2
rotate: false
- xy: 553, 25
+ xy: 1065, 117
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
ore-lead3
rotate: false
- xy: 1661, 363
+ xy: 1099, 117
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
ore-scrap1
rotate: false
- xy: 1709, 413
+ xy: 1133, 117
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
ore-scrap2
rotate: false
- xy: 1743, 429
+ xy: 1167, 117
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
ore-scrap3
rotate: false
- xy: 1777, 429
+ xy: 1201, 117
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
ore-thorium1
rotate: false
- xy: 1825, 445
+ xy: 1235, 117
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
ore-thorium2
rotate: false
- xy: 1859, 445
+ xy: 1269, 117
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
ore-thorium3
rotate: false
- xy: 1893, 445
+ xy: 1303, 117
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
ore-titanium1
rotate: false
- xy: 1927, 445
+ xy: 1337, 117
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
ore-titanium2
rotate: false
- xy: 1961, 445
+ xy: 1371, 117
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
ore-titanium3
rotate: false
- xy: 1995, 445
+ xy: 1405, 115
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
pebbles1
rotate: false
- xy: 1661, 329
+ xy: 1439, 115
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
pebbles2
rotate: false
- xy: 1709, 379
+ xy: 1473, 115
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
pebbles3
rotate: false
- xy: 1743, 395
+ xy: 1489, 149
size: 32, 32
orig: 32, 32
offset: 0, 0
@@ -6683,42 +6452,42 @@ pine
index: -1
rock1
rotate: false
- xy: 1527, 331
+ xy: 265, 43
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
rock2
rotate: false
- xy: 1659, 397
+ xy: 1889, 463
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
rocks-large
rotate: false
- xy: 67, 27
+ xy: 1625, 447
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
rocks1
rotate: false
- xy: 1777, 395
+ xy: 1495, 183
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
rocks2
rotate: false
- xy: 1811, 411
+ xy: 1507, 115
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
salt
rotate: false
- xy: 1845, 411
+ xy: 1523, 149
size: 32, 32
orig: 32, 32
offset: 0, 0
@@ -6732,35 +6501,35 @@ salt-edge
index: -1
saltrocks-large
rotate: false
- xy: 1527, 381
+ xy: 67, 27
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
saltrocks1
rotate: false
- xy: 1879, 411
+ xy: 1541, 115
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
saltrocks2
rotate: false
- xy: 1913, 411
+ xy: 589, 73
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
sand-boulder1
rotate: false
- xy: 1695, 345
+ xy: 725, 83
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
sand-boulder2
rotate: false
- xy: 1743, 361
+ xy: 759, 83
size: 32, 32
orig: 32, 32
offset: 0, 0
@@ -6774,7 +6543,7 @@ sand-edge
index: -1
sand-water
rotate: false
- xy: 1777, 361
+ xy: 793, 83
size: 32, 32
orig: 32, 32
offset: 0, 0
@@ -6786,79 +6555,100 @@ sand-water-edge
orig: 96, 96
offset: 0, 0
index: -1
+sand-water1
+ rotate: false
+ xy: 827, 83
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+sand-water2
+ rotate: false
+ xy: 861, 83
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+sand-water3
+ rotate: false
+ xy: 895, 83
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
sand1
rotate: false
- xy: 1947, 411
+ xy: 623, 73
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
sand2
rotate: false
- xy: 1981, 411
+ xy: 657, 83
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
sand3
rotate: false
- xy: 2015, 411
+ xy: 691, 83
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
sandrocks-large
rotate: false
- xy: 1593, 447
+ xy: 1691, 447
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
sandrocks1
rotate: false
- xy: 1811, 377
+ xy: 929, 83
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
sandrocks2
rotate: false
- xy: 1845, 377
+ xy: 963, 83
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
scrap1
rotate: false
- xy: 1879, 377
+ xy: 997, 83
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
scrap2
rotate: false
- xy: 1913, 377
+ xy: 1031, 83
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
scrap3
rotate: false
- xy: 1947, 377
+ xy: 1065, 83
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
shale-boulder1
rotate: false
- xy: 1729, 327
+ xy: 1201, 83
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
shale-boulder2
rotate: false
- xy: 1763, 327
+ xy: 1235, 83
size: 32, 32
orig: 32, 32
offset: 0, 0
@@ -6872,21 +6662,21 @@ shale-edge
index: -1
shale1
rotate: false
- xy: 1981, 377
+ xy: 1099, 83
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
shale2
rotate: false
- xy: 2015, 377
+ xy: 1133, 83
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
shale3
rotate: false
- xy: 1695, 311
+ xy: 1167, 83
size: 32, 32
orig: 32, 32
offset: 0, 0
@@ -6900,112 +6690,126 @@ shalerocks-large
index: -1
shalerocks1
rotate: false
- xy: 1811, 343
+ xy: 1269, 83
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
shalerocks2
rotate: false
- xy: 1845, 343
+ xy: 1303, 83
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
shrubs-large
rotate: false
- xy: 1593, 381
+ xy: 1757, 447
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
shrubs1
rotate: false
- xy: 1879, 343
+ xy: 1337, 83
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
shrubs2
rotate: false
- xy: 1913, 343
+ xy: 1371, 83
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
-snow-edge
+slag
+ rotate: false
+ xy: 1405, 81
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+slag-edge
rotate: false
xy: 1331, 415
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
+snow-edge
+ rotate: false
+ xy: 1233, 219
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
snow-pine
rotate: false
- xy: 1725, 463
+ xy: 315, 43
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
snow1
rotate: false
- xy: 1947, 343
+ xy: 1439, 81
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
snow2
rotate: false
- xy: 1981, 343
+ xy: 1473, 81
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
snow3
rotate: false
- xy: 2015, 343
+ xy: 1507, 81
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
snowrock1
rotate: false
- xy: 265, 43
+ xy: 1939, 463
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
snowrock2
rotate: false
- xy: 1577, 331
+ xy: 365, 43
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
snowrocks-large
rotate: false
- xy: 1659, 447
+ xy: 199, 27
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
snowrocks1
rotate: false
- xy: 1729, 293
+ xy: 1541, 81
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
snowrocks2
rotate: false
- xy: 1763, 293
+ xy: 595, 39
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
spawn
rotate: false
- xy: 1797, 309
+ xy: 629, 39
size: 32, 32
orig: 32, 32
offset: 0, 0
@@ -7026,196 +6830,196 @@ spore-cluster2
index: -1
spore-cluster3
rotate: false
- xy: 589, 99
+ xy: 349, 1
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
spore-moss-edge
rotate: false
- xy: 1233, 219
+ xy: 1331, 317
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
spore-moss1
rotate: false
- xy: 1831, 309
+ xy: 663, 49
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
spore-moss2
rotate: false
- xy: 1865, 309
+ xy: 697, 49
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
spore-moss3
rotate: false
- xy: 1899, 309
+ xy: 731, 49
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
spore-pine
rotate: false
- xy: 1775, 463
+ xy: 1989, 463
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
sporerocks-large
rotate: false
- xy: 199, 27
+ xy: 1823, 447
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
sporerocks1
rotate: false
- xy: 1933, 309
+ xy: 765, 49
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
sporerocks2
rotate: false
- xy: 1967, 309
+ xy: 799, 49
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
stone-edge
rotate: false
- xy: 1331, 317
+ xy: 1429, 415
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
stone1
rotate: false
- xy: 2001, 309
+ xy: 833, 49
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
stone2
rotate: false
- xy: 1797, 275
+ xy: 867, 49
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
stone3
rotate: false
- xy: 1831, 275
+ xy: 901, 49
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
tainted-water
rotate: false
- xy: 1865, 275
+ xy: 935, 49
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
tainted-water-edge
rotate: false
- xy: 1429, 415
+ xy: 1331, 219
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
tar
rotate: false
- xy: 1899, 275
+ xy: 969, 49
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
tar-edge
rotate: false
- xy: 1331, 219
+ xy: 1429, 317
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
tendrils1
rotate: false
- xy: 1933, 275
+ xy: 1003, 49
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
tendrils2
rotate: false
- xy: 1967, 275
+ xy: 1037, 49
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
tendrils3
rotate: false
- xy: 2001, 275
+ xy: 1071, 49
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
thorium1
rotate: false
- xy: 1529, 263
+ xy: 1105, 49
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
thorium2
rotate: false
- xy: 1563, 263
+ xy: 1139, 49
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
thorium3
rotate: false
- xy: 1597, 263
+ xy: 1173, 49
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
titanium1
rotate: false
- xy: 639, 117
+ xy: 1207, 49
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
titanium2
rotate: false
- xy: 673, 117
+ xy: 1241, 49
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
titanium3
rotate: false
- xy: 707, 117
+ xy: 1275, 49
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
water
rotate: false
- xy: 741, 117
+ xy: 1309, 49
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
water-edge
rotate: false
- xy: 1429, 317
+ xy: 1527, 415
size: 96, 96
orig: 96, 96
offset: 0, 0
@@ -7249,7 +7053,7 @@ alpha-bg
index: -1
bar
rotate: false
- xy: 986, 337
+ xy: 1899, 869
size: 27, 36
split: 9, 9, 9, 9
orig: 27, 36
@@ -7257,7 +7061,7 @@ bar
index: -1
bar-top
rotate: false
- xy: 955, 303
+ xy: 1870, 869
size: 27, 36
split: 9, 10, 9, 10
orig: 27, 36
@@ -7272,21 +7076,21 @@ block-alloy-smelter-large
index: -1
block-alloy-smelter-medium
rotate: false
- xy: 1929, 899
+ xy: 821, 944
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-alloy-smelter-small
rotate: false
- xy: 781, 690
+ xy: 1981, 949
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-alloy-smelter-tiny
rotate: false
- xy: 2031, 923
+ xy: 301, 1
size: 16, 16
orig: 16, 16
offset: 0, 0
@@ -7307,21 +7111,21 @@ block-arc-large
index: -1
block-arc-medium
rotate: false
- xy: 1963, 899
+ xy: 1505, 941
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-arc-small
rotate: false
- xy: 80, 2
+ xy: 781, 690
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-arc-tiny
rotate: false
- xy: 2031, 905
+ xy: 319, 1
size: 16, 16
orig: 16, 16
offset: 0, 0
@@ -7335,28 +7139,28 @@ block-arc-xlarge
index: -1
block-armored-conveyor-large
rotate: false
- xy: 551, 474
+ xy: 401, 424
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-armored-conveyor-medium
rotate: false
- xy: 1997, 907
+ xy: 1539, 941
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-armored-conveyor-small
rotate: false
- xy: 1015, 349
+ xy: 38, 2
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-armored-conveyor-tiny
rotate: false
- xy: 301, 1
+ xy: 309, 698
size: 16, 16
orig: 16, 16
offset: 0, 0
@@ -7370,35 +7174,35 @@ block-armored-conveyor-xlarge
index: -1
block-battery-large
rotate: false
- xy: 601, 524
+ xy: 451, 474
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-battery-large-large
rotate: false
- xy: 651, 574
+ xy: 501, 524
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-battery-large-medium
rotate: false
- xy: 859, 857
+ xy: 1573, 941
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-battery-large-small
rotate: false
- xy: 1913, 810
+ xy: 859, 682
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-battery-large-tiny
rotate: false
- xy: 319, 1
+ xy: 331, 598
size: 16, 16
orig: 16, 16
offset: 0, 0
@@ -7412,21 +7216,21 @@ block-battery-large-xlarge
index: -1
block-battery-medium
rotate: false
- xy: 859, 823
+ xy: 1607, 941
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-battery-small
rotate: false
- xy: 1942, 873
+ xy: 1505, 711
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-battery-tiny
rotate: false
- xy: 309, 698
+ xy: 761, 598
size: 16, 16
orig: 16, 16
offset: 0, 0
@@ -7440,28 +7244,28 @@ block-battery-xlarge
index: -1
block-blast-drill-large
rotate: false
- xy: 351, 224
+ xy: 551, 574
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-blast-drill-medium
rotate: false
- xy: 893, 857
+ xy: 1641, 941
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-blast-drill-small
rotate: false
- xy: 106, 2
+ xy: 1675, 745
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-blast-drill-tiny
rotate: false
- xy: 331, 598
+ xy: 1907, 851
size: 16, 16
orig: 16, 16
offset: 0, 0
@@ -7475,28 +7279,28 @@ block-blast-drill-xlarge
index: -1
block-blast-mixer-large
rotate: false
- xy: 401, 274
+ xy: 351, 324
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-blast-mixer-medium
rotate: false
- xy: 859, 789
+ xy: 1675, 941
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-blast-mixer-small
rotate: false
- xy: 1913, 784
+ xy: 1709, 779
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-blast-mixer-tiny
rotate: false
- xy: 955, 285
+ xy: 1059, 534
size: 16, 16
orig: 16, 16
offset: 0, 0
@@ -7510,28 +7314,28 @@ block-blast-mixer-xlarge
index: -1
block-bridge-conduit-large
rotate: false
- xy: 451, 324
+ xy: 401, 382
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-bridge-conduit-medium
rotate: false
- xy: 927, 857
+ xy: 1709, 941
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-bridge-conduit-small
rotate: false
- xy: 1942, 847
+ xy: 1743, 813
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-bridge-conduit-tiny
rotate: false
- xy: 132, 10
+ xy: 1015, 482
size: 16, 16
orig: 16, 16
offset: 0, 0
@@ -7545,28 +7349,28 @@ block-bridge-conduit-xlarge
index: -1
block-bridge-conveyor-large
rotate: false
- xy: 501, 374
+ xy: 593, 574
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-bridge-conveyor-medium
rotate: false
- xy: 893, 823
+ xy: 1743, 941
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-bridge-conveyor-small
rotate: false
- xy: 1968, 873
+ xy: 1777, 841
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-bridge-conveyor-tiny
rotate: false
- xy: 1065, 422
+ xy: 1033, 508
size: 16, 16
orig: 16, 16
offset: 0, 0
@@ -7580,28 +7384,28 @@ block-bridge-conveyor-xlarge
index: -1
block-char-large
rotate: false
- xy: 551, 432
+ xy: 351, 282
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-char-medium
rotate: false
- xy: 859, 755
+ xy: 1777, 941
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-char-small
rotate: false
- xy: 1913, 758
+ xy: 1957, 881
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-char-tiny
rotate: false
- xy: 1325, 578
+ xy: 309, 680
size: 16, 16
orig: 16, 16
offset: 0, 0
@@ -7613,140 +7417,140 @@ block-char-xlarge
orig: 48, 48
offset: 0, 0
index: -1
-block-cliffs-large
+block-cliff-large
rotate: false
- xy: 693, 574
+ xy: 635, 574
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
-block-cliffs-medium
+block-cliff-medium
rotate: false
- xy: 961, 857
+ xy: 1811, 941
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
-block-cliffs-small
+block-cliff-small
rotate: false
- xy: 1968, 847
+ xy: 64, 2
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
-block-cliffs-tiny
+block-cliff-tiny
rotate: false
- xy: 1221, 448
+ xy: 331, 580
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
-block-cliffs-xlarge
+block-cliff-xlarge
rotate: false
xy: 51, 428
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
-block-coal-centrifuge-large
+block-cliffs-large
rotate: false
- xy: 351, 182
+ xy: 351, 240
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
-block-coal-centrifuge-medium
+block-cliffs-medium
rotate: false
- xy: 927, 823
+ xy: 1845, 941
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
-block-coal-centrifuge-small
+block-cliffs-small
rotate: false
- xy: 1913, 732
+ xy: 885, 682
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
-block-coal-centrifuge-tiny
+block-cliffs-tiny
rotate: false
- xy: 1273, 484
+ xy: 761, 580
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
-block-coal-centrifuge-xlarge
+block-cliffs-xlarge
rotate: false
xy: 181, 558
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
-block-combustion-generator-large
+block-coal-centrifuge-large
rotate: false
- xy: 735, 574
+ xy: 677, 574
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
-block-combustion-generator-medium
+block-coal-centrifuge-medium
rotate: false
- xy: 893, 789
+ xy: 1879, 941
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
-block-combustion-generator-small
+block-coal-centrifuge-small
rotate: false
- xy: 1913, 706
+ xy: 1531, 711
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
-block-combustion-generator-tiny
+block-coal-centrifuge-tiny
rotate: false
- xy: 1299, 515
+ xy: 1077, 534
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
-block-combustion-generator-xlarge
+block-coal-centrifuge-xlarge
rotate: false
xy: 259, 719
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
-block-command-center-large
+block-combustion-generator-large
rotate: false
- xy: 351, 140
+ xy: 351, 198
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
-block-command-center-medium
+block-combustion-generator-medium
rotate: false
- xy: 859, 721
+ xy: 1913, 941
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
-block-command-center-small
+block-combustion-generator-small
rotate: false
- xy: 984, 311
+ xy: 1803, 841
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
-block-command-center-tiny
+block-combustion-generator-tiny
rotate: false
- xy: 309, 680
+ xy: 1015, 464
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
-block-command-center-xlarge
+block-combustion-generator-xlarge
rotate: false
xy: 1, 328
size: 48, 48
@@ -7755,28 +7559,28 @@ block-command-center-xlarge
index: -1
block-conduit-large
rotate: false
- xy: 351, 98
+ xy: 719, 574
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-conduit-medium
rotate: false
- xy: 995, 857
+ xy: 1947, 941
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-conduit-small
rotate: false
- xy: 1041, 349
+ xy: 1957, 855
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-conduit-tiny
rotate: false
- xy: 331, 580
+ xy: 1033, 490
size: 16, 16
orig: 16, 16
offset: 0, 0
@@ -7790,28 +7594,28 @@ block-conduit-xlarge
index: -1
block-container-large
rotate: false
- xy: 351, 56
+ xy: 351, 156
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-container-medium
rotate: false
- xy: 961, 823
+ xy: 981, 334
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-container-small
rotate: false
- xy: 729, 2
+ xy: 1983, 881
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-container-tiny
rotate: false
- xy: 1083, 422
+ xy: 1095, 534
size: 16, 16
orig: 16, 16
offset: 0, 0
@@ -7825,28 +7629,28 @@ block-container-xlarge
index: -1
block-conveyor-large
rotate: false
- xy: 351, 14
+ xy: 351, 114
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-conveyor-medium
rotate: false
- xy: 927, 789
+ xy: 981, 300
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-conveyor-small
rotate: false
- xy: 755, 2
+ xy: 90, 2
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-conveyor-tiny
rotate: false
- xy: 1325, 560
+ xy: 1015, 446
size: 16, 16
orig: 16, 16
offset: 0, 0
@@ -7860,35 +7664,35 @@ block-conveyor-xlarge
index: -1
block-copper-wall-large
rotate: false
- xy: 551, 390
+ xy: 351, 72
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-copper-wall-large-large
rotate: false
- xy: 593, 474
+ xy: 351, 30
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-copper-wall-large-medium
rotate: false
- xy: 893, 755
+ xy: 981, 266
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-copper-wall-large-small
rotate: false
- xy: 781, 2
+ xy: 911, 682
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-copper-wall-large-tiny
rotate: false
- xy: 1343, 578
+ xy: 1033, 472
size: 16, 16
orig: 16, 16
offset: 0, 0
@@ -7902,21 +7706,21 @@ block-copper-wall-large-xlarge
index: -1
block-copper-wall-medium
rotate: false
- xy: 859, 687
+ xy: 981, 232
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-copper-wall-small
rotate: false
- xy: 807, 2
+ xy: 1557, 711
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-copper-wall-tiny
rotate: false
- xy: 1101, 422
+ xy: 1113, 534
size: 16, 16
orig: 16, 16
offset: 0, 0
@@ -7930,28 +7734,28 @@ block-copper-wall-xlarge
index: -1
block-core-foundation-large
rotate: false
- xy: 593, 432
+ xy: 401, 340
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-core-foundation-medium
rotate: false
- xy: 995, 823
+ xy: 981, 198
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-core-foundation-small
rotate: false
- xy: 833, 2
+ xy: 1829, 841
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-core-foundation-tiny
rotate: false
- xy: 1325, 542
+ xy: 1015, 428
size: 16, 16
orig: 16, 16
offset: 0, 0
@@ -7965,28 +7769,28 @@ block-core-foundation-xlarge
index: -1
block-core-nucleus-large
rotate: false
- xy: 593, 390
+ xy: 393, 298
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-core-nucleus-medium
rotate: false
- xy: 961, 789
+ xy: 977, 164
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-core-nucleus-small
rotate: false
- xy: 859, 2
+ xy: 1983, 855
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-core-nucleus-tiny
rotate: false
- xy: 1343, 560
+ xy: 1033, 454
size: 16, 16
orig: 16, 16
offset: 0, 0
@@ -8000,28 +7804,28 @@ block-core-nucleus-xlarge
index: -1
block-core-shard-large
rotate: false
- xy: 643, 524
+ xy: 393, 256
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-core-shard-medium
rotate: false
- xy: 927, 755
+ xy: 977, 130
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-core-shard-small
rotate: false
- xy: 885, 2
+ xy: 2009, 881
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-core-shard-tiny
rotate: false
- xy: 1361, 578
+ xy: 1131, 534
size: 16, 16
orig: 16, 16
offset: 0, 0
@@ -8035,28 +7839,28 @@ block-core-shard-xlarge
index: -1
block-craters-large
rotate: false
- xy: 635, 482
+ xy: 393, 214
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-craters-medium
rotate: false
- xy: 893, 721
+ xy: 977, 96
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-craters-small
rotate: false
- xy: 911, 2
+ xy: 116, 2
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-craters-tiny
rotate: false
- xy: 1119, 422
+ xy: 1015, 410
size: 16, 16
orig: 16, 16
offset: 0, 0
@@ -8068,6239 +7872,5749 @@ block-craters-xlarge
orig: 48, 48
offset: 0, 0
index: -1
-block-crawler-factory-large
- rotate: false
- xy: 635, 440
- size: 40, 40
- orig: 40, 40
- offset: 0, 0
- index: -1
-block-crawler-factory-medium
- rotate: false
- xy: 995, 789
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-crawler-factory-small
- rotate: false
- xy: 1063, 674
- size: 24, 24
- orig: 24, 24
- offset: 0, 0
- index: -1
-block-crawler-factory-tiny
- rotate: false
- xy: 1343, 542
- size: 16, 16
- orig: 16, 16
- offset: 0, 0
- index: -1
-block-crawler-factory-xlarge
- rotate: false
- xy: 51, 178
- size: 48, 48
- orig: 48, 48
- offset: 0, 0
- index: -1
block-cryofluidmixer-large
rotate: false
- xy: 635, 398
+ xy: 393, 172
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-cryofluidmixer-medium
rotate: false
- xy: 961, 755
+ xy: 977, 62
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-cryofluidmixer-small
rotate: false
- xy: 1089, 674
+ xy: 937, 682
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-cryofluidmixer-tiny
rotate: false
- xy: 1361, 560
+ xy: 1033, 436
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-cryofluidmixer-xlarge
rotate: false
- xy: 1, 78
+ xy: 51, 178
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-cultivator-large
rotate: false
- xy: 685, 532
+ xy: 393, 130
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-cultivator-medium
rotate: false
- xy: 927, 721
+ xy: 977, 28
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-cultivator-small
rotate: false
- xy: 1115, 674
+ xy: 1583, 711
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-cultivator-tiny
rotate: false
- xy: 1379, 578
+ xy: 1149, 534
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-cultivator-xlarge
rotate: false
- xy: 51, 128
+ xy: 1, 78
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-cyclone-large
rotate: false
- xy: 727, 532
+ xy: 393, 88
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-cyclone-medium
rotate: false
- xy: 893, 687
+ xy: 1011, 164
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-cyclone-small
rotate: false
- xy: 1141, 674
+ xy: 2009, 855
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-cyclone-tiny
rotate: false
- xy: 1137, 422
+ xy: 1015, 392
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-cyclone-xlarge
rotate: false
- xy: 1, 28
- size: 48, 48
- orig: 48, 48
- offset: 0, 0
- index: -1
-block-dagger-factory-large
- rotate: false
- xy: 393, 224
- size: 40, 40
- orig: 40, 40
- offset: 0, 0
- index: -1
-block-dagger-factory-medium
- rotate: false
- xy: 995, 755
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-dagger-factory-small
- rotate: false
- xy: 1167, 674
- size: 24, 24
- orig: 24, 24
- offset: 0, 0
- index: -1
-block-dagger-factory-tiny
- rotate: false
- xy: 1361, 542
- size: 16, 16
- orig: 16, 16
- offset: 0, 0
- index: -1
-block-dagger-factory-xlarge
- rotate: false
- xy: 51, 78
+ xy: 51, 128
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-dark-metal-large
rotate: false
- xy: 393, 182
+ xy: 393, 46
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-dark-metal-medium
rotate: false
- xy: 961, 721
+ xy: 1011, 130
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-dark-metal-small
rotate: false
- xy: 1193, 674
+ xy: 963, 682
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-dark-metal-tiny
rotate: false
- xy: 1379, 560
+ xy: 1033, 418
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-dark-metal-xlarge
rotate: false
- xy: 51, 28
+ xy: 1, 28
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-dark-panel-1-large
rotate: false
- xy: 393, 140
+ xy: 393, 4
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-dark-panel-1-medium
rotate: false
- xy: 927, 687
+ xy: 1011, 96
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-dark-panel-1-small
rotate: false
- xy: 1219, 674
+ xy: 989, 682
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-dark-panel-1-tiny
rotate: false
- xy: 1397, 578
+ xy: 1167, 534
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-dark-panel-1-xlarge
rotate: false
- xy: 857, 975
+ xy: 51, 78
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-dark-panel-2-large
rotate: false
- xy: 393, 98
+ xy: 443, 424
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-dark-panel-2-medium
rotate: false
- xy: 995, 721
+ xy: 1011, 62
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-dark-panel-2-small
rotate: false
- xy: 1245, 674
+ xy: 1015, 682
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-dark-panel-2-tiny
rotate: false
- xy: 1155, 422
+ xy: 1033, 400
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-dark-panel-2-xlarge
rotate: false
- xy: 907, 975
+ xy: 51, 28
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-dark-panel-3-large
rotate: false
- xy: 393, 56
+ xy: 443, 382
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-dark-panel-3-medium
rotate: false
- xy: 961, 687
+ xy: 1011, 28
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-dark-panel-3-small
rotate: false
- xy: 1271, 674
+ xy: 1609, 711
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-dark-panel-3-tiny
rotate: false
- xy: 1379, 542
+ xy: 1185, 534
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-dark-panel-3-xlarge
rotate: false
- xy: 957, 975
+ xy: 857, 975
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-dark-panel-4-large
rotate: false
- xy: 393, 14
+ xy: 443, 340
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-dark-panel-4-medium
rotate: false
- xy: 995, 687
+ xy: 859, 912
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-dark-panel-4-small
rotate: false
- xy: 1297, 674
+ xy: 1041, 682
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-dark-panel-4-tiny
rotate: false
- xy: 1397, 560
+ xy: 1203, 534
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-dark-panel-4-xlarge
rotate: false
- xy: 1007, 975
+ xy: 907, 975
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-dark-panel-5-large
rotate: false
- xy: 443, 274
+ xy: 435, 298
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-dark-panel-5-medium
rotate: false
- xy: 1029, 857
+ xy: 845, 878
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-dark-panel-5-small
rotate: false
- xy: 1323, 674
+ xy: 1635, 711
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-dark-panel-5-tiny
rotate: false
- xy: 1415, 578
+ xy: 1221, 534
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-dark-panel-5-xlarge
rotate: false
- xy: 1057, 975
+ xy: 957, 975
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-dark-panel-6-large
rotate: false
- xy: 435, 232
+ xy: 435, 256
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-dark-panel-6-medium
rotate: false
- xy: 1029, 823
+ xy: 893, 912
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-dark-panel-6-small
rotate: false
- xy: 1349, 674
+ xy: 1067, 682
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-dark-panel-6-tiny
rotate: false
- xy: 1173, 422
+ xy: 1239, 534
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-dark-panel-6-xlarge
rotate: false
- xy: 1107, 975
+ xy: 1007, 975
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-darksand-large
rotate: false
- xy: 435, 190
+ xy: 435, 214
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-darksand-medium
rotate: false
- xy: 1029, 789
+ xy: 879, 878
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-darksand-small
rotate: false
- xy: 1375, 674
+ xy: 1093, 682
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-darksand-tainted-water-large
rotate: false
- xy: 435, 148
+ xy: 435, 172
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-darksand-tainted-water-medium
rotate: false
- xy: 1029, 755
+ xy: 859, 844
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-darksand-tainted-water-small
rotate: false
- xy: 1401, 674
+ xy: 1119, 682
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-darksand-tainted-water-tiny
rotate: false
- xy: 1397, 542
+ xy: 1257, 534
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-darksand-tainted-water-xlarge
rotate: false
- xy: 1157, 975
+ xy: 1057, 975
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-darksand-tiny
rotate: false
- xy: 1415, 560
+ xy: 1275, 534
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-darksand-water-large
rotate: false
- xy: 435, 106
+ xy: 435, 130
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-darksand-water-medium
rotate: false
- xy: 1029, 721
+ xy: 927, 912
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-darksand-water-small
rotate: false
- xy: 1427, 674
+ xy: 1145, 682
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-darksand-water-tiny
rotate: false
- xy: 1433, 578
+ xy: 1293, 534
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-darksand-water-xlarge
rotate: false
- xy: 1207, 975
+ xy: 1107, 975
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-darksand-xlarge
rotate: false
- xy: 1257, 975
- size: 48, 48
- orig: 48, 48
- offset: 0, 0
- index: -1
-block-dart-mech-pad-large
- rotate: false
- xy: 435, 64
- size: 40, 40
- orig: 40, 40
- offset: 0, 0
- index: -1
-block-dart-mech-pad-medium
- rotate: false
- xy: 1029, 687
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-dart-mech-pad-small
- rotate: false
- xy: 1453, 674
- size: 24, 24
- orig: 24, 24
- offset: 0, 0
- index: -1
-block-dart-mech-pad-tiny
- rotate: false
- xy: 1191, 422
- size: 16, 16
- orig: 16, 16
- offset: 0, 0
- index: -1
-block-dart-mech-pad-xlarge
- rotate: false
- xy: 1307, 975
+ xy: 1157, 975
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-deepwater-large
rotate: false
- xy: 435, 22
+ xy: 435, 88
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-deepwater-medium
rotate: false
- xy: 881, 653
+ xy: 913, 878
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-deepwater-small
rotate: false
- xy: 1479, 674
+ xy: 1171, 682
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-deepwater-tiny
rotate: false
- xy: 1415, 542
+ xy: 1311, 534
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-deepwater-xlarge
rotate: false
- xy: 1357, 975
- size: 48, 48
- orig: 48, 48
- offset: 0, 0
- index: -1
-block-delta-mech-pad-large
- rotate: false
- xy: 493, 324
- size: 40, 40
- orig: 40, 40
- offset: 0, 0
- index: -1
-block-delta-mech-pad-medium
- rotate: false
- xy: 881, 619
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-delta-mech-pad-small
- rotate: false
- xy: 1505, 674
- size: 24, 24
- orig: 24, 24
- offset: 0, 0
- index: -1
-block-delta-mech-pad-tiny
- rotate: false
- xy: 1433, 560
- size: 16, 16
- orig: 16, 16
- offset: 0, 0
- index: -1
-block-delta-mech-pad-xlarge
- rotate: false
- xy: 1407, 975
+ xy: 1207, 975
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-differential-generator-large
rotate: false
- xy: 485, 282
+ xy: 435, 46
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-differential-generator-medium
rotate: false
- xy: 915, 653
+ xy: 859, 810
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-differential-generator-small
rotate: false
- xy: 1531, 674
+ xy: 1197, 682
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-differential-generator-tiny
rotate: false
- xy: 1451, 578
+ xy: 1329, 534
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-differential-generator-xlarge
rotate: false
- xy: 1457, 975
+ xy: 1257, 975
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-diode-large
rotate: false
- xy: 543, 348
+ xy: 435, 4
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-diode-medium
rotate: false
- xy: 881, 585
+ xy: 893, 844
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-diode-small
rotate: false
- xy: 1557, 674
+ xy: 1223, 682
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-diode-tiny
rotate: false
- xy: 1433, 542
+ xy: 1347, 534
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-diode-xlarge
rotate: false
- xy: 1507, 975
+ xy: 1307, 975
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-distributor-large
rotate: false
- xy: 585, 348
+ xy: 493, 474
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-distributor-medium
rotate: false
- xy: 949, 653
+ xy: 961, 912
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-distributor-small
rotate: false
- xy: 1583, 674
+ xy: 1249, 682
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-distributor-tiny
rotate: false
- xy: 1451, 560
+ xy: 1365, 534
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-distributor-xlarge
rotate: false
- xy: 1557, 975
+ xy: 1357, 975
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-door-large
rotate: false
- xy: 535, 306
+ xy: 485, 432
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-door-large-large
rotate: false
- xy: 577, 306
+ xy: 485, 390
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-door-large-medium
rotate: false
- xy: 915, 619
+ xy: 947, 878
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-door-large-small
rotate: false
- xy: 1609, 674
+ xy: 1275, 682
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-door-large-tiny
rotate: false
- xy: 1469, 578
+ xy: 1383, 534
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-door-large-xlarge
rotate: false
- xy: 1607, 975
+ xy: 1407, 975
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-door-medium
rotate: false
- xy: 983, 653
+ xy: 859, 776
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-door-small
rotate: false
- xy: 1635, 674
+ xy: 1301, 682
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-door-tiny
rotate: false
- xy: 1451, 542
+ xy: 1401, 534
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-door-xlarge
rotate: false
- xy: 1657, 975
- size: 48, 48
- orig: 48, 48
- offset: 0, 0
- index: -1
-block-draug-factory-large
- rotate: false
- xy: 527, 264
- size: 40, 40
- orig: 40, 40
- offset: 0, 0
- index: -1
-block-draug-factory-medium
- rotate: false
- xy: 949, 619
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-draug-factory-small
- rotate: false
- xy: 1661, 674
- size: 24, 24
- orig: 24, 24
- offset: 0, 0
- index: -1
-block-draug-factory-tiny
- rotate: false
- xy: 1469, 560
- size: 16, 16
- orig: 16, 16
- offset: 0, 0
- index: -1
-block-draug-factory-xlarge
- rotate: false
- xy: 1707, 975
+ xy: 1457, 975
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-dunerocks-large
rotate: false
- xy: 569, 264
+ xy: 485, 348
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-dunerocks-medium
rotate: false
- xy: 915, 585
+ xy: 893, 810
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-dunerocks-small
rotate: false
- xy: 1687, 674
+ xy: 1327, 682
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-dunerocks-tiny
rotate: false
- xy: 1487, 578
+ xy: 1419, 534
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-dunerocks-xlarge
rotate: false
- xy: 1757, 975
+ xy: 1507, 975
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-duo-large
rotate: false
- xy: 485, 240
+ xy: 543, 524
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-duo-medium
rotate: false
- xy: 1017, 653
+ xy: 927, 844
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-duo-small
rotate: false
- xy: 1713, 674
+ xy: 1353, 682
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-duo-tiny
rotate: false
- xy: 1469, 542
+ xy: 1437, 534
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-duo-xlarge
rotate: false
- xy: 1807, 975
+ xy: 1557, 975
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-force-projector-large
rotate: false
- xy: 477, 198
+ xy: 535, 482
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-force-projector-medium
rotate: false
- xy: 983, 619
+ xy: 995, 912
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-force-projector-small
rotate: false
- xy: 1739, 674
+ xy: 1379, 682
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-force-projector-tiny
rotate: false
- xy: 1487, 560
+ xy: 1455, 534
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-force-projector-xlarge
rotate: false
- xy: 1857, 975
- size: 48, 48
- orig: 48, 48
- offset: 0, 0
- index: -1
-block-fortress-factory-large
- rotate: false
- xy: 477, 156
- size: 40, 40
- orig: 40, 40
- offset: 0, 0
- index: -1
-block-fortress-factory-medium
- rotate: false
- xy: 949, 585
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-fortress-factory-small
- rotate: false
- xy: 1765, 674
- size: 24, 24
- orig: 24, 24
- offset: 0, 0
- index: -1
-block-fortress-factory-tiny
- rotate: false
- xy: 1505, 578
- size: 16, 16
- orig: 16, 16
- offset: 0, 0
- index: -1
-block-fortress-factory-xlarge
- rotate: false
- xy: 1907, 975
+ xy: 1607, 975
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-fuse-large
rotate: false
- xy: 477, 114
+ xy: 585, 532
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-fuse-medium
rotate: false
- xy: 1017, 619
+ xy: 981, 878
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-fuse-small
rotate: false
- xy: 1791, 674
+ xy: 1405, 682
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-fuse-tiny
rotate: false
- xy: 1487, 542
+ xy: 1473, 534
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-fuse-xlarge
rotate: false
- xy: 1957, 975
- size: 48, 48
- orig: 48, 48
- offset: 0, 0
- index: -1
-block-ghoul-factory-large
- rotate: false
- xy: 477, 72
- size: 40, 40
- orig: 40, 40
- offset: 0, 0
- index: -1
-block-ghoul-factory-medium
- rotate: false
- xy: 983, 585
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-ghoul-factory-small
- rotate: false
- xy: 1817, 674
- size: 24, 24
- orig: 24, 24
- offset: 0, 0
- index: -1
-block-ghoul-factory-tiny
- rotate: false
- xy: 1505, 560
- size: 16, 16
- orig: 16, 16
- offset: 0, 0
- index: -1
-block-ghoul-factory-xlarge
- rotate: false
- xy: 345, 866
- size: 48, 48
- orig: 48, 48
- offset: 0, 0
- index: -1
-block-glaive-ship-pad-large
- rotate: false
- xy: 477, 30
- size: 40, 40
- orig: 40, 40
- offset: 0, 0
- index: -1
-block-glaive-ship-pad-medium
- rotate: false
- xy: 1017, 585
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-glaive-ship-pad-small
- rotate: false
- xy: 1843, 674
- size: 24, 24
- orig: 24, 24
- offset: 0, 0
- index: -1
-block-glaive-ship-pad-tiny
- rotate: false
- xy: 1523, 578
- size: 16, 16
- orig: 16, 16
- offset: 0, 0
- index: -1
-block-glaive-ship-pad-xlarge
- rotate: false
- xy: 395, 866
+ xy: 1657, 975
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-graphite-press-large
rotate: false
- xy: 527, 222
+ xy: 627, 532
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-graphite-press-medium
rotate: false
- xy: 895, 551
+ xy: 859, 742
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-graphite-press-small
rotate: false
- xy: 1869, 674
+ xy: 1431, 682
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-graphite-press-tiny
rotate: false
- xy: 1505, 542
+ xy: 1491, 534
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-graphite-press-xlarge
rotate: false
- xy: 445, 866
+ xy: 1707, 975
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-grass-large
rotate: false
- xy: 569, 222
+ xy: 669, 532
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-grass-medium
rotate: false
- xy: 929, 551
+ xy: 893, 776
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-grass-small
rotate: false
- xy: 1895, 674
+ xy: 1457, 682
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-grass-tiny
rotate: false
- xy: 1523, 560
+ xy: 935, 8
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-grass-xlarge
rotate: false
- xy: 495, 866
+ xy: 1757, 975
+ size: 48, 48
+ orig: 48, 48
+ offset: 0, 0
+ index: -1
+block-ground-factory-large
+ rotate: false
+ xy: 711, 532
+ size: 40, 40
+ orig: 40, 40
+ offset: 0, 0
+ index: -1
+block-ground-factory-medium
+ rotate: false
+ xy: 927, 810
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-ground-factory-small
+ rotate: false
+ xy: 881, 656
+ size: 24, 24
+ orig: 24, 24
+ offset: 0, 0
+ index: -1
+block-ground-factory-tiny
+ rotate: false
+ xy: 953, 8
+ size: 16, 16
+ orig: 16, 16
+ offset: 0, 0
+ index: -1
+block-ground-factory-xlarge
+ rotate: false
+ xy: 1807, 975
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-hail-large
rotate: false
- xy: 519, 180
+ xy: 477, 298
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-hail-medium
rotate: false
- xy: 963, 551
+ xy: 961, 844
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-hail-small
rotate: false
- xy: 1051, 648
+ xy: 881, 630
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-hail-tiny
rotate: false
- xy: 1541, 578
+ xy: 1015, 374
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-hail-xlarge
rotate: false
- xy: 545, 866
+ xy: 1857, 975
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-holostone-large
rotate: false
- xy: 519, 138
+ xy: 477, 256
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-holostone-medium
rotate: false
- xy: 997, 551
+ xy: 1029, 912
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-holostone-small
rotate: false
- xy: 1051, 622
+ xy: 907, 656
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-holostone-tiny
rotate: false
- xy: 1523, 542
+ xy: 1033, 382
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-holostone-xlarge
rotate: false
- xy: 595, 866
+ xy: 1907, 975
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-hotrock-large
rotate: false
- xy: 561, 180
+ xy: 477, 214
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-hotrock-medium
rotate: false
- xy: 1063, 870
+ xy: 1015, 878
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-hotrock-small
rotate: false
- xy: 1077, 648
+ xy: 881, 604
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-hotrock-tiny
rotate: false
- xy: 1541, 560
+ xy: 1015, 356
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-hotrock-xlarge
rotate: false
- xy: 645, 866
+ xy: 1957, 975
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-ice-large
rotate: false
- xy: 519, 96
+ xy: 477, 172
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-ice-medium
rotate: false
- xy: 1063, 836
+ xy: 859, 708
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-ice-small
rotate: false
- xy: 1051, 596
+ xy: 881, 578
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-ice-snow-large
rotate: false
- xy: 561, 138
+ xy: 477, 130
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-ice-snow-medium
rotate: false
- xy: 1097, 870
+ xy: 893, 742
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-ice-snow-small
rotate: false
- xy: 1077, 622
+ xy: 933, 656
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-ice-snow-tiny
rotate: false
- xy: 1559, 578
+ xy: 1033, 364
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-ice-snow-xlarge
rotate: false
- xy: 695, 866
+ xy: 345, 866
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-ice-tiny
rotate: false
- xy: 1541, 542
+ xy: 1015, 338
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-ice-xlarge
rotate: false
- xy: 101, 478
+ xy: 395, 866
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-icerocks-large
rotate: false
- xy: 519, 54
+ xy: 477, 88
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-icerocks-medium
rotate: false
- xy: 1063, 802
+ xy: 927, 776
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-icerocks-small
rotate: false
- xy: 1103, 648
+ xy: 907, 630
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-icerocks-tiny
rotate: false
- xy: 1559, 560
+ xy: 1033, 346
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-icerocks-xlarge
rotate: false
- xy: 101, 428
+ xy: 445, 866
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-ignarock-large
rotate: false
- xy: 561, 96
+ xy: 477, 46
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-ignarock-medium
rotate: false
- xy: 1097, 836
+ xy: 961, 810
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-ignarock-small
rotate: false
- xy: 1077, 596
+ xy: 959, 656
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-ignarock-tiny
rotate: false
- xy: 1577, 578
+ xy: 1015, 320
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-ignarock-xlarge
rotate: false
- xy: 101, 378
+ xy: 495, 866
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-illuminator-large
rotate: false
- xy: 561, 54
+ xy: 477, 4
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-illuminator-medium
rotate: false
- xy: 1131, 870
+ xy: 995, 844
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-illuminator-small
rotate: false
- xy: 1103, 622
+ xy: 933, 630
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-illuminator-tiny
rotate: false
- xy: 1559, 542
+ xy: 1033, 328
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-illuminator-xlarge
rotate: false
- xy: 101, 328
+ xy: 545, 866
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-impact-reactor-large
rotate: false
- xy: 519, 12
+ xy: 527, 432
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-impact-reactor-medium
rotate: false
- xy: 1063, 768
+ xy: 1063, 912
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-impact-reactor-small
rotate: false
- xy: 1129, 648
+ xy: 907, 604
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-impact-reactor-tiny
rotate: false
- xy: 1577, 560
+ xy: 1015, 302
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-impact-reactor-xlarge
rotate: false
- xy: 101, 278
+ xy: 595, 866
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-incinerator-large
rotate: false
- xy: 561, 12
+ xy: 527, 390
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-incinerator-medium
rotate: false
- xy: 1097, 802
+ xy: 1049, 878
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-incinerator-small
rotate: false
- xy: 1103, 596
+ xy: 907, 578
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-incinerator-tiny
rotate: false
- xy: 1595, 578
+ xy: 1033, 310
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-incinerator-xlarge
rotate: false
- xy: 101, 228
+ xy: 645, 866
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-inverted-sorter-large
rotate: false
- xy: 677, 482
+ xy: 527, 348
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-inverted-sorter-medium
rotate: false
- xy: 1131, 836
+ xy: 893, 708
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-inverted-sorter-small
rotate: false
- xy: 1129, 622
+ xy: 985, 656
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-inverted-sorter-tiny
rotate: false
- xy: 1577, 542
+ xy: 1015, 284
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-inverted-sorter-xlarge
rotate: false
- xy: 101, 178
+ xy: 695, 866
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-item-source-large
rotate: false
- xy: 677, 440
+ xy: 519, 306
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-item-source-medium
rotate: false
- xy: 1165, 870
+ xy: 927, 742
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-item-source-small
rotate: false
- xy: 1155, 648
+ xy: 959, 630
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-item-source-tiny
rotate: false
- xy: 1595, 560
+ xy: 1033, 292
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-item-source-xlarge
rotate: false
- xy: 101, 128
+ xy: 101, 478
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-item-void-large
rotate: false
- xy: 677, 398
+ xy: 519, 264
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-item-void-medium
rotate: false
- xy: 1063, 734
+ xy: 961, 776
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-item-void-small
rotate: false
- xy: 1129, 596
+ xy: 933, 604
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-item-void-tiny
rotate: false
- xy: 1613, 578
+ xy: 1015, 266
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-item-void-xlarge
rotate: false
- xy: 101, 78
- size: 48, 48
- orig: 48, 48
- offset: 0, 0
- index: -1
-block-javelin-ship-pad-large
- rotate: false
- xy: 719, 490
- size: 40, 40
- orig: 40, 40
- offset: 0, 0
- index: -1
-block-javelin-ship-pad-medium
- rotate: false
- xy: 1097, 768
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-javelin-ship-pad-small
- rotate: false
- xy: 1155, 622
- size: 24, 24
- orig: 24, 24
- offset: 0, 0
- index: -1
-block-javelin-ship-pad-tiny
- rotate: false
- xy: 1595, 542
- size: 16, 16
- orig: 16, 16
- offset: 0, 0
- index: -1
-block-javelin-ship-pad-xlarge
- rotate: false
- xy: 101, 28
+ xy: 101, 428
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-junction-large
rotate: false
- xy: 719, 448
+ xy: 519, 222
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-junction-medium
rotate: false
- xy: 1131, 802
+ xy: 995, 810
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-junction-small
rotate: false
- xy: 1181, 648
+ xy: 1011, 656
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-junction-tiny
rotate: false
- xy: 1613, 560
+ xy: 1033, 274
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-junction-xlarge
rotate: false
- xy: 231, 608
+ xy: 101, 378
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-kiln-large
rotate: false
- xy: 719, 406
+ xy: 519, 180
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-kiln-medium
rotate: false
- xy: 1165, 836
+ xy: 1029, 844
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-kiln-small
rotate: false
- xy: 1155, 596
+ xy: 985, 630
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-kiln-tiny
rotate: false
- xy: 1631, 578
+ xy: 1015, 248
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-kiln-xlarge
rotate: false
- xy: 231, 558
+ xy: 101, 328
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-lancer-large
rotate: false
- xy: 635, 356
+ xy: 519, 138
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-lancer-medium
rotate: false
- xy: 1199, 870
+ xy: 1097, 912
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-lancer-small
rotate: false
- xy: 1181, 622
+ xy: 959, 604
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-lancer-tiny
rotate: false
- xy: 1613, 542
+ xy: 1033, 256
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-lancer-xlarge
rotate: false
- xy: 745, 866
+ xy: 101, 278
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-laser-drill-large
rotate: false
- xy: 677, 356
+ xy: 519, 96
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-laser-drill-medium
rotate: false
- xy: 1063, 700
+ xy: 1083, 878
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-laser-drill-small
rotate: false
- xy: 1207, 648
+ xy: 933, 578
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-laser-drill-tiny
rotate: false
- xy: 1631, 560
+ xy: 1015, 230
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-laser-drill-xlarge
rotate: false
- xy: 151, 508
+ xy: 101, 228
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-launch-pad-large
rotate: false
- xy: 719, 364
+ xy: 519, 54
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-launch-pad-large-large
rotate: false
- xy: 769, 532
+ xy: 519, 12
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-launch-pad-large-medium
rotate: false
- xy: 1097, 734
+ xy: 927, 708
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-launch-pad-large-small
rotate: false
- xy: 1181, 596
+ xy: 921, 552
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-launch-pad-large-tiny
rotate: false
- xy: 1649, 578
+ xy: 1033, 238
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-launch-pad-large-xlarge
rotate: false
- xy: 151, 458
+ xy: 101, 178
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-launch-pad-medium
rotate: false
- xy: 1131, 768
+ xy: 961, 742
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-launch-pad-small
rotate: false
- xy: 1207, 622
+ xy: 1037, 656
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-launch-pad-tiny
rotate: false
- xy: 1631, 542
+ xy: 1015, 212
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-launch-pad-xlarge
rotate: false
- xy: 201, 508
+ xy: 101, 128
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-liquid-junction-large
rotate: false
- xy: 761, 490
+ xy: 577, 482
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-liquid-junction-medium
rotate: false
- xy: 1165, 802
+ xy: 995, 776
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-liquid-junction-small
rotate: false
- xy: 1233, 648
+ xy: 1011, 630
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-liquid-junction-tiny
rotate: false
- xy: 1649, 560
+ xy: 1033, 220
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-liquid-junction-xlarge
rotate: false
- xy: 151, 408
+ xy: 101, 78
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-liquid-router-large
rotate: false
- xy: 761, 448
+ xy: 569, 440
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-liquid-router-medium
rotate: false
- xy: 1199, 836
+ xy: 1063, 844
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-liquid-router-small
rotate: false
- xy: 1207, 596
+ xy: 985, 604
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-liquid-router-tiny
rotate: false
- xy: 1667, 578
+ xy: 1509, 534
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-liquid-router-xlarge
rotate: false
- xy: 201, 458
+ xy: 101, 28
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-liquid-source-large
rotate: false
- xy: 761, 406
+ xy: 569, 398
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-liquid-source-medium
rotate: false
- xy: 1233, 870
+ xy: 1029, 810
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-liquid-source-small
rotate: false
- xy: 1233, 622
+ xy: 959, 578
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-liquid-source-tiny
rotate: false
- xy: 1649, 542
+ xy: 603, 2
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-liquid-source-xlarge
rotate: false
- xy: 151, 358
+ xy: 231, 608
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-liquid-tank-large
rotate: false
- xy: 761, 364
+ xy: 569, 356
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-liquid-tank-medium
rotate: false
- xy: 1097, 700
+ xy: 1131, 912
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-liquid-tank-small
rotate: false
- xy: 1259, 648
+ xy: 947, 552
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-liquid-tank-tiny
rotate: false
- xy: 1667, 560
+ xy: 621, 2
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-liquid-tank-xlarge
rotate: false
- xy: 201, 408
+ xy: 231, 558
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-liquid-void-large
rotate: false
- xy: 811, 536
+ xy: 619, 490
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-liquid-void-medium
rotate: false
- xy: 1131, 734
+ xy: 1117, 878
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-liquid-void-small
rotate: false
- xy: 1233, 596
+ xy: 1063, 656
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-liquid-void-tiny
rotate: false
- xy: 1685, 578
+ xy: 639, 2
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-liquid-void-xlarge
rotate: false
- xy: 151, 308
+ xy: 745, 866
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-magmarock-large
rotate: false
- xy: 853, 536
+ xy: 661, 490
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-magmarock-medium
rotate: false
- xy: 1165, 768
+ xy: 961, 708
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-magmarock-small
rotate: false
- xy: 1259, 622
+ xy: 1037, 630
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-magmarock-tiny
rotate: false
- xy: 1667, 542
+ xy: 657, 2
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-magmarock-xlarge
rotate: false
- xy: 201, 358
+ xy: 151, 508
+ size: 48, 48
+ orig: 48, 48
+ offset: 0, 0
+ index: -1
+block-mass-conveyor-large
+ rotate: false
+ xy: 703, 490
+ size: 40, 40
+ orig: 40, 40
+ offset: 0, 0
+ index: -1
+block-mass-conveyor-medium
+ rotate: false
+ xy: 995, 742
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-mass-conveyor-small
+ rotate: false
+ xy: 1011, 604
+ size: 24, 24
+ orig: 24, 24
+ offset: 0, 0
+ index: -1
+block-mass-conveyor-tiny
+ rotate: false
+ xy: 675, 2
+ size: 16, 16
+ orig: 16, 16
+ offset: 0, 0
+ index: -1
+block-mass-conveyor-xlarge
+ rotate: false
+ xy: 151, 458
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-mass-driver-large
rotate: false
- xy: 619, 306
+ xy: 753, 532
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-mass-driver-medium
rotate: false
- xy: 1199, 802
+ xy: 1097, 844
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-mass-driver-small
rotate: false
- xy: 1285, 648
+ xy: 985, 578
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-mass-driver-tiny
rotate: false
- xy: 1685, 560
+ xy: 693, 10
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-mass-driver-xlarge
rotate: false
- xy: 151, 258
+ xy: 201, 508
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-mechanical-drill-large
rotate: false
- xy: 611, 264
+ xy: 745, 490
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-mechanical-drill-medium
rotate: false
- xy: 1233, 836
+ xy: 1063, 810
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-mechanical-drill-small
rotate: false
- xy: 1259, 596
+ xy: 973, 552
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-mechanical-drill-tiny
rotate: false
- xy: 1703, 578
+ xy: 711, 10
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-mechanical-drill-xlarge
rotate: false
- xy: 201, 308
+ xy: 151, 408
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-mechanical-pump-large
rotate: false
- xy: 611, 222
+ xy: 795, 536
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-mechanical-pump-medium
rotate: false
- xy: 1267, 870
+ xy: 1029, 776
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-mechanical-pump-small
rotate: false
- xy: 1285, 622
+ xy: 1089, 656
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-mechanical-pump-tiny
rotate: false
- xy: 1685, 542
+ xy: 729, 10
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-mechanical-pump-xlarge
rotate: false
- xy: 151, 208
+ xy: 201, 458
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-meltdown-large
rotate: false
- xy: 603, 180
+ xy: 837, 536
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-meltdown-medium
rotate: false
- xy: 1131, 700
+ xy: 1165, 912
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-meltdown-small
rotate: false
- xy: 1311, 648
+ xy: 1063, 630
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-meltdown-tiny
rotate: false
- xy: 1703, 560
+ xy: 747, 10
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-meltdown-xlarge
rotate: false
- xy: 201, 258
+ xy: 151, 358
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-melter-large
rotate: false
- xy: 603, 138
+ xy: 561, 306
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-melter-medium
rotate: false
- xy: 1165, 734
+ xy: 1151, 878
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-melter-small
rotate: false
- xy: 1285, 596
+ xy: 1037, 604
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-melter-tiny
rotate: false
- xy: 1721, 578
+ xy: 765, 10
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-melter-xlarge
rotate: false
- xy: 151, 158
+ xy: 201, 408
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-mend-projector-large
rotate: false
- xy: 603, 96
+ xy: 561, 264
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-mend-projector-medium
rotate: false
- xy: 1199, 768
+ xy: 995, 708
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-mend-projector-small
rotate: false
- xy: 1311, 622
+ xy: 1011, 578
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-mend-projector-tiny
rotate: false
- xy: 1703, 542
+ xy: 783, 10
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-mend-projector-xlarge
rotate: false
- xy: 201, 208
+ xy: 151, 308
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-mender-large
rotate: false
- xy: 603, 54
+ xy: 561, 222
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-mender-medium
rotate: false
- xy: 1233, 802
+ xy: 1131, 844
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-mender-small
rotate: false
- xy: 1337, 648
+ xy: 999, 552
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-mender-tiny
rotate: false
- xy: 1721, 560
+ xy: 801, 10
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-mender-xlarge
rotate: false
- xy: 151, 108
+ xy: 201, 358
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-message-large
rotate: false
- xy: 603, 12
+ xy: 561, 180
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-message-medium
rotate: false
- xy: 1267, 836
+ xy: 1097, 810
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-message-small
rotate: false
- xy: 1311, 596
+ xy: 1115, 656
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-message-tiny
rotate: false
- xy: 1739, 578
+ xy: 819, 10
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-message-xlarge
rotate: false
- xy: 201, 158
+ xy: 151, 258
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-metal-floor-2-large
rotate: false
- xy: 661, 314
+ xy: 561, 138
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-metal-floor-2-medium
rotate: false
- xy: 1301, 870
+ xy: 1063, 776
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-metal-floor-2-small
rotate: false
- xy: 1337, 622
+ xy: 1089, 630
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-metal-floor-2-tiny
rotate: false
- xy: 1721, 542
+ xy: 837, 10
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-metal-floor-2-xlarge
rotate: false
- xy: 151, 58
+ xy: 201, 308
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-metal-floor-3-large
rotate: false
- xy: 703, 314
+ xy: 561, 96
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-metal-floor-3-medium
rotate: false
- xy: 1165, 700
+ xy: 1029, 742
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-metal-floor-3-small
rotate: false
- xy: 1363, 648
+ xy: 1063, 604
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-metal-floor-3-tiny
rotate: false
- xy: 1739, 560
+ xy: 855, 10
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-metal-floor-3-xlarge
rotate: false
- xy: 201, 108
+ xy: 151, 208
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-metal-floor-5-large
rotate: false
- xy: 745, 322
+ xy: 561, 54
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-metal-floor-5-medium
rotate: false
- xy: 1199, 734
+ xy: 1199, 912
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-metal-floor-5-small
rotate: false
- xy: 1337, 596
+ xy: 1037, 578
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-metal-floor-5-tiny
rotate: false
- xy: 1757, 578
+ xy: 873, 10
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-metal-floor-5-xlarge
rotate: false
- xy: 201, 58
+ xy: 201, 258
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-metal-floor-damaged-large
rotate: false
- xy: 787, 322
+ xy: 561, 12
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-metal-floor-damaged-medium
rotate: false
- xy: 1233, 768
+ xy: 1185, 878
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-metal-floor-damaged-small
rotate: false
- xy: 1363, 622
+ xy: 1025, 552
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-metal-floor-damaged-tiny
rotate: false
- xy: 1739, 542
+ xy: 1701, 753
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-metal-floor-damaged-xlarge
rotate: false
- xy: 251, 508
+ xy: 151, 158
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-metal-floor-large
rotate: false
- xy: 653, 264
+ xy: 611, 440
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-metal-floor-medium
rotate: false
- xy: 1267, 802
+ xy: 1165, 844
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-metal-floor-small
rotate: false
- xy: 1389, 648
+ xy: 1141, 656
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-metal-floor-tiny
rotate: false
- xy: 1757, 560
+ xy: 1735, 787
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-metal-floor-xlarge
rotate: false
- xy: 251, 458
+ xy: 201, 208
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-moss-large
rotate: false
- xy: 653, 222
+ xy: 611, 398
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-moss-medium
rotate: false
- xy: 1301, 836
+ xy: 1131, 810
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-moss-small
rotate: false
- xy: 1363, 596
+ xy: 1115, 630
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-moss-tiny
rotate: false
- xy: 1775, 578
+ xy: 1769, 821
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-moss-xlarge
rotate: false
- xy: 251, 408
+ xy: 151, 108
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-multi-press-large
rotate: false
- xy: 645, 180
+ xy: 611, 356
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-multi-press-medium
rotate: false
- xy: 1335, 870
+ xy: 1097, 776
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-multi-press-small
rotate: false
- xy: 1389, 622
+ xy: 1089, 604
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-multi-press-tiny
rotate: false
- xy: 1757, 542
+ xy: 1787, 823
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-multi-press-xlarge
rotate: false
- xy: 251, 358
+ xy: 201, 158
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-oil-extractor-large
rotate: false
- xy: 645, 138
+ xy: 603, 314
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-oil-extractor-medium
rotate: false
- xy: 1199, 700
+ xy: 1063, 742
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-oil-extractor-small
rotate: false
- xy: 1415, 648
+ xy: 1063, 578
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-oil-extractor-tiny
rotate: false
- xy: 1775, 560
+ xy: 1805, 823
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-oil-extractor-xlarge
rotate: false
- xy: 251, 308
- size: 48, 48
- orig: 48, 48
- offset: 0, 0
- index: -1
-block-omega-mech-pad-large
- rotate: false
- xy: 645, 96
- size: 40, 40
- orig: 40, 40
- offset: 0, 0
- index: -1
-block-omega-mech-pad-medium
- rotate: false
- xy: 1233, 734
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-omega-mech-pad-small
- rotate: false
- xy: 1389, 596
- size: 24, 24
- orig: 24, 24
- offset: 0, 0
- index: -1
-block-omega-mech-pad-tiny
- rotate: false
- xy: 1793, 578
- size: 16, 16
- orig: 16, 16
- offset: 0, 0
- index: -1
-block-omega-mech-pad-xlarge
- rotate: false
- xy: 251, 258
+ xy: 151, 58
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-ore-coal-large
rotate: false
- xy: 645, 54
+ xy: 603, 272
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-ore-coal-medium
rotate: false
- xy: 1267, 768
+ xy: 1029, 708
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-ore-coal-small
rotate: false
- xy: 1415, 622
+ xy: 1051, 552
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-ore-coal-tiny
rotate: false
- xy: 1775, 542
+ xy: 1823, 823
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-ore-coal-xlarge
rotate: false
- xy: 251, 208
+ xy: 201, 108
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-ore-copper-large
rotate: false
- xy: 645, 12
+ xy: 603, 230
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-ore-copper-medium
rotate: false
- xy: 1301, 802
+ xy: 1233, 912
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-ore-copper-small
rotate: false
- xy: 1441, 648
+ xy: 1167, 656
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-ore-copper-tiny
rotate: false
- xy: 1793, 560
+ xy: 1841, 823
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-ore-copper-xlarge
rotate: false
- xy: 251, 158
+ xy: 201, 58
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-ore-lead-large
rotate: false
- xy: 695, 272
+ xy: 603, 188
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-ore-lead-medium
rotate: false
- xy: 1335, 836
+ xy: 1219, 878
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-ore-lead-small
rotate: false
- xy: 1415, 596
+ xy: 1141, 630
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-ore-lead-tiny
rotate: false
- xy: 1811, 578
+ xy: 1859, 823
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-ore-lead-xlarge
rotate: false
- xy: 251, 108
+ xy: 251, 508
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-ore-scrap-large
rotate: false
- xy: 695, 230
+ xy: 603, 146
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-ore-scrap-medium
rotate: false
- xy: 1369, 870
+ xy: 1199, 844
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-ore-scrap-small
rotate: false
- xy: 1441, 622
+ xy: 1115, 604
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-ore-scrap-tiny
rotate: false
- xy: 1793, 542
+ xy: 1907, 833
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-ore-scrap-xlarge
rotate: false
- xy: 251, 58
+ xy: 251, 458
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-ore-thorium-large
rotate: false
- xy: 745, 280
+ xy: 603, 104
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-ore-thorium-medium
rotate: false
- xy: 1233, 700
+ xy: 1165, 810
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-ore-thorium-small
rotate: false
- xy: 1467, 648
+ xy: 1089, 578
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-ore-thorium-tiny
rotate: false
- xy: 1811, 560
+ xy: 1059, 516
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-ore-thorium-xlarge
rotate: false
- xy: 151, 8
+ xy: 251, 408
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-ore-titanium-large
rotate: false
- xy: 787, 280
+ xy: 603, 62
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-ore-titanium-medium
rotate: false
- xy: 1267, 734
+ xy: 1131, 776
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-ore-titanium-small
rotate: false
- xy: 1441, 596
+ xy: 1077, 552
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-ore-titanium-tiny
rotate: false
- xy: 1829, 578
+ xy: 1077, 516
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-ore-titanium-xlarge
rotate: false
- xy: 201, 8
+ xy: 251, 358
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-overdrive-projector-large
rotate: false
- xy: 737, 238
+ xy: 603, 20
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-overdrive-projector-medium
rotate: false
- xy: 1301, 768
+ xy: 1097, 742
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-overdrive-projector-small
rotate: false
- xy: 1467, 622
+ xy: 1193, 656
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-overdrive-projector-tiny
rotate: false
- xy: 1811, 542
+ xy: 1095, 516
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-overdrive-projector-xlarge
rotate: false
- xy: 251, 8
+ xy: 251, 308
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-overflow-gate-large
rotate: false
- xy: 779, 238
+ xy: 653, 448
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-overflow-gate-medium
rotate: false
- xy: 1335, 802
+ xy: 1063, 708
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-overflow-gate-small
rotate: false
- xy: 1493, 648
+ xy: 1167, 630
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-overflow-gate-tiny
rotate: false
- xy: 1829, 560
+ xy: 1113, 516
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-overflow-gate-xlarge
rotate: false
- xy: 281, 619
+ xy: 251, 258
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-pebbles-large
rotate: false
- xy: 803, 490
+ xy: 653, 406
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-pebbles-medium
rotate: false
- xy: 1369, 836
+ xy: 1267, 912
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-pebbles-small
rotate: false
- xy: 1467, 596
+ xy: 1141, 604
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-pebbles-tiny
rotate: false
- xy: 1847, 578
+ xy: 1131, 516
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-pebbles-xlarge
rotate: false
- xy: 281, 569
- size: 48, 48
- orig: 48, 48
- offset: 0, 0
- index: -1
-block-phantom-factory-large
- rotate: false
- xy: 803, 448
- size: 40, 40
- orig: 40, 40
- offset: 0, 0
- index: -1
-block-phantom-factory-medium
- rotate: false
- xy: 1403, 870
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-phantom-factory-small
- rotate: false
- xy: 1493, 622
- size: 24, 24
- orig: 24, 24
- offset: 0, 0
- index: -1
-block-phantom-factory-tiny
- rotate: false
- xy: 1829, 542
- size: 16, 16
- orig: 16, 16
- offset: 0, 0
- index: -1
-block-phantom-factory-xlarge
- rotate: false
- xy: 301, 519
+ xy: 251, 208
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-phase-conduit-large
rotate: false
- xy: 803, 406
+ xy: 695, 448
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-phase-conduit-medium
rotate: false
- xy: 1267, 700
+ xy: 1253, 878
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-phase-conduit-small
rotate: false
- xy: 1519, 648
+ xy: 1115, 578
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-phase-conduit-tiny
rotate: false
- xy: 1847, 560
+ xy: 1149, 516
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-phase-conduit-xlarge
rotate: false
- xy: 301, 469
+ xy: 251, 158
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-phase-conveyor-large
rotate: false
- xy: 803, 364
+ xy: 653, 364
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-phase-conveyor-medium
rotate: false
- xy: 1301, 734
+ xy: 1233, 844
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-phase-conveyor-small
rotate: false
- xy: 1493, 596
+ xy: 1103, 552
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-phase-conveyor-tiny
rotate: false
- xy: 1865, 578
+ xy: 1167, 516
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-phase-conveyor-xlarge
rotate: false
- xy: 301, 419
+ xy: 251, 108
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-phase-wall-large
rotate: false
- xy: 845, 494
+ xy: 695, 406
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-phase-wall-large-large
rotate: false
- xy: 845, 452
+ xy: 737, 448
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-phase-wall-large-medium
rotate: false
- xy: 1335, 768
+ xy: 1199, 810
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-phase-wall-large-small
rotate: false
- xy: 1519, 622
+ xy: 1219, 656
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-phase-wall-large-tiny
rotate: false
- xy: 1847, 542
+ xy: 1185, 516
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-phase-wall-large-xlarge
rotate: false
- xy: 301, 369
+ xy: 251, 58
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-phase-wall-medium
rotate: false
- xy: 1369, 802
+ xy: 1165, 776
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-phase-wall-small
rotate: false
- xy: 1545, 648
+ xy: 1193, 630
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-phase-wall-tiny
rotate: false
- xy: 1865, 560
+ xy: 1203, 516
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-phase-wall-xlarge
rotate: false
- xy: 301, 319
+ xy: 151, 8
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-phase-weaver-large
rotate: false
- xy: 845, 410
+ xy: 695, 364
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-phase-weaver-medium
rotate: false
- xy: 1403, 836
+ xy: 1131, 742
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-phase-weaver-small
rotate: false
- xy: 1519, 596
+ xy: 1167, 604
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-phase-weaver-tiny
rotate: false
- xy: 1883, 578
+ xy: 1221, 516
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-phase-weaver-xlarge
rotate: false
- xy: 301, 269
+ xy: 201, 8
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-pine-large
rotate: false
- xy: 845, 368
+ xy: 737, 406
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-pine-medium
rotate: false
- xy: 1437, 870
+ xy: 1097, 708
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-pine-small
rotate: false
- xy: 1545, 622
+ xy: 1141, 578
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-pine-tiny
rotate: false
- xy: 1865, 542
+ xy: 1239, 516
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-pine-xlarge
rotate: false
- xy: 301, 219
+ xy: 251, 8
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-plastanium-compressor-large
rotate: false
- xy: 829, 322
+ xy: 737, 364
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-plastanium-compressor-medium
rotate: false
- xy: 1301, 700
+ xy: 1301, 912
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-plastanium-compressor-small
rotate: false
- xy: 1571, 648
+ xy: 1129, 552
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-plastanium-compressor-tiny
rotate: false
- xy: 1883, 560
+ xy: 1257, 516
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-plastanium-compressor-xlarge
rotate: false
- xy: 301, 169
+ xy: 281, 619
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-plastanium-conveyor-large
rotate: false
- xy: 829, 280
+ xy: 787, 490
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-plastanium-conveyor-medium
rotate: false
- xy: 1335, 734
+ xy: 1287, 878
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-plastanium-conveyor-small
rotate: false
- xy: 1545, 596
+ xy: 1245, 656
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-plastanium-conveyor-tiny
rotate: false
- xy: 1883, 542
+ xy: 1275, 516
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-plastanium-conveyor-xlarge
rotate: false
- xy: 301, 119
+ xy: 281, 569
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-plastanium-wall-large
rotate: false
- xy: 821, 238
+ xy: 779, 448
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-plastanium-wall-large-large
rotate: false
- xy: 871, 326
+ xy: 779, 406
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-plastanium-wall-large-medium
rotate: false
- xy: 1369, 768
+ xy: 1267, 844
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-plastanium-wall-large-small
rotate: false
- xy: 1571, 622
+ xy: 1219, 630
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-plastanium-wall-large-tiny
rotate: false
- xy: 1299, 497
+ xy: 1293, 516
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-plastanium-wall-large-xlarge
rotate: false
- xy: 301, 69
+ xy: 301, 519
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-plastanium-wall-medium
rotate: false
- xy: 1403, 802
+ xy: 1233, 810
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-plastanium-wall-small
rotate: false
- xy: 1597, 648
+ xy: 1193, 604
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-plastanium-wall-tiny
rotate: false
- xy: 1015, 331
+ xy: 1311, 516
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-plastanium-wall-xlarge
rotate: false
- xy: 301, 19
+ xy: 301, 469
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-plated-conduit-large
rotate: false
- xy: 871, 284
+ xy: 779, 364
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-plated-conduit-medium
rotate: false
- xy: 1437, 836
+ xy: 1199, 776
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-plated-conduit-small
rotate: false
- xy: 1571, 596
+ xy: 1167, 578
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-plated-conduit-tiny
rotate: false
- xy: 1033, 331
+ xy: 1329, 516
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-plated-conduit-xlarge
rotate: false
- xy: 795, 878
+ xy: 301, 419
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-pneumatic-drill-large
rotate: false
- xy: 687, 180
+ xy: 829, 494
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-pneumatic-drill-medium
rotate: false
- xy: 1471, 870
+ xy: 1165, 742
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-pneumatic-drill-small
rotate: false
- xy: 1597, 622
+ xy: 1155, 552
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-pneumatic-drill-tiny
rotate: false
- xy: 1051, 331
+ xy: 1347, 516
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-pneumatic-drill-xlarge
rotate: false
- xy: 309, 816
+ xy: 301, 369
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-power-node-large
rotate: false
- xy: 687, 138
+ xy: 645, 314
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-power-node-large-large
rotate: false
- xy: 687, 96
+ xy: 645, 272
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-power-node-large-medium
rotate: false
- xy: 1335, 700
+ xy: 1131, 708
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-power-node-large-small
rotate: false
- xy: 1623, 648
+ xy: 1271, 656
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-power-node-large-tiny
rotate: false
- xy: 1010, 313
+ xy: 1365, 516
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-power-node-large-xlarge
rotate: false
- xy: 309, 766
+ xy: 301, 319
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-power-node-medium
rotate: false
- xy: 1369, 734
+ xy: 1335, 912
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-power-node-small
rotate: false
- xy: 1597, 596
+ xy: 1245, 630
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-power-node-tiny
rotate: false
- xy: 1028, 313
+ xy: 1383, 516
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-power-node-xlarge
rotate: false
- xy: 359, 816
+ xy: 301, 269
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-power-source-large
rotate: false
- xy: 687, 54
+ xy: 645, 230
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-power-source-medium
rotate: false
- xy: 1403, 768
+ xy: 1321, 878
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-power-source-small
rotate: false
- xy: 1623, 622
+ xy: 1219, 604
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-power-source-tiny
rotate: false
- xy: 1046, 313
+ xy: 1401, 516
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-power-source-xlarge
rotate: false
- xy: 309, 716
+ xy: 301, 219
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-power-void-large
rotate: false
- xy: 687, 12
+ xy: 645, 188
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-power-void-medium
rotate: false
- xy: 1437, 802
+ xy: 1301, 844
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-power-void-small
rotate: false
- xy: 1649, 648
+ xy: 1193, 578
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-power-void-tiny
rotate: false
- xy: 1921, 688
+ xy: 1419, 516
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-power-void-xlarge
rotate: false
- xy: 359, 766
+ xy: 301, 169
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-pulse-conduit-large
rotate: false
- xy: 737, 196
+ xy: 645, 146
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-pulse-conduit-medium
rotate: false
- xy: 1471, 836
+ xy: 1267, 810
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-pulse-conduit-small
rotate: false
- xy: 1623, 596
+ xy: 1181, 552
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-pulse-conduit-tiny
rotate: false
- xy: 1921, 670
+ xy: 1437, 516
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-pulse-conduit-xlarge
rotate: false
- xy: 409, 816
+ xy: 301, 119
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-pulverizer-large
rotate: false
- xy: 779, 196
+ xy: 645, 104
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-pulverizer-medium
rotate: false
- xy: 1505, 870
+ xy: 1233, 776
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-pulverizer-small
rotate: false
- xy: 1649, 622
+ xy: 1297, 656
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-pulverizer-tiny
rotate: false
- xy: 1209, 422
+ xy: 1455, 516
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-pulverizer-xlarge
rotate: false
- xy: 359, 716
+ xy: 301, 69
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-pyratite-mixer-large
rotate: false
- xy: 821, 196
+ xy: 645, 62
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-pyratite-mixer-medium
rotate: false
- xy: 1369, 700
+ xy: 1199, 742
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-pyratite-mixer-small
rotate: false
- xy: 1675, 648
+ xy: 1271, 630
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-pyratite-mixer-tiny
rotate: false
- xy: 1942, 829
+ xy: 1473, 516
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-pyratite-mixer-xlarge
rotate: false
- xy: 409, 766
+ xy: 301, 19
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-repair-point-large
rotate: false
- xy: 729, 154
+ xy: 645, 20
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-repair-point-medium
rotate: false
- xy: 1403, 734
+ xy: 1165, 708
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-repair-point-small
rotate: false
- xy: 1649, 596
+ xy: 1245, 604
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-repair-point-tiny
rotate: false
- xy: 1960, 829
+ xy: 1491, 516
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-repair-point-xlarge
rotate: false
- xy: 459, 816
- size: 48, 48
- orig: 48, 48
- offset: 0, 0
- index: -1
-block-revenant-factory-large
- rotate: false
- xy: 729, 112
- size: 40, 40
- orig: 40, 40
- offset: 0, 0
- index: -1
-block-revenant-factory-medium
- rotate: false
- xy: 1437, 768
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-revenant-factory-small
- rotate: false
- xy: 1675, 622
- size: 24, 24
- orig: 24, 24
- offset: 0, 0
- index: -1
-block-revenant-factory-tiny
- rotate: false
- xy: 1978, 829
- size: 16, 16
- orig: 16, 16
- offset: 0, 0
- index: -1
-block-revenant-factory-xlarge
- rotate: false
- xy: 409, 716
+ xy: 795, 878
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-ripple-large
rotate: false
- xy: 771, 154
+ xy: 687, 322
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-ripple-medium
rotate: false
- xy: 1471, 802
+ xy: 1369, 912
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-ripple-small
rotate: false
- xy: 1701, 648
+ xy: 1219, 578
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-ripple-tiny
rotate: false
- xy: 1939, 811
+ xy: 1509, 516
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-ripple-xlarge
rotate: false
- xy: 459, 766
+ xy: 309, 816
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-rock-large
rotate: false
- xy: 729, 70
+ xy: 687, 280
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-rock-medium
rotate: false
- xy: 1505, 836
+ xy: 1355, 878
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-rock-small
rotate: false
- xy: 1675, 596
+ xy: 1207, 552
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-rock-tiny
rotate: false
- xy: 1939, 793
+ xy: 1051, 498
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-rock-xlarge
rotate: false
- xy: 509, 816
+ xy: 309, 766
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-rocks-large
rotate: false
- xy: 771, 112
+ xy: 729, 322
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-rocks-medium
rotate: false
- xy: 1539, 870
+ xy: 1335, 844
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-rocks-small
rotate: false
- xy: 1701, 622
+ xy: 1323, 656
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-rocks-tiny
rotate: false
- xy: 1957, 811
+ xy: 1051, 480
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-rocks-xlarge
rotate: false
- xy: 459, 716
+ xy: 359, 816
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-rotary-pump-large
rotate: false
- xy: 813, 154
+ xy: 687, 238
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-rotary-pump-medium
rotate: false
- xy: 1403, 700
+ xy: 1301, 810
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-rotary-pump-small
rotate: false
- xy: 1727, 648
+ xy: 1297, 630
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-rotary-pump-tiny
rotate: false
- xy: 1939, 775
+ xy: 1069, 498
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-rotary-pump-xlarge
rotate: false
- xy: 509, 766
+ xy: 309, 716
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-router-large
rotate: false
- xy: 729, 28
+ xy: 729, 280
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-router-medium
rotate: false
- xy: 1437, 734
+ xy: 1267, 776
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-router-small
rotate: false
- xy: 1701, 596
+ xy: 1271, 604
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-router-tiny
rotate: false
- xy: 1957, 793
+ xy: 1051, 462
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-router-xlarge
rotate: false
- xy: 559, 816
+ xy: 359, 766
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-rtg-generator-large
rotate: false
- xy: 771, 70
+ xy: 771, 322
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-rtg-generator-medium
rotate: false
- xy: 1471, 768
+ xy: 1233, 742
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-rtg-generator-small
rotate: false
- xy: 1727, 622
+ xy: 1245, 578
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-rtg-generator-tiny
rotate: false
- xy: 1975, 811
+ xy: 1069, 480
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-rtg-generator-xlarge
rotate: false
- xy: 509, 716
+ xy: 409, 816
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-salt-large
rotate: false
- xy: 813, 112
+ xy: 687, 196
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-salt-medium
rotate: false
- xy: 1505, 802
+ xy: 1199, 708
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-salt-small
rotate: false
- xy: 1753, 648
+ xy: 1233, 552
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-salt-tiny
rotate: false
- xy: 1939, 757
+ xy: 1087, 498
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-salt-xlarge
rotate: false
- xy: 559, 766
+ xy: 359, 716
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-saltrocks-large
rotate: false
- xy: 771, 28
+ xy: 729, 238
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-saltrocks-medium
rotate: false
- xy: 1539, 836
+ xy: 1403, 912
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-saltrocks-small
rotate: false
- xy: 1727, 596
+ xy: 1349, 656
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-saltrocks-tiny
rotate: false
- xy: 1957, 775
+ xy: 1051, 444
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-saltrocks-xlarge
rotate: false
- xy: 609, 816
+ xy: 409, 766
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-salvo-large
rotate: false
- xy: 813, 70
+ xy: 771, 280
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-salvo-medium
rotate: false
- xy: 1573, 870
+ xy: 1389, 878
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-salvo-small
rotate: false
- xy: 1753, 622
+ xy: 1323, 630
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-salvo-tiny
rotate: false
- xy: 1975, 793
+ xy: 1069, 462
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-salvo-xlarge
rotate: false
- xy: 559, 716
+ xy: 459, 816
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-sand-boulder-large
rotate: false
- xy: 813, 28
+ xy: 687, 154
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-sand-boulder-medium
rotate: false
- xy: 1437, 700
+ xy: 1369, 844
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-sand-boulder-small
rotate: false
- xy: 1779, 648
+ xy: 1297, 604
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-sand-boulder-tiny
rotate: false
- xy: 1939, 739
+ xy: 1087, 480
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-sand-boulder-xlarge
rotate: false
- xy: 609, 766
+ xy: 409, 716
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-sand-large
rotate: false
- xy: 863, 238
+ xy: 729, 196
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-sand-medium
rotate: false
- xy: 1471, 734
+ xy: 1335, 810
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-sand-small
rotate: false
- xy: 1753, 596
+ xy: 1271, 578
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-sand-tiny
rotate: false
- xy: 1957, 757
+ xy: 1105, 498
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-sand-water-large
rotate: false
- xy: 863, 196
+ xy: 771, 238
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-sand-water-medium
rotate: false
- xy: 1505, 768
+ xy: 1301, 776
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-sand-water-small
rotate: false
- xy: 1779, 622
+ xy: 1259, 552
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-sand-water-tiny
rotate: false
- xy: 1975, 775
+ xy: 1051, 426
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-sand-water-xlarge
rotate: false
- xy: 659, 816
+ xy: 459, 766
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-sand-xlarge
rotate: false
- xy: 609, 716
+ xy: 509, 816
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-sandrocks-large
rotate: false
- xy: 855, 154
+ xy: 687, 112
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-sandrocks-medium
rotate: false
- xy: 1539, 802
+ xy: 1267, 742
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-sandrocks-small
rotate: false
- xy: 1805, 648
+ xy: 1375, 656
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-sandrocks-tiny
rotate: false
- xy: 1939, 721
+ xy: 1069, 444
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-sandrocks-xlarge
rotate: false
- xy: 659, 766
+ xy: 459, 716
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-scatter-large
rotate: false
- xy: 855, 112
+ xy: 729, 154
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-scatter-medium
rotate: false
- xy: 1573, 836
+ xy: 1233, 708
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-scatter-small
rotate: false
- xy: 1779, 596
+ xy: 1349, 630
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-scatter-tiny
rotate: false
- xy: 1957, 739
+ xy: 1087, 462
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-scatter-xlarge
rotate: false
- xy: 709, 816
+ xy: 509, 766
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-scorch-large
rotate: false
- xy: 855, 70
+ xy: 771, 196
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-scorch-medium
rotate: false
- xy: 1607, 870
+ xy: 1437, 912
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-scorch-small
rotate: false
- xy: 1805, 622
+ xy: 1323, 604
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-scorch-tiny
rotate: false
- xy: 1975, 757
+ xy: 1105, 480
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-scorch-xlarge
rotate: false
- xy: 659, 716
+ xy: 559, 816
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-scrap-wall-gigantic-large
rotate: false
- xy: 855, 28
+ xy: 687, 70
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-scrap-wall-gigantic-medium
rotate: false
- xy: 1471, 700
+ xy: 1471, 912
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-scrap-wall-gigantic-small
rotate: false
- xy: 1831, 648
+ xy: 1297, 578
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-scrap-wall-gigantic-tiny
rotate: false
- xy: 1939, 703
+ xy: 1123, 498
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-scrap-wall-gigantic-xlarge
rotate: false
- xy: 709, 766
+ xy: 509, 716
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-scrap-wall-huge-large
rotate: false
- xy: 887, 494
+ xy: 729, 112
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-scrap-wall-huge-medium
rotate: false
- xy: 1505, 734
+ xy: 1423, 878
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-scrap-wall-huge-small
rotate: false
- xy: 1805, 596
+ xy: 1285, 552
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-scrap-wall-huge-tiny
rotate: false
- xy: 1957, 721
+ xy: 1051, 408
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-scrap-wall-huge-xlarge
rotate: false
- xy: 709, 716
+ xy: 559, 766
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-scrap-wall-large
rotate: false
- xy: 887, 452
+ xy: 771, 154
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-scrap-wall-large-large
rotate: false
- xy: 887, 410
+ xy: 687, 28
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-scrap-wall-large-medium
rotate: false
- xy: 1539, 768
+ xy: 1403, 844
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-scrap-wall-large-small
rotate: false
- xy: 1831, 622
+ xy: 1401, 656
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-scrap-wall-large-tiny
rotate: false
- xy: 1975, 739
+ xy: 1069, 426
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-scrap-wall-large-xlarge
rotate: false
- xy: 759, 816
+ xy: 609, 816
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-scrap-wall-medium
rotate: false
- xy: 1573, 802
+ xy: 1369, 810
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-scrap-wall-small
rotate: false
- xy: 1857, 648
+ xy: 1375, 630
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-scrap-wall-tiny
rotate: false
- xy: 1939, 685
+ xy: 1087, 444
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-scrap-wall-xlarge
rotate: false
- xy: 759, 766
+ xy: 559, 716
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-separator-large
rotate: false
- xy: 887, 368
+ xy: 729, 70
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-separator-medium
rotate: false
- xy: 1607, 836
+ xy: 1335, 776
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-separator-small
rotate: false
- xy: 1831, 596
+ xy: 1349, 604
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-separator-tiny
rotate: false
- xy: 1957, 703
+ xy: 1105, 462
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-separator-xlarge
rotate: false
- xy: 759, 716
+ xy: 609, 766
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-shale-boulder-large
rotate: false
- xy: 913, 326
+ xy: 771, 112
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-shale-boulder-medium
rotate: false
- xy: 1641, 870
+ xy: 1301, 742
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-shale-boulder-small
rotate: false
- xy: 1857, 622
+ xy: 1323, 578
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-shale-boulder-tiny
rotate: false
- xy: 1975, 721
+ xy: 1123, 480
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-shale-boulder-xlarge
rotate: false
- xy: 809, 828
+ xy: 659, 816
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-shale-large
rotate: false
- xy: 913, 284
+ xy: 729, 28
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-shale-medium
rotate: false
- xy: 1505, 700
+ xy: 1267, 708
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-shale-small
rotate: false
- xy: 1883, 648
+ xy: 1311, 552
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-shale-tiny
rotate: false
- xy: 1957, 685
+ xy: 1141, 498
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-shale-xlarge
rotate: false
- xy: 809, 778
+ xy: 609, 716
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-shalerocks-large
rotate: false
- xy: 905, 242
+ xy: 771, 70
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-shalerocks-medium
rotate: false
- xy: 1539, 734
+ xy: 1457, 878
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-shalerocks-small
rotate: false
- xy: 1857, 596
+ xy: 1427, 656
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-shalerocks-tiny
rotate: false
- xy: 1975, 703
+ xy: 1051, 390
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-shalerocks-xlarge
rotate: false
- xy: 809, 728
+ xy: 659, 766
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-shock-mine-large
rotate: false
- xy: 905, 200
+ xy: 771, 28
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-shock-mine-medium
rotate: false
- xy: 1573, 768
+ xy: 1437, 844
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-shock-mine-small
rotate: false
- xy: 1883, 622
+ xy: 1401, 630
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-shock-mine-tiny
rotate: false
- xy: 1975, 685
+ xy: 1069, 408
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-shock-mine-xlarge
rotate: false
- xy: 809, 678
+ xy: 709, 816
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-shrubs-large
rotate: false
- xy: 897, 154
+ xy: 821, 448
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-shrubs-medium
rotate: false
- xy: 1607, 802
+ xy: 1403, 810
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-shrubs-small
rotate: false
- xy: 1883, 596
+ xy: 1375, 604
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-shrubs-tiny
rotate: false
- xy: 1939, 667
+ xy: 1087, 426
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-shrubs-xlarge
rotate: false
- xy: 331, 666
+ xy: 659, 716
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-silicon-smelter-large
rotate: false
- xy: 897, 112
+ xy: 821, 406
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-silicon-smelter-medium
rotate: false
- xy: 1641, 836
+ xy: 1369, 776
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-silicon-smelter-small
rotate: false
- xy: 1065, 570
+ xy: 1349, 578
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-silicon-smelter-tiny
rotate: false
- xy: 1957, 667
+ xy: 1105, 444
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-silicon-smelter-xlarge
rotate: false
- xy: 331, 616
+ xy: 709, 766
+ size: 48, 48
+ orig: 48, 48
+ offset: 0, 0
+ index: -1
+block-slag-large
+ rotate: false
+ xy: 821, 364
+ size: 40, 40
+ orig: 40, 40
+ offset: 0, 0
+ index: -1
+block-slag-medium
+ rotate: false
+ xy: 1335, 742
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+block-slag-small
+ rotate: false
+ xy: 1337, 552
+ size: 24, 24
+ orig: 24, 24
+ offset: 0, 0
+ index: -1
+block-slag-tiny
+ rotate: false
+ xy: 1123, 462
+ size: 16, 16
+ orig: 16, 16
+ offset: 0, 0
+ index: -1
+block-slag-xlarge
+ rotate: false
+ xy: 709, 716
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-snow-large
rotate: false
- xy: 897, 70
+ xy: 813, 322
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-snow-medium
rotate: false
- xy: 1675, 870
+ xy: 1301, 708
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-snow-pine-large
rotate: false
- xy: 897, 28
+ xy: 813, 280
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-snow-pine-medium
rotate: false
- xy: 1539, 700
+ xy: 1437, 810
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-snow-pine-small
rotate: false
- xy: 1065, 544
+ xy: 1453, 656
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-snow-pine-tiny
rotate: false
- xy: 1975, 667
+ xy: 1141, 480
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-snow-pine-xlarge
rotate: false
- xy: 381, 666
+ xy: 759, 816
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-snow-small
rotate: false
- xy: 1091, 570
+ xy: 1427, 630
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-snow-tiny
rotate: false
- xy: 973, 285
+ xy: 1159, 498
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-snow-xlarge
rotate: false
- xy: 381, 616
+ xy: 759, 766
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-snowrock-large
rotate: false
- xy: 947, 242
+ xy: 813, 238
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-snowrock-medium
rotate: false
- xy: 1573, 734
+ xy: 1403, 776
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-snowrock-small
rotate: false
- xy: 1065, 518
+ xy: 1401, 604
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-snowrock-tiny
rotate: false
- xy: 1247, 458
+ xy: 1051, 372
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-snowrock-xlarge
rotate: false
- xy: 431, 666
+ xy: 759, 716
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-snowrocks-large
rotate: false
- xy: 947, 200
+ xy: 813, 196
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-snowrocks-medium
rotate: false
- xy: 1607, 768
+ xy: 1369, 742
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-snowrocks-small
rotate: false
- xy: 1091, 544
+ xy: 1375, 578
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-snowrocks-tiny
rotate: false
- xy: 991, 293
+ xy: 1069, 390
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-snowrocks-xlarge
rotate: false
- xy: 431, 616
+ xy: 809, 828
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-solar-panel-large
rotate: false
- xy: 939, 158
+ xy: 813, 154
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-solar-panel-large-large
rotate: false
- xy: 939, 116
+ xy: 813, 112
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-solar-panel-large-medium
rotate: false
- xy: 1641, 802
+ xy: 1335, 708
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-solar-panel-large-small
rotate: false
- xy: 1117, 570
+ xy: 1363, 552
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-solar-panel-large-tiny
rotate: false
- xy: 1325, 524
+ xy: 1087, 408
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-solar-panel-large-xlarge
rotate: false
- xy: 481, 666
+ xy: 809, 778
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-solar-panel-medium
rotate: false
- xy: 1675, 836
+ xy: 1437, 776
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-solar-panel-small
rotate: false
- xy: 1065, 492
+ xy: 1453, 630
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-solar-panel-tiny
rotate: false
- xy: 1343, 524
+ xy: 1105, 426
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-solar-panel-xlarge
rotate: false
- xy: 481, 616
+ xy: 809, 728
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-sorter-large
rotate: false
- xy: 939, 74
+ xy: 813, 70
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-sorter-medium
rotate: false
- xy: 1709, 870
+ xy: 1403, 742
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-sorter-small
rotate: false
- xy: 1091, 518
+ xy: 1427, 604
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-sorter-tiny
rotate: false
- xy: 1361, 524
+ xy: 1123, 444
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-sorter-xlarge
rotate: false
- xy: 531, 666
+ xy: 809, 678
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-spawn-large
rotate: false
- xy: 939, 32
+ xy: 813, 28
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-spawn-medium
rotate: false
- xy: 1573, 700
+ xy: 1369, 708
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-spawn-small
rotate: false
- xy: 1117, 544
+ xy: 1401, 578
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-spawn-tiny
rotate: false
- xy: 1379, 524
+ xy: 1141, 462
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-spawn-xlarge
rotate: false
- xy: 531, 616
+ xy: 331, 666
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-spectre-large
rotate: false
- xy: 981, 158
+ xy: 871, 494
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-spectre-medium
rotate: false
- xy: 1607, 734
+ xy: 1437, 742
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-spectre-small
rotate: false
- xy: 1143, 570
+ xy: 1389, 552
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-spectre-tiny
rotate: false
- xy: 1397, 524
+ xy: 1159, 480
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-spectre-xlarge
rotate: false
- xy: 581, 666
- size: 48, 48
- orig: 48, 48
- offset: 0, 0
- index: -1
-block-spirit-factory-large
- rotate: false
- xy: 981, 116
- size: 40, 40
- orig: 40, 40
- offset: 0, 0
- index: -1
-block-spirit-factory-medium
- rotate: false
- xy: 1641, 768
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-spirit-factory-small
- rotate: false
- xy: 1065, 466
- size: 24, 24
- orig: 24, 24
- offset: 0, 0
- index: -1
-block-spirit-factory-tiny
- rotate: false
- xy: 1415, 524
- size: 16, 16
- orig: 16, 16
- offset: 0, 0
- index: -1
-block-spirit-factory-xlarge
- rotate: false
- xy: 581, 616
+ xy: 331, 616
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-spore-cluster-large
rotate: false
- xy: 981, 74
+ xy: 863, 452
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-spore-cluster-medium
rotate: false
- xy: 1675, 802
+ xy: 1403, 708
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-spore-cluster-small
rotate: false
- xy: 1091, 492
+ xy: 1453, 604
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-spore-cluster-tiny
rotate: false
- xy: 1433, 524
+ xy: 1177, 498
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-spore-cluster-xlarge
rotate: false
- xy: 631, 666
+ xy: 381, 666
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-spore-moss-large
rotate: false
- xy: 981, 32
+ xy: 863, 410
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-spore-moss-medium
rotate: false
- xy: 1709, 836
+ xy: 1437, 708
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-spore-moss-small
rotate: false
- xy: 1117, 518
+ xy: 1427, 578
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-spore-moss-tiny
rotate: false
- xy: 1451, 524
+ xy: 1051, 354
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-spore-moss-xlarge
rotate: false
- xy: 631, 616
+ xy: 381, 616
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-spore-pine-large
rotate: false
- xy: 821, 933
+ xy: 863, 368
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-spore-pine-medium
rotate: false
- xy: 1743, 870
+ xy: 1505, 907
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-spore-pine-small
rotate: false
- xy: 1143, 544
+ xy: 1415, 552
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-spore-pine-tiny
rotate: false
- xy: 1469, 524
+ xy: 1069, 372
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-spore-pine-xlarge
rotate: false
- xy: 681, 666
+ xy: 431, 666
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-spore-press-large
rotate: false
- xy: 863, 933
+ xy: 879, 536
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-spore-press-medium
rotate: false
- xy: 1607, 700
+ xy: 1539, 907
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-spore-press-small
rotate: false
- xy: 1169, 570
+ xy: 1453, 578
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-spore-press-tiny
rotate: false
- xy: 1487, 524
+ xy: 1087, 390
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-spore-press-xlarge
rotate: false
- xy: 681, 616
+ xy: 431, 616
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-sporerocks-large
rotate: false
- xy: 905, 933
+ xy: 855, 322
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-sporerocks-medium
rotate: false
- xy: 1641, 734
+ xy: 1573, 907
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-sporerocks-small
rotate: false
- xy: 1065, 440
+ xy: 1441, 552
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-sporerocks-tiny
rotate: false
- xy: 1505, 524
+ xy: 1105, 408
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-sporerocks-xlarge
rotate: false
- xy: 731, 666
+ xy: 481, 666
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-stone-large
rotate: false
- xy: 947, 933
+ xy: 855, 280
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-stone-medium
rotate: false
- xy: 1675, 768
+ xy: 1607, 907
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-stone-small
rotate: false
- xy: 1091, 466
+ xy: 1483, 682
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-stone-tiny
rotate: false
- xy: 1523, 524
+ xy: 1123, 426
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-stone-xlarge
rotate: false
- xy: 731, 616
+ xy: 481, 616
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-surge-tower-large
rotate: false
- xy: 989, 933
+ xy: 855, 238
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-surge-tower-medium
rotate: false
- xy: 1709, 802
+ xy: 1641, 907
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-surge-tower-small
rotate: false
- xy: 1117, 492
+ xy: 1479, 656
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-surge-tower-tiny
rotate: false
- xy: 1541, 524
+ xy: 1141, 444
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-surge-tower-xlarge
rotate: false
- xy: 781, 628
+ xy: 531, 666
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-surge-wall-large
rotate: false
- xy: 1031, 933
+ xy: 855, 196
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-surge-wall-large-large
rotate: false
- xy: 1073, 933
+ xy: 855, 154
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-surge-wall-large-medium
rotate: false
- xy: 1743, 836
+ xy: 1675, 907
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-surge-wall-large-small
rotate: false
- xy: 1143, 518
+ xy: 1479, 630
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-surge-wall-large-tiny
rotate: false
- xy: 1559, 524
+ xy: 1159, 462
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-surge-wall-large-xlarge
rotate: false
- xy: 831, 628
+ xy: 531, 616
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-surge-wall-medium
rotate: false
- xy: 1777, 870
+ xy: 1709, 907
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-surge-wall-small
rotate: false
- xy: 1169, 544
+ xy: 1479, 604
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-surge-wall-tiny
rotate: false
- xy: 1577, 524
+ xy: 1177, 480
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-surge-wall-xlarge
rotate: false
- xy: 781, 578
+ xy: 581, 666
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-swarmer-large
rotate: false
- xy: 1115, 933
+ xy: 855, 112
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-swarmer-medium
rotate: false
- xy: 1641, 700
+ xy: 1743, 907
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-swarmer-small
rotate: false
- xy: 1195, 570
+ xy: 1479, 578
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-swarmer-tiny
rotate: false
- xy: 1595, 524
+ xy: 1195, 498
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-swarmer-xlarge
rotate: false
- xy: 831, 578
+ xy: 581, 616
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-tainted-water-large
rotate: false
- xy: 1157, 933
+ xy: 855, 70
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-tainted-water-medium
rotate: false
- xy: 1675, 734
+ xy: 1777, 907
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-tainted-water-small
rotate: false
- xy: 1091, 440
+ xy: 1467, 552
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-tainted-water-tiny
rotate: false
- xy: 1613, 524
+ xy: 1051, 336
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-tainted-water-xlarge
rotate: false
- xy: 351, 566
+ xy: 631, 666
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-tar-large
rotate: false
- xy: 1199, 933
+ xy: 855, 28
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-tar-medium
rotate: false
- xy: 1709, 768
+ xy: 1811, 907
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-tar-small
rotate: false
- xy: 1117, 466
+ xy: 1509, 685
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-tar-tiny
rotate: false
- xy: 1631, 524
+ xy: 1069, 354
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-tar-xlarge
rotate: false
- xy: 351, 516
- size: 48, 48
- orig: 48, 48
- offset: 0, 0
- index: -1
-block-tau-mech-pad-large
- rotate: false
- xy: 1241, 933
- size: 40, 40
- orig: 40, 40
- offset: 0, 0
- index: -1
-block-tau-mech-pad-medium
- rotate: false
- xy: 1743, 802
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-tau-mech-pad-small
- rotate: false
- xy: 1143, 492
- size: 24, 24
- orig: 24, 24
- offset: 0, 0
- index: -1
-block-tau-mech-pad-tiny
- rotate: false
- xy: 1649, 524
- size: 16, 16
- orig: 16, 16
- offset: 0, 0
- index: -1
-block-tau-mech-pad-xlarge
- rotate: false
- xy: 401, 566
+ xy: 631, 616
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-tendrils-large
rotate: false
- xy: 1283, 933
+ xy: 905, 452
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-tendrils-medium
rotate: false
- xy: 1777, 836
+ xy: 1845, 907
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-tendrils-small
rotate: false
- xy: 1169, 518
+ xy: 1535, 685
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-tendrils-tiny
rotate: false
- xy: 1667, 524
+ xy: 1087, 372
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-tendrils-xlarge
rotate: false
- xy: 351, 466
+ xy: 681, 666
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-thermal-generator-large
rotate: false
- xy: 1325, 933
+ xy: 905, 410
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-thermal-generator-medium
rotate: false
- xy: 1811, 870
+ xy: 1879, 907
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-thermal-generator-small
rotate: false
- xy: 1195, 544
+ xy: 1561, 685
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-thermal-generator-tiny
rotate: false
- xy: 1685, 524
+ xy: 1105, 390
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-thermal-generator-xlarge
rotate: false
- xy: 401, 516
+ xy: 681, 616
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-thermal-pump-large
rotate: false
- xy: 1367, 933
+ xy: 913, 494
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-thermal-pump-medium
rotate: false
- xy: 1675, 700
+ xy: 1913, 907
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-thermal-pump-small
rotate: false
- xy: 1221, 570
+ xy: 1587, 685
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-thermal-pump-tiny
rotate: false
- xy: 1703, 524
+ xy: 1123, 408
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-thermal-pump-xlarge
rotate: false
- xy: 451, 566
+ xy: 731, 666
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-thorium-reactor-large
rotate: false
- xy: 1409, 933
+ xy: 905, 368
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-thorium-reactor-medium
rotate: false
- xy: 1709, 734
+ xy: 1947, 907
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-thorium-reactor-small
rotate: false
- xy: 1117, 440
+ xy: 1613, 685
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-thorium-reactor-tiny
rotate: false
- xy: 1721, 524
+ xy: 1141, 426
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-thorium-reactor-xlarge
rotate: false
- xy: 351, 416
+ xy: 731, 616
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-thorium-wall-large
rotate: false
- xy: 1451, 933
+ xy: 897, 326
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-thorium-wall-large-large
rotate: false
- xy: 1493, 933
+ xy: 897, 284
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-thorium-wall-large-medium
rotate: false
- xy: 1743, 768
+ xy: 1471, 844
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-thorium-wall-large-small
rotate: false
- xy: 1143, 466
+ xy: 1639, 685
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-thorium-wall-large-tiny
rotate: false
- xy: 1739, 524
+ xy: 1159, 444
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-thorium-wall-large-xlarge
rotate: false
- xy: 401, 466
+ xy: 781, 628
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-thorium-wall-medium
rotate: false
- xy: 1777, 802
+ xy: 1471, 810
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-thorium-wall-small
rotate: false
- xy: 1169, 492
+ xy: 1661, 711
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-thorium-wall-tiny
rotate: false
- xy: 1757, 524
+ xy: 1177, 462
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-thorium-wall-xlarge
rotate: false
- xy: 451, 516
+ xy: 831, 628
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-thruster-large
rotate: false
- xy: 1535, 933
+ xy: 897, 242
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-thruster-medium
rotate: false
- xy: 1811, 836
+ xy: 1471, 776
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-thruster-small
rotate: false
- xy: 1195, 518
+ xy: 1665, 685
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-thruster-tiny
rotate: false
- xy: 1775, 524
+ xy: 1195, 480
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-thruster-xlarge
rotate: false
- xy: 501, 566
- size: 48, 48
- orig: 48, 48
- offset: 0, 0
- index: -1
-block-titan-factory-large
- rotate: false
- xy: 1577, 933
- size: 40, 40
- orig: 40, 40
- offset: 0, 0
- index: -1
-block-titan-factory-medium
- rotate: false
- xy: 1845, 870
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-titan-factory-small
- rotate: false
- xy: 1221, 544
- size: 24, 24
- orig: 24, 24
- offset: 0, 0
- index: -1
-block-titan-factory-tiny
- rotate: false
- xy: 1793, 524
- size: 16, 16
- orig: 16, 16
- offset: 0, 0
- index: -1
-block-titan-factory-xlarge
- rotate: false
- xy: 351, 366
+ xy: 781, 578
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-titanium-conveyor-large
rotate: false
- xy: 1619, 933
+ xy: 897, 200
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-titanium-conveyor-medium
rotate: false
- xy: 1709, 700
+ xy: 1471, 742
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-titanium-conveyor-small
rotate: false
- xy: 1247, 570
+ xy: 1855, 841
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-titanium-conveyor-tiny
rotate: false
- xy: 1811, 524
+ xy: 1213, 498
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-titanium-conveyor-xlarge
rotate: false
- xy: 401, 416
+ xy: 831, 578
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-titanium-wall-large
rotate: false
- xy: 1661, 933
+ xy: 897, 158
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-titanium-wall-large-large
rotate: false
- xy: 1703, 933
+ xy: 897, 116
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-titanium-wall-large-medium
rotate: false
- xy: 1743, 734
+ xy: 1471, 708
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-titanium-wall-large-small
rotate: false
- xy: 1143, 440
+ xy: 1881, 843
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-titanium-wall-large-tiny
rotate: false
- xy: 1829, 524
+ xy: 1051, 318
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-titanium-wall-large-xlarge
rotate: false
- xy: 451, 466
+ xy: 351, 566
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-titanium-wall-medium
rotate: false
- xy: 1777, 768
+ xy: 1981, 907
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-titanium-wall-small
rotate: false
- xy: 1169, 466
+ xy: 1493, 552
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-titanium-wall-tiny
rotate: false
- xy: 1847, 524
+ xy: 1069, 336
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-titanium-wall-xlarge
rotate: false
- xy: 501, 516
- size: 48, 48
- orig: 48, 48
- offset: 0, 0
- index: -1
-block-trident-ship-pad-large
- rotate: false
- xy: 1745, 933
- size: 40, 40
- orig: 40, 40
- offset: 0, 0
- index: -1
-block-trident-ship-pad-medium
- rotate: false
- xy: 1811, 802
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-trident-ship-pad-small
- rotate: false
- xy: 1195, 492
- size: 24, 24
- orig: 24, 24
- offset: 0, 0
- index: -1
-block-trident-ship-pad-tiny
- rotate: false
- xy: 1865, 524
- size: 16, 16
- orig: 16, 16
- offset: 0, 0
- index: -1
-block-trident-ship-pad-xlarge
- rotate: false
- xy: 551, 566
+ xy: 351, 516
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-turbine-generator-large
rotate: false
- xy: 1787, 933
+ xy: 897, 74
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-turbine-generator-medium
rotate: false
- xy: 1845, 836
+ xy: 2015, 907
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-turbine-generator-small
rotate: false
- xy: 1221, 518
+ xy: 1957, 829
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-turbine-generator-tiny
rotate: false
- xy: 1883, 524
+ xy: 1087, 354
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-turbine-generator-xlarge
rotate: false
- xy: 351, 316
+ xy: 401, 566
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-underflow-gate-large
rotate: false
- xy: 1829, 933
+ xy: 897, 32
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-underflow-gate-medium
rotate: false
- xy: 1879, 870
+ xy: 1505, 873
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-underflow-gate-small
rotate: false
- xy: 1247, 544
+ xy: 1983, 829
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-underflow-gate-tiny
rotate: false
- xy: 1317, 506
+ xy: 1105, 372
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-underflow-gate-xlarge
rotate: false
- xy: 401, 366
+ xy: 351, 466
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-unloader-large
rotate: false
- xy: 1871, 933
+ xy: 947, 452
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-unloader-medium
rotate: false
- xy: 1743, 700
+ xy: 1505, 839
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-unloader-small
rotate: false
- xy: 1273, 570
+ xy: 2009, 829
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-unloader-tiny
rotate: false
- xy: 1335, 506
+ xy: 1123, 390
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-unloader-xlarge
rotate: false
- xy: 451, 416
+ xy: 401, 516
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-vault-large
rotate: false
- xy: 1913, 933
+ xy: 947, 410
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-vault-medium
rotate: false
- xy: 1777, 734
+ xy: 1539, 873
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-vault-small
rotate: false
- xy: 1169, 440
+ xy: 955, 526
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-vault-tiny
rotate: false
- xy: 1353, 506
+ xy: 1141, 408
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-vault-xlarge
rotate: false
- xy: 501, 466
+ xy: 451, 566
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-water-extractor-large
rotate: false
- xy: 1955, 933
+ xy: 947, 368
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-water-extractor-medium
rotate: false
- xy: 1811, 768
+ xy: 1505, 805
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-water-extractor-small
rotate: false
- xy: 1195, 466
+ xy: 955, 500
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-water-extractor-tiny
rotate: false
- xy: 1371, 506
+ xy: 1159, 426
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-water-extractor-xlarge
rotate: false
- xy: 551, 516
+ xy: 351, 416
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-water-large
rotate: false
- xy: 845, 891
+ xy: 939, 326
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-water-medium
rotate: false
- xy: 1845, 802
+ xy: 1539, 839
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-water-small
rotate: false
- xy: 1221, 492
+ xy: 981, 526
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-water-tiny
rotate: false
- xy: 1389, 506
+ xy: 1177, 444
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-water-xlarge
rotate: false
- xy: 601, 566
+ xy: 401, 466
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-wave-large
rotate: false
- xy: 887, 891
+ xy: 939, 284
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-wave-medium
rotate: false
- xy: 1879, 836
+ xy: 1573, 873
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-wave-small
rotate: false
- xy: 1247, 518
+ xy: 1007, 526
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-wave-tiny
rotate: false
- xy: 1407, 506
+ xy: 1195, 462
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-wave-xlarge
rotate: false
- xy: 351, 266
+ xy: 451, 516
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-white-tree-dead-large
rotate: false
- xy: 929, 891
+ xy: 939, 242
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-white-tree-dead-medium
rotate: false
- xy: 1777, 700
+ xy: 1505, 771
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-white-tree-dead-small
rotate: false
- xy: 1273, 544
+ xy: 981, 500
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-white-tree-dead-tiny
rotate: false
- xy: 1425, 506
+ xy: 1213, 480
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-white-tree-dead-xlarge
rotate: false
- xy: 401, 316
+ xy: 501, 566
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
block-white-tree-large
rotate: false
- xy: 971, 891
+ xy: 939, 200
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
block-white-tree-medium
rotate: false
- xy: 1811, 734
+ xy: 1539, 805
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
block-white-tree-small
rotate: false
- xy: 1299, 570
+ xy: 1033, 526
size: 24, 24
orig: 24, 24
offset: 0, 0
index: -1
block-white-tree-tiny
rotate: false
- xy: 1443, 506
+ xy: 1231, 498
size: 16, 16
orig: 16, 16
offset: 0, 0
index: -1
block-white-tree-xlarge
rotate: false
- xy: 451, 366
- size: 48, 48
- orig: 48, 48
- offset: 0, 0
- index: -1
-block-wraith-factory-large
- rotate: false
- xy: 1013, 891
- size: 40, 40
- orig: 40, 40
- offset: 0, 0
- index: -1
-block-wraith-factory-medium
- rotate: false
- xy: 1845, 768
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-block-wraith-factory-small
- rotate: false
- xy: 1195, 440
- size: 24, 24
- orig: 24, 24
- offset: 0, 0
- index: -1
-block-wraith-factory-tiny
- rotate: false
- xy: 1461, 506
- size: 16, 16
- orig: 16, 16
- offset: 0, 0
- index: -1
-block-wraith-factory-xlarge
- rotate: false
- xy: 501, 416
+ xy: 351, 366
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
button
rotate: false
- xy: 1625, 904
+ xy: 1201, 946
size: 36, 27
split: 12, 12, 12, 12
orig: 36, 27
@@ -14308,7 +13622,7 @@ button
index: -1
button-disabled
rotate: false
- xy: 477, 1
+ xy: 939, 171
size: 36, 27
split: 12, 12, 12, 12
orig: 36, 27
@@ -14316,7 +13630,7 @@ button-disabled
index: -1
button-down
rotate: false
- xy: 1055, 904
+ xy: 939, 142
size: 36, 27
split: 12, 12, 12, 12
orig: 36, 27
@@ -14324,7 +13638,7 @@ button-down
index: -1
button-edge-1
rotate: false
- xy: 1093, 904
+ xy: 939, 113
size: 36, 27
split: 12, 12, 12, 12
orig: 36, 27
@@ -14332,7 +13646,7 @@ button-edge-1
index: -1
button-edge-2
rotate: false
- xy: 1131, 904
+ xy: 939, 84
size: 36, 27
split: 12, 12, 12, 12
orig: 36, 27
@@ -14340,7 +13654,7 @@ button-edge-2
index: -1
button-edge-3
rotate: false
- xy: 1169, 904
+ xy: 939, 55
size: 36, 27
split: 12, 12, 12, 12
orig: 36, 27
@@ -14348,7 +13662,7 @@ button-edge-3
index: -1
button-edge-4
rotate: false
- xy: 1207, 904
+ xy: 939, 26
size: 36, 27
split: 12, 12, 12, 12
orig: 36, 27
@@ -14356,7 +13670,7 @@ button-edge-4
index: -1
button-edge-over-4
rotate: false
- xy: 1245, 904
+ xy: 897, 3
size: 36, 27
split: 12, 12, 12, 12
orig: 36, 27
@@ -14364,7 +13678,7 @@ button-edge-over-4
index: -1
button-over
rotate: false
- xy: 1283, 904
+ xy: 859, 946
size: 36, 27
split: 12, 12, 12, 12
orig: 36, 27
@@ -14372,7 +13686,7 @@ button-over
index: -1
button-red
rotate: false
- xy: 1321, 904
+ xy: 897, 946
size: 36, 27
split: 12, 12, 12, 12
orig: 36, 27
@@ -14380,7 +13694,7 @@ button-red
index: -1
button-right
rotate: false
- xy: 1435, 904
+ xy: 1011, 946
size: 36, 27
split: 12, 12, 12, 12
orig: 36, 27
@@ -14388,7 +13702,7 @@ button-right
index: -1
button-right-down
rotate: false
- xy: 1359, 904
+ xy: 935, 946
size: 36, 27
split: 12, 12, 12, 12
orig: 36, 27
@@ -14396,7 +13710,7 @@ button-right-down
index: -1
button-right-over
rotate: false
- xy: 1397, 904
+ xy: 973, 946
size: 36, 27
split: 12, 12, 12, 12
orig: 36, 27
@@ -14404,7 +13718,7 @@ button-right-over
index: -1
button-select
rotate: false
- xy: 1221, 466
+ xy: 1007, 500
size: 24, 24
split: 4, 4, 4, 4
orig: 24, 24
@@ -14412,7 +13726,7 @@ button-select
index: -1
button-square
rotate: false
- xy: 1549, 904
+ xy: 1125, 946
size: 36, 27
split: 12, 12, 12, 12
orig: 36, 27
@@ -14420,7 +13734,7 @@ button-square
index: -1
button-square-down
rotate: false
- xy: 1473, 904
+ xy: 1049, 946
size: 36, 27
split: 12, 12, 12, 12
orig: 36, 27
@@ -14428,7 +13742,7 @@ button-square-down
index: -1
button-square-over
rotate: false
- xy: 1511, 904
+ xy: 1087, 946
size: 36, 27
split: 12, 12, 12, 12
orig: 36, 27
@@ -14436,7 +13750,7 @@ button-square-over
index: -1
button-trans
rotate: false
- xy: 1587, 904
+ xy: 1163, 946
size: 36, 27
split: 12, 12, 12, 12
orig: 36, 27
@@ -14444,42 +13758,42 @@ button-trans
index: -1
check-disabled
rotate: false
- xy: 1879, 802
+ xy: 1573, 839
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
check-off
rotate: false
- xy: 1811, 700
+ xy: 1607, 873
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
check-on
rotate: false
- xy: 1845, 734
+ xy: 1505, 737
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
check-on-disabled
rotate: false
- xy: 1879, 768
+ xy: 1539, 771
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
check-on-over
rotate: false
- xy: 1845, 700
+ xy: 1573, 805
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
check-over
rotate: false
- xy: 1879, 734
+ xy: 1607, 839
size: 32, 32
orig: 32, 32
offset: 0, 0
@@ -14500,7 +13814,7 @@ crater
index: -1
cursor
rotate: false
- xy: 986, 375
+ xy: 955, 494
size: 4, 4
orig: 4, 4
offset: 0, 0
@@ -14514,7 +13828,7 @@ discord-banner
index: -1
flat-down-base
rotate: false
- xy: 1663, 904
+ xy: 1239, 946
size: 36, 27
split: 12, 12, 12, 12
orig: 36, 27
@@ -14529,7 +13843,7 @@ info-banner
index: -1
inventory
rotate: false
- xy: 1247, 476
+ xy: 989, 458
size: 24, 40
split: 10, 10, 10, 14
orig: 24, 40
@@ -14537,140 +13851,140 @@ inventory
index: -1
item-blast-compound-icon
rotate: false
- xy: 1879, 700
+ xy: 1641, 873
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-coal-icon
rotate: false
- xy: 1031, 551
+ xy: 1539, 737
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-copper-icon
rotate: false
- xy: 929, 517
+ xy: 1573, 771
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-graphite-icon
rotate: false
- xy: 929, 483
+ xy: 1607, 805
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-lead-icon
rotate: false
- xy: 963, 517
+ xy: 1641, 839
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-metaglass-icon
rotate: false
- xy: 929, 449
+ xy: 1675, 873
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-phase-fabric-icon
rotate: false
- xy: 997, 517
+ xy: 1573, 737
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-plastanium-icon
rotate: false
- xy: 963, 483
+ xy: 1607, 771
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-pyratite-icon
rotate: false
- xy: 929, 415
+ xy: 1641, 805
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-sand-icon
rotate: false
- xy: 1031, 517
+ xy: 1675, 839
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-scrap-icon
rotate: false
- xy: 997, 483
+ xy: 1709, 873
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-silicon-icon
rotate: false
- xy: 963, 449
+ xy: 1607, 737
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-spore-pod-icon
rotate: false
- xy: 929, 381
+ xy: 1641, 771
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-surge-alloy-icon
rotate: false
- xy: 1031, 483
+ xy: 1675, 805
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-thorium-icon
rotate: false
- xy: 997, 449
+ xy: 1709, 839
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-titanium-icon
rotate: false
- xy: 963, 415
+ xy: 1743, 873
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
liquid-cryofluid-icon
rotate: false
- xy: 1031, 449
+ xy: 1641, 737
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
liquid-oil-icon
rotate: false
- xy: 997, 415
+ xy: 1675, 771
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
liquid-slag-icon
rotate: false
- xy: 963, 381
+ xy: 1709, 805
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
liquid-water-icon
rotate: false
- xy: 1031, 415
+ xy: 1743, 839
size: 32, 32
orig: 32, 32
offset: 0, 0
@@ -14691,7 +14005,7 @@ nomap
index: -1
pane
rotate: false
- xy: 1739, 904
+ xy: 1315, 946
size: 36, 27
split: 12, 12, 12, 12
orig: 36, 27
@@ -14699,7 +14013,7 @@ pane
index: -1
pane-2
rotate: false
- xy: 1701, 904
+ xy: 1277, 946
size: 36, 27
split: 12, 12, 12, 12
orig: 36, 27
@@ -14707,7 +14021,7 @@ pane-2
index: -1
scroll
rotate: false
- xy: 1299, 533
+ xy: 989, 379
size: 24, 35
split: 10, 10, 6, 5
orig: 24, 35
@@ -14715,7 +14029,7 @@ scroll
index: -1
scroll-horizontal
rotate: false
- xy: 43, 2
+ xy: 1, 2
size: 35, 24
split: 6, 5, 10, 10
orig: 35, 24
@@ -14723,56 +14037,56 @@ scroll-horizontal
index: -1
scroll-knob-horizontal-black
rotate: false
- xy: 1, 2
+ xy: 351, 4
size: 40, 24
orig: 40, 24
offset: 0, 0
index: -1
scroll-knob-vertical-black
rotate: false
- xy: 1273, 502
+ xy: 989, 416
size: 24, 40
orig: 24, 40
offset: 0, 0
index: -1
scroll-knob-vertical-thin
rotate: false
- xy: 1901, 554
+ xy: 2035, 865
size: 12, 40
orig: 12, 40
offset: 0, 0
index: -1
selection
rotate: false
- xy: 821, 975
+ xy: 1505, 708
size: 1, 1
orig: 1, 1
offset: 0, 0
index: -1
slider
rotate: false
- xy: 131, 528
+ xy: 1925, 859
size: 1, 8
orig: 1, 8
offset: 0, 0
index: -1
slider-knob
rotate: false
- xy: 997, 375
+ xy: 1777, 867
size: 29, 38
orig: 29, 38
offset: 0, 0
index: -1
slider-knob-down
rotate: false
- xy: 1028, 375
+ xy: 1808, 867
size: 29, 38
orig: 29, 38
offset: 0, 0
index: -1
slider-knob-over
rotate: false
- xy: 955, 341
+ xy: 1839, 867
size: 29, 38
orig: 29, 38
offset: 0, 0
@@ -14786,7 +14100,7 @@ slider-vertical
index: -1
underline
rotate: false
- xy: 1891, 904
+ xy: 1467, 946
size: 36, 27
split: 12, 12, 12, 12
orig: 36, 27
@@ -14794,7 +14108,7 @@ underline
index: -1
underline-2
rotate: false
- xy: 1777, 904
+ xy: 1353, 946
size: 36, 27
split: 12, 12, 12, 12
orig: 36, 27
@@ -14802,7 +14116,7 @@ underline-2
index: -1
underline-disabled
rotate: false
- xy: 1815, 904
+ xy: 1391, 946
size: 36, 27
split: 12, 12, 12, 12
orig: 36, 27
@@ -14810,7 +14124,7 @@ underline-disabled
index: -1
underline-red
rotate: false
- xy: 1853, 904
+ xy: 1429, 946
size: 36, 27
split: 12, 12, 12, 12
orig: 36, 27
@@ -14818,14 +14132,14 @@ underline-red
index: -1
whiteui
rotate: false
- xy: 821, 928
+ xy: 259, 664
size: 3, 3
orig: 3, 3
offset: 0, 0
index: -1
window-empty
rotate: false
- xy: 1913, 836
+ xy: 1928, 844
size: 27, 61
split: 4, 4, 2, 2
orig: 27, 61
@@ -14927,2047 +14241,2284 @@ size: 2048,1024
format: RGBA8888
filter: Nearest,Nearest
repeat: none
+rubble-1-0
+ rotate: false
+ xy: 1933, 723
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+rubble-1-1
+ rotate: false
+ xy: 839, 363
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+rubble-2-0
+ rotate: false
+ xy: 1335, 191
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+rubble-2-1
+ rotate: false
+ xy: 1401, 191
+ size: 64, 64
+ orig: 64, 64
+ offset: 0, 0
+ index: -1
+rubble-3-0
+ rotate: false
+ xy: 1237, 189
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
+rubble-4-0
+ rotate: false
+ xy: 1827, 115
+ size: 128, 128
+ orig: 128, 128
+ offset: 0, 0
+ index: -1
+rubble-5-0
+ rotate: false
+ xy: 1887, 387
+ size: 160, 160
+ orig: 160, 160
+ offset: 0, 0
+ index: -1
+rubble-6-0
+ rotate: false
+ xy: 1043, 33
+ size: 192, 192
+ orig: 192, 192
+ offset: 0, 0
+ index: -1
+rubble-7-0
+ rotate: false
+ xy: 817, 1
+ size: 224, 224
+ orig: 224, 224
+ offset: 0, 0
+ index: -1
+rubble-8-0
+ rotate: false
+ xy: 1611, 463
+ size: 256, 256
+ orig: 256, 256
+ offset: 0, 0
+ index: -1
+scorch-0-0
+ rotate: false
+ xy: 675, 347
+ size: 80, 80
+ orig: 80, 80
+ offset: 0, 0
+ index: -1
+scorch-0-1
+ rotate: false
+ xy: 757, 347
+ size: 80, 80
+ orig: 80, 80
+ offset: 0, 0
+ index: -1
+scorch-0-2
+ rotate: false
+ xy: 1957, 163
+ size: 80, 80
+ orig: 80, 80
+ offset: 0, 0
+ index: -1
+scorch-1-0
+ rotate: false
+ xy: 1933, 901
+ size: 110, 110
+ orig: 110, 110
+ offset: 0, 0
+ index: -1
+scorch-1-1
+ rotate: false
+ xy: 1933, 789
+ size: 110, 110
+ orig: 110, 110
+ offset: 0, 0
+ index: -1
+scorch-1-2
+ rotate: false
+ xy: 1237, 33
+ size: 110, 110
+ orig: 110, 110
+ offset: 0, 0
+ index: -1
+scorch-2-0
+ rotate: false
+ xy: 1887, 245
+ size: 140, 140
+ orig: 140, 140
+ offset: 0, 0
+ index: -1
+scorch-2-1
+ rotate: false
+ xy: 1543, 145
+ size: 140, 140
+ orig: 140, 140
+ offset: 0, 0
+ index: -1
+scorch-2-2
+ rotate: false
+ xy: 1685, 145
+ size: 140, 140
+ orig: 140, 140
+ offset: 0, 0
+ index: -1
+scorch-3-0
+ rotate: false
+ xy: 1543, 287
+ size: 170, 170
+ orig: 170, 170
+ offset: 0, 0
+ index: -1
+scorch-3-1
+ rotate: false
+ xy: 1715, 291
+ size: 170, 170
+ orig: 170, 170
+ offset: 0, 0
+ index: -1
+scorch-3-2
+ rotate: false
+ xy: 1869, 549
+ size: 170, 170
+ orig: 170, 170
+ offset: 0, 0
+ index: -1
+scorch-4-0
+ rotate: false
+ xy: 1139, 489
+ size: 200, 200
+ orig: 200, 200
+ offset: 0, 0
+ index: -1
+scorch-4-1
+ rotate: false
+ xy: 1139, 287
+ size: 200, 200
+ orig: 200, 200
+ offset: 0, 0
+ index: -1
+scorch-4-2
+ rotate: false
+ xy: 1341, 257
+ size: 200, 200
+ orig: 200, 200
+ offset: 0, 0
+ index: -1
+scorch-5-0
+ rotate: false
+ xy: 675, 429
+ size: 230, 230
+ orig: 230, 230
+ offset: 0, 0
+ index: -1
+scorch-5-1
+ rotate: false
+ xy: 907, 459
+ size: 230, 230
+ orig: 230, 230
+ offset: 0, 0
+ index: -1
+scorch-5-2
+ rotate: false
+ xy: 907, 227
+ size: 230, 230
+ orig: 230, 230
+ offset: 0, 0
+ index: -1
+scorch-6-0
+ rotate: false
+ xy: 293, 47
+ size: 260, 260
+ orig: 260, 260
+ offset: 0, 0
+ index: -1
+scorch-6-1
+ rotate: false
+ xy: 555, 77
+ size: 260, 260
+ orig: 260, 260
+ offset: 0, 0
+ index: -1
+scorch-6-2
+ rotate: false
+ xy: 1349, 459
+ size: 260, 260
+ orig: 260, 260
+ offset: 0, 0
+ index: -1
+scorch-7-0
+ rotate: false
+ xy: 1, 17
+ size: 290, 290
+ orig: 290, 290
+ offset: 0, 0
+ index: -1
+scorch-7-1
+ rotate: false
+ xy: 1349, 721
+ size: 290, 290
+ orig: 290, 290
+ offset: 0, 0
+ index: -1
+scorch-7-2
+ rotate: false
+ xy: 1641, 721
+ size: 290, 290
+ orig: 290, 290
+ offset: 0, 0
+ index: -1
+scorch-8-0
+ rotate: false
+ xy: 353, 339
+ size: 320, 320
+ orig: 320, 320
+ offset: 0, 0
+ index: -1
+scorch-8-1
+ rotate: false
+ xy: 705, 691
+ size: 320, 320
+ orig: 320, 320
+ offset: 0, 0
+ index: -1
+scorch-8-2
+ rotate: false
+ xy: 1027, 691
+ size: 320, 320
+ orig: 320, 320
+ offset: 0, 0
+ index: -1
+scorch-9-0
+ rotate: false
+ xy: 1, 661
+ size: 350, 350
+ orig: 350, 350
+ offset: 0, 0
+ index: -1
+scorch-9-1
+ rotate: false
+ xy: 1, 309
+ size: 350, 350
+ orig: 350, 350
+ offset: 0, 0
+ index: -1
+scorch-9-2
+ rotate: false
+ xy: 353, 661
+ size: 350, 350
+ orig: 350, 350
+ offset: 0, 0
+ index: -1
+
+sprites6.png
+size: 2048,512
+format: RGBA8888
+filter: Nearest,Nearest
+repeat: none
alloy-smelter-icon-editor
rotate: false
- xy: 1, 23
+ xy: 905, 285
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
arc-icon-editor
rotate: false
- xy: 261, 145
+ xy: 2015, 479
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
armored-conveyor-icon-editor
rotate: false
- xy: 569, 399
+ xy: 2015, 445
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
battery-icon-editor
rotate: false
- xy: 603, 399
+ xy: 1209, 117
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
battery-large-icon-editor
rotate: false
- xy: 745, 927
+ xy: 1035, 415
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
blast-drill-icon-editor
rotate: false
- xy: 1, 251
+ xy: 645, 383
size: 128, 128
orig: 128, 128
offset: 0, 0
index: -1
blast-mixer-icon-editor
rotate: false
- xy: 745, 861
+ xy: 1043, 219
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
block-border-editor
rotate: false
- xy: 637, 399
+ xy: 1555, 273
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
bridge-conduit-icon-editor
rotate: false
- xy: 671, 399
+ xy: 1597, 315
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
bridge-conveyor-icon-editor
rotate: false
- xy: 295, 13
+ xy: 1243, 117
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
char-icon-editor
rotate: false
- xy: 329, 13
+ xy: 1631, 315
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-char1
rotate: false
- xy: 329, 13
+ xy: 1631, 315
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
clear-editor
rotate: false
- xy: 261, 378
+ xy: 645, 250
size: 1, 1
orig: 1, 1
offset: 0, 0
index: -1
+cliff-icon-editor
+ rotate: false
+ xy: 1277, 117
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
cliffs-icon-editor
rotate: false
- xy: 363, 13
+ xy: 1665, 315
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
coal-centrifuge-icon-editor
rotate: false
- xy: 811, 861
+ xy: 1043, 153
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
combustion-generator-icon-editor
rotate: false
- xy: 397, 13
+ xy: 1311, 117
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
-command-center-icon-editor
- rotate: false
- xy: 877, 861
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
conduit-icon-editor
rotate: false
- xy: 493, 103
+ xy: 1699, 315
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
container-icon-editor
rotate: false
- xy: 943, 861
+ xy: 1043, 87
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
conveyor-icon-editor
rotate: false
- xy: 535, 145
+ xy: 1345, 117
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
copper-wall-icon-editor
rotate: false
- xy: 431, 29
+ xy: 1733, 315
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
copper-wall-large-icon-editor
rotate: false
- xy: 1009, 861
+ xy: 1101, 349
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
core-foundation-icon-editor
rotate: false
- xy: 323, 733
+ xy: 163, 61
size: 128, 128
orig: 128, 128
offset: 0, 0
index: -1
core-nucleus-icon-editor
rotate: false
- xy: 323, 863
+ xy: 1, 29
size: 160, 160
orig: 160, 160
offset: 0, 0
index: -1
core-shard-icon-editor
rotate: false
- xy: 99, 23
+ xy: 1133, 415
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
craters-icon-editor
rotate: false
- xy: 477, 69
+ xy: 1379, 117
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-craters1
rotate: false
- xy: 477, 69
+ xy: 1379, 117
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
-crawler-factory-icon-editor
- rotate: false
- xy: 1075, 861
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
cryofluidmixer-icon-editor
rotate: false
- xy: 1141, 861
+ xy: 1167, 349
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
cultivator-icon-editor
rotate: false
- xy: 1207, 861
+ xy: 1233, 349
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
cyclone-icon-editor
rotate: false
- xy: 843, 927
+ xy: 1231, 415
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
-dagger-factory-icon-editor
- rotate: false
- xy: 1273, 861
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
dark-metal-icon-editor
rotate: false
- xy: 569, 365
+ xy: 1767, 315
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
dark-panel-1-icon-editor
rotate: false
- xy: 603, 365
+ xy: 1801, 315
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-dark-panel-1
rotate: false
- xy: 603, 365
+ xy: 1801, 315
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
dark-panel-2-icon-editor
rotate: false
- xy: 637, 365
+ xy: 1835, 315
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-dark-panel-2
rotate: false
- xy: 637, 365
+ xy: 1835, 315
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
dark-panel-3-icon-editor
rotate: false
- xy: 671, 365
+ xy: 1869, 315
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-dark-panel-3
rotate: false
- xy: 671, 365
+ xy: 1869, 315
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
dark-panel-4-icon-editor
rotate: false
- xy: 555, 331
+ xy: 1903, 315
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-dark-panel-4
rotate: false
- xy: 555, 331
+ xy: 1903, 315
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
dark-panel-5-icon-editor
rotate: false
- xy: 589, 331
+ xy: 1937, 315
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-dark-panel-5
rotate: false
- xy: 589, 331
+ xy: 1937, 315
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
dark-panel-6-icon-editor
rotate: false
- xy: 555, 297
+ xy: 1971, 315
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-dark-panel-6
rotate: false
- xy: 555, 297
+ xy: 1971, 315
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
darksand-icon-editor
rotate: false
- xy: 623, 331
+ xy: 163, 27
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-darksand1
rotate: false
- xy: 623, 331
+ xy: 163, 27
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
darksand-tainted-water-icon-editor
rotate: false
- xy: 589, 297
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-editor-darksand-tainted-water
- rotate: false
- xy: 589, 297
+ xy: 197, 27
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
darksand-water-icon-editor
rotate: false
- xy: 555, 263
+ xy: 231, 27
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
-editor-darksand-water
- rotate: false
- xy: 555, 263
- size: 32, 32
- orig: 32, 32
- offset: 0, 0
- index: -1
-dart-mech-pad-icon-editor
- rotate: false
- xy: 1339, 861
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
deepwater-icon-editor
rotate: false
- xy: 657, 331
+ xy: 265, 27
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-deepwater
rotate: false
- xy: 657, 331
+ xy: 265, 27
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
-delta-mech-pad-icon-editor
- rotate: false
- xy: 1405, 861
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
differential-generator-icon-editor
rotate: false
- xy: 941, 927
+ xy: 1329, 415
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
diode-icon-editor
rotate: false
- xy: 623, 297
+ xy: 299, 27
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
distributor-icon-editor
rotate: false
- xy: 1471, 861
+ xy: 1299, 349
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
door-icon-editor
rotate: false
- xy: 589, 263
+ xy: 333, 27
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
door-large-icon-editor
rotate: false
- xy: 1537, 861
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-draug-factory-icon-editor
- rotate: false
- xy: 1603, 861
+ xy: 1365, 349
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
dunerocks-icon-editor
rotate: false
- xy: 555, 229
+ xy: 367, 27
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
duo-icon-editor
rotate: false
- xy: 657, 297
+ xy: 401, 27
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-char2
rotate: false
- xy: 623, 263
+ xy: 435, 27
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-char3
rotate: false
- xy: 589, 229
+ xy: 469, 27
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-clear
rotate: false
- xy: 733, 883
+ xy: 905, 273
size: 10, 10
orig: 10, 10
offset: 0, 0
index: -1
editor-craters2
rotate: false
- xy: 555, 195
+ xy: 503, 27
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-craters3
rotate: false
- xy: 657, 263
+ xy: 1505, 215
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+editor-darksand-tainted-water1
+ rotate: false
+ xy: 1143, 67
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+editor-darksand-tainted-water2
+ rotate: false
+ xy: 1143, 33
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+editor-darksand-tainted-water3
+ rotate: false
+ xy: 1177, 67
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+editor-darksand-water1
+ rotate: false
+ xy: 1177, 33
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+editor-darksand-water2
+ rotate: false
+ xy: 2005, 315
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+editor-darksand-water3
+ rotate: false
+ xy: 1489, 181
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-darksand2
rotate: false
- xy: 623, 229
+ xy: 1413, 117
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-darksand3
rotate: false
- xy: 589, 195
+ xy: 1555, 239
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-grass1
rotate: false
- xy: 657, 229
+ xy: 1447, 133
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
grass-icon-editor
rotate: false
- xy: 657, 229
+ xy: 1447, 133
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-grass2
rotate: false
- xy: 623, 195
+ xy: 1211, 83
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-grass3
rotate: false
- xy: 657, 195
+ xy: 1211, 49
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-holostone1
rotate: false
- xy: 569, 161
+ xy: 1245, 83
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
holostone-icon-editor
rotate: false
- xy: 569, 161
+ xy: 1245, 83
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-holostone2
rotate: false
- xy: 603, 161
+ xy: 1245, 49
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-holostone3
rotate: false
- xy: 637, 161
+ xy: 1279, 83
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-hotrock1
rotate: false
- xy: 671, 161
+ xy: 1279, 49
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
hotrock-icon-editor
rotate: false
- xy: 671, 161
+ xy: 1279, 49
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-hotrock2
rotate: false
- xy: 511, 69
+ xy: 1313, 83
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-hotrock3
rotate: false
- xy: 527, 103
+ xy: 1313, 49
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-ice-snow1
rotate: false
- xy: 671, 127
+ xy: 1381, 49
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
ice-snow-icon-editor
rotate: false
- xy: 671, 127
+ xy: 1381, 49
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-ice-snow2
rotate: false
- xy: 545, 69
+ xy: 1415, 83
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-ice-snow3
rotate: false
- xy: 691, 331
+ xy: 1415, 49
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-ice1
rotate: false
- xy: 569, 127
+ xy: 1347, 83
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
ice-icon-editor
rotate: false
- xy: 569, 127
+ xy: 1347, 83
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-ice2
rotate: false
- xy: 603, 127
+ xy: 1347, 49
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-ice3
rotate: false
- xy: 637, 127
+ xy: 1381, 83
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-ignarock1
rotate: false
- xy: 691, 297
+ xy: 1523, 181
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
ignarock-icon-editor
rotate: false
- xy: 691, 297
+ xy: 1523, 181
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-ignarock2
rotate: false
- xy: 691, 263
+ xy: 1211, 15
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-ignarock3
rotate: false
- xy: 691, 229
+ xy: 1245, 15
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-magmarock1
rotate: false
- xy: 691, 195
+ xy: 1279, 15
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
magmarock-icon-editor
rotate: false
- xy: 691, 195
+ xy: 1279, 15
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-magmarock2
rotate: false
- xy: 705, 161
+ xy: 1313, 15
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-magmarock3
rotate: false
- xy: 705, 127
+ xy: 1347, 15
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-metal-floor
rotate: false
- xy: 465, 29
+ xy: 1381, 15
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
metal-floor-icon-editor
rotate: false
- xy: 465, 29
+ xy: 1381, 15
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-metal-floor-2
rotate: false
- xy: 499, 35
+ xy: 1415, 15
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
metal-floor-2-icon-editor
rotate: false
- xy: 499, 35
+ xy: 1415, 15
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-metal-floor-3
rotate: false
- xy: 499, 1
+ xy: 1449, 99
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
metal-floor-3-icon-editor
rotate: false
- xy: 499, 1
+ xy: 1449, 99
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-metal-floor-5
rotate: false
- xy: 533, 35
+ xy: 1449, 65
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
metal-floor-5-icon-editor
rotate: false
- xy: 533, 35
+ xy: 1449, 65
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-metal-floor-damaged1
rotate: false
- xy: 533, 1
+ xy: 1449, 31
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
metal-floor-damaged-icon-editor
rotate: false
- xy: 533, 1
+ xy: 1449, 31
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-metal-floor-damaged2
rotate: false
- xy: 705, 399
+ xy: 1489, 147
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-metal-floor-damaged3
rotate: false
- xy: 705, 365
+ xy: 1523, 147
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-moss1
rotate: false
- xy: 725, 331
+ xy: 1483, 113
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
moss-icon-editor
rotate: false
- xy: 725, 331
+ xy: 1483, 113
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-moss2
rotate: false
- xy: 725, 297
+ xy: 1483, 79
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-moss3
rotate: false
- xy: 725, 263
+ xy: 1517, 113
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-ore-coal1
rotate: false
- xy: 725, 229
+ xy: 1483, 45
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-ore-coal2
rotate: false
- xy: 725, 195
+ xy: 1517, 79
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-ore-coal3
rotate: false
- xy: 739, 161
+ xy: 1517, 45
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-ore-copper1
rotate: false
- xy: 739, 127
+ xy: 1483, 11
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-ore-copper2
rotate: false
- xy: 567, 35
+ xy: 1517, 11
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-ore-copper3
rotate: false
- xy: 567, 1
+ xy: 1589, 273
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-ore-lead1
rotate: false
- xy: 579, 93
+ xy: 1589, 239
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-ore-lead2
rotate: false
- xy: 613, 93
+ xy: 1623, 281
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-ore-lead3
rotate: false
- xy: 647, 93
+ xy: 1623, 247
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-ore-scrap1
rotate: false
- xy: 681, 93
+ xy: 1657, 281
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-ore-scrap2
rotate: false
- xy: 715, 93
+ xy: 1657, 247
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-ore-scrap3
rotate: false
- xy: 749, 93
+ xy: 1691, 281
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-ore-thorium1
rotate: false
- xy: 601, 59
+ xy: 1691, 247
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-ore-thorium2
rotate: false
- xy: 601, 25
+ xy: 1725, 281
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-ore-thorium3
rotate: false
- xy: 635, 59
+ xy: 1725, 247
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-ore-titanium1
rotate: false
- xy: 635, 25
+ xy: 1759, 281
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-ore-titanium2
rotate: false
- xy: 669, 59
+ xy: 1759, 247
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-ore-titanium3
rotate: false
- xy: 669, 25
+ xy: 1793, 281
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-pebbles1
rotate: false
- xy: 703, 59
+ xy: 1793, 247
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-pebbles2
rotate: false
- xy: 703, 25
+ xy: 1827, 281
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-pebbles3
rotate: false
- xy: 737, 59
+ xy: 1827, 247
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-salt
rotate: false
- xy: 737, 25
+ xy: 1861, 281
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
salt-icon-editor
rotate: false
- xy: 737, 25
+ xy: 1861, 281
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
-editor-sand-water
+editor-sand-water1
rotate: false
- xy: 767, 827
+ xy: 1929, 281
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
-sand-water-icon-editor
+editor-sand-water2
rotate: false
- xy: 767, 827
+ xy: 1929, 247
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+editor-sand-water3
+ rotate: false
+ xy: 1963, 281
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-sand1
rotate: false
- xy: 771, 59
+ xy: 1861, 247
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
sand-icon-editor
rotate: false
- xy: 771, 59
+ xy: 1861, 247
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-sand2
rotate: false
- xy: 771, 25
+ xy: 1895, 281
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-sand3
rotate: false
- xy: 733, 827
+ xy: 1895, 247
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-shale1
rotate: false
- xy: 801, 827
+ xy: 1963, 247
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
shale-icon-editor
rotate: false
- xy: 801, 827
+ xy: 1963, 247
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-shale2
rotate: false
- xy: 835, 827
+ xy: 1997, 281
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-shale3
rotate: false
- xy: 869, 827
+ xy: 1997, 247
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+editor-slag
+ rotate: false
+ xy: 1557, 205
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+slag-icon-editor
+ rotate: false
+ xy: 1557, 205
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-snow1
rotate: false
- xy: 903, 827
+ xy: 1557, 171
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-snow2
rotate: false
- xy: 937, 827
+ xy: 1591, 205
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-snow3
rotate: false
- xy: 971, 827
+ xy: 1591, 171
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-spawn
rotate: false
- xy: 1005, 827
+ xy: 1625, 213
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-spore-moss1
rotate: false
- xy: 1039, 827
+ xy: 1625, 179
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
spore-moss-icon-editor
rotate: false
- xy: 1039, 827
+ xy: 1625, 179
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-spore-moss2
rotate: false
- xy: 1073, 827
+ xy: 1659, 213
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-spore-moss3
rotate: false
- xy: 1107, 827
+ xy: 1659, 179
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-stone1
rotate: false
- xy: 1141, 827
+ xy: 1693, 213
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
stone-icon-editor
rotate: false
- xy: 1141, 827
+ xy: 1693, 213
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-stone2
rotate: false
- xy: 1175, 827
+ xy: 1693, 179
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-stone3
rotate: false
- xy: 1209, 827
+ xy: 1727, 213
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-tainted-water
rotate: false
- xy: 1243, 827
+ xy: 1727, 179
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
tainted-water-icon-editor
rotate: false
- xy: 1243, 827
+ xy: 1727, 179
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-tar
rotate: false
- xy: 1277, 827
+ xy: 1761, 213
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
tar-icon-editor
rotate: false
- xy: 1277, 827
+ xy: 1761, 213
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-tendrils1
rotate: false
- xy: 1311, 827
+ xy: 1761, 179
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-tendrils2
rotate: false
- xy: 1345, 827
+ xy: 1795, 213
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-tendrils3
rotate: false
- xy: 1379, 827
+ xy: 1795, 179
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
editor-water
rotate: false
- xy: 1413, 827
+ xy: 1829, 213
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
water-icon-editor
rotate: false
- xy: 1413, 827
+ xy: 1829, 213
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
force-projector-icon-editor
rotate: false
- xy: 1039, 927
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-fortress-factory-icon-editor
- rotate: false
- xy: 1137, 927
+ xy: 1427, 415
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
fuse-icon-editor
rotate: false
- xy: 1235, 927
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-ghoul-factory-icon-editor
- rotate: false
- xy: 1333, 927
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-glaive-ship-pad-icon-editor
- rotate: false
- xy: 1431, 927
+ xy: 1525, 415
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
graphite-press-icon-editor
rotate: false
- xy: 1669, 861
+ xy: 1431, 349
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
+ground-factory-icon-editor
+ rotate: false
+ xy: 1623, 415
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
hail-icon-editor
rotate: false
- xy: 1447, 827
+ xy: 1829, 179
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
icerocks-icon-editor
rotate: false
- xy: 1481, 827
+ xy: 1863, 213
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
illuminator-icon-editor
rotate: false
- xy: 1515, 827
+ xy: 1863, 179
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
impact-reactor-icon-editor
rotate: false
- xy: 485, 895
+ xy: 645, 253
size: 128, 128
orig: 128, 128
offset: 0, 0
index: -1
incinerator-icon-editor
rotate: false
- xy: 1549, 827
+ xy: 1897, 213
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
inverted-sorter-icon-editor
rotate: false
- xy: 1583, 827
+ xy: 1897, 179
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-source-icon-editor
rotate: false
- xy: 1617, 827
+ xy: 1931, 213
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
item-void-icon-editor
rotate: false
- xy: 1651, 827
+ xy: 1931, 179
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
-javelin-ship-pad-icon-editor
- rotate: false
- xy: 1735, 861
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
junction-icon-editor
rotate: false
- xy: 1685, 827
+ xy: 1965, 213
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
kiln-icon-editor
rotate: false
- xy: 1801, 861
+ xy: 1497, 349
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
lancer-icon-editor
rotate: false
- xy: 1867, 861
+ xy: 1563, 349
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
laser-drill-icon-editor
rotate: false
- xy: 1529, 927
+ xy: 1721, 415
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
launch-pad-icon-editor
rotate: false
- xy: 1627, 927
+ xy: 1819, 415
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
launch-pad-large-icon-editor
rotate: false
- xy: 1, 121
+ xy: 775, 383
size: 128, 128
orig: 128, 128
offset: 0, 0
index: -1
liquid-junction-icon-editor
rotate: false
- xy: 1719, 827
+ xy: 1965, 179
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
liquid-router-icon-editor
rotate: false
- xy: 1753, 827
+ xy: 1999, 213
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
liquid-source-icon-editor
rotate: false
- xy: 1787, 827
+ xy: 1999, 179
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
liquid-tank-icon-editor
rotate: false
- xy: 1725, 927
+ xy: 1917, 415
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
liquid-void-icon-editor
rotate: false
- xy: 1821, 827
+ xy: 1557, 137
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
+mass-conveyor-icon-editor
+ rotate: false
+ xy: 553, 93
+ size: 96, 96
+ orig: 96, 96
+ offset: 0, 0
+ index: -1
mass-driver-icon-editor
rotate: false
- xy: 1823, 927
+ xy: 651, 155
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
mechanical-drill-icon-editor
rotate: false
- xy: 1933, 861
+ xy: 1629, 349
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
mechanical-pump-icon-editor
rotate: false
- xy: 1855, 827
+ xy: 1591, 137
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
meltdown-icon-editor
rotate: false
- xy: 131, 251
+ xy: 293, 61
size: 128, 128
orig: 128, 128
offset: 0, 0
index: -1
melter-icon-editor
rotate: false
- xy: 1889, 827
+ xy: 1625, 145
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
mend-projector-icon-editor
rotate: false
- xy: 485, 829
+ xy: 1695, 349
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
mender-icon-editor
rotate: false
- xy: 1923, 827
+ xy: 1659, 145
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
message-icon-editor
rotate: false
- xy: 1957, 827
+ xy: 1693, 145
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
multi-press-icon-editor
rotate: false
- xy: 1921, 927
+ xy: 749, 155
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
oil-extractor-icon-editor
rotate: false
- xy: 323, 375
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
-omega-mech-pad-icon-editor
- rotate: false
- xy: 197, 23
+ xy: 651, 57
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
overdrive-projector-icon-editor
rotate: false
- xy: 551, 829
+ xy: 1761, 349
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
overflow-gate-icon-editor
rotate: false
- xy: 717, 793
+ xy: 1727, 145
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
pebbles-icon-editor
rotate: false
- xy: 717, 759
+ xy: 1761, 145
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
-phantom-factory-icon-editor
- rotate: false
- xy: 617, 829
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
phase-conduit-icon-editor
rotate: false
- xy: 751, 793
+ xy: 1795, 145
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
phase-conveyor-icon-editor
rotate: false
- xy: 717, 725
+ xy: 1829, 145
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
phase-wall-icon-editor
rotate: false
- xy: 785, 793
+ xy: 1863, 145
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
phase-wall-large-icon-editor
rotate: false
- xy: 453, 763
+ xy: 1827, 349
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
phase-weaver-icon-editor
rotate: false
- xy: 519, 763
+ xy: 1893, 349
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
pine-icon-editor
rotate: false
- xy: 1999, 877
+ xy: 1109, 101
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
plastanium-compressor-icon-editor
rotate: false
- xy: 453, 697
+ xy: 1959, 349
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
plastanium-conveyor-icon-editor
rotate: false
- xy: 751, 759
+ xy: 1897, 145
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
plastanium-wall-icon-editor
rotate: false
- xy: 717, 691
+ xy: 1931, 145
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
plastanium-wall-large-icon-editor
rotate: false
- xy: 519, 697
+ xy: 553, 27
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
plated-conduit-icon-editor
rotate: false
- xy: 819, 793
+ xy: 1965, 145
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
pneumatic-drill-icon-editor
rotate: false
- xy: 585, 763
+ xy: 945, 23
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
power-node-icon-editor
rotate: false
- xy: 785, 759
+ xy: 1999, 145
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
power-node-large-icon-editor
rotate: false
- xy: 453, 631
+ xy: 1011, 21
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
power-source-icon-editor
rotate: false
- xy: 751, 725
+ xy: 1551, 103
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
power-void-icon-editor
rotate: false
- xy: 717, 657
+ xy: 1551, 69
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
pulse-conduit-icon-editor
rotate: false
- xy: 853, 793
+ xy: 1585, 103
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
pulverizer-icon-editor
rotate: false
- xy: 819, 759
+ xy: 1551, 35
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
pyratite-mixer-icon-editor
rotate: false
- xy: 519, 631
+ xy: 1077, 21
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
repair-point-icon-editor
rotate: false
- xy: 785, 725
+ xy: 1551, 1
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
-revenant-factory-icon-editor
- rotate: false
- xy: 323, 603
- size: 128, 128
- orig: 128, 128
- offset: 0, 0
- index: -1
ripple-icon-editor
rotate: false
- xy: 261, 277
+ xy: 749, 57
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
rock-icon-editor
rotate: false
- xy: 1999, 827
+ xy: 1505, 299
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
rocks-icon-editor
rotate: false
- xy: 751, 691
+ xy: 1585, 69
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
rotary-pump-icon-editor
rotate: false
- xy: 585, 697
+ xy: 1109, 283
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
router-icon-editor
rotate: false
- xy: 717, 623
+ xy: 1585, 35
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
rtg-generator-icon-editor
rotate: false
- xy: 453, 565
+ xy: 1109, 217
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
saltrocks-icon-editor
rotate: false
- xy: 887, 793
+ xy: 1585, 1
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
salvo-icon-editor
rotate: false
- xy: 519, 565
+ xy: 1175, 283
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
sand-boulder-icon-editor
rotate: false
- xy: 853, 759
+ xy: 1625, 111
+ size: 32, 32
+ orig: 32, 32
+ offset: 0, 0
+ index: -1
+sand-water-icon-editor
+ rotate: false
+ xy: 1659, 111
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
sandrocks-icon-editor
rotate: false
- xy: 819, 725
+ xy: 1693, 111
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
scatter-icon-editor
rotate: false
- xy: 585, 631
+ xy: 1109, 151
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
scorch-icon-editor
rotate: false
- xy: 785, 691
+ xy: 1727, 111
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
scrap-wall-gigantic-icon-editor
rotate: false
- xy: 615, 895
+ xy: 775, 253
size: 128, 128
orig: 128, 128
offset: 0, 0
index: -1
scrap-wall-huge-icon-editor
rotate: false
- xy: 261, 179
+ xy: 847, 155
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
scrap-wall-icon-editor
rotate: false
- xy: 751, 657
+ xy: 1761, 111
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
scrap-wall-large-icon-editor
rotate: false
- xy: 453, 499
+ xy: 1175, 217
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
separator-icon-editor
rotate: false
- xy: 519, 499
+ xy: 1241, 283
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
shale-boulder-icon-editor
rotate: false
- xy: 717, 589
+ xy: 1795, 111
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
shalerocks-icon-editor
rotate: false
- xy: 921, 793
+ xy: 1829, 111
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
shock-mine-icon-editor
rotate: false
- xy: 887, 759
+ xy: 1863, 111
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
shrubs-icon-editor
rotate: false
- xy: 853, 725
+ xy: 1897, 111
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
silicon-smelter-icon-editor
rotate: false
- xy: 585, 565
+ xy: 1175, 151
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
snow-icon-editor
rotate: false
- xy: 819, 691
+ xy: 1931, 111
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
snow-pine-icon-editor
rotate: false
- xy: 519, 383
+ xy: 1439, 167
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
snowrock-icon-editor
rotate: false
- xy: 683, 845
+ xy: 1159, 101
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
snowrocks-icon-editor
rotate: false
- xy: 785, 657
+ xy: 1965, 111
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
solar-panel-icon-editor
rotate: false
- xy: 751, 623
+ xy: 1999, 111
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
solar-panel-large-icon-editor
rotate: false
- xy: 359, 277
+ xy: 847, 57
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
sorter-icon-editor
rotate: false
- xy: 717, 555
+ xy: 1619, 77
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
spawn-icon-editor
rotate: false
- xy: 955, 793
+ xy: 1619, 43
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
spectre-icon-editor
rotate: false
- xy: 131, 121
+ xy: 905, 383
size: 128, 128
orig: 128, 128
offset: 0, 0
index: -1
-spirit-factory-icon-editor
- rotate: false
- xy: 585, 499
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
spore-cluster-icon-editor
rotate: false
- xy: 493, 137
+ xy: 1555, 307
size: 40, 40
orig: 40, 40
offset: 0, 0
index: -1
spore-pine-icon-editor
rotate: false
- xy: 427, 63
+ xy: 1505, 249
size: 48, 48
orig: 48, 48
offset: 0, 0
index: -1
spore-press-icon-editor
rotate: false
- xy: 519, 433
+ xy: 1241, 217
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
sporerocks-icon-editor
rotate: false
- xy: 921, 759
+ xy: 1653, 77
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
surge-tower-icon-editor
rotate: false
- xy: 585, 433
+ xy: 1307, 283
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
surge-wall-icon-editor
rotate: false
- xy: 887, 725
+ xy: 1619, 9
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
surge-wall-large-icon-editor
rotate: false
- xy: 651, 763
+ xy: 1241, 151
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
swarmer-icon-editor
rotate: false
- xy: 651, 697
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-tau-mech-pad-icon-editor
- rotate: false
- xy: 651, 631
+ xy: 1307, 217
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
tendrils-icon-editor
rotate: false
- xy: 853, 691
+ xy: 1653, 43
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
thermal-generator-icon-editor
rotate: false
- xy: 651, 565
+ xy: 1373, 283
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
thermal-pump-icon-editor
rotate: false
- xy: 359, 179
+ xy: 1003, 285
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
thorium-reactor-icon-editor
rotate: false
- xy: 421, 375
+ xy: 945, 187
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
thorium-wall-icon-editor
rotate: false
- xy: 819, 657
+ xy: 1687, 77
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
thorium-wall-large-icon-editor
rotate: false
- xy: 651, 499
+ xy: 1307, 151
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
thruster-icon-editor
rotate: false
- xy: 323, 473
+ xy: 423, 61
size: 128, 128
orig: 128, 128
offset: 0, 0
index: -1
-titan-factory-icon-editor
- rotate: false
- xy: 457, 277
- size: 96, 96
- orig: 96, 96
- offset: 0, 0
- index: -1
titanium-conveyor-icon-editor
rotate: false
- xy: 785, 623
+ xy: 1653, 9
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
titanium-wall-icon-editor
rotate: false
- xy: 751, 589
+ xy: 1687, 43
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
titanium-wall-large-icon-editor
rotate: false
- xy: 651, 433
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
-trident-ship-pad-icon-editor
- rotate: false
- xy: 295, 113
+ xy: 1373, 217
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
turbine-generator-icon-editor
rotate: false
- xy: 295, 47
+ xy: 1439, 283
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
underflow-gate-icon-editor
rotate: false
- xy: 717, 521
+ xy: 1721, 77
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
unloader-icon-editor
rotate: false
- xy: 989, 793
+ xy: 1687, 9
size: 32, 32
orig: 32, 32
offset: 0, 0
index: -1
vault-icon-editor
rotate: false
- xy: 457, 179
+ xy: 945, 89
size: 96, 96
orig: 96, 96
offset: 0, 0
index: -1
water-extractor-icon-editor
rotate: false
- xy: 361, 113
+ xy: 1373, 151
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
wave-icon-editor
rotate: false
- xy: 361, 47
+ xy: 1439, 217
size: 64, 64
orig: 64, 64
offset: 0, 0
index: -1
white-tree-dead-icon-editor
rotate: false
- xy: 1, 703
+ xy: 1, 191
size: 320, 320
orig: 320, 320
offset: 0, 0
index: -1
white-tree-icon-editor
rotate: false
- xy: 1, 381
+ xy: 323, 191
size: 320, 320
orig: 320, 320
offset: 0, 0
index: -1
-wraith-factory-icon-editor
- rotate: false
- xy: 427, 113
- size: 64, 64
- orig: 64, 64
- offset: 0, 0
- index: -1
diff --git a/core/assets/sprites/sprites.png b/core/assets/sprites/sprites.png
index cd515ea955..0060e3f66e 100644
Binary files a/core/assets/sprites/sprites.png and b/core/assets/sprites/sprites.png differ
diff --git a/core/assets/sprites/sprites2.png b/core/assets/sprites/sprites2.png
index 1776b09b12..d5d3c40bdd 100644
Binary files a/core/assets/sprites/sprites2.png and b/core/assets/sprites/sprites2.png differ
diff --git a/core/assets/sprites/sprites3.png b/core/assets/sprites/sprites3.png
index b1980d6f8d..aab64f68ad 100644
Binary files a/core/assets/sprites/sprites3.png and b/core/assets/sprites/sprites3.png differ
diff --git a/core/assets/sprites/sprites4.png b/core/assets/sprites/sprites4.png
index 9c08c17bf7..e2146e8186 100644
Binary files a/core/assets/sprites/sprites4.png and b/core/assets/sprites/sprites4.png differ
diff --git a/core/assets/sprites/sprites5.png b/core/assets/sprites/sprites5.png
index d79a70a8f0..d263559418 100644
Binary files a/core/assets/sprites/sprites5.png and b/core/assets/sprites/sprites5.png differ
diff --git a/core/assets/sprites/sprites6.png b/core/assets/sprites/sprites6.png
new file mode 100644
index 0000000000..7bd921b560
Binary files /dev/null and b/core/assets/sprites/sprites6.png differ
diff --git a/core/src/mindustry/ClientLauncher.java b/core/src/mindustry/ClientLauncher.java
index fd94c323aa..17a71d6b06 100644
--- a/core/src/mindustry/ClientLauncher.java
+++ b/core/src/mindustry/ClientLauncher.java
@@ -92,10 +92,7 @@ public abstract class ClientLauncher extends ApplicationCore implements Platform
assets.load(mods);
assets.load(schematics);
- assets.loadRun("contentinit", ContentLoader.class, () -> {
- content.init();
- content.load();
- });
+ assets.loadRun("contentinit", ContentLoader.class, () -> content.init(), () -> content.load());
}
@Override
diff --git a/core/src/mindustry/Vars.java b/core/src/mindustry/Vars.java
index ab88d572bf..d3fed00cba 100644
--- a/core/src/mindustry/Vars.java
+++ b/core/src/mindustry/Vars.java
@@ -13,18 +13,15 @@ import arc.util.io.*;
import mindustry.ai.*;
import mindustry.core.*;
import mindustry.entities.*;
-import mindustry.entities.effect.*;
-import mindustry.entities.traits.*;
-import mindustry.entities.type.*;
import mindustry.game.*;
import mindustry.game.EventType.*;
import mindustry.gen.*;
import mindustry.input.*;
import mindustry.maps.*;
+import mindustry.maps.Map;
import mindustry.mod.*;
import mindustry.net.Net;
import mindustry.net.*;
-import mindustry.world.blocks.defense.ForceProjector.*;
import java.io.*;
import java.nio.charset.*;
@@ -77,6 +74,10 @@ public class Vars implements Loadable{
public static final float worldBounds = 100f;
/** units outside of this bound will simply die instantly */
public static final float finalWorldBounds = worldBounds + 500;
+ /** mining range for manual miners */
+ public static final float miningRange = 70f;
+ /** range for building */
+ public static final float buildingRange = 220f;
/** ticks spent out of bound until self destruct. */
public static final float boundsCountdown = 60 * 7;
/** for map generator dialog */
@@ -142,6 +143,8 @@ public class Vars implements Loadable{
public static Fi schematicDirectory;
/** data subdirectory used for bleeding edge build versions */
public static Fi bebuildDirectory;
+ /** empty map, indicates no current map */
+ public static Map emptyMap;
/** map file extension */
public static final String mapExtension = "msav";
/** save file extension */
@@ -152,7 +155,7 @@ public class Vars implements Loadable{
/** list of all locales that can be switched to */
public static Locale[] locales;
- public static FileTree tree;
+ public static FileTree tree = new FileTree();
public static Net net;
public static ContentLoader content;
public static GameState state;
@@ -165,6 +168,7 @@ public class Vars implements Loadable{
public static Schematics schematics = new Schematics();
public static BeControl becontrol;
+ public static Universe universe;
public static World world;
public static Maps maps;
public static WaveSpawner spawner;
@@ -178,18 +182,7 @@ public class Vars implements Loadable{
public static NetServer netServer;
public static NetClient netClient;
- public static Entities entities;
- public static EntityGroup playerGroup;
- public static EntityGroup tileGroup;
- public static EntityGroup bulletGroup;
- public static EntityGroup effectGroup;
- public static EntityGroup groundEffectGroup;
- public static EntityGroup shieldGroup;
- public static EntityGroup puddleGroup;
- public static EntityGroup fireGroup;
- public static EntityGroup unitGroup;
-
- public static Player player;
+ public static Playerc player;
@Override
public void loadAsync(){
@@ -199,6 +192,7 @@ public class Vars implements Loadable{
public static void init(){
Serialization.init();
+ Groups.init();
DefaultSerializers.typeMappings.put("mindustry.type.ContentType", "mindustry.ctype.ContentType");
if(loadLocales){
@@ -219,47 +213,6 @@ public class Vars implements Loadable{
Version.init();
- if(tree == null) tree = new FileTree();
- if(mods == null) mods = new Mods();
-
- content = new ContentLoader();
- loops = new LoopControl();
- defaultWaves = new DefaultWaves();
- collisions = new EntityCollisions();
- world = new World();
- becontrol = new BeControl();
-
- maps = new Maps();
- spawner = new WaveSpawner();
- indexer = new BlockIndexer();
- pathfinder = new Pathfinder();
-
- entities = new Entities();
- playerGroup = entities.add(Player.class).enableMapping();
- tileGroup = entities.add(TileEntity.class, false);
- bulletGroup = entities.add(Bullet.class).enableMapping();
- effectGroup = entities.add(EffectEntity.class, false);
- groundEffectGroup = entities.add(DrawTrait.class, false);
- puddleGroup = entities.add(Puddle.class).enableMapping();
- shieldGroup = entities.add(ShieldEntity.class, false);
- fireGroup = entities.add(Fire.class).enableMapping();
- unitGroup = entities.add(BaseUnit.class).enableMapping();
-
- for(EntityGroup> group : entities.all()){
- group.setRemoveListener(entity -> {
- if(entity instanceof SyncTrait && net.client()){
- netClient.addRemovedEntity((entity).getID());
- }
- });
- }
-
- state = new GameState();
- data = new GlobalData();
-
- mobile = Core.app.getType() == ApplicationType.Android || Core.app.getType() == ApplicationType.iOS || testMobile;
- ios = Core.app.getType() == ApplicationType.iOS;
- android = Core.app.getType() == ApplicationType.Android;
-
dataDirectory = Core.settings.getDataDirectory();
screenshotDirectory = dataDirectory.child("screenshots/");
customMapDirectory = dataDirectory.child("maps/");
@@ -269,6 +222,30 @@ public class Vars implements Loadable{
modDirectory = dataDirectory.child("mods/");
schematicDirectory = dataDirectory.child("schematics/");
bebuildDirectory = dataDirectory.child("be_builds/");
+ emptyMap = new Map(new StringMap());
+
+ if(tree == null) tree = new FileTree();
+ if(mods == null) mods = new Mods();
+
+ content = new ContentLoader();
+ loops = new LoopControl();
+ defaultWaves = new DefaultWaves();
+ collisions = new EntityCollisions();
+ world = new World();
+ universe = new Universe();
+ becontrol = new BeControl();
+
+ maps = new Maps();
+ spawner = new WaveSpawner();
+ indexer = new BlockIndexer();
+ pathfinder = new Pathfinder();
+
+ state = new GameState();
+ data = new GlobalData();
+
+ mobile = Core.app.getType() == ApplicationType.Android || Core.app.getType() == ApplicationType.iOS || testMobile;
+ ios = Core.app.getType() == ApplicationType.iOS;
+ android = Core.app.getType() == ApplicationType.Android;
modDirectory.mkdirs();
diff --git a/core/src/mindustry/ai/BlockIndexer.java b/core/src/mindustry/ai/BlockIndexer.java
index ff17679630..f79fc74b91 100644
--- a/core/src/mindustry/ai/BlockIndexer.java
+++ b/core/src/mindustry/ai/BlockIndexer.java
@@ -4,17 +4,20 @@ import arc.*;
import arc.func.*;
import arc.math.*;
import arc.math.geom.*;
+import arc.struct.EnumSet;
import arc.struct.*;
import arc.util.*;
import mindustry.content.*;
-import mindustry.entities.type.*;
import mindustry.game.EventType.*;
import mindustry.game.*;
+import mindustry.gen.*;
import mindustry.type.*;
import mindustry.world.*;
import mindustry.world.blocks.*;
import mindustry.world.meta.*;
+import java.util.*;
+
import static mindustry.Vars.*;
/** Class used for indexing special target blocks for AI. */
@@ -25,24 +28,24 @@ public class BlockIndexer{
/** Set of all ores that are being scanned. */
private final ObjectSet- scanOres = new ObjectSet<>();
+ private final IntSet intSet = new IntSet();
private final ObjectSet
- itemSet = new ObjectSet<>();
/** Stores all ore quadtrants on the map. */
- private ObjectMap
- > ores = new ObjectMap<>();
+ private ObjectMap
- ores = new ObjectMap<>();
/** Maps each team ID to a quarant. A quadrant is a grid of bits, where each bit is set if and only if there is a block of that team in that quadrant. */
private GridBits[] structQuadrants;
/** Stores all damaged tile entities by team. */
- private ObjectSet[] damagedTiles = new ObjectSet[Team.all().length];
+ private TileArray[] damagedTiles = new TileArray[Team.all().length];
/**All ores available on this map.*/
private ObjectSet
- allOres = new ObjectSet<>();
/**Stores teams that are present here as tiles.*/
- private ObjectSet activeTeams = new ObjectSet<>();
-
+ private Array activeTeams = new Array<>();
/** Maps teams to a map of flagged tiles by type. */
- private ObjectSet[][] flagMap = new ObjectSet[Team.all().length][BlockFlag.all.length];
+ private TileArray[][] flagMap = new TileArray[Team.all().length][BlockFlag.all.length];
/** Maps tile positions to their last known tile index data. */
private IntMap typeMap = new IntMap<>();
/** Empty set used for returning. */
- private ObjectSet emptySet = new ObjectSet<>();
+ private TileArray emptySet = new TileArray();
/** Array used for returning and reusing. */
private Array returnArray = new Array<>();
@@ -61,12 +64,12 @@ public class BlockIndexer{
Events.on(WorldLoadEvent.class, event -> {
scanOres.clear();
scanOres.addAll(Item.getAllOres());
- damagedTiles = new ObjectSet[Team.all().length];
- flagMap = new ObjectSet[Team.all().length][BlockFlag.all.length];
+ damagedTiles = new TileArray[Team.all().length];
+ flagMap = new TileArray[Team.all().length][BlockFlag.all.length];
for(int i = 0; i < flagMap.length; i++){
for(int j = 0; j < BlockFlag.all.length; j++){
- flagMap[i][j] = new ObjectSet<>();
+ flagMap[i][j] = new TileArray();
}
}
@@ -77,18 +80,14 @@ public class BlockIndexer{
//create bitset for each team type that contains each quadrant
structQuadrants = new GridBits[Team.all().length];
- for(int x = 0; x < world.width(); x++){
- for(int y = 0; y < world.height(); y++){
- Tile tile = world.tile(x, y);
+ for(Tile tile : world.tiles){
+ process(tile);
- process(tile);
-
- if(tile.entity != null && tile.entity.damaged()){
- notifyTileDamaged(tile.entity);
- }
-
- if(tile.drop() != null) allOres.add(tile.drop());
+ if(tile.entity != null && tile.entity.damaged()){
+ notifyTileDamaged(tile.entity);
}
+
+ if(tile.drop() != null) allOres.add(tile.drop());
}
for(int x = 0; x < quadWidth(); x++){
@@ -101,7 +100,7 @@ public class BlockIndexer{
});
}
- private ObjectSet[] getFlagged(Team team){
+ private TileArray[] getFlagged(Team team){
return flagMap[team.id];
}
@@ -118,14 +117,11 @@ public class BlockIndexer{
if(structQuadrants == null) return;
//go through every tile... ouch
- for(int x = 0; x < world.width(); x++){
- for(int y = 0; y < world.height(); y++){
- Tile tile = world.tile(x, y);
- if(tile.getTeam() == team){
- int quadrantX = tile.x / quadrantSize;
- int quadrantY = tile.y / quadrantSize;
- structQuadrant(team).set(quadrantX, quadrantY);
- }
+ for(Tile tile : world.tiles){
+ if(tile.team() == team){
+ int quadrantX = tile.x / quadrantSize;
+ int quadrantY = tile.y / quadrantSize;
+ structQuadrant(team).set(quadrantX, quadrantY);
}
}
}
@@ -136,16 +132,16 @@ public class BlockIndexer{
}
/** Returns all damaged tiles by team. */
- public ObjectSet getDamaged(Team team){
+ public TileArray getDamaged(Team team){
returnArray.clear();
if(damagedTiles[team.id] == null){
- damagedTiles[team.id] = new ObjectSet<>();
+ damagedTiles[team.id] = new TileArray();
}
- ObjectSet set = damagedTiles[team.id];
+ TileArray set = damagedTiles[team.id];
for(Tile tile : set){
- if((tile.entity == null || tile.entity.getTeam() != team || !tile.entity.damaged()) || tile.block() instanceof BuildBlock){
+ if((tile.entity == null || tile.entity.team() != team || !tile.entity.damaged()) || tile.block() instanceof BuildBlock){
returnArray.add(tile);
}
}
@@ -158,16 +154,49 @@ public class BlockIndexer{
}
/** Get all allied blocks with a flag. */
- public ObjectSet getAllied(Team team, BlockFlag type){
+ public TileArray getAllied(Team team, BlockFlag type){
return flagMap[team.id][type.ordinal()];
}
+ public boolean eachBlock(Teamc team, float range, Boolf pred, Cons cons){
+ return eachBlock(team.team(), team.getX(), team.getY(), range, pred, cons);
+ }
+
+ public boolean eachBlock(Team team, float wx, float wy, float range, Boolf pred, Cons cons){
+ intSet.clear();
+
+ int tx = world.toTile(wx);
+ int ty = world.toTile(wy);
+
+ int tileRange = (int)(range / tilesize + 1);
+ intSet.clear();
+ boolean any = false;
+
+ for(int x = -tileRange + tx; x <= tileRange + tx; x++){
+ for(int y = -tileRange + ty; y <= tileRange + ty; y++){
+ if(!Mathf.within(x * tilesize, y * tilesize, wx, wy, range)) continue;
+
+ Tilec other = world.ent(x, y);
+
+ if(other == null) continue;
+
+ if(other.team() == team && !intSet.contains(other.pos()) && pred.get(other)){
+ cons.get(other);
+ any = true;
+ intSet.add(other.pos());
+ }
+ }
+ }
+
+ return any;
+ }
+
/** Get all enemy blocks with a flag. */
public Array getEnemy(Team team, BlockFlag type){
returnArray.clear();
for(Team enemy : team.enemies()){
if(state.teams.isActive(enemy)){
- ObjectSet set = getFlagged(enemy)[type.ordinal()];
+ TileArray set = getFlagged(enemy)[type.ordinal()];
if(set != null){
for(Tile tile : set){
returnArray.add(tile);
@@ -178,20 +207,20 @@ public class BlockIndexer{
return returnArray;
}
- public void notifyTileDamaged(TileEntity entity){
- if(damagedTiles[(int)entity.getTeam().id] == null){
- damagedTiles[(int)entity.getTeam().id] = new ObjectSet<>();
+ public void notifyTileDamaged(Tilec entity){
+ if(damagedTiles[(int)entity.team().id] == null){
+ damagedTiles[(int)entity.team().id] = new TileArray();
}
- ObjectSet set = damagedTiles[(int)entity.getTeam().id];
- set.add(entity.tile);
+ TileArray set = damagedTiles[(int)entity.team().id];
+ set.add(entity.tile());
}
- public TileEntity findEnemyTile(Team team, float x, float y, float range, Boolf pred){
+ public Tilec findEnemyTile(Team team, float x, float y, float range, Boolf pred){
for(Team enemy : activeTeams){
if(!team.isEnemy(enemy)) continue;
- TileEntity entity = indexer.findTile(enemy, x, y, range, pred, true);
+ Tilec entity = indexer.findTile(enemy, x, y, range, pred, true);
if(entity != null){
return entity;
}
@@ -200,12 +229,12 @@ public class BlockIndexer{
return null;
}
- public TileEntity findTile(Team team, float x, float y, float range, Boolf pred){
+ public Tilec findTile(Team team, float x, float y, float range, Boolf pred){
return findTile(team, x, y, range, pred, false);
}
- public TileEntity findTile(Team team, float x, float y, float range, Boolf pred, boolean usePriority){
- TileEntity closest = null;
+ public Tilec findTile(Team team, float x, float y, float range, Boolf pred, boolean usePriority){
+ Tilec closest = null;
float dst = 0;
float range2 = range*range;
@@ -216,21 +245,19 @@ public class BlockIndexer{
for(int tx = rx * quadrantSize; tx < (rx + 1) * quadrantSize && tx < world.width(); tx++){
for(int ty = ry * quadrantSize; ty < (ry + 1) * quadrantSize && ty < world.height(); ty++){
- Tile other = world.ltile(tx, ty);
+ Tilec e = world.ent(tx, ty);
- if(other == null) continue;
+ if(e == null) continue;
- if(other.entity == null || other.getTeam() != team || !pred.get(other) || !other.block().targetable)
+ if(e.team() != team || !pred.get(e) || !e.block().targetable)
continue;
- TileEntity e = other.entity;
-
- float ndst = Mathf.dst2(x, y, e.x, e.y);
+ float ndst = e.dst2(x, y);
if(ndst < range2 && (closest == null ||
//this one is closer, and it is at least of equal priority
- (ndst < dst && (!usePriority || closest.block.priority.ordinal() <= e.block.priority.ordinal())) ||
+ (ndst < dst && (!usePriority || closest.block().priority.ordinal() <= e.block().priority.ordinal())) ||
//priority is used, and new block has higher priority regardless of range
- (usePriority && closest.block.priority.ordinal() < e.block.priority.ordinal()))){
+ (usePriority && closest.block().priority.ordinal() < e.block().priority.ordinal()))){
dst = ndst;
closest = e;
}
@@ -248,7 +275,7 @@ public class BlockIndexer{
* each tile will at least have an ore within {@link #quadrantSize} / 2 blocks of it.
* Only specific ore types are scanned. See {@link #scanOres}.
*/
- public ObjectSet getOrePositions(Item item){
+ public TileArray getOrePositions(Item item){
return ores.get(item, emptySet);
}
@@ -271,20 +298,22 @@ public class BlockIndexer{
}
private void process(Tile tile){
- if(tile.block().flags.size() > 0 && tile.getTeam() != Team.derelict){
- ObjectSet[] map = getFlagged(tile.getTeam());
+ if(tile.block().flags.size() > 0 && tile.team() != Team.derelict){
+ TileArray[] map = getFlagged(tile.team());
for(BlockFlag flag : tile.block().flags){
- ObjectSet arr = map[flag.ordinal()];
+ TileArray arr = map[flag.ordinal()];
arr.add(tile);
map[flag.ordinal()] = arr;
}
- typeMap.put(tile.pos(), new TileIndex(tile.block().flags, tile.getTeam()));
+ typeMap.put(tile.pos(), new TileIndex(tile.block().flags, tile.team()));
+ }
+ if(!activeTeams.contains(tile.team())){
+ activeTeams.add(tile.team());
}
- activeTeams.add(tile.getTeam());
if(ores == null) return;
@@ -306,7 +335,7 @@ public class BlockIndexer{
//update quadrant at this position
for(Item item : scanOres){
- ObjectSet set = ores.get(item);
+ TileArray set = ores.get(item);
//update quadrant status depending on whether the item is in it
if(!itemSet.contains(item)){
@@ -328,7 +357,7 @@ public class BlockIndexer{
GridBits bits = structQuadrant(team);
//fast-set this quadrant to 'occupied' if the tile just placed is already of this team
- if(tile.getTeam() == team && tile.entity != null && tile.block().targetable){
+ if(tile.team() == team && tile.entity != null && tile.block().targetable){
bits.set(quadrantX, quadrantY);
continue; //no need to process futher
}
@@ -338,9 +367,9 @@ public class BlockIndexer{
outer:
for(int x = quadrantX * quadrantSize; x < world.width() && x < (quadrantX + 1) * quadrantSize; x++){
for(int y = quadrantY * quadrantSize; y < world.height() && y < (quadrantY + 1) * quadrantSize; y++){
- Tile result = world.ltile(x, y);
+ Tilec result = world.ent(x, y);
//when a targetable block is found, mark this quadrant as occupied and stop searching
- if(result.entity != null && result.getTeam() == team){
+ if(result!= null && result.team() == team){
bits.set(quadrantX, quadrantY);
break outer;
}
@@ -366,23 +395,19 @@ public class BlockIndexer{
//initialize ore map with empty sets
for(Item item : scanOres){
- ores.put(item, new ObjectSet<>());
+ ores.put(item, new TileArray());
}
- for(int x = 0; x < world.width(); x++){
- for(int y = 0; y < world.height(); y++){
- int qx = (x / quadrantSize);
- int qy = (y / quadrantSize);
+ for(Tile tile : world.tiles){
+ int qx = (tile.x / quadrantSize);
+ int qy = (tile.y / quadrantSize);
- Tile tile = world.tile(x, y);
-
- //add position of quadrant to list when an ore is found
- if(tile.drop() != null && scanOres.contains(tile.drop()) && tile.block() == Blocks.air){
- ores.get(tile.drop()).add(world.tile(
- //make sure to clamp quadrant middle position, since it might go off bounds
- Mathf.clamp(qx * quadrantSize + quadrantSize / 2, 0, world.width() - 1),
- Mathf.clamp(qy * quadrantSize + quadrantSize / 2, 0, world.height() - 1)));
- }
+ //add position of quadrant to list when an ore is found
+ if(tile.drop() != null && scanOres.contains(tile.drop()) && tile.block() == Blocks.air){
+ ores.get(tile.drop()).add(world.tile(
+ //make sure to clamp quadrant middle position, since it might go off bounds
+ Mathf.clamp(qx * quadrantSize + quadrantSize / 2, 0, world.width() - 1),
+ Mathf.clamp(qy * quadrantSize + quadrantSize / 2, 0, world.height() - 1)));
}
}
}
@@ -396,4 +421,34 @@ public class BlockIndexer{
this.team = team;
}
}
+
+ public static class TileArray implements Iterable{
+ private Array tiles = new Array<>(false, 16);
+ private IntSet contained = new IntSet();
+
+ public void add(Tile tile){
+ if(contained.add(tile.pos())){
+ tiles.add(tile);
+ }
+ }
+
+ public void remove(Tile tile){
+ if(contained.remove(tile.pos())){
+ tiles.remove(tile);
+ }
+ }
+
+ public int size(){
+ return tiles.size;
+ }
+
+ public Tile first(){
+ return tiles.first();
+ }
+
+ @Override
+ public Iterator iterator(){
+ return tiles.iterator();
+ }
+ }
}
diff --git a/core/src/mindustry/ai/NewBlockIndexer.java b/core/src/mindustry/ai/NewBlockIndexer.java
new file mode 100644
index 0000000000..bd1dc00f78
--- /dev/null
+++ b/core/src/mindustry/ai/NewBlockIndexer.java
@@ -0,0 +1,50 @@
+package mindustry.ai;
+
+//new indexer implementation, uses quadtrees
+public class NewBlockIndexer{
+
+ /*
+ public ObjectSet getOrePositions(Item item){
+
+ }
+
+ public Tile findClosestOre(float xp, float yp, Item item){
+
+ }
+
+ public ObjectSet getDamaged(Team team){
+
+ }
+
+ public ObjectSet getAllied(Team team, BlockFlag type){
+
+ }
+
+ public boolean eachBlock(Teamc team, float range, Boolf pred, Cons cons){
+ return eachBlock(team.team(), team.getX(), team.getY(), range, pred, cons);
+ }
+
+ public boolean eachBlock(Team team, float wx, float wy, float range, Boolf pred, Cons cons){
+
+ }
+
+ public Array getEnemy(Team team, BlockFlag type){
+
+ }
+
+ public void notifyTileDamaged(Tilec entity){
+
+ }
+
+ public Tilec findEnemyTile(Team team, float x, float y, float range, Boolf pred){
+
+ }
+
+ public Tilec findTile(Team team, float x, float y, float range, Boolf pred, boolean usePriority){
+
+ }
+
+ public Tilec findTile(Team team, float x, float y, float range, Boolf pred){
+ return findTile(team, x, y, range, pred, false);
+ }*/
+}
diff --git a/core/src/mindustry/ai/Pathfinder.java b/core/src/mindustry/ai/Pathfinder.java
index b40e3543da..10b3cd2bee 100644
--- a/core/src/mindustry/ai/Pathfinder.java
+++ b/core/src/mindustry/ai/Pathfinder.java
@@ -1,13 +1,13 @@
package mindustry.ai;
import arc.*;
-import mindustry.annotations.Annotations.*;
-import arc.struct.*;
import arc.func.*;
import arc.math.geom.*;
-import arc.util.*;
+import arc.struct.*;
import arc.util.ArcAnnotate.*;
+import arc.util.*;
import arc.util.async.*;
+import mindustry.annotations.Annotations.*;
import mindustry.game.EventType.*;
import mindustry.game.*;
import mindustry.gen.*;
@@ -45,10 +45,8 @@ public class Pathfinder implements Runnable{
created = new GridBits(Team.all().length, PathTarget.all.length);
list = new Array<>();
- for(int x = 0; x < world.width(); x++){
- for(int y = 0; y < world.height(); y++){
- tiles[x][y] = packTile(world.rawTile(x, y));
- }
+ for(Tile tile : world.tiles){
+ tiles[tile.x][tile.y] = packTile(tile);
}
//special preset which may help speed things up; this is optional
@@ -218,7 +216,7 @@ public class Pathfinder implements Runnable{
//add targets
for(int i = 0; i < path.targets.size; i++){
int pos = path.targets.get(i);
- int tx = Pos.x(pos), ty = Pos.y(pos);
+ int tx = Point2.x(pos), ty = Point2.y(pos);
path.weights[tx][ty] = 0;
path.searches[tx][ty] = (short)path.search;
@@ -255,7 +253,7 @@ public class Pathfinder implements Runnable{
//add targets
for(int i = 0; i < path.targets.size; i++){
int pos = path.targets.get(i);
- path.weights[Pos.x(pos)][Pos.y(pos)] = 0;
+ path.weights[Point2.x(pos)][Point2.y(pos)] = 0;
path.frontier.addFirst(pos);
}
@@ -285,7 +283,7 @@ public class Pathfinder implements Runnable{
if(other != null && (path.weights[dx][dy] > cost + other.cost || path.searches[dx][dy] < path.search) && passable(dx, dy, path.team)){
if(other.cost < 0) throw new IllegalArgumentException("Tile cost cannot be negative! " + other);
- path.frontier.addFirst(Pos.get(dx, dy));
+ path.frontier.addFirst(Point2.pack(dx, dy));
path.weights[dx][dy] = cost + other.cost;
path.searches[dx][dy] = (short)path.search;
}
@@ -303,7 +301,7 @@ public class Pathfinder implements Runnable{
//spawn points are also enemies.
if(state.rules.waves && team == state.rules.defaultTeam){
- for(Tile other : spawner.getGroundSpawns()){
+ for(Tile other : spawner.getSpawns()){
out.add(other.pos());
}
}
diff --git a/core/src/mindustry/ai/WaveSpawner.java b/core/src/mindustry/ai/WaveSpawner.java
index d011ce8dd8..f30fbadefb 100644
--- a/core/src/mindustry/ai/WaveSpawner.java
+++ b/core/src/mindustry/ai/WaveSpawner.java
@@ -1,28 +1,23 @@
package mindustry.ai;
-import arc.Events;
-import arc.struct.Array;
-import arc.func.Floatc2;
-import arc.math.Angles;
-import arc.math.Mathf;
-import arc.util.Time;
-import arc.util.Tmp;
-import mindustry.content.Blocks;
-import mindustry.content.Fx;
-import mindustry.entities.Damage;
-import mindustry.entities.Effects;
-import mindustry.entities.type.*;
-import mindustry.game.EventType.WorldLoadEvent;
-import mindustry.game.SpawnGroup;
-import mindustry.world.Tile;
+import arc.*;
+import arc.func.*;
+import arc.math.*;
+import arc.struct.*;
+import arc.util.*;
+import mindustry.content.*;
+import mindustry.entities.*;
+import mindustry.game.EventType.*;
+import mindustry.game.*;
+import mindustry.gen.*;
+import mindustry.world.*;
import static mindustry.Vars.*;
public class WaveSpawner{
private static final float margin = 40f, coreMargin = tilesize * 3; //how far away from the edge flying units spawn
- private Array flySpawns = new Array<>();
- private Array groundSpawns = new Array<>();
+ private Array spawns = new Array<>();
private boolean spawning = false;
public WaveSpawner(){
@@ -30,16 +25,16 @@ public class WaveSpawner{
}
public int countSpawns(){
- return groundSpawns.size;
+ return spawns.size;
}
- public Array getGroundSpawns(){
- return groundSpawns;
+ public Array getSpawns(){
+ return spawns;
}
/** @return true if the player is near a ground spawn point. */
public boolean playerNear(){
- return groundSpawns.contains(g -> Mathf.dst(g.x * tilesize, g.y * tilesize, player.x, player.y) < state.rules.dropZoneRadius && player.getTeam() != state.rules.waveTeam);
+ return !player.dead() && spawns.contains(g -> Mathf.dst(g.x * tilesize, g.y * tilesize, player.x(), player.y()) < state.rules.dropZoneRadius && player.team() != state.rules.waveTeam);
}
public void spawnEnemies(){
@@ -53,7 +48,7 @@ public class WaveSpawner{
eachFlyerSpawn((spawnX, spawnY) -> {
for(int i = 0; i < spawned; i++){
- BaseUnit unit = group.createUnit(state.rules.waveTeam);
+ Unitc unit = group.createUnit(state.rules.waveTeam);
unit.set(spawnX + Mathf.range(spread), spawnY + Mathf.range(spread));
unit.add();
}
@@ -66,9 +61,8 @@ public class WaveSpawner{
for(int i = 0; i < spawned; i++){
Tmp.v1.rnd(spread);
- BaseUnit unit = group.createUnit(state.rules.waveTeam);
+ Unitc unit = group.createUnit(state.rules.waveTeam);
unit.set(spawnX + Tmp.v1.x, spawnY + Tmp.v1.y);
-
Time.run(Math.min(i * 5, 60 * 2), () -> spawnEffect(unit));
}
});
@@ -77,7 +71,7 @@ public class WaveSpawner{
eachGroundSpawn((spawnX, spawnY, doShockwave) -> {
if(doShockwave){
- Time.run(20f, () -> Effects.effect(Fx.spawnShockwave, spawnX, spawnY, state.rules.dropZoneRadius));
+ Time.run(20f, () -> Fx.spawnShockwave.at(spawnX, spawnY, state.rules.dropZoneRadius));
Time.run(40f, () -> Damage.damage(state.rules.waveTeam, spawnX, spawnY, state.rules.dropZoneRadius, 99999999f, true));
}
});
@@ -86,30 +80,32 @@ public class WaveSpawner{
}
private void eachGroundSpawn(SpawnConsumer cons){
- for(Tile spawn : groundSpawns){
+ for(Tile spawn : spawns){
cons.accept(spawn.worldx(), spawn.worldy(), true);
}
if(state.rules.attackMode && state.teams.isActive(state.rules.waveTeam) && !state.teams.playerCores().isEmpty()){
- TileEntity firstCore = state.teams.playerCores().first();
- for(TileEntity core : state.rules.waveTeam.cores()){
- Tmp.v1.set(firstCore).sub(core.x, core.y).limit(coreMargin + core.block.size*tilesize);
- cons.accept(core.x + Tmp.v1.x, core.y + Tmp.v1.y, false);
+ Tilec firstCore = state.teams.playerCores().first();
+ for(Tilec core : state.rules.waveTeam.cores()){
+ Tmp.v1.set(firstCore).sub(core).limit(coreMargin + core.block().size*tilesize);
+ cons.accept(core.x() + Tmp.v1.x, core.y() + Tmp.v1.y, false);
}
}
}
private void eachFlyerSpawn(Floatc2 cons){
- for(FlyerSpawn spawn : flySpawns){
- float trns = (world.width() + world.height()) * tilesize;
- float spawnX = Mathf.clamp(world.width() * tilesize / 2f + Angles.trnsx(spawn.angle, trns), -margin, world.width() * tilesize + margin);
- float spawnY = Mathf.clamp(world.height() * tilesize / 2f + Angles.trnsy(spawn.angle, trns), -margin, world.height() * tilesize + margin);
+ for(Tile tile : spawns){
+ float angle = Angles.angle(tile.x, tile.y, world.width()/2, world.height()/2);
+
+ float trns = Math.max(world.width(), world.height()) * Mathf.sqrt2 * tilesize;
+ float spawnX = Mathf.clamp(world.width() * tilesize / 2f + Angles.trnsx(angle, trns), -margin, world.width() * tilesize + margin);
+ float spawnY = Mathf.clamp(world.height() * tilesize / 2f + Angles.trnsy(angle, trns), -margin, world.height() * tilesize + margin);
cons.get(spawnX, spawnY);
}
if(state.rules.attackMode && state.teams.isActive(state.rules.waveTeam)){
- for(TileEntity core : state.teams.get(state.rules.waveTeam).cores){
- cons.get(core.x, core.y);
+ for(Tilec core : state.teams.get(state.rules.waveTeam).cores){
+ cons.get(core.x(), core.y());
}
}
}
@@ -119,41 +115,24 @@ public class WaveSpawner{
}
private void reset(){
+ spawns.clear();
- flySpawns.clear();
- groundSpawns.clear();
-
- for(int x = 0; x < world.width(); x++){
- for(int y = 0; y < world.height(); y++){
-
- if(world.tile(x, y).overlay() == Blocks.spawn){
- addSpawns(x, y);
- }
+ for(Tile tile : world.tiles){
+ if(tile.overlay() == Blocks.spawn){
+ spawns.add(tile);
}
}
}
- private void addSpawns(int x, int y){
- groundSpawns.add(world.tile(x, y));
-
- FlyerSpawn fspawn = new FlyerSpawn();
- fspawn.angle = Angles.angle(world.width() / 2f, world.height() / 2f, x, y);
- flySpawns.add(fspawn);
- }
-
- private void spawnEffect(BaseUnit unit){
- Effects.effect(Fx.unitSpawn, unit.x, unit.y, 0f, unit);
+ private void spawnEffect(Unitc unit){
+ Fx.unitSpawn.at(unit.x(), unit.y(), 0f, unit);
Time.run(30f, () -> {
unit.add();
- Effects.effect(Fx.spawn, unit);
+ Fx.spawn.at(unit);
});
}
private interface SpawnConsumer{
void accept(float x, float y, boolean shockwave);
}
-
- private class FlyerSpawn{
- float angle;
- }
}
diff --git a/core/src/mindustry/ai/types/FlyingAI.java b/core/src/mindustry/ai/types/FlyingAI.java
new file mode 100644
index 0000000000..b6b3a841de
--- /dev/null
+++ b/core/src/mindustry/ai/types/FlyingAI.java
@@ -0,0 +1,102 @@
+package mindustry.ai.types;
+
+import arc.math.*;
+import arc.math.geom.*;
+import arc.util.*;
+import mindustry.*;
+import mindustry.entities.*;
+import mindustry.entities.units.*;
+import mindustry.world.meta.*;
+
+public class FlyingAI extends AIController{
+
+ @Override
+ public void update(){
+ unit.rotation(unit.vel().angle());
+
+ if(unit.isFlying()){
+ unit.wobble();
+ }
+
+ if(Units.invalidateTarget(target, unit.team(), unit.x(), unit.y())){
+ target = null;
+ }
+
+ if(retarget()){
+ targetClosest();
+
+ if(target == null) targetClosestEnemyFlag(BlockFlag.producer);
+ if(target == null) targetClosestEnemyFlag(BlockFlag.turret);
+ }
+
+ boolean shoot = false;
+
+ if(target != null){
+ attack(80f);
+
+ shoot = unit.inRange(target);
+
+ if(shoot && unit.type().hasWeapons()){
+ Vec2 to = Predict.intercept(unit, target, unit.type().weapons.first().bullet.speed);
+ unit.aim(to);
+ }
+ }else{
+ target = unit.closestCore();
+ moveTo(Vars.state.rules.dropZoneRadius + 120f);
+ }
+
+ unit.controlWeapons(shoot, shoot);
+ }
+
+ protected void circle(float circleLength){
+ circle(circleLength, unit.type().speed);
+ }
+
+ protected void circle(float circleLength, float speed){
+ if(target == null) return;
+
+ vec.set(target).sub(unit);
+
+ if(vec.len() < circleLength){
+ vec.rotate((circleLength - vec.len()) / circleLength * 180f);
+ }
+
+ vec.setLength(speed * Time.delta());
+
+ unit.moveAt(vec);
+ }
+
+ protected void moveTo(float circleLength){
+ if(target == null) return;
+
+ vec.set(target).sub(unit);
+
+ float length = circleLength <= 0.001f ? 1f : Mathf.clamp((unit.dst(target) - circleLength) / 100f, -1f, 1f);
+
+ vec.setLength(unit.type().speed * Time.delta() * length);
+ if(length < -0.5f){
+ vec.rotate(180f);
+ }else if(length < 0){
+ vec.setZero();
+ }
+
+ unit.moveAt(vec);
+ }
+
+ protected void attack(float circleLength){
+ vec.set(target).sub(unit);
+
+ float ang = unit.angleTo(target);
+ float diff = Angles.angleDist(ang, unit.rotation());
+
+ if(diff > 100f && vec.len() < circleLength){
+ vec.setAngle(unit.vel().angle());
+ }else{
+ vec.setAngle(Mathf.slerpDelta(unit.vel().angle(), vec.angle(), 0.6f));
+ }
+
+ vec.setLength(unit.type().speed * Time.delta());
+
+ unit.moveAt(vec);
+ }
+}
diff --git a/core/src/mindustry/ai/types/GroundAI.java b/core/src/mindustry/ai/types/GroundAI.java
new file mode 100644
index 0000000000..2e295bd68b
--- /dev/null
+++ b/core/src/mindustry/ai/types/GroundAI.java
@@ -0,0 +1,95 @@
+package mindustry.ai.types;
+
+import arc.util.*;
+import mindustry.ai.Pathfinder.*;
+import mindustry.entities.*;
+import mindustry.entities.units.*;
+import mindustry.game.*;
+import mindustry.gen.*;
+import mindustry.world.*;
+
+import static mindustry.Vars.pathfinder;
+
+public class GroundAI extends AIController{
+
+ @Override
+ public void update(){
+ if(Units.invalidateTarget(target, unit.team(), unit.x(), unit.y(), Float.MAX_VALUE)){
+ target = null;
+
+ //TODO this is hacky, cleanup
+ if(unit instanceof Legsc){
+ unit.lookAt(((Legsc)unit).baseRotation());
+ }
+ }
+
+ if(retarget()){
+ targetClosest();
+ }
+
+ Tilec core = unit.closestEnemyCore();
+
+ if(core == null) return;
+
+ float dst = unit.dst(core);
+
+ if(dst < unit.range() / 1.1f){
+ target = core;
+ }
+
+ if(dst > unit.range() * 0.5f){
+ moveToCore(PathTarget.enemyCores);
+ }
+
+ boolean rotate = false, shoot = false;
+
+ if(!Units.invalidateTarget(target, unit, unit.range())){
+ rotate = true;
+ shoot = unit.within(target, unit.range());
+
+ if(unit.type().hasWeapons()){
+ unit.aimLook(Predict.intercept(unit, target, unit.type().weapons.first().bullet.speed));
+ }
+ }
+
+ unit.controlWeapons(rotate, shoot);
+ }
+
+ protected void moveToCore(PathTarget path){
+ Tile tile = unit.tileOn();
+ if(tile == null) return;
+ Tile targetTile = pathfinder.getTargetTile(tile, unit.team(), path);
+
+ if(tile == targetTile) return;
+
+ unit.moveAt(vec.trns(unit.angleTo(targetTile), unit.type().speed * Time.delta()));
+ }
+
+ protected void moveAwayFromCore(){
+ Team enemy = null;
+ for(Team team : unit.team().enemies()){
+ if(team.active()){
+ enemy = team;
+ break;
+ }
+ }
+
+ if(enemy == null){
+ for(Team team : unit.team().enemies()){
+ enemy = team;
+ break;
+ }
+ }
+
+ if(enemy == null) return;
+
+ Tile tile = unit.tileOn();
+ if(tile == null) return;
+ Tile targetTile = pathfinder.getTargetTile(tile, enemy, PathTarget.enemyCores);
+ Tilec core = unit.closestCore();
+
+ if(tile == targetTile || core == null || unit.within(core, 120f)) return;
+
+ unit.moveAt(vec.trns(unit.angleTo(targetTile), unit.type().speed * Time.delta()));
+ }
+}
diff --git a/core/src/mindustry/ai/types/MimicAI.java b/core/src/mindustry/ai/types/MimicAI.java
new file mode 100644
index 0000000000..6e4ea74ca3
--- /dev/null
+++ b/core/src/mindustry/ai/types/MimicAI.java
@@ -0,0 +1,31 @@
+package mindustry.ai.types;
+
+import arc.util.ArcAnnotate.*;
+import arc.util.*;
+import mindustry.entities.units.*;
+import mindustry.gen.*;
+
+public class MimicAI extends AIController{
+ public @Nullable Unitc control;
+
+ public MimicAI(@Nullable Unitc control){
+ this.control = control;
+ }
+
+ public MimicAI(){
+ }
+
+ @Override
+ public void update(){
+ if(control != null){
+ unit.controlWeapons(control.isRotate(), control.isShooting());
+ //TODO this isn't accurate
+ unit.moveAt(Tmp.v1.set(control.vel()).limit(unit.type().speed));
+ if(control.isShooting()){
+ unit.aimLook(control.aimX(), control.aimY());
+ }else{
+ unit.lookAt(unit.vel().angle());
+ }
+ }
+ }
+}
diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java
index 2dcaa95d2c..b191eb9757 100644
--- a/core/src/mindustry/content/Blocks.java
+++ b/core/src/mindustry/content/Blocks.java
@@ -1,7 +1,6 @@
package mindustry.content;
import arc.*;
-import arc.struct.*;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.math.*;
@@ -10,7 +9,6 @@ import mindustry.*;
import mindustry.ctype.*;
import mindustry.entities.*;
import mindustry.entities.bullet.*;
-import mindustry.entities.type.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.type.*;
@@ -19,6 +17,8 @@ import mindustry.world.blocks.*;
import mindustry.world.blocks.defense.*;
import mindustry.world.blocks.defense.turrets.*;
import mindustry.world.blocks.distribution.*;
+import mindustry.world.blocks.environment.*;
+import mindustry.world.blocks.legacy.*;
import mindustry.world.blocks.liquid.*;
import mindustry.world.blocks.logic.*;
import mindustry.world.blocks.power.*;
@@ -28,13 +28,12 @@ import mindustry.world.blocks.storage.*;
import mindustry.world.blocks.units.*;
import mindustry.world.consumers.*;
import mindustry.world.meta.*;
-import mindustry.world.modules.*;
public class Blocks implements ContentList{
public static Block
//environment
- air, spawn, deepwater, water, taintedWater, tar, stone, craters, charr, sand, darksand, ice, snow, darksandTaintedWater,
+ air, spawn, cliff, deepwater, water, taintedWater, tar, slag, stone, craters, charr, sand, darksand, ice, snow, darksandTaintedWater,
holostone, rocks, sporerocks, icerocks, cliffs, sporePine, snowPine, pine, shrubs, whiteTree, whiteTreeDead, sporeCluster,
iceSnow, sandWater, darksandWater, duneRocks, sandRocks, moss, sporeMoss, shale, shaleRocks, shaleBoulder, sandBoulder, grass, salt,
metalFloor, metalFloorDamaged, metalFloor2, metalFloor3, metalFloor5, ignarock, magmarock, hotrock, snowrocks, rock, snowrock, saltRocks,
@@ -57,7 +56,8 @@ public class Blocks implements ContentList{
scrapWall, scrapWallLarge, scrapWallHuge, scrapWallGigantic, thruster, //ok, these names are getting ridiculous, but at least I don't have humongous walls yet
//transport
- conveyor, titaniumConveyor, plastaniumConveyor, armoredConveyor, distributor, junction, itemBridge, phaseConveyor, sorter, invertedSorter, router, overflowGate, underflowGate, massDriver,
+ conveyor, titaniumConveyor, plastaniumConveyor, armoredConveyor, distributor, junction, itemBridge, phaseConveyor, sorter, invertedSorter, router,
+ overflowGate, underflowGate, massDriver, massConveyor,
//liquid
mechanicalPump, rotaryPump, thermalPump, conduit, pulseConduit, platedConduit, liquidRouter, liquidTank, liquidJunction, bridgeConduit, phaseConduit,
@@ -76,11 +76,9 @@ public class Blocks implements ContentList{
duo, scatter, scorch, hail, arc, wave, lancer, swarmer, salvo, fuse, ripple, cyclone, spectre, meltdown,
//units
- commandCenter, draugFactory, spiritFactory, phantomFactory, wraithFactory, ghoulFactory, revenantFactory, daggerFactory, crawlerFactory, titanFactory,
- fortressFactory, repairPoint,
+ groundFactory, repairPoint
- //upgrades
- dartPad, deltaPad, tauPad, omegaPad, javelinPad, tridentPad, glaivePad;
+ ;
@Override
public void load(){
@@ -92,7 +90,7 @@ public class Blocks implements ContentList{
hasShadow = false;
}
- public void draw(Tile tile){}
+ public void drawBase(Tile tile){}
public void load(){}
public void init(){}
public boolean isHidden(){
@@ -107,23 +105,16 @@ public class Blocks implements ContentList{
}
};
- //create special blockpart variants
- for(int dx = 0; dx < BlockPart.maxSize; dx++){
- for(int dy = 0; dy < BlockPart.maxSize; dy++){
- int fx = dx - BlockPart.maxSize/2, fy = dy - BlockPart.maxSize/2;
- if(fx != 0 || fy != 0){
- new BlockPart(fx, fy);
- }
- }
- }
-
spawn = new OverlayFloor("spawn"){
{
variants = 0;
}
- public void draw(Tile tile){}
+ @Override
+ public void drawBase(Tile tile){}
};
+ cliff = new Cliff("cliff");
+
//Registers build blocks
//no reference is needed here since they can be looked up by name later
for(int i = 1; i <= BuildBlock.maxSize; i++){
@@ -139,6 +130,7 @@ public class Blocks implements ContentList{
statusDuration = 120f;
drownTime = 140f;
cacheLayer = CacheLayer.water;
+ albedo = 0.5f;
}};
water = new Floor("water"){{
@@ -149,6 +141,7 @@ public class Blocks implements ContentList{
liquidDrop = Liquids.water;
isLiquid = true;
cacheLayer = CacheLayer.water;
+ albedo = 0.5f;
}};
taintedWater = new Floor("tainted-water"){{
@@ -160,36 +153,25 @@ public class Blocks implements ContentList{
liquidDrop = Liquids.water;
isLiquid = true;
cacheLayer = CacheLayer.water;
+ albedo = 0.5f;
}};
- darksandTaintedWater = new Floor("darksand-tainted-water"){{
+ darksandTaintedWater = new ShallowLiquid("darksand-tainted-water"){{
speedMultiplier = 0.75f;
- variants = 0;
- status = StatusEffects.wet;
statusDuration = 60f;
- liquidDrop = Liquids.water;
- isLiquid = true;
- cacheLayer = CacheLayer.water;
+ albedo = 0.5f;
}};
- sandWater = new Floor("sand-water"){{
+ sandWater = new ShallowLiquid("sand-water"){{
speedMultiplier = 0.8f;
- variants = 0;
- status = StatusEffects.wet;
statusDuration = 50f;
- liquidDrop = Liquids.water;
- isLiquid = true;
- cacheLayer = CacheLayer.water;
+ albedo = 0.5f;
}};
- darksandWater = new Floor("darksand-water"){{
+ darksandWater = new ShallowLiquid("darksand-water"){{
speedMultiplier = 0.8f;
- variants = 0;
- status = StatusEffects.wet;
statusDuration = 50f;
- liquidDrop = Liquids.water;
- isLiquid = true;
- cacheLayer = CacheLayer.water;
+ albedo = 0.5f;
}};
tar = new Floor("tar"){{
@@ -203,6 +185,17 @@ public class Blocks implements ContentList{
cacheLayer = CacheLayer.tar;
}};
+ slag = new Floor("slag"){{
+ drownTime = 150f;
+ status = StatusEffects.melting;
+ statusDuration = 240f;
+ speedMultiplier = 0.19f;
+ variants = 0;
+ liquidDrop = Liquids.slag;
+ isLiquid = true;
+ cacheLayer = CacheLayer.slag;
+ }};
+
stone = new Floor("stone"){{
}};
@@ -217,16 +210,18 @@ public class Blocks implements ContentList{
}};
ignarock = new Floor("ignarock"){{
-
+ attributes.set(Attribute.water, -0.1f);
}};
hotrock = new Floor("hotrock"){{
attributes.set(Attribute.heat, 0.5f);
+ attributes.set(Attribute.water, -0.2f);
blendGroup = ignarock;
}};
magmarock = new Floor("magmarock"){{
attributes.set(Attribute.heat, 0.75f);
+ attributes.set(Attribute.water, -0.5f);
updateEffect = Fx.magmasmoke;
blendGroup = ignarock;
}};
@@ -241,6 +236,10 @@ public class Blocks implements ContentList{
playerUnmineable = true;
}};
+ ((ShallowLiquid)darksandTaintedWater).set(Blocks.taintedWater, Blocks.darksand);
+ ((ShallowLiquid)sandWater).set(Blocks.water, Blocks.sand);
+ ((ShallowLiquid)darksandWater).set(Blocks.water, Blocks.darksand);
+
holostone = new Floor("holostone"){{
}};
@@ -251,6 +250,7 @@ public class Blocks implements ContentList{
salt = new Floor("salt"){{
variants = 0;
+ attributes.set(Attribute.water, -0.2f);
}};
snow = new Floor("snow"){{
@@ -258,13 +258,13 @@ public class Blocks implements ContentList{
}};
ice = new Floor("ice"){{
- //TODO fix drag/speed
- dragMultiplier = 1f;
- speedMultiplier = 1f;
+ dragMultiplier = 0.35f;
+ speedMultiplier = 0.9f;
attributes.set(Attribute.water, 0.4f);
}};
iceSnow = new Floor("ice-snow"){{
+ dragMultiplier = 0.6f;
variants = 3;
attributes.set(Attribute.water, 0.3f);
}};
@@ -292,6 +292,7 @@ public class Blocks implements ContentList{
icerocks = new StaticWall("icerocks"){{
variants = 2;
+ iceSnow.asFloor().wall = this;
}};
snowrocks = new StaticWall("snowrocks"){{
@@ -355,11 +356,13 @@ public class Blocks implements ContentList{
moss = new Floor("moss"){{
variants = 3;
attributes.set(Attribute.spores, 0.15f);
+ wall = sporePine;
}};
sporeMoss = new Floor("spore-moss"){{
variants = 3;
attributes.set(Attribute.spores, 0.3f);
+ wall = sporerocks;
}};
metalFloor = new Floor("metal-floor"){{
@@ -506,13 +509,10 @@ public class Blocks implements ContentList{
int topRegion = reg("-top");
- drawer = tile -> {
- Draw.rect(region, tile.drawx(), tile.drawy());
-
- GenericCrafterEntity entity = tile.ent();
-
+ drawer = entity -> {
+ Draw.rect(region, entity.x(), entity.y());
Draw.alpha(Mathf.absin(entity.totalProgress, 3f, 0.9f) * entity.warmup);
- Draw.rect(reg(topRegion), tile.drawx(), tile.drawy());
+ Draw.rect(reg(topRegion), entity.x(), entity.y());
Draw.reset();
};
}};
@@ -533,24 +533,22 @@ public class Blocks implements ContentList{
drawIcons = () -> new TextureRegion[]{Core.atlas.find(name + "-bottom"), Core.atlas.find(name), Core.atlas.find(name + "-weave")};
- drawer = tile -> {
- GenericCrafterEntity entity = tile.ent();
-
- Draw.rect(reg(bottomRegion), tile.drawx(), tile.drawy());
- Draw.rect(reg(weaveRegion), tile.drawx(), tile.drawy(), entity.totalProgress);
+ drawer = entity -> {
+ Draw.rect(reg(bottomRegion), entity.x(), entity.y());
+ Draw.rect(reg(weaveRegion), entity.x(), entity.y(), entity.totalProgress);
Draw.color(Pal.accent);
Draw.alpha(entity.warmup);
Lines.lineAngleCenter(
- tile.drawx() + Mathf.sin(entity.totalProgress, 6f, Vars.tilesize / 3f * size),
- tile.drawy(),
+ entity.x() + Mathf.sin(entity.totalProgress, 6f, Vars.tilesize / 3f * size),
+ entity.y(),
90,
size * Vars.tilesize / 2f);
Draw.reset();
- Draw.rect(region, tile.drawx(), tile.drawy());
+ Draw.rect(region, entity.x(), entity.y());
};
}};
@@ -586,21 +584,19 @@ public class Blocks implements ContentList{
drawIcons = () -> new TextureRegion[]{Core.atlas.find(name + "-bottom"), Core.atlas.find(name + "-top")};
- drawer = tile -> {
- LiquidModule mod = tile.entity.liquids;
+ drawer = entity -> {
+ int rotation = rotate ? entity.rotation() * 90 : 0;
- int rotation = rotate ? tile.rotation() * 90 : 0;
+ Draw.rect(reg(bottomRegion), entity.x(), entity.y(), rotation);
- Draw.rect(reg(bottomRegion), tile.drawx(), tile.drawy(), rotation);
-
- if(mod.total() > 0.001f){
+ if(entity.liquids().total() > 0.001f){
Draw.color(outputLiquid.liquid.color);
- Draw.alpha(mod.get(outputLiquid.liquid) / liquidCapacity);
- Draw.rect(reg(liquidRegion), tile.drawx(), tile.drawy(), rotation);
+ Draw.alpha(entity.liquids().get(outputLiquid.liquid) / liquidCapacity);
+ Draw.rect(reg(liquidRegion), entity.x(), entity.y(), rotation);
Draw.color();
}
- Draw.rect(reg(topRegion), tile.drawx(), tile.drawy(), rotation);
+ Draw.rect(reg(topRegion), entity.x(), entity.y(), rotation);
};
}};
@@ -678,15 +674,13 @@ public class Blocks implements ContentList{
int topRegion = reg("-top");
drawIcons = () -> new TextureRegion[]{Core.atlas.find(name), Core.atlas.find(name + "-top")};
- drawer = tile -> {
- GenericCrafterEntity entity = tile.ent();
-
- Draw.rect(region, tile.drawx(), tile.drawy());
- Draw.rect(reg(frameRegions[(int)Mathf.absin(entity.totalProgress, 5f, 2.999f)]), tile.drawx(), tile.drawy());
- Draw.color(Color.clear, tile.entity.liquids.current().color, tile.entity.liquids.total() / liquidCapacity);
- Draw.rect(reg(liquidRegion), tile.drawx(), tile.drawy());
+ drawer = entity -> {
+ Draw.rect(region, entity.x(), entity.y());
+ Draw.rect(reg(frameRegions[(int)Mathf.absin(entity.totalProgress, 5f, 2.999f)]), entity.x(), entity.y());
+ Draw.color(Color.clear, entity.liquids().current().color, entity.liquids().total() / liquidCapacity);
+ Draw.rect(reg(liquidRegion), entity.x(), entity.y());
Draw.color();
- Draw.rect(reg(topRegion), tile.drawx(), tile.drawy());
+ Draw.rect(reg(topRegion), entity.x(), entity.y());
};
}};
@@ -705,11 +699,9 @@ public class Blocks implements ContentList{
drawIcons = () -> new TextureRegion[]{Core.atlas.find(name), Core.atlas.find(name + "-rotator")};
- drawer = tile -> {
- GenericCrafterEntity entity = tile.ent();
-
- Draw.rect(region, tile.drawx(), tile.drawy());
- Draw.rect(reg(rotatorRegion), tile.drawx(), tile.drawy(), entity.totalProgress * 2f);
+ drawer = entity -> {
+ Draw.rect(region, entity.x(), entity.y());
+ Draw.rect(reg(rotatorRegion), entity.x(), entity.y(), entity.totalProgress * 2f);
};
}};
@@ -990,6 +982,10 @@ public class Blocks implements ContentList{
consumes.power(1.75f);
}};
+ massConveyor = new MassConveyor("mass-conveyor"){{
+ requirements(Category.distribution, ItemStack.with(Items.copper, 1));
+ }};
+
//endregion
//region liquid
@@ -1040,7 +1036,7 @@ public class Blocks implements ContentList{
liquidCapacity = 20f;
}};
- liquidTank = new LiquidTank("liquid-tank"){{
+ liquidTank = new LiquidRouter("liquid-tank"){{
requirements(Category.liquid, ItemStack.with(Items.titanium, 25, Items.metaglass, 25));
size = 3;
liquidCapacity = 1500f;
@@ -1297,13 +1293,13 @@ public class Blocks implements ContentList{
size = 5;
}};
- vault = new Vault("vault"){{
+ vault = new StorageBlock("vault"){{
requirements(Category.effect, ItemStack.with(Items.titanium, 250, Items.thorium, 125));
size = 3;
itemCapacity = 1000;
}};
- container = new Vault("container"){{
+ container = new StorageBlock("container"){{
requirements(Category.effect, ItemStack.with(Items.titanium, 100));
size = 2;
itemCapacity = 300;
@@ -1336,7 +1332,7 @@ public class Blocks implements ContentList{
//endregion
//region turrets
- duo = new DoubleTurret("duo"){{
+ duo = new ItemTurret("duo"){{
requirements(Category.turret, ItemStack.with(Items.copper, 35), true);
ammo(
Items.copper, Bullets.standardCopper,
@@ -1344,7 +1340,11 @@ public class Blocks implements ContentList{
Items.pyratite, Bullets.standardIncendiary,
Items.silicon, Bullets.standardHoming
);
- reload = 20f;
+
+ spread = 4f;
+ shots = 2;
+ alternate = true;
+ reloadTime = 20f;
restitution = 0.03f;
range = 100;
shootCone = 15f;
@@ -1361,14 +1361,14 @@ public class Blocks implements ContentList{
Items.lead, Bullets.flakLead,
Items.metaglass, Bullets.flakGlass
);
- reload = 18f;
+ reloadTime = 18f;
range = 170f;
size = 2;
burstSpacing = 5f;
shots = 2;
targetGround = false;
- recoil = 2f;
+ recoilAmount = 2f;
rotatespeed = 15f;
inaccuracy = 17f;
shootCone = 35f;
@@ -1383,8 +1383,8 @@ public class Blocks implements ContentList{
Items.coal, Bullets.basicFlame,
Items.pyratite, Bullets.pyraFlame
);
- recoil = 0f;
- reload = 5f;
+ recoilAmount = 0f;
+ reloadTime = 5f;
coolantMultiplier = 2f;
range = 60f;
shootCone = 50f;
@@ -1401,8 +1401,8 @@ public class Blocks implements ContentList{
Items.silicon, Bullets.artilleryHoming,
Items.pyratite, Bullets.artilleryIncendiary
);
- reload = 60f;
- recoil = 2f;
+ reloadTime = 60f;
+ recoilAmount = 2f;
range = 230f;
inaccuracy = 1f;
shootCone = 10f;
@@ -1419,8 +1419,8 @@ public class Blocks implements ContentList{
Liquids.oil, Bullets.oilShot
);
size = 2;
- recoil = 0f;
- reload = 2f;
+ recoilAmount = 0f;
+ reloadTime = 2f;
inaccuracy = 5f;
shootCone = 50f;
shootEffect = Fx.shootLiquid;
@@ -1436,8 +1436,8 @@ public class Blocks implements ContentList{
chargeMaxDelay = 30f;
chargeEffects = 7;
shootType = Bullets.lancerLaser;
- recoil = 2f;
- reload = 90f;
+ recoilAmount = 2f;
+ reloadTime = 90f;
cooldown = 0.03f;
powerUse = 2.5f;
shootShake = 2f;
@@ -1455,7 +1455,7 @@ public class Blocks implements ContentList{
arc = new PowerTurret("arc"){{
requirements(Category.turret, ItemStack.with(Items.copper, 35, Items.lead, 50));
shootType = Bullets.arc;
- reload = 35f;
+ reloadTime = 35f;
shootCone = 40f;
rotatespeed = 8f;
powerUse = 1.5f;
@@ -1463,7 +1463,7 @@ public class Blocks implements ContentList{
range = 90f;
shootEffect = Fx.lightningShoot;
heatColor = Color.red;
- recoil = 1f;
+ recoilAmount = 1f;
size = 1;
health = 260;
shootSound = Sounds.spark;
@@ -1476,7 +1476,7 @@ public class Blocks implements ContentList{
Items.pyratite, Bullets.missileIncendiary,
Items.surgealloy, Bullets.missileSurge
);
- reload = 40f;
+ reloadTime = 40f;
shots = 4;
burstSpacing = 5;
inaccuracy = 10f;
@@ -1499,11 +1499,11 @@ public class Blocks implements ContentList{
size = 2;
range = 150f;
- reload = 38f;
+ reloadTime = 38f;
restitution = 0.03f;
ammoEjectBack = 3f;
cooldown = 0.03f;
- recoil = 3f;
+ recoilAmount = 3f;
shootShake = 2f;
burstSpacing = 3f;
shots = 4;
@@ -1515,10 +1515,10 @@ public class Blocks implements ContentList{
fuse = new ItemTurret("fuse"){{
requirements(Category.turret, ItemStack.with(Items.copper, 225, Items.graphite, 225, Items.thorium, 100));
- reload = 35f;
+ reloadTime = 35f;
shootShake = 4f;
range = 90f;
- recoil = 5f;
+ recoilAmount = 5f;
shots = 3;
spread = 20f;
restitution = 0.1f;
@@ -1541,25 +1541,25 @@ public class Blocks implements ContentList{
}
@Override
- public void init(mindustry.entities.type.Bullet b){
+ public void init(Bulletc b){
for(int i = 0; i < rays; i++){
- Damage.collideLine(b, b.getTeam(), hitEffect, b.x, b.y, b.rot(), rayLength - Math.abs(i - (rays / 2)) * 20f);
+ Damage.collideLine(b, b.team(), hitEffect, b.x(), b.y(), b.rotation(), rayLength - Math.abs(i - (rays / 2)) * 20f);
}
}
@Override
- public void draw(Bullet b){
+ public void draw(Bulletc b){
super.draw(b);
Draw.color(Color.white, Pal.lancerLaser, b.fin());
//Draw.alpha(b.fout());
for(int i = 0; i < 7; i++){
- Tmp.v1.trns(b.rot(), i * 8f);
+ Tmp.v1.trns(b.rotation(), i * 8f);
float sl = Mathf.clamp(b.fout() - 0.5f) * (80f - i * 10);
- Drawf.tri(b.x + Tmp.v1.x, b.y + Tmp.v1.y, 4f, sl, b.rot() + 90);
- Drawf.tri(b.x + Tmp.v1.x, b.y + Tmp.v1.y, 4f, sl, b.rot() - 90);
+ Drawf.tri(b.x() + Tmp.v1.x, b.y() + Tmp.v1.y, 4f, sl, b.rotation() + 90);
+ Drawf.tri(b.x() + Tmp.v1.x, b.y() + Tmp.v1.y, 4f, sl, b.rotation() - 90);
}
- Drawf.tri(b.x, b.y, 20f * b.fout(), (rayLength + 50), b.rot());
- Drawf.tri(b.x, b.y, 20f * b.fout(), 10f, b.rot() + 180f);
+ Drawf.tri(b.x(), b.y(), 20f * b.fout(), (rayLength + 50), b.rotation());
+ Drawf.tri(b.x(), b.y(), 20f * b.fout(), 10f, b.rotation() + 180f);
Draw.reset();
}
});
@@ -1577,13 +1577,13 @@ public class Blocks implements ContentList{
size = 3;
shots = 4;
inaccuracy = 12f;
- reload = 60f;
+ reloadTime = 60f;
ammoEjectBack = 5f;
ammoUseEffect = Fx.shellEjectBig;
cooldown = 0.03f;
velocityInaccuracy = 0.2f;
restitution = 0.02f;
- recoil = 6f;
+ recoilAmount = 6f;
shootShake = 2f;
range = 290f;
@@ -1600,10 +1600,10 @@ public class Blocks implements ContentList{
Items.surgealloy, Bullets.flakSurge
);
xRand = 4f;
- reload = 6f;
+ reloadTime = 6f;
range = 200f;
size = 3;
- recoil = 3f;
+ recoilAmount = 3f;
rotatespeed = 10f;
inaccuracy = 10f;
shootCone = 30f;
@@ -1612,22 +1612,22 @@ public class Blocks implements ContentList{
health = 145 * size * size;
}};
- spectre = new DoubleTurret("spectre"){{
+ spectre = new ItemTurret("spectre"){{
requirements(Category.turret, ItemStack.with(Items.copper, 350, Items.graphite, 300, Items.surgealloy, 250, Items.plastanium, 175, Items.thorium, 250));
ammo(
Items.graphite, Bullets.standardDenseBig,
Items.pyratite, Bullets.standardIncendiaryBig,
Items.thorium, Bullets.standardThoriumBig
);
- reload = 6f;
+ reloadTime = 6f;
coolantMultiplier = 0.5f;
restitution = 0.1f;
ammoUseEffect = Fx.shellEjectBig;
range = 200f;
inaccuracy = 3f;
- recoil = 3f;
- xRand = 3f;
- shotWidth = 4f;
+ recoilAmount = 3f;
+ spread = 8f;
+ alternate = true;
shootShake = 2f;
shots = 2;
size = 4;
@@ -1643,11 +1643,11 @@ public class Blocks implements ContentList{
shootType = Bullets.meltdownLaser;
shootEffect = Fx.shootBigSmoke2;
shootCone = 40f;
- recoil = 4f;
+ recoilAmount = 4f;
size = 4;
shootShake = 2f;
range = 190f;
- reload = 80f;
+ reloadTime = 80f;
firingMoveFract = 0.5f;
shootDuration = 220f;
powerUse = 14f;
@@ -1662,106 +1662,16 @@ public class Blocks implements ContentList{
//endregion
//region units
- draugFactory = new UnitFactory("draug-factory"){{
+ //for testing only.
+ groundFactory = new UnitFactory("ground-factory"){{
requirements(Category.units, ItemStack.with(Items.copper, 30, Items.lead, 70));
- unitType = UnitTypes.draug;
- produceTime = 2500;
- size = 2;
- maxSpawn = 1;
- consumes.power(1.2f);
- consumes.items();
- }};
-
- spiritFactory = new UnitFactory("spirit-factory"){{
- requirements(Category.units, ItemStack.with(Items.metaglass, 45, Items.lead, 55, Items.silicon, 45));
- unitType = UnitTypes.spirit;
- produceTime = 4000;
- size = 2;
- maxSpawn = 1;
- consumes.power(1.2f);
- consumes.items(new ItemStack(Items.silicon, 30), new ItemStack(Items.lead, 30));
- }};
-
- phantomFactory = new UnitFactory("phantom-factory"){{
- requirements(Category.units, ItemStack.with(Items.titanium, 50, Items.thorium, 60, Items.lead, 65, Items.silicon, 105));
- unitType = UnitTypes.phantom;
- produceTime = 4400;
- size = 2;
- maxSpawn = 1;
- consumes.power(2.5f);
- consumes.items(new ItemStack(Items.silicon, 50), new ItemStack(Items.lead, 30), new ItemStack(Items.titanium, 20));
- }};
-
- commandCenter = new CommandCenter("command-center"){{
- requirements(Category.units, ItemStack.with(Items.copper, 200, Items.lead, 250, Items.silicon, 250, Items.graphite, 100));
- flags = EnumSet.of(BlockFlag.rally, BlockFlag.comandCenter);
- size = 2;
- health = size * size * 55;
- }};
-
- wraithFactory = new UnitFactory("wraith-factory"){{
- requirements(Category.units, ItemStack.with(Items.titanium, 30, Items.lead, 40, Items.silicon, 45));
- unitType = UnitTypes.wraith;
- produceTime = 700;
- size = 2;
- consumes.power(0.5f);
- consumes.items(new ItemStack(Items.silicon, 10), new ItemStack(Items.titanium, 5));
- }};
-
- ghoulFactory = new UnitFactory("ghoul-factory"){{
- requirements(Category.units, ItemStack.with(Items.titanium, 75, Items.lead, 65, Items.silicon, 110));
- unitType = UnitTypes.ghoul;
- produceTime = 1150;
+ plans = new UnitPlan[]{
+ new UnitPlan(UnitTypes.dagger, 60f, ItemStack.with(Items.silicon, 10)),
+ new UnitPlan(UnitTypes.wraith, 60f, ItemStack.with(Items.silicon, 10)),
+ };
size = 3;
consumes.power(1.2f);
- consumes.items(new ItemStack(Items.silicon, 15), new ItemStack(Items.titanium, 10));
- }};
-
- revenantFactory = new UnitFactory("revenant-factory"){{
- requirements(Category.units, ItemStack.with(Items.plastanium, 50, Items.titanium, 150, Items.lead, 150, Items.silicon, 200));
- unitType = UnitTypes.revenant;
- produceTime = 2000;
- size = 4;
- consumes.power(3f);
- consumes.items(new ItemStack(Items.silicon, 40), new ItemStack(Items.titanium, 30));
- }};
-
- daggerFactory = new UnitFactory("dagger-factory"){{
- requirements(Category.units, ItemStack.with(Items.lead, 55, Items.silicon, 35));
- unitType = UnitTypes.dagger;
- produceTime = 850;
- size = 2;
- consumes.power(0.5f);
- consumes.items(new ItemStack(Items.silicon, 6));
- }};
-
- crawlerFactory = new UnitFactory("crawler-factory"){{
- requirements(Category.units, ItemStack.with(Items.lead, 45, Items.silicon, 30));
- unitType = UnitTypes.crawler;
- produceTime = 300;
- size = 2;
- maxSpawn = 6;
- consumes.power(0.5f);
- consumes.items(new ItemStack(Items.coal, 10));
- }};
-
- titanFactory = new UnitFactory("titan-factory"){{
- requirements(Category.units, ItemStack.with(Items.graphite, 50, Items.lead, 50, Items.silicon, 45));
- unitType = UnitTypes.titan;
- produceTime = 1050;
- size = 3;
- consumes.power(0.60f);
- consumes.items(new ItemStack(Items.silicon, 12));
- }};
-
- fortressFactory = new UnitFactory("fortress-factory"){{
- requirements(Category.units, ItemStack.with(Items.thorium, 40, Items.lead, 110, Items.silicon, 75));
- unitType = UnitTypes.fortress;
- produceTime = 2000;
- size = 3;
- maxSpawn = 3;
- consumes.power(1.4f);
- consumes.items(new ItemStack(Items.silicon, 20), new ItemStack(Items.graphite, 10));
+ consumes.items(new ItemStack(Items.silicon, 10));
}};
repairPoint = new RepairPoint("repair-point"){{
@@ -1771,58 +1681,6 @@ public class Blocks implements ContentList{
powerUse = 1f;
}};
- //endregion
- //region upgrades
-
- dartPad = new MechPad("dart-mech-pad"){{
- requirements(Category.upgrade, ItemStack.with(Items.lead, 100, Items.graphite, 50, Items.copper, 75));
- mech = Mechs.alpha;
- size = 2;
- consumes.power(0.5f);
- }};
-
- deltaPad = new MechPad("delta-mech-pad"){{
- requirements(Category.upgrade, ItemStack.with(Items.lead, 175, Items.titanium, 175, Items.copper, 200, Items.silicon, 225, Items.thorium, 150));
- mech = Mechs.delta;
- size = 2;
- consumes.power(0.7f);
- }};
-
- tauPad = new MechPad("tau-mech-pad"){{
- requirements(Category.upgrade, ItemStack.with(Items.lead, 125, Items.titanium, 125, Items.copper, 125, Items.silicon, 125));
- mech = Mechs.tau;
- size = 2;
- consumes.power(1f);
- }};
-
- omegaPad = new MechPad("omega-mech-pad"){{
- requirements(Category.upgrade, ItemStack.with(Items.lead, 225, Items.graphite, 275, Items.silicon, 325, Items.thorium, 300, Items.surgealloy, 120));
- mech = Mechs.omega;
- size = 3;
- consumes.power(1.2f);
- }};
-
- javelinPad = new MechPad("javelin-ship-pad"){{
- requirements(Category.upgrade, ItemStack.with(Items.lead, 175, Items.silicon, 225, Items.titanium, 250, Items.plastanium, 200, Items.phasefabric, 100));
- mech = Mechs.javelin;
- size = 2;
- consumes.power(0.8f);
- }};
-
- tridentPad = new MechPad("trident-ship-pad"){{
- requirements(Category.upgrade, ItemStack.with(Items.lead, 125, Items.copper, 125, Items.silicon, 125, Items.titanium, 150, Items.plastanium, 100));
- mech = Mechs.trident;
- size = 2;
- consumes.power(1f);
- }};
-
- glaivePad = new MechPad("glaive-ship-pad"){{
- requirements(Category.upgrade, ItemStack.with(Items.lead, 225, Items.silicon, 325, Items.titanium, 350, Items.plastanium, 300, Items.surgealloy, 100));
- mech = Mechs.glaive;
- size = 3;
- consumes.power(1.2f);
- }};
-
//endregion
//region sandbox
@@ -1867,6 +1725,14 @@ public class Blocks implements ContentList{
consumes.power(0.05f);
}};
+ //endregion
+ //region legacy
+
+ //looked up by name, no ref needed
+ new LegacyMechPad("legacy-mech-pad");
+ new LegacyUnitFactory("legacy-unit-factory");
+ new LegacyCommandCenter("legacy-command-center");
+
//endregion
}
}
diff --git a/core/src/mindustry/content/Bullets.java b/core/src/mindustry/content/Bullets.java
index 017798731c..c37f60f946 100644
--- a/core/src/mindustry/content/Bullets.java
+++ b/core/src/mindustry/content/Bullets.java
@@ -4,11 +4,10 @@ import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.math.*;
import arc.util.*;
-import mindustry.ctype.ContentList;
+import mindustry.ctype.*;
import mindustry.entities.*;
import mindustry.entities.bullet.*;
-import mindustry.entities.effect.*;
-import mindustry.entities.type.*;
+import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.world.*;
@@ -384,7 +383,7 @@ public class Bullets implements ContentList{
}};
damageLightning = new BulletType(0.0001f, 0f){{
- lifetime = Lightning.lifetime;
+ lifetime = Fx.lightning.lifetime;
hitEffect = Fx.hitLancer;
despawnEffect = Fx.none;
status = StatusEffects.shocked;
@@ -410,32 +409,32 @@ public class Bullets implements ContentList{
}
@Override
- public void init(Bullet b){
- b.velocity().setLength(0.6f + Mathf.random(2f));
+ public void init(Bulletc b){
+ b.vel().setLength(0.6f + Mathf.random(2f));
}
@Override
- public void draw(Bullet b){
+ public void draw(Bulletc b){
Draw.color(Pal.lightFlame, Pal.darkFlame, Color.gray, b.fin());
- Fill.circle(b.x, b.y, 3f * b.fout());
+ Fill.circle(b.x(), b.y(), 3f * b.fout());
Draw.reset();
}
@Override
- public void update(Bullet b){
+ public void update(Bulletc b){
if(Mathf.chance(0.04 * Time.delta())){
- Tile tile = world.tileWorld(b.x, b.y);
+ Tile tile = world.tileWorld(b.x(), b.y());
if(tile != null){
- Fire.create(tile);
+ Fires.create(tile);
}
}
if(Mathf.chance(0.1 * Time.delta())){
- Effects.effect(Fx.fireballsmoke, b.x, b.y);
+ Fx.fireballsmoke.at(b.x(), b.y());
}
if(Mathf.chance(0.1 * Time.delta())){
- Effects.effect(Fx.ballfire, b.x, b.y);
+ Fx.ballfire.at(b.x(), b.y());
}
}
};
@@ -452,6 +451,7 @@ public class Bullets implements ContentList{
hitEffect = Fx.hitFlameSmall;
despawnEffect = Fx.none;
status = StatusEffects.burning;
+ keepVelocity = false;
}
@Override
@@ -460,7 +460,7 @@ public class Bullets implements ContentList{
}
@Override
- public void draw(Bullet b){
+ public void draw(Bulletc b){
}
};
@@ -479,50 +479,17 @@ public class Bullets implements ContentList{
}
@Override
- public void draw(Bullet b){
+ public void draw(Bulletc b){
}
};
- lancerLaser = new BulletType(0.001f, 140){
- Color[] colors = {Pal.lancerLaser.cpy().mul(1f, 1f, 1f, 0.4f), Pal.lancerLaser, Color.white};
- float[] tscales = {1f, 0.7f, 0.5f, 0.2f};
- float[] lenscales = {1f, 1.1f, 1.13f, 1.14f};
- float length = 160f;
-
- {
- hitEffect = Fx.hitLancer;
- despawnEffect = Fx.none;
- hitSize = 4;
- lifetime = 16f;
- pierce = true;
- }
-
- @Override
- public float range(){
- return length;
- }
-
- @Override
- public void init(Bullet b){
- Damage.collideLine(b, b.getTeam(), hitEffect, b.x, b.y, b.rot(), length);
- }
-
- @Override
- public void draw(Bullet b){
- float f = Mathf.curve(b.fin(), 0f, 0.2f);
- float baseLen = length * f;
-
- Lines.lineAngle(b.x, b.y, b.rot(), baseLen);
- for(int s = 0; s < 3; s++){
- Draw.color(colors[s]);
- for(int i = 0; i < tscales.length; i++){
- Lines.stroke(7f * b.fout() * (s == 0 ? 1.5f : s == 1 ? 1f : 0.3f) * tscales[i]);
- Lines.lineAngle(b.x, b.y, b.rot(), baseLen * lenscales[i]);
- }
- }
- Draw.reset();
- }
- };
+ lancerLaser = new LaserBulletType(140){{
+ colors = new Color[]{Pal.lancerLaser.cpy().mul(1f, 1f, 1f, 0.4f), Pal.lancerLaser, Color.white};
+ hitEffect = Fx.hitLancer;
+ despawnEffect = Fx.none;
+ hitSize = 4;
+ lifetime = 16f;
+ }};
meltdownLaser = new BulletType(0.001f, 70){
Color tmpColor = new Color();
@@ -542,32 +509,32 @@ public class Bullets implements ContentList{
}
@Override
- public void update(Bullet b){
- if(b.timer.get(1, 5f)){
- Damage.collideLine(b, b.getTeam(), hitEffect, b.x, b.y, b.rot(), length, true);
+ public void update(Bulletc b){
+ if(b.timer(1, 5f)){
+ Damage.collideLine(b, b.team(), hitEffect, b.x(), b.y(), b.rotation(), length, true);
}
- Effects.shake(1f, 1f, b.x, b.y);
+ Effects.shake(1f, 1f, b.x(), b.y());
}
@Override
- public void hit(Bullet b, float hitx, float hity){
- Effects.effect(hitEffect, colors[2], hitx, hity);
+ public void hit(Bulletc b, float hitx, float hity){
+ hitEffect.at(hitx, hity, colors[2]);
if(Mathf.chance(0.4)){
- Fire.create(world.tileWorld(hitx + Mathf.range(5f), hity + Mathf.range(5f)));
+ Fires.create(world.tileWorld(hitx + Mathf.range(5f), hity + Mathf.range(5f)));
}
}
@Override
- public void draw(Bullet b){
+ public void draw(Bulletc b){
float baseLen = (length) * b.fout();
- Lines.lineAngle(b.x, b.y, b.rot(), baseLen);
+ Lines.lineAngle(b.x(), b.y(), b.rotation(), baseLen);
for(int s = 0; s < colors.length; s++){
Draw.color(tmpColor.set(colors[s]).mul(1f + Mathf.absin(Time.time(), 1f, 0.1f)));
for(int i = 0; i < tscales.length; i++){
- Tmp.v1.trns(b.rot() + 180f, (lenscales[i] - 1f) * 35f);
+ Tmp.v1.trns(b.rotation() + 180f, (lenscales[i] - 1f) * 35f);
Lines.stroke((9f + Mathf.absin(Time.time(), 0.8f, 1.5f)) * b.fout() * strokes[s] * tscales[i]);
- Lines.lineAngle(b.x + Tmp.v1.x, b.y + Tmp.v1.y, b.rot(), baseLen * lenscales[i], CapStyle.none);
+ Lines.lineAngle(b.x() + Tmp.v1.x, b.y() + Tmp.v1.y, b.rotation(), baseLen * lenscales[i], CapStyle.none);
}
}
Draw.reset();
@@ -613,31 +580,20 @@ public class Bullets implements ContentList{
}
@Override
- public void draw(Bullet b){
+ public void draw(Bulletc b){
}
@Override
- public void init(Bullet b){
- Lightning.create(b.getTeam(), Pal.lancerLaser, damage * (b.getOwner() instanceof Player ? state.rules.playerDamageMultiplier : 1f), b.x, b.y, b.rot(), 30);
+ public void init(Bulletc b){
+ //TODO owners are never players...
+ Lightning.create(b.team(), Pal.lancerLaser, damage * (b.owner() instanceof Playerc ? state.rules.playerDamageMultiplier : 1f), b.x(), b.y(), b.rotation(), 30);
}
};
- arc = new BulletType(0.001f, 21){
- {
- lifetime = 1;
- despawnEffect = Fx.none;
- hitEffect = Fx.hitLancer;
- }
-
- @Override
- public void draw(Bullet b){
- }
-
- @Override
- public void init(Bullet b){
- Lightning.create(b.getTeam(), Pal.lancerLaser, damage, b.x, b.y, b.rot(), 25);
- }
- };
+ arc = new LightningBulletType(){{
+ damage = 21;
+ lightningLength = 25;
+ }};
driverBolt = new MassDriverBolt();
@@ -678,12 +634,12 @@ public class Bullets implements ContentList{
}
@Override
- public void hit(Bullet b, float x, float y){
+ public void hit(Bulletc b, float x, float y){
super.hit(b, x, y);
for(int i = 0; i < 3; i++){
Tile tile = world.tileWorld(x + Mathf.range(8f), y + Mathf.range(8f));
- Puddle.deposit(tile, Liquids.oil, 5f);
+ Puddles.deposit(tile, Liquids.oil, 5f);
}
}
};
diff --git a/core/src/mindustry/content/Fx.java b/core/src/mindustry/content/Fx.java
index a116034e1a..19741e8892 100644
--- a/core/src/mindustry/content/Fx.java
+++ b/core/src/mindustry/content/Fx.java
@@ -4,1097 +4,1175 @@ import arc.*;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.math.*;
+import arc.math.geom.*;
+import arc.struct.*;
import arc.util.*;
-import mindustry.ctype.ContentList;
-import mindustry.entities.Effects.*;
-import mindustry.entities.effect.GroundEffectEntity.*;
-import mindustry.entities.type.*;
+import mindustry.entities.*;
+import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.type.*;
-import mindustry.ui.Cicon;
+import mindustry.ui.*;
+import static arc.graphics.g2d.Draw.*;
+import static arc.graphics.g2d.Lines.*;
+import static arc.math.Angles.*;
import static mindustry.Vars.*;
-public class Fx implements ContentList{
- public static Effect
+public class Fx{
+ public static final Effect
- none, placeBlock, breakBlock, smoke, spawn, tapBlock, select,
- vtolHover, unitDrop, unitPickup, unitLand, pickup, healWave, heal, landShock, reactorsmoke, nuclearsmoke, nuclearcloud,
- redgeneratespark, generatespark, fuelburn, plasticburn, pulverize, pulverizeRed, pulverizeRedder, pulverizeSmall, pulverizeMedium,
- producesmoke, smeltsmoke, formsmoke, blastsmoke, lava, doorclose, dooropen, dooropenlarge, doorcloselarge, purify, purifyoil, purifystone, generate,
- mine, mineBig, mineHuge, smelt, teleportActivate, teleport, teleportOut, ripple, bubble, launch,
- healBlock, healBlockFull, healWaveMend, overdriveWave, overdriveBlockFull, shieldBreak, hitBulletSmall, hitFuse,
- hitBulletBig, hitFlameSmall, hitLiquid, hitLaser, hitLancer, hitMeltdown, despawn, flakExplosion, blastExplosion,
- plasticExplosion, artilleryTrail, incendTrail, missileTrail, absorb, flakExplosionBig, plasticExplosionFlak, burning, fire,
- fireSmoke, steam, fireballsmoke, ballfire, freezing, melting, wet, oily, overdriven, dropItem, shockwave,
- bigShockwave, nuclearShockwave, explosion, blockExplosion, blockExplosionSmoke, shootSmall, shootHeal, shootSmallSmoke, shootBig, shootBig2, shootBigSmoke,
- shootBigSmoke2, shootSmallFlame, shootPyraFlame, shootLiquid, shellEjectSmall, shellEjectMedium,
- shellEjectBig, lancerLaserShoot, lancerLaserShootSmoke, lancerLaserCharge, lancerLaserChargeBegin, lightningCharge, lightningShoot,
- unitSpawn, spawnShockwave, magmasmoke, impactShockwave, impactcloud, impactsmoke, dynamicExplosion, padlaunch, commandSend, coreLand;
+ none = new Effect(0, 0f, e -> {}),
- @Override
- public void load(){
+ unitSpawn = new Effect(30f, e -> {
+ if(!(e.data instanceof Unitc)) return;
+
+ alpha(e.fin());
- none = new Effect(0, 0f, e -> {});
+ float scl = 1f + e.fout() * 2f;
- unitSpawn = new Effect(30f, e -> {
- if(!(e.data instanceof BaseUnit)) return;
+ Unitc unit = (Unitc)e.data;
+ rect(unit.type().region, e.x, e.y,
+ unit.type().region.getWidth() * Draw.scl * scl, unit.type().region.getHeight() * Draw.scl * scl, 180f);
- Draw.alpha(e.fin());
+ }),
- float scl = 1f + e.fout() * 2f;
+ unitControl = new Effect(30f, e -> {
+ if(!(e.data instanceof Unitc)) return;
- BaseUnit unit = (BaseUnit)e.data;
- Draw.rect(unit.getIconRegion(), e.x, e.y,
- unit.getIconRegion().getWidth() * Draw.scl * scl, unit.getIconRegion().getWidth() * Draw.scl * scl, 180f);
+ Unitc select = (Unitc)e.data;
- });
+ mixcol(Pal.accent, 1f);
+ alpha(e.fout());
+ rect(select.type().icon(Cicon.full), select.x(), select.y(), select.rotation() - 90f);
+ alpha(1f);
+ Lines.stroke(e.fslope() * 1f);
+ Lines.square(select.x(), select.y(), e.fout() * select.hitSize() * 2f, 45);
+ Lines.stroke(e.fslope() * 2f);
+ Lines.square(select.x(), select.y(), e.fout() * select.hitSize() * 3f, 45f);
+ reset();
+ }),
+
+ unitSpirit = new Effect(20f, e -> {
+ if(!(e.data instanceof Position)) return;
+ Position to = e.data();
+
+ color(Pal.accent);
+
+ Tmp.v1.set(e.x, e.y).interpolate(Tmp.v2.set(to), e.fin(), Interpolation.pow2In);
+ float x = Tmp.v1.x, y = Tmp.v1.y;
+ float size = 2.5f * e.fin();
+
+ Fill.square(x, y, 1.5f * size, 45f);
+
+ Tmp.v1.set(e.x, e.y).interpolate(Tmp.v2.set(to), e.fin(), Interpolation.pow5In);
+ x = Tmp.v1.x;
+ y = Tmp.v1.y;
+
+ Fill.square(x, y, 1f * size, 45f);
+ }),
+
+ itemTransfer = new Effect(30f, e -> {
+ if(!(e.data instanceof Position)) return;
+ Position to = e.data();
+ Tmp.v1.set(e.x, e.y).interpolate(Tmp.v2.set(to), e.fin(), Interpolation.pow3)
+ .add(Tmp.v2.sub(e.x, e.y).nor().rotate90(1).scl(Mathf.randomSeedRange(e.id, 1f) * e.fslope() * 10f));
+ float x = Tmp.v1.x, y = Tmp.v1.y;
+ float size = Math.min(0.8f + e.rotation / 5f, 2);
+
+ stroke(e.fslope() * 2f * size, Pal.accent);
+ Lines.circle(x, y, e.fslope() * 2f * size);
+
+ color(e.color);
+ Fill.circle(x, y, e.fslope() * 1.5f * size);
+ }),
+
+ lightning = new Effect(10f, 500f, e -> {
+ if(!(e.data instanceof Array)) return;
+ Array lines = e.data();
+
+ stroke(3f * e.fout());
+ color(e.color, Color.white, e.fin());
+ beginLine();
+
+ linePoint(e.x, e.y);
+ lines.each(Lines::linePoint);
+ endLine();
+
+ int i = 0;
+ for(Vec2 p : lines){
+ Fill.square(p.x, p.y, (5f - (float)i++ / lines.size * 2f) * e.fout(), 45);
+ }
+ }),
+
+ commandSend = new Effect(28, e -> {
+ color(Pal.command);
+ stroke(e.fout() * 2f);
+ Lines.circle(e.x, e.y, 4f + e.finpow() * 120f);
+ }),
+
+ placeBlock = new Effect(16, e -> {
+ color(Pal.accent);
+ stroke(3f - e.fin() * 2f);
+ Lines.square(e.x, e.y, tilesize / 2f * e.rotation + e.fin() * 3f);
+ }),
+
+ tapBlock = new Effect(12, e -> {
+ color(Pal.accent);
+ stroke(3f - e.fin() * 2f);
+ Lines.circle(e.x, e.y, 4f + (tilesize / 1.5f * e.rotation) * e.fin());
+ }),
+
+ breakBlock = new Effect(12, e -> {
+ color(Pal.remove);
+ stroke(3f - e.fin() * 2f);
+ Lines.square(e.x, e.y, tilesize / 2f * e.rotation + e.fin() * 3f);
+
+ randLenVectors(e.id, 3 + (int)(e.rotation * 3), e.rotation * 2f + (tilesize * e.rotation) * e.finpow(), (x, y) -> {
+ Fill.square(e.x + x, e.y + y, 1f + e.fout() * (3f + e.rotation));
+ });
+ }),
+
+ select = new Effect(23, e -> {
+ color(Pal.accent);
+ stroke(e.fout() * 3f);
+ Lines.circle(e.x, e.y, 3f + e.fin() * 14f);
+ }),
+
+ smoke = new Effect(100, e -> {
+ color(Color.gray, Pal.darkishGray, e.fin());
+ Fill.circle(e.x, e.y, (7f - e.fin() * 7f)/2f);
+ }),
+
+ magmasmoke = new Effect(110, e -> {
+ color(Color.gray);
+ Fill.circle(e.x, e.y, e.fslope() * 6f);
+ }),
+
+ spawn = new Effect(30, e -> {
+ stroke(2f * e.fout());
+ color(Pal.accent);
+ Lines.poly(e.x, e.y, 4, 5f + e.fin() * 12f);
+ }),
- commandSend = new Effect(28, e -> {
- Draw.color(Pal.command);
- Lines.stroke(e.fout() * 2f);
- Lines.circle(e.x, e.y, 4f + e.finpow() * 120f);
- });
+ padlaunch = new Effect(10, e -> {
+ stroke(4f * e.fout());
+ color(Pal.accent);
+ Lines.poly(e.x, e.y, 4, 5f + e.fin() * 60f);
+ }),
- placeBlock = new Effect(16, e -> {
- Draw.color(Pal.accent);
- Lines.stroke(3f - e.fin() * 2f);
- Lines.square(e.x, e.y, tilesize / 2f * e.rotation + e.fin() * 3f);
- });
+ vtolHover = new Effect(40f, e -> {
+ float len = e.finpow() * 10f;
+ float ang = e.rotation + Mathf.randomSeedRange(e.id, 30f);
+ color(Pal.lightFlame, Pal.lightOrange, e.fin());
+ Fill.circle(e.x + trnsx(ang, len), e.y + trnsy(ang, len), 2f * e.fout());
+ }),
- tapBlock = new Effect(12, e -> {
- Draw.color(Pal.accent);
- Lines.stroke(3f - e.fin() * 2f);
- Lines.circle(e.x, e.y, 4f + (tilesize / 1.5f * e.rotation) * e.fin());
+ unitDrop = new Effect(30, e -> {
+ color(Pal.lightishGray);
+ randLenVectors(e.id, 9, 3 + 20f * e.finpow(), (x, y) -> {
+ Fill.circle(e.x + x, e.y + y, e.fout() * 4f + 0.4f);
});
+ }).ground(),
- breakBlock = new Effect(12, e -> {
- Draw.color(Pal.remove);
- Lines.stroke(3f - e.fin() * 2f);
- Lines.square(e.x, e.y, tilesize / 2f * e.rotation + e.fin() * 3f);
-
- Angles.randLenVectors(e.id, 3 + (int)(e.rotation * 3), e.rotation * 2f + (tilesize * e.rotation) * e.finpow(), (x, y) -> {
- Fill.square(e.x + x, e.y + y, 1f + e.fout() * (3f + e.rotation));
- });
+ unitLand = new Effect(30, e -> {
+ color(Tmp.c1.set(e.color).mul(1.1f));
+ randLenVectors(e.id, 6, 17f * e.finpow(), (x, y) -> {
+ Fill.circle(e.x + x, e.y + y, e.fout() * 4f + 0.3f);
});
+ }).ground(),
- select = new Effect(23, e -> {
- Draw.color(Pal.accent);
- Lines.stroke(e.fout() * 3f);
- Lines.circle(e.x, e.y, 3f + e.fin() * 14f);
- });
+ unitPickup = new Effect(18, e -> {
+ color(Pal.lightishGray);
+ stroke(e.fin() * 2f);
+ Lines.poly(e.x, e.y, 4, 13f * e.fout());
+ }).ground(),
- smoke = new Effect(100, e -> {
- Draw.color(Color.gray, Pal.darkishGray, e.fin());
- float size = 7f - e.fin() * 7f;
- Draw.rect("circle", e.x, e.y, size, size);
- });
+ landShock = new Effect(12, e -> {
+ color(Pal.lancerLaser);
+ stroke(e.fout() * 3f);
+ Lines.poly(e.x, e.y, 12, 20f * e.fout());
+ }).ground(),
- magmasmoke = new Effect(110, e -> {
- Draw.color(Color.gray);
- Fill.circle(e.x, e.y, e.fslope() * 6f);
- });
+ pickup = new Effect(18, e -> {
+ color(Pal.lightishGray);
+ stroke(e.fout() * 2f);
+ Lines.spikes(e.x, e.y, 1f + e.fin() * 6f, e.fout() * 4f, 6);
+ }),
- spawn = new Effect(30, e -> {
- Lines.stroke(2f * e.fout());
- Draw.color(Pal.accent);
- Lines.poly(e.x, e.y, 4, 5f + e.fin() * 12f);
- });
+ healWave = new Effect(22, e -> {
+ color(Pal.heal);
+ stroke(e.fout() * 2f);
+ Lines.circle(e.x, e.y, 4f + e.finpow() * 60f);
+ }),
- padlaunch = new Effect(10, e -> {
- Lines.stroke(4f * e.fout());
- Draw.color(Pal.accent);
- Lines.poly(e.x, e.y, 4, 5f + e.fin() * 60f);
- });
+ heal = new Effect(11, e -> {
+ color(Pal.heal);
+ stroke(e.fout() * 2f);
+ Lines.circle(e.x, e.y, 2f + e.finpow() * 7f);
+ }),
- vtolHover = new Effect(40f, e -> {
- float len = e.finpow() * 10f;
- float ang = e.rotation + Mathf.randomSeedRange(e.id, 30f);
- Draw.color(Pal.lightFlame, Pal.lightOrange, e.fin());
- Fill.circle(e.x + Angles.trnsx(ang, len), e.y + Angles.trnsy(ang, len), 2f * e.fout());
- });
+ hitBulletSmall = new Effect(14, e -> {
+ color(Color.white, Pal.lightOrange, e.fin());
- unitDrop = new GroundEffect(30, e -> {
- Draw.color(Pal.lightishGray);
- Angles.randLenVectors(e.id, 9, 3 + 20f * e.finpow(), (x, y) -> {
- Fill.circle(e.x + x, e.y + y, e.fout() * 4f + 0.4f);
- });
+ e.scaled(7f, s -> {
+ stroke(0.5f + s.fout());
+ Lines.circle(e.x, e.y, s.fin() * 5f);
});
- unitLand = new GroundEffect(30, e -> {
- Draw.color(Tmp.c1.set(e.color).mul(1.1f));
- Angles.randLenVectors(e.id, 6, 17f * e.finpow(), (x, y) -> {
- Fill.circle(e.x + x, e.y + y, e.fout() * 4f + 0.3f);
- });
- });
+ stroke(0.5f + e.fout());
- unitPickup = new GroundEffect(18, e -> {
- Draw.color(Pal.lightishGray);
- Lines.stroke(e.fin() * 2f);
- Lines.poly(e.x, e.y, 4, 13f * e.fout());
+ randLenVectors(e.id, 5, e.fin() * 15f, (x, y) -> {
+ float ang = Mathf.angle(x, y);
+ lineAngle(e.x + x, e.y + y, ang, e.fout() * 3 + 1f);
});
+ }),
- landShock = new GroundEffect(12, e -> {
- Draw.color(Pal.lancerLaser);
- Lines.stroke(e.fout() * 3f);
- Lines.poly(e.x, e.y, 12, 20f * e.fout());
- });
+ hitFuse = new Effect(14, e -> {
+ color(Color.white, Pal.surge, e.fin());
- pickup = new Effect(18, e -> {
- Draw.color(Pal.lightishGray);
- Lines.stroke(e.fout() * 2f);
- Lines.spikes(e.x, e.y, 1f + e.fin() * 6f, e.fout() * 4f, 6);
+ e.scaled(7f, s -> {
+ stroke(0.5f + s.fout());
+ Lines.circle(e.x, e.y, s.fin() * 7f);
});
- healWave = new Effect(22, e -> {
- Draw.color(Pal.heal);
- Lines.stroke(e.fout() * 2f);
- Lines.circle(e.x, e.y, 4f + e.finpow() * 60f);
- });
+ stroke(0.5f + e.fout());
- heal = new Effect(11, e -> {
- Draw.color(Pal.heal);
- Lines.stroke(e.fout() * 2f);
- Lines.circle(e.x, e.y, 2f + e.finpow() * 7f);
+ randLenVectors(e.id, 6, e.fin() * 15f, (x, y) -> {
+ float ang = Mathf.angle(x, y);
+ lineAngle(e.x + x, e.y + y, ang, e.fout() * 3 + 1f);
});
+ }),
- hitBulletSmall = new Effect(14, e -> {
- Draw.color(Color.white, Pal.lightOrange, e.fin());
-
- e.scaled(7f, s -> {
- Lines.stroke(0.5f + s.fout());
- Lines.circle(e.x, e.y, s.fin() * 5f);
- });
-
-
- Lines.stroke(0.5f + e.fout());
-
- Angles.randLenVectors(e.id, 5, e.fin() * 15f, (x, y) -> {
- float ang = Mathf.angle(x, y);
- Lines.lineAngle(e.x + x, e.y + y, ang, e.fout() * 3 + 1f);
- });
+ hitBulletBig = new Effect(13, e -> {
+ color(Color.white, Pal.lightOrange, e.fin());
+ stroke(0.5f + e.fout() * 1.5f);
+ randLenVectors(e.id, 8, e.finpow() * 30f, e.rotation, 50f, (x, y) -> {
+ float ang = Mathf.angle(x, y);
+ lineAngle(e.x + x, e.y + y, ang, e.fout() * 4 + 1.5f);
});
- hitFuse = new Effect(14, e -> {
- Draw.color(Color.white, Pal.surge, e.fin());
+ }),
- e.scaled(7f, s -> {
- Lines.stroke(0.5f + s.fout());
- Lines.circle(e.x, e.y, s.fin() * 7f);
- });
+ hitFlameSmall = new Effect(14, e -> {
+ color(Pal.lightFlame, Pal.darkFlame, e.fin());
+ stroke(0.5f + e.fout());
+ randLenVectors(e.id, 2, e.fin() * 15f, e.rotation, 50f, (x, y) -> {
+ float ang = Mathf.angle(x, y);
+ lineAngle(e.x + x, e.y + y, ang, e.fout() * 3 + 1f);
+ });
- Lines.stroke(0.5f + e.fout());
+ }),
- Angles.randLenVectors(e.id, 6, e.fin() * 15f, (x, y) -> {
- float ang = Mathf.angle(x, y);
- Lines.lineAngle(e.x + x, e.y + y, ang, e.fout() * 3 + 1f);
- });
+ hitLiquid = new Effect(16, e -> {
+ color(e.color);
+ randLenVectors(e.id, 5, e.fin() * 15f, e.rotation + 180f, 60f, (x, y) -> {
+ Fill.circle(e.x + x, e.y + y, e.fout() * 2f);
});
- hitBulletBig = new Effect(13, e -> {
- Draw.color(Color.white, Pal.lightOrange, e.fin());
- Lines.stroke(0.5f + e.fout() * 1.5f);
+ }),
- Angles.randLenVectors(e.id, 8, e.finpow() * 30f, e.rotation, 50f, (x, y) -> {
- float ang = Mathf.angle(x, y);
- Lines.lineAngle(e.x + x, e.y + y, ang, e.fout() * 4 + 1.5f);
- });
+ hitLancer = new Effect(12, e -> {
+ color(Color.white);
+ stroke(e.fout() * 1.5f);
+ randLenVectors(e.id, 8, e.finpow() * 17f, e.rotation, 360f, (x, y) -> {
+ float ang = Mathf.angle(x, y);
+ lineAngle(e.x + x, e.y + y, ang, e.fout() * 4 + 1f);
});
- hitFlameSmall = new Effect(14, e -> {
- Draw.color(Pal.lightFlame, Pal.darkFlame, e.fin());
- Lines.stroke(0.5f + e.fout());
+ }),
- Angles.randLenVectors(e.id, 2, e.fin() * 15f, e.rotation, 50f, (x, y) -> {
- float ang = Mathf.angle(x, y);
- Lines.lineAngle(e.x + x, e.y + y, ang, e.fout() * 3 + 1f);
- });
+ hitMeltdown = new Effect(12, e -> {
+ color(Pal.meltdownHit);
+ stroke(e.fout() * 2f);
+ randLenVectors(e.id, 6, e.finpow() * 18f, e.rotation, 360f, (x, y) -> {
+ float ang = Mathf.angle(x, y);
+ lineAngle(e.x + x, e.y + y, ang, e.fout() * 4 + 1f);
});
- hitLiquid = new Effect(16, e -> {
- Draw.color(e.color);
-
- Angles.randLenVectors(e.id, 5, e.fin() * 15f, e.rotation + 180f, 60f, (x, y) -> {
- Fill.circle(e.x + x, e.y + y, e.fout() * 2f);
- });
+ }),
- });
+ hitLaser = new Effect(8, e -> {
+ color(Color.white, Pal.heal, e.fin());
+ stroke(0.5f + e.fout());
+ Lines.circle(e.x, e.y, e.fin() * 5f);
+ }),
- hitLancer = new Effect(12, e -> {
- Draw.color(Color.white);
- Lines.stroke(e.fout() * 1.5f);
+ hitYellowLaser = new Effect(8, e -> {
+ color(Color.white, Pal.lightTrail, e.fin());
+ stroke(0.5f + e.fout());
+ Lines.circle(e.x, e.y, e.fin() * 5f);
+ }),
- Angles.randLenVectors(e.id, 8, e.finpow() * 17f, e.rotation, 360f, (x, y) -> {
- float ang = Mathf.angle(x, y);
- Lines.lineAngle(e.x + x, e.y + y, ang, e.fout() * 4 + 1f);
- });
+ despawn = new Effect(12, e -> {
+ color(Pal.lighterOrange, Color.gray, e.fin());
+ stroke(e.fout());
+ randLenVectors(e.id, 7, e.fin() * 7f, e.rotation, 40f, (x, y) -> {
+ float ang = Mathf.angle(x, y);
+ lineAngle(e.x + x, e.y + y, ang, e.fout() * 2 + 1f);
});
- hitMeltdown = new Effect(12, e -> {
- Draw.color(Pal.meltdownHit);
- Lines.stroke(e.fout() * 2f);
+ }),
- Angles.randLenVectors(e.id, 6, e.finpow() * 18f, e.rotation, 360f, (x, y) -> {
- float ang = Mathf.angle(x, y);
- Lines.lineAngle(e.x + x, e.y + y, ang, e.fout() * 4 + 1f);
- });
+ flakExplosion = new Effect(20, e -> {
+ color(Pal.bulletYellow);
+ e.scaled(6, i -> {
+ stroke(3f * i.fout());
+ Lines.circle(e.x, e.y, 3f + i.fin() * 10f);
});
- hitLaser = new Effect(8, e -> {
- Draw.color(Color.white, Pal.heal, e.fin());
- Lines.stroke(0.5f + e.fout());
- Lines.circle(e.x, e.y, e.fin() * 5f);
- });
+ color(Color.gray);
- despawn = new Effect(12, e -> {
- Draw.color(Pal.lighterOrange, Color.gray, e.fin());
- Lines.stroke(e.fout());
+ randLenVectors(e.id, 5, 2f + 23f * e.finpow(), (x, y) -> {
+ Fill.circle(e.x + x, e.y + y, e.fout() * 3f + 0.5f);
+ });
- Angles.randLenVectors(e.id, 7, e.fin() * 7f, e.rotation, 40f, (x, y) -> {
- float ang = Mathf.angle(x, y);
- Lines.lineAngle(e.x + x, e.y + y, ang, e.fout() * 2 + 1f);
- });
+ color(Pal.lighterOrange);
+ stroke(1f * e.fout());
+ randLenVectors(e.id + 1, 4, 1f + 23f * e.finpow(), (x, y) -> {
+ lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), 1f + e.fout() * 3f);
});
- flakExplosion = new Effect(20, e -> {
+ }),
- Draw.color(Pal.bulletYellow);
- e.scaled(6, i -> {
- Lines.stroke(3f * i.fout());
- Lines.circle(e.x, e.y, 3f + i.fin() * 10f);
- });
+ plasticExplosion = new Effect(24, e -> {
- Draw.color(Color.gray);
+ color(Pal.plastaniumFront);
+ e.scaled(7, i -> {
+ stroke(3f * i.fout());
+ Lines.circle(e.x, e.y, 3f + i.fin() * 24f);
+ });
- Angles.randLenVectors(e.id, 5, 2f + 23f * e.finpow(), (x, y) -> {
- Fill.circle(e.x + x, e.y + y, e.fout() * 3f + 0.5f);
- });
+ color(Color.gray);
- Draw.color(Pal.lighterOrange);
- Lines.stroke(1f * e.fout());
+ randLenVectors(e.id, 7, 2f + 28f * e.finpow(), (x, y) -> {
+ Fill.circle(e.x + x, e.y + y, e.fout() * 4f + 0.5f);
+ });
- Angles.randLenVectors(e.id + 1, 4, 1f + 23f * e.finpow(), (x, y) -> {
- Lines.lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), 1f + e.fout() * 3f);
- });
+ color(Pal.plastaniumBack);
+ stroke(1f * e.fout());
+ randLenVectors(e.id + 1, 4, 1f + 25f * e.finpow(), (x, y) -> {
+ lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), 1f + e.fout() * 3f);
});
- plasticExplosion = new Effect(24, e -> {
+ }),
- Draw.color(Pal.plastaniumFront);
- e.scaled(7, i -> {
- Lines.stroke(3f * i.fout());
- Lines.circle(e.x, e.y, 3f + i.fin() * 24f);
- });
+ plasticExplosionFlak = new Effect(28, e -> {
- Draw.color(Color.gray);
+ color(Pal.plastaniumFront);
+ e.scaled(7, i -> {
+ stroke(3f * i.fout());
+ Lines.circle(e.x, e.y, 3f + i.fin() * 34f);
+ });
- Angles.randLenVectors(e.id, 7, 2f + 28f * e.finpow(), (x, y) -> {
- Fill.circle(e.x + x, e.y + y, e.fout() * 4f + 0.5f);
- });
+ color(Color.gray);
- Draw.color(Pal.plastaniumBack);
- Lines.stroke(1f * e.fout());
+ randLenVectors(e.id, 7, 2f + 30f * e.finpow(), (x, y) -> {
+ Fill.circle(e.x + x, e.y + y, e.fout() * 4f + 0.5f);
+ });
- Angles.randLenVectors(e.id + 1, 4, 1f + 25f * e.finpow(), (x, y) -> {
- Lines.lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), 1f + e.fout() * 3f);
- });
+ color(Pal.plastaniumBack);
+ stroke(1f * e.fout());
+ randLenVectors(e.id + 1, 4, 1f + 30f * e.finpow(), (x, y) -> {
+ lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), 1f + e.fout() * 3f);
});
- plasticExplosionFlak = new Effect(28, e -> {
+ }),
- Draw.color(Pal.plastaniumFront);
- e.scaled(7, i -> {
- Lines.stroke(3f * i.fout());
- Lines.circle(e.x, e.y, 3f + i.fin() * 34f);
- });
+ blastExplosion = new Effect(22, e -> {
- Draw.color(Color.gray);
+ color(Pal.missileYellow);
+ e.scaled(6, i -> {
+ stroke(3f * i.fout());
+ Lines.circle(e.x, e.y, 3f + i.fin() * 15f);
+ });
- Angles.randLenVectors(e.id, 7, 2f + 30f * e.finpow(), (x, y) -> {
- Fill.circle(e.x + x, e.y + y, e.fout() * 4f + 0.5f);
- });
+ color(Color.gray);
- Draw.color(Pal.plastaniumBack);
- Lines.stroke(1f * e.fout());
+ randLenVectors(e.id, 5, 2f + 23f * e.finpow(), (x, y) -> {
+ Fill.circle(e.x + x, e.y + y, e.fout() * 4f + 0.5f);
+ });
- Angles.randLenVectors(e.id + 1, 4, 1f + 30f * e.finpow(), (x, y) -> {
- Lines.lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), 1f + e.fout() * 3f);
- });
+ color(Pal.missileYellowBack);
+ stroke(1f * e.fout());
+ randLenVectors(e.id + 1, 4, 1f + 23f * e.finpow(), (x, y) -> {
+ lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), 1f + e.fout() * 3f);
});
- blastExplosion = new Effect(22, e -> {
+ }),
- Draw.color(Pal.missileYellow);
- e.scaled(6, i -> {
- Lines.stroke(3f * i.fout());
- Lines.circle(e.x, e.y, 3f + i.fin() * 15f);
- });
+ artilleryTrail = new Effect(50, e -> {
+ color(e.color);
+ Fill.circle(e.x, e.y, e.rotation * e.fout());
+ }),
- Draw.color(Color.gray);
+ incendTrail = new Effect(50, e -> {
+ color(Pal.lightOrange);
+ Fill.circle(e.x, e.y, e.rotation * e.fout());
+ }),
- Angles.randLenVectors(e.id, 5, 2f + 23f * e.finpow(), (x, y) -> {
- Fill.circle(e.x + x, e.y + y, e.fout() * 4f + 0.5f);
- });
+ missileTrail = new Effect(50, e -> {
+ color(e.color);
+ Fill.circle(e.x, e.y, e.rotation * e.fout());
+ }),
- Draw.color(Pal.missileYellowBack);
- Lines.stroke(1f * e.fout());
+ absorb = new Effect(12, e -> {
+ color(Pal.accent);
+ stroke(2f * e.fout());
+ Lines.circle(e.x, e.y, 5f * e.fout());
+ }),
- Angles.randLenVectors(e.id + 1, 4, 1f + 23f * e.finpow(), (x, y) -> {
- Lines.lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), 1f + e.fout() * 3f);
- });
+ flakExplosionBig = new Effect(30, e -> {
+ color(Pal.bulletYellowBack);
+ e.scaled(6, i -> {
+ stroke(3f * i.fout());
+ Lines.circle(e.x, e.y, 3f + i.fin() * 25f);
});
- artilleryTrail = new Effect(50, e -> {
- Draw.color(e.color);
- Fill.circle(e.x, e.y, e.rotation * e.fout());
- });
+ color(Color.gray);
- incendTrail = new Effect(50, e -> {
- Draw.color(Pal.lightOrange);
- Fill.circle(e.x, e.y, e.rotation * e.fout());
+ randLenVectors(e.id, 6, 2f + 23f * e.finpow(), (x, y) -> {
+ Fill.circle(e.x + x, e.y + y, e.fout() * 4f + 0.5f);
});
- missileTrail = new Effect(50, e -> {
- Draw.color(e.color);
- Fill.circle(e.x, e.y, e.rotation * e.fout());
- });
+ color(Pal.bulletYellow);
+ stroke(1f * e.fout());
- absorb = new Effect(12, e -> {
- Draw.color(Pal.accent);
- Lines.stroke(2f * e.fout());
- Lines.circle(e.x, e.y, 5f * e.fout());
+ randLenVectors(e.id + 1, 4, 1f + 23f * e.finpow(), (x, y) -> {
+ lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), 1f + e.fout() * 3f);
});
- flakExplosionBig = new Effect(30, e -> {
+ }),
- Draw.color(Pal.bulletYellowBack);
- e.scaled(6, i -> {
- Lines.stroke(3f * i.fout());
- Lines.circle(e.x, e.y, 3f + i.fin() * 25f);
- });
-
- Draw.color(Color.gray);
-
- Angles.randLenVectors(e.id, 6, 2f + 23f * e.finpow(), (x, y) -> {
- Fill.circle(e.x + x, e.y + y, e.fout() * 4f + 0.5f);
- });
-
- Draw.color(Pal.bulletYellow);
- Lines.stroke(1f * e.fout());
-
- Angles.randLenVectors(e.id + 1, 4, 1f + 23f * e.finpow(), (x, y) -> {
- Lines.lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), 1f + e.fout() * 3f);
- });
+ burning = new Effect(35f, e -> {
+ color(Pal.lightFlame, Pal.darkFlame, e.fin());
+ randLenVectors(e.id, 3, 2f + e.fin() * 7f, (x, y) -> {
+ Fill.circle(e.x + x, e.y + y, 0.1f + e.fout() * 1.4f);
});
+ }),
- burning = new Effect(35f, e -> {
- Draw.color(Pal.lightFlame, Pal.darkFlame, e.fin());
-
- Angles.randLenVectors(e.id, 3, 2f + e.fin() * 7f, (x, y) -> {
- Fill.circle(e.x + x, e.y + y, 0.1f + e.fout() * 1.4f);
- });
+ fire = new Effect(50f, e -> {
+ color(Pal.lightFlame, Pal.darkFlame, e.fin());
+ randLenVectors(e.id, 2, 2f + e.fin() * 9f, (x, y) -> {
+ Fill.circle(e.x + x, e.y + y, 0.2f + e.fslope() * 1.5f);
});
- fire = new Effect(50f, e -> {
- Draw.color(Pal.lightFlame, Pal.darkFlame, e.fin());
+ color();
- Angles.randLenVectors(e.id, 2, 2f + e.fin() * 9f, (x, y) -> {
- Fill.circle(e.x + x, e.y + y, 0.2f + e.fslope() * 1.5f);
- });
+ renderer.lights.add(e.x, e.y, 20f * e.fslope(), Pal.lightFlame, 0.5f);
+ }),
- Draw.color();
+ fireSmoke = new Effect(35f, e -> {
+ color(Color.gray);
- renderer.lights.add(e.x, e.y, 20f * e.fslope(), Pal.lightFlame, 0.5f);
+ randLenVectors(e.id, 1, 2f + e.fin() * 7f, (x, y) -> {
+ Fill.circle(e.x + x, e.y + y, 0.2f + e.fslope() * 1.5f);
});
- fireSmoke = new Effect(35f, e -> {
- Draw.color(Color.gray);
+ }),
- Angles.randLenVectors(e.id, 1, 2f + e.fin() * 7f, (x, y) -> {
- Fill.circle(e.x + x, e.y + y, 0.2f + e.fslope() * 1.5f);
- });
+ steam = new Effect(35f, e -> {
+ color(Color.lightGray);
+ randLenVectors(e.id, 2, 2f + e.fin() * 7f, (x, y) -> {
+ Fill.circle(e.x + x, e.y + y, 0.2f + e.fslope() * 1.5f);
});
- steam = new Effect(35f, e -> {
- Draw.color(Color.lightGray);
+ }),
- Angles.randLenVectors(e.id, 2, 2f + e.fin() * 7f, (x, y) -> {
- Fill.circle(e.x + x, e.y + y, 0.2f + e.fslope() * 1.5f);
- });
+ fireballsmoke = new Effect(25f, e -> {
+ color(Color.gray);
+ randLenVectors(e.id, 1, 2f + e.fin() * 7f, (x, y) -> {
+ Fill.circle(e.x + x, e.y + y, 0.2f + e.fout() * 1.5f);
});
- fireballsmoke = new Effect(25f, e -> {
- Draw.color(Color.gray);
+ }),
- Angles.randLenVectors(e.id, 1, 2f + e.fin() * 7f, (x, y) -> {
- Fill.circle(e.x + x, e.y + y, 0.2f + e.fout() * 1.5f);
- });
+ ballfire = new Effect(25f, e -> {
+ color(Pal.lightFlame, Pal.darkFlame, e.fin());
+ randLenVectors(e.id, 2, 2f + e.fin() * 7f, (x, y) -> {
+ Fill.circle(e.x + x, e.y + y, 0.2f + e.fout() * 1.5f);
});
- ballfire = new Effect(25f, e -> {
- Draw.color(Pal.lightFlame, Pal.darkFlame, e.fin());
+ }),
- Angles.randLenVectors(e.id, 2, 2f + e.fin() * 7f, (x, y) -> {
- Fill.circle(e.x + x, e.y + y, 0.2f + e.fout() * 1.5f);
- });
+ freezing = new Effect(40f, e -> {
+ color(Liquids.cryofluid.color);
+ randLenVectors(e.id, 2, 1f + e.fin() * 2f, (x, y) -> {
+ Fill.circle(e.x + x, e.y + y, e.fout() * 1.2f);
});
- freezing = new Effect(40f, e -> {
- Draw.color(Liquids.cryofluid.color);
+ }),
- Angles.randLenVectors(e.id, 2, 1f + e.fin() * 2f, (x, y) -> {
- Fill.circle(e.x + x, e.y + y, e.fout() * 1.2f);
- });
+ melting = new Effect(40f, e -> {
+ color(Liquids.slag.color, Color.white, e.fout() / 5f + Mathf.randomSeedRange(e.id, 0.12f));
+ randLenVectors(e.id, 2, 1f + e.fin() * 3f, (x, y) -> {
+ Fill.circle(e.x + x, e.y + y, .2f + e.fout() * 1.2f);
});
- melting = new Effect(40f, e -> {
- Draw.color(Liquids.slag.color, Color.white, e.fout() / 5f + Mathf.randomSeedRange(e.id, 0.12f));
+ }),
- Angles.randLenVectors(e.id, 2, 1f + e.fin() * 3f, (x, y) -> {
- Fill.circle(e.x + x, e.y + y, .2f + e.fout() * 1.2f);
- });
+ wet = new Effect(40f, e -> {
+ color(Liquids.water.color);
+ randLenVectors(e.id, 2, 1f + e.fin() * 2f, (x, y) -> {
+ Fill.circle(e.x + x, e.y + y, e.fout() * 1f);
});
- wet = new Effect(40f, e -> {
- Draw.color(Liquids.water.color);
+ }),
- Angles.randLenVectors(e.id, 2, 1f + e.fin() * 2f, (x, y) -> {
- Fill.circle(e.x + x, e.y + y, e.fout() * 1f);
- });
+ oily = new Effect(42f, e -> {
+ color(Liquids.oil.color);
+ randLenVectors(e.id, 2, 1f + e.fin() * 2f, (x, y) -> {
+ Fill.circle(e.x + x, e.y + y, e.fout() * 1f);
});
- oily = new Effect(42f, e -> {
- Draw.color(Liquids.oil.color);
+ }),
- Angles.randLenVectors(e.id, 2, 1f + e.fin() * 2f, (x, y) -> {
- Fill.circle(e.x + x, e.y + y, e.fout() * 1f);
- });
+ overdriven = new Effect(20f, e -> {
+ color(Pal.accent);
+ randLenVectors(e.id, 2, 1f + e.fin() * 2f, (x, y) -> {
+ Fill.square(e.x + x, e.y + y, e.fout() * 2.3f + 0.5f);
});
- overdriven = new Effect(20f, e -> {
- Draw.color(Pal.accent);
+ }),
- Angles.randLenVectors(e.id, 2, 1f + e.fin() * 2f, (x, y) -> {
- Fill.square(e.x + x, e.y + y, e.fout() * 2.3f + 0.5f);
- });
+ dropItem = new Effect(20f, e -> {
+ float length = 20f * e.finpow();
+ float size = 7f * e.fout();
- });
+ rect(((Item)e.data).icon(Cicon.medium), e.x + trnsx(e.rotation, length), e.y + trnsy(e.rotation, length), size, size);
+ }),
- dropItem = new Effect(20f, e -> {
- float length = 20f * e.finpow();
- float size = 7f * e.fout();
+ shockwave = new Effect(10f, 80f, e -> {
+ color(Color.white, Color.lightGray, e.fin());
+ stroke(e.fout() * 2f + 0.2f);
+ Lines.circle(e.x, e.y, e.fin() * 28f);
+ }),
- Draw.rect(((Item)e.data).icon(Cicon.medium), e.x + Angles.trnsx(e.rotation, length), e.y + Angles.trnsy(e.rotation, length), size, size);
- });
+ bigShockwave = new Effect(10f, 80f, e -> {
+ color(Color.white, Color.lightGray, e.fin());
+ stroke(e.fout() * 3f);
+ Lines.circle(e.x, e.y, e.fin() * 50f);
+ }),
+ nuclearShockwave = new Effect(10f, 200f, e -> {
+ color(Color.white, Color.lightGray, e.fin());
+ stroke(e.fout() * 3f + 0.2f);
+ Lines.circle(e.x, e.y, e.fin() * 140f);
+ }),
- shockwave = new Effect(10f, 80f, e -> {
- Draw.color(Color.white, Color.lightGray, e.fin());
- Lines.stroke(e.fout() * 2f + 0.2f);
- Lines.circle(e.x, e.y, e.fin() * 28f);
- });
+ impactShockwave = new Effect(13f, 300f, e -> {
+ color(Pal.lighterOrange, Color.lightGray, e.fin());
+ stroke(e.fout() * 4f + 0.2f);
+ Lines.circle(e.x, e.y, e.fin() * 200f);
+ }),
- bigShockwave = new Effect(10f, 80f, e -> {
- Draw.color(Color.white, Color.lightGray, e.fin());
- Lines.stroke(e.fout() * 3f);
- Lines.circle(e.x, e.y, e.fin() * 50f);
- });
+ spawnShockwave = new Effect(20f, 400f, e -> {
+ color(Color.white, Color.lightGray, e.fin());
+ stroke(e.fout() * 3f + 0.5f);
+ Lines.circle(e.x, e.y, e.fin() * (e.rotation + 50f));
+ }),
- nuclearShockwave = new Effect(10f, 200f, e -> {
- Draw.color(Color.white, Color.lightGray, e.fin());
- Lines.stroke(e.fout() * 3f + 0.2f);
- Lines.circle(e.x, e.y, e.fin() * 140f);
+ explosion = new Effect(30, e -> {
+ e.scaled(7, i -> {
+ stroke(3f * i.fout());
+ Lines.circle(e.x, e.y, 3f + i.fin() * 10f);
});
- impactShockwave = new Effect(13f, 300f, e -> {
- Draw.color(Pal.lighterOrange, Color.lightGray, e.fin());
- Lines.stroke(e.fout() * 4f + 0.2f);
- Lines.circle(e.x, e.y, e.fin() * 200f);
- });
+ color(Color.gray);
- spawnShockwave = new Effect(20f, 400f, e -> {
- Draw.color(Color.white, Color.lightGray, e.fin());
- Lines.stroke(e.fout() * 3f + 0.5f);
- Lines.circle(e.x, e.y, e.fin() * (e.rotation + 50f));
+ randLenVectors(e.id, 6, 2f + 19f * e.finpow(), (x, y) -> {
+ Fill.circle(e.x + x, e.y + y, e.fout() * 3f + 0.5f);
+ Fill.circle(e.x + x / 2f, e.y + y / 2f, e.fout() * 1f);
});
- explosion = new Effect(30, e -> {
- e.scaled(7, i -> {
- Lines.stroke(3f * i.fout());
- Lines.circle(e.x, e.y, 3f + i.fin() * 10f);
- });
-
- Draw.color(Color.gray);
-
- Angles.randLenVectors(e.id, 6, 2f + 19f * e.finpow(), (x, y) -> {
- Fill.circle(e.x + x, e.y + y, e.fout() * 3f + 0.5f);
- Fill.circle(e.x + x / 2f, e.y + y / 2f, e.fout() * 1f);
- });
-
- Draw.color(Pal.lighterOrange, Pal.lightOrange, Color.gray, e.fin());
- Lines.stroke(1.5f * e.fout());
-
- Angles.randLenVectors(e.id + 1, 8, 1f + 23f * e.finpow(), (x, y) -> {
- Lines.lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), 1f + e.fout() * 3f);
- });
+ color(Pal.lighterOrange, Pal.lightOrange, Color.gray, e.fin());
+ stroke(1.5f * e.fout());
+ randLenVectors(e.id + 1, 8, 1f + 23f * e.finpow(), (x, y) -> {
+ lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), 1f + e.fout() * 3f);
});
+ }),
- dynamicExplosion = new Effect(30, e -> {
- float intensity = e.rotation;
-
- e.scaled(5 + intensity * 2, i -> {
- Lines.stroke(3.1f * i.fout());
- Lines.circle(e.x, e.y, (3f + i.fin() * 14f) * intensity);
- });
-
- Draw.color(Color.gray);
-
- Angles.randLenVectors(e.id, e.finpow(), (int)(6 * intensity), 21f * intensity, (x, y, in, out) -> {
- Fill.circle(e.x + x, e.y + y, out * (2f + intensity) * 3 + 0.5f);
- Fill.circle(e.x + x / 2f, e.y + y / 2f, out * (intensity) * 3);
- });
-
- Draw.color(Pal.lighterOrange, Pal.lightOrange, Color.gray, e.fin());
- Lines.stroke((1.7f * e.fout()) * (1f + (intensity - 1f) / 2f));
-
- Angles.randLenVectors(e.id + 1, e.finpow(), (int)(9 * intensity), 40f * intensity, (x, y, in, out) -> {
- Lines.lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), 1f + out * 4 * (3f + intensity));
- });
+ dynamicExplosion = new Effect(30, e -> {
+ float intensity = e.rotation;
+ e.scaled(5 + intensity * 2, i -> {
+ stroke(3.1f * i.fout());
+ Lines.circle(e.x, e.y, (3f + i.fin() * 14f) * intensity);
});
- blockExplosion = new Effect(30, e -> {
- e.scaled(7, i -> {
- Lines.stroke(3.1f * i.fout());
- Lines.circle(e.x, e.y, 3f + i.fin() * 14f);
- });
-
- Draw.color(Color.gray);
-
- Angles.randLenVectors(e.id, 6, 2f + 19f * e.finpow(), (x, y) -> {
- Fill.circle(e.x + x, e.y + y, e.fout() * 3f + 0.5f);
- Fill.circle(e.x + x / 2f, e.y + y / 2f, e.fout() * 1f);
- });
+ color(Color.gray);
- Draw.color(Pal.lighterOrange, Pal.lightOrange, Color.gray, e.fin());
- Lines.stroke(1.7f * e.fout());
+ randLenVectors(e.id, e.finpow(), (int)(6 * intensity), 21f * intensity, (x, y, in, out) -> {
+ Fill.circle(e.x + x, e.y + y, out * (2f + intensity) * 3 + 0.5f);
+ Fill.circle(e.x + x / 2f, e.y + y / 2f, out * (intensity) * 3);
+ });
- Angles.randLenVectors(e.id + 1, 9, 1f + 23f * e.finpow(), (x, y) -> {
- Lines.lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), 1f + e.fout() * 3f);
- });
+ color(Pal.lighterOrange, Pal.lightOrange, Color.gray, e.fin());
+ stroke((1.7f * e.fout()) * (1f + (intensity - 1f) / 2f));
+ randLenVectors(e.id + 1, e.finpow(), (int)(9 * intensity), 40f * intensity, (x, y, in, out) -> {
+ lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), 1f + out * 4 * (3f + intensity));
});
+ }),
- blockExplosionSmoke = new Effect(30, e -> {
- Draw.color(Color.gray);
+ blockExplosion = new Effect(30, e -> {
+ e.scaled(7, i -> {
+ stroke(3.1f * i.fout());
+ Lines.circle(e.x, e.y, 3f + i.fin() * 14f);
+ });
- Angles.randLenVectors(e.id, 6, 4f + 30f * e.finpow(), (x, y) -> {
- Fill.circle(e.x + x, e.y + y, e.fout() * 3f);
- Fill.circle(e.x + x / 2f, e.y + y / 2f, e.fout() * 1f);
- });
+ color(Color.gray);
+ randLenVectors(e.id, 6, 2f + 19f * e.finpow(), (x, y) -> {
+ Fill.circle(e.x + x, e.y + y, e.fout() * 3f + 0.5f);
+ Fill.circle(e.x + x / 2f, e.y + y / 2f, e.fout() * 1f);
});
+ color(Pal.lighterOrange, Pal.lightOrange, Color.gray, e.fin());
+ stroke(1.7f * e.fout());
- shootSmall = new Effect(8, e -> {
- Draw.color(Pal.lighterOrange, Pal.lightOrange, e.fin());
- float w = 1f + 5 * e.fout();
- Drawf.tri(e.x, e.y, w, 15f * e.fout(), e.rotation);
- Drawf.tri(e.x, e.y, w, 3f * e.fout(), e.rotation + 180f);
+ randLenVectors(e.id + 1, 9, 1f + 23f * e.finpow(), (x, y) -> {
+ lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), 1f + e.fout() * 3f);
});
- shootHeal = new Effect(8, e -> {
- Draw.color(Pal.heal);
- float w = 1f + 5 * e.fout();
- Drawf.tri(e.x, e.y, w, 17f * e.fout(), e.rotation);
- Drawf.tri(e.x, e.y, w, 4f * e.fout(), e.rotation + 180f);
- });
+ }),
- shootSmallSmoke = new Effect(20f, e -> {
- Draw.color(Pal.lighterOrange, Color.lightGray, Color.gray, e.fin());
-
- Angles.randLenVectors(e.id, 5, e.finpow() * 6f, e.rotation, 20f, (x, y) -> {
- Fill.circle(e.x + x, e.y + y, e.fout() * 1.5f);
- });
+ blockExplosionSmoke = new Effect(30, e -> {
+ color(Color.gray);
+ randLenVectors(e.id, 6, 4f + 30f * e.finpow(), (x, y) -> {
+ Fill.circle(e.x + x, e.y + y, e.fout() * 3f);
+ Fill.circle(e.x + x / 2f, e.y + y / 2f, e.fout() * 1f);
});
- shootBig = new Effect(9, e -> {
- Draw.color(Pal.lighterOrange, Pal.lightOrange, e.fin());
- float w = 1.2f + 7 * e.fout();
- Drawf.tri(e.x, e.y, w, 25f * e.fout(), e.rotation);
- Drawf.tri(e.x, e.y, w, 4f * e.fout(), e.rotation + 180f);
- });
+ }),
- shootBig2 = new Effect(10, e -> {
- Draw.color(Pal.lightOrange, Color.gray, e.fin());
- float w = 1.2f + 8 * e.fout();
- Drawf.tri(e.x, e.y, w, 29f * e.fout(), e.rotation);
- Drawf.tri(e.x, e.y, w, 5f * e.fout(), e.rotation + 180f);
- });
+ shootSmall = new Effect(8, e -> {
+ color(Pal.lighterOrange, Pal.lightOrange, e.fin());
+ float w = 1f + 5 * e.fout();
+ Drawf.tri(e.x, e.y, w, 15f * e.fout(), e.rotation);
+ Drawf.tri(e.x, e.y, w, 3f * e.fout(), e.rotation + 180f);
+ }),
- shootBigSmoke = new Effect(17f, e -> {
- Draw.color(Pal.lighterOrange, Color.lightGray, Color.gray, e.fin());
+ shootHeal = new Effect(8, e -> {
+ color(Pal.heal);
+ float w = 1f + 5 * e.fout();
+ Drawf.tri(e.x, e.y, w, 17f * e.fout(), e.rotation);
+ Drawf.tri(e.x, e.y, w, 4f * e.fout(), e.rotation + 180f);
+ }),
- Angles.randLenVectors(e.id, 8, e.finpow() * 19f, e.rotation, 10f, (x, y) -> {
- Fill.circle(e.x + x, e.y + y, e.fout() * 2f + 0.2f);
- });
+ shootHealYellow = new Effect(8, e -> {
+ color(Pal.lightTrail);
+ float w = 1f + 5 * e.fout();
+ Drawf.tri(e.x, e.y, w, 17f * e.fout(), e.rotation);
+ Drawf.tri(e.x, e.y, w, 4f * e.fout(), e.rotation + 180f);
+ }),
+
+ shootSmallSmoke = new Effect(20f, e -> {
+ color(Pal.lighterOrange, Color.lightGray, Color.gray, e.fin());
+ randLenVectors(e.id, 5, e.finpow() * 6f, e.rotation, 20f, (x, y) -> {
+ Fill.circle(e.x + x, e.y + y, e.fout() * 1.5f);
});
- shootBigSmoke2 = new Effect(18f, e -> {
- Draw.color(Pal.lightOrange, Color.lightGray, Color.gray, e.fin());
+ }),
- Angles.randLenVectors(e.id, 9, e.finpow() * 23f, e.rotation, 20f, (x, y) -> {
- Fill.circle(e.x + x, e.y + y, e.fout() * 2.4f + 0.2f);
- });
+ shootBig = new Effect(9, e -> {
+ color(Pal.lighterOrange, Pal.lightOrange, e.fin());
+ float w = 1.2f + 7 * e.fout();
+ Drawf.tri(e.x, e.y, w, 25f * e.fout(), e.rotation);
+ Drawf.tri(e.x, e.y, w, 4f * e.fout(), e.rotation + 180f);
+ }),
- });
-
- shootSmallFlame = new Effect(32f, e -> {
- Draw.color(Pal.lightFlame, Pal.darkFlame, Color.gray, e.fin());
+ shootBig2 = new Effect(10, e -> {
+ color(Pal.lightOrange, Color.gray, e.fin());
+ float w = 1.2f + 8 * e.fout();
+ Drawf.tri(e.x, e.y, w, 29f * e.fout(), e.rotation);
+ Drawf.tri(e.x, e.y, w, 5f * e.fout(), e.rotation + 180f);
+ }),
- Angles.randLenVectors(e.id, 8, e.finpow() * 60f, e.rotation, 10f, (x, y) -> {
- Fill.circle(e.x + x, e.y + y, 0.65f + e.fout() * 1.5f);
- });
+ shootBigSmoke = new Effect(17f, e -> {
+ color(Pal.lighterOrange, Color.lightGray, Color.gray, e.fin());
+ randLenVectors(e.id, 8, e.finpow() * 19f, e.rotation, 10f, (x, y) -> {
+ Fill.circle(e.x + x, e.y + y, e.fout() * 2f + 0.2f);
});
- shootPyraFlame = new Effect(33f, e -> {
- Draw.color(Pal.lightPyraFlame, Pal.darkPyraFlame, Color.gray, e.fin());
+ }),
- Angles.randLenVectors(e.id, 10, e.finpow() * 70f, e.rotation, 10f, (x, y) -> {
- Fill.circle(e.x + x, e.y + y, 0.65f + e.fout() * 1.6f);
- });
+ shootBigSmoke2 = new Effect(18f, e -> {
+ color(Pal.lightOrange, Color.lightGray, Color.gray, e.fin());
+ randLenVectors(e.id, 9, e.finpow() * 23f, e.rotation, 20f, (x, y) -> {
+ Fill.circle(e.x + x, e.y + y, e.fout() * 2.4f + 0.2f);
});
- shootLiquid = new Effect(40f, e -> {
- Draw.color(e.color, Color.white, e.fout() / 6f + Mathf.randomSeedRange(e.id, 0.1f));
+ }),
- Angles.randLenVectors(e.id, 6, e.finpow() * 60f, e.rotation, 11f, (x, y) -> {
- Fill.circle(e.x + x, e.y + y, 0.5f + e.fout() * 2.5f);
- });
+ shootSmallFlame = new Effect(32f, e -> {
+ color(Pal.lightFlame, Pal.darkFlame, Color.gray, e.fin());
+ randLenVectors(e.id, 8, e.finpow() * 60f, e.rotation, 10f, (x, y) -> {
+ Fill.circle(e.x + x, e.y + y, 0.65f + e.fout() * 1.5f);
});
- shellEjectSmall = new GroundEffect(30f, 400f, e -> {
- Draw.color(Pal.lightOrange, Color.lightGray, Pal.lightishGray, e.fin());
- float rot = Math.abs(e.rotation) + 90f;
+ }),
- int i = Mathf.sign(e.rotation);
-
- float len = (2f + e.finpow() * 6f) * i;
- float lr = rot + e.fin() * 30f * i;
- Fill.rect(e.x + Angles.trnsx(lr, len) + Mathf.randomSeedRange(e.id + i + 7, 3f * e.fin()),
- e.y + Angles.trnsy(lr, len) + Mathf.randomSeedRange(e.id + i + 8, 3f * e.fin()),
- 1f, 2f, rot + e.fin() * 50f * i);
+ shootPyraFlame = new Effect(33f, e -> {
+ color(Pal.lightPyraFlame, Pal.darkPyraFlame, Color.gray, e.fin());
+ randLenVectors(e.id, 10, e.finpow() * 70f, e.rotation, 10f, (x, y) -> {
+ Fill.circle(e.x + x, e.y + y, 0.65f + e.fout() * 1.6f);
});
- shellEjectMedium = new GroundEffect(34f, 400f, e -> {
- Draw.color(Pal.lightOrange, Color.lightGray, Pal.lightishGray, e.fin());
- float rot = e.rotation + 90f;
- for(int i : Mathf.signs){
- float len = (2f + e.finpow() * 10f) * i;
- float lr = rot + e.fin() * 20f * i;
- Draw.rect(Core.atlas.find("casing"),
- e.x + Angles.trnsx(lr, len) + Mathf.randomSeedRange(e.id + i + 7, 3f * e.fin()),
- e.y + Angles.trnsy(lr, len) + Mathf.randomSeedRange(e.id + i + 8, 3f * e.fin()),
- 2f, 3f, rot);
- }
-
- Draw.color(Color.lightGray, Color.gray, e.fin());
+ }),
- for(int i : Mathf.signs){
- float ex = e.x, ey = e.y, fout = e.fout();
- Angles.randLenVectors(e.id, 4, 1f + e.finpow() * 11f, e.rotation + 90f * i, 20f, (x, y) -> {
- Fill.circle(ex + x, ey + y, fout * 1.5f);
- });
- }
+ shootLiquid = new Effect(40f, e -> {
+ color(e.color, Color.white, e.fout() / 6f + Mathf.randomSeedRange(e.id, 0.1f));
+ randLenVectors(e.id, 6, e.finpow() * 60f, e.rotation, 11f, (x, y) -> {
+ Fill.circle(e.x + x, e.y + y, 0.5f + e.fout() * 2.5f);
});
- shellEjectBig = new GroundEffect(22f, 400f, e -> {
- Draw.color(Pal.lightOrange, Color.lightGray, Pal.lightishGray, e.fin());
- float rot = e.rotation + 90f;
- for(int i : Mathf.signs){
- float len = (4f + e.finpow() * 8f) * i;
- float lr = rot + Mathf.randomSeedRange(e.id + i + 6, 20f * e.fin()) * i;
- Draw.rect(Core.atlas.find("casing"),
- e.x + Angles.trnsx(lr, len) + Mathf.randomSeedRange(e.id + i + 7, 3f * e.fin()),
- e.y + Angles.trnsy(lr, len) + Mathf.randomSeedRange(e.id + i + 8, 3f * e.fin()),
- 2.5f, 4f,
- rot + e.fin() * 30f * i + Mathf.randomSeedRange(e.id + i + 9, 40f * e.fin()));
- }
-
- Draw.color(Color.lightGray);
+ }),
- for(int i : Mathf.signs){
- float ex = e.x, ey = e.y, fout = e.fout();
- Angles.randLenVectors(e.id, 4, -e.finpow() * 15f, e.rotation + 90f * i, 25f, (x, y) -> {
- Fill.circle(ex + x, ey + y, fout * 2f);
- });
- }
+ shellEjectSmall = new Effect(30f, e -> {
+ color(Pal.lightOrange, Color.lightGray, Pal.lightishGray, e.fin());
+ float rot = Math.abs(e.rotation) + 90f;
- });
+ int i = Mathf.sign(e.rotation);
- lancerLaserShoot = new Effect(21f, e -> {
- Draw.color(Pal.lancerLaser);
+ float len = (2f + e.finpow() * 6f) * i;
+ float lr = rot + e.fin() * 30f * i;
+ Fill.rect(e.x + trnsx(lr, len) + Mathf.randomSeedRange(e.id + i + 7, 3f * e.fin()),
+ e.y + trnsy(lr, len) + Mathf.randomSeedRange(e.id + i + 8, 3f * e.fin()),
+ 1f, 2f, rot + e.fin() * 50f * i);
- for(int i : Mathf.signs){
- Drawf.tri(e.x, e.y, 4f * e.fout(), 29f, e.rotation + 90f * i);
- }
+ }).ground(400f),
- });
+ shellEjectMedium = new Effect(34f, e -> {
+ color(Pal.lightOrange, Color.lightGray, Pal.lightishGray, e.fin());
+ float rot = e.rotation + 90f;
+ for(int i : Mathf.signs){
+ float len = (2f + e.finpow() * 10f) * i;
+ float lr = rot + e.fin() * 20f * i;
+ rect(Core.atlas.find("casing"),
+ e.x + trnsx(lr, len) + Mathf.randomSeedRange(e.id + i + 7, 3f * e.fin()),
+ e.y + trnsy(lr, len) + Mathf.randomSeedRange(e.id + i + 8, 3f * e.fin()),
+ 2f, 3f, rot);
+ }
- lancerLaserShootSmoke = new Effect(26f, e -> {
- Draw.color(Pal.lancerLaser);
+ color(Color.lightGray, Color.gray, e.fin());
- Angles.randLenVectors(e.id, 7, 80f, e.rotation, 0f, (x, y) -> {
- Lines.lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), e.fout() * 9f);
+ for(int i : Mathf.signs){
+ float ex = e.x, ey = e.y, fout = e.fout();
+ randLenVectors(e.id, 4, 1f + e.finpow() * 11f, e.rotation + 90f * i, 20f, (x, y) -> {
+ Fill.circle(ex + x, ey + y, fout * 1.5f);
});
+ }
- });
+ }).ground(400f),
- lancerLaserCharge = new Effect(38f, e -> {
- Draw.color(Pal.lancerLaser);
+ shellEjectBig = new Effect(22f, e -> {
+ color(Pal.lightOrange, Color.lightGray, Pal.lightishGray, e.fin());
+ float rot = e.rotation + 90f;
+ for(int i : Mathf.signs){
+ float len = (4f + e.finpow() * 8f) * i;
+ float lr = rot + Mathf.randomSeedRange(e.id + i + 6, 20f * e.fin()) * i;
+ rect(Core.atlas.find("casing"),
+ e.x + trnsx(lr, len) + Mathf.randomSeedRange(e.id + i + 7, 3f * e.fin()),
+ e.y + trnsy(lr, len) + Mathf.randomSeedRange(e.id + i + 8, 3f * e.fin()),
+ 2.5f, 4f,
+ rot + e.fin() * 30f * i + Mathf.randomSeedRange(e.id + i + 9, 40f * e.fin()));
+ }
- Angles.randLenVectors(e.id, 2, 1f + 20f * e.fout(), e.rotation, 120f, (x, y) -> {
- Lines.lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), e.fslope() * 3f + 1f);
+ color(Color.lightGray);
+
+ for(int i : Mathf.signs){
+ float ex = e.x, ey = e.y, fout = e.fout();
+ randLenVectors(e.id, 4, -e.finpow() * 15f, e.rotation + 90f * i, 25f, (x, y) -> {
+ Fill.circle(ex + x, ey + y, fout * 2f);
});
+ }
- });
+ }).ground(400f),
- lancerLaserChargeBegin = new Effect(71f, e -> {
- Draw.color(Pal.lancerLaser);
- Fill.circle(e.x, e.y, e.fin() * 3f);
+ lancerLaserShoot = new Effect(21f, e -> {
+ color(Pal.lancerLaser);
- Draw.color();
- Fill.circle(e.x, e.y, e.fin() * 2f);
- });
+ for(int i : Mathf.signs){
+ Drawf.tri(e.x, e.y, 4f * e.fout(), 29f, e.rotation + 90f * i);
+ }
- lightningCharge = new Effect(38f, e -> {
- Draw.color(Pal.lancerLaser);
+ }),
- Angles.randLenVectors(e.id, 2, 1f + 20f * e.fout(), e.rotation, 120f, (x, y) -> {
- Drawf.tri(e.x + x, e.y + y, e.fslope() * 3f + 1, e.fslope() * 3f + 1, Mathf.angle(x, y));
- });
+ lancerLaserShootSmoke = new Effect(26f, e -> {
+ color(Color.white);
+ randLenVectors(e.id, 7, 70f, e.rotation, 0f, (x, y) -> {
+ lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), e.fout() * 9f);
});
- lightningShoot = new Effect(12f, e -> {
- Draw.color(Color.white, Pal.lancerLaser, e.fin());
- Lines.stroke(e.fout() * 1.2f + 0.5f);
+ }),
- Angles.randLenVectors(e.id, 7, 25f * e.finpow(), e.rotation, 50f, (x, y) -> {
- Lines.lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), e.fin() * 5f + 2f);
- });
+ lancerLaserCharge = new Effect(38f, e -> {
+ color(Pal.lancerLaser);
+ randLenVectors(e.id, 2, 1f + 20f * e.fout(), e.rotation, 120f, (x, y) -> {
+ lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), e.fslope() * 3f + 1f);
});
+ }),
- reactorsmoke = new Effect(17, e -> {
- Angles.randLenVectors(e.id, 4, e.fin() * 8f, (x, y) -> {
- float size = 1f + e.fout() * 5f;
- Draw.color(Color.lightGray, Color.gray, e.fin());
- Draw.rect("circle", e.x + x, e.y + y, size, size);
- });
- });
- nuclearsmoke = new Effect(40, e -> {
- Angles.randLenVectors(e.id, 4, e.fin() * 13f, (x, y) -> {
- float size = e.fslope() * 4f;
- Draw.color(Color.lightGray, Color.gray, e.fin());
- Draw.rect("circle", e.x + x, e.y + y, size, size);
- });
- });
- nuclearcloud = new Effect(90, 200f, e -> {
- Angles.randLenVectors(e.id, 10, e.finpow() * 90f, (x, y) -> {
- float size = e.fout() * 14f;
- Draw.color(Color.lime, Color.gray, e.fin());
- Draw.rect("circle", e.x + x, e.y + y, size, size);
- });
- });
- impactsmoke = new Effect(60, e -> {
- Angles.randLenVectors(e.id, 7, e.fin() * 20f, (x, y) -> {
- float size = e.fslope() * 4f;
- Draw.color(Color.lightGray, Color.gray, e.fin());
- Draw.rect("circle", e.x + x, e.y + y, size, size);
- });
- });
- impactcloud = new Effect(140, 400f, e -> {
- Angles.randLenVectors(e.id, 20, e.finpow() * 160f, (x, y) -> {
- float size = e.fout() * 15f;
- Draw.color(Pal.lighterOrange, Color.lightGray, e.fin());
- Draw.rect("circle", e.x + x, e.y + y, size, size);
- });
- });
- redgeneratespark = new Effect(18, e -> {
- Angles.randLenVectors(e.id, 5, e.fin() * 8f, (x, y) -> {
- float len = e.fout() * 4f;
- Draw.color(Pal.redSpark, Color.gray, e.fin());
- Draw.rect("circle", e.x + x, e.y + y, len, len);
- });
- });
- generatespark = new Effect(18, e -> {
- Angles.randLenVectors(e.id, 5, e.fin() * 8f, (x, y) -> {
- float len = e.fout() * 4f;
- Draw.color(Pal.orangeSpark, Color.gray, e.fin());
- Draw.rect("circle", e.x + x, e.y + y, len, len);
- });
- });
- fuelburn = new Effect(23, e -> {
- Angles.randLenVectors(e.id, 5, e.fin() * 9f, (x, y) -> {
- float len = e.fout() * 4f;
- Draw.color(Color.lightGray, Color.gray, e.fin());
- Draw.rect("circle", e.x + x, e.y + y, len, len);
- });
- });
- plasticburn = new Effect(40, e -> {
- Angles.randLenVectors(e.id, 5, 3f + e.fin() * 5f, (x, y) -> {
- Draw.color(Color.valueOf("e9ead3"), Color.gray, e.fin());
- Fill.circle(e.x + x, e.y + y, e.fout() * 1f);
- });
- });
- pulverize = new Effect(40, e -> {
- Angles.randLenVectors(e.id, 5, 3f + e.fin() * 8f, (x, y) -> {
- Draw.color(Pal.stoneGray);
- Fill.square(e.x + x, e.y + y, e.fout() * 2f + 0.5f, 45);
- });
- });
- pulverizeRed = new Effect(40, e -> {
- Angles.randLenVectors(e.id, 5, 3f + e.fin() * 8f, (x, y) -> {
- Draw.color(Pal.redDust, Pal.stoneGray, e.fin());
- Fill.square(e.x + x, e.y + y, e.fout() * 2f + 0.5f, 45);
- });
- });
- pulverizeRedder = new Effect(40, e -> {
- Angles.randLenVectors(e.id, 5, 3f + e.fin() * 9f, (x, y) -> {
- Draw.color(Pal.redderDust, Pal.stoneGray, e.fin());
- Fill.square(e.x + x, e.y + y, e.fout() * 2.5f + 0.5f, 45);
- });
- });
- pulverizeSmall = new Effect(30, e -> {
- Angles.randLenVectors(e.id, 3, e.fin() * 5f, (x, y) -> {
- Draw.color(Pal.stoneGray);
- Fill.square(e.x + x, e.y + y, e.fout() * 1f + 0.5f, 45);
- });
- });
- pulverizeMedium = new Effect(30, e -> {
- Angles.randLenVectors(e.id, 5, 3f + e.fin() * 8f, (x, y) -> {
- Draw.color(Pal.stoneGray);
- Fill.square(e.x + x, e.y + y, e.fout() * 1f + 0.5f, 45);
- });
- });
- producesmoke = new Effect(12, e -> {
- Angles.randLenVectors(e.id, 8, 4f + e.fin() * 18f, (x, y) -> {
- Draw.color(Color.white, Pal.accent, e.fin());
- Fill.square(e.x + x, e.y + y, 1f + e.fout() * 3f, 45);
- });
- });
- smeltsmoke = new Effect(15, e -> {
- Angles.randLenVectors(e.id, 6, 4f + e.fin() * 5f, (x, y) -> {
- Draw.color(Color.white, e.color, e.fin());
- Fill.square(e.x + x, e.y + y, 0.5f + e.fout() * 2f, 45);
- });
- });
- formsmoke = new Effect(40, e -> {
- Angles.randLenVectors(e.id, 6, 5f + e.fin() * 8f, (x, y) -> {
- Draw.color(Pal.plasticSmoke, Color.lightGray, e.fin());
- Fill.square(e.x + x, e.y + y, 0.2f + e.fout() * 2f, 45);
- });
- });
- blastsmoke = new Effect(26, e -> {
- Angles.randLenVectors(e.id, 12, 1f + e.fin() * 23f, (x, y) -> {
- float size = 2f + e.fout() * 6f;
- Draw.color(Color.lightGray, Color.darkGray, e.fin());
- Draw.rect("circle", e.x + x, e.y + y, size, size);
- });
- });
- lava = new Effect(18, e -> {
- Angles.randLenVectors(e.id, 3, 1f + e.fin() * 10f, (x, y) -> {
- float size = e.fslope() * 4f;
- Draw.color(Color.orange, Color.gray, e.fin());
- Draw.rect("circle", e.x + x, e.y + y, size, size);
- });
- });
- dooropen = new Effect(10, e -> {
- Lines.stroke(e.fout() * 1.6f);
- Lines.square(e.x, e.y, tilesize / 2f + e.fin() * 2f);
- });
- doorclose = new Effect(10, e -> {
- Lines.stroke(e.fout() * 1.6f);
- Lines.square(e.x, e.y, tilesize / 2f + e.fout() * 2f);
- });
- dooropenlarge = new Effect(10, e -> {
- Lines.stroke(e.fout() * 1.6f);
- Lines.square(e.x, e.y, tilesize + e.fin() * 2f);
- });
- doorcloselarge = new Effect(10, e -> {
- Lines.stroke(e.fout() * 1.6f);
- Lines.square(e.x, e.y, tilesize + e.fout() * 2f);
- });
- purify = new Effect(10, e -> {
- Draw.color(Color.royal, Color.gray, e.fin());
- Lines.stroke(2f);
- Lines.spikes(e.x, e.y, e.fin() * 4f, 2, 6);
- });
- purifyoil = new Effect(10, e -> {
- Draw.color(Color.black, Color.gray, e.fin());
- Lines.stroke(2f);
- Lines.spikes(e.x, e.y, e.fin() * 4f, 2, 6);
- });
- purifystone = new Effect(10, e -> {
- Draw.color(Color.orange, Color.gray, e.fin());
- Lines.stroke(2f);
- Lines.spikes(e.x, e.y, e.fin() * 4f, 2, 6);
- });
- generate = new Effect(11, e -> {
- Draw.color(Color.orange, Color.yellow, e.fin());
- Lines.stroke(1f);
- Lines.spikes(e.x, e.y, e.fin() * 5f, 2, 8);
- });
- mine = new Effect(20, e -> {
- Angles.randLenVectors(e.id, 6, 3f + e.fin() * 6f, (x, y) -> {
- Draw.color(e.color, Color.lightGray, e.fin());
- Fill.square(e.x + x, e.y + y, e.fout() * 2f, 45);
- });
- });
- mineBig = new Effect(30, e -> {
- Angles.randLenVectors(e.id, 6, 4f + e.fin() * 8f, (x, y) -> {
- Draw.color(e.color, Color.lightGray, e.fin());
- Fill.square(e.x + x, e.y + y, e.fout() * 2f + 0.2f, 45);
- });
- });
- mineHuge = new Effect(40, e -> {
- Angles.randLenVectors(e.id, 8, 5f + e.fin() * 10f, (x, y) -> {
- Draw.color(e.color, Color.lightGray, e.fin());
- Fill.square(e.x + x, e.y + y, e.fout() * 2f + 0.5f, 45);
- });
- });
- smelt = new Effect(20, e -> {
- Angles.randLenVectors(e.id, 6, 2f + e.fin() * 5f, (x, y) -> {
- Draw.color(Color.white, e.color, e.fin());
- Fill.square(e.x + x, e.y + y, 0.5f + e.fout() * 2f, 45);
- });
- });
- teleportActivate = new Effect(50, e -> {
- Draw.color(e.color);
-
- e.scaled(8f, e2 -> {
- Lines.stroke(e2.fout() * 4f);
- Lines.circle(e2.x, e2.y, 4f + e2.fin() * 27f);
- });
+ lancerLaserChargeBegin = new Effect(60f, e -> {
+ color(Pal.lancerLaser);
+ Fill.circle(e.x, e.y, e.fin() * 3f);
- Lines.stroke(e.fout() * 2f);
+ color();
+ Fill.circle(e.x, e.y, e.fin() * 2f);
+ }),
- Angles.randLenVectors(e.id, 30, 4f + 40f * e.fin(), (x, y) -> {
- Lines.lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), e.fin() * 4f + 1f);
- });
+ lightningCharge = new Effect(38f, e -> {
+ color(Pal.lancerLaser);
+ randLenVectors(e.id, 2, 1f + 20f * e.fout(), e.rotation, 120f, (x, y) -> {
+ Drawf.tri(e.x + x, e.y + y, e.fslope() * 3f + 1, e.fslope() * 3f + 1, Mathf.angle(x, y));
});
- teleport = new Effect(60, e -> {
- Draw.color(e.color);
- Lines.stroke(e.fin() * 2f);
- Lines.circle(e.x, e.y, 7f + e.fout() * 8f);
-
- Angles.randLenVectors(e.id, 20, 6f + 20f * e.fout(), (x, y) -> {
- Lines.lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), e.fin() * 4f + 1f);
- });
- });
- teleportOut = new Effect(20, e -> {
- Draw.color(e.color);
- Lines.stroke(e.fout() * 2f);
- Lines.circle(e.x, e.y, 7f + e.fin() * 8f);
+ }),
- Angles.randLenVectors(e.id, 20, 4f + 20f * e.fin(), (x, y) -> {
- Lines.lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), e.fslope() * 4f + 1f);
- });
+ lightningShoot = new Effect(12f, e -> {
+ color(Color.white, Pal.lancerLaser, e.fin());
+ stroke(e.fout() * 1.2f + 0.5f);
- });
- ripple = new GroundEffect(false, 30, e -> {
- Draw.color(Tmp.c1.set(e.color).mul(1.2f));
- Lines.stroke(e.fout() + 0.4f);
- Lines.circle(e.x, e.y, 2f + e.fin() * 4f);
+ randLenVectors(e.id, 7, 25f * e.finpow(), e.rotation, 50f, (x, y) -> {
+ lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), e.fin() * 5f + 2f);
});
- bubble = new Effect(20, e -> {
- Draw.color(Tmp.c1.set(e.color).shiftValue(0.1f));
- Lines.stroke(e.fout() + 0.2f);
- Angles.randLenVectors(e.id, 2, 8f, (x, y) -> {
- Lines.circle(e.x + x, e.y + y, 1f + e.fin() * 3f);
- });
- });
+ }),
- launch = new Effect(28, e -> {
- Draw.color(Pal.command);
- Lines.stroke(e.fout() * 2f);
- Lines.circle(e.x, e.y, 4f + e.finpow() * 120f);
+ reactorsmoke = new Effect(17, e -> {
+ randLenVectors(e.id, 4, e.fin() * 8f, (x, y) -> {
+ float size = 1f + e.fout() * 5f;
+ color(Color.lightGray, Color.gray, e.fin());
+ Fill.circle(e.x + x, e.y + y, size/2f);
});
+ }),
- healWaveMend = new Effect(40, e -> {
- Draw.color(e.color);
- Lines.stroke(e.fout() * 2f);
- Lines.circle(e.x, e.y, e.finpow() * e.rotation);
+ nuclearsmoke = new Effect(40, e -> {
+ randLenVectors(e.id, 4, e.fin() * 13f, (x, y) -> {
+ float size = e.fslope() * 4f;
+ color(Color.lightGray, Color.gray, e.fin());
+ Fill.circle(e.x + x, e.y + y, size/2f);
});
+ }),
- overdriveWave = new Effect(50, e -> {
- Draw.color(e.color);
- Lines.stroke(e.fout() * 1f);
- Lines.circle(e.x, e.y, e.finpow() * e.rotation);
+ nuclearcloud = new Effect(90, 200f, e -> {
+ randLenVectors(e.id, 10, e.finpow() * 90f, (x, y) -> {
+ float size = e.fout() * 14f;
+ color(Color.lime, Color.gray, e.fin());
+ Fill.circle(e.x + x, e.y + y, size/2f);
});
+ }),
- healBlock = new Effect(20, e -> {
- Draw.color(Pal.heal);
- Lines.stroke(2f * e.fout() + 0.5f);
- Lines.square(e.x, e.y, 1f + (e.fin() * e.rotation * tilesize / 2f - 1f));
+ impactsmoke = new Effect(60, e -> {
+ randLenVectors(e.id, 7, e.fin() * 20f, (x, y) -> {
+ float size = e.fslope() * 4f;
+ color(Color.lightGray, Color.gray, e.fin());
+ Fill.circle(e.x + x, e.y + y, size/2f);
});
+ }),
- healBlockFull = new Effect(20, e -> {
- Draw.color(e.color);
- Draw.alpha(e.fout());
- Fill.square(e.x, e.y, e.rotation * tilesize / 2f);
+ impactcloud = new Effect(140, 400f, e -> {
+ randLenVectors(e.id, 20, e.finpow() * 160f, (x, y) -> {
+ float size = e.fout() * 15f;
+ color(Pal.lighterOrange, Color.lightGray, e.fin());
+ Fill.circle(e.x + x, e.y + y, size/2f);
});
+ }),
- overdriveBlockFull = new Effect(60, e -> {
- Draw.color(e.color);
- Draw.alpha(e.fslope() * 0.4f);
- Fill.square(e.x, e.y, e.rotation * tilesize);
+ redgeneratespark = new Effect(18, e -> {
+ randLenVectors(e.id, 5, e.fin() * 8f, (x, y) -> {
+ float len = e.fout() * 4f;
+ color(Pal.redSpark, Color.gray, e.fin());
+ Fill.circle(e.x + x, e.y + y, len/2f);
});
+ }),
- shieldBreak = new Effect(40, e -> {
- Draw.color(Pal.accent);
- Lines.stroke(3f * e.fout());
- Lines.poly(e.x, e.y, 6, e.rotation + e.fin(), 90);
- });
+ generatespark = new Effect(18, e -> {
+ randLenVectors(e.id, 5, e.fin() * 8f, (x, y) -> {
+ float len = e.fout() * 4f;
+ color(Pal.orangeSpark, Color.gray, e.fin());
+ Fill.circle(e.x + x, e.y + y, len/2f);
+ });
+ }),
+
+ fuelburn = new Effect(23, e -> {
+ randLenVectors(e.id, 5, e.fin() * 9f, (x, y) -> {
+ float len = e.fout() * 4f;
+ color(Color.lightGray, Color.gray, e.fin());
+ Fill.circle(e.x + x, e.y + y, len/2f);
+ });
+ }),
+
+ plasticburn = new Effect(40, e -> {
+ randLenVectors(e.id, 5, 3f + e.fin() * 5f, (x, y) -> {
+ color(Color.valueOf("e9ead3"), Color.gray, e.fin());
+ Fill.circle(e.x + x, e.y + y, e.fout() * 1f);
+ });
+ }),
+
+ pulverize = new Effect(40, e -> {
+ randLenVectors(e.id, 5, 3f + e.fin() * 8f, (x, y) -> {
+ color(Pal.stoneGray);
+ Fill.square(e.x + x, e.y + y, e.fout() * 2f + 0.5f, 45);
+ });
+ }),
+
+ pulverizeRed = new Effect(40, e -> {
+ randLenVectors(e.id, 5, 3f + e.fin() * 8f, (x, y) -> {
+ color(Pal.redDust, Pal.stoneGray, e.fin());
+ Fill.square(e.x + x, e.y + y, e.fout() * 2f + 0.5f, 45);
+ });
+ }),
+
+ pulverizeRedder = new Effect(40, e -> {
+ randLenVectors(e.id, 5, 3f + e.fin() * 9f, (x, y) -> {
+ color(Pal.redderDust, Pal.stoneGray, e.fin());
+ Fill.square(e.x + x, e.y + y, e.fout() * 2.5f + 0.5f, 45);
+ });
+ }),
+
+ pulverizeSmall = new Effect(30, e -> {
+ randLenVectors(e.id, 3, e.fin() * 5f, (x, y) -> {
+ color(Pal.stoneGray);
+ Fill.square(e.x + x, e.y + y, e.fout() * 1f + 0.5f, 45);
+ });
+ }),
+
+ pulverizeMedium = new Effect(30, e -> {
+ randLenVectors(e.id, 5, 3f + e.fin() * 8f, (x, y) -> {
+ color(Pal.stoneGray);
+ Fill.square(e.x + x, e.y + y, e.fout() * 1f + 0.5f, 45);
+ });
+ }),
+
+ producesmoke = new Effect(12, e -> {
+ randLenVectors(e.id, 8, 4f + e.fin() * 18f, (x, y) -> {
+ color(Color.white, Pal.accent, e.fin());
+ Fill.square(e.x + x, e.y + y, 1f + e.fout() * 3f, 45);
+ });
+ }),
+
+ smeltsmoke = new Effect(15, e -> {
+ randLenVectors(e.id, 6, 4f + e.fin() * 5f, (x, y) -> {
+ color(Color.white, e.color, e.fin());
+ Fill.square(e.x + x, e.y + y, 0.5f + e.fout() * 2f, 45);
+ });
+ }),
+
+ formsmoke = new Effect(40, e -> {
+ randLenVectors(e.id, 6, 5f + e.fin() * 8f, (x, y) -> {
+ color(Pal.plasticSmoke, Color.lightGray, e.fin());
+ Fill.square(e.x + x, e.y + y, 0.2f + e.fout() * 2f, 45);
+ });
+ }),
+
+ blastsmoke = new Effect(26, e -> {
+ randLenVectors(e.id, 12, 1f + e.fin() * 23f, (x, y) -> {
+ float size = 2f + e.fout() * 6f;
+ color(Color.lightGray, Color.darkGray, e.fin());
+ Fill.circle(e.x + x, e.y + y, size/2f);
+ });
+ }),
+
+ lava = new Effect(18, e -> {
+ randLenVectors(e.id, 3, 1f + e.fin() * 10f, (x, y) -> {
+ float size = e.fslope() * 4f;
+ color(Color.orange, Color.gray, e.fin());
+ Fill.circle(e.x + x, e.y + y, size/2f);
+ });
+ }),
+
+ dooropen = new Effect(10, e -> {
+ stroke(e.fout() * 1.6f);
+ Lines.square(e.x, e.y, tilesize / 2f + e.fin() * 2f);
+ }),
+
+ doorclose = new Effect(10, e -> {
+ stroke(e.fout() * 1.6f);
+ Lines.square(e.x, e.y, tilesize / 2f + e.fout() * 2f);
+ }),
+ dooropenlarge = new Effect(10, e -> {
+ stroke(e.fout() * 1.6f);
+ Lines.square(e.x, e.y, tilesize + e.fin() * 2f);
+ }),
+ doorcloselarge = new Effect(10, e -> {
+ stroke(e.fout() * 1.6f);
+ Lines.square(e.x, e.y, tilesize + e.fout() * 2f);
+ }),
+ purify = new Effect(10, e -> {
+ color(Color.royal, Color.gray, e.fin());
+ stroke(2f);
+ Lines.spikes(e.x, e.y, e.fin() * 4f, 2, 6);
+ }),
+ purifyoil = new Effect(10, e -> {
+ color(Color.black, Color.gray, e.fin());
+ stroke(2f);
+ Lines.spikes(e.x, e.y, e.fin() * 4f, 2, 6);
+ }),
+ purifystone = new Effect(10, e -> {
+ color(Color.orange, Color.gray, e.fin());
+ stroke(2f);
+ Lines.spikes(e.x, e.y, e.fin() * 4f, 2, 6);
+ }),
+ generate = new Effect(11, e -> {
+ color(Color.orange, Color.yellow, e.fin());
+ stroke(1f);
+ Lines.spikes(e.x, e.y, e.fin() * 5f, 2, 8);
+ }),
+ mine = new Effect(20, e -> {
+ randLenVectors(e.id, 6, 3f + e.fin() * 6f, (x, y) -> {
+ color(e.color, Color.lightGray, e.fin());
+ Fill.square(e.x + x, e.y + y, e.fout() * 2f, 45);
+ });
+ }),
+ mineBig = new Effect(30, e -> {
+ randLenVectors(e.id, 6, 4f + e.fin() * 8f, (x, y) -> {
+ color(e.color, Color.lightGray, e.fin());
+ Fill.square(e.x + x, e.y + y, e.fout() * 2f + 0.2f, 45);
+ });
+ }),
+
+ mineHuge = new Effect(40, e -> {
+ randLenVectors(e.id, 8, 5f + e.fin() * 10f, (x, y) -> {
+ color(e.color, Color.lightGray, e.fin());
+ Fill.square(e.x + x, e.y + y, e.fout() * 2f + 0.5f, 45);
+ });
+ }),
+ smelt = new Effect(20, e -> {
+ randLenVectors(e.id, 6, 2f + e.fin() * 5f, (x, y) -> {
+ color(Color.white, e.color, e.fin());
+ Fill.square(e.x + x, e.y + y, 0.5f + e.fout() * 2f, 45);
+ });
+ }),
+ teleportActivate = new Effect(50, e -> {
+ color(e.color);
+
+ e.scaled(8f, e2 -> {
+ stroke(e2.fout() * 4f);
+ Lines.circle(e2.x, e2.y, 4f + e2.fin() * 27f);
+ });
+
+ stroke(e.fout() * 2f);
+
+ randLenVectors(e.id, 30, 4f + 40f * e.fin(), (x, y) -> {
+ lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), e.fin() * 4f + 1f);
+ });
+
+ }),
+ teleport = new Effect(60, e -> {
+ color(e.color);
+ stroke(e.fin() * 2f);
+ Lines.circle(e.x, e.y, 7f + e.fout() * 8f);
+
+ randLenVectors(e.id, 20, 6f + 20f * e.fout(), (x, y) -> {
+ lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), e.fin() * 4f + 1f);
+ });
+
+ }),
+ teleportOut = new Effect(20, e -> {
+ color(e.color);
+ stroke(e.fout() * 2f);
+ Lines.circle(e.x, e.y, 7f + e.fin() * 8f);
+
+ randLenVectors(e.id, 20, 4f + 20f * e.fin(), (x, y) -> {
+ lineAngle(e.x + x, e.y + y, Mathf.angle(x, y), e.fslope() * 4f + 1f);
+ });
+
+ }),
+
+ //TODO fix false in constructor
+ ripple = new Effect(30, e -> {
+ color(Tmp.c1.set(e.color).mul(1.5f));
+ stroke(e.fout() + 0.4f);
+ Lines.circle(e.x, e.y, 2f + e.fin() * 4f);
+ }).ground(),
+
+ bubble = new Effect(20, e -> {
+ color(Tmp.c1.set(e.color).shiftValue(0.1f));
+ stroke(e.fout() + 0.2f);
+ randLenVectors(e.id, 2, 8f, (x, y) -> {
+ Lines.circle(e.x + x, e.y + y, 1f + e.fin() * 3f);
+ });
+ }),
+
+ launch = new Effect(28, e -> {
+ color(Pal.command);
+ stroke(e.fout() * 2f);
+ Lines.circle(e.x, e.y, 4f + e.finpow() * 120f);
+ }),
+
+ healWaveMend = new Effect(40, e -> {
+ color(e.color);
+ stroke(e.fout() * 2f);
+ Lines.circle(e.x, e.y, e.finpow() * e.rotation);
+ }),
+
+ overdriveWave = new Effect(50, e -> {
+ color(e.color);
+ stroke(e.fout() * 1f);
+ Lines.circle(e.x, e.y, e.finpow() * e.rotation);
+ }),
+
+ healBlock = new Effect(20, e -> {
+ color(Pal.heal);
+ stroke(2f * e.fout() + 0.5f);
+ Lines.square(e.x, e.y, 1f + (e.fin() * e.rotation * tilesize / 2f - 1f));
+ }),
+
+ healBlockFull = new Effect(20, e -> {
+ color(e.color);
+ alpha(e.fout());
+ Fill.square(e.x, e.y, e.rotation * tilesize / 2f);
+ }),
+
+ overdriveBlockFull = new Effect(60, e -> {
+ color(e.color);
+ alpha(e.fslope() * 0.4f);
+ Fill.square(e.x, e.y, e.rotation * tilesize);
+ }),
+
+ shieldBreak = new Effect(40, e -> {
+ color(Pal.accent);
+ stroke(3f * e.fout());
+ Lines.poly(e.x, e.y, 6, e.rotation + e.fin(), 90);
+ }),
- coreLand = new Effect(120f, e -> {
- });
- }
+ coreLand = new Effect(120f, e -> {
+ });
}
diff --git a/core/src/mindustry/content/Mechs.java b/core/src/mindustry/content/Mechs.java
deleted file mode 100644
index 9bbb67d51a..0000000000
--- a/core/src/mindustry/content/Mechs.java
+++ /dev/null
@@ -1,378 +0,0 @@
-package mindustry.content;
-
-import arc.*;
-import arc.graphics.*;
-import arc.graphics.g2d.*;
-import arc.math.*;
-import arc.util.*;
-import mindustry.*;
-import mindustry.ctype.ContentList;
-import mindustry.entities.*;
-import mindustry.entities.bullet.*;
-import mindustry.entities.effect.*;
-import mindustry.entities.type.*;
-import mindustry.gen.*;
-import mindustry.graphics.*;
-import mindustry.type.*;
-
-public class Mechs implements ContentList{
- public static Mech alpha, delta, tau, omega, dart, javelin, trident, glaive;
-
- public static Mech starter;
-
- @Override
- public void load(){
-
- alpha = new Mech("alpha-mech", false){
- {
- drillPower = 1;
- mineSpeed = 1.5f;
- mass = 1.2f;
- speed = 0.5f;
- itemCapacity = 40;
- boostSpeed = 0.95f;
- buildPower = 1.2f;
- engineColor = Color.valueOf("ffd37f");
- health = 250f;
-
- weapon = new Weapon("blaster"){{
- length = 1.5f;
- reload = 14f;
- alternate = true;
- ejectEffect = Fx.shellEjectSmall;
- bullet = Bullets.standardMechSmall;
- }};
- }
-
- @Override
- public void updateAlt(Player player){
- player.healBy(Time.delta() * 0.09f);
- }
-
- };
-
- delta = new Mech("delta-mech", false){
- float cooldown = 120;
-
- {
- drillPower = -1;
- speed = 0.75f;
- boostSpeed = 0.95f;
- itemCapacity = 15;
- mass = 0.9f;
- health = 150f;
- buildPower = 0.9f;
- weaponOffsetX = -1;
- weaponOffsetY = -1;
- engineColor = Color.valueOf("d3ddff");
-
- weapon = new Weapon("shockgun"){{
- shake = 2f;
- length = 1f;
- reload = 55f;
- shotDelay = 3f;
- alternate = true;
- shots = 2;
- inaccuracy = 0f;
- ejectEffect = Fx.none;
- bullet = Bullets.lightning;
- shootSound = Sounds.spark;
- }};
- }
-
- @Override
- public void onLand(Player player){
- if(player.timer.get(Player.timerAbility, cooldown)){
- Effects.shake(1f, 1f, player);
- Effects.effect(Fx.landShock, player);
- for(int i = 0; i < 8; i++){
- Time.run(Mathf.random(8f), () -> Lightning.create(player.getTeam(), Pal.lancerLaser, 17f * Vars.state.rules.playerDamageMultiplier, player.x, player.y, Mathf.random(360f), 14));
- }
- }
- }
- };
-
- tau = new Mech("tau-mech", false){
- float healRange = 60f;
- float healAmount = 10f;
- float healReload = 160f;
- boolean wasHealed;
-
- {
- drillPower = 4;
- mineSpeed = 3f;
- itemCapacity = 70;
- weaponOffsetY = -1;
- weaponOffsetX = 1;
- mass = 1.75f;
- speed = 0.44f;
- drag = 0.35f;
- boostSpeed = 0.8f;
- canHeal = true;
- health = 200f;
- buildPower = 1.6f;
- engineColor = Pal.heal;
-
- weapon = new Weapon("heal-blaster"){{
- length = 1.5f;
- reload = 24f;
- alternate = false;
- ejectEffect = Fx.none;
- recoil = 2f;
- bullet = Bullets.healBullet;
- shootSound = Sounds.pew;
- }};
- }
-
- @Override
- public void updateAlt(Player player){
-
- if(player.timer.get(Player.timerAbility, healReload)){
- wasHealed = false;
-
- Units.nearby(player.getTeam(), player.x, player.y, healRange, unit -> {
- if(unit.health < unit.maxHealth()){
- Effects.effect(Fx.heal, unit);
- wasHealed = true;
- }
- unit.healBy(healAmount);
- });
-
- if(wasHealed){
- Effects.effect(Fx.healWave, player);
- }
- }
- }
- };
-
- omega = new Mech("omega-mech", false){
- protected TextureRegion armorRegion;
-
- {
- drillPower = 2;
- mineSpeed = 1.5f;
- itemCapacity = 80;
- speed = 0.36f;
- boostSpeed = 0.6f;
- mass = 4f;
- shake = 4f;
- weaponOffsetX = 1;
- weaponOffsetY = 0;
- engineColor = Color.valueOf("feb380");
- health = 350f;
- buildPower = 1.5f;
- weapon = new Weapon("swarmer"){{
- length = 1.5f;
- recoil = 4f;
- reload = 38f;
- shots = 4;
- spacing = 8f;
- inaccuracy = 8f;
- alternate = true;
- ejectEffect = Fx.none;
- shake = 3f;
- bullet = Bullets.missileSwarm;
- shootSound = Sounds.shootBig;
- }};
- }
-
- @Override
- public float getRotationAlpha(Player player){
- return 0.6f - player.shootHeat * 0.3f;
- }
-
- @Override
- public float spreadX(Player player){
- return player.shootHeat * 2f;
- }
-
- @Override
- public void load(){
- super.load();
- armorRegion = Core.atlas.find(name + "-armor");
- }
-
- @Override
- public void updateAlt(Player player){
- float scl = 1f - player.shootHeat / 2f*Time.delta();
- player.velocity().scl(scl);
- }
-
- @Override
- public float getExtraArmor(Player player){
- return player.shootHeat * 30f;
- }
-
- @Override
- public void draw(Player player){
- if(player.shootHeat <= 0.01f) return;
-
- Shaders.build.progress = player.shootHeat;
- Shaders.build.region = armorRegion;
- Shaders.build.time = Time.time() / 10f;
- Shaders.build.color.set(Pal.accent).a = player.shootHeat;
- Draw.shader(Shaders.build);
- Draw.rect(armorRegion, player.x, player.y, player.rotation);
- Draw.shader();
- }
- };
-
- dart = new Mech("dart-ship", true){
- {
- drillPower = 1;
- mineSpeed = 3f;
- speed = 0.5f;
- drag = 0.09f;
- health = 200f;
- weaponOffsetX = -1;
- weaponOffsetY = -1;
- engineColor = Pal.lightTrail;
- cellTrnsY = 1f;
- buildPower = 1.1f;
- weapon = new Weapon("blaster"){{
- length = 1.5f;
- reload = 15f;
- alternate = true;
- ejectEffect = Fx.shellEjectSmall;
- bullet = Bullets.standardCopper;
- }};
- }
-
- @Override
- public boolean alwaysUnlocked(){
- return true;
- }
- };
-
- javelin = new Mech("javelin-ship", true){
- float minV = 3.6f;
- float maxV = 6f;
- TextureRegion shield;
-
- {
- drillPower = -1;
- speed = 0.11f;
- drag = 0.01f;
- mass = 2f;
- health = 170f;
- engineColor = Color.valueOf("d3ddff");
- cellTrnsY = 1f;
- weapon = new Weapon("missiles"){{
- length = 1.5f;
- reload = 70f;
- shots = 4;
- inaccuracy = 2f;
- alternate = true;
- ejectEffect = Fx.none;
- velocityRnd = 0.2f;
- spacing = 1f;
- bullet = Bullets.missileJavelin;
- shootSound = Sounds.missile;
- }};
- }
-
- @Override
- public void load(){
- super.load();
- shield = Core.atlas.find(name + "-shield");
- }
-
- @Override
- public float getRotationAlpha(Player player){
- return 0.5f;
- }
-
- @Override
- public void updateAlt(Player player){
- float scl = scld(player);
- if(Mathf.chance(Time.delta() * (0.15 * scl))){
- Effects.effect(Fx.hitLancer, Pal.lancerLaser, player.x, player.y);
- Lightning.create(player.getTeam(), Pal.lancerLaser, 10f * Vars.state.rules.playerDamageMultiplier,
- player.x + player.velocity().x, player.y + player.velocity().y, player.rotation, 14);
- }
- }
-
- @Override
- public void draw(Player player){
- float scl = scld(player);
- if(scl < 0.01f) return;
- Draw.color(Pal.lancerLaser);
- Draw.alpha(scl / 2f);
- Draw.blend(Blending.additive);
- Draw.rect(shield, player.x + Mathf.range(scl / 2f), player.y + Mathf.range(scl / 2f), player.rotation - 90);
- Draw.blend();
- }
-
- float scld(Player player){
- return Mathf.clamp((player.velocity().len() - minV) / (maxV - minV));
- }
- };
-
- trident = new Mech("trident-ship", true){
- {
- drillPower = 2;
- speed = 0.15f;
- drag = 0.034f;
- mass = 2.5f;
- turnCursor = false;
- health = 250f;
- itemCapacity = 30;
- engineColor = Color.valueOf("84f491");
- cellTrnsY = 1f;
- buildPower = 2.5f;
- weapon = new Weapon("bomber"){{
- length = 0f;
- width = 2f;
- reload = 25f;
- shots = 2;
- shotDelay = 1f;
- shots = 8;
- alternate = true;
- ejectEffect = Fx.none;
- velocityRnd = 1f;
- inaccuracy = 20f;
- ignoreRotation = true;
- bullet = new BombBulletType(16f, 25f, "shell"){{
- bulletWidth = 10f;
- bulletHeight = 14f;
- hitEffect = Fx.flakExplosion;
- shootEffect = Fx.none;
- smokeEffect = Fx.none;
- shootSound = Sounds.artillery;
- }};
- }};
- }
-
- @Override
- public boolean canShoot(Player player){
- return player.velocity().len() > 1.2f;
- }
- };
-
- glaive = new Mech("glaive-ship", true){
- {
- drillPower = 4;
- mineSpeed = 1.3f;
- speed = 0.32f;
- drag = 0.06f;
- mass = 3f;
- health = 240f;
- itemCapacity = 60;
- engineColor = Color.valueOf("feb380");
- cellTrnsY = 1f;
- buildPower = 1.2f;
-
- weapon = new Weapon("bomber"){{
- length = 1.5f;
- reload = 13f;
- alternate = true;
- ejectEffect = Fx.shellEjectSmall;
- bullet = Bullets.standardGlaive;
- shootSound = Sounds.shootSnap;
- }};
- }
- };
-
- starter = dart;
- }
-}
diff --git a/core/src/mindustry/content/Planets.java b/core/src/mindustry/content/Planets.java
new file mode 100644
index 0000000000..a2c319dd1d
--- /dev/null
+++ b/core/src/mindustry/content/Planets.java
@@ -0,0 +1,45 @@
+package mindustry.content;
+
+import arc.graphics.*;
+import mindustry.ctype.*;
+import mindustry.graphics.g3d.*;
+import mindustry.maps.planet.*;
+import mindustry.type.*;
+
+public class Planets implements ContentList{
+ public static Planet
+ sun,
+ starter;
+
+ @Override
+ public void load(){
+ sun = new Planet("sun", null, 0, 2){{
+ bloom = true;
+ //lightColor = Color.valueOf("f4ee8e");
+ meshLoader = () -> new SunMesh(this, 3){{
+ setColors(
+ 1.1f,
+ Color.valueOf("ff7a38"),
+ Color.valueOf("ff9638"),
+ Color.valueOf("ffc64c"),
+ Color.valueOf("ffc64c"),
+ Color.valueOf("ffe371"),
+ Color.valueOf("f4ee8e")
+ );
+
+ scale = 1f;
+ speed = 1000f;
+ falloff = 0.3f;
+ octaves = 4;
+ spread = 1.2f;
+ magnitude = 0f;
+ }};
+ }};
+
+ starter = new Planet("TODO", sun, 3, 1){{
+ generator = new TODOPlanetGenerator();
+ meshLoader = () -> new HexMesh(this, 6);
+ atmosphereColor = Color.valueOf("3c1b8f");
+ }};
+ }
+}
diff --git a/core/src/mindustry/content/StatusEffects.java b/core/src/mindustry/content/StatusEffects.java
index 6672727847..a925a77be4 100644
--- a/core/src/mindustry/content/StatusEffects.java
+++ b/core/src/mindustry/content/StatusEffects.java
@@ -1,8 +1,8 @@
package mindustry.content;
import arc.*;
+import arc.graphics.*;
import arc.math.Mathf;
-import mindustry.entities.Effects;
import mindustry.ctype.ContentList;
import mindustry.game.EventType.*;
import mindustry.type.StatusEffect;
@@ -24,7 +24,7 @@ public class StatusEffects implements ContentList{
opposite(wet,freezing);
trans(tarred, ((unit, time, newTime, result) -> {
unit.damage(1f);
- Effects.effect(Fx.burning, unit.x + Mathf.range(unit.getSize() / 2f), unit.y + Mathf.range(unit.getSize() / 2f));
+ Fx.burning.at(unit.x() + Mathf.range(unit.bounds() / 2f), unit.y() + Mathf.range(unit.bounds() / 2f));
result.set(this, Math.min(time + newTime, 300f));
}));
});
@@ -41,13 +41,14 @@ public class StatusEffects implements ContentList{
}};
wet = new StatusEffect("wet"){{
+ color = Color.royal;
speedMultiplier = 0.9f;
effect = Fx.wet;
init(() -> {
trans(shocked, ((unit, time, newTime, result) -> {
unit.damage(20f);
- if(unit.getTeam() == state.rules.waveTeam){
+ if(unit.team() == state.rules.waveTeam){
Events.fire(Trigger.shock);
}
result.set(this, time);
diff --git a/core/src/mindustry/content/TechTree.java b/core/src/mindustry/content/TechTree.java
index 83b2bcc2b5..59d7ac389a 100644
--- a/core/src/mindustry/content/TechTree.java
+++ b/core/src/mindustry/content/TechTree.java
@@ -280,6 +280,7 @@ public class TechTree implements ContentList{
});
});
+ /*
node(draugFactory, () -> {
node(spiritFactory, () -> {
node(phantomFactory);
@@ -305,6 +306,7 @@ public class TechTree implements ContentList{
});
});
+ /*
node(dartPad, () -> {
node(deltaPad, () -> {
@@ -320,7 +322,7 @@ public class TechTree implements ContentList{
});
});
});
- });
+ });*/
});
});
});
@@ -347,6 +349,7 @@ public class TechTree implements ContentList{
public static class TechNode{
static TechNode context;
+ public TechNode parent;
public final Block block;
public final ItemStack[] requirements;
public final Array children = new Array<>();
@@ -356,6 +359,7 @@ public class TechTree implements ContentList{
ccontext.children.add(this);
}
+ this.parent = ccontext;
this.block = block;
this.requirements = requirements;
diff --git a/core/src/mindustry/content/TypeIDs.java b/core/src/mindustry/content/TypeIDs.java
deleted file mode 100644
index b99e321e98..0000000000
--- a/core/src/mindustry/content/TypeIDs.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package mindustry.content;
-
-import mindustry.entities.effect.Fire;
-import mindustry.entities.effect.Puddle;
-import mindustry.entities.type.Player;
-import mindustry.ctype.ContentList;
-import mindustry.type.TypeID;
-
-public class TypeIDs implements ContentList{
- public static TypeID fire, puddle, player;
-
- @Override
- public void load(){
- fire = new TypeID("fire", Fire::new);
- puddle = new TypeID("puddle", Puddle::new);
- player = new TypeID("player", Player::new);
- }
-}
diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java
index 5159f8e7c5..6485ca560c 100644
--- a/core/src/mindustry/content/UnitTypes.java
+++ b/core/src/mindustry/content/UnitTypes.java
@@ -1,95 +1,154 @@
package mindustry.content;
import arc.struct.*;
+import mindustry.annotations.Annotations.*;
import mindustry.ctype.*;
-import mindustry.entities.bullet.*;
-import mindustry.entities.type.base.*;
import mindustry.gen.*;
import mindustry.type.*;
public class UnitTypes implements ContentList{
+ //TODO reimplement - DO NOT USE
public static UnitType
- draug, spirit, phantom,
- wraith, ghoul, revenant, lich, reaper,
- dagger, crawler, titan, fortress, eruptor, chaosArray, eradicator;
+ ghoul, revenant, lich,
+ crawler, titan, fortress, eruptor, chaosArray, eradicator;
+
+ public static @EntityDef({Unitc.class, Legsc.class}) UnitType dagger;
+ public static @EntityDef({Unitc.class, WaterMovec.class}) UnitType vanguard;
+ public static @EntityDef({Unitc.class, Minerc.class}) UnitType draug;
+ public static @EntityDef({Unitc.class}) UnitType wraith;
+ public static @EntityDef({Unitc.class}) UnitType reaper;
+ public static @EntityDef({Unitc.class}) UnitType spirit;
+ public static @EntityDef({Unitc.class, Builderc.class}) UnitType phantom;
+
+ //TODO remove
+ public static UnitType alpha, delta, tau, omega, dart, javelin, trident, glaive;
+ public static UnitType starter;
+
@Override
public void load(){
- draug = new UnitType("draug", MinerDrone::new){{
- flying = true;
- drag = 0.01f;
- speed = 0.3f;
- maxVelocity = 1.2f;
- range = 50f;
- health = 80;
- minePower = 0.9f;
- engineSize = 1.8f;
- engineOffset = 5.7f;
- weapon = new Weapon("you have incurred my wrath. prepare to die."){{
- bullet = Bullets.lancerLaser;
- }};
+
+ dagger = new UnitType("dagger"){{
+ speed = 0.5f;
+ drag = 0.3f;
+ hitsize = 8f;
+ mass = 1.75f;
+ health = 130;
+ weapons.add(new Weapon("chain-blaster"){{
+ reload = 14f;
+ x = 4f;
+ alternate = true;
+ ejectEffect = Fx.shellEjectSmall;
+ bullet = Bullets.standardCopper;
+ }});
}};
- spirit = new UnitType("spirit", RepairDrone::new){{
+ wraith = new UnitType("wraith"){{
+ speed = 3f;
+ accel = 0.08f;
+ drag = 0f;
+ mass = 1.5f;
flying = true;
- drag = 0.01f;
- speed = 0.42f;
- maxVelocity = 1.6f;
+ health = 75;
+ engineOffset = 5.5f;
+ range = 140f;
+ weapons.add(new Weapon(){{
+ y = 1.5f;
+ reload = 28f;
+ alternate = true;
+ ejectEffect = Fx.shellEjectSmall;
+ bullet = Bullets.standardCopper;
+ shootSound = Sounds.shoot;
+ }});
+ }};
+
+ reaper = new UnitType("reaper"){{
+ speed = 1f;
+ accel = 0.08f;
+ drag = 0f;
+ mass = 2f;
+ flying = true;
+ health = 75000;
+ engineOffset = 40;
+ engineSize = 7.3f;
+
+ weapons.add(new Weapon(){{
+ y = 1.5f;
+ reload = 28f;
+ alternate = true;
+ ejectEffect = Fx.shellEjectSmall;
+ bullet = Bullets.standardCopper;
+ shootSound = Sounds.shoot;
+ }});
+ }};
+
+
+ vanguard = new UnitType("vanguard"){{
+ speed = 1.3f;
+ drag = 0.1f;
+ hitsize = 8f;
+ mass = 1.75f;
+ health = 130;
+ immunities = ObjectSet.with(StatusEffects.wet);
+ weapons.add(new Weapon("chain-blaster"){{
+ reload = 10f;
+ x = 1.25f;
+ alternate = true;
+ rotate = true;
+ ejectEffect = Fx.shellEjectSmall;
+ bullet = Bullets.standardCopper;
+ }});
+ }};
+
+ draug = new UnitType("draug"){{
+ flying = true;
+ drag = 0.05f;
+ speed = 2f;
+ range = 50f;
+ accel = 0.2f;
+ health = 80;
+ mineSpeed = 0.9f;
+ engineSize = 1.8f;
+ engineOffset = 5.7f;
+ drillTier = 1;
+ }};
+
+ spirit = new UnitType("spirit"){{
+ flying = true;
+ drag = 0.05f;
+ accel = 0.2f;
+ speed = 2f;
range = 50f;
health = 100;
engineSize = 1.8f;
engineOffset = 5.7f;
- weapon = new Weapon(){{
- length = 1.5f;
+ weapons.add(new Weapon(){{
+ y = 1.5f;
reload = 40f;
- width = 0.5f;
+ x = 0.5f;
alternate = true;
ejectEffect = Fx.none;
recoil = 2f;
bullet = Bullets.healBulletBig;
shootSound = Sounds.pew;
- }};
+ }});
}};
- phantom = new UnitType("phantom", BuilderDrone::new){{
+ phantom = new UnitType("phantom"){{
flying = true;
- drag = 0.01f;
+ drag = 0.05f;
mass = 2f;
- speed = 0.45f;
- maxVelocity = 1.9f;
+ speed = 4f;
+ rotateSpeed = 12f;
+ accel = 0.3f;
range = 70f;
itemCapacity = 70;
health = 400;
- buildPower = 0.4f;
+ buildSpeed = 0.4f;
engineOffset = 6.5f;
- toMine = ObjectSet.with(Items.lead, Items.copper, Items.titanium);
- weapon = new Weapon(){{
- length = 1.5f;
- reload = 20f;
- width = 0.5f;
- alternate = true;
- ejectEffect = Fx.none;
- recoil = 2f;
- bullet = Bullets.healBullet;
- }};
}};
-
- dagger = new UnitType("dagger", GroundUnit::new){{
- maxVelocity = 1.1f;
- speed = 0.2f;
- drag = 0.4f;
- hitsize = 8f;
- mass = 1.75f;
- health = 130;
- weapon = new Weapon("chain-blaster"){{
- length = 1.5f;
- reload = 28f;
- alternate = true;
- ejectEffect = Fx.shellEjectSmall;
- bullet = Bullets.standardCopper;
- }};
- }};
-
+
+ /*
crawler = new UnitType("crawler", GroundUnit::new){{
maxVelocity = 1.27f;
speed = 0.285f;
@@ -97,7 +156,7 @@ public class UnitTypes implements ContentList{
hitsize = 8f;
mass = 1.75f;
health = 120;
- weapon = new Weapon(){{
+ weapons.add(new Weapon(){{
reload = 12f;
ejectEffect = Fx.none;
shootSound = Sounds.explosion;
@@ -110,7 +169,7 @@ public class UnitTypes implements ContentList{
splashDamage = 30f;
killShooter = true;
}};
- }};
+ }});
}};
titan = new UnitType("titan", GroundUnit::new){{
@@ -123,7 +182,7 @@ public class UnitTypes implements ContentList{
rotatespeed = 0.1f;
health = 460;
immunities.add(StatusEffects.burning);
- weapon = new Weapon("flamethrower"){{
+ weapons.add(new Weapon("flamethrower"){{
shootSound = Sounds.flame;
length = 1f;
reload = 14f;
@@ -131,7 +190,7 @@ public class UnitTypes implements ContentList{
recoil = 1f;
ejectEffect = Fx.none;
bullet = Bullets.basicFlame;
- }};
+ }});
}};
fortress = new UnitType("fortress", GroundUnit::new){{
@@ -143,7 +202,7 @@ public class UnitTypes implements ContentList{
rotatespeed = 0.06f;
targetAir = false;
health = 750;
- weapon = new Weapon("artillery"){{
+ weapons.add(new Weapon("artillery"){{
length = 1f;
reload = 60f;
width = 10f;
@@ -153,7 +212,7 @@ public class UnitTypes implements ContentList{
ejectEffect = Fx.shellEjectMedium;
bullet = Bullets.artilleryUnit;
shootSound = Sounds.artillery;
- }};
+ }});
}};
eruptor = new UnitType("eruptor", GroundUnit::new){{
@@ -166,7 +225,7 @@ public class UnitTypes implements ContentList{
targetAir = false;
health = 600;
immunities = ObjectSet.with(StatusEffects.burning, StatusEffects.melting);
- weapon = new Weapon("eruption"){{
+ weapons.add(new Weapon("eruption"){{
length = 3f;
reload = 10f;
alternate = true;
@@ -175,7 +234,7 @@ public class UnitTypes implements ContentList{
recoil = 1f;
width = 7f;
shootSound = Sounds.flame;
- }};
+ }});
}};
chaosArray = new UnitType("chaos-array", GroundUnit::new){{
@@ -186,7 +245,7 @@ public class UnitTypes implements ContentList{
hitsize = 20f;
rotatespeed = 0.06f;
health = 3000;
- weapon = new Weapon("chaos"){{
+ weapons.add(new Weapon("chaos"){{
length = 8f;
reload = 50f;
width = 17f;
@@ -199,7 +258,7 @@ public class UnitTypes implements ContentList{
ejectEffect = Fx.shellEjectMedium;
bullet = Bullets.flakSurge;
shootSound = Sounds.shootBig;
- }};
+ }});
}};
eradicator = new UnitType("eradicator", GroundUnit::new){{
@@ -210,7 +269,7 @@ public class UnitTypes implements ContentList{
hitsize = 20f;
rotatespeed = 0.06f;
health = 9000;
- weapon = new Weapon("eradication"){{
+ weapons.add(new Weapon("eradication"){{
length = 13f;
reload = 30f;
width = 22f;
@@ -224,7 +283,7 @@ public class UnitTypes implements ContentList{
ejectEffect = Fx.shellEjectMedium;
bullet = Bullets.standardThoriumBig;
shootSound = Sounds.shootBig;
- }};
+ }});
}};
wraith = new UnitType("wraith", FlyingUnit::new){{
@@ -236,14 +295,14 @@ public class UnitTypes implements ContentList{
health = 75;
engineOffset = 5.5f;
range = 140f;
- weapon = new Weapon(){{
+ weapons.add(new Weapon(){{
length = 1.5f;
reload = 28f;
alternate = true;
ejectEffect = Fx.shellEjectSmall;
bullet = Bullets.standardCopper;
shootSound = Sounds.shoot;
- }};
+ }});
}};
ghoul = new UnitType("ghoul", FlyingUnit::new){{
@@ -256,7 +315,7 @@ public class UnitTypes implements ContentList{
targetAir = false;
engineOffset = 7.8f;
range = 140f;
- weapon = new Weapon(){{
+ weapons.add(new Weapon(){{
length = 0f;
width = 2f;
reload = 12f;
@@ -267,7 +326,7 @@ public class UnitTypes implements ContentList{
ignoreRotation = true;
bullet = Bullets.bombExplosive;
shootSound = Sounds.none;
- }};
+ }});
}};
revenant = new UnitType("revenant", HoverUnit::new){{
@@ -280,13 +339,13 @@ public class UnitTypes implements ContentList{
range = 80f;
shootCone = 40f;
flying = true;
- rotateWeapon = true;
+ //rotateWeapons = true;
engineOffset = 12f;
engineSize = 3f;
rotatespeed = 0.01f;
attackLength = 90f;
baseRotateSpeed = 0.06f;
- weapon = new Weapon("revenant-missiles"){{
+ weapons.add(new Weapon("revenant-missiles"){{
length = 3f;
reload = 70f;
width = 10f;
@@ -298,7 +357,7 @@ public class UnitTypes implements ContentList{
spacing = 1f;
shootSound = Sounds.missile;
bullet = Bullets.missileRevenant;
- }};
+ }});
}};
lich = new UnitType("lich", HoverUnit::new){{
@@ -311,13 +370,13 @@ public class UnitTypes implements ContentList{
range = 80f;
shootCone = 20f;
flying = true;
- rotateWeapon = true;
+ //rotateWeapons = true;
engineOffset = 21;
engineSize = 5.3f;
rotatespeed = 0.01f;
attackLength = 90f;
baseRotateSpeed = 0.04f;
- weapon = new Weapon("lich-missiles"){{
+ weapons.add(new Weapon("lich-missiles"){{
length = 4f;
reload = 160f;
width = 22f;
@@ -331,7 +390,7 @@ public class UnitTypes implements ContentList{
spacing = 1f;
bullet = Bullets.missileRevenant;
shootSound = Sounds.artillery;
- }};
+ }});
}};
reaper = new UnitType("reaper", HoverUnit::new){{
@@ -344,12 +403,12 @@ public class UnitTypes implements ContentList{
range = 80f;
shootCone = 30f;
flying = true;
- rotateWeapon = true;
+ //rotateWeapons = true;
engineOffset = 40;
engineSize = 7.3f;
rotatespeed = 0.01f;
baseRotateSpeed = 0.04f;
- weapon = new Weapon("reaper-gun"){{
+ weapons.add(new Weapon("reaper-gun"){{
length = 3f;
reload = 10f;
width = 32f;
@@ -373,7 +432,442 @@ public class UnitTypes implements ContentList{
}
};
shootSound = Sounds.shootBig;
- }};
+ }});
}};
+
+
+ /*
+ vanguard = new UnitType("vanguard-ship"){
+ float healRange = 60f;
+ float healReload = 200f;
+ float healPercent = 10f;
+
+ {
+ flying = true;
+ drillTier = 1;
+ mineSpeed = 4f;
+ speed = 0.49f;
+ drag = 0.09f;
+ health = 200f;
+ weaponOffsetX = -1;
+ engineSize = 2.3f;
+ weaponOffsetY = -1;
+ engineColor = Pal.lightTrail;
+ cellTrnsY = 1f;
+ buildSpeed = 1.2f;
+ weapons.add(new Weapon("vanguard-blaster"){{
+ length = 1.5f;
+ reload = 30f;
+ alternate = true;
+ inaccuracy = 6f;
+ velocityRnd = 0.1f;
+ ejectEffect = Fx.none;
+ bullet = new HealBulletType(){{
+ healPercent = 3f;
+ backColor = engineColor;
+ homingPower = 20f;
+ bulletHeight = 4f;
+ bulletWidth = 1.5f;
+ damage = 3f;
+ speed = 4f;
+ lifetime = 40f;
+ shootEffect = Fx.shootHealYellow;
+ smokeEffect = hitEffect = despawnEffect = Fx.hitYellowLaser;
+ }});
+ }};
+ }
+
+ @Override
+ public boolean alwaysUnlocked(){
+ return true;
+ }
+
+ @Override
+ public void update(Playerc player){
+ if(player.timer.get(Playerc.timerAbility, healReload)){
+ if(indexer.eachBlock(player, healRange, other -> other.entity.damaged(), other -> {
+ other.entity.heal(other.entity.maxHealth() * healPercent / 100f);
+ Fx.healBlockFull.at(other.drawx(), other.drawy(), other.block().size, Pal.heal);
+ })){
+ Fx.healWave.at(player);
+ }
+ }
+ }
+ };
+
+ alpha = new UnitType("alpha-mech", false){
+ {
+ drillTier = -1;
+ speed = 0.5f;
+ boostSpeed = 0.95f;
+ itemCapacity = 15;
+ mass = 0.9f;
+ health = 150f;
+ buildSpeed = 0.9f;
+ weaponOffsetX = 1;
+ weaponOffsetY = -1;
+ engineColor = Pal.heal;
+
+ weapons.add(new Weapon("shockgun"){{
+ shake = 2f;
+ length = 0.5f;
+ reload = 70f;
+ alternate = true;
+ recoil = 4f;
+ width = 5f;
+ shootSound = Sounds.laser;
+
+ bullet = new LaserBulletType(){{
+ damage = 20f;
+ recoil = 1f;
+ sideAngle = 45f;
+ sideWidth = 1f;
+ sideLength = 70f;
+ colors = new Color[]{Pal.heal.cpy().a(0.4f), Pal.heal, Color.white};
+ }});
+ }};
+ }
+
+ @Override
+ public void update(Playerc player){
+ player.heal(Time.delta() * 0.09f);
+ }
+
+ };
+
+ delta = new UnitType("delta-mech", false){
+ {
+ drillPower = 1;
+ mineSpeed = 1.5f;
+ mass = 1.2f;
+ speed = 0.5f;
+ itemCapacity = 40;
+ boostSpeed = 0.95f;
+ buildSpeed = 1.2f;
+ engineColor = Color.valueOf("ffd37f");
+ health = 250f;
+ weaponOffsetX = 4f;
+
+ weapons.add(new Weapon("flamethrower"){{
+ length = 1.5f;
+ reload = 30f;
+ width = 4f;
+ alternate = true;
+ shots = 3;
+ inaccuracy = 40f;
+ shootSound = Sounds.spark;
+ bullet = new LightningBulletType(){{
+ damage = 5;
+ lightningLength = 10;
+ lightningColor = Pal.lightFlame;
+ }});
+ }};
+ }
+ };
+
+ tau = new UnitType("tau-mech", false){
+ float healRange = 60f;
+ float healAmount = 10f;
+ float healReload = 160f;
+ boolean wasHealed;
+
+ {
+ drillPower = 4;
+ mineSpeed = 3f;
+ itemCapacity = 70;
+ weaponOffsetY = -1;
+ weaponOffsetX = 1;
+ mass = 1.75f;
+ speed = 0.44f;
+ drag = 0.35f;
+ boostSpeed = 0.8f;
+ canHeal = true;
+ health = 200f;
+ buildSpeed = 1.6f;
+ engineColor = Pal.heal;
+
+ weapons.add(new Weapon("heal-blaster"){{
+ length = 1.5f;
+ reload = 24f;
+ alternate = false;
+ ejectEffect = Fx.none;
+ recoil = 2f;
+ bullet = Bullets.healBullet;
+ shootSound = Sounds.pew;
+ }};
+ }
+
+ @Override
+ public void update(Playerc player){
+
+ if(player.timer.get(Playerc.timerAbility, healReload)){
+ wasHealed = false;
+
+ Units.nearby(player.team(), player.x, player.y, healRange, unit -> {
+ if(unit.health < unit.maxHealth()){
+ Fx.heal.at(unit);
+ wasHealed = true;
+ }
+ unit.heal(healAmount);
+ });
+
+ if(wasHealed){
+ Fx.healWave.at(player);
+ }
+ }
+ }
+ };
+
+ omega = new UnitType("omega-mech", false){
+ protected TextureRegion armorRegion;
+
+ {
+ drillPower = 2;
+ mineSpeed = 1.5f;
+ itemCapacity = 80;
+ speed = 0.36f;
+ boostSpeed = 0.6f;
+ mass = 4f;
+ shake = 4f;
+ weaponOffsetX = 1;
+ weaponOffsetY = 0;
+ engineColor = Color.valueOf("feb380");
+ health = 350f;
+ buildSpeed = 1.5f;
+ weapons.add(new Weapon("swarmer"){{
+ length = 1.5f;
+ recoil = 4f;
+ reload = 38f;
+ shots = 4;
+ spacing = 8f;
+ inaccuracy = 8f;
+ alternate = true;
+ ejectEffect = Fx.none;
+ shake = 3f;
+ bullet = Bullets.missileSwarm;
+ shootSound = Sounds.shootBig;
+ }};
+ }
+
+ @Override
+ public float getRotationAlpha(Playerc player){
+ return 0.6f - player.shootHeat * 0.3f;
+ }
+
+ @Override
+ public float spreadX(Playerc player){
+ return player.shootHeat * 2f;
+ }
+
+ @Override
+ public void load(){
+ super.load();
+ armorRegion = Core.atlas.find(name + "-armor");
+ }
+
+ @Override
+ public void update(Playerc player){
+ float scl = 1f - player.shootHeat / 2f*Time.delta();
+ player.vel().scl(scl);
+ }
+
+ @Override
+ public float getExtraArmor(Playerc player){
+ return player.shootHeat * 30f;
+ }
+
+ @Override
+ public void draw(Playerc player){
+ if(player.shootHeat <= 0.01f) return;
+
+ Shaders.build.progress = player.shootHeat;
+ Shaders.build.region = armorRegion;
+ Shaders.build.time = Time.time() / 10f;
+ Shaders.build.color.set(Pal.accent).a = player.shootHeat;
+ Draw.shader(Shaders.build);
+ Draw.rect(armorRegion, player.x, player.y, player.rotation);
+ Draw.shader();
+ }
+ };
+
+ dart = new UnitType("dart-ship"){
+ float effectRange = 60f;
+ float effectReload = 60f * 5;
+ float effectDuration = 60f * 10f;
+
+ {
+ flying = true;
+ drillPower = 1;
+ mineSpeed = 2f;
+ speed = 0.5f;
+ drag = 0.09f;
+ health = 200f;
+ weaponOffsetX = -1;
+ weaponOffsetY = -1;
+ engineColor = Pal.lightTrail;
+ cellTrnsY = 1f;
+ buildSpeed = 1.1f;
+ weapons.add(new Weapon("blaster"){{
+ length = 1.5f;
+ reload = 15f;
+ alternate = true;
+ ejectEffect = Fx.shellEjectSmall;
+ bullet = Bullets.standardCopper;
+ }};
+ }
+
+ @Override
+ public void update(Playerc player){
+ super.update(player);
+
+ if(player.timer.get(Playerc.timerAbility, effectReload)){
+
+ Units.nearby(player.team(), player.x, player.y, effectRange, unit -> {
+ //unit.applyEffect(StatusEffects.overdrive, effectDuration);
+ });
+
+ indexer.eachBlock(player, effectRange, other -> other.entity.damaged(), other -> {
+ other.entity.applyBoost(1.5f, effectDuration);
+ Fx.healBlockFull.at(other.drawx(), other.drawy(), other.block().size, Pal.heal);
+ });
+
+ Fx.overdriveWave.at(player);
+ }
+ }
+ };
+
+ javelin = new UnitType("javelin-ship"){
+ float minV = 3.6f;
+ float maxV = 6f;
+ TextureRegion shield;
+
+ {
+ flying = true;
+ drillPower = -1;
+ speed = 0.11f;
+ drag = 0.01f;
+ mass = 2f;
+ health = 170f;
+ engineColor = Color.valueOf("d3ddff");
+ cellTrnsY = 1f;
+ weapons.add(new Weapon("missiles"){{
+ length = 1.5f;
+ reload = 70f;
+ shots = 4;
+ inaccuracy = 2f;
+ alternate = true;
+ ejectEffect = Fx.none;
+ velocityRnd = 0.2f;
+ spacing = 1f;
+ bullet = Bullets.missileJavelin;
+ shootSound = Sounds.missile;
+ }};
+ }
+
+ @Override
+ public void load(){
+ super.load();
+ shield = Core.atlas.find(name + "-shield");
+ }
+
+ @Override
+ public float getRotationAlpha(Playerc player){
+ return 0.5f;
+ }
+
+ @Override
+ public void update(Playerc player){
+ float scl = scld(player);
+ if(Mathf.chance(Time.delta() * (0.15 * scl))){
+ Fx.hitLancer.at(Pal.lancerLaser, player.x, player.y);
+ Lightning.create(player.team(), Pal.lancerLaser, 10f * Vars.state.rules.playerDamageMultiplier,
+ player.x + player.vel().x, player.y + player.vel().y, player.rotation, 14);
+ }
+ }
+
+ @Override
+ public void draw(Playerc player){
+ float scl = scld(player);
+ if(scl < 0.01f) return;
+ Draw.color(Pal.lancerLaser);
+ Draw.alpha(scl / 2f);
+ Draw.blend(Blending.additive);
+ Draw.rect(shield, player.x + Mathf.range(scl / 2f), player.y + Mathf.range(scl / 2f), player.rotation - 90);
+ Draw.blend();
+ }
+
+ float scld(Playerc player){
+ return Mathf.clamp((player.vel().len() - minV) / (maxV - minV));
+ }
+ };
+
+ trident = new UnitType("trident-ship"){
+ {
+ flying = true;
+ drillPower = 2;
+ speed = 0.15f;
+ drag = 0.034f;
+ mass = 2.5f;
+ turnCursor = false;
+ health = 250f;
+ itemCapacity = 30;
+ engineColor = Color.valueOf("84f491");
+ cellTrnsY = 1f;
+ buildSpeed = 2.5f;
+ weapons.add(new Weapon("bomber"){{
+ length = 0f;
+ width = 2f;
+ reload = 25f;
+ shots = 2;
+ shotDelay = 1f;
+ shots = 8;
+ alternate = true;
+ ejectEffect = Fx.none;
+ velocityRnd = 1f;
+ inaccuracy = 20f;
+ ignoreRotation = true;
+ bullet = new BombBulletType(16f, 25f, "shell"){{
+ bulletWidth = 10f;
+ bulletHeight = 14f;
+ hitEffect = Fx.flakExplosion;
+ shootEffect = Fx.none;
+ smokeEffect = Fx.none;
+ shootSound = Sounds.artillery;
+ }});
+ }};
+ }
+
+ @Override
+ public boolean canShoot(Playerc player){
+ return player.vel().len() > 1.2f;
+ }
+ };
+
+ glaive = new UnitType("glaive-ship"){
+ {
+ flying = true;
+ drillPower = 4;
+ mineSpeed = 1.3f;
+ speed = 0.32f;
+ drag = 0.06f;
+ mass = 3f;
+ health = 240f;
+ itemCapacity = 60;
+ engineColor = Color.valueOf("feb380");
+ cellTrnsY = 1f;
+ buildSpeed = 1.2f;
+
+ weapons.add(new Weapon("bomber"){{
+ length = 1.5f;
+ reload = 13f;
+ alternate = true;
+ ejectEffect = Fx.shellEjectSmall;
+ bullet = Bullets.standardGlaive;
+ shootSound = Sounds.shootSnap;
+ }};
+ }
+ };
+
+ starter = vanguard;*/
}
}
diff --git a/core/src/mindustry/content/Weathers.java b/core/src/mindustry/content/Weathers.java
new file mode 100644
index 0000000000..26f1349571
--- /dev/null
+++ b/core/src/mindustry/content/Weathers.java
@@ -0,0 +1,53 @@
+package mindustry.content;
+
+import arc.*;
+import arc.graphics.g2d.*;
+import arc.math.*;
+import arc.util.*;
+import mindustry.ctype.*;
+import mindustry.type.*;
+
+import static mindustry.Vars.world;
+
+public class Weathers implements ContentList{
+ public static Weather
+ rain,
+ snow;
+
+ @Override
+ public void load(){
+ snow = new Weather("snow"){
+ Rand rand = new Rand();
+
+ @Override
+ public void draw(){
+ rand.setSeed(0);
+ float yspeed = 2f, xspeed = 0.25f;
+ float padding = 16f;
+ float size = 12f;
+ Core.camera.bounds(Tmp.r1);
+ Tmp.r1.grow(padding);
+
+ for(int i = 0; i < 100; i++){
+ float scl = rand.random(0.5f, 1f);
+ float scl2 = rand.random(0.5f, 1f);
+ float sscl = rand.random(0.2f, 1f);
+ float x = (rand.random(0f, world.unitWidth()) + Time.time() * xspeed * scl2);
+ float y = (rand.random(0f, world.unitHeight()) - Time.time() * yspeed * scl);
+
+ x += Mathf.sin(y, rand.random(30f, 80f), rand.random(1f, 7f));
+
+ x -= Tmp.r1.x;
+ y -= Tmp.r1.y;
+ x = Mathf.mod(x, Tmp.r1.width);
+ y = Mathf.mod(y, Tmp.r1.height);
+ x += Tmp.r1.x;
+ y += Tmp.r1.y;
+
+ Draw.rect("circle-shadow", x, y, size * sscl, size * sscl);
+ }
+ //TODO
+ }
+ };
+ }
+}
diff --git a/core/src/mindustry/content/Zones.java b/core/src/mindustry/content/Zones.java
index 1bc988f955..c770ecc669 100644
--- a/core/src/mindustry/content/Zones.java
+++ b/core/src/mindustry/content/Zones.java
@@ -1,19 +1,17 @@
package mindustry.content;
-import mindustry.ctype.ContentList;
-import mindustry.game.*;
+import mindustry.ctype.*;
import mindustry.game.Objectives.*;
import mindustry.maps.generators.*;
-import mindustry.maps.generators.MapGenerator.*;
-import mindustry.maps.zonegen.*;
import mindustry.type.*;
import static arc.struct.Array.with;
import static mindustry.content.Items.*;
+import static mindustry.content.Planets.starter;
import static mindustry.type.ItemStack.list;
public class Zones implements ContentList{
- public static Zone
+ public static SectorPreset
groundZero, desertWastes,
craters, frozenForest, ruinousShores, stainedMountains, tarFields, fungalPass,
saltFlats, overgrowth, impact0078, crags,
@@ -22,7 +20,7 @@ public class Zones implements ContentList{
@Override
public void load(){
- groundZero = new Zone("groundZero", new MapGenerator("groundZero", 1)){{
+ groundZero = new SectorPreset("groundZero", starter, new FileMapGenerator("groundZero")){{
baseLaunchCost = list(copper, -60);
startingItems = list(copper, 60);
alwaysUnlocked = true;
@@ -31,7 +29,9 @@ public class Zones implements ContentList{
resources = with(copper, scrap, lead);
}};
- desertWastes = new Zone("desertWastes", new DesertWastesGenerator(260, 260)){{
+ //TODO remove
+ /*
+ desertWastes = new Zone("desertWastes", starter, new FileMapGenerator("groundZero")){{
startingItems = list(copper, 120);
conditionWave = 20;
launchPeriod = 10;
@@ -80,9 +80,9 @@ public class Zones implements ContentList{
new ZoneWave(groundZero, 20),
new Unlock(Blocks.combustionGenerator)
);
- }};
+ }};*/
- saltFlats = new Zone("saltFlats", new MapGenerator("saltFlats")){{
+ saltFlats = new SectorPreset("saltFlats", starter, new FileMapGenerator("saltFlats")){{
startingItems = list(copper, 200, Items.silicon, 200, lead, 200);
loadout = Loadouts.basicFoundation;
conditionWave = 10;
@@ -91,15 +91,14 @@ public class Zones implements ContentList{
resources = with(copper, scrap, lead, coal, sand, titanium);
requirements = with(
new ZoneWave(desertWastes, 60),
- new Unlock(Blocks.daggerFactory),
- new Unlock(Blocks.draugFactory),
+ //new Unlock(Blocks.daggerFactory),
+ //new Unlock(Blocks.draugFactory),
new Unlock(Blocks.door),
new Unlock(Blocks.waterExtractor)
);
}};
- frozenForest = new Zone("frozenForest", new MapGenerator("frozenForest", 1)
- .decor(new Decoration(Blocks.snow, Blocks.sporeCluster, 0.02))){{
+ frozenForest = new SectorPreset("frozenForest", starter, new FileMapGenerator("frozenForest")){{
loadout = Loadouts.basicFoundation;
startingItems = list(copper, 250);
conditionWave = 10;
@@ -111,7 +110,7 @@ public class Zones implements ContentList{
);
}};
- craters = new Zone("craters", new MapGenerator("craters", 1).decor(new Decoration(Blocks.snow, Blocks.sporeCluster, 0.004))){{
+ craters = new SectorPreset("craters", starter, new FileMapGenerator("craters")){{
startingItems = list(copper, 100);
conditionWave = 10;
resources = with(copper, lead, coal, sand, scrap);
@@ -122,7 +121,7 @@ public class Zones implements ContentList{
);
}};
- ruinousShores = new Zone("ruinousShores", new MapGenerator("ruinousShores", 1)){{
+ ruinousShores = new SectorPreset("ruinousShores", starter, new FileMapGenerator("ruinousShores")){{
loadout = Loadouts.basicFoundation;
startingItems = list(copper, 140, lead, 50);
conditionWave = 20;
@@ -138,8 +137,7 @@ public class Zones implements ContentList{
);
}};
- stainedMountains = new Zone("stainedMountains", new MapGenerator("stainedMountains", 2)
- .decor(new Decoration(Blocks.shale, Blocks.shaleBoulder, 0.02))){{
+ stainedMountains = new SectorPreset("stainedMountains", starter, new FileMapGenerator("stainedMountains")){{
loadout = Loadouts.basicFoundation;
startingItems = list(copper, 200, lead, 50);
conditionWave = 10;
@@ -153,20 +151,20 @@ public class Zones implements ContentList{
);
}};
- fungalPass = new Zone("fungalPass", new MapGenerator("fungalPass")){{
+ fungalPass = new SectorPreset("fungalPass", starter, new FileMapGenerator("fungalPass")){{
startingItems = list(copper, 250, lead, 250, Items.metaglass, 100, Items.graphite, 100);
resources = with(copper, lead, coal, titanium, sand);
configureObjective = new Launched(this);
requirements = with(
new ZoneWave(stainedMountains, 15),
- new Unlock(Blocks.daggerFactory),
- new Unlock(Blocks.crawlerFactory),
+ //new Unlock(Blocks.daggerFactory),
+ //new Unlock(Blocks.crawlerFactory),
new Unlock(Blocks.door),
new Unlock(Blocks.siliconSmelter)
);
}};
- overgrowth = new Zone("overgrowth", new MapGenerator("overgrowth")){{
+ overgrowth = new SectorPreset("overgrowth", starter, new FileMapGenerator("overgrowth")){{
startingItems = list(copper, 1500, lead, 1000, Items.silicon, 500, Items.metaglass, 250);
conditionWave = 12;
launchPeriod = 4;
@@ -177,14 +175,13 @@ public class Zones implements ContentList{
new ZoneWave(craters, 40),
new Launched(fungalPass),
new Unlock(Blocks.cultivator),
- new Unlock(Blocks.sporePress),
- new Unlock(Blocks.titanFactory),
- new Unlock(Blocks.wraithFactory)
+ new Unlock(Blocks.sporePress)
+ //new Unlock(Blocks.titanFactory),
+ //new Unlock(Blocks.wraithFactory)
);
}};
- tarFields = new Zone("tarFields", new MapGenerator("tarFields")
- .decor(new Decoration(Blocks.shale, Blocks.shaleBoulder, 0.02))){{
+ tarFields = new SectorPreset("tarFields", starter, new FileMapGenerator("tarFields")){{
loadout = Loadouts.basicFoundation;
startingItems = list(copper, 250, lead, 100);
conditionWave = 15;
@@ -198,7 +195,7 @@ public class Zones implements ContentList{
);
}};
- desolateRift = new Zone("desolateRift", new MapGenerator("desolateRift")){{
+ desolateRift = new SectorPreset("desolateRift", starter, new FileMapGenerator("desolateRift")){{
loadout = Loadouts.basicNucleus;
startingItems = list(copper, 1000, lead, 1000, Items.graphite, 250, titanium, 250, Items.silicon, 250);
conditionWave = 3;
@@ -223,8 +220,7 @@ public class Zones implements ContentList{
resources = Array.with(Items.copper, Items.scrap, Items.lead, Items.coal, Items.sand};
}};*/
- nuclearComplex = new Zone("nuclearComplex", new MapGenerator("nuclearProductionComplex", 1)
- .decor(new Decoration(Blocks.snow, Blocks.sporeCluster, 0.01))){{
+ nuclearComplex = new SectorPreset("nuclearComplex", starter, new FileMapGenerator("nuclearProductionComplex")){{
loadout = Loadouts.basicNucleus;
startingItems = list(copper, 1250, lead, 1500, Items.silicon, 400, Items.metaglass, 250);
conditionWave = 30;
diff --git a/core/src/mindustry/core/ContentLoader.java b/core/src/mindustry/core/ContentLoader.java
index 9018f5883e..7b6c1069ca 100644
--- a/core/src/mindustry/core/ContentLoader.java
+++ b/core/src/mindustry/core/ContentLoader.java
@@ -30,21 +30,17 @@ public class ContentLoader{
private @Nullable Content lastAdded;
private ObjectSet> initialization = new ObjectSet<>();
private ContentList[] content = {
- new Fx(),
new Items(),
new StatusEffects(),
new Liquids(),
new Bullets(),
- new Mechs(),
new UnitTypes(),
new Blocks(),
new Loadouts(),
new TechTree(),
- new Zones(),
- new TypeIDs(),
-
- //these are not really content classes, but this makes initialization easier
- new LegacyColorMapper(),
+ new Weathers(),
+ new Planets(),
+ new Zones()
};
public ContentLoader(){
@@ -137,13 +133,15 @@ public class ContentLoader{
if(blocks().size > i){
int color = pixmap.getPixel(i, 0);
- if(color == 0) continue;
+ if(color == 0 || color == 255) continue;
Block block = block(i);
- block.color.set(color);
+ block.mapColor.rgba8888(color);
+ block.hasColor = true;
}
}
pixmap.dispose();
+ ColorMapper.load();
}
public void dispose(){
@@ -239,6 +237,10 @@ public class ContentLoader{
return (Block)getByID(ContentType.block, id);
}
+ public Block block(String name){
+ return (Block)getByName(ContentType.block, name);
+ }
+
public Array
- items(){
return getBy(ContentType.item);
}
@@ -263,11 +265,15 @@ public class ContentLoader{
return (BulletType)getByID(ContentType.bullet, id);
}
- public Array zones(){
+ public Array zones(){
return getBy(ContentType.zone);
}
public Array units(){
return getBy(ContentType.unit);
}
+
+ public Array planets(){
+ return getBy(ContentType.planet);
+ }
}
diff --git a/core/src/mindustry/core/Control.java b/core/src/mindustry/core/Control.java
index 77ea0e2150..bbbdc415cb 100644
--- a/core/src/mindustry/core/Control.java
+++ b/core/src/mindustry/core/Control.java
@@ -3,26 +3,24 @@ package mindustry.core;
import arc.*;
import arc.assets.*;
import arc.audio.*;
-import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.input.*;
-import arc.math.geom.*;
import arc.scene.ui.*;
import arc.struct.*;
import arc.util.*;
import mindustry.content.*;
import mindustry.core.GameState.*;
import mindustry.entities.*;
-import mindustry.entities.type.*;
import mindustry.game.EventType.*;
import mindustry.game.*;
+import mindustry.game.Saves.*;
import mindustry.gen.*;
import mindustry.input.*;
+import mindustry.io.SaveIO.*;
import mindustry.maps.Map;
import mindustry.type.*;
import mindustry.ui.dialogs.*;
import mindustry.world.*;
-import mindustry.world.blocks.storage.*;
import java.io.*;
import java.text.*;
@@ -63,21 +61,19 @@ public class Control implements ApplicationListener, Loadable{
});
Events.on(PlayEvent.class, event -> {
- player.setTeam(netServer.assignTeam(player, playerGroup.all()));
- player.setDead(true);
+ player.team(netServer.assignTeam(player));
player.add();
state.set(State.playing);
});
Events.on(WorldLoadEvent.class, event -> {
- Core.app.post(() -> Core.app.post(() -> {
- if(net.active() && player.getClosestCore() != null){
- //set to closest core since that's where the player will probably respawn; prevents camera jumps
- Core.camera.position.set(player.isDead() ? player.getClosestCore() : player);
- }else{
- //locally, set to player position since respawning occurs immediately
- Core.camera.position.set(player);
+ //TODO test this
+ app.post(() -> app.post(() -> {
+ //TODO 0,0 seems like a bad choice?
+ Tilec core = state.teams.closestCore(0, 0, player.team());
+ if(core != null){
+ camera.position.set(core);
}
}));
});
@@ -92,9 +88,9 @@ public class Control implements ApplicationListener, Loadable{
});
Events.on(WaveEvent.class, event -> {
- if(world.getMap().getHightScore() < state.wave){
+ if(state.map.getHightScore() < state.wave){
hiscore = true;
- world.getMap().setHighScore(state.wave);
+ state.map.setHighScore(state.wave);
}
Sounds.wave.play();
@@ -105,20 +101,23 @@ public class Control implements ApplicationListener, Loadable{
Effects.shake(5, 6, Core.camera.position.x, Core.camera.position.y);
//the restart dialog can show info for any number of scenarios
Call.onGameOver(event.winner);
+ //TODO set meta to indicate game over
+ /*
if(state.rules.zone != null && !net.client()){
//remove zone save on game over
if(saves.getZoneSlot() != null && !state.rules.tutorial){
saves.getZoneSlot().delete();
}
- }
+ }*/
});
//autohost for pvp maps
Events.on(WorldLoadEvent.class, event -> app.post(() -> {
+ player.add();
if(state.rules.pvp && !net.active()){
try{
net.host(port);
- player.isAdmin = true;
+ player.admin(true);
}catch(IOException e){
ui.showException("$server.error", e);
state.set(State.menu);
@@ -129,7 +128,7 @@ public class Control implements ApplicationListener, Loadable{
Events.on(UnlockEvent.class, e -> ui.hudfrag.showUnlock(e.content));
Events.on(BlockBuildEndEvent.class, e -> {
- if(e.team == player.getTeam()){
+ if(e.team == player.team()){
if(e.breaking){
state.stats.buildingsDeconstructed++;
}else{
@@ -139,13 +138,13 @@ public class Control implements ApplicationListener, Loadable{
});
Events.on(BlockDestroyEvent.class, e -> {
- if(e.tile.getTeam() == player.getTeam()){
+ if(e.tile.team() == player.team()){
state.stats.buildingsDestroyed++;
}
});
Events.on(UnitDestroyEvent.class, e -> {
- if(e.unit.getTeam() != player.getTeam()){
+ if(e.unit.team() != player.team()){
state.stats.enemyUnitsDestroyed++;
}
});
@@ -163,22 +162,29 @@ public class Control implements ApplicationListener, Loadable{
});
Events.on(Trigger.newGame, () -> {
- TileEntity core = player.getClosestCore();
+ Tilec core = player.closestCore();
if(core == null) return;
+ //TODO this sounds pretty bad due to conflict
+ if(settings.getInt("musicvol") > 0){
+ Musics.land.stop();
+ Musics.land.play();
+ Musics.land.setVolume(settings.getInt("musicvol") / 100f);
+ }
+
app.post(() -> ui.hudfrag.showLand());
renderer.zoomIn(Fx.coreLand.lifetime);
- app.post(() -> Effects.effect(Fx.coreLand, core.x, core.y, 0, core.block));
+ app.post(() -> Fx.coreLand.at(core.getX(), core.getY(), 0, core.block()));
Time.run(Fx.coreLand.lifetime, () -> {
- Effects.effect(Fx.launch, core);
+ Fx.launch.at(core);
Effects.shake(5f, 5f, core);
});
});
Events.on(UnitDestroyEvent.class, e -> {
- if(e.unit instanceof BaseUnit && world.isZone()){
- data.unlockContent(((BaseUnit)e.unit).getType());
+ if(state.isCampaign()){
+ data.unlockContent(e.unit.type());
}
});
}
@@ -204,11 +210,9 @@ public class Control implements ApplicationListener, Loadable{
}
void createPlayer(){
- player = new Player();
- player.name = Core.settings.getString("name");
- player.color.set(Core.settings.getInt("color-0"));
- player.isLocal = true;
- player.isMobile = mobile;
+ player = PlayerEntity.create();
+ player.name(Core.settings.getString("name"));
+ player.color().set(Core.settings.getInt("color-0"));
if(mobile){
input = new MobileInput();
@@ -216,7 +220,7 @@ public class Control implements ApplicationListener, Loadable{
input = new DesktopInput();
}
- if(!state.is(State.menu)){
+ if(state.isGame()){
player.add();
}
@@ -239,7 +243,7 @@ public class Control implements ApplicationListener, Loadable{
logic.reset();
world.loadMap(map, rules);
state.rules = rules;
- state.rules.zone = null;
+ state.rules.sector = null;
state.rules.editor = false;
logic.play();
if(settings.getBool("savecreate") && !world.isInvalidMap()){
@@ -249,27 +253,42 @@ public class Control implements ApplicationListener, Loadable{
});
}
- public void playZone(Zone zone){
+ public void playSector(Sector sector){
ui.loadAnd(() -> {
- logic.reset();
- net.reset();
- world.loadGenerator(zone.generator);
- zone.rules.get(state.rules);
- state.rules.zone = zone;
- for(TileEntity core : state.teams.playerCores()){
- for(ItemStack stack : zone.getStartingItems()){
- core.items.add(stack.item, stack.amount);
+ ui.planet.hide();
+ SaveSlot slot = sector.save;
+ //TODO comment for new sector states
+ slot = null;
+ if(slot != null){
+ try{
+ net.reset();
+ slot.load();
+ state.rules.sector = sector;
+ state.set(State.playing);
+ }catch(SaveException e){
+ Log.err(e);
+ sector.save = null;
+ ui.showErrorMessage("$save.corrupted");
+ slot.delete();
+ playSector(sector);
}
+ ui.planet.hide();
+ }else{
+ net.reset();
+ logic.reset();
+ world.loadSector(sector);
+ state.rules.sector = sector;
+ logic.play();
+ control.saves.saveSector(sector);
+ Events.fire(Trigger.newGame);
}
- state.set(State.playing);
- state.wavetime = state.rules.waveSpacing;
- control.saves.zoneSave();
- logic.play();
- Events.fire(Trigger.newGame);
});
}
public void playTutorial(){
+ //TODO implement
+ ui.showInfo("death");
+ /*
Zone zone = Zones.groundZero;
ui.loadAnd(() -> {
logic.reset();
@@ -277,8 +296,8 @@ public class Control implements ApplicationListener, Loadable{
world.beginMapLoad();
- world.createTiles(zone.generator.width, zone.generator.height);
- zone.generator.generate(world.getTiles());
+ world.resize(zone.generator.width, zone.generator.height);
+ zone.generator.generate(world.tiles);
Tile coreb = null;
@@ -294,7 +313,7 @@ public class Control implements ApplicationListener, Loadable{
Geometry.circle(coreb.x, coreb.y, 10, (cx, cy) -> {
Tile tile = world.ltile(cx, cy);
- if(tile != null && tile.getTeam() == state.rules.defaultTeam && !(tile.block() instanceof CoreBlock)){
+ if(tile != null && tile.team() == state.rules.defaultTeam && !(tile.block() instanceof CoreBlock)){
tile.remove();
}
});
@@ -304,14 +323,15 @@ public class Control implements ApplicationListener, Loadable{
world.endMapLoad();
zone.rules.get(state.rules);
- state.rules.zone = zone;
- for(TileEntity core : state.teams.playerCores()){
+ //TODO assign zone!!
+ //state.rules.zone = zone;
+ for(Tilec core : state.teams.playerCores()){
for(ItemStack stack : zone.getStartingItems()){
- core.items.add(stack.item, stack.amount);
+ core.items().add(stack.item, stack.amount);
}
}
- TileEntity core = state.teams.playerCores().first();
- core.items.clear();
+ Tilec core = state.teams.playerCores().first();
+ core.items().clear();
logic.play();
state.rules.waveTimer = false;
@@ -319,7 +339,7 @@ public class Control implements ApplicationListener, Loadable{
state.rules.buildCostMultiplier = 0.3f;
state.rules.tutorial = true;
Events.fire(Trigger.newGame);
- });
+ });*/
}
public boolean isHighScore(){
@@ -430,13 +450,13 @@ public class Control implements ApplicationListener, Loadable{
settings.save();
}
- if(!state.is(State.menu)){
+ if(state.isGame()){
input.update();
- if(world.isZone()){
- for(TileEntity tile : state.teams.cores(player.getTeam())){
+ if(state.isCampaign()){
+ for(Tilec tile : state.teams.cores(player.team())){
for(Item item : content.items()){
- if(tile.items.has(item)){
+ if(tile.items().has(item)){
data.unlockContent(item);
}
}
diff --git a/core/src/mindustry/core/FileTree.java b/core/src/mindustry/core/FileTree.java
index 810b9669fb..589809c986 100644
--- a/core/src/mindustry/core/FileTree.java
+++ b/core/src/mindustry/core/FileTree.java
@@ -19,6 +19,8 @@ public class FileTree implements FileHandleResolver{
return files.get(path);
}else if(files.containsKey("/" + path)){
return files.get("/" + path);
+ }else if(Core.files == null){ //headless
+ return Fi.get(path);
}else{
return Core.files.internal(path);
}
diff --git a/core/src/mindustry/core/GameState.java b/core/src/mindustry/core/GameState.java
index 2b233789eb..6cd548ab6c 100644
--- a/core/src/mindustry/core/GameState.java
+++ b/core/src/mindustry/core/GameState.java
@@ -1,9 +1,12 @@
package mindustry.core;
import arc.*;
-import mindustry.entities.type.*;
+import arc.util.ArcAnnotate.*;
import mindustry.game.EventType.*;
import mindustry.game.*;
+import mindustry.gen.*;
+import mindustry.maps.*;
+import mindustry.type.*;
import static mindustry.Vars.*;
@@ -14,6 +17,8 @@ public class GameState{
public float wavetime;
/** Whether the game is in game over state. */
public boolean gameOver = false, launched = false;
+ /** Map that is currently being played on. */
+ public @NonNull Map map = emptyMap;
/** The current game rules. */
public Rules rules = new Rules();
/** Statistics for this save/game. Displayed after game over. */
@@ -25,8 +30,8 @@ public class GameState{
/** Current game state. */
private State state = State.menu;
- public BaseUnit boss(){
- return unitGroup.find(u -> u.isBoss() && u.getTeam() == rules.waveTeam);
+ public Unitc boss(){
+ return Groups.unit.find(u -> u.isBoss() && u.team() == rules.waveTeam);
}
public void set(State astate){
@@ -34,6 +39,20 @@ public class GameState{
state = astate;
}
+ /** Note that being in a campaign does not necessarily mean having a sector. */
+ public boolean isCampaign(){
+ return rules.sector != null || rules.region != null;
+ }
+
+ public boolean hasSector(){
+ return rules.sector != null;
+ }
+
+ @Nullable
+ public Sector getSector(){
+ return rules.sector;
+ }
+
public boolean isEditor(){
return rules.editor;
}
@@ -42,6 +61,15 @@ public class GameState{
return (is(State.paused) && !net.active()) || (gameOver && !net.active());
}
+ /** @return whether the current state is *not* the menu. */
+ public boolean isGame(){
+ return state != State.menu;
+ }
+
+ public boolean isMenu(){
+ return state == State.menu;
+ }
+
public boolean is(State astate){
return state == astate;
}
diff --git a/core/src/mindustry/core/Logic.java b/core/src/mindustry/core/Logic.java
index a693000846..91bd2c7020 100644
--- a/core/src/mindustry/core/Logic.java
+++ b/core/src/mindustry/core/Logic.java
@@ -6,12 +6,10 @@ import mindustry.annotations.Annotations.*;
import mindustry.content.*;
import mindustry.core.GameState.*;
import mindustry.ctype.*;
-import mindustry.entities.*;
-import mindustry.entities.type.*;
+import mindustry.gen.*;
import mindustry.game.EventType.*;
import mindustry.game.*;
import mindustry.game.Teams.*;
-import mindustry.gen.*;
import mindustry.type.*;
import mindustry.world.*;
import mindustry.world.blocks.*;
@@ -32,13 +30,15 @@ import static mindustry.Vars.*;
public class Logic implements ApplicationListener{
public Logic(){
- Events.on(WaveEvent.class, event -> {
- for(Player p : playerGroup.all()){
- p.respawns = state.rules.respawns;
- }
+ Events.on(WorldLoadEvent.class, event -> {
+ //TODO remove later
+ //Weathers.snow.create();
+ });
- if(world.isZone()){
- world.getZone().updateWave(state.wave);
+ Events.on(WaveEvent.class, event -> {
+ if(state.isCampaign()){
+ //TODO implement
+ //state.getSector().updateWave(state.wave);
}
});
@@ -62,7 +62,7 @@ public class Logic implements ApplicationListener{
}
}
- TeamData data = state.teams.get(tile.getTeam());
+ TeamData data = state.teams.get(tile.team());
//remove existing blocks that have been placed here.
//painful O(n) iteration + copy
@@ -99,19 +99,20 @@ public class Logic implements ApplicationListener{
}
}
+ /** Adds starting items, resets wave time, and sets state to playing. */
public void play(){
state.set(State.playing);
state.wavetime = state.rules.waveSpacing * 2; //grace period of 2x wave time before game starts
Events.fire(new PlayEvent());
//add starting items
- if(!world.isZone()){
+ if(!state.isCampaign()){
for(TeamData team : state.teams.getActive()){
if(team.hasCore()){
- TileEntity entity = team.core();
- entity.items.clear();
+ Tilec entity = team.core();
+ entity.items().clear();
for(ItemStack stack : state.rules.loadout){
- entity.items.add(stack.item, stack.amount);
+ entity.items().add(stack.item, stack.amount);
}
}
}
@@ -119,24 +120,21 @@ public class Logic implements ApplicationListener{
}
public void reset(){
- state.wave = 1;
- state.wavetime = state.rules.waveSpacing;
- state.gameOver = state.launched = false;
- state.teams = new Teams();
- state.rules = new Rules();
- state.stats = new Stats();
+ State prev = state.getState();
+ //recreate gamestate - sets state to menu
+ state = new GameState();
+ //fire change event, since it was technically changed
+ Events.fire(new StateChangeEvent(prev, State.menu));
- entities.clear();
+ Groups.all.clear();
Time.clear();
- TileEntity.sleepingEntities = 0;
-
Events.fire(new ResetEvent());
}
public void runWave(){
spawner.spawnEnemies();
state.wave++;
- state.wavetime = world.isZone() && world.getZone().isLaunchWave(state.wave) ? state.rules.waveSpacing * state.rules.launchWaveMultiplier : state.rules.waveSpacing;
+ state.wavetime = state.hasSector() && state.getSector().isLaunchWave(state.wave) ? state.rules.waveSpacing * state.rules.launchWaveMultiplier : state.rules.waveSpacing;
Events.fire(new WaveEvent());
}
@@ -158,7 +156,7 @@ public class Logic implements ApplicationListener{
}
if(alive != null && !state.gameOver){
- if(world.isZone() && alive == state.rules.defaultTeam){
+ if(state.isCampaign() && alive == state.rules.defaultTeam){
//in attack maps, a victorious game over is equivalent to a launch
Call.launchZone();
}else{
@@ -175,21 +173,22 @@ public class Logic implements ApplicationListener{
ui.hudfrag.showLaunch();
}
- for(TileEntity tile : state.teams.playerCores()){
- Effects.effect(Fx.launch, tile);
+ for(Tilec tile : state.teams.playerCores()){
+ Fx.launch.at(tile);
}
- if(world.getZone() != null){
- world.getZone().setLaunched();
+ if(state.isCampaign()){
+ //TODO implement
+ //state.getSector().setLaunched();
}
Time.runTask(30f, () -> {
- for(TileEntity entity : state.teams.playerCores()){
+ for(Tilec entity : state.teams.playerCores()){
for(Item item : content.items()){
- data.addItem(item, entity.items.get(item));
- Events.fire(new LaunchItemEvent(item, entity.items.get(item)));
+ data.addItem(item, entity.items().get(item));
+ Events.fire(new LaunchItemEvent(item, entity.items().get(item)));
}
- entity.tile.remove();
+ entity.tile().remove();
}
state.launched = true;
state.gameOver = true;
@@ -209,13 +208,17 @@ public class Logic implements ApplicationListener{
@Override
public void update(){
Events.fire(Trigger.update);
+ universe.updateGlobal();
- if(!state.is(State.menu)){
+ if(state.isGame()){
if(!net.client()){
- state.enemies = unitGroup.count(b -> b.getTeam() == state.rules.waveTeam && b.countsAsEnemy());
+ state.enemies = Groups.unit.count(b -> b.team() == state.rules.waveTeam && b.type().isCounted);
}
if(!state.isPaused()){
+ if(state.isCampaign()){
+ universe.update();
+ }
Time.update();
if(state.rules.waves && state.rules.waveTimer && !state.gameOver){
@@ -228,35 +231,7 @@ public class Logic implements ApplicationListener{
runWave();
}
- if(!headless){
- effectGroup.update();
- groundEffectGroup.update();
- }
-
- if(!state.isEditor()){
- unitGroup.update();
- puddleGroup.update();
- shieldGroup.update();
- bulletGroup.update();
- tileGroup.update();
- fireGroup.update();
- }else{
- unitGroup.updateEvents();
- collisions.updatePhysics(unitGroup);
- }
-
- playerGroup.update();
-
- //effect group only contains item transfers in the headless version, update it!
- if(headless){
- effectGroup.update();
- }
-
- if(!state.isEditor()){
- //bulletGroup
- collisions.collideGroups(bulletGroup, unitGroup);
- collisions.collideGroups(bulletGroup, playerGroup);
- }
+ Groups.update();
}
if(!net.client() && !world.isInvalidMap() && !state.isEditor() && state.rules.canGameOver){
diff --git a/core/src/mindustry/core/NetClient.java b/core/src/mindustry/core/NetClient.java
index 16f89290df..459f761abc 100644
--- a/core/src/mindustry/core/NetClient.java
+++ b/core/src/mindustry/core/NetClient.java
@@ -1,7 +1,6 @@
package mindustry.core;
import arc.*;
-import arc.graphics.*;
import arc.math.*;
import arc.struct.*;
import arc.util.*;
@@ -11,12 +10,7 @@ import arc.util.serialization.*;
import mindustry.*;
import mindustry.annotations.Annotations.*;
import mindustry.core.GameState.*;
-import mindustry.ctype.*;
-import mindustry.entities.*;
-import mindustry.entities.Effects.*;
-import mindustry.entities.traits.BuilderTrait.*;
-import mindustry.entities.traits.*;
-import mindustry.entities.type.*;
+import mindustry.entities.units.*;
import mindustry.game.EventType.*;
import mindustry.game.*;
import mindustry.gen.*;
@@ -24,7 +18,6 @@ import mindustry.net.Administration.*;
import mindustry.net.Net.*;
import mindustry.net.*;
import mindustry.net.Packets.*;
-import mindustry.type.*;
import mindustry.world.*;
import mindustry.world.modules.*;
@@ -62,7 +55,7 @@ public class NetClient implements ApplicationListener{
net.handleClient(Connect.class, packet -> {
Log.info("Connecting to server: {0}", packet.addressTCP);
- player.isAdmin = false;
+ player.admin(false);
reset();
@@ -77,11 +70,11 @@ public class NetClient implements ApplicationListener{
});
ConnectPacket c = new ConnectPacket();
- c.name = player.name;
+ c.name = player.name();
c.mods = mods.getModStrings();
c.mobile = mobile;
c.versionType = Version.type;
- c.color = player.color.rgba();
+ c.color = player.color().rgba();
c.usid = getUsid(packet.addressTCP);
c.uuid = platform.getUUID();
@@ -99,11 +92,10 @@ public class NetClient implements ApplicationListener{
if(quietReset) return;
connecting = false;
- state.set(State.menu);
logic.reset();
platform.updateRPC();
- player.name = Core.settings.getString("name");
- player.color.set(Core.settings.getInt("color-0"));
+ player.name(Core.settings.getString("name"));
+ player.color().set(Core.settings.getInt("color-0"));
if(quiet) return;
@@ -130,21 +122,20 @@ public class NetClient implements ApplicationListener{
});
net.handleClient(InvokePacket.class, packet -> {
- packet.writeBuffer.position(0);
- RemoteReadClient.readPacket(packet.writeBuffer, packet.type);
+ RemoteReadClient.readPacket(packet.reader(), packet.type);
});
}
//called on all clients
@Remote(targets = Loc.server, variants = Variant.both)
- public static void sendMessage(String message, String sender, Player playersender){
+ public static void sendMessage(String message, String sender, Playerc playersender){
if(Vars.ui != null){
Vars.ui.chatfrag.addMessage(message, sender);
}
if(playersender != null){
- playersender.lastText = message;
- playersender.textFadeTime = 1f;
+ playersender.lastText(message);
+ playersender.textFadeTime(1f);
}
}
@@ -158,7 +149,7 @@ public class NetClient implements ApplicationListener{
//called when a server recieves a chat message from a player
@Remote(called = Loc.server, targets = Loc.client)
- public static void sendChatMessage(Player player, String message){
+ public static void sendChatMessage(Playerc player, String message){
if(message.length() > maxTextLength){
throw new ValidateException(player, "Player has sent a message above the text limit.");
}
@@ -176,18 +167,18 @@ public class NetClient implements ApplicationListener{
//special case; graphical server needs to see its message
if(!headless){
- sendMessage(message, colorizeName(player.id, player.name), player);
+ sendMessage(message, colorizeName(player.id(), player.name()), player);
}
//server console logging
- Log.info("&y{0}: &lb{1}", player.name, message);
+ Log.info("&y{0}: &lb{1}", player.name(), message);
//invoke event for all clients but also locally
//this is required so other clients get the correct name even if they don't know who's sending it yet
- Call.sendMessage(message, colorizeName(player.id, player.name), player);
+ Call.sendMessage(message, colorizeName(player.id(), player.name()), player);
}else{
//log command to console but with brackets
- Log.info("<&y{0}: &lm{1}&lg>", player.name, message);
+ Log.info("<&y{0}: &lm{1}&lg>", player.name(), message);
//a command was sent, now get the output
if(response.type != ResponseType.valid){
@@ -208,23 +199,22 @@ public class NetClient implements ApplicationListener{
}
public static String colorizeName(int id, String name){
- Player player = playerGroup.getByID(id);
+ Playerc player = Groups.player.getByID(id);
if(name == null || player == null) return null;
- return "[#" + player.color.toString().toUpperCase() + "]" + name;
+ return "[#" + player.color().toString().toUpperCase() + "]" + name;
}
@Remote(called = Loc.client, variants = Variant.one)
public static void onConnect(String ip, int port){
netClient.disconnectQuietly();
- state.set(State.menu);
logic.reset();
ui.join.connect(ip, port);
}
@Remote(targets = Loc.client)
- public static void onPing(Player player, long time){
- Call.onPingResponse(player.con, time);
+ public static void onPing(Playerc player, long time){
+ Call.onPingResponse(player.con(), time);
}
@Remote(variants = Variant.one)
@@ -233,7 +223,7 @@ public class NetClient implements ApplicationListener{
}
@Remote(variants = Variant.one)
- public static void onTraceInfo(Player player, TraceInfo info){
+ public static void onTraceInfo(Playerc player, TraceInfo info){
if(player != null){
ui.traces.show(player, info);
}
@@ -242,7 +232,6 @@ public class NetClient implements ApplicationListener{
@Remote(variants = Variant.one, priority = PacketPriority.high)
public static void onKick(KickReason reason){
netClient.disconnectQuietly();
- state.set(State.menu);
logic.reset();
if(!reason.quiet){
@@ -258,7 +247,6 @@ public class NetClient implements ApplicationListener{
@Remote(variants = Variant.one, priority = PacketPriority.high)
public static void onKick(String reason){
netClient.disconnectQuietly();
- state.set(State.menu);
logic.reset();
ui.showText("$disconnect", reason, Align.left);
ui.loadfrag.hide();
@@ -303,17 +291,18 @@ public class NetClient implements ApplicationListener{
ui.showLabel(message, duration, worldx, worldy);
}
+ /*
@Remote(variants = Variant.both, unreliable = true)
public static void onEffect(Effect effect, float x, float y, float rotation, Color color){
if(effect == null) return;
- Effects.effect(effect, color, x, y, rotation);
+ effect.at(x, y, rotation, color);
}
@Remote(variants = Variant.both)
public static void onEffectReliable(Effect effect, float x, float y, float rotation, Color color){
onEffect(effect, x, y, rotation, color);
- }
+ }*/
@Remote(variants = Variant.both)
public static void onInfoToast(String message, float duration){
@@ -329,7 +318,7 @@ public class NetClient implements ApplicationListener{
@Remote(variants = Variant.both)
public static void onWorldDataBegin(){
- entities.clear();
+ Groups.all.clear();
netClient.removed.clear();
logic.reset();
@@ -347,60 +336,54 @@ public class NetClient implements ApplicationListener{
@Remote(variants = Variant.one)
public static void onPositionSet(float x, float y){
- player.x = x;
- player.y = y;
+ player.set(x, y);
}
@Remote
public static void onPlayerDisconnect(int playerid){
- playerGroup.removeByID(playerid);
+ Groups.player.removeByID(playerid);
}
@Remote(variants = Variant.one, priority = PacketPriority.low, unreliable = true)
- public static void onEntitySnapshot(byte groupID, short amount, short dataLen, byte[] data){
+ public static void onEntitySnapshot(short amount, short dataLen, byte[] data){
try{
netClient.byteStream.setBytes(net.decompressSnapshot(data, dataLen));
DataInputStream input = netClient.dataStream;
- EntityGroup group = entities.get(groupID);
-
//go through each entity
for(int j = 0; j < amount; j++){
int id = input.readInt();
byte typeID = input.readByte();
- SyncTrait entity = group == null ? null : (SyncTrait)group.getByID(id);
+ Syncc entity = Groups.sync.getByID(id);
boolean add = false, created = false;
- if(entity == null && id == player.id){
+ if(entity == null && id == player.id()){
entity = player;
add = true;
}
//entity must not be added yet, so create it
if(entity == null){
- entity = (SyncTrait)content.getByID(ContentType.typeid, typeID).constructor.get();
- entity.resetID(id);
- if(!netClient.isEntityUsed(entity.getID())){
+ entity = (Syncc)EntityMapping.map(typeID).get();
+ entity.id(id);
+ if(!netClient.isEntityUsed(entity.id())){
add = true;
}
created = true;
}
//read the entity
- entity.read(input);
+ entity.read(Reads.get(input));
- if(created && entity.getInterpolator() != null && entity.getInterpolator().target != null){
+ if(created && entity.interpolator().target != null){
//set initial starting position
- entity.setNet(entity.getInterpolator().target.x, entity.getInterpolator().target.y);
- if(entity instanceof Unit && entity.getInterpolator().targets.length > 0){
- ((Unit)entity).rotation = entity.getInterpolator().targets[0];
- }
+ entity.setNet(entity.interpolator().target.x, entity.interpolator().target.y);
}
if(add){
entity.add();
- netClient.addRemovedEntity(entity.getID());
+ netClient.addRemovedEntity(entity.id());
}
}
}catch(IOException e){
@@ -421,7 +404,7 @@ public class NetClient implements ApplicationListener{
Log.warn("Missing entity at {0}. Skipping block snapshot.", tile);
break;
}
- tile.entity.read(input, tile.entity.version());
+ tile.entity.readAll(Reads.get(input), tile.entity.version());
}
}catch(Exception e){
e.printStackTrace();
@@ -449,9 +432,9 @@ public class NetClient implements ApplicationListener{
Tile tile = world.tile(pos);
if(tile != null && tile.entity != null){
- tile.entity.items.read(input);
+ tile.entity.items().read(Reads.get(input));
}else{
- new ItemModule().read(input);
+ new ItemModule().read(Reads.get(input));
}
}
@@ -464,7 +447,7 @@ public class NetClient implements ApplicationListener{
public void update(){
if(!net.client()) return;
- if(!state.is(State.menu)){
+ if(state.isGame()){
if(!connecting) sync();
}else if(!connecting){
net.disconnect();
@@ -508,7 +491,7 @@ public class NetClient implements ApplicationListener{
quiet = false;
lastSent = 0;
- entities.clear();
+ Groups.all.clear();
ui.chatfrag.clearMessages();
}
@@ -542,22 +525,28 @@ public class NetClient implements ApplicationListener{
}
void sync(){
-
if(timer.get(0, playerSyncTime)){
- BuildRequest[] requests;
- //limit to 10 to prevent buffer overflows
- int usedRequests = Math.min(player.buildQueue().size, 10);
+ BuildRequest[] requests = null;
+ if(player.isBuilder() && control.input.isBuilding){
+ //limit to 10 to prevent buffer overflows
+ int usedRequests = Math.min(player.builder().requests().size, 10);
- requests = new BuildRequest[usedRequests];
- for(int i = 0; i < usedRequests; i++){
- requests[i] = player.buildQueue().get(i);
+ requests = new BuildRequest[usedRequests];
+ for(int i = 0; i < usedRequests; i++){
+ requests[i] = player.builder().requests().get(i);
+ }
}
- Call.onClientShapshot(lastSent++, player.x, player.y,
- player.pointerX, player.pointerY, player.rotation, player.baseRotation,
- player.velocity().x, player.velocity().y,
- player.getMineTile(),
- player.isBoosting, player.isShooting, ui.chatfrag.shown(), player.isBuilding,
+ Unitc unit = player.dead() ? Nulls.unit : player.unit();
+
+ Call.onClientShapshot(lastSent++,
+ unit.x(), unit.y(),
+ player.mouseX(), player.mouseY(),
+ unit.rotation(),
+ unit instanceof Legsc ? ((Legsc)unit).baseRotation() : 0,
+ unit.vel().x, unit.vel().y,
+ player.miner().mineTile(),
+ /*player.isBoosting*/false, control.input.isShooting, ui.chatfrag.shown(),
requests,
Core.camera.position.x, Core.camera.position.y,
Core.camera.width * viewScale, Core.camera.height * viewScale);
diff --git a/core/src/mindustry/core/NetServer.java b/core/src/mindustry/core/NetServer.java
index cc06401a18..12d12532d8 100644
--- a/core/src/mindustry/core/NetServer.java
+++ b/core/src/mindustry/core/NetServer.java
@@ -6,16 +6,14 @@ import arc.math.*;
import arc.math.geom.*;
import arc.struct.*;
import arc.util.*;
+import arc.util.ArcAnnotate.*;
import arc.util.CommandHandler.*;
import arc.util.io.*;
import arc.util.serialization.*;
import mindustry.annotations.Annotations.*;
import mindustry.content.*;
import mindustry.core.GameState.*;
-import mindustry.entities.*;
-import mindustry.entities.traits.BuilderTrait.*;
-import mindustry.entities.traits.*;
-import mindustry.entities.type.*;
+import mindustry.entities.units.*;
import mindustry.game.EventType.*;
import mindustry.game.*;
import mindustry.game.Teams.*;
@@ -51,8 +49,8 @@ public class NetServer implements ApplicationListener{
if((state.rules.waveTeam == data.team && state.rules.waves) || !data.team.active()) return Integer.MAX_VALUE;
int count = 0;
- for(Player other : players){
- if(other.getTeam() == data.team && other != player){
+ for(Playerc other : players){
+ if(other.team() == data.team && other != player){
count++;
}
}
@@ -67,8 +65,8 @@ public class NetServer implements ApplicationListener{
private boolean closing = false;
private Interval timer = new Interval();
- private ByteBuffer writeBuffer = ByteBuffer.allocate(127);
- private ByteBufferOutput outputBuffer = new ByteBufferOutput(writeBuffer);
+ private ReusableByteOutStream writeBuffer = new ReusableByteOutStream(127);
+ private Writes outputBuffer = new Writes(new DataOutputStream(writeBuffer));
/** Stream for writing player sync data to. */
private ReusableByteOutStream syncStream = new ReusableByteOutStream();
@@ -133,7 +131,7 @@ public class NetServer implements ApplicationListener{
return;
}
- if(admins.getPlayerLimit() > 0 && playerGroup.size() >= admins.getPlayerLimit() && !netServer.admins.isAdmin(uuid, packet.usid)){
+ if(admins.getPlayerLimit() > 0 && Groups.player.size() >= admins.getPlayerLimit() && !netServer.admins.isAdmin(uuid, packet.usid)){
con.kick(KickReason.playerLimit);
return;
}
@@ -174,16 +172,14 @@ public class NetServer implements ApplicationListener{
boolean preventDuplicates = headless && netServer.admins.getStrict();
if(preventDuplicates){
- for(Player player : playerGroup.all()){
- if(player.name.trim().equalsIgnoreCase(packet.name.trim())){
- con.kick(KickReason.nameInUse);
- return;
- }
+ if(Groups.player.contains(p -> p.name().trim().equalsIgnoreCase(packet.name.trim()))){
+ con.kick(KickReason.nameInUse);
+ return;
+ }
- if(player.uuid != null && player.usid != null && (player.uuid.equals(packet.uuid) || player.usid.equals(packet.usid))){
- con.kick(KickReason.idInUse);
- return;
- }
+ if(Groups.player.contains(player -> player.uuid().equals(packet.uuid) || player.usid().equals(packet.usid))){
+ con.kick(KickReason.idInUse);
+ return;
}
}
@@ -207,25 +203,22 @@ public class NetServer implements ApplicationListener{
con.modclient = true;
}
- Player player = new Player();
- player.isAdmin = admins.isAdmin(uuid, packet.usid);
- player.con = con;
- player.usid = packet.usid;
- player.name = packet.name;
- player.uuid = uuid;
- player.isMobile = packet.mobile;
- player.dead = true;
- player.setNet(player.x, player.y);
- player.color.set(packet.color);
- player.color.a = 1f;
+ Playerc player = PlayerEntity.create();
+ player.admin(admins.isAdmin(uuid, packet.usid));
+ player.con(con);
+ player.con().usid = packet.usid;
+ player.con().uuid = uuid;
+ player.con().mobile = packet.mobile;
+ player.name(packet.name);
+ player.color().set(packet.color).a(1f);
//save admin ID but don't overwrite it
- if(!player.isAdmin && !info.admin){
+ if(!player.admin() && !info.admin){
info.adminUsid = packet.usid;
}
try{
- writeBuffer.position(0);
+ writeBuffer.reset();
player.write(outputBuffer);
}catch(Throwable t){
t.printStackTrace();
@@ -236,7 +229,7 @@ public class NetServer implements ApplicationListener{
con.player = player;
//playing in pvp mode automatically assigns players to teams
- player.setTeam(assignTeam(player, playerGroup.all()));
+ player.team(assignTeam(player));
sendWorldData(player);
@@ -248,7 +241,7 @@ public class NetServer implements ApplicationListener{
net.handleServer(InvokePacket.class, (con, packet) -> {
if(con.player == null) return;
try{
- RemoteReadServer.readPacket(packet.writeBuffer, packet.type, con.player);
+ RemoteReadServer.readPacket(packet.reader(), packet.type, con.player);
}catch(ValidateException e){
Log.debug("Validation failed for '{0}': {1}", e.player, e.getMessage());
}catch(RuntimeException e){
@@ -270,7 +263,7 @@ public class NetServer implements ApplicationListener{
}
private void registerCommands(){
- clientCommands.register("help", "[page]", "Lists all commands.", (args, player) -> {
+ clientCommands.register("help", "[page]", "Lists all commands.", (args, player) -> {
if(args.length > 0 && !Strings.canParseInt(args[0])){
player.sendMessage("[scarlet]'page' must be a number.");
return;
@@ -296,8 +289,8 @@ public class NetServer implements ApplicationListener{
player.sendMessage(result.toString());
});
- clientCommands.register("t", "", "Send a message only to your teammates.", (args, player) -> {
- playerGroup.all().each(p -> p.getTeam() == player.getTeam(), o -> o.sendMessage(args[0], player, "[#" + player.getTeam().color.toString() + "]" + NetClient.colorizeName(player.id, player.name)));
+ clientCommands.register("t", "", "Send a message only to your teammates.", (args, player) -> {
+ Groups.player.each(p -> p.team() == player.team(), o -> o.sendMessage(args[0], player, "[#" + player.team().color.toString() + "]" + NetClient.colorizeName(player.id(), player.name())));
});
//duration of a a kick in seconds
@@ -308,37 +301,37 @@ public class NetServer implements ApplicationListener{
int voteCooldown = 60 * 1;
class VoteSession{
- Player target;
+ Playerc target;
ObjectSet voted = new ObjectSet<>();
VoteSession[] map;
Timer.Task task;
int votes;
- public VoteSession(VoteSession[] map, Player target){
+ public VoteSession(VoteSession[] map, Playerc target){
this.target = target;
this.map = map;
this.task = Timer.schedule(() -> {
if(!checkPass()){
- Call.sendMessage(Strings.format("[lightgray]Vote failed. Not enough votes to kick[orange] {0}[lightgray].", target.name));
+ Call.sendMessage(Strings.format("[lightgray]Vote failed. Not enough votes to kick[orange] {0}[lightgray].", target.name()));
map[0] = null;
task.cancel();
}
}, voteDuration);
}
- void vote(Player player, int d){
+ void vote(Playerc player, int d){
votes += d;
- voted.addAll(player.uuid, admins.getInfo(player.uuid).lastIP);
+ voted.addAll(player.uuid(), admins.getInfo(player.uuid()).lastIP);
Call.sendMessage(Strings.format("[orange]{0}[lightgray] has voted on kicking[orange] {1}[].[accent] ({2}/{3})\n[lightgray]Type[orange] /vote [] to agree.",
- player.name, target.name, votes, votesRequired()));
+ player.name(), target.name(), votes, votesRequired()));
}
boolean checkPass(){
if(votes >= votesRequired()){
- Call.sendMessage(Strings.format("[orange]Vote passed.[scarlet] {0}[orange] will be banned from the server for {1} minutes.", target.name, (kickDuration/60)));
+ Call.sendMessage(Strings.format("[orange]Vote passed.[scarlet] {0}[orange] will be banned from the server for {1} minutes.", target.name(), (kickDuration/60)));
target.getInfo().lastKicked = Time.millis() + kickDuration*1000;
- playerGroup.all().each(p -> p.uuid != null && p.uuid.equals(target.uuid), p -> p.con.kick(KickReason.vote));
+ Groups.player.each(p -> p.uuid().equals(target.uuid()), p -> p.kick(KickReason.vote));
map[0] = null;
task.cancel();
return true;
@@ -351,18 +344,18 @@ public class NetServer implements ApplicationListener{
//current kick sessions
VoteSession[] currentlyKicking = {null};
- clientCommands.register("votekick", "[player...]", "Vote to kick a player, with a cooldown.", (args, player) -> {
+ clientCommands.register("votekick", "[player...]", "Vote to kick a player, with a cooldown.", (args, player) -> {
if(!Config.enableVotekick.bool()){
player.sendMessage("[scarlet]Vote-kick is disabled on this server.");
return;
}
- if(playerGroup.size() < 3){
+ if(Groups.player.size() < 3){
player.sendMessage("[scarlet]At least 3 players are needed to start a votekick.");
return;
}
- if(player.isLocal){
+ if(player.isLocal()){
player.sendMessage("[scarlet]Just kick them yourself if you're the host.");
return;
}
@@ -370,27 +363,26 @@ public class NetServer implements ApplicationListener{
if(args.length == 0){
StringBuilder builder = new StringBuilder();
builder.append("[orange]Players to kick: \n");
- for(Player p : playerGroup.all()){
- if(p.isAdmin || p.con == null || p == player) continue;
- builder.append("[lightgray] ").append(p.name).append("[accent] (#").append(p.id).append(")\n");
- }
+ Groups.player.each(p -> !p.admin() && p.con() != null && p != player, p -> {
+ builder.append("[lightgray] ").append(p.name()).append("[accent] (#").append(p.id()).append(")\n");
+ });
player.sendMessage(builder.toString());
}else{
- Player found;
+ Playerc found;
if(args[0].length() > 1 && args[0].startsWith("#") && Strings.canParseInt(args[0].substring(1))){
int id = Strings.parseInt(args[0].substring(1));
- found = playerGroup.find(p -> p.id == id);
+ found = Groups.player.find(p -> p.id() == id);
}else{
- found = playerGroup.find(p -> p.name.equalsIgnoreCase(args[0]));
+ found = Groups.player.find(p -> p.name().equalsIgnoreCase(args[0]));
}
if(found != null){
- if(found.isAdmin){
+ if(found.admin()){
player.sendMessage("[scarlet]Did you really expect to be able to kick an admin?");
- }else if(found.isLocal){
+ }else if(found.isLocal()){
player.sendMessage("[scarlet]Local players cannot be kicked.");
- }else if(found.getTeam() != player.getTeam()){
+ }else if(found.team() != player.team()){
player.sendMessage("[scarlet]Only players on your team can be kicked.");
}else{
if(!vtime.get()){
@@ -409,17 +401,17 @@ public class NetServer implements ApplicationListener{
}
});
- clientCommands.register("vote", "", "Vote to kick the current player.", (arg, player) -> {
+ clientCommands.register("vote", "", "Vote to kick the current player.", (arg, player) -> {
if(currentlyKicking[0] == null){
player.sendMessage("[scarlet]Nobody is being voted on.");
}else{
- if(player.isLocal){
+ if(player.isLocal()){
player.sendMessage("Local players can't vote. Kick the player yourself instead.");
return;
}
//hosts can vote all they want
- if(player.uuid != null && (currentlyKicking[0].voted.contains(player.uuid) || currentlyKicking[0].voted.contains(admins.getInfo(player.uuid).lastIP))){
+ if((currentlyKicking[0].voted.contains(player.uuid()) || currentlyKicking[0].voted.contains(admins.getInfo(player.uuid()).lastIP))){
player.sendMessage("[scarlet]You've already voted. Sit down.");
return;
}
@@ -440,8 +432,8 @@ public class NetServer implements ApplicationListener{
});
- clientCommands.register("sync", "Re-synchronize world state.", (args, player) -> {
- if(player.isLocal){
+ clientCommands.register("sync", "Re-synchronize world state.", (args, player) -> {
+ if(player.isLocal()){
player.sendMessage("[scarlet]Re-synchronizing as the host is pointless.");
}else{
if(Time.timeSinceMillis(player.getInfo().lastSyncTime) < 1000 * 5){
@@ -450,69 +442,73 @@ public class NetServer implements ApplicationListener{
}
player.getInfo().lastSyncTime = Time.millis();
- Call.onWorldDataBegin(player.con);
+ Call.onWorldDataBegin(player.con());
netServer.sendWorldData(player);
}
});
}
public int votesRequired(){
- return 2 + (playerGroup.size() > 4 ? 1 : 0);
+ return 2 + (Groups.player.size() > 4 ? 1 : 0);
}
- public Team assignTeam(Player current, Iterable players){
+ public Team assignTeam(Playerc current){
+ return assigner.assign(current, Groups.player);
+ }
+
+ public Team assignTeam(Playerc current, Iterable players){
return assigner.assign(current, players);
}
- public void sendWorldData(Player player){
+ public void sendWorldData(Playerc player){
ByteArrayOutputStream stream = new ByteArrayOutputStream();
DeflaterOutputStream def = new FastDeflaterOutputStream(stream);
NetworkIO.writeWorld(player, def);
WorldStream data = new WorldStream();
data.stream = new ByteArrayInputStream(stream.toByteArray());
- player.con.sendStream(data);
+ player.con().sendStream(data);
Log.debug("Packed {0} compressed bytes of world data.", stream.size());
}
- public static void onDisconnect(Player player, String reason){
+ public static void onDisconnect(Playerc player, String reason){
//singleplayer multiplayer wierdness
- if(player.con == null){
+ if(player.con() == null){
player.remove();
return;
}
- if(!player.con.hasDisconnected){
- if(player.con.hasConnected){
+ if(!player.con().hasDisconnected){
+ if(player.con().hasConnected){
Events.fire(new PlayerLeave(player));
- if(Config.showConnectMessages.bool()) Call.sendMessage("[accent]" + player.name + "[accent] has disconnected.");
- Call.onPlayerDisconnect(player.id);
+ if(Config.showConnectMessages.bool()) Call.sendMessage("[accent]" + player.name() + "[accent] has disconnected.");
+ Call.onPlayerDisconnect(player.id());
}
- if(Config.showConnectMessages.bool()) Log.info("&lm[{1}] &lc{0} has disconnected. &lg&fi({2})", player.name, player.uuid, reason);
+ if(Config.showConnectMessages.bool()) Log.info("&lm[{1}] &lc{0} has disconnected. &lg&fi({2})", player.name(), player.uuid(), reason);
}
player.remove();
- player.con.hasDisconnected = true;
+ player.con().hasDisconnected = true;
}
@Remote(targets = Loc.client, unreliable = true)
public static void onClientShapshot(
- Player player,
+ Playerc player,
int snapshotID,
float x, float y,
float pointerX, float pointerY,
float rotation, float baseRotation,
float xVelocity, float yVelocity,
Tile mining,
- boolean boosting, boolean shooting, boolean chatting, boolean building,
- BuildRequest[] requests,
+ boolean boosting, boolean shooting, boolean chatting,
+ @Nullable BuildRequest[] requests,
float viewX, float viewY, float viewWidth, float viewHeight
){
- NetConnection connection = player.con;
+ NetConnection connection = player.con();
if(connection == null || snapshotID < connection.lastRecievedClientSnapshot) return;
- boolean verifyPosition = !player.isDead() && netServer.admins.getStrict() && headless;
+ boolean verifyPosition = !player.dead() && netServer.admins.getStrict() && headless;
if(connection.lastRecievedClientTime == 0) connection.lastRecievedClientTime = Time.millis() - 16;
@@ -521,91 +517,103 @@ public class NetServer implements ApplicationListener{
connection.viewWidth = viewWidth;
connection.viewHeight = viewHeight;
- long elapsed = Time.timeSinceMillis(connection.lastRecievedClientTime);
+ player.mouseX(pointerX);
+ player.mouseY(pointerY);
+ player.typing(chatting);
- float maxSpeed = boosting && !player.mech.flying ? player.mech.compoundSpeedBoost : player.mech.compoundSpeed;
- float maxMove = elapsed / 1000f * 60f * Math.min(maxSpeed, player.mech.maxSpeed) * 1.2f;
+ player.unit().controlWeapons(shooting, shooting);
+ player.unit().aim(pointerX, pointerY);
- player.pointerX = pointerX;
- player.pointerY = pointerY;
- player.setMineTile(mining);
- player.isTyping = chatting;
- player.isBoosting = boosting;
- player.isShooting = shooting;
- player.isBuilding = building;
- player.buildQueue().clear();
+ if(player.isBuilder()){
+ player.builder().clearBuilding();
+ }
- for(BuildRequest req : requests){
- if(req == null) continue;
- Tile tile = world.tile(req.x, req.y);
- if(tile == null || (!req.breaking && req.block == null)) continue;
- //auto-skip done requests
- if(req.breaking && tile.block() == Blocks.air){
- continue;
- }else if(!req.breaking && tile.block() == req.block && (!req.block.rotate || tile.rotation() == req.rotation)){
- continue;
- }else if(connection.rejectedRequests.contains(r -> r.breaking == req.breaking && r.x == req.x && r.y == req.y)){ //check if request was recently rejected, and skip it if so
- continue;
- }else if(!netServer.admins.allowAction(player, req.breaking ? ActionType.breakBlock : ActionType.placeBlock, tile, action -> { //make sure request is allowed by the server
- action.block = req.block;
- action.rotation = req.rotation;
- action.config = req.config;
- })){
- //force the player to remove this request if that's not the case
- Call.removeQueueBlock(player.con, req.x, req.y, req.breaking);
- connection.rejectedRequests.add(req);
- continue;
+ if(player.isMiner()){
+ player.miner().mineTile(mining);
+ }
+
+ if(requests != null){
+ for(BuildRequest req : requests){
+ if(req == null) continue;
+ Tile tile = world.tile(req.x, req.y);
+ if(tile == null || (!req.breaking && req.block == null)) continue;
+ //auto-skip done requests
+ if(req.breaking && tile.block() == Blocks.air){
+ continue;
+ }else if(!req.breaking && tile.block() == req.block && (!req.block.rotate || tile.rotation() == req.rotation)){
+ continue;
+ }else if(connection.rejectedRequests.contains(r -> r.breaking == req.breaking && r.x == req.x && r.y == req.y)){ //check if request was recently rejected, and skip it if so
+ continue;
+ }else if(!netServer.admins.allowAction(player, req.breaking ? ActionType.breakBlock : ActionType.placeBlock, tile, action -> { //make sure request is allowed by the server
+ action.block = req.block;
+ action.rotation = req.rotation;
+ action.config = req.config;
+ })){
+ //force the player to remove this request if that's not the case
+ Call.removeQueueBlock(player.con(), req.x, req.y, req.breaking);
+ connection.rejectedRequests.add(req);
+ continue;
+ }
+ player.builder().requests().addLast(req);
}
- player.buildQueue().addLast(req);
}
connection.rejectedRequests.clear();
- vector.set(x - player.getInterpolator().target.x, y - player.getInterpolator().target.y);
- vector.limit(maxMove);
+ if(!player.dead()){
+ Unitc unit = player.unit();
+ long elapsed = Time.timeSinceMillis(connection.lastRecievedClientTime);
+ float maxSpeed = player.dead() ? Float.MAX_VALUE : player.unit().type().speed;
+ float maxMove = elapsed / 1000f * 60f * maxSpeed * 1.1f;
- float prevx = player.x, prevy = player.y;
- player.set(player.getInterpolator().target.x, player.getInterpolator().target.y);
- if(!player.mech.flying && player.boostHeat < 0.01f){
- player.move(vector.x, vector.y);
+ vector.set(x - unit.interpolator().target.x, y - unit.interpolator().target.y);
+ vector.limit(maxMove);
+
+ float prevx = unit.x(), prevy = unit.y();
+ unit.set(unit.interpolator().target.x, unit.interpolator().target.y);
+ if(!unit.isFlying()){
+ unit.move(vector.x, vector.y);
+ }else{
+ unit.trns(vector.x, vector.y);
+ }
+ float newx = unit.x(), newy = unit.y();
+
+ if(!verifyPosition){
+ unit.x(prevx);
+ unit.y(prevy);
+ newx = x;
+ newy = y;
+ }else if(Mathf.dst(x, y, newx, newy) > correctDist){
+ Call.onPositionSet(player.con(), newx, newy); //teleport and correct position when necessary
+ }
+
+ //reset player to previous synced position so it gets interpolated
+ unit.x(prevx);
+ unit.y(prevy);
+
+ //set interpolator target to *new* position so it moves toward it
+ unit.interpolator().read(unit.x(), unit.y(), newx, newy, rotation, baseRotation);
+ unit.vel().set(xVelocity, yVelocity); //only for visual calculation purposes, doesn't actually update the player
}else{
- player.x += vector.x;
- player.y += vector.y;
+ player.x(x);
+ player.y(y);
}
- float newx = player.x, newy = player.y;
-
- if(!verifyPosition){
- player.x = prevx;
- player.y = prevy;
- newx = x;
- newy = y;
- }else if(Mathf.dst(x, y, newx, newy) > correctDist){
- Call.onPositionSet(player.con, newx, newy); //teleport and correct position when necessary
- }
-
- //reset player to previous synced position so it gets interpolated
- player.x = prevx;
- player.y = prevy;
-
- //set interpolator target to *new* position so it moves toward it
- player.getInterpolator().read(player.x, player.y, newx, newy, rotation, baseRotation);
- player.velocity().set(xVelocity, yVelocity); //only for visual calculation purposes, doesn't actually update the player
connection.lastRecievedClientSnapshot = snapshotID;
connection.lastRecievedClientTime = Time.millis();
}
@Remote(targets = Loc.client, called = Loc.server)
- public static void onAdminRequest(Player player, Player other, AdminAction action){
+ public static void onAdminRequest(Playerc player, Playerc other, AdminAction action){
- if(!player.isAdmin){
+ if(!player.admin()){
Log.warn("ACCESS DENIED: Player {0} / {1} attempted to perform admin action without proper security access.",
- player.name, player.con.address);
+ player.name(), player.con().address);
return;
}
- if(other == null || ((other.isAdmin && !player.isLocal) && other != player)){
- Log.warn("{0} attempted to perform admin action on nonexistant or admin player.", player.name);
+ if(other == null || ((other.admin() && !player.isLocal()) && other != player)){
+ Log.warn("{0} attempted to perform admin action on nonexistant or admin player.", player.name());
return;
}
@@ -614,32 +622,32 @@ public class NetServer implements ApplicationListener{
//not a real issue, because server owners may want to do just that
state.wavetime = 0f;
}else if(action == AdminAction.ban){
- netServer.admins.banPlayerIP(other.con.address);
- other.con.kick(KickReason.banned);
- Log.info("&lc{0} has banned {1}.", player.name, other.name);
+ netServer.admins.banPlayerIP(other.con().address);
+ other.kick(KickReason.banned);
+ Log.info("&lc{0} has banned {1}.", player.name(), other.name());
}else if(action == AdminAction.kick){
- other.con.kick(KickReason.kick);
- Log.info("&lc{0} has kicked {1}.", player.name, other.name);
+ other.kick(KickReason.kick);
+ Log.info("&lc{0} has kicked {1}.", player.name(), other.name());
}else if(action == AdminAction.trace){
- TraceInfo info = new TraceInfo(other.con.address, other.uuid, other.con.modclient, other.con.mobile);
- if(player.con != null){
- Call.onTraceInfo(player.con, other, info);
+ TraceInfo info = new TraceInfo(other.con().address, other.uuid(), other.con().modclient, other.con().mobile);
+ if(player.con() != null){
+ Call.onTraceInfo(player.con(), other, info);
}else{
NetClient.onTraceInfo(other, info);
}
- Log.info("&lc{0} has requested trace info of {1}.", player.name, other.name);
+ Log.info("&lc{0} has requested trace info of {1}.", player.name(), other.name());
}
}
@Remote(targets = Loc.client)
- public static void connectConfirm(Player player){
- if(player.con == null || player.con.hasConnected) return;
+ public static void connectConfirm(Playerc player){
+ if(player.con() == null || player.con().hasConnected) return;
player.add();
- player.con.hasConnected = true;
+ player.con().hasConnected = true;
if(Config.showConnectMessages.bool()){
- Call.sendMessage("[accent]" + player.name + "[accent] has connected.");
- Log.info("&lm[{1}] &y{0} has connected. ", player.name, player.uuid);
+ Call.sendMessage("[accent]" + player.name() + "[accent] has connected.");
+ Log.info("&lm[{1}] &y{0} has connected. ", player.name(), player.uuid());
}
if(!Config.motd.string().equalsIgnoreCase("off")){
@@ -653,7 +661,7 @@ public class NetServer implements ApplicationListener{
if(state.rules.pvp){
int used = 0;
for(TeamData t : state.teams.getActive()){
- if(playerGroup.count(p -> p.getTeam() == t.team) > 0){
+ if(Groups.player.count(p -> p.team() == t.team) > 0){
used++;
}
}
@@ -665,7 +673,7 @@ public class NetServer implements ApplicationListener{
@Override
public void update(){
- if(!headless && !closing && net.server() && state.is(State.menu)){
+ if(!headless && !closing && net.server() && state.isMenu()){
closing = true;
ui.loadfrag.show("$server.closing");
Time.runTask(5f, () -> {
@@ -675,7 +683,7 @@ public class NetServer implements ApplicationListener{
});
}
- if(!state.is(State.menu) && net.server()){
+ if(state.isGame() && net.server()){
sync();
}
}
@@ -705,12 +713,12 @@ public class NetServer implements ApplicationListener{
syncStream.reset();
short sent = 0;
- for(TileEntity entity : tileGroup.all()){
- if(!entity.block.sync) continue;
+ for(Tilec entity : Groups.tile){
+ if(!entity.block().sync) continue;
sent ++;
- dataStream.writeInt(entity.tile.pos());
- entity.write(dataStream);
+ dataStream.writeInt(entity.tile().pos());
+ entity.writeAll(Writes.get(dataStream));
if(syncStream.size() > maxSnapshotSize){
dataStream.close();
@@ -728,65 +736,53 @@ public class NetServer implements ApplicationListener{
}
}
- public void writeEntitySnapshot(Player player) throws IOException{
+ public void writeEntitySnapshot(Playerc player) throws IOException{
syncStream.reset();
- Array cores = state.teams.cores(player.getTeam());
+ Array cores = state.teams.cores(player.team());
dataStream.writeByte(cores.size);
for(CoreEntity entity : cores){
- dataStream.writeInt(entity.tile.pos());
- entity.items.write(dataStream);
+ dataStream.writeInt(entity.tile().pos());
+ entity.items().write(Writes.get(dataStream));
}
dataStream.close();
byte[] stateBytes = syncStream.toByteArray();
//write basic state data.
- Call.onStateSnapshot(player.con, state.wavetime, state.wave, state.enemies, (short)stateBytes.length, net.compressSnapshot(stateBytes));
+ Call.onStateSnapshot(player.con(), state.wavetime, state.wave, state.enemies, (short)stateBytes.length, net.compressSnapshot(stateBytes));
- viewport.setSize(player.con.viewWidth, player.con.viewHeight).setCenter(player.con.viewX, player.con.viewY);
+ viewport.setSize(player.con().viewWidth, player.con().viewHeight).setCenter(player.con().viewX, player.con().viewY);
- //check for syncable groups
- for(EntityGroup> group : entities.all()){
- if(group.isEmpty() || !(group.all().get(0) instanceof SyncTrait)) continue;
+ syncStream.reset();
- //make sure mapping is enabled for this group
- if(!group.mappingEnabled()){
- throw new RuntimeException("Entity group '" + group.getType() + "' contains SyncTrait entities, yet mapping is not enabled. In order for syncing to work, you must enable mapping for this group.");
- }
+ int sent = 0;
- syncStream.reset();
+ for(Syncc entity : Groups.sync){
+ //write all entities now
+ dataStream.writeInt(entity.id()); //write id
+ dataStream.writeByte(entity.classId()); //write type ID
+ entity.write(Writes.get(dataStream)); //write entity
- int sent = 0;
+ sent++;
- for(Entity entity : group.all()){
- SyncTrait sync = (SyncTrait)entity;
- if(!sync.isSyncing()) continue;
-
- //write all entities now
- dataStream.writeInt(entity.getID()); //write id
- dataStream.writeByte(sync.getTypeID().id); //write type ID
- sync.write(dataStream); //write entity
-
- sent++;
-
- if(syncStream.size() > maxSnapshotSize){
- dataStream.close();
- byte[] syncBytes = syncStream.toByteArray();
- Call.onEntitySnapshot(player.con, (byte)group.getID(), (short)sent, (short)syncBytes.length, net.compressSnapshot(syncBytes));
- sent = 0;
- syncStream.reset();
- }
- }
-
- if(sent > 0){
+ if(syncStream.size() > maxSnapshotSize){
dataStream.close();
-
byte[] syncBytes = syncStream.toByteArray();
- Call.onEntitySnapshot(player.con, (byte)group.getID(), (short)sent, (short)syncBytes.length, net.compressSnapshot(syncBytes));
+ Call.onEntitySnapshot(player.con(), (short)sent, (short)syncBytes.length, net.compressSnapshot(syncBytes));
+ sent = 0;
+ syncStream.reset();
}
}
+
+ if(sent > 0){
+ dataStream.close();
+
+ byte[] syncBytes = syncStream.toByteArray();
+ Call.onEntitySnapshot(player.con(), (short)sent, (short)syncBytes.length, net.compressSnapshot(syncBytes));
+ }
+
}
String fixName(String name){
@@ -842,24 +838,24 @@ public class NetServer implements ApplicationListener{
void sync(){
try{
- //iterate through each player
- for(int i = 0; i < playerGroup.size(); i++){
- Player player = playerGroup.all().get(i);
- if(player.isLocal) continue;
-
- if(player.con == null || !player.con.isConnected()){
+ Groups.player.each(p -> !p.isLocal(), player -> {
+ if(player.con() == null || !player.con().isConnected()){
onDisconnect(player, "disappeared");
- continue;
+ return;
}
- NetConnection connection = player.con;
+ NetConnection connection = player.con();
- if(!player.timer.get(Player.timerSync, serverSyncTime) || !connection.hasConnected) continue;
+ if(!player.timer(0, serverSyncTime) || !connection.hasConnected) return;
- writeEntitySnapshot(player);
- }
+ try{
+ writeEntitySnapshot(player);
+ }catch(IOException e){
+ e.printStackTrace();
+ }
+ });
- if(playerGroup.size() > 0 && Core.settings.getBool("blocksync") && timer.get(timerBlockSync, blockSyncTime)){
+ if(Groups.player.size() > 0 && Core.settings.getBool("blocksync") && timer.get(timerBlockSync, blockSyncTime)){
writeBlockSnapshots();
}
@@ -869,6 +865,6 @@ public class NetServer implements ApplicationListener{
}
public interface TeamAssigner{
- Team assign(Player player, Iterable players);
+ Team assign(Playerc player, Iterable players);
}
}
diff --git a/core/src/mindustry/core/Platform.java b/core/src/mindustry/core/Platform.java
index ba23ff61a5..f1aef6e88f 100644
--- a/core/src/mindustry/core/Platform.java
+++ b/core/src/mindustry/core/Platform.java
@@ -2,11 +2,12 @@ package mindustry.core;
import arc.*;
import arc.Input.*;
-import arc.struct.*;
import arc.files.*;
import arc.func.*;
import arc.math.*;
import arc.scene.ui.*;
+import arc.struct.*;
+import arc.util.*;
import arc.util.serialization.*;
import mindustry.mod.*;
import mindustry.net.*;
@@ -15,7 +16,7 @@ import mindustry.type.*;
import mindustry.ui.dialogs.*;
import org.mozilla.javascript.*;
-import static mindustry.Vars.mobile;
+import static mindustry.Vars.*;
public interface Platform{
@@ -103,6 +104,32 @@ public interface Platform{
default void shareFile(Fi file){
}
+ default void export(String name, String extension, FileWriter writer){
+ if(!ios){
+ platform.showFileChooser(false, extension, file -> {
+ ui.loadAnd(() -> {
+ try{
+ writer.write(file);
+ }catch(Throwable e){
+ ui.showException(e);
+ Log.err(e);
+ }
+ });
+ });
+ }else{
+ ui.loadAnd(() -> {
+ try{
+ Fi result = Core.files.local(name+ "." + extension);
+ writer.write(result);
+ platform.shareFile(result);
+ }catch(Throwable e){
+ ui.showException(e);
+ Log.err(e);
+ }
+ });
+ }
+ }
+
/**
* Show a file chooser.
* @param cons Selection listener
@@ -130,4 +157,8 @@ public interface Platform{
/** Stops forcing the app into landscape orientation.*/
default void endForceLandscape(){
}
+
+ interface FileWriter{
+ void write(Fi file) throws Throwable;
+ }
}
diff --git a/core/src/mindustry/core/Renderer.java b/core/src/mindustry/core/Renderer.java
index 37806c1290..8d6a4e132e 100644
--- a/core/src/mindustry/core/Renderer.java
+++ b/core/src/mindustry/core/Renderer.java
@@ -2,27 +2,18 @@ package mindustry.core;
import arc.*;
import arc.files.*;
-import arc.func.*;
+import arc.fx.*;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.graphics.gl.*;
import arc.math.*;
-import arc.math.geom.*;
import arc.scene.ui.layout.*;
import arc.util.*;
-import arc.util.pooling.*;
import mindustry.content.*;
-import mindustry.core.GameState.*;
-import mindustry.entities.*;
-import mindustry.entities.effect.*;
-import mindustry.entities.effect.GroundEffectEntity.*;
-import mindustry.entities.traits.*;
-import mindustry.entities.type.*;
import mindustry.game.EventType.*;
+import mindustry.gen.*;
import mindustry.graphics.*;
-import mindustry.input.*;
import mindustry.ui.*;
-import mindustry.world.blocks.defense.ForceProjector.*;
import static arc.Core.*;
import static mindustry.Vars.*;
@@ -34,63 +25,26 @@ public class Renderer implements ApplicationListener{
public final LightRenderer lights = new LightRenderer();
public final Pixelator pixelator = new Pixelator();
- public FrameBuffer shieldBuffer = new FrameBuffer(2, 2);
+ public FrameBuffer effectBuffer = new FrameBuffer(2, 2);
private Bloom bloom;
- private Color clearColor;
+ private FxProcessor fx = new FxProcessor();
+ private Color clearColor = new Color(0f, 0f, 0f, 1f);
private float targetscale = Scl.scl(4);
private float camerascale = targetscale;
private float landscale = 0f, landTime;
private float minZoomScl = Scl.scl(0.01f);
- private Rect rect = new Rect(), rect2 = new Rect();
private float shakeIntensity, shaketime;
public Renderer(){
camera = new Camera();
Shaders.init();
- Effects.setScreenShakeProvider((intensity, duration) -> {
- shakeIntensity = Math.max(intensity, shakeIntensity);
- shaketime = Math.max(shaketime, duration);
- });
+ //fx.addEffect(new SnowFilter());
+ }
- Effects.setEffectProvider((effect, color, x, y, rotation, data) -> {
- if(effect == Fx.none) return;
- if(Core.settings.getBool("effects")){
- Rect view = camera.bounds(rect);
- Rect pos = rect2.setSize(effect.size).setCenter(x, y);
-
- if(view.overlaps(pos)){
-
- if(!(effect instanceof GroundEffect)){
- EffectEntity entity = Pools.obtain(EffectEntity.class, EffectEntity::new);
- entity.effect = effect;
- entity.color.set(color);
- entity.rotation = rotation;
- entity.data = data;
- entity.id++;
- entity.set(x, y);
- if(data instanceof Entity){
- entity.setParent((Entity)data);
- }
- effectGroup.add(entity);
- }else{
- GroundEffectEntity entity = Pools.obtain(GroundEffectEntity.class, GroundEffectEntity::new);
- entity.effect = effect;
- entity.color.set(color);
- entity.rotation = rotation;
- entity.id++;
- entity.data = data;
- entity.set(x, y);
- if(data instanceof Entity){
- entity.setParent((Entity)data);
- }
- groundEffectGroup.add(entity);
- }
- }
- }
- });
-
- clearColor = new Color(0f, 0f, 0f, 1f);
+ public void shake(float intensity, float duration){
+ shakeIntensity = Math.max(shakeIntensity, intensity);
+ shaketime = Math.max(shaketime, duration);
}
@Override
@@ -115,25 +69,10 @@ public class Renderer implements ApplicationListener{
camera.width = graphics.getWidth() / camerascale;
camera.height = graphics.getHeight() / camerascale;
- if(state.is(State.menu)){
+ if(state.isMenu()){
landTime = 0f;
graphics.clear(Color.black);
}else{
- Vec2 position = Tmp.v3.set(player);
-
- if(player.isDead()){
- TileEntity core = player.getClosestCore();
- if(core != null){
- if(player.spawner == null){
- camera.position.lerpDelta(core.x, core.y, 0.08f);
- }else{
- camera.position.lerpDelta(position, 0.08f);
- }
- }
- }else if(control.input instanceof DesktopInput && !state.isPaused()){
- camera.position.lerpDelta(position, 0.08f);
- }
-
updateShake(0.75f);
if(pixelator.enabled()){
pixelator.drawPixelate();
@@ -150,7 +89,7 @@ public class Renderer implements ApplicationListener{
@Override
public void dispose(){
minimap.dispose();
- shieldBuffer.dispose();
+ effectBuffer.dispose();
blocks.dispose();
if(bloom != null){
bloom.dispose();
@@ -164,6 +103,8 @@ public class Renderer implements ApplicationListener{
if(settings.getBool("bloom")){
setupBloom();
}
+
+ fx.resize(width, height);
}
@Override
@@ -181,7 +122,7 @@ public class Renderer implements ApplicationListener{
}
bloom = new Bloom(true);
bloom.setClearColor(0f, 0f, 0f, 0f);
- }catch(Exception e){
+ }catch(Throwable e){
e.printStackTrace();
settings.put("bloom", false);
settings.save();
@@ -202,6 +143,23 @@ public class Renderer implements ApplicationListener{
}
}
+ void beginFx(){
+ if(!fx.hasEnabledEffects()) return;
+
+ Draw.flush();
+ fx.clear();
+ fx.begin();
+ }
+
+ void endFx(){
+ if(!fx.hasEnabledEffects()) return;
+
+ Draw.flush();
+ fx.end();
+ fx.applyEffects();
+ fx.render(0, 0, fx.getWidth(), fx.getHeight());
+ }
+
void updateShake(float scale){
if(shaketime > 0){
float intensity = shakeIntensity * (settings.getInt("screenshake", 4) / 4f) * scale;
@@ -218,26 +176,28 @@ public class Renderer implements ApplicationListener{
camera.update();
if(Float.isNaN(camera.position.x) || Float.isNaN(camera.position.y)){
- camera.position.x = player.x;
- camera.position.y = player.y;
+ camera.position.set(player);
}
graphics.clear(clearColor);
- if(!graphics.isHidden() && (Core.settings.getBool("animatedwater") || Core.settings.getBool("animatedshields")) && (shieldBuffer.getWidth() != graphics.getWidth() || shieldBuffer.getHeight() != graphics.getHeight())){
- shieldBuffer.resize(graphics.getWidth(), graphics.getHeight());
+ if(!graphics.isHidden() && (Core.settings.getBool("animatedwater") || Core.settings.getBool("animatedshields")) && (effectBuffer.getWidth() != graphics.getWidth() || effectBuffer.getHeight() != graphics.getHeight())){
+ effectBuffer.resize(graphics.getWidth(), graphics.getHeight());
}
- Draw.proj(camera.projection());
+ Draw.proj(camera);
+ beginFx();
+
+ drawBackground();
+
+ blocks.floor.checkChanges();
blocks.floor.drawFloor();
- groundEffectGroup.draw(e -> e instanceof BelowLiquidTrait);
- puddleGroup.draw();
- groundEffectGroup.draw(e -> !(e instanceof BelowLiquidTrait));
+ Groups.drawFloor();
+ Groups.drawFloorOver();
blocks.processBlocks();
-
blocks.drawShadows();
Draw.color();
@@ -246,7 +206,9 @@ public class Renderer implements ApplicationListener{
blocks.floor.endDraw();
blocks.drawBlocks(Layer.block);
- blocks.drawFog();
+ if(state.rules.drawFog){
+ blocks.drawFog();
+ }
blocks.drawDestroyed();
@@ -256,57 +218,45 @@ public class Renderer implements ApplicationListener{
blocks.drawBlocks(Layer.overlay);
- drawGroundShadows();
-
- drawAllTeams(false);
+ Groups.drawGroundShadows();
+ Groups.drawGroundUnder();
+ Groups.drawGround();
blocks.drawBlocks(Layer.turret);
- drawFlyerShadows();
-
blocks.drawBlocks(Layer.power);
blocks.drawBlocks(Layer.lights);
- drawAllTeams(true);
+ overlays.drawBottom();
+
+ Groups.drawFlyingShadows();
+
+ Groups.drawFlying();
Draw.flush();
if(bloom != null){
bloom.capture();
}
- bulletGroup.draw();
- effectGroup.draw();
+ Groups.drawBullets();
+ Groups.drawEffects();
Draw.flush();
if(bloom != null){
bloom.render();
}
- overlays.drawBottom();
- playerGroup.draw(p -> p.isLocal, Player::drawBuildRequests);
-
- if(shieldGroup.countInBounds() > 0){
- if(settings.getBool("animatedshields") && Shaders.shield != null){
- Draw.flush();
- shieldBuffer.begin();
- graphics.clear(Color.clear);
- shieldGroup.draw();
- shieldGroup.draw(shield -> true, ShieldEntity::drawOver);
- Draw.flush();
- shieldBuffer.end();
- Draw.shader(Shaders.shield);
- Draw.color(Pal.accent);
- Draw.rect(Draw.wrap(shieldBuffer.getTexture()), camera.position.x, camera.position.y, camera.width, -camera.height);
- Draw.color();
- Draw.shader();
- }else{
- shieldGroup.draw(shield -> true, ShieldEntity::drawSimple);
- }
- }
+ Groups.drawOverlays();
overlays.drawTop();
- playerGroup.draw(p -> !p.isDead(), Player::drawName);
+ Groups.drawWeather();
+
+ endFx();
+
+ if(!pixelator.enabled()){
+ Groups.drawNames();
+ }
if(state.rules.lighting){
lights.draw();
@@ -318,70 +268,35 @@ public class Renderer implements ApplicationListener{
Draw.flush();
}
- private void drawLanding(){
- if(landTime > 0 && player.getClosestCore() != null){
- float fract = landTime / Fx.coreLand.lifetime;
- TileEntity entity = player.getClosestCore();
+ private void drawBackground(){
- TextureRegion reg = entity.block.icon(Cicon.full);
+ }
+
+ private void drawLanding(){
+ if(landTime > 0 && player.closestCore() != null){
+ float fract = landTime / Fx.coreLand.lifetime;
+ Tilec entity = player.closestCore();
+
+ TextureRegion reg = entity.block().icon(Cicon.full);
float scl = Scl.scl(4f) / camerascale;
float s = reg.getWidth() * Draw.scl * scl * 4f * fract;
Draw.color(Pal.lightTrail);
- Draw.rect("circle-shadow", entity.x, entity.y, s, s);
+ Draw.rect("circle-shadow", entity.getX(), entity.getY(), s, s);
Angles.randLenVectors(1, (1f- fract), 100, 1000f * scl * (1f-fract), (x, y, fin, fout) -> {
Lines.stroke(scl * fin);
- Lines.lineAngle(entity.x + x, entity.y + y, Mathf.angle(x, y), (fin * 20 + 1f) * scl);
+ Lines.lineAngle(entity.getX() + x, entity.getY() + y, Mathf.angle(x, y), (fin * 20 + 1f) * scl);
});
Draw.color();
Draw.mixcol(Color.white, fract);
- Draw.rect(reg, entity.x, entity.y, reg.getWidth() * Draw.scl * scl, reg.getHeight() * Draw.scl * scl, fract * 135f);
+ Draw.rect(reg, entity.getX(), entity.getY(), reg.getWidth() * Draw.scl * scl, reg.getHeight() * Draw.scl * scl, fract * 135f);
Draw.reset();
}
}
- private void drawGroundShadows(){
- Draw.color(0, 0, 0, 0.4f);
- float rad = 1.6f;
-
- Cons draw = u -> {
- float size = Math.max(u.getIconRegion().getWidth(), u.getIconRegion().getHeight()) * Draw.scl;
- Draw.rect("circle-shadow", u.x, u.y, size * rad, size * rad);
- };
-
- unitGroup.draw(unit -> !unit.isDead(), draw::get);
-
- if(!playerGroup.isEmpty()){
- playerGroup.draw(unit -> !unit.isDead(), draw::get);
- }
-
- Draw.color();
- }
-
- private void drawFlyerShadows(){
- float trnsX = -12, trnsY = -13;
- Draw.color(0, 0, 0, 0.22f);
-
- unitGroup.draw(unit -> unit.isFlying() && !unit.isDead(), baseUnit -> baseUnit.drawShadow(trnsX, trnsY));
- playerGroup.draw(unit -> unit.isFlying() && !unit.isDead(), player -> player.drawShadow(trnsX, trnsY));
-
- Draw.color();
- }
-
- private void drawAllTeams(boolean flying){
- unitGroup.draw(u -> u.isFlying() == flying && !u.isDead(), Unit::drawUnder);
- playerGroup.draw(p -> p.isFlying() == flying && !p.isDead(), Unit::drawUnder);
-
- unitGroup.draw(u -> u.isFlying() == flying && !u.isDead(), Unit::drawAll);
- playerGroup.draw(p -> p.isFlying() == flying, Unit::drawAll);
-
- unitGroup.draw(u -> u.isFlying() == flying && !u.isDead(), Unit::drawOver);
- playerGroup.draw(p -> p.isFlying() == flying, Unit::drawOver);
- }
-
public void scaleCamera(float amount){
targetscale += amount;
clampScale();
@@ -407,7 +322,7 @@ public class Renderer implements ApplicationListener{
}
public void takeMapScreenshot(){
- drawGroundShadows();
+ Groups.drawGroundShadows();
int w = world.width() * tilesize, h = world.height() * tilesize;
int memory = w * h * 4 / 1024 / 1024;
@@ -425,10 +340,8 @@ public class Renderer implements ApplicationListener{
camera.height = h;
camera.position.x = w / 2f + tilesize / 2f;
camera.position.y = h / 2f + tilesize / 2f;
- Draw.flush();
buffer.begin();
draw();
- Draw.flush();
buffer.end();
disableUI = false;
camera.width = vpW;
diff --git a/core/src/mindustry/core/UI.java b/core/src/mindustry/core/UI.java
index c52b5317cb..f7f301cfae 100644
--- a/core/src/mindustry/core/UI.java
+++ b/core/src/mindustry/core/UI.java
@@ -20,7 +20,6 @@ import arc.scene.ui.Tooltip.*;
import arc.scene.ui.layout.*;
import arc.struct.*;
import arc.util.*;
-import mindustry.core.GameState.*;
import mindustry.editor.*;
import mindustry.game.EventType.*;
import mindustry.gen.*;
@@ -63,7 +62,7 @@ public class UI implements ApplicationListener, Loadable{
public TraceDialog traces;
public DatabaseDialog database;
public ContentInfoDialog content;
- public DeployDialog deploy;
+ public PlanetDialog planet;
public TechTreeDialog tech;
//public MinimapDialog minimap;
public SchematicsDialog schematics;
@@ -176,7 +175,7 @@ public class UI implements ApplicationListener, Loadable{
traces = new TraceDialog();
maps = new MapsDialog();
content = new ContentInfoDialog();
- deploy = new DeployDialog();
+ planet = new PlanetDialog();
tech = new TechTreeDialog();
mods = new ModsDialog();
schematics = new SchematicsDialog();
@@ -185,10 +184,10 @@ public class UI implements ApplicationListener, Loadable{
menuGroup.setFillParent(true);
menuGroup.touchable(Touchable.childrenOnly);
- menuGroup.visible(() -> state.is(State.menu));
+ menuGroup.visible(() -> state.isMenu());
hudGroup.setFillParent(true);
hudGroup.touchable(Touchable.childrenOnly);
- hudGroup.visible(() -> !state.is(State.menu));
+ hudGroup.visible(() -> state.isGame());
Core.scene.add(menuGroup);
Core.scene.add(hudGroup);
@@ -296,7 +295,7 @@ public class UI implements ApplicationListener, Loadable{
table.setFillParent(true);
table.touchable(Touchable.disabled);
table.update(() -> {
- if(state.is(State.menu)) table.remove();
+ if(state.isMenu()) table.remove();
});
table.actions(Actions.delay(duration * 0.9f), Actions.fadeOut(duration * 0.1f, Interpolation.fade), Actions.remove());
table.top().table(Styles.black3, t -> t.margin(4).add(info).style(Styles.outlineLabel)).padTop(10);
@@ -309,7 +308,7 @@ public class UI implements ApplicationListener, Loadable{
table.setFillParent(true);
table.touchable(Touchable.disabled);
table.update(() -> {
- if(state.is(State.menu)) table.remove();
+ if(state.isMenu()) table.remove();
});
table.actions(Actions.delay(duration), Actions.remove());
table.align(align).table(Styles.black3, t -> t.margin(4).add(info).style(Styles.outlineLabel)).pad(top, left, bottom, right);
@@ -322,7 +321,7 @@ public class UI implements ApplicationListener, Loadable{
table.setFillParent(true);
table.touchable(Touchable.disabled);
table.update(() -> {
- if(state.is(State.menu)) table.remove();
+ if(state.isMenu()) table.remove();
});
table.actions(Actions.delay(duration), Actions.remove());
table.align(Align.center).table(Styles.black3, t -> t.margin(4).add(info).style(Styles.outlineLabel)).update(t -> {
diff --git a/core/src/mindustry/core/World.java b/core/src/mindustry/core/World.java
index bbc3f4074c..8591eed25a 100644
--- a/core/src/mindustry/core/World.java
+++ b/core/src/mindustry/core/World.java
@@ -1,31 +1,32 @@
package mindustry.core;
import arc.*;
+import arc.func.*;
import arc.math.*;
import arc.math.geom.*;
import arc.struct.*;
import arc.util.ArcAnnotate.*;
import arc.util.*;
+import arc.util.noise.*;
import mindustry.core.GameState.*;
import mindustry.game.EventType.*;
import mindustry.game.*;
import mindustry.game.Teams.*;
+import mindustry.gen.*;
import mindustry.io.*;
import mindustry.maps.*;
import mindustry.maps.filters.*;
import mindustry.maps.filters.GenerateFilter.*;
-import mindustry.maps.generators.*;
import mindustry.type.*;
import mindustry.world.*;
-import mindustry.world.blocks.*;
+import mindustry.world.blocks.legacy.*;
import static mindustry.Vars.*;
public class World{
public final Context context = new Context();
- private Map currentMap;
- private Tile[][] tiles;
+ public @NonNull Tiles tiles = new Tiles(0, 0);
private boolean generating, invalidMap;
@@ -58,20 +59,12 @@ public class World{
return !wallSolid(x, y - 1) || !wallSolid(x, y + 1) || !wallSolid(x - 1, y) || !wallSolid(x + 1, y);
}
- public Map getMap(){
- return currentMap;
- }
-
- public void setMap(Map map){
- this.currentMap = map;
- }
-
public int width(){
- return tiles == null ? 0 : tiles.length;
+ return tiles.width;
}
public int height(){
- return tiles == null ? 0 : tiles[0].length;
+ return tiles.height;
}
public int unitWidth(){
@@ -82,51 +75,61 @@ public class World{
return height()*tilesize;
}
- public @Nullable
- Tile tile(int pos){
- return tiles == null ? null : tile(Pos.x(pos), Pos.y(pos));
+ @Nullable
+ public Tile tile(int pos){
+ return tile(Point2.x(pos), Point2.y(pos));
}
- public @Nullable Tile tile(int x, int y){
- if(tiles == null){
- return null;
- }
- if(!Structs.inBounds(x, y, tiles)) return null;
- return tiles[x][y];
+ @Nullable
+ public Tile tile(int x, int y){
+ return tiles.get(x, y);
}
- public @Nullable Tile ltile(int x, int y){
+ @Nullable
+ public Tile tilec(int x, int y){
+ Tile tile = tiles.get(x, y);
+ if(tile == null) return null;
+ if(tile.entity != null) return tile.entity.tile();
+ return tile;
+ }
+
+ @Nullable
+ public Tilec ent(int x, int y){
Tile tile = tile(x, y);
if(tile == null) return null;
- return tile.block().linked(tile);
+ return tile.entity;
}
+ @Nullable
+ public Tilec ent(int pos){
+ Tile tile = tile(pos);
+ if(tile == null) return null;
+ return tile.entity;
+ }
+
+ @NonNull
public Tile rawTile(int x, int y){
- return tiles[x][y];
+ return tiles.getn(x, y);
}
- public @Nullable Tile tileWorld(float x, float y){
+ @Nullable
+ public Tile tileWorld(float x, float y){
return tile(Math.round(x / tilesize), Math.round(y / tilesize));
}
- public @Nullable Tile ltileWorld(float x, float y){
- return ltile(Math.round(x / tilesize), Math.round(y / tilesize));
+ @Nullable
+ public Tilec entWorld(float x, float y){
+ return ent(Math.round(x / tilesize), Math.round(y / tilesize));
}
public int toTile(float coord){
return Math.round(coord / tilesize);
}
- public Tile[][] getTiles(){
- return tiles;
- }
-
private void clearTileEntities(){
- for(int x = 0; x < tiles.length; x++){
- for(int y = 0; y < tiles[0].length; y++){
- if(tiles[x][y] != null && tiles[x][y].entity != null){
- tiles[x][y].entity.remove();
- }
+ for(Tile tile : tiles){
+ if(tile != null && tile.entity != null){
+ tile.entity.remove();
}
}
}
@@ -135,15 +138,11 @@ public class World{
* Resizes the tile array to the specified size and returns the resulting tile array.
* Only use for loading saves!
*/
- public Tile[][] createTiles(int width, int height){
- if(tiles != null){
- clearTileEntities();
+ public Tiles resize(int width, int height){
+ clearTileEntities();
- if(tiles.length != width || tiles[0].length != height){
- tiles = new Tile[width][height];
- }
- }else{
- tiles = new Tile[width][height];
+ if(tiles.width != width || tiles.height != height){
+ tiles = new Tiles(width, height);
}
return tiles;
@@ -162,16 +161,18 @@ public class World{
* A WorldLoadEvent will be fire.
*/
public void endMapLoad(){
- prepareTiles(tiles);
- for(int x = 0; x < tiles.length; x++){
- for(int y = 0; y < tiles[0].length; y++){
- Tile tile = tiles[x][y];
- tile.updateOcclusion();
+ for(Tile tile : tiles){
+ //remove legacy blocks; they need to stop existing
+ if(tile.block() instanceof LegacyBlock){
+ tile.remove();
+ continue;
+ }
- if(tile.entity != null){
- tile.entity.updateProximity();
- }
+ tile.updateOcclusion();
+
+ if(tile.entity != null){
+ tile.entity.updateProximity();
}
}
@@ -179,7 +180,7 @@ public class World{
addDarkness(tiles);
}
- entities.all().each(group -> group.resize(-finalWorldBounds, -finalWorldBounds, tiles.length * tilesize + finalWorldBounds * 2, tiles[0].length * tilesize + finalWorldBounds * 2));
+ Groups.resize(-finalWorldBounds, -finalWorldBounds, tiles.width * tilesize + finalWorldBounds * 2, tiles.height * tilesize + finalWorldBounds * 2);
generating = false;
Events.fire(new WorldLoadEvent());
@@ -193,23 +194,22 @@ public class World{
return generating;
}
- public boolean isZone(){
- return getZone() != null;
- }
-
- public Zone getZone(){
- return state.rules.zone;
- }
-
- public void loadGenerator(Generator generator){
+ public void loadGenerator(int width, int height, Cons generator){
beginMapLoad();
- createTiles(generator.width, generator.height);
- generator.generate(tiles);
+ resize(width, height);
+ generator.get(tiles);
endMapLoad();
}
+ public void loadSector(Sector sector){
+ state.map = new Map(StringMap.of("name", sector.planet.localizedName + "; Sector " + sector.id));
+ state.rules.sector = sector;
+ int size = sector.getSize();
+ loadGenerator(size, size, tiles -> sector.planet.generator.generate(tiles, sector));
+ }
+
public void loadMap(Map map){
loadMap(map, new Rules());
}
@@ -228,7 +228,7 @@ public class World{
return;
}
- this.currentMap = map;
+ state.map = map;
invalidMap = false;
@@ -297,109 +297,99 @@ public class World{
}
}
- public void addDarkness(Tile[][] tiles){
- byte[][] dark = new byte[tiles.length][tiles[0].length];
- byte[][] writeBuffer = new byte[tiles.length][tiles[0].length];
+ public void addDarkness(Tiles tiles){
+ byte[] dark = new byte[tiles.width * tiles.height];
+ byte[] writeBuffer = new byte[tiles.width * tiles.height];
byte darkIterations = 4;
- for(int x = 0; x < tiles.length; x++){
- for(int y = 0; y < tiles[0].length; y++){
- Tile tile = tiles[x][y];
- if(tile.isDarkened()){
- dark[x][y] = darkIterations;
- }
+
+ for(int i = 0; i < dark.length; i++){
+ Tile tile = tiles.geti(i);
+ if(tile.isDarkened()){
+ dark[i] = darkIterations;
}
}
for(int i = 0; i < darkIterations; i++){
- for(int x = 0; x < tiles.length; x++){
- for(int y = 0; y < tiles[0].length; y++){
- boolean min = false;
- for(Point2 point : Geometry.d4){
- int newX = x + point.x, newY = y + point.y;
- if(Structs.inBounds(newX, newY, tiles) && dark[newX][newY] < dark[x][y]){
- min = true;
- break;
- }
+ for(Tile tile : tiles){
+ int idx = tile.y * tiles.width + tile.x;
+ boolean min = false;
+ for(Point2 point : Geometry.d4){
+ int newX = tile.x + point.x, newY = tile.y + point.y;
+ int nidx = newY * tiles.width + newX;
+ if(tiles.in(newX, newY) && dark[nidx] < dark[idx]){
+ min = true;
+ break;
}
- writeBuffer[x][y] = (byte)Math.max(0, dark[x][y] - Mathf.num(min));
}
+ writeBuffer[idx] = (byte)Math.max(0, dark[idx] - Mathf.num(min));
}
- for(int x = 0; x < tiles.length; x++){
- System.arraycopy(writeBuffer[x], 0, dark[x], 0, tiles[0].length);
- }
+ System.arraycopy(writeBuffer, 0, dark, 0, writeBuffer.length);
}
- for(int x = 0; x < tiles.length; x++){
- for(int y = 0; y < tiles[0].length; y++){
- Tile tile = tiles[x][y];
- if(tile.isDarkened()){
- tiles[x][y].rotation(dark[x][y]);
- }
- if(dark[x][y] == 4){
- boolean full = true;
- for(Point2 p : Geometry.d4){
- int px = p.x + x, py = p.y + y;
- if(Structs.inBounds(px, py, tiles) && !(tiles[px][py].isDarkened() && dark[px][py] == 4)){
- full = false;
- break;
- }
- }
+ for(Tile tile : tiles){
+ int idx = tile.y * tiles.width + tile.x;
- if(full) tiles[x][y].rotation(5);
+ if(tile.isDarkened()){
+ tile.rotation(dark[idx]);
+ }
+
+ if(dark[idx] == 4){
+ boolean full = true;
+ for(Point2 p : Geometry.d4){
+ int px = p.x + tile.x, py = p.y + tile.y;
+ int nidx = py * tiles.width + px;
+ if(tiles.in(px, py) && !(tile.isDarkened() && dark[nidx] == 4)){
+ full = false;
+ break;
+ }
}
+
+ if(full) tile.rotation(5);
}
}
}
- /**
- * 'Prepares' a tile array by:
- * - setting up multiblocks
- * - updating occlusion
- * Usually used before placing structures on a tile array.
- */
- public void prepareTiles(Tile[][] tiles){
+ public float getDarkness(int x, int y){
+ int edgeBlend = 2;
- //find multiblocks
- IntArray multiblocks = new IntArray();
+ float dark = 0;
+ int edgeDst = Math.min(x, Math.min(y, Math.min(Math.abs(x - (tiles.width - 1)), Math.abs(y - (tiles.height - 1)))));
+ if(edgeDst <= edgeBlend){
+ dark = Math.max((edgeBlend - edgeDst) * (4f / edgeBlend), dark);
+ }
- for(int x = 0; x < tiles.length; x++){
- for(int y = 0; y < tiles[0].length; y++){
- Tile tile = tiles[x][y];
+ if(state.hasSector()){
+ int circleBlend = 14;
+ //quantized angle
+ float offset = state.getSector().rect.rotation + 90;
+ float angle = Angles.angle(x, y, tiles.width/2, tiles.height/2) + offset;
+ //polygon sides, depends on sector
+ int sides = state.getSector().tile.corners.length;
+ float step = 360f / sides;
+ //prev and next angles of poly
+ float prev = Mathf.round(angle, step);
+ float next = prev + step;
+ //raw line length to be translated
+ float length = tiles.width/2f;
+ float rawDst = Intersector.distanceLinePoint(Tmp.v1.trns(prev, length), Tmp.v2.trns(next, length), Tmp.v3.set(x - tiles.width/2, y - tiles.height/2).rotate(offset)) / Mathf.sqrt3 - 1;
- if(tile.block().isMultiblock()){
- multiblocks.add(tile.pos());
- }
+ //noise
+ rawDst += Noise.noise(x, y, 11f, 7f) + Noise.noise(x, y, 22f, 15f);
+
+ int circleDst = (int)(rawDst - (tiles.width / 2 - circleBlend));
+ if(circleDst > 0){
+ dark = Math.max(circleDst / 1f, dark);
}
}
- //place multiblocks now
- for(int i = 0; i < multiblocks.size; i++){
- int pos = multiblocks.get(i);
-
- int x = Pos.x(pos);
- int y = Pos.y(pos);
-
- Block result = tiles[x][y].block();
- Team team = tiles[x][y].getTeam();
-
- int offsetx = -(result.size - 1) / 2;
- int offsety = -(result.size - 1) / 2;
-
- for(int dx = 0; dx < result.size; dx++){
- for(int dy = 0; dy < result.size; dy++){
- int worldx = dx + offsetx + x;
- int worldy = dy + offsety + y;
- if(!(worldx == x && worldy == y)){
- Tile toplace = world.tile(worldx, worldy);
- if(toplace != null){
- toplace.setBlock(BlockPart.get(dx + offsetx, dy + offsety), team);
- }
- }
- }
- }
+ Tile tile = world.tile(x, y);
+ if(tile != null && tile.block().solid && tile.block().fillsTile && !tile.block().synthetic()){
+ dark = Math.max(dark, tile.rotation());
}
+
+ return dark;
}
public interface Raycaster{
@@ -408,18 +398,20 @@ public class World{
private class Context implements WorldContext{
@Override
- public Tile tile(int x, int y){
- return tiles[x][y];
+ public Tile tile(int index){
+ return tiles.geti(index);
}
@Override
public void resize(int width, int height){
- createTiles(width, height);
+ World.this.resize(width, height);
}
@Override
public Tile create(int x, int y, int floorID, int overlayID, int wallID){
- return (tiles[x][y] = new Tile(x, y, floorID, overlayID, wallID));
+ Tile tile = new Tile(x, y, floorID, overlayID, wallID);
+ tiles.set(x, y, tile);
+ return tile;
}
@Override
@@ -454,23 +446,8 @@ public class World{
GenerateInput input = new GenerateInput();
for(GenerateFilter filter : filters){
- input.begin(filter, width(), height(), (x, y) -> tiles[x][y]);
-
- //actually apply the filter
- for(int x = 0; x < width(); x++){
- for(int y = 0; y < height(); y++){
- Tile tile = rawTile(x, y);
- input.apply(x, y, tile.floor(), tile.block(), tile.overlay());
- filter.apply(input);
-
- tile.setFloor((Floor)input.floor);
- tile.setOverlay(input.ore);
-
- if(!tile.block().synthetic() && !input.block.synthetic()){
- tile.setBlock(input.block);
- }
- }
- }
+ input.begin(filter, width(), height(), (x, y) -> tiles.getn(x, y));
+ filter.apply(tiles, input);
}
}
diff --git a/core/src/mindustry/ctype/ContentType.java b/core/src/mindustry/ctype/ContentType.java
index 05c70484e3..2c8faaa1ff 100644
--- a/core/src/mindustry/ctype/ContentType.java
+++ b/core/src/mindustry/ctype/ContentType.java
@@ -4,17 +4,18 @@ package mindustry.ctype;
public enum ContentType{
item,
block,
- mech,
+ mech_UNUSED,
bullet,
liquid,
status,
unit,
weather,
- effect,
+ effect_UNUSED,
zone,
- loadout,
- typeid,
- error;
+ loadout_UNUSED,
+ typeid_UNUSED,
+ error,
+ planet;
public static final ContentType[] all = values();
}
diff --git a/core/src/mindustry/ctype/UnlockableContent.java b/core/src/mindustry/ctype/UnlockableContent.java
index 5261560399..4e1043eb9f 100644
--- a/core/src/mindustry/ctype/UnlockableContent.java
+++ b/core/src/mindustry/ctype/UnlockableContent.java
@@ -11,7 +11,7 @@ import mindustry.ui.Cicon;
/** Base interface for an unlockable content type. */
public abstract class UnlockableContent extends MappableContent{
- /** Localized, formal name. Never null. Set to block name if not found in bundle. */
+ /** Localized, formal name. Never null. Set to internal name if not found in bundle. */
public String localizedName;
/** Localized description. May be null. */
public @Nullable String description;
@@ -54,7 +54,7 @@ public abstract class UnlockableContent extends MappableContent{
public void onUnlock(){
}
- /** Whether this content is always hidden in the content info dialog. */
+ /** Whether this content is always hidden in the content database dialog. */
public boolean isHidden(){
return false;
}
@@ -70,7 +70,7 @@ public abstract class UnlockableContent extends MappableContent{
/** @return whether this content is unlocked, or the player is in a custom game. */
public final boolean unlockedCur(){
- return Vars.data.isUnlocked(this) || !Vars.world.isZone();
+ return Vars.data.isUnlocked(this) || !Vars.state.isCampaign();
}
public final boolean locked(){
diff --git a/core/src/mindustry/editor/DrawOperation.java b/core/src/mindustry/editor/DrawOperation.java
index 061a7aee84..c38efca996 100755
--- a/core/src/mindustry/editor/DrawOperation.java
+++ b/core/src/mindustry/editor/DrawOperation.java
@@ -6,7 +6,7 @@ import mindustry.game.Team;
import mindustry.gen.TileOp;
import mindustry.world.Block;
import mindustry.world.Tile;
-import mindustry.world.blocks.Floor;
+import mindustry.world.blocks.environment.Floor;
import static mindustry.Vars.content;
@@ -65,7 +65,7 @@ public class DrawOperation{
tile.setFloor((Floor)content.block(to));
}else if(type == OpType.block.ordinal()){
Block block = content.block(to);
- tile.setBlock(block, tile.getTeam(), tile.rotation());
+ tile.setBlock(block, tile.team(), tile.rotation());
}else if(type == OpType.rotation.ordinal()){
tile.rotation(to);
}else if(type == OpType.team.ordinal()){
diff --git a/core/src/mindustry/editor/EditorTile.java b/core/src/mindustry/editor/EditorTile.java
index 6a2829b098..f4085a2876 100644
--- a/core/src/mindustry/editor/EditorTile.java
+++ b/core/src/mindustry/editor/EditorTile.java
@@ -1,19 +1,16 @@
package mindustry.editor;
-import mindustry.content.Blocks;
-import mindustry.core.GameState.State;
-import mindustry.editor.DrawOperation.OpType;
-import mindustry.game.Team;
-import mindustry.gen.TileOp;
-import mindustry.world.Block;
-import mindustry.world.Tile;
-import mindustry.world.blocks.*;
+import arc.util.ArcAnnotate.*;
+import mindustry.content.*;
+import mindustry.editor.DrawOperation.*;
+import mindustry.game.*;
+import mindustry.gen.*;
+import mindustry.world.*;
+import mindustry.world.blocks.environment.*;
import mindustry.world.modules.*;
-import static mindustry.Vars.state;
-import static mindustry.Vars.ui;
+import static mindustry.Vars.*;
-//TODO somehow remove or replace this class with a more flexible solution
public class EditorTile extends Tile{
public EditorTile(int x, int y, int floor, int overlay, int wall){
@@ -21,8 +18,8 @@ public class EditorTile extends Tile{
}
@Override
- public void setFloor(Floor type){
- if(state.is(State.playing)){
+ public void setFloor(@NonNull Floor type){
+ if(state.isGame()){
super.setFloor(type);
return;
}
@@ -41,35 +38,22 @@ public class EditorTile extends Tile{
super.setFloor(type);
}
- @Override
- public void setBlock(Block type){
- if(state.is(State.playing)){
- super.setBlock(type);
- return;
- }
-
- if(block == type) return;
- op(OpType.block, block.id);
- if(rotation != 0) op(OpType.rotation, rotation);
- if(team != 0) op(OpType.team, team);
- super.setBlock(type);
- }
-
@Override
public void setBlock(Block type, Team team, int rotation){
- if(state.is(State.playing)){
+ if(state.isGame()){
super.setBlock(type, team, rotation);
return;
}
- setBlock(type);
- setTeam(team);
- rotation(rotation);
+ op(OpType.block, block.id);
+ if(rotation != 0) op(OpType.rotation, (byte)rotation);
+ if(team() != Team.derelict) op(OpType.team, team().id);
+ super.setBlock(type, team, rotation);
}
@Override
public void setTeam(Team team){
- if(state.is(State.playing)){
+ if(state.isGame()){
super.setTeam(team);
return;
}
@@ -81,7 +65,7 @@ public class EditorTile extends Tile{
@Override
public void rotation(int rotation){
- if(state.is(State.playing)){
+ if(state.isGame()){
super.rotation(rotation);
return;
}
@@ -93,57 +77,49 @@ public class EditorTile extends Tile{
@Override
public void setOverlay(Block overlay){
- setOverlayID(overlay.id);
- }
-
- @Override
- public void setOverlayID(short overlay){
- if(state.is(State.playing)){
- super.setOverlayID(overlay);
+ if(state.isGame()){
+ super.setOverlay(overlay);
return;
}
if(floor.isLiquid) return;
- if(overlayID() == overlay) return;
+ if(overlay() == overlay) return;
op(OpType.overlay, this.overlay.id);
- super.setOverlayID(overlay);
+ super.setOverlay(overlay);
}
@Override
protected void preChanged(){
- if(state.is(State.playing)){
- super.preChanged();
- return;
- }
-
- super.setTeam(Team.derelict);
+ super.preChanged();
}
@Override
- protected void changed(){
- if(state.is(State.playing)){
- super.changed();
+ public void recache(){
+ if(state.isGame()){
+ super.recache();
+ }
+ }
+
+ @Override
+ protected void changed(Team team){
+ if(state.isGame()){
+ super.changed(team);
return;
}
entity = null;
- if(block == null){
- block = Blocks.air;
- }
-
- if(floor == null){
- floor = (Floor)Blocks.air;
- }
-
+ if(block == null) block = Blocks.air;
+ if(floor == null) floor = (Floor)Blocks.air;
+
Block block = block();
if(block.hasEntity()){
- entity = block.newEntity().init(this, false);
- entity.cons = new ConsumeModule(entity);
- if(block.hasItems) entity.items = new ItemModule();
- if(block.hasLiquids) entity.liquids = new LiquidModule();
- if(block.hasPower) entity.power = new PowerModule();
+ entity = block.newEntity().init(this, team, false);
+ entity.cons(new ConsumeModule(entity));
+ if(block.hasItems) entity.items(new ItemModule());
+ if(block.hasLiquids) entity.liquids(new LiquidModule());
+ if(block.hasPower) entity.power(new PowerModule());
}
}
diff --git a/core/src/mindustry/editor/EditorTool.java b/core/src/mindustry/editor/EditorTool.java
index 8e197bf42e..26820d3c78 100644
--- a/core/src/mindustry/editor/EditorTool.java
+++ b/core/src/mindustry/editor/EditorTool.java
@@ -8,7 +8,6 @@ import arc.util.*;
import mindustry.content.*;
import mindustry.game.*;
import mindustry.world.*;
-import mindustry.world.blocks.*;
public enum EditorTool{
zoom,
@@ -16,7 +15,7 @@ public enum EditorTool{
public void touched(MapEditor editor, int x, int y){
if(!Structs.inBounds(x, y, editor.width(), editor.height())) return;
- Tile tile = editor.tile(x, y).link();
+ Tile tile = editor.tile(x, y);
editor.drawBlock = tile.block() == Blocks.air ? tile.overlay() == Blocks.air ? tile.floor() : tile.overlay() : tile.block();
}
},
@@ -63,7 +62,7 @@ public enum EditorTool{
editor.drawBlocks(x, y, true, tile -> true);
}else if(mode == 2){
//draw teams
- editor.drawCircle(x, y, tile -> tile.link().setTeam(editor.drawTeam));
+ editor.drawCircle(x, y, tile -> tile.setTeam(editor.drawTeam));
}
}
@@ -108,7 +107,7 @@ public enum EditorTool{
//mode 0 or 1, fill everything with the floor/tile or replace it
if(mode == 0 || mode == -1){
//can't fill parts or multiblocks
- if(tile.block() instanceof BlockPart || tile.block().isMultiblock()){
+ if(tile.block().isMultiblock()){
return;
}
@@ -137,10 +136,10 @@ public enum EditorTool{
}else if(mode == 1){ //mode 1 is team fill
//only fill synthetic blocks, it's meaningless otherwise
- if(tile.link().synthetic()){
- Team dest = tile.getTeam();
+ if(tile.synthetic()){
+ Team dest = tile.team();
if(dest == editor.drawTeam) return;
- fill(editor, x, y, false, t -> t.getTeamID() == (int)dest.id && t.link().synthetic(), t -> t.setTeam(editor.drawTeam));
+ fill(editor, x, y, false, t -> t.getTeamID() == (int)dest.id && t.synthetic(), t -> t.setTeam(editor.drawTeam));
}
}
}
@@ -164,35 +163,44 @@ public enum EditorTool{
int x1;
stack.clear();
- stack.add(Pos.get(x, y));
+ stack.add(Point2.pack(x, y));
- while(stack.size > 0){
- int popped = stack.pop();
- x = Pos.x(popped);
- y = Pos.y(popped);
+ try{
+ while(stack.size > 0 && stack.size < width*height){
+ int popped = stack.pop();
+ x = Point2.x(popped);
+ y = Point2.y(popped);
- x1 = x;
- while(x1 >= 0 && tester.get(editor.tile(x1, y))) x1--;
- x1++;
- boolean spanAbove = false, spanBelow = false;
- while(x1 < width && tester.get(editor.tile(x1, y))){
- filler.get(editor.tile(x1, y));
-
- if(!spanAbove && y > 0 && tester.get(editor.tile(x1, y - 1))){
- stack.add(Pos.get(x1, y - 1));
- spanAbove = true;
- }else if(spanAbove && !tester.get(editor.tile(x1, y - 1))){
- spanAbove = false;
- }
-
- if(!spanBelow && y < height - 1 && tester.get(editor.tile(x1, y + 1))){
- stack.add(Pos.get(x1, y + 1));
- spanBelow = true;
- }else if(spanBelow && y < height - 1 && !tester.get(editor.tile(x1, y + 1))){
- spanBelow = false;
- }
+ x1 = x;
+ while(x1 >= 0 && tester.get(editor.tile(x1, y))) x1--;
x1++;
+ boolean spanAbove = false, spanBelow = false;
+ while(x1 < width && tester.get(editor.tile(x1, y))){
+ filler.get(editor.tile(x1, y));
+
+ if(!spanAbove && y > 0 && tester.get(editor.tile(x1, y - 1))){
+ stack.add(Point2.pack(x1, y - 1));
+ spanAbove = true;
+ }else if(spanAbove && !tester.get(editor.tile(x1, y - 1))){
+ spanAbove = false;
+ }
+
+ if(!spanBelow && y < height - 1 && tester.get(editor.tile(x1, y + 1))){
+ stack.add(Point2.pack(x1, y + 1));
+ spanBelow = true;
+ }else if(spanBelow && y < height - 1 && !tester.get(editor.tile(x1, y + 1))){
+ spanBelow = false;
+ }
+ x1++;
+ }
}
+ stack.clear();
+ }catch(OutOfMemoryError e){
+ //hack
+ stack = null;
+ System.gc();
+ e.printStackTrace();
+ stack = new IntArray();
}
}
}
diff --git a/core/src/mindustry/editor/MapEditor.java b/core/src/mindustry/editor/MapEditor.java
index 508db8b6e2..8c743ad11f 100644
--- a/core/src/mindustry/editor/MapEditor.java
+++ b/core/src/mindustry/editor/MapEditor.java
@@ -1,19 +1,16 @@
package mindustry.editor;
-import arc.struct.StringMap;
-import arc.files.Fi;
-import arc.func.Cons;
-import arc.func.Boolf;
-import arc.graphics.Pixmap;
-import arc.math.Mathf;
-import arc.util.Structs;
-import mindustry.content.Blocks;
-import mindustry.game.Team;
-import mindustry.gen.TileOp;
-import mindustry.io.MapIO;
-import mindustry.maps.Map;
+import arc.files.*;
+import arc.func.*;
+import arc.graphics.*;
+import arc.math.*;
+import arc.struct.*;
+import mindustry.content.*;
+import mindustry.game.*;
+import mindustry.gen.*;
+import mindustry.io.*;
+import mindustry.maps.*;
import mindustry.world.*;
-import mindustry.world.blocks.BlockPart;
import static mindustry.Vars.*;
@@ -55,7 +52,6 @@ public class MapEditor{
tags.put("steamid", map.file.parent().name());
}
MapIO.loadMap(map, context);
- checkLinkedTiles();
renderer.resize(width(), height());
loading = false;
}
@@ -64,33 +60,10 @@ public class MapEditor{
reset();
createTiles(pixmap.getWidth(), pixmap.getHeight());
- load(() -> MapIO.readPixmap(pixmap, tiles()));
+ load(() -> MapIO.readImage(pixmap, tiles()));
renderer.resize(width(), height());
}
- //adds missing blockparts
- public void checkLinkedTiles(){
- Tile[][] tiles = world.getTiles();
-
- //clear block parts first
- for(int x = 0; x < width(); x++){
- for(int y = 0; y < height(); y++){
- if(tiles[x][y].block() instanceof BlockPart){
- tiles[x][y].setBlock(Blocks.air);
- }
- }
- }
-
- //set up missing blockparts
- for(int x = 0; x < width(); x++){
- for(int y = 0; y < height(); y++){
- if(tiles[x][y].block().isMultiblock()){
- tiles[x][y].set(tiles[x][y].block(), tiles[x][y].getTeam());
- }
- }
- }
- }
-
public void load(Runnable r){
loading = true;
r.run();
@@ -99,11 +72,11 @@ public class MapEditor{
/** Creates a 2-D array of EditorTiles with stone as the floor block. */
private void createTiles(int width, int height){
- Tile[][] tiles = world.createTiles(width, height);
+ Tiles tiles = world.resize(width, height);
for(int x = 0; x < width; x++){
for(int y = 0; y < height; y++){
- tiles[x][y] = new EditorTile(x, y, Blocks.stone.id, (short)0, (short)0);
+ tiles.set(x, y, new EditorTile(x, y, Blocks.stone.id, (short)0, (short)0));
}
}
}
@@ -119,8 +92,8 @@ public class MapEditor{
tags = new StringMap();
}
- public Tile[][] tiles(){
- return world.getTiles();
+ public Tiles tiles(){
+ return world.tiles;
}
public Tile tile(int x, int y){
@@ -151,42 +124,13 @@ public class MapEditor{
if(drawBlock.isMultiblock()){
x = Mathf.clamp(x, (drawBlock.size - 1) / 2, width() - drawBlock.size / 2 - 1);
y = Mathf.clamp(y, (drawBlock.size - 1) / 2, height() - drawBlock.size / 2 - 1);
-
- int offsetx = -(drawBlock.size - 1) / 2;
- int offsety = -(drawBlock.size - 1) / 2;
-
- for(int dx = 0; dx < drawBlock.size; dx++){
- for(int dy = 0; dy < drawBlock.size; dy++){
- int worldx = dx + offsetx + x;
- int worldy = dy + offsety + y;
-
- if(Structs.inBounds(worldx, worldy, width(), height())){
- Tile tile = tile(worldx, worldy);
-
- Block block = tile.block();
-
- //bail out if there's anything blocking the way
- if(block.isMultiblock() || block instanceof BlockPart){
- return;
- }
-
- renderer.updatePoint(worldx, worldy);
- }
- }
- }
-
- tile(x, y).set(drawBlock, drawTeam);
+ tile(x, y).setBlock(drawBlock, drawTeam, 0);
}else{
boolean isFloor = drawBlock.isFloor() && drawBlock != Blocks.air;
Cons drawer = tile -> {
if(!tester.get(tile)) return;
- //remove linked tiles blocking the way
- if(!isFloor && (tile.isLinked() || tile.block().isMultiblock())){
- tile.link().remove();
- }
-
if(isFloor){
tile.setFloor(drawBlock.asFloor());
}else{
@@ -211,7 +155,7 @@ public class MapEditor{
public void drawCircle(int x, int y, Cons drawer){
for(int rx = -brushSize; rx <= brushSize; rx++){
for(int ry = -brushSize; ry <= brushSize; ry++){
- if(Mathf.dst2(rx, ry) <= (brushSize - 0.5f) * (brushSize - 0.5f)){
+ if(Mathf.within(rx, ry, brushSize - 0.5f + 0.0001f)){
int wx = x + rx, wy = y + ry;
if(wx < 0 || wy < 0 || wx >= width() || wy >= height()){
@@ -245,20 +189,20 @@ public class MapEditor{
public void resize(int width, int height){
clearOp();
- Tile[][] previous = world.getTiles();
+ Tiles previous = world.tiles;
int offsetX = -(width - width()) / 2, offsetY = -(height - height()) / 2;
loading = true;
- Tile[][] tiles = world.createTiles(width, height);
+ Tiles tiles = world.resize(width, height);
for(int x = 0; x < width; x++){
for(int y = 0; y < height; y++){
int px = offsetX + x, py = offsetY + y;
- if(Structs.inBounds(px, py, previous.length, previous[0].length)){
- tiles[x][y] = previous[px][py];
- tiles[x][y].x = (short)x;
- tiles[x][y].y = (short)y;
+ if(previous.in(px, py)){
+ tiles.set(x, y, previous.getn(px, py));
+ tiles.getn(x, y).x = (short)x;
+ tiles.getn(x, y).y = (short)y;
}else{
- tiles[x][y] = new EditorTile(x, y, Blocks.stone.id, (short)0, (short)0);
+ tiles.set(x, y, new EditorTile(x, y, Blocks.stone.id, (short)0, (short)0));
}
}
}
@@ -308,18 +252,20 @@ public class MapEditor{
class Context implements WorldContext{
@Override
- public Tile tile(int x, int y){
- return world.tile(x, y);
+ public Tile tile(int index){
+ return world.tiles.geti(index);
}
@Override
public void resize(int width, int height){
- world.createTiles(width, height);
+ world.resize(width, height);
}
@Override
public Tile create(int x, int y, int floorID, int overlayID, int wallID){
- return (tiles()[x][y] = new EditorTile(x, y, floorID, overlayID, wallID));
+ Tile tile = new EditorTile(x, y, floorID, overlayID, wallID);
+ tiles().set(x, y, tile);
+ return tile;
}
@Override
diff --git a/core/src/mindustry/editor/MapEditorDialog.java b/core/src/mindustry/editor/MapEditorDialog.java
index 577157ff19..e019213012 100644
--- a/core/src/mindustry/editor/MapEditorDialog.java
+++ b/core/src/mindustry/editor/MapEditorDialog.java
@@ -28,7 +28,7 @@ import mindustry.ui.*;
import mindustry.ui.Cicon;
import mindustry.ui.dialogs.*;
import mindustry.world.*;
-import mindustry.world.blocks.*;
+import mindustry.world.blocks.environment.*;
import mindustry.world.blocks.storage.*;
import static mindustry.Vars.*;
@@ -87,62 +87,42 @@ public class MapEditorDialog extends Dialog implements Disposable{
t.row();
- t.addImageTextButton("$editor.import", Icon.download, () ->
- createDialog("$editor.import",
- "$editor.importmap", "$editor.importmap.description", Icon.download, (Runnable)loadDialog::show,
- "$editor.importfile", "$editor.importfile.description", Icon.file, (Runnable)() ->
- platform.showFileChooser(true, mapExtension, file -> ui.loadAnd(() -> {
- maps.tryCatchMapError(() -> {
- if(MapIO.isImage(file)){
- ui.showInfo("$editor.errorimage");
- }else{
- editor.beginEdit(MapIO.createMap(file, true));
- }
- });
- })),
-
- "$editor.importimage", "$editor.importimage.description", Icon.fileImage, (Runnable)() ->
- platform.showFileChooser(true, "png", file ->
- ui.loadAnd(() -> {
- try{
- Pixmap pixmap = new Pixmap(file);
- editor.beginEdit(pixmap);
- pixmap.dispose();
- }catch(Exception e){
- ui.showException("$editor.errorload", e);
- Log.err(e);
- }
- })))
- );
-
- t.addImageTextButton("$editor.export", Icon.upload, () -> {
- if(!ios){
- platform.showFileChooser(false, mapExtension, file -> {
- ui.loadAnd(() -> {
- try{
- if(!editor.getTags().containsKey("name")){
- editor.getTags().put("name", file.nameWithoutExtension());
- }
- MapIO.writeMap(file, editor.createMap(file));
- }catch(Exception e){
- ui.showException("$editor.errorsave", e);
- Log.err(e);
- }
- });
- });
- }else{
- ui.loadAnd(() -> {
- try{
- Fi result = Core.files.local(editor.getTags().get("name", "unknown") + "." + mapExtension);
- MapIO.writeMap(result, editor.createMap(result));
- platform.shareFile(result);
- }catch(Exception e){
- ui.showException("$editor.errorsave", e);
- Log.err(e);
+ t.addImageTextButton("$editor.import", Icon.download, () -> createDialog("$editor.import",
+ "$editor.importmap", "$editor.importmap.description", Icon.download, (Runnable)loadDialog::show,
+ "$editor.importfile", "$editor.importfile.description", Icon.file, (Runnable)() ->
+ platform.showFileChooser(true, mapExtension, file -> ui.loadAnd(() -> {
+ maps.tryCatchMapError(() -> {
+ if(MapIO.isImage(file)){
+ ui.showInfo("$editor.errorimage");
+ }else{
+ editor.beginEdit(MapIO.createMap(file, true));
}
});
- }
- });
+ })),
+
+ "$editor.importimage", "$editor.importimage.description", Icon.fileImage, (Runnable)() ->
+ platform.showFileChooser(true, "png", file ->
+ ui.loadAnd(() -> {
+ try{
+ Pixmap pixmap = new Pixmap(file);
+ editor.beginEdit(pixmap);
+ pixmap.dispose();
+ }catch(Exception e){
+ ui.showException("$editor.errorload", e);
+ Log.err(e);
+ }
+ })))
+ );
+
+ t.addImageTextButton("$editor.export", Icon.upload, () -> createDialog("$editor.export",
+ "$editor.exportfile", "$editor.exportfile.description", Icon.file,
+ (Runnable)() -> platform.export(editor.getTags().get("name", "unknown"), mapExtension, file -> MapIO.writeMap(file, editor.createMap(file))),
+ "$editor.exportimage", "$editor.exportimage.description", Icon.fileImage,
+ (Runnable)() -> platform.export(editor.getTags().get("name", "unknown"), "png", file -> {
+ Pixmap out = MapIO.writeImage(editor.tiles());
+ file.writePNG(out);
+ out.dispose();
+ })));
});
menu.cont.row();
@@ -176,7 +156,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
}
platform.publish(map);
- }).padTop(-3).size(swidth * 2f + 10, 60f).update(b -> b.setText(editor.getTags().containsKey("steamid") ? editor.getTags().get("author").equals(player.name) ? "$workshop.listing" : "$view.workshop" : "$editor.publish.workshop"));
+ }).padTop(-3).size(swidth * 2f + 10, 60f).update(b -> b.setText(editor.getTags().containsKey("steamid") ? editor.getTags().get("author").equals(player.name()) ? "$workshop.listing" : "$view.workshop" : "$editor.publish.workshop"));
menu.cont.row();
}
@@ -266,24 +246,21 @@ public class MapEditorDialog extends Dialog implements Disposable{
state.teams = new Teams();
player.reset();
state.rules = Gamemode.editor.apply(lastSavedRules.copy());
- state.rules.zone = null;
- world.setMap(new Map(StringMap.of(
- "name", "Editor Playtesting",
- "width", editor.width(),
- "height", editor.height()
- )));
+ state.rules.sector = null;
+ state.map = new Map(StringMap.of(
+ "name", "Editor Playtesting",
+ "width", editor.width(),
+ "height", editor.height()
+ ));
world.endMapLoad();
//add entities so they update. is this really needed?
- for(int x = 0; x < world.width(); x++){
- for(int y = 0; y < world.height(); y++){
- Tile tile = world.rawTile(x, y);
- if(tile.entity != null){
- tile.entity.add();
- }
+ for(Tile tile : world.tiles){
+ if(tile.entity != null){
+ tile.entity.add();
}
}
player.set(world.width() * tilesize/2f, world.height() * tilesize/2f);
- player.setDead(false);
+ player.clearUnit();
logic.play();
});
}
@@ -295,7 +272,8 @@ public class MapEditorDialog extends Dialog implements Disposable{
editor.getTags().put("rules", JsonIO.write(state.rules));
editor.getTags().remove("width");
editor.getTags().remove("height");
- player.dead = true;
+ //TODO unkill player
+ //player.dead = true;
Map returned = null;
diff --git a/core/src/mindustry/editor/MapGenerateDialog.java b/core/src/mindustry/editor/MapGenerateDialog.java
index 7d6791f846..66de62325f 100644
--- a/core/src/mindustry/editor/MapGenerateDialog.java
+++ b/core/src/mindustry/editor/MapGenerateDialog.java
@@ -21,7 +21,7 @@ import mindustry.maps.filters.GenerateFilter.*;
import mindustry.ui.*;
import mindustry.ui.dialogs.*;
import mindustry.world.*;
-import mindustry.world.blocks.*;
+import mindustry.world.blocks.environment.*;
import static mindustry.Vars.*;
@@ -30,7 +30,7 @@ public class MapGenerateDialog extends FloatingDialog{
private final Prov[] filterTypes = new Prov[]{
NoiseFilter::new, ScatterFilter::new, TerrainFilter::new, DistortFilter::new,
RiverNoiseFilter::new, OreFilter::new, OreMedianFilter::new, MedianFilter::new,
- BlendFilter::new, MirrorFilter::new, ClearFilter::new
+ BlendFilter::new, MirrorFilter::new, ClearFilter::new, CoreSpawnFilter::new, EnemySpawnFilter::new
};
private final MapEditor editor;
private final boolean applied;
@@ -52,7 +52,7 @@ public class MapGenerateDialog extends FloatingDialog{
private CachedTile ctile = new CachedTile(){
//nothing.
@Override
- protected void changed(){
+ protected void changed(Team team){
}
};
@@ -124,7 +124,7 @@ public class MapGenerateDialog extends FloatingDialog{
Tile tile = editor.tile(x, y);
input.apply(x, y, tile.floor(), tile.block(), tile.overlay());
filter.apply(input);
- writeTiles[x][y].set(input.floor, input.block, input.ore, tile.getTeam(), tile.rotation());
+ writeTiles[x][y].set(input.floor, input.block, input.ore, tile.team(), tile.rotation());
}
}
@@ -146,7 +146,6 @@ public class MapGenerateDialog extends FloatingDialog{
}
//reset undo stack as generation... messes things up
- editor.load(editor::checkLinkedTiles);
editor.renderer().updateAll();
editor.clearOp();
}
@@ -263,7 +262,7 @@ public class MapGenerateDialog extends FloatingDialog{
//all the options
c.table(f -> {
f.left().top();
- for(FilterOption option : filter.options){
+ for(FilterOption option : filter.options()){
option.changed = this::update;
f.table(t -> {
@@ -292,7 +291,7 @@ public class MapGenerateDialog extends FloatingDialog{
for(Prov gen : filterTypes){
GenerateFilter filter = gen.get();
- if(!applied && filter.buffered) continue;
+ if((!applied && filter.isBuffered()) || (filter.isPost() && applied)) continue;
selection.cont.addButton(filter.name(), () -> {
filters.add(filter);
@@ -360,21 +359,17 @@ public class MapGenerateDialog extends FloatingDialog{
for(GenerateFilter filter : copy){
input.begin(filter, editor.width(), editor.height(), (x, y) -> buffer1[Mathf.clamp(x / scaling, 0, pixmap.getWidth()-1)][Mathf.clamp(y / scaling, 0, pixmap.getHeight()-1)].tile());
+
//read from buffer1 and write to buffer2
- for(int px = 0; px < pixmap.getWidth(); px++){
- for(int py = 0; py < pixmap.getHeight(); py++){
- int x = px * scaling, y = py * scaling;
- GenTile tile = buffer1[px][py];
- input.apply(x, y, content.block(tile.floor), content.block(tile.block), content.block(tile.ore));
- filter.apply(input);
- buffer2[px][py].set(input.floor, input.block, input.ore, Team.get(tile.team), tile.rotation);
- }
- }
- for(int px = 0; px < pixmap.getWidth(); px++){
- for(int py = 0; py < pixmap.getHeight(); py++){
- buffer1[px][py].set(buffer2[px][py]);
- }
- }
+ pixmap.each((px, py) -> {
+ int x = px * scaling, y = py * scaling;
+ GenTile tile = buffer1[px][py];
+ input.apply(x, y, content.block(tile.floor), content.block(tile.block), content.block(tile.ore));
+ filter.apply(input);
+ buffer2[px][py].set(input.floor, input.block, input.ore, Team.get(tile.team), tile.rotation);
+ });
+
+ pixmap.each((px, py) -> buffer1[px][py].set(buffer2[px][py]));
}
for(int px = 0; px < pixmap.getWidth(); px++){
@@ -428,7 +423,7 @@ public class MapGenerateDialog extends FloatingDialog{
}
public GenTile set(Tile other){
- set(other.floor(), other.block(), other.overlay(), other.getTeam(), other.rotation());
+ set(other.floor(), other.block(), other.overlay(), other.team(), other.rotation());
return this;
}
diff --git a/core/src/mindustry/editor/MapRenderer.java b/core/src/mindustry/editor/MapRenderer.java
index c5d007c92a..54708f4cf5 100644
--- a/core/src/mindustry/editor/MapRenderer.java
+++ b/core/src/mindustry/editor/MapRenderer.java
@@ -15,7 +15,6 @@ import mindustry.game.Team;
import mindustry.graphics.IndexedRenderer;
import mindustry.world.Block;
import mindustry.world.Tile;
-import mindustry.world.blocks.BlockPart;
import static mindustry.Vars.tilesize;
@@ -109,9 +108,9 @@ public class MapRenderer implements Disposable{
private void render(int wx, int wy){
int x = wx / chunkSize, y = wy / chunkSize;
IndexedRenderer mesh = chunks[x][y];
- Tile tile = editor.tiles()[wx][wy];
+ Tile tile = editor.tiles().getn(wx, wy);
- Team team = tile.getTeam();
+ Team team = tile.team();
Block floor = tile.floor();
Block wall = tile.block();
@@ -119,9 +118,10 @@ public class MapRenderer implements Disposable{
int idxWall = (wx % chunkSize) + (wy % chunkSize) * chunkSize;
int idxDecal = (wx % chunkSize) + (wy % chunkSize) * chunkSize + chunkSize * chunkSize;
+ boolean center = tile.isCenter();
- if(wall != Blocks.air && (wall.synthetic() || wall instanceof BlockPart)){
- region = !Core.atlas.isFound(wall.editorIcon()) ? Core.atlas.find("clear-editor") : wall.editorIcon();
+ if(wall != Blocks.air && wall.synthetic()){
+ region = !Core.atlas.isFound(wall.editorIcon()) || !center ? Core.atlas.find("clear-editor") : wall.editorIcon();
if(wall.rotate){
mesh.draw(idxWall, region,
@@ -143,14 +143,14 @@ public class MapRenderer implements Disposable{
float offsetX = -(wall.size / 3) * tilesize, offsetY = -(wall.size / 3) * tilesize;
- if(wall.update || wall.destructible){
+ if((wall.update || wall.destructible) && center){
mesh.setColor(team.color);
region = Core.atlas.find("block-border-editor");
- }else if(!wall.synthetic() && wall != Blocks.air){
+ }else if(!wall.synthetic() && wall != Blocks.air && center){
region = !Core.atlas.isFound(wall.editorIcon()) ? Core.atlas.find("clear-editor") : wall.editorIcon();
offsetX = tilesize / 2f - region.getWidth() / 2f * Draw.scl;
offsetY = tilesize / 2f - region.getHeight() / 2f * Draw.scl;
- }else if(wall == Blocks.air && tile.overlay() != null){
+ }else if(wall == Blocks.air){
region = tile.overlay().editorVariantRegions()[Mathf.randomSeed(idxWall, 0, tile.overlay().editorVariantRegions().length - 1)];
}else{
region = Core.atlas.find("clear-editor");
diff --git a/core/src/mindustry/editor/MapView.java b/core/src/mindustry/editor/MapView.java
index f2d5b45dbd..23c7afae96 100644
--- a/core/src/mindustry/editor/MapView.java
+++ b/core/src/mindustry/editor/MapView.java
@@ -236,7 +236,7 @@ public class MapView extends Element implements GestureListener{
image.setImageSize(editor.width(), editor.height());
- if(!ScissorStack.pushScissors(rect.set(x, y, width, height))){
+ if(!ScissorStack.push(rect.set(x, y, width, height))){
return;
}
@@ -304,7 +304,7 @@ public class MapView extends Element implements GestureListener{
Lines.rect(x, y, width, height);
Draw.reset();
- ScissorStack.popScissors();
+ ScissorStack.pop();
}
private boolean active(){
diff --git a/core/src/mindustry/entities/AllDefs.java b/core/src/mindustry/entities/AllDefs.java
new file mode 100644
index 0000000000..b042733b89
--- /dev/null
+++ b/core/src/mindustry/entities/AllDefs.java
@@ -0,0 +1,37 @@
+package mindustry.entities;
+
+import mindustry.annotations.Annotations.*;
+import mindustry.gen.*;
+
+class AllDefs{
+
+ @GroupDef(Entityc.class)
+ class all{
+
+ }
+
+ @GroupDef(value = Playerc.class, mapping = true)
+ class player{
+
+ }
+
+ @GroupDef(value = Bulletc.class, spatial = true, collide = {unit.class})
+ class bullet{
+
+ }
+
+ @GroupDef(value = Unitc.class, spatial = true, collide = {unit.class}, mapping = true)
+ class unit{
+
+ }
+
+ @GroupDef(Tilec.class)
+ class tile{
+
+ }
+
+ @GroupDef(value = Syncc.class, mapping = true)
+ class sync{
+
+ }
+}
diff --git a/core/src/mindustry/entities/Damage.java b/core/src/mindustry/entities/Damage.java
index 335ac96385..e6066023fb 100644
--- a/core/src/mindustry/entities/Damage.java
+++ b/core/src/mindustry/entities/Damage.java
@@ -1,17 +1,14 @@
package mindustry.entities;
import arc.*;
-import mindustry.annotations.Annotations.*;
-import arc.struct.*;
import arc.func.*;
import arc.graphics.*;
import arc.math.*;
import arc.math.geom.*;
+import arc.struct.*;
import arc.util.*;
+import mindustry.annotations.Annotations.*;
import mindustry.content.*;
-import mindustry.entities.Effects.*;
-import mindustry.entities.effect.*;
-import mindustry.entities.type.*;
import mindustry.game.EventType.*;
import mindustry.game.*;
import mindustry.gen.*;
@@ -33,12 +30,11 @@ public class Damage{
public static void dynamicExplosion(float x, float y, float flammability, float explosiveness, float power, float radius, Color color){
for(int i = 0; i < Mathf.clamp(power / 20, 0, 6); i++){
int branches = 5 + Mathf.clamp((int)(power / 30), 1, 20);
- Time.run(i * 2f + Mathf.random(4f), () -> Lightning.create(Team.derelict, Pal.power, 3,
- x, y, Mathf.random(360f), branches + Mathf.range(2)));
+ Time.run(i * 2f + Mathf.random(4f), () -> Lightning.create(Team.derelict, Pal.power, 3, x, y, Mathf.random(360f), branches + Mathf.range(2)));
}
for(int i = 0; i < Mathf.clamp(flammability / 4, 0, 30); i++){
- Time.run(i / 2f, () -> Call.createBullet(Bullets.fireball, Team.derelict, x, y, Mathf.random(360f), 1, 1));
+ Time.run(i / 2f, () -> Call.createBullet(Bullets.fireball, Team.derelict, x, y, -1f, Mathf.random(360f), 1, 1));
}
int waves = Mathf.clamp((int)(explosiveness / 4), 0, 30);
@@ -47,21 +43,21 @@ public class Damage{
int f = i;
Time.run(i * 2f, () -> {
Damage.damage(x, y, Mathf.clamp(radius + explosiveness, 0, 50f) * ((f + 1f) / waves), explosiveness / 2f);
- Effects.effect(Fx.blockExplosionSmoke, x + Mathf.range(radius), y + Mathf.range(radius));
+ Fx.blockExplosionSmoke.at(x + Mathf.range(radius), y + Mathf.range(radius));
});
}
if(explosiveness > 15f){
- Effects.effect(Fx.shockwave, x, y);
+ Fx.shockwave.at(x, y);
}
if(explosiveness > 30f){
- Effects.effect(Fx.bigShockwave, x, y);
+ Fx.bigShockwave.at(x, y);
}
float shake = Math.min(explosiveness / 4f + 3f, 9f);
Effects.shake(shake, shake, x, y);
- Effects.effect(Fx.dynamicExplosion, x, y, radius / 8f);
+ Fx.dynamicExplosion.at(x, y, radius / 8f);
}
public static void createIncend(float x, float y, float range, int amount){
@@ -70,12 +66,12 @@ public class Damage{
float cy = y + Mathf.range(range);
Tile tile = world.tileWorld(cx, cy);
if(tile != null){
- Fire.create(tile);
+ Fires.create(tile);
}
}
}
- public static void collideLine(Bullet hitter, Team team, Effect effect, float x, float y, float angle, float length){
+ public static void collideLine(Bulletc hitter, Team team, Effect effect, float x, float y, float angle, float length){
collideLine(hitter, team, effect, x, y, angle, length, false);
}
@@ -83,15 +79,15 @@ public class Damage{
* Damages entities in a line.
* Only enemies of the specified team are damaged.
*/
- public static void collideLine(Bullet hitter, Team team, Effect effect, float x, float y, float angle, float length, boolean large){
+ public static void collideLine(Bulletc hitter, Team team, Effect effect, float x, float y, float angle, float length, boolean large){
collidedBlocks.clear();
tr.trns(angle, length);
Intc2 collider = (cx, cy) -> {
- Tile tile = world.ltile(cx, cy);
- if(tile != null && !collidedBlocks.contains(tile.pos()) && tile.entity != null && tile.getTeamID() != team.id && tile.entity.collide(hitter)){
- tile.entity.collision(hitter);
+ Tilec tile = world.ent(cx, cy);
+ if(tile != null && !collidedBlocks.contains(tile.pos()) && tile.team() != team && tile.collide(hitter)){
+ tile.collision(hitter);
collidedBlocks.add(tile.pos());
- hitter.getBulletType().hit(hitter, tile.worldx(), tile.worldy());
+ hitter.type().hit(hitter, tile.x(), tile.y());
}
};
@@ -125,7 +121,7 @@ public class Damage{
rect.width += expand * 2;
rect.height += expand * 2;
- Cons cons = e -> {
+ Cons cons = e -> {
e.hitbox(hitrect);
Rect other = hitrect;
other.y -= expand;
@@ -136,7 +132,7 @@ public class Damage{
Vec2 vec = Geometry.raycastRect(x, y, x2, y2, other);
if(vec != null){
- Effects.effect(effect, vec.x, vec.y);
+ effect.at(vec.x, vec.y);
e.collision(hitter, vec.x, vec.y);
hitter.collision(e, vec.x, vec.y);
}
@@ -146,8 +142,8 @@ public class Damage{
}
/** Damages all entities and blocks in a radius that are enemies of the team. */
- public static void damageUnits(Team team, float x, float y, float size, float damage, Boolf predicate, Cons acceptor){
- Cons cons = entity -> {
+ public static void damageUnits(Team team, float x, float y, float size, float damage, Boolf predicate, Cons acceptor){
+ Cons cons = entity -> {
if(!predicate.get(entity)) return;
entity.hitbox(hitrect);
@@ -178,15 +174,15 @@ public class Damage{
/** Damages all entities and blocks in a radius that are enemies of the team. */
public static void damage(Team team, float x, float y, float radius, float damage, boolean complete){
- Cons cons = entity -> {
- if(entity.getTeam() == team || entity.dst(x, y) > radius){
+ Cons cons = entity -> {
+ if(entity.team() == team || entity.dst(x, y) > radius){
return;
}
- float amount = calculateDamage(x, y, entity.x, entity.y, radius, damage);
+ float amount = calculateDamage(x, y, entity.getX(), entity.getY(), radius, damage);
entity.damage(amount);
//TODO better velocity displacement
- float dst = tr.set(entity.x - x, entity.y - y).len();
- entity.velocity().add(tr.setLength((1f - dst / radius) * 2f / entity.mass()));
+ float dst = tr.set(entity.getX() - x, entity.getY() - y).len();
+ entity.vel().add(tr.setLength((1f - dst / radius) * 2f / entity.mass()));
if(complete && damage >= 9999999f && entity == player){
Events.fire(Trigger.exclusionDeath);
@@ -231,15 +227,15 @@ public class Damage{
int scaledDamage = (int)(damage * (1f - (float)dst / radius));
bits.set(bitOffset + x, bitOffset + y);
- Tile tile = world.ltile(startx + x, starty + y);
+ Tilec tile = world.ent(startx + x, starty + y);
if(scaledDamage <= 0 || tile == null) continue;
//apply damage to entity if needed
- if(tile.entity != null && tile.getTeam() != team){
- int health = (int)tile.entity.health;
- if(tile.entity.health > 0){
- tile.entity.damage(scaledDamage);
+ if(tile.team() != team){
+ int health = (int)tile.health();
+ if(tile.health() > 0){
+ tile.damage(scaledDamage);
scaledDamage -= health;
if(scaledDamage <= 0) continue;
@@ -259,7 +255,7 @@ public class Damage{
for(int dx = -trad; dx <= trad; dx++){
for(int dy = -trad; dy <= trad; dy++){
Tile tile = world.tile(Math.round(x / tilesize) + dx, Math.round(y / tilesize) + dy);
- if(tile != null && tile.entity != null && (team == null ||team.isEnemy(tile.getTeam())) && Mathf.dst(dx, dy) <= trad){
+ if(tile != null && tile.entity != null && (team == null ||team.isEnemy(tile.team())) && Mathf.dst(dx, dy) <= trad){
tile.entity.damage(damage);
}
}
diff --git a/core/src/mindustry/entities/Effect.java b/core/src/mindustry/entities/Effect.java
new file mode 100644
index 0000000000..b1dd73ed69
--- /dev/null
+++ b/core/src/mindustry/entities/Effect.java
@@ -0,0 +1,118 @@
+package mindustry.entities;
+
+import arc.func.*;
+import arc.graphics.*;
+import arc.graphics.g2d.*;
+import arc.math.*;
+import arc.math.geom.*;
+
+public class Effect{
+ private static final EffectContainer container = new EffectContainer();
+ private static int lastid = 0;
+
+ public final int id;
+ public final Cons renderer;
+ public final float lifetime;
+ /** Clip size. */
+ public float size;
+
+ public boolean ground;
+ public float groundDuration;
+
+ public Effect(float life, float clipsize, Cons renderer){
+ this.id = lastid++;
+ this.lifetime = life;
+ this.renderer = renderer;
+ this.size = clipsize;
+ }
+
+ public Effect(float life, Cons renderer){
+ this(life, 28f, renderer);
+ }
+
+ public Effect ground(){
+ ground = true;
+ return this;
+ }
+
+ public Effect ground(float duration){
+ ground = true;
+ this.groundDuration = duration;
+ return this;
+ }
+
+ public void at(Position pos){
+ Effects.create(this, pos.getX(), pos.getY(), 0, Color.white, null);
+ }
+
+ public void at(Position pos, float rotation){
+ Effects.create(this, pos.getX(), pos.getY(), rotation, Color.white, null);
+ }
+
+ public void at(float x, float y){
+ Effects.create(this, x, y, 0, Color.white, null);
+ }
+
+ public void at(float x, float y, float rotation){
+ Effects.create(this, x, y, rotation, Color.white, null);
+ }
+
+ public void at(float x, float y, float rotation, Color color){
+ Effects.create(this, x, y, rotation, color, null);
+ }
+
+ public void at(float x, float y, Color color){
+ Effects.create(this, x, y, 0, color, null);
+ }
+
+ public void at(float x, float y, float rotation, Color color, Object data){
+ Effects.create(this, x, y, rotation, color, data);
+ }
+
+ public void at(float x, float y, float rotation, Object data){
+ Effects.create(this, x, y, rotation, Color.white, data);
+ }
+
+ public void render(int id, Color color, float life, float rotation, float x, float y, Object data){
+ container.set(id, color, life, lifetime, rotation, x, y, data);
+ renderer.get(container);
+ Draw.reset();
+ }
+
+ public static class EffectContainer implements Scaled{
+ public float x, y, time, lifetime, rotation;
+ public Color color;
+ public int id;
+ public Object data;
+ private EffectContainer innerContainer;
+
+ public void set(int id, Color color, float life, float lifetime, float rotation, float x, float y, Object data){
+ this.x = x;
+ this.y = y;
+ this.color = color;
+ this.time = life;
+ this.lifetime = lifetime;
+ this.id = id;
+ this.rotation = rotation;
+ this.data = data;
+ }
+
+ public T data(){
+ return (T)data;
+ }
+
+ public void scaled(float lifetime, Cons cons){
+ if(innerContainer == null) innerContainer = new EffectContainer();
+ if(time <= lifetime){
+ innerContainer.set(id, color, time, lifetime, rotation, x, y, data);
+ cons.get(innerContainer);
+ }
+ }
+
+ @Override
+ public float fin(){
+ return time / lifetime;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/core/src/mindustry/entities/Effects.java b/core/src/mindustry/entities/Effects.java
index c1f85aceef..2f1eb20faf 100644
--- a/core/src/mindustry/entities/Effects.java
+++ b/core/src/mindustry/entities/Effects.java
@@ -1,90 +1,25 @@
package mindustry.entities;
import arc.*;
-import arc.func.*;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.math.*;
import arc.math.geom.*;
-import arc.struct.*;
-import arc.util.pooling.*;
-import mindustry.entities.type.*;
+import arc.util.*;
+import mindustry.content.*;
+import mindustry.gen.*;
+import mindustry.graphics.*;
+import mindustry.world.*;
+
+import static mindustry.Vars.*;
public class Effects{
- private static final EffectContainer container = new EffectContainer();
- private static Array effects = new Array<>();
- private static ScreenshakeProvider shakeProvider;
- private static float shakeFalloff = 10000f;
- private static EffectProvider provider = (effect, color, x, y, rotation, data) -> {
- EffectEntity entity = Pools.obtain(EffectEntity.class, EffectEntity::new);
- entity.effect = effect;
- entity.color = color;
- entity.rotation = rotation;
- entity.data = data;
- entity.set(x, y);
- entity.add();
- };
-
- public static void setEffectProvider(EffectProvider prov){
- provider = prov;
- }
-
- public static void setScreenShakeProvider(ScreenshakeProvider provider){
- shakeProvider = provider;
- }
-
- public static void renderEffect(int id, Effect render, Color color, float life, float rotation, float x, float y, Object data){
- container.set(id, color, life, render.lifetime, rotation, x, y, data);
- render.draw.render(container);
- Draw.reset();
- }
-
- public static Effect getEffect(int id){
- if(id >= effects.size || id < 0)
- throw new IllegalArgumentException("The effect with ID \"" + id + "\" does not exist!");
- return effects.get(id);
- }
-
- public static Array all(){
- return effects;
- }
-
- public static void effect(Effect effect, float x, float y, float rotation){
- provider.createEffect(effect, Color.white, x, y, rotation, null);
- }
-
- public static void effect(Effect effect, float x, float y){
- effect(effect, x, y, 0);
- }
-
- public static void effect(Effect effect, Color color, float x, float y){
- provider.createEffect(effect, color, x, y, 0f, null);
- }
-
- public static void effect(Effect effect, Position loc){
- provider.createEffect(effect, Color.white, loc.getX(), loc.getY(), 0f, null);
- }
-
- public static void effect(Effect effect, Color color, float x, float y, float rotation){
- provider.createEffect(effect, color, x, y, rotation, null);
- }
-
- public static void effect(Effect effect, Color color, float x, float y, float rotation, Object data){
- provider.createEffect(effect, color, x, y, rotation, data);
- }
-
- public static void effect(Effect effect, float x, float y, float rotation, Object data){
- provider.createEffect(effect, Color.white, x, y, rotation, data);
- }
-
- /** Default value is 1000. Higher numbers mean more powerful shake (less falloff). */
- public static void setShakeFalloff(float falloff){
- shakeFalloff = falloff;
- }
+ private static final float shakeFalloff = 10000f;
private static void shake(float intensity, float duration){
- if(shakeProvider == null) throw new RuntimeException("Screenshake provider is null! Set it first.");
- shakeProvider.accept(intensity, duration);
+ if(!headless){
+ renderer.shake(intensity, duration);
+ }
}
public static void shake(float intensity, float duration, float x, float y){
@@ -100,68 +35,58 @@ public class Effects{
shake(intensity, duration, loc.getX(), loc.getY());
}
- public interface ScreenshakeProvider{
- void accept(float intensity, float duration);
- }
+ public static void create(Effect effect, float x, float y, float rotation, Color color, Object data){
+ if(headless || effect == Fx.none) return;
+ if(Core.settings.getBool("effects")){
+ Rect view = Core.camera.bounds(Tmp.r1);
+ Rect pos = Tmp.r2.setSize(effect.size).setCenter(x, y);
- public static class Effect{
- private static int lastid = 0;
- public final int id;
- public final EffectRenderer draw;
- public final float lifetime;
- /** Clip size. */
- public float size;
-
- public Effect(float life, float clipsize, EffectRenderer draw){
- this.id = lastid++;
- this.lifetime = life;
- this.draw = draw;
- this.size = clipsize;
- effects.add(this);
- }
-
- public Effect(float life, EffectRenderer draw){
- this(life, 28f, draw);
- }
- }
-
- public static class EffectContainer implements Scaled{
- public float x, y, time, lifetime, rotation;
- public Color color;
- public int id;
- public Object data;
- private EffectContainer innerContainer;
-
- public void set(int id, Color color, float life, float lifetime, float rotation, float x, float y, Object data){
- this.x = x;
- this.y = y;
- this.color = color;
- this.time = life;
- this.lifetime = lifetime;
- this.id = id;
- this.rotation = rotation;
- this.data = data;
- }
-
- public void scaled(float lifetime, Cons cons){
- if(innerContainer == null) innerContainer = new EffectContainer();
- if(time <= lifetime){
- innerContainer.set(id, color, time, lifetime, rotation, x, y, data);
- cons.get(innerContainer);
+ if(view.overlaps(pos)){
+ Effectc entity = effect.ground ? GroundEffectEntity.create() : StandardEffectEntity.create();
+ entity.effect(effect);
+ entity.rotation(rotation);
+ entity.data(data);
+ entity.lifetime(effect.lifetime);
+ entity.set(x, y);
+ entity.color().set(color);
+ if(data instanceof Posc) entity.parent((Posc)data);
+ entity.add();
}
}
-
- @Override
- public float fin(){
- return time / lifetime;
- }
}
- public interface EffectProvider{
- void createEffect(Effect effect, Color color, float x, float y, float rotation, Object data);
+ public static void decal(TextureRegion region, float x, float y, float rotation, float lifetime, Color color){
+ if(headless || region == null || !Core.atlas.isFound(region)) return;
+
+ Decalc decal = DecalEntity.create();
+ decal.set(x, y);
+ decal.rotation(rotation);
+ decal.lifetime(lifetime);
+ decal.color().set(color);
+ decal.region(region);
+ decal.add();
}
- public interface EffectRenderer{
- void render(EffectContainer effect);
+ public static void scorch(float x, float y, int size){
+ if(headless) return;
+
+ Tile tile = world.tileWorld(x, y);
+ if(tile == null || tile.floor().isLiquid) return;
+
+ size = Mathf.clamp(size, 0, 9);
+
+ TextureRegion region = Core.atlas.find("scorch-" + size + "-" + Mathf.random(2));
+ decal(region, x, y, Mathf.random(4) * 90, 3600, Pal.rubble);
+
+ }
+
+ public static void rubble(float x, float y, int blockSize){
+ if(headless) return;
+
+ Tile tile = world.tileWorld(x, y);
+ if(tile == null || tile.floor().isLiquid) return;
+
+ TextureRegion region = Core.atlas.find("rubble-" + blockSize + "-" + (Core.atlas.has("rubble-" + blockSize + "-1") ? Mathf.random(0, 1) : "0"));
+ decal(region, x, y, Mathf.random(4) * 90, 3600, Pal.rubble);
}
}
diff --git a/core/src/mindustry/entities/Entities.java b/core/src/mindustry/entities/Entities.java
deleted file mode 100755
index 022af6b95d..0000000000
--- a/core/src/mindustry/entities/Entities.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package mindustry.entities;
-
-import arc.struct.*;
-import mindustry.entities.traits.*;
-
-/** Simple container for managing entity groups.*/
-public class Entities{
- private final Array> groupArray = new Array<>();
-
- public void clear(){
- for(EntityGroup group : groupArray){
- group.clear();
- }
- }
-
- public EntityGroup> get(int id){
- return groupArray.get(id);
- }
-
- public Array> all(){
- return groupArray;
- }
-
- public EntityGroup add(Class type){
- return add(type, true);
- }
-
- public EntityGroup add(Class type, boolean useTree){
- EntityGroup group = new EntityGroup<>(groupArray.size, type, useTree);
- groupArray.add(group);
- return group;
- }
-}
diff --git a/core/src/mindustry/entities/EntityCollisions.java b/core/src/mindustry/entities/EntityCollisions.java
index 72e177d71e..00bf484a6c 100644
--- a/core/src/mindustry/entities/EntityCollisions.java
+++ b/core/src/mindustry/entities/EntityCollisions.java
@@ -1,14 +1,12 @@
package mindustry.entities;
-import arc.struct.Array;
-import arc.math.Mathf;
+import arc.math.*;
import arc.math.geom.*;
-import mindustry.entities.traits.Entity;
-import mindustry.entities.traits.SolidTrait;
-import mindustry.world.Tile;
+import arc.struct.*;
+import mindustry.gen.*;
+import mindustry.world.*;
-import static mindustry.Vars.tilesize;
-import static mindustry.Vars.world;
+import static mindustry.Vars.*;
public class EntityCollisions{
//range for tile collision scanning
@@ -24,15 +22,19 @@ public class EntityCollisions{
private Rect r2 = new Rect();
//entity collisions
- private Array arrOut = new Array<>();
+ private Array arrOut = new Array<>();
- public void move(SolidTrait entity, float deltax, float deltay){
+ public void move(Hitboxc entity, float deltax, float deltay){
+ move(entity, deltax, deltay, EntityCollisions::solid);
+ }
+
+ public void move(Hitboxc entity, float deltax, float deltay, SolidPred solidCheck){
boolean movedx = false;
while(Math.abs(deltax) > 0 || !movedx){
movedx = true;
- moveDelta(entity, Math.min(Math.abs(deltax), seg) * Mathf.sign(deltax), 0, true);
+ moveDelta(entity, Math.min(Math.abs(deltax), seg) * Mathf.sign(deltax), 0, true, solidCheck);
if(Math.abs(deltax) >= seg){
deltax -= seg * Mathf.sign(deltax);
@@ -45,7 +47,7 @@ public class EntityCollisions{
while(Math.abs(deltay) > 0 || !movedy){
movedy = true;
- moveDelta(entity, 0, Math.min(Math.abs(deltay), seg) * Mathf.sign(deltay), false);
+ moveDelta(entity, 0, Math.min(Math.abs(deltay), seg) * Mathf.sign(deltay), false, solidCheck);
if(Math.abs(deltay) >= seg){
deltay -= seg * Mathf.sign(deltay);
@@ -55,33 +57,30 @@ public class EntityCollisions{
}
}
- public void moveDelta(SolidTrait entity, float deltax, float deltay, boolean x){
-
- Rect rect = r1;
- entity.hitboxTile(rect);
+ public void moveDelta(Hitboxc entity, float deltax, float deltay, boolean x, SolidPred solidCheck){
+ entity.hitboxTile(r1);
entity.hitboxTile(r2);
- rect.x += deltax;
- rect.y += deltay;
+ r1.x += deltax;
+ r1.y += deltay;
- int tilex = Math.round((rect.x + rect.width / 2) / tilesize), tiley = Math.round((rect.y + rect.height / 2) / tilesize);
+ int tilex = Math.round((r1.x + r1.width / 2) / tilesize), tiley = Math.round((r1.y + r1.height / 2) / tilesize);
for(int dx = -r; dx <= r; dx++){
for(int dy = -r; dy <= r; dy++){
int wx = dx + tilex, wy = dy + tiley;
- if(solid(wx, wy) && entity.collidesGrid(wx, wy)){
+ if(solidCheck.solid(wx, wy)){
tmp.setSize(tilesize).setCenter(wx * tilesize, wy * tilesize);
- if(tmp.overlaps(rect)){
- Vec2 v = Geometry.overlap(rect, tmp, x);
- rect.x += v.x;
- rect.y += v.y;
+ if(tmp.overlaps(r1)){
+ Vec2 v = Geometry.overlap(r1, tmp, x);
+ if(x) r1.x += v.x;
+ if(!x) r1.y += v.y;
}
}
}
}
- entity.setX(entity.getX() + rect.x - r2.x);
- entity.setY(entity.getY() + rect.y - r2.y);
+ entity.trns(r1.x - r2.x, r1.y - r2.y);
}
public boolean overlapsTile(Rect rect){
@@ -108,44 +107,43 @@ public class EntityCollisions{
}
@SuppressWarnings("unchecked")
- public void updatePhysics(EntityGroup group){
+ public void updatePhysics(EntityGroup group){
QuadTree tree = group.tree();
tree.clear();
- for(Entity entity : group.all()){
- if(entity instanceof SolidTrait){
- SolidTrait s = (SolidTrait)entity;
- s.lastPosition().set(s.getX(), s.getY());
- tree.insert(s);
- }
- }
+ group.each(s -> {
+ s.updateLastPosition();
+ tree.insert(s);
+ });
}
- private static boolean solid(int x, int y){
+ public static boolean waterSolid(int x, int y){
+ Tile tile = world.tile(x, y);
+ return tile != null && (tile.solid() || !tile.floor().isLiquid);
+ }
+
+ public static boolean solid(int x, int y){
Tile tile = world.tile(x, y);
return tile != null && tile.solid();
}
- private void checkCollide(Entity entity, Entity other){
-
- SolidTrait a = (SolidTrait)entity;
- SolidTrait b = (SolidTrait)other;
+ private void checkCollide(Hitboxc a, Hitboxc b){
a.hitbox(this.r1);
b.hitbox(this.r2);
- r1.x += (a.lastPosition().x - a.getX());
- r1.y += (a.lastPosition().y - a.getY());
- r2.x += (b.lastPosition().x - b.getX());
- r2.y += (b.lastPosition().y - b.getY());
+ r1.x += (a.lastX() - a.getX());
+ r1.y += (a.lastY() - a.getY());
+ r2.x += (b.lastX() - b.getX());
+ r2.y += (b.lastY() - b.getY());
- float vax = a.getX() - a.lastPosition().x;
- float vay = a.getY() - a.lastPosition().y;
- float vbx = b.getX() - b.lastPosition().x;
- float vby = b.getY() - b.lastPosition().y;
+ float vax = a.getX() - a.lastX();
+ float vay = a.getY() - a.lastY();
+ float vbx = b.getX() - b.lastX();
+ float vby = b.getY() - b.lastY();
- if(a != b && a.collides(b) && b.collides(a)){
+ if(a != b && a.collides(b)){
l1.set(a.getX(), a.getY());
boolean collide = r1.overlaps(r2) || collide(r1.x, r1.y, r1.width, r1.height, vax, vay,
r2.x, r2.y, r2.width, r2.height, vbx, vby, l1);
@@ -207,17 +205,12 @@ public class EntityCollisions{
}
@SuppressWarnings("unchecked")
- public void collideGroups(EntityGroup> groupa, EntityGroup> groupb){
-
- for(Entity entity : groupa.all()){
- if(!(entity instanceof SolidTrait))
- continue;
-
- SolidTrait solid = (SolidTrait)entity;
+ public void collideGroups(EntityGroup extends Hitboxc> groupa, EntityGroup extends Hitboxc> groupb){
+ groupa.each(solid -> {
solid.hitbox(r1);
- r1.x += (solid.lastPosition().x - solid.getX());
- r1.y += (solid.lastPosition().y - solid.getY());
+ r1.x += (solid.lastX() - solid.getX());
+ r1.y += (solid.lastY() - solid.getY());
solid.hitbox(r2);
r2.merge(r1);
@@ -225,12 +218,18 @@ public class EntityCollisions{
arrOut.clear();
groupb.tree().getIntersect(arrOut, r2);
- for(SolidTrait sc : arrOut){
+ for(Hitboxc sc : arrOut){
sc.hitbox(r1);
if(r2.overlaps(r1)){
- checkCollide(entity, sc);
+ checkCollide(solid, sc);
+ //break out of loop when this object hits something
+ if(!solid.isAdded()) return;
}
}
- }
+ });
+ }
+
+ public interface SolidPred{
+ boolean solid(int x, int y);
}
}
diff --git a/core/src/mindustry/entities/EntityGroup.java b/core/src/mindustry/entities/EntityGroup.java
index 6c4bbea92a..564f131600 100644
--- a/core/src/mindustry/entities/EntityGroup.java
+++ b/core/src/mindustry/entities/EntityGroup.java
@@ -1,11 +1,10 @@
package mindustry.entities;
import arc.*;
-import arc.struct.*;
import arc.func.*;
-import arc.graphics.*;
import arc.math.geom.*;
-import mindustry.entities.traits.*;
+import arc.struct.*;
+import mindustry.gen.*;
import java.util.*;
@@ -13,128 +12,82 @@ import static mindustry.Vars.collisions;
/** Represents a group of a certain type of entity.*/
@SuppressWarnings("unchecked")
-public class EntityGroup implements Iterable{
- private final boolean useTree;
- private final int id;
- private final Class type;
- private final Array entityArray = new Array<>(false, 32);
- private final Array entitiesToRemove = new Array<>(false, 32);
- private final Array entitiesToAdd = new Array<>(false, 32);
+public class EntityGroup implements Iterable{
+ private static int lastId = 0;
+
+ private final Array array;
private final Array intersectArray = new Array<>();
+ private final Rect viewport = new Rect();
private final Rect intersectRect = new Rect();
private IntMap map;
private QuadTree tree;
- private Cons removeListener;
- private Cons addListener;
+ private boolean clearing;
- private final Rect viewport = new Rect();
- private int count = 0;
+ private int index;
- public EntityGroup(int id, Class type, boolean useTree){
- this.useTree = useTree;
- this.id = id;
- this.type = type;
+ public static int nextId(){
+ return lastId++;
+ }
- if(useTree){
+ public EntityGroup(Class type, boolean spatial, boolean mapping){
+ array = new Array<>(false, 32, type);
+
+ if(spatial){
tree = new QuadTree<>(new Rect(0, 0, 0, 0));
}
+
+ if(mapping){
+ map = new IntMap<>();
+ }
+ }
+
+ public void sort(Comparator super T> comp){
+ array.sort(comp);
+ }
+
+ public void collide(EntityGroup extends Hitboxc> other){
+ collisions.collideGroups((EntityGroup extends Hitboxc>)this, other);
+ }
+
+ public void updatePhysics(){
+ collisions.updatePhysics((EntityGroup extends Hitboxc>)this);
}
public void update(){
- updateEvents();
+ each(Entityc::update);
+ }
- if(useTree()){
- collisions.updatePhysics(this);
- }
-
- for(Entity e : all()){
- e.update();
+ public void each(Cons cons){
+ for(index = 0; index < array.size; index++){
+ cons.get(array.items[index]);
}
}
- public int countInBounds(){
- count = 0;
- draw(e -> true, e -> count++);
- return count;
+ public void each(Boolf filter, Cons cons){
+ for(index = 0; index < array.size; index++){
+ if(filter.get(array.items[index])) cons.get(array.items[index]);
+ }
}
- public void draw(){
- draw(e -> true);
- }
+ public void draw(Cons cons){
+ Core.camera.bounds(viewport);
- public void draw(Boolf toDraw){
- draw(toDraw, t -> ((DrawTrait)t).draw());
- }
-
- public void draw(Boolf