diff --git a/android/proguard-project.txt b/android/proguard-project.txt index b166b1e81c..1f34b8cae8 100644 --- a/android/proguard-project.txt +++ b/android/proguard-project.txt @@ -20,26 +20,10 @@ #} -verbose - --dontwarn android.support.** --dontwarn com.badlogic.gdx.backends.android.AndroidFragmentApplication --dontwarn com.badlogic.gdx.utils.GdxBuild --dontwarn com.badlogic.gdx.physics.box2d.utils.Box2DBuild --dontwarn com.badlogic.gdx.jnigen.BuildTarget* --dontwarn com.badlogic.gdx.graphics.g2d.freetype.FreetypeBuild - --keep class com.badlogic.gdx.controllers.android.AndroidControllers - --keepclassmembers class com.badlogic.gdx.backends.android.AndroidInput* { - (com.badlogic.gdx.Application, android.content.Context, java.lang.Object, com.badlogic.gdx.backends.android.AndroidApplicationConfiguration); -} - --keepclassmembers class com.badlogic.gdx.physics.box2d.World { - boolean contactFilter(long, long); - void beginContact(long); - void endContact(long); - void preSolve(long, long); - void postSolve(long, long); - boolean reportFixture(long); - float reportRayFixture(long, float, float, float, float, float); +-verbose +-ignorewarnings +-keep class io.anuke.mindustry.game.Rules +-keep class io.anuke.mindustry.desktop.DesktopLauncher +-keepclasseswithmembers public class * { + public static void main(java.lang.String[]); } diff --git a/annotations/src/main/java/io/anuke/annotations/Annotations.java b/annotations/src/main/java/io/anuke/annotations/Annotations.java index eae4030b44..ce7832f76d 100644 --- a/annotations/src/main/java/io/anuke/annotations/Annotations.java +++ b/annotations/src/main/java/io/anuke/annotations/Annotations.java @@ -14,6 +14,21 @@ public class Annotations{ } + /** Marks a class as a special value type struct. Class name must end in 'Struct'.*/ + @Target(ElementType.TYPE) + @Retention(RetentionPolicy.SOURCE) + public @interface Struct{ + + } + + /**Marks a field of a struct. Optional.*/ + @Target(ElementType.FIELD) + @Retention(RetentionPolicy.SOURCE) + public @interface StructField{ + /**Size of a struct field in bits. Not valid on booleans or floating point numbers.*/ + int value(); + } + public enum PacketPriority{ /** Gets put in a queue and processed if not connected. */ normal, diff --git a/annotations/src/main/java/io/anuke/annotations/RemoteReadGenerator.java b/annotations/src/main/java/io/anuke/annotations/RemoteReadGenerator.java index 61382d3f24..69dbe29f8b 100644 --- a/annotations/src/main/java/io/anuke/annotations/RemoteReadGenerator.java +++ b/annotations/src/main/java/io/anuke/annotations/RemoteReadGenerator.java @@ -2,8 +2,6 @@ package io.anuke.annotations; import com.squareup.javapoet.*; import io.anuke.annotations.IOFinder.ClassSerializer; -import io.anuke.annotations.MethodEntry; -import io.anuke.annotations.Utils; import javax.lang.model.element.Modifier; import javax.lang.model.element.TypeElement; @@ -52,7 +50,7 @@ public class RemoteReadGenerator{ Constructor cons = TypeName.class.getDeclaredConstructor(String.class); cons.setAccessible(true); - TypeName playerType = cons.newInstance("io.anuke.mindustry.entities.Player"); + TypeName playerType = cons.newInstance("io.anuke.mindustry.entities.type.Player"); //add player parameter readMethod.addParameter(playerType, "player"); } diff --git a/annotations/src/main/java/io/anuke/annotations/RemoteWriteGenerator.java b/annotations/src/main/java/io/anuke/annotations/RemoteWriteGenerator.java index 62cff1f25b..2f195aa896 100644 --- a/annotations/src/main/java/io/anuke/annotations/RemoteWriteGenerator.java +++ b/annotations/src/main/java/io/anuke/annotations/RemoteWriteGenerator.java @@ -80,7 +80,7 @@ public class RemoteWriteGenerator{ return; } - if(!elem.getParameters().get(0).asType().toString().equals("io.anuke.mindustry.entities.Player")){ + if(!elem.getParameters().get(0).asType().toString().equals("io.anuke.mindustry.entities.type.Player")){ Utils.messager.printMessage(Kind.ERROR, "Client invoke methods should have a first parameter of type Player.", elem); return; } diff --git a/annotations/src/main/java/io/anuke/annotations/StructAnnotationProcessor.java b/annotations/src/main/java/io/anuke/annotations/StructAnnotationProcessor.java new file mode 100644 index 0000000000..e4efe6c6ad --- /dev/null +++ b/annotations/src/main/java/io/anuke/annotations/StructAnnotationProcessor.java @@ -0,0 +1,229 @@ +package io.anuke.annotations; + +import com.squareup.javapoet.JavaFile; +import com.squareup.javapoet.MethodSpec; +import com.squareup.javapoet.TypeName; +import com.squareup.javapoet.TypeSpec; +import io.anuke.annotations.Annotations.Struct; +import io.anuke.annotations.Annotations.StructField; + +import javax.annotation.processing.*; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.TypeElement; +import javax.lang.model.element.VariableElement; +import javax.lang.model.type.TypeKind; +import javax.lang.model.util.ElementFilter; +import javax.tools.Diagnostic.Kind; +import java.util.List; +import java.util.Set; + +/**Generates ""value types"" classes that are packed into integer primitives of the most aproppriate size. + * It would be nice if Java didn't make crazy hacks like this necessary.*/ +@SupportedSourceVersion(SourceVersion.RELEASE_8) +@SupportedAnnotationTypes({ + "io.anuke.annotations.Annotations.Struct" +}) +public class StructAnnotationProcessor extends AbstractProcessor{ + /** Name of the base package to put all the generated classes. */ + private static final String packageName = "io.anuke.mindustry.gen"; + private int round; + + @Override + public synchronized void init(ProcessingEnvironment processingEnv){ + super.init(processingEnv); + //put all relevant utils into utils class + Utils.typeUtils = processingEnv.getTypeUtils(); + Utils.elementUtils = processingEnv.getElementUtils(); + Utils.filer = processingEnv.getFiler(); + Utils.messager = processingEnv.getMessager(); + } + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv){ + if(round++ != 0) return false; //only process 1 round + + try{ + Set elements = ElementFilter.typesIn(roundEnv.getElementsAnnotatedWith(Struct.class)); + + for(TypeElement elem : elements){ + + if(!elem.getSimpleName().toString().endsWith("Struct")){ + Utils.messager.printMessage(Kind.ERROR, "All classes annotated with @Struct must have their class names end in 'Struct'.", elem); + continue; + } + + String structName = elem.getSimpleName().toString().substring(0, elem.getSimpleName().toString().length() - "Struct".length()); + String structParam = structName.toLowerCase(); + + TypeSpec.Builder classBuilder = TypeSpec.classBuilder(structName) + .addModifiers(Modifier.FINAL, Modifier.PUBLIC); + + try{ + List variables = ElementFilter.fieldsIn(elem.getEnclosedElements()); + int structSize = variables.stream().mapToInt(StructAnnotationProcessor::varSize).sum(); + int structTotalSize = (structSize <= 8 ? 8 : structSize <= 16 ? 16 : structSize <= 32 ? 32 : 64); + + if(variables.size() == 0){ + Utils.messager.printMessage(Kind.ERROR, "making a struct with no fields is utterly pointles.", elem); + continue; + } + + //obtain type which will be stored + Class structType = typeForSize(structSize); + + //[constructor] get(fields...) : structType + MethodSpec.Builder constructor = MethodSpec.methodBuilder("get") //TODO 'get'..? + .addModifiers(Modifier.STATIC, Modifier.PUBLIC) + .returns(structType); + + StringBuilder cons = new StringBuilder(); + StringBuilder doc = new StringBuilder(); + doc.append("Bits used: ").append(structSize).append(" / ").append(structTotalSize).append("\n"); + + int offset = 0; + for(VariableElement var : variables){ + int size = varSize(var); + TypeName varType = TypeName.get(var.asType()); + String varName = var.getSimpleName().toString(); + + //add val param to constructor + constructor.addParameter(varType, varName); + + //[get] field(structType) : fieldType + MethodSpec.Builder getter = MethodSpec.methodBuilder(var.getSimpleName().toString()) + .addModifiers(Modifier.STATIC, Modifier.PUBLIC) + .returns(varType) + .addParameter(structType, structParam); + //[set] field(structType, fieldType) : structType + MethodSpec.Builder setter = MethodSpec.methodBuilder(var.getSimpleName().toString()) + .addModifiers(Modifier.STATIC, Modifier.PUBLIC) + .returns(structType) + .addParameter(structType, structParam).addParameter(varType, "value"); + + //[getter] + if(varType == TypeName.BOOLEAN){ + //bools: single bit, is simplified + getter.addStatement("return ($L & (1L << $L)) != 0", structParam, offset); + }else if(varType == TypeName.FLOAT){ + //floats: need conversion + getter.addStatement("return Float.intBitsToFloat((int)(($L >>> $L) & $L))", structParam, offset, bitString(size, structTotalSize)); + }else{ + //bytes, shorts, chars, ints + getter.addStatement("return ($T)(($L >>> $L) & $L)", varType, structParam, offset, bitString(size, structTotalSize)); + } + + //[setter] + [constructor building] + if(varType == TypeName.BOOLEAN){ + cons.append(" | (").append(varName).append(" ? ").append("1L << ").append(offset).append("L : 0)"); + + //bools: single bit, needs special case to clear things + setter.beginControlFlow("if(value)"); + setter.addStatement("return ($T)(($L & ~(1L << $LL)))", structType, structParam, offset); + setter.nextControlFlow("else"); + setter.addStatement("return ($T)(($L & ~(1L << $LL)) | (1L << $LL))", structType, structParam, offset, offset); + setter.endControlFlow(); + }else if(varType == TypeName.FLOAT){ + cons.append(" | (").append("(").append(structType).append(")").append("Float.floatToIntBits(").append(varName).append(") << ").append(offset).append("L)"); + + //floats: need conversion + setter.addStatement("return ($T)(($L & $L) | (($T)Float.floatToIntBits(value) << $LL))", structType, structParam, bitString(offset, size, structTotalSize), structType, offset); + }else{ + cons.append(" | (").append("(").append(structType).append(")").append(varName).append(" << ").append(offset).append("L)"); + + //bytes, shorts, chars, ints + setter.addStatement("return ($T)(($L & $L) | (($T)value << $LL))", structType, structParam, bitString(offset, size, structTotalSize), structType, offset); + } + + doc.append("
").append(varName).append(" [").append(offset).append("..").append(size + offset).append("]\n"); + + //add finished methods + classBuilder.addMethod(getter.build()); + classBuilder.addMethod(setter.build()); + + offset += size; + } + + classBuilder.addJavadoc(doc.toString()); + + //add constructor final statement + add to class and build + constructor.addStatement("return ($T)($L)", structType, cons.toString().substring(3)); + classBuilder.addMethod(constructor.build()); + + JavaFile.builder(packageName, classBuilder.build()).build().writeTo(Utils.filer); + }catch(IllegalArgumentException e){ + e.printStackTrace(); + Utils.messager.printMessage(Kind.ERROR, e.getMessage(), elem); + } + } + + return true; + }catch(Exception e){ + e.printStackTrace(); + throw new RuntimeException(e); + } + } + + static String bitString(int offset, int size, int totalSize){ + StringBuilder builder = new StringBuilder(); + for(int i = 0; i < offset; i++) builder.append('0'); + for(int i = 0; i < size; i++) builder.append('1'); + for(int i = 0; i < totalSize - size - offset; i++) builder.append('0'); + return "0b" + builder.reverse().toString() + "L"; + } + + static String bitString(int size, int totalSize){ + StringBuilder builder = new StringBuilder(); + for(int i = 0; i < size; i++) builder.append('1'); + for(int i = 0; i < totalSize - size; i++) builder.append('0'); + return "0b" + builder.reverse().toString() + "L"; + } + + static int varSize(VariableElement var) throws IllegalArgumentException{ + if(!var.asType().getKind().isPrimitive()){ + throw new IllegalArgumentException("All struct fields must be primitives: " + var); + } + + StructField an = var.getAnnotation(StructField.class); + if(var.asType().getKind() == TypeKind.BOOLEAN && an != null && an.value() != 1){ + throw new IllegalArgumentException("Booleans can only be one bit long... why would you do this?"); + } + + if(var.asType().getKind() == TypeKind.FLOAT && an != null && an.value() != 32){ + throw new IllegalArgumentException("Float size can't be changed. Very sad."); + } + + return an == null ? typeSize(var.asType().getKind()) : an.value(); + } + + static Class typeForSize(int size) throws IllegalArgumentException{ + if(size <= 8){ + return byte.class; + }else if(size <= 16){ + return short.class; + }else if(size <= 32){ + return int.class; + }else if(size <= 64){ + return long.class; + } + throw new IllegalArgumentException("Too many fields, must fit in 64 bits. Curent size: " + size); + } + + /**returns a type's element size in bits.*/ + static int typeSize(TypeKind kind) throws IllegalArgumentException{ + switch(kind){ + case BOOLEAN: + return 1; + case BYTE: + return 8; + case SHORT: + return 16; + case FLOAT: + case CHAR: + case INT: + return 32; + default: + throw new IllegalArgumentException("Invalid type kind: " + kind + ". Note that doubles and longs are not supported."); + } + } +} diff --git a/annotations/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/annotations/src/main/resources/META-INF/services/javax.annotation.processing.Processor index a83673baa6..af76756139 100644 --- a/annotations/src/main/resources/META-INF/services/javax.annotation.processing.Processor +++ b/annotations/src/main/resources/META-INF/services/javax.annotation.processing.Processor @@ -1,2 +1,3 @@ io.anuke.annotations.RemoteMethodAnnotationProcessor io.anuke.annotations.SerializeAnnotationProcessor +io.anuke.annotations.StructAnnotationProcessor diff --git a/build.gradle b/build.gradle index 249dacf7ba..8fb24f284b 100644 --- a/build.gradle +++ b/build.gradle @@ -26,6 +26,10 @@ allprojects{ gdxVersion = '1.9.9' roboVMVersion = '2.3.0' arcHash = null + + debugged = { + return new File(projectDir.parent, '../debug').exists() && System.properties["release"] == null + } localArc = { return (System.properties["release"] == null || System.properties["release"] == "false") && new File(projectDir.parent, '../Arc').exists() @@ -35,7 +39,7 @@ allprojects{ //get latest commit hash from gtihub since JITPack's '-snapshot' version doesn't work correctly if(arcHash == null){ try{ - arcHash = 'git ls-remote https://github.com/Anuken/Arc.git'.execute().text.split("\t")[0]//new JsonSlurper().parse(new URL("https://api.github.com/repos/Anuken/Arc/commits/master"))["sha"] + arcHash = 'git ls-remote https://github.com/Anuken/Arc.git'.execute().text.split("\t")[0] }catch(e){ e.printStackTrace() arcHash = "-SNAPSHOT"; @@ -117,7 +121,7 @@ project(":desktop"){ compile project(":core") compile project(":net") - if(new File(projectDir.parent, '../debug').exists() && System.properties["release"] == null) compile project(":debug") + if(debugged()) compile project(":debug") compile "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop" compile "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-desktop" @@ -194,6 +198,7 @@ project(":core"){ compile arcModule("arc-core") compile arcModule("extensions:freetype") + if(localArc() && debugged()) compile arcModule("extensions:recorder") compileOnly project(":annotations") annotationProcessor project(":annotations") diff --git a/core/assets-raw/sprites/blocks/distribution/mass-driver.png b/core/assets-raw/sprites/blocks/distribution/mass-driver-base.png similarity index 100% rename from core/assets-raw/sprites/blocks/distribution/mass-driver.png rename to core/assets-raw/sprites/blocks/distribution/mass-driver-base.png diff --git a/core/assets-raw/sprites/blocks/distribution/warp-gate-top.png b/core/assets-raw/sprites/blocks/distribution/warp-gate-top.png deleted file mode 100644 index 57ec334c4e..0000000000 Binary files a/core/assets-raw/sprites/blocks/distribution/warp-gate-top.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/distribution/warp-gate.png b/core/assets-raw/sprites/blocks/distribution/warp-gate.png deleted file mode 100644 index 6ccfb3b703..0000000000 Binary files a/core/assets-raw/sprites/blocks/distribution/warp-gate.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/environment/blackrock1.png b/core/assets-raw/sprites/blocks/environment/blackrock1.png deleted file mode 100644 index 4a43dbe023..0000000000 Binary files a/core/assets-raw/sprites/blocks/environment/blackrock1.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/environment/blackstone1.png b/core/assets-raw/sprites/blocks/environment/blackstone1.png deleted file mode 100644 index 5bc819ae4e..0000000000 Binary files a/core/assets-raw/sprites/blocks/environment/blackstone1.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/environment/blackstone2.png b/core/assets-raw/sprites/blocks/environment/blackstone2.png deleted file mode 100644 index 458d40c265..0000000000 Binary files a/core/assets-raw/sprites/blocks/environment/blackstone2.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/environment/blackstone3.png b/core/assets-raw/sprites/blocks/environment/blackstone3.png deleted file mode 100644 index cd064a04cd..0000000000 Binary files a/core/assets-raw/sprites/blocks/environment/blackstone3.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/environment/blackstoneedge.png b/core/assets-raw/sprites/blocks/environment/blackstoneedge.png deleted file mode 100644 index 0bd91906aa..0000000000 Binary files a/core/assets-raw/sprites/blocks/environment/blackstoneedge.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/environment/cliffs1.png b/core/assets-raw/sprites/blocks/environment/cliffs1.png new file mode 100644 index 0000000000..f07190276d Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/cliffs1.png differ diff --git a/core/assets-raw/sprites/blocks/environment/craters1.png b/core/assets-raw/sprites/blocks/environment/craters1.png index 0ed5c848cf..e819484335 100644 Binary files a/core/assets-raw/sprites/blocks/environment/craters1.png and b/core/assets-raw/sprites/blocks/environment/craters1.png differ diff --git a/core/assets-raw/sprites/blocks/environment/craters2.png b/core/assets-raw/sprites/blocks/environment/craters2.png index f4b4ea3aed..f33ee31d60 100644 Binary files a/core/assets-raw/sprites/blocks/environment/craters2.png and b/core/assets-raw/sprites/blocks/environment/craters2.png differ diff --git a/core/assets-raw/sprites/blocks/environment/craters3.png b/core/assets-raw/sprites/blocks/environment/craters3.png index 923b0bc05b..36a73ab5a5 100644 Binary files a/core/assets-raw/sprites/blocks/environment/craters3.png and b/core/assets-raw/sprites/blocks/environment/craters3.png differ diff --git a/core/assets-raw/sprites/blocks/environment/craters4.png b/core/assets-raw/sprites/blocks/environment/craters4.png new file mode 100644 index 0000000000..57c362e366 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/craters4.png differ diff --git a/core/assets-raw/sprites/blocks/environment/craters5.png b/core/assets-raw/sprites/blocks/environment/craters5.png new file mode 100644 index 0000000000..684ebd3e2b Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/craters5.png differ diff --git a/core/assets-raw/sprites/blocks/environment/craters6.png b/core/assets-raw/sprites/blocks/environment/craters6.png new file mode 100644 index 0000000000..2ee1c2dfd1 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/craters6.png differ diff --git a/core/assets-raw/sprites/blocks/environment/deepwater.png b/core/assets-raw/sprites/blocks/environment/deepwater.png index bc4f5312d3..869752084b 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/differential-generator-top.png b/core/assets-raw/sprites/blocks/environment/differential-generator-top.png new file mode 100644 index 0000000000..a540f2b93c Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/differential-generator-top.png differ diff --git a/core/assets-raw/sprites/blocks/environment/differential-generator.png b/core/assets-raw/sprites/blocks/environment/differential-generator.png new file mode 100644 index 0000000000..adf332a1e9 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/differential-generator.png differ diff --git a/core/assets-raw/sprites/blocks/environment/dirt1.png b/core/assets-raw/sprites/blocks/environment/dirt1.png deleted file mode 100644 index 8738655fe7..0000000000 Binary files a/core/assets-raw/sprites/blocks/environment/dirt1.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/environment/dirt2.png b/core/assets-raw/sprites/blocks/environment/dirt2.png deleted file mode 100644 index 9e04571b90..0000000000 Binary files a/core/assets-raw/sprites/blocks/environment/dirt2.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/environment/dirt3.png b/core/assets-raw/sprites/blocks/environment/dirt3.png deleted file mode 100644 index c62c7dcc36..0000000000 Binary files a/core/assets-raw/sprites/blocks/environment/dirt3.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/environment/dirtedge.png b/core/assets-raw/sprites/blocks/environment/dirtedge.png deleted file mode 100644 index 9e2a03cd15..0000000000 Binary files a/core/assets-raw/sprites/blocks/environment/dirtedge.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/environment/dunerocks-large.png b/core/assets-raw/sprites/blocks/environment/dunerocks-large.png new file mode 100644 index 0000000000..44f6a2f372 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/dunerocks-large.png differ diff --git a/core/assets-raw/sprites/blocks/environment/dunerocks1.png b/core/assets-raw/sprites/blocks/environment/dunerocks1.png new file mode 100644 index 0000000000..384904fa48 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/dunerocks1.png differ diff --git a/core/assets-raw/sprites/blocks/environment/dunerocks2.png b/core/assets-raw/sprites/blocks/environment/dunerocks2.png new file mode 100644 index 0000000000..0409649b3f Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/dunerocks2.png differ diff --git a/core/assets-raw/sprites/blocks/environment/edge-stencil-blocky.png b/core/assets-raw/sprites/blocks/environment/edge-stencil-blocky.png new file mode 100644 index 0000000000..e9e15f64bb Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/edge-stencil-blocky.png differ diff --git a/core/assets-raw/sprites/blocks/environment/edge-stencil-smooth.png b/core/assets-raw/sprites/blocks/environment/edge-stencil-smooth.png new file mode 100644 index 0000000000..ae245b60c4 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/edge-stencil-smooth.png differ diff --git a/core/assets-raw/sprites/blocks/environment/grassedge.png b/core/assets-raw/sprites/blocks/environment/grassedge.png deleted file mode 100644 index 70f08ac618..0000000000 Binary files a/core/assets-raw/sprites/blocks/environment/grassedge.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/environment/holostone1.png b/core/assets-raw/sprites/blocks/environment/holostone1.png new file mode 100644 index 0000000000..7e9ea228b2 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/holostone1.png differ diff --git a/core/assets-raw/sprites/blocks/environment/holostone2.png b/core/assets-raw/sprites/blocks/environment/holostone2.png new file mode 100644 index 0000000000..1c0c94d197 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/holostone2.png differ diff --git a/core/assets-raw/sprites/blocks/environment/holostone3.png b/core/assets-raw/sprites/blocks/environment/holostone3.png new file mode 100644 index 0000000000..928118bee8 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/holostone3.png differ diff --git a/core/assets-raw/sprites/blocks/environment/hotrock1.png b/core/assets-raw/sprites/blocks/environment/hotrock1.png new file mode 100644 index 0000000000..f7c566bf06 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/hotrock1.png differ diff --git a/core/assets-raw/sprites/blocks/environment/hotrock2.png b/core/assets-raw/sprites/blocks/environment/hotrock2.png new file mode 100644 index 0000000000..41586d523b Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/hotrock2.png differ diff --git a/core/assets-raw/sprites/blocks/environment/hotrock3.png b/core/assets-raw/sprites/blocks/environment/hotrock3.png new file mode 100644 index 0000000000..cc72227234 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/hotrock3.png differ diff --git a/core/assets-raw/sprites/blocks/environment/ice-edge.png b/core/assets-raw/sprites/blocks/environment/ice-edge.png new file mode 100644 index 0000000000..0355b50f3a Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/ice-edge.png differ diff --git a/core/assets-raw/sprites/blocks/environment/ice-snow1.png b/core/assets-raw/sprites/blocks/environment/ice-snow1.png new file mode 100644 index 0000000000..23764ff1cc Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/ice-snow1.png differ diff --git a/core/assets-raw/sprites/blocks/environment/ice-snow2.png b/core/assets-raw/sprites/blocks/environment/ice-snow2.png new file mode 100644 index 0000000000..538943b64c Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/ice-snow2.png differ diff --git a/core/assets-raw/sprites/blocks/environment/ice-snow3.png b/core/assets-raw/sprites/blocks/environment/ice-snow3.png new file mode 100644 index 0000000000..2e56e2e7e7 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/ice-snow3.png differ diff --git a/core/assets-raw/sprites/blocks/environment/ice1.png b/core/assets-raw/sprites/blocks/environment/ice1.png index dd7af2fd0d..f27c916fa2 100644 Binary files a/core/assets-raw/sprites/blocks/environment/ice1.png and b/core/assets-raw/sprites/blocks/environment/ice1.png differ diff --git a/core/assets-raw/sprites/blocks/environment/ice2.png b/core/assets-raw/sprites/blocks/environment/ice2.png index fa8e08f161..463317a9d2 100644 Binary files a/core/assets-raw/sprites/blocks/environment/ice2.png and b/core/assets-raw/sprites/blocks/environment/ice2.png differ diff --git a/core/assets-raw/sprites/blocks/environment/ice3.png b/core/assets-raw/sprites/blocks/environment/ice3.png index 73908890a1..21e0023570 100644 Binary files a/core/assets-raw/sprites/blocks/environment/ice3.png and b/core/assets-raw/sprites/blocks/environment/ice3.png differ diff --git a/core/assets-raw/sprites/blocks/environment/iceedge.png b/core/assets-raw/sprites/blocks/environment/iceedge.png deleted file mode 100644 index 7065c36213..0000000000 Binary files a/core/assets-raw/sprites/blocks/environment/iceedge.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/environment/icerock1.png b/core/assets-raw/sprites/blocks/environment/icerock1.png deleted file mode 100644 index d81cdfcc84..0000000000 Binary files a/core/assets-raw/sprites/blocks/environment/icerock1.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/environment/icerock2.png b/core/assets-raw/sprites/blocks/environment/icerock2.png deleted file mode 100644 index e5adab47a2..0000000000 Binary files a/core/assets-raw/sprites/blocks/environment/icerock2.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/environment/icerocks-large.png b/core/assets-raw/sprites/blocks/environment/icerocks-large.png new file mode 100644 index 0000000000..79671701fa Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/icerocks-large.png differ diff --git a/core/assets-raw/sprites/blocks/environment/icerocks1.png b/core/assets-raw/sprites/blocks/environment/icerocks1.png new file mode 100644 index 0000000000..ca5db6fedf Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/icerocks1.png differ diff --git a/core/assets-raw/sprites/blocks/environment/icerocks2.png b/core/assets-raw/sprites/blocks/environment/icerocks2.png new file mode 100644 index 0000000000..b2dd1a0cee Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/icerocks2.png differ diff --git a/core/assets-raw/sprites/blocks/environment/ignarock1.png b/core/assets-raw/sprites/blocks/environment/ignarock1.png new file mode 100644 index 0000000000..c329cb2f15 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/ignarock1.png differ diff --git a/core/assets-raw/sprites/blocks/environment/ignarock2.png b/core/assets-raw/sprites/blocks/environment/ignarock2.png new file mode 100644 index 0000000000..08834e87af Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/ignarock2.png differ diff --git a/core/assets-raw/sprites/blocks/environment/ignarock3.png b/core/assets-raw/sprites/blocks/environment/ignarock3.png new file mode 100644 index 0000000000..eb0af3a572 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/ignarock3.png differ diff --git a/core/assets-raw/sprites/blocks/environment/lava.png b/core/assets-raw/sprites/blocks/environment/lava.png deleted file mode 100644 index 4f1f9cfe10..0000000000 Binary files a/core/assets-raw/sprites/blocks/environment/lava.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/environment/lavaedge.png b/core/assets-raw/sprites/blocks/environment/lavaedge.png deleted file mode 100644 index fc8a770308..0000000000 Binary files a/core/assets-raw/sprites/blocks/environment/lavaedge.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/environment/magmarock1.png b/core/assets-raw/sprites/blocks/environment/magmarock1.png new file mode 100644 index 0000000000..05d62c8859 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/magmarock1.png differ diff --git a/core/assets-raw/sprites/blocks/environment/magmarock2.png b/core/assets-raw/sprites/blocks/environment/magmarock2.png new file mode 100644 index 0000000000..65640ff22c Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/magmarock2.png differ diff --git a/core/assets-raw/sprites/blocks/environment/magmarock3.png b/core/assets-raw/sprites/blocks/environment/magmarock3.png new file mode 100644 index 0000000000..07dbf8366d Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/magmarock3.png differ diff --git a/core/assets-raw/sprites/blocks/environment/metal-floor-2.png b/core/assets-raw/sprites/blocks/environment/metal-floor-2.png new file mode 100644 index 0000000000..8d3b818096 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/metal-floor-2.png differ diff --git a/core/assets-raw/sprites/blocks/environment/metal-floor-3.png b/core/assets-raw/sprites/blocks/environment/metal-floor-3.png new file mode 100644 index 0000000000..eb6b15d03b Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/metal-floor-3.png differ diff --git a/core/assets-raw/sprites/blocks/environment/metal-floor-5.png b/core/assets-raw/sprites/blocks/environment/metal-floor-5.png new file mode 100644 index 0000000000..e9d39b3db2 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/metal-floor-5.png differ diff --git a/core/assets-raw/sprites/blocks/environment/metal-floor-damaged1.png b/core/assets-raw/sprites/blocks/environment/metal-floor-damaged1.png new file mode 100644 index 0000000000..e4220e9adc Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/metal-floor-damaged1.png differ diff --git a/core/assets-raw/sprites/blocks/environment/metal-floor-damaged2.png b/core/assets-raw/sprites/blocks/environment/metal-floor-damaged2.png new file mode 100644 index 0000000000..a74ac3897d Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/metal-floor-damaged2.png differ diff --git a/core/assets-raw/sprites/blocks/environment/metal-floor-damaged3.png b/core/assets-raw/sprites/blocks/environment/metal-floor-damaged3.png new file mode 100644 index 0000000000..2f07315bc5 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/metal-floor-damaged3.png differ diff --git a/core/assets-raw/sprites/blocks/environment/metal-floor-damaged4.png b/core/assets-raw/sprites/blocks/environment/metal-floor-damaged4.png new file mode 100644 index 0000000000..64027a66f1 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/metal-floor-damaged4.png differ diff --git a/core/assets-raw/sprites/blocks/environment/metal-floor-damaged5.png b/core/assets-raw/sprites/blocks/environment/metal-floor-damaged5.png new file mode 100644 index 0000000000..9c9b48708b Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/metal-floor-damaged5.png differ diff --git a/core/assets-raw/sprites/blocks/environment/metal-floor-damaged6.png b/core/assets-raw/sprites/blocks/environment/metal-floor-damaged6.png new file mode 100644 index 0000000000..f2b7f15be5 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/metal-floor-damaged6.png differ diff --git a/core/assets-raw/sprites/blocks/environment/metal-floor.png b/core/assets-raw/sprites/blocks/environment/metal-floor.png new file mode 100644 index 0000000000..049e13a3ae Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/metal-floor.png differ diff --git a/core/assets-raw/sprites/blocks/environment/metalfloor1.png b/core/assets-raw/sprites/blocks/environment/metalfloor1.png deleted file mode 100644 index 2c625b7a77..0000000000 Binary files a/core/assets-raw/sprites/blocks/environment/metalfloor1.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/environment/metalfloor2.png b/core/assets-raw/sprites/blocks/environment/metalfloor2.png deleted file mode 100644 index 74c443f2f1..0000000000 Binary files a/core/assets-raw/sprites/blocks/environment/metalfloor2.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/environment/metalfloor3.png b/core/assets-raw/sprites/blocks/environment/metalfloor3.png deleted file mode 100644 index 1215611d66..0000000000 Binary files a/core/assets-raw/sprites/blocks/environment/metalfloor3.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/environment/metalfloor4.png b/core/assets-raw/sprites/blocks/environment/metalfloor4.png deleted file mode 100644 index 937133c441..0000000000 Binary files a/core/assets-raw/sprites/blocks/environment/metalfloor4.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/environment/metalfloor5.png b/core/assets-raw/sprites/blocks/environment/metalfloor5.png deleted file mode 100644 index 1d5e775c80..0000000000 Binary files a/core/assets-raw/sprites/blocks/environment/metalfloor5.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/environment/metalfloor6.png b/core/assets-raw/sprites/blocks/environment/metalfloor6.png deleted file mode 100644 index a14136822c..0000000000 Binary files a/core/assets-raw/sprites/blocks/environment/metalfloor6.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/environment/metalflooredge.png b/core/assets-raw/sprites/blocks/environment/metalflooredge.png deleted file mode 100644 index b8089a6c63..0000000000 Binary files a/core/assets-raw/sprites/blocks/environment/metalflooredge.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/environment/pine.png b/core/assets-raw/sprites/blocks/environment/pine.png index 6fc0b12c16..3e6f3c7ef8 100644 Binary files a/core/assets-raw/sprites/blocks/environment/pine.png and b/core/assets-raw/sprites/blocks/environment/pine.png differ diff --git a/core/assets-raw/sprites/blocks/environment/rocks-large.png b/core/assets-raw/sprites/blocks/environment/rocks-large.png new file mode 100644 index 0000000000..391ce2f941 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/rocks-large.png differ diff --git a/core/assets-raw/sprites/blocks/environment/sand1.png b/core/assets-raw/sprites/blocks/environment/sand1.png index 6ef1e28bc0..f6259baf64 100644 Binary files a/core/assets-raw/sprites/blocks/environment/sand1.png and b/core/assets-raw/sprites/blocks/environment/sand1.png differ diff --git a/core/assets-raw/sprites/blocks/environment/sand2.png b/core/assets-raw/sprites/blocks/environment/sand2.png index 05bedd0bc3..ce03f296ba 100644 Binary files a/core/assets-raw/sprites/blocks/environment/sand2.png and b/core/assets-raw/sprites/blocks/environment/sand2.png differ diff --git a/core/assets-raw/sprites/blocks/environment/sand3.png b/core/assets-raw/sprites/blocks/environment/sand3.png index 69b1dd2ec7..7ff6f2e9f0 100644 Binary files a/core/assets-raw/sprites/blocks/environment/sand3.png and b/core/assets-raw/sprites/blocks/environment/sand3.png differ diff --git a/core/assets-raw/sprites/blocks/environment/sandedge.png b/core/assets-raw/sprites/blocks/environment/sandedge.png deleted file mode 100644 index 51b4c9f290..0000000000 Binary files a/core/assets-raw/sprites/blocks/environment/sandedge.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/environment/shrub.png b/core/assets-raw/sprites/blocks/environment/shrub.png deleted file mode 100644 index 27e40fdc75..0000000000 Binary files a/core/assets-raw/sprites/blocks/environment/shrub.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/environment/snow1.png b/core/assets-raw/sprites/blocks/environment/snow1.png index 87ffafe61c..25042c14c5 100644 Binary files a/core/assets-raw/sprites/blocks/environment/snow1.png and b/core/assets-raw/sprites/blocks/environment/snow1.png differ diff --git a/core/assets-raw/sprites/blocks/environment/snow2.png b/core/assets-raw/sprites/blocks/environment/snow2.png index 96c0889c85..2ef4c13aca 100644 Binary files a/core/assets-raw/sprites/blocks/environment/snow2.png and b/core/assets-raw/sprites/blocks/environment/snow2.png differ diff --git a/core/assets-raw/sprites/blocks/environment/snow3.png b/core/assets-raw/sprites/blocks/environment/snow3.png index 7695fa4265..79c9b36ab7 100644 Binary files a/core/assets-raw/sprites/blocks/environment/snow3.png and b/core/assets-raw/sprites/blocks/environment/snow3.png differ diff --git a/core/assets-raw/sprites/blocks/environment/snowedge.png b/core/assets-raw/sprites/blocks/environment/snowedge.png deleted file mode 100644 index b3d088df1f..0000000000 Binary files a/core/assets-raw/sprites/blocks/environment/snowedge.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/environment/snowrocks-large.png b/core/assets-raw/sprites/blocks/environment/snowrocks-large.png new file mode 100644 index 0000000000..75017dbee1 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/snowrocks-large.png differ diff --git a/core/assets-raw/sprites/blocks/environment/snowrocks1.png b/core/assets-raw/sprites/blocks/environment/snowrocks1.png new file mode 100644 index 0000000000..5a18216caa Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/snowrocks1.png differ diff --git a/core/assets-raw/sprites/blocks/environment/snowrocks2.png b/core/assets-raw/sprites/blocks/environment/snowrocks2.png new file mode 100644 index 0000000000..d3f14dc536 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/snowrocks2.png differ diff --git a/core/assets-raw/sprites/blocks/environment/space.png b/core/assets-raw/sprites/blocks/environment/space.png deleted file mode 100644 index 9d8e9aade9..0000000000 Binary files a/core/assets-raw/sprites/blocks/environment/space.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/environment/spaceedge.png b/core/assets-raw/sprites/blocks/environment/spaceedge.png deleted file mode 100644 index 20f01523c5..0000000000 Binary files a/core/assets-raw/sprites/blocks/environment/spaceedge.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/environment/spore-cluster1.png b/core/assets-raw/sprites/blocks/environment/spore-cluster1.png new file mode 100644 index 0000000000..89a95e4f5f Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/spore-cluster1.png differ diff --git a/core/assets-raw/sprites/blocks/environment/spore-cluster2.png b/core/assets-raw/sprites/blocks/environment/spore-cluster2.png new file mode 100644 index 0000000000..c8975c0472 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/spore-cluster2.png differ diff --git a/core/assets-raw/sprites/blocks/environment/spore-cluster3.png b/core/assets-raw/sprites/blocks/environment/spore-cluster3.png new file mode 100644 index 0000000000..c1a4749033 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/spore-cluster3.png differ diff --git a/core/assets-raw/sprites/blocks/environment/stained-boulder1.png b/core/assets-raw/sprites/blocks/environment/stained-boulder1.png new file mode 100644 index 0000000000..66f88b2a06 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/stained-boulder1.png differ diff --git a/core/assets-raw/sprites/blocks/environment/stained-boulder2.png b/core/assets-raw/sprites/blocks/environment/stained-boulder2.png new file mode 100644 index 0000000000..4b45697887 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/stained-boulder2.png differ diff --git a/core/assets-raw/sprites/blocks/environment/stained-rocks-large.png b/core/assets-raw/sprites/blocks/environment/stained-rocks-large.png new file mode 100644 index 0000000000..ec311cc1fc Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/stained-rocks-large.png differ diff --git a/core/assets-raw/sprites/blocks/environment/stained-rocks-red-large.png b/core/assets-raw/sprites/blocks/environment/stained-rocks-red-large.png new file mode 100644 index 0000000000..1697abb808 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/stained-rocks-red-large.png differ diff --git a/core/assets-raw/sprites/blocks/environment/stained-rocks-red1.png b/core/assets-raw/sprites/blocks/environment/stained-rocks-red1.png new file mode 100644 index 0000000000..e646fcbba3 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/stained-rocks-red1.png differ diff --git a/core/assets-raw/sprites/blocks/environment/stained-rocks-red2.png b/core/assets-raw/sprites/blocks/environment/stained-rocks-red2.png new file mode 100644 index 0000000000..f85c1882bc Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/stained-rocks-red2.png differ diff --git a/core/assets-raw/sprites/blocks/environment/stained-rocks-yellow-large.png b/core/assets-raw/sprites/blocks/environment/stained-rocks-yellow-large.png new file mode 100644 index 0000000000..055bd4cc44 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/stained-rocks-yellow-large.png differ diff --git a/core/assets-raw/sprites/blocks/environment/stained-rocks-yellow1.png b/core/assets-raw/sprites/blocks/environment/stained-rocks-yellow1.png new file mode 100644 index 0000000000..9e59a807c8 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/stained-rocks-yellow1.png differ diff --git a/core/assets-raw/sprites/blocks/environment/stained-rocks-yellow2.png b/core/assets-raw/sprites/blocks/environment/stained-rocks-yellow2.png new file mode 100644 index 0000000000..4788cb582a Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/stained-rocks-yellow2.png differ diff --git a/core/assets-raw/sprites/blocks/environment/stained-rocks1.png b/core/assets-raw/sprites/blocks/environment/stained-rocks1.png new file mode 100644 index 0000000000..e0aa379812 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/stained-rocks1.png differ diff --git a/core/assets-raw/sprites/blocks/environment/stained-rocks2.png b/core/assets-raw/sprites/blocks/environment/stained-rocks2.png new file mode 100644 index 0000000000..7b6eabb5d1 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/stained-rocks2.png differ diff --git a/core/assets-raw/sprites/blocks/environment/stained-stone-red1.png b/core/assets-raw/sprites/blocks/environment/stained-stone-red1.png new file mode 100644 index 0000000000..a32936fdb2 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/stained-stone-red1.png differ diff --git a/core/assets-raw/sprites/blocks/environment/stained-stone-red2.png b/core/assets-raw/sprites/blocks/environment/stained-stone-red2.png new file mode 100644 index 0000000000..baae667241 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/stained-stone-red2.png differ diff --git a/core/assets-raw/sprites/blocks/environment/stained-stone-red3.png b/core/assets-raw/sprites/blocks/environment/stained-stone-red3.png new file mode 100644 index 0000000000..7269b8fd14 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/stained-stone-red3.png differ diff --git a/core/assets-raw/sprites/blocks/environment/stained-stone-yellow1.png b/core/assets-raw/sprites/blocks/environment/stained-stone-yellow1.png new file mode 100644 index 0000000000..c2a6b18117 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/stained-stone-yellow1.png differ diff --git a/core/assets-raw/sprites/blocks/environment/stained-stone-yellow2.png b/core/assets-raw/sprites/blocks/environment/stained-stone-yellow2.png new file mode 100644 index 0000000000..20b285b768 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/stained-stone-yellow2.png differ diff --git a/core/assets-raw/sprites/blocks/environment/stained-stone-yellow3.png b/core/assets-raw/sprites/blocks/environment/stained-stone-yellow3.png new file mode 100644 index 0000000000..2a92d862be Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/stained-stone-yellow3.png differ diff --git a/core/assets-raw/sprites/blocks/environment/stained-stone1.png b/core/assets-raw/sprites/blocks/environment/stained-stone1.png new file mode 100644 index 0000000000..464ac94806 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/stained-stone1.png differ diff --git a/core/assets-raw/sprites/blocks/environment/stained-stone2.png b/core/assets-raw/sprites/blocks/environment/stained-stone2.png new file mode 100644 index 0000000000..36a8896dd8 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/stained-stone2.png differ diff --git a/core/assets-raw/sprites/blocks/environment/stained-stone3.png b/core/assets-raw/sprites/blocks/environment/stained-stone3.png new file mode 100644 index 0000000000..092ec5dac7 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/stained-stone3.png differ diff --git a/core/assets-raw/sprites/blocks/environment/stainedrocks-large.png b/core/assets-raw/sprites/blocks/environment/stainedrocks-large.png new file mode 100644 index 0000000000..46c60a3be4 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/stainedrocks-large.png differ diff --git a/core/assets-raw/sprites/blocks/environment/stainedrocks1.png b/core/assets-raw/sprites/blocks/environment/stainedrocks1.png new file mode 100644 index 0000000000..d8af4693e9 Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/stainedrocks1.png differ diff --git a/core/assets-raw/sprites/blocks/environment/stainedrocks2.png b/core/assets-raw/sprites/blocks/environment/stainedrocks2.png new file mode 100644 index 0000000000..7a8d8b178b Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/stainedrocks2.png differ diff --git a/core/assets-raw/sprites/blocks/environment/stoneedge.png b/core/assets-raw/sprites/blocks/environment/stoneedge.png deleted file mode 100644 index 0a8b5cc987..0000000000 Binary files a/core/assets-raw/sprites/blocks/environment/stoneedge.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/environment/taredge.png b/core/assets-raw/sprites/blocks/environment/taredge.png deleted file mode 100644 index e7f2a2182d..0000000000 Binary files a/core/assets-raw/sprites/blocks/environment/taredge.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/environment/titanium1.png b/core/assets-raw/sprites/blocks/environment/titanium1.png index 2496e3bc4c..95bc34dd60 100644 Binary files a/core/assets-raw/sprites/blocks/environment/titanium1.png and b/core/assets-raw/sprites/blocks/environment/titanium1.png differ diff --git a/core/assets-raw/sprites/blocks/environment/titanium2.png b/core/assets-raw/sprites/blocks/environment/titanium2.png index edf8b6db31..68d021abe7 100644 Binary files a/core/assets-raw/sprites/blocks/environment/titanium2.png and b/core/assets-raw/sprites/blocks/environment/titanium2.png differ diff --git a/core/assets-raw/sprites/blocks/environment/titanium3.png b/core/assets-raw/sprites/blocks/environment/titanium3.png index bdb5d318fb..e4bb5b45dd 100644 Binary files a/core/assets-raw/sprites/blocks/environment/titanium3.png and b/core/assets-raw/sprites/blocks/environment/titanium3.png differ diff --git a/core/assets-raw/sprites/blocks/environment/water-cliff-edge-1.png b/core/assets-raw/sprites/blocks/environment/water-cliff-edge-1.png deleted file mode 100644 index d9dc5602b8..0000000000 Binary files a/core/assets-raw/sprites/blocks/environment/water-cliff-edge-1.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/environment/water-cliff-edge-2.png b/core/assets-raw/sprites/blocks/environment/water-cliff-edge-2.png deleted file mode 100644 index 9bc0ee1962..0000000000 Binary files a/core/assets-raw/sprites/blocks/environment/water-cliff-edge-2.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/environment/water-cliff-edge.png b/core/assets-raw/sprites/blocks/environment/water-cliff-edge.png deleted file mode 100644 index 460663e57d..0000000000 Binary files a/core/assets-raw/sprites/blocks/environment/water-cliff-edge.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/environment/water-cliff-side.png b/core/assets-raw/sprites/blocks/environment/water-cliff-side.png deleted file mode 100644 index 7e0402fa97..0000000000 Binary files a/core/assets-raw/sprites/blocks/environment/water-cliff-side.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/environment/water.png b/core/assets-raw/sprites/blocks/environment/water.png deleted file mode 100644 index b923481473..0000000000 Binary files a/core/assets-raw/sprites/blocks/environment/water.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/environment/wateredge.png b/core/assets-raw/sprites/blocks/environment/wateredge.png deleted file mode 100644 index 5dcc17b20e..0000000000 Binary files a/core/assets-raw/sprites/blocks/environment/wateredge.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/environment/white-tree-dead.png b/core/assets-raw/sprites/blocks/environment/white-tree-dead.png new file mode 100644 index 0000000000..adc18507bb Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/white-tree-dead.png differ diff --git a/core/assets-raw/sprites/blocks/environment/white-tree.png b/core/assets-raw/sprites/blocks/environment/white-tree.png new file mode 100644 index 0000000000..a6e26a8ede Binary files /dev/null and b/core/assets-raw/sprites/blocks/environment/white-tree.png differ diff --git a/core/assets-raw/sprites/blocks/extra/rubble-4-0.png b/core/assets-raw/sprites/blocks/extra/rubble-4-0.png new file mode 100644 index 0000000000..0a23d121b1 Binary files /dev/null and b/core/assets-raw/sprites/blocks/extra/rubble-4-0.png 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 new file mode 100644 index 0000000000..0bc32c92a7 Binary files /dev/null and b/core/assets-raw/sprites/blocks/extra/rubble-4-1.png differ diff --git a/core/assets-raw/sprites/blocks/mechs/alpha-mech-pad.png b/core/assets-raw/sprites/blocks/mechs/alpha-dart-mech-pad.png similarity index 100% rename from core/assets-raw/sprites/blocks/mechs/alpha-mech-pad.png rename to core/assets-raw/sprites/blocks/mechs/alpha-dart-mech-pad.png diff --git a/core/assets-raw/sprites/blocks/mechs/dart-ship-pad.png b/core/assets-raw/sprites/blocks/mechs/dart-ship-pad.png deleted file mode 100644 index 112c9e6ebd..0000000000 Binary files a/core/assets-raw/sprites/blocks/mechs/dart-ship-pad.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/power/battery-large.png b/core/assets-raw/sprites/blocks/power/battery-large.png index e140bf1bd0..fb5c37bf18 100644 Binary files a/core/assets-raw/sprites/blocks/power/battery-large.png and b/core/assets-raw/sprites/blocks/power/battery-large.png differ diff --git a/core/assets-raw/sprites/blocks/power/battery.png b/core/assets-raw/sprites/blocks/power/battery.png index 902ab6a6c3..527ab35d5a 100644 Binary files a/core/assets-raw/sprites/blocks/power/battery.png and b/core/assets-raw/sprites/blocks/power/battery.png differ diff --git a/core/assets-raw/sprites/blocks/power/combustion-generator.png b/core/assets-raw/sprites/blocks/power/combustion-generator.png index 09d42c06ef..bc22c6fc55 100644 Binary files a/core/assets-raw/sprites/blocks/power/combustion-generator.png and b/core/assets-raw/sprites/blocks/power/combustion-generator.png differ diff --git a/core/assets-raw/sprites/blocks/power/fusion-reactor-bottom.png b/core/assets-raw/sprites/blocks/power/impact-reactor-bottom.png similarity index 100% rename from core/assets-raw/sprites/blocks/power/fusion-reactor-bottom.png rename to core/assets-raw/sprites/blocks/power/impact-reactor-bottom.png diff --git a/core/assets-raw/sprites/blocks/power/fusion-reactor-light.png b/core/assets-raw/sprites/blocks/power/impact-reactor-light.png similarity index 100% rename from core/assets-raw/sprites/blocks/power/fusion-reactor-light.png rename to core/assets-raw/sprites/blocks/power/impact-reactor-light.png diff --git a/core/assets-raw/sprites/blocks/power/fusion-reactor-plasma-0.png b/core/assets-raw/sprites/blocks/power/impact-reactor-plasma-0.png similarity index 100% rename from core/assets-raw/sprites/blocks/power/fusion-reactor-plasma-0.png rename to core/assets-raw/sprites/blocks/power/impact-reactor-plasma-0.png diff --git a/core/assets-raw/sprites/blocks/power/fusion-reactor-plasma-1.png b/core/assets-raw/sprites/blocks/power/impact-reactor-plasma-1.png similarity index 100% rename from core/assets-raw/sprites/blocks/power/fusion-reactor-plasma-1.png rename to core/assets-raw/sprites/blocks/power/impact-reactor-plasma-1.png diff --git a/core/assets-raw/sprites/blocks/power/fusion-reactor-plasma-2.png b/core/assets-raw/sprites/blocks/power/impact-reactor-plasma-2.png similarity index 100% rename from core/assets-raw/sprites/blocks/power/fusion-reactor-plasma-2.png rename to core/assets-raw/sprites/blocks/power/impact-reactor-plasma-2.png diff --git a/core/assets-raw/sprites/blocks/power/fusion-reactor-plasma-3.png b/core/assets-raw/sprites/blocks/power/impact-reactor-plasma-3.png similarity index 100% rename from core/assets-raw/sprites/blocks/power/fusion-reactor-plasma-3.png rename to core/assets-raw/sprites/blocks/power/impact-reactor-plasma-3.png diff --git a/core/assets-raw/sprites/blocks/power/fusion-reactor-top.png b/core/assets-raw/sprites/blocks/power/impact-reactor-top.png similarity index 100% rename from core/assets-raw/sprites/blocks/power/fusion-reactor-top.png rename to core/assets-raw/sprites/blocks/power/impact-reactor-top.png diff --git a/core/assets-raw/sprites/blocks/power/fusion-reactor.png b/core/assets-raw/sprites/blocks/power/impact-reactor.png similarity index 100% rename from core/assets-raw/sprites/blocks/power/fusion-reactor.png rename to core/assets-raw/sprites/blocks/power/impact-reactor.png diff --git a/core/assets-raw/sprites/blocks/power/power-node-large.png b/core/assets-raw/sprites/blocks/power/power-node-large.png index 81a87f4fcd..95d43bb0b2 100644 Binary files a/core/assets-raw/sprites/blocks/power/power-node-large.png and b/core/assets-raw/sprites/blocks/power/power-node-large.png differ diff --git a/core/assets-raw/sprites/blocks/power/power-node.png b/core/assets-raw/sprites/blocks/power/power-node.png index aba8cca098..2081207f2a 100644 Binary files a/core/assets-raw/sprites/blocks/power/power-node.png and b/core/assets-raw/sprites/blocks/power/power-node.png differ diff --git a/core/assets-raw/sprites/blocks/power/power-source.png b/core/assets-raw/sprites/blocks/power/power-source.png index 5a14712e46..079397e307 100644 Binary files a/core/assets-raw/sprites/blocks/power/power-source.png and b/core/assets-raw/sprites/blocks/power/power-source.png differ diff --git a/core/assets-raw/sprites/blocks/power/power-void.png b/core/assets-raw/sprites/blocks/power/power-void.png index 5634353f59..4506ce2f99 100644 Binary files a/core/assets-raw/sprites/blocks/power/power-void.png and b/core/assets-raw/sprites/blocks/power/power-void.png differ diff --git a/core/assets-raw/sprites/blocks/power/solar-panel-large.png b/core/assets-raw/sprites/blocks/power/solar-panel-large.png index 6dfa4d7c59..d226e9f8b8 100644 Binary files a/core/assets-raw/sprites/blocks/power/solar-panel-large.png and b/core/assets-raw/sprites/blocks/power/solar-panel-large.png differ diff --git a/core/assets-raw/sprites/blocks/power/surge-tower.png b/core/assets-raw/sprites/blocks/power/surge-tower.png new file mode 100644 index 0000000000..50ad5a1852 Binary files /dev/null and b/core/assets-raw/sprites/blocks/power/surge-tower.png differ diff --git a/core/assets-raw/sprites/blocks/power/turbine-generator.png b/core/assets-raw/sprites/blocks/power/turbine-generator.png index 566b38a505..246f90efe9 100644 Binary files a/core/assets-raw/sprites/blocks/power/turbine-generator.png and b/core/assets-raw/sprites/blocks/power/turbine-generator.png differ diff --git a/core/assets-raw/sprites/blocks/production/alloy-smelter-top.png b/core/assets-raw/sprites/blocks/production/alloy-smelter-top.png index 04220393c4..52616bf864 100644 Binary files a/core/assets-raw/sprites/blocks/production/alloy-smelter-top.png and b/core/assets-raw/sprites/blocks/production/alloy-smelter-top.png differ diff --git a/core/assets-raw/sprites/blocks/production/centrifuge-liquid.png b/core/assets-raw/sprites/blocks/production/centrifuge-liquid.png deleted file mode 100644 index 9c215f6166..0000000000 Binary files a/core/assets-raw/sprites/blocks/production/centrifuge-liquid.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/production/centrifuge.png b/core/assets-raw/sprites/blocks/production/centrifuge.png deleted file mode 100644 index d8afadff79..0000000000 Binary files a/core/assets-raw/sprites/blocks/production/centrifuge.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/production/graphite-press.png b/core/assets-raw/sprites/blocks/production/graphite-press.png new file mode 100644 index 0000000000..57d5c43969 Binary files /dev/null and b/core/assets-raw/sprites/blocks/production/graphite-press.png differ diff --git a/core/assets-raw/sprites/blocks/production/arc-smelter-top.png b/core/assets-raw/sprites/blocks/production/kiln-top.png similarity index 100% rename from core/assets-raw/sprites/blocks/production/arc-smelter-top.png rename to core/assets-raw/sprites/blocks/production/kiln-top.png diff --git a/core/assets-raw/sprites/blocks/production/arc-smelter.png b/core/assets-raw/sprites/blocks/production/kiln.png similarity index 100% rename from core/assets-raw/sprites/blocks/production/arc-smelter.png rename to core/assets-raw/sprites/blocks/production/kiln.png diff --git a/core/assets-raw/sprites/blocks/production/multi-press.png b/core/assets-raw/sprites/blocks/production/multi-press.png new file mode 100644 index 0000000000..3adb9c84f1 Binary files /dev/null and b/core/assets-raw/sprites/blocks/production/multi-press.png differ diff --git a/core/assets-raw/sprites/blocks/production/separator.png b/core/assets-raw/sprites/blocks/production/separator.png index c57f740faf..d8afadff79 100644 Binary files a/core/assets-raw/sprites/blocks/production/separator.png and b/core/assets-raw/sprites/blocks/production/separator.png differ diff --git a/core/assets-raw/sprites/blocks/production/solidifer.png b/core/assets-raw/sprites/blocks/production/solidifer.png deleted file mode 100644 index e84862dc9a..0000000000 Binary files a/core/assets-raw/sprites/blocks/production/solidifer.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/storage/core-foundation.png b/core/assets-raw/sprites/blocks/storage/core-foundation.png new file mode 100644 index 0000000000..83e3b25c9f Binary files /dev/null and b/core/assets-raw/sprites/blocks/storage/core-foundation.png differ diff --git a/core/assets-raw/sprites/blocks/storage/core-nucleus.png b/core/assets-raw/sprites/blocks/storage/core-nucleus.png new file mode 100644 index 0000000000..9619e83c9d Binary files /dev/null and b/core/assets-raw/sprites/blocks/storage/core-nucleus.png differ diff --git a/core/assets-raw/sprites/blocks/storage/core-open.png b/core/assets-raw/sprites/blocks/storage/core-open.png deleted file mode 100644 index 627a4bce64..0000000000 Binary files a/core/assets-raw/sprites/blocks/storage/core-open.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/storage/core-top.png b/core/assets-raw/sprites/blocks/storage/core-shard-top.png similarity index 100% rename from core/assets-raw/sprites/blocks/storage/core-top.png rename to core/assets-raw/sprites/blocks/storage/core-shard-top.png diff --git a/core/assets-raw/sprites/blocks/storage/core.png b/core/assets-raw/sprites/blocks/storage/core-shard.png similarity index 100% rename from core/assets-raw/sprites/blocks/storage/core.png rename to core/assets-raw/sprites/blocks/storage/core-shard.png diff --git a/core/assets-raw/sprites/blocks/turrets/turrets/arc-heat.png b/core/assets-raw/sprites/blocks/turrets/arc-heat.png similarity index 100% rename from core/assets-raw/sprites/blocks/turrets/turrets/arc-heat.png rename to core/assets-raw/sprites/blocks/turrets/arc-heat.png diff --git a/core/assets-raw/sprites/blocks/turrets/turrets/arc.png b/core/assets-raw/sprites/blocks/turrets/arc.png similarity index 100% rename from core/assets-raw/sprites/blocks/turrets/turrets/arc.png rename to core/assets-raw/sprites/blocks/turrets/arc.png diff --git a/core/assets-raw/sprites/blocks/turrets/bases/block-1-top.png b/core/assets-raw/sprites/blocks/turrets/bases/block-1-top.png deleted file mode 100644 index 3df51ef476..0000000000 Binary files a/core/assets-raw/sprites/blocks/turrets/bases/block-1-top.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/turrets/bases/block-2-top.png b/core/assets-raw/sprites/blocks/turrets/bases/block-2-top.png deleted file mode 100644 index 0662ec043d..0000000000 Binary files a/core/assets-raw/sprites/blocks/turrets/bases/block-2-top.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/turrets/bases/block-3-top.png b/core/assets-raw/sprites/blocks/turrets/bases/block-3-top.png deleted file mode 100644 index 01fea4f5ab..0000000000 Binary files a/core/assets-raw/sprites/blocks/turrets/bases/block-3-top.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/turrets/bases/block-4-top.png b/core/assets-raw/sprites/blocks/turrets/bases/block-4-top.png deleted file mode 100644 index 527f3abd7e..0000000000 Binary files a/core/assets-raw/sprites/blocks/turrets/bases/block-4-top.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/turrets/turrets/cyclone.png b/core/assets-raw/sprites/blocks/turrets/cyclone.png similarity index 100% rename from core/assets-raw/sprites/blocks/turrets/turrets/cyclone.png rename to core/assets-raw/sprites/blocks/turrets/cyclone.png diff --git a/core/assets-raw/sprites/blocks/turrets/duo.png b/core/assets-raw/sprites/blocks/turrets/duo.png new file mode 100644 index 0000000000..40d21d0fb0 Binary files /dev/null and b/core/assets-raw/sprites/blocks/turrets/duo.png differ diff --git a/core/assets-raw/sprites/blocks/turrets/fuse.png b/core/assets-raw/sprites/blocks/turrets/fuse.png new file mode 100644 index 0000000000..c03bad9cba Binary files /dev/null and b/core/assets-raw/sprites/blocks/turrets/fuse.png differ diff --git a/core/assets-raw/sprites/blocks/turrets/turrets/hail-heat.png b/core/assets-raw/sprites/blocks/turrets/hail-heat.png similarity index 100% rename from core/assets-raw/sprites/blocks/turrets/turrets/hail-heat.png rename to core/assets-raw/sprites/blocks/turrets/hail-heat.png diff --git a/core/assets-raw/sprites/blocks/turrets/turrets/hail.png b/core/assets-raw/sprites/blocks/turrets/hail.png similarity index 100% rename from core/assets-raw/sprites/blocks/turrets/turrets/hail.png rename to core/assets-raw/sprites/blocks/turrets/hail.png diff --git a/core/assets-raw/sprites/blocks/turrets/turrets/lancer-heat.png b/core/assets-raw/sprites/blocks/turrets/lancer-heat.png similarity index 100% rename from core/assets-raw/sprites/blocks/turrets/turrets/lancer-heat.png rename to core/assets-raw/sprites/blocks/turrets/lancer-heat.png diff --git a/core/assets-raw/sprites/blocks/turrets/lancer.png b/core/assets-raw/sprites/blocks/turrets/lancer.png new file mode 100644 index 0000000000..9864ac6ad9 Binary files /dev/null and b/core/assets-raw/sprites/blocks/turrets/lancer.png differ diff --git a/core/assets-raw/sprites/blocks/turrets/turrets/meltdown-heat.png b/core/assets-raw/sprites/blocks/turrets/meltdown-heat.png similarity index 100% rename from core/assets-raw/sprites/blocks/turrets/turrets/meltdown-heat.png rename to core/assets-raw/sprites/blocks/turrets/meltdown-heat.png diff --git a/core/assets-raw/sprites/blocks/turrets/turrets/meltdown.png b/core/assets-raw/sprites/blocks/turrets/meltdown.png similarity index 100% rename from core/assets-raw/sprites/blocks/turrets/turrets/meltdown.png rename to core/assets-raw/sprites/blocks/turrets/meltdown.png diff --git a/core/assets-raw/sprites/blocks/turrets/turrets/ripple-heat.png b/core/assets-raw/sprites/blocks/turrets/ripple-heat.png similarity index 100% rename from core/assets-raw/sprites/blocks/turrets/turrets/ripple-heat.png rename to core/assets-raw/sprites/blocks/turrets/ripple-heat.png diff --git a/core/assets-raw/sprites/blocks/turrets/turrets/ripple.png b/core/assets-raw/sprites/blocks/turrets/ripple.png similarity index 100% rename from core/assets-raw/sprites/blocks/turrets/turrets/ripple.png rename to core/assets-raw/sprites/blocks/turrets/ripple.png diff --git a/core/assets-raw/sprites/blocks/turrets/turrets/salvo-heat.png b/core/assets-raw/sprites/blocks/turrets/salvo-heat.png similarity index 100% rename from core/assets-raw/sprites/blocks/turrets/turrets/salvo-heat.png rename to core/assets-raw/sprites/blocks/turrets/salvo-heat.png diff --git a/core/assets-raw/sprites/blocks/turrets/turrets/salvo-panel-left.png b/core/assets-raw/sprites/blocks/turrets/salvo-panel-left.png similarity index 100% rename from core/assets-raw/sprites/blocks/turrets/turrets/salvo-panel-left.png rename to core/assets-raw/sprites/blocks/turrets/salvo-panel-left.png diff --git a/core/assets-raw/sprites/blocks/turrets/turrets/salvo-panel-right.png b/core/assets-raw/sprites/blocks/turrets/salvo-panel-right.png similarity index 100% rename from core/assets-raw/sprites/blocks/turrets/turrets/salvo-panel-right.png rename to core/assets-raw/sprites/blocks/turrets/salvo-panel-right.png diff --git a/core/assets-raw/sprites/blocks/turrets/salvo.png b/core/assets-raw/sprites/blocks/turrets/salvo.png new file mode 100644 index 0000000000..bfa377509f Binary files /dev/null and b/core/assets-raw/sprites/blocks/turrets/salvo.png differ diff --git a/core/assets-raw/sprites/blocks/turrets/turrets/spectre.png b/core/assets-raw/sprites/blocks/turrets/spectre.png similarity index 100% rename from core/assets-raw/sprites/blocks/turrets/turrets/spectre.png rename to core/assets-raw/sprites/blocks/turrets/spectre.png diff --git a/core/assets-raw/sprites/blocks/turrets/turrets/swarmer.png b/core/assets-raw/sprites/blocks/turrets/swarmer.png similarity index 100% rename from core/assets-raw/sprites/blocks/turrets/turrets/swarmer.png rename to core/assets-raw/sprites/blocks/turrets/swarmer.png diff --git a/core/assets-raw/sprites/blocks/turrets/turrets/duo.png b/core/assets-raw/sprites/blocks/turrets/turrets/duo.png deleted file mode 100644 index d520c6e4f5..0000000000 Binary files a/core/assets-raw/sprites/blocks/turrets/turrets/duo.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/turrets/turrets/fuse.png b/core/assets-raw/sprites/blocks/turrets/turrets/fuse.png deleted file mode 100644 index 32218df362..0000000000 Binary files a/core/assets-raw/sprites/blocks/turrets/turrets/fuse.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/turrets/turrets/lancer.png b/core/assets-raw/sprites/blocks/turrets/turrets/lancer.png deleted file mode 100644 index 7b6c522ae8..0000000000 Binary files a/core/assets-raw/sprites/blocks/turrets/turrets/lancer.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/turrets/turrets/salvo.png b/core/assets-raw/sprites/blocks/turrets/turrets/salvo.png deleted file mode 100644 index 35692ef373..0000000000 Binary files a/core/assets-raw/sprites/blocks/turrets/turrets/salvo.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/turrets/turrets/scatter.png b/core/assets-raw/sprites/blocks/turrets/turrets/scatter.png deleted file mode 100644 index 5e64bd36e4..0000000000 Binary files a/core/assets-raw/sprites/blocks/turrets/turrets/scatter.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/turrets/turrets/scorch-shoot.png b/core/assets-raw/sprites/blocks/turrets/turrets/scorch-shoot.png deleted file mode 100644 index cc73e4bd33..0000000000 Binary files a/core/assets-raw/sprites/blocks/turrets/turrets/scorch-shoot.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/turrets/turrets/scorch.png b/core/assets-raw/sprites/blocks/turrets/turrets/scorch.png deleted file mode 100644 index 875047c7fd..0000000000 Binary files a/core/assets-raw/sprites/blocks/turrets/turrets/scorch.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/turrets/turrets/wave.png b/core/assets-raw/sprites/blocks/turrets/turrets/wave.png deleted file mode 100644 index 2019a6e2a2..0000000000 Binary files a/core/assets-raw/sprites/blocks/turrets/turrets/wave.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/turrets/turrets/wave-liquid.png b/core/assets-raw/sprites/blocks/turrets/wave-liquid.png similarity index 100% rename from core/assets-raw/sprites/blocks/turrets/turrets/wave-liquid.png rename to core/assets-raw/sprites/blocks/turrets/wave-liquid.png diff --git a/core/assets-raw/sprites/blocks/turrets/wave.png b/core/assets-raw/sprites/blocks/turrets/wave.png new file mode 100644 index 0000000000..ff132fbd74 Binary files /dev/null and b/core/assets-raw/sprites/blocks/turrets/wave.png differ diff --git a/core/assets-raw/sprites/blocks/units/command-center.png b/core/assets-raw/sprites/blocks/units/command-center.png deleted file mode 100644 index 16d5d7f4ad..0000000000 Binary files a/core/assets-raw/sprites/blocks/units/command-center.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/units/reconstructor-open.png b/core/assets-raw/sprites/blocks/units/reconstructor-open.png deleted file mode 100644 index 92a6e51ac3..0000000000 Binary files a/core/assets-raw/sprites/blocks/units/reconstructor-open.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/units/reconstructor.png b/core/assets-raw/sprites/blocks/units/reconstructor.png deleted file mode 100644 index 144156ae68..0000000000 Binary files a/core/assets-raw/sprites/blocks/units/reconstructor.png and /dev/null differ diff --git a/core/assets-raw/sprites/blocks/units/repair-point.png b/core/assets-raw/sprites/blocks/units/repair-point-base.png similarity index 100% rename from core/assets-raw/sprites/blocks/units/repair-point.png rename to core/assets-raw/sprites/blocks/units/repair-point-base.png diff --git a/core/assets-raw/sprites/blocks/walls/scrap-wall-gigantic.png b/core/assets-raw/sprites/blocks/walls/scrap-wall-gigantic.png new file mode 100644 index 0000000000..ffdc63ffcc Binary files /dev/null and b/core/assets-raw/sprites/blocks/walls/scrap-wall-gigantic.png differ diff --git a/core/assets-raw/sprites/blocks/walls/scrap-wall-huge1.png b/core/assets-raw/sprites/blocks/walls/scrap-wall-huge1.png new file mode 100644 index 0000000000..c03322d55d Binary files /dev/null and b/core/assets-raw/sprites/blocks/walls/scrap-wall-huge1.png differ diff --git a/core/assets-raw/sprites/blocks/walls/scrap-wall-huge2.png b/core/assets-raw/sprites/blocks/walls/scrap-wall-huge2.png new file mode 100644 index 0000000000..bdf6d1344c Binary files /dev/null and b/core/assets-raw/sprites/blocks/walls/scrap-wall-huge2.png differ diff --git a/core/assets-raw/sprites/blocks/walls/scrap-wall-huge3.png b/core/assets-raw/sprites/blocks/walls/scrap-wall-huge3.png new file mode 100644 index 0000000000..fa12bc5e02 Binary files /dev/null and b/core/assets-raw/sprites/blocks/walls/scrap-wall-huge3.png differ diff --git a/core/assets-raw/sprites/blocks/walls/scrap-wall-large1.png b/core/assets-raw/sprites/blocks/walls/scrap-wall-large1.png new file mode 100644 index 0000000000..7b420a30d3 Binary files /dev/null and b/core/assets-raw/sprites/blocks/walls/scrap-wall-large1.png differ diff --git a/core/assets-raw/sprites/blocks/walls/scrap-wall-large2.png b/core/assets-raw/sprites/blocks/walls/scrap-wall-large2.png new file mode 100644 index 0000000000..804d7749e4 Binary files /dev/null and b/core/assets-raw/sprites/blocks/walls/scrap-wall-large2.png differ diff --git a/core/assets-raw/sprites/blocks/walls/scrap-wall-large3.png b/core/assets-raw/sprites/blocks/walls/scrap-wall-large3.png new file mode 100644 index 0000000000..d7279d6b32 Binary files /dev/null and b/core/assets-raw/sprites/blocks/walls/scrap-wall-large3.png differ diff --git a/core/assets-raw/sprites/blocks/walls/scrap-wall-large4.png b/core/assets-raw/sprites/blocks/walls/scrap-wall-large4.png new file mode 100644 index 0000000000..3ea4802427 Binary files /dev/null and b/core/assets-raw/sprites/blocks/walls/scrap-wall-large4.png differ diff --git a/core/assets-raw/sprites/blocks/walls/scrap-wall1.png b/core/assets-raw/sprites/blocks/walls/scrap-wall1.png new file mode 100644 index 0000000000..736757a9d1 Binary files /dev/null and b/core/assets-raw/sprites/blocks/walls/scrap-wall1.png differ diff --git a/core/assets-raw/sprites/blocks/walls/scrap-wall2.png b/core/assets-raw/sprites/blocks/walls/scrap-wall2.png new file mode 100644 index 0000000000..ed6229481c Binary files /dev/null and b/core/assets-raw/sprites/blocks/walls/scrap-wall2.png differ diff --git a/core/assets-raw/sprites/blocks/walls/scrap-wall3.png b/core/assets-raw/sprites/blocks/walls/scrap-wall3.png new file mode 100644 index 0000000000..59dab303a3 Binary files /dev/null and b/core/assets-raw/sprites/blocks/walls/scrap-wall3.png differ diff --git a/core/assets-raw/sprites/blocks/walls/scrap-wall4.png b/core/assets-raw/sprites/blocks/walls/scrap-wall4.png new file mode 100644 index 0000000000..df86f16cc2 Binary files /dev/null and b/core/assets-raw/sprites/blocks/walls/scrap-wall4.png differ diff --git a/core/assets-raw/sprites/blocks/walls/scrap-wall5.png b/core/assets-raw/sprites/blocks/walls/scrap-wall5.png new file mode 100644 index 0000000000..1f75829f3a Binary files /dev/null and b/core/assets-raw/sprites/blocks/walls/scrap-wall5.png differ diff --git a/core/assets-raw/sprites/blocks/walls/thruster.png b/core/assets-raw/sprites/blocks/walls/thruster.png new file mode 100644 index 0000000000..82ec7622f6 Binary files /dev/null and b/core/assets-raw/sprites/blocks/walls/thruster.png differ diff --git a/core/assets-raw/sprites/effects/error.png b/core/assets-raw/sprites/effects/error.png deleted file mode 100644 index 1f7efdb692..0000000000 Binary files a/core/assets-raw/sprites/effects/error.png and /dev/null differ diff --git a/core/assets-raw/sprites/items/item-coal.png b/core/assets-raw/sprites/items/item-coal.png index 0c094a7436..399e28f7d5 100644 Binary files a/core/assets-raw/sprites/items/item-coal.png and b/core/assets-raw/sprites/items/item-coal.png differ diff --git a/core/assets-raw/sprites/items/item-graphite.png b/core/assets-raw/sprites/items/item-graphite.png index 51179bef65..bacdf52b8a 100644 Binary files a/core/assets-raw/sprites/items/item-graphite.png and b/core/assets-raw/sprites/items/item-graphite.png differ diff --git a/core/assets-raw/sprites/mechs/mechs/chaos-array-base.png b/core/assets-raw/sprites/mechs/mechs/chaos-array-base.png new file mode 100644 index 0000000000..b1174913d6 Binary files /dev/null and b/core/assets-raw/sprites/mechs/mechs/chaos-array-base.png differ diff --git a/core/assets-raw/sprites/mechs/mechs/chaos-array-leg.png b/core/assets-raw/sprites/mechs/mechs/chaos-array-leg.png new file mode 100644 index 0000000000..7269601fcf Binary files /dev/null and b/core/assets-raw/sprites/mechs/mechs/chaos-array-leg.png differ diff --git a/core/assets-raw/sprites/mechs/mechs/chaos-array.png b/core/assets-raw/sprites/mechs/mechs/chaos-array.png new file mode 100644 index 0000000000..afd96f43dc Binary files /dev/null and b/core/assets-raw/sprites/mechs/mechs/chaos-array.png differ diff --git a/core/assets-raw/sprites/mechs/mechs/eradicator-base.png b/core/assets-raw/sprites/mechs/mechs/eradicator-base.png new file mode 100644 index 0000000000..24b5cdb446 Binary files /dev/null and b/core/assets-raw/sprites/mechs/mechs/eradicator-base.png differ diff --git a/core/assets-raw/sprites/mechs/mechs/eradicator-leg.png b/core/assets-raw/sprites/mechs/mechs/eradicator-leg.png new file mode 100644 index 0000000000..3a503a2e6a Binary files /dev/null and b/core/assets-raw/sprites/mechs/mechs/eradicator-leg.png differ diff --git a/core/assets-raw/sprites/mechs/mechs/eradicator.png b/core/assets-raw/sprites/mechs/mechs/eradicator.png new file mode 100644 index 0000000000..c620aa3d0f Binary files /dev/null and b/core/assets-raw/sprites/mechs/mechs/eradicator.png differ diff --git a/core/assets-raw/sprites/ui/icons/icon-play-custom.png b/core/assets-raw/sprites/ui/icons/icon-play-custom.png new file mode 100644 index 0000000000..78716a2fb0 Binary files /dev/null and b/core/assets-raw/sprites/ui/icons/icon-play-custom.png differ diff --git a/core/assets-raw/sprites/ui/sector-edge.png b/core/assets-raw/sprites/ui/sector-edge.png deleted file mode 100644 index 23f8ea4dc8..0000000000 Binary files a/core/assets-raw/sprites/ui/sector-edge.png and /dev/null differ diff --git a/core/assets-raw/sprites/units/eruptor-base.png b/core/assets-raw/sprites/units/eruptor-base.png new file mode 100644 index 0000000000..0b1e55dbb9 Binary files /dev/null and b/core/assets-raw/sprites/units/eruptor-base.png differ diff --git a/core/assets-raw/sprites/units/eruptor-leg.png b/core/assets-raw/sprites/units/eruptor-leg.png new file mode 100644 index 0000000000..c3d622340a Binary files /dev/null and b/core/assets-raw/sprites/units/eruptor-leg.png differ diff --git a/core/assets-raw/sprites/units/eruptor.png b/core/assets-raw/sprites/units/eruptor.png new file mode 100644 index 0000000000..992fc9ea2d Binary files /dev/null and b/core/assets-raw/sprites/units/eruptor.png differ diff --git a/core/assets-raw/sprites/units/lich.png b/core/assets-raw/sprites/units/lich.png new file mode 100644 index 0000000000..9f34958af8 Binary files /dev/null and b/core/assets-raw/sprites/units/lich.png differ diff --git a/core/assets-raw/sprites/units/reaper.png b/core/assets-raw/sprites/units/reaper.png new file mode 100644 index 0000000000..2d70f5d179 Binary files /dev/null and b/core/assets-raw/sprites/units/reaper.png differ diff --git a/core/assets-raw/sprites/units/revenant.png b/core/assets-raw/sprites/units/revenant.png index 6054faf101..2c9616b93e 100644 Binary files a/core/assets-raw/sprites/units/revenant.png and b/core/assets-raw/sprites/units/revenant.png differ diff --git a/core/assets-raw/sprites/weapons/artillery-equip.png b/core/assets-raw/sprites/weapons/artillery-equip.png index 2f18a8de59..843da3adbc 100644 Binary files a/core/assets-raw/sprites/weapons/artillery-equip.png and b/core/assets-raw/sprites/weapons/artillery-equip.png differ diff --git a/core/assets-raw/sprites/weapons/chain-blaster-equip.png b/core/assets-raw/sprites/weapons/chain-blaster-equip.png index 6591a21135..d2bc4331f4 100644 Binary files a/core/assets-raw/sprites/weapons/chain-blaster-equip.png and b/core/assets-raw/sprites/weapons/chain-blaster-equip.png differ diff --git a/core/assets-raw/sprites/weapons/chaos-equip.png b/core/assets-raw/sprites/weapons/chaos-equip.png new file mode 100644 index 0000000000..0a83fcc8a1 Binary files /dev/null and b/core/assets-raw/sprites/weapons/chaos-equip.png differ diff --git a/core/assets-raw/sprites/weapons/eradication-equip.png b/core/assets-raw/sprites/weapons/eradication-equip.png new file mode 100644 index 0000000000..16befb33e1 Binary files /dev/null and b/core/assets-raw/sprites/weapons/eradication-equip.png differ diff --git a/core/assets-raw/sprites/weapons/eruption-equip.png b/core/assets-raw/sprites/weapons/eruption-equip.png new file mode 100644 index 0000000000..7758d622a5 Binary files /dev/null and b/core/assets-raw/sprites/weapons/eruption-equip.png differ diff --git a/core/assets-raw/sprites/weapons/flamethrower-equip.png b/core/assets-raw/sprites/weapons/flamethrower-equip.png index 1d4462bd42..40b085ac43 100644 Binary files a/core/assets-raw/sprites/weapons/flamethrower-equip.png and b/core/assets-raw/sprites/weapons/flamethrower-equip.png differ diff --git a/core/assets-raw/sprites/weapons/lich-missiles-equip.png b/core/assets-raw/sprites/weapons/lich-missiles-equip.png new file mode 100644 index 0000000000..8deeb5416a Binary files /dev/null and b/core/assets-raw/sprites/weapons/lich-missiles-equip.png differ diff --git a/core/assets-raw/sprites/weapons/reaper-gun-equip.png b/core/assets-raw/sprites/weapons/reaper-gun-equip.png new file mode 100644 index 0000000000..1eb3cb64ba Binary files /dev/null and b/core/assets-raw/sprites/weapons/reaper-gun-equip.png differ diff --git a/core/assets-raw/sprites/weapons/revenant-missiles-equip.png b/core/assets-raw/sprites/weapons/revenant-missiles-equip.png new file mode 100644 index 0000000000..e8ebc4be08 Binary files /dev/null and b/core/assets-raw/sprites/weapons/revenant-missiles-equip.png differ diff --git a/core/assets-raw/sprites_replacement/blocks/environment/deepwater.png b/core/assets-raw/sprites_replacement/blocks/environment/deepwater.png new file mode 100644 index 0000000000..2389c5985d Binary files /dev/null and b/core/assets-raw/sprites_replacement/blocks/environment/deepwater.png differ diff --git a/core/assets-raw/sprites_replacement/blocks/environment/edge-stencil-smooth.png b/core/assets-raw/sprites_replacement/blocks/environment/edge-stencil-smooth.png new file mode 100644 index 0000000000..65a450a798 Binary files /dev/null and b/core/assets-raw/sprites_replacement/blocks/environment/edge-stencil-smooth.png differ diff --git a/core/assets-raw/sprites_replacement/blocks/environment/sand-water.png b/core/assets-raw/sprites_replacement/blocks/environment/sand-water.png new file mode 100644 index 0000000000..0144066175 Binary files /dev/null and b/core/assets-raw/sprites_replacement/blocks/environment/sand-water.png differ diff --git a/core/assets-raw/sprites_replacement/blocks/environment/water.png b/core/assets-raw/sprites_replacement/blocks/environment/water.png new file mode 100644 index 0000000000..631f99201a Binary files /dev/null and b/core/assets-raw/sprites_replacement/blocks/environment/water.png differ diff --git a/core/assets-raw/sprites_replacement/blocks/turrets/duo.png b/core/assets-raw/sprites_replacement/blocks/turrets/duo.png new file mode 100644 index 0000000000..efcdb60832 Binary files /dev/null and b/core/assets-raw/sprites_replacement/blocks/turrets/duo.png differ diff --git a/core/assets-raw/sprites_replacement/effects/error.png b/core/assets-raw/sprites_replacement/effects/error.png new file mode 100644 index 0000000000..f784bec923 Binary files /dev/null and b/core/assets-raw/sprites_replacement/effects/error.png differ diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index d95a889547..65a0b3ed5c 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -33,12 +33,15 @@ deconstruction.title = Block Deconstruction Guide deconstruction = You've just selected [accent]block deconstruction mode[].\n\nTo begin breaking, simply tap a block near your ship.\nOnce you have selected some blocks, press the checkbox to confirm, and your ship will begin de-constructing them.\n\n- [accent]Remove blocks[] from your selection by tapping them.\n- [accent]Remove blocks in an area[] by tapping and holding an empty spot, then dragging in a direction.\n- [accent]Cancel deconstruction or selection[] by pressing the X at the bottom left. showagain = Don't show again next session coreattack = < Core is under attack! > +nearpoint = [[ [scarlet]LEAVE DROP POINT IMMEDIATELY[] ]\nannihilation imminent +outofbounds = [[ OUT OF BOUNDS ]\n[]self-destruct in {0} database = Core Database savegame = Save Game loadgame = Load Game joingame = Join Game addplayers = Add/Remove Players customgame = Custom Game +newgame = New Game none = close = Close quit = Quit @@ -246,8 +249,11 @@ locked = Locked complete = [LIGHT_GRAY]Complete: resume = Resume Zone:\n[LIGHT_GRAY]{0} bestwave = [LIGHT_GRAY]Best: {0} -launch = Launch +launch = < LAUNCH > launch.title = Launch Successful +launch.next = [LIGHT_GRAY]next opportunity at wave {0} +launch.unable = [scarlet]Unable to LAUNCH.[] Enemies. +launch.confirm = This will launch all resources in your core.\nYou will not be able to return to this base. zone.unlocked = [LIGHT_GRAY]{0} unlocked. connectfail = [crimson]Failed to connect to server:\n\n[accent]{0} @@ -266,7 +272,7 @@ zone.frozenForest.name = Frozen Forest zone.ruinousShores.name = Ruinous Shores zone.crags.name = Crags zone.stainedMountains.name = Stained Mountains -zone.impact.name = Impact 0079 +zone.impact0079.name = Impact 0079 zone.desolateRift.name = Desolate Rift zone.arcticDesert.name = Arctic Desert zone.dryWastes.name = Dry Wastes @@ -321,12 +327,15 @@ blocks.liquidoutput = Liquid Output blocks.liquidoutputspeed = Liquid Output Speed blocks.liquiduse = Liquid Use blocks.coolant = Coolant +blocks.liquid = Liquid blocks.coolantuse = Coolant Use blocks.inputliquidfuel = Fuel Liquid blocks.liquidfueluse = Liquid Fuel Use blocks.boostitem = Boost Item blocks.boostliquid = Boost Liquid blocks.health = Health +blocks.power = Power +blocks.power.satisfaction = Power Satisfaction blocks.inaccuracy = Inaccuracy blocks.shots = Shots blocks.reload = Shots/Second @@ -334,6 +343,7 @@ blocks.inputfuel = Fuel blocks.fuelburntime = Fuel Burn Time blocks.inputcapacity = Input capacity blocks.outputcapacity = Output capacity +blocks.ammo = Ammo unit.blocks = blocks unit.powersecond = power units/second unit.liquidsecond = liquid units/second @@ -392,6 +402,7 @@ keybind.screenshot.name = Map Screenshot keybind.move_x.name = Move x keybind.move_y.name = Move y keybind.select.name = Select/Shoot +keybind.pick.name = Pick Block keybind.break.name = Break keybind.deselect.name = Deselect keybind.shoot.name = Shoot @@ -411,8 +422,8 @@ keybind.chat_scroll.name = Chat scroll keybind.drop_unit.name = Drop Unit keybind.zoom_minimap.name = Zoom minimap mode.help.title = Description of modes -mode.waves.name = Waves -mode.waves.description = The normal mode. Limited resources and automatic incoming waves. +mode.survival.name = Survival +mode.survival.description = The normal mode. Limited resources and automatic incoming waves. mode.sandbox.name = Sandbox mode.sandbox.description = Infinite resources and no timer for waves. mode.freebuild.name = Freebuild @@ -458,7 +469,7 @@ item.metaglass.description = A super-tough glass compound. Extensively used for item.scrap.name = Scrap item.scrap.description = Leftover remnants of old structures and units. Contains trace amounts of many different metals. liquid.water.name = Water -liquid.lava.name = Lava +liquid.slag.name = Slag liquid.oil.name = Oil liquid.cryofluid.name = Cryofluid mech.alpha-mech.name = Alpha @@ -493,11 +504,10 @@ mech.glaive-ship.weapon = Flame Repeater item.explosiveness = [LIGHT_GRAY]Explosiveness: {0}% item.flammability = [LIGHT_GRAY]Flammability: {0}% item.radioactivity = [LIGHT_GRAY]Radioactivity: {0}% -item.fluxiness = [LIGHT_GRAY]Flux Power: {0}% unit.health = [LIGHT_GRAY]Health: {0} unit.speed = [LIGHT_GRAY]Speed: {0} mech.weapon = [LIGHT_GRAY]Weapon: {0} -mech.armor = [LIGHT_GRAY]Armor: {0} +mech.health = [LIGHT_GRAY]Health: {0} mech.itemcapacity = [LIGHT_GRAY]Item Capacity: {0} mech.minespeed = [LIGHT_GRAY]Mining Speed: {0} mech.minepower = [LIGHT_GRAY]Mining Power: {0} @@ -505,9 +515,15 @@ mech.ability = [LIGHT_GRAY]Ability: {0} liquid.heatcapacity = [LIGHT_GRAY]Heat Capacity: {0} liquid.viscosity = [LIGHT_GRAY]Viscosity: {0} liquid.temperature = [LIGHT_GRAY]Temperature: {0} +block.kiln.name = Kiln +block.kiln.description = Smelts sand and lead into metaglass. Requires small amounts of power. +block.graphite-press.name = Graphite Press +block.multi-press.name = Multi-Press block.constructing = {0} [LIGHT_GRAY](Constructing) block.spawn.name = Enemy Spawn -block.core.name = Core +block.core-shard.name = Core: Shard +block.core-foundation.name = Core: Foundation +block.core-nucleus.name = Core: Nucleus block.metalfloor.name = Metal Floor block.deepwater.name = deepwater block.water.name = water @@ -516,7 +532,7 @@ block.tar.name = Tar block.blackstone.name = Black Stone block.stone.name = Stone block.dirt.name = Dirt -block.sand.name = Sand +block.sand.name = Dark Sand block.ice.name = Ice block.snow.name = Snow block.grass.name = Grass @@ -524,6 +540,36 @@ block.shrub.name = Shrub block.rock.name = Rock block.blackrock.name = Black Rock block.icerock.name = icerock +block.craters.name = Craters +block.sand-water.name = Sand water +block.char.name = Char +block.holostone.name = Holo stone +block.ice-snow.name = Ice Snow +block.rocks.name = Rocks +block.icerocks.name = Ice rocks +block.snowrocks.name = Snow Rocks +block.dunerocks.name = Dune Rocks +block.pine.name = Pine +block.white-tree-dead.name = White Tree Dead +block.white-tree.name = White Tree +block.spore-cluster.name = Spore Cluster +block.stained-rocks.name = Stained Rocks +block.stained-stone.name = Stained Stone +block.stained-rocks-red.name = Stained Rocks Red +block.stained-stone-red.name = Stained Stone Red +block.stained-rocks-yellow.name = Stained Rocks Yellow +block.stained-stone-yellow.name = Stained Stone Yellow +block.stained-boulder.name = Stained Boulde +block.metal-floor.name = Metal Floor +block.metal-floor-1.name = Metal Floor 1 +block.metal-floor-2.name = Metal Floor 2 +block.metal-floor-3.name = Metal Floor 3 +block.metal-floor-5.name = Metal Floor 5 +block.metal-floor-damaged.name = Metal Floor Damaged +block.ignarock.name = Igna Rock +block.hotrock.name = Hot Rock +block.magmarock.name = Magma Rock +block.cliffs.name = Cliffs block.copper-wall.name = Copper Wall block.copper-wall-large.name = Large Copper Wall block.titanium-wall.name = Titanium Wall @@ -560,17 +606,19 @@ block.separator.name = Separator block.centrifuge.name = Centrifuge block.power-node.name = Power Node block.power-node-large.name = Large Power Node +block.surge-tower.name = Surge Tower block.battery.name = Battery block.battery-large.name = Large Battery block.combustion-generator.name = Combustion Generator block.turbine-generator.name = Turbine Generator +block.differential-generator.name = Differential Generator +block.impact-reactor.name = Impact Reactor block.mechanical-drill.name = Mechanical Drill block.pneumatic-drill.name = Pneumatic Drill block.laser-drill.name = Laser Drill block.water-extractor.name = Water Extractor block.cultivator.name = Cultivator -block.alpha-mech-pad.name = Alpha Mech Pad -block.dart-ship-pad.name = Dart Ship Pad +block.alpha-dart-mech-pad.name = Alpha-Dart 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 @@ -635,7 +683,6 @@ block.rtg-generator.name = RTG Generator block.spectre.name = Spectre block.meltdown.name = Meltdown block.container.name = Container -block.core.description = The most important building in the game. block.launch-pad.name = Launch Pad team.blue.name = blue team.red.name = red @@ -650,6 +697,7 @@ unit.phantom.name = Phantom Drone unit.phantom.description = An advanced drone unit. Automatically mines ores and repairs blocks. Significantly more effective than a spirit drone. unit.dagger.name = Dagger unit.dagger.description = A basic ground unit. Useful in swarms. +unit.crawler.name = Crawler unit.titan.name = Titan unit.titan.description = An advanced, armored ground unit. Attacks both ground and air targets. unit.ghoul.name = Ghoul Bomber @@ -659,7 +707,11 @@ unit.wraith.description = A fast, hit-and-run interceptor unit. unit.fortress.name = Fortress unit.fortress.description = A heavy artillery ground unit. unit.revenant.name = Revenant -unit.revenant.description = A heavy laser platform. +unit.eruptor.name = Eruptor +unit.chaos-array.name = Chaos Array +unit.eradicator.name = Eradicator +unit.lich.name = Lich +unit.reaper.name = Reaper tutorial.begin = Your mission here is to eradicate the[LIGHT_GRAY] enemy[].\n\nBegin by[accent] mining copper[]. Tap a copper ore vein near your core to do this. tutorial.drill = Mining manually is inefficient.\n[accent]Drills []can mine automatically.\nPlace one on a copper vein. tutorial.conveyor = [accent]Conveyors[] are used to transport items to the core.\nMake a line of conveyors from the drill to the core. diff --git a/core/assets/bundles/bundle_cs.properties b/core/assets/bundles/bundle_cs.properties index 466827c14f..c5cd86c905 100644 --- a/core/assets/bundles/bundle_cs.properties +++ b/core/assets/bundles/bundle_cs.properties @@ -13,13 +13,15 @@ linkfail = Nepodařilo se otevřít odkaz!\nURL byla zkopírována do schránky. screenshot = Snímek obrazovky uložen {0} gameover = Konec hry gameover.pvp = [accent] {0}[] Tým Vyhrál! -sector.gameover = Tento sektor byl ztracen. Znovu obsadit? -sector.retry = Znovu highscore = [accent]Nový Rekord! -wave.lasted = Vydržel jsi do vlny [accent]{0}[]. -level.highscore = Nejvyšší skóre: [accent]{0} -level.delete.title = Potvrdit smazání +stat.wave = Waves Defeated:[accent] {0} +stat.enemiesDestroyed = Enemies Destroyed:[accent] {0} +stat.built = Buildings Built:[accent] {0} +stat.destroyed = Buildings Destroyed:[accent] {0} +stat.deconstructed = Buildings Deconstructed:[accent] {0} +stat.delivered = Resources Launched: map.delete = Jsi si jistý že chceš smazat mapu "[accent]{0}[]"? +level.highscore = Nejvyšší skóre: [accent]{0} level.select = Výběr levelu level.mode = Herní mód: construction.desktop = K odznačení bloku nebo k zastavení stavby, [accent]stiskni mezerník[]. @@ -29,61 +31,36 @@ deconstruction.title = Návod k dekonstrukci bloků. deconstruction = Právě jsi vybral [accent]Mód dekonstrukce bloků[].\n\nK boření staveb, jednoduše vyber blok poblíž tvé lodi.\nJakmile jsis vybral nějaké bloky, stiskni pole potvrzení, a tvoje loď je začne sama dekonstruovat.\n\n- [accent]Odstranění bloků[] z tvého výběru kliknutím na ně.\n- [accent]Odstranění bloků v oblasti[] provedeš stisknutím prázdného pole a přetažením do jakéhokoliv směru.\n- [accent]Zrušení dekonstrukce nebo výběru[] stisknutím X v levém dolním rohu. showagain = Znovu neukazovat ! coreattack = < Jádro je pod útokem! > -unlocks = Odemykatelné +nearpoint = [[ [scarlet]LEAVE DROP POINT IMMEDIATELY[] ]\nannihilation imminent +outofbounds = [[ OUT OF BOUNDS ]\n[]self-destruct in {0} +database = Core Database savegame = Uložit hru loadgame = Načíst hru joingame = Připojit se ke hře addplayers = Přidat/Odebrat hráče customgame = Vlastní hra -sectors = Sektory -sector = Sektor: [LIGHT_GRAY]{0} -sector.time = Čas: [LIGHT_GRAY]{0} -sector.deploy = Výsadek -sector.abandon = Opustit -sector.abandon.confirm = Jsi si jistý že chceš opustit veškerý postup v tomto sektoru?\nTento krok je nevratný! -sector.resume = Pokračovat -sector.locked = [scarlet][[Incomplete] -sector.unexplored = [accent][[Unexplored] -missions = Mise:[LIGHT_GRAY] {0} -mission = Mise:[LIGHT_GRAY] {0} -mission.main = Hlavní mise:[LIGHT_GRAY] {0} -mission.info = Informace o misi -mission.complete = Mise splněna! -mission.complete.body = Sektor {0},{1} Byl dobyt. -mission.wave = Udrž se[accent] {0}/{1} []Vln\nVlna za {2} -mission.wave.enemies = Udrž se[accent] {0}/{1} []vln\n{2} Nepřátel -mission.wave.enemy = Udrž se[accent] {0}/{1} []vln\n{2} Nepřátel -mission.wave.menu = Udrž se[accent] {0}[] vln -mission.battle = Znič nepřátelské jádro -mission.resource.menu = Získej {0} x{1} -mission.resource = Získej {0}:\n[accent]{1}/{2}[] -mission.block = Vytvoř {0} -mission.unit = Vytvoř {0} Jednotek -mission.command = Pošli rozkaz {0} jednotkám -mission.linknode = Propoj energetický uzel -mission.display = [accent]Mise:\n[LIGHT_GRAY]{0} -mission.mech = Změň na Mecha[accent] {0}[] -mission.create = Vytvoř[accent] {0}[] +newgame = New Game none = close = Zavřít quit = Ukončit maps = Mapy continue = Pokračovat -nextmission = Další Mise maps.none = [LIGHT_GRAY]Žádné mapy nebyly nalezeny! about.button = O hře name = Name: noname = Nejdřív si vyber[accent] herní jméno[]. filename = Jméno složky: unlocked = Nový blok odemknut! -unlocked.plural = Nové bloky odemknuty! +completed = [accent]Completed +techtree = Tech Tree +research.list = [LIGHT_GRAY]Research: +research = Research +researched = [LIGHT_GRAY]{0} researched. players = {0} hráčů online players.single = {0} hráč online server.closing = [accent]Zavírám server... server.kicked.kick = Byl jsi vykopnut ze serveru! server.kicked.serverClose = Server je zavřený. -server.kicked.sectorComplete = Sektor Dokončen. -server.kicked.sectorComplete.text = Tvá mise je dokončena.\nServer teď bude pokračovat v dalším sektoru. server.kicked.clientOutdated = Zastaralý klient hry! Aktualizuj si hru! server.kicked.serverOutdated = Zastaralý server! Řekni hostiteli o aktualizaci! server.kicked.banned = Jsi zabanován na tomto serveru. @@ -92,6 +69,7 @@ server.kicked.nameInUse = Někdo se stejným jménem\nje aktuálně na serveru. server.kicked.nameEmpty = Tvé jméno je neplatné. server.kicked.idInUse = Již jsi na tomhle serveru připojen! Připojování se dvěma účty není povoleno. server.kicked.customClient = Tento server nepodporuje vlastní verze hry. Stáhni si oficiální verzi. +server.kicked.gameover = Game over! host.info = [accent]hostitel[] hostuje server na portu [scarlet]6567[]. \nKdokoliv na stejné [LIGHT_GRAY]wifi nebo místní síti[] by měl vidět server ve svém listu serverů.\n\nJestli chcete aby se uživatelé připojovali odkudkoliv pomocí IP, [accent]přesměrování portů[] je nutné.\n\n[LIGHT_GRAY]Poznámka: Jestli někdo má problém s připojením ke své LAN hře, ujistěte se že má Mindustry povolený přístup k místní síti v nastavení Firewallu. join.info = Tady můžeš vložit [accent]IP serveru[] ke kterému se chceš připojit, nebo objevit [accent]Servery Místní sítě[] ke kterým se chceš připojit.\nLAN i Multiplayer jsou podporovány.\n\n[LIGHT_GRAY]Poznámka: Není žádný globální seznam serverů; Pokud se budeš chtít připojit k někomu pomocí IP, budeš jí muset znát od hostitele. hostserver = Hostovat hru @@ -162,7 +140,6 @@ save.rename.text = Nové jméno: selectslot = Vyber uložení. slot = [accent]Slot {0} save.corrupted = [accent]Uložení je poškozené nebo neplatné\nPokud jsi právě aktualizoval svou hru, je to možná změnou formátu pro ukládání a [scarlet]NE[] chyba hry. -sector.corrupted = [accent]Byla nalezena uložená pozice pro tentosektor, ale načtení se nezdařilo.\nNová pozice byla vytvořena. empty = on = On off = Off @@ -172,6 +149,7 @@ save.wave = Vlna {0} save.difficulty = Obtížnost: {0} save.date = Naposledy uloženo: {0} save.playtime = Herní čas: {0} +warning = Warning. confirm = Potvrdit delete = Smazat ok = OK @@ -262,7 +240,17 @@ tutorial = Tutoriál editor = Editor mapeditor = Editor map donate = Darovat - +abandon = Abandon +abandon.text = This zone and all its resources will be lost to the enemy. +locked = Locked +complete = [LIGHT_GRAY]Complete: +resume = Resume Zone:\n[LIGHT_GRAY]{0} +bestwave = [LIGHT_GRAY]Best: {0} +launch = Launch +launch.title = Launch Successful +launch.next = [LIGHT_GRAY]next opportunity at wave {0} +launch.unable = [scarlet]Unable to LAUNCH.[] Enemies. +zone.unlocked = [LIGHT_GRAY]{0} unlocked. connectfail = [crimson]Nepovedlo se připojení k serveru:\n\n[accent]{0} error.unreachable = Server je nedostupný.\nJe adresa napsaná správně? error.invalidaddress = Neplatná adresa. @@ -270,8 +258,20 @@ error.timedout = Čas vypršel!\nUjisti se že hostitel má nastavené přesměr error.mismatch = Chyba Packetu:\nKlient/Verze serveru se neshodují.\nUjisti se že máš nejnovější verzi Mindustry! error.alreadyconnected = Již připojeno. error.mapnotfound = Soubor mapy nebyl nalezen! +error.io = Network I/O error. error.any = neznámá chyba sítě. - +zone.groundZero.name = Ground Zero +zone.craters.name = The Craters +zone.frozenForest.name = Frozen Forest +zone.ruinousShores.name = Ruinous Shores +zone.crags.name = Crags +zone.stainedMountains.name = Stained Mountains +zone.impact0079.name = Impact 0079 +zone.desolateRift.name = Desolate Rift +zone.arcticDesert.name = Arctic Desert +zone.dryWastes.name = Dry Wastes +zone.nuclearComplex.name = Nuclear Production Complex +zone.moltenFault.name = Molten Fault settings.language = Jazyk settings.reset = nastavit výchozí settings.rebind = Přenastavit @@ -282,7 +282,6 @@ settings.graphics = Zobrazení settings.cleardata = Resetovat data hry... settings.clear.confirm = Jsi si jistý že chceš resetovat obsah hry?\nTento krok je nevratný! settings.clearall.confirm = [scarlet]Varování![]\nToto vyresetuje všechna data, včetně uložení, map, odemykatelných a nastavení ovládání.\nJakmile stiskneš 'ok' data se vymažou a hra se automaticky ukončí. -settings.clearsectors = Vymazaní sektorů settings.clearunlocks = Vymazání odemykatelných settings.clearall = Vymazat všechno paused = [accent]< Pauza > @@ -291,7 +290,7 @@ no = Ne info.title = Informace error.title = [crimson]Objevila se chyba error.crashtitle = Objevila se chyba -blocks.unknown=[LIGHT_GRAY]??? +blocks.unknown = [LIGHT_GRAY]??? blocks.blockinfo = Informace o bloku blocks.powercapacity = Kapacita energie blocks.powershot = Energie na výstřel @@ -321,12 +320,15 @@ blocks.liquidoutput = Výstup tekutin blocks.liquidoutputspeed = Rychlost výstupu tekutin blocks.liquiduse = Spotřebuje tekutin blocks.coolant = Chlazení +blocks.liquid = Liquid blocks.coolantuse = Spotřeba chlazení blocks.inputliquidfuel = Palivo-tekutina blocks.liquidfueluse = Spotřeba Paliva-tekutiny blocks.boostitem = Předmět pro zrychlení blocks.boostliquid = Tekutina pro zrychlení blocks.health = Životy +blocks.power = Power +blocks.power.satisfaction = Power Satisfaction blocks.inaccuracy = Nepřesnost/výchylka blocks.shots = Střely blocks.reload = Střely za sekundu @@ -392,6 +394,7 @@ keybind.screenshot.name = Sníměk mapy keybind.move_x.name = Pohyb na X keybind.move_y.name = Pohyb na Y keybind.select.name = Vybrat/Střílet +keybind.pick.name = Pick Block keybind.break.name = Ničit keybind.deselect.name = Odznačit keybind.shoot.name = Střílet @@ -411,8 +414,8 @@ keybind.chat_scroll.name = Chat posun keybind.drop_unit.name = Zahodit jednotku keybind.zoom_minimap.name = Přiblížit minimapu mode.help.title = Popis módů -mode.waves.name = Vlny -mode.waves.description = Normální mód. Limitované zdroje a automaticky přicházející Vlny nepřátel. +mode.survival.name = Survival +mode.survival.description = The normal mode. Limited resources and automatic incoming waves. mode.sandbox.name = Sandbox mode.sandbox.description = Nekonečné zdroje a žádný čas pro vlny nepřátel. mode.freebuild.name = Freebuild @@ -424,18 +427,15 @@ mode.attack.descrption = Žádné vlny, cílem je zničit nepřátelskou základ content.item.name = Předměty content.liquid.name = Tekutiny content.unit.name = jednotky -content.recipe.name = Bloky +content.block.name = Blocks content.mech.name = Mechy -item.stone.name = Kámen -item.stone.description = Běžný, nespracovaný materiál ,Používá se k separaci a přečišťování do jiných materiáů na roztavení na lávu. item.copper.name = Měď item.copper.description = Užitečný strukturální materiál. Používá se rozsáhle v ostatních typech bloků. item.lead.name = Olovo item.lead.description = Základní počáteční materiál. Požívá se rozsáhle v elektronice a v blocích pro transport tekutin. item.coal.name = Uhlí item.coal.description = Běžné a snadno dostupné palivo, pochází z Ostravy. -item.dense-alloy.name = Hustá Slitina -item.dense-alloy.description = Těžká slitina z Olova a Mědi. Používá se v pokročilých transportních blocích a ve vyšší třídě vrtů. +item.graphite.name = Graphite item.titanium.name = Titánium item.titanium.description = Vzácný, velice lehký kov, používá se rozsáhle v trasportu tekutin, vrtech a letounech. item.thorium.name = Thorium @@ -456,6 +456,10 @@ item.blast-compound.name = Výbušná směs item.blast-compound.description = Těkavá směs používaná v bombácha a výbušninách. Dá se spalovat ale jako palivo se nedoporučuje. item.pyratite.name = Pyratite item.pyratite.description = Extrémně vznětlivá substance, používá ve vznětovém střelivu. +item.metaglass.name = Metaglass +item.metaglass.description = A super-tough glass compound. Extensively used for liquid distribution and storage. +item.scrap.name = Scrap +item.scrap.description = Leftover remnants of old structures and units. Contains trace amounts of many different metals. liquid.water.name = Voda liquid.lava.name = Láva liquid.oil.name = Ropa @@ -492,11 +496,10 @@ mech.glaive-ship.weapon = Plamenný Opakovač item.explosiveness = [LIGHT_GRAY]Výbušnost: {0}% item.flammability = [LIGHT_GRAY]Zápalnost: {0}% item.radioactivity = [LIGHT_GRAY]Radioaktivita: {0}% -item.fluxiness = [LIGHT_GRAY]Tok energie: {0}% unit.health = [LIGHT_GRAY]Životy: {0} unit.speed = [LIGHT_GRAY]Rychlost: {0} mech.weapon = [LIGHT_GRAY]Zbraň: {0} -mech.armor = [LIGHT_GRAY]Brnění: {0} +mech.health = [LIGHT_GRAY]Health: {0} mech.itemcapacity = [LIGHT_GRAY]Kapacita předmětů: {0} mech.minespeed = [LIGHT_GRAY]Rychlost těžení: {0} mech.minepower = [LIGHT_GRAY]Síla těžení: {0} @@ -504,9 +507,15 @@ mech.ability = [LIGHT_GRAY]Schopnost: {0} liquid.heatcapacity = [LIGHT_GRAY]Kapacita teploty: {0} liquid.viscosity = [LIGHT_GRAY]Viskozita: {0} liquid.temperature = [LIGHT_GRAY]Teplota: {0} +block.kiln.name = Kiln +block.kiln.description = Smelts sand and lead into metaglass. Requires small amounts of power. +block.graphite-press.name = Graphite Press +block.multi-press.name = Multi-Press block.constructing = {0} [LIGHT_GRAY](Constructing) block.spawn.name = Nepřátelský Spawn -block.core.name = Jádro +block.core-shard.name = Core: Shard +block.core-foundation.name = Core: Foundation +block.core-nucleus.name = Core: Nucleus block.metalfloor.name = Kovová podlaha block.deepwater.name = Hluboká voda block.water.name = Voda @@ -525,8 +534,8 @@ block.blackrock.name = Černý kámen block.icerock.name = Ledový kámen block.copper-wall.name = Měděná zeď block.copper-wall-large.name = Velká měděná zeď -block.dense-alloy-wall.name = Zeď husté slitiny -block.dense-alloy-wall-large.name = Velká zeď husté slitiny +block.titanium-wall.name = Titanium Wall +block.titanium-wall-large.name = Large Titanium Wall block.phase-wall.name = Fázová stěna block.phase-wall-large.name = Velká fázová stěna block.thorium-wall.name = Thoriová stěna @@ -559,17 +568,19 @@ block.separator.name = Separátor block.centrifuge.name = Centrifuga block.power-node.name = Energetický uzel block.power-node-large.name = Velký energetický uzel +block.surge-tower.name = Surge Tower block.battery.name = Baterie block.battery-large.name = Velká baterie block.combustion-generator.name = Spalovací generátor block.turbine-generator.name = Turbínový generátor +block.differential-generator.name = Differential Generator +block.impact-reactor.name = Impact Reactor block.mechanical-drill.name = Mechanický vrt block.pneumatic-drill.name = Pneumatický vrt block.laser-drill.name = Laserový vrt block.water-extractor.name = Vodní extraktor block.cultivator.name = Kultivátor -block.alpha-mech-pad.name = Plošina pro Alfa Mech -block.dart-ship-pad.name = Plošina pro Šipka Mech +block.alpha-dart-mech-pad.name = Alpha-Dart Mech Pad block.delta-mech-pad.name = Plošina pro Delta Mech block.javelin-ship-pad.name = Plošina pro Oštěp Mech block.trident-ship-pad.name = Plošina pro loď Trojzubec @@ -634,7 +645,7 @@ block.rtg-generator.name = RTG Generátor block.spectre.name = Spektr block.meltdown.name = Meltdown block.container.name = Kontejnér -block.core.description = Ta nejdůležitější stavba ve hře. +block.launch-pad.name = Launch Pad team.blue.name = modrá team.red.name = červená team.orange.name = oranžová @@ -648,6 +659,7 @@ unit.phantom.name = Fantom Dron unit.phantom.description = Pokročilý dron. Automaticky těží rudy a opravuje stavby. Podstatně víc efektivní než Spirit dron. unit.dagger.name = Dagger unit.dagger.description = Základní pozemní jednotka. Efektivní ve velkém počtu. +unit.crawler.name = Crawler unit.titan.name = Titán unit.titan.description = Pokročilá, obrněná pozemní jednotka. Útočí jak na pozemní tak vzdušné nepřátelské jednotky. unit.ghoul.name = Ghůl Bombardér @@ -657,7 +669,11 @@ unit.wraith.description = Rychlý, udeř a uteč stíhací letoun. unit.fortress.name = Pevnost unit.fortress.description = Težká, pozemní artilérní jednotka. unit.revenant.name = Revenant -unit.revenant.description = Težká laserová plošina. +unit.eruptor.name = Eruptor +unit.chaos-array.name = Chaos Array +unit.eradicator.name = Eradicator +unit.lich.name = Lich +unit.reaper.name = Reaper tutorial.begin = Tvá mise tady je vyhladit [LIGHT_GRAY] nepřítele[].\n\nZačneš tím že[accent] budeš těžit měd[]. Klikni na měděnou rudu poblíž tvého jádra pro těžbu. tutorial.drill = Manuální zěžba je neefektivní.\n[accent]Vrty []budou těžit automaticky.\npolož jeden na měděnou rudu. tutorial.conveyor = [accent]Dopravníky[] jsou zapotřebí k dopravě materiálu k jádru.\nVytvoř řadu dopravníku od vrtu až k jádru. diff --git a/core/assets/bundles/bundle_de.properties b/core/assets/bundles/bundle_de.properties index cd1e17809c..098e4ebdc1 100644 --- a/core/assets/bundles/bundle_de.properties +++ b/core/assets/bundles/bundle_de.properties @@ -1,5 +1,6 @@ credits.text = Created by [ROYAL]Anuken[] - [SKY]anukendev@gmail.com[]\n\n[GRAY](In case you can't tell, this text is currently unfinished.\nTranslators, don't edit it yet!) credits = Danksagungen +contributors = Translators and Contributors discord = Trete dem Mindustry Discord bei! link.discord.description = Der offizielle Mindustry Discord Chatroom link.github.description = Quellcode des Spiels @@ -9,15 +10,18 @@ link.itch.io.description = itch.io Seite mit Downloads und der Web-Version des S link.google-play.description = Google Play Store Seite link.wiki.description = Offizelles Mindustry Wiki linkfail = Fehler beim Öffnen des Links!\nDie URL wurde in die Zwischenablage kopiert. +screenshot = Screenshot saved to {0} gameover = Der Kern wurde zerstört. gameover.pvp = Das[accent] {0}[] Team ist siegreich! -sector.gameover = Du hast diesen Sektor verloren. Erneuter Einsatz? -sector.retry = Erneut versuchen highscore = [YELLOW] Neuer Highscore! -wave.lasted = Du hast es bis Welle [accent]{0}[] ausgehalten. -level.highscore = High Score: [accent]{0} -level.delete.title = Löschen bestätigen +stat.wave = Waves Defeated:[accent] {0} +stat.enemiesDestroyed = Enemies Destroyed:[accent] {0} +stat.built = Buildings Built:[accent] {0} +stat.destroyed = Buildings Destroyed:[accent] {0} +stat.deconstructed = Buildings Deconstructed:[accent] {0} +stat.delivered = Resources Launched: map.delete = Bist du sicher, dass du die Karte "[accent]{0}[]" löschen möchtest? +level.highscore = High Score: [accent]{0} level.select = Level Auswahl level.mode = Spielmodus: construction.desktop = Um einen Block zu deselektieren oder den Bau abzubrechen, [accent]verwende die Leertaste[]. @@ -27,60 +31,36 @@ deconstruction.title = Abbruchanleitung für Blöcke deconstruction = Du hast soeben den [accent]Abbruchmodus für Blöcke[] aktiviert.\n\nUm mit dem Abriss zu beginnen, tippe einfach auf einen Block in der Nähe deines Schiffs.\nSobald du einige Blöcke ausgewählt hast, drücke zum Bestätigen auf den Haken, und dein Schiff wird mit dem Abriss beginnen.\n\n- [accent]Entferne einen Block[] von deiner Selektion, indem du darauf tippst.\n- [accent]Reiße Blöcke in einem Gebiet ab[], indem du einen leeren Platz gedrückt hältst, und in eine Richtung ziehst.\n- [accent]Breche den Abriss or die Selektion ab[], indem du das X links unten drückst. showagain = Nächstes mal nicht mehr anzeigen coreattack = < Die Basis wird angegriffen! > -unlocks = Freigeschaltet +nearpoint = [[ [scarlet]LEAVE DROP POINT IMMEDIATELY[] ]\nannihilation imminent +outofbounds = [[ OUT OF BOUNDS ]\n[]self-destruct in {0} +database = Core Database savegame = Spiel speichern loadgame = Spiel laden joingame = Spiel beitreten addplayers = Hinzufügen/Entfernen von Spielern customgame = Benutzerdefiniertes Spiel -sectors = Sektoren -sector = Sektor: [LIGHT_GRAY]{0} -sector.time = Zeit: [LIGHT_GRAY]{0} -sector.deploy = Einsatz -sector.abandon = Aufgeben -sector.abandon.confirm = Bist du sicher, dass du den gesamten Fortschritt in diesem Sektor aufgeben willst?\n Diese Aktion kann nicht rückgängig gemacht werden! -sector.resume = Fortsetzen -sector.locked = [scarlet][[Unvollständig] -sector.unexplored = [accent][[Unerforscht] -missions = Missionen:[LIGHT_GRAY] {0} -mission = Mission:[LIGHT_GRAY] {0} -mission.main = Hauptmission:[LIGHT_GRAY] {0} -mission.info = Missionsbeschreibung -mission.complete = Mission erfolgreich! -mission.complete.body = Sektor {0},{1} wurde erobert. -mission.wave = Überlebe [accent]{0}/{1}[] Wellen\nWelle in {2} -mission.wave.enemies = Überlebe[accent] {0}/{1} []Wellen\n{2} Gegner -mission.wave.enemy = Überlebe[accent] {0}/{1} []Wellen\n{2} Gegner -mission.wave.menu = Überlebe[accent] {0} []Wellen -mission.battle = Zerstöre die gegnerische Basis. -mission.resource.menu = Erlange {0} x{1} -mission.resource = Sammele {0}:\n[accent]{1}/{2}[] -mission.block = Erstelle {0} -mission.unit = Erstelle {0} Einheiten -mission.command = Sende {0}-Kommando an Einheiten -mission.linknode = Verbinde Stromknoten -mission.display = [accent]Mission:\n[LIGHT_GRAY]{0} -mission.mech = Wechsle zum [accent] {0}[]-Mech -mission.create = Platziere[accent] {0}[] +newgame = New Game none = close = Schließen quit = Verlassen maps = Karten continue = Weiter -nextmission = Nächste Mission maps.none = [LIGHT_GRAY]Keine Karten gefunden! about.button = Info name = Name: +noname = Pick a[accent] player name[] first. filename = File Name: unlocked = Neuen Block freigeschaltet! -unlocked.plural = Neue Blöcke freigeschaltet! +completed = [accent]Completed +techtree = Tech Tree +research.list = [LIGHT_GRAY]Research: +research = Research +researched = [LIGHT_GRAY]{0} researched. players = {0} Spieler online players.single = {0} Spieler online server.closing = [accent]Schließe den Server... server.kicked.kick = Du wurdest vom Server gekickt! server.kicked.serverClose = Server geschlossen. -server.kicked.sectorComplete = Sektor abgeschlossen. -server.kicked.sectorComplete.text = Deine Mission ist abgeschlossen.\nDer Server wird nun in einen neuen Sektor wechseln. server.kicked.clientOutdated = Veralteter Client! Aktualisiere dein Spiel! server.kicked.serverOutdated = Veralteter Server! Bitte den Host um ein Update! server.kicked.banned = Du wurdest vom Server verbannt. @@ -89,6 +69,7 @@ server.kicked.nameInUse = Es ist bereits ein Spieler \nmit diesem Namen auf dem server.kicked.nameEmpty = Dein Name muss zumindest einen Buchstaben oder eine Zahl enthalten. server.kicked.idInUse = Du bist bereits auf dem Server! Anmeldungen mit zwei Accounts sind nicht gestattet. server.kicked.customClient = Der Server akzeptiert keine Custom Builds von Mindustry. Lade dir die offizielle Version herunter. +server.kicked.gameover = Game over! host.info = Der [accent]host[] Knopf startet einen Server auf den Ports [scarlet]6567[] und [scarlet]6568.[]\nJeder im gleichen [LIGHT_GRAY]W-Lan oder lokalem Netzwerk[] sollte deinen Server in seiner Server Liste sehen können.\n\nWenn du Leuten die Verbindung über IP ermöglichen willst, benötigst du [accent]Port-Forwarding[].\n\n[LIGHT_GRAY]Hinweis: Falls es Probleme mit der Verbindung im Netzwerk gibt, stell sicher, dass Mindustry in deinen Firewall Einstellungen Zugriff auf das lokale Netzwerk hat. join.info = Hier kannst du eine [accent]Server IP[] eingeben um dich zu verbinden oder Server im [accent]lokalem Netzwerk[] entdecken und dich mit ihnen verbinden.\nSowohl Spielen über das lokale Netzwerk als auch Spielen über das Internet werden unterstützt.\n\n[LIGHT_GRAY]Hinweis: Es gibt keine globale Server Liste; Wenn du dich mit jemand per IP verbinden willst musst du den Host nach seiner IP fragen. hostserver = Server hosten @@ -159,7 +140,6 @@ save.rename.text = Neuer Name selectslot = Wähle einen Spielstand slot = [accent] Platz {0} save.corrupted = [accent] Datei beschädigt oder ungültig! -sector.corrupted = [accent]Ein Spielstand für diesen Sektor wurde nicht gefunden.\nEin neuer Spielstand wurde erstellt. empty = on = An off = Aus @@ -169,6 +149,7 @@ save.wave = Welle: {0} save.difficulty = Schwierigkeitsgrad: {0} save.date = Zuletzt gespeichert: {0} save.playtime = Spielzeit: {0} +warning = Warning. confirm = Bestätigen delete = Löschen ok = OK @@ -259,6 +240,17 @@ tutorial = Tutorial editor = Editor mapeditor = Karten Editor donate = Spenden +abandon = Abandon +abandon.text = This zone and all its resources will be lost to the enemy. +locked = Locked +complete = [LIGHT_GRAY]Complete: +resume = Resume Zone:\n[LIGHT_GRAY]{0} +bestwave = [LIGHT_GRAY]Best: {0} +launch = Launch +launch.title = Launch Successful +launch.next = [LIGHT_GRAY]next opportunity at wave {0} +launch.unable = [scarlet]Unable to LAUNCH.[] Enemies. +zone.unlocked = [LIGHT_GRAY]{0} unlocked. connectfail = [crimson] Verbindung zum Server konnte nicht hergestellt werden: [accent]{0} error.unreachable = Server nicht erreichbar. error.invalidaddress = Ungültige Adresse. @@ -266,7 +258,20 @@ error.timedout = Zeitüberschreitung!\nStelle sicher, dass die Portweiterleitung error.mismatch = Paketfehler:\nClient und Server passen möglicherweise nicht zusammen.\nStelle sicher, dass du und der Host jeweils die neueste Version von Mindustry haben! error.alreadyconnected = Bereits verbunden. error.mapnotfound = Map file not found! +error.io = Network I/O error. error.any = Unbekannter Netzwerkfehler. +zone.groundZero.name = Ground Zero +zone.craters.name = The Craters +zone.frozenForest.name = Frozen Forest +zone.ruinousShores.name = Ruinous Shores +zone.crags.name = Crags +zone.stainedMountains.name = Stained Mountains +zone.impact0079.name = Impact 0079 +zone.desolateRift.name = Desolate Rift +zone.arcticDesert.name = Arctic Desert +zone.dryWastes.name = Dry Wastes +zone.nuclearComplex.name = Nuclear Production Complex +zone.moltenFault.name = Molten Fault settings.language = Sprache settings.reset = Auf Standard zurücksetzen settings.rebind = Zuweisen @@ -277,7 +282,6 @@ settings.graphics = Grafiken settings.cleardata = Spieldaten zurücksetzen... settings.clear.confirm = Bist du sicher, dass du die Spieldaten zurücksetzen willst?\n Diese Aktion kann nicht rückgänig gemacht werden! settings.clearall.confirm = [scarlet]Warnung![]\nDas wird jegliche Spieldaten zurücksetzen inklusive Speicherstände, Karten, Freischaltungen und Tastenbelegungen.\n Nachdem du 'OK' drückst wird alles zurückgesetzt und das Spiel schließt sich automatisch. -settings.clearsectors = Sektoren zurücksetzen settings.clearunlocks = Freischaltungen zurücksetzen settings.clearall = Alles zurücksetzen paused = Pausiert @@ -316,12 +320,15 @@ blocks.liquidoutput = Erzeugte Flüssigkeit blocks.liquidoutputspeed = Ausgabegeschwindigkeit blocks.liquiduse = Flüssigkeitsverbrauch blocks.coolant = Kühlmittel +blocks.liquid = Liquid blocks.coolantuse = Kühlmittelverbrauch blocks.inputliquidfuel = Kraftstoff blocks.liquidfueluse = Kraftstoffverbrauch blocks.boostitem = Boost Item blocks.boostliquid = Boost Liquid blocks.health = Lebenspunkte +blocks.power = Power +blocks.power.satisfaction = Power Satisfaction blocks.inaccuracy = Ungenauigkeit blocks.shots = Schüsse blocks.reload = Schüsse/Sekunde @@ -346,6 +353,7 @@ category.items = Materialien category.crafting = Erzeugung category.shooting = Schießen category.optional = Optional Enhancements +setting.indicators.name = Ally Indicators setting.autotarget.name = Auto-Zielauswahl setting.fpscap.name = Max FPS setting.fpscap.none = kein @@ -378,11 +386,15 @@ category.multiplayer.name = Mehrspieler command.attack = Angreifen command.retreat = Rückzug command.patrol = Patrouillieren +keybind.gridMode.name = Block Select +keybind.gridModeShift.name = Category Select keybind.press = Drücke eine Taste... keybind.press.axis = Drücke eine Taste oder bewege eine Achse... +keybind.screenshot.name = Map Screenshot keybind.move_x.name = X-Achse keybind.move_y.name = Y-Achse keybind.select.name = Auswählen/Schießen +keybind.pick.name = Pick Block keybind.break.name = Abreißen keybind.deselect.name = Auswahl aufheben keybind.shoot.name = Schießen @@ -402,29 +414,28 @@ keybind.chat_scroll.name = Chat scrollen keybind.drop_unit.name = Einheit absetzen keybind.zoom_minimap.name = Minimap-Zoom mode.help.title = Beschreibung der Modi -mode.waves.name = Wellen -mode.waves.description = Der normale Modus. Begrenzte Ressourcen und automatische Wellen. +mode.survival.name = Survival +mode.survival.description = The normal mode. Limited resources and automatic incoming waves. mode.sandbox.name = Sandkasten mode.sandbox.description = Unendliche Ressourcen und kein Timer für Wellen. mode.freebuild.name = Freier Bau mode.freebuild.description = Begrenzte Ressourcen und kein Timer für Wellen. mode.pvp.name = PvP mode.pvp.description = Kämpfe gegen andere Spieler local. +mode.attack.name = Attack +mode.attack.descrption = No waves, with the goal to destroy the enemy base. content.item.name = Materialien content.liquid.name = Flüssigkeiten content.unit.name = Einheiten -content.recipe.name = Blöcke +content.block.name = Blocks content.mech.name = Mechs -item.stone.name = Stein -item.stone.description = Ein gängiger Rohstoff ,der für die Zerteilung und Verfeinerung in andere Materialien oder geschmolzen als Lava verwendet wird. item.copper.name = Kupfer item.copper.description = Ein nützliches Material. Wird in allen Arten von Blöcken verwendet. item.lead.name = Blei item.lead.description = Ein grundliegendes Material. Häufig in Elektronik und Flüssigkeits-Transport-Blöcken verwendet. item.coal.name = Kohle item.coal.description = Ein sehr häufiger vorkommender Kraftstoff. -item.dense-alloy.name = Dichte Legierung -item.dense-alloy.description = Eine robuste Legierung aus Blei und Kupfer. Findet Verwendung in fortgeschrittenen Transport-Blöcken und höherwertigen Bohrern. +item.graphite.name = Graphite item.titanium.name = Titan item.titanium.description = Ein seltenes, sehr leichtes Metall. Häufig in Flüssigkeits-Transport-Blöcken, Abbauanlagen und Flugzeugen verwendet. item.thorium.name = Uran @@ -445,6 +456,10 @@ item.blast-compound.name = Explosive Mischung item.blast-compound.description = Eine flüchtige Mischung, die in Bomben und Sprengstoffen Verwendung findet. Es besteht die Möglichkeit, es als Treibstoff zu verwenden, aber dies ist nicht empfehlenswert. item.pyratite.name = Pyratit item.pyratite.description = Eine extrem leicht entflammbare Substanz. Findet Verwendeung in Brandwaffen. +item.metaglass.name = Metaglass +item.metaglass.description = A super-tough glass compound. Extensively used for liquid distribution and storage. +item.scrap.name = Scrap +item.scrap.description = Leftover remnants of old structures and units. Contains trace amounts of many different metals. liquid.water.name = Wasser liquid.lava.name = Lava liquid.oil.name = Öl @@ -481,11 +496,10 @@ mech.glaive-ship.weapon = Flammen-Mehrlader item.explosiveness = [LIGHT_GRAY]Explosivität: {0} item.flammability = [LIGHT_GRAY]Entflammbarkeit: {0} item.radioactivity = [LIGHT_GRAY]Radioaktivität: {0} -item.fluxiness = [LIGHT_GRAY]Strömungskraft: {0} unit.health = [LIGHT_GRAY]Lebenskraft: {0} unit.speed = [LIGHT_GRAY]Geschwindigkeit: {0} mech.weapon = [LIGHT_GRAY]Waffe: {0} -mech.armor = [LIGHT_GRAY]Rüstung: {0} +mech.health = [LIGHT_GRAY]Health: {0} mech.itemcapacity = [LIGHT_GRAY]Materialkapazität: {0} mech.minespeed = [LIGHT_GRAY]Erzabbaugeschwindigkeit: {0} mech.minepower = [LIGHT_GRAY]Erzabbaukraft: {0} @@ -493,9 +507,15 @@ mech.ability = [LIGHT_GRAY]Fähigkeit: {0} liquid.heatcapacity = [LIGHT_GRAY]Wärmekapazität: {0} liquid.viscosity = [LIGHT_GRAY]Viskosität: {0} liquid.temperature = [LIGHT_GRAY]Temperatur: {0} +block.kiln.name = Kiln +block.kiln.description = Smelts sand and lead into metaglass. Requires small amounts of power. +block.graphite-press.name = Graphite Press +block.multi-press.name = Multi-Press block.constructing = {0}\n[LIGHT_GRAY](Constructing) block.spawn.name = Gegnerischer Startpunkt -block.core.name = Basis +block.core-shard.name = Core: Shard +block.core-foundation.name = Core: Foundation +block.core-nucleus.name = Core: Nucleus block.metalfloor.name = Metallboden block.deepwater.name = Tiefes Wasser block.water.name = Wasser @@ -514,8 +534,8 @@ block.blackrock.name = Schwarzer Fels block.icerock.name = Eisfels block.copper-wall.name = Kupfermauer block.copper-wall-large.name = Große Kupfermauer -block.dense-alloy-wall.name = Dichte Legierungsmauer -block.dense-alloy-wall-large.name = Große dichte Legierungsmauer +block.titanium-wall.name = Titanium Wall +block.titanium-wall-large.name = Large Titanium Wall block.phase-wall.name = Phasenmauer block.phase-wall-large.name = Große Phasenmauer block.thorium-wall.name = Thorium-Mauer @@ -548,17 +568,19 @@ block.separator.name = Separierer block.centrifuge.name = Zentrifuge block.power-node.name = Stromknoten block.power-node-large.name = Großer Stromknoten +block.surge-tower.name = Surge Tower block.battery.name = Batterie block.battery-large.name = Große Batterie block.combustion-generator.name = Verbrennungsgenerator block.turbine-generator.name = Turbinengenerator +block.differential-generator.name = Differential Generator +block.impact-reactor.name = Impact Reactor block.mechanical-drill.name = Mechanischer Bohrer block.pneumatic-drill.name = Pneumatischer Bohrer block.laser-drill.name = Laser-Bohrer block.water-extractor.name = Wasser-Extraktor block.cultivator.name = Kultivierer -block.alpha-mech-pad.name = Alpha Mech Pad -block.dart-ship-pad.name = Dart Ship Pad +block.alpha-dart-mech-pad.name = Alpha-Dart 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 @@ -623,7 +645,7 @@ block.rtg-generator.name = RTG Generator block.spectre.name = Spectre block.meltdown.name = Meltdown block.container.name = Container -block.core.description = Das wichtigste Gebäude im Spiel +block.launch-pad.name = Launch Pad team.blue.name = Blau team.red.name = Rot team.orange.name = Orange @@ -637,6 +659,7 @@ unit.phantom.name = Phantom Drohne unit.phantom.description = Eine fortgeschrittene Drohne. Baut automatisch Erz ab, sammelt Materialien und repariert Blöcke. Deutlich effizienter als die Drohne. unit.dagger.name = Dagger unit.dagger.description = Eine Standard-Bodeneinheit. Nützlich in Schwärmen. +unit.crawler.name = Crawler unit.titan.name = Titan unit.titan.description = Eine fortgeschrittene gepanzerte Bodeneinheit. Greift sowohl Boden- als auch Luftziele an. unit.ghoul.name = Ghoul Bomber @@ -646,7 +669,11 @@ unit.wraith.description = Eine schneller Abfangjäger. unit.fortress.name = Fortress unit.fortress.description = Eine schwere Artillerie-Bodeneinheit. unit.revenant.name = Revenant -unit.revenant.description = Eine schwere Laser-Platform. +unit.eruptor.name = Eruptor +unit.chaos-array.name = Chaos Array +unit.eradicator.name = Eradicator +unit.lich.name = Lich +unit.reaper.name = Reaper tutorial.begin = Deine Mission ist es den [LIGHT_GRAY]Gegner[] auszurotten.\n\n Beginne damit [accent] Kupfer abzubauen[]. Beginne in dem du auf ein Kupfer Vorkommen nahe deines Kerns klickst. tutorial.drill = Manuelles Abbauen von Ressourcen ist ineffizient.\n[accent]Bohrer[] können automatisch abbauen.\n Platziere einen auf einem Kupfer Vorkommen. tutorial.conveyor = [accent]Transportbänder[] werden dazu benutzt Materialien zum Kern zu transportieren.\n Erstelle eine Reihe von Transportbändern zum Kern. diff --git a/core/assets/bundles/bundle_es.properties b/core/assets/bundles/bundle_es.properties index c9886889eb..f0f25c6bac 100644 --- a/core/assets/bundles/bundle_es.properties +++ b/core/assets/bundles/bundle_es.properties @@ -1,5 +1,6 @@ credits.text = Created by [ROYAL]Anuken[] - [SKY]anukendev@gmail.com[]\n\n[GRAY](In case you can't tell, this text is currently unfinished.\nTranslators, don't edit it yet!) credits = Créditos +contributors = Translators and Contributors discord = ¡Únete al Discord de Mindustry! link.discord.description = La sala oficial del Discord de Mindustry link.github.description = Código fuente del juego @@ -9,15 +10,18 @@ link.itch.io.description = itch.io es la página donde podes descargar las versi link.google-play.description = Ficha en la Google Play Store link.wiki.description = Wiki oficial de Mindustry linkfail = ¡Error al abrir el enlace!\nLa URL ha sido copiada a su portapapeles. +screenshot = Screenshot saved to {0} gameover = Tu núcleo ha sido destruido. gameover.pvp = ¡El equipo[accent] {0}[] ha ganado! -sector.gameover = Este sector ha sido perdido. ¿Re-desplegar? -sector.retry = Reintentar highscore = [accent]¡Nueva mejor puntuación! -wave.lasted = Duraste hasta la ronda [accent]{0}[]. -level.highscore = Puntuación más alta: [accent]{0} -level.delete.title = Confirmar Eliminación +stat.wave = Waves Defeated:[accent] {0} +stat.enemiesDestroyed = Enemies Destroyed:[accent] {0} +stat.built = Buildings Built:[accent] {0} +stat.destroyed = Buildings Destroyed:[accent] {0} +stat.deconstructed = Buildings Deconstructed:[accent] {0} +stat.delivered = Resources Launched: map.delete = ¿Estás seguro que quieres borrar el mapa "[accent]{0}[]"? +level.highscore = Puntuación más alta: [accent]{0} level.select = Selección de nivel level.mode = Modo de juego: construction.desktop = Los controles de la versión de escritorio han cambiado.\nPara deseleccionar un bloque o dejar de construir, [accent]usa la space tab[]. @@ -27,60 +31,36 @@ deconstruction.title = Guía de Deconstrucción de Bloques deconstruction = Acaba de seleccionar el [accent]modo de deconstrucción de blocks[].\n\nPara empezar a destruir, simplemente presione en un bloque cercano a su nave.\nCuando haya terminado de seleccionar algunos bloques, presiona la casilla para confirmar, y su nave empezara a de-construirlos.\n\n- [accent]Remueve bloques[] de tu selección presionando en ellos.\n- [accent]Remueve bloques en un area[] presionando y manteniendo en un espacio vacío, y arrastrando hacia cualquier dirección.\n- [accent]Cancela la deconstrucción o selección[] presionando la X abajo a la izquierda. showagain = No mostrar otra vez en la próxima sesión coreattack = < ¡El núcleo está bajo ataque! > -unlocks = Desbloqueos +nearpoint = [[ [scarlet]LEAVE DROP POINT IMMEDIATELY[] ]\nannihilation imminent +outofbounds = [[ OUT OF BOUNDS ]\n[]self-destruct in {0} +database = Core Database savegame = Guardar Partida loadgame = Cargar Partida joingame = Unirse a la Partida addplayers = Agregar/Quitar Jugadores customgame = Partida personalizada -sectors = Sectores -sector = Sector: [LIGHT_GRAY]{0} -sector.time = Tiempo: [LIGHT_GRAY]{0} -sector.deploy = Desplegar -sector.abandon = Abandonar -sector.abandon.confirm = ¿Realmente quieres abandonar todo el progreso hecho en este sector?\n¡Esto no se puede deshacer! -sector.resume = Continuar -sector.locked = [scarlet][[Incompleto] -sector.unexplored = [accent][[No explorado] -missions = Misiones:[LIGHT_GRAY] {0} -mission = Misión:[LIGHT_GRAY] {0} -mission.main = Misión Principal:[LIGHT_GRAY] {0} -mission.info = Información de la Misión -mission.complete = ¡Misión completada! -mission.complete.body = El Sector {0},{1} ha sido conquistado. -mission.wave = Sobrevive [accent]{0}/{1}[] hordas\nHordas en {2} -mission.wave.enemies = Sobrevive[accent] {0}/{1} []hordas\n{2} Enemigas -mission.wave.enemy = Sobrevive[accent] {0}/{1} []hordas\n{2} Enemigas -mission.wave.menu = Sobrevive[accent] {0} []hordas -mission.battle = Destruye la base enemiga. -mission.resource.menu = Obtener {0} x{1} -mission.resource = Obtén {0} x{1} -mission.block = Crear {0} -mission.unit = Crear {0} -mission.command = Envía Comando {0} a las unidades -mission.linknode = Conecta nodo de energía -mission.display = [accent]Misión:\n[LIGHT_GRAY]{0} -mission.mech = Cambiar a mecanoide[accent] {0}[] -mission.create = Crear[accent] {0}[] +newgame = New Game none = close = Cerrar quit = Salir maps = Mapas continue = Continuar -nextmission = Próxima Misión maps.none = [LIGHT_GRAY]¡No se han encontrado mapas! about.button = Acerca de name = Nombre: +noname = Pick a[accent] player name[] first. filename = Nombre del archivo: unlocked = ¡Nuevo Bloque Desbloqueado! -unlocked.plural = ¡Nuevos Bloques Desbloqueados! +completed = [accent]Completed +techtree = Tech Tree +research.list = [LIGHT_GRAY]Research: +research = Research +researched = [LIGHT_GRAY]{0} researched. players = {0} jugadores online players.single = {0} jugador online server.closing = [accent]Cerrando servidor... server.kicked.kick = ¡Has sido expulsado del servidor! server.kicked.serverClose = El servidor ha cerrado. -server.kicked.sectorComplete = Sector completado. -server.kicked.sectorComplete.text = Tu misión ha sido completada.\nEl servidor ahora continuará con el próximo sector. server.kicked.clientOutdated = ¡Cliente desactualizado! ¡Actualiza tu juego! server.kicked.serverOutdated = ¡Servidor desactualizado! ¡Pídele al anfitrión que lo actualice! server.kicked.banned = Has sido baneado del servidor. @@ -89,6 +69,7 @@ server.kicked.nameInUse = Ya hay alguien con ese\nnombre en el servidor. server.kicked.nameEmpty = Tu nombre debe por lo menos contener un carácter o número. server.kicked.idInUse = ¡Ya estás en el servidor! Conectarse con dos cuentas no está permitido. server.kicked.customClient = Este servidor no soporta versiones personalizadas. Descarga una versión oficial. +server.kicked.gameover = Game over! host.info = El botón [accent]host[] hostea un servidor en el puerto [scarlet]6567[]. \nCualquier persona en la misma [LIGHT_GRAY]wifi o red local[] debería poder ver tu servidor en la lista de servidores.\n\nSi quieres que cualquier persona se pueda conectar de cualquier lugar por IP, la [accent]asignación de puertos[] es requerida.\n\n[LIGHT_GRAY]Nota: Si alguien experimenta problemas conectándose a tu partida LAN, asegúrate de permitir a Mindustry acceso a tu red local mediante la configuración de tu firewall. join.info = Aquí, puedes escribir la [accent]IP de un server[] para conectarte, o descubrir servidores de [accent]red local[] para conectarte.\nLAN y WAN es soportado para jugar en multijugador.\n\n[LIGHT_GRAY]Nota: No hay una lista automática global de servidores; si quieres conectarte por IP, tendrás que preguntarle al anfitrión por la IP. hostserver = Hostear Servidor @@ -159,7 +140,6 @@ save.rename.text = Nuevo nombre: selectslot = Selecciona un Punto de Guardado. slot = [accent]Casilla {0} save.corrupted = [accent]¡El punto de guardado está corrupto o es inválido!\nSi acabas de actualizar el juego, esto debe ser probablemente un cambio en el formato de guardado y[scarlet] no[] un error. -sector.corrupted = [accent]El punto de guardado de este sector fue encontrado, pero su carga ha fallado.\nUn nuevo punto ha sido creado. empty = on = Encendido off = Apagado @@ -169,6 +149,7 @@ save.wave = Horda {0} save.difficulty = Dificultad: {0} save.date = Última vez guardado: {0} save.playtime = Tiempo de juego: {0} +warning = Warning. confirm = Confirmar delete = Borrar ok = OK @@ -259,6 +240,17 @@ tutorial = Tutorial editor = Editor mapeditor = Editor de Mapa donate = Donar +abandon = Abandon +abandon.text = This zone and all its resources will be lost to the enemy. +locked = Locked +complete = [LIGHT_GRAY]Complete: +resume = Resume Zone:\n[LIGHT_GRAY]{0} +bestwave = [LIGHT_GRAY]Best: {0} +launch = Launch +launch.title = Launch Successful +launch.next = [LIGHT_GRAY]next opportunity at wave {0} +launch.unable = [scarlet]Unable to LAUNCH.[] Enemies. +zone.unlocked = [LIGHT_GRAY]{0} unlocked. connectfail = [crimson]Ha fallado la conexión con el servidor: [accent]{0} error.unreachable = Servidor inaccesible. error.invalidaddress = Dirección inválida. @@ -266,7 +258,20 @@ error.timedout = ¡Se acabó el tiempo!\n¡Asegúrate que el host ha hecho el po error.mismatch = Error de paquete:\nposible versión no válida del servidor/cliente.\nAsegúrate de que tú y el host tenéis la última versión de Mindustry. error.alreadyconnected = Ya estás conectado. error.mapnotfound = ¡Archivo de mapa no encontrado! +error.io = Network I/O error. error.any = Error de red desconocido. +zone.groundZero.name = Ground Zero +zone.craters.name = The Craters +zone.frozenForest.name = Frozen Forest +zone.ruinousShores.name = Ruinous Shores +zone.crags.name = Crags +zone.stainedMountains.name = Stained Mountains +zone.impact0079.name = Impact 0079 +zone.desolateRift.name = Desolate Rift +zone.arcticDesert.name = Arctic Desert +zone.dryWastes.name = Dry Wastes +zone.nuclearComplex.name = Nuclear Production Complex +zone.moltenFault.name = Molten Fault settings.language = Lenguaje settings.reset = Reiniciar por los de defecto settings.rebind = Reasignar @@ -277,7 +282,6 @@ settings.graphics = Gráficos settings.cleardata = Limpiar Datos del Juego... settings.clear.confirm = ¿Estas seguro de querer limpiar estos datos?\n¡Esta acción no puede deshacerse! settings.clearall.confirm = [scarlet]ADVERTENCIA![]\nEsto va a eliminar todos tus datos, incluyendo guardados, mapas, desbloqueos y keybinds.\nUna vez presiones 'ok', el juego va a borrrar todos tus datos y saldrá del juego automáticamente. -settings.clearsectors = Eliminar Sectores settings.clearunlocks = Eliminar Desbloqueos settings.clearall = Eliminar Todo paused = Pausado @@ -316,12 +320,15 @@ blocks.liquidoutput = Líquido de Salida blocks.liquidoutputspeed = Velocidad de Salida del Líquido blocks.liquiduse = Uso de Líquido blocks.coolant = Refrigerante +blocks.liquid = Liquid blocks.coolantuse = Uso del Refrigerante blocks.inputliquidfuel = Combustible Líquido blocks.liquidfueluse = Uso del Combustible Líquido blocks.boostitem = Boost Item blocks.boostliquid = Boost Liquid blocks.health = Vida +blocks.power = Power +blocks.power.satisfaction = Power Satisfaction blocks.inaccuracy = Imprecisión blocks.shots = Disparos blocks.reload = Recarga @@ -346,6 +353,7 @@ category.items = Objetos category.crafting = Fabricación category.shooting = Disparo category.optional = Mejoras Opcionales +setting.indicators.name = Ally Indicators setting.autotarget.name = Auto apuntado setting.fpscap.name = Máx FPS setting.fpscap.none = Nada @@ -378,11 +386,15 @@ category.multiplayer.name = Multijugador command.attack = Atacar command.retreat = Retirarse command.patrol = Patrullar +keybind.gridMode.name = Block Select +keybind.gridModeShift.name = Category Select keybind.press = Presiona una tecla... keybind.press.axis = Pulsa un eje o botón... +keybind.screenshot.name = Map Screenshot keybind.move_x.name = Mover x keybind.move_y.name = Mover y keybind.select.name = Seleccionar +keybind.pick.name = Pick Block keybind.break.name = Romper keybind.deselect.name = Deseleccionar keybind.shoot.name = Disparar @@ -402,29 +414,28 @@ keybind.chat_scroll.name = Chat scroll keybind.drop_unit.name = drop unit keybind.zoom_minimap.name = Zoom minimapa mode.help.title = Descripción de modos -mode.waves.name = hordas -mode.waves.description = El modo normal. con recursos limitados y entrada de hordas automática. +mode.survival.name = Survival +mode.survival.description = The normal mode. Limited resources and automatic incoming waves. mode.sandbox.name = sandbox mode.sandbox.description = Recursos ilimitados y sin temporizador para las hordas. mode.freebuild.name = construcción libre mode.freebuild.description = recursos limitados y no hay temporizador para las hordas. mode.pvp.name = PvP mode.pvp.description = Pelea contra otros jugadores localmente. +mode.attack.name = Attack +mode.attack.descrption = No waves, with the goal to destroy the enemy base. content.item.name = Objetos content.liquid.name = Líquidos content.unit.name = Unidades -content.recipe.name = Bloques +content.block.name = Blocks content.mech.name = Mecanoides -item.stone.name = Piedra -item.stone.description = Un material muy común. Usado para separar y para refinarse a otros objetos, y también derretir en lava. item.copper.name = Cobre item.copper.description = Un útil material estructural. Usado extensivamente en todo tipo de bloques. item.lead.name = Plomo item.lead.description = Un material básico. Usado extensivamente en electrónicos y bloques de transferencia de líquidos. item.coal.name = Carbón item.coal.description = Un combustible común y preparado para ser quemado. -item.dense-alloy.name = Aleación Densa -item.dense-alloy.description = Una dura aleación fabricada con plomo y cobre. Usado en bloques de transporte avanzados y taladros de alto nivel. +item.graphite.name = Graphite item.titanium.name = Titanio item.titanium.description = Un metal raro super ligero usado extensivamente en transportación de liquidos, taladros y aeronaves. item.thorium.name = Torio @@ -445,6 +456,10 @@ item.blast-compound.name = Compuesto Explosivo item.blast-compound.description = Un compuesto volatil usado en bombas y explosivos. Aunque se puede quemar como combustible, esto no es recomendable. item.pyratite.name = Pirotita item.pyratite.description = Una sustancia extremadamente inflamable usada en armas incendiarias. +item.metaglass.name = Metaglass +item.metaglass.description = A super-tough glass compound. Extensively used for liquid distribution and storage. +item.scrap.name = Scrap +item.scrap.description = Leftover remnants of old structures and units. Contains trace amounts of many different metals. liquid.water.name = Agua liquid.lava.name = Lava liquid.oil.name = Petróleo @@ -481,11 +496,10 @@ mech.glaive-ship.weapon = Flame Repeater item.explosiveness = [LIGHT_GRAY]Explosividad: {0} item.flammability = [LIGHT_GRAY]Inflamabilidad: {0} item.radioactivity = [LIGHT_GRAY]Radioactividad: {0} -item.fluxiness = [LIGHT_GRAY]Poder como Fundente: {0} unit.health = [LIGHT_GRAY]Vida: {0} unit.speed = [LIGHT_GRAY]Velocidad: {0} mech.weapon = [LIGHT_GRAY]Arma: {0} -mech.armor = [LIGHT_GRAY]Armadura: {0} +mech.health = [LIGHT_GRAY]Health: {0} mech.itemcapacity = [LIGHT_GRAY]Capacidad de objetos: {0} mech.minespeed = [LIGHT_GRAY]Velocidad de minado: {0} mech.minepower = [LIGHT_GRAY]Potencia de minado: {0} @@ -493,9 +507,15 @@ mech.ability = [LIGHT_GRAY]Hablidad: {0} liquid.heatcapacity = [LIGHT_GRAY]Capacidad Térmica: {0} liquid.viscosity = [LIGHT_GRAY]Viscosidad: {0} liquid.temperature = [LIGHT_GRAY]Temperatura: {0} +block.kiln.name = Kiln +block.kiln.description = Smelts sand and lead into metaglass. Requires small amounts of power. +block.graphite-press.name = Graphite Press +block.multi-press.name = Multi-Press block.constructing = {0}\n[LIGHT_GRAY](Construyendo) block.spawn.name = Punto de generación -block.core.name = Núcleo +block.core-shard.name = Core: Shard +block.core-foundation.name = Core: Foundation +block.core-nucleus.name = Core: Nucleus block.metalfloor.name = Suelo de Metal block.deepwater.name = Aguas profundas block.water.name = Agua @@ -514,8 +534,8 @@ block.blackrock.name = Roca negra block.icerock.name = Roca de hielo block.copper-wall.name = Muro de cobre block.copper-wall-large.name = Muro de cobre grande -block.dense-alloy-wall.name = Muro de aleación densa -block.dense-alloy-wall-large.name = Muro de aleación densa grande +block.titanium-wall.name = Titanium Wall +block.titanium-wall-large.name = Large Titanium Wall block.phase-wall.name = Muro de Fase grande block.phase-wall-large.name = Muro de Fase grande block.thorium-wall.name = Pared de Torio @@ -548,17 +568,19 @@ block.separator.name = Separador block.centrifuge.name = Centrifugadora block.power-node.name = Nodo de Energía block.power-node-large.name = Nodo de Energía Grande +block.surge-tower.name = Surge Tower block.battery.name = Batería block.battery-large.name = Batería Grande block.combustion-generator.name = Generador de Combustión block.turbine-generator.name = Turbina +block.differential-generator.name = Differential Generator +block.impact-reactor.name = Impact Reactor block.mechanical-drill.name = Taladro mecánico block.pneumatic-drill.name = Taladro neumático block.laser-drill.name = Taladro Laser block.water-extractor.name = Extractor de Agua block.cultivator.name = Cultivador -block.alpha-mech-pad.name = Pad de mecanoide Alpha -block.dart-ship-pad.name = Pad de nave de dardos +block.alpha-dart-mech-pad.name = Alpha-Dart Mech Pad block.delta-mech-pad.name = Pad de mecanoide Delta block.javelin-ship-pad.name = Pad de nave Jabalina block.trident-ship-pad.name = Pad de nave Tridente @@ -623,7 +645,7 @@ block.rtg-generator.name = Generador RTG block.spectre.name = Espectro block.meltdown.name = Meltdown block.container.name = Contenedor -block.core.description = The most important building in the game. +block.launch-pad.name = Launch Pad team.blue.name = Azul team.red.name = Rojo team.orange.name = Naranja @@ -637,6 +659,7 @@ unit.phantom.name = Dron Fantasmal unit.phantom.description = Un dron avanzado. Mina automáticamente minerales, recoge objetos y repra bloques. Bastante más efectivo que un dron normal. unit.dagger.name = Daga unit.dagger.description = Una unidad de terreno. Útil con enjambres. +unit.crawler.name = Crawler unit.titan.name = Titán unit.titan.description = Una unidad blindada de terreno, avanzada. Ataca blancos de aire y de terreno. unit.ghoul.name = Ghoul Bomber @@ -646,7 +669,11 @@ unit.wraith.description = Una unidad interceptora rápida. unit.fortress.name = Fortress unit.fortress.description = Una unidad terrestre pesada de artillería. unit.revenant.name = Revenant -unit.revenant.description = Una plataforma láser pesada. +unit.eruptor.name = Eruptor +unit.chaos-array.name = Chaos Array +unit.eradicator.name = Eradicator +unit.lich.name = Lich +unit.reaper.name = Reaper tutorial.begin = Tu objetivo aquí es erradicar el[LIGHT_GRAY] enemy[].\n\nComienza[accent]minando copper[]. Toca una veta de cobre cerca de tu núcleo para hacer esto. tutorial.drill = Minar manualmente es ineficiente.\nLos [accent]taladros pueden minar automáticamente.\nColoca uno en una veta de cobre. tutorial.conveyor = Los [accent]Conveyors[] se usan para transportar objetos al núcleo.\nConstruye una línea de transportadores del taladro al núcleo. diff --git a/core/assets/bundles/bundle_fr.properties b/core/assets/bundles/bundle_fr.properties index e92454f302..436c82e65b 100644 --- a/core/assets/bundles/bundle_fr.properties +++ b/core/assets/bundles/bundle_fr.properties @@ -1,5 +1,6 @@ credits.text = Created by [ROYAL]Anuken[] - [SKY]anukendev@gmail.com[]\n\n[GRAY](In case you can't tell, this text is currently unfinished.\nTranslators, don't edit it yet!) credits = Crédits +contributors = Translators and Contributors discord = Rejoignez le discord de Mindustry link.discord.description = Le discord officiel de mindustry link.github.description = Code source du jeu @@ -9,15 +10,18 @@ link.itch.io.description = Page itch.io avec le lien du téléchargement pour PC link.google-play.description = Listing par le Google Play Store link.wiki.description = Wiki officiel de mindustry . linkfail = Erreur lors de l'ouverture du lien !\nL'URL a été copié avec succès. +screenshot = Screenshot saved to {0} gameover = Partie terminée. gameover.pvp = L'équipe [accent] {0}[] a gagnée ! -sector.gameover = Ce secteur a été perdu. Réessayer? -sector.retry = Réessayer highscore = [YELLOW]Nouveau meilleur score! -wave.lasted = Vous avez survécu jusqu'à la vague [accent]{0}[]. -level.highscore = Meilleur score: [accent]{0} -level.delete.title = Confirmer +stat.wave = Waves Defeated:[accent] {0} +stat.enemiesDestroyed = Enemies Destroyed:[accent] {0} +stat.built = Buildings Built:[accent] {0} +stat.destroyed = Buildings Destroyed:[accent] {0} +stat.deconstructed = Buildings Deconstructed:[accent] {0} +stat.delivered = Resources Launched: map.delete = Êtes-vous sûr de supprimer cette carte"[accent]{0}[]"? +level.highscore = Meilleur score: [accent]{0} level.select = Sélection de niveau level.mode = Mode de jeu : construction.desktop = Pour désélectionner un bloc ou arrêter de construire, appuyer sur [accent]espace[]. @@ -27,60 +31,36 @@ deconstruction.title = Guide de destruction de blocs deconstruction = Vous venez de sélectionner le mode [accent]destruction de blocs[].\n\nPour commencez à détruire des blocs, appuyez simplement sur un bloc proche de votre vaisseau.\nUne fois que vous avez sélectionné quelques blocs, Appuyez sur le bouton valider pour confirmer, et votre vaisseau commencera à détruire.\n\n- [accent]Enlevez des blocs[] de votre sélection en appuyant dessus.\n- [accent]Déplacez la sélection[] en restant appuyé puis en déplaçant n'importe quel bloc de la sélection.\n- [accent]Placez les blocs en ligne[] En restant appuyé sur un espace vide, puis en étirant dans une direction.\n- [accent]Annulez la construction ou la sélection[] en appuyant sur le X en bas à droite. showagain = Ne pas montrer la prochaine fois coreattack = [scarlet] -unlocks = Débloqué +nearpoint = [[ [scarlet]LEAVE DROP POINT IMMEDIATELY[] ]\nannihilation imminent +outofbounds = [[ OUT OF BOUNDS ]\n[]self-destruct in {0} +database = Core Database savegame = Sauvegarder la partie loadgame = Charger la partie joingame = Rejoindre une partie addplayers = Ajouter/Enlever des joueurs customgame = Partie personnalisée -sectors = Secteurs -sector = Secteur: [LIGHT_GRAY]{0} -sector.time = Temps: [LIGHT_GRAY]{0} -sector.deploy = Se déployer -sector.abandon = Abandonner -sector.abandon.confirm = Êtes-vous sûr d'abandonner ce secteur ?\nCe choix ne peut être annulé! -sector.resume = Reprendre -sector.locked = [scarlet][[Incomplet] -sector.unexplored = [accent][[Inexploré] -missions = Missions:[LIGHT_GRAY] {0} -mission = Mission:[LIGHT_GRAY] {0} -mission.main = Main Mission:[LIGHT_GRAY] {0} -mission.info = Infos sur la Mission -mission.complete = Mission terminée! -mission.complete.body = Le secteur {0},{1} a été conquis. -mission.wave = Survivez à[accent] {0}/{1} []vague\nLa vague commence dans {2} -mission.wave.enemies = Survivez à[accent] {0}/{1} []vagues\n{2} ennemis -mission.wave.enemy = Survivez à[accent] {0}/{1} []vagues\n{2} ennemi -mission.wave.menu = Survivez à[accent] {0} []vagues -mission.battle = Détruisez la base ennemie -mission.resource.menu = Obtenez {0} x{1} -mission.resource = Obtenez {0}:\n[accent]{1}/{2}[] -mission.block = Créez {0} -mission.unit = Créez {0} unités -mission.command = Envoyer une commande à {0} unités -mission.linknode = Reliez un transmetteur -mission.display = [accent]Mission:\n[LIGHT_GRAY]{0} -mission.mech = Équiper ce mécha[accent] {0}[] -mission.create = Créez[accent] {0}[] +newgame = New Game none = close = Fermer quit = Quitter maps = Cartes continue = Continuer -nextmission = Prochaine mission maps.none = [LIGHT_GRAY]Aucune carte trouvée! about.button = À propos name = Nom: +noname = Pick a[accent] player name[] first. filename = Nom du fichier: unlocked = Nouveau bloc débloqué! -unlocked.plural = Nouveaux blocs débloqués! +completed = [accent]Completed +techtree = Tech Tree +research.list = [LIGHT_GRAY]Research: +research = Research +researched = [LIGHT_GRAY]{0} researched. players = {0} joueurs en ligne players.single = {0} joueur en ligne server.closing = [accent]Fermeture du serveur... server.kicked.kick = Vous avez été expulsé du serveur! server.kicked.serverClose = Serveur fermé. -server.kicked.sectorComplete = Secteur terminé. -server.kicked.sectorComplete.text = Votre mission est complète .\nLe serveur va maintenant aller au prochain secteur . server.kicked.clientOutdated = Client dépassé! Mettez à jour votre jeu! server.kicked.serverOutdated = Serveur dépassé! Demandez à l'hôte de le mettre à jour! server.kicked.banned = Vous avez été banni sur ce serveur. @@ -89,6 +69,7 @@ server.kicked.nameInUse = Il y a déjà quelqu'un avec ce nom\nsur ce serveur. server.kicked.nameEmpty = Votre nom doit contenir au moins une lettre ou un chiffre. server.kicked.idInUse = Vous êtes déjà sur ce serveur ! Se connecter avec deux comptes n'est pas permis ! server.kicked.customClient = Ce serveur ne supporte pas les versions personnalisées (Custom builds). Téléchargez une version officielle. +server.kicked.gameover = Game over! host.info = Le bouton [accent]Héberger[] héberge un serveur sur le port [scarlet]6567[]. \nN'importe qui sur le même [LIGHT_GRAY]wifi ou réseau local []devrait voir votre serveur sur leur liste des serveurs.\n\nSi vous voulez que les gens puissent s'y connecter de partout à l'aide de votre IP, [accent]le transfert de port (port forwarding)[] est demandé.\n\n[LIGHT_GRAY]Note: Si quelqu'un a des problèmes de connexion à votre partie LAN, vérifiez que vous avez autorisé l'accès à Mindustry sur votre réseau local dans les paramètres de votre pare-feu. join.info = Ici vous pouvez entrez [accent]l'IP d'un serveur []pour s'y connecter, ou découvrir un serveur en [accent]réseau local[].\nLe multijoueur en LAN ainsi qu'en WAN est supporté.\n\n[LIGHT_GRAY]Note: Il n'y a pas de liste de serveurs globaux automatiques; Si vous voulez vous connectez à quelqu'un par IP, il faudra d'abord demander à l'hébergeur leur IP. hostserver = Héberger une partie @@ -159,7 +140,6 @@ save.rename.text = Nouveau nom: selectslot = Sélectionner une sauvegarde. slot = [accent]Emplacement {0} save.corrupted = [accent]Fichier de sauvegarde corrompu ou invalide!\nSi vous venez de mettre à jour votre jeu, c'est probablement dû à un changement du format de sauvegarde et [scarlet]non[] un bug. -sector.corrupted = [accent]Une sauvegarde pour ce secteur a été trouvé, mais son chargement a raté.\nUne nouvelle sauvegarde a été créé. empty = on = On off = Off @@ -169,6 +149,7 @@ save.wave = Vague {0} save.difficulty = Difficulté: {0} save.date = Dernière sauvegarde: {0} save.playtime = Temps de jeu: {0} +warning = Warning. confirm = Confirmer delete = Supprimer ok = OK @@ -259,6 +240,17 @@ tutorial = Tutoriel editor = Éditeur mapeditor = Éditeur de carte donate = Faire un\ndon +abandon = Abandon +abandon.text = This zone and all its resources will be lost to the enemy. +locked = Locked +complete = [LIGHT_GRAY]Complete: +resume = Resume Zone:\n[LIGHT_GRAY]{0} +bestwave = [LIGHT_GRAY]Best: {0} +launch = Launch +launch.title = Launch Successful +launch.next = [LIGHT_GRAY]next opportunity at wave {0} +launch.unable = [scarlet]Unable to LAUNCH.[] Enemies. +zone.unlocked = [LIGHT_GRAY]{0} unlocked. connectfail = [crimson]Échec de la connexion au serveur : [accent]{0} error.unreachable = Server injoignable. error.invalidaddress = Adresse invalide. @@ -266,7 +258,20 @@ error.timedout = Délai de connexion dépassé!\nAssurez-vous que l'hôte a auto error.mismatch = Erreur de paquet:\nPossible différence de verison entre le client et le serveur .\nVérifiez que vous et l'hôte avez la plus récente version de Mindustry ! error.alreadyconnected = Déjà connecté. error.mapnotfound = Fichier de la carte introuvable! +error.io = Network I/O error. error.any = Erreur réseau inconnue. +zone.groundZero.name = Ground Zero +zone.craters.name = The Craters +zone.frozenForest.name = Frozen Forest +zone.ruinousShores.name = Ruinous Shores +zone.crags.name = Crags +zone.stainedMountains.name = Stained Mountains +zone.impact0079.name = Impact 0079 +zone.desolateRift.name = Desolate Rift +zone.arcticDesert.name = Arctic Desert +zone.dryWastes.name = Dry Wastes +zone.nuclearComplex.name = Nuclear Production Complex +zone.moltenFault.name = Molten Fault settings.language = Langage settings.reset = Valeur par défaut. settings.rebind = Réatttribuer @@ -277,7 +282,6 @@ settings.graphics = Graphiques settings.cleardata = Effacer les données du jeu... settings.clear.confirm = Êtes-vous sûr d'effacer ces données ?\nCe qui est fait ne peut être défait ! settings.clearall.confirm = [scarlet]ATTENTION![]\nCet action effacera toutes les données , incluant les sauvegarges, les cartes, les déblocages et la configuration des touches.\nUne fois que vous aurez pressé 'ok' le jeu effacera toutes les données et se fermera. -settings.clearsectors = Effacer les données des secteurs settings.clearunlocks = Effacer les déblocages settings.clearall = Tout effacer paused = En pause @@ -316,12 +320,15 @@ blocks.liquidoutput = Liquide en sortie blocks.liquidoutputspeed = Vitesse de production de liquide blocks.liquiduse = Quantité de liquide utilisée blocks.coolant = Liquide de refroidissement +blocks.liquid = Liquid blocks.coolantuse = Quantité de liquide de refroidissement utilisée blocks.inputliquidfuel = Carburant liquide blocks.liquidfueluse = Quantité de carburant liquide utilisé blocks.boostitem = Boost Item blocks.boostliquid = Boost Liquid blocks.health = Santé +blocks.power = Power +blocks.power.satisfaction = Power Satisfaction blocks.inaccuracy = Précision blocks.shots = Tir blocks.reload = Tirs/Seconde @@ -346,6 +353,7 @@ category.items = Objets category.crafting = Fabrication category.shooting = Défense category.optional = Optional Enhancements +setting.indicators.name = Ally Indicators setting.autotarget.name = Visée automatique setting.fpscap.name = Max FPS setting.fpscap.none = None @@ -378,11 +386,15 @@ category.multiplayer.name = Multijoueur command.attack = Attaque command.retreat = Retraite command.patrol = Patrouille +keybind.gridMode.name = Block Select +keybind.gridModeShift.name = Category Select keybind.press = Appuyer sur une touche... keybind.press.axis = Appuyer sur un axe ou une touche... +keybind.screenshot.name = Map Screenshot keybind.move_x.name = mouvement x keybind.move_y.name = mouvement y keybind.select.name = sélectionner +keybind.pick.name = Pick Block keybind.break.name = Pause keybind.deselect.name = Déselectionner keybind.shoot.name = tirer @@ -402,29 +414,28 @@ keybind.chat_scroll.name = Chat scroll keybind.drop_unit.name = drop unit keybind.zoom_minimap.name = Zoom minimap mode.help.title = Description des modes de jeu -mode.waves.name = Vagues -mode.waves.description = Le mode de jeu normal. Ressources limitées et vagues d'ennemis. +mode.survival.name = Survival +mode.survival.description = The normal mode. Limited resources and automatic incoming waves. mode.sandbox.name = bac à sable mode.sandbox.description = Ressources infinies et pas de timer pour les vagues. mode.freebuild.name = construction libre mode.freebuild.description = Ressources limitées et pas de timer pour les vagues. mode.pvp.name = JcJ mode.pvp.description = Battez-vous contre d'autres joueurs en local. +mode.attack.name = Attack +mode.attack.descrption = No waves, with the goal to destroy the enemy base. content.item.name = Objets content.liquid.name = Liquides content.unit.name = Unités -content.recipe.name = Blocs +content.block.name = Blocks content.mech.name = Méchas -item.stone.name = Pierre -item.stone.description = Un matériau brut commun. Peut être séparé et raffiné en d'autres matériaux, ou fondu en lave. item.copper.name = Cuivre item.copper.description = Un matériau de construction utile. Utilisé intensivement dans tout les blocs. item.lead.name = Plomb item.lead.description = Un matériau de départ. Utilisé intensivement en électronique et pour le transport de blocs. item.coal.name = Charbon item.coal.description = Un carburant commun et facile à obtenir. -item.dense-alloy.name = Alliage lourd -item.dense-alloy.description = Un alliage résistant fait de plomb et de cuivre. Utilisé dans les blocs de transports avancés et dans les foreuses de haut niveau. +item.graphite.name = Graphite item.titanium.name = Titane item.titanium.description = Un métal rare super-léger largement utilisé dans le transport de liquides et d'objets ainsi que dans les foreuses de haut-niveau et l'aviation. item.thorium.name = Thorium @@ -445,6 +456,10 @@ item.blast-compound.name = Mélange explosif item.blast-compound.description = Un composé volatile utilisé dans les bombes et les explosifs. Bien qu'il puisse être utilisé comme carburant, ce n'est pas conseillé. item.pyratite.name = Pyratite item.pyratite.description = Une substance extrêmement inflammable utilisée dans les armes incendiaires. +item.metaglass.name = Metaglass +item.metaglass.description = A super-tough glass compound. Extensively used for liquid distribution and storage. +item.scrap.name = Scrap +item.scrap.description = Leftover remnants of old structures and units. Contains trace amounts of many different metals. liquid.water.name = Eau liquid.lava.name = Lave liquid.oil.name = Pétrole @@ -481,11 +496,10 @@ mech.glaive-ship.weapon = Fusil automatique incendiaire item.explosiveness = [LIGHT_GRAY]Explosivité: {0} item.flammability = [LIGHT_GRAY]Inflammabilité: {0} item.radioactivity = [LIGHT_GRAY]Radioactivité: {0} -item.fluxiness = [LIGHT_GRAY]Flux de Puissance: {0} unit.health = [LIGHT_GRAY]Santé: {0} unit.speed = [LIGHT_GRAY]Rapidité: {0} mech.weapon = [LIGHT_GRAY]Arme: {0} -mech.armor = [LIGHT_GRAY]Armure: {0} +mech.health = [LIGHT_GRAY]Health: {0} mech.itemcapacity = [LIGHT_GRAY]Capacité de stockage: {0} mech.minespeed = [LIGHT_GRAY]Vitesse de minage: {0} mech.minepower = [LIGHT_GRAY]Puissance du minage: {0} @@ -493,9 +507,15 @@ mech.ability = [LIGHT_GRAY]Compétence: {0} liquid.heatcapacity = [LIGHT_GRAY]Capacité Thermique: {0} liquid.viscosity = [LIGHT_GRAY]Viscosité: {0} liquid.temperature = [LIGHT_GRAY]Température: {0} +block.kiln.name = Kiln +block.kiln.description = Smelts sand and lead into metaglass. Requires small amounts of power. +block.graphite-press.name = Graphite Press +block.multi-press.name = Multi-Press block.constructing = {0}\n[LIGHT_GRAY](En Construction) block.spawn.name = Générateur d'ennemis -block.core.name = Base +block.core-shard.name = Core: Shard +block.core-foundation.name = Core: Foundation +block.core-nucleus.name = Core: Nucleus block.metalfloor.name = Sol en métal block.deepwater.name = Eau profonde block.water.name = Eau @@ -514,8 +534,8 @@ block.blackrock.name = Pierre sombre block.icerock.name = Pierre gelée block.copper-wall.name = Mur de cuivre block.copper-wall-large.name = Grand mur de cuivre -block.dense-alloy-wall.name = Mur en alliage lourd -block.dense-alloy-wall-large.name = Grand mur en alliage lourd +block.titanium-wall.name = Titanium Wall +block.titanium-wall-large.name = Large Titanium Wall block.phase-wall.name = Mur phasé block.phase-wall-large.name = Grand mur phasé block.thorium-wall.name = Mur en Thorium @@ -548,17 +568,19 @@ block.separator.name = Séparateur block.centrifuge.name = Centrifugeuse block.power-node.name = Transmetteur énergétique block.power-node-large.name = Gros transmetteur énergétique +block.surge-tower.name = Surge Tower block.battery.name = Batterie block.battery-large.name = Batterie large block.combustion-generator.name = Générateur à combustion block.turbine-generator.name = Générateur à Turbine +block.differential-generator.name = Differential Generator +block.impact-reactor.name = Impact Reactor block.mechanical-drill.name = Foreuse mécanique block.pneumatic-drill.name = Foreuse à vérin block.laser-drill.name = Foreuse Laser block.water-extractor.name = Extracteur d'eau block.cultivator.name = Cultivateur -block.alpha-mech-pad.name = Reconstructeur de mécha "Alpha" -block.dart-ship-pad.name = Reconstructeur de vaisseau "Dard" +block.alpha-dart-mech-pad.name = Alpha-Dart Mech Pad block.delta-mech-pad.name = Reconstructeur de mécha "Delta" block.javelin-ship-pad.name = Reconstructeur de vaisseau "Javelin" block.trident-ship-pad.name = Reconstructeur de vaisseau "Trident" @@ -623,7 +645,7 @@ block.rtg-generator.name = G.T.R. block.spectre.name = Spectre block.meltdown.name = Meltdown block.container.name = Conteneur -block.core.description = Le batiment le plus important du jeu. +block.launch-pad.name = Launch Pad team.blue.name = Bleu team.red.name = Rouge team.orange.name = Orange @@ -637,6 +659,7 @@ unit.phantom.name = Drone Fantôme unit.phantom.description = Une unité de soutien avancée. Mine automatiquement les minerais, récupère les objets au sol et répare les blocs. Bien plus efficace qu'un drone spirituel. unit.dagger.name = Poignard unit.dagger.description = Une unité terrestre basiquee. Utile en armée. +unit.crawler.name = Crawler unit.titan.name = Titan unit.titan.description = Une unité terrestre cuirassée avancée. Attaque les unités terrestres comme aériennes. unit.ghoul.name = Bombardier goule @@ -646,7 +669,11 @@ unit.wraith.description = Une unité volante rapide harcelant les ennemis .Utili unit.fortress.name = Forteresse unit.fortress.description = Une unité terrestre d'artillerie lourde . unit.revenant.name = Revenant -unit.revenant.description = Une plateforme laser lourde. +unit.eruptor.name = Eruptor +unit.chaos-array.name = Chaos Array +unit.eradicator.name = Eradicator +unit.lich.name = Lich +unit.reaper.name = Reaper tutorial.begin = Votre mission, si vous l'acceptez est de détruire [LIGHT_GRAY]l'ennemi[].\n\nCommencez par [accent] miner du cuivre[]. Appuyer sur un filon de cuivre proche de votre base pour faire ceci. tutorial.drill = Le minage manuel est inefficace.\n[accent]Des foreuses[]peuvent miner automatiquement.\nPlacez-en une sur un filon de cuivre. tutorial.conveyor = [accent]Les Tapis roulants[] sont utilisés pour transporter des objets jusqu'à la base.\nFaites une ligne de tapis roulants de la foreuse à la base . diff --git a/core/assets/bundles/bundle_fr_BE.properties b/core/assets/bundles/bundle_fr_BE.properties index 79788734dc..cea1692a02 100644 --- a/core/assets/bundles/bundle_fr_BE.properties +++ b/core/assets/bundles/bundle_fr_BE.properties @@ -13,13 +13,15 @@ linkfail = L'ouverture du lien a échoué!\nL'URL a été copiée dans votre pre screenshot = Capture d'écran enregistrée sur {0} gameover = Le base a été détruit. gameover.pvp = L'équipe[accent] {0}[] a gagnée ! -sector.gameover = Ce secteur a été perdu. Réessayer ? -sector.retry = Réessayer highscore = [accent]Nouveau meilleur score ! -wave.lasted = Tu as survécu jusqu'à la vagues [accent]{0}[]. -level.highscore = Meilleur score: [accent]{0} -level.delete.title = Confirmer +stat.wave = Waves Defeated:[accent] {0} +stat.enemiesDestroyed = Enemies Destroyed:[accent] {0} +stat.built = Buildings Built:[accent] {0} +stat.destroyed = Buildings Destroyed:[accent] {0} +stat.deconstructed = Buildings Deconstructed:[accent] {0} +stat.delivered = Resources Launched: map.delete = Êtes-vous sûr de vouloir supprimer cette carte ?"[accent]{0}[]"? +level.highscore = Meilleur score: [accent]{0} level.select = Sélection de niveau level.mode = Mode de jeu: construction.desktop = Désélectionner un bloc ou arrêter la construction, [accent]utiliser la touche espace[]. @@ -29,61 +31,36 @@ deconstruction.title = Guide de déconstruction de blocs deconstruction = Vous venez de sélectionner le [accent]mode de destruction de blocs[].\n\nPour détruire, tapez simplement un bloc près de votre vaisseau (vous).\nUne fois que vous avez sélectionné des blocs, appuyez sur le "check" pour confirmer, et votre vaisseau commencera à les détruire.\n\n- [accent]Retirez les blocs[] de votre sélection en les touchant.\n- [accent]Détruisez les blocs dans une aire[] en sélectionnant et en maintenant un emplacement vide, ensuite glissez votre doigt dans une direction.\n- [accent]Annulez une destruction ou une sélection[] en appuyant sur "X" dans le coin en bas à gauche. showagain = Ne plus montrer la prochaine fois. coreattack = -unlocks = Débloqués +nearpoint = [[ [scarlet]LEAVE DROP POINT IMMEDIATELY[] ]\nannihilation imminent +outofbounds = [[ OUT OF BOUNDS ]\n[]self-destruct in {0} +database = Core Database savegame = Sauvegarder la partie loadgame = Charger la partie joingame = Rejoindre la partie addplayers = Ajouter/Enlever des joueurs customgame = Partie personnalisée -sectors = Secteurs -sector = Secteur sélectionné: [LIGHT_GRAY]{0} -sector.time = Temps: [LIGHT_GRAY]{0} -sector.deploy = Déployer -sector.abandon = Abandonner -sector.abandon.confirm = Êtes-vous sûr de vouloir abandonner tout progrès dans ce secteur?\nCette action ne peut être annulée! -sector.resume = Reprendre -sector.locked = [scarlet][[Incomplet] -sector.unexplored = [accent][[Inexploré] -missions = Missions:[LIGHT_GRAY] {0} -mission = Mission:[LIGHT_GRAY] {0} -mission.main = Mission principale:[LIGHT_GRAY] {0} -mission.info = Mission info -mission.complete = Mission terminée ! -mission.complete.body = Le secteur {0},{1} a été conquis. -mission.wave = Survivez[accent] {0}/{1} []vagues\nProchaine vague dans {2} -mission.wave.enemies = Survivez[accent] {0}/{1} []vagues\n{2} Ennemis -mission.wave.enemy = Survivez[accent] {0}/{1} []vagues\n{2} Ennemi -mission.wave.menu = Survivez[accent] {0} []vagues -mission.battle = Détruire la base ennemie. -mission.resource.menu = Obtenez {0} x{1} -mission.resource = Obtenez {0}:\n[accent]{1}/{2}[] -mission.block = Créez {0} -mission.unit = Créez {0} unité -mission.command = Envoyer une commande à {0} unités -mission.linknode = Reliez le transmetteur énergétique -mission.display = [accent]Mission:\n[LIGHT_GRAY]{0} -mission.mech = Changer de mécha[accent] {0}[] -mission.create = Créez[accent] {0}[] +newgame = New Game none = close = Fermer quit = Quitter maps = Cartes continue = Continue -nextmission = Prochaine Mission maps.none = [LIGHT_GRAY]Aucune carte trouvée! about.button = À propos name = Nom: noname = Choisissez d'abord [accent]un pseudo[]. filename = Nom du fichier: unlocked = Nouveau bloc debloqué! -unlocked.plural = Nouveaux blocs débloqués! +completed = [accent]Completed +techtree = Tech Tree +research.list = [LIGHT_GRAY]Research: +research = Research +researched = [LIGHT_GRAY]{0} researched. players = {0} joueurs en ligne players.single = {0} joueur en ligne server.closing = [accent]Fermeture du serveur ... server.kicked.kick = Vous avez été expulsé du serveur ! server.kicked.serverClose = Serveur fermé. -server.kicked.sectorComplete = Secteur terminée. -server.kicked.sectorComplete.text = Votre mission est complète.\nLe serveur va maintenant passer au prochain secteur. server.kicked.clientOutdated = Client dépassé! Mettez à jour votre jeu ! server.kicked.serverOutdated = Serveur dépassé! Demandez à l'hôte de le mettre à jour ! server.kicked.banned = Vous êtes banni de ce serveur. @@ -163,7 +140,6 @@ save.rename.text = Nouveau nom: selectslot = Sélectionnez une sauvegarde. slot = [accent]Emplacement {0} save.corrupted = [accent]Fichier de sauvegarde corrompu ou invalide!\nSi vous venez de mettre à jour votre jeu, c'est probablement dû à un changement du format de sauvegarde et [scarlet]non[] un bug. -sector.corrupted = [accent]Une sauvegarde pour ce secteur a été trouvé, mais son chargement a raté.\nUne nouvelle sauvegarde a été créé. empty = on = Allumer off = Éteint @@ -173,6 +149,7 @@ save.wave = Vague {0} save.difficulty = Difficulté: {0} save.date = Dernière sauvegarde: {0} save.playtime = Temps de jeu: {0} +warning = Warning. confirm = Confirmer delete = Supprimer ok = OK @@ -263,6 +240,17 @@ tutorial = Tutoriel editor = Éditeur mapeditor = Éditeur de carte donate = Faire un\ndon +abandon = Abandon +abandon.text = This zone and all its resources will be lost to the enemy. +locked = Locked +complete = [LIGHT_GRAY]Complete: +resume = Resume Zone:\n[LIGHT_GRAY]{0} +bestwave = [LIGHT_GRAY]Best: {0} +launch = Launch +launch.title = Launch Successful +launch.next = [LIGHT_GRAY]next opportunity at wave {0} +launch.unable = [scarlet]Unable to LAUNCH.[] Enemies. +zone.unlocked = [LIGHT_GRAY]{0} unlocked. connectfail = [crimson]Échec de la connexion au serveur: [accent]{0} error.unreachable = Serveur inaccessible. error.invalidaddress = Adresse invalide. @@ -270,8 +258,20 @@ error.timedout = Expiration du délai !\nAssurez-vous que la redirection de port error.mismatch = Erreur de paquet:\nPossible d'incompatibilité de version client/serveur.\nAssurez-vous que l'hôte et vous disposez de la dernière version de Mindustry ! error.alreadyconnected = Déjà connecté. error.mapnotfound = Fichier de carte introuvable ! -text.error.io = Erreur réseau IO. +error.io = Network I/O error. error.any = Erreur réseau inconnue. +zone.groundZero.name = Ground Zero +zone.craters.name = The Craters +zone.frozenForest.name = Frozen Forest +zone.ruinousShores.name = Ruinous Shores +zone.crags.name = Crags +zone.stainedMountains.name = Stained Mountains +zone.impact0079.name = Impact 0079 +zone.desolateRift.name = Desolate Rift +zone.arcticDesert.name = Arctic Desert +zone.dryWastes.name = Dry Wastes +zone.nuclearComplex.name = Nuclear Production Complex +zone.moltenFault.name = Molten Fault settings.language = Langage settings.reset = Valeur par défaut. settings.rebind = Réatttribuer @@ -282,7 +282,6 @@ settings.graphics = Graphiques settings.cleardata = Effacer les données du jeu... settings.clear.confirm = Êtes-vous sûr d'effacer ces données ?\n[scarlet]Ceci est irréversible settings.clearall.confirm = [scarlet]ATTENTION![]\nCet action effacera toutes les données , incluant les sauvegarges, les cartes, les déblocages et la configuration des touches.\nUne fois que vous aurez pressé 'Ok' le jeu effacera toutes les données et se fermera. -settings.clearsectors = Éffacer les données des secteurs settings.clearunlocks = Éffacer les déblocages settings.clearall = Tout effacer paused = En pause @@ -321,12 +320,15 @@ blocks.liquidoutput = Liquide en sortie blocks.liquidoutputspeed = Vitesse de sortie du liquide blocks.liquiduse = Quantité de liquide utilisé blocks.coolant = Liquide de refroidissement +blocks.liquid = Liquid blocks.coolantuse = Quantité de liquide de refroidissement utilisé blocks.inputliquidfuel = Carburant liquide blocks.liquidfueluse = Quantité de carburant liquide utilisé blocks.boostitem = Objet boostant la production blocks.boostliquid = Liquide boostant la production blocks.health = Santé +blocks.power = Power +blocks.power.satisfaction = Power Satisfaction blocks.inaccuracy = Précision blocks.shots = Tirs blocks.reload = Tirs/Seconde @@ -388,9 +390,11 @@ keybind.gridMode.name = Sélectionnez le bloc keybind.gridModeShift.name = Sélection de la catégorie keybind.press = Appuyez sur une touche ... keybind.press.axis = Appuyez sur un axe ou une touche... +keybind.screenshot.name = Map Screenshot keybind.move_x.name = Mouvement X keybind.move_y.name = Mouvement Y keybind.select.name = Sélectionner/Tirer +keybind.pick.name = Pick Block keybind.break.name = Pause keybind.deselect.name = Déselectionner keybind.shoot.name = Tirer @@ -410,8 +414,8 @@ keybind.chat_scroll.name = Faire défiler le tchat keybind.drop_unit.name = Larguer une unité keybind.zoom_minimap.name = Zoomer la minimap mode.help.title = Description des modes de jeu -mode.waves.name = Vagues -mode.waves.description = Le mode normal. Ressources limitées et vagues déclenchées automatiquement. +mode.survival.name = Survival +mode.survival.description = The normal mode. Limited resources and automatic incoming waves. mode.sandbox.name = Bac à sable mode.sandbox.description = Ressources infinies et pas de compte à rebours pour les vagues. mode.freebuild.name = Construction libre @@ -423,18 +427,15 @@ mode.attack.descrption = Pas de vagues, le but est de détruire la base ennemie. content.item.name = Objets content.liquid.name = Liquides content.unit.name = Unités -content.recipe.name = Bloc +content.block.name = Blocks content.mech.name = Mécha -item.stone.name = Pierre -item.stone.description = Un matériau brut commun. Peut-être séparé et raffiné en d'autres matériaux, ou fondus en lave. item.copper.name = Cuivre item.copper.description = Un matériau de construction utile. Utilisé intensivement dans tout les blocs. item.lead.name = Plomb item.lead.description = Un matériau de départ. Utilisé intensivement en électronique et pour le transport de blocs. item.coal.name = Charbon item.coal.description = Un carburant commun et facile à obtenir. -item.dense-alloy.name = Alliage lourd -item.dense-alloy.description = Un alliage résistant fait de plomb et de cuivre. Utilisé dans les blocs de transports avancés et les foreuses de haut niveau. +item.graphite.name = Graphite item.titanium.name = Titane item.titanium.description = Un métal rare super-léger largement utilisé dans le transport de liquides et d'objets ainsi que dans les foreuses de haut-niveau et l'aviation item.thorium.name = Thorium @@ -455,6 +456,10 @@ item.blast-compound.name = Mélange explosif item.blast-compound.description = Un composé volatile utilisé dans les bombes et les explosifs. Bien qu'il puisse être utilisé comme carburant, ce n'est pas conseillé. item.pyratite.name = Pyratite item.pyratite.description = Une substance extrêmement inflammable utilisée dans les armes incendiaires. +item.metaglass.name = Metaglass +item.metaglass.description = A super-tough glass compound. Extensively used for liquid distribution and storage. +item.scrap.name = Scrap +item.scrap.description = Leftover remnants of old structures and units. Contains trace amounts of many different metals. liquid.water.name = Eau liquid.lava.name = Lave liquid.oil.name = Pétrole @@ -491,11 +496,10 @@ mech.glaive-ship.weapon = Fusil automatique incendiaire item.explosiveness = [LIGHT_GRAY]Explosivité: {0} item.flammability = [LIGHT_GRAY]Inflammabilité: {0} item.radioactivity = [LIGHT_GRAY]Radioactivité: {0} -item.fluxiness = [LIGHT_GRAY]Flux de Puissance: {0} unit.health = [LIGHT_GRAY]Santé: {0} unit.speed = [LIGHT_GRAY]Vitesse: {0} mech.weapon = [LIGHT_GRAY]Arme: {0} -mech.armor = [LIGHT_GRAY]Armure: {0} +mech.health = [LIGHT_GRAY]Health: {0} mech.itemcapacity = [LIGHT_GRAY]Capacité de stockage: {0} mech.minespeed = [LIGHT_GRAY]Vitesse de minage: {0} mech.minepower = [LIGHT_GRAY]Puissance du minage: {0} @@ -503,9 +507,15 @@ mech.ability = [LIGHT_GRAY]Compétence: {0} liquid.heatcapacity = [LIGHT_GRAY]Capacité Thermique {0} liquid.viscosity = [LIGHT_GRAY]Viscosité: {0} liquid.temperature = [LIGHT_GRAY]Température: {0} +block.kiln.name = Kiln +block.kiln.description = Smelts sand and lead into metaglass. Requires small amounts of power. +block.graphite-press.name = Graphite Press +block.multi-press.name = Multi-Press block.constructing = {0}\n[LIGHT_GRAY](En construction) block.spawn.name = Générateur d'ennemi -block.core.name = Base +block.core-shard.name = Core: Shard +block.core-foundation.name = Core: Foundation +block.core-nucleus.name = Core: Nucleus block.metalfloor.name = Sol en métal block.deepwater.name = Eau profonde block.water.name = Eau @@ -524,8 +534,8 @@ block.blackrock.name = Pierre sombre block.icerock.name = Pierre gelée block.copper-wall.name = Mur de cuivre block.copper-wall-large.name = Grand mur de cuivre -block.dense-alloy-wall.name = Mur en alliage lourd -block.dense-alloy-wall-large.name = Grand mur en alliage lourd +block.titanium-wall.name = Titanium Wall +block.titanium-wall-large.name = Large Titanium Wall block.phase-wall.name = Mur phasé block.phase-wall-large.name = Grand mur phasé block.thorium-wall.name = Mur en Thorium @@ -558,17 +568,19 @@ block.separator.name = Séparateur block.centrifuge.name = Centrifugeuse block.power-node.name = Transmetteur énergétique block.power-node-large.name = Grand transmetteur énergétique +block.surge-tower.name = Surge Tower block.battery.name = Batterie block.battery-large.name = Batterie large block.combustion-generator.name = Générateur à combustion block.turbine-generator.name = Générateur à Turbine +block.differential-generator.name = Differential Generator +block.impact-reactor.name = Impact Reactor block.mechanical-drill.name = Foreuse mécanique block.pneumatic-drill.name = Foreuse à vérin block.laser-drill.name = Foreuse Laser block.water-extractor.name = Extracteur d'eau block.cultivator.name = Cultivateur -block.alpha-mech-pad.name = Alpha Mech Pad -block.dart-ship-pad.name = Dart Ship Pad +block.alpha-dart-mech-pad.name = Alpha-Dart 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 @@ -633,7 +645,7 @@ block.rtg-generator.name = G.T.R. block.spectre.name = Spectre block.meltdown.name = Meltdown block.container.name = Conteneur -block.core.description = Sert de point de base pour le/les joueur(s). Ce bâtiment est le plus [scarlet]important[] du jeu ! +block.launch-pad.name = Launch Pad team.blue.name = Bleu team.red.name = Rouge team.orange.name = Orange @@ -647,6 +659,7 @@ unit.phantom.name = Drone Fantôme unit.phantom.description = Une unité de soutien avancée. Mine automatiquement les minerais, récupère les objets au sol et répare les blocs. Bien plus efficace qu'un drone spirituel. unit.dagger.name = Poignard unit.dagger.description = Une unité terrestre de base. Utile en essaims. +unit.crawler.name = Crawler unit.titan.name = Titan unit.titan.description = Une unité terrestre cuirassée avancée. Utilise de l'alliage lourd pour munition. Attaque les unités aérinnes comme terrestres. unit.ghoul.name = Bombardier goule @@ -656,7 +669,11 @@ unit.wraith.description = Une unité volante rapide harcelant les ennemis. Utili unit.fortress.name = Forteresse unit.fortress.description = Une unité terrestre d'artillerie lourde. unit.revenant.name = Revenant -unit.revenant.description = Une plateforme de laser lourd. +unit.eruptor.name = Eruptor +unit.chaos-array.name = Chaos Array +unit.eradicator.name = Eradicator +unit.lich.name = Lich +unit.reaper.name = Reaper tutorial.begin = Votre mission, si vous l'acceptez est de détruire [LIGHT_GRAY]l'ennemi[].\n\nCommencez par [accent] miner du cuivre[]. Appuyer sur un filon de cuivre proche de votre base pour faire ceci. tutorial.drill = Le minage manuel est inefficace.\n[accent]Des foreuses[]peuvent miner automatiquement.\nPlacez-en une sur un filon de cuivre. tutorial.conveyor = [accent]Les Tapis roulants[] sont utilisés pour transporter des objets jusqu'à la base.\nFaites une ligne de tapis roulants de la foreuse à la base . diff --git a/core/assets/bundles/bundle_in_ID.properties b/core/assets/bundles/bundle_in_ID.properties index 392c57acf6..d1604949cd 100644 --- a/core/assets/bundles/bundle_in_ID.properties +++ b/core/assets/bundles/bundle_in_ID.properties @@ -1,5 +1,6 @@ credits.text = Created by [ROYAL]Anuken[] - [SKY]anukendev@gmail.com[]\n\n[GRAY](In case you can't tell, this text is currently unfinished.\nTranslators, don't edit it yet!) credits = Kredit +contributors = Translators and Contributors discord = Mari bergabung di Discord Mindustry! link.discord.description = grup Discord Mindustry resmi link.github.description = Source code permainan @@ -9,15 +10,18 @@ link.itch.io.description = Halaman itch.io dengan unduhan PC dan versi web link.google-play.description = Google Play store link.wiki.description = wiki resmi Mindustry linkfail = Gagal membuka link!\nURL telah disalin ke papan salin. +screenshot = Screenshot saved to {0} gameover = Intinya hancur. gameover.pvp = Tim [accent] {0}[] menang! -sector.gameover = Sektor ini telah hancur. Ulangi? -sector.retry = Ulangi highscore = [YELLOW]Rekor baru! -wave.lasted = Kamu bertahan sampai gelombang ke [accent]{0}[]. -level.highscore = Skor Tinggi: [accent]{0} -level.delete.title = Konfirmasi Hapus +stat.wave = Waves Defeated:[accent] {0} +stat.enemiesDestroyed = Enemies Destroyed:[accent] {0} +stat.built = Buildings Built:[accent] {0} +stat.destroyed = Buildings Destroyed:[accent] {0} +stat.deconstructed = Buildings Deconstructed:[accent] {0} +stat.delivered = Resources Launched: map.delete = Apakah kamu yakin ingin menghapus peta "[orange]{0}[]"? +level.highscore = Skor Tinggi: [accent]{0} level.select = Pilih Level level.mode = Modus permainan: construction.desktop = Kontrol desktop telah berubah.\nUntuk membatalkan blok atau menghentikan pembangunan, [accent]gunakan spasi[]. @@ -27,60 +31,36 @@ deconstruction.title = Block Deconstruction Guide deconstruction = You've just selected [accent]block deconstruction mode[].\n\nTo begin breaking, simply tap a block near your ship.\nOnce you have selected some blocks, press the checkbox to confirm, and your ship will begin de-constructing them.\n\n- [accent]Remove blocks[] from your selection by tapping them.\n- [accent]Remove blocks in an area[] by tapping and holding an empty spot, then dragging in a direction.\n- [accent]Cancel deconstruction or selection[] by pressing the X at the bottom left. showagain = Jangan tampilkan lagi di sesi berikutnya coreattack = < Intinya sedang diserang! > -unlocks = Pencapaian +nearpoint = [[ [scarlet]LEAVE DROP POINT IMMEDIATELY[] ]\nannihilation imminent +outofbounds = [[ OUT OF BOUNDS ]\n[]self-destruct in {0} +database = Core Database savegame = Simpan Permainan loadgame = Lanjutkan joingame = Bermain Bersama addplayers = Tambah/Hapus Pemain customgame = Game Bebas -sectors = Sektor -sector = Sektor Dipilih: [LIGHT_GRAY]{0} -sector.time = Waktu: [LIGHT_GRAY]{0} -sector.deploy = Pasang -sector.abandon = Batalkan -sector.abandon.confirm = Apakah kamu yakin ingin membatalkan all progress at this sector?\nIni tidak dapat diubah kembali! -sector.resume = Lanjutkan -sector.locked = [scarlet][[Belum Selesai] -sector.unexplored = [accent][[Belum Ditelusuri] -missions = Misi:[LIGHT_GRAY] {0} -mission = Misi:[LIGHT_GRAY] {0} -mission.main = Misi Utama:[LIGHT_GRAY] {0} -mission.info = Info Misi -mission.complete = Misi selesai! -mission.complete.body = Sektor {0},{1} telah dikuasai. -mission.wave = Bertahanlah selama [accent]{0}[] gelombang. -mission.wave.enemies = Bertahanlah selama[accent] {0}/{1} []gelombang\n{2} Musuh -mission.wave.enemy = Bertahanlah selama[accent] {0}/{1} []gelombang\n{2} Musuh -mission.wave.menu = Bertahanlah selama[accent] {0} []gelombang -mission.battle = Hancurkan markas musuh. -mission.resource.menu = Dapatkan {0} x{1} -mission.resource = Dapatkan {0}:\n[accent]{1}/{2}[] -mission.block = Buat {0} -mission.unit = Buat {0} Pasukan -mission.command = Beri Perintah {0} Ke Pasukan -mission.linknode = Gabungkan Power Node -mission.display = [accent]Misi:\n[LIGHT_GRAY]{0} -mission.mech = Ganti ke robot[accent] {0}[] -mission.create = Buat[accent] {0}[] +newgame = New Game none = close = Tutup quit = Keluar maps = Peta continue = Lanjutkan -nextmission = Tugas Berikut maps.none = [LIGHT_GRAY]Peta tidak ditemukan! about.button = Tentang name = Nama: +noname = Pick a[accent] player name[] first. filename = Nama file: unlocked = Blok Baru Terbuka! -unlocked.plural = Blok Baru Terbuka! +completed = [accent]Completed +techtree = Tech Tree +research.list = [LIGHT_GRAY]Research: +research = Research +researched = [LIGHT_GRAY]{0} researched. players = {0} pemain online players.single = {0} pemain online server.closing = [accent]Menutup server... server.kicked.kick = Anda telah dikeluarkan dari server! server.kicked.serverClose = Server ditutup. -server.kicked.sectorComplete = Sektor selesai. -server.kicked.sectorComplete.text = Misi Anda telah selesai.\nServer akan melanjutkan ke sektor selanjutnya. server.kicked.clientOutdated = Client versi lama! Update game Anda! server.kicked.serverOutdated = Server versi lama! Tanyakan host untuk memperbaharuinya! server.kicked.banned = Anda telah di-ban dari server ini. @@ -89,6 +69,7 @@ server.kicked.nameInUse = Ada seseorang dengan nama\nitu di server ini. server.kicked.nameEmpty = Nama Anda harus mengandung setidaknya satu karakter atau angka. server.kicked.idInUse = Kamu sudah ada di server ini! Menghubungkan dengan dua akun tidak diizinkan. server.kicked.customClient = Server ini tidak mendukung bentukan khusus. Unduh versi resmi. +server.kicked.gameover = Game over! host.info = Tombol [accent]host[] akan membuat server dengan port [scarlet]6567[] dan [scarlet]6568.[]\nSiapa saja yang terhubung ke [LIGHT_GRAY]WiFi atau jaringan lokal[] dapat melihat server Anda di daftar server.\n\nJika Anda ingin orang-orang agar dapat terhubung dari mana saja melalui IP, diperlukan [accent]port forwarding[].\n\n[LIGHT_GRAY]Catatan: Jika seseorang mengalami kesulitan untuk bergabung, pastikan bahwa Anda telah mengizinkan akses Mindustry ke jaringan lokal Anda di pengaturan firewall. join.info = Di sini, Anda dapat memasukan [accent]IP server[] yang akan dihubungkan, atau menemukan server di [accent]jaringan lokal[] untuk dihubungkan.\nKedua jaringan LAN dan WAN didukung.\n\n[LIGHT_GRAY]Catatan: There is no automatic global server list; if you want to connect to someone by IP, you would need to ask the host for their IP. hostserver = Host Server @@ -159,7 +140,6 @@ save.rename.text = Nama baru: selectslot = Pilih simpanan. slot = [accent]Slot{0} save.corrupted = [accent]Simpanan rusak atau tidak valid! -sector.corrupted = [accent]A save file for this sector was found, but loading failed.\nA new one has been created. empty = on = Hidup off = Mati @@ -169,6 +149,7 @@ save.wave = Gelombang {0} save.difficulty = Difficulty: {0} save.date = Terakhir Disimpan: {0} save.playtime = Playtime: {0} +warning = Warning. confirm = Konfirmasi delete = Hapus ok = OK @@ -259,6 +240,17 @@ tutorial = Tutorial editor = Pengedit mapeditor = Pengedit Peta donate = Sumbangkan +abandon = Abandon +abandon.text = This zone and all its resources will be lost to the enemy. +locked = Locked +complete = [LIGHT_GRAY]Complete: +resume = Resume Zone:\n[LIGHT_GRAY]{0} +bestwave = [LIGHT_GRAY]Best: {0} +launch = Launch +launch.title = Launch Successful +launch.next = [LIGHT_GRAY]next opportunity at wave {0} +launch.unable = [scarlet]Unable to LAUNCH.[] Enemies. +zone.unlocked = [LIGHT_GRAY]{0} unlocked. connectfail = [crimson]Gagal terhubung ke server: [accent]{0} error.unreachable = Server unreachable. error.invalidaddress = Invalid address. @@ -266,7 +258,20 @@ error.timedout = Timed out!\nMake sure the host has port forwarding set up, and error.mismatch = Packet error:\npossible client/server version mismatch.\nMake sure you and the host have the latest version of Mindustry! error.alreadyconnected = Already connected. error.mapnotfound = Map file not found! +error.io = Network I/O error. error.any = Unkown network error. +zone.groundZero.name = Ground Zero +zone.craters.name = The Craters +zone.frozenForest.name = Frozen Forest +zone.ruinousShores.name = Ruinous Shores +zone.crags.name = Crags +zone.stainedMountains.name = Stained Mountains +zone.impact0079.name = Impact 0079 +zone.desolateRift.name = Desolate Rift +zone.arcticDesert.name = Arctic Desert +zone.dryWastes.name = Dry Wastes +zone.nuclearComplex.name = Nuclear Production Complex +zone.moltenFault.name = Molten Fault settings.language = Bahasa settings.reset = Atur ulang ke Default settings.rebind = Rebind @@ -277,7 +282,6 @@ settings.graphics = Grafis settings.cleardata = Clear Game Data... settings.clear.confirm = Are you sure you want to clear this data?\nWhat is done cannot be undone! settings.clearall.confirm = [scarlet]WARNING![]\nThis will clear all data, including saves, maps, unlocks and keybinds.\nOnce you press 'ok' the game will wipe all data and automatically exit. -settings.clearsectors = Clear Sectors settings.clearunlocks = Clear Unlocks settings.clearall = Clear All paused = Jeda @@ -316,12 +320,15 @@ blocks.liquidoutput = Liquid Output blocks.liquidoutputspeed = Liquid Output Speed blocks.liquiduse = Liquid Use blocks.coolant = Coolant +blocks.liquid = Liquid blocks.coolantuse = Coolant Use blocks.inputliquidfuel = Fuel Liquid blocks.liquidfueluse = Liquid Fuel Use blocks.boostitem = Boost Item blocks.boostliquid = Boost Liquid blocks.health = Darah +blocks.power = Power +blocks.power.satisfaction = Power Satisfaction blocks.inaccuracy = Ketidaktelitian blocks.shots = Tembakan blocks.reload = Reload @@ -346,6 +353,7 @@ category.items = Items category.crafting = Crafting category.shooting = Shooting category.optional = Optional Enhancements +setting.indicators.name = Ally Indicators setting.autotarget.name = Auto-Target setting.fpscap.name = Max FPS setting.fpscap.none = None @@ -378,11 +386,15 @@ category.multiplayer.name = Multiplayer command.attack = Attack command.retreat = Retreat command.patrol = Patrol +keybind.gridMode.name = Block Select +keybind.gridModeShift.name = Category Select keybind.press = Press a key... keybind.press.axis = Press an axis or key... +keybind.screenshot.name = Map Screenshot keybind.move_x.name = gerak_x keybind.move_y.name = gerak_y keybind.select.name = pilih +keybind.pick.name = Pick Block keybind.break.name = hapus keybind.deselect.name = Deselect keybind.shoot.name = tembak @@ -402,29 +414,28 @@ keybind.chat_scroll.name = Chat scroll keybind.drop_unit.name = drop unit keybind.zoom_minimap.name = Zoom minimap mode.help.title = Description of modes -mode.waves.name = gelombang -mode.waves.description = the normal mode. limited resources and automatic incoming waves. +mode.survival.name = Survival +mode.survival.description = The normal mode. Limited resources and automatic incoming waves. mode.sandbox.name = sandbox mode.sandbox.description = infinite resources and no timer for waves. mode.freebuild.name = freebuild mode.freebuild.description = limited resources and no timer for waves. mode.pvp.name = PvP mode.pvp.description = fight against other players locally. +mode.attack.name = Attack +mode.attack.descrption = No waves, with the goal to destroy the enemy base. content.item.name = Items content.liquid.name = Liquids content.unit.name = Units -content.recipe.name = Blocks +content.block.name = Blocks content.mech.name = Mechs -item.stone.name = batu -item.stone.description = A common raw material. Used for separating and refining into other materials, or melting into lava. item.copper.name = Copper item.copper.description = A useful structure material. Used extensively in all types of blocks. item.lead.name = Lead item.lead.description = A basic starter material. Used extensively in electronics and liquid transportation blocks. item.coal.name = batu bara item.coal.description = A common and readily available fuel. -item.dense-alloy.name = Dense Alloy -item.dense-alloy.description = A tough alloy made with lead and copper. Used in advanced transportation blocks and high-tier drills. +item.graphite.name = Graphite item.titanium.name = titanium item.titanium.description = A rare super-light metal used extensively in liquid transportation, drills and aircraft. item.thorium.name = thorium @@ -445,6 +456,10 @@ item.blast-compound.name = Blast Compound item.blast-compound.description = A volatile compound used in bombs and explosives. While it can burned as fuel, this is not advised. item.pyratite.name = Pyratite item.pyratite.description = An extremely flammable substance used in incendiary weapons. +item.metaglass.name = Metaglass +item.metaglass.description = A super-tough glass compound. Extensively used for liquid distribution and storage. +item.scrap.name = Scrap +item.scrap.description = Leftover remnants of old structures and units. Contains trace amounts of many different metals. liquid.water.name = air liquid.lava.name = lahar liquid.oil.name = minyak @@ -481,11 +496,10 @@ mech.glaive-ship.weapon = Flame Repeater item.explosiveness = [LIGHT_GRAY]Explosiveness: {0} item.flammability = [LIGHT_GRAY]Flammability: {0} item.radioactivity = [LIGHT_GRAY]Radioactivity: {0} -item.fluxiness = [LIGHT_GRAY]Flux Power: {0} unit.health = [LIGHT_GRAY]Health: {0} unit.speed = [LIGHT_GRAY]Speed: {0} mech.weapon = [LIGHT_GRAY]Weapon: {0} -mech.armor = [LIGHT_GRAY]Armor: {0} +mech.health = [LIGHT_GRAY]Health: {0} mech.itemcapacity = [LIGHT_GRAY]Item Capacity: {0} mech.minespeed = [LIGHT_GRAY]Mining Speed: {0} mech.minepower = [LIGHT_GRAY]Mining Power: {0} @@ -493,9 +507,15 @@ mech.ability = [LIGHT_GRAY]Ability: {0} liquid.heatcapacity = [LIGHT_GRAY]Heat Capacity: {0} liquid.viscosity = [LIGHT_GRAY]Viscosity: {0} liquid.temperature = [LIGHT_GRAY]Temperature: {0} +block.kiln.name = Kiln +block.kiln.description = Smelts sand and lead into metaglass. Requires small amounts of power. +block.graphite-press.name = Graphite Press +block.multi-press.name = Multi-Press block.constructing = {0}\n[LIGHT_GRAY](Constructing) block.spawn.name = Enemy Spawn -block.core.name = Core +block.core-shard.name = Core: Shard +block.core-foundation.name = Core: Foundation +block.core-nucleus.name = Core: Nucleus block.metalfloor.name = Metal Floor block.deepwater.name = deepwater block.water.name = water @@ -514,8 +534,8 @@ block.blackrock.name = blackrock block.icerock.name = icerock block.copper-wall.name = Copper Wall block.copper-wall-large.name = Large Copper Wall -block.dense-alloy-wall.name = Dense Alloy Wall -block.dense-alloy-wall-large.name = Large Dense Alloy Wall +block.titanium-wall.name = Titanium Wall +block.titanium-wall-large.name = Large Titanium Wall block.phase-wall.name = Phase Wall block.phase-wall-large.name = Large Phase Wall block.thorium-wall.name = Thorium Wall @@ -548,17 +568,19 @@ block.separator.name = Separator block.centrifuge.name = Centrifuge block.power-node.name = Power Node block.power-node-large.name = Large Power Node +block.surge-tower.name = Surge Tower block.battery.name = Battery block.battery-large.name = Large Battery block.combustion-generator.name = Combustion Generator block.turbine-generator.name = Turbine Generator +block.differential-generator.name = Differential Generator +block.impact-reactor.name = Impact Reactor block.mechanical-drill.name = Mechanical Drill block.pneumatic-drill.name = Pneumatic Drill block.laser-drill.name = Laser Drill block.water-extractor.name = Water Extractor block.cultivator.name = Cultivator -block.alpha-mech-pad.name = Alpha Mech Pad -block.dart-ship-pad.name = Dart Ship Pad +block.alpha-dart-mech-pad.name = Alpha-Dart 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 @@ -623,7 +645,7 @@ block.rtg-generator.name = RTG Generator block.spectre.name = Spectre block.meltdown.name = Meltdown block.container.name = Container -block.core.description = The most important building in the game. +block.launch-pad.name = Launch Pad team.blue.name = blue team.red.name = red team.orange.name = orange @@ -637,6 +659,7 @@ unit.phantom.name = Phantom Drone unit.phantom.description = An advanced drone unit. Automatically mines ores, collects items and repairs blocks. Significantly more effective than a drone. unit.dagger.name = Dagger unit.dagger.description = A basic ground unit. Useful in swarms. +unit.crawler.name = Crawler unit.titan.name = Titan unit.titan.description = An advanced armored ground unit. Uses carbide as ammo. Attacks both ground and air targets. unit.ghoul.name = Ghoul Bomber @@ -646,7 +669,11 @@ unit.wraith.description = A fast, hit-and-run interceptor unit. unit.fortress.name = Fortress unit.fortress.description = A heavy artillery ground unit. unit.revenant.name = Revenant -unit.revenant.description = A heavy laser platform. +unit.eruptor.name = Eruptor +unit.chaos-array.name = Chaos Array +unit.eradicator.name = Eradicator +unit.lich.name = Lich +unit.reaper.name = Reaper tutorial.begin = Your mission here is to eradicate the[LIGHT_GRAY] enemy[].\n\nBegin by[accent] mining copper[]. Tap a copper ore vein near your core to do this. tutorial.drill = Mining manually is inefficient.\n[accent]Drills []can mine automatically.\nPlace one on a copper vein. tutorial.conveyor = [accent]Conveyors[] are used to transport items to the core.\nMake a line of conveyors from the drill to the core. diff --git a/core/assets/bundles/bundle_it.properties b/core/assets/bundles/bundle_it.properties index fd8af06514..45c352c10a 100644 --- a/core/assets/bundles/bundle_it.properties +++ b/core/assets/bundles/bundle_it.properties @@ -1,5 +1,6 @@ credits.text = Creato da [ROYAL]Anuken[] - [SKY]anukendev@gmail.com[]\n\n[GRAY](Nel caso non te ne sia accorto, la traduzione del gioco non è completa.\n Chi di dovere sta lavorando più velocemente possibile per completarla!) credits = Crediti +contributors = Translators and Contributors discord = Unisciti sul server discord di mindustry! link.discord.description = la chatroom ufficiale del server discord di Mindustry link.github.description = Codice sorgente del gioco @@ -9,15 +10,18 @@ link.itch.io.description = pagina di itch.io con download per PC e versione web link.google-play.description = Elenco di Google Play Store link.wiki.description = wiki ufficiale di Mindustry linkfail = Impossibile aprire il link! L'URL è stato copiato nella tua bacheca. +screenshot = Screenshot saved to {0} gameover = Il nucleo è stato distrutto. gameover.pvp = The[accent] {0}[] team is victorious! -sector.gameover = Hai perso questo settore. Attaccare di nuovo? -sector.retry = Riprova highscore = [YELLOW]Nuovo record! -wave.lasted = Sei sopravvissuto fino all'onda [accent]{0}[]. -level.highscore = Miglior punteggio: [accent]{0} -level.delete.title = Conferma Eliminazione +stat.wave = Waves Defeated:[accent] {0} +stat.enemiesDestroyed = Enemies Destroyed:[accent] {0} +stat.built = Buildings Built:[accent] {0} +stat.destroyed = Buildings Destroyed:[accent] {0} +stat.deconstructed = Buildings Deconstructed:[accent] {0} +stat.delivered = Resources Launched: map.delete = Sei sicuro di voler eliminare questa mappa"[accent]{0}[]"? +level.highscore = Miglior punteggio: [accent]{0} level.select = Selezione del livello level.mode = Modalità di gioco: construction.desktop = Desktop controls have been changed.\nTo deselect a block or stop building, [accent]use space[]. @@ -27,60 +31,36 @@ deconstruction.title = Guida distruzione blocchi deconstruction = Hai appena selezionato la [accent]modalità di distruzione [].\n\nPer iniziare a distruggere, premi sui blocchi interessati.\n Poi premi conferma(✔), e la tua navicella inizierà A INIZIARE\n\n- [accent]Rimuovi i blocchi[] dalla tua selezione cliccandoci sopra.\n- [accent]Per rimuovere più blocchi in un area[] tieni premuto in un punto, poi trascina in modo da selexionare ciò che ti interessa.\n- [accent]Cancella la distruzione[] premendo la X in basso a sinistra. showagain = non mostrare più coreattack = < Il nucleo è sotto attacco! > -unlocks = Sblocchi +nearpoint = [[ [scarlet]LEAVE DROP POINT IMMEDIATELY[] ]\nannihilation imminent +outofbounds = [[ OUT OF BOUNDS ]\n[]self-destruct in {0} +database = Core Database savegame = Salva loadgame = Carica joingame = Unisciti al gioco addplayers = Aggiungi/rimuovi giocatori customgame = Gioco personalizzato -sectors = Settori -sector = Settori Selezionati: [LIGHT_GRAY]{0} -sector.time = Tempo: [LIGHT_GRAY]{0} -sector.deploy = Schiera -sector.abandon = Abandon -sector.abandon.confirm = Are you sure you want to abandon all progress at this sector?\nThis cannot be undone! -sector.resume = Riprendi -sector.locked = [scarlet][[Incomplete] -sector.unexplored = [accent][[Unexplored] -missions = Missions:[LIGHT_GRAY] {0} -mission = Mission:[LIGHT_GRAY] {0} -mission.main = Main Mission:[LIGHT_GRAY] {0} -mission.info = Mission Info -mission.complete = Missione completata! -mission.complete.body = Il settore {0},{1} è stato conquistato. -mission.wave = Sopravvivi a [accent]{0}/{1][] onda/e.Onda in {2} -mission.wave.enemies = Survive[accent] {0}/{1} []waves\n{2} Enemies -mission.wave.enemy = Survive[accent] {0}/{1} []waves\n{2} Enemy -mission.wave.menu = Survive[accent] {0} []waves -mission.battle = Distruggi la base del nemico. -mission.resource.menu = Obtain {0} x{1} -mission.resource = Ottieni {0} x{1} -mission.block = Create {0} -mission.unit = Create {0} Unit -mission.command = Send Command {0} To Units -mission.linknode = Link Power Node -mission.display = [accent]Mission:\n[LIGHT_GRAY]{0} -mission.mech = Switch to mech[accent] {0}[] -mission.create = Create[accent] {0}[] +newgame = New Game none = close = Chiuso quit = Esci maps = Mappe continue = Continua -nextmission = Missione successiva maps.none = [LIGHT_GRAY]Nessuna mappa trovata! about.button = Info name = Nome: +noname = Pick a[accent] player name[] first. filename = File Name: unlocked = Nuovo blocco scoperto! -unlocked.plural = Nuovi blocchi scoperti! +completed = [accent]Completed +techtree = Tech Tree +research.list = [LIGHT_GRAY]Research: +research = Research +researched = [LIGHT_GRAY]{0} researched. players = {0} giocatori online players.single = {0} giocatori online server.closing = [accent]Chiusura server ... server.kicked.kick = Sei stato cacciato dal server! server.kicked.serverClose = Server chiuso. -server.kicked.sectorComplete = Settore completato. -server.kicked.sectorComplete.text = La tua misione è completata.\nOra il server continuerà al settore successivo. server.kicked.clientOutdated = Versione del client obsoleta! Aggiorna il tuo gioco! server.kicked.serverOutdated = Server obsoleto! Chiedi all'host di aggiornare! server.kicked.banned = Sei bannato da questo server. @@ -89,6 +69,7 @@ server.kicked.nameInUse = C'è già qualcuno con il tuo nome\nsu questo server. server.kicked.nameEmpty = Il tuo nome deve contenere almeno un carattere. server.kicked.idInUse = Sei già su questo server! Non è permesso connettersi con due account. server.kicked.customClient = Questo server non supporta le build personalizzate. Scarica la versione ufficiale dal sito. +server.kicked.gameover = Game over! host.info = Il pulsante [accent]hos [] ospita un server sulle porte [scarlet]6567[] e [scarlet]656.[] Chiunque sulla stessa [LIGHT_GRAY]connessione wifi o rete locale[] dovrebbe essere in grado di vedere il proprio server nel proprio elenco server.\n\n Se vuoi che le persone siano in grado di connettersi ovunque tramite IP, è richiesto il [accent]port forwarding[]. \n\n[LIGHT_GRAY]Nota: se qualcuno sta riscontrando problemi durante la connessione al gioco LAN, assicurati di aver consentito a Mindustry di accedere alla rete locale nelle impostazioni del firewall. join.info = Qui è possibile inserire un [accent]IP del server[] a cui connettersi, o scoprire [accento]un server sulla rete locale[] disponibile.\n Sono supportati sia il multiplayer LAN che WAN. \n\n[LIGHT_GRAY]Nota: non esiste un elenco di server globali automatici; se si desidera connettersi a qualcuno tramite IP, è necessario chiedere all'host il proprio IP. hostserver = Host Server @@ -159,7 +140,6 @@ save.rename.text = Nuovo nome: selectslot = Seleziona un salvataggio. slot = [accent]Slot {0} save.corrupted = [orang]Salvataggio corrotto o non valido! -sector.corrupted = [accent]Un file per questo settore è stato trovato, ma è fallito il caricamnto.\nQuindi ne è stato creato uno nuovo. empty = on = On off = Off @@ -169,6 +149,7 @@ save.wave = Ondata: {0} save.difficulty = Difficoltà: {0} save.date = Ultimo salvataggio: {0} save.playtime = Tempo di gioco: {0} +warning = Warning. confirm = Conferma delete = Elimina ok = OK @@ -259,6 +240,17 @@ tutorial = Tutorial editor = Editor mapeditor = Editor Mappe donate = Dona +abandon = Abandon +abandon.text = This zone and all its resources will be lost to the enemy. +locked = Locked +complete = [LIGHT_GRAY]Complete: +resume = Resume Zone:\n[LIGHT_GRAY]{0} +bestwave = [LIGHT_GRAY]Best: {0} +launch = Launch +launch.title = Launch Successful +launch.next = [LIGHT_GRAY]next opportunity at wave {0} +launch.unable = [scarlet]Unable to LAUNCH.[] Enemies. +zone.unlocked = [LIGHT_GRAY]{0} unlocked. connectfail = [crimson] Impossibile connettersi al server: [accent] {0} error.unreachable = Server unreachable. error.invalidaddress = Invalid address. @@ -266,7 +258,20 @@ error.timedout = Timed out!\nMake sure the host has port forwarding set up, and error.mismatch = Packet error:\npossible client/server version mismatch.\nMake sure you and the host have the latest version of Mindustry! error.alreadyconnected = Already connected. error.mapnotfound = Map file not found! +error.io = Network I/O error. error.any = Unkown network error. +zone.groundZero.name = Ground Zero +zone.craters.name = The Craters +zone.frozenForest.name = Frozen Forest +zone.ruinousShores.name = Ruinous Shores +zone.crags.name = Crags +zone.stainedMountains.name = Stained Mountains +zone.impact0079.name = Impact 0079 +zone.desolateRift.name = Desolate Rift +zone.arcticDesert.name = Arctic Desert +zone.dryWastes.name = Dry Wastes +zone.nuclearComplex.name = Nuclear Production Complex +zone.moltenFault.name = Molten Fault settings.language = Lingua settings.reset = Resetta Alle Impostazioni Predefinite settings.rebind = Reinposta @@ -277,7 +282,6 @@ settings.graphics = Grafica settings.cleardata = Clear Game Data... settings.clear.confirm = Are you sure you want to clear this data?\nWhat is done cannot be undone! settings.clearall.confirm = [scarlet]WARNING![]\nThis will clear all data, including saves, maps, unlocks and keybinds.\nOnce you press 'ok' the game will wipe all data and automatically exit. -settings.clearsectors = Clear Sectors settings.clearunlocks = Clear Unlocks settings.clearall = Clear All paused = In pausa @@ -316,12 +320,15 @@ blocks.liquidoutput = Uscita liquidi blocks.liquidoutputspeed = Liquid Output Speed blocks.liquiduse = Uso liquidi blocks.coolant = Refrigerante +blocks.liquid = Liquid blocks.coolantuse = uso refrigerante blocks.inputliquidfuel = carburante liquido blocks.liquidfueluse = Utilizzo carburante liquido blocks.boostitem = Boost Item blocks.boostliquid = Boost Liquid blocks.health = Salute +blocks.power = Power +blocks.power.satisfaction = Power Satisfaction blocks.inaccuracy = Inaccuratezza blocks.shots = Colpi blocks.reload = Ricarica @@ -346,6 +353,7 @@ category.items = Oggetti category.crafting = Produzione category.shooting = Potenza di fuoco category.optional = Optional Enhancements +setting.indicators.name = Ally Indicators setting.autotarget.name = Auto-Target setting.fpscap.name = Limite FPS setting.fpscap.none = Niente @@ -378,11 +386,15 @@ category.multiplayer.name = Multigiocatore command.attack = Attack command.retreat = Retreat command.patrol = Patrol +keybind.gridMode.name = Block Select +keybind.gridModeShift.name = Category Select keybind.press = Press a key... keybind.press.axis = Press an axis or key... +keybind.screenshot.name = Map Screenshot keybind.move_x.name = Sposta_x keybind.move_y.name = Sposta_y keybind.select.name = seleziona +keybind.pick.name = Pick Block keybind.break.name = rompi keybind.deselect.name = Deselect keybind.shoot.name = spara @@ -402,29 +414,28 @@ keybind.chat_scroll.name = Scorri chat keybind.drop_unit.name = droppa materiali keybind.zoom_minimap.name = Zomma minimappa mode.help.title = Descrizione delle modalità -mode.waves.name = ondate -mode.waves.description = modalità normale. risorse limitate e ondate automatiche. +mode.survival.name = Survival +mode.survival.description = The normal mode. Limited resources and automatic incoming waves. mode.sandbox.name = Sandbox mode.sandbox.description = risorse infinite e nessun timer per le ondate. mode.freebuild.name = freebuild mode.freebuild.description = risorse limitate e nessun timer per le ondate. mode.pvp.name = PvP mode.pvp.description = fight against other players locally. +mode.attack.name = Attack +mode.attack.descrption = No waves, with the goal to destroy the enemy base. content.item.name = Oggetti content.liquid.name = Liquidi content.unit.name = Units -content.recipe.name = Blocchi +content.block.name = Blocks content.mech.name = Mech -item.stone.name = pietra -item.stone.description = UN materiale grezzo molto comune, che solitamente viene rifinito per ottenerne degli altri. item.copper.name = Rame item.copper.description = Una utile materiale styrutturale. Molto usato in tutti i blocchi. item.lead.name = Piombo item.lead.description = Un materiale base, molto usato nei blocchi di trasporto. item.coal.name = carbone item.coal.description = Un carburante comune e facilmente ottenibile. -item.dense-alloy.name = LEga ad alta densità -item.dense-alloy.description = Una lega molto pesante composta da piombo e rame. utilizzato in blocchi di trasporto e trapani avanzati. +item.graphite.name = Graphite item.titanium.name = titanio item.titanium.description = Un raro metallo super leggero usato ampiamente nel trasporto di liquidi, trapani e navi. item.thorium.name = Torio @@ -445,6 +456,10 @@ item.blast-compound.name = Polvere esplosiva item.blast-compound.description = Un composto altamente volatile, utilizzato nella produzione di bombe ed esplosivi. Può essere utilizzato come combustibile anche se non è consigliato. item.pyratite.name = Pirite item.pyratite.description = Una sostanza molto infiammabile che viene utilizzata nelle armi a fuoco. +item.metaglass.name = Metaglass +item.metaglass.description = A super-tough glass compound. Extensively used for liquid distribution and storage. +item.scrap.name = Scrap +item.scrap.description = Leftover remnants of old structures and units. Contains trace amounts of many different metals. liquid.water.name = acqua liquid.lava.name = lava liquid.oil.name = petrolio @@ -481,11 +496,10 @@ mech.glaive-ship.weapon = Ripetitore di fiamma item.explosiveness = [LIGHT_GRAY]Esplosività: {0} item.flammability = [LIGHT_GRAY]Infiammabilità: {0} item.radioactivity = [LIGHT_GRAY]Radioattività: {0} -item.fluxiness = [LIGHT_GRAY]Portata: {0} unit.health = [LIGHT_GRAY]Vita: {0} unit.speed = [LIGHT_GRAY]Velocità: {0} mech.weapon = [LIGHT_GRAY]Armi: {0} -mech.armor = [LIGHT_GRAY]Protezione: {0} +mech.health = [LIGHT_GRAY]Health: {0} mech.itemcapacity = [LIGHT_GRAY]Capacità oggetti: {0} mech.minespeed = [LIGHT_GRAY]Velocità di scavo: {0} mech.minepower = [LIGHT_GRAY]Potenza di scavo: {0} @@ -493,9 +507,15 @@ mech.ability = [LIGHT_GRAY]Abilità: {0} liquid.heatcapacity = [LIGHT_GRAY]Capacità calorifica: {0} liquid.viscosity = [LIGHT_GRAY]Viscosità: {0} liquid.temperature = [LIGHT_GRAY]Temperatura: {0} +block.kiln.name = Kiln +block.kiln.description = Smelts sand and lead into metaglass. Requires small amounts of power. +block.graphite-press.name = Graphite Press +block.multi-press.name = Multi-Press block.constructing = {0}\n[LIGHT_GRAY](Constructing) block.spawn.name = Enemy Spawn -block.core.name = Nucleo +block.core-shard.name = Core: Shard +block.core-foundation.name = Core: Foundation +block.core-nucleus.name = Core: Nucleus block.metalfloor.name = Pavimento di ferro block.deepwater.name = acqua profonda block.water.name = acqua @@ -514,8 +534,8 @@ block.blackrock.name = roccia nera block.icerock.name = roccia di ghiaccio block.copper-wall.name = Muro di rame block.copper-wall-large.name = Muro grande di rame -block.dense-alloy-wall.name = Dense Alloy Wall -block.dense-alloy-wall-large.name = Large Dense Alloy Wall +block.titanium-wall.name = Titanium Wall +block.titanium-wall-large.name = Large Titanium Wall block.phase-wall.name = Muro di fase block.phase-wall-large.name = Muro grande di fase block.thorium-wall.name = Muro di torio @@ -548,17 +568,19 @@ block.separator.name = Separatore block.centrifuge.name = Centrifugatore block.power-node.name = Snodo energetico block.power-node-large.name = Snodo energetico grande +block.surge-tower.name = Surge Tower block.battery.name = Batteria block.battery-large.name = Batteria grossa block.combustion-generator.name = generatore a carbone block.turbine-generator.name = Turbina +block.differential-generator.name = Differential Generator +block.impact-reactor.name = Impact Reactor block.mechanical-drill.name = Trapano meccanico block.pneumatic-drill.name = Trapano pneumatico block.laser-drill.name = Estrattore laser block.water-extractor.name = Estrattore d'acqua block.cultivator.name = Coltivatore -block.alpha-mech-pad.name = Alpha Mech Pad -block.dart-ship-pad.name = Dart Ship Pad +block.alpha-dart-mech-pad.name = Alpha-Dart 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 @@ -623,7 +645,7 @@ block.rtg-generator.name = RTG Generator block.spectre.name = Spectre block.meltdown.name = Meltdown block.container.name = Container -block.core.description = The most important building in the game. +block.launch-pad.name = Launch Pad team.blue.name = blue team.red.name = red team.orange.name = orange @@ -637,6 +659,7 @@ unit.phantom.name = Phantom Drone unit.phantom.description = An advanced drone unit. Automatically mines ores, collects items and repairs blocks. Significantly more effective than a drone. unit.dagger.name = Pericolo unit.dagger.description = Un unità terrena base, molto più efficiente se in branco. +unit.crawler.name = Crawler unit.titan.name = Titano unit.titan.description = Un'unità di terra corazzata avanzata. Utilizza carburo come munizione. Attacca sia bersagli terrestri che aerei. unit.ghoul.name = Ghoul Bomber @@ -646,7 +669,11 @@ unit.wraith.description = A fast, hit-and-run interceptor unit. unit.fortress.name = Fortress unit.fortress.description = A heavy artillery ground unit. unit.revenant.name = Revenant -unit.revenant.description = A heavy laser platform. +unit.eruptor.name = Eruptor +unit.chaos-array.name = Chaos Array +unit.eradicator.name = Eradicator +unit.lich.name = Lich +unit.reaper.name = Reaper tutorial.begin = Your mission here is to eradicate the[LIGHT_GRAY] enemy[].\n\nBegin by[accent] mining copper[]. Tap a copper ore vein near your core to do this. tutorial.drill = Mining manually is inefficient.\n[accent]Drills []can mine automatically.\nPlace one on a copper vein. tutorial.conveyor = [accent]Conveyors[] are used to transport items to the core.\nMake a line of conveyors from the drill to the core. diff --git a/core/assets/bundles/bundle_ja.properties b/core/assets/bundles/bundle_ja.properties index 194daffbf4..7743cb1dce 100644 --- a/core/assets/bundles/bundle_ja.properties +++ b/core/assets/bundles/bundle_ja.properties @@ -13,13 +13,15 @@ linkfail = リンクを開けませんでした!\nURLをクリップボードに screenshot = スクリーンショットを {0} に保存しました。 gameover = ゲームオーバー gameover.pvp = [accent] {0}[] チームの勝利! -sector.gameover = この区域は敗北しました。 再配備しますか? -sector.retry = リトライ highscore = [accent]ハイスコアを記録! -wave.lasted = あなたはウェーブ[accent]{0}[]まで続きました。 -level.highscore = ハイスコア: [accent]{0} -level.delete.title = 削除の確認 +stat.wave = Waves Defeated:[accent] {0} +stat.enemiesDestroyed = Enemies Destroyed:[accent] {0} +stat.built = Buildings Built:[accent] {0} +stat.destroyed = Buildings Destroyed:[accent] {0} +stat.deconstructed = Buildings Deconstructed:[accent] {0} +stat.delivered = Resources Launched: map.delete = マップ "[accent]{0}[]" を削除してもよろしいですか? +level.highscore = ハイスコア: [accent]{0} level.select = レベル選択 level.mode = ゲームモード: construction.desktop = ブロックの選択や建設を止めるには、[accent]スペースを使用[]してください。 @@ -29,61 +31,36 @@ deconstruction.title = ブロック撤去ガイド deconstruction = [accent]ブロック撤去モード[]になりました。\n\nブロックを撤去するには、機体の近くのブロックをタップしてください。\nブロックを選択した状態で、チェックボタンを押して確認すると、機体がブロックの撤去を始めます。\n\n- [accent]ブロックを撤去[]するには、タップして範囲を選択してください。\n- [accent]範囲を選択してブロックを撤去[]するには、 タップで空いている場所を長押しして、伸ばしたい方向にドラッグしてください\n- [accent]撤去や範囲選択をキャンセル[]するには、左下の X ボタンを押してください。 showagain = 次回以降表示しない coreattack = < コアが攻撃を受けています! > -unlocks = アンロック +nearpoint = [[ [scarlet]LEAVE DROP POINT IMMEDIATELY[] ]\nannihilation imminent +outofbounds = [[ OUT OF BOUNDS ]\n[]self-destruct in {0} +database = Core Database savegame = ゲームを保存 loadgame = ゲームを読み込む joingame = ゲームに参加 addplayers = プレイヤーを追加/削除 customgame = カスタムゲーム -sectors = 区域 -sector = 区域: [LIGHT_GRAY]{0} -sector.time = 時間: [LIGHT_GRAY]{0} -sector.deploy = 配備 -sector.abandon = 撤退 -sector.abandon.confirm = 区域のすべての進行を撤退します。\nこれは元に戻すことはできません! -sector.resume = 再開 -sector.locked = [scarlet][[不完全] -sector.unexplored = [accent][[未調査] -missions = ミッション:[LIGHT_GRAY] {0} -mission = ミッション:[LIGHT_GRAY] {0} -mission.main = メインミッション:[LIGHT_GRAY] {0} -mission.info = ミッション情報 -mission.complete = ミッション完了! -mission.complete.body = 区域 {0},{1} を征服しました。 -mission.wave = 残り[accent] {0}/{1} []ウェーブ\n次のウェーブまで {2} -mission.wave.enemies = 残り[accent] {0}/{1} []ウェーブ\n敵の残り {2} 体 -mission.wave.enemy = 残り[accent] {0}/{1} []ウェーブ\n敵の残り {2} 体 -mission.wave.menu = 残り[accent] {0}[] ウェーブ -mission.battle = 敵のコアを破壊する -mission.resource.menu = {0} を{1}個を入手する -mission.resource = {0} を入手する :\n[accent]{1}/{2}[] -mission.block = {0} を作る -mission.unit = ユニット {0} を作る -mission.command = ユニットに {0} を命令する -mission.linknode = 電源ノードを接続する -mission.display = [accent]ミッション:\n[LIGHT_GRAY]{0} -mission.mech = 機体を[accent]{0}[]に乗り換える -mission.create = [accent]{0}[] を作る +newgame = New Game none = <なし> close = 閉じる quit = 終了 maps = マップ continue = 続ける -nextmission = 次のミッションへ maps.none = [LIGHT_GRAY]マップが存在しません! about.button = About name = 名前: noname = 先に[accent]プレイヤー名[]を決めてください。 filename = ファイル名: unlocked = 新しいブロックをアンロック! -unlocked.plural = 新しいブロックをアンロック! +completed = [accent]Completed +techtree = Tech Tree +research.list = [LIGHT_GRAY]Research: +research = Research +researched = [LIGHT_GRAY]{0} researched. players = {0} 人がオンライン players.single = {0} 人がオンライン server.closing = [accent]サーバーを閉じています... server.kicked.kick = サーバからキックされました! server.kicked.serverClose = サーバーが閉じました。 -server.kicked.sectorComplete = 区域を制覇しました。 -server.kicked.sectorComplete.text = ミッションが完了しました。\nサーバーは次の区域に移ります。 server.kicked.clientOutdated = 古いクライアントです! ゲームをアップデートしてください! server.kicked.serverOutdated = 古いサーバーです! ホストに更新してもらってください! server.kicked.banned = サーバーからBanされています。 @@ -92,6 +69,7 @@ server.kicked.nameInUse = このサーバーでは、\nその名前はすでに server.kicked.nameEmpty = 無効な名前です。 server.kicked.idInUse = すでにサーバーに参加しています。! 二つのアカウントでの接続は許可されていません。 server.kicked.customClient = このサーバーはカスタムビルドをサポートしていません。公式版をダウンロードしてください。 +server.kicked.gameover = Game over! host.info = [accent]ホスト[]ボタンを押すと、ポート[scarlet]6567[]でサーバーが開かれます。同じ[LIGHT_GRAY]Wifi や ローカルネットワーク[]からはサーバーリストで見ることができます。\n\nIPアドレスからどこからでもアクセスできるようにするには、[accent]ポート開放[]する必要があります。\n\n[LIGHT_GRAY]注意:: LAN上のゲームで接続できない場合、Mindustryがファイアウォールの設定でローカルネットワークに接続が許可されているか確認してください。 join.info = ここでは、[accent]サーバーのIPアドレス[]から接続したり、[accent]ローカルネットワーク[]のサーバーを探すことができます。\nLANとWANの両方のマルチプレイに対応しています。\n\n[LIGHT_GRAY]注意:グローバルサーバーリストはありません。誰かのサーバーにIPで接続したい場合、ホストにIPをお尋ねください。 hostserver = ゲームをホスト @@ -162,7 +140,6 @@ save.rename.text = 新しい名前: selectslot = セーブデータを選択 slot = [accent]スロット {0} save.corrupted = [accent]セーブファイルが無効、または破損しました!\nゲームのアップデート直後の場合、恐らくセーブデータのフォーマットの変更によるもので、バグではありません。 -sector.corrupted = [accent]区域のセーブファイルが見つかりましたが、読み込みに失敗しました。\n新しく区域がが作成されます。 empty = <空> on = オン off = オフ @@ -172,6 +149,7 @@ save.wave = ウェーブ {0} save.difficulty = 難易度: {0} save.date = 最終保存: {0} save.playtime = プレイ時間: {0} +warning = Warning. confirm = 確認 delete = 削除 ok = OK @@ -262,6 +240,17 @@ tutorial = チュートリアル editor = エディター mapeditor = マップエディター donate = 寄附 +abandon = Abandon +abandon.text = This zone and all its resources will be lost to the enemy. +locked = Locked +complete = [LIGHT_GRAY]Complete: +resume = Resume Zone:\n[LIGHT_GRAY]{0} +bestwave = [LIGHT_GRAY]Best: {0} +launch = Launch +launch.title = Launch Successful +launch.next = [LIGHT_GRAY]next opportunity at wave {0} +launch.unable = [scarlet]Unable to LAUNCH.[] Enemies. +zone.unlocked = [LIGHT_GRAY]{0} unlocked. connectfail = [crimson]サーバーへの接続できませんでした:\n\n[accent]{0} error.unreachable = サーバーに到達できません。\nアドレスは正しいですか? error.invalidaddress = 無効なアドレスです。 @@ -269,7 +258,20 @@ error.timedout = タイムアウトしました!\nホストがポート開放さ error.mismatch = パケットエラー:\nクライアント/サーバーのバージョンが一致しません。\nゲームとホストが最新のMindustryか確認してください! error.alreadyconnected = すでに接続されています。 error.mapnotfound = マップファイルが見つかりません! +error.io = Network I/O error. error.any = 不明なネットワークエラーです。 +zone.groundZero.name = Ground Zero +zone.craters.name = The Craters +zone.frozenForest.name = Frozen Forest +zone.ruinousShores.name = Ruinous Shores +zone.crags.name = Crags +zone.stainedMountains.name = Stained Mountains +zone.impact0079.name = Impact 0079 +zone.desolateRift.name = Desolate Rift +zone.arcticDesert.name = Arctic Desert +zone.dryWastes.name = Dry Wastes +zone.nuclearComplex.name = Nuclear Production Complex +zone.moltenFault.name = Molten Fault settings.language = 言語 settings.reset = デフォルトにリセット settings.rebind = 再設定 @@ -280,7 +282,6 @@ settings.graphics = グラフィック settings.cleardata = データを削除... settings.clear.confirm = データを削除してもよろしいですか?\n元に戻すことはできません! settings.clearall.confirm = [scarlet]警告![]\nこれはすべてのデータが削除されます。これにはセーブデータ、マップ、アンロック、キーバインドが含まれます。\n「ok」 を押すと、すべてのデータが削除され、自動的に終了します。 -settings.clearsectors = 区域を削除 settings.clearunlocks = アンロックを削除 settings.clearall = すべてを削除 paused = [accent]< ポーズ > @@ -319,12 +320,15 @@ blocks.liquidoutput = 搬出液体 blocks.liquidoutputspeed = 液体搬出速度 blocks.liquiduse = 液体使用量 blocks.coolant = 冷却 +blocks.liquid = Liquid blocks.coolantuse = 冷却使用量 blocks.inputliquidfuel = 液体燃料 blocks.liquidfueluse = 液体燃料使用量 blocks.boostitem = 加速アイテム blocks.boostliquid = 加速液体 blocks.health = 耐久値 +blocks.power = Power +blocks.power.satisfaction = Power Satisfaction blocks.inaccuracy = 精度のずれ blocks.shots = ショット blocks.reload = ショット/秒 @@ -390,6 +394,7 @@ keybind.screenshot.name = スクリーンショット keybind.move_x.name = 左右移動 keybind.move_y.name = 上下移動 keybind.select.name = 選択/ショット +keybind.pick.name = Pick Block keybind.break.name = 破壊 keybind.deselect.name = 選択解除 keybind.shoot.name = ショット @@ -409,8 +414,8 @@ keybind.chat_scroll.name = チャットスクロール keybind.drop_unit.name = ドロップユニット keybind.zoom_minimap.name = ミニマップのズーム mode.help.title = モード説明 -mode.waves.name = ウェーブ -mode.waves.description = 通常モードです。限られた資源の中でウェーブが自動的に進行します。 +mode.survival.name = Survival +mode.survival.description = The normal mode. Limited resources and automatic incoming waves. mode.sandbox.name = サンドボックス mode.sandbox.description = 無限の資源でウェーブを自由に進行できます。 mode.freebuild.name = フリービルド @@ -422,18 +427,15 @@ mode.attack.descrption = ウェーブはなく、敵基地の破壊を目指し content.item.name = アイテム content.liquid.name = 液体 content.unit.name = ユニット -content.recipe.name = ブロック +content.block.name = Blocks content.mech.name = 機体 -item.stone.name = 石 -item.stone.description = 基本的な原材料です。他の材料を分離したり、精製や溶岩を溶かしたりするのに使用します。 item.copper.name = 銅 item.copper.description = 便利な鉱石です。様々なブロックの材料として幅広く使われています。 item.lead.name = 鉛 item.lead.description = 一般的で手軽な鉱石です。機械や液体輸送ブロックなどに使われます。 item.coal.name = 石炭 item.coal.description = 一般的で有用な燃料です。 -item.dense-alloy.name = 高密度合金 -item.dense-alloy.description = 銅と鉛でできた丈夫な合金です。高性能な輸送ブロックやドリルに使われます。 +item.graphite.name = Graphite item.titanium.name = チタン item.titanium.description = 希少で非常に軽量な金属です。液体輸送やドリル、航空機などで使われます。 item.thorium.name = トリウム @@ -454,6 +456,10 @@ item.blast-compound.name = 爆発性化合物 item.blast-compound.description = 爆弾や爆発物に使われる揮発性の化合物です。燃料として燃やすこともできますが、お勧めしません。 item.pyratite.name = ピラタイト item.pyratite.description = 兵器などに使われる非常に燃えやすい物質です。 +item.metaglass.name = Metaglass +item.metaglass.description = A super-tough glass compound. Extensively used for liquid distribution and storage. +item.scrap.name = Scrap +item.scrap.description = Leftover remnants of old structures and units. Contains trace amounts of many different metals. liquid.water.name = 水 liquid.lava.name = 溶岩 liquid.oil.name = 石油 @@ -490,11 +496,10 @@ mech.glaive-ship.weapon = 焼夷弾 item.explosiveness = [LIGHT_GRAY]爆発性: {0}% item.flammability = [LIGHT_GRAY]可燃性: {0}% item.radioactivity = [LIGHT_GRAY]放射能: {0}% -item.fluxiness = [LIGHT_GRAY]流動性: {0}% unit.health = [LIGHT_GRAY]耐久値: {0} unit.speed = [LIGHT_GRAY]速度: {0} mech.weapon = [LIGHT_GRAY]武器: {0} -mech.armor = [LIGHT_GRAY]装備: {0} +mech.health = [LIGHT_GRAY]Health: {0} mech.itemcapacity = [LIGHT_GRAY]アイテム容量: {0} mech.minespeed = [LIGHT_GRAY]採掘速度: {0} mech.minepower = [LIGHT_GRAY]採掘力: {0} @@ -502,9 +507,15 @@ mech.ability = [LIGHT_GRAY]能力: {0} liquid.heatcapacity = [LIGHT_GRAY]熱容量: {0} liquid.viscosity = [LIGHT_GRAY]粘度: {0} liquid.temperature = [LIGHT_GRAY]温度: {0} +block.kiln.name = Kiln +block.kiln.description = Smelts sand and lead into metaglass. Requires small amounts of power. +block.graphite-press.name = Graphite Press +block.multi-press.name = Multi-Press block.constructing = {0}\n[LIGHT_GRAY](建設中) block.spawn.name = エネミースポーン -block.core.name = コア +block.core-shard.name = Core: Shard +block.core-foundation.name = Core: Foundation +block.core-nucleus.name = Core: Nucleus block.metalfloor.name = 金属製の床 block.deepwater.name = 深層水 block.water.name = 水 @@ -523,8 +534,8 @@ block.blackrock.name = 黒い岩 block.icerock.name = 氷岩 block.copper-wall.name = 銅の壁 block.copper-wall-large.name = 大きな銅の壁 -block.dense-alloy-wall.name = 高密度合金の壁 -block.dense-alloy-wall-large.name = 大きな高密度合金の壁 +block.titanium-wall.name = Titanium Wall +block.titanium-wall-large.name = Large Titanium Wall block.phase-wall.name = フェーズファイバーの壁 block.phase-wall-large.name = 大きなフェーズファイバーの壁 block.thorium-wall.name = トリウムの壁 @@ -557,17 +568,19 @@ block.separator.name = 分離機 block.centrifuge.name = 遠心分離機 block.power-node.name = 電源ノード block.power-node-large.name = 大型電源ノード +block.surge-tower.name = Surge Tower block.battery.name = バッテリー block.battery-large.name = 大型バッテリー block.combustion-generator.name = 火力発電機 block.turbine-generator.name = タービン発電機 +block.differential-generator.name = Differential Generator +block.impact-reactor.name = Impact Reactor block.mechanical-drill.name = 機械ドリル block.pneumatic-drill.name = 空気圧ドリル block.laser-drill.name = レーザードリル block.water-extractor.name = ウォーターポンプ block.cultivator.name = 耕作機 -block.alpha-mech-pad.name = アルファパッド -block.dart-ship-pad.name = ダーツパッド +block.alpha-dart-mech-pad.name = Alpha-Dart Mech Pad block.delta-mech-pad.name = デルタパッド block.javelin-ship-pad.name = ジャベリンパッド block.trident-ship-pad.name = トライデントパッド @@ -632,7 +645,7 @@ block.rtg-generator.name = RTG発電機 block.spectre.name = スペクター block.meltdown.name = メルトダウン block.container.name = コンテナー -block.core.description = ゲームで最も重要な建物です。 +block.launch-pad.name = Launch Pad team.blue.name = ブルー team.red.name = レッド team.orange.name = オレンジ @@ -646,6 +659,7 @@ unit.phantom.name = ファントムドローン unit.phantom.description = 強化されたユニットです。自動で鉱石の採掘やブロックの修理をします。スピリットドローンよりも効率的に行います。 unit.dagger.name = ダガー unit.dagger.description = 一般的な地上ユニットです。集団になると便利です。 +unit.crawler.name = Crawler unit.titan.name = タイタン unit.titan.description = 強化された地上戦闘ユニットです。地上と空の敵の両方に攻撃します。 unit.ghoul.name = グール爆撃機 @@ -655,7 +669,11 @@ unit.wraith.description = 高速な攻撃機ユニットです。 unit.fortress.name = フォートレス unit.fortress.description = 砲撃地上ユニットです。 unit.revenant.name = レベナント -unit.revenant.description = レーザープラットフォームです。 +unit.eruptor.name = Eruptor +unit.chaos-array.name = Chaos Array +unit.eradicator.name = Eradicator +unit.lich.name = Lich +unit.reaper.name = Reaper tutorial.begin = ここでのミッションは[LIGHT_GRAY]敵[]を倒すことです。\n\nまずは、[accent]銅の採掘[]から始めましょう。コアの近くの銅鉱石の鉱脈をタップしましょう。 tutorial.drill = 手動で採掘するのは非効率的です。\n[accent]ドリル[]を使えば自動で採掘できます。\n銅鉱石の鉱脈の上に1つ置いてみましょう。 tutorial.conveyor = [accent]コンベアー[]はコアにアイテムを輸送することができます。\nドリルからコアまでコンベアー作りましょう。 diff --git a/core/assets/bundles/bundle_ko.properties b/core/assets/bundles/bundle_ko.properties index 535cd8481f..8e4ea16128 100644 --- a/core/assets/bundles/bundle_ko.properties +++ b/core/assets/bundles/bundle_ko.properties @@ -1,5 +1,6 @@ credits.text = Created by [ROYAL]Anuken[] - [SKY]anukendev@gmail.com[]\n\n[GRAY](In case you can't tell, this text is currently unfinished.\nTranslators, don't edit it yet!) credits = 제작자 +contributors = Translators and Contributors discord = Mindustry Discord 에 참여하세요! link.discord.description = 공식 Mindustry Discord 채팅방 link.github.description = 게임 소스코드 @@ -9,15 +10,18 @@ link.itch.io.description = PC 버전 다운로드와 HTML5 버전이 있는 itch link.google-play.description = Google Play 스토어 정보 link.wiki.description = 공식 Mindustry 위키 (영어) linkfail = 링크를 여는데 실패했습니다! URL이 기기의 클립보드에 복사되었습니다. +screenshot = Screenshot saved to {0} gameover = 코어가 터졌습니다. 게임 오버! gameover.pvp = [accent]{0}[] 팀이 승리했습니다! -sector.gameover = 이 지역을 공략하는데 실패했습니다. 다시 시도하시겠습니까? -sector.retry = 아니오 highscore = [YELLOW]최고점수 달성! -wave.lasted = [accent]{0}[] 까지 버티셨습니다. -level.highscore = 최고 점수 : [accent]{0} -level.delete.title = 삭제 확인 +stat.wave = Waves Defeated:[accent] {0} +stat.enemiesDestroyed = Enemies Destroyed:[accent] {0} +stat.built = Buildings Built:[accent] {0} +stat.destroyed = Buildings Destroyed:[accent] {0} +stat.deconstructed = Buildings Deconstructed:[accent] {0} +stat.delivered = Resources Launched: map.delete = 정말로 "[accent]{0}[]" 맵을 삭제하시겠습니까? +level.highscore = 최고 점수 : [accent]{0} level.select = 맵 선택 level.mode = 게임모드 : construction.desktop = PC 에서의 조작 방법이 변경되었습니다.\n블록 선택을 해제하거나 건설을 중지하려면 [accent]스페이스 바[]를 누르세요. @@ -27,60 +31,36 @@ deconstruction.title = 블록 삭제 안내서 deconstruction = [accent]블록 삭제 모드[]를 선택하셨습니다\n\n블록을 삭제하고 싶다면, 자신의 건설 가능 범위 내에서 간단히 탭 하면 됩니다.\n일부 블록을 선택한 후에 확인 버튼을 누르면 배가 파괴 작업을 진행할 것입니다.\n\n- [accent]블록을 삭제[]하고 싶다면 배치하고 싶은 영역을 탭 하세요\n- [accent]블록을 넓은 범위로 삭제[]하고 싶다면 배치하고 싶은 시작 영역을 길게 누르며 드래그 하면 됩니다.\n- [accent]블록 삭제 모드를 취소[]하고 싶다면 화면 하단 왼쪽에 있는 X 버튼을 누르면 됩니다. showagain = 다음 세션에서 이 메세지를 표시하지 않습니다 coreattack = < 코어가 공격받고 있습니다! > -unlocks = 아이템들 +nearpoint = [[ [scarlet]LEAVE DROP POINT IMMEDIATELY[] ]\nannihilation imminent +outofbounds = [[ OUT OF BOUNDS ]\n[]self-destruct in {0} +database = Core Database savegame = 게임 저장 loadgame = 게임 불러오기 joingame = 멀티플레이 addplayers = 플레이어 추가/제거 customgame = 커스텀 게임 -sectors = 지역 플레이 -sector = 지역 : [LIGHT_GRAY]{0} -sector.time = 시간 : [LIGHT_GRAY]{0} -sector.deploy = 시작 -sector.abandon = 초기화 -sector.abandon.confirm = 정말로 이 지역의 모든 진행상황을 초기화 하겠습니까?\n이 작업은 되돌릴 수 없습니다! -sector.resume = 계속하기 -sector.locked = [scarlet][[완료안됨] -sector.unexplored = [accent][[탐색안됨] -missions = 목표 : [LIGHT_GRAY] {0} -mission = 목표 : [LIGHT_GRAY] {0} -mission.main = 주요 목표 : [LIGHT_GRAY]{0} -mission.info = 미션 정보 -mission.complete = 미션 성공! -mission.complete.body = 지역 {0},{1} 클리어. -mission.wave = [accent]{0}/{1}[] 단계 생존\n{2}초 남음 -mission.wave.enemies = [accent]{0}/{1} []단계 생존\n{2}마리 남음 -mission.wave.enemy = [accent]{0}/{1} []단계 생존\n{2}마리 남음 -mission.wave.menu = [accent]{0}[] 단계 -mission.battle = 적 코어를 파괴하세요 -mission.resource.menu = {0} {1}개 수집 -mission.resource = {0} 을(를) 수집하세요\n[accent]{1}/{2} -mission.block = {0} 를 만드세요 -mission.unit = {0} 유닛을 만드세요 -mission.command = 유닛에게 {0} 명령을 보내세요 -mission.linknode = 전력 노드를 연결하세요 -mission.display = [accent]목표 : [LIGHT_GRAY]{0} -mission.mech = [accent]{0}[] 기체로 바꾸세요 -mission.create = [accent]{0}[] 을(를)설치하세요. +newgame = New Game none = <없음> close = 닫기 quit = 나가기 maps = 맵 continue = 계속하기 -nextmission = 다음 임무 maps.none = [LIGHT_GRAY]맵을 찾을 수 없습니다! about.button = 정보 name = 이름 : +noname = Pick a[accent] player name[] first. filename = 파일 이름 : unlocked = 새 블록 잠금 해제됨 -unlocked.plural = 잠금 해제 +completed = [accent]Completed +techtree = Tech Tree +research.list = [LIGHT_GRAY]Research: +research = Research +researched = [LIGHT_GRAY]{0} researched. players = 현재 {0}명 접속중 players.single = 현재 {0}명만 있음. server.closing = [accent]서버 닫는중... server.kicked.kick = 서버에서 추방되었습니다! server.kicked.serverClose = 서버 종료됨. -server.kicked.sectorComplete = 지역 클리어. -server.kicked.sectorComplete.text = 임무 성공.\n서버가 다음지역 맵으로 이동되었습니다. server.kicked.clientOutdated = 오래된 버전의 클라이언트 입니다! 게임을 업데이트 하세요! server.kicked.serverOutdated = 오래된 버전의 서버입니다! 서버 호스트 관리자에게 문의하세요! server.kicked.banned = 뭘 하셨는지는 모르겠지만, 이제 영원히 서버에 접속할 수 없습니다. @@ -160,7 +140,6 @@ save.rename.text = 새 이름 : selectslot = 저장슬롯을 선택하십시오. slot = [accent]{0}번째 슬롯 save.corrupted = [accent]세이브 파일이 손상되었거나 잘못된 파일입니다! 만약 게임을 업데이트 했다면 이것은 아마 저장 형식 변경일 것이고, 이것은 버그가 [scarlet]아닙니다[]. -sector.corrupted = [accent]저장 파일에서 지역을 발견했으나 불러오지 못했습니다.\n새로 생성되었습니다. empty = <비어있음> on = 켜기 off = 끄기 @@ -170,6 +149,7 @@ save.wave = {0}단계[] save.difficulty = 난이도 : {0} save.date = 마지막 저장날짜 : {0} save.playtime = 플레이시간 : {0} +warning = Warning. confirm = 확인 delete = 삭제 ok = 확인 @@ -260,6 +240,17 @@ tutorial = 게임 방법 editor = 편집기 mapeditor = 맵 편집기 donate = 기부 +abandon = Abandon +abandon.text = This zone and all its resources will be lost to the enemy. +locked = Locked +complete = [LIGHT_GRAY]Complete: +resume = Resume Zone:\n[LIGHT_GRAY]{0} +bestwave = [LIGHT_GRAY]Best: {0} +launch = Launch +launch.title = Launch Successful +launch.next = [LIGHT_GRAY]next opportunity at wave {0} +launch.unable = [scarlet]Unable to LAUNCH.[] Enemies. +zone.unlocked = [LIGHT_GRAY]{0} unlocked. connectfail = [crimson]{0}[accent] 서버에 연결하지 못했습니다.[] error.unreachable = 서버에 연결하지 못했습니다. error.invalidaddress = 잘못된 주소입니다. @@ -267,7 +258,20 @@ error.timedout = 시간 초과!\n서버에 포트 포워딩이 설정되어 있 error.mismatch = 패킷 오류:\n클라이언트/서버 버전이 일치하지 않습니다.\n접속할려는 서버가 최신 버전의 Mindustry 인지 확인하세요! error.alreadyconnected = 이미 접속중입니다. error.mapnotfound = 맵 파일을 찾을 수 없습니다! +error.io = Network I/O error. error.any = 알 수 없는 네트워크 오류. +zone.groundZero.name = Ground Zero +zone.craters.name = The Craters +zone.frozenForest.name = Frozen Forest +zone.ruinousShores.name = Ruinous Shores +zone.crags.name = Crags +zone.stainedMountains.name = Stained Mountains +zone.impact0079.name = Impact 0079 +zone.desolateRift.name = Desolate Rift +zone.arcticDesert.name = Arctic Desert +zone.dryWastes.name = Dry Wastes +zone.nuclearComplex.name = Nuclear Production Complex +zone.moltenFault.name = Molten Fault settings.language = 언어 settings.reset = 설정 초기화 settings.rebind = 키 재설정 @@ -278,7 +282,6 @@ settings.graphics = 그래픽 settings.cleardata = 게임 데이터 초기화... settings.clear.confirm = 정말로 초기화 하겠습니까?\n이 작업을 되돌릴 수 없습니다! settings.clearall.confirm = [scarlet]경고![]\n이 작업은 저장된 맵, 맵파일, 잠금 해제된 목록과 키 매핑, 그리고 모든 데이터를 삭제합니다.\n확인 버튼을 다시 눌러 모든 데이터를 삭제하고 게임에서 나갑니다. -settings.clearsectors = 지역 초기화 settings.clearunlocks = 잠금 해제 초기화 settings.clearall = 모두 초기화 paused = 일시 정지 @@ -317,12 +320,15 @@ blocks.liquidoutput = 액체 출력 blocks.liquidoutputspeed = 액체 출력속도 blocks.liquiduse = 액체 사용량 blocks.coolant = 냉각제 +blocks.liquid = Liquid blocks.coolantuse = 냉각수 사용 blocks.inputliquidfuel = 연료 액 blocks.liquidfueluse = 액체 연료 사용 blocks.boostitem = 가속 아이템 blocks.boostliquid = 가속 액체 blocks.health = 체력 +blocks.power = Power +blocks.power.satisfaction = Power Satisfaction blocks.inaccuracy = 오차각 blocks.shots = 발포 횟수 blocks.reload = 재장전 @@ -347,6 +353,7 @@ category.items = 아이템 category.crafting = 제작 category.shooting = 사격 category.optional = 선택적 가속 +setting.indicators.name = 인디게이터 표시 setting.autotarget.name = 자동 조준 setting.fpscap.name = 최대 FPS setting.fpscap.none = 없음 @@ -383,9 +390,11 @@ keybind.gridMode.name = 블록 선택 keybind.gridModeShift.name = 카테고리 선택 keybind.press = 키를 누르세요... keybind.press.axis = 축 또는 키를 누르세요... +keybind.screenshot.name = Map Screenshot keybind.move_x.name = 오른쪽/왼쪽 이동 keybind.move_y.name = 위쪽/아래쪽 이동 keybind.select.name = 선택 +keybind.pick.name = Pick Block keybind.break.name = 파괴 keybind.deselect.name = 선택해제 keybind.shoot.name = 사격 @@ -405,29 +414,28 @@ keybind.chat_scroll.name = 채팅 스크롤 keybind.drop_unit.name = 유닛 드롭 keybind.zoom_minimap.name = 미니맵 확대 mode.help.title = 도움말 -mode.waves.name = 단계 -mode.waves.description = 이것은 일반 모드입니다. 제한된 자원과 자동으로 다음 단계가 시작됩니다. +mode.survival.name = Survival +mode.survival.description = The normal mode. Limited resources and automatic incoming waves. mode.sandbox.name = 샌드박스 mode.sandbox.description = 무한한 자원과 다음단계 시작을 위한 타이머가 없습니다. mode.freebuild.name = 자유 건축 mode.freebuild.description = 제한된 자원과 다음단계 시작을 위한 타이머가 없습니다. mode.pvp.name = PvP mode.pvp.description = 몹이 아닌 실제 플레이어와 PvP를 합니다. +mode.attack.name = Attack +mode.attack.descrption = No waves, with the goal to destroy the enemy base. content.item.name = 아이템 content.liquid.name = 액체 content.unit.name = 유닛 -content.recipe.name = 블록 +content.block.name = Blocks content.mech.name = 기체 -item.stone.name = 돌 -item.stone.description = 주로 용암을 사용하여 얻을 수 있는 자원입니다. item.copper.name = 구리 item.copper.description = 모든 종류의 블록에서 광범위하게 사용되는 자원입니다. item.lead.name = 납 item.lead.description = 쉽게 구할 수 있으며, 전자 및 액체 수송 블록에서 광범위하게 사용되는 자원입니다. item.coal.name = 석탄 item.coal.description = 쉽게 구할 수 있으며, 주로 제련소 등에서 연료로 사용됩니다. -item.dense-alloy.name = 고밀도 합금 -item.dense-alloy.description = 납과 구리로 만든 튼튼한 고밀도 합금.\n고급 수송 블록이나 상위 티어 블록을 건설하는데 사용됩니다. +item.graphite.name = Graphite item.titanium.name = 티타늄 item.titanium.description = 파이프 재료나 고급 드릴, 비행기/기체 등에서 재료로 사용되는 자원입니다. item.thorium.name = 토륨 @@ -448,6 +456,10 @@ item.blast-compound.name = 폭발물 item.blast-compound.description = 포탑 및 건설의 재료로 사용되는 휘발성 폭발물.\n연료로도 사용할 수 있지만, 별로 추천하지는 않습니다. item.pyratite.name = 피라테 item.pyratite.description = 폭발성을 가진 재료로, 주로 포탑의 탄약으로 사용됩니다. +item.metaglass.name = Metaglass +item.metaglass.description = A super-tough glass compound. Extensively used for liquid distribution and storage. +item.scrap.name = Scrap +item.scrap.description = Leftover remnants of old structures and units. Contains trace amounts of many different metals. liquid.water.name = 물 liquid.lava.name = 용암 liquid.oil.name = 석유 @@ -484,11 +496,10 @@ mech.glaive-ship.weapon = 방화총 item.explosiveness = [LIGHT_GRAY]폭발성 : {0} item.flammability = [LIGHT_GRAY]인화성 : {0} item.radioactivity = [LIGHT_GRAY]방사능 : {0} -item.fluxiness = [LIGHT_GRAY]유동성 : {0} unit.health = [LIGHT_GRAY]체력 : {0} unit.speed = [LIGHT_GRAY]속도 : {0} mech.weapon = [LIGHT_GRAY]무기 : {0} -mech.armor = [LIGHT_GRAY]방어력 : {0} +mech.health = [LIGHT_GRAY]Health: {0} mech.itemcapacity = [LIGHT_GRAY]아이템 수용 용량 : {0} mech.minespeed = [LIGHT_GRAY]채광 속도 : {0} mech.minepower = [LIGHT_GRAY]채광 레벨 : {0} @@ -496,9 +507,15 @@ mech.ability = [LIGHT_GRAY]능력 : {0} liquid.heatcapacity = [LIGHT_GRAY]발열량 : {0} liquid.viscosity = [LIGHT_GRAY]점도 : {0} liquid.temperature = [LIGHT_GRAY]온도 : {0} +block.kiln.name = Kiln +block.kiln.description = Smelts sand and lead into metaglass. Requires small amounts of power. +block.graphite-press.name = Graphite Press +block.multi-press.name = Multi-Press block.constructing = {0}[LIGHT_GRAY](만드는중) block.spawn.name = 적 스폰지점 -block.core.name = 코어 +block.core-shard.name = Core: Shard +block.core-foundation.name = Core: Foundation +block.core-nucleus.name = Core: Nucleus block.metalfloor.name = 철판 block.deepwater.name = 깊은물 block.water.name = 물 @@ -517,8 +534,8 @@ block.blackrock.name = 검은바위 block.icerock.name = 얼음바위 block.copper-wall.name = 구리벽 block.copper-wall-large.name = 큰 구리벽 -block.dense-alloy-wall.name = 합금 벽 -block.dense-alloy-wall-large.name = 큰 합금 벽 +block.titanium-wall.name = Titanium Wall +block.titanium-wall-large.name = Large Titanium Wall block.phase-wall.name = 메타벽 block.phase-wall-large.name = 큰 메타벽 block.thorium-wall.name = 토륨벽 @@ -551,17 +568,19 @@ block.separator.name = 셉터 block.centrifuge.name = 원심 분리기 block.power-node.name = 전력 송신기 block.power-node-large.name = 대형 전력 송신기 +block.surge-tower.name = Surge Tower block.battery.name = 배터리 block.battery-large.name = 대형 배터리 block.combustion-generator.name = 석탄 발전기 block.turbine-generator.name = 터빈 발전기 +block.differential-generator.name = Differential Generator +block.impact-reactor.name = Impact Reactor block.mechanical-drill.name = 기계식 드릴 block.pneumatic-drill.name = 강철 드릴 block.laser-drill.name = 레이저 드릴 block.water-extractor.name = 물 추출기 block.cultivator.name = 온실 -block.alpha-mech-pad.name = 알파 기체 패드 -block.dart-ship-pad.name = 다트 비행선 패드 +block.alpha-dart-mech-pad.name = Alpha-Dart Mech Pad block.delta-mech-pad.name = 델타 기체 패드 block.javelin-ship-pad.name = 자비린 비행선 패드 block.trident-ship-pad.name = 삼지창 비행선 패드 @@ -626,6 +645,7 @@ block.rtg-generator.name = 토륨 발전소 block.spectre.name = 스펙터 block.meltdown.name = 멜트다운 block.container.name = 컨테이너 +block.launch-pad.name = Launch Pad team.blue.name = 블루팀 team.red.name = 레드팀 team.orange.name = 오렌지팀 @@ -639,6 +659,7 @@ unit.phantom.name = 팬텀 드론 unit.phantom.description = 첨단 드론 유닛.\n광석을 자동으로 채광하며, 아이템을 수집하고 블록을 수리합니다. 일반 드론보다 훨씬 효과적입니다. unit.dagger.name = 디거 unit.dagger.description = 기본 지상 유닛입니다.\n플레이어 기체처럼 드론을 소환하지는 않습니다. +unit.crawler.name = Crawler unit.titan.name = 타이탄 unit.titan.description = 고급 지상 유닛입니다.\n원거리 총 대신에 근접 화염 방사기를 가지고 있으며, 지상과 공중 둘다 공격할 수 있습니다. unit.ghoul.name = 구울 폭격기 @@ -648,7 +669,11 @@ unit.wraith.description = 적 핵심 건물 및 유닛을 집중적으로 공격 unit.fortress.name = 포트리스 unit.fortress.description = 중포 지상 유닛.\n높은 공격력을 가진 총과 높은 체력을 가지고 있습니다. unit.revenant.name = 레비던트 -unit.revenant.description = 튼튼하고 강력한 대형 레이저를 발사하는 공중 유닛입니다. +unit.eruptor.name = Eruptor +unit.chaos-array.name = Chaos Array +unit.eradicator.name = Eradicator +unit.lich.name = Lich +unit.reaper.name = Reaper tutorial.begin = 플레이어의 주요 목표는 [LIGHT_GRAY]적군[]을 제거하는 것입니다.\n\n이 게임은 [accent]구리를 채광[]하는 것으로 시작합니다.\n이것을 하기 위해 플레이어의 중심부 근처에 있는 구리 광맥을 누르세요. tutorial.drill = 수동으로 채광하는 것은 효율이 낮습니다.\n[accent]드릴[]은 자동으로 채광 작업을 합니다.\n구리 광맥에 표시된 영역에 드릴을 하나를 놓으세요. tutorial.conveyor = [accent]컨베이어[]를 사용하여 아이템을 코어로 운반합니다.\n드릴에서 코어까지 컨베이어 라인을 만드세요. @@ -670,7 +695,6 @@ tutorial.daggerfactory = 이[accent] 디거 기체 공장[]은\n\n공격하는 tutorial.router = 공장을 작동시키기 위해 자원이 필요합니다.\n컨베이어에 운반되고 있는 자원을 분할할 분배기를 만드세요. tutorial.dagger = 전력 노드를 공장에 연결하세요.\n일단 요구 사항이 충족되면 기체 생산을 시작합니다.\n\n필요에 따라 드릴 및 발전기, 컨베이어를 더 많이 만들 수 있습니다. tutorial.battle = [LIGHT_GRAY]적[]의 코어가 드러났습니다.\n당신의 부대와 디거를 사용하여 파괴하세요. -block.core.description = 게임에서 가장 중요한 건물.\n코어가 1개밖에 없을때 파괴되면 게임에서 패배합니다. block.copper-wall.description = 구리로 만든 방어벽.\n가장 약한 방어벽입니다. block.copper-wall-large.description = 구리로 만든 큰 방어벽.\n일반 구리벽의 4개를 합쳐놓은 벽이며, 가장 약한 방어벽입니다. block.dense-alloy-wall.description = 고밀도 합금으로 만든 방어벽.\n구리벽보다 체력이 높습니다. @@ -781,5 +805,3 @@ liquid.water.description = 지상 유닛이 이 위를 지나가면 이동속도 liquid.lava.description = 지상 유닛이 이 위를 지나가면 이동속도가 매우 느려지고, 지속적으로 데미지를 입습니다. liquid.oil.description = 일부 조합 블록에서 사용되는 자원입니다. liquid.cryofluid.description = 포탑 및 토륨 원자로에서 사용되는 자원입니다. - -setting.indicators.name = 인디게이터 표시 diff --git a/core/assets/bundles/bundle_pl.properties b/core/assets/bundles/bundle_pl.properties index 683468ca01..6fb8e365f9 100644 --- a/core/assets/bundles/bundle_pl.properties +++ b/core/assets/bundles/bundle_pl.properties @@ -1,5 +1,6 @@ credits.text = Created by [ROYAL]Anuken[] - [SKY]anukendev@gmail.com[]\n\n[GRAY](In case you can't tell, this text is currently unfinished.\nTranslators, don't edit it yet!) credits = Zasłużeni +contributors = Translators and Contributors discord = Odwiedź nasz serwer Discord! link.discord.description = Oficjalny serwer Discord Mindustry link.github.description = Kod Gry @@ -9,15 +10,18 @@ link.itch.io.description = Strona itch.io z oficjanymi wersjami do pobrania link.google-play.description = Google Play store listing link.wiki.description = Oficjana Wiki Mindustry linkfail = Nie udało się otworzyć linku!\nURL został skopiowany. +screenshot = Screenshot saved to {0} gameover = Rdzeń został zniszczony. gameover.pvp = The[accent] {0}[] team is victorious! -sector.gameover = This sector has been lost. Re-deploy? -sector.retry = Spróbuj ponownie highscore = [YELLOW] Nowy rekord! -wave.lasted = Wytrwałeś do [accent]{0}[] fali. -level.highscore = Rekord: [accent]{0} -level.delete.title = Potwierdź usuwanie +stat.wave = Waves Defeated:[accent] {0} +stat.enemiesDestroyed = Enemies Destroyed:[accent] {0} +stat.built = Buildings Built:[accent] {0} +stat.destroyed = Buildings Destroyed:[accent] {0} +stat.deconstructed = Buildings Deconstructed:[accent] {0} +stat.delivered = Resources Launched: map.delete = Jesteś pewny, że chcesz usunąć "[accent]{0}[]"? +level.highscore = Rekord: [accent]{0} level.select = Wybrany poziom level.mode = Tryb gry: construction.desktop = Desktop controls have been changed.\nTo deselect a block or stop building, [accent]use space[]. @@ -27,60 +31,36 @@ deconstruction.title = Poradnik niszczenia bloków deconstruction = Wybrałeś [accent]tryb niszczenia bloków[].\n\nAby zacząć niszczenie, po prostu kliknij na blok obok twojego statku.\nKiedy wybrałeś kilka bloków, kliknij ptaszek i twój statek zacznie niszczyć bloki.\n\n- [accent]Anuluj bloki[] z twojej kolekcji przez klikanie ich(?)\n- [accent]Usuwaj bloki na obszrze[] przez zaznacznie ich.\n- [accent]Anuluj niszcznie [] przez kliknięcie X w lewym dolnym rogu. showagain = Nie pokazuj tego więcej coreattack = < Rdzeń jest atakowany! > -unlocks = Lista przedmiotów +nearpoint = [[ [scarlet]LEAVE DROP POINT IMMEDIATELY[] ]\nannihilation imminent +outofbounds = [[ OUT OF BOUNDS ]\n[]self-destruct in {0} +database = Core Database savegame = Zapisz Grę loadgame = Wczytaj grę joingame = Gra wieloosobowa addplayers = Dodaj/Usuń graczy customgame = Własna Gra -sectors = Sektory -sector = Wybrany Sektor: [LIGHT_GRAY]{0} -sector.time = Czas: [LIGHT_GRAY]{0} -sector.deploy = Wejdź -sector.abandon = Opuść -sector.abandon.confirm = Czy jesteś pewien, że chcesz porzucić cały postęp w tym sektorze?\nProces jest nieodwracalny! -sector.resume = Wznów -sector.locked = [scarlet][[Niegotowy] -sector.unexplored = [accent][[Nieodkryty] -missions = Misje:[LIGHT_GRAY] {0} -mission = Misja:[LIGHT_GRAY] {0} -mission.main = Główna misja:[LIGHT_GRAY] {0} -mission.info = Informacje o misji -mission.complete = Misja zakończona sukcesem! -mission.complete.body = Sektor {0},{1} został podbity. -mission.wave = Przetrwaj[accent] {0}/{1} []fal\nNastępna fala w {2} -mission.wave.enemies = Przetrwaj[accent] {0}/{1} []fal\nPozostało {2} przeciwników -mission.wave.enemy = Przetrwaj[accent] {0}/{1} []fal\nPozostał{2} przeciwnik -mission.wave.menu = Przetrwaj[accent] {0} []fal -mission.battle = Zniszcz bazę przeciwnika -mission.resource.menu = Wydobądź {0} x{1} -mission.resource = Wydobądź {0}:\n[accent]{1}/{2}[] -mission.block = Stwórz {0} -mission.unit = Utwórz {0} jednostkę -mission.command = Wyślij komendę {0} do Jednostek -mission.linknode = Połącz Węzeł prądu -mission.display = [accent]Misja:\n[LIGHT_GRAY]{0} -mission.mech = Switch to mech[accent] {0}[] -mission.create = Utwórz[accent] {0}[] +newgame = New Game none = close = Zamknij quit = Wyjdź maps = Mapy continue = Kontynuuj -nextmission = Następna misja maps.none = [LIGHT_GRAY]Nie znaleziono żadnych map! about.button = O grze name = Nazwa: +noname = Pick a[accent] player name[] first. filename = File Name: unlocked = Odblokowano nowy blok! -unlocked.plural = Odblokowano nowe bloki! +completed = [accent]Completed +techtree = Tech Tree +research.list = [LIGHT_GRAY]Research: +research = Research +researched = [LIGHT_GRAY]{0} researched. players = {0} graczy online players.single = {0} gracz online server.closing = [accent] Zamykanie serwera... server.kicked.kick = Zostałeś wyrzucony z serwera! server.kicked.serverClose = Serwer został zamknięty. -server.kicked.sectorComplete = Sektor ukończony. -server.kicked.sectorComplete.text = Twoja misja została ukończona.\nSerwer kontynuuje w następnym sektorze. server.kicked.clientOutdated = Nieaktualna gra! Zaktualizują ją! server.kicked.serverOutdated = Nieaktualny serwer! server.kicked.banned = Zostałeś zbanowany na tym serwerze. @@ -89,6 +69,7 @@ server.kicked.nameInUse = Ta nazwa jest już zajęta na tym serwerze. server.kicked.nameEmpty = Nazwa musi zawierać przynajmniej 1 literę lub cyfrę. server.kicked.idInUse = Jesteś już na serwerze! Używanie tego samego konta na 2 urządzeniach jest zabronione. server.kicked.customClient = Ten serwer nie wspomaga wersji deweloperskich. Pobierz oryginalną wersję. +server.kicked.gameover = Game over! host.info = Przycisk [accent]host[] hostuje serwer na porcie [scarlet]6567[] i [scarlet]6568.[]\nKtokolwiek z tym samym [LIGHT_GRAY]wifi lub hotspotem[] powinien zobaczyć twój serwer.\n\nJeśli chcesz, aby każdy z twoim IP mógł dołączyć, [accent]przekierowywanie portów[] jest potrzebne.\n\n[LIGHT_GRAY]Notka:Jeśli ktokolwiek ma problem z dołączeniem do gry, upewnij się, że udostępniłeś Mindustry dostęp do sieci. join.info = Tutaj możesz wpisać [accent]IP serwera[], aby dołączyć lub wyszukaj [accent]serwery wifi[], do których chcesz dołączyć .\nGra wieloosobowa na LAN i WAN jest wspomagana.\n\n[LIGHT_GRAY]Notka: Nie ma automatycznej listy wszystkich serwerów; jeśli chcesz dołączyć przez IP, musisz zapytać się hosta o IP. hostserver = Stwórz Serwer @@ -159,7 +140,6 @@ save.rename.text = Zmień nazwę selectslot = Wybierz zapis. slot = [accent]Slot {0} save.corrupted = [accent]Zapis gry jest uszkodzony lub nieprawidłowy! -sector.corrupted = [accent]Zapis sektora został znaleziony, ale nie można go otworzyć.\nNowy sektor został utworzony. empty = on = Włączone off = Wyłączone @@ -169,6 +149,7 @@ save.wave = Fala: {0} save.difficulty = Poziom trudności: {0} save.date = Ostatnio zapisano: {0} save.playtime = Czas gry: {0} +warning = Warning. confirm = Potwierdź delete = Usuń ok = Ok @@ -259,6 +240,17 @@ tutorial = Poradnik editor = Edytor mapeditor = Edytor map donate = Wspomóż nas +abandon = Abandon +abandon.text = This zone and all its resources will be lost to the enemy. +locked = Locked +complete = [LIGHT_GRAY]Complete: +resume = Resume Zone:\n[LIGHT_GRAY]{0} +bestwave = [LIGHT_GRAY]Best: {0} +launch = Launch +launch.title = Launch Successful +launch.next = [LIGHT_GRAY]next opportunity at wave {0} +launch.unable = [scarlet]Unable to LAUNCH.[] Enemies. +zone.unlocked = [LIGHT_GRAY]{0} unlocked. connectfail = [crimson]Nie można połączyć się z serwerem: [accent] {0} error.unreachable = Serwer niedostępny. error.invalidaddress = Niepoprawny adres. @@ -266,7 +258,20 @@ error.timedout = Przekroczono limit czasu!/nUpewnij się, że host ma ustawione error.mismatch = Błąd pakietu:\nprawdopodobne niedopasowanie klienta/serwera.\nUpewnij się, że ty i host macie najnowszą wersję Mindustry! error.alreadyconnected = Jesteś już połączony. error.mapnotfound = Plik mapy nie został znaleziony! +error.io = Network I/O error. error.any = Nieznany błąd sieci. +zone.groundZero.name = Ground Zero +zone.craters.name = The Craters +zone.frozenForest.name = Frozen Forest +zone.ruinousShores.name = Ruinous Shores +zone.crags.name = Crags +zone.stainedMountains.name = Stained Mountains +zone.impact0079.name = Impact 0079 +zone.desolateRift.name = Desolate Rift +zone.arcticDesert.name = Arctic Desert +zone.dryWastes.name = Dry Wastes +zone.nuclearComplex.name = Nuclear Production Complex +zone.moltenFault.name = Molten Fault settings.language = Język settings.reset = Przywróć domyślne settings.rebind = Zmień przyciski @@ -277,7 +282,6 @@ settings.graphics = Grafika settings.cleardata = Wyczyść dane gry... settings.clear.confirm = Are you sure you want to clear this data?\nWhat is done cannot be undone! settings.clearall.confirm = [scarlet]WARNING![]\nThis will clear all data, including saves, maps, unlocks and keybinds.\nOnce you press 'ok' the game will wipe all data and automatically exit. -settings.clearsectors = Wyczyść sektory settings.clearunlocks = Wyczyść listę przedmiotów settings.clearall = Wyczyść wszystko paused = Wstrzymano @@ -316,12 +320,15 @@ blocks.liquidoutput = Wyprodukowany płyn blocks.liquidoutputspeed = Prędkość odpływu cieczy blocks.liquiduse = Zużycie płynów blocks.coolant = Płyn chłodzący +blocks.liquid = Liquid blocks.coolantuse = Zużycie płynu chłodzącego blocks.inputliquidfuel = Paliwo blocks.liquidfueluse = Zużycie paliwa blocks.boostitem = Boost Item blocks.boostliquid = Boost Liquid blocks.health = Zdrowie +blocks.power = Power +blocks.power.satisfaction = Power Satisfaction blocks.inaccuracy = Niedokładność blocks.shots = Strzały blocks.reload = Przeładowanie @@ -346,6 +353,7 @@ category.items = Przedmioty category.crafting = Przetwórstwo category.shooting = Strzelanie category.optional = Optional Enhancements +setting.indicators.name = Ally Indicators setting.autotarget.name = Auto-Target setting.fpscap.name = Max FPS setting.fpscap.none = None @@ -378,11 +386,15 @@ category.multiplayer.name = Multiplayer command.attack = Atakuj command.retreat = Wycofaj command.patrol = Patrol +keybind.gridMode.name = Block Select +keybind.gridModeShift.name = Category Select keybind.press = Naciśnij wybrany klawisz... keybind.press.axis = Naciśnij oś lub klawisz... +keybind.screenshot.name = Map Screenshot keybind.move_x.name = Poruszanie w poziomie keybind.move_y.name = Poruszanie w pionie keybind.select.name = Wybieranie +keybind.pick.name = Pick Block keybind.break.name = Niszczenie keybind.deselect.name = Deselect keybind.shoot.name = Strzelanie @@ -402,29 +414,28 @@ keybind.chat_scroll.name = Chat scroll keybind.drop_unit.name = Wyrzuć przedmiot keybind.zoom_minimap.name = Powiększenie mapy mode.help.title = Opis trybów -mode.waves.name = Fale -mode.waves.description = Normalny tryb. Normalne surowce i fale. +mode.survival.name = Survival +mode.survival.description = The normal mode. Limited resources and automatic incoming waves. mode.sandbox.name = Sandbox mode.sandbox.description = Nieskończone surowce i fale bez odliczania. Dla przedszkolaków! mode.freebuild.name = Budowanie mode.freebuild.description = Normalne surowce i fale bez odliczania. mode.pvp.name = PvP mode.pvp.description = Walcz lokalnie przeciwko innym graczom. +mode.attack.name = Attack +mode.attack.descrption = No waves, with the goal to destroy the enemy base. content.item.name = Przedmioty content.liquid.name = Płyny content.unit.name = Jednostki -content.recipe.name = Bloki +content.block.name = Blocks content.mech.name = Mechs -item.stone.name = Kamień -item.stone.description = Zwkły surowy materiał. Używany do separacji i zamiany w inne surowce lub lawę. Już jaskiniowcy go używali. item.copper.name = Copper item.copper.description = A useful structure material. Used extensively in all types of blocks. item.lead.name = Ołów item.lead.description = Podstawowy matriał. Używany w przesyle przemiotów i płynów. Nie jest on przypadkiem szkodliwy? item.coal.name = Węgiel item.coal.description = Zwykły i łatwo dostępny materiał energetyczny. -item.dense-alloy.name = Dense Alloy -item.dense-alloy.description = A tough alloy made with lead and copper. Used in advanced transportation blocks and high-tier drills. +item.graphite.name = Graphite item.titanium.name = Tytan item.titanium.description = Rzadki i bardzo lekki materiał. Używany w bardzo zaawansowanym przewodnictwie, wiertłach i samolotach. Poczuj się jak Tytan! item.thorium.name = Uran @@ -445,6 +456,10 @@ item.blast-compound.name = Wybuchowy związek item.blast-compound.description = Lotny związek używany w pirotechnice. Może być używany jako materiał energetyczny, ale nie polecam. BOOOM! item.pyratite.name = Piratian item.pyratite.description = Niesamowicie palny związek używany w zbrojeniu. Nielegalny w 9 państwach. +item.metaglass.name = Metaglass +item.metaglass.description = A super-tough glass compound. Extensively used for liquid distribution and storage. +item.scrap.name = Scrap +item.scrap.description = Leftover remnants of old structures and units. Contains trace amounts of many different metals. liquid.water.name = woda liquid.lava.name = lawa liquid.oil.name = ropa @@ -481,11 +496,10 @@ mech.glaive-ship.weapon = Flame Repeater item.explosiveness = [LIGHT_GRAY]Wybuchowość: {0} item.flammability = [LIGHT_GRAY]Palność: {0} item.radioactivity = [LIGHT_GRAY]Promieniotwórczość: {0} -item.fluxiness = [LIGHT_GRAY]Moc topnika: {0} unit.health = [LIGHT_GRAY]Zdrowie: {0} unit.speed = [LIGHT_GRAY]Prędkość: {0} mech.weapon = [LIGHT_GRAY]Broń: {0} -mech.armor = [LIGHT_GRAY]Uzbrojenie: {0} +mech.health = [LIGHT_GRAY]Health: {0} mech.itemcapacity = [LIGHT_GRAY]Pojemność przedmiotów: {0} mech.minespeed = [LIGHT_GRAY]Prędkość kopania: {0} mech.minepower = [LIGHT_GRAY]Moc kopania: {0} @@ -493,9 +507,15 @@ mech.ability = [LIGHT_GRAY]Umiejętność: {0} liquid.heatcapacity = [LIGHT_GRAY]Wytrzymałość na przegrzewanie: {0} liquid.viscosity = [LIGHT_GRAY]Lepkość: {0} liquid.temperature = [LIGHT_GRAY]Temperatura: {0} +block.kiln.name = Kiln +block.kiln.description = Smelts sand and lead into metaglass. Requires small amounts of power. +block.graphite-press.name = Graphite Press +block.multi-press.name = Multi-Press block.constructing = {0}\n[LIGHT_GRAY](Budowa) block.spawn.name = Spawn wrogów -block.core.name = Rdzeń +block.core-shard.name = Core: Shard +block.core-foundation.name = Core: Foundation +block.core-nucleus.name = Core: Nucleus block.metalfloor.name = Podłoga metalowa block.deepwater.name = Głęboka woda block.water.name = Woda @@ -514,8 +534,8 @@ block.blackrock.name = Czarna skała block.icerock.name = Lodowa skała block.copper-wall.name = Miedziana ściana block.copper-wall-large.name = Duża miedziana ściana -block.dense-alloy-wall.name = Dense Alloy Wall -block.dense-alloy-wall-large.name = Large Dense Alloy Wall +block.titanium-wall.name = Titanium Wall +block.titanium-wall-large.name = Large Titanium Wall block.phase-wall.name = Phase Wall block.phase-wall-large.name = Large Phase Wall block.thorium-wall.name = Torowa Ściana @@ -548,17 +568,19 @@ block.separator.name = Separator block.centrifuge.name = Wirnik block.power-node.name = Węzeł Prądu block.power-node-large.name = Duży Węzeł Prądu +block.surge-tower.name = Surge Tower block.battery.name = Bateria block.battery-large.name = Duża Bateria block.combustion-generator.name = Generator Spalinowy block.turbine-generator.name = Generator Turbinowy +block.differential-generator.name = Differential Generator +block.impact-reactor.name = Impact Reactor block.mechanical-drill.name = Wiertło Mechaniczne block.pneumatic-drill.name = Wiertło Pneumatyczne block.laser-drill.name = Wiertło Laserowe block.water-extractor.name = Ekstraktor Wody block.cultivator.name = Spluchniacz -block.alpha-mech-pad.name = Alpha Mech Pad -block.dart-ship-pad.name = Dart Ship Pad +block.alpha-dart-mech-pad.name = Alpha-Dart 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 @@ -623,7 +645,7 @@ block.rtg-generator.name = Generator RTG block.spectre.name = Spectre block.meltdown.name = Meltdown block.container.name = Container -block.core.description = Najważniejszy budynek w grze. +block.launch-pad.name = Launch Pad team.blue.name = niebieski team.red.name = czerwony team.orange.name = pomarańczowy @@ -637,6 +659,7 @@ unit.phantom.name = Phantom Drone unit.phantom.description = An advanced drone unit. Automatically mines ores, collects items and repairs blocks. Significantly more effective than a drone. unit.dagger.name = Dagger unit.dagger.description = A basic ground unit. Useful in swarms. +unit.crawler.name = Crawler unit.titan.name = Titan unit.titan.description = An advanced armored ground unit. Uses carbide as ammo. Attacks both ground and air targets. unit.ghoul.name = Ghoul Bomber @@ -646,7 +669,11 @@ unit.wraith.description = A fast, hit-and-run interceptor unit. unit.fortress.name = Fortress unit.fortress.description = A heavy artillery ground unit. unit.revenant.name = Revenant -unit.revenant.description = A heavy laser platform. +unit.eruptor.name = Eruptor +unit.chaos-array.name = Chaos Array +unit.eradicator.name = Eradicator +unit.lich.name = Lich +unit.reaper.name = Reaper tutorial.begin = Your mission here is to eradicate the[LIGHT_GRAY] enemy[].\n\nBegin by[accent] mining copper[]. Tap a copper ore vein near your core to do this. tutorial.drill = Mining manually is inefficient.\n[accent]Drills []can mine automatically.\nPlace one on a copper vein. tutorial.conveyor = [accent]Conveyors[] are used to transport items to the core.\nMake a line of conveyors from the drill to the core. diff --git a/core/assets/bundles/bundle_pt_BR.properties b/core/assets/bundles/bundle_pt_BR.properties index a08ef30ff6..3dacf3560a 100644 --- a/core/assets/bundles/bundle_pt_BR.properties +++ b/core/assets/bundles/bundle_pt_BR.properties @@ -1,5 +1,6 @@ credits.text = Created by [ROYAL]Anuken[] - [SKY]anukendev@gmail.com[]\n\n[GRAY](In case you can't tell, this text is currently unfinished.\nTranslators, don't edit it yet!) credits = Creditos +contributors = Translators and Contributors discord = Junte-se ao Discord do Mindustry! (Lá nós falamos em inglês) link.discord.description = O discord oficial do Mindustry link.github.description = Codigo fonte do jogo. @@ -9,78 +10,57 @@ link.itch.io.description = Pagina da Itch.io com os Downloads link.google-play.description = Listamento do google play store link.wiki.description = Wiki oficial do Mindustry linkfail = Falha ao abrir o link\nO Url foi copiado +screenshot = Screenshot saved to {0} gameover = O núcleo foi destruído. gameover.pvp = O time[accent] {0}[] É vitorioso! -sector.gameover = Esse setor foi perdido! Soltar Novamente? -sector.retry = Tentar novamente? highscore = [YELLOW]Novo recorde! -wave.lasted = Você sobreviveu até a onda [accent]{0}[]. -level.highscore = Melhor\npontuação: [accent] {0} -level.delete.title = Confirmar exclusão +stat.wave = Waves Defeated:[accent] {0} +stat.enemiesDestroyed = Enemies Destroyed:[accent] {0} +stat.built = Buildings Built:[accent] {0} +stat.destroyed = Buildings Destroyed:[accent] {0} +stat.deconstructed = Buildings Deconstructed:[accent] {0} +stat.delivered = Resources Launched: map.delete = Certeza que quer deletar o mapa "[accent]{0}[]"? +level.highscore = Melhor\npontuação: [accent] {0} level.select = Seleção de Fase level.mode = Modo de Jogo: construction.desktop = Os controles do Desktop foram Mudados.\nPara descelecionar um bloco ou parar de construir, [accent]Use espaço.[]. construction.title = Guia de contrução de blocos -construction =Você selecionou [accent]Modo de construção de blocos[].\n\nPara começar a colocar, Simplesmente clique um lugar valido perto de sua nave.\nUma vez que você selecionou alguns blocos, Clique na caixa para confirmar, E sua nave vai começar a construi-los.\n\n- [accent]Remova blocos[] De sua seleção clicando neles.\n- [accent]Mude a seleção[] Segurando e arrastando qualquer bloco na seleção.\n- [accent]Coloque os blocos em linha[] Clicando e segurando em um lugar vazio e arrastando em uma direção.\n- [accent]Cancele a construção ou seleção[] Pressionando X no canto esquerdo. +construction = Você selecionou [accent]Modo de construção de blocos[].\n\nPara começar a colocar, Simplesmente clique um lugar valido perto de sua nave.\nUma vez que você selecionou alguns blocos, Clique na caixa para confirmar, E sua nave vai começar a construi-los.\n\n- [accent]Remova blocos[] De sua seleção clicando neles.\n- [accent]Mude a seleção[] Segurando e arrastando qualquer bloco na seleção.\n- [accent]Coloque os blocos em linha[] Clicando e segurando em um lugar vazio e arrastando em uma direção.\n- [accent]Cancele a construção ou seleção[] Pressionando X no canto esquerdo. deconstruction.title = Block Deconstruction Guide deconstruction = Você selecionou [accent]O modo de destruição de blocos[].\n\nPara Começar a quebrar, Simplesmente clique num bloco perto da nave.\nQuando tiver selecionados alguns blocos, Aperte a caixa para confirmar, E sua nave vai começar a construir.\n\n- [accent]Remova blocos[] De sua seleção clicando neles.\n- [accent]Remova blocos em uma area[] Clicando e Apertando um lugar vazio então arraste numa direção.\n- [accent]Cancele a construção ou Seleção[] Apertando X no canto Esquerdo. showagain = Não mostrar na proxima sessão coreattack = < A base está sobre ataque! > -unlocks = Desbloqueados +nearpoint = [[ [scarlet]LEAVE DROP POINT IMMEDIATELY[] ]\nannihilation imminent +outofbounds = [[ OUT OF BOUNDS ]\n[]self-destruct in {0} +database = Core Database savegame = Salvar Jogo loadgame = Carregar Jogo joingame = Entrar no Jogo addplayers = Adicionar/Remover Jogador customgame = Jogo Customizado -sectors = Setores -sector = Setor Selecionado: [LIGHT_GRAY]{0} -sector.time = Tempo: [LIGHT_GRAY]{0} -sector.deploy = Soltar -sector.abandon = Abandonar -sector.abandon.confirm = Certeza que quer abandonar seu progresso nesse setor?\nThis cannot be undone! -sector.resume = Voltar -sector.locked = [scarlet][[Não liberado] -sector.unexplored = [accent][[Inexplorado] -missions = Missões:[LIGHT_GRAY] {0} -mission = Missão:[LIGHT_GRAY] {0} -mission.main = Missão principal:[LIGHT_GRAY] {0} -mission.info = Info da missão -mission.complete = Missão completa! -mission.complete.body = Setor {0},{1} Foi conquistado. -mission.wave = Sobrevive [accent]{0}/{1}[] Onda\nOnda em {2} -mission.wave.enemies = Sobreviva[accent] {0}/{1} []ondas\n{2} inimigos -mission.wave.enemy = Sobreviva[accent] {0}/{1} []Ondas\n{2} Inimigos -mission.wave.menu = Sobreviva[accent] {0} []Ondas -mission.battle = Destrua a base inimiga. -mission.resource.menu = Obtenha {0} x{1} -mission.resource = Obtenha {0}:\n[accent]{1}/{2}[] -mission.block = Criar {0} -mission.unit = Criar {0} Unidade -mission.command = Enviar comando {0} As unidades -mission.linknode = Ligar nodo de energia -mission.display = [accent]Missão:\n[LIGHT_GRAY]{0} -mission.mech = Trocar para Meca[accent] {0}[] -mission.create = Criar[accent] {0}[] +newgame = New Game none = close = Fechar quit = Sair maps = Mapas continue = Continue -nextmission = Próxima Missão maps.none = [LIGHT_GRAY]Nenhum Mapa Encontrado! about.button = Sobre name = Nome: +noname = Pick a[accent] player name[] first. filename = Nome do arquivo: unlocked = Novo bloco Desbloqueado! -unlocked.plural = Novos Blocos desbloqueados! +completed = [accent]Completed +techtree = Tech Tree +research.list = [LIGHT_GRAY]Research: +research = Research +researched = [LIGHT_GRAY]{0} researched. players = {0} Jogadores Ativos players.single = {0} Jogador Ativo server.closing = [accent]Fechando servidor... server.kicked.kick = Voce foi expulso do servidor! server.kicked.serverClose = Servidor Fechado. -server.kicked.sectorComplete = Setor completo. -server.kicked.sectorComplete.text = Sua missão esta completa.\nO servidor vai continuar no proximo setor. server.kicked.clientOutdated = Cliente desatualizado! Atualize seu jogo! server.kicked.serverOutdated = Servidor desatualiado! Peca ao dono para atualizar! server.kicked.banned = Voce foi banido do servidor. @@ -89,6 +69,7 @@ server.kicked.nameInUse = Este nome ja esta sendo usado\nneste servidor. server.kicked.nameEmpty = Voce deve ter pelo menos uma letra ou numero. server.kicked.idInUse = Voce ja esta neste servidor! Conectar com duas contas não é permitido. server.kicked.customClient = Este servidor não suporta construções customizadas. Baixe a versão original. +server.kicked.gameover = Game over! host.info = The [accent]Hospedar[]Botão Hopeda um servidor no Host[scarlet]6567[] e [scarlet]6568.[]\nQualquer um no [LIGHT_GRAY]Wi-fi Ou Internet local[] Pode ver este servidor na lista de servidores.\n\nSe voce quer poder entrar em qualquer servidor em seu ip, [accent]port forwarding[] é requerido.\n\n[LIGHT_GRAY]Note: Se alguem esta com problemas em conectar no seu servidor lan, Tenha certeza que deixou mindustry Acessar sua internet local nas configurações de firewall join.info = Aqui, Você pode entar em um [accent]IP De servidor[] Para conectar, Ou descobrir [accent]Servidores[] Da rede local.\nAmbos os servidores LAN e WAN São suportados.\n\n[LIGHT_GRAY]Note: Não tem uma lista de servidores automaticos; Se você quer conectar ao IP de alguem, Você precisa pedir o IP Ao Rosteador. hostserver = Hospedar servidor @@ -159,7 +140,6 @@ save.rename.text = Novo jogo: selectslot = Selecione um slot para salvar. slot = [accent]Slot {0} save.corrupted = [accent]Arquivo corrompido ou inválido! -sector.corrupted = [accent]Um arquivo de save Foi encontrado neste setor, Mas o login falhou.\nUm novo foi criado. empty = on = Ligado off = Desligado @@ -169,6 +149,7 @@ save.wave = Horda {0} save.difficulty = Dificuldade: {0} save.date = Último salvamento: {0} save.playtime = Playtime: {0} +warning = Warning. confirm = Confirmar delete = Excluir ok = OK @@ -259,6 +240,17 @@ tutorial = Tutorial editor = Editor mapeditor = Editor de mapa donate = Doar +abandon = Abandon +abandon.text = This zone and all its resources will be lost to the enemy. +locked = Locked +complete = [LIGHT_GRAY]Complete: +resume = Resume Zone:\n[LIGHT_GRAY]{0} +bestwave = [LIGHT_GRAY]Best: {0} +launch = Launch +launch.title = Launch Successful +launch.next = [LIGHT_GRAY]next opportunity at wave {0} +launch.unable = [scarlet]Unable to LAUNCH.[] Enemies. +zone.unlocked = [LIGHT_GRAY]{0} unlocked. connectfail = [crimson]Falha ao entrar no servidor: [accent]{0} error.unreachable = Servidor inalcançavel. error.invalidaddress = Endereço invalido. @@ -266,7 +258,20 @@ error.timedout = Desconectado!\nTenha certeza que o Rosteador tenha feito Port f error.mismatch = Erro de pacote:\nPossivel versão do cliente/Servidor incompatibilidade.\nTenha certeza que você e o host tenham a ultima versão! error.alreadyconnected = Já conectado. error.mapnotfound = Arquivo de mapa não encontrado! +error.io = Network I/O error. error.any = Erro de rede desconhecido. +zone.groundZero.name = Ground Zero +zone.craters.name = The Craters +zone.frozenForest.name = Frozen Forest +zone.ruinousShores.name = Ruinous Shores +zone.crags.name = Crags +zone.stainedMountains.name = Stained Mountains +zone.impact0079.name = Impact 0079 +zone.desolateRift.name = Desolate Rift +zone.arcticDesert.name = Arctic Desert +zone.dryWastes.name = Dry Wastes +zone.nuclearComplex.name = Nuclear Production Complex +zone.moltenFault.name = Molten Fault settings.language = Linguagem settings.reset = Restaurar Padrões settings.rebind = Religar @@ -277,7 +282,6 @@ settings.graphics = Gráficos settings.cleardata = Data do jogo limpa... settings.clear.confirm = Certeza que quer limpar a data?\nOque é feito não pode ser desfeito! settings.clearall.confirm = [scarlet]Aviso![]\nIsso vai limpar toda a data, Incluindo saves, mapas, Keybinds e desbloqueados.\nQuando apertar 'ok' Vai apagar toda a data e sair automaticamente. -settings.clearsectors = Limpar setores settings.clearunlocks = Limpar liberados settings.clearall = Limpar tudo paused = Pausado @@ -316,12 +320,15 @@ blocks.liquidoutput = Saida de liquido blocks.liquidoutputspeed = Velocidade da saida de líquido blocks.liquiduse = Uso de liquido blocks.coolant = Esfriador +blocks.liquid = Liquid blocks.coolantuse = Uso do esfriador blocks.inputliquidfuel = Liquido de combustivel blocks.liquidfueluse = Uso do liquido de combustivel blocks.boostitem = Acelerar item blocks.boostliquid = Acelerar líquido blocks.health = Saúde +blocks.power = Power +blocks.power.satisfaction = Power Satisfaction blocks.inaccuracy = Imprecisão blocks.shots = Tiros blocks.reload = Recarregar @@ -346,6 +353,7 @@ category.items = Itens category.crafting = Construindo category.shooting = Atirando category.optional = Melhoras opcionais +setting.indicators.name = Ally Indicators setting.autotarget.name = Alvo automatico setting.fpscap.name = FPS Maximo setting.fpscap.none = Nenhum @@ -378,11 +386,15 @@ category.multiplayer.name = Multijogador command.attack = Atacar command.retreat = Recuar command.patrol = Patrulha +keybind.gridMode.name = Block Select +keybind.gridModeShift.name = Category Select keybind.press = Pressione uma tecla... keybind.press.axis = Pressione uma Axis ou tecla... +keybind.screenshot.name = Map Screenshot keybind.move_x.name = mover_x keybind.move_y.name = mover_y keybind.select.name = selecionar +keybind.pick.name = Pick Block keybind.break.name = quebrar keybind.deselect.name = Deselecionar keybind.shoot.name = Atirar @@ -402,29 +414,28 @@ keybind.chat_scroll.name = Rolar chat keybind.drop_unit.name = Soltar unidade keybind.zoom_minimap.name = Zoom minimap mode.help.title = Descrição dos modos -mode.waves.name = hordas -mode.waves.description = O modo normal. Recursos limitados E os ataques vem automaticamente. +mode.survival.name = Survival +mode.survival.description = The normal mode. Limited resources and automatic incoming waves. mode.sandbox.name = Caixa de areia mode.sandbox.description = Recursos infinitos E sem tempo para Ataques. mode.freebuild.name = construção \nlivre mode.freebuild.description = recursos limitados e Sem tempo para Ataques. mode.pvp.name = PvP mode.pvp.description = Lutar contra outros jogadores locais. +mode.attack.name = Attack +mode.attack.descrption = No waves, with the goal to destroy the enemy base. content.item.name = Itens content.liquid.name = Liquidos content.unit.name = Units -content.recipe.name = Blocos +content.block.name = Blocks content.mech.name = Mecas -item.stone.name = Pedra -item.stone.description = Um Material Incomum Cru. Usado para separar e refinar Em outros materiais,Ou Derreter em Lava. item.copper.name = Cobre item.copper.description = Um material de estrutura util. Usado extensivamente em Maioria dos blocos. item.lead.name = Chumbo item.lead.description = Material de comeco basico. usado intensivamente em Blocos de transporte de liquidos e eletronicos. item.coal.name = Carvão item.coal.description = Combustivel pronto. -item.dense-alloy.name = Liga densa -item.dense-alloy.description = Uma liga densa de chumbo e cobre. Usado na transportação de blocos e mineradoras de alto nivel. +item.graphite.name = Graphite item.titanium.name = Titânio item.titanium.description = Um Material raro super leve, metal usado intensivamente na transportação de líquidos, Brocas e Aeronaves. item.thorium.name = Urânio @@ -445,6 +456,10 @@ item.blast-compound.name = Composto de explosão item.blast-compound.description = Um composto volatil usado em bombas em bombas em explosivos. Enquanto pode ser queimado como combustivel, Isso não é recomendado. item.pyratite.name = piratita item.pyratite.description = Substancia extremamente inflamavel usado em armas incendiarias. +item.metaglass.name = Metaglass +item.metaglass.description = A super-tough glass compound. Extensively used for liquid distribution and storage. +item.scrap.name = Scrap +item.scrap.description = Leftover remnants of old structures and units. Contains trace amounts of many different metals. liquid.water.name = Água liquid.lava.name = Lava liquid.oil.name = Petróleo @@ -481,11 +496,10 @@ mech.glaive-ship.weapon = Repetidor de fogo item.explosiveness = [LIGHT_GRAY]Explosividade: {0} item.flammability = [LIGHT_GRAY]Inflamabilidade: {0} item.radioactivity = [LIGHT_GRAY]RadioAtividade: {0} -item.fluxiness = [LIGHT_GRAY]Poder do fluxo: {0} unit.health = [LIGHT_GRAY]Vida: {0} unit.speed = [LIGHT_GRAY]Velocidade: {0} mech.weapon = [LIGHT_GRAY]Arma: {0} -mech.armor = [LIGHT_GRAY]Armadura: {0} +mech.health = [LIGHT_GRAY]Health: {0} mech.itemcapacity = [LIGHT_GRAY]Capacidade de itens: {0} mech.minespeed = [LIGHT_GRAY]Velocidade de mineração: {0} mech.minepower = [LIGHT_GRAY]Poder de mineração: {0} @@ -493,9 +507,15 @@ mech.ability = [LIGHT_GRAY]Habilidade: {0} liquid.heatcapacity = [LIGHT_GRAY]Capacidade de aquecimento: {0} liquid.viscosity = [LIGHT_GRAY]Viscosidade: {0} liquid.temperature = [LIGHT_GRAY]Temperatura: {0} +block.kiln.name = Kiln +block.kiln.description = Smelts sand and lead into metaglass. Requires small amounts of power. +block.graphite-press.name = Graphite Press +block.multi-press.name = Multi-Press block.constructing = {0}\n[LIGHT_GRAY](Construindo) block.spawn.name = Spawn dos inimigos -block.core.name = Core +block.core-shard.name = Core: Shard +block.core-foundation.name = Core: Foundation +block.core-nucleus.name = Core: Nucleus block.metalfloor.name = Chão de metal block.deepwater.name = água funda block.water.name = água @@ -514,8 +534,8 @@ block.blackrock.name = rocha negra block.icerock.name = rocha de gelo block.copper-wall.name = Parede de Cobre block.copper-wall-large.name = Parede de Cobre Grande -block.dense-alloy-wall.name = Parede de liga densa -block.dense-alloy-wall-large.name = Parede de liga densa grande +block.titanium-wall.name = Titanium Wall +block.titanium-wall-large.name = Large Titanium Wall block.phase-wall.name = Parede de fase block.phase-wall-large.name = Parde de fase grande block.thorium-wall.name = Parede de tório @@ -548,17 +568,19 @@ block.separator.name = Separador block.centrifuge.name = Centrifuga block.power-node.name = Célula de energia block.power-node-large.name = Célula de energia Grande +block.surge-tower.name = Surge Tower block.battery.name = Bateria block.battery-large.name = Bateria Grande block.combustion-generator.name = Gerador de combustão block.turbine-generator.name = Gerador de Turbina +block.differential-generator.name = Differential Generator +block.impact-reactor.name = Impact Reactor block.mechanical-drill.name = Furadera Mecânica block.pneumatic-drill.name = Mineradora Pneumatica block.laser-drill.name = Broca a Laser block.water-extractor.name = Extrator de Agua block.cultivator.name = Cultivador -block.alpha-mech-pad.name = Controle do meca Alfa -block.dart-ship-pad.name = Controle do meca Dart +block.alpha-dart-mech-pad.name = Alpha-Dart Mech Pad block.delta-mech-pad.name = Controle do meca Delta block.javelin-ship-pad.name = Controle do meca Javelin block.trident-ship-pad.name = Controle do meca Tridente @@ -623,7 +645,7 @@ block.rtg-generator.name = Gerador RTG block.spectre.name = Espectra block.meltdown.name = Derreter block.container.name = Container -block.core.description = A mais importante construção do jogo. +block.launch-pad.name = Launch Pad team.blue.name = Azul team.red.name = Vermelho team.orange.name = Laranja @@ -637,6 +659,7 @@ unit.phantom.name = Drone Phantom unit.phantom.description = Uma unidade de drone avançada. Minera minérios automaticamente, Coleta itens e repara blocos automaticamente. Significantemente mais efetiva. unit.dagger.name = Dagger unit.dagger.description = Unidade terrestre basica, Forte em grupos. +unit.crawler.name = Crawler unit.titan.name = Titan unit.titan.description = Uma unidade armadurada terreste avancada. Usa carbide como munição. Ataca ambas as unidades de Aereas e terrestres. unit.ghoul.name = Bombardeiro Ghoul @@ -646,7 +669,11 @@ unit.wraith.description = Uma unidade rapida, Interceptadora de bater e correr. unit.fortress.name = Fortaleza unit.fortress.description = Uma unidade pesada de artilharia terrestre. unit.revenant.name = Revenant -unit.revenant.description = Uma plataforma de laser pesada. +unit.eruptor.name = Eruptor +unit.chaos-array.name = Chaos Array +unit.eradicator.name = Eradicator +unit.lich.name = Lich +unit.reaper.name = Reaper tutorial.begin = Sua missão aqui é de erradicar[LIGHT_GRAY] Inimigo[].\n\nComeçe por[accent] Minerar cobre[]. Clique numa veia de cobre perto de seu core para fazer isso. tutorial.drill = Minerar manualmente é ineficiente.\n[accent]Mineradoras []podem minerar automaticamente.\nColoque uma numa veia de cobre. tutorial.conveyor = [accent]Esteiras[] São usadas para transportar itens até o core.\nFaça uma linha de Esteiras da mineradora até o core. diff --git a/core/assets/bundles/bundle_ru.properties b/core/assets/bundles/bundle_ru.properties index feeda265f1..c330164986 100644 --- a/core/assets/bundles/bundle_ru.properties +++ b/core/assets/bundles/bundle_ru.properties @@ -10,15 +10,18 @@ link.itch.io.description = itch.io страница с загрузкой ПК link.google-play.description = Скачать для Android c Google play link.wiki.description = Официальная вики Mindustry(англ.) linkfail = Не удалось открыть ссылку!\nURL-адрес был скопирован в буфер обмена. +screenshot = Screenshot saved to {0} gameover = Игра окончена gameover.pvp = [accent] {0}[] команда победила! -sector.gameover = Этот сектор потерян. Высадиться повторно? -sector.retry = Повторить попытку highscore = [YELLOW]Новый рекорд! -wave.lasted = Вы продержались до [accent]{0}[]-ой волны. -level.highscore = Рекорд: [accent]{0} -level.delete.title = Подтвердите удаление +stat.wave = Waves Defeated:[accent] {0} +stat.enemiesDestroyed = Enemies Destroyed:[accent] {0} +stat.built = Buildings Built:[accent] {0} +stat.destroyed = Buildings Destroyed:[accent] {0} +stat.deconstructed = Buildings Deconstructed:[accent] {0} +stat.delivered = Resources Launched: map.delete = Вы действительно хотите удалить карту "[accent]{0}[]"? +level.highscore = Рекорд: [accent]{0} level.select = Выбор карты level.mode = Режим игры: construction.desktop = Чтобы отменить выбор блока или остановить строительство, [accent] используйте пробел[]. @@ -28,60 +31,36 @@ deconstruction.title = Руководство по разрушению блок deconstruction = Вы только что перешли в режим сноса[accent] блоков.[].\n\nЧтобы начать удалять, просто нажмите на блок рядом с вашим мехом.\nПосле того как вы выбрали несколько блоков, нажмите на галочку, чтобы подтвердить, и ваш мех начнёт их сносить.\n\n- [accent]Уберите блоки [] из вашего выбора, нажав на них.\n- [accent]Удалите блоки в области [], нажав и удерживая на пустом месте, а затем перетаскивая в нужном направлении.\n- [accent]Отменить снос или выбор [] можно нажав X в нижнем правом углу. showagain = Не показывать снова до следующей сессии coreattack = < Ядро находится под атакой! > -unlocks = Разблокированные +nearpoint = [[ [scarlet]LEAVE DROP POINT IMMEDIATELY[] ]\nannihilation imminent +outofbounds = [[ OUT OF BOUNDS ]\n[]self-destruct in {0} +database = Core Database savegame = Сохранить игру loadgame = Загрузить игру joingame = Присоеди\nниться addplayers = Доб/удалить игроков customgame = Пользовательская игра -sectors = Секторы -sector = Выбранный сектор: [LIGHT_GRAY]{0} -sector.time = Время: [LIGHT_GRAY]{0} -sector.deploy = Высадиться -sector.abandon = Отступить -sector.abandon.confirm = Вы уверены, что хотите отступить?\nПрогресс на секторе нельзя восстановить! -sector.resume = Продолжить -sector.locked = [scarlet][[Не завершён] -sector.unexplored = [accent][[Неисследованный] -missions = Миссий:[LIGHT_GRAY] {0} -mission = Миссия:[LIGHT_GRAY] {0} -mission.main = Главная миссия:[LIGHT_GRAY] {0} -mission.info = Информация о миссии -mission.complete = Миссия выполнена! -mission.complete.body = Сектор {0},{1} был завоёван. -mission.wave = Волна[accent] {0}[] из[accent] {1}[]\nВолна через {2} -mission.wave.enemies = Волна[accent] {0} из {1}[]\n{2} враг. -mission.wave.enemy = Волна[accent] {0} из {1}[]\n{2} враг -mission.wave.menu = Пережить[accent] {0} []волн -mission.battle = Уничтожьте ядро противника. -mission.resource.menu = Добыть {0} х{1} -mission.resource = Добыть {0}:\n[accent]{1}/{2}[] -mission.block = Создать {0} -mission.unit = Создать {0} боев. ед. -mission.command = Отправить команду {0} к боев. единицам -mission.linknode = Соединить силовые узлы -mission.display = [accent]Миссия:\n[LIGHT_GRAY]{0} -mission.mech = Переключиться на мех[accent] {0}[] -mission.create = Создать[accent] {0}[] +newgame = New Game none = <нет> close = Закрыть quit = Выход maps = Карты continue = Продолжить -nextmission = Следующая миссия maps.none = [LIGHT_GRAY]Карты не найдены! about.button = Об игре name = Ник: +noname = Pick a[accent] player name[] first. filename = Имя файла: unlocked = Новый блок разблокирован! -unlocked.plural = Новые блоки разблокированы! +completed = [accent]Completed +techtree = Tech Tree +research.list = [LIGHT_GRAY]Research: +research = Research +researched = [LIGHT_GRAY]{0} researched. players = Игроков на сервере: {0} players.single = {0} игрок на сервере server.closing = [accent]Закрытие сервера... server.kicked.kick = Вас выгнали с сервера! server.kicked.serverClose = Сервер закрыт. -server.kicked.sectorComplete = Сектор завоёван. -server.kicked.sectorComplete.text = Ваша миссия завершена.\nСервер продолжит работу и высадит вас в следующем секторе. server.kicked.clientOutdated = Устаревший клиент! Обновите игру! server.kicked.serverOutdated = Устаревший сервер! Попросите хоста обновить сервер/игру! server.kicked.banned = Вы заблокированы на этом сервере. @@ -90,6 +69,7 @@ server.kicked.nameInUse = На этом сервере есть кто-то с server.kicked.nameEmpty = Ваше имя должно содержать хотя бы один символ или цифру. server.kicked.idInUse = Вы уже на этом сервере! Соединение с двумя учетными записями не разрешено. server.kicked.customClient = Этот сервер не поддерживает пользовательские сборки. Загрузите официальную версию. +server.kicked.gameover = Game over! host.info = Кнопка [accent] Сервер [] размещает сервер на порт [accent]6567[].[]\nЛюбой пользователь в той же [LIGHT_GRAY]сети [] получет возможность видеть ваш сервер в своём списке серверов.\n\nЕсли вы хотите, чтобы люди могли подключаться из любого места по IP, то требуется переадресация(проброс) портов.[].\n\n[LIGHT_GRAY] Примечание. Если у кого-то возникают проблемы с подключением к вашей локальной сети, убедитесь, что вы разрешили Mindustry доступ к вашей локальной сети в настройках брандмауэра. join.info = Здесь вы можете ввести IP-адрес [accent]сервера[] для подключения или открыть [accent]локальную сеть [] для подключения к другим серверам.\nПоддерживается многопользовательский режим LAN и WAN.\n\n[LIGHT_GRAY] Примечание: это не является автоматическим глобальным списком серверов; если вы хотите подключиться к кому-то по IP, вам нужно будет спросить у хоста его IP-адрес. hostserver = Запустить сервер @@ -160,7 +140,6 @@ save.rename.text = Новое название: selectslot = Выберите сохранение. slot = [accent]Слот {0} save.corrupted = [accent]Сохранённый файл повреждён или имеет недействительный формат!\nЕсли вы только что обновили свою игру, это, вероятно, из-за изменение формата сохранения[scarlet], а не []ошибка. -sector.corrupted = [accent] Файл сохранения для этого сектора был найден, но загрузка не удалась.\nСоздан новый файл. empty = <Пусто> on = Вкл off = Выкл @@ -170,6 +149,7 @@ save.wave = Волна: {0} save.difficulty = Сложность: {0} save.date = Последнее сохранение: {0} save.playtime = Время в игре: {0} +warning = Warning. confirm = Подтверждение delete = Удалить ok = ОК @@ -260,6 +240,17 @@ tutorial = Обучение editor = Редактор mapeditor = Редактор карт donate = Пожертво\nвать +abandon = Abandon +abandon.text = This zone and all its resources will be lost to the enemy. +locked = Locked +complete = [LIGHT_GRAY]Complete: +resume = Resume Zone:\n[LIGHT_GRAY]{0} +bestwave = [LIGHT_GRAY]Best: {0} +launch = Launch +launch.title = Launch Successful +launch.next = [LIGHT_GRAY]next opportunity at wave {0} +launch.unable = [scarlet]Unable to LAUNCH.[] Enemies. +zone.unlocked = [LIGHT_GRAY]{0} unlocked. connectfail = [crimson]Не удалось подключиться к серверу: [accent] {0} error.unreachable = Сервер недоступен. error.invalidaddress = Некорректный адрес. @@ -267,7 +258,20 @@ error.timedout = Время ожидания истекло!\nУбедитесь error.mismatch = Ошибка пакета:\nвозможное несоответствие версии клиента/сервера. \nУбедитесь, что у Вас и у владельца сервера установлена последняя версия Mindustry! error.alreadyconnected = Вы уже подключены. error.mapnotfound = Не найден файл карты! +error.io = Network I/O error. error.any = Неизвестная сетевая ошибка. +zone.groundZero.name = Ground Zero +zone.craters.name = The Craters +zone.frozenForest.name = Frozen Forest +zone.ruinousShores.name = Ruinous Shores +zone.crags.name = Crags +zone.stainedMountains.name = Stained Mountains +zone.impact0079.name = Impact 0079 +zone.desolateRift.name = Desolate Rift +zone.arcticDesert.name = Arctic Desert +zone.dryWastes.name = Dry Wastes +zone.nuclearComplex.name = Nuclear Production Complex +zone.moltenFault.name = Molten Fault settings.language = Язык settings.reset = Сбросить по умолчанию settings.rebind = Смена @@ -278,7 +282,6 @@ settings.graphics = Графика settings.cleardata = Очистить данные ... settings.clear.confirm = Вы действительно хотите очистить свои данные?\nТо, что сделано, нельзя отменить! settings.clearall.confirm = [scarlet]ОСТОРОЖНО![]\nЭто уничтожит все данные, включая сохранения, карты, разблокированное и настройки управления.\nПосле того как вы нажмете ОК, игра уничтожит все данные и автоматически закроется. -settings.clearsectors = Очистить секторы settings.clearunlocks = Очистить разблокированное settings.clearall = Очистить всё paused = Пауза @@ -317,12 +320,15 @@ blocks.liquidoutput = Выходящая жидкость blocks.liquidoutputspeed = Выходная скорость жидкости blocks.liquiduse = Используется жидкости blocks.coolant = Охлаждающая жидкость +blocks.liquid = Liquid blocks.coolantuse = Охлажд. жидкости используется blocks.inputliquidfuel = Жидкое топливо blocks.liquidfueluse = Жидкого топлива используется blocks.boostitem = Ускоряющий предмет blocks.boostliquid = Ускоряющая жидкость blocks.health = Здоровье +blocks.power = Power +blocks.power.satisfaction = Power Satisfaction blocks.inaccuracy = Разброс blocks.shots = Выстрелы blocks.reload = Выстрелы/секунду @@ -347,6 +353,7 @@ category.items = Предметы category.crafting = Создание category.shooting = Стрельба category.optional = Дополнительные улучшения +setting.indicators.name = Ally Indicators setting.autotarget.name = Авто-цель setting.fpscap.name = Макс. FPS setting.fpscap.none = Неограниченный @@ -379,11 +386,15 @@ category.multiplayer.name = Мультиплеер command.attack = Атаковать command.retreat = Отступить command.patrol = Патрулирование +keybind.gridMode.name = Block Select +keybind.gridModeShift.name = Category Select keybind.press = Нажмите клавишу... keybind.press.axis = Нажмите клавишу... +keybind.screenshot.name = Map Screenshot keybind.move_x.name = Движение по оси x keybind.move_y.name = Движение по оси y keybind.select.name = Выбор/Выстрел +keybind.pick.name = Pick Block keybind.break.name = Разрушение keybind.deselect.name = Отмена keybind.shoot.name = Выстрел @@ -403,29 +414,28 @@ keybind.chat_scroll.name = Прокрутка чата keybind.drop_unit.name = Сбросить юнита keybind.zoom_minimap.name = Увеличить миникарту. mode.help.title = Описание режимов -mode.waves.name = Волны -mode.waves.description = Обычный режим. В режиме "Волны" надо самим добывать ресурсы и сами волны идут безостановочно. +mode.survival.name = Survival +mode.survival.description = The normal mode. Limited resources and automatic incoming waves. mode.sandbox.name = Песочница mode.sandbox.description = Бесконечные ресурсы и нет таймера для волн, но можно самим вызвать волну. mode.freebuild.name = Свободная\nстройка mode.freebuild.description = Ограниченные ресурсы и нет таймера для волн. mode.pvp.name = Противо-\nстояние mode.pvp.description = боритесь против других игроков. +mode.attack.name = Attack +mode.attack.descrption = No waves, with the goal to destroy the enemy base. content.item.name = Предметы content.liquid.name = Жидкости content.unit.name = Боевые единицы -content.recipe.name = Блоки +content.block.name = Blocks content.mech.name = Мехи -item.stone.name = Камень -item.stone.description = Обычное сырьё. Используется для разделения и переработки в другие материалы или переплавки в лаву. item.copper.name = Медь item.copper.description = Полезный строительный материал. Широко используется во всех типах блоков. item.lead.name = Свинец item.lead.description = Основной начальный материал. Широко используется в электронике и транспортировке жидкости. item.coal.name = Уголь item.coal.description = Распространённое и легкодоступное топливо. -item.dense-alloy.name = Плотный сплав -item.dense-alloy.description = Жёсткий сплав, изготовленный из свинца и меди. Используется в передовых транспортных блоках и высокоуровневых бурах. +item.graphite.name = Graphite item.titanium.name = Титан item.titanium.description = Редкий сверхлёгкий металл широко используется в производстве: транспорта, буров и самолётов. item.thorium.name = Торий @@ -446,6 +456,10 @@ item.blast-compound.name = Взрывоопасное соединение item.blast-compound.description = Летучее соединение, используемое в бомбах и взрывчатых веществах. Также может гореть в качестве топлива, но не рекомендуется этого делать. item.pyratite.name = Пиротит item.pyratite.description = Очень огнеопасное вещество, используемое в зажигательном оружии. +item.metaglass.name = Metaglass +item.metaglass.description = A super-tough glass compound. Extensively used for liquid distribution and storage. +item.scrap.name = Scrap +item.scrap.description = Leftover remnants of old structures and units. Contains trace amounts of many different metals. liquid.water.name = Вода liquid.lava.name = Лава liquid.oil.name = Нефть @@ -482,11 +496,10 @@ mech.glaive-ship.weapon = Огненный пулемёт item.explosiveness = [LIGHT_GRAY]Взрывоопасность: {0}% item.flammability = [LIGHT_GRAY]Воспламеняемость: {0}% item.radioactivity = [LIGHT_GRAY]Радиоактивность: {0}% -item.fluxiness = [LIGHT_GRAY]Осадочность: {0}% unit.health = [LIGHT_GRAY]Здоровье: {0} unit.speed = [LIGHT_GRAY]Скорость: {0} mech.weapon = [LIGHT_GRAY]Оружие: {0} -mech.armor = [LIGHT_GRAY]Броня: {0} +mech.health = [LIGHT_GRAY]Health: {0} mech.itemcapacity = [LIGHT_GRAY]Вместимость предметов: {0} mech.minespeed = [LIGHT_GRAY]Скорость добычи: {0} mech.minepower = [LIGHT_GRAY]Мощность добычи: {0} @@ -494,10 +507,15 @@ mech.ability = [LIGHT_GRAY]Способность: {0} liquid.heatcapacity = [LIGHT_GRAY]Теплоёмкость: {0} liquid.viscosity = [LIGHT_GRAY]Вязкость: {0} liquid.temperature = [LIGHT_GRAY]Температура: {0} +block.kiln.name = Kiln +block.kiln.description = Smelts sand and lead into metaglass. Requires small amounts of power. +block.graphite-press.name = Graphite Press +block.multi-press.name = Multi-Press block.constructing = {0}[LIGHT_GRAY](В процессе) block.spawn.name = Точка появления врагов -block.core.name = Ядро -block.space.name = Пустота +block.core-shard.name = Core: Shard +block.core-foundation.name = Core: Foundation +block.core-nucleus.name = Core: Nucleus block.metalfloor.name = Металлическая плита block.deepwater.name = Глубоководье block.water.name = Вода @@ -516,8 +534,8 @@ block.blackrock.name = Чёрный булыжник block.icerock.name = Ледяной булыжник block.copper-wall.name = Медная стена block.copper-wall-large.name = Большая медная стена -block.dense-alloy-wall.name = Стена из плотного сплава -block.dense-alloy-wall-large.name = Большая стена из плотного сплава +block.titanium-wall.name = Titanium Wall +block.titanium-wall-large.name = Large Titanium Wall block.phase-wall.name = Фазовая стена block.phase-wall-large.name = Большая фазовая стена block.thorium-wall.name = Ториевая стена @@ -550,17 +568,19 @@ block.separator.name = Отделитель block.centrifuge.name = Центрифуга block.power-node.name = Силовой узел block.power-node-large.name = Большой силовой узел +block.surge-tower.name = Surge Tower block.battery.name = Аккумулятор block.battery-large.name = Большой аккумулятор block.combustion-generator.name = Генератор внутреннего сгорания block.turbine-generator.name = Турбинный генератор +block.differential-generator.name = Differential Generator +block.impact-reactor.name = Impact Reactor block.mechanical-drill.name = Механический бур block.pneumatic-drill.name = Пневматический бур block.laser-drill.name = Лазерный бур block.water-extractor.name = Экстрактор воды block.cultivator.name = Культиватор -block.alpha-mech-pad.name = Реконструктор мехов "Альфа" -block.dart-ship-pad.name = Реконструктор кораблей "Дротик" +block.alpha-dart-mech-pad.name = Alpha-Dart Mech Pad block.delta-mech-pad.name = Реконструктор мехов "Дельта" block.javelin-ship-pad.name = Реконструктор кораблей "Джавелин" block.trident-ship-pad.name = Реконструктор кораблей "Трезубeц" @@ -625,7 +645,7 @@ block.rtg-generator.name = Радиоизотопный термоэлектри block.spectre.name = Призрак block.meltdown.name = Катастрофа block.container.name = Склад -block.core.description = Самое главное здание в игре. +block.launch-pad.name = Launch Pad team.blue.name = Синяя team.red.name = Красная team.orange.name = Оранжевая @@ -639,6 +659,7 @@ unit.phantom.name = Фантомный дрон unit.phantom.description = Продвинутый дрон. Автоматически добывает руды, собирает предметы, ремонтирует блоки. Значительнее эффективней нежели обычный дрон unit.dagger.name = Разведчик unit.dagger.description = Основная наземная боевая единица. Может быть полезен в группах. +unit.crawler.name = Crawler unit.titan.name = Титан unit.titan.description = Улучшенная бронированная наземная боевая единица. Атакует наземные и воздушные цели. unit.ghoul.name = Бомбардировщик "Гуль" @@ -648,7 +669,11 @@ unit.wraith.description = Быстрый перехватчик, который unit.fortress.name = Крепость unit.fortress.description = Боевая единица с тяжёлой артилерийской установкой. unit.revenant.name = Потусторонний убийца -unit.revenant.description = Боевая единица с тяжёлой лазерной установкой. +unit.eruptor.name = Eruptor +unit.chaos-array.name = Chaos Array +unit.eradicator.name = Eradicator +unit.lich.name = Lich +unit.reaper.name = Reaper tutorial.begin = Ваша миссия здесь состоит в том, чтобы уничтожить[LIGHT_GRAY] вашего врага[].\n\nНачните с[accent] добычи меди[]. Чтобы добыть её, коснитесь месторождения медной руды рядом с вашим ядром. tutorial.drill = Ручная работа не очень эффективна.\n[accent]Буры[] могут копать автоматически.\nПоставьте один на медной жиле. tutorial.conveyor = [accent]Конвейеры[] используются для транспортировки предметов. \nСоздайте конвейеры от бура к ядру. diff --git a/core/assets/bundles/bundle_tk.properties b/core/assets/bundles/bundle_tk.properties index 7d5e1c9daf..10cefc3ba5 100644 --- a/core/assets/bundles/bundle_tk.properties +++ b/core/assets/bundles/bundle_tk.properties @@ -1,5 +1,6 @@ credits.text = Created by [ROYAL]Anuken[] - [SKY]anukendev@gmail.com[]\n\n[GRAY](In case you can't tell, this text is currently unfinished.\nTranslators, don't edit it yet!) credits = Emegi gecenler +contributors = Translators and Contributors discord = Mindustry'in Discord'una katilin! link.discord.description = Orjinal Mindustry'in Discord Konusma Odasi link.github.description = Oyunun Kodu @@ -9,15 +10,18 @@ link.itch.io.description = Bilgisayar ve Site versiyonunun bulundugu Site link.google-play.description = Google Play magaza sayfasi link.wiki.description = Orjinal Mindustry Bilgilendirme Sayfasi linkfail = Link Acilamadi!\nLink sizin icin kopyalandi. +screenshot = Screenshot saved to {0} gameover = Cekirdegin yok edildi. gameover.pvp = The[accent] {0}[] team is victorious! -sector.gameover = Sektor kaybedildi. Geri gitmek ister misin? -sector.retry = Gene dene highscore = [accent]Yeni Yuksek skor! -wave.lasted = Su dalgaya kadar dayandin: [accent]{0}[]. -level.highscore = Yuksek Skor: [accent]{0} -level.delete.title = Silmeyi onayla +stat.wave = Waves Defeated:[accent] {0} +stat.enemiesDestroyed = Enemies Destroyed:[accent] {0} +stat.built = Buildings Built:[accent] {0} +stat.destroyed = Buildings Destroyed:[accent] {0} +stat.deconstructed = Buildings Deconstructed:[accent] {0} +stat.delivered = Resources Launched: map.delete = Su haritayi silmek istediginden emin misin? "[accent]{0}[]"? +level.highscore = Yuksek Skor: [accent]{0} level.select = Seviye secimi level.mode = Oyun Modu: construction.desktop = Bilgisayar kontrolleri degisti.\nEsyayi secmeyi birakmak istiyorsan [accent]bosluga bas[]. @@ -27,60 +31,36 @@ deconstruction.title = Yapi yikma egitimi deconstruction = Daha demin sen[accent]Yapi yikmak icin yikma moduna girdin..[].\n\nkirmak icin, unitinin cevresindeki bir yapiya/yapilara tikla.\nisin bitince, tamamlama tusuna tikla ve gemin onlari lirbaya basliyacak\n\n- [accent]Yapi yikmak [] icin uzerlerine tikla.\n- [accent]bir arazideki yapilari yikmak[] icin bir arazi sec ve tamamlama tusuna bas\n- [accent]yikma modundan cikmak[] icin kosedeki X tusuna bas showagain = Don't show again next session coreattack = < Cekirdek Saldiri altinda! > -unlocks = Oduller +nearpoint = [[ [scarlet]LEAVE DROP POINT IMMEDIATELY[] ]\nannihilation imminent +outofbounds = [[ OUT OF BOUNDS ]\n[]self-destruct in {0} +database = Core Database savegame = Oyunu kaydet loadgame = Devam et joingame = Oyuna katil addplayers = Oyuncu ekle/cikar customgame = Ozel oyun -sectors = Sektorler -sector = Sector: [LIGHT_GRAY]{0} -sector.time = Time: [LIGHT_GRAY]{0} -sector.deploy = Yukle -sector.abandon = Abandon -sector.abandon.confirm = Are you sure you want to abandon all progress at this sector?\nThis cannot be undone! -sector.resume = Devam et -sector.locked = [scarlet][[Incomplete] -sector.unexplored = [accent][[Unexplored] -missions = Missions:[LIGHT_GRAY] {0} -mission = Mission:[LIGHT_GRAY] {0} -mission.main = Main Mission:[LIGHT_GRAY] {0} -mission.info = Mission Info -mission.complete = Gorev tamamlandi! -mission.complete.body = Sektor {0},{1} ele gecirildi -mission.wave = [accent]{0}/{1}[] Dalga hayatta kal\n{2} Dalga -mission.wave.enemies = Survive[accent] {0}/{1} []waves\n{2} Enemies -mission.wave.enemy = Survive[accent] {0}/{1} []waves\n{2} Enemy -mission.wave.menu = Survive[accent] {0} []waves -mission.battle = Dusmanin cekirdegini yok et -mission.resource.menu = Obtain {0} x{1} -mission.resource = {0} x{1} Kazan -mission.block = Create {0} -mission.unit = Create {0} Unit -mission.command = Send Command {0} To Units -mission.linknode = Link Power Node -mission.display = [accent]Mission:\n[LIGHT_GRAY]{0} -mission.mech = Switch to mech[accent] {0}[] -mission.create = Create[accent] {0}[] +newgame = New Game none = close = Kapat quit = Cik maps = Haritalar continue = Devam et -nextmission = Yeni gorev maps.none = [LIGHT_GRAY]Harita bulunamadi! about.button = Hakkinda name = isim: +noname = Pick a[accent] player name[] first. filename = File Name: unlocked = Yeni yapi acildi!! -unlocked.plural = Yeni yapilar acildi! +completed = [accent]Completed +techtree = Tech Tree +research.list = [LIGHT_GRAY]Research: +research = Research +researched = [LIGHT_GRAY]{0} researched. players = {0} oyuncu cevrimici players.single = {0} oyuncu cevrimici server.closing = [accent]Oyun kapaniyor. server.kicked.kick = Oyundan cikarildin server.kicked.serverClose = Oyun kapandi -server.kicked.sectorComplete = Sektor tamamlandi -server.kicked.sectorComplete.text = Gorev Tamamlandi.\nOyun siradaki sektorden devam edecek server.kicked.clientOutdated = Yeni bir versiyon mevcut! Hemen indir! server.kicked.serverOutdated = Eski oyun! Yapimciya guncellemesini soyle! server.kicked.banned = Oyundan kalici olarak cikarildin. @@ -89,6 +69,7 @@ server.kicked.nameInUse = Oyunda bu isimde bir\nkisi zaten var. server.kicked.nameEmpty = ismin gecerli degil. server.kicked.idInUse = Zaten oyundasin! iki ayri hesapla oyuna katilamazsin! server.kicked.customClient = Bu oyun ayarlanmis vesiyonlara izin vermiyor. Orijinal bir versiyon dene! +server.kicked.gameover = Game over! host.info = [accent]host[] su linkte bir oyun acti! [scarlet]6567[]. \nSeninle [LIGHT_GRAY]ayni internete[] sahip olan kisiler oyunu gorebilir.\n\neger baska yerlerden kisilerind de gelmesini istiyorsan, [accent]oyun acmak[]zorunludur.\n\n[LIGHT_GRAY]Not: eger baglanmakta gucluk cekiliyorsa, antivirusunun internetine baglanmasini izin vermesini sagla. join.info = Buradan,[accent]Oyunun linkini[] kullanarak katilabilir, yada, [accent]internetinle[] baglanacak oyun bulabilirsin\ninternetli ve Linkli oyunlar desteklenir.\n\n[LIGHT_GRAY]Not: Otomatik bir oyun listesi goruntulenemez. Yapimcidan linkini iste. hostserver = Oyun ac @@ -159,7 +140,6 @@ save.rename.text = Yeni isim: selectslot = Kayitli bir dosya sec. slot = [accent]Slot {0} save.corrupted = [accent]Kayit gecersiz!\nOyunu guncellediysen, bu buyuk ihtimalle degistirilecek vebu bir [scarlet]sorun degildir.[] -sector.corrupted = [accent]Yeni dosyalar bulundu, ama yuklenemedi.\nYeni bir tane yapildi. empty = on = Acik off = Kapali @@ -169,6 +149,7 @@ save.wave = Dalga {0} save.difficulty = Zorluk: {0} save.date = En sonki kayit: {0} save.playtime = Oyun Zamani!: {0} +warning = Warning. confirm = Onayla delete = Sil ok = Tamam @@ -259,6 +240,17 @@ tutorial = Tutorial editor = Editor mapeditor = Harita yaraticisi donate = Bagis yap +abandon = Abandon +abandon.text = This zone and all its resources will be lost to the enemy. +locked = Locked +complete = [LIGHT_GRAY]Complete: +resume = Resume Zone:\n[LIGHT_GRAY]{0} +bestwave = [LIGHT_GRAY]Best: {0} +launch = Launch +launch.title = Launch Successful +launch.next = [LIGHT_GRAY]next opportunity at wave {0} +launch.unable = [scarlet]Unable to LAUNCH.[] Enemies. +zone.unlocked = [LIGHT_GRAY]{0} unlocked. connectfail = [crimson]Su Oyuna baglanilamadi: [accent]{0} error.unreachable = Server unreachable. error.invalidaddress = Invalid address. @@ -266,7 +258,20 @@ error.timedout = Timed out!\nMake sure the host has port forwarding set up, and error.mismatch = Packet error:\npossible client/server version mismatch.\nMake sure you and the host have the latest version of Mindustry! error.alreadyconnected = Already connected. error.mapnotfound = Map file not found! +error.io = Network I/O error. error.any = Unkown network error. +zone.groundZero.name = Ground Zero +zone.craters.name = The Craters +zone.frozenForest.name = Frozen Forest +zone.ruinousShores.name = Ruinous Shores +zone.crags.name = Crags +zone.stainedMountains.name = Stained Mountains +zone.impact0079.name = Impact 0079 +zone.desolateRift.name = Desolate Rift +zone.arcticDesert.name = Arctic Desert +zone.dryWastes.name = Dry Wastes +zone.nuclearComplex.name = Nuclear Production Complex +zone.moltenFault.name = Molten Fault settings.language = Dil settings.reset = ilk ayarlara geri al settings.rebind = Geri al @@ -277,7 +282,6 @@ settings.graphics = Grafikler settings.cleardata = Clear Game Data... settings.clear.confirm = Are you sure you want to clear this data?\nWhat is done cannot be undone! settings.clearall.confirm = [scarlet]WARNING![]\nThis will clear all data, including saves, maps, unlocks and keybinds.\nOnce you press 'ok' the game will wipe all data and automatically exit. -settings.clearsectors = Clear Sectors settings.clearunlocks = Clear Unlocks settings.clearall = Clear All paused = Duraklatildi @@ -316,12 +320,15 @@ blocks.liquidoutput = Sivi cikisi blocks.liquidoutputspeed = Liquid Output Speed blocks.liquiduse = Sivi kullanimi blocks.coolant = Sogutma sivisi +blocks.liquid = Liquid blocks.coolantuse = Sogutma sivi kullanimi blocks.inputliquidfuel = Yakit sivisi blocks.liquidfueluse = Sivi yakit kullanimi blocks.boostitem = Boost Item blocks.boostliquid = Boost Liquid blocks.health = Can +blocks.power = Power +blocks.power.satisfaction = Power Satisfaction blocks.inaccuracy = sekme blocks.shots = vuruslar blocks.reload = Yeniden doldurma @@ -346,6 +353,7 @@ category.items = esyalar category.crafting = uretim category.shooting = sikma category.optional = Optional Enhancements +setting.indicators.name = Ally Indicators setting.autotarget.name = Auto-Target setting.fpscap.name = Max FPS setting.fpscap.none = Yok @@ -378,11 +386,15 @@ category.multiplayer.name = Cok oyunculu command.attack = Attack command.retreat = Retreat command.patrol = Patrol +keybind.gridMode.name = Block Select +keybind.gridModeShift.name = Category Select keybind.press = Bir tusa bas... keybind.press.axis = Bir yone cevir yada tusa bas... +keybind.screenshot.name = Map Screenshot keybind.move_x.name = Sol/Sag hareket keybind.move_y.name = Yukari/asagi hareket keybind.select.name = Sec/silahi sik +keybind.pick.name = Pick Block keybind.break.name = Kirma keybind.deselect.name = Eldeki yapiyi birak keybind.shoot.name = Sik @@ -402,29 +414,28 @@ keybind.chat_scroll.name = Konusma kaydir keybind.drop_unit.name = Unit birak keybind.zoom_minimap.name = Haritayi yaklastir mode.help.title = Modlarin aciklamalari -mode.waves.name = Dalgali -mode.waves.description = Klasik mod. Dalgalara karsi cekirdegi koru. +mode.survival.name = Survival +mode.survival.description = The normal mode. Limited resources and automatic incoming waves. mode.sandbox.name = Serbest mode.sandbox.description = Sonsuz esyalar ve Dalga suresi yok mode.freebuild.name = Yapi Yapma mode.freebuild.description = Sinirli esyalar ama dalga suresi yok. mode.pvp.name = PvP mode.pvp.description = fight against other players locally. +mode.attack.name = Attack +mode.attack.descrption = No waves, with the goal to destroy the enemy base. content.item.name = Esyalar content.liquid.name = Sivilar content.unit.name = Units -content.recipe.name = Yapilar +content.block.name = Blocks content.mech.name = Robotlar -item.stone.name = Tas -item.stone.description = Yaygin bir materyal. Magma'yi eriterek yada Kazma makineleriyle alinabilir. item.copper.name = Bakir item.copper.description = ise yayar bir materyal. Kazma makineleriyle yada tasimayla alinabilir. item.lead.name = Kursun item.lead.description = Basit bir baslangic materyali. sivi tasimada kullanilabilir. item.coal.name = Komur item.coal.description = Yaygin bir yakit. -item.dense-alloy.name = Sert karisim -item.dense-alloy.description = Bakir ve kursunun karistirilmasiyle elde edildi. Gelismis yapilar ve kazma makileneri icin kullanilabilir. +item.graphite.name = Graphite item.titanium.name = Titanyum item.titanium.description = Nadir ve hafif bir materyal. Hava araclarinda, Kazma makinelerinde ve sivi tasima tuplerinde kullanilir. item.thorium.name = Toryum @@ -445,6 +456,10 @@ item.blast-compound.name = patlama birlesimi item.blast-compound.description = Bombalar ve patlayicilarda kullanilabilir. Yakit olarak kullanilmasi tavsiye edilmez. item.pyratite.name = Pyratite item.pyratite.description = Yakici silahlar icin yakici bir madde. +item.metaglass.name = Metaglass +item.metaglass.description = A super-tough glass compound. Extensively used for liquid distribution and storage. +item.scrap.name = Scrap +item.scrap.description = Leftover remnants of old structures and units. Contains trace amounts of many different metals. liquid.water.name = Su liquid.lava.name = Magma liquid.oil.name = Benzin @@ -481,11 +496,10 @@ mech.glaive-ship.weapon = Orman yakici item.explosiveness = [LIGHT_GRAY]Patlayicilik: {0} item.flammability = [LIGHT_GRAY]Yanbilirlik: {0} item.radioactivity = [LIGHT_GRAY]Radyoaktivite: {0} -item.fluxiness = [LIGHT_GRAY]akis gucu: {0} unit.health = [LIGHT_GRAY]Can: {0} unit.speed = [LIGHT_GRAY]hiz: {0} mech.weapon = [LIGHT_GRAY]silah: {0} -mech.armor = [LIGHT_GRAY]zirh: {0} +mech.health = [LIGHT_GRAY]Health: {0} mech.itemcapacity = [LIGHT_GRAY]esya kapasitesi: {0} mech.minespeed = [LIGHT_GRAY]kazma hizi: {0} mech.minepower = [LIGHT_GRAY]kazma gucu: {0} @@ -493,9 +507,15 @@ mech.ability = [LIGHT_GRAY]yetenek gucu: {0} liquid.heatcapacity = [LIGHT_GRAY]isinma kapasitesi: {0} liquid.viscosity = [LIGHT_GRAY]Yari sivilik: {0} liquid.temperature = [LIGHT_GRAY]isi: {0} +block.kiln.name = Kiln +block.kiln.description = Smelts sand and lead into metaglass. Requires small amounts of power. +block.graphite-press.name = Graphite Press +block.multi-press.name = Multi-Press block.constructing = {0}\n[LIGHT_GRAY](Constructing) block.spawn.name = Enemy Spawn -block.core.name = cekirdek +block.core-shard.name = Core: Shard +block.core-foundation.name = Core: Foundation +block.core-nucleus.name = Core: Nucleus block.metalfloor.name = metal zemin block.deepwater.name = su alti block.water.name = su @@ -514,8 +534,8 @@ block.blackrock.name = bkara tas block.icerock.name = buz tasi block.copper-wall.name = bakir duvar block.copper-wall-large.name = buyuk bakir duvar -block.dense-alloy-wall.name = Dense Alloy Wall -block.dense-alloy-wall-large.name = Large Dense Alloy Wall +block.titanium-wall.name = Titanium Wall +block.titanium-wall-large.name = Large Titanium Wall block.phase-wall.name = faz duvar block.phase-wall-large.name = genis faz duvar block.thorium-wall.name = Toryum duvari @@ -548,17 +568,19 @@ block.separator.name = separator block.centrifuge.name = Santrifuj block.power-node.name = Guc Dugumu block.power-node-large.name = buyuk Guc Dugumu +block.surge-tower.name = Surge Tower block.battery.name = batarya block.battery-large.name = buyuk batarya block.combustion-generator.name = sicaklik jenaratoru block.turbine-generator.name = termal jenaratoru +block.differential-generator.name = Differential Generator +block.impact-reactor.name = Impact Reactor block.mechanical-drill.name = Mekanikal Kazici block.pneumatic-drill.name = Pneumatik Kazici block.laser-drill.name = Lazer kazici block.water-extractor.name = su ayiricisi block.cultivator.name = ekici -block.alpha-mech-pad.name = Alpha Mech Pad -block.dart-ship-pad.name = Dart Ship Pad +block.alpha-dart-mech-pad.name = Alpha-Dart 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 @@ -623,7 +645,7 @@ block.rtg-generator.name = RTG Generator block.spectre.name = Spectre block.meltdown.name = Meltdown block.container.name = Container -block.core.description = The most important building in the game. +block.launch-pad.name = Launch Pad team.blue.name = blue team.red.name = red team.orange.name = orange @@ -637,6 +659,7 @@ unit.phantom.name = Phantom Drone unit.phantom.description = An advanced drone unit. Automatically mines ores, collects items and repairs blocks. Significantly more effective than a drone. unit.dagger.name = Dagger unit.dagger.description = basit bir zemin uniti +unit.crawler.name = Crawler unit.titan.name = Titan unit.titan.description = havaya sikabilen, gelismis bir unit unit.ghoul.name = Ghoul Bomber @@ -646,7 +669,11 @@ unit.wraith.description = A fast, hit-and-run interceptor unit. unit.fortress.name = Fortress unit.fortress.description = A heavy artillery ground unit. unit.revenant.name = Revenant -unit.revenant.description = A heavy laser platform. +unit.eruptor.name = Eruptor +unit.chaos-array.name = Chaos Array +unit.eradicator.name = Eradicator +unit.lich.name = Lich +unit.reaper.name = Reaper tutorial.begin = Your mission here is to eradicate the[LIGHT_GRAY] enemy[].\n\nBegin by[accent] mining copper[]. Tap a copper ore vein near your core to do this. tutorial.drill = Mining manually is inefficient.\n[accent]Drills []can mine automatically.\nPlace one on a copper vein. tutorial.conveyor = [accent]Conveyors[] are used to transport items to the core.\nMake a line of conveyors from the drill to the core. diff --git a/core/assets/bundles/bundle_tr.properties b/core/assets/bundles/bundle_tr.properties index 440393ee6a..13c62b3f50 100644 --- a/core/assets/bundles/bundle_tr.properties +++ b/core/assets/bundles/bundle_tr.properties @@ -1,5 +1,6 @@ credits.text = Created by [ROYAL]Anuken[] - [SKY]anukendev@gmail.com[]\n\n[GRAY](In case you can't tell, this text is currently unfinished.\nTranslators, don't edit it yet!) credits = Yapımcılar +contributors = Translators and Contributors discord = Mindustry Discord'una katılın! link.discord.description = Resmi Mindustry Discord iletişim kanalı link.github.description = Oyunun kaynak kodu @@ -8,18 +9,19 @@ link.trello.description = Planlanan özellikler için resmi Trello Bülteni link.itch.io.description = PC yüklemeleri ve web sürümü ile itch.io sayfası link.google-play.description = Google Play mağaza sayfası link.wiki.description = Resmi Mindustry Wikipedi'si -linkfail = Bağlantı açılamadı\! URL, yazı tahtanıza kopyalandı. -editor.web = Web sürümü editörü desteklemiyor\! Editörü kullanmak için oyunu indirin. -web.unsupported = Site versiyonu bunu desteklemiyor\! Oyunu indirip dene. +linkfail = Bağlantı açılamadı! URL, yazı tahtanıza kopyalandı. +screenshot = Screenshot saved to {0} gameover = Çekirdek yok edildi. -gameover.pvp = [accent] {0}[] takimi kazandi \! -sector.gameover = Sektor kaybedildi. -sector.retry = Tekrar dene -highscore = [SARI] Yeni yüksek puan\! -wave.lasted = Su dalgaya kadar yasadin: [accent]{0}[]. -level.highscore = Yüksek Puan\: [accent] {0} -level.delete.title = Silmeyi onaylayın +gameover.pvp = [accent] {0}[] takimi kazandi ! +highscore = [SARI] Yeni yüksek puan! +stat.wave = Waves Defeated:[accent] {0} +stat.enemiesDestroyed = Enemies Destroyed:[accent] {0} +stat.built = Buildings Built:[accent] {0} +stat.destroyed = Buildings Destroyed:[accent] {0} +stat.deconstructed = Buildings Deconstructed:[accent] {0} +stat.delivered = Resources Launched: map.delete = Su haritayi silmek istedigine emin misin? "[orange]{0}[]"? +level.highscore = Yüksek Puan: [accent] {0} level.select = Seviye Seç level.mode = Oyun Modu construction.desktop = Masaustu kontrolleri degisti.\nSecmeyi birakip yapmayi kesmek icin, [accent]bosluga bas[]. @@ -28,61 +30,37 @@ construction = Sen su anda [accent]blok yapma moduna gectin[].\n\nYapmaya baslam deconstruction.title = Blok Yikim Ogreticisi deconstruction = Sen su anda [accent]blok yikim moduna gectin[].\n\nKirmaya baslamak icin, geminin cevresinde bir bloga tikla\nBiraz blok sectikten sonra, "tik" tusuna basarak onayla, ve gemin onlari yikmaya baslayacaktir.\n\n- [accent]Blok kaldirmak[] icin onlari secme yerine gene tikla\n- [accent]Bir alanin icinde blok kirmak icin[] bos bir yere tikla, ve surukle\n- [accent]Yikma modundan cikmak icin[] Kosedeki X tusuna bas showagain = Bunu gene gosterme -coreattack = < Cekirdek saldiri altinda\! > -unlocks = Koleksiyon +coreattack = < Cekirdek saldiri altinda! > +nearpoint = [[ [scarlet]LEAVE DROP POINT IMMEDIATELY[] ]\nannihilation imminent +outofbounds = [[ OUT OF BOUNDS ]\n[]self-destruct in {0} +database = Core Database savegame = Oyunu Kaydet loadgame = Oyunu yükle joingame = Oyuna katıl addplayers = Oyuncu ekle/cikar customgame = Ozel oyun -sectors = Sektorler -sector = Su sektoru sectin\: [LIGHT_GRAY]{0} -sector.time = Zaman\: [LIGHT_GRAY]{0} -sector.deploy = Basla -sector.abandon = Terk et -sector.abandon.confirm = Buradaki ilerlemeni silmek istedigine emin misin\nBu geri alinamaz\! -sector.resume = Devam et -sector.locked = [scarlet][[Bitirilmedi] -sector.unexplored = [accent][[Kesvedilmedş] -missions = Gorevler\:[LIGHT_GRAY] {0} -mission = Gorev\:[LIGHT_GRAY] {0} -mission.main = Ana gorev\:[LIGHT_GRAY] {0} -mission.info = Gorev bilgisi -mission.complete = Gorev tamamlandi\! -mission.complete.body = Sektor {0},{1} ele gecirildi -mission.wave = [accent]{0}[] dalga hayatta kal -mission.wave.enemies = [accent] {0}/{1} []dalga hayatta kal\n{2} Dusman oldur -mission.wave.enemy = [accent] {0}/{1} []dalga hayatta kal\n{2} Dusman oldur -mission.wave.menu = [accent] {0} []dalga hayatta kal -mission.battle = Dusman temelini yok et -mission.resource.menu = Sunlari ele gecir {0} x{1} -mission.resource = Sunlari ele gecir {0}\:\n[accent]{1}/{2}[] -mission.block = Su kadar yarat {0} -mission.unit = {0} Kadar unit yarat -mission.command = {0} Unite komut yolla -mission.linknode = Guc nodu bagla -mission.display = [accent]Gorev\:\n[LIGHT_GRAY]{0} -mission.mech = Su gemiye degis[accent] {0}[] -mission.create = Su kadar yarat[accent] {0}[] +newgame = New Game none = close = Kapat quit = Çık maps = Haritalar continue = Devam et -nextmission = Siradaki gorev -maps.none = [LIGHT_GRAY]Harita bulunamadi\! +maps.none = [LIGHT_GRAY]Harita bulunamadi! about.button = Hakkında name = Adı: +noname = Pick a[accent] player name[] first. filename = File Name: unlocked = New Block Unlocked! -unlocked.plural = New Blocks Unlocked! +completed = [accent]Completed +techtree = Tech Tree +research.list = [LIGHT_GRAY]Research: +research = Research +researched = [LIGHT_GRAY]{0} researched. players = 1090 oyuncu çevrimiçi players.single = {0} Oyuncu Çevrimiçi server.closing = [accent] Sunucu kapatılıyor ... server.kicked.kick = Sunucudan kovuldun! server.kicked.serverClose = Server closed. -server.kicked.sectorComplete = Sector completed. -server.kicked.sectorComplete.text = Your mission is complete.\nThe server will now continue at the next sector. server.kicked.clientOutdated = Oyun sürümünüz geçerli değil. Oyununu güncelleyin! server.kicked.serverOutdated = Eski sunucu! Ev sahibinden güncellemesini isteyin! server.kicked.banned = Bu sunucudan yasaklandınız. @@ -91,6 +69,7 @@ server.kicked.nameInUse = There is someone with that name\nalready on this serve server.kicked.nameEmpty = Your name must contain at least one character or number. server.kicked.idInUse = You are already on this server! Connecting with two accounts is not permitted. server.kicked.customClient = This server does not support custom builds. Download an official version. +server.kicked.gameover = Game over! host.info = [Vurgu] ana bilgisayarı [] düğmesi, [657] [65] [65] ve [65] [6568] bağlantı noktalarında bir sunucuyu barındırır. [] Aynı [LIGHT_GRAY] wifi veya yerel ağ [] üzerindeki herkes sunucunuzu sunucularında görebilir. liste. Kişilerin IP tarafından herhangi bir yerden bağlanabilmesini istiyorsanız [vurgu] bağlantı noktası iletme [] gereklidir. [LIGHT_GRAY] Not: Birisi LAN oyununuza bağlanırken sorun yaşıyorsa, güvenlik duvarı ayarlarınızda Mindustry'e yerel ağınıza erişebildiğinizden emin olun. join.info = Burada, bağlanmak için yerel ağ [] sunucularına bağlanmak ya da [aksan] sunucularını bulmak için bir [vurgu] sunucunun IP [] girebilirsiniz. Hem LAN hem de WAN çok oyunculu desteklenir. [LIGHT_GRAY] Not: Otomatik bir global sunucu listesi yoktur; Birisine IP ile bağlanmak isterseniz, ana bilgisayardan kendi IP adreslerini sormanız gerekir. hostserver = Oyunu Sun @@ -161,7 +140,6 @@ save.rename.text = Yeni İsim: selectslot = Bir kayıt seçin. slot = [accent] Yuva {0} save.corrupted = [accent] Kayıt dosyası bozuk veya geçersiz! -sector.corrupted = [accent]A save file for this sector was found, but loading failed.\nA new one has been created. empty = on = Açık off = Kapalı @@ -171,6 +149,7 @@ save.wave = Dalga save.difficulty = zorluk save.date = Son Kaydedilen: {0} save.playtime = Playtime: {0} +warning = Warning. confirm = Onayla delete = Sil ok = Tamam @@ -261,6 +240,17 @@ tutorial = Eğitim editor = Editör mapeditor = Harita Editörü donate = Bağışlamak +abandon = Abandon +abandon.text = This zone and all its resources will be lost to the enemy. +locked = Locked +complete = [LIGHT_GRAY]Complete: +resume = Resume Zone:\n[LIGHT_GRAY]{0} +bestwave = [LIGHT_GRAY]Best: {0} +launch = Launch +launch.title = Launch Successful +launch.next = [LIGHT_GRAY]next opportunity at wave {0} +launch.unable = [scarlet]Unable to LAUNCH.[] Enemies. +zone.unlocked = [LIGHT_GRAY]{0} unlocked. connectfail = [crimson] Sunucuya bağlanılamadı: [accent] {0} error.unreachable = Server unreachable. error.invalidaddress = Invalid address. @@ -268,7 +258,20 @@ error.timedout = Timed out!\nMake sure the host has port forwarding set up, and error.mismatch = Packet error:\npossible client/server version mismatch.\nMake sure you and the host have the latest version of Mindustry! error.alreadyconnected = Already connected. error.mapnotfound = Map file not found! +error.io = Network I/O error. error.any = Unkown network error. +zone.groundZero.name = Ground Zero +zone.craters.name = The Craters +zone.frozenForest.name = Frozen Forest +zone.ruinousShores.name = Ruinous Shores +zone.crags.name = Crags +zone.stainedMountains.name = Stained Mountains +zone.impact0079.name = Impact 0079 +zone.desolateRift.name = Desolate Rift +zone.arcticDesert.name = Arctic Desert +zone.dryWastes.name = Dry Wastes +zone.nuclearComplex.name = Nuclear Production Complex +zone.moltenFault.name = Molten Fault settings.language = Dil settings.reset = Varsayılanlara Dön settings.rebind = Rebind @@ -279,7 +282,6 @@ settings.graphics = Grafik settings.cleardata = Clear Game Data... settings.clear.confirm = Are you sure you want to clear this data?\nWhat is done cannot be undone! settings.clearall.confirm = [scarlet]WARNING![]\nThis will clear all data, including saves, maps, unlocks and keybinds.\nOnce you press 'ok' the game will wipe all data and automatically exit. -settings.clearsectors = Clear Sectors settings.clearunlocks = Clear Unlocks settings.clearall = Clear All paused = Duraklatıldı @@ -318,12 +320,15 @@ blocks.liquidoutput = Liquid Output blocks.liquidoutputspeed = Liquid Output Speed blocks.liquiduse = Liquid Use blocks.coolant = Coolant +blocks.liquid = Liquid blocks.coolantuse = Coolant Use blocks.inputliquidfuel = Fuel Liquid blocks.liquidfueluse = Liquid Fuel Use blocks.boostitem = Boost Item blocks.boostliquid = Boost Liquid blocks.health = Can +blocks.power = Power +blocks.power.satisfaction = Power Satisfaction blocks.inaccuracy = yanlışlık blocks.shots = atışlar blocks.reload = Reload @@ -348,6 +353,7 @@ category.items = Items category.crafting = Crafting category.shooting = Shooting category.optional = Optional Enhancements +setting.indicators.name = Ally Indicators setting.autotarget.name = Auto-Target setting.fpscap.name = Max FPS setting.fpscap.none = None @@ -380,11 +386,15 @@ category.multiplayer.name = Multiplayer command.attack = Attack command.retreat = Retreat command.patrol = Patrol +keybind.gridMode.name = Block Select +keybind.gridModeShift.name = Category Select keybind.press = Press a key... keybind.press.axis = Press an axis or key... +keybind.screenshot.name = Map Screenshot keybind.move_x.name = sağ / sol keybind.move_y.name = yukarı / aşağı keybind.select.name = seçmek +keybind.pick.name = Pick Block keybind.break.name = kırmak keybind.deselect.name = Deselect keybind.shoot.name = ateş etme @@ -404,29 +414,28 @@ keybind.chat_scroll.name = Chat scroll keybind.drop_unit.name = drop unit keybind.zoom_minimap.name = Zoom minimap mode.help.title = Modların açıklaması -mode.waves.name = dalgalar -mode.waves.description = normal mod. sınırlı kaynaklar ve otomatik gelen dalgalar. +mode.survival.name = Survival +mode.survival.description = The normal mode. Limited resources and automatic incoming waves. mode.sandbox.name = Limitsiz Oynama mode.sandbox.description = sonsuz kaynaklar ve dalgalar için zamanlayıcı yok. mode.freebuild.name = Özgür Oynama mode.freebuild.description = sınırlı kaynaklar ve dalgalar için zamanlayıcı yok. mode.pvp.name = PvP mode.pvp.description = fight against other players locally. +mode.attack.name = Attack +mode.attack.descrption = No waves, with the goal to destroy the enemy base. content.item.name = Items content.liquid.name = Liquids content.unit.name = Units -content.recipe.name = Blocks +content.block.name = Blocks content.mech.name = Mechs -item.stone.name = taş -item.stone.description = A common raw material. Used for separating and refining into other materials, or melting into lava. item.copper.name = Copper item.copper.description = A useful structure material. Used extensively in all types of blocks. item.lead.name = Lead item.lead.description = A basic starter material. Used extensively in electronics and liquid transportation blocks. item.coal.name = kömür item.coal.description = A common and readily available fuel. -item.dense-alloy.name = Dense Alloy -item.dense-alloy.description = A tough alloy made with lead and copper. Used in advanced transportation blocks and high-tier drills. +item.graphite.name = Graphite item.titanium.name = titanyum item.titanium.description = A rare super-light metal used extensively in liquid transportation, drills and aircraft. item.thorium.name = Thorium @@ -447,6 +456,10 @@ item.blast-compound.name = Blast Compound item.blast-compound.description = A volatile compound used in bombs and explosives. While it can burned as fuel, this is not advised. item.pyratite.name = Pyratite item.pyratite.description = An extremely flammable substance used in incendiary weapons. +item.metaglass.name = Metaglass +item.metaglass.description = A super-tough glass compound. Extensively used for liquid distribution and storage. +item.scrap.name = Scrap +item.scrap.description = Leftover remnants of old structures and units. Contains trace amounts of many different metals. liquid.water.name = su liquid.lava.name = lav liquid.oil.name = petrol @@ -483,11 +496,10 @@ mech.glaive-ship.weapon = Flame Repeater item.explosiveness = [LIGHT_GRAY]Explosiveness: {0} item.flammability = [LIGHT_GRAY]Flammability: {0} item.radioactivity = [LIGHT_GRAY]Radioactivity: {0} -item.fluxiness = [LIGHT_GRAY]Flux Power: {0} unit.health = [LIGHT_GRAY]Health: {0} unit.speed = [LIGHT_GRAY]Speed: {0} mech.weapon = [LIGHT_GRAY]Weapon: {0} -mech.armor = [LIGHT_GRAY]Armor: {0} +mech.health = [LIGHT_GRAY]Health: {0} mech.itemcapacity = [LIGHT_GRAY]Item Capacity: {0} mech.minespeed = [LIGHT_GRAY]Mining Speed: {0} mech.minepower = [LIGHT_GRAY]Mining Power: {0} @@ -495,9 +507,15 @@ mech.ability = [LIGHT_GRAY]Ability: {0} liquid.heatcapacity = [LIGHT_GRAY]Heat Capacity: {0} liquid.viscosity = [LIGHT_GRAY]Viscosity: {0} liquid.temperature = [LIGHT_GRAY]Temperature: {0} +block.kiln.name = Kiln +block.kiln.description = Smelts sand and lead into metaglass. Requires small amounts of power. +block.graphite-press.name = Graphite Press +block.multi-press.name = Multi-Press block.constructing = {0}\n[LIGHT_GRAY](Constructing) block.spawn.name = Enemy Spawn -block.core.name = Core +block.core-shard.name = Core: Shard +block.core-foundation.name = Core: Foundation +block.core-nucleus.name = Core: Nucleus block.metalfloor.name = Metal Floor block.deepwater.name = deepwater block.water.name = water @@ -516,8 +534,8 @@ block.blackrock.name = blackrock block.icerock.name = icerock block.copper-wall.name = Copper Wall block.copper-wall-large.name = Large Copper Wall -block.dense-alloy-wall.name = Dense Alloy Wall -block.dense-alloy-wall-large.name = Large Dense Alloy Wall +block.titanium-wall.name = Titanium Wall +block.titanium-wall-large.name = Large Titanium Wall block.phase-wall.name = Phase Wall block.phase-wall-large.name = Large Phase Wall block.thorium-wall.name = Thorium Wall @@ -550,17 +568,19 @@ block.separator.name = Separator block.centrifuge.name = Centrifuge block.power-node.name = Power Node block.power-node-large.name = Large Power Node +block.surge-tower.name = Surge Tower block.battery.name = Battery block.battery-large.name = Large Battery block.combustion-generator.name = Combustion Generator block.turbine-generator.name = Turbine Generator +block.differential-generator.name = Differential Generator +block.impact-reactor.name = Impact Reactor block.mechanical-drill.name = Mechanical Drill block.pneumatic-drill.name = Pneumatic Drill block.laser-drill.name = Laser Drill block.water-extractor.name = Water Extractor block.cultivator.name = Cultivator -block.alpha-mech-pad.name = Alpha Mech Pad -block.dart-ship-pad.name = Dart Ship Pad +block.alpha-dart-mech-pad.name = Alpha-Dart 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 @@ -625,7 +645,7 @@ block.rtg-generator.name = RTG Generator block.spectre.name = Spectre block.meltdown.name = Meltdown block.container.name = Container -block.core.description = The most important building in the game. +block.launch-pad.name = Launch Pad team.blue.name = blue team.red.name = red team.orange.name = orange @@ -639,6 +659,7 @@ unit.phantom.name = Phantom Drone unit.phantom.description = An advanced drone unit. Automatically mines ores, collects items and repairs blocks. Significantly more effective than a drone. unit.dagger.name = Dagger unit.dagger.description = A basic ground unit. Useful in swarms. +unit.crawler.name = Crawler unit.titan.name = Titan unit.titan.description = An advanced armored ground unit. Uses carbide as ammo. Attacks both ground and air targets. unit.ghoul.name = Ghoul Bomber @@ -648,7 +669,11 @@ unit.wraith.description = A fast, hit-and-run interceptor unit. unit.fortress.name = Fortress unit.fortress.description = A heavy artillery ground unit. unit.revenant.name = Revenant -unit.revenant.description = A heavy laser platform. +unit.eruptor.name = Eruptor +unit.chaos-array.name = Chaos Array +unit.eradicator.name = Eradicator +unit.lich.name = Lich +unit.reaper.name = Reaper tutorial.begin = Your mission here is to eradicate the[LIGHT_GRAY] enemy[].\n\nBegin by[accent] mining copper[]. Tap a copper ore vein near your core to do this. tutorial.drill = Mining manually is inefficient.\n[accent]Drills []can mine automatically.\nPlace one on a copper vein. tutorial.conveyor = [accent]Conveyors[] are used to transport items to the core.\nMake a line of conveyors from the drill to the core. diff --git a/core/assets/bundles/bundle_uk_UA.properties b/core/assets/bundles/bundle_uk_UA.properties index 19ebd95999..2e13882933 100644 --- a/core/assets/bundles/bundle_uk_UA.properties +++ b/core/assets/bundles/bundle_uk_UA.properties @@ -13,13 +13,15 @@ linkfail = Не вдалося відкрити посилання!\nURL-адр screenshot = Скріншот збережено в {0} gameover = Гру закінчено gameover.pvp = [accent] {0}[] команда перемогла! -sector.gameover = Цей сектор було втрачено. Повторно висадитися? -sector.retry = Повторити спробу highscore = [YELLOW]Новий рекорд! -wave.lasted = Вы продержались до [accent]{0}[]-ой волны. -level.highscore = Рекорд: [accent]{0} -level.delete.title = Підтвердьте видалення +stat.wave = Waves Defeated:[accent] {0} +stat.enemiesDestroyed = Enemies Destroyed:[accent] {0} +stat.built = Buildings Built:[accent] {0} +stat.destroyed = Buildings Destroyed:[accent] {0} +stat.deconstructed = Buildings Deconstructed:[accent] {0} +stat.delivered = Resources Launched: map.delete = Ви впевнені, що хочете видалити карту "[accent]{0}[]"? +level.highscore = Рекорд: [accent]{0} level.select = Вибір мапи level.mode = Режим гри: construction.desktop = Щоб скасувати вибір блоку або припинити будівництво, [accent] скористайтеся пробілом[]. @@ -29,64 +31,38 @@ deconstruction.title = Інструкція з деконструкції бло deconstruction = Ви тільки що перешли в [accent] режим деконструкції блоків[].\n\nЩоб почати руйнувати, просто торкніться блоку поруч із вашим кораблем.\nПісля вибору деяких блоків натисніть прапорець, щоб підтвердити, і ваш корабель почне їх деконструювати.\n\n- [accent]Вилучіть блоки[] з вашого вибору, торкнувшись їх.\n- [accent]Вилучіть блоки в зоні[] , торкнувшись і утримуючи порожнє місце, потім перетягніть у потрібному напрямку.\n- [accent]Скасуйте деконструкцію або виділення[] натиснувши X внизу праворуч. showagain = Не показувати знову до наступного сеансу coreattack = < Ядро під атакою! > -unlocks = Розблоковане +nearpoint = [[ [scarlet]LEAVE DROP POINT IMMEDIATELY[] ]\nannihilation imminent +outofbounds = [[ OUT OF BOUNDS ]\n[]self-destruct in {0} +database = Core Database savegame = Зберегти гру loadgame = Завантажити гру joingame = Мережева гра addplayers = Дод/Видалити гравців customgame = Користувальницька гра -sectors = Сектори -sector = Обраний сектор: [LIGHT_GRAY]{0} -sector.time = Час: [LIGHT_GRAY]{0} -sector.deploy = Висадитися -sector.abandon = Відступити -sector.abandon.confirm = Ви впевнені, що хочете відступити?\nПрогрес в секторі не можна відновити! -sector.resume = Продовжити -sector.locked = [scarlet][[Незавершений] -sector.unexplored = [accent][[Недосліджений] -missions = Місії:[LIGHT_GRAY] {0} -mission = Місія:[LIGHT_GRAY] {0} -mission.main = Головна місія:[LIGHT_GRAY] {0} -mission.info = Інформація про місію -mission.complete = Місія виконана! -mission.complete.body = Сектор {0},{1} був завойований. -mission.wave = Пережити [accent]{0}/{1}[]\nХвиля через {2} -mission.wave.enemies = Пережити [accent] {0}/{1} []хвиль\n{2} ворог. -mission.wave.enemy = Пережити[accent] {0}/{1} []хвил.\n{2} Ворог -mission.wave.menu = Пережити[accent] {0} [] хвиль -mission.battle = Знищте ядро супротивника. -mission.resource.menu = Добути {0} x{1} -mission.resource = Добути {0}:\n[accent]{1}/{2}[] -mission.block = Створити {0} -mission.unit = Створити {0} бой.од. -mission.command = Надіслати команду {0} боїв. одиницям -mission.linknode = З'єднати силові вузли -mission.display = [accent]Місія:\n[LIGHT_GRAY]{0} -mission.mech = Переключитися на мех[accent] {0}[] -mission.create = Створити[accent] {0}[] +newgame = New Game none = <нічого> close = Закрити quit = Вийти maps = Мапи continue = Продовжити -nextmission = Наступна місія maps.none = [LIGHT_GRAY]Карт не знайдено! about.button = Про гру name = Нік: noname = Спочатку придумайте[accent] собі нікнейм[]. filename = Ім'я файлу: unlocked = Новий блок розблоковано! -unlocked.plural = Нові блоки розблоковано! +completed = [accent]Completed +techtree = Tech Tree +research.list = [LIGHT_GRAY]Research: +research = Research +researched = [LIGHT_GRAY]{0} researched. players = Гравців на сервері: {0} players.single = {0} гравець на сервері server.closing = [accent]Закриття серверу... server.kicked.kick = Ви були вигнані(кікнуті) з сервера! server.kicked.serverClose = Сервер закрито. -server.kicked.sectorComplete = Сектор завойовано. -server.kicked.sectorComplete.text = Ваша місія завершена. \nСервер продовжить роботу і висадить Вас в наступному секторі. server.kicked.clientOutdated = Застарілий клієнт! Оновіть свою гру! server.kicked.serverOutdated = Застарілий сервер! Попросіть адміністратора серверу оновити сервер/гру! -server.kicked.commitMismatch = Номер збірки серверу не співпадає з номером вашої збірки клієнта. Скачайте підходящу версію. server.kicked.banned = Ви були заблоковані на цьому сервері. server.kicked.recentKick = Нещодавно Вас вигнали(кікнули). \nПочекайте трохи перед наступним підключенням. server.kicked.nameInUse = На цьому сервері є хтось \nз таким ніком. @@ -164,7 +140,6 @@ save.rename.text = Нова назва: selectslot = Виберіть збереження. slot = [accent]Слот {0} save.corrupted = [accent]Збережений файл пошкоджено або э недійсним! \nЯкщо ви щойно оновили свою гру, це, мабуть, є зміною формату збереження та [scarlet] не[] є помилкою. -sector.corrupted = [accent]Файл збереження для цього сектора знайдено, але завантаження не вдалося. \n Буде створено новий файл. empty = <порожній> on = Включено off = Вимкнено @@ -174,6 +149,7 @@ save.wave = Хвиля {0} save.difficulty = Складність: {0} save.date = Останнє збереження save.playtime = Час гри: {0} +warning = Warning. confirm = Підтвердження delete = Видалити ok = ОК @@ -209,7 +185,7 @@ map.nospawn = Ця мапа не має жодного ядра для спав map.nospawn.pvp = У цій карти немає ворожих ядер, в яких гравець може з'явитися! Додайте[SCARLET] червоні[] ядра до цієї карті в редакторі. map.invalid = Помилка завантаження карти: пошкоджений або невірний файл карти. editor.brush = Пензлик -editor.slope = +editor.slope = \\ editor.openin = Відкрити в редакторі editor.oregen = Генерація руд editor.oregen.info = Генерація руд: @@ -264,6 +240,17 @@ tutorial = Навчання editor = Редактор mapeditor = Редактор мап donate = Пожертву\nвання +abandon = Abandon +abandon.text = This zone and all its resources will be lost to the enemy. +locked = Locked +complete = [LIGHT_GRAY]Complete: +resume = Resume Zone:\n[LIGHT_GRAY]{0} +bestwave = [LIGHT_GRAY]Best: {0} +launch = Launch +launch.title = Launch Successful +launch.next = [LIGHT_GRAY]next opportunity at wave {0} +launch.unable = [scarlet]Unable to LAUNCH.[] Enemies. +zone.unlocked = [LIGHT_GRAY]{0} unlocked. connectfail = [crimson]Не вдалося підключитися до сервера: [accent]{0} error.unreachable = Сервер не доступний. error.invalidaddress = Некоректна адреса. @@ -273,6 +260,18 @@ error.alreadyconnected = Ви вже підключилися. error.mapnotfound = Файл мапи не знайдено error.io = Мережева помилка введення-виведення error.any = Невідома мережева помилка +zone.groundZero.name = Ground Zero +zone.craters.name = The Craters +zone.frozenForest.name = Frozen Forest +zone.ruinousShores.name = Ruinous Shores +zone.crags.name = Crags +zone.stainedMountains.name = Stained Mountains +zone.impact0079.name = Impact 0079 +zone.desolateRift.name = Desolate Rift +zone.arcticDesert.name = Arctic Desert +zone.dryWastes.name = Dry Wastes +zone.nuclearComplex.name = Nuclear Production Complex +zone.moltenFault.name = Molten Fault settings.language = Мова settings.reset = Скинути за замовчуванням settings.rebind = Зміна @@ -283,7 +282,6 @@ settings.graphics = Графіка settings.cleardata = Очистити дані... settings.clear.confirm = Ви впевнені, що хочете очистити ці дані?\nЦя дія не може бути скасовано! settings.clearall.confirm = [scarlet]УВАГА![]\nЦе очистить всі дані, включаючи збереження, карти, розблокуване та призначенні клавіші.\nПісля того, як ви натиснете ОК, гра видалить усі дані та автоматично вийде. -settings.clearsectors = Очистити сектори settings.clearunlocks = Очистити розблоковане settings.clearall = Очистити все paused = Пауза @@ -322,12 +320,15 @@ blocks.liquidoutput = Вихідна рідина blocks.liquidoutputspeed = Швидкість вихідної рідини blocks.liquiduse = Використовуеться рідин blocks.coolant = Охолоджуюча рідина +blocks.liquid = Liquid blocks.coolantuse = Охолодж. рідини використовуеться blocks.inputliquidfuel = Рідке паливо blocks.liquidfueluse = Рідкого палива використовуеться blocks.boostitem = Прискорюючий предмет blocks.boostliquid = Прискорююча рідина blocks.health = Здоров'я +blocks.power = Power +blocks.power.satisfaction = Power Satisfaction blocks.inaccuracy = Розкид blocks.shots = Постріли blocks.reload = Постріли/секунду @@ -393,6 +394,7 @@ keybind.screenshot.name = Скріншот мапи keybind.move_x.name = Рух по осі x keybind.move_y.name = Рух по осі x keybind.select.name = ВибратиПостріл +keybind.pick.name = Pick Block keybind.break.name = Руйнування keybind.deselect.name = Скасувати keybind.shoot.name = Постріл @@ -412,8 +414,8 @@ keybind.chat_scroll.name = Прокрутка чату keybind.drop_unit.name = Скинути бой. од. keybind.zoom_minimap.name = Збільшити мінікарту mode.help.title = Опис режимів -mode.waves.name = Хвилі -mode.waves.description = Звичайний режим. В режимі "Хвилі" треба самим добувати ресурси та хвилі йдуть беззупинно. +mode.survival.name = Survival +mode.survival.description = The normal mode. Limited resources and automatic incoming waves. mode.sandbox.name = Пісочниця mode.sandbox.description = В режимі "Пісочниця" бескінечні ресурси(але їх все одно можно добувати) та хвилі йдуть за вашим бажанням. mode.freebuild.name = Вільне\nбудівництво @@ -425,23 +427,20 @@ mode.attack.descrption = Немає хвиль, мета - знищити баз content.item.name = Предмети content.liquid.name = Рідини content.unit.name = Бойові одиниці -content.recipe.name = Блоки +content.block.name = Blocks content.mech.name = Мехи -item.stone.name = Камінь -item.stone.description = Загальна сировина. Використовується для розділення та переробки в інші матеріали або плавки в лаву. item.copper.name = Мідь item.copper.description = Корисний структурний матеріал. Широко використовується у всіх типах блоків. item.lead.name = Свинець item.lead.description = Базовий стартовий матеріал. Широко використовується в електроніки та транспорту рідин. item.coal.name = Вугілля item.coal.description = Загальне та легкодоступне паливо. -item.dense-alloy.name = Щільний сплав -item.dense-alloy.description = Сплав, котрий вироблений зі свинця та міді. Використовується в передових транспортних блоках та високорівневих свердлах. +item.graphite.name = Graphite item.titanium.name = Титан item.titanium.description = Рідкий суперлегкий метал широко використовується в рідкому транспорті, свердлах та літальних апаратах. item.thorium.name = Торій item.thorium.description = Густий, радіоактивний метал, що використовується як структурна підтримка та ядерне паливо. -item.silicon.name = Кремній +item.silicon.name = Кремній item.silicon.description = Надзвичайно корисний напівпровідник з застосуванням в сонячних батареях та складній електроніці. item.plastanium.name = Пластиній item.plastanium.description = Легкий, пластичний матеріал, що використовується в сучасних літальних апаратах та у боєприпасах для фрагментації. @@ -457,6 +456,10 @@ item.blast-compound.name = Вибухонебезпечне з'єднання item.blast-compound.description = Нестійке з'єднання, що використовується в бомбах та вибухових речовинах. Хоча воно може спалюватися як паливо, та це не рекомендується. item.pyratite.name = Піротит item.pyratite.description = Вкрай легкозаймиста речовина, що використовується у запальній зброї. +item.metaglass.name = Metaglass +item.metaglass.description = A super-tough glass compound. Extensively used for liquid distribution and storage. +item.scrap.name = Scrap +item.scrap.description = Leftover remnants of old structures and units. Contains trace amounts of many different metals. liquid.water.name = Вода liquid.lava.name = Лава liquid.oil.name = Нафта @@ -493,11 +496,10 @@ mech.glaive-ship.weapon = Вогняний кулемет item.explosiveness = [LIGHT_GRAY]Вибухонебезпечність: {0} item.flammability = [LIGHT_GRAY]Вогненебезпечність: {0} item.radioactivity = [LIGHT_GRAY]Радіоактивність: {0} -item.fluxiness = [LIGHT_GRAY]Осадковість: {0} unit.health = [LIGHT_GRAY]Здоров'я: {0} unit.speed = [LIGHT_GRAY]Швидкість: {0} mech.weapon = [LIGHT_GRAY]Зброя: {0} -mech.armor = [LIGHT_GRAY]Броня: {0} +mech.health = [LIGHT_GRAY]Health: {0} mech.itemcapacity = [LIGHT_GRAY] Ємність елементів: {0} mech.minespeed = [LIGHT_GRAY]Швидкість видобутку: {0} mech.minepower = [LIGHT_GRAY]Потужність видобутку: {0} @@ -505,10 +507,15 @@ mech.ability = [LIGHT_GRAY]Здібність: {0} liquid.heatcapacity = [LIGHT_GRAY]Теплоємність: {0} liquid.viscosity = [LIGHT_GRAY]В'язкість: {0} liquid.temperature = [LIGHT_GRAY]Температура: {0} +block.kiln.name = Kiln +block.kiln.description = Smelts sand and lead into metaglass. Requires small amounts of power. +block.graphite-press.name = Graphite Press +block.multi-press.name = Multi-Press block.constructing = {0}\n[LIGHT_GRAY](В процесі) block.spawn.name = Місце появи ворога -block.core.name = Ядро -block.space.name = Пустота +block.core-shard.name = Core: Shard +block.core-foundation.name = Core: Foundation +block.core-nucleus.name = Core: Nucleus block.metalfloor.name = Металева плитка block.deepwater.name = Глибоководдя block.water.name = Вода @@ -527,8 +534,8 @@ block.blackrock.name = Чорний кругляк block.icerock.name = Льодяний кругляк block.copper-wall.name = Мідна стіна block.copper-wall-large.name = Велика мідна стіна -block.dense-alloy-wall.name = Стіна з щільного сплаву -block.dense-alloy-wall-large.name = Велика стіна з щільного сплаву +block.titanium-wall.name = Titanium Wall +block.titanium-wall-large.name = Large Titanium Wall block.phase-wall.name = Фазова стіна block.phase-wall-large.name = Велика фазова стіна block.thorium-wall.name = Торієва стіна @@ -561,17 +568,19 @@ block.separator.name = Сепаратор block.centrifuge.name = Центрифуга block.power-node.name = Енергійний вузол block.power-node-large.name = Великий енергетичний вузол +block.surge-tower.name = Surge Tower block.battery.name = Акумулятор block.battery-large.name = Великий акумулятор block.combustion-generator.name = Генератор горіння block.turbine-generator.name = Турбогенератор +block.differential-generator.name = Differential Generator +block.impact-reactor.name = Impact Reactor block.mechanical-drill.name = Механічний дриль block.pneumatic-drill.name = Пневматичний дриль block.laser-drill.name = Лазерний дриль block.water-extractor.name = Екстрактор води block.cultivator.name = Культиватор -block.alpha-mech-pad.name = Реконстуктор "Альфа" -block.dart-ship-pad.name = Завод дротікових літаків +block.alpha-dart-mech-pad.name = Alpha-Dart Mech Pad block.delta-mech-pad.name = Реконструктор "Дельта" block.javelin-ship-pad.name = Реконструктор "Джавелін" block.trident-ship-pad.name = Реконструктор "Тризуб" @@ -636,6 +645,7 @@ block.rtg-generator.name = Радіоізотопний термоелектри block.spectre.name = Мара block.meltdown.name = Розтоплення block.container.name = Склад +block.launch-pad.name = Launch Pad team.blue.name = Синя team.red.name = Червона team.orange.name = Помаренчева @@ -649,6 +659,7 @@ unit.phantom.name = Фантом unit.phantom.description = Покращений дрон. Автоматично добуває руди та ремонтує блоки. unit.dagger.name = Кинджал unit.dagger.description = Базова наземна бойова одиниця. Корисен у купі. +unit.crawler.name = Crawler unit.titan.name = Титан unit.titan.description = Улучшенная бронированная наземная боевая единица. Атакует наземные и воздушные цели. unit.ghoul.name = Бомбардувальний "Ґуль" @@ -658,7 +669,11 @@ unit.wraith.description = Швидка бойова одиниця, котрий unit.fortress.name = Фортеця unit.fortress.description = Тяжка артилерійна наземна бойова одиниця. unit.revenant.name = Потойбічний вбивця -unit.revenant.description = Важка бойова одиниця з лазерною зброєю. +unit.eruptor.name = Eruptor +unit.chaos-array.name = Chaos Array +unit.eradicator.name = Eradicator +unit.lich.name = Lich +unit.reaper.name = Reaper tutorial.begin = Ваша місія тут полягає в ліквідації[LIGHT_GRAY] противника[].\n\nПочнімо з[accent] видобутку міді[]. Щоб зробити це, торкніться мідної рудної жили біля вашого ядра. tutorial.drill = Ручна робота не ефективна\n[accent]Бури []можуть копати автоматично.\nПоставте один на мідній жилі. tutorial.conveyor = [accent]Конвейери[] використовуються для транспортування предметів в ядра.\nЗробіть лінію конвейерів від бурів до ядра. @@ -680,7 +695,6 @@ tutorial.daggerfactory = Побудуйте[accent] завод "Кинджал". tutorial.router = Фабрики потребують ресурсів для функціонування.\nСтворіть маршрутизатор для розподілення ресурсів з конвейера. tutorial.dagger = Зв'яжіть силовий вузол з заводом.\nЯк тільки вимоги будуть виконані, буде створено мех.\n\nЯкщо необхідно, то створіть ще бурів, генераторів та конвейерів tutorial.battle = [LIGHT_GRAY] Супротивник[] показав своє ядро.\nЗнищьте його з вашим мехом та бойовою одиницею. -block.core.description = Найголовніше будівля в грі. block.copper-wall.description = Дешевий оборонний блок.\nКорисен для захисту ядра і турелей під час перших хвиль. block.copper-wall-large.description = Велика стіна найменшим запасом міцності.\nКорисна на початку гри. block.dense-alloy-wall.description = Стіна з показником міцності "нижче середнього". @@ -730,7 +744,7 @@ block.incinerator.description = Якщо є непотрібні ресурси, block.biomattercompressor.description = Виробляє нафту з біоматеріі, біосміття і енергії. block.separator.description = Шукає в камені різні ресурси. Чим цінніше ресурс, тим з меншою ймовірністю він "знайдеться". block.centrifuge.description = Шукає в камені різні ресурси. Чим цінніше ресурс, тим з меншою ймовірністю він "знайдеться".\nТребует енергію. -block.power-node.description = Максимум допустимо 4 підключення.\nЩоб з'єднати з якимось блоком потрібно наступне\:\n1. Щоб він знаходився в радіусі дії \n2. Натиснити на потрібний силовий вузол, а потім на інший силовий вузол або блок. +block.power-node.description = Максимум допустимо 4 підключення.\nЩоб з'єднати з якимось блоком потрібно наступне:\n1. Щоб він знаходився в радіусі дії \n2. Натиснити на потрібний силовий вузол, а потім на інший силовий вузол або блок. block.power-node-large.description = Силовий вузол другого покоління. Збільшено радіус дії і кількість максимально допустимих підключень. block.battery.description = Хранит энергию всякий раз, когда есть изобилие, и обеспечивает мощность всякий раз, когда есть недостаток, если есть мощность, але БАТАРЕЙКИ DURACELL ЗБЕРІГАЮТЬ БІЛЬШЕ! (прихована реклама) block.battery-large.description = Зберігає значно більше енергії, ніж звичайна батарейка... diff --git a/core/assets/bundles/bundle_zh_CN.properties b/core/assets/bundles/bundle_zh_CN.properties index e64258afdd..81c4b9024c 100644 --- a/core/assets/bundles/bundle_zh_CN.properties +++ b/core/assets/bundles/bundle_zh_CN.properties @@ -1,5 +1,6 @@ credits.text = Created by [ROYAL]Anuken[] - [SKY]anukendev@gmail.com[]\n\n[GRAY](In case you can't tell, this text is currently unfinished.\nTranslators, don't edit it yet!) credits = 致谢 +contributors = Translators and Contributors discord = 加入 Mindustry 的 Discord! link.discord.description = 官方 Mindustry discord 聊天室 link.github.description = 游戏源码 @@ -9,15 +10,18 @@ link.itch.io.description = PC版下载和网页版(itch.io) link.google-play.description = 从谷歌商店获取安卓版 link.wiki.description = 官方 Mindustry 维基 linkfail = 打开链接失败!\nURL 已经复制到剪贴板。 +screenshot = Screenshot saved to {0} gameover = 你的核心被摧毁了! gameover.pvp = accent] {0}[] 队获胜! -sector.gameover = 这个区域失守了,要重新部署吗? -sector.retry = 重试 highscore = [accent]新纪录! -wave.lasted = 你坚持到了第 [accent]{0}[] 波。 -level.highscore = 最高分: [accent]{0} -level.delete.title = 确认删除 +stat.wave = Waves Defeated:[accent] {0} +stat.enemiesDestroyed = Enemies Destroyed:[accent] {0} +stat.built = Buildings Built:[accent] {0} +stat.destroyed = Buildings Destroyed:[accent] {0} +stat.deconstructed = Buildings Deconstructed:[accent] {0} +stat.delivered = Resources Launched: map.delete = 确定要删除 "[accent]{0}[]" 地图吗? +level.highscore = 最高分: [accent]{0} level.select = 选择关卡 level.mode = 游戏模式: construction.desktop = 桌面控制已更改.\n取消选择快活停止构建, [accent]使用空间[]. @@ -27,60 +31,36 @@ deconstruction.title = 方块删除指导 deconstruction = 你选择了 [accent]删除模式[]。\n\n点击你附近的有效位置以删除\n选择了方块以后,点击复选框就会开始删除。\n\n- [accent]移除方块-[] 点击想要删除的方块。\n- [accent]移除选中部分-[] 按住并拖动以选中一个区域。\n- [accent]取消删除或选择-[] 按左下角的X. showagain = 不再显示 coreattack = < 核心正在受到攻击! > -unlocks = 已解锁 +nearpoint = [[ [scarlet]LEAVE DROP POINT IMMEDIATELY[] ]\nannihilation imminent +outofbounds = [[ OUT OF BOUNDS ]\n[]self-destruct in {0} +database = Core Database savegame = 保存游戏 loadgame = 载入游戏 joingame = 加入游戏 addplayers = 增加/删除玩家 customgame = 自定义游戏 -sectors = 区域 -sector = 区域: [LIGHT_GRAY]{0} -sector.time = 时间: [LIGHT_GRAY]{0} -sector.deploy = 部署 -sector.abandon = 放弃 -sector.abandon.confirm = 你确定要放弃这个区域的所有进展吗?\n此操作不可撤销! -sector.resume = 继续 -sector.locked = [scarlet][[Incomplete] -sector.unexplored = [accent][[Unexplored] -missions = 任务:[LIGHT_GRAY] {0} -mission = 任务[LIGHT_GRAY] {0} -mission.main = 主要任务:[LIGHT_GRAY] {0} -mission.info = 任务信息 -mission.complete = 任务完成! -mission.complete.body = 区域 {0},攻占了 {1} 个 -mission.wave = 存活了 [accent]{0}/{1}[] 波。\n下一波 {2} -mission.wave.enemies = 存活[accent] {0}/{1} []波\n{2} 敌人 -mission.wave.enemy = 存活[accent] {0}/{1} []波\n{2} 敌人 -mission.wave.menu = 存活[accent] {0} []波 -mission.battle = 摧毁敌方基地。 -mission.resource.menu = 获取{0}x{1} -mission.resource = 获取{0}︰\n[accent]{1}/{2}[] -mission.block = 建造{0} -mission.unit = 生产{0}机组 -mission.command = 发送{0}指令至机组 -mission.linknode = 连接能源节点 -mission.display = [accent]任务︰\n[LIGHT_GRAY]{0} -mission.mech = 转换至[accent]{0}[]机甲 -mission.create = 制造[accent] {0}[] +newgame = New Game none = <无> close = 关闭 quit = 退出 maps = 地图 continue = 继续 -nextmission = 下一个任务 maps.none = [LIGHT_GRAY]未发现地图! about.button = 关于 name = 名字: +noname = Pick a[accent] player name[] first. filename = 文件名: unlocked = 新方块已解锁! -unlocked.plural = 新方块已解锁! +completed = [accent]Completed +techtree = Tech Tree +research.list = [LIGHT_GRAY]Research: +research = Research +researched = [LIGHT_GRAY]{0} researched. players = {0} 玩家在线 players.single = {0} 玩家在线 server.closing = [accent]正在关闭服务器…… server.kicked.kick = 你被踢出服务器了! server.kicked.serverClose = 服务器已关闭。 -server.kicked.sectorComplete = 区域已完成。 -server.kicked.sectorComplete.text = 任务已完成。\n服务器将在下一个区域继续。 server.kicked.clientOutdated = 客户端版本过旧!请升级! server.kicked.serverOutdated = 服务器版本过旧!请联系房主升级! server.kicked.banned = 你被这个服务器拉黑了。 @@ -89,6 +69,7 @@ server.kicked.nameInUse = 服务器中已经\n有人有相同的名字了。 server.kicked.nameEmpty = 你的名字必须至少包含一个字母或数字。 server.kicked.idInUse = 你已经在服务器中!不允许用两个账号。 server.kicked.customClient = 这个服务器不支持修改版客户端,请下载官方版本。 +server.kicked.gameover = Game over! host.info = [accent]创建局域网游戏[]按钮会在[scarlet]6567[]端口运行一个服务器。[]\n任何在同一个[LIGHT_GRAY]网络或本地网络[]下的人都将在服务器列表中看到你的服务器。\n\n如果你想让别人在任何地方都能通过IP地址连接,你需要设定[accent]端口转发[]。\n\n[LIGHT_GRAY]请注意:如果某人无法连接到你的局域网游戏,请确保你在防火墙设置里允许了Mindustry连接本地网络。 join.info = 你可以在这里输入[accent]服务器的IP地址[]以连接,或寻找[accent]本地网络[]中的服务器以连接。\n目前支持局域网或广域网多人游戏。\n\n[LIGHT_GRAY]请注意:没有全球服务器列表;如果你想通过IP地址连接某个服务器,你需要向房主询问IP地址。 hostserver = 创建服务器 @@ -159,7 +140,6 @@ save.rename.text = 新名字: selectslot = 选择一个存档。 slot = [accent]存档 {0} save.corrupted = [accent]存档损坏或无效!\n如果你刚刚升级了游戏,那么这可能是因为存档格式改变了而[scarlet]不是[] bug 。 -sector.corrupted = [accent]发现了一个此区域的保存文件,但是加载失败。\n已经创建了一个新的。 empty = <空> on = 开 off = 关 @@ -169,6 +149,7 @@ save.wave = 第 {0} 波 save.difficulty = 难度: {0} save.date = 最后保存日期:{0} save.playtime = 游戏时间:{0} +warning = Warning. confirm = 确认 delete = 删除 ok = 好的 @@ -259,6 +240,17 @@ tutorial = 教程 editor = 编辑器 mapeditor = 地图编辑器 donate = 捐赠 +abandon = Abandon +abandon.text = This zone and all its resources will be lost to the enemy. +locked = Locked +complete = [LIGHT_GRAY]Complete: +resume = Resume Zone:\n[LIGHT_GRAY]{0} +bestwave = [LIGHT_GRAY]Best: {0} +launch = Launch +launch.title = Launch Successful +launch.next = [LIGHT_GRAY]next opportunity at wave {0} +launch.unable = [scarlet]Unable to LAUNCH.[] Enemies. +zone.unlocked = [LIGHT_GRAY]{0} unlocked. connectfail = [crimson]服务器连接失败: [accent]{0} error.unreachable = 服务器无法访问。 error.invalidaddress = 地址无效。 @@ -266,7 +258,20 @@ error.timedout = 连接超时!\n确保服务器设置了端口转发,并且 error.mismatch = 包错误:\n可能是客户端/服务器版本不匹配.\n请确保客户端和服务器都是最新的版本! error.alreadyconnected = 已连接。 error.mapnotfound = 找不到地图文件! +error.io = Network I/O error. error.any = 未知网络错误. +zone.groundZero.name = Ground Zero +zone.craters.name = The Craters +zone.frozenForest.name = Frozen Forest +zone.ruinousShores.name = Ruinous Shores +zone.crags.name = Crags +zone.stainedMountains.name = Stained Mountains +zone.impact0079.name = Impact 0079 +zone.desolateRift.name = Desolate Rift +zone.arcticDesert.name = Arctic Desert +zone.dryWastes.name = Dry Wastes +zone.nuclearComplex.name = Nuclear Production Complex +zone.moltenFault.name = Molten Fault settings.language = 语言 settings.reset = 恢复默认 settings.rebind = 重新绑定 @@ -277,7 +282,6 @@ settings.graphics = 图像 settings.cleardata = 清除游戏数据…… settings.clear.confirm = 您确定要清除数据吗?\n这个操作无法撤销! settings.clearall.confirm = [scarlet]警告![]\n这将清除所有数据,包括存档、地图、解锁和键绑定。\n按「是」后,游戏将删除所有数据并自动退出。 -settings.clearsectors = 清除区域 settings.clearunlocks = 清除解锁 settings.clearall = 清除所有 paused = 暂停 @@ -316,12 +320,15 @@ blocks.liquidoutput = 液体输出 blocks.liquidoutputspeed = 液体输出速度 blocks.liquiduse = 液体使用速度 blocks.coolant = 冷却剂 +blocks.liquid = Liquid blocks.coolantuse = 冷却剂使用速度 blocks.inputliquidfuel = 液体燃料输入 blocks.liquidfueluse = 液体燃料使用速度 blocks.boostitem = Boost Item blocks.boostliquid = Boost Liquid blocks.health = 生命值 +blocks.power = Power +blocks.power.satisfaction = Power Satisfaction blocks.inaccuracy = 误差 blocks.shots = 发射数 blocks.reload = 重新装弹 @@ -346,6 +353,7 @@ category.items = 物品 category.crafting = 制造 category.shooting = 发射 category.optional = Optional Enhancements +setting.indicators.name = Ally Indicators setting.autotarget.name = 自动发射 setting.fpscap.name = 最高 FPS setting.fpscap.none = 无 @@ -378,11 +386,15 @@ category.multiplayer.name = 多人 command.attack = 攻击 command.retreat = 撤退 command.patrol = 巡逻 +keybind.gridMode.name = Block Select +keybind.gridModeShift.name = Category Select keybind.press = 按一下键…… keybind.press.axis = 按一下轴或键…… +keybind.screenshot.name = Map Screenshot keybind.move_x.name = 水平移动 keybind.move_y.name = 垂直移动 keybind.select.name = 选择 +keybind.pick.name = Pick Block keybind.break.name = 破坏 keybind.deselect.name = 取消 keybind.shoot.name = 射击 @@ -402,29 +414,28 @@ keybind.chat_scroll.name = 聊天记录滚动 keybind.drop_unit.name = 掉落单位 keybind.zoom_minimap.name = 小地图缩放 mode.help.title = 模式说明 -mode.waves.name = 普通 -mode.waves.description = 普通模式,有限的资源和自动生成敌人。 +mode.survival.name = Survival +mode.survival.description = The normal mode. Limited resources and automatic incoming waves. mode.sandbox.name = 沙盒 mode.sandbox.description = 无限的资源,不会自动生成敌人。 mode.freebuild.name = 自由建造 mode.freebuild.description = 有限的资源,不会自动生成敌人。 mode.pvp.name = PvP mode.pvp.description = 和本地玩家对战. +mode.attack.name = Attack +mode.attack.descrption = No waves, with the goal to destroy the enemy base. content.item.name = 物品 content.liquid.name = 液体 content.unit.name = 部队 -content.recipe.name = 方块 +content.block.name = Blocks content.mech.name = 机甲 -item.stone.name = 石头 -item.stone.description = 一种常见的原料。用于分离和提炼成其他材料,或熔化成熔岩。 item.copper.name = 铜 item.copper.description = 一种有用的结构材料。在各种类型的方块中广泛使用。 item.lead.name = 铅 item.lead.description = 一种基本的起始材料。被广泛用于电子设备和液体运输方块。 item.coal.name = 煤 item.coal.description = 一种常见并容易获得的燃料。 -item.dense-alloy.name = 致密合金 -item.dense-alloy.description = 一种由铅和铜制成的坚韧合金。用于高级的运输方块和高级钻头。 +item.graphite.name = Graphite item.titanium.name = 钛 item.titanium.description = 一种罕见的超轻金属,被广泛运用于液体运输、钻头和飞机。 item.thorium.name = 钍 @@ -445,6 +456,10 @@ item.blast-compound.name = 爆炸混合物 item.blast-compound.description = 一种用于炸弹和炸药的挥发性混合物。虽然它可以作为燃料燃烧,但不建议这样做。 item.pyratite.name = 硫 item.pyratite.description = 一种燃烧武器中使用的极易燃物质。 +item.metaglass.name = Metaglass +item.metaglass.description = A super-tough glass compound. Extensively used for liquid distribution and storage. +item.scrap.name = Scrap +item.scrap.description = Leftover remnants of old structures and units. Contains trace amounts of many different metals. liquid.water.name = 水 liquid.lava.name = 岩浆 liquid.oil.name = 石油 @@ -481,11 +496,10 @@ mech.glaive-ship.weapon = 火焰机枪 item.explosiveness = [LIGHT_GRAY]爆炸性:{0} item.flammability = [LIGHT_GRAY]易燃性:{0} item.radioactivity = [LIGHT_GRAY]放射性:{0} -item.fluxiness = [LIGHT_GRAY]助熔性:{0} unit.health = [LIGHT_GRAY]生命值:{0} unit.speed = [LIGHT_GRAY]速度:{0} mech.weapon = [LIGHT_GRAY]武器:{0} -mech.armor = [LIGHT_GRAY]装甲:{0} +mech.health = [LIGHT_GRAY]Health: {0} mech.itemcapacity = [LIGHT_GRAY]物品容量:{0} mech.minespeed = [LIGHT_GRAY]采矿速度:{0} mech.minepower = [LIGHT_GRAY]采矿力量:{0} @@ -493,9 +507,15 @@ mech.ability = [LIGHT_GRAY]能力:{0} liquid.heatcapacity = [LIGHT_GRAY]热容量:{0} liquid.viscosity = [LIGHT_GRAY]粘度:{0} liquid.temperature = [LIGHT_GRAY]温度:{0} +block.kiln.name = Kiln +block.kiln.description = Smelts sand and lead into metaglass. Requires small amounts of power. +block.graphite-press.name = Graphite Press +block.multi-press.name = Multi-Press block.constructing = {0}\n[LIGHT_GRAY](Constructing) block.spawn.name = 敌人出生点 -block.core.name = 核心 +block.core-shard.name = Core: Shard +block.core-foundation.name = Core: Foundation +block.core-nucleus.name = Core: Nucleus block.metalfloor.name = 金属地板 block.deepwater.name = 深水 block.water.name = 水 @@ -514,8 +534,8 @@ block.blackrock.name = 黑岩 block.icerock.name = 冰岩 block.copper-wall.name = 铜墙 block.copper-wall-large.name = 大型铜墙 -block.dense-alloy-wall.name = 致密合金墙 -block.dense-alloy-wall-large.name = 大型致密合金墙 +block.titanium-wall.name = Titanium Wall +block.titanium-wall-large.name = Large Titanium Wall block.phase-wall.name = 相织布墙 block.phase-wall-large.name = 大型相织布墙 block.thorium-wall.name = 钍墙 @@ -548,17 +568,19 @@ block.separator.name = 分离机 block.centrifuge.name = 离心机 block.power-node.name = 能量节点 block.power-node-large.name = 大型能量节点 +block.surge-tower.name = Surge Tower block.battery.name = 电池 block.battery-large.name = 大型电池 block.combustion-generator.name = 燃烧发电机 block.turbine-generator.name = 涡轮发电机 +block.differential-generator.name = Differential Generator +block.impact-reactor.name = Impact Reactor block.mechanical-drill.name = 机械钻头 block.pneumatic-drill.name = 气动钻头 block.laser-drill.name = 激光钻头 block.water-extractor.name = 抽水机 block.cultivator.name = 耕种机 -block.alpha-mech-pad.name = Alpha 机甲平台 -block.dart-ship-pad.name = Dart 机甲平台 +block.alpha-dart-mech-pad.name = Alpha-Dart Mech Pad block.delta-mech-pad.name = Delta 机甲平台 block.javelin-ship-pad.name = 标枪 机甲平台 block.trident-ship-pad.name = 三叉戟 机甲平台 @@ -623,7 +645,7 @@ block.rtg-generator.name = RTG 发电机 block.spectre.name = 幽灵 block.meltdown.name = 熔毁 block.container.name = 容器 -block.core.description = 游戏中最重要的建筑。 +block.launch-pad.name = Launch Pad team.blue.name = 蓝 team.red.name = 红 team.orange.name = 橙 @@ -637,6 +659,7 @@ unit.phantom.name = 鬼怪无人机 unit.phantom.description = 一种先进的无人机单位。自动开采矿石,收集物品和修理块。比初始无人机有效得多。 unit.dagger.name = 尖刀 unit.dagger.description = 基础的地面单位,在蜂群中很有用。 +unit.crawler.name = Crawler unit.titan.name = 泰坦 unit.titan.description = 高级的有武装地面单位,使用电石作为弹药.攻击地面单位和空中单位. unit.ghoul.name = 食尸鬼轰炸机 @@ -646,7 +669,11 @@ unit.wraith.description = 一种快速,打了就跑的截击机。 unit.fortress.name = 堡垒 unit.fortress.description = 一种重炮地面部队。 unit.revenant.name = 亡魂 -unit.revenant.description = 一种重型激光平台。 +unit.eruptor.name = Eruptor +unit.chaos-array.name = Chaos Array +unit.eradicator.name = Eradicator +unit.lich.name = Lich +unit.reaper.name = Reaper tutorial.begin = 你的任务是消灭[LIGHT_GRAY] 敌人 [].\n\n首先开始[accent] 采集铜矿 []。点击核心附近的铜矿开始。 tutorial.drill = 手动采矿效率低.\n[accent] 钻头 []可以自动采矿.\n放一个在铜矿上吧. tutorial.conveyor = [accent]传送带[] 可以把物资传送到核心.\n请造一个传送线,从钻头到核心. diff --git a/core/assets/bundles/bundle_zh_TW.properties b/core/assets/bundles/bundle_zh_TW.properties index 8b00e13b6d..d270e4536d 100644 --- a/core/assets/bundles/bundle_zh_TW.properties +++ b/core/assets/bundles/bundle_zh_TW.properties @@ -14,14 +14,12 @@ screenshot = 截圖保存到{0} gameover = 遊戲結束 gameover.pvp = [accent]{0}[]隊獲勝! highscore = [accent]新的高分紀錄! - stat.wave = 打敗的波次:[accent]{0} stat.enemiesDestroyed = 摧毀的敵人:[accent]{0} stat.built = 建設的建築:[accent]{0} stat.destroyed = 摧毀的建築:[accent]{0} stat.deconstructed = 移除的建築:[accent]{0} stat.delivered = 發射的資源: - map.delete = 確認要刪除「[accent]{0}[]」地圖嗎? level.highscore = 最高分:[accent]{0} level.select = 選擇關卡 @@ -33,12 +31,15 @@ deconstruction.title = 方塊移除指南 deconstruction = 你選擇了[accent]方塊移除模式[]。\n\n要移除方塊,點擊你的船附近的方塊。\n選擇了方塊後,點擊複選框就會開始移除。\n\n- 點擊方塊以從選擇區[accent]移除方塊[]。\n- 按住一個空點向任何方向拖動以[accent]移除選中區域的方塊[]。\n- 點擊左下角的「X」以[accent]取消移除或取消選擇[]。 showagain = 下次不再顯示 coreattack = 〈核心正在受到攻擊!〉 -unlocks = 已解鎖 +nearpoint = [[ [scarlet]LEAVE DROP POINT IMMEDIATELY[] ]\nannihilation imminent +outofbounds = [[ OUT OF BOUNDS ]\n[]self-destruct in {0} +database = Core Database savegame = 儲存遊戲 loadgame = 載入遊戲 joingame = 多人連線 addplayers = 增加/移除玩家 customgame = 自訂遊戲 +newgame = New Game none = <沒有> close = 關閉 quit = 退出 @@ -139,7 +140,6 @@ save.rename.text = 新名稱: selectslot = 選取一個存檔。 slot = [accent]存檔{0} save.corrupted = [accent]此存檔無效或已損毀!\n如果你剛剛升級了遊戲,那麼這可能是因為存檔格式改變了而[scarlet]不是[]錯誤。 -sector.corrupted = [accent]找到此區域的存檔,但是加載失敗。\n已經創建了一個新的存檔。 empty = <空白> on = 開啟 off = 關閉 @@ -149,6 +149,7 @@ save.wave = 波次:{0} save.difficulty = 難度:{0} save.date = 最後存檔時間:{0} save.playtime = 遊玩時間: {0} +warning = Warning. confirm = 確認 delete = 刪除 ok = 確定 @@ -239,7 +240,6 @@ tutorial = 教學 editor = 地圖編輯器 mapeditor = 地圖編輯器 donate = 贊助 - abandon = 放棄 abandon.text = 此區域及其所有資源將會丟失給敵人。 locked = 鎖定 @@ -249,7 +249,8 @@ bestwave = [LIGHT_GRAY]高分:{0} launch = 發射 launch.title = 發射成功 zone.unlocked = [LIGHT_GRAY]{0}已解鎖。 - +launch.next = [LIGHT_GRAY]next opportunity at wave {0} +launch.unable = [scarlet]Unable to LAUNCH.[] Enemies. connectfail = [crimson]無法連線到伺服器:[accent]{0} error.unreachable = 無法到達伺服器。 error.invalidaddress = 無效地址。 @@ -259,20 +260,18 @@ error.alreadyconnected = 已連接。 error.mapnotfound = 找不到地圖! error.io = 網絡輸入輸出錯誤。 error.any = 未知網絡錯誤。 - zone.groundZero.name = Ground Zero zone.craters.name = The Craters zone.frozenForest.name = Frozen Forest zone.ruinousShores.name = Ruinous Shores zone.crags.name = Crags zone.stainedMountains.name = Stained Mountains -zone.impact.name = Impact 0079 +zone.impact0079.name = Impact 0079 zone.desolateRift.name = Desolate Rift zone.arcticDesert.name = Arctic Desert zone.dryWastes.name = Dry Wastes zone.nuclearComplex.name = Nuclear Production Complex zone.moltenFault.name = Molten Fault - settings.language = 語言 settings.reset = 重設為預設設定 settings.rebind = 重新綁定 @@ -321,12 +320,15 @@ blocks.liquidoutput = 輸出液體 blocks.liquidoutputspeed = 輸出液體速度 blocks.liquiduse = 使用液體速度 blocks.coolant = 冷卻劑 +blocks.liquid = Liquid blocks.coolantuse = 使用冷卻劑 blocks.inputliquidfuel = 輸入液體燃料 blocks.liquidfueluse = 使用液體燃料速度 blocks.boostitem = 強化物品 blocks.boostliquid = 強化液體 blocks.health = 耐久度 +blocks.power = Power +blocks.power.satisfaction = Power Satisfaction blocks.inaccuracy = 誤差 blocks.shots = 射擊數 blocks.reload = 重裝彈藥 @@ -392,6 +394,7 @@ keybind.screenshot.name = 地圖截圖 keybind.move_x.name = 水平移動 keybind.move_y.name = 垂直移動 keybind.select.name = 選取 +keybind.pick.name = Pick Block keybind.break.name = 拆除 keybind.deselect.name = 取消選取 keybind.shoot.name = 射擊 @@ -411,8 +414,8 @@ keybind.chat_scroll.name = 聊天記錄滾動 keybind.drop_unit.name = 放下單位 keybind.zoom_minimap.name = 縮放小地圖 mode.help.title = 模式說明 -mode.waves.name = 一般 -mode.waves.description = 一般模式,有限的資源與自動來襲的波次。 +mode.survival.name = Survival +mode.survival.description = The normal mode. Limited resources and automatic incoming waves. mode.sandbox.name = 沙盒 mode.sandbox.description = 無限的資源,與不倒數計時的波次。 mode.freebuild.name = 自由建造 @@ -420,7 +423,7 @@ mode.freebuild.description = 有限的資源,與不倒數計時的波次。 mode.pvp.name = 對戰 mode.pvp.description = 和其他玩家鬥爭。 mode.attack.name = 攻擊 -mode.attack.description = 沒有波次,目標是摧毀敵人的基地。 +mode.attack.descrption = No waves, with the goal to destroy the enemy base. content.item.name = 物品 content.liquid.name = 液體 content.unit.name = 機組 @@ -493,11 +496,10 @@ mech.glaive-ship.weapon = 火焰機關槍 item.explosiveness = [LIGHT_GRAY]爆炸性:{0} item.flammability = [LIGHT_GRAY]易燃性:{0} item.radioactivity = [LIGHT_GRAY]放射性:{0} -item.fluxiness = [LIGHT_GRAY]助熔性:{0} unit.health = [LIGHT_GRAY]耐久度:{0} unit.speed = [LIGHT_GRAY]速度:{0} mech.weapon = [LIGHT_GRAY]武器:{0} -mech.armor = [LIGHT_GRAY]裝甲:{0} +mech.health = [LIGHT_GRAY]Health: {0} mech.itemcapacity = [LIGHT_GRAY]物品容量:{0} mech.minespeed = [LIGHT_GRAY]採礦速度:{0} mech.minepower = [LIGHT_GRAY]採礦力度:{0} @@ -505,9 +507,15 @@ mech.ability = [LIGHT_GRAY]能力:{0} liquid.heatcapacity = [LIGHT_GRAY]熱容量:{0} liquid.viscosity = [LIGHT_GRAY]粘性:{0} liquid.temperature = [LIGHT_GRAY]温度:{0} +block.kiln.name = Kiln +block.kiln.description = Smelts sand and lead into metaglass. Requires small amounts of power. +block.graphite-press.name = Graphite Press +block.multi-press.name = Multi-Press block.constructing = {0}\n[LIGHT_GRAY](Constructing) block.spawn.name = 敵人生成 -block.core.name = 核心 +block.core-shard.name = Core: Shard +block.core-foundation.name = Core: Foundation +block.core-nucleus.name = Core: Nucleus block.metalfloor.name = 金屬地板 block.deepwater.name = 深水 block.water.name = 水 @@ -526,8 +534,8 @@ block.blackrock.name = 黑岩石 block.icerock.name = 冰岩石 block.copper-wall.name = 銅牆 block.copper-wall-large.name = 大型銅牆 -block.dense-alloy-wall.name = 稠密合金牆 -block.dense-alloy-wall-large.name = 大型稠密合金牆 +block.titanium-wall.name = Titanium Wall +block.titanium-wall-large.name = Large Titanium Wall block.phase-wall.name = 相織布牆 block.phase-wall-large.name = 大型相織布牆 block.thorium-wall.name = 釷牆 @@ -560,17 +568,19 @@ block.separator.name = 分離機 block.centrifuge.name = 離心機 block.power-node.name = 能量節點 block.power-node-large.name = 大型能量節點 +block.surge-tower.name = Surge Tower block.battery.name = 電池 block.battery-large.name = 大型電池 block.combustion-generator.name = 燃燒發電機 block.turbine-generator.name = 渦輪發電機 +block.differential-generator.name = Differential Generator +block.impact-reactor.name = Impact Reactor block.mechanical-drill.name = 機械鑽頭 block.pneumatic-drill.name = 氣動鑽頭 block.laser-drill.name = 激光鑽頭 block.water-extractor.name = 水提取器 block.cultivator.name = 耕種機 -block.alpha-mech-pad.name = 阿爾法機甲墊 -block.dart-ship-pad.name = 鏢船墊 +block.alpha-dart-mech-pad.name = Alpha-Dart Mech Pad block.delta-mech-pad.name = 德爾塔機甲墊 block.javelin-ship-pad.name = 標槍機甲墊 block.trident-ship-pad.name = 三叉船墊 @@ -650,6 +660,7 @@ unit.phantom.name = 幻影無人機 unit.phantom.description = 一種高級的無人機。自動挖掘礦石、收集物品和修理方塊。比輕型無人機明顯更有效。 unit.dagger.name = 匕首 unit.dagger.description = 一種基本的地面單位。最好一群地使用。 +unit.crawler.name = Crawler unit.titan.name = 泰坦 unit.titan.description = 一種高級的具有裝甲的地面單位。使用碳化物作為彈藥。攻擊地面單位和空中單位。 unit.ghoul.name = 食屍鬼轟炸機 @@ -659,7 +670,11 @@ unit.wraith.description = 一種快速、打了就跑的攔截機。 unit.fortress.name = 堡壘 unit.fortress.description = 一種具有重型大砲的地面單位。 unit.revenant.name = 亡魂 -unit.revenant.description = 一種重型的激光平台。 +unit.eruptor.name = Eruptor +unit.chaos-array.name = Chaos Array +unit.eradicator.name = Eradicator +unit.lich.name = Lich +unit.reaper.name = Reaper tutorial.begin = 你的任務是毀滅[LIGHT_GRAY]敵人[]。\n\n首先[accent]挖掘銅礦[]。點擊核心附近的銅脈以開始。 tutorial.drill = 手動挖掘礦石是低效率的。\n[accent]鑽頭[]能夠自動挖掘礦石。\n在銅脈上放置一個鑽頭。 tutorial.conveyor = [accent]輸送帶[]能夠將物品運輸到核心。\n製作一條從鑽頭開始到核心的輸送帶。 diff --git a/core/assets/maps/craters.mmap b/core/assets/maps/craters.mmap index 8175a9710e..b3a6e5432d 100644 Binary files a/core/assets/maps/craters.mmap and b/core/assets/maps/craters.mmap differ diff --git a/core/assets/maps/desolateRift.mmap b/core/assets/maps/desolateRift.mmap new file mode 100644 index 0000000000..f6a9515fee Binary files /dev/null and b/core/assets/maps/desolateRift.mmap differ diff --git a/core/assets/maps/frozenForest.mmap b/core/assets/maps/frozenForest.mmap new file mode 100644 index 0000000000..273ddcea84 Binary files /dev/null and b/core/assets/maps/frozenForest.mmap differ diff --git a/core/assets/maps/groundZero.mmap b/core/assets/maps/groundZero.mmap index ff8b5a9b56..b73cd867af 100644 Binary files a/core/assets/maps/groundZero.mmap and b/core/assets/maps/groundZero.mmap differ diff --git a/core/assets/maps/impact0079.mmap b/core/assets/maps/impact0079.mmap new file mode 100644 index 0000000000..a8036f1bb2 Binary files /dev/null and b/core/assets/maps/impact0079.mmap differ diff --git a/core/assets/maps/nuclearProductionComplex.mmap b/core/assets/maps/nuclearProductionComplex.mmap new file mode 100644 index 0000000000..afb13fb5a6 Binary files /dev/null and b/core/assets/maps/nuclearProductionComplex.mmap differ diff --git a/core/assets/maps/ruinousShores.mmap b/core/assets/maps/ruinousShores.mmap new file mode 100644 index 0000000000..d05fc7681a Binary files /dev/null and b/core/assets/maps/ruinousShores.mmap differ diff --git a/core/assets/maps/stainedMountains.mmap b/core/assets/maps/stainedMountains.mmap new file mode 100644 index 0000000000..b57ae403d3 Binary files /dev/null and b/core/assets/maps/stainedMountains.mmap differ diff --git a/core/assets/shaders/blockbuild.fragment b/core/assets/shaders/blockbuild.fragment index e683997ba4..858018291f 100644 --- a/core/assets/shaders/blockbuild.fragment +++ b/core/assets/shaders/blockbuild.fragment @@ -22,7 +22,7 @@ bool id(vec2 coords, vec4 base){ } bool cont(vec2 T, vec2 v){ - float step = 1.0; + const float step = 3.0; vec4 base = texture2D(u_texture, T); return base.a > 0.1 && (id(T + vec2(0, step) * v, base) || id(T + vec2(0, -step) * v, base) || @@ -41,13 +41,8 @@ void main() { vec2 center = ((u_uv + u_uv2)/2.0 - u_uv) /v; float dst = (abs(center.x - coords.x) + abs(center.y - coords.y))/2.0; - float chance = 1.0; - if(u_progress > 0.8){ - chance = 1.0-(u_progress-0.8)*5.0; - } - - if((mod(u_time / 1.5 + value, 20.0) < 5.0 && cont(t, v))){ + if((mod(u_time / 1.5 + value, 20.0) < 15.0 && cont(t, v))){ gl_FragColor = u_color; }else if(dst > (1.0-u_progress) * (center.x)){ gl_FragColor = color; diff --git a/core/assets/shaders/cache.vertex b/core/assets/shaders/cache.vertex new file mode 100644 index 0000000000..058b8888ef --- /dev/null +++ b/core/assets/shaders/cache.vertex @@ -0,0 +1,14 @@ +attribute vec4 a_position; +attribute vec4 a_color; +attribute vec2 a_texCoord0; +uniform mat4 u_projectionViewMatrix; +varying vec4 v_color; +varying vec2 v_texCoords; + +void main() +{ + v_color = a_color; + v_color.a = v_color.a * (255.0/254.0); + v_texCoords = a_texCoord0; + gl_Position = u_projectionViewMatrix * a_position; +} \ No newline at end of file diff --git a/core/assets/shaders/fog.fragment b/core/assets/shaders/fog.fragment index 8955cc9665..b31fbea93b 100644 --- a/core/assets/shaders/fog.fragment +++ b/core/assets/shaders/fog.fragment @@ -5,18 +5,13 @@ precision mediump int; uniform sampler2D u_texture; -const float round = 0.23; +const float round = 0.01; varying vec4 v_color; varying vec2 v_texCoord; void main() { vec4 color = texture2D(u_texture, v_texCoord.xy); - color.a = 1.0 - color.r; - color.rgb = vec3(0.0); - color.a = float(int(color.a / round)) * round; - if(color.a >= 1.0 - round){ - color.a = 1.0; - } + color = vec4(0.0, 0.0, 0.0, 1.0 - color.r); gl_FragColor = color * v_color; } diff --git a/core/assets/shaders/shadow.fragment b/core/assets/shaders/shadow.fragment new file mode 100644 index 0000000000..b1d73a8b1f --- /dev/null +++ b/core/assets/shaders/shadow.fragment @@ -0,0 +1,44 @@ +#ifdef GL_ES +precision mediump float; +precision mediump int; +#endif + +#define SPACE 2.0 + +uniform sampler2D u_texture; + +uniform vec4 u_color; +uniform vec2 u_texsize; +uniform float u_scl; + +varying vec4 v_color; +varying vec2 v_texCoord; + +void main() { + vec2 v = vec2(1.0/u_texsize.x, 1.0/u_texsize.y); + + vec4 c = texture2D(u_texture, v_texCoord.xy); + float spacing = SPACE * u_scl; + + gl_FragColor = mix(vec4(0.0, 0.0, 0.0, min(c.a, u_color.a)), u_color, + (1.0-step(0.001, texture2D(u_texture, v_texCoord.xy).a)) * + step(0.001, + //cardinals + texture2D(u_texture, v_texCoord.xy + vec2(0, spacing) * v).a + + texture2D(u_texture, v_texCoord.xy + vec2(0, -spacing) * v).a + + texture2D(u_texture, v_texCoord.xy + vec2(spacing, 0) * v).a + + texture2D(u_texture, v_texCoord.xy + vec2(-spacing, 0) * v).a + + + //cardinal edges + texture2D(u_texture, v_texCoord.xy + vec2(spacing, spacing) * v).a + + texture2D(u_texture, v_texCoord.xy + vec2(spacing, -spacing) * v).a + + texture2D(u_texture, v_texCoord.xy + vec2(-spacing, spacing) * v).a + + texture2D(u_texture, v_texCoord.xy + vec2(-spacing, -spacing) * v).a + + + //cardinals * 2 + texture2D(u_texture, v_texCoord.xy + vec2(0, spacing) * v*2.0).a + + texture2D(u_texture, v_texCoord.xy + vec2(0, -spacing) * v*2.0).a + + texture2D(u_texture, v_texCoord.xy + vec2(spacing, 0) * v*2.0).a + + texture2D(u_texture, v_texCoord.xy + vec2(-spacing, 0) * v*2.0).a + )); +} diff --git a/core/assets/shaders/water.fragment b/core/assets/shaders/water.fragment index d8f26bebb1..172725177b 100644 --- a/core/assets/shaders/water.fragment +++ b/core/assets/shaders/water.fragment @@ -1,90 +1,18 @@ #ifdef GL_ES -precision highp float; -precision mediump int; +precision mediump float; #endif +varying vec4 v_color; +varying vec2 v_texCoords; uniform sampler2D u_texture; +uniform float u_time; -uniform vec2 camerapos; -uniform vec2 screensize; -uniform float time; - -varying vec4 v_color; -varying vec2 v_texCoord; - -float round(float num, float f){ - return float(int(num / f)) * f; +float round(float f, float v){ + return float(int(f / v)) * v; } -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); - ivec2 icoords = ivec2(int(c.x / v.x + camerapos.x), int(c.y / v.y + camerapos.y)); - vec2 coords = vec2(float(icoords.x), float(icoords.y)); - - float stime = time / 5.0; - - float mscl = 30.0; - float mth = 5.0; - - //if there's something actually there - if(color.r > 0.01){ - vec4 old = color; - 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; - - if(color.r < 0.01){ - color = old; - } - - 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; - - if(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 < mth){ - - color *= 1.2; - color.a = 1.0; - } - } - - gl_FragColor = color; -} +void main(){ + vec2 r = v_texCoords.xy; + vec4 c = v_color * texture2D(u_texture, v_texCoords.xy); + gl_FragColor = c * vec4(vec3(round(1.0 + sin((r.x + r.y) * 404.0 + u_time / 20.0) / 10.0, 0.05)), 1.0); +} \ No newline at end of file diff --git a/core/assets/sprites/block_colors.png b/core/assets/sprites/block_colors.png new file mode 100644 index 0000000000..b4e5879938 Binary files /dev/null and b/core/assets/sprites/block_colors.png differ diff --git a/core/assets/sprites/sprites.atlas b/core/assets/sprites/sprites.atlas index 2847ab0c19..7cd10688ec 100644 --- a/core/assets/sprites/sprites.atlas +++ b/core/assets/sprites/sprites.atlas @@ -6,8680 +6,8253 @@ filter: Nearest,Nearest repeat: none force-projector rotate: false - xy: 457, 1439 + xy: 673, 1462 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 force-projector-top rotate: false - xy: 359, 1243 + xy: 453, 1170 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 mend-projector rotate: false - xy: 653, 1645 + xy: 639, 740 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 mend-projector-top rotate: false - xy: 785, 1777 + xy: 705, 806 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 overdrive-projector rotate: false - xy: 653, 1579 + xy: 771, 872 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 overdrive-projector-top rotate: false - xy: 785, 1711 + xy: 639, 674 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 shock-mine rotate: false - xy: 855, 581 + xy: 1421, 329 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 bridge-conveyor rotate: false - xy: 843, 1017 + xy: 1742, 722 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 bridge-conveyor-bridge rotate: false - xy: 843, 983 + xy: 1776, 714 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 bridge-conveyor-end rotate: false - xy: 877, 1025 + xy: 1810, 714 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conveyor-0-0 rotate: false - xy: 1495, 1359 + xy: 979, 542 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conveyor-0-1 rotate: false - xy: 1483, 1325 + xy: 945, 474 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conveyor-0-2 rotate: false - xy: 1529, 1354 + xy: 979, 508 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conveyor-0-3 rotate: false - xy: 1563, 1354 + xy: 945, 440 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conveyor-1-0 rotate: false - xy: 1597, 1354 + xy: 979, 474 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conveyor-1-1 rotate: false - xy: 1631, 1354 + xy: 945, 406 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conveyor-1-2 rotate: false - xy: 1665, 1354 + xy: 979, 440 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conveyor-1-3 rotate: false - xy: 1699, 1354 + xy: 945, 372 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conveyor-2-0 rotate: false - xy: 1733, 1354 + xy: 979, 406 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conveyor-2-1 rotate: false - xy: 1767, 1354 + xy: 945, 338 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conveyor-2-2 rotate: false - xy: 1801, 1354 + xy: 979, 372 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conveyor-2-3 rotate: false - xy: 1835, 1354 + xy: 945, 304 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conveyor-3-0 rotate: false - xy: 1517, 1320 + xy: 979, 338 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conveyor-3-1 rotate: false - xy: 1551, 1320 + xy: 945, 270 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conveyor-3-2 rotate: false - xy: 1585, 1320 + xy: 979, 304 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conveyor-3-3 rotate: false - xy: 1619, 1320 + xy: 945, 236 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conveyor-4-0 rotate: false - xy: 1653, 1320 + xy: 979, 270 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conveyor-4-1 rotate: false - xy: 1687, 1320 + xy: 945, 202 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conveyor-4-2 rotate: false - xy: 1721, 1320 + xy: 979, 236 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conveyor-4-3 rotate: false - xy: 1755, 1320 + xy: 979, 202 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium-conveyor-0-0 rotate: false - xy: 915, 785 + xy: 1557, 204 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium-conveyor-0-1 rotate: false - xy: 949, 785 + xy: 1557, 170 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium-conveyor-0-2 rotate: false - xy: 915, 751 + xy: 1489, 136 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium-conveyor-0-3 rotate: false - xy: 949, 751 + xy: 1523, 136 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium-conveyor-1-0 rotate: false - xy: 915, 717 + xy: 1557, 136 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium-conveyor-1-1 rotate: false - xy: 949, 717 + xy: 1591, 499 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium-conveyor-1-2 rotate: false - xy: 915, 683 + xy: 1591, 465 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium-conveyor-1-3 rotate: false - xy: 949, 683 + xy: 1591, 431 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium-conveyor-2-0 rotate: false - xy: 915, 649 + xy: 1591, 397 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium-conveyor-2-1 rotate: false - xy: 949, 649 + xy: 1591, 363 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium-conveyor-2-2 rotate: false - xy: 915, 313 + xy: 1591, 329 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium-conveyor-2-3 rotate: false - xy: 915, 279 + xy: 1591, 295 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium-conveyor-3-0 rotate: false - xy: 915, 245 + xy: 1591, 261 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium-conveyor-3-1 rotate: false - xy: 915, 211 + xy: 1591, 227 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium-conveyor-3-2 rotate: false - xy: 915, 177 + xy: 1591, 193 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium-conveyor-3-3 rotate: false - xy: 915, 143 + xy: 1591, 159 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium-conveyor-4-0 rotate: false - xy: 915, 109 + xy: 1591, 125 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium-conveyor-4-1 rotate: false - xy: 915, 75 + xy: 1625, 485 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium-conveyor-4-2 rotate: false - xy: 940, 41 + xy: 1659, 485 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium-conveyor-4-3 rotate: false - xy: 940, 7 + xy: 1625, 451 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 distributor rotate: false - xy: 858, 1843 + xy: 1207, 1264 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 junction rotate: false - xy: 979, 989 + xy: 1285, 482 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -mass-driver +mass-driver-base rotate: false - xy: 359, 655 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -mass-driver-turret - rotate: false - xy: 457, 655 + xy: 1359, 1494 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 overflow-gate rotate: false - xy: 1653, 1184 + xy: 1745, 646 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 phase-conveyor rotate: false - xy: 1789, 1184 + xy: 1779, 612 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 phase-conveyor-arrow rotate: false - xy: 1789, 1150 + xy: 1813, 646 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 phase-conveyor-bridge rotate: false - xy: 1823, 1184 + xy: 1847, 680 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 phase-conveyor-end rotate: false - xy: 1823, 1150 + xy: 1745, 544 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 router rotate: false - xy: 1653, 1082 + xy: 1881, 510 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 sorter rotate: false - xy: 906, 37 + xy: 1429, 23 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -warp-gate - rotate: false - xy: 539, 459 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -warp-gate-top - rotate: false - xy: 539, 361 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 blast-drill rotate: false - xy: 261, 1635 + xy: 1161, 1592 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 blast-drill-rim rotate: false - xy: 261, 1537 + xy: 1357, 1592 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 blast-drill-rotator rotate: false - xy: 359, 1635 + xy: 1455, 1592 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 blast-drill-top rotate: false - xy: 457, 1733 + xy: 1553, 1592 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 laser-drill rotate: false - xy: 1716, 1851 + xy: 713, 938 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 laser-drill-rotator rotate: false - xy: 1848, 1851 + xy: 845, 971 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 laser-drill-top rotate: false - xy: 1914, 1851 + xy: 845, 905 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 mechanical-drill rotate: false - xy: 1980, 1851 + xy: 421, 174 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 mechanical-drill-rotator rotate: false - xy: 653, 1711 + xy: 639, 806 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 mechanical-drill-top rotate: false - xy: 719, 1777 + xy: 705, 872 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 oil-extractor rotate: false - xy: 261, 557 + xy: 1653, 1494 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 oil-extractor-liquid rotate: false - xy: 457, 557 + xy: 1849, 1494 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 oil-extractor-rotator rotate: false - xy: 245, 459 + xy: 453, 1072 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 oil-extractor-top rotate: false - xy: 245, 361 + xy: 551, 1070 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 plasma-drill rotate: false - xy: 1, 68 + xy: 453, 506 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 plasma-drill-rim rotate: false - xy: 131, 1628 + xy: 656, 1690 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 plasma-drill-rotator rotate: false - xy: 131, 1498 + xy: 786, 1690 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 plasma-drill-top rotate: false - xy: 131, 1368 + xy: 916, 1690 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 pneumatic-drill rotate: false - xy: 653, 1381 + xy: 681, 542 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 pneumatic-drill-rotator rotate: false - xy: 785, 1513 + xy: 681, 476 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 pneumatic-drill-top rotate: false - xy: 851, 1579 + xy: 747, 542 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 water-extractor rotate: false - xy: 917, 1249 + xy: 1579, 1132 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 water-extractor-liquid rotate: false - xy: 1049, 1381 + xy: 1711, 1132 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 water-extractor-rotator rotate: false - xy: 1115, 1447 + xy: 1777, 1132 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 water-extractor-top rotate: false - xy: 653, 919 + xy: 1843, 1132 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 -blackrock1 - rotate: false - xy: 1812, 1388 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -blackstone1 - rotate: false - xy: 1880, 1379 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -blackstone2 - rotate: false - xy: 1914, 1379 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -blackstone3 - rotate: false - xy: 260, 32 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -blackstoneedge - rotate: false - xy: 329, 311 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 char1 rotate: false - xy: 917, 1091 + xy: 1844, 714 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 char2 rotate: false - xy: 951, 1091 + xy: 1878, 714 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 char3 rotate: false - xy: 711, 885 + xy: 1912, 714 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +cliffs1 + rotate: false + xy: 1946, 714 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 coal1 rotate: false - xy: 711, 817 + xy: 1980, 714 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 coal2 rotate: false - xy: 711, 783 + xy: 2013, 998 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 coal3 rotate: false - xy: 711, 749 + xy: 1419, 533 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 copper1 rotate: false - xy: 1823, 1320 + xy: 1013, 616 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 copper2 rotate: false - xy: 1869, 1345 + xy: 1013, 582 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 copper3 rotate: false - xy: 1903, 1345 + xy: 1013, 548 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 craters1 rotate: false - xy: 1585, 1286 + xy: 1013, 344 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 craters2 rotate: false - xy: 1619, 1286 + xy: 1013, 310 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 craters3 rotate: false - xy: 1653, 1286 + xy: 1013, 276 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -deepwater +craters4 rotate: false - xy: 1891, 1311 + xy: 1013, 242 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -deepwater-icon-full +craters5 rotate: false - xy: 1891, 1311 + xy: 1013, 208 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -deepwater-icon-medium - rotate: false - xy: 1891, 1311 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -dirt1 - rotate: false - xy: 1857, 1277 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -dirt2 - rotate: false - xy: 1891, 1277 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -dirt3 - rotate: false - xy: 1925, 1277 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -dirtedge - rotate: false - xy: 687, 375 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -grass1 - rotate: false - xy: 341, 77 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -grass2 - rotate: false - xy: 375, 77 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -grass3 - rotate: false - xy: 409, 77 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -grassedge - rotate: false - xy: 629, 125 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -ice1 - rotate: false - xy: 545, 77 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ice2 - rotate: false - xy: 579, 77 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ice3 - rotate: false - xy: 1191, 1208 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -iceedge - rotate: false - xy: 729, 175 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -icerock1 - rotate: false - xy: 1279, 1283 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -icerock2 - rotate: false - xy: 1313, 1283 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -lava - rotate: false - xy: 294, 42 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -lavaedge - rotate: false - xy: 1588, 1801 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -lead1 - rotate: false - xy: 362, 43 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -lead2 - rotate: false - xy: 396, 43 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -lead3 - rotate: false - xy: 430, 43 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -metalfloor1 - rotate: false - xy: 702, 7 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -metalfloor2 - rotate: false - xy: 736, 7 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -metalfloor3 - rotate: false - xy: 770, 19 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -metalfloor4 - rotate: false - xy: 804, 19 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -metalfloor5 - rotate: false - xy: 1075, 1197 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -metalfloor6 - rotate: false - xy: 1109, 1197 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -metalflooredge - rotate: false - xy: 1231, 1651 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -pine - rotate: false - xy: 1891, 1175 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -rock1 - rotate: false - xy: 1781, 1751 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -rock2 - rotate: false - xy: 1531, 1451 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -rocks1 - rotate: false - xy: 1517, 1082 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -rocks2 - rotate: false - xy: 1551, 1082 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -sand1 - rotate: false - xy: 1823, 1082 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -sand2 - rotate: false - xy: 1857, 1073 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -sand3 - rotate: false - xy: 1891, 1073 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -sandedge - rotate: false - xy: 1631, 1501 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -scrap1 - rotate: false - xy: 847, 853 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -scrap2 - rotate: false - xy: 847, 819 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -scrap3 - rotate: false - xy: 847, 785 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -shrub - rotate: false - xy: 855, 479 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -snow1 - rotate: false - xy: 855, 343 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -snow2 - rotate: false - xy: 881, 309 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -snow3 - rotate: false - xy: 881, 275 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -snowedge - rotate: false - xy: 1681, 1501 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -space - rotate: false - xy: 1013, 1048 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -space-icon-full - rotate: false - xy: 1013, 1048 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -space-icon-medium - rotate: false - xy: 1013, 1048 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -spaceedge - rotate: false - xy: 1931, 1751 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 stone1 rotate: false - xy: 881, 891 + xy: 1013, 208 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +craters6 + rotate: false + xy: 1047, 608 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 stone2 rotate: false - xy: 881, 857 + xy: 1047, 608 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +deepwater + rotate: false + xy: 1047, 506 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +differential-generator + rotate: false + xy: 477, 1462 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +differential-generator-top + rotate: false + xy: 575, 1462 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +dunerocks-large + rotate: false + xy: 1405, 1264 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +dunerocks1 + rotate: false + xy: 1081, 438 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +dunerocks2 + rotate: false + xy: 1047, 370 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +edge-stencil-blocky + rotate: false + xy: 1, 798 + size: 288, 96 + orig: 288, 96 + offset: 0, 0 + index: -1 +edge-stencil-smooth + rotate: false + xy: 1, 700 + size: 288, 96 + orig: 288, 96 + offset: 0, 0 + index: -1 +grass1 + rotate: false + xy: 1081, 234 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +grass2 + rotate: false + xy: 1115, 566 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +grass3 + rotate: false + xy: 1115, 532 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +holostone1 + rotate: false + xy: 1115, 430 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +holostone2 + rotate: false + xy: 1115, 396 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +holostone3 + rotate: false + xy: 1115, 362 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +hotrock1 + rotate: false + xy: 1115, 328 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +hotrock2 + rotate: false + xy: 1115, 294 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +hotrock3 + rotate: false + xy: 1115, 260 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ice-edge + rotate: false + xy: 1, 504 + size: 288, 96 + orig: 288, 96 + offset: 0, 0 + index: -1 +ice-snow1 + rotate: false + xy: 1115, 192 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ice-snow2 + rotate: false + xy: 1149, 558 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ice-snow3 + rotate: false + xy: 1149, 524 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ice1 + rotate: false + xy: 1047, 200 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ice2 + rotate: false + xy: 1081, 200 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ice3 + rotate: false + xy: 1115, 226 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +icerocks-large + rotate: false + xy: 511, 1004 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +icerocks1 + rotate: false + xy: 1149, 490 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +icerocks2 + rotate: false + xy: 1183, 558 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ignarock1 + rotate: false + xy: 1183, 524 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ignarock2 + rotate: false + xy: 1183, 490 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ignarock3 + rotate: false + xy: 1149, 422 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +lead1 + rotate: false + xy: 1353, 490 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +lead2 + rotate: false + xy: 1217, 346 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +lead3 + rotate: false + xy: 1251, 380 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +magmarock1 + rotate: false + xy: 1319, 354 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +magmarock2 + rotate: false + xy: 1353, 388 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +magmarock3 + rotate: false + xy: 1217, 244 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +metal-floor + rotate: false + xy: 1319, 286 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +metal-floor-damaged5 + rotate: false + xy: 1319, 286 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +metal-floor-2 + rotate: false + xy: 1353, 320 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +metal-floor-3 + rotate: false + xy: 1285, 244 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +metal-floor-5 + rotate: false + xy: 1319, 252 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +metal-floor-damaged1 + rotate: false + xy: 1353, 286 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +metal-floor-damaged2 + rotate: false + xy: 1353, 252 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +metal-floor-damaged3 + rotate: false + xy: 1149, 184 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +metal-floor-damaged4 + rotate: false + xy: 1183, 184 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +metal-floor-damaged6 + rotate: false + xy: 1217, 210 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +pine + rotate: false + xy: 1881, 680 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +rock1 + rotate: false + xy: 937, 77 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +rock2 + rotate: false + xy: 937, 27 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +rocks-large + rotate: false + xy: 813, 509 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +rocks1 + rotate: false + xy: 1779, 510 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +rocks2 + rotate: false + xy: 1813, 510 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +sand-water + rotate: false + xy: 1387, 397 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +sand1 + rotate: false + xy: 1387, 499 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +sand2 + rotate: false + xy: 1387, 465 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +sand3 + rotate: false + xy: 1387, 431 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +scrap1 + rotate: false + xy: 1387, 363 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +scrap2 + rotate: false + xy: 1387, 329 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +scrap3 + rotate: false + xy: 1387, 295 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +snow1 + rotate: false + xy: 1421, 193 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +snow2 + rotate: false + xy: 1421, 159 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +snow3 + rotate: false + xy: 1421, 125 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +snowrocks-large + rotate: false + xy: 903, 689 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +snowrocks1 + rotate: false + xy: 1395, 91 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +snowrocks2 + rotate: false + xy: 1395, 57 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +spore-cluster1 + rotate: false + xy: 903, 647 + size: 40, 40 + orig: 40, 40 + offset: 0, 0 + index: -1 +spore-cluster2 + rotate: false + xy: 1519, 782 + size: 40, 40 + orig: 40, 40 + offset: 0, 0 + index: -1 +spore-cluster3 + rotate: false + xy: 1469, 732 + size: 40, 40 + orig: 40, 40 + offset: 0, 0 + index: -1 +stained-boulder1 + rotate: false + xy: 1455, 379 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +stained-boulder2 + rotate: false + xy: 1455, 345 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +stained-rocks-large + rotate: false + xy: 1195, 1198 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +stained-rocks-red-large + rotate: false + xy: 1261, 1198 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +stained-rocks-red1 + rotate: false + xy: 1455, 243 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +stained-rocks-red2 + rotate: false + xy: 1455, 209 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +stained-rocks-yellow-large + rotate: false + xy: 1327, 1198 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +stained-rocks-yellow1 + rotate: false + xy: 1455, 175 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +stained-rocks-yellow2 + rotate: false + xy: 1455, 141 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +stained-rocks1 + rotate: false + xy: 1455, 311 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +stained-rocks2 + rotate: false + xy: 1455, 277 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +stained-stone-red1 + rotate: false + xy: 1489, 442 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +stained-stone-red2 + rotate: false + xy: 1523, 476 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +stained-stone-red3 + rotate: false + xy: 1557, 510 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +stained-stone-yellow1 + rotate: false + xy: 1489, 408 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +stained-stone-yellow2 + rotate: false + xy: 1523, 442 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +stained-stone-yellow3 + rotate: false + xy: 1557, 476 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +stained-stone1 + rotate: false + xy: 1489, 510 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +stained-stone2 + rotate: false + xy: 1489, 476 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +stained-stone3 + rotate: false + xy: 1523, 510 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +stainedrocks-large + rotate: false + xy: 1393, 1198 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +stainedrocks1 + rotate: false + xy: 1489, 374 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +stainedrocks2 + rotate: false + xy: 1523, 408 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 stone3 rotate: false - xy: 881, 823 + xy: 1557, 442 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -stoneedge - rotate: false - xy: 1931, 1701 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 tar rotate: false - xy: 881, 619 + xy: 1523, 340 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -tar-icon-full - rotate: false - xy: 881, 619 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -tar-icon-medium - rotate: false - xy: 881, 619 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -taredge - rotate: false - xy: 1931, 1651 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 thorium1 rotate: false - xy: 889, 483 + xy: 1557, 340 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 thorium2 rotate: false - xy: 889, 449 + xy: 1489, 238 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 thorium3 rotate: false - xy: 889, 415 + xy: 1523, 272 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium1 rotate: false - xy: 949, 853 + xy: 1523, 204 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium2 rotate: false - xy: 915, 819 + xy: 1557, 238 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium3 rotate: false - xy: 949, 819 + xy: 1523, 170 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 water rotate: false - xy: 1017, 776 + xy: 1659, 349 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -water-icon-full +white-tree rotate: false - xy: 1017, 776 - size: 32, 32 - orig: 32, 32 + xy: 1, 1316 + size: 320, 320 + orig: 320, 320 offset: 0, 0 index: -1 -water-icon-medium +white-tree-dead rotate: false - xy: 1017, 776 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -water-cliff-edge - rotate: false - xy: 1017, 742 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -water-cliff-edge-1 - rotate: false - xy: 1017, 708 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -water-cliff-edge-2 - rotate: false - xy: 1017, 674 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -water-cliff-side - rotate: false - xy: 983, 640 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -wateredge - rotate: false - xy: 1323, 1401 - size: 48, 48 - orig: 48, 48 + xy: 1, 994 + size: 320, 320 + orig: 320, 320 offset: 0, 0 index: -1 block-border rotate: false - xy: 1381, 1317 + xy: 1887, 748 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 block-middle rotate: false - xy: 1415, 1317 + xy: 1921, 748 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 pump-liquid rotate: false - xy: 1415, 1317 + xy: 1921, 748 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conduit-liquid rotate: false - xy: 779, 291 + xy: 1541, 544 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 place-arrow rotate: false - xy: 441, 459 + xy: 747, 1070 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 rubble-1-0 rotate: false - xy: 1115, 1777 + xy: 813, 443 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 rubble-1-1 rotate: false - xy: 653, 1249 + xy: 813, 377 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 rubble-2-0 rotate: false - xy: 719, 1315 + xy: 879, 575 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 rubble-2-1 rotate: false - xy: 785, 1381 + xy: 879, 509 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 rubble-3-0 rotate: false - xy: 555, 1537 + xy: 967, 1396 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 rubble-3-1 rotate: false - xy: 555, 1537 + xy: 967, 1396 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 +rubble-4-0 + rotate: false + xy: 1566, 1690 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 +rubble-4-1 + rotate: false + xy: 1566, 1690 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 spawn rotate: false - xy: 1013, 1014 + xy: 1455, 515 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 bridge-conduit rotate: false - xy: 1449, 1317 + xy: 1955, 748 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 bridge-conduit-arrow rotate: false - xy: 1157, 1208 + xy: 1989, 748 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 bridge-conveyor-arrow rotate: false - xy: 1157, 1208 + xy: 1989, 748 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 bridge-conduit-bridge rotate: false - xy: 1948, 1379 + xy: 1674, 723 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 bridge-conduit-end rotate: false - xy: 1982, 1388 + xy: 1708, 723 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conduit-bottom rotate: false - xy: 745, 757 + xy: 1507, 646 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conduit-bottom-0 rotate: false - xy: 745, 723 + xy: 1507, 612 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conduit-bottom-1 rotate: false - xy: 745, 689 + xy: 1507, 578 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conduit-bottom-2 rotate: false - xy: 745, 655 + xy: 1507, 544 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conduit-bottom-3 rotate: false - xy: 711, 613 + xy: 1545, 714 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conduit-bottom-4 rotate: false - xy: 745, 621 + xy: 1541, 680 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conduit-bottom-5 rotate: false - xy: 707, 579 + xy: 1541, 646 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conduit-bottom-6 rotate: false - xy: 1041, 1215 + xy: 1541, 612 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conduit-top-0 rotate: false - xy: 779, 257 + xy: 945, 644 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conduit-top-1 rotate: false - xy: 779, 223 + xy: 979, 644 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conduit-top-2 rotate: false - xy: 779, 189 + xy: 945, 610 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conduit-top-3 rotate: false - xy: 779, 155 + xy: 945, 576 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conduit-top-4 rotate: false - xy: 779, 121 + xy: 979, 610 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conduit-top-5 rotate: false - xy: 779, 87 + xy: 945, 542 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conduit-top-6 rotate: false - xy: 779, 53 + xy: 979, 576 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 liquid-junction rotate: false - xy: 498, 43 + xy: 1319, 422 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 liquid-router-bottom rotate: false - xy: 294, 8 + xy: 1217, 312 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 liquid-router-liquid rotate: false - xy: 362, 9 + xy: 1285, 380 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 liquid-router-top rotate: false - xy: 396, 9 + xy: 1319, 388 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 liquid-tank-bottom rotate: false - xy: 457, 949 + xy: 869, 1494 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 liquid-tank-liquid rotate: false - xy: 359, 753 + xy: 1065, 1494 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 liquid-tank-top rotate: false - xy: 457, 851 + xy: 1163, 1494 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 mechanical-pump rotate: false - xy: 668, 41 + xy: 1319, 320 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 phase-conduit rotate: false - xy: 1687, 1150 + xy: 1745, 612 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 phase-conduit-arrow rotate: false - xy: 1721, 1184 + xy: 1779, 646 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 phase-conduit-bridge rotate: false - xy: 1721, 1150 + xy: 1813, 680 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 phase-conduit-end rotate: false - xy: 1755, 1184 + xy: 1745, 578 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 pulse-conduit-top-0 rotate: false - xy: 1415, 1113 + xy: 1847, 544 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 pulse-conduit-top-1 rotate: false - xy: 1449, 1113 + xy: 1881, 578 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 pulse-conduit-top-2 rotate: false - xy: 1483, 1113 + xy: 1915, 612 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 pulse-conduit-top-3 rotate: false - xy: 1517, 1116 + xy: 1949, 646 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 pulse-conduit-top-4 rotate: false - xy: 1551, 1116 + xy: 1983, 680 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 pulse-conduit-top-5 rotate: false - xy: 1585, 1116 + xy: 1881, 544 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 pulse-conduit-top-6 rotate: false - xy: 1619, 1116 + xy: 1915, 578 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 rotary-pump rotate: false - xy: 851, 1513 + xy: 681, 410 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 thermal-pump rotate: false - xy: 983, 1447 + xy: 1855, 1198 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 -alpha-mech-pad +alpha-dart-mech-pad rotate: false - xy: 1252, 1983 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -dart-ship-pad - rotate: false - xy: 1980, 1917 + xy: 943, 1283 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 delta-mech-pad rotate: false - xy: 726, 1843 + xy: 1141, 1264 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 glaive-ship-pad rotate: false - xy: 359, 949 + xy: 649, 1168 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 javelin-ship-pad rotate: false - xy: 1386, 1851 + xy: 577, 1004 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 omega-mech-pad rotate: false - xy: 343, 459 + xy: 649, 1070 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 tau-mech-pad rotate: false - xy: 719, 1183 + xy: 1723, 1198 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 trident-ship-pad rotate: false - xy: 983, 1381 + xy: 1183, 1132 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 battery rotate: false - xy: 1676, 1388 + xy: 2013, 1468 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 battery-large rotate: false - xy: 131, 66 + xy: 1063, 1592 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 combustion-generator rotate: false - xy: 711, 715 + xy: 2014, 714 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 combustion-generator-top rotate: false - xy: 711, 647 + xy: 1519, 748 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -fusion-reactor +impact-reactor rotate: false - xy: 1, 1498 + xy: 656, 1820 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 -fusion-reactor-bottom +impact-reactor-bottom rotate: false - xy: 334, 1831 + xy: 786, 1820 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 -fusion-reactor-light +impact-reactor-light rotate: false - xy: 1, 1238 + xy: 1046, 1820 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 -fusion-reactor-plasma-0 +impact-reactor-plasma-0 rotate: false - xy: 1, 1108 + xy: 1176, 1820 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 -fusion-reactor-plasma-1 +impact-reactor-plasma-1 rotate: false - xy: 1, 978 + xy: 1306, 1820 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 -fusion-reactor-plasma-2 +impact-reactor-plasma-2 rotate: false - xy: 1, 848 + xy: 1436, 1820 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 -fusion-reactor-plasma-3 +impact-reactor-plasma-3 rotate: false - xy: 1, 718 + xy: 1566, 1820 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 -fusion-reactor-top +impact-reactor-top rotate: false - xy: 1, 588 + xy: 1696, 1820 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 power-node rotate: false - xy: 1891, 1141 + xy: 1881, 646 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 power-node-large rotate: false - xy: 917, 1645 + xy: 747, 476 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 power-source rotate: false - xy: 1993, 1150 + xy: 1813, 544 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 power-void rotate: false - xy: 1245, 1113 + xy: 1847, 578 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 powerinfinite rotate: false - xy: 1313, 1113 + xy: 1881, 612 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 powervoid rotate: false - xy: 1347, 1113 + xy: 1915, 646 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 rtg-generator rotate: false - xy: 983, 1645 + xy: 747, 410 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 rtg-generator-top rotate: false - xy: 1755, 1082 + xy: 1949, 510 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 solar-panel rotate: false - xy: 881, 207 + xy: 1395, 23 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 solar-panel-large rotate: false - xy: 555, 1439 + xy: 1359, 1396 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 +surge-tower + rotate: false + xy: 1459, 1198 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 thermal-generator rotate: false - xy: 851, 1315 + xy: 1789, 1198 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 thorium-reactor rotate: false - xy: 555, 1243 + xy: 1457, 1396 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 thorium-reactor-center rotate: false - xy: 555, 1145 + xy: 1555, 1396 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 thorium-reactor-lights rotate: false - xy: 555, 949 + xy: 1653, 1396 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 turbine-generator rotate: false - xy: 1115, 1513 + xy: 1249, 1132 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 turbine-generator-top rotate: false - xy: 719, 1051 + xy: 1315, 1132 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 alloy-smelter rotate: false - xy: 131, 262 + xy: 867, 1592 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 alloy-smelter-top rotate: false - xy: 1186, 1983 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -arc-smelter - rotate: false - xy: 1384, 1983 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -arc-smelter-top - rotate: false - xy: 1450, 1983 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -silicon-smelter-top - rotate: false - xy: 1450, 1983 - size: 64, 64 - orig: 64, 64 + xy: 965, 1592 + size: 96, 96 + orig: 96, 96 offset: 0, 0 index: -1 biomattercompressor rotate: false - xy: 1516, 1983 + xy: 1029, 1330 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 biomattercompressor-frame0 rotate: false - xy: 1582, 1983 + xy: 1095, 1330 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 biomattercompressor-frame1 rotate: false - xy: 1648, 1983 + xy: 1161, 1330 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 biomattercompressor-frame2 rotate: false - xy: 1714, 1983 + xy: 1227, 1330 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 biomattercompressor-liquid rotate: false - xy: 1846, 1983 + xy: 1359, 1330 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 biomattercompressor-top rotate: false - xy: 1912, 1983 + xy: 1425, 1330 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 blast-mixer rotate: false - xy: 1978, 1983 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -centrifuge - rotate: false - xy: 726, 1909 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -centrifuge-liquid - rotate: false - xy: 792, 1909 + xy: 1491, 1330 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 cryofluidmixer-bottom rotate: false - xy: 1188, 1917 + xy: 1755, 1330 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 cryofluidmixer-liquid rotate: false - xy: 1320, 1917 + xy: 1887, 1330 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 cryofluidmixer-top rotate: false - xy: 1386, 1917 + xy: 1956, 1662 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 cultivator rotate: false - xy: 1452, 1917 + xy: 1945, 1596 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 cultivator-middle rotate: false - xy: 1584, 1917 + xy: 1947, 1464 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 cultivator-top rotate: false - xy: 1650, 1917 + xy: 1947, 1398 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +graphite-press + rotate: false + xy: 1867, 1264 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 incinerator rotate: false - xy: 1415, 1283 + xy: 1149, 388 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 item-source rotate: false - xy: 1925, 1243 + xy: 1251, 516 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 item-void rotate: false - xy: 945, 955 + xy: 1217, 414 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 +kiln + rotate: false + xy: 643, 1004 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +kiln-top + rotate: false + xy: 709, 1004 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +silicon-smelter-top + rotate: false + xy: 709, 1004 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 lavasmelter rotate: false - xy: 328, 43 + xy: 1319, 456 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 liquid-source rotate: false - xy: 464, 9 + xy: 1217, 278 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 melter rotate: false - xy: 600, 7 + xy: 1251, 244 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 +multi-press + rotate: false + xy: 1555, 1494 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 oilrefinery rotate: false - xy: 1143, 1174 + xy: 1319, 218 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 phase-weaver rotate: false - xy: 917, 1777 + xy: 771, 674 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 phase-weaver-bottom rotate: false - xy: 653, 1447 + xy: 837, 839 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 phase-weaver-weave rotate: false - xy: 785, 1579 + xy: 837, 707 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 plastanium-compressor rotate: false - xy: 851, 1645 + xy: 837, 641 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 plastanium-compressor-top rotate: false - xy: 983, 1777 + xy: 681, 608 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 pulverizer rotate: false - xy: 1653, 1116 + xy: 1949, 612 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 pulverizer-rotator rotate: false - xy: 1721, 1116 + xy: 1915, 544 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 pyratite-mixer rotate: false - xy: 1049, 1777 + xy: 813, 575 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 separator rotate: false - xy: 847, 683 - size: 32, 32 - orig: 32, 32 + xy: 903, 821 + size: 64, 64 + orig: 64, 64 offset: 0, 0 index: -1 separator-liquid rotate: false - xy: 847, 615 + xy: 1421, 363 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 silicon-smelter rotate: false - xy: 653, 1183 + xy: 903, 755 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 smelter rotate: false - xy: 855, 377 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -solidifer - rotate: false - xy: 881, 105 + xy: 1421, 227 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 container rotate: false - xy: 924, 1909 + xy: 1623, 1330 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 -core +core-foundation rotate: false - xy: 457, 1635 + xy: 526, 1820 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 +core-nucleus + rotate: false + xy: 291, 492 + size: 160, 160 + orig: 160, 160 + offset: 0, 0 + index: -1 +core-shard + rotate: false + xy: 1749, 1592 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 -core-open +core-shard-top rotate: false - xy: 359, 1439 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -core-top - rotate: false - xy: 457, 1537 + xy: 1847, 1592 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 launch-pad rotate: false - xy: 261, 753 + xy: 747, 1168 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 sortedunloader rotate: false - xy: 881, 71 + xy: 1429, 57 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 unloader rotate: false - xy: 1017, 878 + xy: 1659, 383 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 vault rotate: false - xy: 555, 655 + xy: 845, 1298 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 -block-1 +arc-heat rotate: false - xy: 1313, 1317 + xy: 2013, 1536 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -block-1-top +block-1 rotate: false - xy: 1347, 1317 + xy: 1853, 748 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 block-2 rotate: false - xy: 594, 1870 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -block-2-top - rotate: false - xy: 660, 1909 + xy: 1557, 1330 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 block-3 rotate: false - xy: 261, 1439 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -block-3-top - rotate: false - xy: 359, 1537 + xy: 1651, 1592 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 block-4 rotate: false - xy: 1, 1628 + xy: 323, 1375 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 -block-4-top - rotate: false - xy: 204, 1831 - size: 128, 128 - orig: 128, 128 - offset: 0, 0 - index: -1 -arc - rotate: false - xy: 1574, 1388 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -arc-heat - rotate: false - xy: 1608, 1388 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -cyclone - rotate: false - xy: 261, 1243 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -duo - rotate: false - xy: 877, 957 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -fuse - rotate: false - xy: 261, 949 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -hail - rotate: false - xy: 477, 77 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 hail-heat rotate: false - xy: 1423, 1409 + xy: 581, 896 size: 40, 40 orig: 40, 40 offset: 0, 0 index: -1 -lancer - rotate: false - xy: 1518, 1851 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 lancer-heat rotate: false - xy: 1584, 1851 + xy: 581, 938 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 -meltdown - rotate: false - xy: 1, 458 - size: 128, 128 - orig: 128, 128 - offset: 0, 0 - index: -1 meltdown-heat rotate: false - xy: 1, 328 + xy: 509, 766 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 -ripple - rotate: false - xy: 441, 361 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 ripple-heat rotate: false - xy: 555, 1733 + xy: 583, 440 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 -salvo - rotate: false - xy: 851, 1447 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 salvo-heat rotate: false - xy: 917, 1513 + xy: 879, 377 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 salvo-panel-left rotate: false - xy: 1049, 1645 + xy: 931, 1217 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 salvo-panel-right rotate: false - xy: 1115, 1711 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -scatter - rotate: false - xy: 1959, 1073 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -scorch - rotate: false - xy: 1993, 1048 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -scorch-shoot - rotate: false - xy: 847, 887 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -spectre - rotate: false - xy: 131, 718 - size: 128, 128 - orig: 128, 128 - offset: 0, 0 - index: -1 -swarmer - rotate: false - xy: 1115, 1645 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -wave - rotate: false - xy: 719, 985 + xy: 919, 1151 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 wave-liquid rotate: false - xy: 851, 1117 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -command-center - rotate: false - xy: 858, 1909 + xy: 1051, 1066 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 dagger-factory rotate: false - xy: 1716, 1917 + xy: 1953, 1332 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 phantom-factory rotate: false - xy: 1716, 1917 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -reconstructor - rotate: false - xy: 1716, 1917 + xy: 1953, 1332 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 spirit-factory rotate: false - xy: 1716, 1917 + xy: 1953, 1332 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 wraith-factory rotate: false - xy: 1716, 1917 + xy: 1953, 1332 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 dagger-factory-top rotate: false - xy: 1848, 1917 + xy: 1009, 1264 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 dagger-factory-top-open rotate: false - xy: 1914, 1917 + xy: 1075, 1264 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 fortress-factory rotate: false - xy: 457, 1341 + xy: 551, 1364 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 fortress-factory-top rotate: false - xy: 359, 1145 + xy: 551, 1266 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 ghoul-factory-top rotate: false - xy: 359, 1145 + xy: 551, 1266 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 titan-factory-top rotate: false - xy: 359, 1145 + xy: 551, 1266 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 fortress-factory-top-open rotate: false - xy: 457, 1243 + xy: 649, 1266 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 ghoul-factory-top-open rotate: false - xy: 457, 1243 + xy: 649, 1266 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 titan-factory-top-open rotate: false - xy: 457, 1243 + xy: 649, 1266 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 ghoul-factory rotate: false - xy: 457, 1145 + xy: 747, 1266 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 phantom-factory-top rotate: false - xy: 653, 1513 + xy: 771, 806 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 phantom-factory-top-open rotate: false - xy: 719, 1579 + xy: 705, 674 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 -reconstructor-open +repair-point-base rotate: false - xy: 785, 1447 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -repair-point - rotate: false - xy: 1823, 1116 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -repair-point-turret - rotate: false - xy: 1891, 1107 + xy: 1949, 544 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 revenant-factory rotate: false - xy: 131, 1238 + xy: 1046, 1690 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 revenant-factory-top rotate: false - xy: 131, 978 + xy: 1306, 1690 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 revenant-factory-top-open rotate: false - xy: 131, 848 + xy: 1436, 1690 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 spirit-factory-top rotate: false - xy: 851, 1381 + xy: 1063, 1198 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 spirit-factory-top-open rotate: false - xy: 917, 1447 + xy: 1129, 1198 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 titan-factory rotate: false - xy: 555, 851 + xy: 1751, 1396 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 wraith-factory-top rotate: false - xy: 983, 1249 + xy: 1183, 1066 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 wraith-factory-top-open rotate: false - xy: 1049, 1315 + xy: 1249, 1066 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 copper-wall rotate: false - xy: 1937, 1345 + xy: 1013, 514 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 copper-wall-large rotate: false - xy: 1056, 1909 + xy: 1689, 1330 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 door rotate: false - xy: 1993, 1320 + xy: 1047, 438 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 door-large rotate: false - xy: 990, 1843 + xy: 1273, 1264 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 door-large-open rotate: false - xy: 1122, 1843 + xy: 1339, 1264 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 door-open rotate: false - xy: 785, 959 + xy: 1047, 404 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 phase-wall rotate: false - xy: 1891, 1209 + xy: 1779, 578 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 phase-wall-large rotate: false - xy: 785, 1645 + xy: 771, 740 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 +scrap-wall-gigantic + rotate: false + xy: 1696, 1690 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 +scrap-wall-huge1 + rotate: false + xy: 1065, 1396 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +scrap-wall-huge2 + rotate: false + xy: 1163, 1396 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +scrap-wall-huge3 + rotate: false + xy: 1261, 1396 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 +scrap-wall-large1 + rotate: false + xy: 919, 1085 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +scrap-wall-large2 + rotate: false + xy: 911, 1019 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +scrap-wall-large3 + rotate: false + xy: 911, 953 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +scrap-wall-large4 + rotate: false + xy: 911, 887 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +scrap-wall1 + rotate: false + xy: 1387, 261 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +scrap-wall2 + rotate: false + xy: 1387, 227 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +scrap-wall3 + rotate: false + xy: 1387, 193 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +scrap-wall4 + rotate: false + xy: 1387, 159 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +scrap-wall5 + rotate: false + xy: 1387, 159 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 surge-wall rotate: false - xy: 881, 755 + xy: 1523, 374 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 surge-wall-large rotate: false - xy: 983, 1513 + xy: 1525, 1198 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 thorium-wall rotate: false - xy: 889, 347 + xy: 1489, 204 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 thorium-wall-large rotate: false - xy: 1115, 1579 + xy: 1921, 1198 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 +thruster + rotate: false + xy: 607, 1560 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 titanium-wall rotate: false - xy: 983, 844 + xy: 1625, 417 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium-wall-large rotate: false - xy: 851, 1249 + xy: 1117, 1132 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 beam rotate: false - xy: 2043, 1214 + xy: 863, 1412 size: 4, 48 orig: 4, 48 offset: 0, 0 index: -1 beam-end rotate: false - xy: 668, 1975 + xy: 1956, 1876 size: 72, 72 orig: 72, 72 offset: 0, 0 index: -1 bullet rotate: false - xy: 204, 1777 + xy: 1209, 954 size: 52, 52 orig: 52, 52 offset: 0, 0 index: -1 bullet-back rotate: false - xy: 653, 575 + xy: 1670, 1078 size: 52, 52 orig: 52, 52 offset: 0, 0 index: -1 casing rotate: false - xy: 990, 6 + xy: 1891, 190 size: 8, 16 orig: 8, 16 offset: 0, 0 index: -1 command-attack rotate: false - xy: 745, 893 + xy: 1319, 524 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 command-idle rotate: false - xy: 745, 859 + xy: 1353, 524 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 command-patrol rotate: false - xy: 745, 825 + xy: 1511, 714 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 command-retreat rotate: false - xy: 745, 791 + xy: 1507, 680 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 enemyarrow rotate: false - xy: 909, 1061 + xy: 645, 410 size: 32, 28 orig: 32, 28 offset: 0, 0 index: -1 error rotate: false - xy: 737, 375 + xy: 1169, 750 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 laser rotate: false - xy: 2043, 1164 + xy: 2043, 1134 size: 4, 48 orig: 4, 48 offset: 0, 0 index: -1 laser-end rotate: false - xy: 816, 1975 + xy: 1956, 1802 size: 72, 72 orig: 72, 72 offset: 0, 0 index: -1 laserfull rotate: false - xy: 890, 1975 + xy: 845, 1103 size: 72, 72 orig: 72, 72 offset: 0, 0 index: -1 minelaser rotate: false - xy: 2043, 1114 + xy: 2043, 484 size: 4, 48 orig: 4, 48 offset: 0, 0 index: -1 minelaser-end rotate: false - xy: 964, 1975 + xy: 1956, 1728 size: 72, 72 orig: 72, 72 offset: 0, 0 index: -1 missile rotate: false - xy: 1883, 1413 + xy: 1469, 578 size: 36, 36 orig: 36, 36 offset: 0, 0 index: -1 missile-back rotate: false - xy: 1921, 1413 + xy: 1561, 757 size: 36, 36 orig: 36, 36 offset: 0, 0 index: -1 scale_marker rotate: false - xy: 654, 1864 + xy: 903, 641 size: 4, 4 orig: 4, 4 offset: 0, 0 index: -1 scorch1 rotate: false - xy: 923, 513 + xy: 2017, 572 size: 28, 100 orig: 28, 100 offset: 0, 0 index: -1 scorch2 rotate: false - xy: 953, 513 + xy: 1693, 416 size: 28, 100 orig: 28, 100 offset: 0, 0 index: -1 scorch3 rotate: false - xy: 923, 411 + xy: 1693, 314 size: 28, 100 orig: 28, 100 offset: 0, 0 index: -1 scorch4 rotate: false - xy: 953, 411 + xy: 1723, 408 size: 28, 100 orig: 28, 100 offset: 0, 0 index: -1 scorch5 rotate: false - xy: 983, 504 + xy: 1753, 408 size: 28, 100 orig: 28, 100 offset: 0, 0 index: -1 shell rotate: false - xy: 1173, 1309 + xy: 1675, 757 size: 36, 36 orig: 36, 36 offset: 0, 0 index: -1 shell-back rotate: false - xy: 1165, 1271 + xy: 1713, 757 size: 36, 36 orig: 36, 36 offset: 0, 0 index: -1 shot rotate: false - xy: 855, 513 + xy: 1421, 295 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 transfer rotate: false - xy: 2043, 1064 + xy: 2043, 434 size: 4, 48 orig: 4, 48 offset: 0, 0 index: -1 transfer-arrow rotate: false - xy: 983, 742 + xy: 1625, 383 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 transfer-end rotate: false - xy: 1038, 1975 + xy: 437, 998 size: 72, 72 orig: 72, 72 offset: 0, 0 index: -1 -alloy-smelter-icon-full - rotate: false - xy: 131, 164 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 alloy-smelter-icon-large rotate: false - xy: 210, 16 + xy: 1999, 1282 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 alloy-smelter-icon-medium rotate: false - xy: 1461, 1359 + xy: 1751, 790 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 alloy-smelter-icon-small rotate: false - xy: 923, 347 + xy: 1293, 116 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -alpha-mech-pad-icon-full +alpha-dart-mech-pad-icon-large rotate: false - xy: 1318, 1983 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -alpha-mech-pad-icon-large - rotate: false - xy: 1115, 1281 + xy: 1999, 1232 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 -alpha-mech-pad-icon-medium +alpha-dart-mech-pad-icon-medium rotate: false - xy: 1540, 1388 + xy: 1751, 756 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -alpha-mech-pad-icon-small +alpha-dart-mech-pad-icon-small rotate: false - xy: 1075, 1231 + xy: 2023, 756 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -arc-icon-full +arc rotate: false - xy: 1642, 1388 + xy: 2013, 1570 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -arc-icon-medium +arc-icon-full rotate: false - xy: 1642, 1388 + xy: 2013, 1502 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 arc-icon-large rotate: false - xy: 229, 310 + xy: 1924, 1082 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 arc-icon-small rotate: false - xy: 753, 527 + xy: 987, 176 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -battery-icon-full - rotate: false - xy: 1710, 1388 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -battery-icon-medium - rotate: false - xy: 1710, 1388 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 battery-icon-large rotate: false - xy: 229, 210 + xy: 1263, 958 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 battery-icon-small rotate: false - xy: 915, 623 + xy: 1021, 4 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -battery-large-icon-full - rotate: false - xy: 261, 1733 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 battery-large-icon-large rotate: false - xy: 229, 160 + xy: 1317, 1017 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 battery-large-icon-medium rotate: false - xy: 1744, 1388 + xy: 2013, 1434 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 battery-large-icon-small rotate: false - xy: 952, 385 + xy: 1659, 215 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 biomattercompressor-icon-full rotate: false - xy: 1780, 1983 + xy: 1293, 1330 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 biomattercompressor-icon-large rotate: false - xy: 229, 110 + xy: 977, 878 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 biomattercompressor-icon-medium rotate: false - xy: 1778, 1388 + xy: 2013, 1400 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 biomattercompressor-icon-small rotate: false - xy: 983, 440 - size: 24, 24 - orig: 24, 24 - offset: 0, 0 - index: -1 -blackrock-icon-full - rotate: false - xy: 1846, 1388 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -blackrock-icon-medium - rotate: false - xy: 1846, 1388 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -blackrock-icon-large - rotate: false - xy: 279, 311 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -blackrock-icon-small - rotate: false - xy: 1013, 511 - size: 24, 24 - orig: 24, 24 - offset: 0, 0 - index: -1 -blackstone-icon-full - rotate: false - xy: 1211, 1313 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -blackstone-icon-medium - rotate: false - xy: 1211, 1313 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -blackstone-icon-large - rotate: false - xy: 279, 261 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -blackstone-icon-small - rotate: false - xy: 983, 414 + xy: 1693, 288 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 blast-drill-icon-full rotate: false - xy: 359, 1733 + xy: 1259, 1592 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 blast-drill-icon-large rotate: false - xy: 279, 211 + xy: 969, 828 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 blast-drill-icon-medium rotate: false - xy: 1245, 1317 + xy: 1785, 748 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 blast-drill-icon-small rotate: false - xy: 777, 933 + xy: 1783, 484 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -blast-mixer-icon-full - rotate: false - xy: 594, 1936 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 blast-mixer-icon-large rotate: false - xy: 329, 261 + xy: 969, 778 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 blast-mixer-icon-medium rotate: false - xy: 1279, 1317 + xy: 1819, 748 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 blast-mixer-icon-small rotate: false - xy: 260, 6 + xy: 1723, 319 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -bridge-conduit-icon-full - rotate: false - xy: 1982, 1354 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -bridge-conduit-icon-medium - rotate: false - xy: 1982, 1354 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 bridge-conduit-icon-large rotate: false - xy: 329, 211 + xy: 1035, 900 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 bridge-conduit-icon-small rotate: false - xy: 952, 359 + xy: 1752, 382 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -bridge-conveyor-icon-full - rotate: false - xy: 877, 991 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -bridge-conveyor-icon-medium - rotate: false - xy: 877, 991 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 bridge-conveyor-icon-large rotate: false - xy: 379, 261 + xy: 1085, 900 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 bridge-conveyor-icon-small rotate: false - xy: 949, 333 + xy: 1047, 4 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -char-icon-full - rotate: false - xy: 711, 851 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -char-icon-medium - rotate: false - xy: 711, 851 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 char-icon-large rotate: false - xy: 279, 111 + xy: 1185, 900 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 char-icon-small rotate: false - xy: 949, 281 + xy: 1809, 484 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -combustion-generator-icon-full +cliffs-icon-large rotate: false - xy: 711, 681 - size: 32, 32 - orig: 32, 32 + xy: 1235, 904 + size: 48, 48 + orig: 48, 48 offset: 0, 0 index: -1 -combustion-generator-icon-medium +cliffs-icon-small rotate: false - xy: 711, 681 - size: 32, 32 - orig: 32, 32 + xy: 1752, 356 + size: 24, 24 + orig: 24, 24 offset: 0, 0 index: -1 combustion-generator-icon-large rotate: false - xy: 329, 161 + xy: 1285, 908 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 combustion-generator-icon-small rotate: false - xy: 949, 255 + xy: 1783, 432 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 conduit-icon-full rotate: false - xy: 1041, 1181 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -conduit-icon-medium - rotate: false - xy: 1041, 1181 + xy: 1541, 578 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 conduit-icon-large rotate: false - xy: 379, 211 + xy: 1313, 958 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 conduit-icon-small rotate: false - xy: 949, 229 + xy: 1809, 458 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -container-icon-full - rotate: false - xy: 990, 1909 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 container-icon-large rotate: false - xy: 429, 261 + xy: 1335, 908 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 container-icon-medium rotate: false - xy: 1203, 1275 + xy: 945, 508 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 container-icon-small rotate: false - xy: 949, 203 + xy: 1835, 484 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -conveyor-icon-full - rotate: false - xy: 1789, 1320 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -conveyor-icon-medium - rotate: false - xy: 1789, 1320 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 conveyor-icon-large rotate: false - xy: 479, 311 + xy: 1987, 1182 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 conveyor-icon-small rotate: false - xy: 949, 177 + xy: 1809, 432 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -copper-wall-icon-full - rotate: false - xy: 1483, 1291 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -copper-wall-icon-medium - rotate: false - xy: 1483, 1291 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 copper-wall-icon-large rotate: false - xy: 329, 111 + xy: 1975, 1132 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 copper-wall-icon-small rotate: false - xy: 949, 151 + xy: 1835, 458 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -copper-wall-large-icon-full - rotate: false - xy: 1122, 1909 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 copper-wall-large-icon-large rotate: false - xy: 379, 161 + xy: 1974, 1082 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 copper-wall-large-icon-medium rotate: false - xy: 1517, 1286 + xy: 1013, 480 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 copper-wall-large-icon-small rotate: false - xy: 949, 125 + xy: 1861, 484 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -core-icon-full +core-foundation-icon-large rotate: false - xy: 261, 1341 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -core-icon-large - rotate: false - xy: 429, 211 + xy: 453, 456 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 -core-icon-medium +core-foundation-icon-medium rotate: false - xy: 1551, 1286 + xy: 1013, 446 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -core-icon-small +core-foundation-icon-small rotate: false - xy: 949, 99 + xy: 1835, 432 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -craters-icon-full +core-nucleus-icon-large rotate: false - xy: 1687, 1286 + xy: 503, 456 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +core-nucleus-icon-medium + rotate: false + xy: 1013, 412 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -craters-icon-medium +core-nucleus-icon-small rotate: false - xy: 1687, 1286 + xy: 1861, 458 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +core-shard-icon-large + rotate: false + xy: 445, 406 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +core-shard-icon-medium + rotate: false + xy: 1013, 378 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 +core-shard-icon-small + rotate: false + xy: 1887, 484 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 craters-icon-large rotate: false - xy: 479, 261 + xy: 445, 356 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 craters-icon-small rotate: false - xy: 1195, 1245 + xy: 1861, 432 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 cryofluidmixer-icon-full rotate: false - xy: 1254, 1917 + xy: 1821, 1330 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 cryofluidmixer-icon-large rotate: false - xy: 479, 211 + xy: 445, 256 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 cryofluidmixer-icon-medium rotate: false - xy: 1721, 1286 + xy: 1047, 574 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 cryofluidmixer-icon-small rotate: false - xy: 1013, 485 + xy: 1887, 458 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 cultivator-icon-full rotate: false - xy: 1518, 1917 + xy: 1947, 1530 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 cultivator-icon-large rotate: false - xy: 529, 261 + xy: 495, 306 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 cultivator-icon-medium rotate: false - xy: 1755, 1286 + xy: 1081, 608 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 cultivator-icon-small rotate: false - xy: 1012, 459 + xy: 1913, 484 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 +cyclone + rotate: false + xy: 291, 12 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 cyclone-icon-full rotate: false - xy: 359, 1341 + xy: 583, 538 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 cyclone-icon-large rotate: false - xy: 579, 311 + xy: 495, 256 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 cyclone-icon-medium rotate: false - xy: 1789, 1286 + xy: 1047, 540 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 cyclone-icon-small rotate: false - xy: 1009, 433 + xy: 1887, 432 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 dagger-factory-icon-full rotate: false - xy: 1782, 1917 + xy: 845, 1037 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 dagger-factory-icon-large rotate: false - xy: 529, 211 + xy: 1027, 850 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 dagger-factory-icon-medium rotate: false - xy: 1823, 1286 + xy: 1081, 574 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 dagger-factory-icon-small rotate: false - xy: 1009, 407 + xy: 1913, 458 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -dart-ship-pad-icon-full +deepwater-edge rotate: false - xy: 660, 1843 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -dart-ship-pad-icon-large - rotate: false - xy: 529, 161 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -dart-ship-pad-icon-medium - rotate: false - xy: 1857, 1311 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -dart-ship-pad-icon-small - rotate: false - xy: 983, 388 - size: 24, 24 - orig: 24, 24 + xy: 1, 896 + size: 288, 96 + orig: 288, 96 offset: 0, 0 index: -1 deepwater-icon-large rotate: false - xy: 579, 211 + xy: 1177, 850 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 deepwater-icon-small rotate: false - xy: 978, 362 + xy: 1939, 484 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -delta-mech-pad-icon-full - rotate: false - xy: 792, 1843 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 delta-mech-pad-icon-large rotate: false - xy: 687, 475 + xy: 1019, 700 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 delta-mech-pad-icon-medium rotate: false - xy: 1925, 1311 + xy: 1081, 540 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 delta-mech-pad-icon-small rotate: false - xy: 1009, 381 + xy: 1913, 432 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -dirt-icon-full +differential-generator-icon-large rotate: false - xy: 1959, 1311 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -dirt-icon-medium - rotate: false - xy: 1959, 1311 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -dirt-icon-large - rotate: false - xy: 687, 425 + xy: 1069, 750 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 -dirt-icon-small +differential-generator-icon-medium rotate: false - xy: 1004, 355 + xy: 1047, 472 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +differential-generator-icon-small + rotate: false + xy: 1939, 458 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -distributor-icon-full - rotate: false - xy: 924, 1843 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 distributor-icon-large rotate: false - xy: 703, 525 + xy: 1119, 800 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 distributor-icon-medium rotate: false - xy: 1959, 1277 + xy: 1081, 506 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 distributor-icon-small rotate: false - xy: 978, 336 + xy: 1965, 484 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -door-icon-full - rotate: false - xy: 1993, 1286 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -door-icon-medium - rotate: false - xy: 1993, 1286 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 door-icon-large rotate: false - xy: 1107, 1231 + xy: 1069, 700 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 door-icon-small rotate: false - xy: 975, 310 + xy: 1939, 432 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -door-large-icon-full - rotate: false - xy: 1056, 1843 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 door-large-icon-large rotate: false - xy: 737, 475 + xy: 1119, 750 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 door-large-icon-medium rotate: false - xy: 1993, 1252 + xy: 1081, 472 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 door-large-icon-small rotate: false - xy: 975, 284 + xy: 1965, 458 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -duo-icon-full +dunerocks-icon-large rotate: false - xy: 745, 587 + xy: 1169, 800 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +dunerocks-icon-small + rotate: false + xy: 1991, 484 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +duo + rotate: false + xy: 1081, 404 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -duo-icon-medium +duo-icon-full rotate: false - xy: 745, 587 + xy: 1047, 336 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 duo-icon-large rotate: false - xy: 737, 425 + xy: 1119, 700 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 duo-icon-small rotate: false - xy: 975, 258 + xy: 2017, 508 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -force-projector-icon-full - rotate: false - xy: 261, 1145 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 force-projector-icon-large rotate: false - xy: 737, 325 + xy: 1119, 650 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 force-projector-icon-medium rotate: false - xy: 911, 1027 + xy: 1047, 302 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 force-projector-icon-small rotate: false - xy: 975, 232 + xy: 1965, 432 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 fortress-factory-icon-full rotate: false - xy: 261, 1047 + xy: 649, 1364 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 fortress-factory-icon-large rotate: false - xy: 629, 275 + xy: 1169, 642 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 fortress-factory-icon-medium rotate: false - xy: 911, 993 + xy: 1081, 336 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 fortress-factory-icon-small rotate: false - xy: 975, 206 + xy: 1991, 458 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 +fuse + rotate: false + xy: 771, 1462 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 fuse-icon-full rotate: false - xy: 359, 1047 + xy: 747, 1364 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 fuse-icon-large rotate: false - xy: 629, 225 + xy: 1119, 600 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 fuse-icon-medium rotate: false - xy: 911, 959 + xy: 1047, 268 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 fuse-icon-small rotate: false - xy: 975, 180 - size: 24, 24 - orig: 24, 24 - offset: 0, 0 - index: -1 -fusion-reactor-icon-full - rotate: false - xy: 1, 1368 - size: 128, 128 - orig: 128, 128 - offset: 0, 0 - index: -1 -fusion-reactor-icon-large - rotate: false - xy: 679, 275 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -fusion-reactor-icon-medium - rotate: false - xy: 975, 1149 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -fusion-reactor-icon-small - rotate: false - xy: 975, 154 + xy: 2017, 482 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 ghoul-factory-icon-full rotate: false - xy: 261, 851 + xy: 551, 1168 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 ghoul-factory-icon-large rotate: false - xy: 629, 175 + xy: 1169, 592 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 ghoul-factory-icon-medium rotate: false - xy: 273, 76 + xy: 1081, 302 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ghoul-factory-icon-small rotate: false - xy: 975, 128 + xy: 1991, 432 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -glaive-ship-pad-icon-full - rotate: false - xy: 457, 1047 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 glaive-ship-pad-icon-large rotate: false - xy: 679, 225 + xy: 1367, 1017 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 glaive-ship-pad-icon-medium rotate: false - xy: 307, 77 + xy: 1047, 234 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 glaive-ship-pad-icon-small rotate: false - xy: 975, 102 + xy: 2017, 456 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -grass-icon-full +graphite-press-icon-large rotate: false - xy: 443, 77 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -grass-icon-medium - rotate: false - xy: 443, 77 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -grass-icon-large - rotate: false - xy: 729, 275 + xy: 1417, 1024 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 -grass-icon-small +graphite-press-icon-medium rotate: false - xy: 1004, 329 - size: 24, 24 - orig: 24, 24 - offset: 0, 0 - index: -1 -hail-icon-full - rotate: false - xy: 511, 77 + xy: 1081, 268 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -hail-icon-medium +graphite-press-icon-small rotate: false - xy: 511, 77 + xy: 1783, 406 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +hail + rotate: false + xy: 1115, 498 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +hail-icon-full + rotate: false + xy: 1115, 464 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 hail-icon-large rotate: false - xy: 679, 175 + xy: 1467, 1024 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 hail-icon-small rotate: false - xy: 1001, 303 + xy: 1809, 406 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -ice-icon-full +holostone-edge rotate: false - xy: 1245, 1283 - size: 32, 32 - orig: 32, 32 + xy: 1, 602 + size: 288, 96 + orig: 288, 96 offset: 0, 0 index: -1 -ice-icon-medium +holostone-icon-large rotate: false - xy: 1245, 1283 - size: 32, 32 - orig: 32, 32 + xy: 1567, 1024 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +holostone-icon-small + rotate: false + xy: 1835, 406 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +hotrock-icon-large + rotate: false + xy: 1617, 1024 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +hotrock-icon-small + rotate: false + xy: 1861, 406 + size: 24, 24 + orig: 24, 24 offset: 0, 0 index: -1 ice-icon-large rotate: false - xy: 679, 125 + xy: 1363, 967 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 ice-icon-small rotate: false - xy: 1001, 277 + xy: 1887, 406 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -icerock-icon-full +ice-snow-edge rotate: false - xy: 1347, 1283 - size: 32, 32 - orig: 32, 32 + xy: 1, 406 + size: 288, 96 + orig: 288, 96 offset: 0, 0 index: -1 -icerock-icon-medium +ice-snow-icon-large rotate: false - xy: 1347, 1283 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -icerock-icon-large - rotate: false - xy: 729, 125 + xy: 1385, 917 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 -icerock-icon-small +ice-snow-icon-small rotate: false - xy: 1001, 251 + xy: 1913, 406 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -incinerator-icon-full +icerocks-icon-large rotate: false - xy: 1449, 1283 + xy: 1413, 967 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +icerocks-icon-small + rotate: false + xy: 1939, 406 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +ignarock-icon-large + rotate: false + xy: 1513, 974 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ignarock-icon-small + rotate: false + xy: 2017, 404 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +impact-reactor-icon-full + rotate: false + xy: 916, 1820 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 +impact-reactor-icon-large + rotate: false + xy: 1563, 974 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +impact-reactor-icon-medium + rotate: false + xy: 1183, 456 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -incinerator-icon-medium +impact-reactor-icon-small rotate: false - xy: 1449, 1283 - size: 32, 32 - orig: 32, 32 + xy: 1778, 380 + size: 24, 24 + orig: 24, 24 offset: 0, 0 index: -1 incinerator-icon-large rotate: false - xy: 679, 75 + xy: 1613, 974 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 incinerator-icon-small rotate: false - xy: 1001, 147 + xy: 1804, 380 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -item-source-icon-full - rotate: false - xy: 1959, 1243 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -item-source-icon-medium - rotate: false - xy: 1959, 1243 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 item-source-icon-large rotate: false - xy: 729, 75 + xy: 1435, 917 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 item-source-icon-small rotate: false - xy: 1042, 574 + xy: 1830, 380 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -item-void-icon-full - rotate: false - xy: 979, 1057 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -item-void-icon-medium - rotate: false - xy: 979, 1057 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 item-void-icon-large rotate: false - xy: 1188, 1801 + xy: 1485, 924 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 item-void-icon-small rotate: false - xy: 1042, 548 + xy: 1463, 73 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -javelin-ship-pad-icon-full - rotate: false - xy: 1452, 1851 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 javelin-ship-pad-icon-large rotate: false - xy: 1288, 1801 + xy: 1585, 924 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 javelin-ship-pad-icon-medium rotate: false - xy: 979, 1023 + xy: 1251, 448 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 javelin-ship-pad-icon-small rotate: false - xy: 1042, 522 + xy: 1489, 110 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -junction-icon-full - rotate: false - xy: 979, 955 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -junction-icon-medium - rotate: false - xy: 979, 955 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 junction-icon-large rotate: false - xy: 1388, 1801 + xy: 1663, 974 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 junction-icon-small rotate: false - xy: 1039, 496 + xy: 1856, 380 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 +kiln-icon-large + rotate: false + xy: 1667, 1024 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +kiln-icon-medium + rotate: false + xy: 1319, 490 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +kiln-icon-small + rotate: false + xy: 1463, 47 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +lancer + rotate: false + xy: 775, 1004 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 lancer-icon-full rotate: false - xy: 1650, 1851 + xy: 647, 938 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 lancer-icon-large rotate: false - xy: 1438, 1801 + xy: 1685, 924 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 lancer-icon-medium rotate: false - xy: 911, 925 + xy: 1217, 380 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 lancer-icon-small rotate: false - xy: 1039, 470 + xy: 1489, 84 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 laser-drill-icon-full rotate: false - xy: 1782, 1851 + xy: 779, 938 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 laser-drill-icon-large rotate: false - xy: 1488, 1801 + xy: 1713, 974 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 laser-drill-icon-medium rotate: false - xy: 945, 921 + xy: 1251, 414 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 laser-drill-icon-small rotate: false - xy: 1038, 444 + xy: 1515, 110 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -launch-pad-icon-full - rotate: false - xy: 359, 851 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 launch-pad-icon-large rotate: false - xy: 1538, 1801 + xy: 1735, 924 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 launch-pad-icon-medium rotate: false - xy: 979, 921 + xy: 1285, 448 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 launch-pad-icon-small rotate: false - xy: 1035, 418 + xy: 1882, 380 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -liquid-junction-icon-full - rotate: false - xy: 532, 43 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -liquid-junction-icon-medium - rotate: false - xy: 532, 43 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 liquid-junction-icon-large rotate: false - xy: 1638, 1801 + xy: 595, 390 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 liquid-junction-icon-small rotate: false - xy: 1035, 392 + xy: 1489, 58 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 liquid-router-icon-full rotate: false - xy: 328, 9 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -liquid-router-icon-medium - rotate: false - xy: 328, 9 + xy: 1251, 346 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 liquid-router-icon-large rotate: false - xy: 1688, 1801 + xy: 545, 340 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 liquid-router-icon-small rotate: false - xy: 1035, 366 + xy: 1515, 84 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -liquid-source-icon-full - rotate: false - xy: 498, 9 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -liquid-source-icon-medium - rotate: false - xy: 498, 9 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 liquid-source-icon-large rotate: false - xy: 1738, 1801 + xy: 545, 290 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 liquid-source-icon-small rotate: false - xy: 1030, 340 + xy: 1541, 110 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 liquid-tank-icon-full rotate: false - xy: 261, 655 + xy: 967, 1494 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 liquid-tank-icon-large rotate: false - xy: 1788, 1801 + xy: 595, 340 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 liquid-tank-icon-medium rotate: false - xy: 532, 9 + xy: 1251, 312 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 liquid-tank-icon-small rotate: false - xy: 1030, 314 + xy: 1908, 380 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 +magmarock-icon-large + rotate: false + xy: 595, 290 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +magmarock-icon-small + rotate: false + xy: 1515, 58 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +mass-driver + rotate: false + xy: 1261, 1494 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 mass-driver-icon-full rotate: false - xy: 457, 753 + xy: 1457, 1494 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 mass-driver-icon-large rotate: false - xy: 1838, 1801 + xy: 545, 240 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 mass-driver-icon-medium rotate: false - xy: 600, 41 + xy: 1251, 278 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 mass-driver-icon-small rotate: false - xy: 1027, 288 + xy: 1541, 84 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 mech-icon-alpha-mech rotate: false - xy: 1888, 1801 + xy: 595, 240 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 mech-icon-dart-ship rotate: false - xy: 1938, 1801 + xy: 537, 190 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 mech-icon-delta-mech rotate: false - xy: 1988, 1801 + xy: 587, 190 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 mech-icon-glaive-ship rotate: false - xy: 653, 861 + xy: 1380, 1074 size: 56, 56 orig: 56, 56 offset: 0, 0 index: -1 mech-icon-javelin-ship rotate: false - xy: 1181, 1751 + xy: 537, 140 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 mech-icon-omega-mech rotate: false - xy: 719, 927 + xy: 1035, 1008 size: 56, 56 orig: 56, 56 offset: 0, 0 index: -1 mech-icon-tau-mech rotate: false - xy: 785, 993 + xy: 1438, 1074 size: 56, 56 orig: 56, 56 offset: 0, 0 index: -1 mech-icon-trident-ship rotate: false - xy: 851, 1059 + xy: 1035, 950 size: 56, 56 orig: 56, 56 offset: 0, 0 index: -1 mechanical-drill-icon-full rotate: false - xy: 653, 1777 + xy: 639, 872 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 mechanical-drill-icon-large rotate: false - xy: 1181, 1701 + xy: 587, 140 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 mechanical-drill-icon-medium rotate: false - xy: 634, 41 + xy: 1285, 312 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 mechanical-drill-icon-small rotate: false - xy: 1027, 262 + xy: 1934, 380 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -mechanical-pump-icon-full - rotate: false - xy: 702, 41 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -mechanical-pump-icon-medium - rotate: false - xy: 702, 41 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 mechanical-pump-icon-large rotate: false - xy: 1231, 1751 + xy: 487, 106 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 mechanical-pump-icon-small rotate: false - xy: 1027, 236 + xy: 1541, 58 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 +meltdown + rotate: false + xy: 1826, 1820 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 meltdown-icon-full rotate: false - xy: 1, 198 + xy: 509, 636 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 meltdown-icon-large rotate: false - xy: 1181, 1651 + xy: 487, 56 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 meltdown-icon-medium rotate: false - xy: 736, 41 + xy: 1353, 354 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 meltdown-icon-small rotate: false - xy: 1027, 210 + xy: 1960, 380 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -melter-icon-full - rotate: false - xy: 634, 7 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -melter-icon-medium - rotate: false - xy: 634, 7 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 melter-icon-large rotate: false - xy: 1231, 1701 + xy: 537, 90 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 melter-icon-small rotate: false - xy: 1027, 184 + xy: 1986, 380 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -mend-projector-icon-full - rotate: false - xy: 719, 1711 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 mend-projector-icon-large rotate: false - xy: 1281, 1751 + xy: 587, 90 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 mend-projector-icon-medium rotate: false - xy: 668, 7 + xy: 1285, 278 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 mend-projector-icon-small rotate: false - xy: 1027, 158 + xy: 1778, 354 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -metalfloor-icon-full +metal-floor-2-icon-large rotate: false - xy: 1075, 1163 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -metalfloor-icon-medium - rotate: false - xy: 1075, 1163 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -metalfloor-icon-large - rotate: false - xy: 1181, 1601 + xy: 487, 6 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 -metalfloor-icon-small +metal-floor-2-icon-small rotate: false - xy: 1027, 132 + xy: 1804, 354 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +metal-floor-3-icon-large + rotate: false + xy: 537, 40 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +metal-floor-3-icon-small + rotate: false + xy: 1830, 354 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +metal-floor-5-icon-large + rotate: false + xy: 587, 40 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +metal-floor-5-icon-small + rotate: false + xy: 1856, 354 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +metal-floor-damaged-icon-large + rotate: false + xy: 645, 360 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +metal-floor-damaged-icon-small + rotate: false + xy: 1882, 354 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +metal-floor-edge + rotate: false + xy: 1, 308 + size: 288, 96 + orig: 288, 96 + offset: 0, 0 + index: -1 +metal-floor-icon-large + rotate: false + xy: 695, 360 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +metal-floor-icon-small + rotate: false + xy: 1908, 354 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +multi-press-icon-large + rotate: false + xy: 645, 310 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +multi-press-icon-medium + rotate: false + xy: 1251, 210 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +multi-press-icon-small + rotate: false + xy: 1934, 354 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 oil-extractor-icon-full rotate: false - xy: 359, 557 + xy: 1751, 1494 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 oil-extractor-icon-large rotate: false - xy: 1281, 1701 + xy: 745, 360 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 oil-extractor-icon-medium rotate: false - xy: 1109, 1163 + xy: 1285, 210 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 oil-extractor-icon-small rotate: false - xy: 1027, 106 + xy: 1960, 354 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -omega-mech-pad-icon-full - rotate: false - xy: 343, 361 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 omega-mech-pad-icon-large rotate: false - xy: 1331, 1751 + xy: 645, 260 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 omega-mech-pad-icon-medium rotate: false - xy: 1177, 1174 + xy: 1353, 218 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 omega-mech-pad-icon-small rotate: false - xy: 1056, 340 + xy: 1986, 354 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -ore-coal-blackstone-icon-large +ore-coal-holostone-icon-large rotate: false - xy: 1181, 1551 + xy: 695, 310 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 -ore-coal-blackstone-icon-small +ore-coal-holostone-icon-small rotate: false - xy: 1056, 314 + xy: 1463, 21 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -ore-coal-blackstone1 +ore-coal-holostone1 rotate: false - xy: 1211, 1174 + xy: 1217, 176 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-coal-blackstone2 +ore-coal-holostone2 rotate: false - xy: 1143, 1140 + xy: 1251, 176 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-coal-blackstone3 +ore-coal-holostone3 rotate: false - xy: 1177, 1140 + xy: 1285, 176 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-coal-blackstone-icon-full +ore-coal-holostone-icon-full rotate: false - xy: 1177, 1140 + xy: 1285, 176 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-coal-blackstone-icon-medium +ore-coal-holostone-icon-medium rotate: false - xy: 1177, 1140 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-coal-grass-icon-large - rotate: false - xy: 1231, 1601 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -ore-coal-grass-icon-small - rotate: false - xy: 1053, 288 - size: 24, 24 - orig: 24, 24 - offset: 0, 0 - index: -1 -ore-coal-grass1 - rotate: false - xy: 1211, 1140 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-coal-grass2 - rotate: false - xy: 779, 887 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-coal-grass3 - rotate: false - xy: 779, 853 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-coal-grass-icon-full - rotate: false - xy: 779, 853 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-coal-grass-icon-medium - rotate: false - xy: 779, 853 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-coal-ice-icon-large - rotate: false - xy: 1281, 1651 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -ore-coal-ice-icon-small - rotate: false - xy: 1053, 262 - size: 24, 24 - orig: 24, 24 - offset: 0, 0 - index: -1 -ore-coal-ice1 - rotate: false - xy: 779, 819 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-coal-ice2 - rotate: false - xy: 779, 785 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-coal-ice3 - rotate: false - xy: 779, 751 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-coal-ice-icon-full - rotate: false - xy: 779, 751 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-coal-ice-icon-medium - rotate: false - xy: 779, 751 + xy: 1285, 176 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-coal-sand-icon-large rotate: false - xy: 1331, 1701 + xy: 695, 260 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 ore-coal-sand-icon-small rotate: false - xy: 1053, 236 + xy: 1489, 32 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 ore-coal-sand1 rotate: false - xy: 779, 717 + xy: 1319, 184 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-coal-sand2 rotate: false - xy: 779, 683 + xy: 1353, 184 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-coal-sand3 rotate: false - xy: 779, 649 + xy: 1013, 174 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-coal-sand-icon-full rotate: false - xy: 779, 649 + xy: 1013, 174 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-coal-sand-icon-medium rotate: false - xy: 779, 649 + xy: 1013, 174 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-coal-snow-icon-large +ore-coal-stained-stone-icon-large rotate: false - xy: 1381, 1751 + xy: 745, 310 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 -ore-coal-snow-icon-small +ore-coal-stained-stone-icon-small rotate: false - xy: 1053, 210 + xy: 1515, 32 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -ore-coal-snow1 +ore-coal-stained-stone-red-icon-large rotate: false - xy: 779, 615 + xy: 745, 260 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-coal-stained-stone-red-icon-small + rotate: false + xy: 1541, 32 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +ore-coal-stained-stone-red1 + rotate: false + xy: 1149, 150 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-coal-snow2 +ore-coal-stained-stone-red2 rotate: false - xy: 819, 949 + xy: 1183, 150 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-coal-snow3 +ore-coal-stained-stone-red3 rotate: false - xy: 813, 887 + xy: 1217, 142 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-coal-snow-icon-full +ore-coal-stained-stone-red-icon-full rotate: false - xy: 813, 887 + xy: 1217, 142 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-coal-snow-icon-medium +ore-coal-stained-stone-red-icon-medium rotate: false - xy: 813, 887 + xy: 1217, 142 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-coal-stained-stone1 + rotate: false + xy: 1047, 166 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-coal-stained-stone2 + rotate: false + xy: 1081, 166 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-coal-stained-stone3 + rotate: false + xy: 1115, 158 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-coal-stained-stone-icon-full + rotate: false + xy: 1115, 158 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-coal-stained-stone-icon-medium + rotate: false + xy: 1115, 158 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-coal-stone-icon-large rotate: false - xy: 1181, 1501 + xy: 795, 327 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 ore-coal-stone-icon-small rotate: false - xy: 1053, 184 + xy: 2012, 378 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 ore-coal-stone1 rotate: false - xy: 813, 853 + xy: 1251, 142 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-coal-stone2 rotate: false - xy: 813, 819 + xy: 1285, 142 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-coal-stone3 rotate: false - xy: 813, 785 + xy: 1319, 150 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-coal-stone-icon-full rotate: false - xy: 813, 785 + xy: 1319, 150 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-coal-stone-icon-medium rotate: false - xy: 813, 785 + xy: 1319, 150 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-copper-blackstone-icon-large +ore-copper-holostone-icon-large rotate: false - xy: 1231, 1551 + xy: 795, 277 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 -ore-copper-blackstone-icon-small +ore-copper-holostone-icon-small rotate: false - xy: 1053, 158 + xy: 2012, 352 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -ore-copper-blackstone1 +ore-copper-holostone1 rotate: false - xy: 813, 751 + xy: 1353, 150 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-copper-blackstone2 +ore-copper-holostone2 rotate: false - xy: 813, 717 + xy: 987, 140 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-copper-blackstone3 +ore-copper-holostone3 rotate: false - xy: 813, 683 + xy: 987, 106 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-copper-blackstone-icon-full +ore-copper-holostone-icon-full rotate: false - xy: 813, 683 + xy: 987, 106 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-copper-blackstone-icon-medium +ore-copper-holostone-icon-medium rotate: false - xy: 813, 683 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-copper-grass-icon-large - rotate: false - xy: 1281, 1601 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -ore-copper-grass-icon-small - rotate: false - xy: 1053, 132 - size: 24, 24 - orig: 24, 24 - offset: 0, 0 - index: -1 -ore-copper-grass1 - rotate: false - xy: 813, 649 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-copper-grass2 - rotate: false - xy: 813, 615 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-copper-grass3 - rotate: false - xy: 787, 581 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-copper-grass-icon-full - rotate: false - xy: 787, 581 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-copper-grass-icon-medium - rotate: false - xy: 787, 581 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-copper-ice-icon-large - rotate: false - xy: 1331, 1651 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -ore-copper-ice-icon-small - rotate: false - xy: 1053, 106 - size: 24, 24 - orig: 24, 24 - offset: 0, 0 - index: -1 -ore-copper-ice1 - rotate: false - xy: 787, 547 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-copper-ice2 - rotate: false - xy: 821, 581 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-copper-ice3 - rotate: false - xy: 821, 547 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-copper-ice-icon-full - rotate: false - xy: 821, 547 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-copper-ice-icon-medium - rotate: false - xy: 821, 547 + xy: 987, 106 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-copper-sand-icon-large rotate: false - xy: 1381, 1701 + xy: 845, 327 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 ore-copper-sand-icon-small rotate: false - xy: 975, 76 + xy: 787, 1 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 ore-copper-sand1 rotate: false - xy: 787, 513 + xy: 987, 72 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-copper-sand2 rotate: false - xy: 787, 479 + xy: 987, 38 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-copper-sand3 rotate: false - xy: 821, 513 + xy: 987, 4 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-copper-sand-icon-full rotate: false - xy: 821, 513 + xy: 987, 4 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-copper-sand-icon-medium rotate: false - xy: 821, 513 + xy: 987, 4 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-copper-snow-icon-large +ore-copper-stained-stone-icon-large rotate: false - xy: 1431, 1751 + xy: 845, 277 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 -ore-copper-snow-icon-small +ore-copper-stained-stone-icon-small rotate: false - xy: 1001, 79 + xy: 813, 1 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -ore-copper-snow1 +ore-copper-stained-stone-red-icon-large rotate: false - xy: 787, 445 + xy: 895, 327 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-copper-stained-stone-red-icon-small + rotate: false + xy: 839, 1 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +ore-copper-stained-stone-red1 + rotate: false + xy: 1055, 132 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-copper-snow2 +ore-copper-stained-stone-red2 rotate: false - xy: 821, 479 + xy: 1021, 98 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-copper-snow3 +ore-copper-stained-stone-red3 rotate: false - xy: 787, 411 + xy: 1021, 64 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-copper-snow-icon-full +ore-copper-stained-stone-red-icon-full rotate: false - xy: 787, 411 + xy: 1021, 64 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-copper-snow-icon-medium +ore-copper-stained-stone-red-icon-medium rotate: false - xy: 787, 411 + xy: 1021, 64 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-copper-stained-stone1 + rotate: false + xy: 1319, 116 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-copper-stained-stone2 + rotate: false + xy: 1353, 116 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-copper-stained-stone3 + rotate: false + xy: 1021, 132 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-copper-stained-stone-icon-full + rotate: false + xy: 1021, 132 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-copper-stained-stone-icon-medium + rotate: false + xy: 1021, 132 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-copper-stone-icon-large rotate: false - xy: 1181, 1451 + xy: 895, 277 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 ore-copper-stone-icon-small rotate: false - xy: 1027, 80 + xy: 865, 1 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 ore-copper-stone1 rotate: false - xy: 821, 445 + xy: 1055, 98 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-copper-stone2 rotate: false - xy: 787, 377 + xy: 1021, 30 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-copper-stone3 rotate: false - xy: 821, 411 + xy: 1055, 64 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-copper-stone-icon-full rotate: false - xy: 821, 411 + xy: 1055, 64 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-copper-stone-icon-medium rotate: false - xy: 821, 411 + xy: 1055, 64 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-lead-blackstone-icon-large +ore-lead-holostone-icon-large rotate: false - xy: 1231, 1501 + xy: 645, 210 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 -ore-lead-blackstone-icon-small +ore-lead-holostone-icon-small rotate: false - xy: 1053, 80 + xy: 891, 1 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -ore-lead-blackstone1 +ore-lead-holostone1 rotate: false - xy: 787, 343 + xy: 1055, 30 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-lead-blackstone2 +ore-lead-holostone2 rotate: false - xy: 821, 377 + xy: 1089, 124 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-lead-blackstone3 +ore-lead-holostone3 rotate: false - xy: 821, 343 + xy: 1089, 90 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-lead-blackstone-icon-full +ore-lead-holostone-icon-full rotate: false - xy: 821, 343 + xy: 1089, 90 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-lead-blackstone-icon-medium +ore-lead-holostone-icon-medium rotate: false - xy: 821, 343 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-lead-grass-icon-large - rotate: false - xy: 1281, 1551 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -ore-lead-grass-icon-small - rotate: false - xy: 974, 50 - size: 24, 24 - orig: 24, 24 - offset: 0, 0 - index: -1 -ore-lead-grass1 - rotate: false - xy: 813, 309 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-lead-grass2 - rotate: false - xy: 813, 275 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-lead-grass3 - rotate: false - xy: 813, 241 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-lead-grass-icon-full - rotate: false - xy: 813, 241 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-lead-grass-icon-medium - rotate: false - xy: 813, 241 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-lead-ice-icon-large - rotate: false - xy: 1331, 1601 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -ore-lead-ice-icon-small - rotate: false - xy: 974, 24 - size: 24, 24 - orig: 24, 24 - offset: 0, 0 - index: -1 -ore-lead-ice1 - rotate: false - xy: 813, 207 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-lead-ice2 - rotate: false - xy: 813, 173 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-lead-ice3 - rotate: false - xy: 813, 139 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-lead-ice-icon-full - rotate: false - xy: 813, 139 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-lead-ice-icon-medium - rotate: false - xy: 813, 139 + xy: 1089, 90 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-lead-sand-icon-large rotate: false - xy: 1381, 1651 + xy: 695, 210 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 ore-lead-sand-icon-small rotate: false - xy: 1048, 614 + xy: 917, 1 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 ore-lead-sand1 rotate: false - xy: 813, 105 + xy: 1089, 56 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-lead-sand2 rotate: false - xy: 813, 71 + xy: 1089, 22 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-lead-sand3 rotate: false - xy: 847, 309 + xy: 1123, 116 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-lead-sand-icon-full rotate: false - xy: 847, 309 + xy: 1123, 116 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-lead-sand-icon-medium rotate: false - xy: 847, 309 + xy: 1123, 116 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-lead-snow-icon-large +ore-lead-stained-stone-icon-large rotate: false - xy: 1431, 1701 + xy: 745, 210 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 -ore-lead-snow-icon-small +ore-lead-stained-stone-icon-small rotate: false - xy: 1065, 496 + xy: 943, 1 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -ore-lead-snow1 +ore-lead-stained-stone-red-icon-large rotate: false - xy: 847, 275 + xy: 795, 227 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-lead-stained-stone-red-icon-small + rotate: false + xy: 553, 446 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +ore-lead-stained-stone-red1 + rotate: false + xy: 1157, 82 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-lead-snow2 +ore-lead-stained-stone-red2 rotate: false - xy: 847, 241 + xy: 1157, 48 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-lead-snow3 +ore-lead-stained-stone-red3 rotate: false - xy: 847, 207 + xy: 1123, 14 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-lead-snow-icon-full +ore-lead-stained-stone-red-icon-full rotate: false - xy: 847, 207 + xy: 1123, 14 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-lead-snow-icon-medium +ore-lead-stained-stone-red-icon-medium rotate: false - xy: 847, 207 + xy: 1123, 14 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-lead-stained-stone1 + rotate: false + xy: 1123, 82 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-lead-stained-stone2 + rotate: false + xy: 1157, 116 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-lead-stained-stone3 + rotate: false + xy: 1123, 48 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-lead-stained-stone-icon-full + rotate: false + xy: 1123, 48 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-lead-stained-stone-icon-medium + rotate: false + xy: 1123, 48 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-lead-stone-icon-large rotate: false - xy: 1481, 1751 + xy: 845, 227 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 ore-lead-stone-icon-small rotate: false - xy: 1065, 470 + xy: 1625, 115 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 ore-lead-stone1 rotate: false - xy: 847, 173 + xy: 1157, 14 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-lead-stone2 rotate: false - xy: 847, 139 + xy: 1191, 108 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-lead-stone3 rotate: false - xy: 847, 105 + xy: 1225, 108 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-lead-stone-icon-full rotate: false - xy: 847, 105 + xy: 1225, 108 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-lead-stone-icon-medium rotate: false - xy: 847, 105 + xy: 1225, 108 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-scrap-blackstone-icon-large +ore-scrap-holostone-icon-large rotate: false - xy: 1231, 1451 + xy: 895, 227 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 -ore-scrap-blackstone-icon-small +ore-scrap-holostone-icon-small rotate: false - xy: 1064, 444 + xy: 1752, 330 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -ore-scrap-blackstone1 +ore-scrap-holostone1 rotate: false - xy: 847, 71 + xy: 1191, 74 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-scrap-blackstone2 +ore-scrap-holostone2 rotate: false - xy: 838, 37 + xy: 1259, 108 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-scrap-blackstone3 +ore-scrap-holostone3 rotate: false - xy: 838, 3 + xy: 1191, 40 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-scrap-blackstone-icon-full +ore-scrap-holostone-icon-full rotate: false - xy: 838, 3 + xy: 1191, 40 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-scrap-blackstone-icon-medium +ore-scrap-holostone-icon-medium rotate: false - xy: 838, 3 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-scrap-grass-icon-large - rotate: false - xy: 1281, 1501 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -ore-scrap-grass-icon-small - rotate: false - xy: 1061, 418 - size: 24, 24 - orig: 24, 24 - offset: 0, 0 - index: -1 -ore-scrap-grass1 - rotate: false - xy: 872, 37 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-scrap-grass2 - rotate: false - xy: 872, 3 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-scrap-grass3 - rotate: false - xy: 1009, 1147 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-scrap-grass-icon-full - rotate: false - xy: 1009, 1147 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-scrap-grass-icon-medium - rotate: false - xy: 1009, 1147 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-scrap-ice-icon-large - rotate: false - xy: 1331, 1551 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -ore-scrap-ice-icon-small - rotate: false - xy: 1061, 392 - size: 24, 24 - orig: 24, 24 - offset: 0, 0 - index: -1 -ore-scrap-ice1 - rotate: false - xy: 1237, 1249 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-scrap-ice2 - rotate: false - xy: 1271, 1249 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-scrap-ice3 - rotate: false - xy: 1305, 1249 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-scrap-ice-icon-full - rotate: false - xy: 1305, 1249 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-scrap-ice-icon-medium - rotate: false - xy: 1305, 1249 + xy: 1191, 40 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-scrap-sand-icon-large rotate: false - xy: 1381, 1601 + xy: 637, 160 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 ore-scrap-sand-icon-small rotate: false - xy: 1061, 366 + xy: 1778, 328 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 ore-scrap-sand1 rotate: false - xy: 1339, 1249 + xy: 1225, 74 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-scrap-sand2 rotate: false - xy: 1373, 1249 + xy: 1225, 40 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-scrap-sand3 rotate: false - xy: 1407, 1249 + xy: 1259, 74 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-scrap-sand-icon-full rotate: false - xy: 1407, 1249 + xy: 1259, 74 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-scrap-sand-icon-medium rotate: false - xy: 1407, 1249 + xy: 1259, 74 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-scrap-snow-icon-large rotate: false - xy: 1431, 1651 + xy: 637, 110 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 ore-scrap-snow-icon-small rotate: false - xy: 1082, 340 + xy: 1804, 328 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 ore-scrap-snow1 rotate: false - xy: 1441, 1249 + xy: 1259, 40 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-scrap-snow2 rotate: false - xy: 1225, 1215 + xy: 1191, 6 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-scrap-snow3 rotate: false - xy: 1259, 1215 + xy: 1225, 6 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-scrap-snow-icon-full rotate: false - xy: 1259, 1215 + xy: 1225, 6 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-scrap-snow-icon-medium rotate: false - xy: 1259, 1215 + xy: 1225, 6 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-scrap-stained-stone-icon-large + rotate: false + xy: 687, 160 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-scrap-stained-stone-icon-small + rotate: false + xy: 1830, 328 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +ore-scrap-stained-stone-red-icon-large + rotate: false + xy: 637, 60 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-scrap-stained-stone-red-icon-small + rotate: false + xy: 1856, 328 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +ore-scrap-stained-stone-red1 + rotate: false + xy: 1327, 82 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-scrap-stained-stone-red2 + rotate: false + xy: 1293, 14 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-scrap-stained-stone-red3 + rotate: false + xy: 1327, 48 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-scrap-stained-stone-red-icon-full + rotate: false + xy: 1327, 48 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-scrap-stained-stone-red-icon-medium + rotate: false + xy: 1327, 48 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-scrap-stained-stone1 + rotate: false + xy: 1259, 6 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-scrap-stained-stone2 + rotate: false + xy: 1293, 82 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-scrap-stained-stone3 + rotate: false + xy: 1293, 48 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-scrap-stained-stone-icon-full + rotate: false + xy: 1293, 48 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-scrap-stained-stone-icon-medium + rotate: false + xy: 1293, 48 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-scrap-stone-icon-large rotate: false - xy: 1481, 1701 + xy: 687, 110 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 ore-scrap-stone-icon-small rotate: false - xy: 1082, 314 + xy: 1882, 328 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 ore-scrap-stone1 rotate: false - xy: 1293, 1215 + xy: 1327, 14 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-scrap-stone2 rotate: false - xy: 1327, 1215 + xy: 1361, 82 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-scrap-stone3 rotate: false - xy: 1361, 1215 + xy: 1361, 48 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-scrap-stone-icon-full rotate: false - xy: 1361, 1215 + xy: 1361, 48 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-scrap-stone-icon-medium rotate: false - xy: 1361, 1215 + xy: 1361, 48 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-thorium-blackstone-icon-large +ore-thorium-holostone-icon-large rotate: false - xy: 1531, 1751 + xy: 737, 160 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 -ore-thorium-blackstone-icon-small +ore-thorium-holostone-icon-small rotate: false - xy: 1079, 288 + xy: 1908, 328 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -ore-thorium-blackstone1 +ore-thorium-holostone1 rotate: false - xy: 1395, 1215 + xy: 1361, 14 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-thorium-blackstone2 +ore-thorium-holostone2 rotate: false - xy: 1429, 1215 + xy: 1575, 680 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-thorium-blackstone3 +ore-thorium-holostone3 rotate: false - xy: 1245, 1181 + xy: 1575, 646 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-thorium-blackstone-icon-full +ore-thorium-holostone-icon-full rotate: false - xy: 1245, 1181 + xy: 1575, 646 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-thorium-blackstone-icon-medium +ore-thorium-holostone-icon-medium rotate: false - xy: 1245, 1181 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-thorium-grass-icon-large - rotate: false - xy: 1281, 1451 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -ore-thorium-grass-icon-small - rotate: false - xy: 1079, 262 - size: 24, 24 - orig: 24, 24 - offset: 0, 0 - index: -1 -ore-thorium-grass1 - rotate: false - xy: 1245, 1147 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-thorium-grass2 - rotate: false - xy: 1279, 1181 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-thorium-grass3 - rotate: false - xy: 1279, 1147 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-thorium-grass-icon-full - rotate: false - xy: 1279, 1147 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-thorium-grass-icon-medium - rotate: false - xy: 1279, 1147 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-thorium-ice-icon-large - rotate: false - xy: 1331, 1501 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -ore-thorium-ice-icon-small - rotate: false - xy: 1079, 236 - size: 24, 24 - orig: 24, 24 - offset: 0, 0 - index: -1 -ore-thorium-ice1 - rotate: false - xy: 1313, 1181 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-thorium-ice2 - rotate: false - xy: 1313, 1147 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-thorium-ice3 - rotate: false - xy: 1347, 1181 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-thorium-ice-icon-full - rotate: false - xy: 1347, 1181 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-thorium-ice-icon-medium - rotate: false - xy: 1347, 1181 + xy: 1575, 646 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-thorium-sand-icon-large rotate: false - xy: 1381, 1551 + xy: 687, 60 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 ore-thorium-sand-icon-small rotate: false - xy: 1079, 210 + xy: 1934, 328 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 ore-thorium-sand1 rotate: false - xy: 1347, 1147 + xy: 1575, 612 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-thorium-sand2 rotate: false - xy: 1381, 1181 + xy: 1575, 578 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-thorium-sand3 rotate: false - xy: 1381, 1147 + xy: 1575, 544 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-thorium-sand-icon-full rotate: false - xy: 1381, 1147 + xy: 1575, 544 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-thorium-sand-icon-medium rotate: false - xy: 1381, 1147 + xy: 1575, 544 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-thorium-snow-icon-large +ore-thorium-stained-stone-icon-large rotate: false - xy: 1431, 1601 + xy: 737, 110 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 -ore-thorium-snow-icon-small +ore-thorium-stained-stone-icon-small rotate: false - xy: 1079, 184 + xy: 1960, 328 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -ore-thorium-snow1 +ore-thorium-stained-stone-red-icon-large rotate: false - xy: 1415, 1181 + xy: 737, 60 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-thorium-stained-stone-red-icon-small + rotate: false + xy: 1986, 328 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +ore-thorium-stained-stone-red1 + rotate: false + xy: 1609, 601 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-thorium-snow2 +ore-thorium-stained-stone-red2 rotate: false - xy: 1415, 1147 + xy: 1609, 567 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-thorium-snow3 +ore-thorium-stained-stone-red3 rotate: false - xy: 1449, 1181 + xy: 1609, 533 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-thorium-snow-icon-full +ore-thorium-stained-stone-red-icon-full rotate: false - xy: 1449, 1181 + xy: 1609, 533 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-thorium-snow-icon-medium +ore-thorium-stained-stone-red-icon-medium rotate: false - xy: 1449, 1181 + xy: 1609, 533 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-thorium-stained-stone1 + rotate: false + xy: 1609, 703 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-thorium-stained-stone2 + rotate: false + xy: 1609, 669 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-thorium-stained-stone3 + rotate: false + xy: 1609, 635 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-thorium-stained-stone-icon-full + rotate: false + xy: 1609, 635 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-thorium-stained-stone-icon-medium + rotate: false + xy: 1609, 635 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-thorium-stone-icon-large rotate: false - xy: 1481, 1651 + xy: 637, 10 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 ore-thorium-stone-icon-small rotate: false - xy: 1079, 158 + xy: 2012, 326 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 ore-thorium-stone1 rotate: false - xy: 1449, 1147 + xy: 1643, 689 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-thorium-stone2 rotate: false - xy: 1463, 1215 + xy: 1677, 689 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-thorium-stone3 rotate: false - xy: 1483, 1181 + xy: 1643, 655 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-thorium-stone-icon-full rotate: false - xy: 1483, 1181 + xy: 1643, 655 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-thorium-stone-icon-medium rotate: false - xy: 1483, 1181 + xy: 1643, 655 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-titanium-blackstone-icon-large +ore-titanium-holostone-icon-large rotate: false - xy: 1531, 1701 + xy: 687, 10 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 -ore-titanium-blackstone-icon-small +ore-titanium-holostone-icon-small rotate: false - xy: 1079, 132 + xy: 1489, 6 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -ore-titanium-blackstone1 +ore-titanium-holostone1 rotate: false - xy: 1483, 1147 + xy: 1643, 621 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-titanium-blackstone2 +ore-titanium-holostone2 rotate: false - xy: 1497, 1218 + xy: 1677, 655 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-titanium-blackstone3 +ore-titanium-holostone3 rotate: false - xy: 1531, 1218 + xy: 1643, 587 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-titanium-blackstone-icon-full +ore-titanium-holostone-icon-full rotate: false - xy: 1531, 1218 + xy: 1643, 587 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-titanium-blackstone-icon-medium +ore-titanium-holostone-icon-medium rotate: false - xy: 1531, 1218 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-titanium-grass-icon-large - rotate: false - xy: 1581, 1751 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -ore-titanium-grass-icon-small - rotate: false - xy: 1079, 106 - size: 24, 24 - orig: 24, 24 - offset: 0, 0 - index: -1 -ore-titanium-grass1 - rotate: false - xy: 1565, 1218 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-titanium-grass2 - rotate: false - xy: 1599, 1218 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-titanium-grass3 - rotate: false - xy: 1633, 1218 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-titanium-grass-icon-full - rotate: false - xy: 1633, 1218 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-titanium-grass-icon-medium - rotate: false - xy: 1633, 1218 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-titanium-ice-icon-large - rotate: false - xy: 1331, 1451 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -ore-titanium-ice-icon-small - rotate: false - xy: 1079, 80 - size: 24, 24 - orig: 24, 24 - offset: 0, 0 - index: -1 -ore-titanium-ice1 - rotate: false - xy: 1667, 1218 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-titanium-ice2 - rotate: false - xy: 1701, 1218 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-titanium-ice3 - rotate: false - xy: 1735, 1218 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-titanium-ice-icon-full - rotate: false - xy: 1735, 1218 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -ore-titanium-ice-icon-medium - rotate: false - xy: 1735, 1218 + xy: 1643, 587 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-titanium-sand-icon-large rotate: false - xy: 1381, 1501 + xy: 737, 10 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 ore-titanium-sand-icon-small rotate: false - xy: 1001, 53 + xy: 1515, 6 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 ore-titanium-sand1 rotate: false - xy: 1769, 1218 + xy: 1677, 621 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-titanium-sand2 rotate: false - xy: 1803, 1218 + xy: 1643, 553 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-titanium-sand3 rotate: false - xy: 1517, 1184 + xy: 1677, 587 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-titanium-sand-icon-full rotate: false - xy: 1517, 1184 + xy: 1677, 587 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-titanium-sand-icon-medium rotate: false - xy: 1517, 1184 + xy: 1677, 587 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-titanium-snow-icon-large +ore-titanium-stained-stone-icon-large rotate: false - xy: 1431, 1551 + xy: 795, 177 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 -ore-titanium-snow-icon-small +ore-titanium-stained-stone-icon-small rotate: false - xy: 1027, 54 + xy: 1541, 6 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -ore-titanium-snow1 +ore-titanium-stained-stone-red-icon-large rotate: false - xy: 1517, 1150 + xy: 845, 177 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +ore-titanium-stained-stone-red-icon-small + rotate: false + xy: 2022, 1702 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +ore-titanium-stained-stone-red1 + rotate: false + xy: 1711, 688 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-titanium-snow2 +ore-titanium-stained-stone-red2 rotate: false - xy: 1551, 1184 + xy: 1711, 654 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-titanium-snow3 +ore-titanium-stained-stone-red3 rotate: false - xy: 1551, 1150 + xy: 1711, 620 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-titanium-snow-icon-full +ore-titanium-stained-stone-red-icon-full rotate: false - xy: 1551, 1150 + xy: 1711, 620 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -ore-titanium-snow-icon-medium +ore-titanium-stained-stone-red-icon-medium rotate: false - xy: 1551, 1150 + xy: 1711, 620 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-titanium-stained-stone1 + rotate: false + xy: 1677, 553 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-titanium-stained-stone2 + rotate: false + xy: 1643, 519 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-titanium-stained-stone3 + rotate: false + xy: 1677, 519 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-titanium-stained-stone-icon-full + rotate: false + xy: 1677, 519 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +ore-titanium-stained-stone-icon-medium + rotate: false + xy: 1677, 519 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-titanium-stone-icon-large rotate: false - xy: 1481, 1601 + xy: 895, 177 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 ore-titanium-stone-icon-small rotate: false - xy: 1053, 54 + xy: 2022, 1676 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 ore-titanium-stone1 rotate: false - xy: 1585, 1184 + xy: 1711, 586 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-titanium-stone2 rotate: false - xy: 1585, 1150 + xy: 1711, 552 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-titanium-stone3 rotate: false - xy: 1619, 1184 + xy: 1711, 518 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-titanium-stone-icon-full rotate: false - xy: 1619, 1184 + xy: 1711, 518 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ore-titanium-stone-icon-medium rotate: false - xy: 1619, 1184 + xy: 1711, 518 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -overdrive-projector-icon-full - rotate: false - xy: 719, 1645 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 overdrive-projector-icon-large rotate: false - xy: 1531, 1651 + xy: 787, 127 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 overdrive-projector-icon-medium rotate: false - xy: 1619, 1150 + xy: 1745, 680 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 overdrive-projector-icon-small rotate: false - xy: 1079, 54 + xy: 1749, 304 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -overflow-gate-icon-full - rotate: false - xy: 1653, 1150 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -overflow-gate-icon-medium - rotate: false - xy: 1653, 1150 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 overflow-gate-icon-large rotate: false - xy: 1581, 1701 + xy: 787, 77 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 overflow-gate-icon-small rotate: false - xy: 1000, 27 + xy: 1775, 302 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 phantom-factory-icon-full rotate: false - xy: 851, 1777 + xy: 705, 740 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 phantom-factory-icon-large rotate: false - xy: 1631, 1751 + xy: 837, 127 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 phantom-factory-icon-medium rotate: false - xy: 1687, 1184 + xy: 1779, 680 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 phantom-factory-icon-small rotate: false - xy: 1000, 1 + xy: 1801, 302 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -phase-conduit-icon-full - rotate: false - xy: 1755, 1150 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -phase-conduit-icon-medium - rotate: false - xy: 1755, 1150 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 phase-conduit-icon-large rotate: false - xy: 1381, 1451 + xy: 787, 27 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 phase-conduit-icon-small rotate: false - xy: 1087, 418 + xy: 1827, 302 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -phase-conveyor-icon-full - rotate: false - xy: 1857, 1209 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -phase-conveyor-icon-medium - rotate: false - xy: 1857, 1209 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 phase-conveyor-icon-large rotate: false - xy: 1431, 1501 + xy: 837, 77 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 phase-conveyor-icon-small rotate: false - xy: 1087, 392 + xy: 1853, 302 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -phase-wall-icon-full - rotate: false - xy: 1857, 1175 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -phase-wall-icon-medium - rotate: false - xy: 1857, 1175 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 phase-wall-icon-large rotate: false - xy: 1481, 1551 + xy: 887, 127 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 phase-wall-icon-small rotate: false - xy: 1087, 366 + xy: 1879, 302 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -phase-wall-large-icon-full - rotate: false - xy: 851, 1711 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 phase-wall-large-icon-large rotate: false - xy: 1531, 1601 + xy: 837, 27 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 phase-wall-large-icon-medium rotate: false - xy: 1925, 1209 + xy: 1813, 612 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 phase-wall-large-icon-small rotate: false - xy: 1090, 444 + xy: 1905, 302 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 phase-weaver-icon-full rotate: false - xy: 719, 1513 + xy: 837, 773 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 phase-weaver-icon-large rotate: false - xy: 1581, 1651 + xy: 887, 77 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 phase-weaver-icon-medium rotate: false - xy: 1959, 1209 + xy: 1847, 646 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 phase-weaver-icon-small rotate: false - xy: 1108, 340 + xy: 1931, 302 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -pine-icon-full - rotate: false - xy: 1925, 1175 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -pine-icon-medium - rotate: false - xy: 1925, 1175 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 pine-icon-large rotate: false - xy: 1631, 1701 + xy: 887, 27 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 pine-icon-small rotate: false - xy: 1108, 314 + xy: 1957, 302 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 plasma-drill-icon-full rotate: false - xy: 464, 1831 + xy: 526, 1690 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 plasma-drill-icon-large rotate: false - xy: 1681, 1751 + xy: 1385, 867 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 plasma-drill-icon-medium rotate: false - xy: 1959, 1175 + xy: 1779, 544 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 plasma-drill-icon-small rotate: false - xy: 1105, 288 + xy: 1983, 302 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -plastanium-compressor-icon-full - rotate: false - xy: 917, 1711 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 plastanium-compressor-icon-large rotate: false - xy: 1431, 1451 + xy: 1435, 867 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 plastanium-compressor-icon-medium rotate: false - xy: 1993, 1184 + xy: 1813, 578 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 plastanium-compressor-icon-small rotate: false - xy: 1105, 262 + xy: 2009, 300 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 pneumatic-drill-icon-full rotate: false - xy: 719, 1447 + xy: 747, 608 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 pneumatic-drill-icon-large rotate: false - xy: 1481, 1501 + xy: 1485, 874 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 pneumatic-drill-icon-medium rotate: false - xy: 1857, 1141 + xy: 1847, 612 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 pneumatic-drill-icon-small rotate: false - xy: 1105, 236 + xy: 1723, 293 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -power-node-icon-full - rotate: false - xy: 1925, 1141 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -power-node-icon-medium - rotate: false - xy: 1925, 1141 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 power-node-icon-large rotate: false - xy: 1531, 1551 + xy: 1535, 874 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 power-node-icon-small rotate: false - xy: 1105, 210 + xy: 1749, 278 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -power-node-large-icon-full - rotate: false - xy: 983, 1711 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 power-node-large-icon-large rotate: false - xy: 1581, 1601 + xy: 1585, 874 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 power-node-large-icon-medium rotate: false - xy: 1959, 1141 + xy: 1915, 680 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 power-node-large-icon-small rotate: false - xy: 1105, 184 + xy: 1775, 276 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -power-source-icon-full - rotate: false - xy: 1993, 1116 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -power-source-icon-medium - rotate: false - xy: 1993, 1116 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 power-source-icon-large rotate: false - xy: 1631, 1651 + xy: 1635, 874 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 power-source-icon-small rotate: false - xy: 1105, 158 + xy: 1801, 276 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -power-void-icon-full - rotate: false - xy: 1279, 1113 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -power-void-icon-medium - rotate: false - xy: 1279, 1113 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 power-void-icon-large rotate: false - xy: 1681, 1701 + xy: 1685, 874 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 power-void-icon-small rotate: false - xy: 1105, 132 + xy: 1827, 276 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 pulse-conduit-icon-full rotate: false - xy: 1381, 1113 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -pulse-conduit-icon-medium - rotate: false - xy: 1381, 1113 + xy: 1949, 680 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 pulse-conduit-icon-large rotate: false - xy: 1731, 1751 + xy: 1735, 874 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 pulse-conduit-icon-small rotate: false - xy: 1105, 106 + xy: 1853, 276 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 pulverizer-icon-full rotate: false - xy: 1687, 1116 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -pulverizer-icon-medium - rotate: false - xy: 1687, 1116 + xy: 1983, 646 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 pulverizer-icon-large rotate: false - xy: 1481, 1451 + xy: 1219, 800 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 pulverizer-icon-small rotate: false - xy: 1105, 80 + xy: 1879, 276 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -pyratite-mixer-icon-full - rotate: false - xy: 653, 1315 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 pyratite-mixer-icon-large rotate: false - xy: 1531, 1501 + xy: 1219, 750 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 pyratite-mixer-icon-medium rotate: false - xy: 1755, 1116 + xy: 1949, 578 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 pyratite-mixer-icon-small rotate: false - xy: 1105, 54 + xy: 1905, 276 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -reconstructor-icon-full +repair-point rotate: false - xy: 719, 1381 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 -reconstructor-icon-large - rotate: false - xy: 1581, 1551 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -reconstructor-icon-medium - rotate: false - xy: 1789, 1116 + xy: 1983, 612 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -reconstructor-icon-small - rotate: false - xy: 1113, 418 - size: 24, 24 - orig: 24, 24 - offset: 0, 0 - index: -1 repair-point-icon-full rotate: false - xy: 1857, 1107 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -repair-point-icon-medium - rotate: false - xy: 1857, 1107 + xy: 1983, 578 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 repair-point-icon-large rotate: false - xy: 1631, 1601 + xy: 1219, 700 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 repair-point-icon-small rotate: false - xy: 1113, 392 + xy: 1931, 276 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 revenant-factory-icon-full rotate: false - xy: 131, 1108 + xy: 1176, 1690 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 revenant-factory-icon-large rotate: false - xy: 1681, 1651 + xy: 1219, 650 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 revenant-factory-icon-medium rotate: false - xy: 1925, 1107 + xy: 1983, 544 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 revenant-factory-icon-small rotate: false - xy: 1113, 366 + xy: 1957, 276 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 +ripple + rotate: false + xy: 389, 12 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 ripple-icon-full rotate: false - xy: 555, 1635 + xy: 869, 1396 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 ripple-icon-large rotate: false - xy: 1731, 1701 + xy: 937, 127 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 ripple-icon-medium rotate: false - xy: 1959, 1107 + xy: 1745, 510 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 ripple-icon-small rotate: false - xy: 1134, 340 + xy: 1983, 276 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -rock-icon-full - rotate: false - xy: 1581, 1501 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -rock-icon-large - rotate: false - xy: 1581, 1501 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -rock-icon-medium - rotate: false - xy: 1993, 1082 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -rock-icon-small - rotate: false - xy: 1134, 314 - size: 24, 24 - orig: 24, 24 - offset: 0, 0 - index: -1 -rocks-icon-full - rotate: false - xy: 1585, 1082 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -rocks-icon-medium - rotate: false - xy: 1585, 1082 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 rocks-icon-large rotate: false - xy: 1631, 1551 + xy: 1269, 800 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 rocks-icon-small rotate: false - xy: 1131, 288 + xy: 2009, 274 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -rotary-pump-icon-full - rotate: false - xy: 917, 1579 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 rotary-pump-icon-large rotate: false - xy: 1681, 1601 + xy: 1269, 750 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 rotary-pump-icon-medium rotate: false - xy: 1619, 1082 + xy: 1847, 510 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 rotary-pump-icon-small rotate: false - xy: 1131, 262 + xy: 1693, 262 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -router-icon-full - rotate: false - xy: 1687, 1082 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -router-icon-medium - rotate: false - xy: 1687, 1082 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 router-icon-large rotate: false - xy: 1731, 1651 + xy: 1269, 700 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 router-icon-small rotate: false - xy: 1131, 236 + xy: 1719, 267 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -rtg-generator-icon-full - rotate: false - xy: 1049, 1711 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 rtg-generator-icon-large rotate: false - xy: 1781, 1701 + xy: 1269, 650 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 rtg-generator-icon-medium rotate: false - xy: 1721, 1082 + xy: 1915, 510 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 rtg-generator-icon-small rotate: false - xy: 1131, 210 + xy: 1690, 236 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 +salvo + rotate: false + xy: 879, 443 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 salvo-icon-full rotate: false - xy: 983, 1579 + xy: 1933, 1264 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 salvo-icon-large rotate: false - xy: 1831, 1751 + xy: 1269, 600 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 salvo-icon-medium rotate: false - xy: 1789, 1082 + xy: 1983, 510 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 salvo-icon-small rotate: false - xy: 1131, 184 + xy: 1685, 210 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -sand-icon-full +sand-edge rotate: false - xy: 1925, 1073 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -sand-icon-medium - rotate: false - xy: 1925, 1073 - size: 32, 32 - orig: 32, 32 + xy: 1, 210 + size: 288, 96 + orig: 288, 96 offset: 0, 0 index: -1 sand-icon-large rotate: false - xy: 1581, 1451 + xy: 1219, 550 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 sand-icon-small rotate: false - xy: 1131, 158 + xy: 1745, 252 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -separator-icon-full +sand-water-edge rotate: false - xy: 847, 649 - size: 32, 32 - orig: 32, 32 + xy: 1, 112 + size: 288, 96 + orig: 288, 96 offset: 0, 0 index: -1 -separator-icon-medium +sand-water-icon-large rotate: false - xy: 847, 649 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -separator-icon-large - rotate: false - xy: 1681, 1551 + xy: 1269, 550 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 -separator-icon-small +sand-water-icon-small rotate: false - xy: 1131, 53 + xy: 1719, 241 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -shock-mine-icon-full +scrap-wall-gigantic-icon-large rotate: false - xy: 855, 547 + xy: 1485, 824 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +scrap-wall-gigantic-icon-medium + rotate: false + xy: 1387, 125 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -shock-mine-icon-medium +scrap-wall-gigantic-icon-small rotate: false - xy: 855, 547 + xy: 1771, 250 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +scrap-wall-huge-icon-large + rotate: false + xy: 1535, 824 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +scrap-wall-huge-icon-medium + rotate: false + xy: 1421, 499 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 +scrap-wall-huge-icon-small + rotate: false + xy: 1797, 250 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +scrap-wall-icon-large + rotate: false + xy: 1585, 824 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +scrap-wall-icon-small + rotate: false + xy: 1823, 250 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +scrap-wall-large-icon-large + rotate: false + xy: 1635, 824 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +scrap-wall-large-icon-medium + rotate: false + xy: 1421, 465 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +scrap-wall-large-icon-small + rotate: false + xy: 1849, 250 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +separator-icon-large + rotate: false + xy: 1685, 824 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +separator-icon-medium + rotate: false + xy: 1421, 397 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +separator-icon-small + rotate: false + xy: 1927, 250 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 shock-mine-icon-large rotate: false - xy: 1731, 1601 + xy: 1735, 824 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 shock-mine-icon-small rotate: false - xy: 1157, 288 + xy: 1953, 250 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -shrub-icon-full - rotate: false - xy: 855, 445 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -shrub-icon-medium - rotate: false - xy: 855, 445 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -shrub-icon-large - rotate: false - xy: 1831, 1701 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -shrub-icon-small - rotate: false - xy: 1157, 262 - size: 24, 24 - orig: 24, 24 - offset: 0, 0 - index: -1 -silicon-smelter-icon-full - rotate: false - xy: 719, 1249 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 silicon-smelter-icon-large rotate: false - xy: 1881, 1751 + xy: 1774, 1032 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 silicon-smelter-icon-medium rotate: false - xy: 855, 411 + xy: 1421, 261 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 silicon-smelter-icon-small rotate: false - xy: 1157, 236 + xy: 1979, 250 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -snow-icon-full +snow-edge rotate: false - xy: 881, 241 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -snow-icon-medium - rotate: false - xy: 881, 241 - size: 32, 32 - orig: 32, 32 + xy: 1, 14 + size: 288, 96 + orig: 288, 96 offset: 0, 0 index: -1 snow-icon-large rotate: false - xy: 1631, 1451 + xy: 1824, 1032 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 snow-icon-small rotate: false - xy: 1157, 210 + xy: 2005, 248 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -solar-panel-icon-full +snowrocks-icon-large rotate: false - xy: 881, 173 - size: 32, 32 - orig: 32, 32 + xy: 1874, 1032 + size: 48, 48 + orig: 48, 48 offset: 0, 0 index: -1 -solar-panel-icon-medium +snowrocks-icon-small rotate: false - xy: 881, 173 - size: 32, 32 - orig: 32, 32 + xy: 1745, 226 + size: 24, 24 + orig: 24, 24 offset: 0, 0 index: -1 solar-panel-icon-large rotate: false - xy: 1731, 1551 + xy: 1924, 1032 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 solar-panel-icon-small rotate: false - xy: 1157, 184 + xy: 1771, 224 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -solar-panel-large-icon-full - rotate: false - xy: 555, 1341 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 solar-panel-large-icon-large rotate: false - xy: 1781, 1601 + xy: 1974, 1032 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 solar-panel-large-icon-medium rotate: false - xy: 881, 139 + xy: 1429, 91 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 solar-panel-large-icon-small rotate: false - xy: 1157, 158 + xy: 1797, 224 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -sorter-icon-full - rotate: false - xy: 906, 3 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -sorter-icon-medium - rotate: false - xy: 906, 3 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 sorter-icon-large rotate: false - xy: 1831, 1651 + xy: 1763, 982 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 sorter-icon-small rotate: false - xy: 1157, 132 + xy: 1823, 224 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -space-icon-large - rotate: false - xy: 1881, 1701 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -space-icon-small - rotate: false - xy: 1157, 106 - size: 24, 24 - orig: 24, 24 - offset: 0, 0 - index: -1 -spawn-icon-full - rotate: false - xy: 1013, 980 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -spawn-icon-medium - rotate: false - xy: 1013, 980 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 spawn-icon-large rotate: false - xy: 1681, 1451 + xy: 1813, 982 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 spawn-icon-small rotate: false - xy: 1157, 80 + xy: 1849, 224 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 +spectre + rotate: false + xy: 1826, 1690 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 spectre-icon-full rotate: false - xy: 131, 588 + xy: 477, 1560 size: 128, 128 orig: 128, 128 offset: 0, 0 index: -1 spectre-icon-large rotate: false - xy: 1731, 1501 + xy: 1863, 982 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 spectre-icon-medium rotate: false - xy: 1013, 946 + xy: 1455, 481 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 spectre-icon-small rotate: false - xy: 1157, 54 + xy: 1927, 224 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 spirit-factory-icon-full rotate: false - xy: 785, 1315 + xy: 997, 1198 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 spirit-factory-icon-large rotate: false - xy: 1831, 1601 + xy: 1963, 982 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 spirit-factory-icon-medium rotate: false - xy: 1013, 912 + xy: 1455, 447 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 spirit-factory-icon-small rotate: false - xy: 1134, 1114 + xy: 1953, 224 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -stone-icon-full +spore-cluster-icon-large rotate: false - xy: 881, 789 + xy: 1785, 932 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +spore-cluster-icon-medium + rotate: false + xy: 1455, 413 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -stone-icon-medium +spore-cluster-icon-small rotate: false - xy: 881, 789 - size: 32, 32 - orig: 32, 32 + xy: 1979, 224 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +stained-boulder-icon-large + rotate: false + xy: 1785, 882 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +stained-boulder-icon-small + rotate: false + xy: 2005, 222 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +stained-rocks-icon-large + rotate: false + xy: 1835, 932 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +stained-rocks-icon-small + rotate: false + xy: 1901, 213 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +stained-rocks-red-icon-large + rotate: false + xy: 1785, 832 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +stained-rocks-red-icon-small + rotate: false + xy: 1875, 208 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +stained-rocks-yellow-icon-large + rotate: false + xy: 1835, 882 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +stained-rocks-yellow-icon-small + rotate: false + xy: 1927, 198 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +stained-stone-edge + rotate: false + xy: 582, 1950 + size: 288, 96 + orig: 288, 96 + offset: 0, 0 + index: -1 +stained-stone-icon-large + rotate: false + xy: 1885, 932 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +stained-stone-icon-small + rotate: false + xy: 1953, 198 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +stained-stone-red-edge + rotate: false + xy: 872, 1950 + size: 288, 96 + orig: 288, 96 + offset: 0, 0 + index: -1 +stained-stone-red-icon-large + rotate: false + xy: 1835, 832 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +stained-stone-red-icon-small + rotate: false + xy: 1979, 198 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +stained-stone-yellow-edge + rotate: false + xy: 1162, 1950 + size: 288, 96 + orig: 288, 96 + offset: 0, 0 + index: -1 +stained-stone-yellow-icon-large + rotate: false + xy: 1885, 882 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +stained-stone-yellow-icon-small + rotate: false + xy: 2005, 196 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +stone-edge + rotate: false + xy: 1452, 1950 + size: 288, 96 + orig: 288, 96 offset: 0, 0 index: -1 stone-icon-large rotate: false - xy: 1881, 1651 + xy: 1935, 932 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 stone-icon-small rotate: false - xy: 1160, 1114 + xy: 1901, 187 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -surge-wall-icon-full +surge-tower-icon-large rotate: false - xy: 881, 721 + xy: 1885, 832 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +surge-tower-icon-medium + rotate: false + xy: 1489, 340 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 -surge-wall-icon-medium +surge-tower-icon-small rotate: false - xy: 881, 721 - size: 32, 32 - orig: 32, 32 + xy: 1927, 172 + size: 24, 24 + orig: 24, 24 offset: 0, 0 index: -1 surge-wall-icon-large rotate: false - xy: 1981, 1751 + xy: 1935, 882 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 surge-wall-icon-small rotate: false - xy: 1186, 1114 + xy: 1953, 172 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -surge-wall-large-icon-full - rotate: false - xy: 1049, 1579 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 surge-wall-large-icon-large rotate: false - xy: 1731, 1451 + xy: 1935, 832 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 surge-wall-large-icon-medium rotate: false - xy: 881, 687 + xy: 1557, 408 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 surge-wall-large-icon-small rotate: false - xy: 1212, 1114 + xy: 1979, 172 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 +swarmer + rotate: false + xy: 1591, 1198 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 swarmer-icon-full rotate: false - xy: 653, 1117 + xy: 1657, 1198 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 swarmer-icon-large rotate: false - xy: 1831, 1551 + xy: 1985, 882 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 swarmer-icon-medium rotate: false - xy: 881, 653 + xy: 1489, 306 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 swarmer-icon-small rotate: false - xy: 1026, 27 + xy: 2005, 170 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 +tar-edge + rotate: false + xy: 1742, 1950 + size: 288, 96 + orig: 288, 96 + offset: 0, 0 + index: -1 tar-icon-large rotate: false - xy: 1881, 1601 + xy: 1985, 832 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 tar-icon-small rotate: false - xy: 1026, 1 + xy: 1659, 189 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -tau-mech-pad-icon-full - rotate: false - xy: 785, 1249 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 tau-mech-pad-icon-large rotate: false - xy: 1831, 1501 + xy: 1885, 782 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 tau-mech-pad-icon-medium rotate: false - xy: 889, 585 + xy: 1557, 374 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 tau-mech-pad-icon-small rotate: false - xy: 1052, 28 + xy: 1685, 184 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -thermal-generator-icon-full - rotate: false - xy: 917, 1381 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 thermal-generator-icon-large rotate: false - xy: 1881, 1551 + xy: 1935, 782 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 thermal-generator-icon-medium rotate: false - xy: 889, 551 + xy: 1489, 272 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 thermal-generator-icon-small rotate: false - xy: 1052, 2 + xy: 1655, 163 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -thermal-pump-icon-full - rotate: false - xy: 1049, 1513 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 thermal-pump-icon-large rotate: false - xy: 1931, 1601 + xy: 1985, 782 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 thermal-pump-icon-medium rotate: false - xy: 889, 517 + xy: 1523, 306 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 thermal-pump-icon-small rotate: false - xy: 1078, 28 + xy: 1654, 137 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -thorium-reactor-icon-full - rotate: false - xy: 555, 1047 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 thorium-reactor-icon-large rotate: false - xy: 1981, 1651 + xy: 1285, 858 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 thorium-reactor-icon-medium rotate: false - xy: 889, 381 + xy: 1557, 306 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 thorium-reactor-icon-small rotate: false - xy: 1078, 2 + xy: 1651, 111 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -thorium-wall-icon-full - rotate: false - xy: 915, 887 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -thorium-wall-icon-medium - rotate: false - xy: 915, 887 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 thorium-wall-icon-large rotate: false - xy: 1831, 1451 + xy: 1335, 858 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 thorium-wall-icon-small rotate: false - xy: 1104, 28 + xy: 1681, 158 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -thorium-wall-large-icon-full - rotate: false - xy: 653, 1051 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 thorium-wall-large-icon-large rotate: false - xy: 1881, 1501 + xy: 1319, 808 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 thorium-wall-large-icon-medium rotate: false - xy: 949, 887 + xy: 1523, 238 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 thorium-wall-large-icon-small rotate: false - xy: 1104, 2 + xy: 1680, 132 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +thruster-icon-large + rotate: false + xy: 1319, 758 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +thruster-icon-medium + rotate: false + xy: 1557, 272 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +thruster-icon-small + rotate: false + xy: 1677, 106 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 titan-factory-icon-full rotate: false - xy: 555, 753 + xy: 1849, 1396 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 titan-factory-icon-large rotate: false - xy: 1931, 1551 + xy: 1319, 708 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 titan-factory-icon-medium rotate: false - xy: 915, 853 + xy: 1489, 170 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titan-factory-icon-small rotate: false - xy: 1130, 27 + xy: 1711, 210 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -titanium-conveyor-icon-full - rotate: false - xy: 983, 878 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -titanium-conveyor-icon-medium - rotate: false - xy: 983, 878 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 titanium-conveyor-icon-large rotate: false - xy: 1981, 1601 + xy: 1319, 658 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 titanium-conveyor-icon-small rotate: false - xy: 1130, 1 + xy: 1711, 184 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -titanium-wall-icon-full - rotate: false - xy: 983, 810 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -titanium-wall-icon-medium - rotate: false - xy: 983, 810 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 titanium-wall-icon-large rotate: false - xy: 1881, 1451 + xy: 1319, 608 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 titanium-wall-icon-small rotate: false - xy: 1157, 28 + xy: 1707, 158 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -titanium-wall-large-icon-full - rotate: false - xy: 917, 1315 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 titanium-wall-large-icon-large rotate: false - xy: 1931, 1501 + xy: 1319, 558 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 titanium-wall-large-icon-medium rotate: false - xy: 983, 776 + xy: 1659, 451 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 titanium-wall-large-icon-small rotate: false - xy: 1156, 2 + xy: 1706, 132 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -trident-ship-pad-icon-full - rotate: false - xy: 1049, 1447 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 trident-ship-pad-icon-large rotate: false - xy: 1981, 1551 + xy: 1369, 808 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 trident-ship-pad-icon-medium rotate: false - xy: 983, 708 + xy: 1659, 417 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 trident-ship-pad-icon-small rotate: false - xy: 1182, 2 + xy: 1703, 106 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -turbine-generator-icon-full - rotate: false - xy: 653, 985 - size: 64, 64 - orig: 64, 64 - offset: 0, 0 - index: -1 turbine-generator-icon-large rotate: false - xy: 1931, 1451 + xy: 1369, 758 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 turbine-generator-icon-medium rotate: false - xy: 983, 674 + xy: 1625, 349 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 turbine-generator-icon-small rotate: false - xy: 1047, 1056 + xy: 1737, 200 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 +unit-icon-chaos-array + rotate: false + xy: 737, 1560 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 unit-icon-crawler rotate: false - xy: 1981, 1501 + xy: 1369, 708 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 unit-icon-dagger rotate: false - xy: 1981, 1451 + xy: 1369, 658 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 +unit-icon-eradicator + rotate: false + xy: 291, 240 + size: 152, 124 + orig: 152, 124 + offset: 0, 0 + index: -1 +unit-icon-eruptor + rotate: false + xy: 1381, 1132 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 unit-icon-fortress rotate: false - xy: 785, 1117 + xy: 1447, 1132 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 -unit-icon-ghoul - rotate: false - xy: 1112, 1975 - size: 72, 72 - orig: 72, 72 - offset: 0, 0 - index: -1 -unit-icon-phantom - rotate: false - xy: 653, 629 - size: 56, 56 - orig: 56, 56 - offset: 0, 0 - index: -1 -unit-icon-revenant - rotate: false - xy: 131, 360 - size: 112, 112 - orig: 112, 112 - offset: 0, 0 - index: -1 -unit-icon-spirit - rotate: false - xy: 1173, 1397 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 unit-icon-titan rotate: false - xy: 851, 1183 + xy: 1513, 1132 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 -unit-icon-wraith - rotate: false - xy: 1173, 1347 - size: 48, 48 - orig: 48, 48 - offset: 0, 0 - index: -1 -unloader-icon-full - rotate: false - xy: 1017, 844 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 -unloader-icon-medium - rotate: false - xy: 1017, 844 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 unloader-icon-large rotate: false - xy: 1223, 1401 + xy: 1369, 608 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 unloader-icon-small rotate: false - xy: 1047, 1030 + xy: 1763, 198 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 -vault-icon-full - rotate: false - xy: 555, 557 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 vault-icon-large rotate: false - xy: 1223, 1351 + xy: 1369, 558 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 vault-icon-medium rotate: false - xy: 1017, 810 + xy: 1625, 315 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 vault-icon-small rotate: false - xy: 1047, 1004 + xy: 1789, 198 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 +water-edge + rotate: false + xy: 291, 896 + size: 288, 96 + orig: 288, 96 + offset: 0, 0 + index: -1 water-extractor-icon-full rotate: false - xy: 983, 1315 + xy: 1645, 1132 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 water-extractor-icon-large rotate: false - xy: 1273, 1401 + xy: 1419, 817 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 water-extractor-icon-medium rotate: false - xy: 1017, 640 + xy: 1625, 281 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 water-extractor-icon-small rotate: false - xy: 1047, 978 + xy: 1815, 198 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 water-icon-large rotate: false - xy: 1273, 1351 + xy: 1419, 767 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 water-icon-small rotate: false - xy: 1047, 952 + xy: 1841, 198 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 +wave + rotate: false + xy: 1909, 1132 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 wave-icon-full rotate: false - xy: 785, 1051 + xy: 985, 1066 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 wave-icon-large rotate: false - xy: 1323, 1351 + xy: 1419, 717 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 wave-icon-medium rotate: false - xy: 949, 615 + xy: 1659, 315 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 wave-icon-small rotate: false - xy: 1047, 926 + xy: 1737, 174 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +white-tree-dead-icon-large + rotate: false + xy: 1419, 667 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +white-tree-dead-icon-medium + rotate: false + xy: 1625, 247 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +white-tree-dead-icon-small + rotate: false + xy: 1763, 172 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +white-tree-icon-large + rotate: false + xy: 1419, 617 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +white-tree-icon-medium + rotate: false + xy: 1659, 281 + size: 32, 32 + orig: 32, 32 + offset: 0, 0 + index: -1 +white-tree-icon-small + rotate: false + xy: 1789, 172 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 wraith-factory-icon-full rotate: false - xy: 917, 1183 + xy: 1117, 1066 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 wraith-factory-icon-large rotate: false - xy: 1373, 1351 + xy: 1469, 774 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 wraith-factory-icon-medium rotate: false - xy: 983, 606 + xy: 1625, 213 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 wraith-factory-icon-small rotate: false - xy: 1051, 900 + xy: 1815, 172 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 item-biomatter rotate: false - xy: 1483, 1257 + xy: 1183, 422 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 item-blast-compound rotate: false - xy: 1517, 1252 + xy: 1149, 354 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 item-coal rotate: false - xy: 1551, 1252 + xy: 1183, 388 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 item-copper rotate: false - xy: 1585, 1252 + xy: 1149, 320 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 item-graphite rotate: false - xy: 1619, 1252 + xy: 1183, 354 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 item-lead rotate: false - xy: 1653, 1252 + xy: 1149, 286 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 item-metaglass rotate: false - xy: 1687, 1252 + xy: 1183, 320 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 item-phase-fabric rotate: false - xy: 1721, 1252 + xy: 1149, 252 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 item-plastanium rotate: false - xy: 1755, 1252 + xy: 1183, 286 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 item-pyratite rotate: false - xy: 1789, 1252 + xy: 1149, 218 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 item-sand rotate: false - xy: 1823, 1252 + xy: 1183, 252 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 item-scrap rotate: false - xy: 1857, 1243 + xy: 1183, 218 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 item-silicon rotate: false - xy: 1891, 1243 + xy: 1217, 516 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 item-stone rotate: false - xy: 1993, 1218 + xy: 1285, 516 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 item-surge-alloy rotate: false - xy: 945, 1057 + xy: 1217, 482 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 item-thorium rotate: false - xy: 945, 1023 + xy: 1217, 448 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 item-titanium rotate: false - xy: 945, 989 + xy: 1251, 482 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 liquid-cryofluid rotate: false - xy: 464, 43 + xy: 1285, 414 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 liquid-oil rotate: false - xy: 566, 43 + xy: 1353, 456 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 liquid-slag rotate: false - xy: 430, 9 + xy: 1353, 422 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 liquid-water rotate: false - xy: 566, 9 + xy: 1285, 346 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 alpha-mech rotate: false - xy: 637, 475 + xy: 1774, 1082 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 alpha-mech-base rotate: false - xy: 637, 425 + xy: 1824, 1082 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 alpha-mech-leg rotate: false - xy: 637, 375 + xy: 1874, 1082 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 +chaos-array + rotate: false + xy: 291, 110 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 +chaos-array-base + rotate: false + xy: 323, 1245 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 +chaos-array-leg + rotate: false + xy: 323, 1115 + size: 128, 128 + orig: 128, 128 + offset: 0, 0 + index: -1 delta-mech rotate: false - xy: 529, 111 + xy: 1019, 800 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 delta-mech-base rotate: false - xy: 579, 161 + xy: 1019, 750 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 delta-mech-leg rotate: false - xy: 579, 111 + xy: 1069, 800 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 +eradicator + rotate: false + xy: 323, 1631 + size: 152, 124 + orig: 152, 124 + offset: 0, 0 + index: -1 +eradicator-base + rotate: false + xy: 291, 366 + size: 152, 124 + orig: 152, 124 + offset: 0, 0 + index: -1 +eradicator-leg + rotate: false + xy: 323, 1505 + size: 152, 124 + orig: 152, 124 + offset: 0, 0 + index: -1 omega-mech rotate: false - xy: 917, 1125 + xy: 1093, 1008 size: 56, 56 orig: 56, 56 offset: 0, 0 index: -1 omega-mech-armor rotate: false - xy: 983, 1191 + xy: 1496, 1074 size: 56, 56 orig: 56, 56 offset: 0, 0 index: -1 omega-mech-base rotate: false - xy: 1049, 1257 + xy: 1093, 950 size: 56, 56 orig: 56, 56 offset: 0, 0 index: -1 omega-mech-leg rotate: false - xy: 152, 8 + xy: 1151, 1008 size: 56, 56 orig: 56, 56 offset: 0, 0 index: -1 tau-mech rotate: false - xy: 653, 745 + xy: 1209, 1008 size: 56, 56 orig: 56, 56 offset: 0, 0 index: -1 tau-mech-base rotate: false - xy: 1981, 1701 + xy: 1785, 782 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 tau-mech-leg rotate: false - xy: 1781, 1451 + xy: 1835, 782 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 dart-ship rotate: false - xy: 479, 111 + xy: 1127, 850 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 glaive-ship rotate: false - xy: 1115, 1389 + xy: 421, 116 size: 56, 56 orig: 56, 56 offset: 0, 0 index: -1 javelin-ship rotate: false - xy: 1238, 1801 + xy: 1535, 924 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 javelin-ship-shield rotate: false - xy: 1338, 1801 + xy: 1635, 924 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 trident-ship rotate: false - xy: 653, 687 + xy: 1612, 1074 size: 56, 56 orig: 56, 56 offset: 0, 0 index: -1 blank rotate: false - xy: 258, 1828 + xy: 1749, 342 size: 1, 1 orig: 1, 1 offset: 0, 0 index: -1 circle rotate: false - xy: 1, 1758 + xy: 323, 1757 size: 201, 201 orig: 201, 201 offset: 0, 0 index: -1 clear rotate: false - xy: 1880, 1419 + xy: 1690, 278 size: 1, 1 orig: 1, 1 offset: 0, 0 index: -1 shape-3 rotate: false - xy: 87, 1 + xy: 1315, 1067 size: 63, 63 orig: 63, 63 offset: 0, 0 index: -1 bar rotate: false - xy: 983, 466 + xy: 2017, 534 size: 27, 36 split: 9, 9, 9, 9 orig: 27, 36 @@ -8687,7 +8260,7 @@ bar index: -1 bar-top rotate: false - xy: 923, 373 + xy: 1625, 141 size: 27, 36 split: 9, 10, 9, 10 orig: 27, 36 @@ -8695,7 +8268,7 @@ bar-top index: -1 button rotate: false - xy: 1731, 1422 + xy: 1469, 645 size: 36, 27 split: 12, 12, 12, 12 orig: 36, 27 @@ -8703,7 +8276,7 @@ button index: -1 button-down rotate: false - xy: 1423, 1380 + xy: 2011, 1633 size: 36, 27 split: 12, 12, 12, 12 orig: 36, 27 @@ -8711,7 +8284,7 @@ button-down index: -1 button-edge-1 rotate: false - xy: 1465, 1422 + xy: 2011, 1604 size: 36, 27 split: 12, 12, 12, 12 orig: 36, 27 @@ -8719,7 +8292,7 @@ button-edge-1 index: -1 button-edge-2 rotate: false - xy: 1423, 1351 + xy: 537, 11 size: 36, 27 split: 12, 12, 12, 12 orig: 36, 27 @@ -8727,7 +8300,7 @@ button-edge-2 index: -1 button-edge-3 rotate: false - xy: 1503, 1422 + xy: 1561, 795 size: 36, 27 split: 12, 12, 12, 12 orig: 36, 27 @@ -8735,7 +8308,7 @@ button-edge-3 index: -1 button-edge-4 rotate: false - xy: 1541, 1422 + xy: 1469, 703 size: 36, 27 split: 12, 12, 12, 12 orig: 36, 27 @@ -8743,7 +8316,7 @@ button-edge-4 index: -1 button-over rotate: false - xy: 1579, 1422 + xy: 575, 11 size: 36, 27 split: 12, 12, 12, 12 orig: 36, 27 @@ -8751,7 +8324,7 @@ button-over index: -1 button-right rotate: false - xy: 1693, 1422 + xy: 1637, 795 size: 36, 27 split: 12, 12, 12, 12 orig: 36, 27 @@ -8759,7 +8332,7 @@ button-right index: -1 button-right-down rotate: false - xy: 1617, 1422 + xy: 1599, 795 size: 36, 27 split: 12, 12, 12, 12 orig: 36, 27 @@ -8767,7 +8340,7 @@ button-right-down index: -1 button-right-over rotate: false - xy: 1655, 1422 + xy: 1469, 674 size: 36, 27 split: 12, 12, 12, 12 orig: 36, 27 @@ -8775,7 +8348,7 @@ button-right-over index: -1 button-select rotate: false - xy: 949, 307 + xy: 1783, 458 size: 24, 24 split: 4, 4, 4, 4 orig: 24, 24 @@ -8783,42 +8356,42 @@ button-select index: -1 check-off rotate: false - xy: 2016, 1388 + xy: 553, 472 size: 28, 32 orig: 28, 32 offset: 0, 0 index: -1 check-on rotate: false - xy: 2016, 1354 + xy: 2019, 1366 size: 28, 32 orig: 28, 32 offset: 0, 0 index: -1 check-on-over rotate: false - xy: 1074, 1129 + xy: 2019, 1332 size: 28, 32 orig: 28, 32 offset: 0, 0 index: -1 check-over rotate: false - xy: 1104, 1129 + xy: 1625, 179 size: 28, 32 orig: 28, 32 offset: 0, 0 index: -1 clear rotate: false - xy: 741, 575 + xy: 931, 1286 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 content-background rotate: false - xy: 1845, 1422 + xy: 1713, 795 size: 36, 27 split: 12, 12, 12, 12 orig: 36, 27 @@ -8826,7 +8399,7 @@ content-background index: -1 content-background-locked rotate: false - xy: 1769, 1422 + xy: 1675, 795 size: 36, 27 split: 12, 12, 12, 12 orig: 36, 27 @@ -8834,7 +8407,7 @@ content-background-locked index: -1 content-background-over rotate: false - xy: 1807, 1422 + xy: 1469, 616 size: 36, 27 split: 12, 12, 12, 12 orig: 36, 27 @@ -8842,875 +8415,882 @@ content-background-over index: -1 cursor rotate: false - xy: 1101, 1251 + xy: 421, 110 size: 4, 4 orig: 4, 4 offset: 0, 0 index: -1 discord-banner rotate: false - xy: 582, 2002 + xy: 845, 1251 size: 84, 45 orig: 84, 45 offset: 0, 0 index: -1 empty-sector rotate: false - xy: 753, 553 + xy: 1081, 370 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 icon-crafting rotate: false - xy: 2031, 1747 + xy: 2031, 220 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-defense rotate: false - xy: 2031, 1729 + xy: 2031, 202 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-distribution rotate: false - xy: 2031, 1711 + xy: 2031, 184 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-effect rotate: false - xy: 2031, 1693 + xy: 2031, 166 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-liquid rotate: false - xy: 2031, 1531 + xy: 945, 184 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-power rotate: false - xy: 853, 965 + xy: 1567, 82 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-production rotate: false - xy: 2027, 1336 + xy: 1567, 64 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-turret rotate: false - xy: 2027, 1300 + xy: 2024, 1074 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-units rotate: false - xy: 57, 3 + xy: 2024, 1038 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-upgrade rotate: false - xy: 1051, 828 + xy: 1732, 138 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 controller-cursor rotate: false - xy: 787, 325 + xy: 453, 636 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-about rotate: false - xy: 245, 572 + xy: 437, 1099 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-add rotate: false - xy: 637, 541 + xy: 445, 240 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-admin rotate: false - xy: 637, 525 + xy: 1469, 851 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-admin-small rotate: false - xy: 660, 1994 + xy: 837, 930 size: 6, 6 orig: 6, 6 offset: 0, 0 index: -1 icon-areaDelete rotate: false - xy: 582, 1990 + xy: 919, 1239 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-arrow rotate: false - xy: 813, 53 + xy: 795, 392 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-arrow-16 rotate: false - xy: 813, 53 + xy: 795, 392 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-arrow-down rotate: false - xy: 75, 9 + xy: 997, 1271 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-arrow-left rotate: false - xy: 1051, 640 + xy: 985, 1205 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-arrow-right rotate: false - xy: 582, 1978 + xy: 1987, 1252 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-arrow-up rotate: false - xy: 582, 1966 + xy: 1975, 1186 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-back rotate: false - xy: 770, 1 + xy: 969, 9 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-ban rotate: false - xy: 613, 95 + xy: 623, 922 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-break rotate: false - xy: 788, 1 + xy: 471, 636 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-cancel rotate: false - xy: 806, 1 + xy: 489, 636 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-cancel-2 rotate: false - xy: 1001, 225 + xy: 1965, 406 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 icon-chat rotate: false - xy: 779, 921 + xy: 639, 636 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-check rotate: false - xy: 2031, 1783 + xy: 2031, 256 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-check-2 rotate: false - xy: 1001, 199 + xy: 1991, 406 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 icon-copy rotate: false - xy: 2031, 1765 + xy: 2031, 238 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-cursor rotate: false - xy: 791, 921 + xy: 1597, 725 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-dev-builds rotate: false - xy: 1837, 1218 + xy: 2013, 982 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-discord rotate: false - xy: 613, 79 + xy: 1453, 551 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-donate rotate: false - xy: 1221, 1259 + xy: 437, 1083 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-dots rotate: false - xy: 803, 943 + xy: 461, 240 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-editor rotate: false - xy: 993, 1133 + xy: 1469, 835 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-egg rotate: false - xy: 974, 8 + xy: 623, 906 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-elevation rotate: false - xy: 2031, 1675 + xy: 453, 1487 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-eraser rotate: false - xy: 2031, 1657 + xy: 845, 1444 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-exit rotate: false - xy: 853, 949 + xy: 1073, 14 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-file rotate: false - xy: 2031, 1639 + xy: 1009, 1331 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-file-image rotate: false - xy: 2031, 1621 + xy: 813, 656 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-file-text rotate: false - xy: 1051, 812 + xy: 2029, 982 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-fill rotate: false - xy: 2031, 1603 + xy: 477, 1695 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-floppy rotate: false - xy: 2027, 1248 + xy: 2032, 2032 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-floppy-16 rotate: false - xy: 2031, 1585 + xy: 613, 22 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-folder rotate: false - xy: 1051, 796 + xy: 1603, 109 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-folder-parent rotate: false - xy: 2027, 1232 + xy: 1585, 91 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-generated rotate: false - xy: 629, 75 + xy: 1463, 974 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 icon-github rotate: false - xy: 1051, 780 + xy: 2032, 2016 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-google-play rotate: false - xy: 2027, 1216 + xy: 1585, 75 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-grid rotate: false - xy: 2031, 1567 + xy: 1579, 719 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-hold rotate: false - xy: 819, 921 + xy: 845, 1396 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-holdDelete rotate: false - xy: 831, 921 + xy: 857, 1396 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-home rotate: false - xy: 1051, 764 + xy: 2032, 2000 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-host rotate: false - xy: 2027, 1200 + xy: 1585, 59 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-info rotate: false - xy: 1051, 748 + xy: 2032, 1984 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-itch.io rotate: false - xy: 2027, 1184 + xy: 1585, 43 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-item rotate: false - xy: 843, 921 + xy: 2037, 1220 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-items-none rotate: false - xy: 273, 66 + xy: 526, 1950 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-line rotate: false - xy: 2031, 1549 + xy: 1387, 540 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-link rotate: false - xy: 1051, 732 + xy: 2032, 1968 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-liquid-small rotate: false - xy: 855, 921 + xy: 919, 1227 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-load rotate: false - xy: 2027, 1168 + xy: 1585, 27 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-load-image rotate: false - xy: 2031, 1513 + xy: 1567, 118 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-load-map rotate: false - xy: 2031, 1495 + xy: 1841, 180 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-loading rotate: false - xy: 2031, 1477 + xy: 453, 1469 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-locked rotate: false - xy: 2031, 1459 + xy: 845, 1426 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-logic rotate: false - xy: 1063, 640 + xy: 1987, 1240 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-map rotate: false - xy: 1051, 716 + xy: 2032, 1952 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-menu rotate: false - xy: 594, 1832 + xy: 651, 636 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-menu-large rotate: false - xy: 204, 1759 + xy: 495, 1695 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-missing rotate: false - xy: 1143, 1219 + xy: 2037, 1208 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-mission-background rotate: false - xy: 1, 1 + xy: 1579, 737 size: 18, 18 orig: 18, 18 offset: 0, 0 index: -1 icon-mission-battle rotate: false - xy: 1048, 602 + xy: 663, 636 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-mission-defense rotate: false - xy: 824, 7 + xy: 2037, 1196 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-mission-done rotate: false - xy: 245, 560 + xy: 2037, 1184 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-none rotate: false - xy: 606, 1832 + xy: 1751, 162 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-paste rotate: false - xy: 636, 1852 + xy: 963, 184 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-pause rotate: false - xy: 1060, 602 + xy: 1, 2 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-pencil rotate: false - xy: 975, 1131 + xy: 1567, 100 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-pencil-small rotate: false - xy: 2027, 1152 + xy: 1585, 11 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-pick rotate: false - xy: 1837, 1234 + xy: 845, 1408 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-play rotate: false - xy: 618, 1832 + xy: 1625, 521 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-play-2 rotate: false - xy: 1051, 700 + xy: 1643, 724 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +icon-play-custom + rotate: false + xy: 613, 6 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-players rotate: false - xy: 210, 4 + xy: 2022, 1664 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-power-small rotate: false - xy: 222, 4 + xy: 795, 380 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-quit rotate: false - xy: 2027, 1136 + xy: 1395, 7 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-redo rotate: false - xy: 949, 81 + xy: 1567, 46 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-refresh rotate: false - xy: 1051, 684 + xy: 1411, 7 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-rename rotate: false - xy: 2027, 1120 + xy: 1427, 7 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-resize rotate: false - xy: 1051, 882 + xy: 1567, 28 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-rotate rotate: false - xy: 1051, 668 + xy: 1443, 7 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-rotate-arrow rotate: false - xy: 2027, 1104 + xy: 1459, 5 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-rotate-left rotate: false - xy: 1051, 652 + xy: 1841, 164 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-rotate-right rotate: false - xy: 2027, 1088 + xy: 1859, 182 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-save rotate: false - xy: 2027, 1072 + xy: 1089, 6 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-save-image rotate: false - xy: 21, 3 + xy: 1567, 10 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-save-map rotate: false - xy: 222, 1759 + xy: 2025, 1164 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-settings rotate: false - xy: 234, 4 + xy: 813, 644 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-spray rotate: false - xy: 2027, 1318 + xy: 2025, 1146 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-terrain rotate: false - xy: 1051, 864 + xy: 2025, 1128 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-tools rotate: false - xy: 2027, 1056 + xy: 1105, 6 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-touch rotate: false - xy: 246, 4 + xy: 825, 644 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-touchDelete rotate: false - xy: 636, 1840 + xy: 1405, 546 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 icon-trash rotate: false - xy: 1009, 1131 + xy: 1732, 122 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-trash-16 rotate: false - xy: 39, 3 + xy: 2024, 1110 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-tree rotate: false - xy: 240, 1759 + xy: 2024, 1092 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-tree-locked rotate: false - xy: 1381, 1283 + xy: 1149, 456 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 icon-trello rotate: false - xy: 1025, 1131 + xy: 1729, 106 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-tutorial rotate: false - xy: 803, 927 + xy: 1875, 192 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-undo rotate: false - xy: 1051, 846 + xy: 2024, 1056 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-unlocked rotate: false - xy: 2027, 1282 + xy: 1733, 156 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-unlocks rotate: false - xy: 819, 933 + xy: 1875, 176 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-wiki rotate: false - xy: 835, 933 + xy: 1859, 166 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 icon-zone rotate: false - xy: 1001, 173 + xy: 2017, 430 size: 24, 24 orig: 24, 24 offset: 0, 0 index: -1 icon-zone-locked rotate: false - xy: 229, 66 + xy: 477, 1713 size: 42, 42 orig: 42, 42 offset: 0, 0 index: -1 icon-zoom rotate: false - xy: 2027, 1264 + xy: 1585, 107 size: 16, 16 orig: 16, 16 offset: 0, 0 index: -1 icon-zoom-small rotate: false - xy: 851, 933 + xy: 1875, 160 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 info-banner rotate: false - xy: 1, 21 + xy: 943, 1349 size: 84, 45 orig: 84, 45 offset: 0, 0 index: -1 inventory rotate: false - xy: 1001, 105 + xy: 1463, 99 size: 24, 40 split: 10, 10, 10, 14 orig: 24, 40 @@ -9718,14 +9298,14 @@ inventory index: -1 logotext rotate: false - xy: 1, 1961 + xy: 1, 1960 size: 579, 86 orig: 579, 86 offset: 0, 0 index: -1 pane rotate: false - xy: 1997, 1422 + xy: 1637, 766 size: 36, 27 split: 12, 12, 12, 12 orig: 36, 27 @@ -9733,7 +9313,7 @@ pane index: -1 pane-2 rotate: false - xy: 1959, 1422 + xy: 1599, 766 size: 36, 27 split: 12, 12, 12, 12 orig: 36, 27 @@ -9741,7 +9321,7 @@ pane-2 index: -1 scroll rotate: false - xy: 1131, 79 + xy: 1901, 239 size: 24, 35 split: 10, 10, 6, 5 orig: 24, 35 @@ -9749,7 +9329,7 @@ scroll index: -1 scroll-horizontal rotate: false - xy: 1503, 1396 + xy: 1637, 740 size: 35, 24 split: 6, 5, 10, 10 orig: 35, 24 @@ -9757,7 +9337,7 @@ scroll-horizontal index: -1 scroll-knob-horizontal-black rotate: false - xy: 594, 1844 + xy: 639, 648 size: 40, 24 split: 11, 10, 10, 10 orig: 40, 24 @@ -9765,71 +9345,64 @@ scroll-knob-horizontal-black index: -1 scroll-knob-vertical-black rotate: false - xy: 1131, 116 + xy: 1875, 234 size: 24, 40 split: 10, 10, 6, 10 orig: 24, 40 offset: 0, 0 index: -1 -sector-edge - rotate: false - xy: 847, 751 - size: 32, 32 - orig: 32, 32 - offset: 0, 0 - index: -1 sector-select rotate: false - xy: 847, 717 + xy: 1421, 431 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 selection rotate: false - xy: 1497, 1215 + xy: 1651, 138 size: 1, 1 orig: 1, 1 offset: 0, 0 index: -1 slider rotate: false - xy: 949, 363 + xy: 1729, 122 size: 1, 8 orig: 1, 8 offset: 0, 0 index: -1 slider-knob rotate: false - xy: 1043, 1141 + xy: 2017, 674 size: 29, 38 orig: 29, 38 offset: 0, 0 index: -1 slider-knob-down rotate: false - xy: 1017, 600 + xy: 1659, 241 size: 29, 38 orig: 29, 38 offset: 0, 0 index: -1 slider-knob-over rotate: false - xy: 1017, 600 + xy: 1659, 241 size: 29, 38 orig: 29, 38 offset: 0, 0 index: -1 slider-vertical rotate: false - xy: 1503, 1393 + xy: 931, 1283 size: 8, 1 orig: 8, 1 offset: 0, 0 index: -1 underline rotate: false - xy: 1465, 1393 + xy: 1599, 737 size: 36, 27 split: 12, 12, 12, 12 orig: 36, 27 @@ -9837,7 +9410,7 @@ underline index: -1 underline-2 rotate: false - xy: 1157, 1242 + xy: 1469, 549 size: 36, 27 split: 12, 12, 12, 12 orig: 36, 27 @@ -9845,14 +9418,14 @@ underline-2 index: -1 white rotate: false - xy: 2044, 2044 + xy: 1685, 236 size: 3, 3 orig: 3, 3 offset: 0, 0 index: -1 window-empty rotate: false - xy: 1013, 537 + xy: 1723, 345 size: 27, 61 split: 8, 8, 44, 11 orig: 27, 61 @@ -9860,203 +9433,280 @@ window-empty index: -1 alpha-drone rotate: false - xy: 653, 525 + xy: 1724, 1082 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 crawler rotate: false - xy: 529, 311 + xy: 495, 406 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 crawler-base rotate: false - xy: 379, 111 + xy: 445, 306 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 crawler-leg rotate: false - xy: 429, 161 + xy: 495, 356 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 dagger rotate: false - xy: 429, 111 + xy: 487, 206 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 dagger-base rotate: false - xy: 479, 161 + xy: 487, 156 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 dagger-leg rotate: false - xy: 579, 261 + xy: 1077, 850 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 +eruptor + rotate: false + xy: 1471, 1264 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +eruptor-base + rotate: false + xy: 1537, 1264 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 +eruptor-leg + rotate: false + xy: 1603, 1264 + size: 64, 64 + orig: 64, 64 + offset: 0, 0 + index: -1 fortress rotate: false - xy: 1188, 1851 + xy: 1669, 1264 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 fortress-base rotate: false - xy: 1254, 1851 + xy: 1735, 1264 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 titan-base rotate: false - xy: 1254, 1851 + xy: 1735, 1264 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 fortress-leg rotate: false - xy: 1320, 1851 + xy: 1801, 1264 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 ghoul rotate: false - xy: 742, 1975 + xy: 845, 1177 size: 72, 72 orig: 72, 72 offset: 0, 0 index: -1 +lich + rotate: false + xy: 291, 654 + size: 216, 240 + orig: 216, 240 + offset: 0, 0 + index: -1 phantom rotate: false - xy: 1115, 1331 + xy: 1554, 1074 size: 56, 56 orig: 56, 56 offset: 0, 0 index: -1 power-cell rotate: false - xy: 653, 803 + xy: 1151, 950 size: 56, 56 orig: 56, 56 offset: 0, 0 index: -1 +reaper + rotate: false + xy: 1, 1638 + size: 320, 320 + orig: 320, 320 + offset: 0, 0 + index: -1 revenant rotate: false - xy: 131, 474 + xy: 323, 1001 size: 112, 112 orig: 112, 112 offset: 0, 0 index: -1 spirit rotate: false - xy: 1781, 1551 + xy: 1913, 982 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 titan rotate: false - xy: 719, 1117 + xy: 985, 1132 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 titan-leg rotate: false - xy: 785, 1183 + xy: 1051, 1132 size: 64, 64 orig: 64, 64 offset: 0, 0 index: -1 wraith rotate: false - xy: 1373, 1401 + xy: 1419, 567 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 artillery-equip rotate: false - xy: 229, 260 - size: 48, 48 - orig: 48, 48 + xy: 1267, 1008 + size: 48, 56 + orig: 48, 56 offset: 0, 0 index: -1 blaster-equip rotate: false - xy: 379, 311 + xy: 969, 728 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 bomber-equip rotate: false - xy: 279, 161 + xy: 969, 678 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 missiles-equip rotate: false - xy: 279, 161 + xy: 969, 678 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 chain-blaster-equip rotate: false - xy: 429, 311 + xy: 1135, 900 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 +chaos-equip + rotate: false + xy: 977, 928 + size: 56, 136 + orig: 56, 136 + offset: 0, 0 + index: -1 +eradication-equip + rotate: false + xy: 453, 1268 + size: 96, 192 + orig: 96, 192 + offset: 0, 0 + index: -1 +eruption-equip + rotate: false + xy: 1169, 692 + size: 48, 56 + orig: 48, 56 + offset: 0, 0 + index: -1 flakgun-equip rotate: false - xy: 637, 325 + xy: 1019, 650 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 flamethrower-equip rotate: false - xy: 687, 325 - size: 48, 48 - orig: 48, 48 + xy: 1069, 642 + size: 48, 56 + orig: 48, 56 offset: 0, 0 index: -1 heal-blaster-equip rotate: false - xy: 729, 225 + xy: 1517, 1024 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +lich-missiles-equip + rotate: false + xy: 545, 390 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +reaper-gun-equip + rotate: false + xy: 1227, 850 + size: 48, 48 + orig: 48, 48 + offset: 0, 0 + index: -1 +revenant-missiles-equip + rotate: false + xy: 1219, 600 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 shockgun-equip rotate: false - xy: 1781, 1651 + xy: 1724, 1032 size: 48, 48 orig: 48, 48 offset: 0, 0 index: -1 swarmer-equip rotate: false - xy: 1781, 1501 + xy: 1985, 932 size: 48, 48 orig: 48, 48 offset: 0, 0 diff --git a/core/assets/sprites/sprites.png b/core/assets/sprites/sprites.png index 186fe61020..a2b60390dd 100644 Binary files a/core/assets/sprites/sprites.png and b/core/assets/sprites/sprites.png differ diff --git a/core/assets/sprites/uiskin.json b/core/assets/sprites/uiskin.json index 3006ee32f2..507f97942b 100644 --- a/core/assets/sprites/uiskin.json +++ b/core/assets/sprites/uiskin.json @@ -1,81 +1,308 @@ { -Color: { - black: {a: 1, b: 0, g: 0, r: 0 }, - white: {a: 1, b: 1, g: 1, r: 1 }, - gray: {a: 1, b: 0.32, g: 0.32, r: 0.32 }, - lightgray: {a: 1, b: 0.65, g: 0.65, r: 0.65 } - orange: {hex: "FFA500"}, - accent: {hex: "ffd37f"} -}, -TintedDrawable: { - dialogDim: {name: white, color: {r: 0, g: 0, b: 0, a: 0.9} }, - invis: {name: white, color: {r: 0, g: 0, b: 0, a: 0} } - loadDim: {name: white, color: {r: 0, g: 0, b: 0, a: 0.8} }, - chatfield: {name: white, color: {r: 0, g: 0, b: 0, a: 0.2}}, - dark: {name: white, color: {hex: "#000000ff"}}, - none: {name: white, color: {r: 0, g: 0, b: 0, a: 0}}, - flat: {name: white, color: {r: 0.0, g: 0.0, b: 0.0, a: 0.6}}, - flat-over: {name: white, color: { hex: "#ffffff82" }}, - flat-down: {name: white, color: { hex: "#ffd37fff" }} -}, -ButtonStyle: { - default: {down: button-down, up: button }, - toggle: {checked: button-down, down: button-down, up: button } -}, -TextButtonStyle: { - default: {over: button-over, disabled: button, font: default-font, fontColor: white, disabledFontColor: gray, down: button-down, up: button}, - node: {disabled: content-background, font: default-font, fontColor: white, disabledFontColor: gray, up: content-background, over: content-background-over}, - right: {over: button-right-over, font: default-font, fontColor: white, disabledFontColor: gray, down: button-right-down, up: button-right}, - wave: {font: default-font, fontColor: white, disabledFontColor: gray, up: button-edge-4}, - clear: {over: flat-over, font: default-font, fontColor: white, disabledFontColor: gray, down: flat-over, up: flat}, - discord: {font: default-font, fontColor: white, up: discord-banner}, - info: {font: default-font, fontColor: white, up: info-banner}, - clear-partial: {down: white, up: button-select, over: flat-down, font: default-font, fontColor: white, disabledFontColor: gray }, - clear-partial-2: {down: flat-over, up: none, over: flat-over, font: default-font, fontColor: white, disabledFontColor: gray }, - empty: {font: default-font}, - clear-toggle: {font: default-font, fontColor: white, checked: flat-down, down: flat-down, up: flat, over: flat-over, disabled: flat, disabledFontColor: gray } - toggle: {font: default-font, fontColor: white, checked: button-down, down: button-down, up: button, over: button-over, disabled: button, disabledFontColor: gray } -}, -ImageButtonStyle: { - default: {down: button-down, up: button, over: button-over, imageDisabledColor: gray, imageUpColor: white }, - node: {up: content-background, over: content-background-over}, - right: {over: button-right-over, down: button-right-down, up: button-right}, - empty: { imageDownColor: accent, imageUpColor: white}, - emptytoggle: {imageCheckedColor: white, imageDownColor: white, imageUpColor: gray}, - static: {up: button }, - static-down: {up: button-down }, - toggle: {checked: button-down, down: button-down, up: button, imageDisabledColor: gray, imageUpColor: white }, - select: {checked: button-select, up: none }, - clear: {down: flat-over, up: flat, over: flat-over}, - clear-full: {down: white, up: button-select, over: flat-down}, - clear-partial: {down: flat-down, up: none, over: flat-over}, - clear-toggle: {down: flat-down, checked: flat-down, up: flat, over: flat-over}, - clear-toggle-partial: {down: flat-down, checked: flat-down, up: none, over: flat-over}, -}, -ScrollPaneStyle: { - default: {vScroll: scroll, vScrollKnob: scroll-knob-vertical-black}, - horizontal: {vScroll: scroll, vScrollKnob: scroll-knob-vertical-black, hScroll: scroll-horizontal, hScrollKnob: scroll-knob-horizontal-black}, -}, -WindowStyle: { - default: {titleFont: default-font, titleFontColor: accent }, - dialog: {stageBackground: dialogDim, titleFont: default-font, background: window-empty, titleFontColor: accent } -}, -KeybindDialogStyle: { - default: {keyColor: accent, keyNameColor: white, controllerColor: lightgray}, -}, -SliderStyle: { - default-horizontal: {background: slider, knob: slider-knob, knobOver: slider-knob-over, knobDown: slider-knob-down}, - default-vertical: {background: slider-vertical, knob: slider-knob, knobOver: slider-knob-over, knobDown: slider-knob-down} -}, -LabelStyle: { - default: {font: default-font, fontColor: white }, - small: {font: default-font, fontColor: white } -}, -TextFieldStyle: { - default: {font: default-font-chat, fontColor: white, disabledFontColor: gray, selection: selection, background: underline, cursor: cursor, messageFont: default-font, messageFontColor: gray } - textarea: {font: default-font-chat, fontColor: white, disabledFontColor: gray, selection: selection, background: underline, cursor: cursor, messageFont: default-font, messageFontColor: gray } -}, -CheckBoxStyle: { - default: {checkboxOn: check-on, checkboxOff: check-off, checkboxOnOver: check-on-over, checkboxOver: check-over, font: default-font, fontColor: white, disabledFontColor: gray } -} + Color: { + black: { a: 1, b: 0, g: 0, r: 0 }, + white: { a: 1, b: 1, g: 1, r: 1 }, + gray: { a: 1, b: 0.32, g: 0.32, r: 0.32 }, + lightgray: { a: 1, b: 0.65, g: 0.65, r: 0.65 } + orange: { hex: "FFA500" }, + accent: { hex: "ffd37f" } + }, + TintedDrawable: { + dialogDim: { + name: white, + color: { r: 0, g: 0, b: 0, a: 0.9 } + }, + invis: { + name: white, + color: { r: 0, g: 0, b: 0, a: 0 } + } + loadDim: { + name: white, + color: { r: 0, g: 0, b: 0, a: 0.8 } + }, + chatfield: { + name: white, + color: { r: 0, g: 0, b: 0, a: 0.2 } + }, + dark: { + name: white, + color: { hex: "#000000ff" } + }, + none: { + name: white, + color: { r: 0, g: 0, b: 0, a: 0 } + }, + flat: { + name: white, + color: { r: 0.0, g: 0.0, b: 0.0, a: 0.6 } + }, + flat-over: { + name: white, + color: { hex: "#ffffff82" } + }, + flat-down: { + name: white, + color: { hex: "#ffd37fff" } + } + }, + ButtonStyle: { + default: { + down: button-down, + up: button + }, + toggle: { + checked: button-down, + down: button-down, + up: button + } + }, + TextButtonStyle: { + default: { + over: button-over, + disabled: button, + font: default-font, + fontColor: white, + disabledFontColor: gray, + down: button-down, + up: button + }, + node: { + disabled: content-background-locked, + font: default-font, + fontColor: white, + disabledFontColor: gray, + up: content-background, + over: content-background-over + }, + right: { + over: button-right-over, + font: default-font, + fontColor: white, + disabledFontColor: gray, + down: button-right-down, + up: button-right + }, + wave: { + font: default-font, + fontColor: white, + disabledFontColor: gray, + up: button-edge-4 + }, + clear: { + over: flat-over, + font: default-font, + fontColor: white, + disabledFontColor: gray, + down: flat-over, + up: flat + }, + discord: { + font: default-font, + fontColor: white, + up: discord-banner + }, + info: { + font: default-font, + fontColor: white, + up: info-banner + }, + clear-partial: { + down: white, + up: button-select, + over: flat-down, + font: default-font, + fontColor: white, + disabledFontColor: gray + }, + clear-partial-2: { + down: flat-over, + up: none, + over: flat-over, + font: default-font, + fontColor: white, + disabledFontColor: gray + }, + empty: { + font: default-font + }, + clear-toggle: { + font: default-font, + fontColor: white, + checked: flat-down, + down: flat-down, + up: flat, + over: flat-over, + disabled: flat, + disabledFontColor: gray + } + toggle: { + font: default-font, + fontColor: white, + checked: button-down, + down: button-down, + up: button, + over: button-over, + disabled: button, + disabledFontColor: gray + } + }, + ImageButtonStyle: { + default: { + down: button-down, + up: button, + over: button-over, + imageDisabledColor: gray, + imageUpColor: white + }, + node: { + up: content-background, + over: content-background-over + }, + right: { + over: button-right-over, + down: button-right-down, + up: button-right + }, + empty: { + imageDownColor: accent, + imageUpColor: white + }, + emptytoggle: { + imageCheckedColor: white, + imageDownColor: white, + imageUpColor: gray + }, + static: { + up: button + }, + static-down: { + up: button-down + }, + toggle: { + checked: button-down, + down: button-down, + up: button, + imageDisabledColor: gray, + imageUpColor: white + }, + select: { + checked: button-select, + up: none + }, + clear: { + down: flat-over, + up: flat, + over: flat-over + }, + clear-full: { + down: white, + up: button-select, + over: flat-down + }, + clear-partial: { + down: flat-down, + up: none, + over: flat-over + }, + clear-toggle: { + down: flat-down, + checked: flat-down, + up: flat, + over: flat-over + }, + clear-toggle-partial: { + down: flat-down, + checked: flat-down, + up: none, + over: flat-over + }, + }, + ScrollPaneStyle: { + default: { + vScroll: scroll, + vScrollKnob: scroll-knob-vertical-black + }, + horizontal: { + vScroll: scroll, + vScrollKnob: scroll-knob-vertical-black, + hScroll: scroll-horizontal, + hScrollKnob: scroll-knob-horizontal-black + }, + }, + WindowStyle: { + default: { + titleFont: default-font, + titleFontColor: accent + }, + dialog: { + stageBackground: dialogDim, + titleFont: default-font, + background: window-empty, + titleFontColor: accent + } + }, + KeybindDialogStyle: { + default: { + keyColor: accent, + keyNameColor: white, + controllerColor: lightgray + }, + }, + SliderStyle: { + default-horizontal: { + background: slider, + knob: slider-knob, + knobOver: slider-knob-over, + knobDown: slider-knob-down + }, + default-vertical: { + background: slider-vertical, + knob: slider-knob, + knobOver: slider-knob-over, + knobDown: slider-knob-down + } + }, + LabelStyle: { + default: { + font: default-font, + fontColor: white + }, + small: { + font: default-font, + fontColor: white + } + }, + TextFieldStyle: { + default: { + font: default-font-chat, + fontColor: white, + disabledFontColor: gray, + selection: selection, + background: underline, + cursor: cursor, + messageFont: default-font, + messageFontColor: gray + } + textarea: { + font: default-font-chat, + fontColor: white, + disabledFontColor: gray, + selection: selection, + background: underline, + cursor: cursor, + messageFont: default-font, + messageFontColor: gray + } + }, + CheckBoxStyle: { + default: { + checkboxOn: check-on, + checkboxOff: check-off, + checkboxOnOver: check-on-over, + checkboxOver: check-over, + font: default-font, + fontColor: white, + disabledFontColor: gray + } + } } diff --git a/core/build.gradle b/core/build.gradle index f4c5695bbb..abcec6d8f6 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -1,8 +1,4 @@ apply plugin: "java" sourceCompatibility = 1.8 [compileJava, compileTestJava]*.options*.encoding = 'UTF-8' -sourceSets.main.java.srcDirs = ["src/"] - -compileJava{ - options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation" -} \ No newline at end of file +sourceSets.main.java.srcDirs = ["src/"] \ No newline at end of file diff --git a/core/src/io/anuke/mindustry/Mindustry.java b/core/src/io/anuke/mindustry/Mindustry.java index c00058a403..c4a571ef1e 100644 --- a/core/src/io/anuke/mindustry/Mindustry.java +++ b/core/src/io/anuke/mindustry/Mindustry.java @@ -27,6 +27,7 @@ public class Mindustry extends ApplicationCore{ Log.setUseColors(false); BundleLoader.load(); content.load(); + content.loadColors(); add(logic = new Logic()); add(world = new World()); @@ -47,18 +48,18 @@ public class Mindustry extends ApplicationCore{ @Override public void update(){ - long lastFrameTime = Time.millis(); + long lastFrameTime = Time.nanos(); super.update(); int fpsCap = Core.settings.getInt("fpscap", 125); if(fpsCap <= 120){ - long target = 1000/fpsCap; - long elapsed = Time.timeSinceMillis(lastFrameTime); + long target = (1000 * 1000000)/fpsCap; //target in nanos + long elapsed = Time.timeSinceNanos(lastFrameTime); if(elapsed < target){ try{ - Thread.sleep(target - elapsed); + Thread.sleep((target - elapsed) / 1000000, (int)((target - elapsed) % 1000000)); }catch(InterruptedException e){ e.printStackTrace(); } diff --git a/core/src/io/anuke/mindustry/Vars.java b/core/src/io/anuke/mindustry/Vars.java index 5164fd56ae..cade7d56df 100644 --- a/core/src/io/anuke/mindustry/Vars.java +++ b/core/src/io/anuke/mindustry/Vars.java @@ -2,21 +2,21 @@ package io.anuke.mindustry; import io.anuke.arc.Application.ApplicationType; import io.anuke.arc.Core; -import io.anuke.arc.entities.Entities; -import io.anuke.arc.entities.EntityGroup; -import io.anuke.arc.entities.impl.EffectEntity; -import io.anuke.arc.entities.trait.DrawTrait; +import io.anuke.mindustry.entities.Entities; +import io.anuke.mindustry.entities.EntityGroup; +import io.anuke.mindustry.entities.impl.EffectEntity; +import io.anuke.mindustry.entities.traits.DrawTrait; import io.anuke.arc.files.FileHandle; import io.anuke.arc.graphics.Color; import io.anuke.arc.util.Structs; import io.anuke.mindustry.core.*; -import io.anuke.mindustry.entities.Player; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.Player; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.entities.bullet.Bullet; import io.anuke.mindustry.entities.effect.Fire; import io.anuke.mindustry.entities.effect.Puddle; import io.anuke.mindustry.entities.traits.SyncTrait; -import io.anuke.mindustry.entities.units.BaseUnit; +import io.anuke.mindustry.entities.type.BaseUnit; import io.anuke.mindustry.game.GlobalData; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.game.Version; @@ -51,6 +51,10 @@ public class Vars{ public static final int maxNameLength = 40; /**displayed item size when ingame, TODO remove.*/ public static final float itemSize = 5f; + /**extra padding around the world; units outside this bound will begin to self-destruct.*/ + public static final float worldBounds = 100f; + /**ticks spent out of bound until self destruct.*/ + public static final float boundsCountdown = 60*7; /**size of tiles in units*/ public static final int tilesize = 8; /**all choosable player colors in join/host dialog*/ diff --git a/core/src/io/anuke/mindustry/ai/BlockIndexer.java b/core/src/io/anuke/mindustry/ai/BlockIndexer.java index 6f5e840dcf..b20ef572a8 100644 --- a/core/src/io/anuke/mindustry/ai/BlockIndexer.java +++ b/core/src/io/anuke/mindustry/ai/BlockIndexer.java @@ -6,7 +6,7 @@ import io.anuke.arc.function.Predicate; import io.anuke.arc.math.Mathf; import io.anuke.arc.math.geom.Geometry; import io.anuke.mindustry.content.Blocks; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.game.EventType.TileChangeEvent; import io.anuke.mindustry.game.EventType.WorldLoadEvent; import io.anuke.mindustry.game.Team; @@ -215,7 +215,7 @@ public class BlockIndexer{ } private void process(Tile tile){ - if(tile.block().flags != null && + if(tile.block().flags.size() > 0 && tile.getTeam() != Team.none){ ObjectSet[] map = getFlagged(tile.getTeam()); diff --git a/core/src/io/anuke/mindustry/ai/Pathfinder.java b/core/src/io/anuke/mindustry/ai/Pathfinder.java index 2f27133d89..024d83ed4a 100644 --- a/core/src/io/anuke/mindustry/ai/Pathfinder.java +++ b/core/src/io/anuke/mindustry/ai/Pathfinder.java @@ -128,7 +128,7 @@ public class Pathfinder{ for(int y = 0; y < world.height(); y++){ Tile tile = world.tile(x, y); - if(tile.block().flags != null && state.teams.areEnemies(tile.getTeam(), team) + if(state.teams.areEnemies(tile.getTeam(), team) && tile.block().flags.contains(BlockFlag.target)){ path.frontier.addFirst(tile); path.weights[x][y] = 0; @@ -145,7 +145,7 @@ public class Pathfinder{ private void updateFrontier(Team team, long nsToRun){ PathData path = paths[team.ordinal()]; - long start = Time.nanoTime(); + long start = Time.nanos(); while(path.frontier.size > 0 && (nsToRun < 0 || Time.timeSinceNanos(start) <= nsToRun)){ Tile tile = path.frontier.removeLast(); @@ -159,6 +159,7 @@ public class Pathfinder{ if(other != null && (path.weights[dx][dy] > cost + other.cost || path.searches[dx][dy] < path.search) && passable(other, team)){ + if(other.cost < 0) throw new IllegalArgumentException("Tile cost cannot be negative! " + other); path.frontier.addFirst(world.tile(dx, dy)); path.weights[dx][dy] = cost + other.cost; path.searches[dx][dy] = (short)path.search; diff --git a/core/src/io/anuke/mindustry/ai/WaveSpawner.java b/core/src/io/anuke/mindustry/ai/WaveSpawner.java index ec098dcf8d..005712e733 100644 --- a/core/src/io/anuke/mindustry/ai/WaveSpawner.java +++ b/core/src/io/anuke/mindustry/ai/WaveSpawner.java @@ -2,25 +2,61 @@ package io.anuke.mindustry.ai; import io.anuke.arc.Events; import io.anuke.arc.collection.Array; +import io.anuke.arc.collection.IntArray; import io.anuke.arc.math.Angles; import io.anuke.arc.math.Mathf; +import io.anuke.arc.util.Time; +import io.anuke.arc.util.Tmp; import io.anuke.mindustry.content.Blocks; -import io.anuke.mindustry.entities.units.BaseUnit; -import io.anuke.mindustry.entities.units.Squad; +import io.anuke.mindustry.content.Fx; +import io.anuke.mindustry.entities.Damage; +import io.anuke.mindustry.entities.Effects; +import io.anuke.mindustry.entities.type.BaseUnit; import io.anuke.mindustry.game.EventType.WorldLoadEvent; import io.anuke.mindustry.game.SpawnGroup; +import io.anuke.mindustry.world.Pos; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; import static io.anuke.mindustry.Vars.*; public class WaveSpawner{ + private static final float shockwaveBase = 380f, shockwaveRand = 50f, maxShockwaveDst = shockwaveBase + shockwaveRand; private Array groups; private Array flySpawns = new Array<>(); private Array groundSpawns = new Array<>(); + private IntArray loadedSpawns = new IntArray(); public WaveSpawner(){ Events.on(WorldLoadEvent.class, e -> reset()); } + public void write(DataOutput stream) throws IOException{ + stream.writeInt(groundSpawns.size); + for(GroundSpawn spawn : groundSpawns){ + stream.writeInt(Pos.get(spawn.x, spawn.y)); + } + } + + public void read(DataInput stream) throws IOException{ + flySpawns.clear(); + groundSpawns.clear(); + loadedSpawns.clear(); + + int amount = stream.readInt(); + + for(int i = 0; i < amount; i++){ + loadedSpawns.add(stream.readInt()); + } + } + + /**@return true if the player is near a ground spawn point.*/ + public boolean playerNear(){ + return groundSpawns.count(g -> Mathf.dst(g.x * tilesize, g.y * tilesize, players[0].x, players[0].y) < maxShockwaveDst) > 0; + } + public void spawnEnemies(){ for(SpawnGroup group : groups){ @@ -31,7 +67,6 @@ public class WaveSpawner{ if(group.type.isFlying){ for(FlyerSpawn spawn : flySpawns){ - Squad squad = new Squad(); float margin = 40f; //how far away from the edge flying units spawn float trns = (world.width() + world.height()) * tilesize; spawnX = Mathf.clamp(world.width() * tilesize / 2f + Angles.trnsx(spawn.angle, trns), -margin, world.width() * tilesize + margin); @@ -40,26 +75,27 @@ public class WaveSpawner{ for(int i = 0; i < spawned; i++){ BaseUnit unit = group.createUnit(waveTeam); - unit.setWave(); - unit.setSquad(squad); unit.set(spawnX + Mathf.range(spread), spawnY + Mathf.range(spread)); unit.add(); } } }else{ for(GroundSpawn spawn : groundSpawns){ - Squad squad = new Squad(); spawnX = spawn.x * tilesize; spawnY = spawn.y * tilesize; - spread = tilesize; + spread = tilesize*2; for(int i = 0; i < spawned; i++){ + Tmp.v1.rnd(spread); + BaseUnit unit = group.createUnit(waveTeam); - unit.setWave(); - unit.setSquad(squad); - unit.set(spawnX + Mathf.range(spread), spawnY + Mathf.range(spread)); - unit.add(); + unit.set(spawnX + Tmp.v1.x, spawnY + Tmp.v1.y); + + Time.run(i*5, () -> shockwave(unit)); } + Time.run(20f, () -> Effects.effect(Fx.spawnShockwave, spawn.x * tilesize, spawn.y * tilesize)); + //would be interesting to see player structures survive this without hacks + Time.run(40f, () -> Damage.damage(waveTeam, spawn.x * tilesize, spawn.y * tilesize, shockwaveBase + Mathf.random(shockwaveRand), 99999999f)); } } } @@ -73,17 +109,39 @@ public class WaveSpawner{ for(int x = 0; x < world.width(); x++){ for(int y = 0; y < world.height(); y++){ if(world.tile(x, y).block() == Blocks.spawn){ - GroundSpawn spawn = new GroundSpawn(); - spawn.x = x; - spawn.y = y; - groundSpawns.add(spawn); + addSpawns(x, y); - FlyerSpawn fspawn = new FlyerSpawn(); - fspawn.angle = Angles.angle(world.width()/2f, world.height()/2f, x, y); - flySpawns.add(fspawn); + //hide spawnpoints, they have served their purpose + world.tile(x, y).setBlock(Blocks.air); } } } + + for(int i = 0; i < loadedSpawns.size; i++){ + int pos = loadedSpawns.get(i); + addSpawns(Pos.x(pos), Pos.y(pos)); + } + + loadedSpawns.clear(); + } + + private void addSpawns(int x, int y){ + GroundSpawn spawn = new GroundSpawn(); + spawn.x = x; + spawn.y = y; + groundSpawns.add(spawn); + + FlyerSpawn fspawn = new FlyerSpawn(); + fspawn.angle = Angles.angle(world.width()/2f, world.height()/2f, x, y); + flySpawns.add(fspawn); + } + + private void shockwave(BaseUnit unit){ + Effects.effect(Fx.unitSpawn, unit.x, unit.y, 0f, unit); + Time.run(30f, () -> { + unit.add(); + Effects.effect(Fx.spawn, unit); + }); } private class FlyerSpawn{ diff --git a/core/src/io/anuke/mindustry/content/Blocks.java b/core/src/io/anuke/mindustry/content/Blocks.java index 4a2ea6e6aa..9ef07e5f47 100644 --- a/core/src/io/anuke/mindustry/content/Blocks.java +++ b/core/src/io/anuke/mindustry/content/Blocks.java @@ -1,7 +1,9 @@ package io.anuke.mindustry.content; +import io.anuke.arc.Core; import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.g2d.Draw; +import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.mindustry.game.ContentList; import io.anuke.mindustry.graphics.CacheLayer; import io.anuke.mindustry.type.Category; @@ -21,56 +23,59 @@ import io.anuke.mindustry.world.blocks.storage.LaunchPad; import io.anuke.mindustry.world.blocks.storage.SortedUnloader; import io.anuke.mindustry.world.blocks.storage.Vault; import io.anuke.mindustry.world.blocks.units.MechPad; -import io.anuke.mindustry.world.blocks.units.Reconstructor; import io.anuke.mindustry.world.blocks.units.RepairPoint; import io.anuke.mindustry.world.blocks.units.UnitFactory; +import io.anuke.mindustry.world.consumers.ConsumeItemFilter; +import io.anuke.mindustry.world.consumers.ConsumeLiquidFilter; -import static io.anuke.mindustry.Vars.content; -import static io.anuke.mindustry.Vars.state; +import static io.anuke.mindustry.Vars.*; public class Blocks implements ContentList{ public static Block //environment - air, part, spawn, space, metalfloor, deepwater, water, tar, stone, craters, charr, blackstone, dirt, sand, ice, snow, - grass, shrub, rock, icerock, blackrock, rocks, pine, + air, part, spawn, deepwater, water, tar, stone, craters, charr, sand, ice, snow, + holostone, rocks, icerocks, cliffs, pine, whiteTree, whiteTreeDead, sporeCluster, + iceSnow, sandWater, duneRocks, stainedRocks, stainedStone, stainedRocksRed, stainedStoneRed, stainedRocksYellow, stainedStoneYellow, stainedBoulder, + metalFloor, metalFloorDamaged, metalFloor2, metalFloor3, metalFloor5, ignarock, magmarock, hotrock, snowrocks, //crafting - siliconSmelter, graphitePress, plastaniumCompressor, phaseWeaver, surgeSmelter, pyratiteMixer, blastMixer, cryofluidMixer, + siliconSmelter, kiln, graphitePress, plastaniumCompressor, multiPress, phaseWeaver, surgeSmelter, pyratiteMixer, blastMixer, cryofluidMixer, melter, separator, centrifuge, biomatterCompressor, pulverizer, incinerator, //sandbox powerVoid, powerSource, itemSource, liquidSource, itemVoid, //defense + scrapWall, scrapWallLarge, scrapWallHuge, scrapWallGigantic, thruster, //ok, these names are getting ridiculous, but at least I don't have humongous walls yet copperWall, copperWallLarge, titaniumWall, titaniumWallLarge, thoriumWall, thoriumWallLarge, door, doorLarge, phaseWall, phaseWallLarge, surgeWall, surgeWallLarge, mendProjector, overdriveProjector, forceProjector, shockMine, - //transport + //transpor conveyor, titaniumConveyor, distributor, junction, itemBridge, phaseConveyor, sorter, router, overflowGate, massDriver, //liquids mechanicalPump, rotaryPump, thermalPump, conduit, pulseConduit, liquidRouter, liquidTank, liquidJunction, bridgeConduit, phaseConduit, //power - combustionGenerator, thermalGenerator, turbineGenerator, rtgGenerator, solarPanel, largeSolarPanel, thoriumReactor, - fusionReactor, battery, batteryLarge, powerNode, powerNodeLarge, + combustionGenerator, thermalGenerator, turbineGenerator, differentialGenerator, rtgGenerator, solarPanel, largeSolarPanel, thoriumReactor, + impactReactor, battery, batteryLarge, powerNode, powerNodeLarge, surgeTower, //production mechanicalDrill, pneumaticDrill, laserDrill, blastDrill, plasmaDrill, waterExtractor, oilExtractor, cultivator, //storage - core, vault, container, unloader, launchPad, + coreShard, coreFoundation, coreNucleus, vault, container, unloader, launchPad, //turrets duo, hail, arc, wave, lancer, swarmer, salvo, fuse, ripple, cyclone, spectre, meltdown, //units spiritFactory, phantomFactory, wraithFactory, ghoulFactory, revenantFactory, daggerFactory, titanFactory, - fortressFactory, reconstructor, repairPoint, + fortressFactory, repairPoint, //upgrades - alphaPad, deltaPad, tauPad, omegaPad, dartPad, javelinPad, tridentPad, glaivePad; + alphaDartPad, deltaPad, tauPad, omegaPad, javelinPad, tridentPad, glaivePad; @Override public void load(){ @@ -83,6 +88,12 @@ public class Blocks implements ContentList{ public void draw(Tile tile){} public void load(){} public void init(){} + public TextureRegion[] variantRegions(){ + if(variantRegions == null){ + variantRegions = new TextureRegion[]{Core.atlas.find("clear")}; + } + return variantRegions; + } }; part = new BlockPart(); @@ -97,20 +108,8 @@ public class Blocks implements ContentList{ new BuildBlock("build" + i); } - space = new Floor("space"){{ - placeableOn = false; - variants = 0; - cacheLayer = CacheLayer.space; - solid = true; - minimapColor = Color.valueOf("000001"); - }}; - - metalfloor = new Floor("metalfloor"){{ - variants = 6; - }}; - deepwater = new Floor("deepwater"){{ - liquidColor = Color.valueOf("546bb3"); + liquidColor = Color.valueOf("4d5ca4"); speedMultiplier = 0.2f; variants = 0; liquidDrop = Liquids.water; @@ -119,11 +118,10 @@ public class Blocks implements ContentList{ statusDuration = 120f; drownTime = 140f; cacheLayer = CacheLayer.water; - minimapColor = Color.valueOf("465a96"); }}; water = new Floor("water"){{ - liquidColor = Color.valueOf("546bb3"); + liquidColor = Color.valueOf("596ab8"); speedMultiplier = 0.5f; variants = 0; status = StatusEffects.wet; @@ -131,7 +129,6 @@ public class Blocks implements ContentList{ liquidDrop = Liquids.water; isLiquid = true; cacheLayer = CacheLayer.water; - minimapColor = Color.valueOf("506eb4"); }}; tar = new Floor("tar"){{ @@ -144,109 +141,216 @@ public class Blocks implements ContentList{ liquidDrop = Liquids.oil; isLiquid = true; cacheLayer = CacheLayer.oil; - minimapColor = Color.valueOf("292929"); }}; stone = new Floor("stone"){{ hasOres = true; - minimapColor = Color.valueOf("323232"); }}; craters = new Floor("craters"){{ - minimapColor = Color.valueOf("323232"); + variants = 6; + blendGroup = stone; }}; charr = new Floor("char"){{ - minimapColor = Color.valueOf("323232"); + blendGroup = stone; }}; - blackstone = new Floor("blackstone"){{ - minimapColor = Color.valueOf("252525"); - playerUnmineable = true; - hasOres = true; - }}; - - dirt = new Floor("dirt"){{ - minimapColor = Color.valueOf("6e501e"); + sandWater = new Floor("sand-water"){{ + liquidColor = Color.valueOf("596ab8"); + speedMultiplier = 0.8f; + variants = 0; + status = StatusEffects.wet; + statusDuration = 50f; + liquidDrop = Liquids.water; + isLiquid = true; + cacheLayer = CacheLayer.water; }}; sand = new Floor("sand"){{ itemDrop = Items.sand; - minimapColor = Color.valueOf("988a67"); hasOres = true; playerUnmineable = true; }}; - ice = new Floor("ice"){{ - dragMultiplier = 0.2f; - speedMultiplier = 0.4f; - minimapColor = Color.valueOf("b8eef8"); + holostone = new Floor("holostone"){{ hasOres = true; + edgeStyle = "blocky"; + }}; + + iceSnow = new Floor("ice-snow"){{ + variants = 3; }}; snow = new Floor("snow"){{ - minimapColor = Color.valueOf("c2d1d2"); - hasOres = true; }}; - grass = new Floor("grass"){{ - hasOres = true; - minimapColor = Color.valueOf("549d5b"); + ice = new Floor("ice"){{ + //TODO fix + dragMultiplier = 1f; + speedMultiplier = 1f; }}; - shrub = new Rock("shrub"); - - rock = new Rock("rock"){{ - variants = 2; - }}; - - icerock = new Rock("icerock"){{ - variants = 2; - }}; - - blackrock = new Rock("blackrock"){{ + cliffs = new StaticWall("cliffs"){{ variants = 1; + fillsTile = false; }}; rocks = new StaticWall("rocks"){{ variants = 2; }}; + icerocks = new StaticWall("icerocks"){{ + variants = 2; + }}; + + snowrocks = new StaticWall("snowrocks"){{ + variants = 2; + }}; + + duneRocks = new StaticWall("dunerocks"){{ + variants = 2; + }}; + pine = new StaticWall("pine"){{ //fillsTile = false; variants = 0; }}; + whiteTreeDead = new TreeBlock("white-tree-dead"){{ + }}; + + whiteTree = new TreeBlock("white-tree"){{ + }}; + + sporeCluster = new Rock("spore-cluster"){{ + variants = 3; + }}; + + stainedRocks = new StaticWall("stained-rocks"){{ + variants = 2; + }}; + + stainedStone = new Floor("stained-stone"){{ + edgeStyle = "blocky"; + hasOres = true; + }}; + + stainedRocksRed = new StaticWall("stained-rocks-red"){{ + variants = 2; + }}; + + stainedStoneRed = new Floor("stained-stone-red"){{ + edgeStyle = "blocky"; + hasOres = true; + }}; + + stainedRocksYellow = new StaticWall("stained-rocks-yellow"){{ + variants = 2; + }}; + + stainedStoneYellow = new Floor("stained-stone-yellow"){{ + edgeStyle = "blocky"; + }}; + + stainedBoulder = new Rock("stained-boulder"){{ + variants = 2; + }}; + + metalFloor = new Floor("metal-floor"){{ + variants = 0; + }}; + + metalFloorDamaged = new Floor("metal-floor-damaged"){{ + variants = 6; + blendGroup = metalFloor; + }}; + + metalFloor2 = new Floor("metal-floor-2"){{ + variants = 0; + blendGroup = metalFloor; + }}; + + metalFloor3 = new Floor("metal-floor-3"){{ + variants = 0; + blendGroup = metalFloor; + }}; + + metalFloor5 = new Floor("metal-floor-5"){{ + variants = 0; + blendGroup = metalFloor; + }}; + + ignarock = new Floor("ignarock"){{ + blendGroup = sand; + }}; + + hotrock = new Floor("hotrock"){{ + heat = 0.5f; + blendGroup = sand; + }}; + + magmarock = new Floor("magmarock"){{ + heat = 0.75f; + updateEffect = Fx.magmasmoke; + blendGroup = sand; + }}; + //endregion //region crafting + graphitePress = new GenericCrafter("graphite-press"){{ + requirements(Category.crafting, ItemStack.with(Items.copper, 150, Items.lead, 60)); + + craftEffect = Fx.pulverizeMedium; + output = Items.graphite; + craftTime = 90f; + size = 2; + hasItems = true; + + consumes.item(Items.coal, 2); + }}; + + multiPress = new GenericCrafter("multi-press"){{ + requirements(Category.crafting, ItemStack.with(Items.titanium, 200, Items.silicon, 50, Items.lead, 200, Items.graphite, 100)); + + craftEffect = Fx.pulverizeMedium; + output = Items.graphite; + craftTime = 30f; + size = 3; + hasItems = true; + hasLiquids = true; + hasPower = true; + + consumes.power(2f); + consumes.item(Items.coal, 2); + consumes.liquid(Liquids.water, 0.1f); + }}; + siliconSmelter = new PowerSmelter("silicon-smelter"){{ requirements(Category.crafting, ItemStack.with(Items.copper, 60, Items.lead, 50)); - health = 90; craftEffect = Fx.smeltsmoke; - result = Items.silicon; + output = Items.silicon; craftTime = 40f; size = 2; hasLiquids = false; flameColor = Color.valueOf("ffef99"); consumes.items(new ItemStack(Items.coal, 1), new ItemStack(Items.sand, 2)); - consumes.power(0.05f); + consumes.power(0.50f); }}; - graphitePress = new PowerSmelter("graphite-press"){{ - requirements(Category.crafting, ItemStack.with(Items.copper, 200, Items.lead, 50)); - - health = 90; + kiln = new PowerSmelter("kiln"){{ + requirements(Category.crafting, ItemStack.with(Items.copper, 120, Items.graphite, 60, Items.lead, 60)); craftEffect = Fx.smeltsmoke; - result = Items.graphite; - craftTime = 50f; + output = Items.metaglass; + craftTime = 30f; size = 2; - hasLiquids = false; - flameColor = Color.valueOf("ffef99"); + hasPower = hasItems = true; + flameColor = Color.valueOf("ffc099"); - consumes.items(new ItemStack(Items.coal, 1), new ItemStack(Items.sand, 2)); - consumes.power(0.05f); + consumes.items(new ItemStack(Items.lead, 1), new ItemStack(Items.sand, 1)); + consumes.power(0.60f); }}; plastaniumCompressor = new PlastaniumCompressor("plastanium-compressor"){{ @@ -262,32 +366,29 @@ public class Blocks implements ContentList{ updateEffect = Fx.plasticburn; consumes.liquid(Liquids.oil, 0.25f); - consumes.power(0.3f); + consumes.power(3f); consumes.item(Items.titanium, 2); }}; phaseWeaver = new PhaseWeaver("phase-weaver"){{ requirements(Category.crafting, ItemStack.with(Items.silicon, 260, Items.lead, 240, Items.thorium, 150)); craftEffect = Fx.smeltsmoke; - result = Items.phasefabric; + output = Items.phasefabric; craftTime = 120f; size = 2; consumes.items(new ItemStack(Items.thorium, 4), new ItemStack(Items.sand, 10)); - consumes.power(0.5f); + consumes.power(5f); }}; surgeSmelter = new PowerSmelter("alloy-smelter"){{ requirements(Category.crafting, ItemStack.with(Items.silicon, 160, Items.lead, 160, Items.thorium, 140)); craftEffect = Fx.smeltsmoke; - result = Items.surgealloy; + output = Items.surgealloy; craftTime = 75f; - size = 2; + size = 3; - useFlux = true; - fluxNeeded = 3; - - consumes.power(0.4f); + consumes.power(4f); consumes.items(new ItemStack(Items.titanium, 2), new ItemStack(Items.lead, 4), new ItemStack(Items.silicon, 3), new ItemStack(Items.copper, 3)); }}; @@ -298,7 +399,7 @@ public class Blocks implements ContentList{ size = 2; hasPower = true; - consumes.power(0.1f); + consumes.power(1f); consumes.item(Items.titanium); consumes.liquid(Liquids.water, 0.3f); }}; @@ -307,13 +408,11 @@ public class Blocks implements ContentList{ requirements(Category.crafting, ItemStack.with(Items.lead, 60, Items.titanium, 40)); hasItems = true; hasPower = true; - hasLiquids = true; output = Items.blastCompound; size = 2; - consumes.liquid(Liquids.oil, 0.05f); - consumes.item(Items.pyratite, 1); - consumes.power(0.04f); + consumes.items(new ItemStack(Items.pyratite, 1), new ItemStack(Items.biomatter, 1)); + consumes.power(0.40f); }}; pyratiteMixer = new PowerSmelter("pyratite-mixer"){{ @@ -321,11 +420,11 @@ public class Blocks implements ContentList{ flameColor = Color.CLEAR; hasItems = true; hasPower = true; - result = Items.pyratite; + output = Items.pyratite; size = 2; - consumes.power(0.02f); + consumes.power(0.20f); consumes.items(new ItemStack(Items.coal, 1), new ItemStack(Items.lead, 2), new ItemStack(Items.sand, 2)); }}; @@ -333,21 +432,21 @@ public class Blocks implements ContentList{ requirements(Category.crafting, ItemStack.with(Items.copper, 60, Items.lead, 70, Items.graphite, 90)); health = 200; outputLiquid = Liquids.slag; - outputLiquidAmount = 1.5f; + outputLiquidAmount = 2f; craftTime = 10f; hasLiquids = hasPower = true; - consumes.power(0.1f); + consumes.power(1f); consumes.item(Items.scrap, 1); }}; separator = new Separator("separator"){{ requirements(Category.crafting, ItemStack.with(Items.copper, 60, Items.titanium, 50)); results = new ItemStack[]{ - new ItemStack(Items.copper, 5), - new ItemStack(Items.lead, 3), - new ItemStack(Items.titanium, 2), - new ItemStack(Items.thorium, 1) + new ItemStack(Items.copper, 5), + new ItemStack(Items.lead, 3), + new ItemStack(Items.titanium, 2), + new ItemStack(Items.thorium, 1) }; hasPower = true; filterTime = 15f; @@ -358,7 +457,20 @@ public class Blocks implements ContentList{ spinnerSpeed = 3f; size = 2; - consumes.liquid(Liquids.slag, 0.3f); + consumes.liquid(Liquids.slag, 0.1f); + }}; + + cultivator = new Cultivator("cultivator"){{ + requirements(Category.crafting, ItemStack.with(Items.copper, 20, Items.lead, 50, Items.silicon, 20)); + output = Items.biomatter; + craftTime = 200; + size = 2; + hasLiquids = true; + hasPower = true; + hasItems = true; + + consumes.power(0.80f); + consumes.liquid(Liquids.water, 0.15f); }}; biomatterCompressor = new Compressor("biomattercompressor"){{ @@ -372,7 +484,7 @@ public class Blocks implements ContentList{ hasLiquids = true; consumes.item(Items.biomatter, 1); - consumes.power(0.06f); + consumes.power(0.60f); }}; pulverizer = new Pulverizer("pulverizer"){{ @@ -384,12 +496,13 @@ public class Blocks implements ContentList{ hasItems = hasPower = true; consumes.item(Items.scrap, 1); - consumes.power(0.05f); + consumes.power(0.50f); }}; incinerator = new Incinerator("incinerator"){{ requirements(Category.crafting, ItemStack.with(Items.graphite, 10, Items.lead, 30)); health = 90; + consumes.power(0.50f); }}; //endregion @@ -421,6 +534,33 @@ public class Blocks implements ContentList{ int wallHealthMultiplier = 3; + scrapWall = new Wall("scrap-wall"){{ + health = 60 * wallHealthMultiplier; + variants = 5; + }}; + + scrapWallLarge = new Wall("scrap-wall-large"){{ + health = 60 * 4 * wallHealthMultiplier; + size = 2; + variants = 4; + }}; + + scrapWallHuge = new Wall("scrap-wall-huge"){{ + health = 60 * 9 * wallHealthMultiplier; + size = 3; + variants = 3; + }}; + + scrapWallGigantic = new Wall("scrap-wall-gigantic"){{ + health = 60 * 16 * wallHealthMultiplier; + size = 4; + }}; + + thruster = new Wall("thruster"){{ + health = 55 * 16 * wallHealthMultiplier; + size = 4; + }}; + copperWall = new Wall("copper-wall"){{ requirements(Category.defense, ItemStack.with(Items.copper, 12)); health = 80 * wallHealthMultiplier; @@ -428,7 +568,6 @@ public class Blocks implements ContentList{ copperWallLarge = new Wall("copper-wall-large"){{ requirements(Category.defense, ItemStack.with(Items.copper, 12 * 4)); - requirements(Category.defense, ItemStack.with(Items.copper, 12)); health = 80 * 4 * wallHealthMultiplier; size = 2; }}; @@ -440,7 +579,6 @@ public class Blocks implements ContentList{ titaniumWallLarge = new Wall("titanium-wall-large"){{ requirements(Category.defense, ItemStack.with(Items.titanium, 12 * 4)); - requirements(Category.defense, ItemStack.with(Items.titanium, 12)); health = 110 * wallHealthMultiplier * 4; size = 2; }}; @@ -452,7 +590,6 @@ public class Blocks implements ContentList{ thoriumWallLarge = new Wall("thorium-wall-large"){{ requirements(Category.defense, ItemStack.with(Items.thorium, 12 * 4)); - requirements(Category.defense, ItemStack.with(Items.thorium, 12)); health = 200 * wallHealthMultiplier * 4; size = 2; }}; @@ -464,7 +601,6 @@ public class Blocks implements ContentList{ phaseWallLarge = new DeflectorWall("phase-wall-large"){{ requirements(Category.defense, ItemStack.with(Items.phasefabric, 12 * 4)); - requirements(Category.defense, ItemStack.with(Items.phasefabric, 12)); health = 150 * 4 * wallHealthMultiplier; size = 2; }}; @@ -476,7 +612,6 @@ public class Blocks implements ContentList{ surgeWallLarge = new SurgeWall("surge-wall-large"){{ requirements(Category.defense, ItemStack.with(Items.surgealloy, 12 * 4)); - requirements(Category.defense, ItemStack.with(Items.surgealloy, 12)); health = 230 * 4 * wallHealthMultiplier; size = 2; }}; @@ -488,7 +623,6 @@ public class Blocks implements ContentList{ doorLarge = new Door("door-large"){{ requirements(Category.defense, ItemStack.with(Items.titanium, 12 * 4, Items.silicon, 8 * 4)); - requirements(Category.defense, ItemStack.with(Items.titanium, 12, Items.silicon, 8)); openfx = Fx.dooropenlarge; closefx = Fx.doorcloselarge; health = 100 * 4 * wallHealthMultiplier; @@ -496,23 +630,23 @@ public class Blocks implements ContentList{ }}; mendProjector = new MendProjector("mend-projector"){{ - requirements(Category.effect, ItemStack.with(Items.lead, 200, Items.titanium, 150, Items.titanium, 50, Items.silicon, 180)); - consumes.power(0.2f, 1.0f); + requirements(Category.effect, ItemStack.with(Items.lead, 200, Items.titanium, 50, Items.silicon, 180)); + consumes.power(2f); size = 2; consumes.item(Items.phasefabric).optional(true); }}; overdriveProjector = new OverdriveProjector("overdrive-projector"){{ - requirements(Category.effect, ItemStack.with(Items.lead, 200, Items.titanium, 150, Items.titanium, 150, Items.silicon, 250)); - consumes.power(0.35f, 1.0f); + requirements(Category.effect, ItemStack.with(Items.lead, 200, Items.titanium, 150, Items.silicon, 250)); + consumes.power(3.50f); size = 2; - consumes.item(Items.phasefabric).optional(true); + consumes.item(Items.phasefabric).optional(true).boost(true); }}; forceProjector = new ForceProjector("force-projector"){{ - requirements(Category.effect, ItemStack.with(Items.lead, 200, Items.titanium, 150, Items.titanium, 150, Items.silicon, 250)); + requirements(Category.effect, ItemStack.with(Items.lead, 200, Items.titanium, 150, Items.silicon, 250)); size = 3; - consumes.item(Items.phasefabric).optional(true); + consumes.item(Items.phasefabric).optional(true).boost(true); }}; shockMine = new ShockMine("shock-mine"){{ @@ -540,9 +674,10 @@ public class Blocks implements ContentList{ }}; junction = new Junction("junction"){{ - requirements(Category.distribution, ItemStack.with(Items.copper, 2)); + requirements(Category.distribution, ItemStack.with(Items.copper, 3)); speed = 26; capacity = 32; + health = 25; }}; itemBridge = new BufferedItemBridge("bridge-conveyor"){{ @@ -556,7 +691,7 @@ public class Blocks implements ContentList{ requirements(Category.distribution, ItemStack.with(Items.phasefabric, 10, Items.silicon, 15, Items.lead, 20, Items.graphite, 20)); range = 12; hasPower = true; - consumes.power(0.03f, 1.0f); + consumes.power(0.30f); }}; sorter = new Sorter("sorter"){{ @@ -598,7 +733,7 @@ public class Blocks implements ContentList{ rotaryPump = new Pump("rotary-pump"){{ requirements(Category.liquid, ItemStack.with(Items.copper, 140, Items.lead, 100, Items.silicon, 40, Items.titanium, 70)); pumpAmount = 0.2f; - consumes.power(0.015f); + consumes.power(1.50f); liquidCapacity = 30f; hasPower = true; size = 2; @@ -608,7 +743,7 @@ public class Blocks implements ContentList{ thermalPump = new Pump("thermal-pump"){{ requirements(Category.liquid, ItemStack.with(Items.copper, 160, Items.lead, 130, Items.silicon, 60, Items.titanium, 80, Items.thorium, 70)); pumpAmount = 0.275f; - consumes.power(0.03f); + consumes.power(0.30f); liquidCapacity = 40f; hasPower = true; size = 2; @@ -653,7 +788,7 @@ public class Blocks implements ContentList{ requirements(Category.liquid, ItemStack.with(Items.phasefabric, 10, Items.silicon, 15, Items.lead, 20, Items.titanium, 20)); range = 12; hasPower = true; - consumes.power(0.03f, 1.0f); + consumes.power(0.30f); }}; //endregion @@ -667,81 +802,103 @@ public class Blocks implements ContentList{ powerNodeLarge = new PowerNode("power-node-large"){{ requirements(Category.power, ItemStack.with(Items.titanium, 10, Items.lead, 20, Items.silicon, 6)); - requirements(Category.power, ItemStack.with(Items.copper, 2, Items.lead, 6)); size = 2; maxNodes = 6; laserRange = 9.5f; }}; + surgeTower = new PowerNode("surge-tower"){{ + requirements(Category.power, ItemStack.with(Items.titanium, 15, Items.lead, 20, Items.silicon, 30, Items.surgealloy, 30)); + size = 2; + maxNodes = 2; + laserRange = 30f; + }}; + battery = new Battery("battery"){{ requirements(Category.power, ItemStack.with(Items.copper, 8, Items.lead, 30, Items.silicon, 4)); - consumes.powerBuffered(320f, 1f); + consumes.powerBuffered(3200f, 1f); }}; batteryLarge = new Battery("battery-large"){{ requirements(Category.power, ItemStack.with(Items.titanium, 40, Items.lead, 80, Items.silicon, 30)); requirements(Category.power, ItemStack.with(Items.copper, 8, Items.lead, 30, Items.silicon, 4)); size = 3; - consumes.powerBuffered(2000f, 1f); + consumes.powerBuffered(20000f, 1f); }}; combustionGenerator = new BurnerGenerator("combustion-generator"){{ requirements(Category.power, ItemStack.with(Items.copper, 50, Items.lead, 30)); - powerProduction = 0.09f; + powerProduction = 1f; itemDuration = 40f; }}; - thermalGenerator = new LiquidHeatGenerator("thermal-generator"){{ + thermalGenerator = new ThermalGenerator("thermal-generator"){{ requirements(Category.power, ItemStack.with(Items.copper, 80, Items.graphite, 70, Items.lead, 100, Items.silicon, 70, Items.thorium, 70)); - maxLiquidGenerate = 2f; - powerProduction = 2f; + powerProduction = 3f; generateEffect = Fx.redgeneratespark; size = 2; }}; turbineGenerator = new TurbineGenerator("turbine-generator"){{ requirements(Category.power, ItemStack.with(Items.copper, 70, Items.graphite, 50, Items.lead, 80, Items.silicon, 60)); - powerProduction = 0.28f; + powerProduction = 6f; itemDuration = 30f; consumes.liquid(Liquids.water, 0.05f); size = 2; }}; + differentialGenerator = new DifferentialGenerator("differential-generator"){{ + requirements(Category.power, ItemStack.with(Items.copper, 140, Items.titanium, 100, Items.lead, 200, Items.silicon, 130, Items.metaglass, 100)); + powerProduction = 16f; + itemDuration = 50f; + consumes.remove(ConsumeItemFilter.class); + consumes.remove(ConsumeLiquidFilter.class); + consumes.item(Items.pyratite); + consumes.liquid(Liquids.cryofluid, 0.12f); + size = 3; + }}; + rtgGenerator = new DecayGenerator("rtg-generator"){{ requirements(Category.power, ItemStack.with(Items.lead, 200, Items.silicon, 150, Items.phasefabric, 50, Items.plastanium, 150, Items.thorium, 100)); size = 2; - powerProduction = 0.3f; + powerProduction = 3f; itemDuration = 220f; }}; solarPanel = new SolarGenerator("solar-panel"){{ requirements(Category.power, ItemStack.with(Items.lead, 20, Items.silicon, 30)); - powerProduction = 0.0045f; + powerProduction = 0.045f; }}; largeSolarPanel = new SolarGenerator("solar-panel-large"){{ requirements(Category.power, ItemStack.with(Items.lead, 200, Items.silicon, 290, Items.phasefabric, 30)); size = 3; - powerProduction = 0.055f; + powerProduction = 0.55f; }}; thoriumReactor = new NuclearReactor("thorium-reactor"){{ requirements(Category.power, ItemStack.with(Items.lead, 600, Items.silicon, 400, Items.graphite, 300, Items.thorium, 300)); size = 3; health = 700; - powerProduction = 1.1f; + powerProduction = 12f; + consumes.liquid(Liquids.cryofluid, maxLiquidUse); }}; - fusionReactor = new FusionReactor("fusion-reactor"){{ + impactReactor = new ImpactReactor("impact-reactor"){{ + requirements(Category.power, ItemStack.with(Items.lead, 800, Items.silicon, 600, Items.graphite, 600, Items.thorium, 200, Items.surgealloy, 400, Items.metaglass, 200)); size = 4; - health = 600; + health = 900; + powerProduction = 70f; + consumes.power(23f); + consumes.item(Items.blastCompound); + consumes.liquid(Liquids.water, 0.3f); }}; //endregion power //region production mechanicalDrill = new Drill("mechanical-drill"){{ - requirements(Category.production, ItemStack.with(Items.copper, 20), true); + requirements(Category.production, ItemStack.with(Items.copper, 25), true); tier = 2; drillTime = 600; size = 2; @@ -765,12 +922,12 @@ public class Blocks implements ContentList{ updateEffect = Fx.pulverizeMedium; drillEffect = Fx.mineBig; - consumes.power(0.11f); + consumes.power(1.10f); }}; blastDrill = new Drill("blast-drill"){{ requirements(Category.production, ItemStack.with(Items.copper, 130, Items.silicon, 120, Items.titanium, 100, Items.thorium, 60)); - drillTime = 120; + drillTime = 200; size = 3; drawRim = true; hasPower = true; @@ -781,12 +938,12 @@ public class Blocks implements ContentList{ rotateSpeed = 6f; warmupSpeed = 0.01f; - consumes.power(0.3f); + consumes.power(3f); }}; plasmaDrill = new Drill("plasma-drill"){{ heatColor = Color.valueOf("ff461b"); - drillTime = 100; + drillTime = 150; size = 4; hasLiquids = true; hasPower = true; @@ -798,7 +955,7 @@ public class Blocks implements ContentList{ drillEffect = Fx.mineHuge; warmupSpeed = 0.005f; - consumes.power(0.7f); + consumes.power(7f); }}; waterExtractor = new SolidPump("water-extractor"){{ @@ -809,7 +966,7 @@ public class Blocks implements ContentList{ liquidCapacity = 30f; rotateSpeed = 1.4f; - consumes.power(0.09f); + consumes.power(0.90f); }}; oilExtractor = new Fracker("oil-extractor"){{ @@ -823,34 +980,36 @@ public class Blocks implements ContentList{ liquidCapacity = 30f; consumes.item(Items.sand); - consumes.power(0.3f); - consumes.liquid(Liquids.water, 0.15f); - }}; - - cultivator = new Cultivator("cultivator"){{ - requirements(Category.production, ItemStack.with(Items.copper, 20, Items.lead, 50, Items.silicon, 20)); - result = Items.biomatter; - drillTime = 200; - size = 2; - hasLiquids = true; - hasPower = true; - - consumes.power(0.08f); + consumes.power(3f); consumes.liquid(Liquids.water, 0.15f); }}; //endregion //region storage - core = new CoreBlock("core"){{ + coreShard = new CoreBlock("core-shard"){{ requirements(Category.effect, () -> false, ItemStack.with(Items.titanium, 2000)); alwaysUnlocked = true; health = 1100; - itemCapacity = 1000; - launchThreshold = 500; - launchTime = 60f * 10; - launchChunkSize = 100; + itemCapacity = 5000; + size = 3; + }}; + + coreFoundation = new CoreBlock("core-foundation"){{ + requirements(Category.effect, () -> false, ItemStack.with(Items.titanium, 4000, Items.silicon, 2000)); + + health = 2000; + itemCapacity = 8000; + size = 4; + }}; + + coreNucleus = new CoreBlock("core-nucleus"){{ + requirements(Category.effect, () -> false, ItemStack.with(Items.titanium, 8000, Items.silicon, 4000, Items.surgealloy, 2000)); + + health = 4000; + itemCapacity = 12000; + size = 5; }}; vault = new Vault("vault"){{ @@ -871,19 +1030,19 @@ public class Blocks implements ContentList{ }}; launchPad = new LaunchPad("launch-pad"){{ - requirements(Category.effect, ItemStack.with(Items.copper, 500)); + requirements(Category.effect, () -> world.isZone(), ItemStack.with(Items.copper, 500, Items.titanium, 200, Items.silicon, 200, Items.lead, 200)); size = 3; itemCapacity = 100; launchTime = 60f * 6; hasPower = true; - consumes.power(0.1f); + consumes.power(1f); }}; //endregion //region turrets duo = new DoubleTurret("duo"){{ - requirements(Category.turret, ItemStack.with(Items.copper, 60), true); + requirements(Category.turret, ItemStack.with(Items.copper, 70), true); ammo( Items.copper, Bullets.standardCopper, Items.graphite, Bullets.standardDense, @@ -892,10 +1051,10 @@ public class Blocks implements ContentList{ ); reload = 20f; restitution = 0.03f; - range = 90f; + range = 95f; shootCone = 15f; ammoUseEffect = Fx.shellEjectSmall; - health = 110; + health = 210; inaccuracy = 2f; rotatespeed = 10f; }}; @@ -903,9 +1062,9 @@ public class Blocks implements ContentList{ hail = new ArtilleryTurret("hail"){{ requirements(Category.turret, ItemStack.with(Items.copper, 60, Items.graphite, 35)); ammo( - Items.graphite, Bullets.artilleryDense, - Items.silicon, Bullets.artilleryHoming, - Items.pyratite, Bullets.artlleryIncendiary + Items.graphite, Bullets.artilleryDense, + Items.silicon, Bullets.artilleryHoming, + Items.pyratite, Bullets.artlleryIncendiary ); reload = 60f; recoil = 2f; @@ -918,18 +1077,18 @@ public class Blocks implements ContentList{ wave = new LiquidTurret("wave"){{ requirements(Category.turret, ItemStack.with(Items.titanium, 70, Items.lead, 150)); ammo( - Liquids.water, Bullets.waterShot, - Liquids.slag, Bullets.slagShot, - Liquids.cryofluid, Bullets.cryoShot, - Liquids.oil, Bullets.oilShot + Liquids.water, Bullets.waterShot, + Liquids.slag, Bullets.slagShot, + Liquids.cryofluid, Bullets.cryoShot, + Liquids.oil, Bullets.oilShot ); size = 2; recoil = 0f; - reload = 4f; + reload = 3f; inaccuracy = 5f; shootCone = 50f; shootEffect = Fx.shootLiquid; - range = 90f; + range = 100f; health = 360; drawer = (tile, entity) -> { @@ -944,16 +1103,16 @@ public class Blocks implements ContentList{ lancer = new ChargeTurret("lancer"){{ requirements(Category.turret, ItemStack.with(Items.copper, 50, Items.lead, 100, Items.silicon, 90)); - range = 90f; - chargeTime = 60f; + range = 155f; + chargeTime = 50f; chargeMaxDelay = 30f; chargeEffects = 7; shootType = Bullets.lancerLaser; recoil = 2f; - reload = 100f; + reload = 90f; cooldown = 0.03f; powerUsed = 1 / 3f; - consumes.powerBuffered(60f); + consumes.powerBuffered(600f); shootShake = 2f; shootEffect = Fx.lancerLaserShoot; smokeEffect = Fx.lancerLaserShootSmoke; @@ -968,13 +1127,12 @@ public class Blocks implements ContentList{ arc = new PowerTurret("arc"){{ requirements(Category.turret, ItemStack.with(Items.copper, 70, Items.lead, 60)); shootType = Bullets.arc; - reload = 85f; - shootShake = 1f; + reload = 20f; shootCone = 40f; rotatespeed = 8f; - powerUsed = 1f / 3f; - consumes.powerBuffered(30f); - range = 150f; + powerUsed = 1f / 2f; + consumes.powerBuffered(80f); + range = 80f; shootEffect = Fx.lightningShoot; heatColor = Color.RED; recoil = 1f; @@ -984,9 +1142,9 @@ public class Blocks implements ContentList{ swarmer = new BurstTurret("swarmer"){{ requirements(Category.turret, ItemStack.with(Items.graphite, 70, Items.titanium, 70, Items.plastanium, 90, Items.silicon, 60)); ammo( - Items.blastCompound, Bullets.missileExplosive, - Items.pyratite, Bullets.missileIncendiary, - Items.surgealloy, Bullets.missileSurge + Items.blastCompound, Bullets.missileExplosive, + Items.pyratite, Bullets.missileIncendiary, + Items.surgealloy, Bullets.missileSurge ); reload = 50f; shots = 4; @@ -1001,11 +1159,11 @@ public class Blocks implements ContentList{ salvo = new BurstTurret("salvo"){{ requirements(Category.turret, ItemStack.with(Items.copper, 210, Items.graphite, 190, Items.thorium, 130)); ammo( - Items.copper, Bullets.standardCopper, - Items.graphite, Bullets.standardDense, - Items.pyratite, Bullets.standardIncendiary, - Items.silicon, Bullets.standardHoming, - Items.thorium, Bullets.standardThorium + Items.copper, Bullets.standardCopper, + Items.graphite, Bullets.standardDense, + Items.pyratite, Bullets.standardIncendiary, + Items.silicon, Bullets.standardHoming, + Items.thorium, Bullets.standardThorium ); size = 2; @@ -1025,11 +1183,11 @@ public class Blocks implements ContentList{ ripple = new ArtilleryTurret("ripple"){{ requirements(Category.turret, ItemStack.with(Items.copper, 300, Items.graphite, 220, Items.thorium, 120)); ammo( - Items.graphite, Bullets.artilleryDense, - Items.silicon, Bullets.artilleryHoming, - Items.pyratite, Bullets.artlleryIncendiary, - Items.blastCompound, Bullets.artilleryExplosive, - Items.plastanium, Bullets.arilleryPlastic + Items.graphite, Bullets.artilleryDense, + Items.silicon, Bullets.artilleryHoming, + Items.pyratite, Bullets.artlleryIncendiary, + Items.blastCompound, Bullets.artilleryExplosive, + Items.plastanium, Bullets.arilleryPlastic ); size = 3; shots = 4; @@ -1042,7 +1200,7 @@ public class Blocks implements ContentList{ restitution = 0.02f; recoil = 6f; shootShake = 2f; - range = 320f; + range = 290f; health = 550; }}; @@ -1050,9 +1208,9 @@ public class Blocks implements ContentList{ cyclone = new ItemTurret("cyclone"){{ requirements(Category.turret, ItemStack.with(Items.copper, 400, Items.surgealloy, 200, Items.plastanium, 150)); ammo( - Items.blastCompound, Bullets.flakExplosive, - Items.plastanium, Bullets.flakPlastic, - Items.surgealloy, Bullets.flakSurge + Items.blastCompound, Bullets.flakExplosive, + Items.plastanium, Bullets.flakPlastic, + Items.surgealloy, Bullets.flakSurge ); xRand = 4f; reload = 8f; @@ -1069,22 +1227,22 @@ public class Blocks implements ContentList{ fuse = new ItemTurret("fuse"){{ requirements(Category.turret, ItemStack.with(Items.copper, 450, Items.graphite, 450, Items.surgealloy, 250)); ammo(Items.graphite, Bullets.fuseShot); - reload = 50f; + reload = 40f; shootShake = 4f; range = 80f; recoil = 5f; restitution = 0.1f; size = 3; - health = 155 * size * size; + health = 165 * size * size; }}; spectre = new DoubleTurret("spectre"){{ requirements(Category.turret, ItemStack.with(Items.copper, 700, Items.graphite, 600, Items.surgealloy, 500, Items.plastanium, 350, Items.thorium, 500)); ammo( - Items.graphite, Bullets.standardDenseBig, - Items.pyratite, Bullets.standardIncendiaryBig, - Items.thorium, Bullets.standardThoriumBig + Items.graphite, Bullets.standardDenseBig, + Items.pyratite, Bullets.standardIncendiaryBig, + Items.thorium, Bullets.standardThoriumBig ); reload = 6f; coolantMultiplier = 0.5f; @@ -1113,7 +1271,7 @@ public class Blocks implements ContentList{ size = 4; shootShake = 2f; powerUsed = 0.5f; - consumes.powerBuffered(120f); + consumes.powerBuffered(1200f); range = 160f; reload = 200f; firingMoveFract = 0.1f; @@ -1130,7 +1288,7 @@ public class Blocks implements ContentList{ type = UnitTypes.spirit; produceTime = 5700; size = 2; - consumes.power(0.08f); + consumes.power(0.80f); consumes.items(new ItemStack(Items.silicon, 30), new ItemStack(Items.lead, 30)); }}; @@ -1139,7 +1297,7 @@ public class Blocks implements ContentList{ type = UnitTypes.phantom; produceTime = 7300; size = 2; - consumes.power(0.2f); + consumes.power(2f); consumes.items(new ItemStack(Items.silicon, 70), new ItemStack(Items.lead, 80), new ItemStack(Items.titanium, 80)); }}; @@ -1148,7 +1306,7 @@ public class Blocks implements ContentList{ type = UnitTypes.wraith; produceTime = 1800; size = 2; - consumes.power(0.1f); + consumes.power(1f); consumes.items(new ItemStack(Items.silicon, 10), new ItemStack(Items.titanium, 10)); }}; @@ -1157,7 +1315,7 @@ public class Blocks implements ContentList{ type = UnitTypes.ghoul; produceTime = 3600; size = 3; - consumes.power(0.2f); + consumes.power(2f); consumes.items(new ItemStack(Items.silicon, 30), new ItemStack(Items.titanium, 30), new ItemStack(Items.plastanium, 20)); }}; @@ -1166,7 +1324,7 @@ public class Blocks implements ContentList{ type = UnitTypes.revenant; produceTime = 8000; size = 4; - consumes.power(0.3f); + consumes.power(3f); consumes.items(new ItemStack(Items.silicon, 80), new ItemStack(Items.titanium, 80), new ItemStack(Items.plastanium, 50)); }}; @@ -1175,7 +1333,7 @@ public class Blocks implements ContentList{ type = UnitTypes.dagger; produceTime = 1700; size = 2; - consumes.power(0.05f); + consumes.power(0.50f); consumes.items(new ItemStack(Items.silicon, 10)); }}; @@ -1184,7 +1342,7 @@ public class Blocks implements ContentList{ type = UnitTypes.titan; produceTime = 3400; size = 3; - consumes.power(0.15f); + consumes.power(1.50f); consumes.items(new ItemStack(Items.silicon, 20), new ItemStack(Items.thorium, 30)); }}; @@ -1193,7 +1351,7 @@ public class Blocks implements ContentList{ type = UnitTypes.fortress; produceTime = 5000; size = 3; - consumes.power(0.2f); + consumes.power(2f); consumes.items(new ItemStack(Items.silicon, 40), new ItemStack(Items.thorium, 50)); }}; @@ -1202,14 +1360,10 @@ public class Blocks implements ContentList{ repairSpeed = 0.1f; }}; - reconstructor = new Reconstructor("reconstructor"){{ - size = 2; - }}; - //endregion //region upgrades - alphaPad = new MechPad("alpha-mech-pad"){{ + alphaDartPad = new MechPad("alpha-dart-mech-pad"){{ requirements(Category.upgrade, ItemStack.with(Items.lead, 200, Items.graphite, 100, Items.copper, 150)); mech = Mechs.alpha; size = 2; @@ -1237,13 +1391,6 @@ public class Blocks implements ContentList{ consumes.powerBuffered(120f); }}; - dartPad = new MechPad("dart-ship-pad"){{ - requirements(Category.upgrade, ItemStack.with(Items.lead, 150, Items.copper, 150, Items.silicon, 200, Items.titanium, 240)); - mech = Mechs.dart; - size = 2; - consumes.powerBuffered(50f); - }}; - javelinPad = new MechPad("javelin-ship-pad"){{ requirements(Category.upgrade, ItemStack.with(Items.lead, 350, Items.silicon, 450, Items.titanium, 500, Items.plastanium, 400, Items.phasefabric, 200)); mech = Mechs.javelin; @@ -1279,6 +1426,9 @@ public class Blocks implements ContentList{ } } + //special variants + new OreBlock(Items.scrap, (Floor)snow); + //endregion } } diff --git a/core/src/io/anuke/mindustry/content/Bullets.java b/core/src/io/anuke/mindustry/content/Bullets.java index 439387c198..bcc7a59e52 100644 --- a/core/src/io/anuke/mindustry/content/Bullets.java +++ b/core/src/io/anuke/mindustry/content/Bullets.java @@ -1,6 +1,6 @@ package io.anuke.mindustry.content; -import io.anuke.arc.entities.Effects; +import io.anuke.mindustry.entities.Effects; import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.g2d.CapStyle; import io.anuke.arc.graphics.g2d.Draw; @@ -10,13 +10,13 @@ import io.anuke.arc.math.Mathf; import io.anuke.arc.util.Time; import io.anuke.arc.util.Tmp; import io.anuke.mindustry.entities.Damage; -import io.anuke.mindustry.entities.Unit; +import io.anuke.mindustry.entities.type.Unit; import io.anuke.mindustry.entities.bullet.*; import io.anuke.mindustry.entities.effect.Fire; import io.anuke.mindustry.entities.effect.Lightning; import io.anuke.mindustry.entities.effect.Puddle; import io.anuke.mindustry.game.ContentList; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.graphics.Shapes; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.BuildBlock; @@ -33,7 +33,7 @@ public class Bullets implements ContentList{ flakPlastic, flakExplosive, flakSurge, //missiles - missileExplosive, missileIncendiary, missileSurge, missileJavelin, missileSwarm, + missileExplosive, missileIncendiary, missileSurge, missileJavelin, missileSwarm, missileRevenant, //standard standardCopper, standardDense, standardThorium, standardHoming, standardIncendiary, standardMechSmall, @@ -46,7 +46,7 @@ public class Bullets implements ContentList{ waterShot, cryoShot, slagShot, oilShot, //environment, misc. - fireball, basicFlame, fuseShot, driverBolt, healBullet, frag, + fireball, basicFlame, fuseShot, driverBolt, healBullet, frag, eruptorShot, //bombs bombExplosive, bombIncendiary, bombOil, explode; @@ -64,28 +64,28 @@ public class Bullets implements ContentList{ splashDamage = 33f; }}; - artilleryPlasticFrag = new BasicBulletType(2.5f, 6, "bullet"){{ + artilleryPlasticFrag = new BasicBulletType(2.5f, 7, "bullet"){{ bulletWidth = 10f; bulletHeight = 12f; bulletShrink = 1f; lifetime = 15f; - backColor = Palette.plastaniumBack; - frontColor = Palette.plastaniumFront; + backColor = Pal.plastaniumBack; + frontColor = Pal.plastaniumFront; despawnEffect = Fx.none; }}; - arilleryPlastic = new ArtilleryBulletType(3.3f, 0, "shell"){{ + arilleryPlastic = new ArtilleryBulletType(3.4f, 0, "shell"){{ hitEffect = Fx.plasticExplosion; knockback = 1f; lifetime = 55f; bulletWidth = bulletHeight = 13f; collidesTiles = false; splashDamageRadius = 35f; - splashDamage = 35f; + splashDamage = 45f; fragBullet = artilleryPlasticFrag; - fragBullets = 9; - backColor = Palette.plastaniumBack; - frontColor = Palette.plastaniumFront; + fragBullets = 10; + backColor = Pal.plastaniumBack; + frontColor = Pal.plastaniumFront; }}; artilleryHoming = new ArtilleryBulletType(3f, 0, "shell"){{ @@ -110,8 +110,8 @@ public class Bullets implements ContentList{ splashDamage = 30f; incendAmount = 4; incendSpread = 11f; - frontColor = Palette.lightishOrange; - backColor = Palette.lightOrange; + frontColor = Pal.lightishOrange; + backColor = Pal.lightOrange; trailEffect = Fx.incendTrail; }}; @@ -123,8 +123,8 @@ public class Bullets implements ContentList{ collidesTiles = false; splashDamageRadius = 45f; splashDamage = 50f; - backColor = Palette.missileYellowBack; - frontColor = Palette.missileYellow; + backColor = Pal.missileYellowBack; + frontColor = Pal.missileYellow; }}; artilleryUnit = new ArtilleryBulletType(2f, 0, "shell"){{ @@ -136,27 +136,30 @@ public class Bullets implements ContentList{ collidesTiles = true; splashDamageRadius = 45f; splashDamage = 50f; - backColor = Palette.bulletYellowBack; - frontColor = Palette.bulletYellow; + backColor = Pal.bulletYellowBack; + frontColor = Pal.bulletYellow; }}; - flakPlastic = new FlakBulletType(4f, 5){{ - splashDamageRadius = 40f; + flakPlastic = new FlakBulletType(4f, 6){{ + splashDamageRadius = 50f; fragBullet = artilleryPlasticFrag; - fragBullets = 4; + fragBullets = 6; hitEffect = Fx.plasticExplosion; - frontColor = Palette.plastaniumFront; - backColor = Palette.plastaniumBack; + frontColor = Pal.plastaniumFront; + backColor = Pal.plastaniumBack; + shootEffect = Fx.shootBig; }}; flakExplosive = new FlakBulletType(4f, 5){{ //default bullet type, no changes + shootEffect = Fx.shootBig; }}; flakSurge = new FlakBulletType(4f, 7){{ splashDamage = 33f; lightining = 2; lightningLength = 12; + shootEffect = Fx.shootBig; }}; missileExplosive = new MissileBulletType(1.8f, 10, "missile"){{ @@ -172,8 +175,8 @@ public class Bullets implements ContentList{ }}; missileIncendiary = new MissileBulletType(2f, 12, "missile"){{ - frontColor = Palette.lightishOrange; - backColor = Palette.lightOrange; + frontColor = Pal.lightishOrange; + backColor = Pal.lightOrange; bulletWidth = 7f; bulletHeight = 8f; bulletShrink = 0f; @@ -213,8 +216,8 @@ public class Bullets implements ContentList{ trailColor = Color.valueOf("b6c6fd"); hitEffect = Fx.blastExplosion; despawnEffect = Fx.blastExplosion; - backColor = Palette.bulletYellowBack; - frontColor = Palette.bulletYellow; + backColor = Pal.bulletYellowBack; + frontColor = Pal.bulletYellow; weaveScale = 8f; weaveMag = 2f; }}; @@ -230,20 +233,39 @@ public class Bullets implements ContentList{ splashDamage = 10f; lifetime = 120f; trailColor = Color.GRAY; - backColor = Palette.bulletYellowBack; - frontColor = Palette.bulletYellow; + backColor = Pal.bulletYellowBack; + frontColor = Pal.bulletYellow; hitEffect = Fx.blastExplosion; despawnEffect = Fx.blastExplosion; weaveScale = 8f; weaveMag = 2f; }}; - standardCopper = new BasicBulletType(2.5f, 7, "bullet"){{ + missileRevenant = new MissileBulletType(2.7f, 12, "missile"){{ + bulletWidth = 8f; + bulletHeight = 8f; + bulletShrink = 0f; + drag = -0.003f; + homingRange = 60f; + keepVelocity = false; + splashDamageRadius = 25f; + splashDamage = 10f; + lifetime = 80f; + trailColor = Pal.unitBack; + backColor = Pal.unitBack; + frontColor = Pal.unitFront; + hitEffect = Fx.blastExplosion; + despawnEffect = Fx.blastExplosion; + weaveScale = 6f; + weaveMag = 1f; + }}; + + standardCopper = new BasicBulletType(2.5f, 9, "bullet"){{ bulletWidth = 7f; bulletHeight = 9f; shootEffect = Fx.shootSmall; smokeEffect = Fx.shootSmallSmoke; - ammoMultiplier = 2; + ammoMultiplier = 1; }}; standardDense = new BasicBulletType(3.5f, 18, "bullet"){{ @@ -274,8 +296,8 @@ public class Bullets implements ContentList{ standardIncendiary = new BasicBulletType(3.2f, 11, "bullet"){{ bulletWidth = 10f; bulletHeight = 12f; - frontColor = Palette.lightishOrange; - backColor = Palette.lightOrange; + frontColor = Pal.lightishOrange; + backColor = Pal.lightOrange; incendSpread = 3f; incendAmount = 1; incendChance = 0.3f; @@ -304,22 +326,25 @@ public class Bullets implements ContentList{ bulletWidth = 15f; bulletHeight = 21f; armorPierce = 0.2f; + shootEffect = Fx.shootBig; }}; standardThoriumBig = new BasicBulletType(8f, 65, "bullet"){{ bulletWidth = 16f; bulletHeight = 23f; armorPierce = 0.5f; + shootEffect = Fx.shootBig; }}; standardIncendiaryBig = new BasicBulletType(7f, 38, "bullet"){{ bulletWidth = 16f; bulletHeight = 21f; - frontColor = Palette.lightishOrange; - backColor = Palette.lightOrange; + frontColor = Pal.lightishOrange; + backColor = Pal.lightOrange; incendSpread = 3f; incendAmount = 2; incendChance = 0.3f; + shootEffect = Fx.shootBig; }}; damageLightning = new BulletType(0.0001f, 0f){{ @@ -346,7 +371,7 @@ public class Bullets implements ContentList{ @Override public void draw(Bullet b){ - Draw.color(Palette.heal); + Draw.color(Pal.heal); Lines.stroke(2f); Lines.lineAngleCenter(b.x, b.y, b.rot(), 7f); Draw.color(Color.WHITE); @@ -360,7 +385,7 @@ public class Bullets implements ContentList{ tile = tile.target(); if(tile != null && tile.getTeam() == b.getTeam() && !(tile.block() instanceof BuildBlock)){ - Effects.effect(Fx.healBlockFull, Palette.heal, tile.drawx(), tile.drawy(), tile.block().size); + Effects.effect(Fx.healBlockFull, Pal.heal, tile.drawx(), tile.drawy(), tile.block().size); tile.entity.healBy(healPercent / 100f * tile.entity.maxHealth()); } } @@ -384,7 +409,7 @@ public class Bullets implements ContentList{ @Override public void draw(Bullet b){ //TODO add color to the bullet depending on the color of the flame it came from - Draw.color(Palette.lightFlame, Palette.darkFlame, Color.GRAY, b.fin()); + Draw.color(Pal.lightFlame, Pal.darkFlame, Color.GRAY, b.fin()); Fill.circle(b.x, b.y, 3f * b.fout()); Draw.reset(); } @@ -427,10 +452,10 @@ public class Bullets implements ContentList{ }; lancerLaser = new BulletType(0.001f, 140){ - Color[] colors = {Palette.lancerLaser.cpy().mul(1f, 1f, 1f, 0.4f), Palette.lancerLaser, Color.WHITE}; + 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 = 100f; + float length = 160f; { hitEffect = Fx.hitLancer; @@ -440,6 +465,11 @@ public class Bullets implements ContentList{ 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); @@ -462,7 +492,7 @@ public class Bullets implements ContentList{ } }; - meltdownLaser = new BulletType(0.001f, 26){ + meltdownLaser = new BulletType(0.001f, 35){ Color tmpColor = new Color(); Color[] colors = {Color.valueOf("ec745855"), Color.valueOf("ec7458aa"), Color.valueOf("ff9c5a"), Color.WHITE}; float[] tscales = {1f, 0.7f, 0.5f, 0.2f}; @@ -532,7 +562,7 @@ public class Bullets implements ContentList{ @Override public void draw(Bullet b) { super.draw(b); - Draw.color(Color.WHITE, Palette.surge, b.fin()); + Draw.color(Color.WHITE, Pal.surge, b.fin()); for(int i = 0; i < 7; i++){ Tmp.v1.trns(b.rot(), i * 8f); float sl = Mathf.clamp(b.fout()-0.5f) * (80f - i *10); @@ -546,7 +576,7 @@ public class Bullets implements ContentList{ }; waterShot = new LiquidBulletType(Liquids.water){{ - knockback = 0.65f; + knockback = 0.7f; }}; cryoShot = new LiquidBulletType(Liquids.cryofluid){{ @@ -559,6 +589,12 @@ public class Bullets implements ContentList{ drag = 0.03f; }}; + eruptorShot = new LiquidBulletType(Liquids.slag){{ + damage = 2; + speed = 2.1f; + drag = 0.02f; + }}; + oilShot = new LiquidBulletType(Liquids.oil){{ speed = 2f; drag = 0.03f; @@ -578,11 +614,11 @@ public class Bullets implements ContentList{ @Override public void init(Bullet b){ - Lightning.create(b.getTeam(), Palette.lancerLaser, damage, b.x, b.y, b.rot(), 30); + Lightning.create(b.getTeam(), Pal.lancerLaser, damage, b.x, b.y, b.rot(), 30); } }; - arc = new BulletType(0.001f, 26){{ + arc = new BulletType(0.001f, 20){{ lifetime = 1; despawnEffect = Fx.none; hitEffect = Fx.hitLancer; @@ -593,7 +629,7 @@ public class Bullets implements ContentList{ @Override public void init(Bullet b){ - Lightning.create(b.getTeam(), Palette.lancerLaser, damage, b.x, b.y, b.rot(), 36); + Lightning.create(b.getTeam(), Pal.lancerLaser, damage, b.x, b.y, b.rot(), 14); } }; @@ -617,8 +653,8 @@ public class Bullets implements ContentList{ bulletWidth = 8f; bulletHeight = 12f; hitEffect = Fx.flakExplosion; - backColor = Palette.lightOrange; - frontColor = Palette.lightishOrange; + backColor = Pal.lightOrange; + frontColor = Pal.lightishOrange; incendChance = 1f; incendAmount = 3; incendSpread = 10f; diff --git a/core/src/io/anuke/mindustry/content/Fx.java b/core/src/io/anuke/mindustry/content/Fx.java index 3cf94dd06f..0b7c5221e5 100644 --- a/core/src/io/anuke/mindustry/content/Fx.java +++ b/core/src/io/anuke/mindustry/content/Fx.java @@ -1,7 +1,7 @@ package io.anuke.mindustry.content; import io.anuke.arc.Core; -import io.anuke.arc.entities.Effects.Effect; +import io.anuke.mindustry.entities.Effects.Effect; import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.graphics.g2d.Fill; @@ -10,8 +10,9 @@ import io.anuke.arc.math.Angles; import io.anuke.arc.math.Mathf; import io.anuke.arc.util.Tmp; import io.anuke.mindustry.entities.effect.GroundEffectEntity.GroundEffect; +import io.anuke.mindustry.entities.type.BaseUnit; import io.anuke.mindustry.game.ContentList; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.graphics.Shapes; import io.anuke.mindustry.type.Item; @@ -32,29 +33,43 @@ public class Fx implements ContentList{ bigShockwave, nuclearShockwave, explosion, blockExplosion, blockExplosionSmoke, shootSmall, shootHeal, shootSmallSmoke, shootBig, shootBig2, shootBigSmoke, shootBigSmoke2, shootSmallFlame, shootLiquid, shellEjectSmall, shellEjectMedium, shellEjectBig, lancerLaserShoot, lancerLaserShootSmoke, lancerLaserCharge, lancerLaserChargeBegin, lightningCharge, lightningShoot, - launchFull; + launchFull, unitSpawn, spawnShockwave, magmasmoke; @Override public void load(){ none = new Effect(0, 0f, e -> {}); + unitSpawn = new Effect(30f, e -> { + if(!(e.data instanceof BaseUnit)) return; + + Draw.alpha(e.fin()); + + float scl = 1f + e.fout()*2f; + + 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); + + Draw.reset(); + }); + placeBlock = new Effect(16, e -> { - Draw.color(Palette.accent); + Draw.color(Pal.accent); Lines.stroke(3f - e.fin() * 2f); Lines.square(e.x, e.y, tilesize / 2f * e.rotation + e.fin() * 3f); Draw.reset(); }); tapBlock = new Effect(12, e -> { - Draw.color(Palette.accent); + Draw.color(Pal.accent); Lines.stroke(3f - e.fin() * 2f); Lines.circle(e.x, e.y, 4f + (tilesize / 1.5f * e.rotation) * e.fin()); Draw.reset(); }); breakBlock = new Effect(12, e -> { - Draw.color(Palette.remove); + Draw.color(Pal.remove); Lines.stroke(3f - e.fin() * 2f); Lines.square(e.x, e.y, tilesize / 2f * e.rotation + e.fin() * 3f); @@ -65,36 +80,42 @@ public class Fx implements ContentList{ }); select = new Effect(23, e -> { - Draw.color(Palette.accent); + Draw.color(Pal.accent); Lines.stroke(e.fout() * 3f); Lines.circle(e.x, e.y, 3f + e.fin() * 14f); Draw.reset(); }); smoke = new Effect(100, e -> { - Draw.color(Color.GRAY, Palette.darkishGray, e.fin()); + Draw.color(Color.GRAY, Pal.darkishGray, e.fin()); float size = 7f - e.fin() * 7f; Draw.rect("circle", e.x, e.y, size, size); Draw.reset(); }); - spawn = new Effect(23, e -> { + magmasmoke = new Effect(110, e -> { + Draw.color(Color.GRAY); + Fill.circle(e.x, e.y, e.fslope() * 6f); + Draw.reset(); + }); + + spawn = new Effect(30, e -> { Lines.stroke(2f * e.fout()); - Draw.color(Palette.accent); - Lines.poly(e.x, e.y, 4, 3f + e.fin() * 8f); + Draw.color(Pal.accent); + Lines.poly(e.x, e.y, 4, 5f + e.fin() * 12f); Draw.reset(); }); vtolHover = new Effect(40f, e -> { float len = e.finpow() * 10f; float ang = e.rotation + Mathf.randomSeedRange(e.id, 30f); - Draw.color(Palette.lightFlame, Palette.lightOrange, e.fin()); + 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()); Draw.reset(); }); unitDrop = new GroundEffect(30, e -> { - Draw.color(Palette.lightishGray); + 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); }); @@ -102,7 +123,7 @@ public class Fx implements ContentList{ }); unitLand = new GroundEffect(30, e -> { - Draw.color(Palette.lightishGray, e.color, e.rotation); + 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); }); @@ -110,35 +131,35 @@ public class Fx implements ContentList{ }); unitPickup = new GroundEffect(18, e -> { - Draw.color(Palette.lightishGray); + Draw.color(Pal.lightishGray); Lines.stroke(e.fin() * 2f); Lines.poly(e.x, e.y, 4, 13f * e.fout()); Draw.reset(); }); landShock = new GroundEffect(12, e -> { - Draw.color(Palette.lancerLaser); + Draw.color(Pal.lancerLaser); Lines.stroke(e.fout() * 3f); Lines.poly(e.x, e.y, 12, 20f * e.fout()); Draw.reset(); }); pickup = new Effect(18, e -> { - Draw.color(Palette.lightishGray); + Draw.color(Pal.lightishGray); Lines.stroke(e.fout() * 2f); Lines.spikes(e.x, e.y, 1f + e.fin() * 6f, e.fout() * 4f, 6); Draw.reset(); }); healWave = new Effect(22, e -> { - Draw.color(Palette.heal); + Draw.color(Pal.heal); Lines.stroke(e.fout() * 2f); Lines.poly(e.x, e.y, 30, 4f + e.finpow() * 60f); Draw.color(); }); heal = new Effect(11, e -> { - Draw.color(Palette.heal); + Draw.color(Pal.heal); Lines.stroke(e.fout() * 2f); Lines.poly(e.x, e.y, 10, 2f + e.finpow() * 7f); Draw.color(); @@ -146,7 +167,7 @@ public class Fx implements ContentList{ hitBulletSmall = new Effect(14, e -> { - Draw.color(Color.WHITE, Palette.lightOrange, e.fin()); + Draw.color(Color.WHITE, Pal.lightOrange, e.fin()); e.scaled(7f, s -> { Lines.stroke(0.5f + s.fout()); @@ -165,7 +186,7 @@ public class Fx implements ContentList{ }); hitFuse = new Effect(14, e -> { - Draw.color(Color.WHITE, Palette.surge, e.fin()); + Draw.color(Color.WHITE, Pal.surge, e.fin()); e.scaled(7f, s -> { Lines.stroke(0.5f + s.fout()); @@ -184,7 +205,7 @@ public class Fx implements ContentList{ }); hitBulletBig = new Effect(13, e -> { - Draw.color(Color.WHITE, Palette.lightOrange, e.fin()); + 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) -> { @@ -196,7 +217,7 @@ public class Fx implements ContentList{ }); hitFlameSmall = new Effect(14, e -> { - Draw.color(Palette.lightFlame, Palette.darkFlame, e.fin()); + Draw.color(Pal.lightFlame, Pal.darkFlame, e.fin()); Lines.stroke(0.5f + e.fout()); Angles.randLenVectors(e.id, 5, e.fin() * 15f, e.rotation, 50f, (x, y) -> { @@ -230,7 +251,7 @@ public class Fx implements ContentList{ }); hitMeltdown = new Effect(12, e -> { - Draw.color(Palette.meltdownHit); + Draw.color(Pal.meltdownHit); Lines.stroke(e.fout() * 2f); Angles.randLenVectors(e.id, 6, e.finpow() * 18f, e.rotation, 360f, (x, y) -> { @@ -242,14 +263,14 @@ public class Fx implements ContentList{ }); hitLaser = new Effect(8, e -> { - Draw.color(Color.WHITE, Palette.heal, e.fin()); + Draw.color(Color.WHITE, Pal.heal, e.fin()); Lines.stroke(0.5f + e.fout()); Lines.circle(e.x, e.y, e.fin()*5f); Draw.reset(); }); despawn = new Effect(12, e -> { - Draw.color(Palette.lighterOrange, Color.GRAY, e.fin()); + Draw.color(Pal.lighterOrange, Color.GRAY, e.fin()); Lines.stroke(e.fout()); Angles.randLenVectors(e.id, 7, e.fin() * 7f, e.rotation, 40f, (x, y) -> { @@ -262,7 +283,7 @@ public class Fx implements ContentList{ flakExplosion = new Effect(20, e -> { - Draw.color(Palette.bulletYellow); + Draw.color(Pal.bulletYellow); e.scaled(6, i -> { Lines.stroke(3f * i.fout()); Lines.circle(e.x, e.y, 3f + i.fin() * 10f); @@ -274,7 +295,7 @@ public class Fx implements ContentList{ Fill.circle(e.x + x, e.y + y, e.fout() * 3f + 0.5f); }); - Draw.color(Palette.lighterOrange); + Draw.color(Pal.lighterOrange); Lines.stroke(1f * e.fout()); Angles.randLenVectors(e.id + 1, 4, 1f + 23f * e.finpow(), (x, y) -> { @@ -286,7 +307,7 @@ public class Fx implements ContentList{ plasticExplosion = new Effect(24, e -> { - Draw.color(Palette.plastaniumFront); + Draw.color(Pal.plastaniumFront); e.scaled(7, i -> { Lines.stroke(3f * i.fout()); Lines.circle(e.x, e.y, 3f + i.fin() * 24f); @@ -298,7 +319,7 @@ public class Fx implements ContentList{ Fill.circle(e.x + x, e.y + y, e.fout() * 4f + 0.5f); }); - Draw.color(Palette.plastaniumBack); + Draw.color(Pal.plastaniumBack); Lines.stroke(1f * e.fout()); Angles.randLenVectors(e.id + 1, 4, 1f + 25f * e.finpow(), (x, y) -> { @@ -310,7 +331,7 @@ public class Fx implements ContentList{ plasticExplosionFlak = new Effect(28, e -> { - Draw.color(Palette.plastaniumFront); + Draw.color(Pal.plastaniumFront); e.scaled(7, i -> { Lines.stroke(3f * i.fout()); Lines.circle(e.x, e.y, 3f + i.fin() * 34f); @@ -322,7 +343,7 @@ public class Fx implements ContentList{ Fill.circle(e.x + x, e.y + y, e.fout() * 4f + 0.5f); }); - Draw.color(Palette.plastaniumBack); + Draw.color(Pal.plastaniumBack); Lines.stroke(1f * e.fout()); Angles.randLenVectors(e.id + 1, 4, 1f + 30f * e.finpow(), (x, y) -> { @@ -334,7 +355,7 @@ public class Fx implements ContentList{ blastExplosion = new Effect(22, e -> { - Draw.color(Palette.missileYellow); + Draw.color(Pal.missileYellow); e.scaled(6, i -> { Lines.stroke(3f * i.fout()); Lines.circle(e.x, e.y, 3f + i.fin() * 15f); @@ -346,7 +367,7 @@ public class Fx implements ContentList{ Fill.circle(e.x + x, e.y + y, e.fout() * 4f + 0.5f); }); - Draw.color(Palette.missileYellowBack); + Draw.color(Pal.missileYellowBack); Lines.stroke(1f * e.fout()); Angles.randLenVectors(e.id + 1, 4, 1f + 23f * e.finpow(), (x, y) -> { @@ -363,7 +384,7 @@ public class Fx implements ContentList{ }); incendTrail = new Effect(50, e -> { - Draw.color(Palette.lightOrange); + Draw.color(Pal.lightOrange); Fill.circle(e.x, e.y, e.rotation * e.fout()); Draw.reset(); }); @@ -375,7 +396,7 @@ public class Fx implements ContentList{ }); absorb = new Effect(12, e -> { - Draw.color(Palette.accent); + Draw.color(Pal.accent); Lines.stroke(2f * e.fout()); Lines.circle(e.x, e.y, 5f * e.fout()); Draw.reset(); @@ -383,7 +404,7 @@ public class Fx implements ContentList{ flakExplosionBig = new Effect(30, e -> { - Draw.color(Palette.bulletYellowBack); + Draw.color(Pal.bulletYellowBack); e.scaled(6, i -> { Lines.stroke(3f * i.fout()); Lines.circle(e.x, e.y, 3f + i.fin() * 25f); @@ -395,7 +416,7 @@ public class Fx implements ContentList{ Fill.circle(e.x + x, e.y + y, e.fout() * 4f + 0.5f); }); - Draw.color(Palette.bulletYellow); + Draw.color(Pal.bulletYellow); Lines.stroke(1f * e.fout()); Angles.randLenVectors(e.id + 1, 4, 1f + 23f * e.finpow(), (x, y) -> { @@ -407,7 +428,7 @@ public class Fx implements ContentList{ burning = new Effect(35f, e -> { - Draw.color(Palette.lightFlame, Palette.darkFlame, e.fin()); + 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); @@ -417,7 +438,7 @@ public class Fx implements ContentList{ }); fire = new Effect(35f, e -> { - Draw.color(Palette.lightFlame, Palette.darkFlame, e.fin()); + 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.fslope() * 1.5f); @@ -457,7 +478,7 @@ public class Fx implements ContentList{ }); ballfire = new Effect(25f, e -> { - Draw.color(Palette.lightFlame, Palette.darkFlame, e.fin()); + 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); @@ -507,7 +528,7 @@ public class Fx implements ContentList{ }); overdriven = new Effect(20f, e -> { - Draw.color(Palette.accent); + 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); @@ -545,6 +566,13 @@ public class Fx implements ContentList{ Draw.reset(); }); + spawnShockwave = new Effect(20f, 400f, e -> { + Draw.color(Color.WHITE, Color.LIGHT_GRAY, e.fin()); + Lines.stroke(e.fout() * 3f + 0.5f); + Lines.poly(e.x, e.y, 60, e.fin() * 450f); + Draw.reset(); + }); + explosion = new Effect(30, e -> { e.scaled(7, i -> { Lines.stroke(3f * i.fout()); @@ -558,7 +586,7 @@ public class Fx implements ContentList{ Fill.circle(e.x + x / 2f, e.y + y / 2f, e.fout() * 1f); }); - Draw.color(Palette.lighterOrange, Palette.lightOrange, Color.GRAY, e.fin()); + 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) -> { @@ -581,7 +609,7 @@ public class Fx implements ContentList{ Fill.circle(e.x + x / 2f, e.y + y / 2f, e.fout() * 1f); }); - Draw.color(Palette.lighterOrange, Palette.lightOrange, Color.GRAY, e.fin()); + Draw.color(Pal.lighterOrange, Pal.lightOrange, Color.GRAY, e.fin()); Lines.stroke(1.7f * e.fout()); Angles.randLenVectors(e.id + 1, 9, 1f + 23f * e.finpow(), (x, y) -> { @@ -604,7 +632,7 @@ public class Fx implements ContentList{ shootSmall = new Effect(8, e -> { - Draw.color(Palette.lighterOrange, Palette.lightOrange, e.fin()); + Draw.color(Pal.lighterOrange, Pal.lightOrange, e.fin()); float w = 1f + 5 * e.fout(); Shapes.tri(e.x, e.y, w, 15f * e.fout(), e.rotation); Shapes.tri(e.x, e.y, w, 3f * e.fout(), e.rotation + 180f); @@ -612,7 +640,7 @@ public class Fx implements ContentList{ }); shootHeal = new Effect(8, e -> { - Draw.color(Palette.heal); + Draw.color(Pal.heal); float w = 1f + 5 * e.fout(); Shapes.tri(e.x, e.y, w, 17f * e.fout(), e.rotation); Shapes.tri(e.x, e.y, w, 4f * e.fout(), e.rotation + 180f); @@ -620,7 +648,7 @@ public class Fx implements ContentList{ }); shootSmallSmoke = new Effect(20f, e -> { - Draw.color(Palette.lighterOrange, Color.LIGHT_GRAY, Color.GRAY, e.fin()); + Draw.color(Pal.lighterOrange, Color.LIGHT_GRAY, 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); @@ -630,7 +658,7 @@ public class Fx implements ContentList{ }); shootBig = new Effect(9, e -> { - Draw.color(Palette.lighterOrange, Palette.lightOrange, e.fin()); + Draw.color(Pal.lighterOrange, Pal.lightOrange, e.fin()); float w = 1.2f + 7 * e.fout(); Shapes.tri(e.x, e.y, w, 25f * e.fout(), e.rotation); Shapes.tri(e.x, e.y, w, 4f * e.fout(), e.rotation + 180f); @@ -638,7 +666,7 @@ public class Fx implements ContentList{ }); shootBig2 = new Effect(10, e -> { - Draw.color(Palette.lightOrange, Color.GRAY, e.fin()); + Draw.color(Pal.lightOrange, Color.GRAY, e.fin()); float w = 1.2f + 8 * e.fout(); Shapes.tri(e.x, e.y, w, 29f * e.fout(), e.rotation); Shapes.tri(e.x, e.y, w, 5f * e.fout(), e.rotation + 180f); @@ -646,7 +674,7 @@ public class Fx implements ContentList{ }); shootBigSmoke = new Effect(17f, e -> { - Draw.color(Palette.lighterOrange, Color.LIGHT_GRAY, Color.GRAY, e.fin()); + Draw.color(Pal.lighterOrange, Color.LIGHT_GRAY, Color.GRAY, e.fin()); 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); @@ -656,7 +684,7 @@ public class Fx implements ContentList{ }); shootBigSmoke2 = new Effect(18f, e -> { - Draw.color(Palette.lightOrange, Color.LIGHT_GRAY, Color.GRAY, e.fin()); + Draw.color(Pal.lightOrange, Color.LIGHT_GRAY, 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); @@ -666,7 +694,7 @@ public class Fx implements ContentList{ }); shootSmallFlame = new Effect(32f, e -> { - Draw.color(Palette.lightFlame, Palette.darkFlame, Color.GRAY, e.fin()); + Draw.color(Pal.lightFlame, Pal.darkFlame, Color.GRAY, e.fin()); Angles.randLenVectors(e.id, 8, e.finpow() * 44f, e.rotation, 10f, (x, y) -> { Fill.circle(e.x + x, e.y + y, 0.65f + e.fout() * 1.5f); @@ -686,7 +714,7 @@ public class Fx implements ContentList{ }); shellEjectSmall = new GroundEffect(30f, 400f, e -> { - Draw.color(Palette.lightOrange, Color.LIGHT_GRAY, Palette.lightishGray, e.fin()); + Draw.color(Pal.lightOrange, Color.LIGHT_GRAY, Pal.lightishGray, e.fin()); float rot = Math.abs(e.rotation) + 90f; int i = Mathf.sign(e.rotation); @@ -701,7 +729,7 @@ public class Fx implements ContentList{ }); shellEjectMedium = new GroundEffect(34f, 400f, e -> { - Draw.color(Palette.lightOrange, Color.LIGHT_GRAY, Palette.lightishGray, e.fin()); + Draw.color(Pal.lightOrange, Color.LIGHT_GRAY, Pal.lightishGray, e.fin()); float rot = e.rotation + 90f; for(int i : Mathf.signs){ float len = (2f + e.finpow() * 10f) * i; @@ -724,7 +752,7 @@ public class Fx implements ContentList{ }); shellEjectBig = new GroundEffect(22f, 400f, e -> { - Draw.color(Palette.lightOrange, Color.LIGHT_GRAY, Palette.lightishGray, e.fin()); + Draw.color(Pal.lightOrange, Color.LIGHT_GRAY, Pal.lightishGray, e.fin()); float rot = e.rotation + 90f; for(int i : Mathf.signs){ float len = (4f + e.finpow() * 8f) * i; @@ -748,7 +776,7 @@ public class Fx implements ContentList{ }); lancerLaserShoot = new Effect(21f, e -> { - Draw.color(Palette.lancerLaser); + Draw.color(Pal.lancerLaser); for(int i : Mathf.signs){ Shapes.tri(e.x, e.y, 4f * e.fout(), 29f, e.rotation + 90f * i); @@ -758,7 +786,7 @@ public class Fx implements ContentList{ }); lancerLaserShootSmoke = new Effect(26f, e -> { - Draw.color(Palette.lancerLaser); + Draw.color(Pal.lancerLaser); 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); @@ -768,7 +796,7 @@ public class Fx implements ContentList{ }); lancerLaserCharge = new Effect(38f, e -> { - Draw.color(Palette.lancerLaser); + Draw.color(Pal.lancerLaser); 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); @@ -778,7 +806,7 @@ public class Fx implements ContentList{ }); lancerLaserChargeBegin = new Effect(71f, e -> { - Draw.color(Palette.lancerLaser); + Draw.color(Pal.lancerLaser); Fill.circle(e.x, e.y, e.fin() * 3f); Draw.color(); @@ -786,7 +814,7 @@ public class Fx implements ContentList{ }); lightningCharge = new Effect(38f, e -> { - Draw.color(Palette.lancerLaser); + Draw.color(Pal.lancerLaser); Angles.randLenVectors(e.id, 2, 1f + 20f * e.fout(), e.rotation, 120f, (x, y) -> { Shapes.tri(e.x + x, e.y + y, e.fslope() * 3f + 1, e.fslope() * 3f + 1, Mathf.angle(x, y)); @@ -796,7 +824,7 @@ public class Fx implements ContentList{ }); lightningShoot = new Effect(12f, e -> { - Draw.color(Color.WHITE, Palette.lancerLaser, e.fin()); + 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) -> { @@ -834,8 +862,7 @@ public class Fx implements ContentList{ redgeneratespark = new Effect(18, e -> { Angles.randLenVectors(e.id, 5, e.fin() * 8f, (x, y) -> { float len = e.fout() * 4f; - Draw.color(Palette.redSpark, Color.GRAY, e.fin()); - //Draw.alpha(e.fout()); + Draw.color(Pal.redSpark, Color.GRAY, e.fin()); Draw.rect("circle", e.x + x, e.y + y, len, len); Draw.reset(); }); @@ -843,7 +870,7 @@ public class Fx implements ContentList{ generatespark = new Effect(18, e -> { Angles.randLenVectors(e.id, 5, e.fin() * 8f, (x, y) -> { float len = e.fout() * 4f; - Draw.color(Palette.orangeSpark, Color.GRAY, e.fin()); + Draw.color(Pal.orangeSpark, Color.GRAY, e.fin()); Draw.rect("circle", e.x + x, e.y + y, len, len); Draw.reset(); }); @@ -865,42 +892,42 @@ public class Fx implements ContentList{ }); pulverize = new Effect(40, e -> { Angles.randLenVectors(e.id, 5, 3f + e.fin() * 8f, (x, y) -> { - Draw.color(Palette.stoneGray); + Draw.color(Pal.stoneGray); Fill.square(e.x + x, e.y + y, e.fout() * 2f + 0.5f, 45); Draw.reset(); }); }); pulverizeRed = new Effect(40, e -> { Angles.randLenVectors(e.id, 5, 3f + e.fin() * 8f, (x, y) -> { - Draw.color(Palette.redDust, Palette.stoneGray, e.fin()); + Draw.color(Pal.redDust, Pal.stoneGray, e.fin()); Fill.square(e.x + x, e.y + y, e.fout() * 2f + 0.5f, 45); Draw.reset(); }); }); pulverizeRedder = new Effect(40, e -> { Angles.randLenVectors(e.id, 5, 3f + e.fin() * 9f, (x, y) -> { - Draw.color(Palette.redderDust, Palette.stoneGray, e.fin()); + Draw.color(Pal.redderDust, Pal.stoneGray, e.fin()); Fill.square(e.x + x, e.y + y, e.fout() * 2.5f + 0.5f, 45); Draw.reset(); }); }); pulverizeSmall = new Effect(30, e -> { Angles.randLenVectors(e.id, 3, e.fin() * 5f, (x, y) -> { - Draw.color(Palette.stoneGray); + Draw.color(Pal.stoneGray); Fill.square(e.x + x, e.y + y, e.fout() * 1f + 0.5f, 45); Draw.reset(); }); }); pulverizeMedium = new Effect(30, e -> { Angles.randLenVectors(e.id, 5, 3f + e.fin() * 8f, (x, y) -> { - Draw.color(Palette.stoneGray); + Draw.color(Pal.stoneGray); Fill.square(e.x + x, e.y + y, e.fout() * 1f + 0.5f, 45); Draw.reset(); }); }); producesmoke = new Effect(12, e -> { Angles.randLenVectors(e.id, 8, 4f + e.fin() * 18f, (x, y) -> { - Draw.color(Color.WHITE, Palette.accent, e.fin()); + Draw.color(Color.WHITE, Pal.accent, e.fin()); Fill.square(e.x + x, e.y + y, 1f + e.fout() * 3f, 45); Draw.reset(); }); @@ -914,7 +941,7 @@ public class Fx implements ContentList{ }); formsmoke = new Effect(40, e -> { Angles.randLenVectors(e.id, 6, 5f + e.fin() * 8f, (x, y) -> { - Draw.color(Palette.plasticSmoke, Color.LIGHT_GRAY, e.fin()); + Draw.color(Pal.plasticSmoke, Color.LIGHT_GRAY, e.fin()); Fill.square(e.x + x, e.y + y, 0.2f + e.fout() * 2f, 45); Draw.reset(); }); @@ -1046,7 +1073,7 @@ public class Fx implements ContentList{ Draw.reset(); }); ripple = new GroundEffect(false, 30, e -> { - Draw.color(Tmp.c1.set(e.color).shiftValue(0.1f)); + 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); Draw.reset(); @@ -1062,7 +1089,7 @@ public class Fx implements ContentList{ }); launch = new Effect(28, e -> { - Draw.color(Palette.command); + Draw.color(Pal.command); Lines.stroke(e.fout() * 2f); Lines.poly(e.x, e.y, 40, 4f + e.finpow() * 120f); Draw.color(); @@ -1083,7 +1110,7 @@ public class Fx implements ContentList{ }); healBlock = new Effect(20, e -> { - Draw.color(Palette.heal); + 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)); Draw.color(); @@ -1104,7 +1131,7 @@ public class Fx implements ContentList{ }); shieldBreak = new Effect(40, e -> { - Draw.color(Palette.accent); + Draw.color(Pal.accent); Lines.stroke(3f * e.fout()); Lines.poly(e.x, e.y, 6, e.rotation + e.fin(), 90); Draw.reset(); diff --git a/core/src/io/anuke/mindustry/content/Items.java b/core/src/io/anuke/mindustry/content/Items.java index a3e7279909..d7f8516505 100644 --- a/core/src/io/anuke/mindustry/content/Items.java +++ b/core/src/io/anuke/mindustry/content/Items.java @@ -37,8 +37,8 @@ public class Items implements ContentList{ }}; coal = new Item("coal", Color.valueOf("272727")){{ - explosiveness = 0.2f; - flammability = 0.5f; + explosiveness = 0.4f; + flammability = 1f; hardness = 2; genOre = true; }}; @@ -52,9 +52,9 @@ public class Items implements ContentList{ thorium = new Item("thorium", Color.valueOf("f9a3c7")){{ type = ItemType.material; - explosiveness = 0.1f; + explosiveness = 0.2f; hardness = 4; - radioactivity = 0.5f; + radioactivity = 1f; cost = 1.4f; genOre = true; }}; @@ -70,16 +70,15 @@ public class Items implements ContentList{ plastanium = new Item("plastanium", Color.valueOf("cbd97f")){{ type = ItemType.material; - flammability = 0.1f; - explosiveness = 0.1f; + flammability = 0.2f; + explosiveness = 0.2f; cost = 1.6f; }}; phasefabric = new Item("phase-fabric", Color.valueOf("f4ba6e")){{ type = ItemType.material; cost = 1.5f; - fluxiness = 0.9f; - radioactivity = 0.3f; + radioactivity = 0.6f; }}; surgealloy = new Item("surge-alloy", Color.valueOf("f3e979")){{ @@ -87,22 +86,21 @@ public class Items implements ContentList{ }}; biomatter = new Item("biomatter", Color.valueOf("648b55")){{ - flammability = 0.55f; - fluxiness = 0.3f; + flammability = 1.05f; }}; sand = new Item("sand", Color.valueOf("e3d39e")){{ - fluxiness = 0.5f; + }}; blastCompound = new Item("blast-compound", Color.valueOf("ff795e")){{ - flammability = 0.2f; - explosiveness = 0.6f; + flammability = 0.4f; + explosiveness = 1.2f; }}; pyratite = new Item("pyratite", Color.valueOf("ffaa5f")){{ - flammability = 0.7f; - explosiveness = 0.2f; + flammability = 1.4f; + explosiveness = 0.4f; }}; } } diff --git a/core/src/io/anuke/mindustry/content/Liquids.java b/core/src/io/anuke/mindustry/content/Liquids.java index f7f120725f..dadd720f47 100644 --- a/core/src/io/anuke/mindustry/content/Liquids.java +++ b/core/src/io/anuke/mindustry/content/Liquids.java @@ -10,13 +10,13 @@ public class Liquids implements ContentList{ @Override public void load(){ - water = new Liquid("water", Color.valueOf("486acd")){{ + water = new Liquid("water", Color.valueOf("596ab8")){{ heatCapacity = 0.4f; tier = 0; effect = StatusEffects.wet; }}; - slag = new Liquid("slag", Color.valueOf("ffcd66")){{ + slag = new Liquid("slag", Color.valueOf("ffa166")){{ temperature = 1f; viscosity = 0.8f; tier = 2; @@ -25,8 +25,8 @@ public class Liquids implements ContentList{ oil = new Liquid("oil", Color.valueOf("313131")){{ viscosity = 0.7f; - flammability = 0.6f; - explosiveness = 0.6f; + flammability = 1.2f; + explosiveness = 1.2f; heatCapacity = 0.7f; tier = 1; effect = StatusEffects.tarred; diff --git a/core/src/io/anuke/mindustry/content/Mechs.java b/core/src/io/anuke/mindustry/content/Mechs.java index 59e654c357..5695a681bd 100644 --- a/core/src/io/anuke/mindustry/content/Mechs.java +++ b/core/src/io/anuke/mindustry/content/Mechs.java @@ -1,7 +1,6 @@ package io.anuke.mindustry.content; import io.anuke.arc.Core; -import io.anuke.arc.entities.Effects; import io.anuke.arc.graphics.Blending; import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.g2d.Draw; @@ -9,13 +8,15 @@ import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.math.Mathf; import io.anuke.arc.math.geom.Rectangle; import io.anuke.arc.util.Time; -import io.anuke.mindustry.entities.Player; +import io.anuke.mindustry.entities.Effects; import io.anuke.mindustry.entities.Units; import io.anuke.mindustry.entities.effect.Lightning; +import io.anuke.mindustry.entities.type.Player; import io.anuke.mindustry.game.ContentList; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.graphics.Shaders; import io.anuke.mindustry.type.Mech; +import io.anuke.mindustry.type.Weapon; public class Mechs implements ContentList{ public static Mech alpha, delta, tau, omega, dart, javelin, trident, glaive; @@ -34,9 +35,16 @@ public class Mechs implements ContentList{ mass = 1.2f; speed = 0.5f; boostSpeed = 0.85f; - weapon = Weapons.blaster; - trailColorTo = Color.valueOf("ffd37f"); - armor = 20f; + engineColor = Color.valueOf("ffd37f"); + health = 250f; + + weapon = new Weapon("blaster"){{ + length = 1.5f; + reload = 14f; + roundrobin = true; + ejectEffect = Fx.shellEjectSmall; + bullet = Bullets.standardMechSmall; + }}; } @Override @@ -54,11 +62,21 @@ public class Mechs implements ContentList{ boostSpeed = 0.95f; itemCapacity = 15; mass = 0.9f; - armor = 30f; + health = 220f; weaponOffsetX = -1; weaponOffsetY = -1; - weapon = Weapons.shockgun; - trailColorTo = Color.valueOf("d3ddff"); + engineColor = Color.valueOf("d3ddff"); + + weapon = new Weapon("shockgun"){{ + length = 1f; + reload = 40f; + roundrobin = true; + shots = 1; + inaccuracy = 0f; + velocityRnd = 0.2f; + ejectEffect = Fx.none; + bullet = Bullets.lightning; + }}; } @Override @@ -67,7 +85,7 @@ public class Mechs implements ContentList{ 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(), Palette.lancerLaser, 17f, player.x, player.y, Mathf.random(360f), 14)); + Time.run(Mathf.random(8f), () -> Lightning.create(player.getTeam(), Pal.lancerLaser, 17f, player.x, player.y, Mathf.random(360f), 14)); } } } @@ -91,9 +109,17 @@ public class Mechs implements ContentList{ drag = 0.35f; boostSpeed = 0.8f; canHeal = true; - weapon = Weapons.healBlaster; - armor = 15f; - trailColorTo = Palette.heal; + health = 200f; + engineColor = Pal.heal; + + weapon = new Weapon("heal-blaster"){{ + length = 1.5f; + reload = 24f; + roundrobin = false; + ejectEffect = Fx.none; + recoil = 2f; + bullet = Bullets.healBullet; + }}; } @Override @@ -133,9 +159,20 @@ public class Mechs implements ContentList{ shake = 4f; weaponOffsetX = 1; weaponOffsetY = 0; - weapon = Weapons.swarmer; - trailColorTo = Color.valueOf("feb380"); - armor = 45f; + engineColor = Color.valueOf("feb380"); + health = 300f; + weapon = new Weapon("swarmer"){{ + length = 1.5f; + recoil = 4f; + reload = 60f; + shots = 4; + spacing = 8f; + inaccuracy = 8f; + roundrobin = true; + ejectEffect = Fx.none; + shake = 3f; + bullet = Bullets.missileSwarm; + }}; } @Override @@ -173,7 +210,7 @@ public class Mechs implements ContentList{ Shaders.build.progress = player.shootHeat; Shaders.build.region = armorRegion; Shaders.build.time = Time.time() / 10f; - Shaders.build.color.set(Palette.accent).a = player.shootHeat; + Shaders.build.color.set(Pal.accent).a = player.shootHeat; Draw.shader(Shaders.build); Draw.alpha(1f); Draw.rect(armorRegion, player.x, player.y, player.rotation); @@ -188,12 +225,18 @@ public class Mechs implements ContentList{ mineSpeed = 0.9f; speed = 0.4f; drag = 0.1f; - armor = 10f; - weapon = Weapons.blasterSmall; + health = 180f; weaponOffsetX = -1; weaponOffsetY = -1; - trailColor = Palette.lightTrail; + engineColor = Pal.lightTrail; cellTrnsY = 1f; + weapon = new Weapon("blaster"){{ + length = 1.5f; + reload = 20f; + roundrobin = true; + ejectEffect = Fx.shellEjectSmall; + bullet = Bullets.standardCopper; + }}; } @Override @@ -211,10 +254,20 @@ public class Mechs implements ContentList{ speed = 0.11f; drag = 0.01f; mass = 2f; - armor = 5f; - weapon = Weapons.missiles; - trailColor = Color.valueOf("d3ddff"); + health = 170f; + engineColor = Color.valueOf("d3ddff"); cellTrnsY = 1f; + weapon = new Weapon("missiles"){{ + length = 1.5f; + reload = 70f; + shots = 4; + inaccuracy = 2f; + roundrobin = true; + ejectEffect = Fx.none; + velocityRnd = 0.2f; + spacing = 1f; + bullet = Bullets.missileJavelin; + }}; } @Override @@ -232,8 +285,8 @@ public class Mechs implements ContentList{ public void updateAlt(Player player){ float scl = scld(player); if(Mathf.chance(Time.delta() * (0.15*scl))){ - Effects.effect(Fx.hitLancer, Palette.lancerLaser, player.x, player.y); - Lightning.create(player.getTeam(), Palette.lancerLaser, 10f, + Effects.effect(Fx.hitLancer, Pal.lancerLaser, player.x, player.y); + Lightning.create(player.getTeam(), Pal.lancerLaser, 10f, player.x + player.velocity().x, player.y + player.velocity().y, player.rotation, 14); } } @@ -244,7 +297,7 @@ public class Mechs implements ContentList{ if(scl < 0.01f) return; float alpha = Draw.getColor().a; Draw.shader(); - Draw.color(Palette.lancerLaser); + 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); @@ -266,11 +319,22 @@ public class Mechs implements ContentList{ drag = 0.034f; mass = 2.5f; turnCursor = false; - armor = 20f; + health = 220f; itemCapacity = 30; - trailColor = Color.valueOf("84f491"); - weapon = Weapons.bomberTrident; + engineColor = Color.valueOf("84f491"); cellTrnsY = 1f; + weapon = new Weapon("bomber"){{ + length = 0f; + width = 2f; + reload = 8f; + shots = 2; + roundrobin = true; + ejectEffect = Fx.none; + velocityRnd = 1f; + inaccuracy = 40f; + ignoreRotation = true; + bullet = Bullets.bombExplosive; + }}; } @Override @@ -281,16 +345,23 @@ public class Mechs implements ContentList{ glaive = new Mech("glaive-ship", true){ { - weapon = Weapons.glaiveBlaster; drillPower = 4; mineSpeed = 1.3f; speed = 0.32f; drag = 0.06f; mass = 3f; - armor = 30f; + health = 240f; itemCapacity = 60; - trailColor = Color.valueOf("feb380"); + engineColor = Color.valueOf("feb380"); cellTrnsY = 1f; + + weapon = new Weapon("bomber"){{ + length = 1.5f; + reload = 13f; + roundrobin = true; + ejectEffect = Fx.shellEjectSmall; + bullet = Bullets.standardGlaive; + }}; } }; diff --git a/core/src/io/anuke/mindustry/content/StatusEffects.java b/core/src/io/anuke/mindustry/content/StatusEffects.java index fe676e591d..328a617c1f 100644 --- a/core/src/io/anuke/mindustry/content/StatusEffects.java +++ b/core/src/io/anuke/mindustry/content/StatusEffects.java @@ -1,6 +1,6 @@ package io.anuke.mindustry.content; -import io.anuke.arc.entities.Effects; +import io.anuke.mindustry.entities.Effects; import io.anuke.arc.math.Mathf; import io.anuke.mindustry.game.ContentList; import io.anuke.mindustry.type.StatusEffect; diff --git a/core/src/io/anuke/mindustry/content/TechTree.java b/core/src/io/anuke/mindustry/content/TechTree.java index 92e3103a91..4591469f55 100644 --- a/core/src/io/anuke/mindustry/content/TechTree.java +++ b/core/src/io/anuke/mindustry/content/TechTree.java @@ -12,7 +12,7 @@ public class TechTree implements ContentList{ @Override public void load(){ - root = node(core, () -> { + root = node(coreShard, () -> { node(conveyor, () -> { node(launchPad, () -> { @@ -31,11 +31,12 @@ public class TechTree implements ContentList{ }); }); - }); - node(titaniumConveyor, () -> { - node(phaseConveyor, () -> { - node(massDriver, () -> { + node(titaniumConveyor, () -> { + node(phaseConveyor, () -> { + node(massDriver, () -> { + + }); }); }); }); @@ -117,41 +118,51 @@ public class TechTree implements ContentList{ }); }); - node(siliconSmelter, () -> { - + node(graphitePress, () -> { node(pyratiteMixer, () -> { node(blastMixer, () -> { }); }); - node(biomatterCompressor, () -> { - node(plastaniumCompressor, () -> { - node(phaseWeaver, () -> { + node(siliconSmelter, () -> { - }); - }); - }); - - node(incinerator, () -> { - node(melter, () -> { - node(surgeSmelter, () -> { + node(biomatterCompressor, () -> { + node(multiPress, () -> { }); - node(separator, () -> { - node(pulverizer, () -> { + node(plastaniumCompressor, () -> { + node(phaseWeaver, () -> { }); }); + }); - node(cryofluidMixer, () -> { + node(kiln, () -> { + node(incinerator, () -> { + node(melter, () -> { + node(surgeSmelter, () -> { + }); + + node(separator, () -> { + node(pulverizer, () -> { + + }); + }); + + node(cryofluidMixer, () -> { + + }); + }); }); }); }); }); + + node(mechanicalPump, () -> { node(conduit, () -> { node(liquidJunction, () -> { @@ -181,7 +192,9 @@ public class TechTree implements ContentList{ node(powerNodeLarge, () -> { node(battery, () -> { node(batteryLarge, () -> { + node(surgeTower, () -> { + }); }); }); @@ -201,8 +214,12 @@ public class TechTree implements ContentList{ node(turbineGenerator, () -> { node(thermalGenerator, () -> { node(rtgGenerator, () -> { - node(thoriumReactor, () -> { + node(differentialGenerator, () -> { + node(thoriumReactor, () -> { + node(impactReactor, () -> { + }); + }); }); }); }); @@ -215,8 +232,7 @@ public class TechTree implements ContentList{ }); }); - node(alphaPad, () -> { - node(dartPad); + node(alphaDartPad, () -> { node(deltaPad, () -> { node(javelinPad); node(tauPad, () -> { diff --git a/core/src/io/anuke/mindustry/content/UnitTypes.java b/core/src/io/anuke/mindustry/content/UnitTypes.java index 680f94f46e..f841cdb343 100644 --- a/core/src/io/anuke/mindustry/content/UnitTypes.java +++ b/core/src/io/anuke/mindustry/content/UnitTypes.java @@ -1,26 +1,37 @@ package io.anuke.mindustry.content; import io.anuke.arc.collection.ObjectSet; -import io.anuke.mindustry.entities.units.UnitType; -import io.anuke.mindustry.entities.units.types.*; +import io.anuke.mindustry.entities.type.base.*; import io.anuke.mindustry.game.ContentList; +import io.anuke.mindustry.type.UnitType; +import io.anuke.mindustry.type.Weapon; public class UnitTypes implements ContentList{ public static UnitType spirit, phantom, - wraith, ghoul, revenant, - dagger, crawler, titan, fortress; + wraith, ghoul, revenant, lich, reaper, + dagger, crawler, titan, fortress, eruptor, chaosArray, eradicator; @Override public void load(){ spirit = new UnitType("spirit", Spirit.class, Spirit::new){{ - weapon = Weapons.healBlasterDrone; isFlying = true; drag = 0.01f; speed = 0.2f; maxVelocity = 0.8f; range = 50f; health = 60; + engineSize = 1.8f; + engineOffset = 5.7f; + weapon = new Weapon("heal-blaster"){{ + length = 1.5f; + reload = 40f; + width = 0.5f; + roundrobin = true; + ejectEffect = Fx.none; + recoil = 2f; + bullet = Bullets.healBullet; + }}; }}; dagger = new UnitType("dagger", Dagger.class, Dagger::new){{ @@ -29,8 +40,14 @@ public class UnitTypes implements ContentList{ drag = 0.4f; hitsize = 8f; mass = 1.75f; - weapon = Weapons.chainBlaster; health = 130; + weapon = new Weapon("chain-blaster"){{ + length = 1.5f; + reload = 28f; + roundrobin = true; + ejectEffect = Fx.shellEjectSmall; + bullet = Bullets.standardCopper; + }}; }}; crawler = new UnitType("crawler", Crawler.class, Crawler::new){{ @@ -39,8 +56,12 @@ public class UnitTypes implements ContentList{ drag = 0.4f; hitsize = 8f; mass = 1.75f; - weapon = Weapons.suicideBomb; health = 100; + weapon = new Weapon("bomber"){{ + reload = 12f; + ejectEffect = Fx.none; + bullet = Bullets.explode; + }}; }}; titan = new UnitType("titan", Titan.class, Titan::new){{ @@ -50,21 +71,105 @@ public class UnitTypes implements ContentList{ mass = 3.5f; hitsize = 9f; rotatespeed = 0.1f; - weapon = Weapons.flamethrower; health = 440; + immunities.add(StatusEffects.burning); + weapon = new Weapon("flamethrower"){{ + length = 1f; + reload = 14f; + roundrobin = true; + recoil = 1f; + ejectEffect = Fx.none; + bullet = Bullets.basicFlame; + }}; }}; fortress = new UnitType("fortress", Fortress.class, Fortress::new){{ - maxVelocity = 0.8f; + maxVelocity = 0.78f; speed = 0.15f; drag = 0.4f; mass = 5f; hitsize = 10f; rotatespeed = 0.06f; - weaponOffsetX = 1; targetAir = false; - weapon = Weapons.artillery; health = 800; + weapon = new Weapon("artillery"){{ + length = 1f; + reload = 60f; + width = 10f; + roundrobin = true; + recoil = 4f; + shake = 2f; + ejectEffect = Fx.shellEjectMedium; + bullet = Bullets.artilleryUnit; + }}; + }}; + + eruptor = new UnitType("eruptor", Eruptor.class, Eruptor::new){{ + maxVelocity = 0.81f; + speed = 0.16f; + drag = 0.4f; + mass = 5f; + hitsize = 9f; + rotatespeed = 0.05f; + targetAir = false; + health = 600; + immunities = ObjectSet.with(StatusEffects.burning, StatusEffects.melting); + weapon = new Weapon("eruption"){{ + length = 3f; + reload = 10f; + roundrobin = true; + ejectEffect = Fx.none; + bullet = Bullets.eruptorShot; + recoil = 1f; + width = 7f; + }}; + }}; + + chaosArray = new UnitType("chaos-array", Dagger.class, Dagger::new){{ + maxVelocity = 0.68f; + speed = 0.12f; + drag = 0.4f; + mass = 5f; + hitsize = 20f; + rotatespeed = 0.06f; + health = 20000; + weapon = new Weapon("chaos"){{ + length = 8f; + reload = 50f; + width = 17f; + roundrobin = true; + recoil = 3f; + shake = 2f; + shots = 4; + spacing = 4f; + shotDelay = 5; + ejectEffect = Fx.shellEjectMedium; + bullet = Bullets.flakSurge; + }}; + }}; + + eradicator = new UnitType("eradicator", Dagger.class, Dagger::new){{ + maxVelocity = 0.68f; + speed = 0.12f; + drag = 0.4f; + mass = 5f; + hitsize = 20f; + rotatespeed = 0.06f; + health = 80000; + weapon = new Weapon("eradication"){{ + length = 13f; + reload = 30f; + width = 22f; + roundrobin = true; + recoil = 3f; + shake = 2f; + inaccuracy = 3f; + shots = 4; + spacing = 0f; + shotDelay = 3; + ejectEffect = Fx.shellEjectMedium; + bullet = Bullets.standardThoriumBig; + }}; }}; wraith = new UnitType("wraith", Wraith.class, Wraith::new){{ @@ -72,9 +177,16 @@ public class UnitTypes implements ContentList{ maxVelocity = 1.9f; drag = 0.01f; mass = 1.5f; - weapon = Weapons.chainBlaster; isFlying = true; health = 70; + engineOffset = 5.5f; + weapon = new Weapon("chain-blaster"){{ + length = 1.5f; + reload = 28f; + roundrobin = true; + ejectEffect = Fx.shellEjectSmall; + bullet = Bullets.standardCopper; + }}; }}; ghoul = new UnitType("ghoul", Ghoul.class, Ghoul::new){{ @@ -85,23 +197,21 @@ public class UnitTypes implements ContentList{ drag = 0.01f; isFlying = true; targetAir = false; - weapon = Weapons.bomber; - }}; - - revenant = new UnitType("revenant", Revenant.class, Revenant::new){{ - health = 250; - mass = 5f; - hitsize = 12f; - speed = 0.14f; - maxVelocity = 1.3f; - drag = 0.01f; - range = 80f; - isFlying = true; - weapon = Weapons.laserBurster; + engineOffset = 7.8f; + weapon = new Weapon("bomber"){{ + length = 0f; + width = 2f; + reload = 12f; + roundrobin = true; + ejectEffect = Fx.none; + velocityRnd = 1f; + inaccuracy = 40f; + ignoreRotation = true; + bullet = Bullets.bombExplosive; + }}; }}; phantom = new UnitType("phantom", Phantom.class, Phantom::new){{ - weapon = Weapons.healBlasterDrone2; isFlying = true; drag = 0.01f; mass = 2f; @@ -112,7 +222,107 @@ public class UnitTypes implements ContentList{ health = 220; buildPower = 0.9f; minePower = 1.1f; + engineOffset = 6.5f; toMine = ObjectSet.with(Items.lead, Items.copper, Items.titanium); + weapon = new Weapon("heal-blaster"){{ + length = 1.5f; + reload = 20f; + width = 0.5f; + roundrobin = true; + ejectEffect = Fx.none; + recoil = 2f; + bullet = Bullets.healBullet; + }}; + }}; + + revenant = new UnitType("revenant", Revenant.class, Revenant::new){{ + health = 4000; + mass = 5f; + hitsize = 20f; + speed = 0.1f; + maxVelocity = 1f; + drag = 0.01f; + range = 80f; + shootCone = 40f; + isFlying = true; + rotateWeapon = true; + engineOffset = 12f; + engineSize = 3f; + rotatespeed = 0.01f; + attackLength = 90f; + baseRotateSpeed = 0.06f; + weapon = new Weapon("revenant-missiles"){{ + length = 3f; + reload = 70f; + width = 10f; + shots = 2; + inaccuracy = 2f; + roundrobin = true; + ejectEffect = Fx.none; + velocityRnd = 0.2f; + spacing = 1f; + bullet = Bullets.missileRevenant; + }}; + }}; + + lich = new UnitType("lich", Revenant.class, Revenant::new){{ + health = 15000; + mass = 20f; + hitsize = 40f; + speed = 0.01f; + maxVelocity = 0.6f; + drag = 0.02f; + range = 80f; + shootCone = 20f; + isFlying = true; + rotateWeapon = true; + engineOffset = 21; + engineSize = 5.3f; + rotatespeed = 0.01f; + attackLength = 90f; + baseRotateSpeed = 0.04f; + weapon = new Weapon("lich-missiles"){{ + length = 4f; + reload = 180f; + width = 22f; + shots = 20; + shotDelay = 2; + inaccuracy = 10f; + roundrobin = true; + ejectEffect = Fx.none; + velocityRnd = 0.2f; + spacing = 1f; + bullet = Bullets.missileRevenant; + }}; + }}; + + reaper = new UnitType("reaper", Revenant.class, Revenant::new){{ + health = 30000; + mass = 30f; + hitsize = 56f; + speed = 0.01f; + maxVelocity = 0.6f; + drag = 0.02f; + range = 80f; + shootCone = 30f; + isFlying = true; + rotateWeapon = true; + engineOffset = 40; + engineSize = 7.3f; + rotatespeed = 0.01f; + baseRotateSpeed = 0.04f; + weapon = new Weapon("reaper-gun"){{ + length = 3f; + reload = 10f; + width = 32f; + shots = 1; + + shake = 1f; + inaccuracy = 3f; + roundrobin = true; + ejectEffect = Fx.none; + bullet = Bullets.standardDenseBig; + }}; }}; } } diff --git a/core/src/io/anuke/mindustry/content/Weapons.java b/core/src/io/anuke/mindustry/content/Weapons.java deleted file mode 100644 index 53587abff8..0000000000 --- a/core/src/io/anuke/mindustry/content/Weapons.java +++ /dev/null @@ -1,188 +0,0 @@ -package io.anuke.mindustry.content; - -import io.anuke.mindustry.game.ContentList; -import io.anuke.mindustry.type.Weapon; - -public class Weapons implements ContentList{ - public static Weapon blaster, blasterSmall, glaiveBlaster, droneBlaster, healBlaster, healBlasterDrone, chainBlaster, shockgun, - swarmer, bomber, bomberTrident, flakgun, flamethrower, missiles, artillery, laserBurster, healBlasterDrone2, suicideBomb; - - @Override - public void load(){ - - blaster = new Weapon("blaster"){{ - length = 1.5f; - reload = 14f; - roundrobin = true; - ejectEffect = Fx.shellEjectSmall; - ammo = Bullets.standardMechSmall; - }}; - - blasterSmall = new Weapon("blaster"){{ - length = 1.5f; - reload = 20f; - roundrobin = true; - ejectEffect = Fx.shellEjectSmall; - ammo = Bullets.standardCopper; - }}; - - glaiveBlaster = new Weapon("bomber"){{ - length = 1.5f; - reload = 13f; - roundrobin = true; - ejectEffect = Fx.shellEjectSmall; - ammo = Bullets.standardGlaive; - }}; - - droneBlaster = new Weapon("blaster"){{ - length = 2f; - reload = 25f; - width = 1f; - roundrobin = true; - ejectEffect = Fx.shellEjectSmall; - ammo = Bullets.standardCopper; - }}; - - healBlaster = new Weapon("heal-blaster"){{ - length = 1.5f; - reload = 24f; - roundrobin = false; - ejectEffect = Fx.none; - recoil = 2f; - ammo = Bullets.healBullet; - }}; - - missiles = new Weapon("missiles"){{ - length = 1.5f; - reload = 70f; - shots = 4; - inaccuracy = 2f; - roundrobin = true; - ejectEffect = Fx.none; - velocityRnd = 0.2f; - spacing = 1f; - ammo = Bullets.missileJavelin; - }}; - - swarmer = new Weapon("swarmer"){{ - length = 1.5f; - recoil = 4f; - reload = 60f; - shots = 4; - spacing = 8f; - inaccuracy = 8f; - roundrobin = true; - ejectEffect = Fx.none; - shake = 3f; - ammo = Bullets.missileSwarm; - }}; - - chainBlaster = new Weapon("chain-blaster"){{ - length = 1.5f; - reload = 28f; - roundrobin = true; - ejectEffect = Fx.shellEjectSmall; - ammo = Bullets.standardCopper; - }}; - - shockgun = new Weapon("shockgun"){{ - length = 1f; - reload = 40f; - roundrobin = true; - shots = 1; - inaccuracy = 0f; - velocityRnd = 0.2f; - ejectEffect = Fx.none; - ammo = Bullets.lightning; - }}; - - flakgun = new Weapon("flakgun"){{ - length = 1f; - reload = 70f; - roundrobin = true; - shots = 1; - inaccuracy = 3f; - recoil = 3f; - velocityRnd = 0.1f; - ejectEffect = Fx.shellEjectMedium; - ammo = Bullets.artilleryDense; - }}; - - flamethrower = new Weapon("flamethrower"){{ - length = 1f; - reload = 14f; - roundrobin = true; - recoil = 1f; - ejectEffect = Fx.none; - ammo = Bullets.basicFlame; - }}; - - artillery = new Weapon("artillery"){{ - length = 1f; - reload = 60f; - roundrobin = true; - recoil = 5f; - shake = 2f; - ejectEffect = Fx.shellEjectMedium; - ammo = Bullets.artilleryUnit; - }}; - - suicideBomb = new Weapon("bomber"){{ - reload = 12f; - ejectEffect = Fx.none; - ammo = Bullets.explode; - }}; - - bomber = new Weapon("bomber"){{ - length = 0f; - width = 2f; - reload = 12f; - roundrobin = true; - ejectEffect = Fx.none; - velocityRnd = 1f; - inaccuracy = 40f; - ammo = Bullets.bombExplosive; - }}; - - bomberTrident = new Weapon("bomber"){{ - length = 0f; - width = 2f; - reload = 8f; - shots = 2; - roundrobin = true; - ejectEffect = Fx.none; - velocityRnd = 1f; - inaccuracy = 40f; - ammo = Bullets.bombExplosive; - }}; - - laserBurster = new Weapon("bomber"){{ - reload = 80f; - shake = 3f; - width = 0f; - roundrobin = true; - ejectEffect = Fx.none; - ammo = Bullets.lancerLaser; - }}; - - healBlasterDrone = new Weapon("heal-blaster"){{ - length = 1.5f; - reload = 40f; - width = 0.5f; - roundrobin = true; - ejectEffect = Fx.none; - recoil = 2f; - ammo = Bullets.healBullet; - }}; - - healBlasterDrone2 = new Weapon("heal-blaster"){{ - length = 1.5f; - reload = 20f; - width = 0.5f; - roundrobin = true; - ejectEffect = Fx.none; - recoil = 2f; - ammo = Bullets.healBullet; - }}; - } -} diff --git a/core/src/io/anuke/mindustry/content/Zones.java b/core/src/io/anuke/mindustry/content/Zones.java index e301e404f9..37d5e16993 100644 --- a/core/src/io/anuke/mindustry/content/Zones.java +++ b/core/src/io/anuke/mindustry/content/Zones.java @@ -5,6 +5,7 @@ import io.anuke.mindustry.game.ContentList; import io.anuke.mindustry.game.Rules; import io.anuke.mindustry.game.SpawnGroup; import io.anuke.mindustry.maps.generators.MapGenerator; +import io.anuke.mindustry.maps.generators.MapGenerator.Decoration; import io.anuke.mindustry.type.ItemStack; import io.anuke.mindustry.type.Zone; import io.anuke.mindustry.world.Block; @@ -21,6 +22,7 @@ public class Zones implements ContentList{ startingItems = ItemStack.with(Items.copper, 50); alwaysUnlocked = true; conditionWave = 10; + launchPeriod = 5; rules = () -> new Rules(){{ waves = true; waveTimer = true; @@ -58,19 +60,17 @@ public class Zones implements ContentList{ }}; }}; - craters = new Zone("craters", new MapGenerator("craters", 1){{ distortion = 1.44f; }}){{ - alwaysUnlocked = true; - - deployCost = ItemStack.with(Items.copper, 300); + craters = new Zone("craters", new MapGenerator("craters", 1).dist(0)){{ + deployCost = ItemStack.with(Items.copper, 200); startingItems = ItemStack.with(Items.copper, 200); - conditionWave = 15; + conditionWave = 10; itemRequirements = ItemStack.with(Items.copper, 2000); zoneRequirements = new Zone[]{groundZero}; blockRequirements = new Block[]{Blocks.router}; rules = () -> new Rules(){{ waves = true; waveTimer = true; - waveSpacing = 60 * 60; + waveSpacing = 60 * 60 * 1.5f; spawns = Array.with( new SpawnGroup(UnitTypes.dagger){{ unitScaling = 2; @@ -91,6 +91,7 @@ public class Zones implements ContentList{ new SpawnGroup(UnitTypes.crawler){{ begin = 15; unitScaling = 1; + unitAmount = 2; }}, new SpawnGroup(UnitTypes.dagger){{ @@ -101,37 +102,131 @@ public class Zones implements ContentList{ new SpawnGroup(UnitTypes.crawler){{ begin = 25; unitScaling = 1; + unitAmount = 2; }} ); }}; }}; - frozenForest = new Zone("frozenForest", new MapGenerator("groundZero", 1)){{ //TODO implement - deployCost = ItemStack.with(Items.copper, 300); - startingItems = ItemStack.with(Items.copper, 200); - conditionWave = 15; - zoneRequirements = new Zone[]{frozenForest}; - blockRequirements = new Block[]{Blocks.copperWall}; + frozenForest = new Zone("frozenForest", new MapGenerator("frozenForest", 2) + .decor(new Decoration(Blocks.snow, Blocks.sporeCluster, 0.02))){{ + deployCost = ItemStack.with(Items.copper, 500); + startingItems = ItemStack.with(Items.copper, 400); + conditionWave = 10; + zoneRequirements = new Zone[]{craters}; + itemRequirements = ItemStack.with(Items.copper, 4000, Items.lead, 2000); rules = () -> new Rules(){{ waves = true; waveTimer = true; - waveSpacing = 60 * 80; + waveSpacing = 60 * 60 * 1.5f; + spawns = Array.with( + new SpawnGroup(UnitTypes.titan){{ + unitScaling = 3; + end = 9; + }}, + + new SpawnGroup(UnitTypes.dagger){{ + unitScaling = 2; + begin = 2; + end = 9; + }}, + + new SpawnGroup(UnitTypes.dagger){{ + unitScaling = 2; + begin = 5; + end = 9; + }}, + + new SpawnGroup(UnitTypes.crawler){{ + unitScaling = 0.5f; + begin = 10; + spacing = 10; + unitAmount = 5; + }}, + + new SpawnGroup(UnitTypes.titan){{ + begin = 11; + unitAmount = 2; + unitScaling = 2; + spacing = 2; + }}, + + new SpawnGroup(UnitTypes.dagger){{ + begin = 12; + unitAmount = 2; + unitScaling = 2; + spacing = 2; + }}, + + new SpawnGroup(UnitTypes.crawler){{ + unitScaling = 0.5f; + begin = 35; + spacing = 10; + unitAmount = 6; + }} + ); }}; }}; - ruinousShores = new Zone("ruinousShores", new MapGenerator("groundZero", 1)){{ //TODO implement - deployCost = ItemStack.with(Items.copper, 300); - startingItems = ItemStack.with(Items.copper, 200); - conditionWave = 15; + ruinousShores = new Zone("ruinousShores", new MapGenerator("ruinousShores", 1)){{ + deployCost = ItemStack.with(Items.copper, 600, Items.graphite, 50); + startingItems = ItemStack.with(Items.copper, 400); + conditionWave = 20; + launchPeriod = 20; zoneRequirements = new Zone[]{frozenForest}; - blockRequirements = new Block[]{Blocks.copperWall}; + itemRequirements = ItemStack.with(Items.lead, 6000, Items.graphite, 2000); + blockRequirements = new Block[]{Blocks.graphitePress, Blocks.combustionGenerator}; rules = () -> new Rules(){{ waves = true; waveTimer = true; - waveSpacing = 60 * 80; + waveSpacing = 60 * 60; + spawns = Array.with( + new SpawnGroup(UnitTypes.wraith){{ + unitScaling = 2; + spacing = 2; + end = 10; + }}, + + new SpawnGroup(UnitTypes.dagger){{ + begin = 2; + spacing = 2; + unitScaling = 2; + }}, + + new SpawnGroup(UnitTypes.wraith){{ + begin = 10; + unitScaling = 0.5f; + unitAmount = 6; + spacing = 10; + }}, + + new SpawnGroup(UnitTypes.crawler){{ + begin = 5; + unitScaling = 1; + spacing = 5; + unitAmount = 1; + effect = StatusEffects.overdrive; + }}, + + new SpawnGroup(UnitTypes.crawler){{ + begin = 22; + unitScaling = 1; + spacing = 20; + unitScaling = 0.5f; + unitAmount = 10; + }}, + + new SpawnGroup(UnitTypes.dagger){{ + begin = 11; + spacing = 2; + unitScaling = 2; + unitAmount = 2; + }} + ); }}; }}; + /* crags = new Zone("crags", new MapGenerator("groundZero", 1)){{ //TODO implement deployCost = ItemStack.with(Items.copper, 300); startingItems = ItemStack.with(Items.copper, 200); @@ -143,47 +238,218 @@ public class Zones implements ContentList{ waveTimer = true; waveSpacing = 60 * 80; }}; - }}; + }};*/ - stainedMountains = new Zone("stainedMountains", new MapGenerator("groundZero", 1)){{ //TODO implement - deployCost = ItemStack.with(Items.copper, 300); - startingItems = ItemStack.with(Items.copper, 200); - conditionWave = 15; + stainedMountains = new Zone("stainedMountains", new MapGenerator("stainedMountains", 2) + .dist(2.5f, true) + .decor(new Decoration(Blocks.stainedStone, Blocks.stainedBoulder, 0.01))){{ + deployCost = ItemStack.with(Items.copper, 500, Items.lead, 300, Items.silicon, 100); + startingItems = ItemStack.with(Items.copper, 400, Items.lead, 100); + conditionWave = 10; + launchPeriod = 10; zoneRequirements = new Zone[]{frozenForest}; - blockRequirements = new Block[]{Blocks.copperWall}; + blockRequirements = new Block[]{Blocks.pneumaticDrill}; + itemRequirements = ItemStack.with(Items.copper, 8000, Items.silicon, 2000); rules = () -> new Rules(){{ waves = true; waveTimer = true; - waveSpacing = 60 * 80; + waveSpacing = 60 * 60 * 2; + spawns = Array.with( + new SpawnGroup(UnitTypes.titan){{ + unitScaling = 2; + spacing = 2; + end = 10; + }}, + + new SpawnGroup(UnitTypes.dagger){{ + begin = 2; + unitScaling = 1; + spacing = 2; + }}, + + new SpawnGroup(UnitTypes.dagger){{ + begin = 10; + spacing = 2; + unitScaling = 2; + unitAmount = 2; + }}, + + new SpawnGroup(UnitTypes.ghoul){{ + begin = 5; + unitScaling = 0.5f; + unitAmount = 1; + spacing = 5; + }}, + + new SpawnGroup(UnitTypes.wraith){{ + begin = 10; + unitScaling = 1f; + unitAmount = 1; + spacing = 5; + }}, + + new SpawnGroup(UnitTypes.dagger){{ + begin = 2; + unitScaling = 1; + spacing = 2; + }}, + + new SpawnGroup(UnitTypes.wraith){{ + begin = 23; + unitScaling = 1f; + unitAmount = 1; + spacing = 2; + }}, + + new SpawnGroup(UnitTypes.crawler){{ + begin = 20; + unitScaling = 1; + spacing = 10; + unitScaling = 0.5f; + unitAmount = 10; + }} + ); }}; }}; - impact = new Zone("impact", new MapGenerator("groundZero", 1)){{ //TODO implement - deployCost = ItemStack.with(Items.copper, 300); - startingItems = ItemStack.with(Items.copper, 200); - conditionWave = 15; - zoneRequirements = new Zone[]{frozenForest}; - blockRequirements = new Block[]{Blocks.copperWall}; + impact = new Zone("impact0079", new MapGenerator("impact0079", 2) + .decor( + new Decoration(Blocks.snow, Blocks.sporeCluster, 0.01), + new Decoration(Blocks.metalFloor, Blocks.metalFloorDamaged, 0.02) + ).drops(ItemStack.with(Items.copper, 2000, Items.lead, 1500, Items.silicon, 1000, Items.graphite, 1000, Items.pyratite, 2000, Items.titanium, 2000, Items.metaglass, 1000))){{ + deployCost = ItemStack.with(Items.copper, 2500, Items.lead, 1000, Items.silicon, 300); + startingItems = ItemStack.with(Items.copper, 2000, Items.lead, 500, Items.silicon, 200); + itemRequirements = ItemStack.with(Items.silicon, 8000, Items.titanium, 6000, Items.graphite, 4000); + conditionWave = 20; + zoneRequirements = new Zone[]{stainedMountains}; + blockRequirements = new Block[]{Blocks.launchPad, Blocks.unloader, Blocks.coreFoundation}; rules = () -> new Rules(){{ waves = true; waveTimer = true; - waveSpacing = 60 * 80; + waveSpacing = 60 * 60; + + spawns = Array.with( + new SpawnGroup(UnitTypes.titan){{ + unitScaling = 2; + spacing = 2; + end = 10; + }}, + + new SpawnGroup(UnitTypes.dagger){{ + begin = 2; + unitScaling = 1; + spacing = 2; + }}, + + new SpawnGroup(UnitTypes.dagger){{ + begin = 10; + spacing = 2; + unitScaling = 2; + unitAmount = 2; + }}, + + new SpawnGroup(UnitTypes.ghoul){{ + begin = 5; + unitScaling = 0.5f; + unitAmount = 1; + spacing = 5; + }}, + + new SpawnGroup(UnitTypes.wraith){{ + begin = 10; + unitScaling = 1f; + unitAmount = 1; + spacing = 5; + }}, + + new SpawnGroup(UnitTypes.dagger){{ + begin = 2; + unitScaling = 1; + spacing = 2; + }}, + + new SpawnGroup(UnitTypes.wraith){{ + begin = 23; + unitScaling = 1f; + unitAmount = 1; + spacing = 2; + }}, + + new SpawnGroup(UnitTypes.crawler){{ + begin = 20; + unitScaling = 1; + spacing = 10; + unitScaling = 0.5f; + unitAmount = 10; + }} + ); }}; }}; - desolateRift = new Zone("desolateRift", new MapGenerator("groundZero", 1)){{ //TODO implement - deployCost = ItemStack.with(Items.copper, 300); - startingItems = ItemStack.with(Items.copper, 200); - conditionWave = 15; - zoneRequirements = new Zone[]{frozenForest}; - blockRequirements = new Block[]{Blocks.copperWall}; + desolateRift = new Zone("desolateRift", new MapGenerator("desolateRift").dist(2f)){{ + deployCost = ItemStack.with(Items.copper, 2000); + startingItems = ItemStack.with(Items.copper, 1500); + itemRequirements = ItemStack.with(Items.copper, 8000, Items.metaglass, 2000, Items.graphite, 3000); + conditionWave = 10; + launchPeriod = 20; + zoneRequirements = new Zone[]{ruinousShores}; + blockRequirements = new Block[]{Blocks.thermalGenerator}; rules = () -> new Rules(){{ waves = true; waveTimer = true; - waveSpacing = 60 * 80; + waveSpacing = 30 * 60; + spawns = Array.with( + new SpawnGroup(UnitTypes.crawler){{ + unitScaling = 1; + spacing = 2; + end = 10; + }}, + + new SpawnGroup(UnitTypes.dagger){{ + begin = 2; + spacing = 2; + unitScaling = 2; + }}, + + new SpawnGroup(UnitTypes.titan){{ + begin = 10; + unitScaling = 1f; + unitAmount = 3; + spacing = 3; + }}, + + new SpawnGroup(UnitTypes.fortress){{ + begin = 5; + unitScaling = 1; + spacing = 5; + unitAmount = 1; + }}, + + new SpawnGroup(UnitTypes.fortress){{ + begin = 13; + unitScaling = 1; + spacing = 4; + unitAmount = 1; + }}, + + new SpawnGroup(UnitTypes.dagger){{ + begin = 11; + spacing = 2; + unitScaling = 2; + unitAmount = 2; + }}, + + new SpawnGroup(UnitTypes.crawler){{ + unitScaling = 1; + spacing = 2; + unitAmount = 4; + begin = 13; + }} + ); }}; }}; + /* arcticDesert = new Zone("arcticDesert", new MapGenerator("groundZero", 1)){{ //TODO implement deployCost = ItemStack.with(Items.copper, 300); startingItems = ItemStack.with(Items.copper, 200); @@ -210,19 +476,81 @@ public class Zones implements ContentList{ }}; }}; - nuclearComplex = new Zone("nuclearComplex", new MapGenerator("groundZero", 1)){{ //TODO implement - deployCost = ItemStack.with(Items.copper, 300); - startingItems = ItemStack.with(Items.copper, 200); - conditionWave = 15; - zoneRequirements = new Zone[]{frozenForest}; - blockRequirements = new Block[]{Blocks.copperWall}; + */ + nuclearComplex = new Zone("nuclearComplex", new MapGenerator("nuclearProductionComplex", 1) + .drops(ItemStack.with(Items.copper, 2000, Items.lead, 1500, Items.silicon, 1000, Items.graphite, 1000, Items.thorium, 200, Items.titanium, 2000, Items.metaglass, 1000)) + .decor(new Decoration(Blocks.snow, Blocks.sporeCluster, 0.01))){{ + deployCost = ItemStack.with(Items.copper, 3000, Items.lead, 2000, Items.silicon, 1000, Items.metaglass, 500); + startingItems = ItemStack.with(Items.copper, 2500, Items.lead, 1500, Items.silicon, 800, Items.metaglass, 400); + itemRequirements = ItemStack.with(Items.copper, 10000, Items.titanium, 8000, Items.metaglass, 6000, Items.plastanium, 2000); + conditionWave = 30; + launchPeriod = 15; + zoneRequirements = new Zone[]{impact}; + blockRequirements = new Block[]{Blocks.blastDrill, Blocks.thermalGenerator}; rules = () -> new Rules(){{ waves = true; waveTimer = true; - waveSpacing = 60 * 80; + waveSpacing = 60 * 60 * 2; + + spawns = Array.with( + new SpawnGroup(UnitTypes.titan){{ + unitScaling = 2; + spacing = 2; + end = 10; + }}, + + new SpawnGroup(UnitTypes.dagger){{ + begin = 2; + unitScaling = 1; + spacing = 2; + }}, + + new SpawnGroup(UnitTypes.dagger){{ + begin = 10; + spacing = 2; + unitScaling = 2; + unitAmount = 2; + }}, + + new SpawnGroup(UnitTypes.ghoul){{ + begin = 5; + unitScaling = 0.5f; + unitAmount = 1; + spacing = 5; + }}, + + new SpawnGroup(UnitTypes.wraith){{ + begin = 10; + unitScaling = 1f; + unitAmount = 1; + spacing = 5; + }}, + + new SpawnGroup(UnitTypes.dagger){{ + begin = 2; + unitScaling = 1; + spacing = 2; + }}, + + new SpawnGroup(UnitTypes.wraith){{ + begin = 23; + unitScaling = 1f; + unitAmount = 1; + spacing = 2; + }}, + + new SpawnGroup(UnitTypes.crawler){{ + begin = 20; + unitScaling = 1; + spacing = 10; + unitScaling = 0.5f; + unitAmount = 10; + }} + ); }}; }}; + /* moltenFault = new Zone("moltenFault", new MapGenerator("groundZero", 1)){{ //TODO implement deployCost = ItemStack.with(Items.copper, 300); startingItems = ItemStack.with(Items.copper, 200); @@ -234,8 +562,6 @@ public class Zones implements ContentList{ waveTimer = true; waveSpacing = 60 * 80; }}; - }}; - - frozenForest.zoneRequirements = new Zone[]{frozenForest}; + }};*/ } } diff --git a/core/src/io/anuke/mindustry/core/ContentLoader.java b/core/src/io/anuke/mindustry/core/ContentLoader.java index c2ce06754a..317a6a04bd 100644 --- a/core/src/io/anuke/mindustry/core/ContentLoader.java +++ b/core/src/io/anuke/mindustry/core/ContentLoader.java @@ -4,9 +4,11 @@ import io.anuke.arc.collection.Array; import io.anuke.arc.collection.ObjectMap; import io.anuke.arc.collection.ObjectSet; import io.anuke.arc.function.Consumer; +import io.anuke.arc.graphics.Color; +import io.anuke.arc.graphics.Pixmap; import io.anuke.arc.util.Log; import io.anuke.mindustry.content.*; -import io.anuke.mindustry.entities.Player; +import io.anuke.mindustry.entities.type.Player; import io.anuke.mindustry.entities.bullet.Bullet; import io.anuke.mindustry.entities.bullet.BulletType; import io.anuke.mindustry.entities.effect.Fire; @@ -16,11 +18,15 @@ import io.anuke.mindustry.entities.traits.TypeTrait; import io.anuke.mindustry.game.Content; import io.anuke.mindustry.game.ContentList; import io.anuke.mindustry.game.MappableContent; -import io.anuke.mindustry.type.*; +import io.anuke.mindustry.type.ContentType; +import io.anuke.mindustry.type.Item; +import io.anuke.mindustry.type.Liquid; +import io.anuke.mindustry.type.Zone; import io.anuke.mindustry.world.Block; -import io.anuke.mindustry.world.ColorMapper; import io.anuke.mindustry.world.LegacyColorMapper; +import static io.anuke.arc.Core.files; + /** * Loads all game content. * Call load() before doing anything with content. @@ -40,7 +46,6 @@ public class ContentLoader{ new StatusEffects(), new Liquids(), new Bullets(), - new Weapons(), new Mechs(), new UnitTypes(), new Blocks(), @@ -48,7 +53,6 @@ public class ContentLoader{ new Zones(), //these are not really content classes, but this makes initialization easier - new ColorMapper(), new LegacyColorMapper(), }; @@ -126,6 +130,22 @@ public class ContentLoader{ initialization.add(callable); } + /**Loads block colors.*/ + public void loadColors(){ + Pixmap pixmap = new Pixmap(files.internal("sprites/block_colors.png")); + for(int i = 0; i < 256; i++){ + if(blocks().size > i){ + int color = pixmap.getPixel(i, 0); + + if(color == 0) continue; + + Block block = block(i); + Color.rgba8888ToColor(block.color, color); + } + } + pixmap.dispose(); + } + public void verbose(boolean verbose){ this.verbose = verbose; } diff --git a/core/src/io/anuke/mindustry/core/Control.java b/core/src/io/anuke/mindustry/core/Control.java index e9b793fc73..eb7936d6ac 100644 --- a/core/src/io/anuke/mindustry/core/Control.java +++ b/core/src/io/anuke/mindustry/core/Control.java @@ -3,8 +3,6 @@ package io.anuke.mindustry.core; import io.anuke.arc.ApplicationListener; import io.anuke.arc.Core; import io.anuke.arc.Events; -import io.anuke.arc.entities.Effects; -import io.anuke.arc.entities.EntityQuery; import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.graphics.g2d.TextureAtlas; @@ -15,10 +13,13 @@ import io.anuke.arc.util.Strings; import io.anuke.arc.util.Time; import io.anuke.mindustry.content.Mechs; import io.anuke.mindustry.core.GameState.State; -import io.anuke.mindustry.entities.Player; +import io.anuke.mindustry.entities.Effects; +import io.anuke.mindustry.entities.EntityQuery; +import io.anuke.mindustry.entities.type.Player; import io.anuke.mindustry.game.Content; import io.anuke.mindustry.game.EventType.*; import io.anuke.mindustry.game.GlobalData; +import io.anuke.mindustry.game.Rules; import io.anuke.mindustry.game.Saves; import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.input.Binding; @@ -227,9 +228,10 @@ public class Control implements ApplicationListener{ return inputs[index]; } - public void playMap(Map map){ + public void playMap(Map map, Rules rules){ ui.loadAnd(() -> { logic.reset(); + state.rules = rules; world.loadMap(map); logic.play(); }); @@ -305,7 +307,7 @@ public class Control implements ApplicationListener{ } //auto-update rpc every 5 seconds - if(timer.get(60 * 5)){ + if(timer.get(0, 60 * 5)){ Platform.instance.updateRPC(); } diff --git a/core/src/io/anuke/mindustry/core/GameState.java b/core/src/io/anuke/mindustry/core/GameState.java index b1d19aa9ec..fd521bf2c0 100644 --- a/core/src/io/anuke/mindustry/core/GameState.java +++ b/core/src/io/anuke/mindustry/core/GameState.java @@ -38,7 +38,7 @@ public class GameState{ } public boolean isPaused(){ - return is(State.paused) && !Net.active(); + return (is(State.paused) && !Net.active()) || gameOver; } public boolean is(State astate){ diff --git a/core/src/io/anuke/mindustry/core/Logic.java b/core/src/io/anuke/mindustry/core/Logic.java index 50681fb1b4..28a4e44461 100644 --- a/core/src/io/anuke/mindustry/core/Logic.java +++ b/core/src/io/anuke/mindustry/core/Logic.java @@ -4,15 +4,19 @@ import io.anuke.annotations.Annotations.Loc; import io.anuke.annotations.Annotations.Remote; import io.anuke.arc.ApplicationListener; import io.anuke.arc.Events; -import io.anuke.arc.entities.Entities; -import io.anuke.arc.entities.EntityGroup; -import io.anuke.arc.entities.EntityQuery; +import io.anuke.arc.collection.ObjectSet.ObjectSetIterator; +import io.anuke.mindustry.entities.Effects; +import io.anuke.mindustry.entities.Entities; +import io.anuke.mindustry.entities.EntityGroup; +import io.anuke.mindustry.entities.EntityQuery; import io.anuke.arc.util.Time; +import io.anuke.mindustry.content.Fx; import io.anuke.mindustry.core.GameState.State; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.game.EventType.*; import io.anuke.mindustry.game.*; import io.anuke.mindustry.net.Net; +import io.anuke.mindustry.type.Item; import io.anuke.mindustry.world.Tile; import static io.anuke.mindustry.Vars.*; @@ -28,12 +32,6 @@ import static io.anuke.mindustry.Vars.*; public class Logic implements ApplicationListener{ public Logic(){ - Events.on(TileChangeEvent.class, event -> { - if(event.tile.getTeam() == defaultTeam && event.tile.block().isVisible()){ - handleContent(event.tile.block()); - } - }); - Events.on(WaveEvent.class, event -> { if(world.isZone()){ data.updateWaveScore(world.getZone(), state.wave); @@ -111,6 +109,25 @@ public class Logic implements ApplicationListener{ } } + @Remote(called = Loc.both) + public static void launchZone(){ + Effects.effect(Fx.launchFull, 0, 0); + + for(Tile tile : new ObjectSetIterator<>(state.teams.get(defaultTeam).cores)){ + Effects.effect(Fx.launch, tile); + } + + Time.runTask(30f, () -> { + for(Tile tile : new ObjectSetIterator<>(state.teams.get(defaultTeam).cores)){ + for(Item item : content.items()){ + data.addItem(item, tile.entity.items.get(item) / playerGroup.size()); + } + world.removeBlock(tile); + } + state.launched = true; + }); + } + @Remote(called = Loc.both) public static void onGameOver(Team winner){ ui.restart.show(winner); diff --git a/core/src/io/anuke/mindustry/core/NetClient.java b/core/src/io/anuke/mindustry/core/NetClient.java index 86a4fb4735..3a47eee4ff 100644 --- a/core/src/io/anuke/mindustry/core/NetClient.java +++ b/core/src/io/anuke/mindustry/core/NetClient.java @@ -7,8 +7,8 @@ import io.anuke.annotations.Annotations.Variant; import io.anuke.arc.ApplicationListener; import io.anuke.arc.Core; import io.anuke.arc.collection.IntSet; -import io.anuke.arc.entities.Entities; -import io.anuke.arc.entities.EntityGroup; +import io.anuke.mindustry.entities.Entities; +import io.anuke.mindustry.entities.EntityGroup; import io.anuke.arc.graphics.Color; import io.anuke.arc.util.Interval; import io.anuke.arc.util.Log; @@ -17,7 +17,7 @@ import io.anuke.arc.util.io.ReusableByteArrayInputStream; import io.anuke.arc.util.serialization.Base64Coder; import io.anuke.mindustry.Vars; import io.anuke.mindustry.core.GameState.State; -import io.anuke.mindustry.entities.Player; +import io.anuke.mindustry.entities.type.Player; import io.anuke.mindustry.entities.traits.BuilderTrait.BuildRequest; import io.anuke.mindustry.entities.traits.SyncTrait; import io.anuke.mindustry.entities.traits.TypeTrait; @@ -345,7 +345,7 @@ public class NetClient implements ApplicationListener{ requests[i] = player.getPlaceQueue().get(i); } - Call.onClientShapshot(lastSent++, Time.millis(), player.x, player.y, + Call.onClientShapshot(lastSent++, player.x, player.y, player.pointerX, player.pointerY, player.rotation, player.baseRotation, player.velocity().x, player.velocity().y, player.getMineTile(), diff --git a/core/src/io/anuke/mindustry/core/NetServer.java b/core/src/io/anuke/mindustry/core/NetServer.java index 1df4e182e1..7e0cdbef72 100644 --- a/core/src/io/anuke/mindustry/core/NetServer.java +++ b/core/src/io/anuke/mindustry/core/NetServer.java @@ -7,10 +7,10 @@ import io.anuke.arc.Events; import io.anuke.arc.collection.Array; import io.anuke.arc.collection.IntMap; import io.anuke.arc.collection.ObjectSet; -import io.anuke.arc.entities.Entities; -import io.anuke.arc.entities.EntityGroup; -import io.anuke.arc.entities.EntityQuery; -import io.anuke.arc.entities.trait.Entity; +import io.anuke.mindustry.entities.Entities; +import io.anuke.mindustry.entities.EntityGroup; +import io.anuke.mindustry.entities.EntityQuery; +import io.anuke.mindustry.entities.traits.Entity; import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.Colors; import io.anuke.arc.math.Mathf; @@ -24,7 +24,7 @@ import io.anuke.arc.util.io.CountableByteArrayOutputStream; import io.anuke.mindustry.content.Mechs; import io.anuke.mindustry.content.Blocks; import io.anuke.mindustry.core.GameState.State; -import io.anuke.mindustry.entities.Player; +import io.anuke.mindustry.entities.type.Player; import io.anuke.mindustry.entities.traits.BuilderTrait.BuildRequest; import io.anuke.mindustry.entities.traits.SyncTrait; import io.anuke.mindustry.game.EventType.WorldLoadEvent; @@ -156,7 +156,7 @@ public class NetServer implements ApplicationListener{ return; } - Log.info("Recieved connect packet for player '{0}' / UUID {1} / IP {2}", packet.name, uuid, connection.address); + Log.debug("Recieved connect packet for player '{0}' / UUID {1} / IP {2}", packet.name, uuid, connection.address); String ip = Net.getConnection(id).address; @@ -234,7 +234,7 @@ public class NetServer implements ApplicationListener{ data.stream = new ByteArrayInputStream(stream.toByteArray()); Net.sendStream(clientID, data); - Log.info("Packed {0} compressed bytes of world data.", stream.size()); + Log.debug("Packed {0} compressed bytes of world data.", stream.size()); } public static void onDisconnect(Player player){ @@ -259,7 +259,7 @@ public class NetServer implements ApplicationListener{ @Remote(targets = Loc.client, unreliable = true) public static void onClientShapshot( Player player, - int snapshotID, long sent, + int snapshotID, float x, float y, float pointerX, float pointerY, float rotation, float baseRotation, @@ -272,7 +272,7 @@ public class NetServer implements ApplicationListener{ NetConnection connection = player.con; if(connection == null || snapshotID < connection.lastRecievedClientSnapshot) return; - boolean verifyPosition = !player.isDead() && netServer.admins.getStrict() && headless && player.getCarrier() == null; + boolean verifyPosition = !player.isDead() && netServer.admins.getStrict() && headless; if(connection.lastRecievedClientTime == 0) connection.lastRecievedClientTime = Time.millis() - 16; @@ -329,7 +329,7 @@ public class NetServer implements ApplicationListener{ player.y = prevy; //set interpolator target to *new* position so it moves toward it - player.getInterpolator().read(player.x, player.y, newx, newy, sent, rotation, baseRotation); + 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; @@ -340,13 +340,13 @@ public class NetServer implements ApplicationListener{ public static void onAdminRequest(Player player, Player other, AdminAction action){ if(!player.isAdmin){ - Log.err("ACCESS DENIED: Player {0} / {1} attempted to perform admin action without proper security access.", + Log.warn("ACCESS DENIED: Player {0} / {1} attempted to perform admin action without proper security access.", player.name, player.con.address); return; } if(other == null || ((other.isAdmin && !player.isLocal) && other != player)){ - Log.err("{0} attempted to perform admin action on nonexistant or admin player.", player.name); + Log.warn("{0} attempted to perform admin action on nonexistant or admin player.", player.name); return; } diff --git a/core/src/io/anuke/mindustry/core/Renderer.java b/core/src/io/anuke/mindustry/core/Renderer.java index a1fd94c4bb..e0bf8704a1 100644 --- a/core/src/io/anuke/mindustry/core/Renderer.java +++ b/core/src/io/anuke/mindustry/core/Renderer.java @@ -2,12 +2,6 @@ package io.anuke.mindustry.core; import io.anuke.arc.ApplicationListener; import io.anuke.arc.Core; -import io.anuke.arc.entities.Effects; -import io.anuke.arc.entities.EntityDraw; -import io.anuke.arc.entities.EntityGroup; -import io.anuke.arc.entities.impl.EffectEntity; -import io.anuke.arc.entities.trait.DrawTrait; -import io.anuke.arc.entities.trait.Entity; import io.anuke.arc.function.Consumer; import io.anuke.arc.function.Predicate; import io.anuke.arc.graphics.Camera; @@ -15,6 +9,7 @@ import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.graphics.g2d.Lines; import io.anuke.arc.graphics.g2d.SpriteBatch; +import io.anuke.arc.graphics.glutils.FrameBuffer; import io.anuke.arc.math.Mathf; import io.anuke.arc.math.geom.Rectangle; import io.anuke.arc.math.geom.Vector2; @@ -23,15 +18,22 @@ import io.anuke.arc.util.Time; import io.anuke.arc.util.pooling.Pools; import io.anuke.mindustry.content.Fx; import io.anuke.mindustry.core.GameState.State; -import io.anuke.mindustry.entities.Player; -import io.anuke.mindustry.entities.TileEntity; -import io.anuke.mindustry.entities.Unit; +import io.anuke.mindustry.entities.Effects; +import io.anuke.mindustry.entities.EntityDraw; +import io.anuke.mindustry.entities.EntityGroup; import io.anuke.mindustry.entities.effect.GroundEffectEntity; import io.anuke.mindustry.entities.effect.GroundEffectEntity.GroundEffect; +import io.anuke.mindustry.entities.impl.EffectEntity; import io.anuke.mindustry.entities.traits.BelowLiquidTrait; -import io.anuke.mindustry.entities.units.BaseUnit; +import io.anuke.mindustry.entities.traits.DrawTrait; +import io.anuke.mindustry.entities.traits.Entity; +import io.anuke.mindustry.entities.type.BaseUnit; +import io.anuke.mindustry.entities.type.Player; +import io.anuke.mindustry.entities.type.TileEntity; +import io.anuke.mindustry.entities.type.Unit; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.graphics.*; +import io.anuke.mindustry.world.blocks.defense.ForceProjector.ShieldEntity; import static io.anuke.arc.Core.*; import static io.anuke.mindustry.Vars.*; @@ -41,6 +43,7 @@ public class Renderer implements ApplicationListener{ public final MinimapRenderer minimap = new MinimapRenderer(); public final OverlayRenderer overlays = new OverlayRenderer(); + private FrameBuffer shieldBuffer = new FrameBuffer(2, 2); private Color clearColor; private float targetscale = io.anuke.arc.scene.ui.layout.Unit.dp.scl(4); private float camerascale = targetscale; @@ -52,7 +55,6 @@ public class Renderer implements ApplicationListener{ batch = new SpriteBatch(4096); camera = new Camera(); Lines.setCircleVertices(14); - Shaders.init(); Effects.setScreenShakeProvider((intensity, duration) -> { @@ -72,7 +74,7 @@ public class Renderer implements ApplicationListener{ if(!(effect instanceof GroundEffect)){ EffectEntity entity = Pools.obtain(EffectEntity.class, EffectEntity::new); entity.effect = effect; - entity.color = color; + entity.color.set(color); entity.rotation = rotation; entity.data = data; entity.id++; @@ -84,7 +86,7 @@ public class Renderer implements ApplicationListener{ }else{ GroundEffectEntity entity = Pools.obtain(GroundEffectEntity.class, GroundEffectEntity::new); entity.effect = effect; - entity.color = color; + entity.color.set(color); entity.rotation = rotation; entity.id++; entity.data = data; @@ -117,7 +119,7 @@ public class Renderer implements ApplicationListener{ if(players[0].isDead()){ TileEntity core = players[0].getClosestCore(); - if(core != null && players[0].spawner == Unit.noSpawner){ + if(core != null && players[0].spawner == null){ camera.position.lerpDelta(core.x, core.y, 0.08f); }else{ camera.position.lerpDelta(position, 0.08f); @@ -126,9 +128,6 @@ public class Renderer implements ApplicationListener{ camera.position.lerpDelta(position, 0.08f); } - camera.position.x = Mathf.clamp(camera.position.x, -tilesize / 2f, world.width() * tilesize - tilesize / 2f); - camera.position.y = Mathf.clamp(camera.position.y, -tilesize / 2f, world.height() * tilesize - tilesize / 2f); - updateShake(0.75f); draw(); @@ -172,7 +171,13 @@ public class Renderer implements ApplicationListener{ blocks.processBlocks(); blocks.drawShadows(); + + blocks.floor.beginDraw(); + blocks.floor.drawLayer(CacheLayer.walls); + blocks.floor.endDraw(); + blocks.drawBlocks(Layer.block); + blocks.drawFog(); Draw.shader(Shaders.blockbuild, true); blocks.drawBlocks(Layer.placement); @@ -196,16 +201,25 @@ public class Renderer implements ApplicationListener{ drawAndInterpolate(playerGroup, p -> true, Player::drawBuildRequests); //TODO shield - /* - if(shieldGroup.size() > 0){ - Graphics.beginShaders(Shaders.shield); + + if(EntityDraw.countInBounds(shieldGroup) > 0){ + if(graphics.getWidth() >= 2 && graphics.getHeight() >= 2 && (shieldBuffer.getWidth() != graphics.getWidth() || shieldBuffer.getHeight() != graphics.getHeight())){ + shieldBuffer.resize(graphics.getWidth(), graphics.getHeight()); + } + + Draw.flush(); + shieldBuffer.begin(); + graphics.clear(Color.CLEAR); EntityDraw.draw(shieldGroup); EntityDraw.drawWith(shieldGroup, shield -> true, shield -> ((ShieldEntity)shield).drawOver()); - Draw.color(Palette.accent); - Graphics.endShaders(); + 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(); } - */ overlays.drawTop(); @@ -247,7 +261,7 @@ public class Renderer implements ApplicationListener{ playerGroup.count(p -> p.isFlying() == flying && p.getTeam() == team) == 0 && flying) continue; drawAndInterpolate(unitGroups[team.ordinal()], u -> u.isFlying() == flying && !u.isDead(), Unit::drawUnder); - drawAndInterpolate(playerGroup, p -> p.isFlying() == flying && p.getTeam() == team, Unit::drawUnder); + drawAndInterpolate(playerGroup, p -> p.isFlying() == flying && p.getTeam() == team && !p.isDead(), Unit::drawUnder); Shaders.outline.color.set(team.color); Shaders.mix.color.set(Color.WHITE); diff --git a/core/src/io/anuke/mindustry/core/UI.java b/core/src/io/anuke/mindustry/core/UI.java index 881ea4b0a1..85cf266f77 100644 --- a/core/src/io/anuke/mindustry/core/UI.java +++ b/core/src/io/anuke/mindustry/core/UI.java @@ -28,7 +28,7 @@ import io.anuke.arc.util.Strings; import io.anuke.arc.util.Time; import io.anuke.mindustry.editor.MapEditorDialog; import io.anuke.mindustry.game.EventType.ResizeEvent; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.ui.dialogs.*; import io.anuke.mindustry.ui.fragments.*; @@ -48,7 +48,7 @@ public class UI implements ApplicationListener{ public AboutDialog about; public GameOverDialog restart; - public CustomGameDialog levels; + public CustomGameDialog custom; public MapsDialog maps; public LoadDialog load; public DiscordDialog discord; @@ -108,7 +108,7 @@ public class UI implements ApplicationListener{ Core.app.post(() -> showError("Failed to access local storage.\nSettings will not be saved.")); }); - Colors.put("accent", Palette.accent); + Colors.put("accent", Pal.accent); loadCursors(); } @@ -163,7 +163,7 @@ public class UI implements ApplicationListener{ join = new JoinDialog(); discord = new DiscordDialog(); load = new LoadDialog(); - levels = new CustomGameDialog(); + custom = new CustomGameDialog(); language = new LanguageDialog(); database = new DatabaseDialog(); settings = new SettingsMenuDialog(); @@ -277,7 +277,7 @@ public class UI implements ApplicationListener{ public void showConfirm(String title, String text, Runnable confirmed){ FloatingDialog dialog = new FloatingDialog(title); - dialog.cont.add(text).width(400f).wrap().pad(4f).get().setAlignment(Align.center, Align.center); + dialog.cont.add(text).width(500f).wrap().pad(4f).get().setAlignment(Align.center, Align.center); dialog.buttons.defaults().size(200f, 54f).pad(2f); dialog.setFillParent(false); dialog.buttons.addButton("$cancel", dialog::hide); diff --git a/core/src/io/anuke/mindustry/core/World.java b/core/src/io/anuke/mindustry/core/World.java index 1be624f8c6..f9b85f5f97 100644 --- a/core/src/io/anuke/mindustry/core/World.java +++ b/core/src/io/anuke/mindustry/core/World.java @@ -5,21 +5,17 @@ import io.anuke.arc.Core; import io.anuke.arc.Events; import io.anuke.arc.collection.Array; import io.anuke.arc.collection.IntArray; -import io.anuke.arc.collection.ObjectSet.ObjectSetIterator; -import io.anuke.arc.entities.Effects; -import io.anuke.arc.entities.EntityQuery; +import io.anuke.mindustry.entities.EntityQuery; import io.anuke.arc.math.Mathf; import io.anuke.arc.math.geom.Geometry; import io.anuke.arc.math.geom.Point2; import io.anuke.arc.util.Log; import io.anuke.arc.util.Structs; -import io.anuke.arc.util.Time; import io.anuke.arc.util.Tmp; import io.anuke.mindustry.ai.BlockIndexer; import io.anuke.mindustry.ai.Pathfinder; import io.anuke.mindustry.ai.WaveSpawner; import io.anuke.mindustry.content.Blocks; -import io.anuke.mindustry.content.Fx; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.game.EventType.TileChangeEvent; import io.anuke.mindustry.game.EventType.WorldLoadEvent; @@ -31,7 +27,6 @@ import io.anuke.mindustry.maps.MapTileData.TileDataMarker; import io.anuke.mindustry.maps.Maps; import io.anuke.mindustry.maps.generators.Generator; import io.anuke.mindustry.type.ContentType; -import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.ItemStack; import io.anuke.mindustry.type.Zone; import io.anuke.mindustry.world.Block; @@ -190,7 +185,9 @@ public class World implements ApplicationListener{ addDarkness(tiles); - EntityQuery.resizeTree(0, 0, tiles.length * tilesize, tiles[0].length * tilesize); + int padding = 50; + + EntityQuery.resizeTree(-padding * tilesize, -padding * tilesize, (tiles.length + padding) * tilesize, (tiles[0].length + padding) * tilesize); generating = false; Events.fire(new WorldLoadEvent()); @@ -200,24 +197,6 @@ public class World implements ApplicationListener{ return generating; } - public void launchZone(){ - Effects.effect(Fx.launchFull, 0, 0); - - for(Tile tile : new ObjectSetIterator<>(state.teams.get(defaultTeam).cores)){ - Effects.effect(Fx.launch, tile); - } - - Time.runTask(30f, () -> { - for(Tile tile : new ObjectSetIterator<>(state.teams.get(defaultTeam).cores)){ - for(Item item : content.items()){ - data.addItem(item, tile.entity.items.get(item)); - } - world.removeBlock(tile); - } - state.launched = true; - }); - } - public boolean isZone(){ return getZone() != null; } @@ -230,13 +209,13 @@ public class World implements ApplicationListener{ ui.loadAnd(() -> { logic.reset(); state.rules = zone.rules.get(); + state.rules.zone = zone.id; loadGenerator(zone.generator); for(Tile core : state.teams.get(defaultTeam).cores){ for(ItemStack stack : zone.startingItems){ core.entity.items.add(stack.item, stack.amount); } } - state.rules.zone = zone.id; state.set(State.playing); control.saves.zoneSave(); logic.play(); @@ -451,7 +430,7 @@ public class World implements ApplicationListener{ for(int x = 0; x < tiles.length; x++){ for(int y = 0; y < tiles[0].length; y++){ Tile tile = tiles[x][y]; - if(tile.block().solid && !tile.block().update && tile.block().fillsTile){ + if(tile.block().solid && !tile.block().synthetic() && tile.block().fillsTile){ dark[x][y] = darkIterations; } } @@ -482,7 +461,7 @@ public class World implements ApplicationListener{ for(int x = 0; x < tiles.length; x++){ for(int y = 0; y < tiles[0].length; y++){ Tile tile = tiles[x][y]; - if(tile.block().solid && !tile.block().update){ + if(tile.block().solid && !tile.block().synthetic()){ tiles[x][y].setRotation(dark[x][y]); } } diff --git a/core/src/io/anuke/mindustry/editor/EditorTool.java b/core/src/io/anuke/mindustry/editor/EditorTool.java index fd50405241..3ec34b21da 100644 --- a/core/src/io/anuke/mindustry/editor/EditorTool.java +++ b/core/src/io/anuke/mindustry/editor/EditorTool.java @@ -1,7 +1,9 @@ package io.anuke.mindustry.editor; +import io.anuke.arc.Core; import io.anuke.arc.collection.IntArray; import io.anuke.arc.function.IntPositionConsumer; +import io.anuke.arc.input.KeyCode; import io.anuke.arc.util.Pack; import io.anuke.arc.util.Structs; import io.anuke.mindustry.content.Blocks; @@ -43,7 +45,7 @@ public enum EditorTool{ @Override public void touched(MapEditor editor, int x, int y){ - editor.draw(x, y); + editor.draw(x, y, isPaint()); } }, eraser{ @@ -54,7 +56,7 @@ public enum EditorTool{ @Override public void touched(MapEditor editor, int x, int y){ - editor.draw(x, y, Blocks.air); + editor.draw(x, y, isPaint(), Blocks.air); } }, spray{ @@ -65,7 +67,7 @@ public enum EditorTool{ @Override public void touched(MapEditor editor, int x, int y){ - editor.draw(x, y, editor.getDrawBlock(), 0.012); + editor.draw(x, y, isPaint(), editor.getDrawBlock(), 0.012); } }, line{ @@ -112,13 +114,6 @@ public enum EditorTool{ width = editor.getMap().width(); int height = editor.getMap().height(); - int x1; - boolean spanAbove, spanBelow; - - stack.clear(); - - stack.add(asi(x, y)); - IntPositionConsumer writer = (px, py) -> { TileDataMarker prev = editor.getPrev(px, py, false); @@ -135,32 +130,49 @@ public enum EditorTool{ editor.onWrite(px, py, prev); }; - while(stack.size > 0){ - int popped = stack.pop(); - x = popped % width; - y = popped / width; - - x1 = x; - while(x1 >= 0 && eq(x1, y)) x1--; - x1++; - spanAbove = spanBelow = false; - while(x1 < width && eq(x1, y)){ - writer.accept(x1, y); - - if(!spanAbove && y > 0 && eq(x1, y - 1)){ - stack.add(asi(x1, y - 1)); - spanAbove = true; - }else if(spanAbove && y > 0 && eq(x1, y - 1)){ - spanAbove = false; + if(isAlt()){ + for(int cx = 0; cx < width; cx++){ + for(int cy = 0; cy < height; cy++){ + if(eq(cx, cy)){ + writer.accept(cx, cy); + } } + } + }else{ + int x1; + boolean spanAbove, spanBelow; - if(!spanBelow && y < height - 1 && eq(x1, y + 1)){ - stack.add(asi(x1, y + 1)); - spanBelow = true; - }else if(spanBelow && y < height - 1 && eq(x1, y + 1)){ - spanBelow = false; - } + stack.clear(); + + stack.add(asi(x, y)); + + while(stack.size > 0){ + int popped = stack.pop(); + x = popped % width; + y = popped / width; + + x1 = x; + while(x1 >= 0 && eq(x1, y)) x1--; x1++; + spanAbove = spanBelow = false; + while(x1 < width && eq(x1, y)){ + writer.accept(x1, y); + + if(!spanAbove && y > 0 && eq(x1, y - 1)){ + stack.add(asi(x1, y - 1)); + spanAbove = true; + }else if(spanAbove && y > 0 && eq(x1, y - 1)){ + spanAbove = false; + } + + if(!spanBelow && y < height - 1 && eq(x1, y + 1)){ + stack.add(asi(x1, y + 1)); + spanBelow = true; + }else if(spanBelow && y < height - 1 && eq(x1, y + 1)){ + spanBelow = false; + } + x1++; + } } } } @@ -181,6 +193,14 @@ public enum EditorTool{ boolean edit, draggable; + public static boolean isPaint(){ + return Core.input.keyDown(KeyCode.CONTROL_LEFT); + } + + public static boolean isAlt(){ + return Core.input.keyDown(KeyCode.TAB); + } + public void touched(MapEditor editor, int x, int y){ } diff --git a/core/src/io/anuke/mindustry/editor/MapEditor.java b/core/src/io/anuke/mindustry/editor/MapEditor.java index 4c8b274b34..b70ab01467 100644 --- a/core/src/io/anuke/mindustry/editor/MapEditor.java +++ b/core/src/io/anuke/mindustry/editor/MapEditor.java @@ -85,15 +85,15 @@ public class MapEditor{ this.brushSize = size; } - public void draw(int x, int y){ - draw(x, y, drawBlock); + public void draw(int x, int y, boolean paint){ + draw(x, y, paint, drawBlock); } - public void draw(int x, int y, Block drawBlock){ - draw(x, y, drawBlock, 1.0); + public void draw(int x, int y, boolean paint, Block drawBlock){ + draw(x, y, paint, drawBlock, 1.0); } - public void draw(int x, int y, Block drawBlock, double chance){ + public void draw(int x, int y, boolean paint, Block drawBlock, double chance){ byte writeID = drawBlock.id; byte partID = Blocks.part.id; byte rotationTeam = Pack.byteByte(drawBlock.rotate ? (byte)rotation : 0, drawBlock.synthetic() ? (byte)drawTeam.ordinal() : 0); @@ -150,7 +150,7 @@ public class MapEditor{ if(Mathf.dst(rx, ry) <= brushSize - 0.5f && (chance >= 0.999 || Mathf.chance(chance))){ int wx = x + rx, wy = y + ry; - if(wx < 0 || wy < 0 || wx >= map.width() || wy >= map.height()){ + if(wx < 0 || wy < 0 || wx >= map.width() || wy >= map.height() || (paint && !isfloor && content.block(map.read(wx, wy, DataPosition.wall)) == Blocks.air)){ continue; } @@ -236,10 +236,21 @@ public class MapEditor{ } public void resize(int width, int height){ + MapTileData previous = map; + int offsetX = -(width - previous.width())/2, offsetY = -(height - previous.height())/2; + map = new MapTileData(width, height); for(int x = 0; x < map.width(); x++){ for(int y = 0; y < map.height(); y++){ - map.write(x, y, DataPosition.floor, Blocks.stone.id); + int px = offsetX + x, py = offsetY + y; + if(Structs.inBounds(px, py, previous.width(), previous.height())){ + map.write(x, y, DataPosition.floor, previous.read(px, py, DataPosition.floor)); + map.write(x, y, DataPosition.wall, previous.read(px, py, DataPosition.wall)); + map.write(x, y, DataPosition.link, previous.read(px, py, DataPosition.link)); + map.write(x, y, DataPosition.rotationTeam, previous.read(px, py, DataPosition.rotationTeam)); + }else{ + map.write(x, y, DataPosition.floor, Blocks.stone.id); + } } } renderer.resize(width, height); diff --git a/core/src/io/anuke/mindustry/editor/MapEditorDialog.java b/core/src/io/anuke/mindustry/editor/MapEditorDialog.java index e2d9020667..17155c2af1 100644 --- a/core/src/io/anuke/mindustry/editor/MapEditorDialog.java +++ b/core/src/io/anuke/mindustry/editor/MapEditorDialog.java @@ -167,7 +167,7 @@ public class MapEditorDialog extends Dialog implements Disposable{ editor.beginEdit(data, meta.tags, false); view.clearStack(); }catch(Exception e){ - ui.showError(Core.bundle.format("editor.errormapload", Strings.parseException(e, false))); + ui.showError(Core.bundle.format("editor.errorimageload", Strings.parseException(e, false))); Log.err(e); } })); @@ -202,7 +202,7 @@ public class MapEditorDialog extends Dialog implements Disposable{ view.clearStack(); Core.scene.setScrollFocus(view); if(!shownWithMap){ - editor.beginEdit(new MapTileData(256, 256), new ObjectMap<>(), true); + editor.beginEdit(new MapTileData(200, 200), new ObjectMap<>(), true); } shownWithMap = false; diff --git a/core/src/io/anuke/mindustry/editor/MapInfoDialog.java b/core/src/io/anuke/mindustry/editor/MapInfoDialog.java index 73b6ce6220..f1e81e7ab0 100644 --- a/core/src/io/anuke/mindustry/editor/MapInfoDialog.java +++ b/core/src/io/anuke/mindustry/editor/MapInfoDialog.java @@ -60,13 +60,6 @@ public class MapInfoDialog extends FloatingDialog{ }).size(400, 55f).get(); author.setMessageText("$unknown"); - cont.row(); - - cont.add().padRight(8).left(); - cont.addCheck("$editor.oregen", enabled -> { - tags.put("oregen", enabled ? "1" : "0"); - }).update(c -> c.setChecked(!tags.get("oregen", "0").equals("0"))).left(); - name.change(); description.change(); author.change(); diff --git a/core/src/io/anuke/mindustry/editor/MapRenderer.java b/core/src/io/anuke/mindustry/editor/MapRenderer.java index c994c9978a..5917cd67a2 100644 --- a/core/src/io/anuke/mindustry/editor/MapRenderer.java +++ b/core/src/io/anuke/mindustry/editor/MapRenderer.java @@ -6,6 +6,7 @@ import io.anuke.arc.collection.IntSet.IntSetIterator; import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.graphics.g2d.TextureRegion; +import io.anuke.arc.math.Mathf; import io.anuke.arc.util.Disposable; import io.anuke.arc.util.Pack; import io.anuke.mindustry.content.Blocks; @@ -128,22 +129,26 @@ public class MapRenderer implements Disposable{ region.getWidth() * Draw.scl, region.getHeight() * Draw.scl); } }else{ - region = floor.icon(Icon.full); + region = floor.variantRegions()[Mathf.randomSeed(idxWall, 0, floor.variantRegions().length-1)]; mesh.draw(idxWall, region, wx * tilesize, wy * tilesize, 8, 8); } + float offsetX = -(wall.size/3)*tilesize, offsetY = -(wall.size/3) * tilesize; + if(wall.update || wall.destructible){ mesh.setColor(team.color); region = Core.atlas.find("block-border"); }else if(!wall.synthetic() && bw != 0){ region = wall.icon(Icon.full) == Core.atlas.find("____") ? Core.atlas.find("clear") : wall.icon(Icon.full); + offsetX = tilesize/2f - region.getWidth()/2f * Draw.scl; + offsetY = tilesize/2f - region.getHeight()/2f * Draw.scl; }else{ region = Core.atlas.find("clear"); } mesh.draw(idxDecal, region, - wx * tilesize - (wall.size/3) * tilesize, wy * tilesize - (wall.size/3) * tilesize, + wx * tilesize + offsetX, wy * tilesize + offsetY, region.getWidth() * Draw.scl, region.getHeight() * Draw.scl); mesh.setColor(Color.WHITE); } diff --git a/core/src/io/anuke/mindustry/editor/MapResizeDialog.java b/core/src/io/anuke/mindustry/editor/MapResizeDialog.java index 95a6bb8b21..b0a9ec2cfb 100644 --- a/core/src/io/anuke/mindustry/editor/MapResizeDialog.java +++ b/core/src/io/anuke/mindustry/editor/MapResizeDialog.java @@ -1,15 +1,13 @@ package io.anuke.mindustry.editor; +import io.anuke.arc.function.BiConsumer; +import io.anuke.arc.math.Mathf; +import io.anuke.arc.scene.ui.layout.Table; import io.anuke.mindustry.maps.MapTileData; import io.anuke.mindustry.ui.dialogs.FloatingDialog; -import io.anuke.arc.function.BiConsumer; -import io.anuke.arc.scene.ui.ButtonGroup; -import io.anuke.arc.scene.ui.TextButton; -import io.anuke.arc.scene.ui.layout.Table; -import io.anuke.arc.math.Mathf; public class MapResizeDialog extends FloatingDialog{ - int[] validMapSizes = {200, 300, 400, 500}; + private static final int minSize = 50, maxSize = 500, increment = 50; int width, height; public MapResizeDialog(MapEditor editor, BiConsumer cons){ @@ -23,28 +21,23 @@ public class MapResizeDialog extends FloatingDialog{ Table table = new Table(); for(boolean w : Mathf.booleans){ - int curr = w ? data.width() : data.height(); - int idx = 0; - for(int i = 0; i < validMapSizes.length; i++){ - if(validMapSizes[i] == curr) idx = i; - } - table.add(w ? "$width" : "$height").padRight(8f); - ButtonGroup group = new ButtonGroup<>(); - for(int i = 0; i < validMapSizes.length; i++){ - int size = validMapSizes[i]; - TextButton button = new TextButton(size + "", "toggle"); - button.clicked(() -> { - if(w) - width = size; - else - height = size; - }); - group.add(button); - if(i == idx) button.setChecked(true); - table.add(button).size(100f, 54f).pad(2f); - } + table.defaults().height(60f).padTop(8); + table.addButton("<", () -> { + if(w) + width = move(width, -1); + else + height = move(height, -1); + }).size(60f); + table.table("button", t -> t.label(() -> (w ? width : height) + "")).width(200); + + table.addButton(">", () -> { + if(w) + width = move(width, 1); + else + height = move(height, 1); + }).size(60f); table.row(); } cont.row(); @@ -58,6 +51,9 @@ public class MapResizeDialog extends FloatingDialog{ cons.accept(width, height); hide(); }); + } + static int move(int value, int direction){ + return Mathf.clamp((value / increment + direction) * increment, minSize, maxSize); } } diff --git a/core/src/io/anuke/mindustry/editor/MapView.java b/core/src/io/anuke/mindustry/editor/MapView.java index 66cb6c748c..d382439978 100644 --- a/core/src/io/anuke/mindustry/editor/MapView.java +++ b/core/src/io/anuke/mindustry/editor/MapView.java @@ -19,7 +19,7 @@ import io.anuke.arc.scene.ui.TextField; import io.anuke.arc.scene.ui.layout.Unit; import io.anuke.arc.util.Tmp; import io.anuke.mindustry.editor.DrawOperation.TileOperation; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.input.Binding; import io.anuke.mindustry.ui.GridImage; @@ -58,6 +58,8 @@ public class MapView extends Element implements GestureListener{ Core.input.getInputProcessors().insert(0, new GestureDetector(20, 0.5f, 2, 0.15f, this)); touchable(Touchable.enabled); + Point2 firstTouch = new Point2(); + addListener(new InputListener(){ @Override @@ -67,7 +69,6 @@ public class MapView extends Element implements GestureListener{ return false; } - @Override public boolean touchDown(InputEvent event, float x, float y, int pointer, KeyCode button){ if(pointer != 0){ @@ -96,6 +97,7 @@ public class MapView extends Element implements GestureListener{ startx = p.x; starty = p.y; tool.touched(editor, p.x, p.y); + firstTouch.set(p); if(tool.edit){ updated = true; @@ -117,10 +119,18 @@ public class MapView extends Element implements GestureListener{ Point2 p = project(x, y); if(tool == EditorTool.line){ + if(Core.input.keyDown(KeyCode.TAB)){ + if(Math.abs(p.x - firstTouch.x) > Math.abs(p.y - firstTouch.y)){ + p.y = firstTouch.y; + }else{ + p.x = firstTouch.x; + } + } + ui.editor.resetSaved(); Array points = br.line(startx, starty, p.x, p.y); for(Point2 point : points){ - editor.draw(point.x, point.y); + editor.draw(point.x, point.y, EditorTool.isPaint()); } updated = true; } @@ -132,7 +142,7 @@ public class MapView extends Element implements GestureListener{ op = null; } - if(lastTool != null){ + if(button == KeyCode.MOUSE_MIDDLE && lastTool != null){ tool = lastTool; lastTool = null; } @@ -141,6 +151,7 @@ public class MapView extends Element implements GestureListener{ @Override public void touchDragged(InputEvent event, float x, float y, int pointer){ + mousex = x; mousey = y; @@ -154,8 +165,19 @@ public class MapView extends Element implements GestureListener{ } updated = true; } - lastx = p.x; - lasty = p.y; + + if(tool == EditorTool.line && Core.input.keyDown(KeyCode.TAB)){ + if(Math.abs(p.x - firstTouch.x) > Math.abs(p.y - firstTouch.y)){ + lastx = p.x; + lasty = firstTouch.y; + }else{ + lastx = firstTouch.x; + lasty = p.y; + } + }else{ + lastx = p.x; + lasty = p.y; + } } }); } @@ -216,6 +238,16 @@ public class MapView extends Element implements GestureListener{ offsety -= ay * 15f / zoom; } + if(Core.input.keyTap(KeyCode.SHIFT_LEFT)){ + lastTool = tool; + tool = EditorTool.pick; + } + + if(Core.input.keyRelease(KeyCode.SHIFT_LEFT) && lastTool != null){ + tool = lastTool; + lastTool = null; + } + if(ui.editor.hasPane()) return; zoom += Core.input.axis(KeyCode.SCROLL) / 10f * zoom; @@ -267,7 +299,7 @@ public class MapView extends Element implements GestureListener{ return; } - Draw.color(Palette.remove); + Draw.color(Pal.remove); Lines.stroke(2f); Lines.rect(centerx - sclwidth / 2 - 1, centery - sclheight / 2 - 1, sclwidth + 2, sclheight + 2); editor.renderer().draw(centerx - sclwidth / 2, centery - sclheight / 2, sclwidth, sclheight); @@ -294,10 +326,10 @@ public class MapView extends Element implements GestureListener{ float scaling = zoom * Math.min(width, height) / editor.getMap().width(); - Draw.color(Palette.accent); - Lines.stroke(Unit.dp.scl(1f * zoom)); + Draw.color(Pal.accent); + Lines.stroke(Unit.dp.scl(2f)); - if(!editor.getDrawBlock().isMultiblock() || tool == EditorTool.eraser){ + if((!editor.getDrawBlock().isMultiblock() || tool == EditorTool.eraser) && tool != EditorTool.fill){ if(tool == EditorTool.line && drawing){ Vector2 v1 = unproject(startx, starty).add(x, y); float sx = v1.x, sy = v1.y; @@ -307,7 +339,7 @@ public class MapView extends Element implements GestureListener{ Lines.poly(brushPolygons[index], v2.x, v2.y, scaling); } - if(tool.edit && (!mobile || drawing)){ + if((tool.edit || (tool == EditorTool.line && !drawing)) && (!mobile || drawing)){ Point2 p = project(mousex, mousey); Vector2 v = unproject(p.x, p.y).add(x, y); Lines.poly(brushPolygons[index], v.x, v.y, scaling); @@ -324,7 +356,7 @@ public class MapView extends Element implements GestureListener{ } } - Draw.color(Palette.accent); + Draw.color(Pal.accent); Lines.stroke(Unit.dp.scl(3f)); Lines.rect(x, y, width, height); Draw.reset(); diff --git a/core/src/io/anuke/mindustry/entities/Damage.java b/core/src/io/anuke/mindustry/entities/Damage.java index e8b51dbf35..79194260c7 100644 --- a/core/src/io/anuke/mindustry/entities/Damage.java +++ b/core/src/io/anuke/mindustry/entities/Damage.java @@ -1,7 +1,6 @@ package io.anuke.mindustry.entities; -import io.anuke.arc.entities.Effects; -import io.anuke.arc.entities.Effects.Effect; +import io.anuke.mindustry.entities.Effects.Effect; import io.anuke.arc.function.Consumer; import io.anuke.arc.function.Predicate; import io.anuke.arc.graphics.Color; @@ -15,9 +14,10 @@ import io.anuke.mindustry.content.Fx; import io.anuke.mindustry.entities.bullet.Bullet; import io.anuke.mindustry.entities.effect.Fire; import io.anuke.mindustry.entities.effect.Lightning; +import io.anuke.mindustry.entities.type.Unit; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.gen.Call; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.world.Tile; import static io.anuke.mindustry.Vars.*; @@ -32,7 +32,7 @@ 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.none, Palette.power, 3, + Time.run(i * 2f + Mathf.random(4f), () -> Lightning.create(Team.none, Pal.power, 3, x, y, Mathf.random(360f), branches + Mathf.range(2))); } @@ -109,7 +109,7 @@ public class Damage{ rect.width += expand * 2; rect.height += expand * 2; - Consumer cons = e -> { + Consumer cons = e -> { e.hitbox(hitrect); Rectangle other = hitrect; other.y -= expand; @@ -130,8 +130,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, Predicate predicate, Consumer acceptor){ - Consumer cons = entity -> { + public static void damageUnits(Team team, float x, float y, float size, float damage, Predicate predicate, Consumer acceptor){ + Consumer cons = entity -> { if(!predicate.test(entity)) return; entity.hitbox(hitrect); @@ -158,14 +158,14 @@ 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){ Consumer cons = entity -> { - if(entity.team == team || entity.dst(x, y) > radius){ + if(entity.getTeam() == team || entity.dst(x, y) > radius){ return; } float amount = calculateDamage(x, y, entity.x, entity.y, 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.velocity().add(tr.setLength((1f - dst / radius) * 2f / entity.mass())); }; rect.setSize(radius * 2).setCenter(x, y); diff --git a/core/src/io/anuke/mindustry/entities/Effects.java b/core/src/io/anuke/mindustry/entities/Effects.java new file mode 100644 index 0000000000..576d5cc56e --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/Effects.java @@ -0,0 +1,166 @@ +package io.anuke.mindustry.entities; + +import io.anuke.arc.Core; +import io.anuke.arc.collection.Array; +import io.anuke.arc.function.Consumer; +import io.anuke.arc.graphics.Color; +import io.anuke.arc.math.Mathf; +import io.anuke.arc.math.geom.Position; +import io.anuke.arc.util.pooling.Pools; +import io.anuke.mindustry.entities.impl.EffectEntity; +import io.anuke.mindustry.entities.traits.ScaleTrait; + +public class Effects{ + private static final EffectContainer container = new EffectContainer(); + private static Array effects = new Array<>(); + private static ScreenshakeProvider shakeProvider; + private static float shakeFalloff = 1000f; + 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); + } + + 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 void shake(float intensity, float duration){ + if(shakeProvider == null) throw new RuntimeException("Screenshake provider is null! Set it first."); + shakeProvider.accept(intensity, duration); + } + + public static void shake(float intensity, float duration, float x, float y){ + if(Core.camera == null) return; + + float distance = Core.camera.position.dst(x, y); + if(distance < 1) distance = 1; + + shake(Mathf.clamp(1f / (distance * distance / shakeFalloff)) * intensity, duration); + } + + public static void shake(float intensity, float duration, Position loc){ + shake(intensity, duration, loc.getX(), loc.getY()); + } + + public interface ScreenshakeProvider{ + void accept(float intensity, float duration); + } + + 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 ScaleTrait{ + 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, Consumer cons){ + if(innerContainer == null) innerContainer = new EffectContainer(); + if(time <= lifetime){ + innerContainer.set(id, color, time, lifetime, rotation, x, y, data); + cons.accept(innerContainer); + } + } + + @Override + public float fin(){ + return time / lifetime; + } + } + + public static interface EffectProvider{ + void createEffect(Effect effect, Color color, float x, float y, float rotation, Object data); + } + + public static interface EffectRenderer{ + void render(EffectContainer effect); + } +} diff --git a/core/src/io/anuke/mindustry/entities/Entities.java b/core/src/io/anuke/mindustry/entities/Entities.java new file mode 100755 index 0000000000..94a2baa629 --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/Entities.java @@ -0,0 +1,66 @@ +package io.anuke.mindustry.entities; + +import io.anuke.arc.collection.Array; +import io.anuke.arc.collection.IntMap; +import io.anuke.mindustry.entities.traits.Entity; + +public class Entities{ + public static final int maxLeafObjects = 5; + private static final EntityGroup defaultGroup; + private static final Array> groupArray = new Array<>(); + private static final IntMap> groups = new IntMap<>(); + + static{ + defaultGroup = addGroup(Entity.class); + } + + public static void clear(){ + for(EntityGroup group : groupArray){ + group.clear(); + } + } + + public static Iterable all(){ + return defaultGroup.all(); + } + + public static EntityGroup getGroup(int id){ + return groups.get(id); + } + + public static Iterable> getAllGroups(){ + return groups.values(); + } + + public static EntityGroup defaultGroup(){ + return defaultGroup; + } + + public static EntityGroup addGroup(Class type){ + return addGroup(type, true); + } + + public static EntityGroup addGroup(Class type, boolean useTree){ + EntityGroup group = new EntityGroup<>(type, useTree); + groups.put(group.getID(), group); + groupArray.add(group); + return group; + } + + public static void update(){ + update(defaultGroup()); + EntityQuery.collideGroups(defaultGroup(), defaultGroup()); + } + + public static void update(EntityGroup group){ + group.updateEvents(); + + if(group.useTree()){ + EntityQuery.collisions().updatePhysics(group); + } + + for(Entity e : group.all()){ + e.update(); + } + } +} diff --git a/core/src/io/anuke/mindustry/entities/EntityCollisions.java b/core/src/io/anuke/mindustry/entities/EntityCollisions.java new file mode 100644 index 0000000000..62e5e214d6 --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/EntityCollisions.java @@ -0,0 +1,261 @@ +package io.anuke.mindustry.entities; + +import io.anuke.arc.collection.Array; +import io.anuke.arc.collection.IntSet; +import io.anuke.arc.math.Mathf; +import io.anuke.arc.math.geom.Geometry; +import io.anuke.arc.math.geom.QuadTree; +import io.anuke.arc.math.geom.Rectangle; +import io.anuke.arc.math.geom.Vector2; +import io.anuke.mindustry.entities.traits.Entity; +import io.anuke.mindustry.entities.traits.SolidTrait; + +public class EntityCollisions{ + //range for tile collision scanning + private static final int r = 2; + //move in 1-unit chunks + private static final float seg = 1f; + + //tile collisions + private float tilesize; + private Rectangle tmp = new Rectangle(); + private TileCollider collider; + private TileHitboxProvider hitboxProvider; + private Vector2 vector = new Vector2(); + private Vector2 l1 = new Vector2(); + private Rectangle r1 = new Rectangle(); + private Rectangle r2 = new Rectangle(); + + //entity collisions + private IntSet collided = new IntSet(); + private Array arrOut = new Array<>(); + + public void setCollider(float tilesize, TileCollider collider, TileHitboxProvider hitbox){ + this.tilesize = tilesize; + this.collider = collider; + this.hitboxProvider = hitbox; + } + + public void setCollider(float tilesize, TileCollider collider){ + setCollider(tilesize, collider, (x, y, out) -> out.setSize(tilesize).setCenter(x * tilesize, y * tilesize)); + } + + public void move(SolidTrait entity, float deltax, float deltay){ + + boolean movedx = false; + + while(Math.abs(deltax) > 0 || !movedx){ + movedx = true; + moveInternal(entity, Math.min(Math.abs(deltax), seg) * Mathf.sign(deltax), 0, true); + + if(Math.abs(deltax) >= seg){ + deltax -= seg * Mathf.sign(deltax); + }else{ + deltax = 0f; + } + } + + boolean movedy = false; + + while(Math.abs(deltay) > 0 || !movedy){ + movedy = true; + moveInternal(entity, 0, Math.min(Math.abs(deltay), seg) * Mathf.sign(deltay), false); + + if(Math.abs(deltay) >= seg){ + deltay -= seg * Mathf.sign(deltay); + }else{ + deltay = 0f; + } + } + } + + public void moveInternal(SolidTrait entity, float deltax, float deltay, boolean x){ + if(collider == null) + throw new IllegalArgumentException("No tile collider specified! Call setCollider() first."); + + Rectangle rect = r1; + entity.hitboxTile(rect); + entity.hitboxTile(r2); + rect.x += deltax; + rect.y += deltay; + + int tilex = Math.round((rect.x + rect.width / 2) / tilesize), tiley = Math.round((rect.y + rect.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(collider.solid(wx, wy) && entity.collidesGrid(wx, wy)){ + + hitboxProvider.getHitbox(wx, wy, tmp); + + if(tmp.overlaps(rect)){ + Vector2 v = Geometry.overlap(rect, tmp, x); + rect.x += v.x; + rect.y += v.y; + } + } + } + } + + entity.setX(entity.getX() + rect.x - r2.x); + entity.setY(entity.getY() + rect.y - r2.y); + } + + public boolean overlapsTile(Rectangle rect){ + if(collider == null) + throw new IllegalArgumentException("No tile collider specified! Call setCollider() first."); + + rect.getCenter(vector); + int r = 1; + + //assumes tiles are centered + int tilex = Math.round(vector.x / tilesize); + int tiley = Math.round(vector.y / tilesize); + + for(int dx = -r; dx <= r; dx++){ + for(int dy = -r; dy <= r; dy++){ + int wx = dx + tilex, wy = dy + tiley; + if(collider.solid(wx, wy)){ + hitboxProvider.getHitbox(wx, wy, r2); + + if(r2.overlaps(rect)){ + return true; + } + } + } + } + return false; + } + + public void updatePhysics(EntityGroup group){ + collided.clear(); + + 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); + } + } + } + + private void checkCollide(Entity entity, Entity other){ + + SolidTrait a = (SolidTrait) entity; + SolidTrait b = (SolidTrait) other; + + 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()); + + 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; + + if(a != b && a.collides(b) && b.collides(a)){ + 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); + if(collide){ + a.collision(b, l1.x, l1.y); + b.collision(a, l1.x, l1.y); + } + } + } + + private boolean collide(float x1, float y1, float w1, float h1, float vx1, float vy1, + float x2, float y2, float w2, float h2, float vx2, float vy2, Vector2 out){ + float px = vx1, py = vy1; + + vx1 -= vx2; + vy1 -= vy2; + + float xInvEntry, yInvEntry; + float xInvExit, yInvExit; + + if(vx1 > 0.0f){ + xInvEntry = x2 - (x1 + w1); + xInvExit = (x2 + w2) - x1; + }else{ + xInvEntry = (x2 + w2) - x1; + xInvExit = x2 - (x1 + w1); + } + + if(vy1 > 0.0f){ + yInvEntry = y2 - (y1 + h1); + yInvExit = (y2 + h2) - y1; + }else{ + yInvEntry = (y2 + h2) - y1; + yInvExit = y2 - (y1 + h1); + } + + float xEntry, yEntry; + float xExit, yExit; + + xEntry = xInvEntry / vx1; + xExit = xInvExit / vx1; + + yEntry = yInvEntry / vy1; + yExit = yInvExit / vy1; + + float entryTime = Math.max(xEntry, yEntry); + float exitTime = Math.min(xExit, yExit); + + if(entryTime > exitTime || xExit < 0.0f || yExit < 0.0f || xEntry > 1.0f || yEntry > 1.0f){ + return false; + }else{ + float dx = x1 + w1 / 2f + px * entryTime; + float dy = y1 + h1 / 2f + py * entryTime; + + out.set(dx, dy); + + return true; + } + } + + public void collideGroups(EntityGroup groupa, EntityGroup groupb){ + collided.clear(); + + for(Entity entity : groupa.all()){ + if(!(entity instanceof SolidTrait) || collided.contains(entity.getID())) + continue; + + SolidTrait solid = (SolidTrait) entity; + + solid.hitbox(r1); + r1.x += (solid.lastPosition().x - solid.getX()); + r1.y += (solid.lastPosition().y - solid.getY()); + + solid.hitbox(r2); + r2.merge(r1); + + arrOut.clear(); + groupb.tree().getIntersect(arrOut, r2); + + for(SolidTrait sc : arrOut){ + sc.hitbox(r1); + if(r2.overlaps(r1) && !collided.contains(sc.getID())){ + checkCollide(entity, sc); + } + } + + collided.add(entity.getID()); + } + } + + public interface TileCollider{ + boolean solid(int x, int y); + } + + public interface TileHitboxProvider{ + void getHitbox(int x, int y, Rectangle out); + } +} diff --git a/core/src/io/anuke/mindustry/entities/EntityDraw.java b/core/src/io/anuke/mindustry/entities/EntityDraw.java new file mode 100644 index 0000000000..e0a95627c2 --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/EntityDraw.java @@ -0,0 +1,56 @@ +package io.anuke.mindustry.entities; + +import io.anuke.arc.Core; +import io.anuke.arc.function.Consumer; +import io.anuke.arc.function.Predicate; +import io.anuke.arc.graphics.Camera; +import io.anuke.arc.math.geom.Rectangle; +import io.anuke.mindustry.entities.traits.DrawTrait; + +public class EntityDraw{ + private static final Rectangle viewport = new Rectangle(); + private static final Rectangle rect = new Rectangle(); + private static boolean clip = true; + private static int count = 0; + + public static void setClip(boolean clip){ + EntityDraw.clip = clip; + } + + public static int countInBounds(EntityGroup group){ + count = 0; + drawWith(group, e -> true, e -> count++); + return count; + } + + public static void draw(){ + draw(Entities.defaultGroup()); + } + + public static void draw(EntityGroup group){ + draw(group, e -> true); + } + + public static void draw(EntityGroup group, Predicate toDraw){ + drawWith(group, toDraw, DrawTrait::draw); + } + + @SuppressWarnings("unchecked") + public static void drawWith(EntityGroup group, Predicate toDraw, Consumer cons){ + if(clip){ + Camera cam = Core.camera; + viewport.set(cam.position.x - cam.width / 2, cam.position.y - cam.height / 2, cam.width, cam.height); + } + + group.forEach(e -> { + if(!(e instanceof DrawTrait)) return; + T t = (T) e; + + if(!toDraw.test(t) || !e.isAdded()) return; + + if(!clip || rect.setSize(((DrawTrait) e).drawSize()).setCenter(e.getX(), e.getY()).overlaps(viewport)){ + cons.accept(t); + } + }); + } +} diff --git a/core/src/io/anuke/mindustry/entities/EntityGroup.java b/core/src/io/anuke/mindustry/entities/EntityGroup.java new file mode 100644 index 0000000000..2050535843 --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/EntityGroup.java @@ -0,0 +1,194 @@ +package io.anuke.mindustry.entities; + +import io.anuke.arc.collection.Array; +import io.anuke.arc.collection.IntMap; +import io.anuke.arc.function.Consumer; +import io.anuke.arc.function.Predicate; +import io.anuke.arc.math.geom.QuadTree; +import io.anuke.arc.math.geom.Rectangle; +import io.anuke.mindustry.entities.traits.Entity; + +public class EntityGroup{ + private static int lastid; + private final boolean useTree; + private final int id; + private final Class type; + private final Array entityArray = new Array<>(false, 16); + private final Array entitiesToRemove = new Array<>(false, 16); + private final Array entitiesToAdd = new Array<>(false, 16); + private IntMap map; + private QuadTree tree; + private Consumer removeListener; + private Consumer addListener; + + public EntityGroup(Class type, boolean useTree){ + this.useTree = useTree; + this.id = lastid++; + this.type = type; + } + + public boolean useTree(){ + return useTree; + } + + public void setRemoveListener(Consumer removeListener){ + this.removeListener = removeListener; + } + + public void setAddListener(Consumer addListener){ + this.addListener = addListener; + } + + public EntityGroup enableMapping(){ + map = new IntMap<>(); + return this; + } + + public boolean mappingEnabled(){ + return map != null; + } + + public Class getType(){ + return type; + } + + public int getID(){ + return id; + } + + public void updateEvents(){ + + for(T e : entitiesToAdd){ + if(e == null) + continue; + entityArray.add(e); + e.added(); + + if(map != null){ + map.put(e.getID(), e); + } + } + + entitiesToAdd.clear(); + + for(T e : entitiesToRemove){ + entityArray.removeValue(e, true); + if(map != null){ + map.remove(e.getID()); + } + e.removed(); + } + + entitiesToRemove.clear(); + } + + public T getByID(int id){ + if(map == null) throw new RuntimeException("Mapping is not enabled for group " + id + "!"); + return map.get(id); + } + + public void removeByID(int id){ + if(map == null) throw new RuntimeException("Mapping is not enabled for group " + id + "!"); + T t = map.get(id); + if(t != null){ //remove if present in map already + remove(t); + }else{ //maybe it's being queued? + for(T check : entitiesToAdd){ + if(check.getID() == id){ //if it is indeed queued, remove it + entitiesToAdd.removeValue(check, true); + if(removeListener != null){ + removeListener.accept(check); + } + break; + } + } + } + } + + public QuadTree tree(){ + return tree; + } + + public void setTree(float x, float y, float w, float h){ + tree = new QuadTree<>(Entities.maxLeafObjects, new Rectangle(x, y, w, h)); + } + + public boolean isEmpty(){ + return entityArray.size == 0; + } + + public int size(){ + return entityArray.size; + } + + public int count(Predicate pred){ + int count = 0; + for(int i = 0; i < entityArray.size; i++){ + if(pred.test(entityArray.get(i))) count++; + } + return count; + } + + public void add(T type){ + if(type == null) throw new RuntimeException("Cannot add a null entity!"); + if(type.getGroup() != null) return; + type.setGroup(this); + entitiesToAdd.add(type); + + if(mappingEnabled()){ + map.put(type.getID(), type); + } + + if(addListener != null){ + addListener.accept(type); + } + } + + public void remove(T type){ + if(type == null) throw new RuntimeException("Cannot remove a null entity!"); + type.setGroup(null); + entitiesToRemove.add(type); + + if(removeListener != null){ + removeListener.accept(type); + } + } + + public void clear(){ + for(T entity : entityArray) + entity.setGroup(null); + + for(T entity : entitiesToAdd) + entity.setGroup(null); + + for(T entity : entitiesToRemove) + entity.setGroup(null); + + entitiesToAdd.clear(); + entitiesToRemove.clear(); + entityArray.clear(); + if(map != null) + map.clear(); + } + + public T find(Predicate pred){ + + for(int i = 0; i < entityArray.size; i++){ + if(pred.test(entityArray.get(i))) return entityArray.get(i); + } + + return null; + } + + /**Returns the logic-only array for iteration.*/ + public Array all(){ + return entityArray; + } + + public void forEach(Consumer cons){ + + for(T t : entityArray){ + cons.accept(t); + } + } +} diff --git a/core/src/io/anuke/mindustry/entities/EntityQuery.java b/core/src/io/anuke/mindustry/entities/EntityQuery.java new file mode 100644 index 0000000000..8e25527400 --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/EntityQuery.java @@ -0,0 +1,95 @@ +package io.anuke.mindustry.entities; + +import io.anuke.arc.collection.Array; +import io.anuke.arc.function.Consumer; +import io.anuke.arc.function.Predicate; +import io.anuke.arc.math.Mathf; +import io.anuke.arc.math.geom.Rectangle; +import io.anuke.mindustry.entities.traits.Entity; +import io.anuke.mindustry.entities.traits.SolidTrait; + +import static io.anuke.mindustry.entities.Entities.defaultGroup; + +public class EntityQuery{ + private static final EntityCollisions collisions = new EntityCollisions(); + private static final Array array = new Array<>(); + private static final Rectangle r1 = new Rectangle(); + + public static EntityCollisions collisions(){ + return collisions; + } + + public static void init(float x, float y, float w, float h){ + + for(EntityGroup group : Entities.getAllGroups()){ + if(group.useTree()){ + group.setTree(x, y, w, h); + } + } + } + + public static void init(){ + init(0, 0, 0, 0); + } + + public static void resizeTree(float x, float y, float w, float h){ + init(x, y, w, h); + } + + public static void getNearby(EntityGroup group, Rectangle rect, Consumer out){ + + if(!group.useTree()) + throw new RuntimeException("This group does not support quadtrees! Enable quadtrees when creating it."); + group.tree().getIntersect(out, rect); + } + + public static Array getNearby(EntityGroup group, Rectangle rect){ + + array.clear(); + if(!group.useTree()) + throw new RuntimeException("This group does not support quadtrees! Enable quadtrees when creating it."); + group.tree().getIntersect(array, rect); + return array; + } + + public static void getNearby(float x, float y, float size, Consumer out){ + getNearby(defaultGroup(), r1.setSize(size).setCenter(x, y), out); + } + + public static void getNearby(EntityGroup group, float x, float y, float size, Consumer out){ + getNearby(group, r1.setSize(size).setCenter(x, y), out); + } + + public static Array getNearby(float x, float y, float size){ + return getNearby(defaultGroup(), r1.setSize(size).setCenter(x, y)); + } + + public static Array getNearby(EntityGroup group, float x, float y, float size){ + return getNearby(group, r1.setSize(size).setCenter(x, y)); + } + + public static T getClosest(EntityGroup group, float x, float y, float range, Predicate pred){ + + T closest = null; + float cdist = 0f; + Array entities = getNearby(group, x, y, range * 2f); + for(int i = 0; i < entities.size; i++){ + T e = (T) entities.get(i); + if(!pred.test(e)) + continue; + + float dist = Mathf.dst(e.getX(), e.getY(), x, y); + if(dist < range) + if(closest == null || dist < cdist){ + closest = e; + cdist = dist; + } + } + + return closest; + } + + public static void collideGroups(EntityGroup groupa, EntityGroup groupb){ + collisions().collideGroups(groupa, groupb); + } +} diff --git a/core/src/io/anuke/mindustry/entities/UnitInventory.java b/core/src/io/anuke/mindustry/entities/UnitInventory.java deleted file mode 100644 index d4d27d3a3d..0000000000 --- a/core/src/io/anuke/mindustry/entities/UnitInventory.java +++ /dev/null @@ -1,88 +0,0 @@ -package io.anuke.mindustry.entities; - -import io.anuke.mindustry.entities.traits.Saveable; -import io.anuke.mindustry.type.Item; -import io.anuke.mindustry.type.ItemStack; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -import static io.anuke.mindustry.Vars.content; - -public class UnitInventory implements Saveable{ - private final Unit unit; - private ItemStack item = new ItemStack(content.item(0), 0); - - public UnitInventory(Unit unit){ - this.unit = unit; - } - - public boolean isFull(){ - return item != null && item.amount >= unit.getItemCapacity(); - } - - @Override - public void writeSave(DataOutput stream) throws IOException{ - stream.writeByte(item.amount); - stream.writeByte(item.item.id); - } - - @Override - public void readSave(DataInput stream) throws IOException{ - int iamount = stream.readUnsignedByte(); - byte iid = stream.readByte(); - - item.item = content.item(iid); - item.amount = iamount; - } - - public void clear(){ - item.amount = 0; - } - - public int capacity(){ - return unit.getItemCapacity(); - } - - public boolean isEmpty(){ - return item.amount == 0; - } - - public int itemCapacityUsed(Item type){ - if(canAcceptItem(type)){ - return !hasItem() ? unit.getItemCapacity() : (unit.getItemCapacity() - item.amount); - }else{ - return unit.getItemCapacity(); - } - } - - public boolean canAcceptItem(Item type){ - return (!hasItem() && 1 <= unit.getItemCapacity()) || (item.item == type && unit.getItemCapacity() - item.amount > 0); - } - - public boolean canAcceptItem(Item type, int amount){ - return (!hasItem() && amount <= unit.getItemCapacity()) || (item.item == type && item.amount + amount <= unit.getItemCapacity()); - } - - public void clearItem(){ - item.amount = 0; - } - - public boolean hasItem(){ - return item.amount > 0; - } - - public boolean hasItem(Item i, int amount){ - return item.item == i && item.amount >= amount; - } - - public void addItem(Item item, int amount){ - getItem().amount = getItem().item == item ? getItem().amount + amount : amount; - getItem().item = item; - } - - public ItemStack getItem(){ - return item; - } -} diff --git a/core/src/io/anuke/mindustry/entities/Units.java b/core/src/io/anuke/mindustry/entities/Units.java index a265a9bcd0..d9c82f7ec0 100644 --- a/core/src/io/anuke/mindustry/entities/Units.java +++ b/core/src/io/anuke/mindustry/entities/Units.java @@ -1,15 +1,16 @@ package io.anuke.mindustry.entities; import io.anuke.arc.collection.EnumSet; -import io.anuke.arc.entities.EntityGroup; -import io.anuke.arc.entities.EntityQuery; import io.anuke.arc.function.Consumer; import io.anuke.arc.function.Predicate; import io.anuke.arc.math.Mathf; import io.anuke.arc.math.geom.Geometry; import io.anuke.arc.math.geom.Rectangle; import io.anuke.mindustry.entities.traits.TargetTrait; -import io.anuke.mindustry.entities.units.BaseUnit; +import io.anuke.mindustry.entities.type.Player; +import io.anuke.mindustry.entities.type.TileEntity; +import io.anuke.mindustry.entities.type.BaseUnit; +import io.anuke.mindustry.entities.type.Unit; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; @@ -21,11 +22,10 @@ import static io.anuke.mindustry.Vars.*; */ public class Units{ private static Rectangle rect = new Rectangle(); - private static Rectangle rectGraphics = new Rectangle(); private static Rectangle hitrect = new Rectangle(); private static Unit result; private static float cdist; - private static boolean boolResult, boolResultGraphics; + private static boolean boolResult; /** * Validates a target. @@ -48,7 +48,7 @@ public class Units{ /**See {@link #invalidateTarget(TargetTrait, Team, float, float, float)}*/ public static boolean invalidateTarget(TargetTrait target, Unit targeter){ - return invalidateTarget(target, targeter.team, targeter.x, targeter.y, targeter.getWeapon().getAmmo().range()); + return invalidateTarget(target, targeter.getTeam(), targeter.x, targeter.y, targeter.getWeapon().bullet.range()); } /**Returns whether there are any entities on this tile.*/ @@ -101,18 +101,18 @@ public class Units{ } /**Returns the neareset damaged tile.*/ - public static TileEntity findDamagedTile(Team team, float x, float y){ + public static io.anuke.mindustry.entities.type.TileEntity findDamagedTile(Team team, float x, float y){ Tile tile = Geometry.findClosest(x, y, world.indexer.getDamaged(team)); return tile == null ? null : tile.entity; } /**Returns the neareset ally tile in a range.*/ - public static TileEntity findAllyTile(Team team, float x, float y, float range, Predicate pred){ + public static io.anuke.mindustry.entities.type.TileEntity findAllyTile(Team team, float x, float y, float range, Predicate pred){ return world.indexer.findTile(team, x, y, range, pred); } /**Returns the neareset enemy tile in a range.*/ - public static TileEntity findEnemyTile(Team team, float x, float y, float range, Predicate pred){ + public static io.anuke.mindustry.entities.type.TileEntity findEnemyTile(Team team, float x, float y, float range, Predicate pred){ for(Team enemy : state.teams.enemiesOf(team)){ TileEntity entity = world.indexer.findTile(enemy, x, y, range, pred); if(entity != null){ @@ -134,7 +134,7 @@ public class Units{ } //then check all player groups - for(Player player : playerGroup.all()){ + for(io.anuke.mindustry.entities.type.Player player : playerGroup.all()){ cons.accept(player); } } @@ -210,7 +210,7 @@ public class Units{ //now check all players EntityQuery.getNearby(playerGroup, rect, player -> { - if(((Unit) player).team == team) cons.accept((Unit) player); + if(((Unit) player).getTeam() == team) cons.accept((Unit) player); }); } @@ -229,7 +229,7 @@ public class Units{ //now check all players EntityQuery.getNearby(playerGroup, rect, player -> { - if(((Unit) player).team == team && player.dst(x, y) <= radius){ + if(((Unit) player).getTeam() == team && player.dst(x, y) <= radius){ cons.accept((Unit) player); } }); @@ -262,7 +262,7 @@ public class Units{ //now check all enemy players EntityQuery.getNearby(playerGroup, rect, player -> { - if(targets.contains(((Player) player).team)){ + if(targets.contains(((Player) player).getTeam())){ cons.accept((Unit) player); } }); diff --git a/core/src/io/anuke/mindustry/entities/bullet/ArtilleryBulletType.java b/core/src/io/anuke/mindustry/entities/bullet/ArtilleryBulletType.java index ee5237a2c8..5c74a9f9f7 100644 --- a/core/src/io/anuke/mindustry/entities/bullet/ArtilleryBulletType.java +++ b/core/src/io/anuke/mindustry/entities/bullet/ArtilleryBulletType.java @@ -1,7 +1,7 @@ package io.anuke.mindustry.entities.bullet; -import io.anuke.arc.entities.Effects; -import io.anuke.arc.entities.Effects.Effect; +import io.anuke.mindustry.entities.Effects; +import io.anuke.mindustry.entities.Effects.Effect; import io.anuke.arc.graphics.g2d.Draw; import io.anuke.mindustry.content.Fx; diff --git a/core/src/io/anuke/mindustry/entities/bullet/BasicBulletType.java b/core/src/io/anuke/mindustry/entities/bullet/BasicBulletType.java index 6152de43fa..b1127b6581 100644 --- a/core/src/io/anuke/mindustry/entities/bullet/BasicBulletType.java +++ b/core/src/io/anuke/mindustry/entities/bullet/BasicBulletType.java @@ -1,22 +1,21 @@ package io.anuke.mindustry.entities.bullet; import io.anuke.arc.Core; -import io.anuke.arc.entities.Effects; import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.math.Angles; import io.anuke.arc.math.Mathf; -import io.anuke.arc.util.Time; import io.anuke.mindustry.entities.Damage; +import io.anuke.mindustry.entities.Effects; import io.anuke.mindustry.entities.Units; import io.anuke.mindustry.entities.effect.Lightning; import io.anuke.mindustry.entities.traits.TargetTrait; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.graphics.Pal; /**An extended BulletType for most ammo-based bullets shot from turrets and units.*/ public class BasicBulletType extends BulletType{ - public Color backColor = Palette.bulletYellowBack, frontColor = Palette.bulletYellow; + public Color backColor = Pal.bulletYellowBack, frontColor = Pal.bulletYellow; public float bulletWidth = 5f, bulletHeight = 7f; public float bulletShrink = 0.5f; public String bulletSprite; @@ -72,7 +71,7 @@ public class BasicBulletType extends BulletType{ if(homingPower > 0.0001f){ TargetTrait target = Units.getClosestTarget(b.getTeam(), b.x, b.y, homingRange); if(target != null){ - b.velocity().setAngle(Angles.moveToward(b.velocity().angle(), b.angleTo(target), homingPower * Time.delta())); + b.velocity().setAngle(Mathf.slerpDelta(b.velocity().angle(), b.angleTo(target), 0.08f)); } } } @@ -108,7 +107,7 @@ public class BasicBulletType extends BulletType{ } for (int i = 0; i < lightining; i++) { - Lightning.create(b.getTeam(), Palette.surge, damage, b.x, b.y, Mathf.random(360f), lightningLength); + Lightning.create(b.getTeam(), Pal.surge, damage, b.x, b.y, Mathf.random(360f), lightningLength); } } } diff --git a/core/src/io/anuke/mindustry/entities/bullet/Bullet.java b/core/src/io/anuke/mindustry/entities/bullet/Bullet.java index f784e7322a..9206c8d6c3 100644 --- a/core/src/io/anuke/mindustry/entities/bullet/Bullet.java +++ b/core/src/io/anuke/mindustry/entities/bullet/Bullet.java @@ -2,9 +2,8 @@ package io.anuke.mindustry.entities.bullet; import io.anuke.annotations.Annotations.Loc; import io.anuke.annotations.Annotations.Remote; -import io.anuke.arc.entities.EntityGroup; -import io.anuke.arc.entities.impl.SolidEntity; -import io.anuke.arc.entities.trait.*; +import io.anuke.mindustry.entities.EntityGroup; +import io.anuke.mindustry.entities.impl.SolidEntity; import io.anuke.arc.math.Mathf; import io.anuke.arc.math.geom.Rectangle; import io.anuke.arc.math.geom.Vector2; @@ -13,11 +12,9 @@ import io.anuke.arc.util.Time; import io.anuke.arc.util.Tmp; import io.anuke.arc.util.pooling.Pool.Poolable; import io.anuke.arc.util.pooling.Pools; -import io.anuke.mindustry.entities.Unit; +import io.anuke.mindustry.entities.traits.*; +import io.anuke.mindustry.entities.type.Unit; import io.anuke.mindustry.entities.effect.Lightning; -import io.anuke.mindustry.entities.traits.AbsorbTrait; -import io.anuke.mindustry.entities.traits.SyncTrait; -import io.anuke.mindustry.entities.traits.TeamTrait; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.world.Tile; diff --git a/core/src/io/anuke/mindustry/entities/bullet/BulletType.java b/core/src/io/anuke/mindustry/entities/bullet/BulletType.java index 59ef42b6d6..198adaaf37 100644 --- a/core/src/io/anuke/mindustry/entities/bullet/BulletType.java +++ b/core/src/io/anuke/mindustry/entities/bullet/BulletType.java @@ -1,7 +1,7 @@ package io.anuke.mindustry.entities.bullet; -import io.anuke.arc.entities.Effects; -import io.anuke.arc.entities.Effects.Effect; +import io.anuke.mindustry.entities.Effects; +import io.anuke.mindustry.entities.Effects.Effect; import io.anuke.mindustry.content.StatusEffects; import io.anuke.mindustry.content.Fx; import io.anuke.mindustry.game.Content; @@ -66,7 +66,7 @@ public abstract class BulletType extends Content{ /**Returns maximum distance the bullet this bullet type has can travel.*/ public float range(){ - return speed * lifetime; + return speed * lifetime * (1f - drag); } public boolean collides(Bullet bullet, Tile tile){ diff --git a/core/src/io/anuke/mindustry/entities/bullet/LiquidBulletType.java b/core/src/io/anuke/mindustry/entities/bullet/LiquidBulletType.java index 8b1677360d..6b4c7d8bb9 100644 --- a/core/src/io/anuke/mindustry/entities/bullet/LiquidBulletType.java +++ b/core/src/io/anuke/mindustry/entities/bullet/LiquidBulletType.java @@ -1,6 +1,6 @@ package io.anuke.mindustry.entities.bullet; -import io.anuke.arc.entities.Effects; +import io.anuke.mindustry.entities.Effects; import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.graphics.g2d.Fill; @@ -20,16 +20,22 @@ public class LiquidBulletType extends BulletType{ Liquid liquid; public LiquidBulletType(Liquid liquid){ - super(2.5f, 0); + super(2.8f, 0); this.liquid = liquid; - lifetime = 70f; + lifetime = 74f; status = liquid.effect; statusDuration = 90f; despawnEffect = Fx.none; hitEffect = Fx.hitLiquid; - drag = 0.01f; - knockback = 0.5f; + shootEffect = Fx.none; + drag = 0.009f; + knockback = 0.55f; + } + + @Override + public float range(){ + return speed * lifetime /2f; } @Override diff --git a/core/src/io/anuke/mindustry/entities/bullet/MassDriverBolt.java b/core/src/io/anuke/mindustry/entities/bullet/MassDriverBolt.java index a10421113a..237aa09a15 100644 --- a/core/src/io/anuke/mindustry/entities/bullet/MassDriverBolt.java +++ b/core/src/io/anuke/mindustry/entities/bullet/MassDriverBolt.java @@ -1,12 +1,12 @@ package io.anuke.mindustry.entities.bullet; -import io.anuke.arc.entities.Effects; +import io.anuke.mindustry.entities.Effects; import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.math.Angles; import io.anuke.arc.math.Mathf; import io.anuke.mindustry.content.Fx; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.world.blocks.distribution.MassDriver.DriverBulletData; import static io.anuke.mindustry.Vars.content; @@ -26,10 +26,10 @@ public class MassDriverBolt extends BulletType{ public void draw(Bullet b){ float w = 11f, h = 13f; - Draw.color(Palette.bulletYellowBack); + Draw.color(Pal.bulletYellowBack); Draw.rect("shell-back", b.x, b.y, w, h, b.rot() + 90); - Draw.color(Palette.bulletYellow); + Draw.color(Pal.bulletYellow); Draw.rect("shell", b.x, b.y, w, h, b.rot() + 90); Draw.reset(); diff --git a/core/src/io/anuke/mindustry/entities/bullet/MissileBulletType.java b/core/src/io/anuke/mindustry/entities/bullet/MissileBulletType.java index 6200666f1f..351078866d 100644 --- a/core/src/io/anuke/mindustry/entities/bullet/MissileBulletType.java +++ b/core/src/io/anuke/mindustry/entities/bullet/MissileBulletType.java @@ -2,21 +2,21 @@ package io.anuke.mindustry.entities.bullet; import io.anuke.arc.graphics.Color; import io.anuke.mindustry.content.Fx; -import io.anuke.mindustry.graphics.Palette; -import io.anuke.arc.entities.Effects; +import io.anuke.mindustry.graphics.Pal; +import io.anuke.mindustry.entities.Effects; import io.anuke.arc.util.Time; import io.anuke.arc.math.Mathf; public class MissileBulletType extends BasicBulletType{ - protected Color trailColor = Palette.missileYellowBack; + protected Color trailColor = Pal.missileYellowBack; protected float weaveScale = 0f; protected float weaveMag = -1f; public MissileBulletType(float speed, float damage, String bulletSprite){ super(speed, damage, bulletSprite); - backColor = Palette.missileYellowBack; - frontColor = Palette.missileYellow; + backColor = Pal.missileYellowBack; + frontColor = Pal.missileYellow; homingPower = 7f; } diff --git a/core/src/io/anuke/mindustry/entities/effect/Decal.java b/core/src/io/anuke/mindustry/entities/effect/Decal.java index 9bcaf7a2c3..1cb773a3cc 100644 --- a/core/src/io/anuke/mindustry/entities/effect/Decal.java +++ b/core/src/io/anuke/mindustry/entities/effect/Decal.java @@ -2,9 +2,9 @@ package io.anuke.mindustry.entities.effect; import io.anuke.arc.graphics.Color; import io.anuke.mindustry.entities.traits.BelowLiquidTrait; -import io.anuke.arc.entities.EntityGroup; -import io.anuke.arc.entities.impl.TimedEntity; -import io.anuke.arc.entities.trait.DrawTrait; +import io.anuke.mindustry.entities.EntityGroup; +import io.anuke.mindustry.entities.impl.TimedEntity; +import io.anuke.mindustry.entities.traits.DrawTrait; import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.math.Mathf; diff --git a/core/src/io/anuke/mindustry/entities/effect/Fire.java b/core/src/io/anuke/mindustry/entities/effect/Fire.java index 28a2dc42f5..9689824893 100644 --- a/core/src/io/anuke/mindustry/entities/effect/Fire.java +++ b/core/src/io/anuke/mindustry/entities/effect/Fire.java @@ -3,9 +3,9 @@ package io.anuke.mindustry.entities.effect; import io.anuke.annotations.Annotations.Loc; import io.anuke.annotations.Annotations.Remote; import io.anuke.arc.collection.IntMap; -import io.anuke.arc.entities.Effects; -import io.anuke.arc.entities.EntityGroup; -import io.anuke.arc.entities.impl.TimedEntity; +import io.anuke.mindustry.entities.Effects; +import io.anuke.mindustry.entities.EntityGroup; +import io.anuke.mindustry.entities.impl.TimedEntity; import io.anuke.arc.math.Mathf; import io.anuke.arc.math.geom.Geometry; import io.anuke.arc.math.geom.Point2; @@ -17,7 +17,7 @@ import io.anuke.mindustry.content.Bullets; import io.anuke.mindustry.content.StatusEffects; import io.anuke.mindustry.content.Fx; import io.anuke.mindustry.entities.Damage; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.entities.traits.SaveTrait; import io.anuke.mindustry.entities.traits.SyncTrait; import io.anuke.mindustry.gen.Call; @@ -152,7 +152,7 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait, Poolable{ entity.damage(0.4f); } Damage.damageUnits(null, tile.worldx(), tile.worldy(), tilesize, 3f, - unit -> !unit.isFlying(), + unit -> !unit.isFlying() && !unit.isImmune(StatusEffects.burning), unit -> unit.applyEffect(StatusEffects.burning, 60 * 5)); } } diff --git a/core/src/io/anuke/mindustry/entities/effect/GroundEffectEntity.java b/core/src/io/anuke/mindustry/entities/effect/GroundEffectEntity.java index 812cbd0db4..bc98f1619a 100644 --- a/core/src/io/anuke/mindustry/entities/effect/GroundEffectEntity.java +++ b/core/src/io/anuke/mindustry/entities/effect/GroundEffectEntity.java @@ -1,9 +1,9 @@ package io.anuke.mindustry.entities.effect; -import io.anuke.arc.entities.Effects; -import io.anuke.arc.entities.Effects.Effect; -import io.anuke.arc.entities.Effects.EffectRenderer; -import io.anuke.arc.entities.impl.EffectEntity; +import io.anuke.mindustry.entities.Effects; +import io.anuke.mindustry.entities.Effects.Effect; +import io.anuke.mindustry.entities.Effects.EffectRenderer; +import io.anuke.mindustry.entities.impl.EffectEntity; import io.anuke.arc.math.Mathf; import io.anuke.arc.util.Time; import io.anuke.mindustry.Vars; diff --git a/core/src/io/anuke/mindustry/entities/effect/ItemTransfer.java b/core/src/io/anuke/mindustry/entities/effect/ItemTransfer.java index 8c32ccde94..5083897a33 100644 --- a/core/src/io/anuke/mindustry/entities/effect/ItemTransfer.java +++ b/core/src/io/anuke/mindustry/entities/effect/ItemTransfer.java @@ -2,9 +2,9 @@ package io.anuke.mindustry.entities.effect; import io.anuke.annotations.Annotations.Loc; import io.anuke.annotations.Annotations.Remote; -import io.anuke.arc.entities.EntityGroup; -import io.anuke.arc.entities.impl.TimedEntity; -import io.anuke.arc.entities.trait.DrawTrait; +import io.anuke.mindustry.entities.EntityGroup; +import io.anuke.mindustry.entities.impl.TimedEntity; +import io.anuke.mindustry.entities.traits.DrawTrait; import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.graphics.g2d.Fill; import io.anuke.arc.graphics.g2d.Lines; @@ -14,8 +14,8 @@ import io.anuke.arc.math.geom.Position; import io.anuke.arc.math.geom.Vector2; import io.anuke.arc.util.Time; import io.anuke.arc.util.pooling.Pools; -import io.anuke.mindustry.entities.Unit; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.entities.type.Unit; +import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.world.Tile; @@ -43,7 +43,7 @@ public class ItemTransfer extends TimedEntity implements DrawTrait{ @Remote(called = Loc.server, unreliable = true) public static void transferItemToUnit(Item item, float x, float y, Unit to){ if(to == null) return; - create(item, x, y, to, () -> to.inventory.addItem(item, 1)); + create(item, x, y, to, () -> to.addItem(item)); } @Remote(called = Loc.server) @@ -105,7 +105,7 @@ public class ItemTransfer extends TimedEntity implements DrawTrait{ @Override public void draw(){ - Lines.stroke(fslope() * 2f, Palette.accent); + Lines.stroke(fslope() * 2f, Pal.accent); Lines.circle(x, y, fslope() * 2f); diff --git a/core/src/io/anuke/mindustry/entities/effect/Lightning.java b/core/src/io/anuke/mindustry/entities/effect/Lightning.java index 7ee5e771af..7a89b29f9d 100644 --- a/core/src/io/anuke/mindustry/entities/effect/Lightning.java +++ b/core/src/io/anuke/mindustry/entities/effect/Lightning.java @@ -4,13 +4,14 @@ import io.anuke.annotations.Annotations.Loc; import io.anuke.annotations.Annotations.Remote; import io.anuke.arc.collection.Array; import io.anuke.arc.collection.IntSet; -import io.anuke.arc.entities.EntityGroup; -import io.anuke.arc.entities.impl.TimedEntity; -import io.anuke.arc.entities.trait.DrawTrait; -import io.anuke.arc.entities.trait.TimeTrait; +import io.anuke.arc.graphics.g2d.Fill; +import io.anuke.arc.graphics.g2d.Lines; +import io.anuke.mindustry.entities.EntityGroup; +import io.anuke.mindustry.entities.impl.TimedEntity; +import io.anuke.mindustry.entities.traits.DrawTrait; +import io.anuke.mindustry.entities.traits.TimeTrait; import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.g2d.Draw; -import io.anuke.arc.graphics.g2d.Lines; import io.anuke.arc.math.Angles; import io.anuke.arc.math.Mathf; import io.anuke.arc.math.RandomXS128; @@ -20,13 +21,13 @@ import io.anuke.arc.math.geom.Rectangle; import io.anuke.arc.math.geom.Vector2; import io.anuke.arc.util.pooling.Pools; import io.anuke.mindustry.content.Bullets; -import io.anuke.mindustry.entities.Unit; +import io.anuke.mindustry.entities.type.Unit; import io.anuke.mindustry.entities.Units; import io.anuke.mindustry.entities.bullet.Bullet; import io.anuke.mindustry.entities.traits.SyncTrait; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.gen.Call; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.graphics.Pal; import java.io.DataInput; import java.io.DataOutput; @@ -45,7 +46,7 @@ public class Lightning extends TimedEntity implements DrawTrait, SyncTrait, Time private static int lastSeed = 0; private Array lines = new Array<>(); - private Color color = Palette.lancerLaser; + private Color color = Pal.lancerLaser; /**For pooling use only. Do not call directly!*/ public Lightning(){ @@ -118,7 +119,7 @@ public class Lightning extends TimedEntity implements DrawTrait, SyncTrait, Time @Override public void reset(){ super.reset(); - color = Palette.lancerLaser; + color = Pal.lancerLaser; lines.clear(); } @@ -130,31 +131,22 @@ public class Lightning extends TimedEntity implements DrawTrait, SyncTrait, Time @Override public void draw(){ - float lx = x, ly = y; + Lines.stroke(3f * fout()); Draw.color(color, Color.WHITE, fin()); - //TODO this is really, really bad rendering - /* - for(int i = 0; i < lines.size; i++){ - Position v = lines.get(i); + Lines.beginLine(); - float f = (float) i / lines.size; + Lines.linePoint(x, y); + for(Position p : lines){ + Lines.linePoint(p.getX(), p.getY()); + } + Lines.endLine(); - Lines.stroke(fout() * 3f * (1.5f - f)); + int i = 0; - Lines.stroke(Lines.getStroke() * 4f); - Draw.alpha(0.3f); - Lines.line(lx, ly, v.getX(), v.getY()); - - Lines.stroke(Lines.getStroke()/4f); - Draw.alpha(1f); - Lines.line(lx, ly, v.getX(), v.getY()); - - Lines.stroke(3f * fout() * (1f - f)); - - lx = v.getX(); - ly = v.getY(); - }*/ - Draw.color(); + for(Position p : lines){ + Fill.square(p.getX(), p.getY(), (5f - (float)i++/lines.size*2f) * fout(), 45); + } + Draw.reset(); } @Override diff --git a/core/src/io/anuke/mindustry/entities/effect/Puddle.java b/core/src/io/anuke/mindustry/entities/effect/Puddle.java index 68f590cc5f..8c3eb67ff7 100644 --- a/core/src/io/anuke/mindustry/entities/effect/Puddle.java +++ b/core/src/io/anuke/mindustry/entities/effect/Puddle.java @@ -3,10 +3,10 @@ package io.anuke.mindustry.entities.effect; import io.anuke.annotations.Annotations.Loc; import io.anuke.annotations.Annotations.Remote; import io.anuke.arc.collection.IntMap; -import io.anuke.arc.entities.Effects; -import io.anuke.arc.entities.EntityGroup; -import io.anuke.arc.entities.impl.SolidEntity; -import io.anuke.arc.entities.trait.DrawTrait; +import io.anuke.mindustry.entities.Effects; +import io.anuke.mindustry.entities.EntityGroup; +import io.anuke.mindustry.entities.impl.SolidEntity; +import io.anuke.mindustry.entities.traits.DrawTrait; import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.graphics.g2d.Fill; @@ -212,7 +212,7 @@ public class Puddle extends SolidEntity implements SaveTrait, Poolable, DrawTrai } }); - if(liquid.temperature > 0.7f && tile.entity != null && Mathf.chance(0.3 * Time.delta())){ + if(liquid.temperature > 0.7f && (tile.target().entity != null) && Mathf.chance(0.3 * Time.delta())){ Fire.create(tile); } diff --git a/core/src/io/anuke/mindustry/entities/effect/ScorchDecal.java b/core/src/io/anuke/mindustry/entities/effect/ScorchDecal.java index 58aa066d06..b9a4d35f84 100644 --- a/core/src/io/anuke/mindustry/entities/effect/ScorchDecal.java +++ b/core/src/io/anuke/mindustry/entities/effect/ScorchDecal.java @@ -7,6 +7,7 @@ import io.anuke.arc.math.Angles; import io.anuke.arc.math.Mathf; import io.anuke.mindustry.world.Tile; +import static io.anuke.mindustry.Vars.headless; import static io.anuke.mindustry.Vars.world; public class ScorchDecal extends Decal{ @@ -14,6 +15,7 @@ public class ScorchDecal extends Decal{ private static final TextureRegion[] regions = new TextureRegion[scorches]; public static void create(float x, float y){ + if(headless) return; if(regions[0] == null){ for(int i = 0; i < regions.length; i++){ regions[i] = Core.atlas.find("scorch" + (i + 1)); diff --git a/core/src/io/anuke/mindustry/entities/impl/BaseEntity.java b/core/src/io/anuke/mindustry/entities/impl/BaseEntity.java new file mode 100755 index 0000000000..4fb4462c03 --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/impl/BaseEntity.java @@ -0,0 +1,61 @@ +package io.anuke.mindustry.entities.impl; + +import io.anuke.mindustry.entities.EntityGroup; +import io.anuke.mindustry.entities.traits.Entity; + +public abstract class BaseEntity implements Entity{ + private static int lastid; + /** Do not modify. Used for network operations and mapping. */ + public int id; + public float x, y; + protected transient EntityGroup group; + + public BaseEntity(){ + id = lastid++; + } + + @Override + public int getID(){ + return id; + } + + @Override + public void resetID(int id){ + this.id = id; + } + + @Override + public EntityGroup getGroup(){ + return group; + } + + @Override + public void setGroup(EntityGroup group){ + this.group = group; + } + + @Override + public float getX(){ + return x; + } + + @Override + public void setX(float x){ + this.x = x; + } + + @Override + public float getY(){ + return y; + } + + @Override + public void setY(float y){ + this.y = y; + } + + @Override + public String toString(){ + return getClass() + " " + id; + } +} diff --git a/core/src/io/anuke/mindustry/entities/impl/DestructibleEntity.java b/core/src/io/anuke/mindustry/entities/impl/DestructibleEntity.java new file mode 100644 index 0000000000..fdb22094c6 --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/impl/DestructibleEntity.java @@ -0,0 +1,45 @@ +package io.anuke.mindustry.entities.impl; + + +import io.anuke.mindustry.entities.traits.DamageTrait; +import io.anuke.mindustry.entities.traits.HealthTrait; +import io.anuke.mindustry.entities.traits.SolidTrait; + +public abstract class DestructibleEntity extends SolidEntity implements HealthTrait{ + public transient boolean dead; + public float health; + + @Override + public boolean collides(SolidTrait other){ + return other instanceof DamageTrait; + } + + @Override + public void collision(SolidTrait other, float x, float y){ + if(other instanceof DamageTrait){ + onHit(other); + damage(((DamageTrait) other).damage()); + } + } + + @Override + public void health(float health){ + this.health = health; + } + + @Override + public float health(){ + return health; + } + + @Override + public boolean isDead(){ + return dead; + } + + @Override + public void setDead(boolean dead){ + this.dead = dead; + } + +} diff --git a/core/src/io/anuke/mindustry/entities/impl/EffectEntity.java b/core/src/io/anuke/mindustry/entities/impl/EffectEntity.java new file mode 100644 index 0000000000..e678f29964 --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/impl/EffectEntity.java @@ -0,0 +1,72 @@ +package io.anuke.mindustry.entities.impl; + +import io.anuke.arc.graphics.Color; +import io.anuke.arc.util.pooling.Pool.Poolable; +import io.anuke.arc.util.pooling.Pools; +import io.anuke.mindustry.entities.Effects; +import io.anuke.mindustry.entities.Effects.Effect; +import io.anuke.mindustry.entities.traits.DrawTrait; +import io.anuke.mindustry.entities.traits.Entity; + +public class EffectEntity extends TimedEntity implements Poolable, DrawTrait{ + public Effect effect; + public Color color = new Color(Color.WHITE); + public Object data; + public float rotation = 0f; + + public Entity parent; + public float poffsetx, poffsety; + + /** For pooling use only! */ + public EffectEntity(){ + } + + public void setParent(Entity parent){ + this.parent = parent; + this.poffsetx = x - parent.getX(); + this.poffsety = y - parent.getY(); + } + + @Override + public float lifetime(){ + return effect.lifetime; + } + + @Override + public float drawSize(){ + return effect.size; + } + + @Override + public void update(){ + if(effect == null){ + remove(); + return; + } + + super.update(); + if(parent != null){ + x = parent.getX() + poffsetx; + y = parent.getY() + poffsety; + } + } + + @Override + public void reset(){ + effect = null; + color.set(Color.WHITE); + rotation = time = poffsetx = poffsety = 0f; + parent = null; + data = null; + } + + @Override + public void draw(){ + Effects.renderEffect(id, effect, color, time, rotation, x, y, data); + } + + @Override + public void removed(){ + Pools.free(this); + } +} diff --git a/core/src/io/anuke/mindustry/entities/impl/SolidEntity.java b/core/src/io/anuke/mindustry/entities/impl/SolidEntity.java new file mode 100644 index 0000000000..544abdbefa --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/impl/SolidEntity.java @@ -0,0 +1,19 @@ +package io.anuke.mindustry.entities.impl; + +import io.anuke.arc.math.geom.Vector2; +import io.anuke.mindustry.entities.traits.SolidTrait; + +public abstract class SolidEntity extends BaseEntity implements SolidTrait{ + protected transient Vector2 velocity = new Vector2(0f, 0.0001f); + private transient Vector2 lastPosition = new Vector2(); + + @Override + public Vector2 lastPosition(){ + return lastPosition; + } + + @Override + public Vector2 velocity(){ + return velocity; + } +} diff --git a/core/src/io/anuke/mindustry/entities/impl/TimedEntity.java b/core/src/io/anuke/mindustry/entities/impl/TimedEntity.java new file mode 100644 index 0000000000..e4007a5c4b --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/impl/TimedEntity.java @@ -0,0 +1,34 @@ +package io.anuke.mindustry.entities.impl; + +import io.anuke.arc.util.pooling.Pool.Poolable; +import io.anuke.mindustry.entities.traits.ScaleTrait; +import io.anuke.mindustry.entities.traits.TimeTrait; + +public abstract class TimedEntity extends BaseEntity implements ScaleTrait, TimeTrait, Poolable{ + public float time; + + @Override + public void time(float time){ + this.time = time; + } + + @Override + public float time(){ + return time; + } + + @Override + public void update(){ + updateTime(); + } + + @Override + public void reset(){ + time = 0f; + } + + @Override + public float fin(){ + return time() / lifetime(); + } +} diff --git a/core/src/io/anuke/mindustry/entities/traits/AbsorbTrait.java b/core/src/io/anuke/mindustry/entities/traits/AbsorbTrait.java index dedffc5203..d408296c7c 100644 --- a/core/src/io/anuke/mindustry/entities/traits/AbsorbTrait.java +++ b/core/src/io/anuke/mindustry/entities/traits/AbsorbTrait.java @@ -1,8 +1,5 @@ package io.anuke.mindustry.entities.traits; -import io.anuke.arc.entities.trait.DamageTrait; -import io.anuke.arc.entities.trait.Entity; - public interface AbsorbTrait extends Entity, TeamTrait, DamageTrait{ void absorb(); diff --git a/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java b/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java index 503f5d780e..c9cc53e521 100644 --- a/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java +++ b/core/src/io/anuke/mindustry/entities/traits/BuilderTrait.java @@ -4,8 +4,6 @@ import io.anuke.arc.Core; import io.anuke.arc.Events; import io.anuke.arc.collection.Array; import io.anuke.arc.collection.Queue; -import io.anuke.arc.entities.Effects; -import io.anuke.arc.entities.trait.Entity; import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.graphics.g2d.Fill; @@ -17,12 +15,13 @@ import io.anuke.arc.util.Time; import io.anuke.mindustry.Vars; import io.anuke.mindustry.content.Blocks; import io.anuke.mindustry.content.Fx; -import io.anuke.mindustry.entities.Player; -import io.anuke.mindustry.entities.TileEntity; -import io.anuke.mindustry.entities.Unit; +import io.anuke.mindustry.entities.Effects; +import io.anuke.mindustry.entities.type.Player; +import io.anuke.mindustry.entities.type.TileEntity; +import io.anuke.mindustry.entities.type.Unit; import io.anuke.mindustry.game.EventType.BuildSelectEvent; import io.anuke.mindustry.gen.Call; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.graphics.Shapes; import io.anuke.mindustry.net.Net; import io.anuke.mindustry.type.Item; @@ -43,7 +42,7 @@ import static io.anuke.mindustry.Vars.*; /** * Interface for units that build, break or mine things. */ -public interface BuilderTrait extends Entity{ +public interface BuilderTrait extends Entity, TeamTrait{ //these are not instance variables! Vector2[] tmptr = new Vector2[]{new Vector2(), new Vector2(), new Vector2(), new Vector2()}; float placeDistance = 150f; @@ -125,22 +124,6 @@ public interface BuilderTrait extends Entity{ return getPlaceQueue().size != 0; } - /** - * If a place request matching this signature is present, it is removed. - * Otherwise, a new place request is added to the queue. - */ - default void replaceBuilding(int x, int y, int rotation, Block block){ - for(BuildRequest request : getPlaceQueue()){ - if(request.x == x && request.y == y){ - clearBuilding(); - addBuildRequest(request); - return; - } - } - - addBuildRequest(new BuildRequest(x, y, rotation, block)); - } - /**Clears the placement queue.*/ default void clearBuilding(){ getPlaceQueue().clear(); @@ -172,7 +155,8 @@ public interface BuilderTrait extends Entity{ * Update building mechanism for this unit. * This includes mining. */ - default void updateBuilding(Unit unit){ + default void updateBuilding(){ + Unit unit = (Unit)this; //remove already completed build requests removal.clear(); for(BuildRequest req : getPlaceQueue()){ @@ -183,8 +167,7 @@ public interface BuilderTrait extends Entity{ for(BuildRequest request : removal){ if(!((request.breaking && world.tile(request.x, request.y).block() == Blocks.air) || - (!request.breaking && - (world.tile(request.x, request.y).getRotation() == request.rotation || !request.block.rotate) + (!request.breaking && (world.tile(request.x, request.y).getRotation() == request.rotation || !request.block.rotate) && world.tile(request.x, request.y).block() == request.block))){ getPlaceQueue().addLast(request); } @@ -195,7 +178,7 @@ public interface BuilderTrait extends Entity{ //update mining here if(current == null){ if(getMineTile() != null){ - updateMining(unit); + updateMining(); } return; }else{ @@ -204,15 +187,19 @@ public interface BuilderTrait extends Entity{ Tile tile = world.tile(current.x, current.y); - if(unit.dst(tile) > placeDistance){ + if(dst(tile) > placeDistance){ + if(getPlaceQueue().size > 1){ + getPlaceQueue().removeFirst(); + getPlaceQueue().addLast(current); + } return; } if(!(tile.block() instanceof BuildBlock)){ - if(canCreateBlocks() && !current.breaking && Build.validPlace(unit.getTeam(), current.x, current.y, current.block, current.rotation)){ - Build.beginPlace(unit.getTeam(), current.x, current.y, current.block, current.rotation); - }else if(canCreateBlocks() && current.breaking && Build.validBreak(unit.getTeam(), current.x, current.y)){ - Build.beginBreak(unit.getTeam(), current.x, current.y); + if(canCreateBlocks() && !current.breaking && Build.validPlace(getTeam(), current.x, current.y, current.block, current.rotation)){ + Build.beginPlace(getTeam(), current.x, current.y, current.block, current.rotation); + }else if(canCreateBlocks() && current.breaking && Build.validBreak(getTeam(), current.x, current.y)){ + Build.beginBreak(getTeam(), current.x, current.y); }else{ getPlaceQueue().removeFirst(); return; @@ -259,12 +246,13 @@ public interface BuilderTrait extends Entity{ } /**Do not call directly.*/ - default void updateMining(Unit unit){ + default void updateMining(){ + Unit unit = (Unit)this; Tile tile = getMineTile(); TileEntity core = unit.getClosestCore(); - if(core == null || tile.block() != Blocks.air || unit.dst(tile.worldx(), tile.worldy()) > mineDistance - || tile.floor().itemDrop == null || !unit.inventory.canAcceptItem(tile.floor().itemDrop) || !canMine(tile.floor().itemDrop)){ + if(core == null || tile.block() != Blocks.air || dst(tile.worldx(), tile.worldy()) > mineDistance + || tile.floor().itemDrop == null || !unit.acceptsItem(tile.floor().itemDrop) || !canMine(tile.floor().itemDrop)){ setMineTile(null); }else{ Item item = tile.floor().itemDrop; @@ -276,7 +264,7 @@ public interface BuilderTrait extends Entity{ Call.transferItemTo(item, 1, tile.worldx() + Mathf.range(tilesize / 2f), tile.worldy() + Mathf.range(tilesize / 2f), core.tile); - }else if(unit.inventory.canAcceptItem(item)){ + }else if(unit.acceptsItem(item)){ Call.transferItemToUnit(item, tile.worldx() + Mathf.range(tilesize / 2f), tile.worldy() + Mathf.range(tilesize / 2f), @@ -293,11 +281,12 @@ public interface BuilderTrait extends Entity{ } /**Draw placement effects for an entity. This includes mining*/ - default void drawBuilding(Unit unit){ + default void drawBuilding(){ + Unit unit = (Unit)this; BuildRequest request; if(!isBuilding()){ if(getMineTile() != null){ - drawMining(unit); + drawMining(); } return; } @@ -306,11 +295,11 @@ public interface BuilderTrait extends Entity{ Tile tile = world.tile(request.x, request.y); - if(unit.dst(tile) > placeDistance){ + if(dst(tile) > placeDistance){ return; } - Lines.stroke(1f, Palette.accent); + Lines.stroke(1f, Pal.accent); float focusLen = 3.8f + Mathf.absin(Time.time(), 1.1f, 0.6f); float px = unit.x + Angles.trnsx(unit.rotation, focusLen); float py = unit.y + Angles.trnsy(unit.rotation, focusLen); @@ -340,7 +329,8 @@ public interface BuilderTrait extends Entity{ } /**Internal use only.*/ - default void drawMining(Unit unit){ + default void drawMining(){ + Unit unit = (Unit)this; Tile tile = getMineTile(); if(tile == null) return; @@ -360,7 +350,7 @@ public interface BuilderTrait extends Entity{ Shapes.laser("minelaser", "minelaser-end", px, py, ex, ey); if(unit instanceof Player && ((Player) unit).isLocal){ - Lines.stroke(1f, Palette.accent); + Lines.stroke(1f, Pal.accent); Lines.poly(tile.worldx(), tile.worldy(), 4, tilesize / 2f * Mathf.sqrt2, Time.time()); } diff --git a/core/src/io/anuke/mindustry/entities/traits/CarriableTrait.java b/core/src/io/anuke/mindustry/entities/traits/CarriableTrait.java deleted file mode 100644 index 3755245e8e..0000000000 --- a/core/src/io/anuke/mindustry/entities/traits/CarriableTrait.java +++ /dev/null @@ -1,14 +0,0 @@ -package io.anuke.mindustry.entities.traits; - -import io.anuke.arc.entities.trait.SolidTrait; - -public interface CarriableTrait extends TeamTrait, TargetTrait, SolidTrait{ - - default boolean isCarried(){ - return getCarrier() != null; - } - - CarryTrait getCarrier(); - - void setCarrier(CarryTrait carrier); -} diff --git a/core/src/io/anuke/mindustry/entities/traits/CarryTrait.java b/core/src/io/anuke/mindustry/entities/traits/CarryTrait.java deleted file mode 100644 index de7f571161..0000000000 --- a/core/src/io/anuke/mindustry/entities/traits/CarryTrait.java +++ /dev/null @@ -1,69 +0,0 @@ -package io.anuke.mindustry.entities.traits; - -import io.anuke.annotations.Annotations.Loc; -import io.anuke.annotations.Annotations.Remote; -import io.anuke.mindustry.content.Fx; -import io.anuke.mindustry.entities.Player; -import io.anuke.mindustry.gen.Call; -import io.anuke.arc.entities.Effects; -import io.anuke.arc.entities.trait.SolidTrait; - -public interface CarryTrait extends TeamTrait, SolidTrait, TargetTrait{ - - @Remote(called = Loc.both, targets = Loc.both, forward = true) - static void dropSelf(Player player){ - if(player != null && player.getCarrier() != null){ - player.getCarrier().dropCarry(); - } - } - - @Remote(called = Loc.both, targets = Loc.both, forward = true) - static void setCarryOf(Player player, CarryTrait trait, CarriableTrait unit){ - if(trait == null) return; - if(player != null){ //when a server recieves this called from a player, set the carrier to the player. - trait = player; - } - - if(trait.getCarry() != null){ //already carrying something, drop it - //drop current - Effects.effect(Fx.unitDrop, trait.getCarry()); - trait.getCarry().setCarrier(null); - trait.setCarry(null); - - if(unit != null){ - trait.carry(unit); //now carry this new thing - } - }else if(unit != null){ //not currently carrying anything, make sure it's not null - trait.setCarry(unit); - unit.setCarrier(trait); - - Effects.effect(Fx.unitPickup, trait); - } - } - - /**Returns the thing this carrier is carrying.*/ - CarriableTrait getCarry(); - - /**Sets the carrying unit. Internal use only! Use {@link #carry(CarriableTrait)} to set state.*/ - void setCarry(CarriableTrait unit); - - /**Returns maximum mass this carrier can carry.*/ - float getCarryWeight(); - - /**Drops the unit that is being carried, if applicable.*/ - default void dropCarry(){ - carry(null); - } - - default void dropCarryLocal(){ - setCarryOf(null, this, null); - } - - /** - * Do not override unless absolutely necessary. - * Carries a unit. To drop a unit, call with {@code null}. - */ - default void carry(CarriableTrait unit){ - Call.setCarryOf(this instanceof Player ? (Player) this : null, this, unit); - } -} diff --git a/core/src/io/anuke/mindustry/entities/traits/DamageTrait.java b/core/src/io/anuke/mindustry/entities/traits/DamageTrait.java new file mode 100644 index 0000000000..3f009687d6 --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/traits/DamageTrait.java @@ -0,0 +1,5 @@ +package io.anuke.mindustry.entities.traits; + +public interface DamageTrait{ + float damage(); +} diff --git a/core/src/io/anuke/mindustry/entities/traits/DrawTrait.java b/core/src/io/anuke/mindustry/entities/traits/DrawTrait.java new file mode 100644 index 0000000000..648d9797b3 --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/traits/DrawTrait.java @@ -0,0 +1,10 @@ +package io.anuke.mindustry.entities.traits; + +public interface DrawTrait extends Entity{ + + default float drawSize(){ + return 20f; + } + + void draw(); +} diff --git a/core/src/io/anuke/mindustry/entities/traits/Entity.java b/core/src/io/anuke/mindustry/entities/traits/Entity.java new file mode 100644 index 0000000000..582880beac --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/traits/Entity.java @@ -0,0 +1,46 @@ +package io.anuke.mindustry.entities.traits; + +import io.anuke.mindustry.entities.Entities; +import io.anuke.mindustry.entities.EntityGroup; + +public interface Entity extends MoveTrait{ + + int getID(); + + void resetID(int id); + + default void update(){ + } + + default void removed(){ + } + + default void added(){ + } + + default EntityGroup targetGroup(){ + return Entities.defaultGroup(); + } + + @SuppressWarnings("unchecked") + default void add(){ + targetGroup().add(this); + } + + @SuppressWarnings("unchecked") + default void remove(){ + if(getGroup() != null){ + getGroup().remove(this); + } + + setGroup(null); + } + + EntityGroup getGroup(); + + void setGroup(EntityGroup group); + + default boolean isAdded(){ + return getGroup() != null; + } +} diff --git a/core/src/io/anuke/mindustry/entities/traits/HealthTrait.java b/core/src/io/anuke/mindustry/entities/traits/HealthTrait.java new file mode 100644 index 0000000000..536b6caad2 --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/traits/HealthTrait.java @@ -0,0 +1,48 @@ +package io.anuke.mindustry.entities.traits; + +import io.anuke.arc.math.Mathf; + +public interface HealthTrait{ + + void health(float health); + + float health(); + + float maxHealth(); + + boolean isDead(); + + void setDead(boolean dead); + + default void onHit(SolidTrait entity){ + } + + default void onDeath(){ + } + + default void damage(float amount){ + health(health() - amount); + if(health() <= 0 && !isDead()){ + onDeath(); + setDead(true); + } + } + + default void clampHealth(){ + health(Mathf.clamp(health(), 0, maxHealth())); + } + + default float healthf(){ + return health() / maxHealth(); + } + + default void healBy(float amount){ + health(health() + amount); + clampHealth(); + } + + default void heal(){ + health(maxHealth()); + setDead(false); + } +} diff --git a/core/src/io/anuke/mindustry/entities/traits/InventoryTrait.java b/core/src/io/anuke/mindustry/entities/traits/InventoryTrait.java deleted file mode 100644 index c84eaea6b4..0000000000 --- a/core/src/io/anuke/mindustry/entities/traits/InventoryTrait.java +++ /dev/null @@ -1,7 +0,0 @@ -package io.anuke.mindustry.entities.traits; - -import io.anuke.mindustry.entities.UnitInventory; - -public interface InventoryTrait{ - UnitInventory getInventory(); -} diff --git a/core/src/io/anuke/mindustry/entities/traits/MoveTrait.java b/core/src/io/anuke/mindustry/entities/traits/MoveTrait.java new file mode 100644 index 0000000000..561c7a76bd --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/traits/MoveTrait.java @@ -0,0 +1,20 @@ +package io.anuke.mindustry.entities.traits; + +import io.anuke.arc.math.geom.Position; + +public interface MoveTrait extends Position{ + + void setX(float x); + + void setY(float y); + + default void moveBy(float x, float y){ + setX(getX() + x); + setY(getY() + y); + } + + default void set(float x, float y){ + setX(x); + setY(y); + } +} diff --git a/core/src/io/anuke/mindustry/entities/traits/SaveTrait.java b/core/src/io/anuke/mindustry/entities/traits/SaveTrait.java index bcf357f4e5..dfaf8011aa 100644 --- a/core/src/io/anuke/mindustry/entities/traits/SaveTrait.java +++ b/core/src/io/anuke/mindustry/entities/traits/SaveTrait.java @@ -1,7 +1,5 @@ package io.anuke.mindustry.entities.traits; -import io.anuke.arc.entities.trait.Entity; - /** * Marks an entity as serializable. */ diff --git a/core/src/io/anuke/mindustry/entities/traits/ScaleTrait.java b/core/src/io/anuke/mindustry/entities/traits/ScaleTrait.java new file mode 100644 index 0000000000..9975bb12a8 --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/traits/ScaleTrait.java @@ -0,0 +1,43 @@ +package io.anuke.mindustry.entities.traits; + +import io.anuke.arc.math.Interpolation; + +public interface ScaleTrait{ + /** 0 to 1. */ + float fin(); + + /** 1 to 0 */ + default float fout(){ + return 1f - fin(); + } + + /** 1 to 0 */ + default float fout(Interpolation i){ + return i.apply(fout()); + } + + /** 1 to 0, ending at the specified margin */ + default float fout(float margin){ + float f = fin(); + if(f >= 1f - margin){ + return 1f - (f - (1f - margin)) / margin; + }else{ + return 1f; + } + } + + /** 0 to 1 **/ + default float fin(Interpolation i){ + return i.apply(fin()); + } + + /** 0 to 1 */ + default float finpow(){ + return Interpolation.pow3Out.apply(fin()); + } + + /** 0 to 1 to 0 */ + default float fslope(){ + return (0.5f - Math.abs(fin() - 0.5f)) * 2f; + } +} diff --git a/core/src/io/anuke/mindustry/entities/traits/ShooterTrait.java b/core/src/io/anuke/mindustry/entities/traits/ShooterTrait.java index 22072cfd64..ca3010eec3 100644 --- a/core/src/io/anuke/mindustry/entities/traits/ShooterTrait.java +++ b/core/src/io/anuke/mindustry/entities/traits/ShooterTrait.java @@ -1,10 +1,9 @@ package io.anuke.mindustry.entities.traits; -import io.anuke.arc.entities.trait.VelocityTrait; import io.anuke.arc.util.Interval; import io.anuke.mindustry.type.Weapon; -public interface ShooterTrait extends VelocityTrait, TeamTrait, InventoryTrait{ +public interface ShooterTrait extends VelocityTrait, TeamTrait{ Interval getTimer(); diff --git a/core/src/io/anuke/mindustry/entities/traits/SolidTrait.java b/core/src/io/anuke/mindustry/entities/traits/SolidTrait.java new file mode 100644 index 0000000000..83f5a70524 --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/traits/SolidTrait.java @@ -0,0 +1,43 @@ +package io.anuke.mindustry.entities.traits; + + +import io.anuke.mindustry.entities.EntityQuery; +import io.anuke.arc.math.geom.Position; +import io.anuke.arc.math.geom.QuadTree.QuadTreeObject; +import io.anuke.arc.math.geom.Rectangle; +import io.anuke.arc.math.geom.Vector2; + +public interface SolidTrait extends QuadTreeObject, MoveTrait, VelocityTrait, Entity, Position{ + + void hitbox(Rectangle rectangle); + + void hitboxTile(Rectangle rectangle); + + Vector2 lastPosition(); + + default boolean collidesGrid(int x, int y){ + return true; + } + + default float getDeltaX(){ + return getX() - lastPosition().x; + } + + default float getDeltaY(){ + return getY() - lastPosition().y; + } + + default boolean movable(){ + return false; + } + + default boolean collides(SolidTrait other){ + return true; + } + + default void collision(SolidTrait other, float x, float y){} + + default void move(float x, float y){ + EntityQuery.collisions().move(this, x, y); + } +} diff --git a/core/src/io/anuke/mindustry/entities/traits/SpawnerTrait.java b/core/src/io/anuke/mindustry/entities/traits/SpawnerTrait.java index 55c1763b1f..cb98c0086a 100644 --- a/core/src/io/anuke/mindustry/entities/traits/SpawnerTrait.java +++ b/core/src/io/anuke/mindustry/entities/traits/SpawnerTrait.java @@ -1,12 +1,15 @@ package io.anuke.mindustry.entities.traits; -import io.anuke.mindustry.entities.Unit; +import io.anuke.mindustry.entities.type.Player; import io.anuke.mindustry.world.Tile; -public interface SpawnerTrait{ +public interface SpawnerTrait extends TargetTrait{ Tile getTile(); - void updateSpawning(Unit unit); + void updateSpawning(Player unit); - float getSpawnProgress(); + @Override + default boolean isValid(){ + return getTile().entity instanceof SpawnerTrait; + } } diff --git a/core/src/io/anuke/mindustry/entities/traits/SyncTrait.java b/core/src/io/anuke/mindustry/entities/traits/SyncTrait.java index 38bbe23088..cbcc0317ee 100644 --- a/core/src/io/anuke/mindustry/entities/traits/SyncTrait.java +++ b/core/src/io/anuke/mindustry/entities/traits/SyncTrait.java @@ -3,7 +3,6 @@ package io.anuke.mindustry.entities.traits; import io.anuke.mindustry.core.NetClient; import io.anuke.mindustry.net.Interpolator; import io.anuke.arc.Core; -import io.anuke.arc.entities.trait.Entity; import io.anuke.arc.util.Tmp; import java.io.DataInput; diff --git a/core/src/io/anuke/mindustry/entities/traits/TargetTrait.java b/core/src/io/anuke/mindustry/entities/traits/TargetTrait.java index f59ed37091..dcc7a876b9 100644 --- a/core/src/io/anuke/mindustry/entities/traits/TargetTrait.java +++ b/core/src/io/anuke/mindustry/entities/traits/TargetTrait.java @@ -1,7 +1,5 @@ package io.anuke.mindustry.entities.traits; -import io.anuke.arc.entities.trait.SolidTrait; -import io.anuke.arc.entities.trait.VelocityTrait; import io.anuke.arc.math.geom.Position; import io.anuke.mindustry.game.Team; diff --git a/core/src/io/anuke/mindustry/entities/traits/TeamTrait.java b/core/src/io/anuke/mindustry/entities/traits/TeamTrait.java index 6954258423..5f800b2098 100644 --- a/core/src/io/anuke/mindustry/entities/traits/TeamTrait.java +++ b/core/src/io/anuke/mindustry/entities/traits/TeamTrait.java @@ -1,7 +1,6 @@ package io.anuke.mindustry.entities.traits; import io.anuke.mindustry.game.Team; -import io.anuke.arc.entities.trait.Entity; public interface TeamTrait extends Entity{ Team getTeam(); diff --git a/core/src/io/anuke/mindustry/entities/traits/TimeTrait.java b/core/src/io/anuke/mindustry/entities/traits/TimeTrait.java new file mode 100644 index 0000000000..47dc7dfe48 --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/traits/TimeTrait.java @@ -0,0 +1,23 @@ +package io.anuke.mindustry.entities.traits; + +import io.anuke.arc.math.Mathf; +import io.anuke.arc.util.Time; + +public interface TimeTrait extends ScaleTrait, Entity{ + + float lifetime(); + + void time(float time); + + float time(); + + default void updateTime(){ + time(Mathf.clamp(time() + Time.delta(), 0, lifetime())); + + if(time() >= lifetime()){ + remove(); + } + } + + //fin() is not implemented due to compiler issues with iOS/RoboVM +} diff --git a/core/src/io/anuke/mindustry/entities/traits/VelocityTrait.java b/core/src/io/anuke/mindustry/entities/traits/VelocityTrait.java new file mode 100644 index 0000000000..c836154f9c --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/traits/VelocityTrait.java @@ -0,0 +1,36 @@ +package io.anuke.mindustry.entities.traits; + +import io.anuke.arc.math.geom.Vector2; +import io.anuke.arc.util.Time; + +public interface VelocityTrait extends MoveTrait{ + + Vector2 velocity(); + + default void applyImpulse(float x, float y){ + velocity().x += x / mass(); + velocity().y += y / mass(); + } + + default float maxVelocity(){ + return Float.MAX_VALUE; + } + + default float mass(){ + return 1f; + } + + default float drag(){ + return 0f; + } + + default void updateVelocity(){ + velocity().scl(1f - drag() * Time.delta()); + + if(this instanceof SolidTrait){ + ((SolidTrait) this).move(velocity().x * Time.delta(), velocity().y * Time.delta()); + }else{ + moveBy(velocity().x * Time.delta(), velocity().y * Time.delta()); + } + } +} diff --git a/core/src/io/anuke/mindustry/entities/units/BaseUnit.java b/core/src/io/anuke/mindustry/entities/type/BaseUnit.java similarity index 77% rename from core/src/io/anuke/mindustry/entities/units/BaseUnit.java rename to core/src/io/anuke/mindustry/entities/type/BaseUnit.java index 3894e22ea5..e12f0d2400 100644 --- a/core/src/io/anuke/mindustry/entities/units/BaseUnit.java +++ b/core/src/io/anuke/mindustry/entities/type/BaseUnit.java @@ -1,10 +1,8 @@ -package io.anuke.mindustry.entities.units; +package io.anuke.mindustry.entities.type; import io.anuke.annotations.Annotations.Loc; import io.anuke.annotations.Annotations.Remote; import io.anuke.arc.Core; -import io.anuke.arc.entities.Effects; -import io.anuke.arc.entities.EntityGroup; import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.math.Angles; @@ -14,21 +12,19 @@ import io.anuke.arc.math.geom.Rectangle; import io.anuke.arc.util.Interval; import io.anuke.arc.util.Time; import io.anuke.mindustry.Vars; -import io.anuke.mindustry.content.Fx; -import io.anuke.mindustry.entities.Damage; -import io.anuke.mindustry.entities.TileEntity; -import io.anuke.mindustry.entities.Unit; +import io.anuke.mindustry.entities.EntityGroup; import io.anuke.mindustry.entities.Units; -import io.anuke.mindustry.entities.effect.ScorchDecal; import io.anuke.mindustry.entities.traits.ShooterTrait; -import io.anuke.mindustry.entities.traits.SpawnerTrait; import io.anuke.mindustry.entities.traits.TargetTrait; +import io.anuke.mindustry.entities.units.StateMachine; +import io.anuke.mindustry.entities.units.UnitDrops; +import io.anuke.mindustry.entities.units.UnitState; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.gen.Call; -import io.anuke.mindustry.graphics.Palette; import io.anuke.mindustry.net.Net; import io.anuke.mindustry.type.ContentType; -import io.anuke.mindustry.type.ItemStack; +import io.anuke.mindustry.type.StatusEffect; +import io.anuke.mindustry.type.UnitType; import io.anuke.mindustry.type.Weapon; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.meta.BlockFlag; @@ -53,8 +49,6 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{ protected StateMachine state = new StateMachine(); protected TargetTrait target; - protected boolean isWave; - protected Squad squad; protected int spawner = noSpawner; /**internal constructor used for deserialization, DO NOT USE*/ @@ -69,16 +63,8 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{ UnitDrops.dropItems(unit); } - float explosiveness = 2f + (unit.inventory.hasItem() ? unit.inventory.getItem().item.explosiveness * unit.inventory.getItem().amount : 0f); - float flammability = (unit.inventory.hasItem() ? unit.inventory.getItem().item.flammability * unit.inventory.getItem().amount : 0f); - Damage.dynamicExplosion(unit.x, unit.y, flammability, explosiveness, 0f, unit.getSize() / 2f, Palette.darkFlame); - unit.onSuperDeath(); - ScorchDecal.create(unit.x, unit.y); - Effects.effect(Fx.explosion, unit); - Effects.shake(2f, 2f, unit); - //must run afterwards so the unit's group is not null when sending the removal packet Core.app.post(unit::remove); } @@ -104,36 +90,12 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{ this.spawner = tile.pos(); } - /**Sets this to a 'wave' unit, which means it has slightly different AI and will not run out of ammo.*/ - public void setWave(){ - isWave = true; - } - - public void setSquad(Squad squad){ - this.squad = squad; - squad.units++; - } - public void rotate(float angle){ rotation = Mathf.slerpDelta(rotation, angle, type.rotatespeed); } public boolean targetHasFlag(BlockFlag flag){ - return target instanceof TileEntity && ((TileEntity) target).tile.block().flags != null && - ((TileEntity) target).tile.block().flags.contains(flag); - } - - public void updateRespawning(){ - if(spawner == noSpawner) return; - - Tile tile = world.tile(spawner); - if(tile != null && tile.entity != null){ - if(tile.entity instanceof SpawnerTrait){ - ((SpawnerTrait) tile.entity).updateSpawning(this); - } - }else{ - spawner = noSpawner; - } + return target instanceof TileEntity && ((TileEntity) target).tile.block().flags.contains(flag); } public void setState(UnitState state){ @@ -169,7 +131,7 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{ } public void targetClosest(){ - target = Units.getClosestTarget(team, x, y, Math.max(getWeapon().getAmmo().range(), type.range), u -> type.targetAir || !u.isFlying()); + target = Units.getClosestTarget(team, x, y, Math.max(getWeapon().bullet.range(), type.range), u -> type.targetAir || !u.isFlying()); } public TileEntity getClosestEnemyCore(){ @@ -190,14 +152,13 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{ protected void drawItems(){ float backTrns = 4f, itemSize = 5f; - if(inventory.hasItem()){ - ItemStack stack = inventory.getItem(); - int stored = Mathf.clamp(stack.amount / 6, 1, 8); + if(item.amount > 0){ + int stored = Mathf.clamp(item.amount / 6, 1, 8); for(int i = 0; i < stored; i++){ float angT = i == 0 ? 0 : Mathf.randomSeedRange(i + 2, 60f); float lenT = i == 0 ? 0 : Mathf.randomSeedRange(i + 3, 1f) - 1f; - Draw.rect(stack.item.region, + Draw.rect(item.item.region, x + Angles.trnsx(rotation + 180f + angT, backTrns + lenT), y + Angles.trnsy(rotation + 180f + angT, backTrns + lenT), itemSize, itemSize, rotation); @@ -205,6 +166,11 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{ } } + @Override + public boolean isImmune(StatusEffect effect){ + return type.immunities.contains(effect); + } + @Override public boolean isValid(){ return super.isValid() && isAdded(); @@ -249,11 +215,6 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{ return type.health; } - @Override - public float getArmor(){ - return type.armor; - } - @Override public float getSize(){ return 8; @@ -274,7 +235,6 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{ hitTime -= Time.delta(); if(isDead()){ - updateRespawning(); return; } @@ -290,10 +250,6 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{ damage(health); } - if(squad != null){ - squad.update(); - } - updateTargeting(); state.update(); @@ -301,8 +257,9 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{ if(target != null) behavior(); - x = Mathf.clamp(x, tilesize, world.width() * tilesize - tilesize); - y = Mathf.clamp(y, tilesize, world.height() * tilesize - tilesize); + if(!isFlying()){ + clampPosition(); + } } @Override @@ -317,12 +274,17 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{ @Override public void removed(){ + Tile tile = world.tile(spawner); + if(tile != null){ + tile.block().unitRemoved(tile, this); + } + spawner = noSpawner; } @Override public float drawSize(){ - return 14; + return type.hitsize * 10; } @Override @@ -356,7 +318,6 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{ public void writeSave(DataOutput stream) throws IOException{ super.writeSave(stream); stream.writeByte(type.id); - stream.writeBoolean(isWave); stream.writeInt(spawner); } @@ -364,7 +325,6 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{ public void readSave(DataInput stream) throws IOException{ super.readSave(stream); byte type = stream.readByte(); - this.isWave = stream.readBoolean(); this.spawner = stream.readInt(); this.type = content.getByID(ContentType.unit, type); diff --git a/core/src/io/anuke/mindustry/entities/units/FlyingUnit.java b/core/src/io/anuke/mindustry/entities/type/FlyingUnit.java similarity index 55% rename from core/src/io/anuke/mindustry/entities/units/FlyingUnit.java rename to core/src/io/anuke/mindustry/entities/type/FlyingUnit.java index fe1ecd0ff7..a545da4608 100644 --- a/core/src/io/anuke/mindustry/entities/units/FlyingUnit.java +++ b/core/src/io/anuke/mindustry/entities/type/FlyingUnit.java @@ -1,16 +1,19 @@ -package io.anuke.mindustry.entities.units; +package io.anuke.mindustry.entities.type; +import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.g2d.Draw; +import io.anuke.arc.graphics.g2d.Fill; import io.anuke.arc.math.Angles; import io.anuke.arc.math.Mathf; import io.anuke.arc.math.geom.Geometry; import io.anuke.arc.math.geom.Vector2; import io.anuke.arc.util.Time; +import io.anuke.arc.util.Tmp; import io.anuke.mindustry.entities.Predict; import io.anuke.mindustry.entities.Units; import io.anuke.mindustry.entities.bullet.BulletType; -import io.anuke.mindustry.entities.traits.CarriableTrait; -import io.anuke.mindustry.entities.traits.CarryTrait; +import io.anuke.mindustry.entities.units.UnitState; +import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.graphics.Shaders; import io.anuke.mindustry.net.Net; import io.anuke.mindustry.world.Tile; @@ -18,10 +21,9 @@ import io.anuke.mindustry.world.meta.BlockFlag; import static io.anuke.mindustry.Vars.world; -public abstract class FlyingUnit extends BaseUnit implements CarryTrait{ - protected static Vector2 vec = new Vector2(); +public abstract class FlyingUnit extends BaseUnit{ + protected float[] weaponAngles = {0, 0}; - protected CarriableTrait carrying; protected final UnitState idle = new UnitState(){ @@ -54,6 +56,7 @@ public abstract class FlyingUnit extends BaseUnit implements CarryTrait{ } if(target == null){ + retarget(() -> { targetClosest(); @@ -71,15 +74,27 @@ public abstract class FlyingUnit extends BaseUnit implements CarryTrait{ } }); }else{ - attack(150f); + attack(type.attackLength); - if((Angles.near(angleTo(target), rotation, 15f) || !getWeapon().getAmmo().keepVelocity) //bombers don't care about rotation - && dst(target) < Math.max(getWeapon().getAmmo().range(), type.range)){ - BulletType ammo = getWeapon().getAmmo(); + if((Angles.near(angleTo(target), rotation, type.shootCone) || getWeapon().ignoreRotation) //bombers and such don't care about rotation + && dst(target) < Math.max(getWeapon().bullet.range(), type.range)){ + BulletType ammo = getWeapon().bullet; - Vector2 to = Predict.intercept(FlyingUnit.this, target, ammo.speed); + if(type.rotateWeapon){ + for(boolean left : Mathf.booleans){ + int wi = Mathf.num(left); + float wx = x + Angles.trnsx(rotation - 90, getWeapon().width * Mathf.sign(left)); + float wy = y + Angles.trnsy(rotation - 90, getWeapon().width * Mathf.sign(left)); - getWeapon().update(FlyingUnit.this, to.x, to.y); + weaponAngles[wi] = Mathf.slerpDelta(weaponAngles[wi], Angles.angle(wx, wy, target.getX(), target.getY()), 0.1f); + + Tmp.v2.trns(weaponAngles[wi], getWeapon().length); + getWeapon().update(FlyingUnit.this, wx + Tmp.v2.x, wy + Tmp.v2.y, weaponAngles[wi], left); + } + }else{ + Vector2 to = Predict.intercept(FlyingUnit.this, target, ammo.speed); + getWeapon().update(FlyingUnit.this, to.x, to.y); + } } } } @@ -125,21 +140,6 @@ public abstract class FlyingUnit extends BaseUnit implements CarryTrait{ moveBy(x, y); } - @Override - public CarriableTrait getCarry(){ - return carrying; - } - - @Override - public void setCarry(CarriableTrait unit){ - this.carrying = unit; - } - - @Override - public float getCarryWeight(){ - return type.carryWeight; - } - @Override public void update(){ super.update(); @@ -150,28 +150,50 @@ public abstract class FlyingUnit extends BaseUnit implements CarryTrait{ } } + @Override + public void drawUnder(){ + drawEngine(); + } + @Override public void draw(){ Draw.alpha(Draw.getShader() != Shaders.mix ? 1f : hitTime / hitDuration); + Draw.rect(type.region, x, y, rotation - 90); - Draw.rect(type.name, x, y, rotation - 90); - + drawWeapons(); drawItems(); Draw.alpha(1f); } + public void drawWeapons(){ + + } + + public void drawEngine(){ + Draw.color(Pal.engine); + Fill.circle(x + Angles.trnsx(rotation + 180, type.engineOffset), y + Angles.trnsy(rotation + 180, type.engineOffset), + type.engineSize + Mathf.absin(Time.time(), 2f, type.engineSize/4f)); + + Draw.color(Color.WHITE); + Fill.circle(x + Angles.trnsx(rotation + 180, type.engineOffset-1f), y + Angles.trnsy(rotation + 180, type.engineOffset-1f), + (type.engineSize + Mathf.absin(Time.time(), 2f, type.engineSize/4f)) / 2f); + Draw.color(); + } + @Override public void behavior(){ + if(Units.invalidateTarget(target, this)){ + for(boolean left : Mathf.booleans){ + int wi = Mathf.num(left); + weaponAngles[wi] = Mathf.slerpDelta(weaponAngles[wi],rotation, 0.1f); + } + } + if(health <= health * type.retreatPercent && Geometry.findClosest(x, y, world.indexer.getAllied(team, BlockFlag.repair)) != null){ setState(retreat); } - - if(squad != null){ - squad.direction.add(velocity.x / squad.units, velocity.y / squad.units); - velocity.setAngle(Mathf.slerpDelta(velocity.angle(), squad.direction.angle(), 0.3f)); - } } @Override @@ -179,19 +201,14 @@ public abstract class FlyingUnit extends BaseUnit implements CarryTrait{ return attack; } - @Override - public float drawSize(){ - return 60; - } - protected void wobble(){ if(Net.client()) return; - x += Mathf.sin(Time.time() + id * 999, 25f, 0.08f)*Time.delta(); - y += Mathf.cos(Time.time() + id * 999, 25f, 0.08f)*Time.delta(); + x += Mathf.sin(Time.time() + id * 999, 25f, 0.05f)*Time.delta(); + y += Mathf.cos(Time.time() + id * 999, 25f, 0.05f)*Time.delta(); if(velocity.len() <= 0.05f){ - rotation += Mathf.sin(Time.time() + id * 99, 10f, 2.5f)*Time.delta(); + //rotation += Mathf.sin(Time.time() + id * 99, 10f, 2f * type.speed)*Time.delta(); } } @@ -206,44 +223,48 @@ public abstract class FlyingUnit extends BaseUnit implements CarryTrait{ protected void circle(float circleLength, float speed){ if(target == null) return; - vec.set(target.getX() - x, target.getY() - y); + Tmp.v1.set(target.getX() - x, target.getY() - y); - if(vec.len() < circleLength){ - vec.rotate((circleLength - vec.len()) / circleLength * 180f); + if(Tmp.v1.len() < circleLength){ + Tmp.v1.rotate((circleLength - Tmp.v1.len()) / circleLength * 180f); } - vec.setLength(speed * Time.delta()); + Tmp.v1.setLength(speed * Time.delta()); - velocity.add(vec); + velocity.add(Tmp.v1); } protected void moveTo(float circleLength){ if(target == null) return; - vec.set(target.getX() - x, target.getY() - y); + Tmp.v1.set(target.getX() - x, target.getY() - y); float length = circleLength <= 0.001f ? 1f : Mathf.clamp((dst(target) - circleLength) / 100f, -1f, 1f); - vec.setLength(type.speed * Time.delta() * length); - if(length < 0) vec.rotate(180f); + Tmp.v1.setLength(type.speed * Time.delta() * length); + if(length < -0.5f){ + Tmp.v1.rotate(180f); + }else if(length < 0){ + Tmp.v1.setZero(); + } - velocity.add(vec); + velocity.add(Tmp.v1); } protected void attack(float circleLength){ - vec.set(target.getX() - x, target.getY() - y); + Tmp.v1.set(target.getX() - x, target.getY() - y); float ang = angleTo(target); float diff = Angles.angleDist(ang, rotation); - if(diff > 100f && vec.len() < circleLength){ - vec.setAngle(velocity.angle()); + if(diff > 100f && Tmp.v1.len() < circleLength){ + Tmp.v1.setAngle(velocity.angle()); }else{ - vec.setAngle(Mathf.slerpDelta(velocity.angle(), vec.angle(), 0.44f)); + Tmp.v1.setAngle(Mathf.slerpDelta(velocity.angle(), Tmp.v1.angle(), 0.44f)); } - vec.setLength(type.speed * Time.delta()); + Tmp.v1.setLength(type.speed * Time.delta()); - velocity.add(vec); + velocity.add(Tmp.v1); } } diff --git a/core/src/io/anuke/mindustry/entities/units/GroundUnit.java b/core/src/io/anuke/mindustry/entities/type/GroundUnit.java similarity index 76% rename from core/src/io/anuke/mindustry/entities/units/GroundUnit.java rename to core/src/io/anuke/mindustry/entities/type/GroundUnit.java index ae278c9c36..85458a8e3a 100644 --- a/core/src/io/anuke/mindustry/entities/units/GroundUnit.java +++ b/core/src/io/anuke/mindustry/entities/type/GroundUnit.java @@ -1,4 +1,4 @@ -package io.anuke.mindustry.entities.units; +package io.anuke.mindustry.entities.type; import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.g2d.Draw; @@ -8,21 +8,15 @@ import io.anuke.arc.math.geom.Vector2; import io.anuke.arc.util.Time; import io.anuke.mindustry.Vars; import io.anuke.mindustry.entities.Predict; -import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.entities.Units; import io.anuke.mindustry.entities.bullet.BulletType; +import io.anuke.mindustry.entities.units.UnitState; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.graphics.Shaders; -import io.anuke.mindustry.type.ContentType; import io.anuke.mindustry.type.Weapon; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.Floor; -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -import static io.anuke.mindustry.Vars.content; import static io.anuke.mindustry.Vars.world; public abstract class GroundUnit extends BaseUnit{ @@ -31,7 +25,6 @@ public abstract class GroundUnit extends BaseUnit{ protected float walkTime; protected float stuckTime; protected float baseRotation; - protected Weapon weapon; public final UnitState @@ -44,11 +37,11 @@ public abstract class GroundUnit extends BaseUnit{ TileEntity core = getClosestEnemyCore(); float dst = core == null ? 0 : dst(core); - if(core != null && dst < getWeapon().getAmmo().range() / 1.1f){ + if(core != null && dst < getWeapon().bullet.range() / 1.1f){ target = core; } - if(dst > getWeapon().getAmmo().range() * 0.5f){ + if(dst > getWeapon().bullet.range() * 0.5f){ moveToCore(); } } @@ -79,12 +72,6 @@ public abstract class GroundUnit extends BaseUnit{ } }; - @Override - public void init(UnitType type, Team team){ - super.init(type, team); - this.weapon = type.weapon; - } - @Override public void interpolate(){ super.interpolate(); @@ -124,18 +111,14 @@ public abstract class GroundUnit extends BaseUnit{ @Override public Weapon getWeapon(){ - return weapon; - } - - public void setWeapon(Weapon weapon){ - this.weapon = weapon; + return type.weapon; } @Override public void draw(){ Draw.alpha(Draw.getShader() != Shaders.mix ? 1f : hitTime / hitDuration); - float ft = Mathf.sin(walkTime * type.speed*5f, 6f, 2f); + float ft = Mathf.sin(walkTime * type.speed*5f, 6f, 2f + type.hitsize/15f); Floor floor = getFloorOn(); @@ -147,7 +130,7 @@ public abstract class GroundUnit extends BaseUnit{ Draw.rect(type.legRegion, x + Angles.trnsx(baseRotation, ft * i), y + Angles.trnsy(baseRotation, ft * i), - 12f * i, 12f - Mathf.clamp(ft * i, 0, 2), baseRotation - 90); + type.legRegion.getWidth() * i * Draw.scl, type.legRegion.getHeight() * Draw.scl - Mathf.clamp(ft * i, 0, 2), baseRotation - 90); } if(floor.isLiquid){ @@ -161,11 +144,11 @@ public abstract class GroundUnit extends BaseUnit{ Draw.rect(type.region, x, y, rotation - 90); for(int i : Mathf.signs){ - float tra = rotation - 90, trY = -weapon.getRecoil(this, i > 0) + type.weaponOffsetY; - float w = i > 0 ? -12 : 12; - Draw.rect(weapon.equipRegion, - x + Angles.trnsx(tra, type.weaponOffsetX * i, trY), - y + Angles.trnsy(tra, type.weaponOffsetX * i, trY), w, 12, rotation - 90); + float tra = rotation - 90, trY = -type.weapon.getRecoil(this, i > 0) + type.weaponOffsetY; + float w = - i * type.weapon.region.getWidth() * Draw.scl; + Draw.rect(type.weapon.region, + x + Angles.trnsx(tra, getWeapon().width * i, trY), + y + Angles.trnsy(tra, getWeapon().width * i, trY), w, type.weapon.region.getHeight() * Draw.scl, rotation - 90); } drawItems(); @@ -180,11 +163,11 @@ public abstract class GroundUnit extends BaseUnit{ } if(!Units.invalidateTarget(target, this)){ - if(dst(target) < getWeapon().getAmmo().range()){ + if(dst(target) < getWeapon().bullet.range()){ rotate(angleTo(target)); if(Angles.near(angleTo(target), rotation, 13f)){ - BulletType ammo = getWeapon().getAmmo(); + BulletType ammo = getWeapon().bullet; Vector2 to = Predict.intercept(GroundUnit.this, target, ammo.speed); @@ -205,30 +188,6 @@ public abstract class GroundUnit extends BaseUnit{ retarget(this::targetClosest); } - @Override - public void write(DataOutput data) throws IOException{ - super.write(data); - data.writeByte(weapon.id); - } - - @Override - public void read(DataInput data) throws IOException{ - super.read(data); - weapon = content.getByID(ContentType.weapon, data.readByte()); - } - - @Override - public void writeSave(DataOutput stream) throws IOException{ - stream.writeByte(weapon.id); - super.writeSave(stream); - } - - @Override - public void readSave(DataInput stream) throws IOException{ - weapon = content.getByID(ContentType.weapon, stream.readByte()); - super.readSave(stream); - } - protected void patrol(){ vec.trns(baseRotation, type.speed * Time.delta()); velocity.add(vec.x, vec.y); diff --git a/core/src/io/anuke/mindustry/entities/Player.java b/core/src/io/anuke/mindustry/entities/type/Player.java similarity index 80% rename from core/src/io/anuke/mindustry/entities/Player.java rename to core/src/io/anuke/mindustry/entities/type/Player.java index a1dbab0c41..7dbe978342 100644 --- a/core/src/io/anuke/mindustry/entities/Player.java +++ b/core/src/io/anuke/mindustry/entities/type/Player.java @@ -1,12 +1,9 @@ -package io.anuke.mindustry.entities; +package io.anuke.mindustry.entities.type; import io.anuke.annotations.Annotations.Loc; import io.anuke.annotations.Annotations.Remote; import io.anuke.arc.Core; import io.anuke.arc.collection.Queue; -import io.anuke.arc.entities.Effects; -import io.anuke.arc.entities.EntityGroup; -import io.anuke.arc.entities.EntityQuery; import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.g2d.*; import io.anuke.arc.math.Angles; @@ -14,18 +11,18 @@ import io.anuke.arc.math.Mathf; import io.anuke.arc.math.geom.Geometry; import io.anuke.arc.math.geom.Rectangle; import io.anuke.arc.math.geom.Vector2; -import io.anuke.arc.util.Align; -import io.anuke.arc.util.Interval; -import io.anuke.arc.util.Pack; -import io.anuke.arc.util.Time; +import io.anuke.arc.util.*; import io.anuke.arc.util.pooling.Pools; -import io.anuke.mindustry.content.Mechs; import io.anuke.mindustry.content.Fx; -import io.anuke.mindustry.entities.effect.ScorchDecal; -import io.anuke.mindustry.entities.traits.*; +import io.anuke.mindustry.content.Mechs; +import io.anuke.mindustry.entities.*; +import io.anuke.mindustry.entities.traits.BuilderTrait; +import io.anuke.mindustry.entities.traits.ShooterTrait; +import io.anuke.mindustry.entities.traits.SpawnerTrait; +import io.anuke.mindustry.entities.traits.TargetTrait; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.gen.Call; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.graphics.Shaders; import io.anuke.mindustry.input.Binding; import io.anuke.mindustry.io.TypeIO; @@ -36,7 +33,6 @@ import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Block.Icon; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.Floor; -import io.anuke.mindustry.world.blocks.storage.CoreBlock.CoreEntity; import java.io.DataInput; import java.io.DataOutput; @@ -44,7 +40,7 @@ import java.io.IOException; import static io.anuke.mindustry.Vars.*; -public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTrait{ +public class Player extends Unit implements BuilderTrait, ShooterTrait{ public static final int timerSync = 2; public static final int timerAbility = 3; private static final int timerShootLeft = 0; @@ -60,11 +56,11 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra public String name = "name"; public String uuid, usid; public boolean isAdmin, isTransferring, isShooting, isBoosting, isMobile; - public float boostHeat, shootHeat; + public float boostHeat, shootHeat, destructTime; public boolean achievedFlight; public Color color = new Color(); public Mech mech; - public int spawner = noSpawner; + public SpawnerTrait spawner, lastSpawner; public NetConnection con; public int playerIndex = 0; @@ -76,7 +72,6 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra private float walktime; private Queue placeQueue = new Queue<>(); private Tile mining; - private CarriableTrait carrying; private Vector2 movement = new Vector2(); private boolean moved; @@ -90,15 +85,8 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra player.dead = true; player.placeQueue.clear(); - - player.dropCarry(); - - float explosiveness = 2f + (player.inventory.hasItem() ? player.inventory.getItem().item.explosiveness * player.inventory.getItem().amount : 0f); - float flammability = (player.inventory.hasItem() ? player.inventory.getItem().item.flammability * player.inventory.getItem().amount : 0f); - Damage.dynamicExplosion(player.x, player.y, flammability, explosiveness, 0f, player.getSize() / 2f, Palette.darkFlame); - - ScorchDecal.create(player.x, player.y); player.onDeath(); + player.mech = (player.isMobile ? Mechs.starterMobile : Mechs.starterDesktop); } @Override @@ -129,11 +117,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra @Override public boolean collidesGrid(int x, int y){ Tile tile = world.tile(x, y); - if(!isFlying()) return true; - if(!mech.flying && tile != null && !tile.block().synthetic() && tile.block().solid){ - return true; - } - return false; + return !isFlying() || (!mech.flying && tile != null && !tile.block().synthetic() && tile.block().solid); } @Override @@ -184,21 +168,6 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra } } - @Override - public CarriableTrait getCarry(){ - return carrying; - } - - @Override - public void setCarry(CarriableTrait unit){ - this.carrying = unit; - } - - @Override - public float getCarryWeight(){ - return mech.carryWeight; - } - @Override public float getBuildPower(Tile tile){ return mech.buildPower; @@ -206,7 +175,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra @Override public float maxHealth(){ - return 200; + return mech.health; } @Override @@ -225,8 +194,8 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra } @Override - public float getArmor(){ - return mech.armor + mech.getExtraArmor(this); + public float calculateDamage(float amount){ + return amount * Mathf.clamp(1f - (status.getArmorMultiplier() + mech.getExtraArmor(this)) / 100f); } @Override @@ -241,7 +210,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra @Override public boolean isFlying(){ - return mech.flying || boostHeat > liftoffBoost || isCarried(); + return mech.flying || boostHeat > liftoffBoost; } @Override @@ -282,16 +251,6 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra return "Player{" + id + ", mech=" + mech.name + ", local=" + isLocal + ", " + x + ", " + y + "}"; } - @Override - public void removed(){ - dropCarryLocal(); - - TileEntity core = getClosestCore(); - if(core != null && ((CoreEntity) core).currentUnit == this){ - ((CoreEntity) core).currentUnit = null; - } - } - @Override public EntityGroup targetGroup(){ return playerGroup; @@ -322,7 +281,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra if(dead) return; if(!movement.isZero() && moved && !state.isPaused()){ - walktime += movement.len() / 0.7f * getFloorOn().speedMultiplier; + walktime += movement.len() / 1f * getFloorOn().speedMultiplier; baseRotation = Mathf.slerpDelta(baseRotation, movement.angle(), 0.13f); } @@ -366,18 +325,18 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra for(int i : Mathf.signs){ float tra = rotation - 90, trY = -mech.weapon.getRecoil(this, i > 0) + mech.weaponOffsetY; - float w = i > 0 ? -mech.weapon.equipRegion.getWidth() : mech.weapon.equipRegion.getWidth(); - Draw.rect(mech.weapon.equipRegion, + float w = i > 0 ? -mech.weapon.region.getWidth() : mech.weapon.region.getWidth(); + Draw.rect(mech.weapon.region, x + Angles.trnsx(tra, (mech.weaponOffsetX + mech.spreadX(this)) * i, trY), y + Angles.trnsy(tra, (mech.weaponOffsetX + mech.spreadX(this)) * i, trY), w * Draw.scl, - mech.weapon.equipRegion.getHeight() * Draw.scl, + mech.weapon.region.getHeight() * Draw.scl, rotation - 90); } float backTrns = 4f, itemSize = 5f; - if(inventory.hasItem()){ - ItemStack stack = inventory.getItem(); + if(item.amount > 0){ + ItemStack stack = item; int stored = Mathf.clamp(stack.amount / 6, 1, 8); for(int i = 0; i < stored; i++){ @@ -405,7 +364,21 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra public void drawOver(){ if(dead) return; - drawBuilding(this); + drawBuilding(); + } + + @Override + public void drawUnder(){ + float size = mech.engineSize * (mech.flying ? 1f : boostHeat); + + Draw.color(mech.engineColor); + Fill.circle(x + Angles.trnsx(rotation + 180, mech.engineOffset), y + Angles.trnsy(rotation + 180, mech.engineOffset), + size + Mathf.absin(Time.time(), 2f, size/4f)); + + Draw.color(Color.WHITE); + Fill.circle(x + Angles.trnsx(rotation + 180, mech.engineOffset-1f), y + Angles.trnsy(rotation + 180, mech.engineOffset-1f), + (size + Mathf.absin(Time.time(), 2f, size/4f)) / 2f); + Draw.color(); } public void drawName(){ @@ -434,19 +407,20 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra Draw.reset(); Pools.free(layout); font.getData().setScale(1f); + font.setColor(Color.WHITE); font.setUseIntegerPositions(ints); } /** Draw all current build requests. Does not draw the beam effect, only the positions. */ public void drawBuildRequests(){ for(BuildRequest request : getPlaceQueue()){ - if(getCurrentRequest() == request) continue; + if(getCurrentRequest() == request && request.progress > 0.001f) continue; if(request.breaking){ Block block = world.tile(request.x, request.y).target().block(); //draw removal request - Lines.stroke(2f, Palette.removeBack); + Lines.stroke(2f, Pal.removeBack); float rad = Mathf.absin(Time.time(), 7f, 1f) + block.size * tilesize / 2f - 1; Lines.square( @@ -454,7 +428,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra request.y * tilesize + block.offset() - 1, rad); - Draw.color(Palette.remove); + Draw.color(Pal.remove); Lines.square( request.x * tilesize + block.offset(), @@ -464,7 +438,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra float rad = Mathf.absin(Time.time(), 7f, 1f) - 1.5f + request.block.size * tilesize / 2f; //draw place request - Lines.stroke(1f, Palette.accentBack); + Lines.stroke(1f, Pal.accentBack); Lines.square( request.x * tilesize + request.block.offset(), @@ -478,7 +452,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra request.y * tilesize + request.block.offset(), rad*2, rad*2, request.rotation * 90); - Draw.color(Palette.accent); + Draw.color(Pal.accent); Lines.square( request.x * tilesize + request.block.offset(), @@ -509,13 +483,23 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra setDead(true); } + if(!isDead() && isOutOfBounds()){ + destructTime += Time.delta(); + + if(destructTime >= boundsCountdown){ + kill(); + } + }else{ + destructTime = 0f; + } + if(isDead()){ isBoosting = false; boostHeat = 0f; updateRespawning(); return; }else{ - spawner = noSpawner; + spawner = null; } avoidOthers(1f); @@ -535,7 +519,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra if(mech.shake > 1f){ Effects.shake(mech.shake, mech.shake, this); } - Effects.effect(Fx.unitLand, tile.floor().minimapColor, x, y, tile.floor().isLiquid ? 1f : 0.5f); + Effects.effect(Fx.unitLand, tile.floor().liquidColor == null ? tile.floor().color : tile.floor().color, x, y, tile.floor().isLiquid ? 1f : 0.5f); } mech.onLand(this); achievedFlight = false; @@ -543,15 +527,10 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra if(!isLocal){ interpolate(); - updateBuilding(this); //building happens even with non-locals + updateBuilding(); //building happens even with non-locals status.update(this); //status effect updating also happens with non locals for effect purposes updateVelocityStatus(); //velocity too, for visual purposes - if(getCarrier() != null){ - x = getCarrier().getX(); - y = getCarrier().getY(); - } - if(Net.server()){ updateShooting(); //server simulates player shooting } @@ -567,10 +546,11 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra updateMech(); } - updateBuilding(this); + updateBuilding(); - x = Mathf.clamp(x, 0, world.width() * tilesize - tilesize); - y = Mathf.clamp(y, 0, world.height() * tilesize - tilesize); + if(!mech.flying){ + clampPosition(); + } } protected void updateMech(){ @@ -584,10 +564,6 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra } float speed = isBoosting && !mech.flying ? mech.boostSpeed : mech.speed; - //fraction of speed when at max load - float carrySlowdown = 0.7f; - - speed *= ((inventory.hasItem() ? Mathf.lerp(1f, carrySlowdown, (float) inventory.getItem().amount / inventory.capacity()) : 1f)); if(mech.flying){ //prevent strafing backwards, have a penalty for doing so @@ -595,23 +571,6 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra speed *= Mathf.lerp(1f, penalty, Angles.angleDist(rotation, velocity.angle()) / 180f); } - //drop from carrier on key press - if(!ui.chatfrag.chatOpen() && Core.input.keyTap(Binding.drop_unit)){ - if(!mech.flying){ - if(getCarrier() != null){ - Call.dropSelf(this); - } - }else if(getCarry() != null){ - dropCarry(); - }else{ - Unit unit = Units.getClosest(team, x, y, 8f, u -> !u.isFlying() && u.mass() <= mech.carryWeight); - - if(unit != null){ - carry(unit); - } - } - } - movement.setZero(); float xa = Core.input.axis(Binding.move_x); @@ -628,18 +587,12 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra movement.limit(speed).scl(Time.delta()); - if(getCarrier() == null){ - if(!ui.chatfrag.chatOpen()){ - velocity.add(movement.x, movement.y); - } - float prex = x, prey = y; - updateVelocityStatus(); - moved = dst(prex, prey) > 0.001f; - }else{ - velocity.setZero(); - x = Mathf.lerpDelta(x, getCarrier().getX(), 0.1f); - y = Mathf.lerpDelta(y, getCarrier().getY(), 0.1f); + if(!ui.chatfrag.chatOpen()){ + velocity.add(movement.x, movement.y); } + float prex = x, prey = y; + updateVelocityStatus(); + moved = dst(prex, prey) > 0.001f; if(!ui.chatfrag.chatOpen()){ float baseLerp = mech.getRotationAlpha(this); @@ -662,7 +615,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra protected void updateFlying(){ if(Units.invalidateTarget(target, this) && !(target instanceof TileEntity && ((TileEntity) target).damaged() && target.getTeam() == team && - mech.canHeal && dst(target) < getWeapon().getAmmo().range())){ + mech.canHeal && dst(target) < getWeapon().bullet.range())){ target = null; } @@ -680,9 +633,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra } if(dst(moveTarget) < 2f){ - if(moveTarget instanceof CarriableTrait){ - carry((CarriableTrait) moveTarget); - }else if(tapping){ + if(tapping){ Tile tile = ((TileEntity) moveTarget).tile; tile.block().tapped(tile, this); } @@ -693,12 +644,6 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra moveTarget = null; } - if(getCarrier() != null){ - velocity.setZero(); - x = Mathf.lerpDelta(x, getCarrier().getX(), 0.1f); - y = Mathf.lerpDelta(y, getCarrier().getY(), 0.1f); - } - movement.set(targetX - x, targetY - y).limit(isBoosting && !mech.flying ? mech.boostSpeed : mech.speed); movement.setAngle(Mathf.slerp(movement.angle(), velocity.angle(), 0.05f)); @@ -726,7 +671,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra float lx = x, ly = y; updateVelocityStatus(); - moved = dst(lx, ly) > 0.001f && !isCarried(); + moved = dst(lx, ly) > 0.001f; if(mech.flying){ //hovering effect @@ -742,11 +687,11 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra if(target == null){ isShooting = false; if(Core.settings.getBool("autotarget")){ - target = Units.getClosestTarget(team, x, y, getWeapon().getAmmo().range()); + target = Units.getClosestTarget(team, x, y, getWeapon().bullet.range()); if(mech.canHeal && target == null){ target = Geometry.findClosest(x, y, world.indexer.getDamaged(Team.blue)); - if(target != null && dst(target) > getWeapon().getAmmo().range()){ + if(target != null && dst(target) > getWeapon().bullet.range()){ target = null; }else if(target != null){ target = ((Tile) target).entity; @@ -758,14 +703,14 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra } } }else if(target.isValid() || (target instanceof TileEntity && ((TileEntity) target).damaged() && target.getTeam() == team && - mech.canHeal && dst(target) < getWeapon().getAmmo().range())){ + mech.canHeal && dst(target) < getWeapon().bullet.range())){ //rotate toward and shoot the target if(mech.turnCursor){ rotation = Mathf.slerpDelta(rotation, angleTo(target), 0.2f); } Vector2 intercept = - Predict.intercept(x, y, target.getX(), target.getY(), target.velocity().x - velocity.x, target.velocity().y - velocity.y, getWeapon().getAmmo().speed); + Predict.intercept(x, y, target.getX(), target.getY(), target.velocity().x - velocity.x, target.velocity().y - velocity.y, getWeapon().bullet.speed); pointerX = intercept.x; pointerY = intercept.y; @@ -799,12 +744,11 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra public void resetNoAdd(){ status.clear(); team = Team.blue; - inventory.clear(); + item.amount = 0; placeQueue.clear(); dead = true; target = null; moveTarget = null; - carrier = null; health = maxHealth(); boostHeat = drownTime = hitTime = 0f; mech = (isMobile ? Mechs.starterMobile : Mechs.starterDesktop); @@ -817,23 +761,25 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra public void updateRespawning(){ - if(spawner != noSpawner && world.tile(spawner) != null && world.tile(spawner).entity instanceof SpawnerTrait){ - ((SpawnerTrait) world.tile(spawner).entity).updateSpawning(this); - }else{ - CoreEntity entity = (CoreEntity) getClosestCore(); - if(entity != null && !netServer.isWaitingForPlayers()){ - this.spawner = entity.tile.pos(); + if(spawner != null && spawner.isValid()){ + spawner.updateSpawning(this); + }else if(!netServer.isWaitingForPlayers()){ + if(lastSpawner != null && lastSpawner.isValid()){ + this.spawner = lastSpawner; + }else if(getClosestCore() != null){ + this.spawner = (SpawnerTrait)getClosestCore(); } } } public void beginRespawning(SpawnerTrait spawner){ - this.spawner = spawner.getTile().pos(); + this.spawner = spawner; + this.lastSpawner = spawner; this.dead = true; } public void endRespawning(){ - spawner = noSpawner; + spawner = null; } //endregion @@ -890,7 +836,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra buffer.writeInt(Color.rgba8888(color)); buffer.writeByte(mech.id); buffer.writeInt(mining == null ? -1 : mining.pos()); - buffer.writeInt(spawner); + buffer.writeInt(spawner == null ? noSpawner : spawner.getTile().pos()); buffer.writeShort((short) (baseRotation * 2)); writeBuilding(buffer); @@ -922,7 +868,12 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra }else{ mining = world.tile(mine); isBoosting = boosting; - this.spawner = spawner; + Tile tile = world.tile(spawner); + if(tile != null && tile.entity instanceof SpawnerTrait){ + this.spawner = (SpawnerTrait)tile.entity; + }else{ + this.spawner = null; + } } } diff --git a/core/src/io/anuke/mindustry/entities/TileEntity.java b/core/src/io/anuke/mindustry/entities/type/TileEntity.java similarity index 96% rename from core/src/io/anuke/mindustry/entities/TileEntity.java rename to core/src/io/anuke/mindustry/entities/type/TileEntity.java index 2d0c82e265..f21b0035bf 100644 --- a/core/src/io/anuke/mindustry/entities/TileEntity.java +++ b/core/src/io/anuke/mindustry/entities/type/TileEntity.java @@ -1,14 +1,14 @@ -package io.anuke.mindustry.entities; +package io.anuke.mindustry.entities.type; import io.anuke.annotations.Annotations.Loc; import io.anuke.annotations.Annotations.Remote; import io.anuke.arc.Events; import io.anuke.arc.collection.Array; import io.anuke.arc.collection.ObjectSet; -import io.anuke.arc.entities.Effects; -import io.anuke.arc.entities.EntityGroup; -import io.anuke.arc.entities.impl.BaseEntity; -import io.anuke.arc.entities.trait.HealthTrait; +import io.anuke.mindustry.entities.Effects; +import io.anuke.mindustry.entities.EntityGroup; +import io.anuke.mindustry.entities.impl.BaseEntity; +import io.anuke.mindustry.entities.traits.HealthTrait; import io.anuke.arc.math.Mathf; import io.anuke.arc.math.geom.Point2; import io.anuke.arc.math.geom.Vector2; @@ -151,7 +151,7 @@ public class TileEntity extends BaseEntity implements TargetTrait, HealthTrait{ if(health <= 0){ Call.onTileDestroyed(tile); - }else if(preHealth >= maxHealth() - 0.00001f && health < maxHealth()){ //when just damaged + }else if(preHealth >= maxHealth() - 0.00001f && health < maxHealth() && world != null){ //when just damaged world.indexer.notifyTileDamaged(this); } } diff --git a/core/src/io/anuke/mindustry/entities/Unit.java b/core/src/io/anuke/mindustry/entities/type/Unit.java similarity index 77% rename from core/src/io/anuke/mindustry/entities/Unit.java rename to core/src/io/anuke/mindustry/entities/type/Unit.java index 8ee287a454..2b7c5c956b 100644 --- a/core/src/io/anuke/mindustry/entities/Unit.java +++ b/core/src/io/anuke/mindustry/entities/type/Unit.java @@ -1,15 +1,9 @@ -package io.anuke.mindustry.entities; +package io.anuke.mindustry.entities.type; import io.anuke.arc.Core; import io.anuke.arc.Events; -import io.anuke.arc.entities.Effects; -import io.anuke.arc.entities.impl.DestructibleEntity; -import io.anuke.arc.entities.trait.DamageTrait; -import io.anuke.arc.entities.trait.DrawTrait; -import io.anuke.arc.entities.trait.SolidTrait; import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.g2d.Draw; -import io.anuke.arc.graphics.g2d.Fill; import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.math.Mathf; import io.anuke.arc.math.geom.Geometry; @@ -17,12 +11,22 @@ import io.anuke.arc.math.geom.Rectangle; import io.anuke.arc.math.geom.Vector2; import io.anuke.arc.util.Time; import io.anuke.mindustry.content.Blocks; +import io.anuke.mindustry.content.Fx; +import io.anuke.mindustry.entities.Damage; +import io.anuke.mindustry.entities.Effects; +import io.anuke.mindustry.entities.Units; +import io.anuke.mindustry.entities.effect.ScorchDecal; +import io.anuke.mindustry.entities.impl.DestructibleEntity; import io.anuke.mindustry.entities.traits.*; +import io.anuke.mindustry.entities.units.Statuses; import io.anuke.mindustry.game.EventType.UnitDestroyEvent; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.game.Teams.TeamData; +import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.net.Interpolator; import io.anuke.mindustry.net.Net; +import io.anuke.mindustry.type.Item; +import io.anuke.mindustry.type.ItemStack; import io.anuke.mindustry.type.StatusEffect; import io.anuke.mindustry.type.Weapon; import io.anuke.mindustry.world.Pos; @@ -33,10 +37,9 @@ import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; -import static io.anuke.mindustry.Vars.state; -import static io.anuke.mindustry.Vars.world; +import static io.anuke.mindustry.Vars.*; -public abstract class Unit extends DestructibleEntity implements SaveTrait, TargetTrait, SyncTrait, DrawTrait, TeamTrait, CarriableTrait, InventoryTrait{ +public abstract class Unit extends DestructibleEntity implements SaveTrait, TargetTrait, SyncTrait, DrawTrait, TeamTrait{ /**Total duration of hit flash effect*/ public static final float hitDuration = 9f; /**Percision divisor of velocity, used when writing. For example a value of '2' would mean the percision is 1/2 = 0.5-size chunks.*/ @@ -48,42 +51,25 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ private static final Rectangle queryRect = new Rectangle(); private static final Vector2 moveVector = new Vector2(); - public final UnitInventory inventory = new UnitInventory(this); public float rotation; - public float hitTime; protected final Interpolator interpolator = new Interpolator(); - protected final StatusController status = new StatusController(); - protected Team team = Team.blue; + protected final Statuses status = new Statuses(); + protected final ItemStack item = new ItemStack(content.item(0), 0); - protected CarryTrait carrier; - protected float drownTime; + protected Team team = Team.blue; + protected float drownTime, hitTime; @Override public boolean movable(){ return !isDead(); } - @Override - public UnitInventory getInventory(){ - return inventory; - } - - @Override - public CarryTrait getCarrier(){ - return carrier; - } - @Override public boolean collidesGrid(int x, int y){ return !isFlying(); } - @Override - public void setCarrier(CarryTrait carrier){ - this.carrier = carrier; - } - @Override public Team getTeam(){ return team; @@ -125,7 +111,15 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ @Override public void onDeath(){ - inventory.clear(); + float explosiveness = 2f + item.item.explosiveness * item.amount; + float flammability = item.item.flammability * item.amount; + Damage.dynamicExplosion(x, y, flammability, explosiveness, 0f, getSize() / 2f, Pal.darkFlame); + + ScorchDecal.create(x, y); + Effects.effect(Fx.explosion, this); + Effects.shake(2f, 2f, this); + + item.amount = 0; drownTime = 0f; status.clear(); Events.fire(new UnitDestroyEvent(this)); @@ -145,6 +139,11 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ } } + @Override + public boolean isValid(){ + return !isDead() && isAdded(); + } + @Override public void writeSave(DataOutput stream) throws IOException{ writeSave(stream, false); @@ -160,9 +159,12 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ byte yv = stream.readByte(); float rotation = stream.readShort() / 2f; int health = stream.readShort(); + byte itemID = stream.readByte(); + short itemAmount = stream.readShort(); this.status.readSave(stream); - this.inventory.readSave(stream); + this.item.amount = itemAmount; + this.item.item = content.item(itemID); this.dead = dead; this.team = Team.all[team]; this.health = health; @@ -181,12 +183,31 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ stream.writeByte((byte) (Mathf.clamp(velocity.y, -maxAbsVelocity, maxAbsVelocity) * velocityPercision)); stream.writeShort((short) (rotation * 2)); stream.writeShort((short) health); + stream.writeByte(item.item.id); + stream.writeShort((short)item.amount); status.writeSave(stream); - inventory.writeSave(stream); + } + + protected void clampPosition(){ + x = Mathf.clamp(x, tilesize, world.width() * tilesize - tilesize); + y = Mathf.clamp(y, tilesize, world.height() * tilesize - tilesize); + } + + public void kill(){ + health = -1; + damage(1); + } + + public boolean isImmune(StatusEffect effect){ + return false; + } + + public boolean isOutOfBounds(){ + return x < -worldBounds || y < -worldBounds || x > world.width() * tilesize + worldBounds || y > world.height() * tilesize + worldBounds; } public float calculateDamage(float amount){ - return amount * Mathf.clamp(1f - getArmor() / 100f * status.getArmorMultiplier()); + return amount * Mathf.clamp(1f - status.getArmorMultiplier() / 100f); } public float getDamageMultipler(){ @@ -202,7 +223,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ queryRect.setSize(queryRect.getWidth() * scaling); Units.getNearby(queryRect, t -> { - if(t == this || t.getCarrier() == this || getCarrier() == t || t.isFlying() != isFlying()) return; + if(t == this || t.isFlying() != isFlying()) return; float dst = dst(t); moveVector.set(x, y).sub(t.getX(), t.getY()).setLength(1f * (1f - (dst / queryRect.getWidth()))); applyImpulse(moveVector.x, moveVector.y); @@ -227,21 +248,10 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ public void onRespawn(Tile tile){} - @Override - public boolean isValid(){ - return !isDead() && isAdded(); - } - /**Updates velocity and status effects.*/ public void updateVelocityStatus(){ Floor floor = getFloorOn(); - if(isCarried()){ //carried units do not take into account velocity normally - set(carrier.getX(), carrier.getY()); - velocity.set(carrier.velocity()); - return; - } - Tile tile = world.tileWorld(x, y); status.update(this); @@ -296,6 +306,31 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ velocity.scl(Mathf.clamp(1f - drag() * (isFlying() ? 1f : floor.dragMultiplier) * Time.delta())); } + public boolean acceptsItem(Item item){ + return this.item.amount <= 0 || (this.item.item == item && this.item.amount <= getItemCapacity()); + } + + public void addItem(Item item){ + addItem(item, 1); + } + + public void addItem(Item item, int amount){ + this.item.amount = this.item.item == item ? this.item.amount + amount : amount; + this.item.item = item; + } + + public void clearItem(){ + item.amount = 0; + } + + public ItemStack item(){ + return item; + } + + public int maxAccepted(Item item){ + return this.item.item != item ? 0 : getItemCapacity() - this.item.amount; + } + public void applyEffect(StatusEffect effect, float duration){ if(dead || Net.client()) return; //effects are synced and thus not applied through clients status.handleApply(this, effect, duration); @@ -343,22 +378,12 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ Draw.rect(getIconRegion(), x + offsetX, y + offsetY, rotation - 90); } - public void drawView(){ - Fill.circle(x, y, getViewDistance()); - } - - public float getViewDistance(){ - return 135f; - } - public abstract TextureRegion getIconRegion(); public abstract Weapon getWeapon(); public abstract int getItemCapacity(); - public abstract float getArmor(); - public abstract float mass(); public abstract boolean isFlying(); diff --git a/core/src/io/anuke/mindustry/entities/type/base/Crawler.java b/core/src/io/anuke/mindustry/entities/type/base/Crawler.java new file mode 100644 index 0000000000..f3c12c9604 --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/type/base/Crawler.java @@ -0,0 +1,6 @@ +package io.anuke.mindustry.entities.type.base; + +import io.anuke.mindustry.entities.type.GroundUnit; + +public class Crawler extends GroundUnit{ +} diff --git a/core/src/io/anuke/mindustry/entities/type/base/Dagger.java b/core/src/io/anuke/mindustry/entities/type/base/Dagger.java new file mode 100644 index 0000000000..13bf6021c9 --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/type/base/Dagger.java @@ -0,0 +1,7 @@ +package io.anuke.mindustry.entities.type.base; + +import io.anuke.mindustry.entities.type.GroundUnit; + +public class Dagger extends GroundUnit{ + +} diff --git a/core/src/io/anuke/mindustry/entities/units/types/Drone.java b/core/src/io/anuke/mindustry/entities/type/base/Drone.java similarity index 91% rename from core/src/io/anuke/mindustry/entities/units/types/Drone.java rename to core/src/io/anuke/mindustry/entities/type/base/Drone.java index 6a7306b950..384d302d84 100644 --- a/core/src/io/anuke/mindustry/entities/units/types/Drone.java +++ b/core/src/io/anuke/mindustry/entities/type/base/Drone.java @@ -1,18 +1,18 @@ -package io.anuke.mindustry.entities.units.types; +package io.anuke.mindustry.entities.type.base; import io.anuke.arc.Events; import io.anuke.arc.collection.Queue; -import io.anuke.arc.entities.EntityGroup; +import io.anuke.mindustry.entities.EntityGroup; import io.anuke.arc.math.Mathf; import io.anuke.arc.math.geom.Geometry; import io.anuke.arc.util.Structs; import io.anuke.mindustry.content.Blocks; -import io.anuke.mindustry.entities.Player; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.Player; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.entities.Units; import io.anuke.mindustry.entities.traits.BuilderTrait; -import io.anuke.mindustry.entities.units.BaseUnit; -import io.anuke.mindustry.entities.units.FlyingUnit; +import io.anuke.mindustry.entities.type.BaseUnit; +import io.anuke.mindustry.entities.type.FlyingUnit; import io.anuke.mindustry.entities.units.UnitState; import io.anuke.mindustry.game.EventType.BuildSelectEvent; import io.anuke.mindustry.gen.Call; @@ -32,8 +32,6 @@ import static io.anuke.mindustry.Vars.unitGroups; import static io.anuke.mindustry.Vars.world; public class Drone extends FlyingUnit implements BuilderTrait{ - protected static int timerRepairEffect = timerIndex++; - protected Item targetItem; protected Tile mineTile; protected Queue placeQueue = new Queue<>(); @@ -135,10 +133,10 @@ public class Drone extends FlyingUnit implements BuilderTrait{ } //if inventory is full, drop it off. - if(inventory.isFull()){ + if(item.amount >= getItemCapacity()){ setState(drop); }else{ - if(targetItem != null && !inventory.canAcceptItem(targetItem)){ + if(targetItem != null && !acceptsItem(targetItem)){ setState(drop); return; } @@ -177,13 +175,13 @@ public class Drone extends FlyingUnit implements BuilderTrait{ } public void update(){ - if(inventory.isEmpty()){ + if(item.amount == 0){ setState(mine); return; } - if(inventory.getItem().item.type != ItemType.material){ - inventory.clearItem(); + if(item.item.type != ItemType.material){ + item.amount = 0; setState(mine); return; } @@ -195,9 +193,9 @@ public class Drone extends FlyingUnit implements BuilderTrait{ TileEntity tile = (TileEntity) target; if(dst(target) < type.range){ - if(tile.tile.block().acceptStack(inventory.getItem().item, inventory.getItem().amount, tile.tile, Drone.this) == inventory.getItem().amount){ - Call.transferItemTo(inventory.getItem().item, inventory.getItem().amount, x, y, tile.tile); - inventory.clearItem(); + if(tile.tile.block().acceptStack(item.item, item.amount, tile.tile, Drone.this) == item.amount){ + Call.transferItemTo(item.item, item.amount, x, y, tile.tile); + item.amount = 0; } setState(repair); @@ -299,7 +297,7 @@ public class Drone extends FlyingUnit implements BuilderTrait{ target = null; } - updateBuilding(this); + updateBuilding(); } @Override @@ -326,7 +324,7 @@ public class Drone extends FlyingUnit implements BuilderTrait{ @Override public void drawOver(){ - drawBuilding(this); + drawBuilding(); } @Override diff --git a/core/src/io/anuke/mindustry/entities/type/base/Eruptor.java b/core/src/io/anuke/mindustry/entities/type/base/Eruptor.java new file mode 100644 index 0000000000..dfbfe9db39 --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/type/base/Eruptor.java @@ -0,0 +1,6 @@ +package io.anuke.mindustry.entities.type.base; + +import io.anuke.mindustry.entities.type.GroundUnit; + +public class Eruptor extends GroundUnit{ +} diff --git a/core/src/io/anuke/mindustry/entities/units/types/Fortress.java b/core/src/io/anuke/mindustry/entities/type/base/Fortress.java similarity index 78% rename from core/src/io/anuke/mindustry/entities/units/types/Fortress.java rename to core/src/io/anuke/mindustry/entities/type/base/Fortress.java index c39e356586..06033fcf66 100644 --- a/core/src/io/anuke/mindustry/entities/units/types/Fortress.java +++ b/core/src/io/anuke/mindustry/entities/type/base/Fortress.java @@ -1,7 +1,7 @@ -package io.anuke.mindustry.entities.units.types; +package io.anuke.mindustry.entities.type.base; import io.anuke.mindustry.entities.Units; -import io.anuke.mindustry.entities.units.GroundUnit; +import io.anuke.mindustry.entities.type.GroundUnit; public class Fortress extends GroundUnit{ diff --git a/core/src/io/anuke/mindustry/entities/type/base/Ghoul.java b/core/src/io/anuke/mindustry/entities/type/base/Ghoul.java new file mode 100644 index 0000000000..bc1f6a5317 --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/type/base/Ghoul.java @@ -0,0 +1,7 @@ +package io.anuke.mindustry.entities.type.base; + +import io.anuke.mindustry.entities.type.FlyingUnit; + +public class Ghoul extends FlyingUnit{ + +} diff --git a/core/src/io/anuke/mindustry/entities/type/base/Phantom.java b/core/src/io/anuke/mindustry/entities/type/base/Phantom.java new file mode 100644 index 0000000000..516d305b94 --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/type/base/Phantom.java @@ -0,0 +1,5 @@ +package io.anuke.mindustry.entities.type.base; + +public class Phantom extends Drone{ + +} diff --git a/core/src/io/anuke/mindustry/entities/type/base/Revenant.java b/core/src/io/anuke/mindustry/entities/type/base/Revenant.java new file mode 100644 index 0000000000..9f3c5f2c6e --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/type/base/Revenant.java @@ -0,0 +1,35 @@ +package io.anuke.mindustry.entities.type.base; + +import io.anuke.arc.graphics.g2d.Draw; +import io.anuke.arc.math.Angles; +import io.anuke.arc.math.Mathf; +import io.anuke.mindustry.entities.Units; +import io.anuke.mindustry.entities.type.FlyingUnit; + +public class Revenant extends FlyingUnit{ + + @Override + public void drawWeapons(){ + for(int i : Mathf.signs){ + float tra = rotation - 90, trY = -getWeapon().getRecoil(this, i > 0) + type.weaponOffsetY; + float w = i > 0 ? -12 : 12; + float wx = x + Angles.trnsx(tra, getWeapon().width * i, trY), wy = y + Angles.trnsy(tra, getWeapon().width * i, trY); + int wi = (i + 1)/2; + Draw.rect(getWeapon().region, wx, wy, w, 12, weaponAngles[wi] - 90); + } + } + + @Override + protected void attack(float circleLength){ + moveTo(circleLength); + } + + @Override + protected void updateRotation(){ + if(!Units.invalidateTarget(target, this)){ + rotation = Mathf.slerpDelta(rotation, angleTo(target), type.rotatespeed); + }else{ + rotation = Mathf.slerpDelta(rotation, velocity.angle(), type.baseRotateSpeed); + } + } +} diff --git a/core/src/io/anuke/mindustry/entities/type/base/Spirit.java b/core/src/io/anuke/mindustry/entities/type/base/Spirit.java new file mode 100644 index 0000000000..f7142e8d6d --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/type/base/Spirit.java @@ -0,0 +1,4 @@ +package io.anuke.mindustry.entities.type.base; + +public class Spirit extends Drone{ +} diff --git a/core/src/io/anuke/mindustry/entities/type/base/Titan.java b/core/src/io/anuke/mindustry/entities/type/base/Titan.java new file mode 100644 index 0000000000..1ac30593ac --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/type/base/Titan.java @@ -0,0 +1,7 @@ +package io.anuke.mindustry.entities.type.base; + +import io.anuke.mindustry.entities.type.GroundUnit; + +public class Titan extends GroundUnit{ + +} diff --git a/core/src/io/anuke/mindustry/entities/type/base/Wraith.java b/core/src/io/anuke/mindustry/entities/type/base/Wraith.java new file mode 100644 index 0000000000..9123ffcb8d --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/type/base/Wraith.java @@ -0,0 +1,7 @@ +package io.anuke.mindustry.entities.type.base; + +import io.anuke.mindustry.entities.type.FlyingUnit; + +public class Wraith extends FlyingUnit{ + +} diff --git a/core/src/io/anuke/mindustry/entities/units/Squad.java b/core/src/io/anuke/mindustry/entities/units/Squad.java deleted file mode 100644 index ef5d2b6e01..0000000000 --- a/core/src/io/anuke/mindustry/entities/units/Squad.java +++ /dev/null @@ -1,22 +0,0 @@ -package io.anuke.mindustry.entities.units; - -import io.anuke.arc.Core; -import io.anuke.arc.math.geom.Vector2; - -/** - * Used to group entities together, for formations and such. - * Usually, squads are used by units spawned in the same wave. - */ -public class Squad{ - public Vector2 direction = new Vector2(); - public int units; - - private long lastUpdated; - - protected void update(){ - if(Core.graphics.getFrameId() != lastUpdated){ - direction.setZero(); - lastUpdated = Core.graphics.getFrameId(); - } - } -} diff --git a/core/src/io/anuke/mindustry/entities/StatusController.java b/core/src/io/anuke/mindustry/entities/units/Statuses.java similarity index 92% rename from core/src/io/anuke/mindustry/entities/StatusController.java rename to core/src/io/anuke/mindustry/entities/units/Statuses.java index fa9dd3c12e..90fc24b270 100644 --- a/core/src/io/anuke/mindustry/entities/StatusController.java +++ b/core/src/io/anuke/mindustry/entities/units/Statuses.java @@ -1,4 +1,4 @@ -package io.anuke.mindustry.entities; +package io.anuke.mindustry.entities.units; import io.anuke.arc.collection.Array; import io.anuke.arc.graphics.Color; @@ -7,6 +7,7 @@ import io.anuke.arc.util.Tmp; import io.anuke.arc.util.pooling.Pools; import io.anuke.mindustry.content.StatusEffects; import io.anuke.mindustry.entities.traits.Saveable; +import io.anuke.mindustry.entities.type.Unit; import io.anuke.mindustry.type.ContentType; import io.anuke.mindustry.type.StatusEffect; @@ -16,7 +17,7 @@ import java.io.IOException; import static io.anuke.mindustry.Vars.content; /** Class for controlling status effects on an entity.*/ -public class StatusController implements Saveable{ +public class Statuses implements Saveable{ private static final StatusEntry globalResult = new StatusEntry(); private static final Array removals = new Array<>(); @@ -26,8 +27,8 @@ public class StatusController implements Saveable{ private float damageMultiplier; private float armorMultiplier; - public void handleApply(Unit unit, StatusEffect effect, float duration){ - if(effect == StatusEffects.none) return; //don't apply empty effects + public void handleApply(io.anuke.mindustry.entities.type.Unit unit, StatusEffect effect, float duration){ + if(effect == StatusEffects.none || unit.isImmune(effect)) return; //don't apply empty or immune effects if(statuses.size > 0){ //check for opposite effects diff --git a/core/src/io/anuke/mindustry/entities/units/UnitDrops.java b/core/src/io/anuke/mindustry/entities/units/UnitDrops.java index e06104cdd2..84c47a4457 100644 --- a/core/src/io/anuke/mindustry/entities/units/UnitDrops.java +++ b/core/src/io/anuke/mindustry/entities/units/UnitDrops.java @@ -2,7 +2,8 @@ package io.anuke.mindustry.entities.units; import io.anuke.mindustry.Vars; import io.anuke.mindustry.content.Items; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.BaseUnit; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.type.Item; import io.anuke.arc.math.Mathf; diff --git a/core/src/io/anuke/mindustry/entities/units/types/Crawler.java b/core/src/io/anuke/mindustry/entities/units/types/Crawler.java deleted file mode 100644 index 73ad2171cd..0000000000 --- a/core/src/io/anuke/mindustry/entities/units/types/Crawler.java +++ /dev/null @@ -1,6 +0,0 @@ -package io.anuke.mindustry.entities.units.types; - -import io.anuke.mindustry.entities.units.GroundUnit; - -public class Crawler extends GroundUnit{ -} diff --git a/core/src/io/anuke/mindustry/entities/units/types/Dagger.java b/core/src/io/anuke/mindustry/entities/units/types/Dagger.java deleted file mode 100644 index aab1b4161b..0000000000 --- a/core/src/io/anuke/mindustry/entities/units/types/Dagger.java +++ /dev/null @@ -1,7 +0,0 @@ -package io.anuke.mindustry.entities.units.types; - -import io.anuke.mindustry.entities.units.GroundUnit; - -public class Dagger extends GroundUnit{ - -} diff --git a/core/src/io/anuke/mindustry/entities/units/types/Ghoul.java b/core/src/io/anuke/mindustry/entities/units/types/Ghoul.java deleted file mode 100644 index bc026434ab..0000000000 --- a/core/src/io/anuke/mindustry/entities/units/types/Ghoul.java +++ /dev/null @@ -1,7 +0,0 @@ -package io.anuke.mindustry.entities.units.types; - -import io.anuke.mindustry.entities.units.FlyingUnit; - -public class Ghoul extends FlyingUnit{ - -} diff --git a/core/src/io/anuke/mindustry/entities/units/types/Phantom.java b/core/src/io/anuke/mindustry/entities/units/types/Phantom.java deleted file mode 100644 index 622a5f245c..0000000000 --- a/core/src/io/anuke/mindustry/entities/units/types/Phantom.java +++ /dev/null @@ -1,5 +0,0 @@ -package io.anuke.mindustry.entities.units.types; - -public class Phantom extends Drone{ - -} diff --git a/core/src/io/anuke/mindustry/entities/units/types/Revenant.java b/core/src/io/anuke/mindustry/entities/units/types/Revenant.java deleted file mode 100644 index b2de68bdce..0000000000 --- a/core/src/io/anuke/mindustry/entities/units/types/Revenant.java +++ /dev/null @@ -1,7 +0,0 @@ -package io.anuke.mindustry.entities.units.types; - -import io.anuke.mindustry.entities.units.FlyingUnit; - -public class Revenant extends FlyingUnit{ - -} diff --git a/core/src/io/anuke/mindustry/entities/units/types/Spirit.java b/core/src/io/anuke/mindustry/entities/units/types/Spirit.java deleted file mode 100644 index 1c535dc3ab..0000000000 --- a/core/src/io/anuke/mindustry/entities/units/types/Spirit.java +++ /dev/null @@ -1,4 +0,0 @@ -package io.anuke.mindustry.entities.units.types; - -public class Spirit extends Drone{ -} diff --git a/core/src/io/anuke/mindustry/entities/units/types/Titan.java b/core/src/io/anuke/mindustry/entities/units/types/Titan.java deleted file mode 100644 index e2c6a845bc..0000000000 --- a/core/src/io/anuke/mindustry/entities/units/types/Titan.java +++ /dev/null @@ -1,7 +0,0 @@ -package io.anuke.mindustry.entities.units.types; - -import io.anuke.mindustry.entities.units.GroundUnit; - -public class Titan extends GroundUnit{ - -} diff --git a/core/src/io/anuke/mindustry/entities/units/types/Wraith.java b/core/src/io/anuke/mindustry/entities/units/types/Wraith.java deleted file mode 100644 index 5033690101..0000000000 --- a/core/src/io/anuke/mindustry/entities/units/types/Wraith.java +++ /dev/null @@ -1,7 +0,0 @@ -package io.anuke.mindustry.entities.units.types; - -import io.anuke.mindustry.entities.units.FlyingUnit; - -public class Wraith extends FlyingUnit{ - -} diff --git a/core/src/io/anuke/mindustry/game/EventType.java b/core/src/io/anuke/mindustry/game/EventType.java index ef730a377a..91b2d05ff7 100644 --- a/core/src/io/anuke/mindustry/game/EventType.java +++ b/core/src/io/anuke/mindustry/game/EventType.java @@ -2,7 +2,7 @@ package io.anuke.mindustry.game; import io.anuke.arc.Events.Event; import io.anuke.mindustry.core.GameState.State; -import io.anuke.mindustry.entities.Unit; +import io.anuke.mindustry.entities.type.Unit; import io.anuke.mindustry.entities.traits.BuilderTrait; import io.anuke.mindustry.world.Tile; diff --git a/core/src/io/anuke/mindustry/game/GlobalData.java b/core/src/io/anuke/mindustry/game/GlobalData.java index d12c5d1889..d8cb461884 100644 --- a/core/src/io/anuke/mindustry/game/GlobalData.java +++ b/core/src/io/anuke/mindustry/game/GlobalData.java @@ -7,7 +7,6 @@ import io.anuke.arc.collection.ObjectMap; import io.anuke.arc.collection.ObjectSet; import io.anuke.mindustry.Vars; import io.anuke.mindustry.content.Items; -import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.game.EventType.UnlockEvent; import io.anuke.mindustry.type.ContentType; import io.anuke.mindustry.type.Item; @@ -79,7 +78,7 @@ public class GlobalData{ /** Returns whether or not this piece of content is unlocked yet.*/ public boolean isUnlocked(UnlockableContent content){ - return (!state.is(State.menu) && !world.isZone()) || content.alwaysUnlocked() || unlocked.getOr(content.getContentType(), ObjectSet::new).contains(content.getContentName()); + return content.alwaysUnlocked() || unlocked.getOr(content.getContentType(), ObjectSet::new).contains(content.getContentName()); } /** @@ -119,8 +118,8 @@ public class GlobalData{ } //set up default values - if(!Core.settings.has("item-" + Items.copper)){ - addItem(Items.copper, 500); + if(!Core.settings.has("item-" + Items.copper.name)){ + addItem(Items.copper, 300); } } diff --git a/core/src/io/anuke/mindustry/game/SpawnGroup.java b/core/src/io/anuke/mindustry/game/SpawnGroup.java index 56347177c3..dbdaaa8a7d 100644 --- a/core/src/io/anuke/mindustry/game/SpawnGroup.java +++ b/core/src/io/anuke/mindustry/game/SpawnGroup.java @@ -1,11 +1,9 @@ package io.anuke.mindustry.game; -import io.anuke.mindustry.entities.units.BaseUnit; -import io.anuke.mindustry.entities.units.GroundUnit; -import io.anuke.mindustry.entities.units.UnitType; +import io.anuke.mindustry.entities.type.BaseUnit; import io.anuke.mindustry.type.ItemStack; import io.anuke.mindustry.type.StatusEffect; -import io.anuke.mindustry.type.Weapon; +import io.anuke.mindustry.type.UnitType; /** * A spawn group defines spawn information for a specific type of unit, with optional extra information like @@ -27,8 +25,6 @@ public class SpawnGroup{ protected float unitScaling = 9999f; /**Amount of enemies spawned initially, with no scaling*/ protected int unitAmount = 1; - /**Weapon used by the spawned unit. Null to disable. Only applicable to ground units.*/ - protected Weapon weapon; /**Status effect applied to the spawned unit. Null to disable.*/ protected StatusEffect effect; /**Items this unit spawns with. Null to disable.*/ @@ -57,16 +53,12 @@ public class SpawnGroup{ public BaseUnit createUnit(Team team){ BaseUnit unit = type.create(team); - if(unit instanceof GroundUnit && weapon != null){ - ((GroundUnit) unit).setWeapon(weapon); - } - if(effect != null){ unit.applyEffect(effect, 999999f); } if(items != null){ - unit.inventory.addItem(items.item, items.amount); + unit.addItem(items.item, items.amount); } return unit; @@ -82,7 +74,6 @@ public class SpawnGroup{ ", max=" + max + ", unitScaling=" + unitScaling + ", unitAmount=" + unitAmount + - ", weapon=" + weapon + ", effect=" + effect + ", items=" + items + '}'; diff --git a/core/src/io/anuke/mindustry/game/UnlockableContent.java b/core/src/io/anuke/mindustry/game/UnlockableContent.java index c2bf0caea7..b5dbb56619 100644 --- a/core/src/io/anuke/mindustry/game/UnlockableContent.java +++ b/core/src/io/anuke/mindustry/game/UnlockableContent.java @@ -2,6 +2,7 @@ package io.anuke.mindustry.game; import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.scene.ui.layout.Table; +import io.anuke.mindustry.Vars; /**Base interface for an unlockable content type.*/ public abstract class UnlockableContent extends MappableContent{ @@ -26,4 +27,12 @@ public abstract class UnlockableContent extends MappableContent{ public boolean alwaysUnlocked(){ return false; } + + public final boolean unlocked(){ + return Vars.data.isUnlocked(this); + } + + public final boolean locked(){ + return !unlocked(); + } } diff --git a/core/src/io/anuke/mindustry/game/Waves.java b/core/src/io/anuke/mindustry/game/Waves.java index 3b6355c2c8..865ae15424 100644 --- a/core/src/io/anuke/mindustry/game/Waves.java +++ b/core/src/io/anuke/mindustry/game/Waves.java @@ -4,7 +4,6 @@ import io.anuke.arc.collection.Array; import io.anuke.mindustry.content.Items; import io.anuke.mindustry.content.StatusEffects; import io.anuke.mindustry.content.UnitTypes; -import io.anuke.mindustry.content.Weapons; import io.anuke.mindustry.type.ItemStack; public class Waves{ @@ -50,7 +49,6 @@ public class Waves{ begin = 28; spacing = 3; unitScaling = 2; - weapon = Weapons.flamethrower; end = 40; }}, @@ -58,7 +56,6 @@ public class Waves{ begin = 45; spacing = 3; unitScaling = 2; - weapon = Weapons.flamethrower; effect = StatusEffects.overdrive; }}, @@ -67,7 +64,6 @@ public class Waves{ spacing = 2; unitScaling = 3; unitAmount = 5; - weapon = Weapons.flakgun; effect = StatusEffects.overdrive; }}, @@ -181,10 +177,6 @@ public class Waves{ if(a > 0){ System.out.print(a + "x" + spawn.type.name); - if(spawn.weapon != null){ - System.out.print(":" + spawn.weapon.name); - } - System.out.print(" "); } } diff --git a/core/src/io/anuke/mindustry/graphics/BlockRenderer.java b/core/src/io/anuke/mindustry/graphics/BlockRenderer.java index 8da7a2280b..35b0d9952e 100644 --- a/core/src/io/anuke/mindustry/graphics/BlockRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/BlockRenderer.java @@ -4,14 +4,16 @@ import io.anuke.arc.Core; import io.anuke.arc.Events; import io.anuke.arc.collection.Array; import io.anuke.arc.collection.Sort; -import io.anuke.arc.entities.EntityDraw; -import io.anuke.arc.entities.EntityGroup; +import io.anuke.mindustry.entities.EntityDraw; +import io.anuke.mindustry.entities.EntityGroup; import io.anuke.arc.graphics.Color; +import io.anuke.arc.graphics.Texture.TextureFilter; import io.anuke.arc.graphics.g2d.Draw; +import io.anuke.arc.graphics.g2d.Fill; import io.anuke.arc.graphics.glutils.FrameBuffer; import io.anuke.arc.util.Tmp; import io.anuke.mindustry.content.Blocks; -import io.anuke.mindustry.entities.Unit; +import io.anuke.mindustry.entities.type.Unit; import io.anuke.mindustry.game.EventType.TileChangeEvent; import io.anuke.mindustry.game.EventType.WorldLoadEvent; import io.anuke.mindustry.game.Team; @@ -34,6 +36,7 @@ public class BlockRenderer{ private int requestidx = 0; private int iterateidx = 0; private FrameBuffer shadows = new FrameBuffer(2, 2); + private FrameBuffer fog = new FrameBuffer(2, 2); public BlockRenderer(){ @@ -43,6 +46,28 @@ public class BlockRenderer{ Events.on(WorldLoadEvent.class, event -> { lastCamY = lastCamX = -99; //invalidate camera position so blocks get updated + + fog.getTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear); + fog.resize(world.width(), world.height()); + fog.begin(); + Core.graphics.clear(Color.WHITE); + Draw.proj().setOrtho(0, 0, fog.getWidth(), fog.getHeight()); + + //TODO highly inefficient, width*height rectangles isn't great + //TODO handle shadow rotation generation with GPU blur/erode algorithm + for(int x = 0; x < world.width(); x++){ + for(int y = 0; y < world.height(); y++){ + Tile tile = world.rawTile(x, y); + if(tile.getRotation() > 0 && tile.block().solid && tile.block().fillsTile && !tile.block().synthetic()){ + Draw.color(0f, 0f, 0f, Math.min((tile.getRotation() + 0.5f)/4f, 1f)); + Fill.rect(tile.x + 0.5f, tile.y + 0.5f, 1, 1); + } + } + } + + Draw.flush(); + Draw.color(); + fog.end(); }); Events.on(TileChangeEvent.class, event -> { @@ -57,25 +82,44 @@ public class BlockRenderer{ }); } + public void drawFog(){ + float ww = world.width() * tilesize, wh = world.height() * tilesize; + float x = camera.position.x + tilesize/2f, y = camera.position.y + tilesize/2f; + float u = (x - camera.width/2f) / ww, + v = (y - camera.height/2f) / wh, + u2 = (x + camera.width/2f) / ww, + v2 = (y + camera.height/2f) / wh; + + Tmp.tr1.set(fog.getTexture()); + Tmp.tr1.set(u, v2, u2, v); + + Draw.shader(Shaders.fog); + Draw.rect(Tmp.tr1, camera.position.x, camera.position.y, camera.width, camera.height); + Draw.shader(); + } + public void drawShadows(){ if(disableShadows) return; + Draw.color(); + if(!Core.graphics.isHidden() && (shadows.getWidth() != Core.graphics.getWidth() || shadows.getHeight() != Core.graphics.getHeight())){ shadows.resize(Core.graphics.getWidth(), Core.graphics.getHeight()); } Tmp.tr1.set(shadows.getTexture()); - Shaders.outline.color.set(shadowColor); - Shaders.outline.scl = renderer.cameraScale()/3f; - Shaders.outline.region = Tmp.tr1; + Shaders.shadow.color.set(shadowColor); + Shaders.shadow.scl = renderer.cameraScale()/3f; + Shaders.shadow.region = Tmp.tr1; Draw.flush(); shadows.begin(); Core.graphics.clear(Color.CLEAR); - Draw.color(shadowColor); + floor.beginDraw(); floor.drawLayer(CacheLayer.walls); floor.endDraw(); + drawBlocks(Layer.shadow); EntityDraw.drawWith(playerGroup, player -> !player.isDead(), Unit::draw); @@ -87,7 +131,7 @@ public class BlockRenderer{ Draw.flush(); shadows.end(); - Draw.shader(Shaders.outline); + Draw.shader(Shaders.shadow); Draw.rect(Draw.wrap(shadows.getTexture()), camera.position.x, camera.position.y, @@ -122,17 +166,14 @@ public class BlockRenderer{ Tile tile = world.rawTile(x, y); Block block = tile.block(); - if(!expanded && block != Blocks.air && block.cacheLayer == CacheLayer.normal && world.isAccessible(x, y)){ - tile.block().drawShadow(tile); - } - if(block != Blocks.air && block.cacheLayer == CacheLayer.normal){ if(!expanded){ - addRequest(tile, Layer.shadow); addRequest(tile, Layer.block); } if(block.expanded || !expanded){ + addRequest(tile, Layer.shadow); + if(block.layer != null && block.isLayer(tile)){ addRequest(tile, block.layer); } @@ -151,10 +192,6 @@ public class BlockRenderer{ lastCamY = avgy; lastRangeX = rangex; lastRangeY = rangey; - - floor.beginDraw(); - floor.drawLayer(CacheLayer.walls); - floor.endDraw(); } public void drawBlocks(Layer stopAt){ @@ -173,9 +210,7 @@ public class BlockRenderer{ }else if(req.layer == Layer.block){ block.draw(req.tile); if(block.synthetic() && req.tile.getTeam() != players[0].getTeam()){ - Draw.color(req.tile.getTeam().color); - Draw.rect("block-border", req.tile.drawx() - block.size * tilesize/2f + 4, req.tile.drawy() - block.size * tilesize/2f + 4); - Draw.color(); + block.drawTeam(req.tile); } }else if(req.layer == block.layer){ block.drawLayer(req.tile); diff --git a/core/src/io/anuke/mindustry/graphics/CacheLayer.java b/core/src/io/anuke/mindustry/graphics/CacheLayer.java index dca1a53df7..ea4f31a20a 100644 --- a/core/src/io/anuke/mindustry/graphics/CacheLayer.java +++ b/core/src/io/anuke/mindustry/graphics/CacheLayer.java @@ -3,6 +3,13 @@ package io.anuke.mindustry.graphics; //TODO implement effects again public enum CacheLayer{ water{ + public void begin(){ + //Draw.shader(Shaders.water); + } + + public void end(){ + //Draw.shader(); + } }, lava{ }, @@ -11,8 +18,7 @@ public enum CacheLayer{ space{ }, normal, - walls{ //TODO implement walls - }; + walls; public void begin(){ diff --git a/core/src/io/anuke/mindustry/graphics/FloorRenderer.java b/core/src/io/anuke/mindustry/graphics/FloorRenderer.java index 263a4d7d2c..cac217ce05 100644 --- a/core/src/io/anuke/mindustry/graphics/FloorRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/FloorRenderer.java @@ -124,6 +124,8 @@ public class FloorRenderer{ int crangex = (int) (camera.width / (chunksize * tilesize)) + 1; int crangey = (int) (camera.height / (chunksize * tilesize)) + 1; + SpriteBatch batch = Core.batch; + Core.batch = cbatch; layer.begin(); for(int x = -crangex; x <= crangex; x++){ @@ -142,6 +144,7 @@ public class FloorRenderer{ } layer.end(); + Core.batch = batch; } private void cacheChunk(int cx, int cy){ @@ -186,7 +189,7 @@ public class FloorRenderer{ if(tile.block().cacheLayer == layer && layer == CacheLayer.walls){ tile.block().draw(tile); - }else if(floor.cacheLayer == layer && (tile.block().cacheLayer != CacheLayer.walls || !tile.block().fillsTile)){ + }else if(floor.cacheLayer == layer && (world.isAccessible(tile.x,tile.y) || tile.block().cacheLayer != CacheLayer.walls || !tile.block().fillsTile)){ floor.draw(tile); } } @@ -201,7 +204,7 @@ public class FloorRenderer{ int chunksx = Mathf.ceil((float) (world.width()) / chunksize), chunksy = Mathf.ceil((float) (world.height()) / chunksize) ; cache = new Chunk[chunksx][chunksy]; - SpriteCache sprites = new SpriteCache(world.width() * world.height() * 2, (world.width() / chunksize) * (world.height() / chunksize) * 2, false); + SpriteCache sprites = new SpriteCache(world.width() * world.height() * 5, (world.width() / chunksize) * (world.height() / chunksize) * 2, false); cbatch = new CacheBatch(sprites); Time.mark(); diff --git a/core/src/io/anuke/mindustry/graphics/MinimapRenderer.java b/core/src/io/anuke/mindustry/graphics/MinimapRenderer.java index 0f133e6b90..5c938d2b8c 100644 --- a/core/src/io/anuke/mindustry/graphics/MinimapRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/MinimapRenderer.java @@ -14,11 +14,11 @@ import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.math.Mathf; import io.anuke.arc.math.geom.Rectangle; import io.anuke.arc.util.Disposable; -import io.anuke.mindustry.entities.Unit; +import io.anuke.mindustry.entities.type.Unit; import io.anuke.mindustry.entities.Units; import io.anuke.mindustry.game.EventType.TileChangeEvent; import io.anuke.mindustry.game.EventType.WorldLoadEvent; -import io.anuke.mindustry.world.ColorMapper; +import io.anuke.mindustry.io.MapIO; import io.anuke.mindustry.world.Tile; import static io.anuke.mindustry.Vars.tilesize; @@ -137,7 +137,7 @@ public class MinimapRenderer implements Disposable{ private int colorFor(Tile tile){ tile = tile.target(); - return ColorMapper.colorFor(tile.floor(), tile.block(), tile.getTeam()); + return MapIO.colorFor(tile.floor(), tile.block(), tile.getTeam()); } @Override diff --git a/core/src/io/anuke/mindustry/graphics/OverlayRenderer.java b/core/src/io/anuke/mindustry/graphics/OverlayRenderer.java index 6211e4ee35..6906357e1b 100644 --- a/core/src/io/anuke/mindustry/graphics/OverlayRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/OverlayRenderer.java @@ -10,7 +10,7 @@ import io.anuke.arc.math.geom.Vector2; import io.anuke.arc.util.Time; import io.anuke.arc.util.Tmp; import io.anuke.mindustry.content.Blocks; -import io.anuke.mindustry.entities.Player; +import io.anuke.mindustry.entities.type.Player; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.input.InputHandler; import io.anuke.mindustry.world.Tile; @@ -28,7 +28,7 @@ public class OverlayRenderer{ if(!input.isDrawing() || player.isDead()) continue; - Shaders.outline.color.set(Palette.accent); + Shaders.outline.color.set(Pal.accent); //TODO draw outlined version //Graphics.beginShaders(Shaders.outline); @@ -79,7 +79,7 @@ public class OverlayRenderer{ if(dst < state.rules.enemyCoreBuildRadius * 1.5f){ Draw.color(Color.DARK_GRAY); Lines.poly(core.drawx(), core.drawy() - 2, 200, state.rules.enemyCoreBuildRadius); - Draw.color(Palette.accent, enemy.color, 0.5f + Mathf.absin(Time.time(), 10f, 0.5f)); + Draw.color(Pal.accent, enemy.color, 0.5f + Mathf.absin(Time.time(), 10f, 0.5f)); Lines.poly(core.drawx(), core.drawy(), 200, state.rules.enemyCoreBuildRadius); } } @@ -102,15 +102,15 @@ public class OverlayRenderer{ if(input.isDroppingItem()){ Vector2 v = Core.input.mouseWorld(input.getMouseX(), input.getMouseY()); float size = 8; - Draw.rect(player.inventory.getItem().item.region, v.x, v.y, size, size); - Draw.color(Palette.accent); + Draw.rect(player.item().item.region, v.x, v.y, size, size); + Draw.color(Pal.accent); Lines.circle(v.x, v.y, 6 + Mathf.absin(Time.time(), 5f, 1f)); Draw.reset(); Tile tile = world.tileWorld(v.x, v.y); if(tile != null) tile = tile.target(); - if(tile != null && tile.getTeam() == player.getTeam() && tile.block().acceptStack(player.inventory.getItem().item, player.inventory.getItem().amount, tile, player) > 0){ - Draw.color(Palette.place); + if(tile != null && tile.getTeam() == player.getTeam() && tile.block().acceptStack(player.item().item, player.item().amount, tile, player) > 0){ + Draw.color(Pal.place); Lines.square(tile.drawx(), tile.drawy(), tile.block().size * tilesize / 2f + 1 + Mathf.absin(Time.time(), 5f, 1f)); Draw.color(); } diff --git a/core/src/io/anuke/mindustry/graphics/Palette.java b/core/src/io/anuke/mindustry/graphics/Pal.java similarity index 91% rename from core/src/io/anuke/mindustry/graphics/Palette.java rename to core/src/io/anuke/mindustry/graphics/Pal.java index 4483f9c281..cad77809cb 100644 --- a/core/src/io/anuke/mindustry/graphics/Palette.java +++ b/core/src/io/anuke/mindustry/graphics/Pal.java @@ -2,7 +2,7 @@ package io.anuke.mindustry.graphics; import io.anuke.arc.graphics.Color; -public class Palette{ +public class Pal{ public static final Color command = Color.valueOf("eab678"), @@ -30,6 +30,7 @@ public class Palette{ lightishGray = Color.valueOf("a2a2a2"), darkishGray = new Color(0.3f, 0.3f, 0.3f, 1f), darkerGray = new Color(0.2f, 0.2f, 0.2f, 1f), + ammo = Color.valueOf("ff8947"), boostTo = Color.valueOf("ffad4d"), boostFrom = Color.valueOf("ff7f57"), @@ -37,6 +38,7 @@ public class Palette{ lancerLaser = Color.valueOf("a9d8ff"), stoneGray = Color.valueOf("8f8f8f"), + engine = Color.valueOf("ffbb64"), health = Color.valueOf("ff341c"), heal = Color.valueOf("98ffa9"), @@ -54,6 +56,9 @@ public class Palette{ powerLight = Color.valueOf("fbd367"), placing = accent, + unitFront = Color.valueOf("ffa665"), + unitBack = Color.valueOf("d06b53"), + lightTrail = Color.valueOf("ffe2a9"), surge = Color.valueOf("f3e979"), diff --git a/core/src/io/anuke/mindustry/graphics/Shaders.java b/core/src/io/anuke/mindustry/graphics/Shaders.java index 2853013ecc..2d8219127d 100644 --- a/core/src/io/anuke/mindustry/graphics/Shaders.java +++ b/core/src/io/anuke/mindustry/graphics/Shaders.java @@ -7,18 +7,12 @@ import io.anuke.arc.graphics.glutils.Shader; import io.anuke.arc.scene.ui.layout.Unit; import io.anuke.arc.util.Time; -import static io.anuke.mindustry.Vars.tilesize; -import static io.anuke.mindustry.Vars.world; - public class Shaders{ public static Outline outline; + public static Shadow shadow; public static BlockBuild blockbuild; public static BlockPreview blockpreview; public static Shield shield; - public static SurfaceShader water; - public static SurfaceShader lava; - public static SurfaceShader oil; - public static Space space; public static UnitBuild build; public static MixShader mix; public static Shader fullMix; @@ -27,13 +21,10 @@ public class Shaders{ public static void init(){ outline = new Outline(); + shadow = new Shadow(); blockbuild = new BlockBuild(); blockpreview = new BlockPreview(); shield = new Shield(); - water = new SurfaceShader("water"); - lava = new SurfaceShader("lava"); - oil = new SurfaceShader("oil"); - space = new Space(); build = new UnitBuild(); mix = new MixShader(); fog = new FogShader(); @@ -80,19 +71,6 @@ public class Shaders{ } } - public static class Space extends SurfaceShader{ - - public Space(){ - super("space2"); - } - - @Override - public void apply(){ - super.apply(); - setUniformf("u_center", world.width() * tilesize / 2f, world.height() * tilesize / 2f); - } - } - public static class UnitBuild extends LoadShader{ public float progress, time; public Color color = new Color(); @@ -130,6 +108,23 @@ public class Shaders{ } } + public static class Shadow extends LoadShader{ + public Color color = new Color(); + public TextureRegion region = new TextureRegion(); + public float scl; + + public Shadow(){ + super("shadow", "default"); + } + + @Override + public void apply(){ + setUniformf("u_color", color); + setUniformf("u_scl", scl); + setUniformf("u_texsize", region.getTexture().getWidth(), region.getTexture().getHeight()); + } + } + public static class BlockBuild extends LoadShader{ public Color color = new Color(); public float progress; @@ -184,23 +179,6 @@ public class Shaders{ Core.camera.height ); } } - - public static class SurfaceShader extends LoadShader{ - - public SurfaceShader(String frag){ - super(frag, "default"); - } - - @Override - public void apply(){ - setUniformf("camerapos", - Core.camera.position.x - Core.camera.width / 2 , - Core.camera.position.y - Core.camera.height / 2 ); - setUniformf("screensize", Core.camera.width, - Core.camera.height ); - setUniformf("time", Time.time()); - } - } public static class LoadShader extends Shader{ public LoadShader(String frag, String vert){ diff --git a/core/src/io/anuke/mindustry/input/Binding.java b/core/src/io/anuke/mindustry/input/Binding.java index 40396ad9b1..78049ad0c9 100644 --- a/core/src/io/anuke/mindustry/input/Binding.java +++ b/core/src/io/anuke/mindustry/input/Binding.java @@ -15,10 +15,11 @@ public enum Binding implements KeyBind{ deselect(KeyCode.MOUSE_RIGHT), break_block(KeyCode.MOUSE_RIGHT), rotate(new Axis(KeyCode.SCROLL)), + pick(KeyCode.MOUSE_MIDDLE), dash(KeyCode.SHIFT_LEFT), drop_unit(KeyCode.SHIFT_LEFT), gridMode(KeyCode.SPACE), - gridModeShift(KeyCode.SHIFT_LEFT), + gridModeShift(KeyCode.ALT_LEFT), zoom_hold(KeyCode.CONTROL_LEFT, "view"), zoom(new Axis(KeyCode.SCROLL)), zoom_minimap(new Axis(KeyCode.MINUS, KeyCode.PLUS)), @@ -30,7 +31,8 @@ public enum Binding implements KeyBind{ chat(KeyCode.ENTER), chat_history_prev(KeyCode.UP), chat_history_next(KeyCode.DOWN), - chat_scroll(new Axis(KeyCode.SCROLL)) + chat_scroll(new Axis(KeyCode.SCROLL)), + ; private final KeybindValue defaultValue; diff --git a/core/src/io/anuke/mindustry/input/DesktopInput.java b/core/src/io/anuke/mindustry/input/DesktopInput.java index 02c212da5c..c0e0d3b1eb 100644 --- a/core/src/io/anuke/mindustry/input/DesktopInput.java +++ b/core/src/io/anuke/mindustry/input/DesktopInput.java @@ -9,8 +9,8 @@ import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.math.Mathf; import io.anuke.mindustry.content.Blocks; import io.anuke.mindustry.core.GameState.State; -import io.anuke.mindustry.entities.Player; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.entities.type.Player; +import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.input.PlaceUtils.NormalizeDrawResult; import io.anuke.mindustry.input.PlaceUtils.NormalizeResult; import io.anuke.mindustry.net.Net; @@ -51,9 +51,9 @@ public class DesktopInput extends InputHandler{ region.getWidth() * selectScale * Draw.scl, region.getHeight() * selectScale * Draw.scl, block.rotate ? rotation * 90 : 0); }else{ - Draw.color(Palette.removeBack); + Draw.color(Pal.removeBack); Lines.square(x * tilesize + block.offset(), y * tilesize + block.offset() - 1, block.size * tilesize / 2f); - Draw.color(Palette.remove); + Draw.color(Pal.remove); Lines.square(x * tilesize + block.offset(), y * tilesize + block.offset(), block.size * tilesize / 2f); } } @@ -78,14 +78,14 @@ public class DesktopInput extends InputHandler{ int y = selectY + i * Mathf.sign(cursorY - selectY) * Mathf.num(!result.isX()); if(i + block.size > result.getLength() && block.rotate){ - Draw.color(!validPlace(x, y, block, result.rotation) ? Palette.removeBack : Palette.accentBack); + Draw.color(!validPlace(x, y, block, result.rotation) ? Pal.removeBack : Pal.accentBack); Draw.rect(Core.atlas.find("place-arrow"), x * tilesize + block.offset(), y * tilesize + block.offset() - 1, Core.atlas.find("place-arrow").getWidth() * Draw.scl, Core.atlas.find("place-arrow").getHeight() * Draw.scl, result.rotation * 90 - 90); - Draw.color(!validPlace(x, y, block, result.rotation) ? Palette.remove : Palette.accent); + Draw.color(!validPlace(x, y, block, result.rotation) ? Pal.remove : Pal.accent); Draw.rect(Core.atlas.find("place-arrow"), x * tilesize + block.offset(), y * tilesize + block.offset(), @@ -107,27 +107,27 @@ public class DesktopInput extends InputHandler{ if(tile == null || !validBreak(tile.x, tile.y)) continue; tile = tile.target(); - Draw.color(Palette.removeBack); + Draw.color(Pal.removeBack); Lines.square(tile.drawx(), tile.drawy()-1, tile.block().size * tilesize / 2f - 1); - Draw.color(Palette.remove); + Draw.color(Pal.remove); Lines.square(tile.drawx(), tile.drawy(), tile.block().size * tilesize / 2f - 1); } } - Draw.color(Palette.removeBack); + Draw.color(Pal.removeBack); Lines.rect(result.x, result.y - 1, result.x2 - result.x, result.y2 - result.y); - Draw.color(Palette.remove); + Draw.color(Pal.remove); Lines.rect(result.x, result.y, result.x2 - result.x, result.y2 - result.y); }else if(isPlacing()){ if(block.rotate){ - Draw.color(!validPlace(cursorX, cursorY, block, rotation) ? Palette.removeBack : Palette.accentBack); + Draw.color(!validPlace(cursorX, cursorY, block, rotation) ? Pal.removeBack : Pal.accentBack); Draw.rect(Core.atlas.find("place-arrow"), cursorX * tilesize + block.offset(), cursorY * tilesize + block.offset() - 1, Core.atlas.find("place-arrow").getWidth() * Draw.scl, Core.atlas.find("place-arrow").getHeight() * Draw.scl, rotation * 90 - 90); - Draw.color(!validPlace(cursorX, cursorY, block, rotation) ? Palette.remove : Palette.accent); + Draw.color(!validPlace(cursorX, cursorY, block, rotation) ? Pal.remove : Pal.accent); Draw.rect(Core.atlas.find("place-arrow"), cursorX * tilesize + block.offset(), cursorY * tilesize + block.offset(), diff --git a/core/src/io/anuke/mindustry/input/InputHandler.java b/core/src/io/anuke/mindustry/input/InputHandler.java index 11a1fa8a56..c9551a5a5d 100644 --- a/core/src/io/anuke/mindustry/input/InputHandler.java +++ b/core/src/io/anuke/mindustry/input/InputHandler.java @@ -3,7 +3,7 @@ package io.anuke.mindustry.input; import io.anuke.annotations.Annotations.Loc; import io.anuke.annotations.Annotations.Remote; import io.anuke.arc.Core; -import io.anuke.arc.entities.Effects; +import io.anuke.mindustry.entities.Effects; import io.anuke.arc.graphics.Color; import io.anuke.arc.input.InputProcessor; import io.anuke.arc.math.Angles; @@ -13,9 +13,10 @@ import io.anuke.arc.scene.ui.layout.Table; import io.anuke.arc.util.Time; import io.anuke.mindustry.content.Blocks; import io.anuke.mindustry.content.Fx; -import io.anuke.mindustry.entities.Player; +import io.anuke.mindustry.entities.type.Player; import io.anuke.mindustry.entities.effect.ItemTransfer; import io.anuke.mindustry.entities.traits.BuilderTrait.BuildRequest; +import io.anuke.mindustry.game.Team; import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.ValidateException; @@ -52,17 +53,17 @@ public abstract class InputHandler implements InputProcessor{ @Remote(targets = Loc.client, called = Loc.server) public static void dropItem(Player player, float angle){ - if(Net.server() && !player.inventory.hasItem()){ + if(Net.server() && player.item().amount <= 0){ throw new ValidateException(player, "Player cannot drop an item."); } - Effects.effect(Fx.dropItem, Color.WHITE, player.x, player.y, angle, player.inventory.getItem().item); - player.inventory.clearItem(); + Effects.effect(Fx.dropItem, Color.WHITE, player.x, player.y, angle, player.item().item); + player.clearItem(); } @Remote(targets = Loc.both, forward = true, called = Loc.server) public static void transferInventory(Player player, Tile tile){ - if(Net.server() && (!player.inventory.hasItem() || player.isTransferring)){ + if(Net.server() && (player.item().amount <= 0 || player.isTransferring)){ throw new ValidateException(player, "Player cannot transfer an item."); } @@ -70,10 +71,10 @@ public abstract class InputHandler implements InputProcessor{ player.isTransferring = true; - Item item = player.inventory.getItem().item; - int amount = player.inventory.getItem().amount; + Item item = player.item().item; + int amount = player.item().amount; int accepted = tile.block().acceptStack(item, amount, tile, player); - player.inventory.getItem().amount -= accepted; + player.item().amount -= accepted; int sent = Mathf.clamp(accepted / 4, 1, 8); int removed = accepted / sent; @@ -184,7 +185,7 @@ public abstract class InputHandler implements InputProcessor{ //consume tap event if necessary if(tile.getTeam() == player.getTeam() && tile.block().consumesTap){ consumed = true; - }else if(tile.getTeam() == player.getTeam() && tile.block().synthetic() && !consumed){ + }else if((tile.getTeam() == player.getTeam() || tile.getTeam() == Team.none) && tile.block().synthetic() && !consumed){ if(tile.block().hasItems && tile.entity.items.total() > 0){ frag.inv.showFor(tile); consumed = true; @@ -215,7 +216,7 @@ public abstract class InputHandler implements InputProcessor{ } boolean canTapPlayer(float x, float y){ - return Mathf.dst(x, y, player.x, player.y) <= playerSelectRange && player.inventory.hasItem(); + return Mathf.dst(x, y, player.x, player.y) <= playerSelectRange && player.item().amount > 0; } /**Tries to begin mining a tile, returns true if successful.*/ @@ -232,7 +233,7 @@ public abstract class InputHandler implements InputProcessor{ return !Core.scene.hasMouse() && tile.floor().itemDrop != null && tile.floor().itemDrop.hardness <= player.mech.drillPower && !tile.floor().playerUnmineable - && player.inventory.canAcceptItem(tile.floor().itemDrop) + && player.acceptsItem(tile.floor().itemDrop) && tile.block() == Blocks.air && player.dst(tile.worldx(), tile.worldy()) <= Player.mineDistance; } @@ -287,14 +288,14 @@ public abstract class InputHandler implements InputProcessor{ } public void tryDropItems(Tile tile, float x, float y){ - if(!droppingItem || !player.inventory.hasItem() || canTapPlayer(x, y)){ + if(!droppingItem || player.item().amount <= 0 || canTapPlayer(x, y)){ droppingItem = false; return; } droppingItem = false; - ItemStack stack = player.inventory.getItem(); + ItemStack stack = player.item(); if(tile.block().acceptStack(stack.item, stack.amount, tile, player) > 0 && tile.getTeam() == player.getTeam() && tile.block().hasItems){ Call.transferInventory(player, tile); diff --git a/core/src/io/anuke/mindustry/input/MobileInput.java b/core/src/io/anuke/mindustry/input/MobileInput.java index d2a0963c49..24d3435cd9 100644 --- a/core/src/io/anuke/mindustry/input/MobileInput.java +++ b/core/src/io/anuke/mindustry/input/MobileInput.java @@ -3,7 +3,6 @@ package io.anuke.mindustry.input; import io.anuke.arc.Core; import io.anuke.arc.collection.Array; import io.anuke.arc.collection.ObjectSet; -import io.anuke.arc.entities.Effects; import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.graphics.g2d.Lines; @@ -21,12 +20,13 @@ import io.anuke.arc.util.Time; import io.anuke.mindustry.content.Blocks; import io.anuke.mindustry.content.Fx; import io.anuke.mindustry.core.GameState.State; -import io.anuke.mindustry.entities.Player; -import io.anuke.mindustry.entities.TileEntity; -import io.anuke.mindustry.entities.Unit; +import io.anuke.mindustry.entities.Effects; import io.anuke.mindustry.entities.Units; import io.anuke.mindustry.entities.traits.TargetTrait; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.entities.type.Player; +import io.anuke.mindustry.entities.type.TileEntity; +import io.anuke.mindustry.entities.type.Unit; +import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.graphics.Shaders; import io.anuke.mindustry.input.PlaceUtils.NormalizeDrawResult; import io.anuke.mindustry.input.PlaceUtils.NormalizeResult; @@ -174,7 +174,7 @@ public class MobileInput extends InputHandler implements GestureListener{ TextureRegion region = request.block.icon(Icon.full); Draw.alpha(Mathf.clamp((1f - request.scale) / 0.5f)); - Draw.tint(Color.WHITE, Palette.breakInvalid, request.redness); + Draw.tint(Color.WHITE, Pal.breakInvalid, request.redness); Draw.rect(region, tile.worldx() + offset, tile.worldy() + offset, region.getWidth() * request.scale * Draw.scl, @@ -184,9 +184,9 @@ public class MobileInput extends InputHandler implements GestureListener{ float rad = (tile.block().size * tilesize / 2f - 1) * request.scale; Draw.alpha(0f); //draw removing request - Draw.tint(Palette.removeBack); + Draw.tint(Pal.removeBack); Lines.square(tile.drawx(), tile.drawy()-1, rad); - Draw.tint(Palette.remove); + Draw.tint(Pal.remove); Lines.square(tile.drawx(), tile.drawy(), rad); } } @@ -213,7 +213,7 @@ public class MobileInput extends InputHandler implements GestureListener{ @Override public void buildUI(Table table){ - table.addImage("blank").color(Palette.accent).height(3f).colspan(4).growX(); + table.addImage("blank").color(Pal.accent).height(3f).colspan(4).growX(); table.row(); table.left().margin(0f).defaults().size(48f); @@ -277,7 +277,7 @@ public class MobileInput extends InputHandler implements GestureListener{ public void drawOutlined(){ Lines.stroke(1f); - Shaders.mix.color.set(Palette.accent); + Shaders.mix.color.set(Pal.accent); Draw.shader(Shaders.mix); //draw removals @@ -318,7 +318,7 @@ public class MobileInput extends InputHandler implements GestureListener{ Draw.shader(); - Draw.color(Palette.accent); + Draw.color(Pal.accent); //Draw lines if(lineMode){ @@ -348,9 +348,9 @@ public class MobileInput extends InputHandler implements GestureListener{ region.getHeight() * lineScale * Draw.scl, block.rotate ? result.rotation * 90 : 0); }else{ - Draw.color(Palette.removeBack); + Draw.color(Pal.removeBack); Lines.square(x * tilesize + block.offset(), y * tilesize + block.offset() - 1, block.size * tilesize / 2f); - Draw.color(Palette.remove); + Draw.color(Pal.remove); Lines.square(x * tilesize + block.offset(), y * tilesize + block.offset(), block.size * tilesize / 2f); } } @@ -366,16 +366,16 @@ public class MobileInput extends InputHandler implements GestureListener{ if(other == null || !validBreak(other.x, other.y)) continue; other = other.target(); - Draw.color(Palette.removeBack); + Draw.color(Pal.removeBack); Lines.square(other.drawx(), other.drawy()-1, other.block().size * tilesize / 2f - 1); - Draw.color(Palette.remove); + Draw.color(Pal.remove); Lines.square(other.drawx(), other.drawy(), other.block().size * tilesize / 2f - 1); } } - Draw.color(Palette.removeBack); + Draw.color(Pal.removeBack); Lines.rect(result.x, result.y - 1, result.x2 - result.x, result.y2 - result.y); - Draw.color(Palette.remove); + Draw.color(Pal.remove); Lines.rect(result.x, result.y, result.x2 - result.x, result.y2 - result.y); } @@ -393,7 +393,7 @@ public class MobileInput extends InputHandler implements GestureListener{ crosshairScale = Mathf.lerpDelta(crosshairScale, 1f, 0.2f); - Draw.color(Palette.remove); + Draw.color(Pal.remove); Lines.stroke(1f); float radius = Interpolation.swingIn.apply(crosshairScale); @@ -547,27 +547,8 @@ public class MobileInput extends InputHandler implements GestureListener{ //add to selection queue if it's a valid BREAK position cursor = cursor.target(); selection.add(new PlaceRequest(cursor.worldx(), cursor.worldy())); - }else if(!canTapPlayer(worldx, worldy)){ - boolean consumed = false; - //else, try and carry units - if(player.mech.flying){ - if(player.getCarry() != null){ - consumed = true; - player.dropCarry(); //drop off unit - }else{ - Unit unit = Units.getClosest(player.getTeam(), Core.input.mouseWorld(x, y).x, Core.input.mouseWorld(x, y).y, 4f, u -> !u.isFlying() && u.mass() <= player.mech.carryWeight); - - if(unit != null){ - consumed = true; - player.moveTarget = unit; - Effects.effect(Fx.select, unit.getX(), unit.getY()); - } - } - } - - if(!consumed && !tileTapped(cursor.target())){ - tryBeginMine(cursor); - } + }else if(!canTapPlayer(worldx, worldy) && !tileTapped(cursor.target())){ + tryBeginMine(cursor); } return false; @@ -661,7 +642,6 @@ public class MobileInput extends InputHandler implements GestureListener{ @Override public boolean pan(float x, float y, float deltaX, float deltaY){ - if(!canPan) return false; float scale = Core.camera.width / Core.graphics.getWidth(); deltaX *= scale; deltaY *= scale; @@ -690,23 +670,12 @@ public class MobileInput extends InputHandler implements GestureListener{ public boolean zoom(float initialDistance, float distance){ if(lastDistance == -1) lastDistance = initialDistance; - float amount = (distance > lastDistance ? 0.07f : -0.07f) * Time.delta(); + float amount = (Mathf.sign(distance > lastDistance) * 0.07f) * Time.delta(); renderer.scaleCamera(io.anuke.arc.scene.ui.layout.Unit.dp.scl(amount)); lastDistance = distance; return true; } - @Override - public boolean touchDown(float x, float y, int pointer, KeyCode button){ - canPan = !Core.scene.hasMouse(); - return false; - } - - @Override - public boolean fling(float velocityX, float velocityY, KeyCode button){ - return false; - } - //endregion class PlaceRequest{ diff --git a/core/src/io/anuke/mindustry/io/MapIO.java b/core/src/io/anuke/mindustry/io/MapIO.java index 20c84ba555..2e83e14d31 100644 --- a/core/src/io/anuke/mindustry/io/MapIO.java +++ b/core/src/io/anuke/mindustry/io/MapIO.java @@ -17,7 +17,6 @@ import io.anuke.mindustry.maps.MapTileData.DataPosition; import io.anuke.mindustry.maps.MapTileData.TileDataMarker; import io.anuke.mindustry.type.ContentType; import io.anuke.mindustry.world.Block; -import io.anuke.mindustry.world.ColorMapper; import io.anuke.mindustry.world.LegacyColorMapper; import io.anuke.mindustry.world.LegacyColorMapper.LegacyBlock; @@ -52,7 +51,7 @@ public class MapIO{ data.read(marker); Block floor = content.block(marker.floor); Block wall = content.block(marker.wall); - int color = ColorMapper.colorFor(floor, wall, Team.all[marker.team]); + int color = colorFor(floor, wall, Team.all[marker.team]); pixmap.drawPixel(x, pixmap.getHeight() - 1 - y, color); } } @@ -72,12 +71,7 @@ public class MapIO{ LegacyBlock block = LegacyColorMapper.get(color); data.write(x, y, DataPosition.floor, block.floor.id); - data.write(x, y, DataPosition.elevation, (byte)0); - - //place spawn - if(color == Color.rgba8888(Color.RED)){ - data.write(x, y, DataPosition.wall, Blocks.spawn.id); - } + data.write(x, y, DataPosition.wall, block.wall.id); //place core if(color == Color.rgba8888(Color.GREEN)){ @@ -94,7 +88,7 @@ public class MapIO{ } } - data.write(x, y, DataPosition.wall, Blocks.core.id); + data.write(x, y, DataPosition.wall, Blocks.coreShard.id); data.write(x, y, DataPosition.rotationTeam, Pack.byteByte((byte)0, (byte)Team.blue.ordinal())); } } @@ -196,4 +190,11 @@ public class MapIO{ stream.writeShort(meta.width); stream.writeShort(meta.height); } + + public static int colorFor(Block floor, Block wall, Team team){ + if(wall.synthetic()){ + return team.intColor; + } + return Color.rgba8888(wall.solid ? wall.color : floor.color); + } } diff --git a/core/src/io/anuke/mindustry/io/SaveFileVersion.java b/core/src/io/anuke/mindustry/io/SaveFileVersion.java index b7f3c2784e..eebe565662 100644 --- a/core/src/io/anuke/mindustry/io/SaveFileVersion.java +++ b/core/src/io/anuke/mindustry/io/SaveFileVersion.java @@ -1,9 +1,9 @@ package io.anuke.mindustry.io; import io.anuke.arc.collection.Array; -import io.anuke.arc.entities.Entities; -import io.anuke.arc.entities.EntityGroup; -import io.anuke.arc.entities.trait.Entity; +import io.anuke.mindustry.entities.Entities; +import io.anuke.mindustry.entities.EntityGroup; +import io.anuke.mindustry.entities.traits.Entity; import io.anuke.arc.util.Pack; import io.anuke.mindustry.content.Blocks; import io.anuke.mindustry.entities.traits.SaveTrait; diff --git a/core/src/io/anuke/mindustry/io/TypeIO.java b/core/src/io/anuke/mindustry/io/TypeIO.java index 0d87fb38f3..937440a425 100644 --- a/core/src/io/anuke/mindustry/io/TypeIO.java +++ b/core/src/io/anuke/mindustry/io/TypeIO.java @@ -2,19 +2,17 @@ package io.anuke.mindustry.io; import io.anuke.annotations.Annotations.ReadClass; import io.anuke.annotations.Annotations.WriteClass; -import io.anuke.arc.entities.Effects; -import io.anuke.arc.entities.Effects.Effect; -import io.anuke.arc.entities.Entities; +import io.anuke.mindustry.entities.Effects; +import io.anuke.mindustry.entities.Effects.Effect; +import io.anuke.mindustry.entities.Entities; import io.anuke.arc.graphics.Color; -import io.anuke.mindustry.entities.Player; -import io.anuke.mindustry.entities.Unit; +import io.anuke.mindustry.entities.type.Player; +import io.anuke.mindustry.entities.type.Unit; import io.anuke.mindustry.entities.bullet.Bullet; import io.anuke.mindustry.entities.bullet.BulletType; import io.anuke.mindustry.entities.traits.BuilderTrait.BuildRequest; -import io.anuke.mindustry.entities.traits.CarriableTrait; -import io.anuke.mindustry.entities.traits.CarryTrait; import io.anuke.mindustry.entities.traits.ShooterTrait; -import io.anuke.mindustry.entities.units.BaseUnit; +import io.anuke.mindustry.entities.type.BaseUnit; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.net.Packets.AdminAction; import io.anuke.mindustry.net.Packets.KickReason; @@ -92,46 +90,6 @@ public class TypeIO{ return bulletGroup.getByID(id); } - @WriteClass(CarriableTrait.class) - public static void writeCarriable(ByteBuffer buffer, CarriableTrait unit){ - if(unit == null){ - buffer.put((byte) -1); - return; - } - buffer.put((byte) unit.getGroup().getID()); - buffer.putInt(unit.getID()); - } - - @ReadClass(CarriableTrait.class) - public static CarriableTrait readCarriable(ByteBuffer buffer){ - byte gid = buffer.get(); - if(gid == -1){ - return null; - } - int id = buffer.getInt(); - return (CarriableTrait) Entities.getGroup(gid).getByID(id); - } - - @WriteClass(CarryTrait.class) - public static void writeCarry(ByteBuffer buffer, CarryTrait unit){ - if(unit == null || unit.getGroup() == null){ - buffer.put((byte) -1); - return; - } - buffer.put((byte) unit.getGroup().getID()); - buffer.putInt(unit.getID()); - } - - @ReadClass(CarryTrait.class) - public static CarryTrait readCarry(ByteBuffer buffer){ - byte gid = buffer.get(); - if(gid == -1){ - return null; - } - int id = buffer.getInt(); - return (CarryTrait) Entities.getGroup(gid).getByID(id); - } - @WriteClass(BaseUnit.class) public static void writeBaseUnit(ByteBuffer buffer, BaseUnit unit){ buffer.put((byte) unitGroups[unit.getTeam().ordinal()].getID()); @@ -251,16 +209,6 @@ public class TypeIO{ return new Color(buffer.getInt()); } - @WriteClass(Weapon.class) - public static void writeWeapon(ByteBuffer buffer, Weapon weapon){ - buffer.put(weapon.id); - } - - @ReadClass(Weapon.class) - public static Weapon readWeapon(ByteBuffer buffer){ - return content.getByID(ContentType.weapon, buffer.get()); - } - @WriteClass(Mech.class) public static void writeMech(ByteBuffer buffer, Mech mech){ buffer.put(mech.id); diff --git a/core/src/io/anuke/mindustry/io/versions/Save16.java b/core/src/io/anuke/mindustry/io/versions/Save16.java index 3735f3c17c..35bf6ba75a 100644 --- a/core/src/io/anuke/mindustry/io/versions/Save16.java +++ b/core/src/io/anuke/mindustry/io/versions/Save16.java @@ -43,6 +43,7 @@ public class Save16 extends SaveFileVersion{ state.wave = wave; state.wavetime = wavetime; state.stats = Serialization.readStats(stream); + world.spawner.read(stream); content.setTemporaryMapper(readContentHeader(stream)); @@ -66,6 +67,7 @@ public class Save16 extends SaveFileVersion{ stream.writeFloat(state.wavetime); //wave countdown Serialization.writeStats(stream, state.stats); + world.spawner.write(stream); writeContentHeader(stream); diff --git a/core/src/io/anuke/mindustry/maps/MapMeta.java b/core/src/io/anuke/mindustry/maps/MapMeta.java index 74228aa5b4..36f815b63f 100644 --- a/core/src/io/anuke/mindustry/maps/MapMeta.java +++ b/core/src/io/anuke/mindustry/maps/MapMeta.java @@ -35,10 +35,6 @@ public class MapMeta{ return tags.containsKey(name) && !tags.get(name).trim().isEmpty() ? tags.get(name): Core.bundle.get("unknown"); } - public boolean hasOreGen(){ - return !tags.get("oregen", "0").equals("0"); - } - @Override public String toString(){ return "MapMeta{" + diff --git a/core/src/io/anuke/mindustry/maps/Maps.java b/core/src/io/anuke/mindustry/maps/Maps.java index 51f8b85ec6..2bd7823ad5 100644 --- a/core/src/io/anuke/mindustry/maps/Maps.java +++ b/core/src/io/anuke/mindustry/maps/Maps.java @@ -54,7 +54,7 @@ public class Maps implements Disposable{ /**Returns map by internal name.*/ public Map getByName(String name){ - return maps.get(name.toLowerCase()); + return maps.get(name); } /**Loads a map from the map folder and returns it. Should only be used for zone maps. @@ -136,7 +136,7 @@ public class Maps implements Disposable{ map.texture = new Texture(MapIO.generatePixmap(MapIO.readTileData(ds, meta, true))); } - maps.put(map.name.toLowerCase(), map); + maps.put(map.name, map); allMaps.add(map); } } diff --git a/core/src/io/anuke/mindustry/maps/generators/MapGenerator.java b/core/src/io/anuke/mindustry/maps/generators/MapGenerator.java index fba9d0b628..52b3f97ba0 100644 --- a/core/src/io/anuke/mindustry/maps/generators/MapGenerator.java +++ b/core/src/io/anuke/mindustry/maps/generators/MapGenerator.java @@ -6,26 +6,36 @@ import io.anuke.arc.math.geom.Point2; import io.anuke.arc.util.Structs; import io.anuke.arc.util.noise.Simplex; import io.anuke.mindustry.content.Blocks; +import io.anuke.mindustry.content.Items; +import io.anuke.mindustry.game.Team; import io.anuke.mindustry.io.MapIO; import io.anuke.mindustry.maps.Map; import io.anuke.mindustry.maps.MapTileData; import io.anuke.mindustry.maps.MapTileData.TileDataMarker; +import io.anuke.mindustry.type.ItemStack; +import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; +import io.anuke.mindustry.world.blocks.Floor; import io.anuke.mindustry.world.blocks.OreBlock; +import io.anuke.mindustry.world.blocks.StaticWall; import io.anuke.mindustry.world.blocks.storage.CoreBlock; +import io.anuke.mindustry.world.blocks.storage.StorageBlock; import static io.anuke.mindustry.Vars.*; public class MapGenerator extends Generator{ private Map map; private String mapName; - + private Array decorations = new Array<>(); /**How much the landscape is randomly distorted.*/ public float distortion = 3; - /**The amount of final enemy spawns used. -1 to use everything in the map. * This amount of enemy spawns is selected randomly from the map.*/ public int enemySpawns = -1; + /*Whether floor is distorted along with blocks.*/ + public boolean distortFloor = false; + /**Items randomly added to containers and vaults.*/ + public ItemStack[] storageDrops = ItemStack.with(Items.copper, 300, Items.lead, 300, Items.silicon, 200, Items.graphite, 200, Items.blastCompound, 200); public MapGenerator(String mapName){ this.mapName = mapName; @@ -36,6 +46,27 @@ public class MapGenerator extends Generator{ this.enemySpawns = enemySpawns; } + public MapGenerator drops(ItemStack[] drops){ + this.storageDrops = drops; + return this; + } + + public MapGenerator decor(Decoration... decor){ + this.decorations.addAll(decor); + return this; + } + + public MapGenerator dist(float distortion){ + this.distortion = distortion; + return this; + } + + public MapGenerator dist(float distortion, boolean floor){ + this.distortion = distortion; + this.distortFloor = floor; + return this; + } + @Override public void init(){ map = world.maps.loadInternalMap(mapName); @@ -50,6 +81,7 @@ public class MapGenerator extends Generator{ data.position(0, 0); TileDataMarker marker = data.newDataMarker(); Array players = new Array<>(); + Array coreTypes = new Array<>(); Array enemies = new Array<>(); for(int y = 0; y < data.height(); y++){ @@ -58,6 +90,7 @@ public class MapGenerator extends Generator{ if(content.block(marker.wall) instanceof CoreBlock){ players.add(new Point2(x, y)); + coreTypes.add(content.block(marker.wall)); marker.wall = 0; } @@ -75,19 +108,44 @@ public class MapGenerator extends Generator{ for(int x = 0; x < data.width(); x++){ for(int y = 0; y < data.height(); y++){ final double scl = 10; + Tile tile = tiles[x][y]; int newX = Mathf.clamp((int)(simplex.octaveNoise2D(1, 1, 1.0 / scl, x, y) * distortion + x), 0, data.width()-1); int newY = Mathf.clamp((int)(simplex.octaveNoise2D(1, 1, 1.0 / scl, x + 9999, y + 9999) * distortion + y), 0, data.height()-1); - if(tiles[newX][newY].block() != Blocks.spawn && !tiles[x][y].block().synthetic()&& !tiles[newX][newY].block().synthetic()){ - tiles[x][y].setBlock(tiles[newX][newY].block()); + + if((tile.block() instanceof StaticWall + && tiles[newX][newY].block() instanceof StaticWall) + || (tile.block() == Blocks.air && !tiles[newX][newY].block().synthetic()) + || (tiles[newX][newY].block() == Blocks.air && tile.block() instanceof StaticWall)){ + tile.setBlock(tiles[newX][newY].block()); + } + + if(distortFloor){ + tile.setFloor(tiles[newX][newY].floor()); + } + + for(Decoration decor : decorations){ + if(tile.block() == Blocks.air && !(decor.wall instanceof Floor) && tile.floor() == decor.floor && Mathf.chance(decor.chance)){ + tile.setBlock(decor.wall); + }else if(tile.floor() == decor.floor && decor.wall instanceof Floor && Mathf.chance(decor.chance)){ + tile.setFloor((Floor)decor.wall); + } + } + + if(tile.getTeam() == Team.none && tile.block() instanceof StorageBlock){ + for(ItemStack stack : storageDrops){ + if(Mathf.chance(0.3)){ + tile.entity.items.add(stack.item, Mathf.random(stack.amount)); + } + } } } } - if(enemySpawns > enemies.size){ - throw new IllegalArgumentException("Enemy spawn pool greater than map spawn number."); - } - if(enemySpawns != -1){ + if(enemySpawns > enemies.size){ + throw new IllegalArgumentException("Enemy spawn pool greater than map spawn number."); + } + enemies.shuffle(); for(int i = 0; i < enemySpawns; i++){ Point2 point = enemies.get(i); @@ -117,9 +175,21 @@ public class MapGenerator extends Generator{ } //TODO set specific core block? - tiles[core.x][core.y].setBlock(Blocks.core, defaultTeam); + tiles[core.x][core.y].setBlock(coreTypes.get(players.indexOf(core)), defaultTeam); world.prepareTiles(tiles); world.setMap(map); } + + public static class Decoration{ + public final Block floor; + public final Block wall; + public final double chance; + + public Decoration(Block floor, Block wall, double chance){ + this.floor = floor; + this.wall = wall; + this.chance = chance; + } + } } diff --git a/core/src/io/anuke/mindustry/maps/generators/RandomGenerator.java b/core/src/io/anuke/mindustry/maps/generators/RandomGenerator.java index 74a51a360c..9692f0dc54 100644 --- a/core/src/io/anuke/mindustry/maps/generators/RandomGenerator.java +++ b/core/src/io/anuke/mindustry/maps/generators/RandomGenerator.java @@ -24,7 +24,7 @@ public abstract class RandomGenerator extends Generator{ } } - tiles[width/2][height/2].setBlock(Blocks.core, Team.blue); + tiles[width/2][height/2].setBlock(Blocks.coreShard, Team.blue); tiles[width/2][height/2 - 6].setBlock(Blocks.launchPad, Team.blue); } diff --git a/core/src/io/anuke/mindustry/net/NetConnection.java b/core/src/io/anuke/mindustry/net/NetConnection.java index 3b572d0bb5..d016c34442 100644 --- a/core/src/io/anuke/mindustry/net/NetConnection.java +++ b/core/src/io/anuke/mindustry/net/NetConnection.java @@ -9,8 +9,6 @@ public abstract class NetConnection{ public boolean modclient; public boolean mobile; - public int lastSentSnapshotID = -1; - /**ID of last recieved client snapshot.*/ public int lastRecievedClientSnapshot = -1; /**Timestamp of last recieved snapshot.*/ diff --git a/core/src/io/anuke/mindustry/net/NetworkIO.java b/core/src/io/anuke/mindustry/net/NetworkIO.java index 09183f4049..04375e7a15 100644 --- a/core/src/io/anuke/mindustry/net/NetworkIO.java +++ b/core/src/io/anuke/mindustry/net/NetworkIO.java @@ -3,9 +3,9 @@ package io.anuke.mindustry.net; import io.anuke.arc.Core; import io.anuke.arc.collection.ObjectMap; import io.anuke.arc.collection.ObjectMap.Entry; -import io.anuke.arc.entities.Entities; +import io.anuke.mindustry.entities.Entities; import io.anuke.arc.util.Time; -import io.anuke.mindustry.entities.Player; +import io.anuke.mindustry.entities.type.Player; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.game.Teams; import io.anuke.mindustry.game.Teams.TeamData; @@ -44,6 +44,7 @@ public class NetworkIO{ stream.writeInt(player.id); player.write(stream); + world.spawner.write(stream); SaveIO.getSaveWriter().writeMap(stream); stream.write(Team.all.length); @@ -105,6 +106,7 @@ public class NetworkIO{ world.beginMapLoad(); //map + world.spawner.read(stream); SaveIO.getSaveWriter().readMap(stream); world.setMap(new Map(map, 0, 0)); diff --git a/core/src/io/anuke/mindustry/net/ValidateException.java b/core/src/io/anuke/mindustry/net/ValidateException.java index 89923702de..08f3f70483 100644 --- a/core/src/io/anuke/mindustry/net/ValidateException.java +++ b/core/src/io/anuke/mindustry/net/ValidateException.java @@ -1,6 +1,6 @@ package io.anuke.mindustry.net; -import io.anuke.mindustry.entities.Player; +import io.anuke.mindustry.entities.type.Player; /** * Thrown when a client sends invalid information. diff --git a/core/src/io/anuke/mindustry/type/ContentType.java b/core/src/io/anuke/mindustry/type/ContentType.java index 1e775dc7e3..30189125ee 100644 --- a/core/src/io/anuke/mindustry/type/ContentType.java +++ b/core/src/io/anuke/mindustry/type/ContentType.java @@ -7,7 +7,6 @@ public enum ContentType { mech, bullet, liquid, - weapon, status, unit, weather, diff --git a/core/src/io/anuke/mindustry/type/Item.java b/core/src/io/anuke/mindustry/type/Item.java index 47bf130f3e..b75ba11c21 100644 --- a/core/src/io/anuke/mindustry/type/Item.java +++ b/core/src/io/anuke/mindustry/type/Item.java @@ -9,7 +9,7 @@ import io.anuke.arc.util.Log; import io.anuke.arc.util.Strings; import io.anuke.mindustry.Vars; import io.anuke.mindustry.game.UnlockableContent; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.ui.ContentDisplay; public class Item extends UnlockableContent implements Comparable{ @@ -26,12 +26,10 @@ public class Item extends UnlockableContent implements Comparable{ public float flammability = 0f; /**how radioactive this item is. 0=none, 1=chernobyl ground zero*/ public float radioactivity; - /**how effective this item is as flux for smelting. 0 = not a flux, 0.5 = normal flux, 1 = very good*/ - public float fluxiness = 0f; /**drill hardness of the item*/ public int hardness = 0; /**the burning color of this item. TODO unused; implement*/ - public Color flameColor = Palette.darkFlame.cpy(); + public Color flameColor = Pal.darkFlame.cpy(); /** * base material cost of this item, used for calculating place times * 1 cost = 1 tick added to build time diff --git a/core/src/io/anuke/mindustry/type/ItemStack.java b/core/src/io/anuke/mindustry/type/ItemStack.java index d7455c8d36..5b77275b36 100644 --- a/core/src/io/anuke/mindustry/type/ItemStack.java +++ b/core/src/io/anuke/mindustry/type/ItemStack.java @@ -20,4 +20,12 @@ public class ItemStack{ } return stacks; } + + @Override + public String toString(){ + return "ItemStack{" + + "item=" + item + + ", amount=" + amount + + '}'; + } } diff --git a/core/src/io/anuke/mindustry/type/Mech.java b/core/src/io/anuke/mindustry/type/Mech.java index 7abf1a8e3c..bfe9842a62 100644 --- a/core/src/io/anuke/mindustry/type/Mech.java +++ b/core/src/io/anuke/mindustry/type/Mech.java @@ -4,10 +4,9 @@ import io.anuke.arc.Core; import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.scene.ui.layout.Table; -import io.anuke.mindustry.content.Weapons; -import io.anuke.mindustry.entities.Player; +import io.anuke.mindustry.entities.type.Player; import io.anuke.mindustry.game.UnlockableContent; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.ui.ContentDisplay; public class Mech extends UnlockableContent{ @@ -21,22 +20,20 @@ public class Mech extends UnlockableContent{ public float drag = 0.4f; public float mass = 1f; public float shake = 0f; - public float armor = 1f; + public float health = 200f; public float hitsize = 6f; public float cellTrnsY = 0f; public float mineSpeed = 1f; public int drillPower = -1; - public float carryWeight = 10f; public float buildPower = 1f; - public Color trailColor = Palette.boostFrom; - public Color trailColorTo = Palette.boostTo; + public Color engineColor = Pal.boostTo; public int itemCapacity = 30; public boolean turnCursor = true; public boolean canHeal = false; - public float weaponOffsetX, weaponOffsetY; - public Weapon weapon = Weapons.blaster; + public float weaponOffsetX, weaponOffsetY, engineOffset = 5f, engineSize = 2.5f; + public Weapon weapon; public TextureRegion baseRegion, legRegion, region, iconRegion; @@ -92,6 +89,7 @@ public class Mech extends UnlockableContent{ @Override public void load(){ + weapon.load(); if(!flying){ legRegion = Core.atlas.find(name + "-leg"); baseRegion = Core.atlas.find(name + "-base"); diff --git a/core/src/io/anuke/mindustry/type/StatusEffect.java b/core/src/io/anuke/mindustry/type/StatusEffect.java index ce2b8dc9af..3852f0a38e 100644 --- a/core/src/io/anuke/mindustry/type/StatusEffect.java +++ b/core/src/io/anuke/mindustry/type/StatusEffect.java @@ -2,15 +2,15 @@ package io.anuke.mindustry.type; import io.anuke.arc.collection.Array; import io.anuke.arc.collection.ObjectMap; -import io.anuke.arc.entities.Effects; -import io.anuke.arc.entities.Effects.Effect; +import io.anuke.mindustry.entities.Effects; +import io.anuke.mindustry.entities.Effects.Effect; import io.anuke.arc.function.Supplier; import io.anuke.arc.graphics.Color; import io.anuke.arc.math.Mathf; import io.anuke.arc.util.Time; import io.anuke.mindustry.content.Fx; -import io.anuke.mindustry.entities.StatusController.StatusEntry; -import io.anuke.mindustry.entities.Unit; +import io.anuke.mindustry.entities.units.Statuses.StatusEntry; +import io.anuke.mindustry.entities.type.Unit; import io.anuke.mindustry.game.Content; public class StatusEffect extends Content{ diff --git a/core/src/io/anuke/mindustry/entities/units/UnitType.java b/core/src/io/anuke/mindustry/type/UnitType.java similarity index 83% rename from core/src/io/anuke/mindustry/entities/units/UnitType.java rename to core/src/io/anuke/mindustry/type/UnitType.java index 9552a786cc..2af1392bad 100644 --- a/core/src/io/anuke/mindustry/entities/units/UnitType.java +++ b/core/src/io/anuke/mindustry/type/UnitType.java @@ -1,21 +1,17 @@ -package io.anuke.mindustry.entities.units; +package io.anuke.mindustry.type; import io.anuke.arc.Core; import io.anuke.arc.collection.ObjectSet; import io.anuke.arc.function.Supplier; -import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.scene.ui.layout.Table; import io.anuke.arc.util.Log; import io.anuke.arc.util.Strings; import io.anuke.mindustry.content.Items; -import io.anuke.mindustry.content.Weapons; import io.anuke.mindustry.entities.traits.TypeTrait; +import io.anuke.mindustry.entities.type.BaseUnit; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.game.UnlockableContent; -import io.anuke.mindustry.type.ContentType; -import io.anuke.mindustry.type.Item; -import io.anuke.mindustry.type.Weapon; import io.anuke.mindustry.ui.ContentDisplay; public class UnitType extends UnlockableContent{ @@ -27,23 +23,23 @@ public class UnitType extends UnlockableContent{ public float hitsize = 7f; public float hitsizeTile = 4f; public float speed = 0.4f; - public float range = 0; + public float range = 0, attackLength = 150f; public float rotatespeed = 0.2f; public float baseRotateSpeed = 0.1f; + public float shootCone = 15f; public float mass = 1f; public boolean isFlying; public boolean targetAir = true; + public boolean rotateWeapon = false; public float drag = 0.1f; public float maxVelocity = 5f; public float retreatPercent = 0.2f; - public float armor = 0f; - public float carryWeight = 1f; public int itemCapacity = 30; public ObjectSet toMine = ObjectSet.with(Items.lead, Items.copper); public float buildPower = 0.3f, minePower = 0.7f; - public Weapon weapon = Weapons.blaster; - public float weaponOffsetX, weaponOffsetY; - public Color trailColor = Color.valueOf("ffa665"); + public Weapon weapon; + public float weaponOffsetY, engineOffset = 6f, engineSize = 2f; + public ObjectSet immunities = new ObjectSet<>(); public TextureRegion iconRegion, legRegion, baseRegion, region; @@ -77,7 +73,8 @@ public class UnitType extends UnlockableContent{ @Override public void load(){ - iconRegion = Core.atlas.find("unit-icon-" + name); + weapon.load(); + iconRegion = Core.atlas.find("unit-icon-" + name, Core.atlas.find(name)); region = Core.atlas.find(name); if(!isFlying){ diff --git a/core/src/io/anuke/mindustry/type/Weapon.java b/core/src/io/anuke/mindustry/type/Weapon.java index dda242a463..093eda0244 100644 --- a/core/src/io/anuke/mindustry/type/Weapon.java +++ b/core/src/io/anuke/mindustry/type/Weapon.java @@ -3,60 +3,70 @@ package io.anuke.mindustry.type; import io.anuke.annotations.Annotations.Loc; import io.anuke.annotations.Annotations.Remote; import io.anuke.arc.Core; -import io.anuke.arc.entities.Effects; -import io.anuke.arc.entities.Effects.Effect; import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.math.Angles; import io.anuke.arc.math.Mathf; -import io.anuke.arc.math.geom.Vector2; +import io.anuke.arc.util.Time; +import io.anuke.arc.util.Tmp; import io.anuke.mindustry.Vars; import io.anuke.mindustry.content.Fx; -import io.anuke.mindustry.entities.Player; +import io.anuke.mindustry.entities.Effects; +import io.anuke.mindustry.entities.Effects.Effect; import io.anuke.mindustry.entities.bullet.Bullet; import io.anuke.mindustry.entities.bullet.BulletType; import io.anuke.mindustry.entities.traits.ShooterTrait; -import io.anuke.mindustry.game.Content; +import io.anuke.mindustry.entities.type.Player; import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.net.Net; -public class Weapon extends Content{ +public class Weapon{ public final String name; /**minimum cursor distance from player, fixes 'cross-eyed' shooting.*/ protected static float minPlayerDist = 20f; - /**ammo type map. set with setAmmo()*/ - protected BulletType ammo; + protected static int sequenceNum = 0; + /**bullet shot*/ + public BulletType bullet; /**shell ejection effect*/ - protected Effect ejectEffect = Fx.none; + public Effect ejectEffect = Fx.none; /**weapon reload in frames*/ - protected float reload; + public float reload; /**amount of shots per fire*/ - protected int shots = 1; + public int shots = 1; /**spacing in degrees between multiple shots, if applicable*/ - protected float spacing = 12f; + public float spacing = 12f; /**inaccuracy of degrees of each shot*/ - protected float inaccuracy = 0f; + public float inaccuracy = 0f; /**intensity and duration of each shot's screen shake*/ - protected float shake = 0f; + public float shake = 0f; /**visual weapon knockback.*/ - protected float recoil = 1.5f; + public float recoil = 1.5f; /**shoot barrel y offset*/ - protected float length = 3f; + public float length = 3f; /**shoot barrel x offset.*/ - protected float width = 4f; + public float width = 4f; /**fraction of velocity that is random*/ - protected float velocityRnd = 0f; + public float velocityRnd = 0f; /**whether to shoot the weapons in different arms one after another, rather than all at once*/ - protected boolean roundrobin = false; - /**vector for vector calulations*/ - protected Vector2 tr = new Vector2(); + public boolean roundrobin = false; + /**randomization of shot length*/ + public float lengthRand = 0f; + /**delay in ticks between shots*/ + public float shotDelay = 0; + /**whether shooter rotation is ignored when shooting.*/ + public boolean ignoreRotation = false; - public TextureRegion equipRegion, region; + public TextureRegion region; protected Weapon(String name){ this.name = name; } + protected Weapon(){ + //no region + this.name = ""; + } + @Remote(targets = Loc.server, called = Loc.both, unreliable = true) public static void onPlayerShootWeapon(Player player, float x, float y, float rotation, boolean left){ if(player == null) return; @@ -81,59 +91,58 @@ public class Weapon extends Content{ Weapon weapon = shooter.getWeapon(); - Angles.shotgun(weapon.shots, weapon.spacing, rotation, f -> weapon.bullet(shooter, x, y, f + Mathf.range(weapon.inaccuracy))); - BulletType ammo = weapon.ammo; + sequenceNum = 0; + if(weapon.shotDelay > 0.01f){ + Angles.shotgun(weapon.shots, weapon.spacing, rotation, f -> { + Time.run(sequenceNum * weapon.shotDelay, () -> weapon.bullet(shooter, x, y, f + Mathf.range(weapon.inaccuracy))); + sequenceNum ++; + }); + }else{ + Angles.shotgun(weapon.shots, weapon.spacing, rotation, f -> weapon.bullet(shooter, x, y, f + Mathf.range(weapon.inaccuracy))); + } - weapon.tr.trns(rotation + 180f, ammo.recoil); + BulletType ammo = weapon.bullet; - shooter.velocity().add(weapon.tr); + Tmp.v1.trns(rotation + 180f, ammo.recoil); - weapon.tr.trns(rotation, 3f); + shooter.velocity().add(Tmp.v1); + + Tmp.v1.trns(rotation, 3f); Effects.shake(weapon.shake, weapon.shake, x, y); Effects.effect(weapon.ejectEffect, x, y, rotation * -Mathf.sign(left)); - Effects.effect(ammo.shootEffect, x + weapon.tr.x, y + weapon.tr.y, rotation, shooter); - Effects.effect(ammo.smokeEffect, x + weapon.tr.x, y + weapon.tr.y, rotation, shooter); + Effects.effect(ammo.shootEffect, x + Tmp.v1.x, y + Tmp.v1.y, rotation, shooter); + Effects.effect(ammo.smokeEffect, x + Tmp.v1.x, y + Tmp.v1.y, rotation, shooter); //reset timer for remote players shooter.getTimer().get(shooter.getShootTimer(left), weapon.reload); } - @Override public void load(){ - equipRegion = Core.atlas.find(name + "-equip"); - region = Core.atlas.find(name); - } - - @Override - public ContentType getContentType(){ - return ContentType.weapon; - } - - public BulletType getAmmo(){ - return ammo; + region = Core.atlas.find(name + "-equip", Core.atlas.find("clear")); } public void update(ShooterTrait shooter, float pointerX, float pointerY){ - update(shooter, true, pointerX, pointerY); - update(shooter, false, pointerX, pointerY); + for(boolean left : Mathf.booleans){ + Tmp.v1.set(pointerX, pointerY).sub(shooter.getX(), shooter.getY()); + if(Tmp.v1.len() < minPlayerDist) Tmp.v1.setLength(minPlayerDist); + + float cx = Tmp.v1.x + shooter.getX(), cy = Tmp.v1.y + shooter.getY(); + + float ang = Tmp.v1.angle(); + Tmp.v1.trns(ang - 90, width * Mathf.sign(left), length + Mathf.range(lengthRand)); + + update(shooter, shooter.getX() + Tmp.v1.x, shooter.getY() + Tmp.v1.y, Angles.angle(shooter.getX() + Tmp.v1.x, shooter.getY() + Tmp.v1.y, cx, cy), left); + } } - private void update(ShooterTrait shooter, boolean left, float pointerX, float pointerY){ + public void update(ShooterTrait shooter, float mountX, float mountY, float angle, boolean left){ if(shooter.getTimer().get(shooter.getShootTimer(left), reload)){ if(roundrobin){ shooter.getTimer().reset(shooter.getShootTimer(!left), reload / 2f); } - tr.set(pointerX, pointerY).sub(shooter.getX(), shooter.getY()); - if(tr.len() < minPlayerDist) tr.setLength(minPlayerDist); - - float cx = tr.x + shooter.getX(), cy = tr.y + shooter.getY(); - - float ang = tr.angle(); - tr.trns(ang - 90, width * Mathf.sign(left), length); - - shoot(shooter, tr.x, tr.y, Angles.angle(shooter.getX() + tr.x, shooter.getY() + tr.y, cx, cy), left); + shoot(shooter, mountX - shooter.getX(), mountY - shooter.getY(), angle, left); } } @@ -141,14 +150,6 @@ public class Weapon extends Content{ return (1f - Mathf.clamp(player.getTimer().getTime(player.getShootTimer(left)) / reload)) * recoil; } - public float getRecoil(){ - return recoil; - } - - public float getReload(){ - return reload; - } - public void shoot(ShooterTrait p, float x, float y, float angle, boolean left){ if(Net.client()){ //call it directly, don't invoke on server @@ -165,8 +166,8 @@ public class Weapon extends Content{ void bullet(ShooterTrait owner, float x, float y, float angle){ if(owner == null) return; - tr.trns(angle, 3f); - Bullet.create(ammo, - owner, owner.getTeam(), x + tr.x, y + tr.y, angle, (1f - velocityRnd) + Mathf.random(velocityRnd)); + Tmp.v1.trns(angle, 3f); + Bullet.create(bullet, + owner, owner.getTeam(), x + Tmp.v1.x, y + Tmp.v1.y, angle, (1f - velocityRnd) + Mathf.random(velocityRnd)); } } diff --git a/core/src/io/anuke/mindustry/type/Zone.java b/core/src/io/anuke/mindustry/type/Zone.java index dabee32514..cc7feb01b8 100644 --- a/core/src/io/anuke/mindustry/type/Zone.java +++ b/core/src/io/anuke/mindustry/type/Zone.java @@ -22,6 +22,7 @@ public class Zone extends UnlockableContent{ public Supplier rules = Rules::new; public boolean alwaysUnlocked; public int conditionWave = Integer.MAX_VALUE; + public int launchPeriod = 10; public Zone(String name, Generator generator){ this.name = name; diff --git a/core/src/io/anuke/mindustry/ui/Bar.java b/core/src/io/anuke/mindustry/ui/Bar.java index bf24bd03f6..0a4b0eab18 100644 --- a/core/src/io/anuke/mindustry/ui/Bar.java +++ b/core/src/io/anuke/mindustry/ui/Bar.java @@ -32,8 +32,10 @@ public class Bar extends Element{ public Bar(Supplier name, Supplier color, FloatProvider fraction){ this.fraction = fraction; + lastValue = value = fraction.get(); update(() -> { this.name = name.get(); + this.blinkColor.set(color.get()); setColor(color.get()); }); } diff --git a/core/src/io/anuke/mindustry/ui/BorderImage.java b/core/src/io/anuke/mindustry/ui/BorderImage.java index 2b479a1980..0db23da2ba 100644 --- a/core/src/io/anuke/mindustry/ui/BorderImage.java +++ b/core/src/io/anuke/mindustry/ui/BorderImage.java @@ -2,7 +2,7 @@ package io.anuke.mindustry.ui; import io.anuke.arc.graphics.Texture; import io.anuke.arc.graphics.g2d.TextureRegion; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.graphics.Pal; import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.graphics.g2d.Lines; import io.anuke.arc.scene.ui.Image; @@ -36,7 +36,7 @@ public class BorderImage extends Image{ float scaleX = getScaleX(); float scaleY = getScaleY(); - Draw.color(Palette.accent); + Draw.color(Pal.accent); Lines.stroke(Unit.dp.scl(thickness)); Lines.rect(x + imageX, y + imageY, imageWidth * scaleX, imageHeight * scaleY); Draw.reset(); diff --git a/core/src/io/anuke/mindustry/ui/ContentDisplay.java b/core/src/io/anuke/mindustry/ui/ContentDisplay.java index ec7a43fe52..7f9e969938 100644 --- a/core/src/io/anuke/mindustry/ui/ContentDisplay.java +++ b/core/src/io/anuke/mindustry/ui/ContentDisplay.java @@ -5,8 +5,8 @@ import io.anuke.arc.collection.OrderedMap; import io.anuke.arc.graphics.Color; import io.anuke.arc.scene.ui.layout.Table; import io.anuke.arc.util.Strings; -import io.anuke.mindustry.entities.units.UnitType; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.type.UnitType; +import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.Liquid; import io.anuke.mindustry.type.Mech; @@ -49,7 +49,7 @@ public class ContentDisplay{ if(map.size == 0) continue; - table.add("$category." + cat.name()).color(Palette.accent).fillX(); + table.add("$category." + cat.name()).color(Pal.accent).fillX(); table.row(); for(BlockStat stat : map.keys()){ @@ -86,13 +86,11 @@ public class ContentDisplay{ table.left().defaults().fillX(); - table.add(Core.bundle.format("item.explosiveness", (int) (item.explosiveness * 100 * 2f))); + table.add(Core.bundle.format("item.explosiveness", (int) (item.explosiveness * 100))); table.row(); - table.add(Core.bundle.format("item.flammability", (int) (item.flammability * 100 * 2f))); + table.add(Core.bundle.format("item.flammability", (int) (item.flammability * 100))); table.row(); - table.add(Core.bundle.format("item.radioactivity", (int) (item.radioactivity * 100 * 2f))); - table.row(); - table.add(Core.bundle.format("item.fluxiness", (int) (item.fluxiness * 100 * 2f))); + table.add(Core.bundle.format("item.radioactivity", (int) (item.radioactivity * 100))); table.row(); } @@ -119,9 +117,9 @@ public class ContentDisplay{ table.left().defaults().fillX(); - table.add(Core.bundle.format("item.explosiveness", (int) (liquid.explosiveness * 100 * 2f))); + table.add(Core.bundle.format("item.explosiveness", (int) (liquid.explosiveness * 100))); table.row(); - table.add(Core.bundle.format("item.flammability", (int) (liquid.flammability * 100 * 2f))); + table.add(Core.bundle.format("item.flammability", (int) (liquid.flammability * 100))); table.row(); table.add(Core.bundle.format("liquid.heatcapacity", (int) (liquid.heatCapacity * 100))); table.row(); @@ -161,7 +159,7 @@ public class ContentDisplay{ table.add(Core.bundle.format("mech.ability", Core.bundle.get("mech." + mech.name + ".ability"))); table.row(); } - table.add(Core.bundle.format("mech.armor", mech.armor)); + table.add(Core.bundle.format("mech.health", (int)mech.health)); table.row(); table.add(Core.bundle.format("mech.itemcapacity", mech.itemCapacity)); table.row(); diff --git a/core/src/io/anuke/mindustry/ui/ItemsDisplay.java b/core/src/io/anuke/mindustry/ui/ItemsDisplay.java new file mode 100644 index 0000000000..98e34facf8 --- /dev/null +++ b/core/src/io/anuke/mindustry/ui/ItemsDisplay.java @@ -0,0 +1,39 @@ +package io.anuke.mindustry.ui; + +import io.anuke.arc.collection.ObjectIntMap; +import io.anuke.arc.graphics.Color; +import io.anuke.arc.scene.ui.layout.Table; +import io.anuke.mindustry.type.Item; +import io.anuke.mindustry.type.ItemType; + +import java.text.NumberFormat; +import java.util.Locale; + +import static io.anuke.mindustry.Vars.content; +import static io.anuke.mindustry.Vars.data; + +public class ItemsDisplay extends Table{ + private static final NumberFormat format = NumberFormat.getNumberInstance(Locale.getDefault()); + + public ItemsDisplay(){ + rebuild(); + } + + public void rebuild(){ + clear(); + top().left(); + + table("flat", t -> { + t.margin(4); + ObjectIntMap items = data.items(); + for(Item item : content.items()){ + if(item.type == ItemType.material && data.isUnlocked(item)){ + t.label(() -> format.format(items.get(item, 0))).left(); + t.addImage(item.region).size(8*3).padLeft(4).padRight(4); + t.add(item.localizedName()).color(Color.LIGHT_GRAY).left(); + t.row(); + } + } + }); + } +} diff --git a/core/src/io/anuke/mindustry/ui/TreeLayout.java b/core/src/io/anuke/mindustry/ui/TreeLayout.java index 209e3a5110..d5f0db4e8e 100644 --- a/core/src/io/anuke/mindustry/ui/TreeLayout.java +++ b/core/src/io/anuke/mindustry/ui/TreeLayout.java @@ -292,12 +292,12 @@ public class TreeLayout{ center, towardsRoot, awayFromRoot } - public static class TreeNode{ + public static class TreeNode{ public float width, height, x, y; //should be initialized by user - public TreeNode[] children; - public TreeNode parent; + public T[] children; + public T parent; private float mode, prelim, change, shift; private int number = -1; diff --git a/core/src/io/anuke/mindustry/ui/dialogs/AboutDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/AboutDialog.java index a10edecfa0..af6ddffe1b 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/AboutDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/AboutDialog.java @@ -4,7 +4,7 @@ import io.anuke.arc.Core; import io.anuke.arc.graphics.Color; import io.anuke.arc.collection.Array; import io.anuke.arc.collection.ObjectSet; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.io.Contributors; import io.anuke.mindustry.io.Contributors.Contributor; import io.anuke.mindustry.ui.Links; @@ -103,7 +103,7 @@ public class AboutDialog extends FloatingDialog{ dialog.cont.add("$credits.text"); dialog.cont.row(); if(!contributors.isEmpty()){ - dialog.cont.addImage("blank").color(Palette.accent).fillX().height(3f).pad(3f); + dialog.cont.addImage("blank").color(Pal.accent).fillX().height(3f).pad(3f); dialog.cont.row(); dialog.cont.add("$contributors"); dialog.cont.row(); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/ControlsDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/ControlsDialog.java index 48fb57029b..2a6db67316 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/ControlsDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/ControlsDialog.java @@ -5,7 +5,7 @@ import io.anuke.arc.input.KeyCode; import io.anuke.arc.scene.ui.Image; import io.anuke.arc.scene.ui.KeybindDialog; import io.anuke.arc.util.Align; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.graphics.Pal; public class ControlsDialog extends KeybindDialog{ @@ -16,7 +16,7 @@ public class ControlsDialog extends KeybindDialog{ title.setAlignment(Align.center); titleTable.row(); titleTable.add(new Image("white")) - .growX().height(3f).pad(4f).get().setColor(Palette.accent); + .growX().height(3f).pad(4f).get().setColor(Pal.accent); } @Override diff --git a/core/src/io/anuke/mindustry/ui/dialogs/CustomGameDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/CustomGameDialog.java index 6e1c8add8c..c068eae79d 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/CustomGameDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/CustomGameDialog.java @@ -20,6 +20,7 @@ import static io.anuke.mindustry.Vars.*; public class CustomGameDialog extends FloatingDialog{ Difficulty difficulty = Difficulty.normal; + RulePreset lastPreset = RulePreset.survival; public CustomGameDialog(){ super("$customgame"); @@ -30,6 +31,7 @@ public class CustomGameDialog extends FloatingDialog{ } void setup(){ + state.rules = lastPreset.get(); cont.clear(); Table maps = new Table(); @@ -48,10 +50,10 @@ public class CustomGameDialog extends FloatingDialog{ modes.marginBottom(5); for(RulePreset mode : RulePreset.values()){ - - //todo fix presets - modes.addButton(mode.toString(), "toggle", () -> state.rules = mode.get())/* - .update(b -> b.setChecked(state.rules == mode))*/.group(group).size(140f, 54f); + modes.addButton(mode.toString(), "toggle", () -> { + state.rules = mode.get(); + lastPreset = mode; + }).update(b -> b.setChecked(lastPreset == mode)).group(group).size(140f, 54f); if(i++ % 2 == 1) modes.row(); } selmode.add(modes); @@ -112,7 +114,7 @@ public class CustomGameDialog extends FloatingDialog{ image.clicked(() -> { hide(); - control.playMap(map); + control.playMap(map, lastPreset.get()); }); maps.add(image); @@ -120,14 +122,6 @@ public class CustomGameDialog extends FloatingDialog{ i++; } - /* - ImageButton gen = maps.addImageButton("icon-editor", "clear", 16*4, () -> { - hide(); - world.generator.playRandomMap(); - }).growY().get(); - gen.row(); - gen.add("$map.random");*/ - if(world.maps.all().size == 0){ maps.add("$maps.none").pad(50); } @@ -136,7 +130,7 @@ public class CustomGameDialog extends FloatingDialog{ } private void displayGameModeHelp(){ - FloatingDialog d = new FloatingDialog(Core.bundle.get("mode.text.help.title")); + FloatingDialog d = new FloatingDialog(Core.bundle.get("mode.help.title")); d.setFillParent(false); Table table = new Table(); table.defaults().pad(1f); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/DatabaseDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/DatabaseDialog.java index a4da5816f4..879a9340e1 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/DatabaseDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/DatabaseDialog.java @@ -4,7 +4,7 @@ import io.anuke.arc.collection.Array; import io.anuke.mindustry.Vars; import io.anuke.mindustry.game.Content; import io.anuke.mindustry.game.UnlockableContent; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.type.ContentType; import io.anuke.arc.scene.event.HandCursorListener; import io.anuke.arc.scene.ui.Image; @@ -38,26 +38,24 @@ public class DatabaseDialog extends FloatingDialog{ for(int j = 0; j < allContent.length; j ++){ ContentType type = ContentType.values()[j]; - Array array = allContent[j]; - if(array.size == 0 || !(array.first() instanceof UnlockableContent)) continue; + Array array = allContent[j].select(c -> c instanceof UnlockableContent && !((UnlockableContent)c).isHidden()); + if(array.size == 0) continue; - table.add("$content." + type.name() + ".name").growX().left().color(Palette.accent); + table.add("$content." + type.name() + ".name").growX().left().color(Pal.accent); table.row(); - table.addImage("white").growX().pad(5).padLeft(0).padRight(0).height(3).color(Palette.accent); + table.addImage("white").growX().pad(5).padLeft(0).padRight(0).height(3).color(Pal.accent); table.row(); table.table(list -> { list.left(); int maxWidth = UIUtils.portrait() ? 7 : 13; - int size = 8 * 6; + int size = 8 * 4; int count = 0; for(int i = 0; i < array.size; i++){ UnlockableContent unlock = (UnlockableContent) array.get(i); - if(unlock.isHidden()) continue; - Image image = data.isUnlocked(unlock) ? new Image(unlock.getContentIcon()) : new Image("icon-tree-locked"); image.addListener(new HandCursorListener()); list.add(image).size(size).pad(3); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/DeployDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/DeployDialog.java index e2987a7662..fc20402fea 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/DeployDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/DeployDialog.java @@ -1,198 +1,97 @@ package io.anuke.mindustry.ui.dialogs; import io.anuke.arc.Core; -import io.anuke.arc.collection.ObjectIntMap; +import io.anuke.arc.collection.Array; +import io.anuke.arc.collection.ObjectSet; import io.anuke.arc.graphics.Color; -import io.anuke.arc.scene.ui.ScrollPane; +import io.anuke.arc.graphics.g2d.Lines; +import io.anuke.arc.scene.Group; import io.anuke.arc.scene.ui.TextButton; import io.anuke.arc.scene.ui.layout.Table; +import io.anuke.arc.util.Align; +import io.anuke.arc.util.Structs; +import io.anuke.mindustry.content.Zones; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.game.Saves.SaveSlot; +import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.io.SaveIO.SaveException; -import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.ItemStack; -import io.anuke.mindustry.type.ItemType; import io.anuke.mindustry.type.Zone; +import io.anuke.mindustry.ui.ItemsDisplay; +import io.anuke.mindustry.ui.TreeLayout; +import io.anuke.mindustry.ui.TreeLayout.TreeNode; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Block.Icon; import static io.anuke.mindustry.Vars.*; public class DeployDialog extends FloatingDialog{ + private static final float nodeSize = 250f; + private ObjectSet nodes = new ObjectSet<>(); public DeployDialog(){ - super("$play"); + super(""); + + ZoneNode root = new ZoneNode(Zones.groundZero, null); + + TreeLayout layout = new TreeLayout(); + layout.gapBetweenLevels = 40f; + layout.gapBetweenNodes = 40f; + layout.layout(root); + + addCloseButton(); + buttons.addImageTextButton("$techtree", "icon-tree", 16 * 2, () -> ui.tech.show()).size(230f, 64f); shown(this::setup); } public void setup(){ - buttons.clear(); cont.clear(); + titleTable.remove(); + marginTop(0f); - addCloseButton(); - buttons.addImageTextButton("$techtree", "icon-tree", 16 * 2, () -> ui.tech.show()).size(230f, 64f); + cont.stack(control.saves.getZoneSlot() == null ? new View() : new Table(){{ + SaveSlot slot = control.saves.getZoneSlot(); - cont.stack(new Table(){{ - top().left().margin(10); + TextButton[] b = {null}; - ObjectIntMap items = data.items(); - for(Item item : content.items()){ - if(item.type == ItemType.material && data.isUnlocked(item)){ - label(() -> items.get(item, 0) + "").left(); - addImage(item.region).size(8*4).pad(4); - add("[LIGHT_GRAY]" + item.localizedName()).left(); - row(); - } - } + TextButton button = addButton(Core.bundle.format("resume", slot.getZone().localizedName()), () -> { + if(b[0].childrenPressed()) return; - }}, new ScrollPane(new Table(){{ - - if(control.saves.getZoneSlot() == null){ - - int i = 0; - for(Zone zone : content.zones()){ - table(t -> { - TextButton button = t.addButton("", () -> { - if(!data.isUnlocked(zone)){ - data.removeItems(zone.itemRequirements); - data.unlockContent(zone); - setup(); - }else{ - data.removeItems(zone.deployCost); - hide(); - world.playZone(zone); - } - }).size(250f).disabled(b -> !canUnlock(zone)).get(); - - button.clearChildren(); - - if(data.isUnlocked(zone)){ - button.table(title -> { - title.addImage("icon-zone").padRight(3); - title.add(zone.localizedName()); - }); - button.row(); - - if(data.getWaveScore(zone) > 0){ - button.add(Core.bundle.format("bestwave", data.getWaveScore(zone))); - } - - button.row(); - - button.add("$launch").color(Color.LIGHT_GRAY).pad(4); - button.row(); - button.table(req -> { - for(ItemStack stack : zone.deployCost){ - req.addImage(stack.item.region).size(8 * 3); - req.add(stack.amount + "").left(); - } - }).pad(3).growX(); - }else{ - button.addImage("icon-zone-locked"); - button.row(); - button.add("$locked").padBottom(6); - - if(!hidden(zone)){ - button.row(); - - button.table(req -> { - req.defaults().left(); - - if(zone.zoneRequirements.length > 0){ - req.table(r -> { - r.add("$complete").colspan(2).left(); - r.row(); - for(Zone other : zone.zoneRequirements){ - r.addImage("icon-zone").padRight(4); - r.add(other.localizedName()).color(Color.LIGHT_GRAY); - r.addImage(data.isCompleted(other) ? "icon-check-2" : "icon-cancel-2") - .color(data.isCompleted(other) ? Color.LIGHT_GRAY : Color.SCARLET).padLeft(3); - r.row(); - } - }); - } - - req.row(); - - if(zone.itemRequirements.length > 0){ - req.table(r -> { - for(ItemStack stack : zone.itemRequirements){ - r.addImage(stack.item.region).size(8 * 3).padRight(4); - r.add(Math.min(data.getItem(stack.item), stack.amount) + "/" + stack.amount) - .color(stack.amount > data.getItem(stack.item) ? Color.SCARLET : Color.LIGHT_GRAY).left(); - r.row(); - } - }).padTop(10); - } - - req.row(); - - if(zone.blockRequirements.length > 0){ - req.table(r -> { - r.add("$research.list").colspan(2).left(); - r.row(); - for(Block block : zone.blockRequirements){ - r.addImage(block.icon(Icon.small)).size(8 * 3).padRight(4); - r.add(block.formalName).color(Color.LIGHT_GRAY); - r.addImage(data.isUnlocked(block) ? "icon-check-2" : "icon-cancel-2") - .color(data.isUnlocked(block) ? Color.LIGHT_GRAY : Color.SCARLET).padLeft(3); - r.row(); - } - - }).padTop(10); - } - }).growX(); - } - } - }).pad(4); - - if(++i % 2 == 0){ - row(); + hide(); + ui.loadAnd(() -> { + try{ + control.saves.getZoneSlot().load(); + state.set(State.playing); + }catch(SaveException e){ //make sure to handle any save load errors! + e.printStackTrace(); + if(control.saves.getZoneSlot() != null) control.saves.getZoneSlot().delete(); + ui.showInfo("$save.corrupted"); + show(); } - } - }else{ - SaveSlot slot = control.saves.getZoneSlot(); + }); + }).size(200f).get(); + b[0] = button; - TextButton b[] = {null}; + String color = "[lightgray]"; - TextButton button = addButton(Core.bundle.format("resume", slot.getZone().localizedName()), () -> { - if(b[0].childrenPressed()) return; + button.defaults().colspan(2); + button.row(); + button.add(Core.bundle.format("save.wave", color + slot.getWave())); + button.row(); + button.label(() -> Core.bundle.format("save.playtime", color + slot.getPlayTime())); + button.row(); + button.add().grow(); + button.row(); - hide(); - ui.loadAnd(() -> { - try{ - control.saves.getZoneSlot().load(); - state.set(State.playing); - }catch(SaveException e){ //make sure to handle any save load errors! - e.printStackTrace(); - if(control.saves.getZoneSlot() != null) control.saves.getZoneSlot().delete(); - ui.showInfo("$save.corrupted"); - show(); - } - }); - }).size(200f).get(); - b[0] = button; + button.addButton("$abandon", () -> { + ui.showConfirm("$warning", "$abandon.text", () -> { + slot.delete(); + setup(); + }); + }).growX().height(50f).pad(-12).padTop(10); - String color = "[lightgray]"; - - button.defaults().colspan(2); - button.row(); - button.add(Core.bundle.format("save.wave", color + slot.getWave())); - button.row(); - button.label(() -> Core.bundle.format("save.playtime", color + slot.getPlayTime())); - button.row(); - button.add().grow(); - button.row(); - - button.addButton("$abandon", () -> { - ui.showConfirm("$warning", "$abandon.text", () -> { - slot.delete(); - setup(); - }); - }).growX().height(50f).pad(-12).padTop(10); - } - }})).grow(); + }}, new ItemsDisplay()).grow(); } boolean hidden(Zone zone){ @@ -204,6 +103,11 @@ public class DeployDialog extends FloatingDialog{ return false; } + @Override + protected void drawBackground(float x, float y){ + drawDefaultBackground(x, y); + } + boolean canUnlock(Zone zone){ if(data.isUnlocked(zone)){ return true; @@ -223,4 +127,155 @@ public class DeployDialog extends FloatingDialog{ return data.hasItems(zone.itemRequirements); } + + void buildButton(Zone zone, TextButton button){ + button.setDisabled(() -> !canUnlock(zone) || !data.hasItems(zone.deployCost)); + button.clicked(() -> { + if(!data.isUnlocked(zone)){ + data.removeItems(zone.itemRequirements); + data.unlockContent(zone); + setup(); + }else{ + data.removeItems(zone.deployCost); + hide(); + world.playZone(zone); + } + }); + + if(zone.unlocked()){ + button.table(title -> { + title.addImage("icon-zone").padRight(3); + title.add(zone.localizedName()); + }); + button.row(); + + if(data.getWaveScore(zone) > 0){ + button.add(Core.bundle.format("bestwave", data.getWaveScore(zone))); + } + + button.row(); + + button.add("$launch").color(Color.LIGHT_GRAY).pad(4); + button.row(); + button.table(req -> { + for(ItemStack stack : zone.deployCost){ + req.addImage(stack.item.region).size(8 * 3); + req.add(stack.amount + "").left(); + } + }).pad(3).growX(); + }else{ + button.addImage("icon-zone-locked"); + button.row(); + button.add("$locked").padBottom(6); + + if(!hidden(zone)){ + button.row(); + + button.table(req -> { + req.defaults().left(); + + if(zone.zoneRequirements.length > 0){ + req.table(r -> { + r.add("$complete").colspan(2).left(); + r.row(); + for(Zone other : zone.zoneRequirements){ + r.addImage("icon-zone").padRight(4); + r.add(other.localizedName()).color(Color.LIGHT_GRAY); + r.addImage(data.isCompleted(other) ? "icon-check-2" : "icon-cancel-2") + .color(data.isCompleted(other) ? Color.LIGHT_GRAY : Color.SCARLET).padLeft(3); + r.row(); + } + }); + } + + req.row(); + + if(zone.itemRequirements.length > 0){ + req.table(r -> { + for(ItemStack stack : zone.itemRequirements){ + r.addImage(stack.item.region).size(8 * 3).padRight(4); + r.add(Math.min(data.getItem(stack.item), stack.amount) + "/" + stack.amount) + .color(stack.amount > data.getItem(stack.item) ? Color.SCARLET : Color.LIGHT_GRAY).left(); + r.row(); + } + }).padTop(10); + } + + req.row(); + + if(zone.blockRequirements.length > 0){ + req.table(r -> { + r.add("$research.list").colspan(2).left(); + r.row(); + for(Block block : zone.blockRequirements){ + r.addImage(block.icon(Icon.small)).size(8 * 3).padRight(4); + r.add(block.formalName).color(Color.LIGHT_GRAY); + r.addImage(data.isUnlocked(block) ? "icon-check-2" : "icon-cancel-2") + .color(data.isUnlocked(block) ? Color.LIGHT_GRAY : Color.SCARLET).padLeft(3); + r.row(); + } + + }).padTop(10); + } + }).growX(); + } + } + } + + //should be static variables of View, but that's impossible + static float panX = 0, panY = -200; + + class View extends Group{ + + { + for(ZoneNode node : nodes){ + TextButton button = new TextButton("", "node"); + button.setSize(nodeSize, nodeSize); + button.update(() -> { + button.setPosition(node.x + panX + width/2f, node.y + panY + height/2f, Align.center); + }); + button.clearChildren(); + buildButton(node.zone, button); + addChild(button); + } + + dragged((x, y) -> { + panX += x; + panY += y; + }); + } + + @Override + public void draw(){ + float offsetX = panX + width/2f + x, offsetY = panY + height/2f + y; + + for(ZoneNode node : nodes){ + for(ZoneNode child : node.children){ + Lines.stroke(3f, node.zone.locked() || child.zone.locked() ? Pal.locked : Pal.accent); + Lines.line(node.x + offsetX, node.y + offsetY, child.x + offsetX, child.y + offsetY); + } + } + + super.draw(); + } + } + + class ZoneNode extends TreeNode{ + final Array arr = new Array<>(); + final Zone zone; + + ZoneNode(Zone zone, ZoneNode parent){ + this.zone = zone; + this.parent = parent; + this.width = this.height = nodeSize; + nodes.add(this); + + arr.selectFrom(content.zones(), other -> Structs.contains(other.zoneRequirements, zone)); + + children = new ZoneNode[arr.size]; + for(int i = 0; i < children.length; i++){ + children[i] = new ZoneNode(arr.get(i), this); + } + } + } } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/DiscordDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/DiscordDialog.java index c064f59729..b21e875749 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/DiscordDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/DiscordDialog.java @@ -2,7 +2,7 @@ package io.anuke.mindustry.ui.dialogs; import io.anuke.arc.Core; import io.anuke.arc.graphics.Color; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.graphics.Pal; import io.anuke.arc.scene.ui.Dialog; import static io.anuke.mindustry.Vars.discordURL; @@ -33,7 +33,7 @@ public class DiscordDialog extends Dialog{ i.addImage("icon-discord").size(14 * 3); }).size(h).left(); - t.add("$discord").color(Palette.accent).growX().padLeft(10f); + t.add("$discord").color(Pal.accent).growX().padLeft(10f); }).size(470f, h).pad(10f); buttons.defaults().size(170f, 50); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/FloatingDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/FloatingDialog.java index 616780ef95..4ad7908bec 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/FloatingDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/FloatingDialog.java @@ -5,7 +5,7 @@ import io.anuke.arc.input.KeyCode; import io.anuke.arc.util.Align; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.game.EventType.ResizeEvent; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.net.Net; import io.anuke.arc.Events; import io.anuke.arc.scene.ui.Dialog; @@ -22,7 +22,7 @@ public class FloatingDialog extends Dialog{ setFillParent(true); this.title.setAlignment(Align.center); titleTable.row(); - titleTable.addImage("white", Palette.accent) + titleTable.addImage("white", Pal.accent) .growX().height(3f).pad(4f); hidden(() -> { diff --git a/core/src/io/anuke/mindustry/ui/dialogs/HostDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/HostDialog.java index 9b4a3cee80..8771012793 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/HostDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/HostDialog.java @@ -6,7 +6,7 @@ import io.anuke.arc.scene.ui.ImageButton; import io.anuke.arc.util.Strings; import io.anuke.arc.util.Time; import io.anuke.mindustry.Vars; -import io.anuke.mindustry.entities.Player; +import io.anuke.mindustry.entities.type.Player; import io.anuke.mindustry.net.Net; import java.io.IOException; diff --git a/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java index 964fc1bf6d..91a263aa7c 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java @@ -14,7 +14,7 @@ import io.anuke.arc.util.Strings; import io.anuke.arc.util.Time; import io.anuke.mindustry.Vars; import io.anuke.mindustry.core.Platform; -import io.anuke.mindustry.entities.Player; +import io.anuke.mindustry.entities.type.Player; import io.anuke.mindustry.game.Version; import io.anuke.mindustry.net.Host; import io.anuke.mindustry.net.Net; diff --git a/core/src/io/anuke/mindustry/ui/dialogs/LocalPlayerDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/LocalPlayerDialog.java index 78640d7c2d..59f23e65ec 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/LocalPlayerDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/LocalPlayerDialog.java @@ -5,7 +5,7 @@ import io.anuke.arc.scene.ui.Image; import io.anuke.arc.scene.ui.layout.Stack; import io.anuke.arc.scene.ui.layout.Table; import io.anuke.arc.util.Scaling; -import io.anuke.mindustry.entities.Player; +import io.anuke.mindustry.entities.type.Player; import static io.anuke.mindustry.Vars.control; import static io.anuke.mindustry.Vars.players; diff --git a/core/src/io/anuke/mindustry/ui/dialogs/MapsDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/MapsDialog.java index 55a1ecb84d..62cc23e37a 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/MapsDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/MapsDialog.java @@ -140,8 +140,6 @@ public class MapsDialog extends FloatingDialog{ t.add(map.meta.description()).growX().wrap().padTop(2); t.row(); t.add("$editor.oregen.info").padRight(10).color(Color.GRAY); - t.row(); - t.add(map.meta.hasOreGen() ? "$on" : "$off").padTop(2); }).height(mapsize).width(mapsize); table.row(); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/PausedDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/PausedDialog.java index b84c0e8e6d..76cb78078f 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/PausedDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/PausedDialog.java @@ -40,7 +40,7 @@ public class PausedDialog extends FloatingDialog{ cont.addButton("$back", this::hide).colspan(2).width(dw*2 + 20f); cont.row(); - cont.addButton("$database", ui.database::show); + cont.addButton("$techtree", ui.tech::show); cont.addButton("$settings", ui.settings::show); if(!world.isZone()){ diff --git a/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java index c54b1c8b3f..810bdd2e20 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java @@ -14,7 +14,7 @@ import io.anuke.arc.scene.ui.layout.Table; import io.anuke.arc.util.Align; import io.anuke.mindustry.Vars; import io.anuke.mindustry.core.GameState.State; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.net.Net; import static io.anuke.mindustry.Vars.*; @@ -49,7 +49,7 @@ public class SettingsMenuDialog extends SettingsDialog{ title.setAlignment(Align.center); titleTable.row(); titleTable.add(new Image("white")) - .growX().height(3f).pad(4f).get().setColor(Palette.accent); + .growX().height(3f).pad(4f).get().setColor(Pal.accent); cont.clearChildren(); cont.remove(); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/TechTreeDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/TechTreeDialog.java index c42d549d01..871611778c 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/TechTreeDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/TechTreeDialog.java @@ -5,14 +5,10 @@ import io.anuke.arc.collection.Array; import io.anuke.arc.collection.ObjectSet; import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.g2d.Lines; -import io.anuke.arc.input.KeyCode; import io.anuke.arc.math.Interpolation; -import io.anuke.arc.math.geom.Rectangle; import io.anuke.arc.scene.Element; import io.anuke.arc.scene.Group; import io.anuke.arc.scene.actions.Actions; -import io.anuke.arc.scene.event.InputEvent; -import io.anuke.arc.scene.event.InputListener; import io.anuke.arc.scene.event.Touchable; import io.anuke.arc.scene.style.TextureRegionDrawable; import io.anuke.arc.scene.ui.ImageButton; @@ -22,8 +18,9 @@ import io.anuke.arc.util.Log; import io.anuke.arc.util.Structs; import io.anuke.mindustry.content.TechTree; import io.anuke.mindustry.content.TechTree.TechNode; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.type.ItemStack; +import io.anuke.mindustry.ui.ItemsDisplay; import io.anuke.mindustry.ui.TreeLayout; import io.anuke.mindustry.ui.TreeLayout.TreeNode; import io.anuke.mindustry.world.Block; @@ -32,21 +29,22 @@ import io.anuke.mindustry.world.Block.Icon; import static io.anuke.mindustry.Vars.*; public class TechTreeDialog extends FloatingDialog{ + private static final float nodeSize = 60f; private ObjectSet nodes = new ObjectSet<>(); private TechTreeNode root = new TechTreeNode(TechTree.root, null); - private static final float nodeSize = 60f; + private ItemsDisplay items; public TechTreeDialog(){ super(""); - cont.setFillParent(true); - TreeLayout layout = new TreeLayout(); layout.gapBetweenLevels = 60f; layout.gapBetweenNodes = 40f; layout.layout(root); - cont.add(new View()).grow(); + titleTable.remove(); + margin(0f); + cont.stack(new View(), items = new ItemsDisplay()).grow(); { //debug code; TODO remove ObjectSet used = new ObjectSet().select(t -> true); @@ -57,9 +55,8 @@ public class TechTreeDialog extends FloatingDialog{ recipes.sort(Structs.comparing(r -> r.buildCost)); if(recipes.size > 0){ - Log.info("Recipe tree coverage: {0}%", (int)((float)nodes.size / content.blocks().select(Block::isVisible).size * 100)); - Log.info("Missing items: "); - recipes.forEach(r -> Log.info(" {0}", r)); + Log.info("Missing recipe tree items! "); + recipes.forEach(r -> Log.info("> {0}", r)); } } @@ -74,13 +71,14 @@ public class TechTreeDialog extends FloatingDialog{ } void checkNodes(TechTreeNode node){ - boolean locked = locked(node); + boolean locked = locked(node.node); if(!locked) node.visible = true; - for(TreeNode child : node.children){ - TechTreeNode l = (TechTreeNode)child; + for(TechTreeNode l : node.children){ l.visible = !locked && l.node.block.isVisible(); checkNodes(l); } + + items.rebuild(); } void showToast(String info){ @@ -106,19 +104,15 @@ public class TechTreeDialog extends FloatingDialog{ Core.scene.add(table); } - boolean locked(TreeNode node){ - return locked(((TechTreeNode)node).node); - } - boolean locked(TechNode node){ return !data.isUnlocked(node.block); } - class TechTreeNode extends TreeNode{ + class TechTreeNode extends TreeNode{ final TechNode node; boolean visible = true; - public TechTreeNode(TechNode node, TreeNode parent){ + TechTreeNode(TechNode node, TechTreeNode parent){ this.node = node; this.parent = parent; this.width = this.height = nodeSize; @@ -135,7 +129,6 @@ public class TechTreeDialog extends FloatingDialog{ class View extends Group{ float panX = 0, panY = -200; boolean moved = false; - Rectangle clip = new Rectangle(); ImageButton hoverNode; Table infoTable = new Table(); @@ -148,7 +141,7 @@ public class TechTreeDialog extends FloatingDialog{ if(mobile){ hoverNode = button; rebuild(); - }else if(data.hasItems(node.node.requirements) && locked(node)){ + }else if(data.hasItems(node.node.requirements) && locked(node.node)){ unlock(node.node); } }); @@ -159,7 +152,7 @@ public class TechTreeDialog extends FloatingDialog{ } }); button.exited(() -> { - if(hoverNode == button && !infoTable.hasMouse() && !hoverNode.hasMouse()){ + if(!mobile && hoverNode == button && !infoTable.hasMouse() && !hoverNode.hasMouse()){ hoverNode = null; rebuild(); } @@ -169,32 +162,20 @@ public class TechTreeDialog extends FloatingDialog{ button.tapped(() -> moved = false); button.setSize(nodeSize, nodeSize); button.update(() -> { - button.setPosition(node.x + panX + width/2f, node.y + panY + height/2f, Align.center); - button.getStyle().up = Core.scene.skin.getDrawable(!locked(node) ? "content-background" : "content-background-locked"); + float offset = (Core.graphics.getHeight() % 2) / 2f; + button.setPosition(node.x + panX + width/2f, node.y + panY + height/2f + offset, Align.center); + button.getStyle().up = Core.scene.skin.getDrawable(!locked(node.node) ? "content-background" : "content-background-locked"); ((TextureRegionDrawable)button.getStyle().imageUp) .setRegion(node.visible ? node.node.block.icon(Icon.medium) : Core.atlas.find("icon-tree-locked")); - button.getImage().setColor(!locked(node) ? Color.WHITE : Color.GRAY); + button.getImage().setColor(!locked(node.node) ? Color.WHITE : Color.GRAY); }); addChild(button); } - addListener(new InputListener(){ - float lastX, lastY; - @Override - public void touchDragged(InputEvent event, float mx, float my, int pointer){ - panX -= lastX - mx; - panY -= lastY - my; - lastX = mx; - lastY = my; - moved = true; - } - - @Override - public boolean touchDown(InputEvent event, float x, float y, int pointer, KeyCode button){ - lastX = x; - lastY = y; - return true; - } + dragged((x, y) -> { + moved = true; + panX += x; + panY += y; }); } @@ -271,9 +252,9 @@ public class TechTreeDialog extends FloatingDialog{ public void draw(){ float offsetX = panX + width/2f + x, offsetY = panY + height/2f + y; - for(TreeNode node : nodes){ - for(TreeNode child : node.children){ - Lines.stroke(3f, locked(node) || locked(child) ? Palette.locked : Palette.accent); + for(TechTreeNode node : nodes){ + for(TechTreeNode child : node.children){ + Lines.stroke(3f, locked(node.node) || locked(child.node) ? Pal.locked : Pal.accent); Lines.line(node.x + offsetX, node.y + offsetY, child.x + offsetX, child.y + offsetY); } diff --git a/core/src/io/anuke/mindustry/ui/fragments/BlockInventoryFragment.java b/core/src/io/anuke/mindustry/ui/fragments/BlockInventoryFragment.java index e127f8db10..31acb045d5 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/BlockInventoryFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/BlockInventoryFragment.java @@ -20,7 +20,7 @@ import io.anuke.arc.util.Align; import io.anuke.arc.util.Strings; import io.anuke.arc.util.Time; import io.anuke.mindustry.core.GameState.State; -import io.anuke.mindustry.entities.Player; +import io.anuke.mindustry.entities.type.Player; import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.input.InputHandler; import io.anuke.mindustry.type.Item; @@ -49,7 +49,7 @@ public class BlockInventoryFragment extends Fragment{ int removed = tile.block().removeStack(tile, item, amount); - player.inventory.addItem(item, removed); + player.addItem(item, removed); for(int j = 0; j < Mathf.clamp(removed / 3, 1, 8); j++){ Time.run(j * 3f, () -> Call.transferItemEffect(item, tile.drawx(), tile.drawy(), player)); } @@ -97,7 +97,7 @@ public class BlockInventoryFragment extends Fragment{ holdTime += Time.delta(); if(holdTime >= holdWithdraw){ - int amount = Math.min(tile.entity.items.get(lastItem), player.inventory.itemCapacityUsed(lastItem)); + int amount = Math.min(tile.entity.items.get(lastItem), player.maxAccepted(lastItem)); Call.requestItem(player, tile, lastItem, amount); holding = false; holdTime = 0f; @@ -130,7 +130,7 @@ public class BlockInventoryFragment extends Fragment{ container.add(i); - BooleanProvider canPick = () -> player.inventory.canAcceptItem(item); + BooleanProvider canPick = () -> player.acceptsItem(item); HandCursorListener l = new HandCursorListener(); l.setEnabled(canPick); @@ -147,7 +147,7 @@ public class BlockInventoryFragment extends Fragment{ @Override public boolean touchDown(InputEvent event, float x, float y, int pointer, KeyCode button){ if(!canPick.get() || !tile.entity.items.has(item)) return false; - int amount = Math.min(1, player.inventory.itemCapacityUsed(item)); + int amount = Math.min(1, player.maxAccepted(item)); Call.requestItem(player, tile, item, amount); lastItem = item; holding = true; diff --git a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java index ee0f2a0e29..3691589184 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java @@ -16,21 +16,22 @@ import io.anuke.arc.scene.ui.TextButton; import io.anuke.arc.scene.ui.layout.Stack; import io.anuke.arc.scene.ui.layout.Table; import io.anuke.arc.scene.ui.layout.Unit; -import io.anuke.arc.util.Align; -import io.anuke.arc.util.Scaling; -import io.anuke.arc.util.Time; +import io.anuke.arc.scene.utils.Elements; +import io.anuke.arc.util.*; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.game.EventType.StateChangeEvent; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.game.UnlockableContent; import io.anuke.mindustry.gen.Call; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.input.Binding; import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.Packets.AdminAction; import io.anuke.mindustry.ui.IntFormat; import io.anuke.mindustry.ui.dialogs.FloatingDialog; +import java.lang.StringBuilder; + import static io.anuke.mindustry.Vars.*; public class HudFragment extends Fragment{ @@ -53,7 +54,6 @@ public class HudFragment extends Fragment{ //menu at top left parent.fill(cont -> { - cont.top().left().visible(() -> !state.is(State.menu)); if(mobile){ @@ -97,11 +97,11 @@ public class HudFragment extends Fragment{ } }).get(); - select.addImage("blank").color(Palette.accent).width(6f).fillY(); + select.addImage("blank").color(Pal.accent).width(6f).fillY(); }); cont.row(); - cont.addImage("blank").height(6f).color(Palette.accent).fillX(); + cont.addImage("blank").height(6f).color(Pal.accent).fillX(); cont.row(); } @@ -146,10 +146,29 @@ public class HudFragment extends Fragment{ //minimap //parent.fill(t -> t.top().right().add(new Minimap()).visible(() -> !state.is(State.menu) && Core.settings.getBool("minimap"))); - //paused table + //spawner warning parent.fill(t -> { - t.top().visible(() -> state.is(State.paused) && !Net.active()); - t.table("button", top -> top.add("$paused").pad(6f)); + t.touchable(Touchable.disabled); + t.visible(() -> !state.is(State.menu)); + t.table("flat", c -> c.add("$nearpoint") + .update(l -> l.setColor(Tmp.c1.set(Color.WHITE).lerp(Color.SCARLET, Mathf.absin(Time.time(), 10f, 1f)))) + .get().setAlignment(Align.center, Align.center)) + .margin(6).update(u -> { + u.color.a = Mathf.lerpDelta(u.color.a, Mathf.num(world.spawner.playerNear()), 0.1f); + }).get().color.a = 0f; + }); + + //out of bounds warning + parent.fill(t -> { + t.touchable(Touchable.disabled); + t.visible(() -> !state.is(State.menu)); + t.table("flat", c -> c.add("") + .update(l ->{ + l.setColor(Tmp.c1.set(Color.WHITE).lerp(Color.SCARLET, Mathf.absin(Time.time(), 10f, 1f))); + l.setText(Core.bundle.format("outofbounds", (int)((boundsCountdown - players[0].destructTime) / 60f))); + }).get().setAlignment(Align.center, Align.center)).margin(6).update(u -> { + u.color.a = Mathf.lerpDelta(u.color.a, Mathf.num(players[0].isOutOfBounds()), 0.1f); + }).get().color.a = 0f; }); parent.fill(t -> { @@ -196,8 +215,44 @@ public class HudFragment extends Fragment{ .update(label -> label.getColor().set(Color.ORANGE).lerp(Color.SCARLET, Mathf.absin(Time.time(), 2f, 1f)))); }); - parent.fill(t -> t.top().right().addRowImageTextButton("$launch", "icon-arrow-up", 8*3, () -> world.launchZone()) - .size(94f, 70f).visible(() -> world.isZone() && world.getZone().metCondition())); + //launch button + parent.fill(t -> { + t.top().visible(() -> !state.is(State.menu)); + + TextButton button = Elements.newButton("$launch", () -> ui.showConfirm("$launch", "$launch.confirm", Call::launchZone)); + + button.getStyle().disabledFontColor = Color.WHITE; + button.visible(() -> + world.isZone() && + world.getZone().metCondition() && + !Net.client() && + state.wave % world.getZone().launchPeriod == 0); + + button.update(() -> { + if(world.getZone() == null){ + button.setText(""); + return; + } + + button.setText(Core.bundle.get(state.enemies() > 0 ? "launch.unable" : "launch") + "\n" + + Core.bundle.format("launch.next", state.wave + world.getZone().launchPeriod)); + + button.getLabel().setColor(Tmp.c1.set(Color.WHITE).lerp(state.enemies() > 0 ? Color.WHITE : Pal.accent, + Mathf.absin(Time.time(), 7f, 1f))); + }); + + button.setDisabled(() -> state.enemies() > 0); + + button.getLabelCell().left().get().setAlignment(Align.left, Align.left); + + t.add(button).size(350f, 80f); + }); + + //paused table + parent.fill(t -> { + t.top().visible(() -> state.is(State.paused) && !Net.active()); + t.table("button", top -> top.add("$paused").pad(6f)); + }); //'saving' indicator parent.fill(t -> { diff --git a/core/src/io/anuke/mindustry/ui/fragments/LoadingFragment.java b/core/src/io/anuke/mindustry/ui/fragments/LoadingFragment.java index 031077b367..2b178a2125 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/LoadingFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/LoadingFragment.java @@ -1,6 +1,6 @@ package io.anuke.mindustry.ui.fragments; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.graphics.Pal; import io.anuke.arc.scene.Group; import io.anuke.arc.scene.event.Touchable; import io.anuke.arc.scene.ui.Label; @@ -18,11 +18,11 @@ public class LoadingFragment extends Fragment{ t.touchable(Touchable.enabled); t.add().height(70f).row(); - t.addImage("white").growX().height(3f).pad(4f).growX().get().setColor(Palette.accent); + t.addImage("white").growX().height(3f).pad(4f).growX().get().setColor(Pal.accent); t.row(); t.add("$loading").name("namelabel").pad(10f); t.row(); - t.addImage("white").growX().height(3f).pad(4f).growX().get().setColor(Palette.accent); + t.addImage("white").growX().height(3f).pad(4f).growX().get().setColor(Pal.accent); t.row(); button = t.addButton("$cancel", () -> {}).pad(20).size(250f, 70f).visible(false).get(); diff --git a/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java b/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java index f1bc3facb7..58c4354f4c 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java @@ -11,6 +11,7 @@ import io.anuke.mindustry.game.EventType.ResizeEvent; import io.anuke.mindustry.game.Version; import io.anuke.mindustry.ui.MenuButton; import io.anuke.mindustry.ui.MobileButton; +import io.anuke.mindustry.ui.dialogs.FloatingDialog; import static io.anuke.mindustry.Vars.*; @@ -56,19 +57,19 @@ public class MenuFragment extends Fragment{ container.defaults().size(size).pad(5).padTop(4f); MobileButton - play = new MobileButton("icon-play-2", isize, "$play", this::showPlaySelect), + play = new MobileButton("icon-play-2", isize, "$play", ui.deploy::show), maps = new MobileButton("icon-map", isize, "$maps", ui.maps::show), - load = new MobileButton("icon-load", isize, "$load", ui.load::show), + custom = new MobileButton("icon-play-custom", isize, "$customgame", this::showCustomSelect), join = new MobileButton("icon-add", isize, "$joingame", ui.join::show), editor = new MobileButton("icon-editor", isize, "$editor", () -> ui.loadAnd(ui.editor::show)), tools = new MobileButton("icon-tools", isize, "$settings", ui.settings::show), - unlocks = new MobileButton("icon-unlocks", isize, "database", ui.database::show), + unlocks = new MobileButton("icon-unlocks", isize, "$database", ui.database::show), donate = new MobileButton("icon-donate", isize, "$donate", Platform.instance::openDonations); if(Core.graphics.getWidth() > Core.graphics.getHeight()){ container.add(play); container.add(join); - container.add(load); + container.add(custom); container.add(maps); container.row(); @@ -85,7 +86,7 @@ public class MenuFragment extends Fragment{ container.add(play); container.add(maps); container.row(); - container.add(load); + container.add(custom); container.add(join); container.row(); container.add(editor); @@ -111,7 +112,13 @@ public class MenuFragment extends Fragment{ out.margin(16); out.defaults().size(w, 66f).padTop(5).padRight(5); - out.add(new MenuButton("icon-play-2", "$play", MenuFragment.this::showPlaySelect)).width(bw).colspan(2); + out.add(new MenuButton("icon-play-2", "$play", ui.deploy::show)).width(bw).colspan(2); + + out.row(); + + out.add(new MenuButton("icon-add", "$joingame", ui.join::show)); + + out.add(new MenuButton("icon-play-custom", "$customgame", this::showCustomSelect)); out.row(); @@ -131,40 +138,20 @@ public class MenuFragment extends Fragment{ }); } - private void showPlaySelect(){ - ui.deploy.show(); - - /* - float w = 220f; - float bw = w * 2f + 10f; - + private void showCustomSelect(){ FloatingDialog dialog = new FloatingDialog("$play"); + dialog.setFillParent(false); dialog.addCloseButton(); - dialog.cont.defaults().height(66f).width(w).padRight(5f); - - dialog.cont.add(new MenuButton("icon-play-2", "$map.random", () -> { - dialog.hide(); - world.generator.playRandomMap(); - })).width(bw).colspan(2); - dialog.cont.row(); - - dialog.cont.add(new MenuButton("icon-add", "$joingame", () -> { - ui.join.show(); + dialog.cont.defaults().size(230f, 64f); + dialog.cont.add(new MenuButton("icon-editor", "$newgame", () -> { dialog.hide(); + ui.custom.show(); })); - - dialog.cont.add(new MenuButton("icon-editor", "$customgame", () -> { - dialog.hide(); - ui.levels.show(); - })); - dialog.cont.row(); - dialog.cont.add(new MenuButton("icon-load", "$loadgame", () -> { ui.load.show(); dialog.hide(); - })).width(bw).colspan(2); - - dialog.show();*/ + })); + dialog.show(); } } diff --git a/core/src/io/anuke/mindustry/ui/fragments/PlacementFragment.java b/core/src/io/anuke/mindustry/ui/fragments/PlacementFragment.java index 32a3fa7ecb..53d45737b4 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/PlacementFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/PlacementFragment.java @@ -15,9 +15,10 @@ import io.anuke.arc.scene.ui.Image; import io.anuke.arc.scene.ui.ImageButton; import io.anuke.arc.scene.ui.layout.Table; import io.anuke.mindustry.core.GameState.State; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.TileEntity; +import io.anuke.mindustry.game.EventType.UnlockEvent; import io.anuke.mindustry.game.EventType.WorldLoadEvent; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.input.Binding; import io.anuke.mindustry.input.InputHandler; import io.anuke.mindustry.type.Category; @@ -33,6 +34,8 @@ public class PlacementFragment extends Fragment{ final int rowWidth = 4; Array returnArray = new Array<>(); + Array returnCatArray = new Array<>(); + boolean[] categoryEmpty = new boolean[Category.values().length]; Category currentCategory = Category.distribution; Block hovered, lastDisplay; Tile lastHover; @@ -56,14 +59,41 @@ public class PlacementFragment extends Fragment{ public PlacementFragment(){ Events.on(WorldLoadEvent.class, event -> { - currentCategory = Category.turret; - Group group = toggler.getParent(); - toggler.remove(); - build(group); + control.input(0).block = null; + rebuild(); + }); + + Events.on(UnlockEvent.class, event -> { + if(event.content instanceof Block){ + rebuild(); + } }); } + void rebuild(){ + currentCategory = Category.turret; + Group group = toggler.getParent(); + int index = toggler.getZIndex(); + toggler.remove(); + build(group); + toggler.setZIndex(index); + } + boolean gridUpdate(InputHandler input){ + if(Core.input.keyDown(Binding.pick)){ //mouse eyedropper select + Tile tile = world.tileWorld(Core.input.mouseWorld().x, Core.input.mouseWorld().y); + + if(tile != null){ + tile = tile.target(); + Block tryRecipe = tile.block(); + if(tryRecipe.isVisible() && unlocked(tryRecipe)){ + input.block = tryRecipe; + currentCategory = input.block.buildCategory; + return true; + } + } + } + if(!Core.input.keyDown(Binding.gridMode) || ui.chatfrag.chatOpen()) return false; if(Core.input.keyDown(Binding.gridModeShift)){ //select category int i = 0; @@ -75,24 +105,12 @@ public class PlacementFragment extends Fragment{ i++; } return true; - }else if(Core.input.keyDown(Binding.select)){ //mouse eyedropper select - Tile tile = world.tileWorld(Core.input.mouseWorld().x, Core.input.mouseWorld().y); - - if(tile != null){ - tile = tile.target(); - Block tryRecipe = tile.block(); - if(tryRecipe.isVisible() && data.isUnlocked(tryRecipe)){ - input.block = tryRecipe; - currentCategory = input.block.buildCategory; - return true; - } - } }else{ //select block int i = 0; Array recipes = getByCategory(currentCategory); for(KeyCode key : inputGrid){ if(Core.input.keyDown(key)) - input.block = (i < recipes.size && data.isUnlocked(recipes.get(i))) ? recipes.get(i) : null; + input.block = (i < recipes.size && unlocked(recipes.get(i))) ? recipes.get(i) : null; i++; } } @@ -119,34 +137,28 @@ public class PlacementFragment extends Fragment{ group.setMinCheckCount(0); for(Block block : getByCategory(currentCategory)){ - if(index++ % rowWidth == 0){ blockTable.row(); } - boolean[] unlocked = {false}; + if(!unlocked(block)){ + blockTable.add().size(46); + continue; + } ImageButton button = blockTable.addImageButton("icon-locked", "select", 8 * 4, () -> { - if(data.isUnlocked(block)){ + if(unlocked(block)){ input.block = input.block == block ? null : block; } }).size(46f).group(group).get(); + button.replaceImage(new Image(block.icon(Icon.medium))); + button.update(() -> { //color unplacable things gray - boolean ulock = data.isUnlocked(block); TileEntity core = players[0].getClosestCore(); - Color color = core != null && (core.items.has(block.buildRequirements) || state.rules.infiniteResources) ? Color.WHITE : ulock ? Color.GRAY : Color.WHITE; + Color color = core != null && (core.items.has(block.buildRequirements) || state.rules.infiniteResources) ? Color.WHITE : Color.GRAY; button.forEach(elem -> elem.setColor(color)); button.setChecked(input.block == block); - - if(ulock == unlocked[0]) return; - unlocked[0] = ulock; - - if(!ulock){ - button.replaceImage(new Image("icon-locked")); - }else{ - button.replaceImage(new Image(block.icon(Icon.medium))); - } }); button.hovered(() -> hovered = block); @@ -181,10 +193,10 @@ public class PlacementFragment extends Fragment{ topTable.table(header -> { header.left(); header.add(new Image(lastDisplay.icon(Icon.medium))).size(8 * 4); - header.labelWrap(() -> !data.isUnlocked(lastDisplay) ? Core.bundle.get("blocks.unknown") : lastDisplay.formalName) + header.labelWrap(() -> !unlocked(lastDisplay) ? Core.bundle.get("blocks.unknown") : lastDisplay.formalName) .left().width(190f).padLeft(5); header.add().growX(); - if(data.isUnlocked(lastDisplay)){ + if(unlocked(lastDisplay)){ header.addButton("?", "clear-partial", () -> ui.content.show(lastDisplay)) .size(8 * 5).padTop(-5).padRight(-5).right().grow(); } @@ -231,7 +243,7 @@ public class PlacementFragment extends Fragment{ }); }).colspan(3).fillX().visible(() -> getSelected() != null || tileDisplayBlock() != null).touchable(Touchable.enabled); frame.row(); - frame.addImage("blank").color(Palette.accent).colspan(3).height(3).growX(); + frame.addImage("blank").color(Pal.accent).colspan(3).height(3).growX(); frame.row(); frame.table("pane-2", blocksSelect -> { blocksSelect.margin(4).marginTop(0); @@ -244,15 +256,25 @@ public class PlacementFragment extends Fragment{ ButtonGroup group = new ButtonGroup<>(); + //update category empty values for(Category cat : Category.values()){ - if(getByCategory(cat).isEmpty()) continue; + Array blocks = getByCategory(cat); + categoryEmpty[cat.ordinal()] = blocks.isEmpty() || !unlocked(blocks.first()); + } + + int f = 0; + for(Category cat : getCategories()){ + if(f++ % 2 == 0) categories.row(); + + if(categoryEmpty[cat.ordinal()]){ + categories.addImage("flat"); + continue; + } categories.addImageButton("icon-" + cat.name(), "clear-toggle", 16 * 2, () -> { currentCategory = cat; rebuildCategory.run(); }).group(group).update(i -> i.setChecked(currentCategory == cat)); - - if(cat.ordinal() % 2 == 1) categories.row(); } }).touchable(Touchable.enabled); @@ -263,6 +285,13 @@ public class PlacementFragment extends Fragment{ }); }); } + + Array getCategories(){ + returnCatArray.clear(); + returnCatArray.addAll(Category.values()); + returnCatArray.sort((c1, c2) -> Boolean.compare(categoryEmpty[c1.ordinal()], categoryEmpty[c2.ordinal()])); + return returnCatArray; + } Array getByCategory(Category cat){ returnArray.clear(); @@ -271,9 +300,14 @@ public class PlacementFragment extends Fragment{ returnArray.add(block); } } + returnArray.sort((b1, b2) -> -Boolean.compare(unlocked(b1), unlocked(b2))); return returnArray; } + boolean unlocked(Block block){ + return !world.isZone() || data.isUnlocked(block); + } + /** Returns the currently displayed block in the top box. */ Block getSelected(){ Block toDisplay = null; diff --git a/core/src/io/anuke/mindustry/ui/fragments/PlayerListFragment.java b/core/src/io/anuke/mindustry/ui/fragments/PlayerListFragment.java index bea91a8001..dbad24b6a6 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/PlayerListFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/PlayerListFragment.java @@ -11,7 +11,7 @@ import io.anuke.arc.scene.ui.layout.Unit; import io.anuke.arc.util.Interval; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.gen.Call; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.NetConnection; import io.anuke.mindustry.net.Packets.AdminAction; @@ -82,7 +82,7 @@ public class PlayerListFragment extends Fragment{ @Override public void draw(){ super.draw(); - Draw.color(Palette.accent); + Draw.color(Pal.accent); Draw.alpha(parentAlpha); Lines.stroke(Unit.dp.scl(3f)); Lines.rect(x, y, width, height); @@ -136,7 +136,7 @@ public class PlayerListFragment extends Fragment{ content.add(button).padBottom(-6).width(350f).maxHeight(h + 14); content.row(); - content.addImage("blank").height(3f).color(state.rules.pvp ? player.getTeam().color : Palette.accent).growX(); + content.addImage("blank").height(3f).color(state.rules.pvp ? player.getTeam().color : Pal.accent).growX(); content.row(); }); diff --git a/core/src/io/anuke/mindustry/world/Block.java b/core/src/io/anuke/mindustry/world/Block.java index 49b3bd2d3a..a9016972ee 100644 --- a/core/src/io/anuke/mindustry/world/Block.java +++ b/core/src/io/anuke/mindustry/world/Block.java @@ -5,7 +5,6 @@ import io.anuke.arc.Graphics.Cursor; import io.anuke.arc.Graphics.Cursor.SystemCursor; import io.anuke.arc.collection.Array; import io.anuke.arc.collection.EnumSet; -import io.anuke.arc.collection.IntArray; import io.anuke.arc.function.BooleanProvider; import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.g2d.Draw; @@ -13,18 +12,20 @@ import io.anuke.arc.graphics.g2d.Lines; import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.math.Mathf; import io.anuke.arc.scene.ui.layout.Table; +import io.anuke.arc.util.Log; +import io.anuke.arc.util.Strings; import io.anuke.arc.util.Time; import io.anuke.mindustry.entities.Damage; -import io.anuke.mindustry.entities.Player; -import io.anuke.mindustry.entities.TileEntity; -import io.anuke.mindustry.entities.Unit; +import io.anuke.mindustry.entities.type.Player; +import io.anuke.mindustry.entities.type.TileEntity; +import io.anuke.mindustry.entities.type.Unit; import io.anuke.mindustry.entities.bullet.Bullet; import io.anuke.mindustry.entities.effect.Puddle; import io.anuke.mindustry.entities.effect.RubbleDecal; import io.anuke.mindustry.game.UnlockableContent; import io.anuke.mindustry.graphics.CacheLayer; import io.anuke.mindustry.graphics.Layer; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.type.Category; import io.anuke.mindustry.type.ContentType; import io.anuke.mindustry.type.Item; @@ -89,17 +90,20 @@ public class Block extends BlockStorage{ /** The block group. Unless {@link #canReplace} is overriden, blocks in the same group can replace each other. */ public BlockGroup group = BlockGroup.none; /** List of block flags. Used for AI indexing. */ - public EnumSet flags; + public EnumSet flags = EnumSet.of(); /** Whether the block can be tapped and selected to configure. */ public boolean configurable; /** Whether this block consumes touchDown events when tapped. */ public boolean consumesTap; - /** The color of this block when displayed on the minimap or map preview. */ - public Color minimapColor = Color.CLEAR; + /** The color of this block when displayed on the minimap or map preview. + * Do not set manually! This is overriden when loading for most blocks.*/ + public Color color = new Color(0, 0, 0, 1); /**Whether units target this block.*/ public boolean targetable = true; /**Whether the overdrive core has any effect on this block.*/ public boolean canOverdrive = true; + /**Whether the icon region has an outline added.*/ + public boolean outlineIcon = false; /**Cost of constructing this block.*/ public ItemStack[] buildRequirements = new ItemStack[]{}; @@ -114,6 +118,7 @@ public class Block extends BlockStorage{ protected Array tempTiles = new Array<>(); protected TextureRegion[] icons = new TextureRegion[Icon.values().length]; protected TextureRegion[] generatedIcons; + protected TextureRegion[] variantRegions; protected TextureRegion region; public Block(String name){ @@ -211,6 +216,12 @@ public class Block extends BlockStorage{ draw(tile); } + public void drawTeam(Tile tile){ + Draw.color(tile.getTeam().color); + Draw.rect("block-border", tile.drawx() - size * tilesize/2f + 4, tile.drawy() - size * tilesize/2f + 4); + Draw.color(); + } + /** Called after the block is placed by this client. */ public void playerPlaced(Tile tile){ } @@ -226,6 +237,11 @@ public class Block extends BlockStorage{ public void unitOn(Tile tile, Unit unit){ } + /** Called when a unit that spawned at this tile is removed.*/ + public void unitRemoved(Tile tile, Unit unit){ + + } + /** Returns whether ot not this block can be place on the specified tile. */ public boolean canPlaceOn(Tile tile){ return true; @@ -245,7 +261,7 @@ public class Block extends BlockStorage{ @Override public TextureRegion getContentIcon(){ - return icon(Icon.large); + return icon(Icon.medium); } @Override @@ -279,6 +295,10 @@ public class Block extends BlockStorage{ setStats(); consumes.checkRequired(this); + + if(buildRequirements.length > 0 && !Core.bundle.has("block." + name + ".name")){ + Log.warn("No name for block '{0}' found. Add the following to bundle.properties:\nblock.{0}.name = {1}", name, Strings.capitalize(name)); + } } @Override @@ -286,19 +306,6 @@ public class Block extends BlockStorage{ region = Core.atlas.find(name); } - /**Called when the world is resized. - * Call super!*/ - public void transformLinks(Tile tile, int oldWidth, int oldHeight, int newWidth, int newHeight, int shiftX, int shiftY){ - if(tile.entity != null && tile.entity.power != null){ - IntArray links = tile.entity.power.links; - IntArray out = new IntArray(); - for(int i = 0; i < links.size; i++){ - out.add(world.transform(links.get(i), oldWidth, oldHeight, newWidth, shiftX, shiftY)); - } - tile.entity.power.links = out; - } - } - /** Called when the block is tapped. */ public void tapped(Tile tile, Player player){ @@ -339,7 +346,7 @@ public class Block extends BlockStorage{ } public void drawConfigure(Tile tile){ - Draw.color(Palette.accent); + Draw.color(Pal.accent); Lines.stroke(1f); Lines.square(tile.drawx(), tile.drawy(), tile.block().size * tilesize / 2f + 1f); Draw.reset(); @@ -392,11 +399,10 @@ public class Block extends BlockStorage{ float power = 0f; if(hasItems){ - float scaling = inventoryScaling(tile); for(Item item : content.items()){ int amount = tile.entity.items.get(item); - explosiveness += item.explosiveness * amount * scaling; - flammability += item.flammability * amount * scaling; + explosiveness += item.explosiveness * amount; + flammability += item.flammability * amount; } } @@ -425,17 +431,12 @@ public class Block extends BlockStorage{ }); } - Damage.dynamicExplosion(x, y, flammability, explosiveness, power, tilesize * size / 2f, Palette.darkFlame); + Damage.dynamicExplosion(x, y, flammability, explosiveness, power, tilesize * size / 2f, Pal.darkFlame); if(!tile.floor().solid && !tile.floor().isLiquid){ RubbleDecal.create(tile.drawx(), tile.drawy(), size); } } - /**Returns scaled # of inventories in this block.*/ - public float inventoryScaling(Tile tile){ - return 1f; - } - /** * Returns the flammability of the tile. Used for fire calculations. * Takes flammability of floor liquid into account. @@ -482,18 +483,23 @@ public class Block extends BlockStorage{ public void displayBars(Tile tile, Table bars){ TileEntity entity = tile.entity; - bars.add(new Bar("blocks.health", Palette.health, entity::healthf).blink(Color.WHITE)); + bars.add(new Bar("blocks.health", Pal.health, entity::healthf).blink(Color.WHITE)); bars.row(); if(entity.liquids != null){ - bars.add(new Bar(() -> entity.liquids.current().localizedName(), () -> entity.liquids.current().color, () -> entity.liquids.total() / liquidCapacity)).growX(); + bars.add(new Bar(() -> entity.liquids.get(entity.liquids.current()) <= 0.001f ? Core.bundle.get("blocks.liquid") : entity.liquids.current().localizedName(), () -> entity.liquids.current().color, () -> entity.liquids.total() / liquidCapacity)).growX(); + bars.row(); + } + + if(entity.power != null && consumes.has(ConsumePower.class)){ + bars.add(new Bar(consumes.get(ConsumePower.class).isBuffered ? "blocks.power" : "blocks.power.satisfaction", Pal.power, () -> entity.power.satisfaction)).growX(); bars.row(); } } public TextureRegion icon(Icon icon){ if(icons[icon.ordinal()] == null){ - icons[icon.ordinal()] = Core.atlas.find(name + "-icon-" + icon.name()); + icons[icon.ordinal()] = Core.atlas.find(name + "-icon-" + icon.name(), icon == Icon.full ? getGeneratedIcons()[0] : Core.atlas.find(name + "-icon-full", getGeneratedIcons()[0])); } return icons[icon.ordinal()]; } @@ -509,6 +515,13 @@ public class Block extends BlockStorage{ return generatedIcons; } + public TextureRegion[] variantRegions(){ + if(variantRegions == null){ + variantRegions = new TextureRegion[]{icon(Icon.full)}; + } + return variantRegions; + } + public boolean hasEntity(){ return destructible || update; } diff --git a/core/src/io/anuke/mindustry/world/BlockStorage.java b/core/src/io/anuke/mindustry/world/BlockStorage.java index 573aad8593..398d533011 100644 --- a/core/src/io/anuke/mindustry/world/BlockStorage.java +++ b/core/src/io/anuke/mindustry/world/BlockStorage.java @@ -1,14 +1,14 @@ package io.anuke.mindustry.world; import io.anuke.arc.collection.Array; -import io.anuke.arc.entities.Effects; +import io.anuke.mindustry.entities.Effects; import io.anuke.arc.math.Mathf; import io.anuke.arc.math.geom.Vector2; import io.anuke.arc.util.Time; import io.anuke.mindustry.Vars; import io.anuke.mindustry.content.Fx; -import io.anuke.mindustry.entities.TileEntity; -import io.anuke.mindustry.entities.Unit; +import io.anuke.mindustry.entities.type.TileEntity; +import io.anuke.mindustry.entities.type.Unit; import io.anuke.mindustry.entities.effect.Puddle; import io.anuke.mindustry.game.UnlockableContent; import io.anuke.mindustry.type.Item; @@ -33,9 +33,9 @@ public abstract class BlockStorage extends UnlockableContent{ public float liquidCapacity = 10f; public float liquidFlowFactor = 4.9f; - public BlockStats stats = new BlockStats(); - public Consumers consumes = new Consumers(); - public Producers produces = new Producers(); + public final BlockStats stats = new BlockStats(); + public final Consumers consumes = new Consumers(); + public final Producers produces = new Producers(); public boolean shouldConsume(Tile tile){ return true; diff --git a/core/src/io/anuke/mindustry/world/ColorMapper.java b/core/src/io/anuke/mindustry/world/ColorMapper.java deleted file mode 100644 index e2319a3c64..0000000000 --- a/core/src/io/anuke/mindustry/world/ColorMapper.java +++ /dev/null @@ -1,39 +0,0 @@ -package io.anuke.mindustry.world; - -import io.anuke.arc.collection.IntMap; -import io.anuke.arc.collection.ObjectIntMap; -import io.anuke.arc.graphics.Color; -import io.anuke.mindustry.game.ContentList; -import io.anuke.mindustry.game.Team; - -import static io.anuke.mindustry.Vars.content; - -public class ColorMapper implements ContentList{ - private static IntMap blockMap = new IntMap<>(); - private static ObjectIntMap colorMap = new ObjectIntMap<>(); - private static ThreadLocal tmpColors = new ThreadLocal<>(); - - private static int getBlockColor(Block block){ - return colorMap.get(block, 0); - } - - public static int colorFor(Block floor, Block wall, Team team){ - if(wall.synthetic()){ - return team.intColor; - } - int color = getBlockColor(wall); - if(color == 0) color = ColorMapper.getBlockColor(floor); - return color; - } - - @Override - public void load(){ - for(Block block : content.blocks()){ - int color = Color.rgba8888(block.minimapColor); - if(color == 0) continue; //skip blocks that are not mapped - - blockMap.put(color, block); - colorMap.put(block, color); - } - } -} diff --git a/core/src/io/anuke/mindustry/world/LegacyColorMapper.java b/core/src/io/anuke/mindustry/world/LegacyColorMapper.java index 076e6a27f7..2edadf36c7 100644 --- a/core/src/io/anuke/mindustry/world/LegacyColorMapper.java +++ b/core/src/io/anuke/mindustry/world/LegacyColorMapper.java @@ -20,36 +20,35 @@ public class LegacyColorMapper implements ContentList{ public void load(){ defaultValue = new LegacyBlock(Blocks.stone, Blocks.air); - map("ff0000", Blocks.dirt, 0); - map("00ff00", Blocks.stone, 0); - map("323232", Blocks.stone, 0); - map("646464", Blocks.stone, 1); - map("50965a", Blocks.grass, 0); - map("5ab464", Blocks.grass, 1); - map("506eb4", Blocks.water, 0); - map("465a96", Blocks.deepwater, 0); - map("252525", Blocks.blackstone, 0); - map("575757", Blocks.blackstone, 1); - map("988a67", Blocks.sand, 0); - map("e5d8bb", Blocks.sand, 1); - map("c2d1d2", Blocks.snow, 0); - map("c4e3e7", Blocks.ice, 0); - map("f7feff", Blocks.snow, 1); - map("6e501e", Blocks.dirt, 0); - map("ed5334", Blocks.blackstone, 0); - map("292929", Blocks.tar, 0); - map("c3a490", OreBlock.get(Blocks.stone, Items.copper), 0); - map("161616", OreBlock.get(Blocks.stone, Items.coal), 0); - map("6277bc", OreBlock.get(Blocks.stone, Items.titanium), 0); - map("83bc58", OreBlock.get(Blocks.stone, Items.thorium), 0); + map("ff0000", Blocks.stainedStone, Blocks.spawn); + map("00ff00", Blocks.stone); + map("323232", Blocks.stone); + map("646464", Blocks.stone, Blocks.rocks); + map("50965a", Blocks.stainedStone); + map("5ab464", Blocks.stainedStone, Blocks.stainedRocks); + map("506eb4", Blocks.water); + map("465a96", Blocks.deepwater); + map("252525", Blocks.ignarock); + map("575757", Blocks.ignarock, Blocks.duneRocks); + map("988a67", Blocks.sand); + map("e5d8bb", Blocks.sand, Blocks.duneRocks); + map("c2d1d2", Blocks.snow); + map("c4e3e7", Blocks.ice); + map("f7feff", Blocks.snow, Blocks.snowrocks); + map("6e501e", Blocks.stainedStone); + map("ed5334", Blocks.stainedStoneRed); + map("292929", Blocks.tar); + map("c3a490", OreBlock.get(Blocks.stone, Items.copper)); + map("161616", OreBlock.get(Blocks.stone, Items.coal)); + map("6277bc", OreBlock.get(Blocks.stone, Items.titanium)); + map("83bc58", OreBlock.get(Blocks.stone, Items.thorium)); } private void map(String color, Block block, Block wall){ blockMap.put(Color.rgba8888(Color.valueOf(color)), new LegacyBlock(block, wall)); } - //todo fix this, implement proper mapping w/ walls - private void map(String color, Block block, int __TODO_fix_this){ + private void map(String color, Block block){ blockMap.put(Color.rgba8888(Color.valueOf(color)), new LegacyBlock(block, Blocks.air)); } diff --git a/core/src/io/anuke/mindustry/world/Tile.java b/core/src/io/anuke/mindustry/world/Tile.java index 7ce5e6453f..2f35604c31 100644 --- a/core/src/io/anuke/mindustry/world/Tile.java +++ b/core/src/io/anuke/mindustry/world/Tile.java @@ -2,13 +2,14 @@ package io.anuke.mindustry.world; import io.anuke.arc.collection.Array; import io.anuke.arc.function.Consumer; +import io.anuke.arc.math.Mathf; import io.anuke.arc.math.geom.Geometry; import io.anuke.arc.math.geom.Point2; import io.anuke.arc.math.geom.Position; import io.anuke.arc.math.geom.Vector2; import io.anuke.arc.util.Pack; import io.anuke.mindustry.content.Blocks; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.entities.traits.TargetTrait; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.world.blocks.BlockPart; @@ -330,11 +331,11 @@ public class Tile implements Position, TargetTrait{ } if(target().synthetic()){ - cost += target().block().health / 10f; + cost += Mathf.clamp(target().block().health / 10f, 0, 28); } if(floor.isLiquid){ - cost += 100f; + cost += 80; } } diff --git a/core/src/io/anuke/mindustry/world/blocks/BuildBlock.java b/core/src/io/anuke/mindustry/world/blocks/BuildBlock.java index a6ca205ce3..3296b08f4e 100644 --- a/core/src/io/anuke/mindustry/world/blocks/BuildBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/BuildBlock.java @@ -6,21 +6,21 @@ import io.anuke.arc.Core; import io.anuke.arc.Events; import io.anuke.arc.Graphics.Cursor; import io.anuke.arc.Graphics.Cursor.SystemCursor; -import io.anuke.arc.entities.Effects; import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.math.Mathf; import io.anuke.mindustry.content.Fx; -import io.anuke.mindustry.entities.Player; -import io.anuke.mindustry.entities.TileEntity; -import io.anuke.mindustry.entities.Unit; +import io.anuke.mindustry.entities.Effects; import io.anuke.mindustry.entities.effect.RubbleDecal; import io.anuke.mindustry.entities.traits.BuilderTrait.BuildRequest; +import io.anuke.mindustry.entities.type.Player; +import io.anuke.mindustry.entities.type.TileEntity; +import io.anuke.mindustry.entities.type.Unit; import io.anuke.mindustry.game.EventType.BlockBuildEndEvent; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.graphics.Layer; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.graphics.Shaders; import io.anuke.mindustry.type.ItemStack; import io.anuke.mindustry.world.Block; @@ -124,7 +124,9 @@ public class BuildBlock extends Block{ if(entity.previous == null) return; - Draw.rect(entity.previous.icon(Icon.full), tile.drawx(), tile.drawy(), entity.previous.rotate ? tile.getRotation() * 90 : 0); + if(Core.atlas.isFound(entity.previous.icon(Icon.full))){ + Draw.rect(entity.previous.icon(Icon.full), tile.drawx(), tile.drawy(), entity.previous.rotate ? tile.getRotation() * 90 : 0); + } } @Override @@ -132,7 +134,7 @@ public class BuildBlock extends Block{ BuildEntity entity = tile.entity(); - Shaders.blockbuild.color = Palette.accent; + Shaders.blockbuild.color = Pal.accent; Block target = entity.block == null ? entity.previous : entity.block; @@ -278,7 +280,7 @@ public class BuildBlock extends Block{ public void setDeconstruct(Block previous){ this.previous = previous; this.progress = 1f; - if(previous.buildCost > 1f){ + if(previous.buildCost >= 0.01f){ this.block = previous; this.accumulator = new float[previous.buildRequirements.length]; this.totalAccumulator = new float[previous.buildRequirements.length]; diff --git a/core/src/io/anuke/mindustry/world/blocks/Floor.java b/core/src/io/anuke/mindustry/world/blocks/Floor.java index 247320b172..a7f4430371 100644 --- a/core/src/io/anuke/mindustry/world/blocks/Floor.java +++ b/core/src/io/anuke/mindustry/world/blocks/Floor.java @@ -1,19 +1,23 @@ package io.anuke.mindustry.world.blocks; import io.anuke.arc.Core; -import io.anuke.arc.entities.Effects.Effect; import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.math.Mathf; +import io.anuke.arc.math.geom.Geometry; +import io.anuke.arc.math.geom.Point2; import io.anuke.mindustry.content.Fx; import io.anuke.mindustry.content.StatusEffects; +import io.anuke.mindustry.entities.Effects.Effect; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.Liquid; import io.anuke.mindustry.type.StatusEffect; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; +import static io.anuke.mindustry.Vars.tilesize; + public class Floor extends Block{ /** number of different variant regions to use */ public int variants; @@ -45,9 +49,19 @@ public class Floor extends Block{ public boolean hasOres = false; /** whether this block can be drowned in */ public boolean isLiquid; + /** Heat of this block, 0 at baseline. Used for calculating output of thermal generators.*/ + public float heat = 0f; /** if true, this block cannot be mined by players. useful for annoying things like sand. */ public boolean playerUnmineable = false; - protected TextureRegion[] variantRegions; + /**Style of the edge stencil. Loaded by looking up "edge-stencil-{name}".*/ + public String edgeStyle = "smooth"; + /**Group of blocks that this block does not draw edges on.*/ + public Block blendGroup = this; + /**Effect displayed when randomly updated.*/ + public Effect updateEffect = Fx.none; + + protected TextureRegion[][] edges; + protected byte eq = 0; public Floor(String name){ super(name); @@ -70,9 +84,18 @@ public class Floor extends Block{ variantRegions[0] = Core.atlas.find(name); } + int size = (int)(tilesize / Draw.scl); + if(Core.atlas.has(name + "-edge")){ + edges = Core.atlas.find(name + "-edge").split(size, size); + } region = variantRegions[0]; } + @Override + public TextureRegion[] generateIcons(){ + return new TextureRegion[]{Core.atlas.find(Core.atlas.has(name) ? name : name + "1")}; + } + @Override public void init(){ super.init(); @@ -87,11 +110,66 @@ public class Floor extends Block{ Mathf.random.setSeed(tile.pos()); Draw.rect(variantRegions[Mathf.randomSeed(tile.pos(), 0, Math.max(0, variantRegions.length - 1))], tile.worldx(), tile.worldy()); + + drawEdges(tile); } - @Override - public TextureRegion[] generateIcons(){ - return new TextureRegion[]{Core.atlas.find(Core.atlas.has(name) ? name : name + "1")}; + protected void drawEdges(Tile tile){ + eq = 0; + + for(int i = 0; i < 8; i++){ + Point2 point = Geometry.d8[i]; + Tile other = tile.getNearby(point); + if(other != null && doEdge(other.floor()) && other.floor().edges() != null){ + eq |= (1 << i); + } + } + + for(int i = 0; i < 8; i++){ + if(eq(i)){ + Point2 point = Geometry.d8[i]; + Tile other = tile.getNearby(point); + + TextureRegion region = edge(other.floor(), type(i), 2-(point.x + 1), 2-(point.y + 1)); + Draw.rect(region, tile.worldx(), tile.worldy()); + } + } + } + + protected TextureRegion[][] edges(){ + return ((Floor)blendGroup).edges; + } + + protected boolean doEdge(Floor other){ + return (other.blendGroup.id > blendGroup.id || edges() == null) && other.edgeOnto(this); + } + + protected boolean edgeOnto(Floor other){ + return true; + } + + int type(int i){ + if(!eq(i - 1) && !eq(i + 1)){ + //case 0: touching + return 0; + }else if(eq(i - 1) && eq(i - 2) && eq(i + 1) && eq(i + 2)){ + //case 2: surrounded + return 2; + }else if(eq(i - 1) && eq(i + 1)){ + //case 1: flat + return 1; + }else{ + //case 0 is rounded, so it's the safest choice, should work for most possibilities + return 0; + } + } + + boolean eq(int i){ + return (eq & (1 << Mathf.mod(i, 8))) != 0; + } + + TextureRegion edge(Floor block, int type, int x, int y){ + return block.edges()[x + type*3][2-y]; } } \ No newline at end of file diff --git a/core/src/io/anuke/mindustry/world/blocks/OreBlock.java b/core/src/io/anuke/mindustry/world/blocks/OreBlock.java index 3d64d8509a..178a8ac83b 100644 --- a/core/src/io/anuke/mindustry/world/blocks/OreBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/OreBlock.java @@ -18,12 +18,18 @@ public class OreBlock extends Floor{ this.itemDrop = ore; this.base = base; this.variants = 3; - this.minimapColor = ore.color; this.edge = base.name; + this.blendGroup = base.blendGroup; + this.color.set(ore.color); oreBlockMap.getOr(ore, ObjectMap::new).put(base, this); } + @Override + public void init(){ + super.init(); + } + @Override public String getDisplayName(Tile tile){ return itemDrop.localizedName(); @@ -32,6 +38,18 @@ public class OreBlock extends Floor{ @Override public void draw(Tile tile){ Draw.rect(variantRegions[Mathf.randomSeed(tile.pos(), 0, Math.max(0, variantRegions.length - 1))], tile.worldx(), tile.worldy()); + + drawEdges(tile); + } + + @Override + public boolean doEdge(Floor floor){ + return floor != base && super.doEdge(floor); + } + + @Override + protected boolean edgeOnto(Floor other){ + return other != base; } public static Block get(Block floor, Item item){ diff --git a/core/src/io/anuke/mindustry/world/blocks/Rock.java b/core/src/io/anuke/mindustry/world/blocks/Rock.java index 943d106b4f..e73652d1c3 100644 --- a/core/src/io/anuke/mindustry/world/blocks/Rock.java +++ b/core/src/io/anuke/mindustry/world/blocks/Rock.java @@ -8,7 +8,7 @@ import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.math.Mathf; public class Rock extends Block{ - protected TextureRegion[] shadowRegions, regions; + protected TextureRegion[] regions; protected int variants; public Rock(String name){ @@ -19,13 +19,16 @@ public class Rock extends Block{ @Override public void draw(Tile tile){ - Draw.colorl(1f - tile.getRotation() / 4f); if(variants > 0){ Draw.rect(regions[Mathf.randomSeed(tile.pos(), 0, Math.max(0, regions.length - 1))], tile.worldx(), tile.worldy()); }else{ Draw.rect(region, tile.worldx(), tile.worldy()); } - Draw.color(); + } + + @Override + public TextureRegion[] variantRegions(){ + return regions; } @Override @@ -38,11 +41,9 @@ public class Rock extends Block{ super.load(); if(variants > 0){ - shadowRegions = new TextureRegion[variants]; regions = new TextureRegion[variants]; for(int i = 0; i < variants; i++){ - shadowRegions[i] = Core.atlas.find(name + "shadow" + (i + 1)); regions[i] = Core.atlas.find(name + (i + 1)); } } diff --git a/core/src/io/anuke/mindustry/world/blocks/SelectionTrait.java b/core/src/io/anuke/mindustry/world/blocks/SelectionTrait.java index 22dbf4c293..bd1cb012ea 100644 --- a/core/src/io/anuke/mindustry/world/blocks/SelectionTrait.java +++ b/core/src/io/anuke/mindustry/world/blocks/SelectionTrait.java @@ -25,7 +25,7 @@ public interface SelectionTrait{ int i = 0; for(Item item : items){ - if(!data.isUnlocked(item)) continue; + if(!data.isUnlocked(item) && world.isZone()) continue; ImageButton button = cont.addImageButton("white", "clear-toggle", 24, () -> {}).group(group).get(); button.changed(() -> consumer.accept(button.isChecked() ? item : null)); diff --git a/core/src/io/anuke/mindustry/world/blocks/StaticWall.java b/core/src/io/anuke/mindustry/world/blocks/StaticWall.java index df881c880b..af2f6e29aa 100644 --- a/core/src/io/anuke/mindustry/world/blocks/StaticWall.java +++ b/core/src/io/anuke/mindustry/world/blocks/StaticWall.java @@ -1,8 +1,18 @@ package io.anuke.mindustry.world.blocks; +import io.anuke.arc.Core; +import io.anuke.arc.graphics.g2d.Draw; +import io.anuke.arc.graphics.g2d.TextureRegion; +import io.anuke.arc.math.Mathf; import io.anuke.mindustry.graphics.CacheLayer; +import io.anuke.mindustry.world.Pos; +import io.anuke.mindustry.world.Tile; + +import static io.anuke.mindustry.Vars.tilesize; +import static io.anuke.mindustry.Vars.world; public class StaticWall extends Rock{ + TextureRegion large; public StaticWall(String name){ super(name); @@ -10,4 +20,42 @@ public class StaticWall extends Rock{ solid = true; cacheLayer = CacheLayer.walls; } + + @Override + public void draw(Tile tile){ + int rx = tile.x / 2 * 2; + int ry = tile.y / 2 * 2; + + if(Core.atlas.isFound(large) && eq(rx, ry) && Mathf.randomSeed(Pos.get(rx, ry)) < 0.5){ + if(rx == tile.x && ry == tile.y){ + Draw.rect(large, tile.worldx() + tilesize/2f, tile.worldy() + tilesize/2f); + } + }else if(variants > 0){ + Draw.rect(regions[Mathf.randomSeed(tile.pos(), 0, Math.max(0, regions.length - 1))], tile.worldx(), tile.worldy()); + }else{ + Draw.rect(region, tile.worldx(), tile.worldy()); + } + } + + @Override + public void load(){ + super.load(); + large = Core.atlas.find(name + "-large"); + } + + //two functions for calculating 2x2 tile brightness + int min(int rx, int ry){ + return Math.min(world.tile(rx + 1, ry).getRotation(), Math.min(world.tile(rx, ry).getRotation(), Math.min(world.tile(rx + 1, ry + 1).getRotation(), world.tile(rx, ry + 1).getRotation()))); + } + + int avg(int rx, int ry){ + return (world.tile(rx + 1, ry).getRotation() + world.tile(rx, ry).getRotation() + world.tile(rx + 1, ry + 1).getRotation() + world.tile(rx, ry + 1).getRotation()) / 4; + } + + boolean eq(int rx, int ry){ + return world.tile(rx + 1, ry).block() == this + && world.tile(rx, ry + 1).block() == this + && world.tile(rx, ry).block() == this + && world.tile(rx + 1, ry + 1).block() == this; + } } diff --git a/core/src/io/anuke/mindustry/world/blocks/TreeBlock.java b/core/src/io/anuke/mindustry/world/blocks/TreeBlock.java new file mode 100644 index 0000000000..60534c8be0 --- /dev/null +++ b/core/src/io/anuke/mindustry/world/blocks/TreeBlock.java @@ -0,0 +1,32 @@ +package io.anuke.mindustry.world.blocks; + +import io.anuke.arc.graphics.g2d.Draw; +import io.anuke.arc.math.Mathf; +import io.anuke.mindustry.graphics.Layer; +import io.anuke.mindustry.world.Block; +import io.anuke.mindustry.world.Tile; + +public class TreeBlock extends Block{ + static final float shadowOffset = 10f; + + public TreeBlock(String name){ + super(name); + solid = true; + layer = Layer.power; + expanded = true; + } + + @Override + public void draw(Tile tile){} + + @Override + public void drawShadow(Tile tile){ + Draw.rect(region, tile.drawx(), tile.drawy(), Mathf.randomSeed(tile.pos(), 0, 4) * 90); + Draw.rect(region, tile.drawx() - shadowOffset, tile.drawy() - shadowOffset, Mathf.randomSeed(tile.pos(), 0, 4) * 90); + } + + @Override + public void drawLayer(Tile tile){ + Draw.rect(region, tile.drawx(), tile.drawy(), Mathf.randomSeed(tile.pos(), 0, 4) * 90); + } +} diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/DeflectorWall.java b/core/src/io/anuke/mindustry/world/blocks/defense/DeflectorWall.java index 08392d7d32..5d9b9080b9 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/DeflectorWall.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/DeflectorWall.java @@ -8,7 +8,7 @@ import io.anuke.arc.math.geom.Geometry; import io.anuke.arc.math.geom.Rectangle; import io.anuke.arc.math.geom.Vector2; import io.anuke.arc.util.Time; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.entities.bullet.Bullet; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.world.Tile; diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/Door.java b/core/src/io/anuke/mindustry/world/blocks/defense/Door.java index a85545453c..d4c6fd75cc 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/Door.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/Door.java @@ -3,14 +3,14 @@ package io.anuke.mindustry.world.blocks.defense; import io.anuke.arc.Core; import io.anuke.arc.Graphics.Cursor; import io.anuke.arc.Graphics.Cursor.SystemCursor; -import io.anuke.arc.entities.Effects; -import io.anuke.arc.entities.Effects.Effect; +import io.anuke.mindustry.entities.Effects; +import io.anuke.mindustry.entities.Effects.Effect; import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.math.geom.Rectangle; import io.anuke.mindustry.content.Fx; -import io.anuke.mindustry.entities.Player; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.Player; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.entities.Units; import io.anuke.mindustry.world.Tile; diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/ForceProjector.java b/core/src/io/anuke/mindustry/world/blocks/defense/ForceProjector.java index 5eaa7b6c42..55ecd34d38 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/ForceProjector.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/ForceProjector.java @@ -1,11 +1,11 @@ package io.anuke.mindustry.world.blocks.defense; import io.anuke.arc.Core; -import io.anuke.arc.entities.Effects; -import io.anuke.arc.entities.EntityGroup; -import io.anuke.arc.entities.EntityQuery; -import io.anuke.arc.entities.impl.BaseEntity; -import io.anuke.arc.entities.trait.DrawTrait; +import io.anuke.mindustry.entities.Effects; +import io.anuke.mindustry.entities.EntityGroup; +import io.anuke.mindustry.entities.EntityQuery; +import io.anuke.mindustry.entities.impl.BaseEntity; +import io.anuke.mindustry.entities.traits.DrawTrait; import io.anuke.arc.graphics.Blending; import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.g2d.Draw; @@ -14,9 +14,9 @@ import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.math.Mathf; import io.anuke.arc.util.Time; import io.anuke.mindustry.content.Fx; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.entities.traits.AbsorbTrait; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.consumers.ConsumeLiquidFilter; @@ -54,7 +54,7 @@ public class ForceProjector extends Block { canOverdrive = false; hasLiquids = true; hasItems = true; - consumes.add(new ConsumeLiquidFilter(liquid -> liquid.temperature <= 0.5f && liquid.flammability < 0.1f, 0.1f)).optional(true).update(false); + consumes.add(new ConsumeLiquidFilter(liquid -> liquid.temperature <= 0.5f && liquid.flammability < 0.1f, 0.1f)).optional(true).boost(true).update(false); consumePower = new ConsumeForceProjectorPower(60f, 60f); consumes.add(consumePower); } @@ -243,7 +243,7 @@ public class ForceProjector extends Block { @Override public void draw(){ - Draw.color(Palette.accent); + Draw.color(Pal.accent); Fill.poly(x, y, 6, realRadius(entity)); Draw.color(); } @@ -265,7 +265,7 @@ public class ForceProjector extends Block { public class ConsumeForceProjectorPower extends ConsumePower{ public ConsumeForceProjectorPower(float powerCapacity, float ticksToFill){ - super(powerCapacity / ticksToFill, 0.0f, powerCapacity, true); + super(powerCapacity / ticksToFill, powerCapacity, true); } @Override public boolean valid(Block block, TileEntity entity){ diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/MendProjector.java b/core/src/io/anuke/mindustry/world/blocks/defense/MendProjector.java index 5877a7b20d..1419f6fd30 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/MendProjector.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/MendProjector.java @@ -2,7 +2,7 @@ package io.anuke.mindustry.world.blocks.defense; import io.anuke.arc.Core; import io.anuke.arc.collection.IntSet; -import io.anuke.arc.entities.Effects; +import io.anuke.mindustry.entities.Effects; import io.anuke.arc.graphics.Blending; import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.g2d.Draw; @@ -12,7 +12,7 @@ import io.anuke.arc.math.Mathf; import io.anuke.arc.util.Time; import io.anuke.arc.util.Tmp; import io.anuke.mindustry.content.Fx; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; @@ -66,8 +66,6 @@ public class MendProjector extends Block{ if(entity.charge >= reload){ float realRange = range + entity.phaseHeat * phaseRangeBoost; - - Effects.effect(Fx.healWaveMend, Tmp.c1.set(color).lerp(phase, entity.phaseHeat), tile.drawx(), tile.drawy(), realRange); entity.charge = 0f; int tileRange = (int)(realRange / tilesize); diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/OverdriveProjector.java b/core/src/io/anuke/mindustry/world/blocks/defense/OverdriveProjector.java index 6e2c303417..e8ce6425a9 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/OverdriveProjector.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/OverdriveProjector.java @@ -2,7 +2,6 @@ package io.anuke.mindustry.world.blocks.defense; import io.anuke.arc.Core; import io.anuke.arc.collection.IntSet; -import io.anuke.arc.entities.Effects; import io.anuke.arc.graphics.Blending; import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.g2d.Draw; @@ -10,9 +9,7 @@ import io.anuke.arc.graphics.g2d.Lines; import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.math.Mathf; import io.anuke.arc.util.Time; -import io.anuke.arc.util.Tmp; -import io.anuke.mindustry.content.Fx; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; @@ -31,7 +28,7 @@ public class OverdriveProjector extends Block{ protected int timerUse = timers ++; protected TextureRegion topRegion; - protected float reload = 260f; + protected float reload = 60f; protected float range = 80f; protected float speedBoost = 1.5f; protected float speedBoostPhase = 0.75f; @@ -69,7 +66,6 @@ public class OverdriveProjector extends Block{ float realRange = range + entity.phaseHeat * phaseRangeBoost; float realBoost = (speedBoost + entity.phaseHeat*speedBoostPhase) * entity.power.satisfaction; - Effects.effect(Fx.overdriveWave, Tmp.c1.set(color).lerp(phase, entity.phaseHeat), tile.drawx(), tile.drawy(), realRange); entity.charge = 0f; int tileRange = (int)(realRange / tilesize); @@ -87,8 +83,7 @@ public class OverdriveProjector extends Block{ if(other.getTeamID() == tile.getTeamID() && !healed.contains(other.pos()) && other.entity != null){ other.entity.timeScaleDuration = Math.max(other.entity.timeScaleDuration, reload + 1f); other.entity.timeScale = Math.max(other.entity.timeScale, realBoost); - Effects.effect(Fx.overdriveBlockFull, Tmp.c1.set(color).lerp(phase, entity.phaseHeat), other.drawx(), other.drawy(), other.block().size); - healed.add(other.pos()); + healed.add(other.pos()); } } } diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/ShockMine.java b/core/src/io/anuke/mindustry/world/blocks/defense/ShockMine.java index 63b7001f51..94e8a0590c 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/ShockMine.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/ShockMine.java @@ -3,10 +3,10 @@ package io.anuke.mindustry.world.blocks.defense; import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.graphics.g2d.Fill; import io.anuke.arc.math.Mathf; -import io.anuke.mindustry.entities.Unit; +import io.anuke.mindustry.entities.type.Unit; import io.anuke.mindustry.entities.effect.Lightning; import io.anuke.mindustry.graphics.Layer; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; @@ -37,6 +37,11 @@ public class ShockMine extends Block{ Draw.color(); } + @Override + public void drawTeam(Tile tile){ + //no + } + @Override public void draw(Tile tile){ //nope @@ -46,7 +51,7 @@ public class ShockMine extends Block{ public void unitOn(Tile tile, Unit unit){ if(unit.getTeam() != tile.getTeam() && tile.entity.timer.get(timerDamage, cooldown)){ for(int i = 0; i < tendrils; i++){ - Lightning.create(tile.getTeam(), Palette.lancerLaser, damage, tile.drawx(), tile.drawy(), Mathf.random(360f), length); + Lightning.create(tile.getTeam(), Pal.lancerLaser, damage, tile.drawx(), tile.drawy(), Mathf.random(360f), length); } tile.entity.damage(tileDamage); } diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/SurgeWall.java b/core/src/io/anuke/mindustry/world/blocks/defense/SurgeWall.java index 5316227bfc..e9a26e505a 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/SurgeWall.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/SurgeWall.java @@ -1,9 +1,9 @@ package io.anuke.mindustry.world.blocks.defense; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.entities.bullet.Bullet; import io.anuke.mindustry.entities.effect.Lightning; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.graphics.Pal; import io.anuke.arc.math.Mathf; public class SurgeWall extends Wall{ @@ -19,7 +19,7 @@ public class SurgeWall extends Wall{ public void handleBulletHit(TileEntity entity, Bullet bullet){ super.handleBulletHit(entity, bullet); if(Mathf.chance(lightningChance)){ - Lightning.create(entity.getTeam(), Palette.surge, lightningDamage, bullet.x, bullet.y, bullet.rot() + 180f, lightningLength); + Lightning.create(entity.getTeam(), Pal.surge, lightningDamage, bullet.x, bullet.y, bullet.rot() + 180f, lightningLength); } } } diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/Wall.java b/core/src/io/anuke/mindustry/world/blocks/defense/Wall.java index cd2f2a61d3..3062883588 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/Wall.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/Wall.java @@ -1,9 +1,15 @@ package io.anuke.mindustry.world.blocks.defense; +import io.anuke.arc.Core; +import io.anuke.arc.graphics.g2d.Draw; +import io.anuke.arc.graphics.g2d.TextureRegion; +import io.anuke.arc.math.Mathf; import io.anuke.mindustry.world.Block; +import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.meta.BlockGroup; public class Wall extends Block{ + protected int variants = 0; public Wall(String name){ super(name); @@ -12,6 +18,34 @@ public class Wall extends Block{ group = BlockGroup.walls; } + @Override + public void load(){ + super.load(); + + if(variants != 0){ + variantRegions = new TextureRegion[variants]; + + for(int i = 0; i < variants; i++){ + variantRegions[i] = Core.atlas.find(name + (i + 1)); + } + region = variantRegions[0]; + } + } + + @Override + public void draw(Tile tile){ + if(variants == 0){ + Draw.rect(region, tile.drawx(), tile.drawy()); + }else{ + Draw.rect(variantRegions[Mathf.randomSeed(tile.pos(), 0, Math.max(0, variantRegions.length - 1))], tile.drawx(), tile.drawy()); + } + } + + @Override + public TextureRegion[] generateIcons(){ + return new TextureRegion[]{Core.atlas.find(Core.atlas.has(name) ? name : name + "1")}; + } + @Override public boolean canReplace(Block other){ return super.canReplace(other) && health > other.health; diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/ChargeTurret.java b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/ChargeTurret.java index 855dc67fb2..47faa0bd91 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/ChargeTurret.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/ChargeTurret.java @@ -1,11 +1,11 @@ package io.anuke.mindustry.world.blocks.defense.turrets; -import io.anuke.arc.entities.Effects; -import io.anuke.arc.entities.Effects.Effect; +import io.anuke.mindustry.entities.Effects; +import io.anuke.mindustry.entities.Effects.Effect; import io.anuke.arc.math.Mathf; import io.anuke.arc.util.Time; import io.anuke.mindustry.content.Fx; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.entities.bullet.BulletType; import io.anuke.mindustry.world.Tile; diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/CooledTurret.java b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/CooledTurret.java index 65053c9284..d81805a721 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/CooledTurret.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/CooledTurret.java @@ -4,8 +4,8 @@ import io.anuke.mindustry.content.Fx; import io.anuke.mindustry.type.Liquid; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.consumers.ConsumeLiquidFilter; -import io.anuke.arc.entities.Effects; -import io.anuke.arc.entities.Effects.Effect; +import io.anuke.mindustry.entities.Effects; +import io.anuke.mindustry.entities.Effects.Effect; import io.anuke.arc.util.Time; import io.anuke.arc.math.Mathf; diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/ItemTurret.java b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/ItemTurret.java index f2f41708aa..616ffb0d53 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/ItemTurret.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/ItemTurret.java @@ -1,10 +1,14 @@ package io.anuke.mindustry.world.blocks.defense.turrets; import io.anuke.arc.collection.ObjectMap; +import io.anuke.arc.scene.ui.layout.Table; import io.anuke.mindustry.Vars; -import io.anuke.mindustry.entities.Unit; import io.anuke.mindustry.entities.bullet.BulletType; +import io.anuke.mindustry.entities.type.TileEntity; +import io.anuke.mindustry.entities.type.Unit; +import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.type.Item; +import io.anuke.mindustry.ui.Bar; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.meta.BlockStat; import io.anuke.mindustry.world.meta.values.ItemFilterValue; @@ -35,6 +39,17 @@ public class ItemTurret extends CooledTurret{ stats.add(BlockStat.inputItems, new ItemFilterValue(item -> ammo.containsKey(item))); } + + @Override + public void displayBars(Tile tile, Table bars){ + super.displayBars(tile, bars); + + TurretEntity entity = tile.entity(); + + bars.add(new Bar("blocks.ammo", Pal.ammo, () -> (float)entity.totalAmmo / maxAmmo)).growX(); + bars.row(); + } + @Override public int acceptStack(Item item, int amount, Tile tile, Unit source){ TurretEntity entity = tile.entity(); @@ -66,7 +81,6 @@ public class ItemTurret extends CooledTurret{ BulletType type = ammo.get(item); entity.totalAmmo += type.ammoMultiplier; - entity.items.add(item, 1); //find ammo entry by type for(int i = 0; i < entity.ammo.size; i++){ @@ -91,6 +105,11 @@ public class ItemTurret extends CooledTurret{ return ammo != null && ammo.get(item) != null && entity.totalAmmo + ammo.get(item).ammoMultiplier <= maxAmmo; } + @Override + public TileEntity newEntity(){ + return new ItemTurretEntity(); + } + public class ItemTurretEntity extends TurretEntity{ @Override public void write(DataOutput stream) throws IOException{ diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/LaserTurret.java b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/LaserTurret.java index ce6414f4ea..3796103fe3 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/LaserTurret.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/LaserTurret.java @@ -1,10 +1,10 @@ package io.anuke.mindustry.world.blocks.defense.turrets; -import io.anuke.arc.entities.Effects; +import io.anuke.mindustry.entities.Effects; import io.anuke.arc.math.Angles; import io.anuke.arc.math.Mathf; import io.anuke.arc.util.Time; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.entities.bullet.Bullet; import io.anuke.mindustry.entities.bullet.BulletType; import io.anuke.mindustry.type.Liquid; diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/LiquidTurret.java b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/LiquidTurret.java index e368901395..4d925f9856 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/LiquidTurret.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/LiquidTurret.java @@ -1,7 +1,7 @@ package io.anuke.mindustry.world.blocks.defense.turrets; import io.anuke.arc.collection.ObjectMap; -import io.anuke.arc.entities.Effects; +import io.anuke.mindustry.entities.Effects; import io.anuke.mindustry.Vars; import io.anuke.mindustry.entities.bullet.BulletType; import io.anuke.mindustry.entities.effect.Fire; diff --git a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/Turret.java b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/Turret.java index 5b6e97a40f..29fe2bab9a 100644 --- a/core/src/io/anuke/mindustry/world/blocks/defense/turrets/Turret.java +++ b/core/src/io/anuke/mindustry/world/blocks/defense/turrets/Turret.java @@ -3,8 +3,8 @@ package io.anuke.mindustry.world.blocks.defense.turrets; import io.anuke.arc.Core; import io.anuke.arc.collection.Array; import io.anuke.arc.collection.EnumSet; -import io.anuke.arc.entities.Effects; -import io.anuke.arc.entities.Effects.Effect; +import io.anuke.mindustry.entities.Effects; +import io.anuke.mindustry.entities.Effects.Effect; import io.anuke.arc.function.BiConsumer; import io.anuke.arc.graphics.Blending; import io.anuke.arc.graphics.Color; @@ -17,13 +17,13 @@ import io.anuke.arc.math.geom.Vector2; import io.anuke.arc.util.Time; import io.anuke.mindustry.content.Fx; import io.anuke.mindustry.entities.Predict; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.entities.Units; import io.anuke.mindustry.entities.bullet.Bullet; import io.anuke.mindustry.entities.bullet.BulletType; import io.anuke.mindustry.entities.traits.TargetTrait; import io.anuke.mindustry.graphics.Layer; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.meta.BlockFlag; @@ -38,7 +38,7 @@ public abstract class Turret extends Block{ protected final int timerTarget = timers++; - protected Color heatColor = Palette.turretHeat; + protected Color heatColor = Pal.turretHeat; protected Effect shootEffect = Fx.none; protected Effect smokeEffect = Fx.none; protected Effect ammoUseEffect = Fx.none; @@ -62,9 +62,7 @@ public abstract class Turret extends Block{ protected Vector2 tr = new Vector2(); protected Vector2 tr2 = new Vector2(); - protected TextureRegion baseRegion; - protected TextureRegion heatRegion; - protected TextureRegion baseTopRegion; + protected TextureRegion baseRegion, heatRegion; protected BiConsumer drawer = (tile, entity) -> Draw.rect(region, tile.drawx() + tr2.x, tile.drawy() + tr2.y, entity.rotation - 90); @@ -84,6 +82,7 @@ public abstract class Turret extends Block{ layer = Layer.turret; group = BlockGroup.turrets; flags = EnumSet.of(BlockFlag.turret); + outlineIcon = true; } @Override @@ -91,13 +90,12 @@ public abstract class Turret extends Block{ return false; } - @Override public void load(){ super.load(); + region = Core.atlas.find(name); baseRegion = Core.atlas.find("block-" + size); - baseTopRegion = Core.atlas.find("block-" + size + "-top"); heatRegion = Core.atlas.find(name + "-heat"); } @@ -145,7 +143,7 @@ public abstract class Turret extends Block{ @Override public void drawPlace(int x, int y, int rotation, boolean valid){ - Lines.stroke(1f, Palette.placing); + Lines.stroke(1f, Pal.placing); Lines.dashCircle(x * tilesize + offset(), y * tilesize + offset(), range); Draw.color(); } diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/BufferedItemBridge.java b/core/src/io/anuke/mindustry/world/blocks/distribution/BufferedItemBridge.java index 1980195b30..6e833659c5 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/BufferedItemBridge.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/BufferedItemBridge.java @@ -1,6 +1,6 @@ package io.anuke.mindustry.world.blocks.distribution; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.world.ItemBuffer; import io.anuke.mindustry.world.Tile; diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/Conduit.java b/core/src/io/anuke/mindustry/world/blocks/distribution/Conduit.java index 0115340429..22d9c2e873 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/Conduit.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/Conduit.java @@ -2,7 +2,7 @@ package io.anuke.mindustry.world.blocks.distribution; import io.anuke.arc.Core; import io.anuke.arc.graphics.g2d.TextureRegion; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.type.Liquid; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.LiquidBlock; diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/Conveyor.java b/core/src/io/anuke/mindustry/world/blocks/distribution/Conveyor.java index 814352f1bd..bc4e4a9275 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/Conveyor.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/Conveyor.java @@ -10,8 +10,8 @@ import io.anuke.arc.math.geom.Vector2; import io.anuke.arc.util.Log; import io.anuke.arc.util.Pack; import io.anuke.arc.util.Time; -import io.anuke.mindustry.entities.TileEntity; -import io.anuke.mindustry.entities.Unit; +import io.anuke.mindustry.entities.type.TileEntity; +import io.anuke.mindustry.entities.type.Unit; import io.anuke.mindustry.graphics.Layer; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.world.Block; diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/ItemBridge.java b/core/src/io/anuke/mindustry/world/blocks/distribution/ItemBridge.java index 96b3c231c2..395251ecdf 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/ItemBridge.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/ItemBridge.java @@ -14,11 +14,11 @@ import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.math.Mathf; import io.anuke.arc.math.geom.Geometry; import io.anuke.arc.util.Time; -import io.anuke.mindustry.entities.Player; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.Player; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.graphics.Layer; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Edges; @@ -98,7 +98,7 @@ public class ItemBridge extends Block{ @Override public void drawPlace(int x, int y, int rotation, boolean valid){ Lines.stroke(2f); - Draw.color(Palette.placing); + Draw.color(Pal.placing); for(int i = 0; i < 4; i++){ Lines.dashLine( x * tilesize + Geometry.d4[i].x * (tilesize / 2f + 2), @@ -115,7 +115,7 @@ public class ItemBridge extends Block{ public void drawConfigure(Tile tile){ ItemBridgeEntity entity = tile.entity(); - Draw.color(Palette.accent); + Draw.color(Pal.accent); Lines.stroke(1f); Lines.square(tile.drawx(), tile.drawy(), tile.block().size * tilesize / 2f + 1f); @@ -125,7 +125,7 @@ public class ItemBridge extends Block{ Tile other = tile.getNearby(Geometry.d4[j].x * i, Geometry.d4[j].y * i); if(linkValid(tile, other)){ boolean linked = other.pos() == entity.link; - Draw.color(linked ? Palette.place : Palette.breakInvalid); + Draw.color(linked ? Pal.place : Pal.breakInvalid); Lines.square(other.drawx(), other.drawy(), other.block().size * tilesize / 2f + 1f + (linked ? 0f : Mathf.absin(Time.time(), 4f, 1f))); @@ -287,14 +287,6 @@ public class ItemBridge extends Block{ return rel != rel2; } - @Override - public void transformLinks(Tile tile, int oldWidth, int oldHeight, int newWidth, int newHeight, int shiftX, int shiftY){ - super.transformLinks(tile, oldWidth, oldHeight, newWidth, newHeight, shiftX, shiftY); - - ItemBridgeEntity entity = tile.entity(); - entity.link = world.transform(entity.link, oldWidth, oldHeight, newWidth, shiftX, shiftY); - } - @Override public TileEntity newEntity(){ return new ItemBridgeEntity(); diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/Junction.java b/core/src/io/anuke/mindustry/world/blocks/distribution/Junction.java index 6663da7469..3aa50c6d4d 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/Junction.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/Junction.java @@ -3,7 +3,7 @@ package io.anuke.mindustry.world.blocks.distribution; import io.anuke.arc.util.NumberUtils; import io.anuke.arc.util.Pack; import io.anuke.arc.util.Time; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/MassDriver.java b/core/src/io/anuke/mindustry/world/blocks/distribution/MassDriver.java index fc24bb7d42..01d1f3f740 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/MassDriver.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/MassDriver.java @@ -4,8 +4,8 @@ import io.anuke.annotations.Annotations.Loc; import io.anuke.annotations.Annotations.Remote; import io.anuke.arc.Core; import io.anuke.arc.collection.ObjectSet; -import io.anuke.arc.entities.Effects; -import io.anuke.arc.entities.Effects.Effect; +import io.anuke.mindustry.entities.Effects; +import io.anuke.mindustry.entities.Effects.Effect; import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.graphics.g2d.Lines; @@ -17,12 +17,12 @@ import io.anuke.arc.util.pooling.Pool.Poolable; import io.anuke.arc.util.pooling.Pools; import io.anuke.mindustry.content.Bullets; import io.anuke.mindustry.content.Fx; -import io.anuke.mindustry.entities.Player; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.Player; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.entities.bullet.Bullet; import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.graphics.Layer; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; @@ -47,8 +47,8 @@ public class MassDriver extends Block{ protected Effect smokeEffect = Fx.shootBigSmoke2; protected Effect recieveEffect = Fx.mineBig; protected float shake = 3f; - protected final static float powerPercentageUsed = 1.0f; - protected TextureRegion turretRegion; + protected float powerPercentageUsed = 0.95f; + protected TextureRegion baseRegion; public MassDriver(String name){ super(name); @@ -59,6 +59,7 @@ public class MassDriver extends Block{ layer = Layer.turret; hasPower = true; consumes.powerBuffered(30f); + outlineIcon = true; } @Remote(targets = Loc.both, called = Loc.server, forward = true) @@ -79,7 +80,7 @@ public class MassDriver extends Block{ entity.reload = 1f; - entity.power.satisfaction -= Math.min(entity.power.satisfaction, powerPercentageUsed); + entity.power.satisfaction -= Math.min(entity.power.satisfaction, driver.powerPercentageUsed); DriverBulletData data = Pools.obtain(DriverBulletData.class, DriverBulletData::new); data.from = entity; @@ -110,14 +111,14 @@ public class MassDriver extends Block{ @Override public TextureRegion[] generateIcons(){ - return new TextureRegion[]{Core.atlas.find(name), Core.atlas.find(name + "-turret")}; + return new TextureRegion[]{Core.atlas.find(name + "-base"), Core.atlas.find(name + "-turret")}; } @Override public void load(){ super.load(); - turretRegion = Core.atlas.find(name + "-turret"); + baseRegion = Core.atlas.find(name + "-base"); } @Override @@ -177,11 +178,16 @@ public class MassDriver extends Block{ entity.waiting.clear(); } + @Override + public void draw(Tile tile){ + Draw.rect(baseRegion, tile.drawx(), tile.drawy()); + } + @Override public void drawLayer(Tile tile){ MassDriverEntity entity = tile.entity(); - Draw.rect(turretRegion, + Draw.rect(region, tile.drawx() + Angles.trnsx(entity.rotation + 180f, entity.reload * knockback), tile.drawy() + Angles.trnsy(entity.rotation + 180f, entity.reload * knockback), entity.rotation - 90); } @@ -190,7 +196,7 @@ public class MassDriver extends Block{ public void drawConfigure(Tile tile){ float sin = Mathf.absin(Time.time(), 6f, 1f); - Draw.color(Palette.accent); + Draw.color(Pal.accent); Lines.stroke(1f); Lines.poly(tile.drawx(), tile.drawy(), 20, (tile.block().size/2f+1) * tilesize + sin); @@ -199,12 +205,12 @@ public class MassDriver extends Block{ if(linkValid(tile)){ Tile target = world.tile(entity.link); - Draw.color(Palette.place); + Draw.color(Pal.place); Lines.poly(target.drawx(), target.drawy(), 20, (target.block().size/2f+1) * tilesize + sin); Draw.reset(); } - Draw.color(Palette.accent); + Draw.color(Pal.accent); Lines.dashCircle(tile.drawx(), tile.drawy(), range); Draw.color(); } @@ -231,14 +237,6 @@ public class MassDriver extends Block{ return tile.entity.items.total() < itemCapacity; } - @Override - public void transformLinks(Tile tile, int oldWidth, int oldHeight, int newWidth, int newHeight, int shiftX, int shiftY){ - super.transformLinks(tile, oldWidth, oldHeight, newWidth, newHeight, shiftX, shiftY); - - MassDriverEntity entity = tile.entity(); - entity.link = world.transform(entity.link, oldWidth, oldHeight, newWidth, shiftX, shiftY); - } - @Override public TileEntity newEntity(){ return new MassDriverEntity(); diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/Router.java b/core/src/io/anuke/mindustry/world/blocks/distribution/Router.java index fe9ba5f5d5..fd1e3cc499 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/Router.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/Router.java @@ -1,7 +1,7 @@ package io.anuke.mindustry.world.blocks.distribution; import io.anuke.arc.collection.Array; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Edges; diff --git a/core/src/io/anuke/mindustry/world/blocks/distribution/Sorter.java b/core/src/io/anuke/mindustry/world/blocks/distribution/Sorter.java index f4b3697c09..fada43be00 100644 --- a/core/src/io/anuke/mindustry/world/blocks/distribution/Sorter.java +++ b/core/src/io/anuke/mindustry/world/blocks/distribution/Sorter.java @@ -3,8 +3,8 @@ package io.anuke.mindustry.world.blocks.distribution; import io.anuke.annotations.Annotations.Loc; import io.anuke.annotations.Annotations.Remote; import io.anuke.arc.Core; -import io.anuke.mindustry.entities.Player; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.Player; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.world.Block; diff --git a/core/src/io/anuke/mindustry/world/blocks/power/BurnerGenerator.java b/core/src/io/anuke/mindustry/world/blocks/power/BurnerGenerator.java index 0441f2a876..6568242ddb 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/BurnerGenerator.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/BurnerGenerator.java @@ -6,7 +6,7 @@ import io.anuke.mindustry.type.Liquid; public class BurnerGenerator extends ItemLiquidGenerator{ public BurnerGenerator(String name){ - super(InputType.LiquidsAndItems, name); + super(true, true, name); } @Override diff --git a/core/src/io/anuke/mindustry/world/blocks/power/DecayGenerator.java b/core/src/io/anuke/mindustry/world/blocks/power/DecayGenerator.java index 678da93587..18b3cd47df 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/DecayGenerator.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/DecayGenerator.java @@ -1,12 +1,11 @@ package io.anuke.mindustry.world.blocks.power; import io.anuke.mindustry.type.Item; -import io.anuke.mindustry.type.Liquid; public class DecayGenerator extends ItemLiquidGenerator{ public DecayGenerator(String name){ - super(InputType.ItemsOnly, name); + super(true, false, name); hasItems = true; hasLiquids = false; } diff --git a/core/src/io/anuke/mindustry/world/blocks/power/DifferentialGenerator.java b/core/src/io/anuke/mindustry/world/blocks/power/DifferentialGenerator.java new file mode 100644 index 0000000000..2313d1e429 --- /dev/null +++ b/core/src/io/anuke/mindustry/world/blocks/power/DifferentialGenerator.java @@ -0,0 +1,27 @@ +package io.anuke.mindustry.world.blocks.power; + +import io.anuke.mindustry.type.Item; +import io.anuke.mindustry.type.Liquid; +import io.anuke.mindustry.world.Tile; +import io.anuke.mindustry.world.consumers.ConsumeItem; +import io.anuke.mindustry.world.consumers.ConsumeLiquid; + +public class DifferentialGenerator extends TurbineGenerator{ + + public DifferentialGenerator(String name){ + super(name); + + consumes.require(ConsumeItem.class); + consumes.require(ConsumeLiquid.class); + } + + @Override + public boolean acceptItem(Item item, Tile tile, Tile source){ + return hasItems && consumes.item() == item && tile.entity.items.total() < itemCapacity; + } + + @Override + public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){ + return hasLiquids && consumes.liquid() == liquid && tile.entity.liquids.get(liquid) < liquidCapacity; + } +} diff --git a/core/src/io/anuke/mindustry/world/blocks/power/FusionReactor.java b/core/src/io/anuke/mindustry/world/blocks/power/ImpactReactor.java similarity index 88% rename from core/src/io/anuke/mindustry/world/blocks/power/FusionReactor.java rename to core/src/io/anuke/mindustry/world/blocks/power/ImpactReactor.java index 77d36761cd..c9f18e8aed 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/FusionReactor.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/ImpactReactor.java @@ -7,43 +7,48 @@ import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.math.Mathf; import io.anuke.arc.util.Time; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.world.Tile; import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; -public class FusionReactor extends PowerGenerator{ +public class ImpactReactor extends PowerGenerator{ + protected int timerUse = timers++; + protected int plasmas = 4; protected float warmupSpeed = 0.001f; + protected float useTime = 60f; protected Color plasma1 = Color.valueOf("ffd06b"), plasma2 = Color.valueOf("ff361b"); protected Color ind1 = Color.valueOf("858585"), ind2 = Color.valueOf("fea080"); - public FusionReactor(String name){ + public ImpactReactor(String name){ super(name); hasPower = true; hasLiquids = true; powerProduction = 2.0f; liquidCapacity = 30f; hasItems = true; + outputsPower = consumesPower = true; } @Override public void update(Tile tile){ FusionReactorEntity entity = tile.entity(); - float increaseOrDecrease = 1.0f; if(entity.cons.valid()){ entity.warmup = Mathf.lerpDelta(entity.warmup, 1f, warmupSpeed); + + if(entity.timer.get(timerUse, useTime)){ + entity.items.remove(consumes.item(), consumes.itemAmount()); + } }else{ entity.warmup = Mathf.lerpDelta(entity.warmup, 0f, 0.01f); - increaseOrDecrease = -1.0f; } - float efficiencyAdded = Mathf.pow(entity.warmup, 4f) * Time.delta(); - entity.productionEfficiency = Mathf.clamp(entity.productionEfficiency + efficiencyAdded * increaseOrDecrease); + entity.productionEfficiency = Mathf.pow(entity.warmup, 5f); super.update(tile); } diff --git a/core/src/io/anuke/mindustry/world/blocks/power/ItemLiquidGenerator.java b/core/src/io/anuke/mindustry/world/blocks/power/ItemLiquidGenerator.java index 44fdd5caf9..6a45c18a4d 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/ItemLiquidGenerator.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/ItemLiquidGenerator.java @@ -1,14 +1,14 @@ package io.anuke.mindustry.world.blocks.power; import io.anuke.arc.Core; -import io.anuke.arc.entities.Effects; +import io.anuke.mindustry.entities.Effects; import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.math.Mathf; import io.anuke.arc.util.Time; import io.anuke.mindustry.content.Fx; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.Liquid; import io.anuke.mindustry.world.Tile; @@ -36,25 +36,18 @@ public class ItemLiquidGenerator extends PowerGenerator{ protected Effects.Effect explodeEffect = Fx.generatespark; protected Color heatColor = Color.valueOf("ff9b59"); protected TextureRegion topRegion; + protected boolean randomlyExplode = false; - public enum InputType{ - ItemsOnly, - LiquidsOnly, - LiquidsAndItems - } - - public ItemLiquidGenerator(InputType inputType, String name){ + public ItemLiquidGenerator(boolean hasItems, boolean hasLiquids, String name){ super(name); - this.hasItems = inputType != InputType.LiquidsOnly; - this.hasLiquids = inputType != InputType.ItemsOnly; + this.hasItems = hasItems; + this.hasLiquids = hasLiquids; if(hasItems){ - itemCapacity = 20; consumes.add(new ConsumeItemFilter(item -> getItemEfficiency(item) >= minItemEfficiency)).update(false).optional(true); } if(hasLiquids){ - liquidCapacity = 10f; consumes.add(new ConsumeLiquidFilter(liquid -> getLiquidEfficiency(liquid) >= minLiquidEfficiency, 0.001f, true)).update(false).optional(true); } } @@ -67,13 +60,12 @@ public class ItemLiquidGenerator extends PowerGenerator{ } } - @Override public void update(Tile tile){ ItemLiquidGeneratorEntity entity = tile.entity(); - // Note: Do not use this delta when calculating the amount of power or the power efficiency, but use it for resource consumption if necessary. - // Power amount is delta'd by PowerGraph class already. + //Note: Do not use this delta when calculating the amount of power or the power efficiency, but use it for resource consumption if necessary. + //Power amount is delta'd by PowerGraph class already. float calculationDelta = entity.delta(); if(!entity.cons.valid()){ @@ -88,6 +80,9 @@ public class ItemLiquidGenerator extends PowerGenerator{ break; } } + + entity.heat = Mathf.lerpDelta(entity.heat, entity.generateTime >= 0.001f ? 1f : 0f, 0.05f); + //liquid takes priority over solids if(hasLiquids && liquid != null && entity.liquids.get(liquid) >= 0.001f){ float baseLiquidEfficiency = getLiquidEfficiency(liquid); @@ -95,9 +90,7 @@ public class ItemLiquidGenerator extends PowerGenerator{ float used = Math.min(entity.liquids.get(liquid) * calculationDelta, maximumPossible); entity.liquids.remove(liquid, used); - - // Note: 0.5 = 100%. PowerGraph will multiply this efficiency by two on its own. - entity.productionEfficiency = Mathf.clamp(baseLiquidEfficiency * used / maximumPossible); + entity.productionEfficiency = baseLiquidEfficiency * used / maximumPossible; if(used > 0.001f && Mathf.chance(0.05 * entity.delta())){ Effects.effect(generateEffect, tile.drawx() + Mathf.range(3f), tile.drawy() + Mathf.range(3f)); @@ -115,9 +108,9 @@ public class ItemLiquidGenerator extends PowerGenerator{ if(entity.generateTime > 0f){ entity.generateTime -= Math.min(1f / itemDuration * entity.delta(), entity.generateTime); - if(Mathf.chance(entity.delta() * 0.06 * Mathf.clamp(entity.explosiveness - 0.25f))){ + if(randomlyExplode && Mathf.chance(entity.delta() * 0.06 * Mathf.clamp(entity.explosiveness - 0.5f))){ //this block is run last so that in the event of a block destruction, no code relies on the block type - entity.damage(Mathf.random(8f)); + entity.damage(Mathf.random(11f)); Effects.effect(explodeEffect, tile.worldx() + Mathf.range(size * tilesize / 2f), tile.worldy() + Mathf.range(size * tilesize / 2f)); } }else{ @@ -142,17 +135,13 @@ public class ItemLiquidGenerator extends PowerGenerator{ public void draw(Tile tile){ super.draw(tile); - GeneratorEntity entity = tile.entity(); + ItemLiquidGeneratorEntity entity = tile.entity(); if(hasItems){ - if(entity.generateTime > 0){ - Draw.color(heatColor); - float alpha = (entity.items.total() > 0 ? 1f : Mathf.clamp(entity.generateTime)); - alpha = alpha * 0.7f + Mathf.absin(Time.time(), 12f, 0.3f) * alpha; - Draw.alpha(alpha); - Draw.rect(topRegion, tile.drawx(), tile.drawy()); - Draw.reset(); - } + Draw.color(heatColor); + Draw.alpha(entity.heat * 0.4f + Mathf.absin(Time.time(), 8f, 0.6f) * entity.heat); + Draw.rect(topRegion, tile.drawx(), tile.drawy()); + Draw.reset(); } if(hasLiquids){ @@ -182,5 +171,6 @@ public class ItemLiquidGenerator extends PowerGenerator{ public static class ItemLiquidGeneratorEntity extends GeneratorEntity{ public float explosiveness; + public float heat; } } diff --git a/core/src/io/anuke/mindustry/world/blocks/power/LiquidHeatGenerator.java b/core/src/io/anuke/mindustry/world/blocks/power/LiquidHeatGenerator.java deleted file mode 100644 index fd7a51833a..0000000000 --- a/core/src/io/anuke/mindustry/world/blocks/power/LiquidHeatGenerator.java +++ /dev/null @@ -1,28 +0,0 @@ -package io.anuke.mindustry.world.blocks.power; - -import io.anuke.mindustry.content.Liquids; -import io.anuke.mindustry.type.Liquid; -import io.anuke.mindustry.world.meta.BlockStat; -import io.anuke.mindustry.world.meta.StatUnit; - -//TODO remove, as this is no longer a thing -public class LiquidHeatGenerator extends ItemLiquidGenerator{ - - public LiquidHeatGenerator(String name){ - super(InputType.LiquidsOnly, name); - } - - @Override - public void setStats(){ - super.setStats(); - - stats.remove(BlockStat.basePowerGeneration); - // right now, Lava is the only thing that can be used. - stats.add(BlockStat.basePowerGeneration, powerProduction * getLiquidEfficiency(Liquids.slag) / maxLiquidGenerate * 60f, StatUnit.powerSecond); - } - - @Override - protected float getLiquidEfficiency(Liquid liquid){ - return liquid.temperature - 0.5f; - } -} diff --git a/core/src/io/anuke/mindustry/world/blocks/power/NuclearReactor.java b/core/src/io/anuke/mindustry/world/blocks/power/NuclearReactor.java index 91e7fadf75..f6e548ff60 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/NuclearReactor.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/NuclearReactor.java @@ -1,22 +1,21 @@ package io.anuke.mindustry.world.blocks.power; import io.anuke.arc.Core; -import io.anuke.arc.entities.Effects; +import io.anuke.mindustry.entities.Effects; import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.math.Mathf; -import io.anuke.arc.util.Time; import io.anuke.arc.math.geom.Vector2; -import io.anuke.mindustry.content.Items; +import io.anuke.arc.util.Time; import io.anuke.mindustry.content.Fx; +import io.anuke.mindustry.content.Items; import io.anuke.mindustry.entities.Damage; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.type.Liquid; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.meta.BlockStat; import io.anuke.mindustry.world.meta.StatUnit; -import io.anuke.mindustry.world.meta.values.LiquidFilterValue; import java.io.DataInput; import java.io.DataOutput; @@ -63,11 +62,9 @@ public class NuclearReactor extends PowerGenerator{ @Override public void setStats(){ super.setStats(); - stats.add(BlockStat.inputLiquid, new LiquidFilterValue(liquid -> liquid.temperature <= 0.5f)); stats.remove(BlockStat.basePowerGeneration); - // Display the power which will be produced at 50% efficiency - stats.add(BlockStat.basePowerGeneration, powerProduction * 60f * 0.5f, StatUnit.powerSecond); + stats.add(BlockStat.basePowerGeneration, powerProduction * 60f, StatUnit.powerSecond); } @Override @@ -76,7 +73,7 @@ public class NuclearReactor extends PowerGenerator{ int fuel = entity.items.get(consumes.item()); float fullness = (float) fuel / itemCapacity; - entity.productionEfficiency = fullness / 2.0f; // Currently, efficiency of 0.5 = 100% + entity.productionEfficiency = fullness; if(fuel > 0){ entity.heat += fullness * heating * Math.min(entity.delta(), 4f); @@ -153,12 +150,6 @@ public class NuclearReactor extends PowerGenerator{ } } - @Override - public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){ - return tile.entity.liquids.get(liquid) + amount < liquidCapacity && liquid.temperature <= 0.5f && - (tile.entity.liquids.current() == liquid || tile.entity.liquids.get(tile.entity.liquids.current()) < 0.01f); - } - @Override public void draw(Tile tile){ super.draw(tile); diff --git a/core/src/io/anuke/mindustry/world/blocks/power/PowerGenerator.java b/core/src/io/anuke/mindustry/world/blocks/power/PowerGenerator.java index b6902c6796..5b5e675558 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/PowerGenerator.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/PowerGenerator.java @@ -1,7 +1,7 @@ package io.anuke.mindustry.world.blocks.power; import io.anuke.arc.collection.EnumSet; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.meta.BlockFlag; import io.anuke.mindustry.world.meta.BlockStat; @@ -12,7 +12,7 @@ import java.io.DataOutput; import java.io.IOException; public class PowerGenerator extends PowerDistributor{ - /** The amount of power produced per tick in case of an efficiency of 1.0, which currently represents 200%. */ + /** The amount of power produced per tick in case of an efficiency of 1.0, which represents 100%. */ protected float powerProduction; public BlockStat generationType = BlockStat.basePowerGeneration; @@ -25,14 +25,11 @@ public class PowerGenerator extends PowerDistributor{ @Override public void setStats(){ super.setStats(); - // Divide power production by two since that is what is produced at an efficiency of 0.5, which currently represents 100% - stats.add(generationType, powerProduction * 60.0f / 2.0f, StatUnit.powerSecond); + stats.add(generationType, powerProduction * 60.0f, StatUnit.powerSecond); } @Override public float getPowerProduction(Tile tile){ - // While 0.5 efficiency currently reflects 100%, we do not need to multiply by any factor since powerProduction states the - // power which would be produced at 1.0 efficiency return powerProduction * tile.entity().productionEfficiency; } @@ -48,7 +45,7 @@ public class PowerGenerator extends PowerDistributor{ public static class GeneratorEntity extends TileEntity{ public float generateTime; - /** The efficiency of the producer. Currently, an efficiency of 0.5 means 100% */ + /** The efficiency of the producer. An efficiency of 1.0 means 100% */ public float productionEfficiency = 0.0f; @Override diff --git a/core/src/io/anuke/mindustry/world/blocks/power/PowerGraph.java b/core/src/io/anuke/mindustry/world/blocks/power/PowerGraph.java index e25e8a649e..c0c88feb5d 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/PowerGraph.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/PowerGraph.java @@ -167,7 +167,10 @@ public class PowerGraph{ tile.entity.power.graph = this; all.add(tile); - if(tile.block().outputsPower && tile.block().consumesPower){ + if(tile.block().outputsPower && tile.block().consumesPower && !tile.block().consumes.get(ConsumePower.class).isBuffered){ + producers.add(tile); + consumers.add(tile); + }else if(tile.block().outputsPower && tile.block().consumesPower){ batteries.add(tile); }else if(tile.block().outputsPower){ producers.add(tile); diff --git a/core/src/io/anuke/mindustry/world/blocks/power/PowerNode.java b/core/src/io/anuke/mindustry/world/blocks/power/PowerNode.java index c98c9fb952..3f7969efd8 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/PowerNode.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/PowerNode.java @@ -9,11 +9,11 @@ import io.anuke.arc.math.Mathf; import io.anuke.arc.math.geom.Vector2; import io.anuke.arc.math.Angles; import io.anuke.arc.util.Time; -import io.anuke.mindustry.entities.Player; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.Player; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.graphics.Layer; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.PowerBlock; import io.anuke.mindustry.world.meta.BlockStat; @@ -141,7 +141,7 @@ public class PowerNode extends PowerBlock{ Lines.stroke(1f); - Draw.color(Palette.accent); + Draw.color(Pal.accent); Lines.poly(tile.drawx(), tile.drawy(), 50, laserRange*tilesize); Draw.reset(); } @@ -150,9 +150,9 @@ public class PowerNode extends PowerBlock{ public void drawConfigure(Tile tile){ TileEntity entity = tile.entity(); - Draw.color(Palette.accent); + Draw.color(Pal.accent); - Lines.stroke(1f); + Lines.stroke(1.5f); Lines.circle(tile.drawx(), tile.drawy(), tile.block().size * tilesize / 2f + 1f + Mathf.absin(Time.time(), 4f, 1f)); @@ -165,14 +165,15 @@ public class PowerNode extends PowerBlock{ if(link != tile && linkValid(tile, link, false)){ boolean linked = linked(tile, link); - Draw.color(linked ? Palette.place : Palette.breakInvalid); + Draw.color(linked ? Pal.place : Pal.breakInvalid); Lines.circle(link.drawx(), link.drawy(), link.block().size * tilesize / 2f + 1f + (linked ? 0f : Mathf.absin(Time.time(), 4f, 1f))); if((entity.power.links.size >= maxNodes || (link.block() instanceof PowerNode && link.entity.power.links.size >= ((PowerNode) link.block()).maxNodes)) && !linked){ + Draw.color(Pal.breakInvalid); + Lines.lineAngleCenter(link.drawx(), link.drawy(), 45, link.block().size * Mathf.sqrt2 * tilesize * 0.9f); Draw.color(); - Draw.rect("cross-" + link.block().size, link.drawx(), link.drawy()); } } } @@ -184,7 +185,7 @@ public class PowerNode extends PowerBlock{ @Override public void drawPlace(int x, int y, int rotation, boolean valid){ Lines.stroke(1f); - Draw.color(Palette.placing); + Draw.color(Pal.placing); Lines.poly(x * tilesize + offset(), y * tilesize + offset(), 50, laserRange*tilesize); Draw.reset(); } @@ -197,8 +198,7 @@ public class PowerNode extends PowerBlock{ for(int i = 0; i < entity.power.links.size; i++){ Tile link = world.tile(entity.power.links.get(i)); - if(linkValid(tile, link) && (!(link.block() instanceof PowerNode) - || ((tile.block().size > link.block().size) || (tile.block().size == link.block().size && tile.pos() < link.pos())))){ + if(linkValid(tile, link)){ drawLaser(tile, link); } } @@ -245,7 +245,7 @@ public class PowerNode extends PowerBlock{ x2 += t2.x; y2 += t2.y; - Draw.color(Palette.powerLight, Palette.power, Mathf.absin(Time.time(), 8f, 1f)); + Draw.color(Pal.powerLight, Pal.power, Mathf.absin(Time.time(), 8f, 1f)); Lines.stroke(2f); Lines.line(x1, y1, x2, y2); } diff --git a/core/src/io/anuke/mindustry/world/blocks/power/SolarGenerator.java b/core/src/io/anuke/mindustry/world/blocks/power/SolarGenerator.java index 3090c389f3..96f3109fc9 100644 --- a/core/src/io/anuke/mindustry/world/blocks/power/SolarGenerator.java +++ b/core/src/io/anuke/mindustry/world/blocks/power/SolarGenerator.java @@ -1,6 +1,6 @@ package io.anuke.mindustry.world.blocks.power; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.world.meta.StatUnit; import io.anuke.arc.collection.EnumSet; diff --git a/core/src/io/anuke/mindustry/world/blocks/power/ThermalGenerator.java b/core/src/io/anuke/mindustry/world/blocks/power/ThermalGenerator.java new file mode 100644 index 0000000000..b0f79b0035 --- /dev/null +++ b/core/src/io/anuke/mindustry/world/blocks/power/ThermalGenerator.java @@ -0,0 +1,55 @@ +package io.anuke.mindustry.world.blocks.power; + +import io.anuke.mindustry.entities.Effects; +import io.anuke.mindustry.entities.Effects.Effect; +import io.anuke.arc.math.Mathf; +import io.anuke.mindustry.content.Fx; +import io.anuke.mindustry.world.Tile; + +public class ThermalGenerator extends PowerGenerator{ + protected Effect generateEffect = Fx.none; + + public ThermalGenerator(String name){ + super(name); + } + + @Override + public void update(Tile tile){ + GeneratorEntity entity = tile.entity(); + + if(entity.productionEfficiency > 0.1f && Mathf.chance(0.05 * entity.delta())){ + Effects.effect(generateEffect, tile.drawx() + Mathf.range(3f), tile.drawy() + Mathf.range(3f)); + } + + super.update(tile); + } + + @Override + public void placed(Tile tile){ + super.placed(tile); + } + + @Override + public void onProximityAdded(Tile tile){ + super.onProximityAdded(tile); + + GeneratorEntity entity = tile.entity(); + entity.productionEfficiency = 0f; + for(Tile other : tile.getLinkedTiles(tempTiles)){ + entity.productionEfficiency += other.floor().heat; + } + } + + @Override + public float getPowerProduction(Tile tile){ + //in this case, productionEfficiency means 'total heat' + //thus, it may be greater than 1.0 + return powerProduction * tile.entity().productionEfficiency; + } + + @Override + public boolean canPlaceOn(Tile tile){ + //make sure there's heat at this location + return tile.getLinkedTilesAs(this, tempTiles).sum(other -> other.floor().heat) > 0.01f; + } +} diff --git a/core/src/io/anuke/mindustry/world/blocks/production/Cultivator.java b/core/src/io/anuke/mindustry/world/blocks/production/Cultivator.java index 59cd3d8da9..857ab635a3 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Cultivator.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Cultivator.java @@ -8,43 +8,26 @@ import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.math.Mathf; import io.anuke.arc.math.RandomXS128; import io.anuke.arc.util.Time; -import io.anuke.mindustry.content.Items; -import io.anuke.mindustry.content.Blocks; import io.anuke.mindustry.content.Fx; -import io.anuke.mindustry.entities.TileEntity; -import io.anuke.mindustry.type.Item; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.world.Tile; -import io.anuke.mindustry.world.meta.BlockStat; import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; -public class Cultivator extends Drill{ - protected Color plantColor = Color.valueOf("648b55"); - protected Color plantColorLight = Color.valueOf("73a75f"); - protected Color bottomColor = Color.valueOf("474747"); +public class Cultivator extends GenericCrafter{ + protected static final Color plantColor = Color.valueOf("648b55"); + protected static final Color plantColorLight = Color.valueOf("73a75f"); + protected static final Color bottomColor = Color.valueOf("474747"); + protected TextureRegion middleRegion, topRegion; - - protected Item result; - protected RandomXS128 random = new RandomXS128(0); protected float recurrence = 6f; public Cultivator(String name){ super(name); - drillEffect = Fx.none; - } - - @Override - public void setStats(){ - super.setStats(); - - stats.remove(BlockStat.drillTier); - stats.add(BlockStat.drillTier, table -> { - table.addImage("grass1").size(8 * 3).padBottom(3).padTop(3); - table.add(Blocks.grass.formalName).padLeft(3); - }); + craftEffect = Fx.none; } @Override @@ -101,17 +84,7 @@ public class Cultivator extends Drill{ return new CultivatorEntity(); } - @Override - public boolean isValid(Tile tile){ - return tile != null && tile.floor() == Blocks.grass; - } - - @Override - public Item getDrop(Tile tile){ - return Items.biomatter; - } - - public static class CultivatorEntity extends DrillEntity{ + public static class CultivatorEntity extends GenericCrafterEntity{ public float warmup; @Override diff --git a/core/src/io/anuke/mindustry/world/blocks/production/Drill.java b/core/src/io/anuke/mindustry/world/blocks/production/Drill.java index 61600aa5fe..bdd3279187 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Drill.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Drill.java @@ -3,8 +3,8 @@ package io.anuke.mindustry.world.blocks.production; import io.anuke.arc.Core; import io.anuke.arc.collection.Array; import io.anuke.arc.collection.ObjectIntMap; -import io.anuke.arc.entities.Effects; -import io.anuke.arc.entities.Effects.Effect; +import io.anuke.mindustry.entities.Effects; +import io.anuke.mindustry.entities.Effects.Effect; import io.anuke.arc.graphics.Blending; import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.g2d.Draw; @@ -13,7 +13,7 @@ import io.anuke.arc.math.Mathf; import io.anuke.arc.util.Time; import io.anuke.mindustry.content.Fx; import io.anuke.mindustry.content.Liquids; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.graphics.Layer; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.world.Block; diff --git a/core/src/io/anuke/mindustry/world/blocks/production/Fracker.java b/core/src/io/anuke/mindustry/world/blocks/production/Fracker.java index cc1e4c4830..2f6e2609a0 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Fracker.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Fracker.java @@ -2,7 +2,7 @@ package io.anuke.mindustry.world.blocks.production; import io.anuke.arc.Core; import io.anuke.arc.graphics.g2d.TextureRegion; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.consumers.ConsumeItem; diff --git a/core/src/io/anuke/mindustry/world/blocks/production/GenericCrafter.java b/core/src/io/anuke/mindustry/world/blocks/production/GenericCrafter.java index eab07cc6c4..09ea091647 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/GenericCrafter.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/GenericCrafter.java @@ -1,12 +1,12 @@ package io.anuke.mindustry.world.blocks.production; -import io.anuke.arc.entities.Effects; -import io.anuke.arc.entities.Effects.Effect; +import io.anuke.mindustry.entities.Effects; +import io.anuke.mindustry.entities.Effects.Effect; import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.math.Mathf; import io.anuke.arc.util.Time; import io.anuke.mindustry.content.Fx; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; @@ -78,6 +78,8 @@ public class GenericCrafter extends Block{ if(entity.progress >= 1f){ + //TODO, bad design, crafter has to know that this consumes items + //there should be a separate trigger in #cons to consume discrete amounts of items if(consumes.has(ConsumeItem.class)) tile.entity.items.remove(consumes.item(), consumes.itemAmount()); useContent(tile, output); diff --git a/core/src/io/anuke/mindustry/world/blocks/production/Incinerator.java b/core/src/io/anuke/mindustry/world/blocks/production/Incinerator.java index 28574e24d0..23825bf5a8 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Incinerator.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Incinerator.java @@ -1,14 +1,14 @@ package io.anuke.mindustry.world.blocks.production; -import io.anuke.arc.entities.Effects; -import io.anuke.arc.entities.Effects.Effect; +import io.anuke.mindustry.entities.Effects; +import io.anuke.mindustry.entities.Effects.Effect; import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.graphics.g2d.Fill; import io.anuke.arc.math.Mathf; import io.anuke.arc.util.Time; import io.anuke.mindustry.content.Fx; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.Liquid; import io.anuke.mindustry.world.Block; @@ -24,9 +24,6 @@ public class Incinerator extends Block{ hasLiquids = true; update = true; solid = true; - - // Incinerator has no speed which could be adjusted, so it will only operate fully powered for now - consumes.power(0.05f, 1.0f); } @Override diff --git a/core/src/io/anuke/mindustry/world/blocks/production/LiquidMixer.java b/core/src/io/anuke/mindustry/world/blocks/production/LiquidMixer.java index 00767ef304..9f0cb76b22 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/LiquidMixer.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/LiquidMixer.java @@ -1,6 +1,6 @@ package io.anuke.mindustry.world.blocks.production; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.type.Liquid; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.LiquidBlock; diff --git a/core/src/io/anuke/mindustry/world/blocks/production/PhaseWeaver.java b/core/src/io/anuke/mindustry/world/blocks/production/PhaseWeaver.java index 2881afc5a6..ae7b2e3530 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/PhaseWeaver.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/PhaseWeaver.java @@ -6,7 +6,7 @@ import io.anuke.arc.graphics.g2d.Lines; import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.math.Mathf; import io.anuke.mindustry.Vars; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.graphics.Shaders; import io.anuke.mindustry.world.Tile; @@ -41,7 +41,7 @@ public class PhaseWeaver extends PowerSmelter{ Shaders.build.region = weaveRegion; Shaders.build.progress = progress; - Shaders.build.color.set(Palette.accent); + Shaders.build.color.set(Pal.accent); Shaders.build.color.a = entity.heat; Shaders.build.time = -entity.time / 10f; @@ -50,7 +50,7 @@ public class PhaseWeaver extends PowerSmelter{ Draw.rect(weaveRegion, tile.drawx(), tile.drawy(), entity.time); Draw.shader(); - Draw.color(Palette.accent); + Draw.color(Pal.accent); Draw.alpha(entity.heat); Lines.lineAngleCenter( diff --git a/core/src/io/anuke/mindustry/world/blocks/production/PowerCrafter.java b/core/src/io/anuke/mindustry/world/blocks/production/PowerCrafter.java index 787b705453..c57831f628 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/PowerCrafter.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/PowerCrafter.java @@ -1,6 +1,6 @@ package io.anuke.mindustry.world.blocks.production; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.Liquid; import io.anuke.mindustry.world.Block; @@ -8,6 +8,8 @@ import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.production.GenericCrafter.GenericCrafterEntity; import io.anuke.mindustry.world.meta.BlockStat; +/**Similar to GenericCrafter, but also optionally outputs liquids. + * TODO consolidate into one class*/ public class PowerCrafter extends Block{ protected final int timerDump = timers++; protected final int timerContentCheck = timers++; diff --git a/core/src/io/anuke/mindustry/world/blocks/production/PowerSmelter.java b/core/src/io/anuke/mindustry/world/blocks/production/PowerSmelter.java index bf2db8d3c4..b6d39ad5f9 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/PowerSmelter.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/PowerSmelter.java @@ -1,17 +1,16 @@ package io.anuke.mindustry.world.blocks.production; import io.anuke.arc.Core; -import io.anuke.arc.entities.Effects; -import io.anuke.arc.entities.Effects.Effect; +import io.anuke.mindustry.entities.Effects; +import io.anuke.mindustry.entities.Effects.Effect; import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.graphics.g2d.Fill; import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.math.Mathf; import io.anuke.arc.util.Time; -import io.anuke.mindustry.content.Items; import io.anuke.mindustry.content.Fx; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.ItemStack; import io.anuke.mindustry.world.Tile; @@ -23,19 +22,10 @@ import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; -import static io.anuke.mindustry.Vars.content; - public class PowerSmelter extends PowerBlock{ protected final int timerDump = timers++; - protected final int timerCraft = timers++; - protected Item result; - - protected float minFlux = 0.2f; - protected int fluxNeeded = 1; - protected float fluxSpeedMult = 0.75f; - protected float baseFluxChance = 0.25f; - protected boolean useFlux = false; + protected Item output; protected float heatUpTime = 80f; protected float minHeat = 0.5f; @@ -57,13 +47,9 @@ public class PowerSmelter extends PowerBlock{ @Override public void init(){ - if(useFlux){ - consumes.item(Items.sand).optional(true); - } - super.init(); - produces.set(result); + produces.set(output); } @Override @@ -76,7 +62,7 @@ public class PowerSmelter extends PowerBlock{ public void setStats(){ super.setStats(); - stats.add(BlockStat.outputItem, result); + stats.add(BlockStat.outputItem, output); stats.add(BlockStat.craftSpeed, 60f / craftTime, StatUnit.itemsSecond); stats.add(BlockStat.inputItemCapacity, itemCapacity, StatUnit.items); stats.add(BlockStat.outputItemCapacity, itemCapacity, StatUnit.items); @@ -87,8 +73,8 @@ public class PowerSmelter extends PowerBlock{ PowerSmelterEntity entity = tile.entity(); - if(entity.timer.get(timerDump, 5) && entity.items.has(result)){ - tryDump(tile, result); + if(entity.timer.get(timerDump, 5) && entity.items.has(output)){ + tryDump(tile, output); } //heat it up if there's enough power @@ -107,46 +93,21 @@ public class PowerSmelter extends PowerBlock{ return; } - float baseSmeltSpeed = 1f; - for(Item item : content.items()){ - if(item.fluxiness >= minFlux && tile.entity.items.get(item) > 0){ - baseSmeltSpeed = fluxSpeedMult; - break; - } - } - entity.craftTime += entity.delta() * entity.power.satisfaction; - if(entity.items.get(result) >= itemCapacity //output full + if(entity.items.get(output) >= itemCapacity //output full || entity.heat <= minHeat //not burning - || entity.craftTime < craftTime*baseSmeltSpeed){ //not yet time + || entity.craftTime < craftTime){ //not yet time return; } entity.craftTime = 0f; - boolean consumeInputs = true; - - if(useFlux){ - //remove flux materials if present - for(Item item : content.items()){ - if(item.fluxiness >= minFlux && tile.entity.items.get(item) >= fluxNeeded){ - tile.entity.items.remove(item, fluxNeeded); - - //chance of not consuming inputs if flux material present - consumeInputs = !Mathf.chance(item.fluxiness * baseFluxChance); - break; - } - } + for(ItemStack item : consumes.items()){ + entity.items.remove(item.item, item.amount); } - if(consumeInputs){ - for(ItemStack item : consumes.items()){ - entity.items.remove(item.item, item.amount); - } - } - - offloadNear(tile, result); + offloadNear(tile, output); Effects.effect(craftEffect, flameColor, tile.drawx(), tile.drawy()); } @@ -159,8 +120,7 @@ public class PowerSmelter extends PowerBlock{ } } - return useFlux && item.fluxiness >= minFlux && tile.entity.items.get(item) < itemCapacity; - + return false; } @Override diff --git a/core/src/io/anuke/mindustry/world/blocks/production/Separator.java b/core/src/io/anuke/mindustry/world/blocks/production/Separator.java index d1cdccf51a..251429e2ea 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Separator.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Separator.java @@ -6,7 +6,7 @@ import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.graphics.g2d.Lines; import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.math.Mathf; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.ItemStack; import io.anuke.mindustry.world.Block; diff --git a/core/src/io/anuke/mindustry/world/blocks/production/Smelter.java b/core/src/io/anuke/mindustry/world/blocks/production/Smelter.java index 68be2ba020..40d3ea3268 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/Smelter.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/Smelter.java @@ -1,8 +1,14 @@ package io.anuke.mindustry.world.blocks.production; +import io.anuke.mindustry.entities.Effects; +import io.anuke.mindustry.entities.Effects.Effect; import io.anuke.arc.graphics.Color; +import io.anuke.arc.graphics.g2d.Draw; +import io.anuke.arc.graphics.g2d.Fill; +import io.anuke.arc.math.Mathf; +import io.anuke.arc.util.Time; import io.anuke.mindustry.content.Fx; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.ItemStack; import io.anuke.mindustry.world.Block; @@ -11,25 +17,12 @@ import io.anuke.mindustry.world.consumers.ConsumeItem; import io.anuke.mindustry.world.consumers.ConsumeItems; import io.anuke.mindustry.world.meta.BlockStat; import io.anuke.mindustry.world.meta.StatUnit; -import io.anuke.arc.entities.Effects; -import io.anuke.arc.entities.Effects.Effect; -import io.anuke.arc.util.Time; -import io.anuke.arc.graphics.g2d.Draw; -import io.anuke.arc.graphics.g2d.Fill; -import io.anuke.arc.math.Mathf; - -import static io.anuke.mindustry.Vars.*; public class Smelter extends Block{ protected final int timerDump = timers++; protected Item result; - protected float minFlux = 0.2f; - protected float fluxSpeedMult = 0.75f; - protected float baseFluxChance = 0.25f; - protected boolean useFlux = false; - protected float craftTime = 20f; protected float burnDuration = 50f; protected Effect craftEffect = Fx.smelt, burnEffect = Fx.fuelburn; @@ -61,13 +54,6 @@ public class Smelter extends Block{ @Override public void init(){ super.init(); - - for(ItemStack item : consumes.items()){ - if(item.item.fluxiness >= minFlux && useFlux){ - throw new IllegalArgumentException("'" + name + "' has input item '" + item.item.name + "', which is a flux, when useFlux is enabled. To prevent ambiguous item use, either remove this flux item from the inputs, or set useFlux to false."); - } - } - produces.set(result); } @@ -99,43 +85,17 @@ public class Smelter extends Block{ return; } - float baseSmeltSpeed = 1f; - for(Item item : content.items()){ - if(item.fluxiness >= minFlux && tile.entity.items.get(item) > 0){ - baseSmeltSpeed = fluxSpeedMult; - break; - } - } - entity.craftTime += entity.delta(); if(entity.items.get(result) >= itemCapacity //output full || entity.burnTime <= 0 //not burning - || entity.craftTime < craftTime*baseSmeltSpeed){ //not yet time + || entity.craftTime < craftTime){ //not yet time return; } entity.craftTime = 0f; - - boolean consumeInputs = true; - - if(useFlux){ - //remove flux materials if present - for(Item item : content.items()){ - if(item.fluxiness >= minFlux && tile.entity.items.get(item) > 0){ - tile.entity.items.remove(item, 1); - - //chance of not consuming inputs if flux material present - consumeInputs = !Mathf.chance(item.fluxiness * baseFluxChance); - break; - } - } - } - - if(consumeInputs){ - for(ItemStack item : consumes.items()){ - entity.items.remove(item.item, item.amount); - } + for(ItemStack item : consumes.items()){ + entity.items.remove(item.item, item.amount); } offloadNear(tile, result); @@ -153,8 +113,7 @@ public class Smelter extends Block{ } } - return (isInput && tile.entity.items.get(item) < itemCapacity) || (item == consumes.item() && tile.entity.items.get(consumes.item()) < itemCapacity) || - (useFlux && item.fluxiness >= minFlux && tile.entity.items.get(item) < itemCapacity); + return (isInput && tile.entity.items.get(item) < itemCapacity) || (item == consumes.item() && tile.entity.items.get(consumes.item()) < itemCapacity); } @Override diff --git a/core/src/io/anuke/mindustry/world/blocks/production/SolidPump.java b/core/src/io/anuke/mindustry/world/blocks/production/SolidPump.java index 89d0635583..7af581fa66 100644 --- a/core/src/io/anuke/mindustry/world/blocks/production/SolidPump.java +++ b/core/src/io/anuke/mindustry/world/blocks/production/SolidPump.java @@ -4,12 +4,12 @@ import io.anuke.arc.Core; import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.mindustry.content.Liquids; import io.anuke.mindustry.content.Fx; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.type.Liquid; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.meta.BlockStat; -import io.anuke.arc.entities.Effects; -import io.anuke.arc.entities.Effects.Effect; +import io.anuke.mindustry.entities.Effects; +import io.anuke.mindustry.entities.Effects.Effect; import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.math.Mathf; diff --git a/core/src/io/anuke/mindustry/world/blocks/sandbox/LiquidSource.java b/core/src/io/anuke/mindustry/world/blocks/sandbox/LiquidSource.java index 26cb7fd389..2901e5fab7 100644 --- a/core/src/io/anuke/mindustry/world/blocks/sandbox/LiquidSource.java +++ b/core/src/io/anuke/mindustry/world/blocks/sandbox/LiquidSource.java @@ -4,22 +4,24 @@ import io.anuke.annotations.Annotations.Loc; import io.anuke.annotations.Annotations.Remote; import io.anuke.arc.collection.Array; import io.anuke.arc.graphics.g2d.Draw; +import io.anuke.arc.scene.style.TextureRegionDrawable; import io.anuke.arc.scene.ui.ButtonGroup; import io.anuke.arc.scene.ui.ImageButton; import io.anuke.arc.scene.ui.layout.Table; import io.anuke.mindustry.content.Liquids; -import io.anuke.mindustry.entities.Player; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.Player; +import io.anuke.mindustry.entities.type.TileEntity; +import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.type.Liquid; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; -import io.anuke.mindustry.gen.Call; import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; -import static io.anuke.mindustry.Vars.*; +import static io.anuke.mindustry.Vars.content; +import static io.anuke.mindustry.Vars.data; public class LiquidSource extends Block{ @@ -65,8 +67,9 @@ public class LiquidSource extends Block{ if(!data.isUnlocked(items.get(i))) continue; final int f = i; - ImageButton button = cont.addImageButton("liquid-icon-" + items.get(i).name, "clear-toggle", 24, + ImageButton button = cont.addImageButton("clear", "clear-toggle", 24, () -> Call.setLiquidSourceLiquid(null, tile, items.get(f))).size(38).group(group).get(); + button.getStyle().imageUp = new TextureRegionDrawable(items.get(i).iconRegion); button.setChecked(entity.source.id == f); if(i % 4 == 3){ diff --git a/core/src/io/anuke/mindustry/world/blocks/storage/CoreBlock.java b/core/src/io/anuke/mindustry/world/blocks/storage/CoreBlock.java index a62b7e30f3..3a4d106d24 100644 --- a/core/src/io/anuke/mindustry/world/blocks/storage/CoreBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/storage/CoreBlock.java @@ -4,31 +4,30 @@ import io.anuke.annotations.Annotations.Loc; import io.anuke.annotations.Annotations.Remote; import io.anuke.arc.Core; import io.anuke.arc.collection.EnumSet; -import io.anuke.arc.entities.Effects; +import io.anuke.mindustry.entities.Effects; import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.graphics.g2d.Lines; import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.math.Mathf; import io.anuke.mindustry.Vars; import io.anuke.mindustry.content.Fx; -import io.anuke.mindustry.entities.Player; -import io.anuke.mindustry.entities.TileEntity; -import io.anuke.mindustry.entities.Unit; +import io.anuke.mindustry.entities.type.Player; +import io.anuke.mindustry.entities.type.TileEntity; +import io.anuke.mindustry.entities.type.Unit; import io.anuke.mindustry.entities.traits.SpawnerTrait; import io.anuke.mindustry.gen.Call; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.graphics.Shaders; import io.anuke.mindustry.net.Net; import io.anuke.mindustry.type.Item; +import io.anuke.mindustry.type.ItemType; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.meta.BlockFlag; import static io.anuke.mindustry.Vars.*; -public class CoreBlock extends LaunchPad{ +public class CoreBlock extends StorageBlock{ protected TextureRegion topRegion; - protected int launchThreshold; - protected int launchChunkSize; public CoreBlock(String name){ super(name); @@ -36,19 +35,18 @@ public class CoreBlock extends LaunchPad{ solid = true; update = true; hasItems = true; - size = 3; - flags = EnumSet.of(BlockFlag.resupplyPoint, BlockFlag.target); + flags = EnumSet.of(BlockFlag.target); } @Remote(called = Loc.server) - public static void onUnitRespawn(Tile tile, Unit player){ + public static void onUnitRespawn(Tile tile, Player player){ if(player == null || tile.entity == null) return; CoreEntity entity = tile.entity(); Effects.effect(Fx.spawn, entity); entity.progress = 0; - entity.currentUnit.onRespawn(tile); entity.currentUnit = player; + entity.currentUnit.onRespawn(tile); entity.currentUnit.heal(); entity.currentUnit.rotation = 90f; entity.currentUnit.applyImpulse(0, 8f); @@ -56,14 +54,12 @@ public class CoreBlock extends LaunchPad{ entity.currentUnit.add(); entity.currentUnit = null; - if(player instanceof Player){ - ((Player) player).endRespawning(); - } + player.endRespawning(); } @Override public int getMaximumAccepted(Tile tile, Item item){ - return itemCapacity * state.teams.get(tile.getTeam()).cores.size; + return item.type == ItemType.material ? itemCapacity * state.teams.get(tile.getTeam()).cores.size : 0; } @Override @@ -120,14 +116,14 @@ public class CoreBlock extends LaunchPad{ Shaders.build.region = region; Shaders.build.progress = entity.progress; - Shaders.build.color.set(Palette.accent); + Shaders.build.color.set(Pal.accent); Shaders.build.time = -entity.time / 10f; Draw.shader(Shaders.build, true); Draw.rect(region, tile.drawx(), tile.drawy()); Draw.shader(); - Draw.color(Palette.accent); + Draw.color(Pal.accent); Lines.lineAngleCenter( tile.drawx() + Mathf.sin(entity.time, 6f, Vars.tilesize / 3f * size), @@ -148,20 +144,12 @@ public class CoreBlock extends LaunchPad{ public void update(Tile tile){ CoreEntity entity = tile.entity(); - for(Item item : Vars.content.items()){ - if(entity.items.get(item) >= launchThreshold + launchChunkSize && entity.timer.get(timerLaunch, launchTime)){ - //TODO play animation of some sort - Effects.effect(Fx.dooropenlarge, tile); - data.addItem(item, launchChunkSize); - entity.items.remove(item, launchChunkSize); - } - } - if(entity.currentUnit != null){ - if(!entity.currentUnit.isDead()){ + if(!entity.currentUnit.isDead() || !entity.currentUnit.isAdded()){ entity.currentUnit = null; return; } + entity.heat = Mathf.lerpDelta(entity.heat, 1f, 0.1f); entity.time += entity.delta(); entity.progress += 1f / state.rules.respawnTime * entity.delta(); @@ -169,6 +157,8 @@ public class CoreBlock extends LaunchPad{ if(entity.progress >= 1f){ Call.onUnitRespawn(tile, entity.currentUnit); } + }else{ + entity.heat = Mathf.lerpDelta(entity.heat, 0f, 0.1f); } } @@ -178,23 +168,18 @@ public class CoreBlock extends LaunchPad{ } public class CoreEntity extends TileEntity implements SpawnerTrait{ - public Unit currentUnit; + public Player currentUnit; float progress; float time; float heat; @Override - public void updateSpawning(Unit unit){ + public void updateSpawning(Player unit){ if(!netServer.isWaitingForPlayers() && currentUnit == null){ currentUnit = unit; progress = 0f; unit.set(tile.drawx(), tile.drawy()); } } - - @Override - public float getSpawnProgress(){ - return progress; - } } } diff --git a/core/src/io/anuke/mindustry/world/blocks/storage/LaunchPad.java b/core/src/io/anuke/mindustry/world/blocks/storage/LaunchPad.java index 5647974149..94875bac5b 100644 --- a/core/src/io/anuke/mindustry/world/blocks/storage/LaunchPad.java +++ b/core/src/io/anuke/mindustry/world/blocks/storage/LaunchPad.java @@ -1,14 +1,15 @@ package io.anuke.mindustry.world.blocks.storage; -import io.anuke.arc.entities.Effects; +import io.anuke.mindustry.entities.Effects; import io.anuke.mindustry.Vars; import io.anuke.mindustry.content.Fx; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.ItemType; import io.anuke.mindustry.world.Tile; import static io.anuke.mindustry.Vars.data; +import static io.anuke.mindustry.Vars.world; public class LaunchPad extends StorageBlock{ protected final int timerLaunch = timers++; @@ -31,7 +32,7 @@ public class LaunchPad extends StorageBlock{ public void update(Tile tile){ TileEntity entity = tile.entity; - if(entity.cons.valid()){ + if(entity.cons.valid() && world.isZone()){ for(Item item : Vars.content.items()){ if(entity.items.get(item) >= itemCapacity && entity.timer.get(timerLaunch, launchTime)){ //TODO play animation of some sort diff --git a/core/src/io/anuke/mindustry/world/blocks/storage/SortedUnloader.java b/core/src/io/anuke/mindustry/world/blocks/storage/SortedUnloader.java index 90b0ca917f..510fb22d66 100644 --- a/core/src/io/anuke/mindustry/world/blocks/storage/SortedUnloader.java +++ b/core/src/io/anuke/mindustry/world/blocks/storage/SortedUnloader.java @@ -4,8 +4,8 @@ import io.anuke.arc.Core; import io.anuke.arc.graphics.Color; import io.anuke.annotations.Annotations.Loc; import io.anuke.annotations.Annotations.Remote; -import io.anuke.mindustry.entities.Player; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.Player; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.gen.Call; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.world.Block; diff --git a/core/src/io/anuke/mindustry/world/blocks/storage/StorageBlock.java b/core/src/io/anuke/mindustry/world/blocks/storage/StorageBlock.java index 08148c65e6..58739c63c5 100644 --- a/core/src/io/anuke/mindustry/world/blocks/storage/StorageBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/storage/StorageBlock.java @@ -1,6 +1,6 @@ package io.anuke.mindustry.world.blocks.storage; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; diff --git a/core/src/io/anuke/mindustry/world/blocks/units/MechPad.java b/core/src/io/anuke/mindustry/world/blocks/units/MechPad.java index 38257657d4..e0b959e1ff 100644 --- a/core/src/io/anuke/mindustry/world/blocks/units/MechPad.java +++ b/core/src/io/anuke/mindustry/world/blocks/units/MechPad.java @@ -3,7 +3,6 @@ package io.anuke.mindustry.world.blocks.units; import io.anuke.annotations.Annotations.Loc; import io.anuke.annotations.Annotations.Remote; import io.anuke.arc.Core; -import io.anuke.arc.entities.Effects; import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.graphics.g2d.Lines; import io.anuke.arc.graphics.g2d.TextureRegion; @@ -11,15 +10,15 @@ import io.anuke.arc.math.Mathf; import io.anuke.arc.math.geom.Geometry; import io.anuke.arc.util.Time; import io.anuke.mindustry.Vars; -import io.anuke.mindustry.content.Mechs; import io.anuke.mindustry.content.Fx; -import io.anuke.mindustry.entities.Player; -import io.anuke.mindustry.entities.TileEntity; -import io.anuke.mindustry.entities.Unit; +import io.anuke.mindustry.content.Mechs; +import io.anuke.mindustry.entities.Effects; import io.anuke.mindustry.entities.Units; import io.anuke.mindustry.entities.traits.SpawnerTrait; +import io.anuke.mindustry.entities.type.Player; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.gen.Call; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.graphics.Shaders; import io.anuke.mindustry.type.Mech; import io.anuke.mindustry.world.Block; @@ -82,7 +81,12 @@ public class MechPad extends Block{ Mech result = ((MechPad) tile.block()).mech; if(entity.player.mech == result){ - entity.player.mech = (entity.player.isMobile ? Mechs.starterMobile : Mechs.starterDesktop); + Mech target = (entity.player.isMobile ? Mechs.starterMobile : Mechs.starterDesktop); + if(entity.player.mech == target){ + entity.player.mech = (entity.player.isMobile ? Mechs.starterDesktop : Mechs.starterMobile); + }else{ + entity.player.mech = target; + } }else{ entity.player.mech = result; } @@ -92,7 +96,7 @@ public class MechPad extends Block{ entity.player.endRespawning(); entity.open = true; entity.player.setDead(false); - entity.player.inventory.clear(); + entity.player.clearItem(); entity.player = null; } @@ -104,7 +108,7 @@ public class MechPad extends Block{ @Override public void drawSelect(Tile tile){ - Draw.color(Palette.accent); + Draw.color(Pal.accent); for(int i = 0; i < 4; i ++){ float length = tilesize * size/2f + 3 + Mathf.absin(Time.time(), 5f, 2f); Draw.rect("transfer-arrow", tile.drawx() + Geometry.d4[i].x * length, tile.drawy() + Geometry.d4[i].y * length, (i+2) * 90); @@ -150,14 +154,14 @@ public class MechPad extends Block{ Shaders.build.region = region; Shaders.build.progress = entity.progress; Shaders.build.time = -entity.time / 4f; - Shaders.build.color.set(Palette.accent); + Shaders.build.color.set(Pal.accent); Draw.shader(Shaders.build, false); Shaders.build.apply(); Draw.rect(region, tile.drawx(), tile.drawy()); Draw.shader(); - Draw.color(Palette.accent); + Draw.color(Pal.accent); Lines.lineAngleCenter( tile.drawx() + Mathf.sin(entity.time, 6f, Vars.tilesize / 3f * size), @@ -212,13 +216,10 @@ public class MechPad extends Block{ boolean open; @Override - public void updateSpawning(Unit unit){ - if(!(unit instanceof Player)) - throw new IllegalArgumentException("Mech factories only accept player respawners."); - + public void updateSpawning(Player unit){ if(player == null){ progress = 0f; - player = (Player) unit; + player = unit; player.rotation = 90f; player.baseRotation = 90f; @@ -227,11 +228,6 @@ public class MechPad extends Block{ } } - @Override - public float getSpawnProgress(){ - return progress; - } - @Override public void write(DataOutput stream) throws IOException{ stream.writeFloat(progress); diff --git a/core/src/io/anuke/mindustry/world/blocks/units/Reconstructor.java b/core/src/io/anuke/mindustry/world/blocks/units/Reconstructor.java deleted file mode 100644 index de7753e644..0000000000 --- a/core/src/io/anuke/mindustry/world/blocks/units/Reconstructor.java +++ /dev/null @@ -1,339 +0,0 @@ -package io.anuke.mindustry.world.blocks.units; - -import io.anuke.annotations.Annotations.Loc; -import io.anuke.annotations.Annotations.Remote; -import io.anuke.arc.Core; -import io.anuke.arc.entities.Effects; -import io.anuke.arc.entities.Effects.Effect; -import io.anuke.arc.graphics.g2d.Draw; -import io.anuke.arc.graphics.g2d.Lines; -import io.anuke.arc.graphics.g2d.TextureRegion; -import io.anuke.arc.math.Mathf; -import io.anuke.arc.util.Time; -import io.anuke.mindustry.Vars; -import io.anuke.mindustry.content.Fx; -import io.anuke.mindustry.entities.Player; -import io.anuke.mindustry.entities.TileEntity; -import io.anuke.mindustry.entities.Unit; -import io.anuke.mindustry.entities.Units; -import io.anuke.mindustry.entities.traits.SpawnerTrait; -import io.anuke.mindustry.gen.Call; -import io.anuke.mindustry.graphics.Palette; -import io.anuke.mindustry.graphics.Shaders; -import io.anuke.mindustry.world.Block; -import io.anuke.mindustry.world.Tile; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -import static io.anuke.mindustry.Vars.tilesize; -import static io.anuke.mindustry.Vars.world; - -//TODO re-implement properly -public class Reconstructor extends Block{ - protected float departTime = 30f; - protected float arriveTime = 40f; - /** Stores the percentage of buffered power to be used upon teleporting. */ - protected float powerPerTeleport = 0.5f; - protected Effect arriveEffect = Fx.spawn; - protected TextureRegion openRegion; - - public Reconstructor(String name){ - super(name); - update = true; - solidifes = true; - hasPower = true; - configurable = true; - consumes.powerBuffered(30f); - } - - protected static boolean checkValidTap(Tile tile, ReconstructorEntity entity, Player player){ - return validLink(tile, entity.link) && - Math.abs(player.x - tile.drawx()) <= tile.block().size * tilesize / 2f && - Math.abs(player.y - tile.drawy()) <= tile.block().size * tilesize / 2f && - entity.current == null && entity.power.satisfaction >= ((Reconstructor) tile.block()).powerPerTeleport; - } - - protected static boolean validLink(Tile tile, int position){ - Tile other = world.tile(position); - return other != tile && other != null && other.block() instanceof Reconstructor; - } - - protected static void unlink(ReconstructorEntity entity){ - Tile other = world.tile(entity.link); - - if(other != null && other.block() instanceof Reconstructor){ - ReconstructorEntity oe = other.entity(); - if(oe.link == entity.tile.pos()){ - oe.link = -1; - } - } - - entity.link = -1; - } - - @Remote(targets = Loc.both, called = Loc.server, forward = true) - public static void reconstructPlayer(Player player, Tile tile){ - ReconstructorEntity entity = tile.entity(); - - if(!checkValidTap(tile, entity, player) || entity.power.satisfaction < ((Reconstructor) tile.block()).powerPerTeleport) - return; - - entity.departing = true; - entity.current = player; - entity.solid = false; - entity.power.satisfaction -= Math.min(entity.power.satisfaction, ((Reconstructor) tile.block()).powerPerTeleport); - entity.updateTime = 1f; - entity.set(tile.drawx(), tile.drawy()); - player.rotation = 90f; - player.baseRotation = 90f; - player.setDead(true); - // player.setRespawning(true); - //player.setRespawning(); - } - - @Remote(targets = Loc.both, called = Loc.server, forward = true) - public static void linkReconstructor(Player player, Tile tile, Tile other){ - //just in case the client has invalid data - if(!(tile.entity instanceof ReconstructorEntity) || !(other.entity instanceof ReconstructorEntity)) return; - - ReconstructorEntity entity = tile.entity(); - ReconstructorEntity oe = other.entity(); - - unlink(entity); - unlink(oe); - - entity.link = other.pos(); - oe.link = tile.pos(); - } - - @Remote(targets = Loc.both, called = Loc.server, forward = true) - public static void unlinkReconstructor(Player player, Tile tile, Tile other){ - //just in case the client has invalid data - if(!(tile.entity instanceof ReconstructorEntity) || !(other.entity instanceof ReconstructorEntity)) return; - - ReconstructorEntity entity = tile.entity(); - ReconstructorEntity oe = other.entity(); - - //called in main thread to prevent issues - unlink(entity); - unlink(oe); - } - - @Override - public void load(){ - super.load(); - openRegion = Core.atlas.find(name + "-open"); - } - - @Override - public boolean isSolidFor(Tile tile){ - ReconstructorEntity entity = tile.entity(); - - return entity.solid; - } - - @Override - public void drawConfigure(Tile tile){ - super.drawConfigure(tile); - - ReconstructorEntity entity = tile.entity(); - - if(validLink(tile, entity.link)){ - Tile target = world.tile(entity.link); - - Draw.color(Palette.place); - Lines.square(target.drawx(), target.drawy(), - target.block().size * tilesize / 2f + 1f); - Draw.reset(); - } - - Draw.color(Palette.accent); - Draw.color(); - } - - @Override - public boolean onConfigureTileTapped(Tile tile, Tile other){ - if(tile == other) return false; - - ReconstructorEntity entity = tile.entity(); - - if(entity.link == other.pos()){ - Call.unlinkReconstructor(null, tile, other); - return false; - }else if(other.block() instanceof Reconstructor){ - Call.linkReconstructor(null, tile, other); - return false; - } - - return true; - } - - @Override - public boolean shouldShowConfigure(Tile tile, Player player){ - ReconstructorEntity entity = tile.entity(); - return !checkValidTap(tile, entity, player); - } - - @Override - public boolean shouldHideConfigure(Tile tile, Player player){ - ReconstructorEntity entity = tile.entity(); - return checkValidTap(tile, entity, player); - } - - @Override - public void draw(Tile tile){ - ReconstructorEntity entity = tile.entity(); - - if(entity.solid){ - Draw.rect(region, tile.drawx(), tile.drawy()); - }else{ - Draw.rect(openRegion, tile.drawx(), tile.drawy()); - } - - if(entity.current != null){ - float progress = entity.departing ? entity.updateTime : (1f - entity.updateTime); - - //Player player = entity.current; - - TextureRegion region = entity.current.getIconRegion(); - - Shaders.build.region = region; - Shaders.build.progress = progress; - Shaders.build.color.set(Palette.accent); - Shaders.build.time = -entity.time / 10f; - - Draw.shader(Shaders.build, false); - Shaders.build.apply(); - Draw.rect(region, tile.drawx(), tile.drawy()); - Draw.shader(); - - Draw.color(Palette.accent); - - Lines.lineAngleCenter( - tile.drawx() + Mathf.sin(entity.time, 6f, Vars.tilesize / 3f * size), - tile.drawy(), - 90, - size * Vars.tilesize / 2f); - - Draw.reset(); - } - } - - @Override - public void update(Tile tile){ - ReconstructorEntity entity = tile.entity(); - - boolean stayOpen = false; - - if(entity.current != null){ - entity.time += Time.delta(); - - entity.solid = true; - - if(entity.departing){ - //force respawn if there's suddenly nothing to link to - if(!validLink(tile, entity.link)){ - //entity.current.setRespawning(false); - return; - } - - ReconstructorEntity other = world.tile(entity.link).entity(); - - entity.updateTime -= Time.delta() / departTime; - if(entity.updateTime <= 0f){ - //no power? death. - if(other.power.satisfaction < powerPerTeleport){ - entity.current.setDead(true); - //entity.current.setRespawning(false); - entity.current = null; - return; - } - other.power.satisfaction -= Math.min(other.power.satisfaction, powerPerTeleport); - other.current = entity.current; - other.departing = false; - other.current.set(other.x, other.y); - other.updateTime = 1f; - entity.current = null; - } - }else{ //else, arriving - entity.updateTime -= Time.delta() / arriveTime; - - if(entity.updateTime <= 0f){ - entity.solid = false; - entity.current.setDead(false); - - Effects.effect(arriveEffect, entity.current); - - entity.current = null; - } - } - - }else{ - - if(validLink(tile, entity.link)){ - Tile other = world.tile(entity.link); - if(other.entity.power.satisfaction >= powerPerTeleport && Units.anyEntities(tile, 4f, unit -> unit.getTeam() == entity.getTeam() && unit instanceof Player) && - entity.power.satisfaction >= powerPerTeleport){ - entity.solid = false; - stayOpen = true; - } - } - - if(!stayOpen && !entity.solid && !Units.anyEntities(tile)){ - entity.solid = true; - } - } - } - - @Override - public void tapped(Tile tile, Player player){ - ReconstructorEntity entity = tile.entity(); - - if(!checkValidTap(tile, entity, player)) return; - - Call.reconstructPlayer(player, tile); - } - - @Override - public void transformLinks(Tile tile, int oldWidth, int oldHeight, int newWidth, int newHeight, int shiftX, int shiftY){ - super.transformLinks(tile, oldWidth, oldHeight, newWidth, newHeight, shiftX, shiftY); - - ReconstructorEntity entity = tile.entity(); - entity.link = world.transform(entity.link, oldWidth, oldHeight, newWidth, shiftX, shiftY); - } - - @Override - public TileEntity newEntity(){ - return new ReconstructorEntity(); - } - - public class ReconstructorEntity extends TileEntity implements SpawnerTrait{ - Unit current; - float updateTime; - float time; - int link; - boolean solid = true, departing; - - @Override - public void updateSpawning(Unit unit){ - - } - - @Override - public float getSpawnProgress(){ - return 0; - } - - @Override - public void write(DataOutput stream) throws IOException{ - stream.writeInt(link); - } - - @Override - public void read(DataInput stream) throws IOException{ - link = stream.readInt(); - } - } -} diff --git a/core/src/io/anuke/mindustry/world/blocks/units/RepairPoint.java b/core/src/io/anuke/mindustry/world/blocks/units/RepairPoint.java index f213ebf15a..f53641b9b6 100644 --- a/core/src/io/anuke/mindustry/world/blocks/units/RepairPoint.java +++ b/core/src/io/anuke/mindustry/world/blocks/units/RepairPoint.java @@ -10,11 +10,11 @@ import io.anuke.arc.math.Angles; import io.anuke.arc.math.Mathf; import io.anuke.arc.math.geom.Rectangle; import io.anuke.arc.util.Time; -import io.anuke.mindustry.entities.TileEntity; -import io.anuke.mindustry.entities.Unit; +import io.anuke.mindustry.entities.type.TileEntity; +import io.anuke.mindustry.entities.type.Unit; import io.anuke.mindustry.entities.Units; import io.anuke.mindustry.graphics.Layer; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.graphics.Shapes; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; @@ -33,7 +33,7 @@ public class RepairPoint extends Block{ protected float powerPerEvent = 0.06f; protected ConsumePower consumePower; - protected TextureRegion topRegion; + protected TextureRegion baseRegion; public RepairPoint(String name){ super(name); @@ -44,13 +44,14 @@ public class RepairPoint extends Block{ layer2 = Layer.laser; hasPower = true; consumePower = consumes.powerBuffered(20f); + outlineIcon = true; } @Override public void load(){ super.load(); - topRegion = Core.atlas.find(name + "-turret"); + baseRegion = Core.atlas.find(name + "-base"); } @Override @@ -61,16 +62,21 @@ public class RepairPoint extends Block{ @Override public void drawSelect(Tile tile){ - Draw.color(Palette.accent); + Draw.color(Pal.accent); Lines.dashCircle(tile.drawx(), tile.drawy(), repairRadius); Draw.color(); } + @Override + public void draw(Tile tile){ + Draw.rect(baseRegion, tile.drawx(), tile.drawy()); + } + @Override public void drawLayer(Tile tile){ RepairPointEntity entity = tile.entity(); - Draw.rect(topRegion, tile.drawx(), tile.drawy(), entity.rotation - 90); + Draw.rect(region, tile.drawx(), tile.drawy(), entity.rotation - 90); } @Override @@ -90,6 +96,11 @@ public class RepairPoint extends Block{ } } + @Override + public TextureRegion[] generateIcons(){ + return new TextureRegion[]{Core.atlas.find(name + "-base"), Core.atlas.find(name + "-turret")}; + } + @Override public void update(Tile tile){ RepairPointEntity entity = tile.entity(); diff --git a/core/src/io/anuke/mindustry/world/blocks/units/UnitFactory.java b/core/src/io/anuke/mindustry/world/blocks/units/UnitFactory.java index e8d6a7f1e3..752598b7eb 100644 --- a/core/src/io/anuke/mindustry/world/blocks/units/UnitFactory.java +++ b/core/src/io/anuke/mindustry/world/blocks/units/UnitFactory.java @@ -4,18 +4,19 @@ import io.anuke.annotations.Annotations.Loc; import io.anuke.annotations.Annotations.Remote; import io.anuke.arc.Core; import io.anuke.arc.collection.EnumSet; -import io.anuke.arc.entities.Effects; +import io.anuke.mindustry.entities.Effects; import io.anuke.arc.graphics.g2d.Draw; import io.anuke.arc.graphics.g2d.Lines; import io.anuke.arc.graphics.g2d.TextureRegion; import io.anuke.arc.math.Mathf; import io.anuke.mindustry.Vars; import io.anuke.mindustry.content.Fx; -import io.anuke.mindustry.entities.TileEntity; -import io.anuke.mindustry.entities.units.BaseUnit; -import io.anuke.mindustry.entities.units.UnitType; +import io.anuke.mindustry.entities.type.TileEntity; +import io.anuke.mindustry.entities.type.Unit; +import io.anuke.mindustry.entities.type.BaseUnit; +import io.anuke.mindustry.type.UnitType; import io.anuke.mindustry.gen.Call; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.graphics.Shaders; import io.anuke.mindustry.net.Net; import io.anuke.mindustry.type.Item; @@ -41,6 +42,7 @@ public class UnitFactory extends Block{ protected float produceTime = 1000f; protected float launchVelocity = 0f; protected TextureRegion topRegion; + protected int maxSpawn = 2; public UnitFactory(String name){ super(name); @@ -61,6 +63,7 @@ public class UnitFactory extends Block{ UnitFactory factory = (UnitFactory) tile.block(); entity.buildTime = 0f; + entity.spawned ++; Effects.shake(2f, 3f, entity); Effects.effect(Fx.producesmoke, tile.drawx(), tile.drawy()); @@ -93,6 +96,12 @@ public class UnitFactory extends Block{ stats.add(BlockStat.craftSpeed, produceTime / 60f, StatUnit.seconds); } + @Override + public void unitRemoved(Tile tile, Unit unit){ + UnitFactoryEntity entity = tile.entity(); + entity.spawned --; + } + @Override public TextureRegion[] generateIcons(){ return new TextureRegion[]{Core.atlas.find(name), Core.atlas.find(name + "-top")}; @@ -107,7 +116,7 @@ public class UnitFactory extends Block{ Shaders.build.region = region; Shaders.build.progress = entity.buildTime / produceTime; - Shaders.build.color.set(Palette.accent); + Shaders.build.color.set(Pal.accent); Shaders.build.color.a = entity.speedScl; Shaders.build.time = -entity.time / 10f; @@ -116,7 +125,7 @@ public class UnitFactory extends Block{ Draw.rect(region, tile.drawx(), tile.drawy()); Draw.shader(); - Draw.color(Palette.accent); + Draw.color(Pal.accent); Draw.alpha(entity.speedScl); Lines.lineAngleCenter( @@ -136,6 +145,10 @@ public class UnitFactory extends Block{ entity.time += entity.delta() * entity.speedScl; + if(entity.spawned >= maxSpawn){ + return; + } + if(tile.isEnemyCheat()){ entity.warmup += entity.delta(); } @@ -211,17 +224,20 @@ public class UnitFactory extends Block{ public float time; public float speedScl; public float warmup; //only for enemy spawners + public int spawned; @Override public void write(DataOutput stream) throws IOException{ stream.writeFloat(buildTime); stream.writeFloat(warmup); + stream.writeInt(spawned); } @Override public void read(DataInput stream) throws IOException{ buildTime = stream.readFloat(); warmup = stream.readFloat(); + spawned = stream.readInt(); } } } diff --git a/core/src/io/anuke/mindustry/world/consumers/Consume.java b/core/src/io/anuke/mindustry/world/consumers/Consume.java index 3902245284..e52901f7c8 100644 --- a/core/src/io/anuke/mindustry/world/consumers/Consume.java +++ b/core/src/io/anuke/mindustry/world/consumers/Consume.java @@ -1,8 +1,8 @@ package io.anuke.mindustry.world.consumers; import io.anuke.arc.graphics.Color; -import io.anuke.mindustry.entities.TileEntity; -import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.entities.type.TileEntity; +import io.anuke.mindustry.graphics.Pal; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.meta.BlockStats; import io.anuke.arc.scene.ui.Tooltip; @@ -10,9 +10,10 @@ import io.anuke.arc.scene.ui.layout.Table; import static io.anuke.mindustry.Vars.mobile; +/**An abstract class that defines a type of resource that a block can consume.*/ public abstract class Consume{ protected boolean optional; - protected boolean update = true; + protected boolean update = true, boost = false; public Consume optional(boolean optional){ this.optional = optional; @@ -24,6 +25,11 @@ public abstract class Consume{ return this; } + public Consume boost(boolean boost){ + this.boost = boost; + return this; + } + public boolean isOptional(){ return optional; } @@ -41,8 +47,8 @@ public abstract class Consume{ table.table(out -> { out.addImage(getIcon()).size(10 * scale).color(Color.DARK_GRAY).padRight(-10 * scale).padBottom(-scale * 2); - out.addImage(getIcon()).size(10 * scale).color(Palette.accent); - out.addImage("icon-missing").size(10 * scale).color(Palette.remove).padLeft(-10 * scale); + out.addImage(getIcon()).size(10 * scale).color(Pal.accent); + out.addImage("icon-missing").size(10 * scale).color(Pal.remove).padLeft(-10 * scale); }).size(10 * scale).get().addListener(new Tooltip<>(t)); } diff --git a/core/src/io/anuke/mindustry/world/consumers/ConsumeItem.java b/core/src/io/anuke/mindustry/world/consumers/ConsumeItem.java index 76e659759a..05d4b84a70 100644 --- a/core/src/io/anuke/mindustry/world/consumers/ConsumeItem.java +++ b/core/src/io/anuke/mindustry/world/consumers/ConsumeItem.java @@ -1,6 +1,6 @@ package io.anuke.mindustry.world.consumers; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.ItemStack; import io.anuke.mindustry.ui.ItemImage; @@ -53,6 +53,6 @@ public class ConsumeItem extends Consume{ @Override public void display(BlockStats stats){ - stats.add(optional ? BlockStat.boostItem : BlockStat.inputItem, item); + stats.add(boost ? BlockStat.boostItem : BlockStat.inputItem, item); } } diff --git a/core/src/io/anuke/mindustry/world/consumers/ConsumeItemFilter.java b/core/src/io/anuke/mindustry/world/consumers/ConsumeItemFilter.java index 155a54e6ec..3d156a4565 100644 --- a/core/src/io/anuke/mindustry/world/consumers/ConsumeItemFilter.java +++ b/core/src/io/anuke/mindustry/world/consumers/ConsumeItemFilter.java @@ -1,7 +1,7 @@ package io.anuke.mindustry.world.consumers; import io.anuke.arc.collection.Array; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.meta.BlockStat; @@ -58,6 +58,6 @@ public class ConsumeItemFilter extends Consume{ @Override public void display(BlockStats stats){ - stats.add(optional ? BlockStat.boostItem : BlockStat.inputItem, new ItemFilterValue(filter)); + stats.add(boost ? BlockStat.boostItem : BlockStat.inputItem, new ItemFilterValue(filter)); } } diff --git a/core/src/io/anuke/mindustry/world/consumers/ConsumeItems.java b/core/src/io/anuke/mindustry/world/consumers/ConsumeItems.java index 8ba9fdbb64..07ccb08278 100644 --- a/core/src/io/anuke/mindustry/world/consumers/ConsumeItems.java +++ b/core/src/io/anuke/mindustry/world/consumers/ConsumeItems.java @@ -1,6 +1,6 @@ package io.anuke.mindustry.world.consumers; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.type.ItemStack; import io.anuke.mindustry.ui.ItemImage; import io.anuke.mindustry.world.Block; @@ -44,6 +44,6 @@ public class ConsumeItems extends Consume{ @Override public void display(BlockStats stats){ - stats.add(optional ? BlockStat.boostItem : BlockStat.inputItems, new ItemListValue(items)); + stats.add(boost ? BlockStat.boostItem : BlockStat.inputItems, new ItemListValue(items)); } } diff --git a/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquid.java b/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquid.java index c5ee119a8f..5f605bdb7f 100644 --- a/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquid.java +++ b/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquid.java @@ -1,6 +1,6 @@ package io.anuke.mindustry.world.consumers; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.type.Liquid; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.meta.BlockStat; @@ -47,7 +47,7 @@ public class ConsumeLiquid extends Consume{ @Override public void display(BlockStats stats){ - if(!optional){ + if(!boost){ stats.add(BlockStat.liquidUse, use * 60f, StatUnit.liquidSecond); stats.add(BlockStat.inputLiquid, liquid); }else{ diff --git a/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquidFilter.java b/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquidFilter.java index 9a663b4c6d..c138143ceb 100644 --- a/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquidFilter.java +++ b/core/src/io/anuke/mindustry/world/consumers/ConsumeLiquidFilter.java @@ -1,7 +1,7 @@ package io.anuke.mindustry.world.consumers; import io.anuke.arc.collection.Array; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.type.Liquid; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.meta.BlockStat; @@ -62,7 +62,7 @@ public class ConsumeLiquidFilter extends Consume{ @Override public void display(BlockStats stats){ - if(optional){ + if(boost){ stats.add(BlockStat.boostLiquid, new LiquidFilterValue(filter)); }else if(isFuel){ stats.add(BlockStat.inputLiquidFuel, new LiquidFilterValue(filter)); diff --git a/core/src/io/anuke/mindustry/world/consumers/ConsumePower.java b/core/src/io/anuke/mindustry/world/consumers/ConsumePower.java index 18b9d57c40..e215c75f4e 100644 --- a/core/src/io/anuke/mindustry/world/consumers/ConsumePower.java +++ b/core/src/io/anuke/mindustry/world/consumers/ConsumePower.java @@ -2,7 +2,7 @@ package io.anuke.mindustry.world.consumers; import io.anuke.arc.math.Mathf; import io.anuke.arc.scene.ui.layout.Table; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.meta.BlockStat; import io.anuke.mindustry.world.meta.BlockStats; @@ -12,39 +12,17 @@ import io.anuke.mindustry.world.meta.StatUnit; public class ConsumePower extends Consume{ /** The maximum amount of power which can be processed per tick. This might influence efficiency or load a buffer. */ protected final float powerPerTick; - /** The minimum power satisfaction (fraction of powerPerTick) which must be achieved before the module may work. */ - public final float minimumSatisfaction; /** The maximum power capacity in power units. */ public final float powerCapacity; /** True if the module can store power. */ public final boolean isBuffered; - protected ConsumePower(float powerPerTick, float minimumSatisfaction, float powerCapacity, boolean isBuffered){ + public ConsumePower(float powerPerTick, float powerCapacity, boolean isBuffered){ this.powerPerTick = powerPerTick; - this.minimumSatisfaction = minimumSatisfaction; this.powerCapacity = powerCapacity; this.isBuffered = isBuffered; } - /** - * Makes the owner consume powerPerTick each tick and disables it unless minimumSatisfaction (1.0 = 100%) of that power is being supplied. - * @param powerPerTick The maximum amount of power which is required per tick for 100% efficiency. - * @param minimumSatisfaction The percentage of powerPerTick which must be available for the module to work. - */ - public static ConsumePower consumePowerDirect(float powerPerTick, float minimumSatisfaction){ - return new ConsumePower(powerPerTick, minimumSatisfaction, 0.0f, false); - } - - /** - * Adds a power buffer to the owner which takes ticksToFill number of ticks to be filled. - * Note that this object does not remove power from the buffer. - * @param powerCapacity The maximum capacity in power units. - * @param ticksToFill The number of ticks it shall take to fill the buffer. - */ - public static ConsumePower consumePowerBuffered(float powerCapacity, float ticksToFill){ - return new ConsumePower(powerCapacity / ticksToFill, 0.0f, powerCapacity, true); - } - @Override public void buildTooltip(Table table){ // No tooltip for power @@ -65,7 +43,7 @@ public class ConsumePower extends Consume{ if(isBuffered){ return true; }else{ - return entity.power.satisfaction >= minimumSatisfaction; + return entity.power.satisfaction >= 0.9999f; } } diff --git a/core/src/io/anuke/mindustry/world/consumers/Consumers.java b/core/src/io/anuke/mindustry/world/consumers/Consumers.java index f4ffaa27a8..23f6f456bf 100644 --- a/core/src/io/anuke/mindustry/world/consumers/Consumers.java +++ b/core/src/io/anuke/mindustry/world/consumers/Consumers.java @@ -36,22 +36,13 @@ public class Consumers{ return c; } - /** - * Creates a consumer which directly uses power without buffering it. The module will work while at least 50% of power is supplied. - * @param powerPerTick The amount of power which is required each tick for 100% efficiency. - * @return the created consumer object. - */ - public ConsumePower power(float powerPerTick){ - return power(powerPerTick, 0.5f); - } - /** * Creates a consumer which directly uses power without buffering it. The module will work while the available power is greater than or equal to the minimumSatisfaction percentage (0..1). * @param powerPerTick The amount of power which is required each tick for 100% efficiency. * @return the created consumer object. */ - public ConsumePower power(float powerPerTick, float minimumSatisfaction){ - ConsumePower c = ConsumePower.consumePowerDirect(powerPerTick, minimumSatisfaction); + public ConsumePower power(float powerPerTick){ + ConsumePower c = new ConsumePower(powerPerTick, 0.0f, false); add(c); return c; } @@ -71,7 +62,7 @@ public class Consumers{ * @param ticksToFill The number of ticks it shall take to fill the buffer. */ public ConsumePower powerBuffered(float powerCapacity, float ticksToFill){ - ConsumePower c = ConsumePower.consumePowerBuffered(powerCapacity, ticksToFill); + ConsumePower c = new ConsumePower(powerCapacity / ticksToFill, powerCapacity, true); add(c); return c; } diff --git a/core/src/io/anuke/mindustry/world/meta/BlockFlag.java b/core/src/io/anuke/mindustry/world/meta/BlockFlag.java index a57e765414..b5c8339854 100644 --- a/core/src/io/anuke/mindustry/world/meta/BlockFlag.java +++ b/core/src/io/anuke/mindustry/world/meta/BlockFlag.java @@ -1,24 +1,16 @@ package io.anuke.mindustry.world.meta; -//TODO fix flagging system, currently doesn't really work public enum BlockFlag{ /**General important target for all types of units.*/ target(0), - /**Point to resupply resources.*/ - resupplyPoint(Float.MAX_VALUE), - /**Point to drop off resources.*/ - dropPoint(Float.MAX_VALUE), /**Producer of important goods.*/ producer(Float.MAX_VALUE), - /**Just a turret.*/ + /**A turret.*/ turret(Float.MAX_VALUE), - /**Producer or storage unit of volatile materials.*/ - explosive(Float.MAX_VALUE), /**Repair point.*/ repair(Float.MAX_VALUE); public final static BlockFlag[] all = values(); - public final float cost; BlockFlag(float cost){ diff --git a/core/src/io/anuke/mindustry/world/modules/ConsumeModule.java b/core/src/io/anuke/mindustry/world/modules/ConsumeModule.java index 68f8585b55..027027938c 100644 --- a/core/src/io/anuke/mindustry/world/modules/ConsumeModule.java +++ b/core/src/io/anuke/mindustry/world/modules/ConsumeModule.java @@ -1,6 +1,6 @@ package io.anuke.mindustry.world.modules; -import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.type.TileEntity; import io.anuke.mindustry.world.consumers.Consume; import java.io.DataInput; diff --git a/ios/src/io/anuke/mindustry/IOSLauncher.java b/ios/src/io/anuke/mindustry/IOSLauncher.java index b8bdb66dda..cc7d8dd154 100644 --- a/ios/src/io/anuke/mindustry/IOSLauncher.java +++ b/ios/src/io/anuke/mindustry/IOSLauncher.java @@ -101,10 +101,10 @@ public class IOSLauncher extends IOSApplication.Delegate { SaveSlot slot = control.saves.importSave(file); ui.load.runLoadSave(slot); }catch (IOException e){ - ui.showError(Core.bundle.format("text.save.import.fail", Strings.parseException(e, false))); + ui.showError(Core.bundle.format("save.import.fail", Strings.parseException(e, false))); } }else{ - ui.showError("$text.save.import.invalid"); + ui.showError("save.import.invalid"); } }else if(file.extension().equalsIgnoreCase(mapExtension)){ //open map diff --git a/net/src/io/anuke/net/KryoServer.java b/net/src/io/anuke/net/KryoServer.java index 0f37c80e19..2a68deb1b6 100644 --- a/net/src/io/anuke/net/KryoServer.java +++ b/net/src/io/anuke/net/KryoServer.java @@ -61,7 +61,7 @@ public class KryoServer implements ServerProvider{ c.id = kn.id; c.addressTCP = ip; - Log.info("&bRecieved connection: {0}", c.addressTCP); + Log.debug("&bRecieved connection: {0}", c.addressTCP); connections.add(kn); Core.app.post(() -> Net.handleServerReceived(kn.id, c)); @@ -90,7 +90,7 @@ public class KryoServer implements ServerProvider{ try{ Net.handleServerReceived(k.id, object); }catch(ValidateException e){ - Log.err("Validate failed: {0} ({1})", e.player.name, e.getMessage()); + Log.err("Validation failed: {0} ({1})", e.player.name, e.getMessage()); }catch(Exception e){ e.printStackTrace(); } diff --git a/server/src/io/anuke/mindustry/server/MindustryServer.java b/server/src/io/anuke/mindustry/server/MindustryServer.java index 7bf7f08298..94a3a01587 100644 --- a/server/src/io/anuke/mindustry/server/MindustryServer.java +++ b/server/src/io/anuke/mindustry/server/MindustryServer.java @@ -28,11 +28,12 @@ public class MindustryServer implements ApplicationListener{ BundleLoader.load(); content.verbose(false); content.load(); - content.initialize(Content::init); Core.app.addListener(logic = new Logic()); Core.app.addListener(world = new World()); Core.app.addListener(netServer = new NetServer()); Core.app.addListener(new ServerControl(args)); + + content.initialize(Content::init); } } diff --git a/server/src/io/anuke/mindustry/server/ServerControl.java b/server/src/io/anuke/mindustry/server/ServerControl.java index 8717c54f44..29d4ee64f5 100644 --- a/server/src/io/anuke/mindustry/server/ServerControl.java +++ b/server/src/io/anuke/mindustry/server/ServerControl.java @@ -5,7 +5,7 @@ import io.anuke.arc.Core; import io.anuke.arc.Events; import io.anuke.arc.collection.Array; import io.anuke.arc.collection.ObjectSet; -import io.anuke.arc.entities.Effects; +import io.anuke.mindustry.entities.Effects; import io.anuke.arc.files.FileHandle; import io.anuke.arc.util.*; import io.anuke.arc.util.CommandHandler.Command; @@ -13,9 +13,10 @@ import io.anuke.arc.util.CommandHandler.Response; import io.anuke.arc.util.CommandHandler.ResponseType; import io.anuke.arc.util.Timer.Task; import io.anuke.mindustry.core.GameState.State; -import io.anuke.mindustry.entities.Player; +import io.anuke.mindustry.entities.type.Player; import io.anuke.mindustry.game.Difficulty; import io.anuke.mindustry.game.EventType.GameOverEvent; +import io.anuke.mindustry.game.RulePreset; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.game.Version; import io.anuke.mindustry.gen.Call; @@ -62,6 +63,11 @@ public class ServerControl implements ApplicationListener{ Log.setLogger(new LogHandler(){ DateTimeFormatter dateTime = DateTimeFormatter.ofPattern("MM-dd-yyyy | HH:mm:ss"); + @Override + public void debug(String text, Object... args){ + print("&lc&fb" + "[DEBUG] " + text, args); + } + @Override public void info(String text, Object... args){ print("&lg&fb" + "[INFO] " + text, args); @@ -184,7 +190,7 @@ public class ServerControl implements ApplicationListener{ info("Stopped server."); }); - handler.register("host", "[mapname]", "Open the server with a specific map.", arg -> { + handler.register("host", " [mode]", "Open the server with a specific map.", arg -> { if(state.is(State.playing)){ err("Already hosting. Type 'stop' to stop hosting first."); return; @@ -192,33 +198,31 @@ public class ServerControl implements ApplicationListener{ if(lastTask != null) lastTask.cancel(); - Map result = null; + Map result = world.maps.all().find(map -> map.name.equalsIgnoreCase(arg[0])); - if(arg.length > 0){ + if(result == null){ + err("No map with name &y'{0}'&lr found.", arg[0]); + return; + } - String search = arg[0]; - for(Map map : world.maps.all()){ - if(map.name.equalsIgnoreCase(search)) result = map; - } + RulePreset preset = RulePreset.survival; - if(result == null){ - err("No map with name &y'{0}'&lr found.", search); + if(arg.length > 1){ + try{ + preset = RulePreset.valueOf(arg[1]); + }catch(IllegalArgumentException e){ + err("No gamemode '{0}' found."); return; } - - - info("Loading map..."); - err("TODO select gamemode"); - - logic.reset(); - world.loadMap(result); - logic.play(); - - }else{ - //TODO - err("TODO play generated map"); } + info("Loading map..."); + + logic.reset(); + state.rules = preset.get(); + world.loadMap(result); + logic.play(); + info("Map loaded."); host(); @@ -240,10 +244,15 @@ public class ServerControl implements ApplicationListener{ }); handler.register("maps", "Display all available maps.", arg -> { - info("Maps:"); - for(Map map : world.maps.all()){ - info(" &ly{0}: &lb&fi{1} / {2}x{3}", map.name, map.custom ? "Custom" : "Default", map.meta.width, map.meta.height); + if(!world.maps.all().isEmpty()){ + info("Maps:"); + for(Map map : world.maps.all()){ + info(" &ly{0}: &lb&fi{1} / {2}x{3}", map.name, map.custom ? "Custom" : "Default", map.meta.width, map.meta.height); + } + }else{ + info("No maps found."); } + info("&lyMap directory: &lb&fi{0}", customMapDirectory.file().getAbsoluteFile().toString()); }); handler.register("status", "Display server status.", arg -> { @@ -251,7 +260,7 @@ public class ServerControl implements ApplicationListener{ info("Status: &rserver closed"); }else{ info("Status:"); - info(" &lyPlaying on map &fi{0}&fb &lb/&ly Wave {1} &lb/&ly {2} &lb/&ly {3}", Strings.capitalize(world.getMap().name), state.wave); + info(" &lyPlaying on map &fi{0}&fb &lb/&ly Wave {1}", Strings.capitalize(world.getMap().name), state.wave); if(!state.rules.waves){ info("&ly {0} enemies.", unitGroups[Team.red.ordinal()].size()); diff --git a/settings.gradle b/settings.gradle index cb3b08c8fe..2f0aa64e78 100644 --- a/settings.gradle +++ b/settings.gradle @@ -25,6 +25,7 @@ if(System.properties["release"] == null || System.properties["release"] == "fals use(':Arc:arc-core', '../Arc/arc-core') use(':Arc:extensions', '../Arc/extensions') use(':Arc:extensions:freetype', '../Arc/extensions/freetype') + use(':Arc:extensions:recorder', '../Arc/extensions/recorder') use(':Arc:backends', '../Arc/backends') use(':Arc:backends:backend-lwjgl3', '../Arc/backends/backend-lwjgl3') use(':Arc:backends:backend-android', '../Arc/backends/backend-android') diff --git a/tests/src/test/java/ApplicationTests.java b/tests/src/test/java/ApplicationTests.java index 0c90191680..28446cf210 100644 --- a/tests/src/test/java/ApplicationTests.java +++ b/tests/src/test/java/ApplicationTests.java @@ -13,8 +13,8 @@ import io.anuke.mindustry.core.Logic; import io.anuke.mindustry.core.NetServer; import io.anuke.mindustry.core.World; import io.anuke.mindustry.entities.traits.BuilderTrait.BuildRequest; -import io.anuke.mindustry.entities.units.BaseUnit; -import io.anuke.mindustry.entities.units.types.Spirit; +import io.anuke.mindustry.entities.type.BaseUnit; +import io.anuke.mindustry.entities.type.base.Spirit; import io.anuke.mindustry.game.Content; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.io.BundleLoader; @@ -114,6 +114,11 @@ public class ApplicationTests{ void spawnWaves(){ world.loadMap(testMap); logic.runWave(); + //force trigger delayed spawns + Time.setDeltaProvider(() -> 1000f); + Time.update(); + Time.update(); + Time.setDeltaProvider(() -> 1f); unitGroups[waveTeam.ordinal()].updateEvents(); assertFalse(unitGroups[waveTeam.ordinal()].isEmpty()); } @@ -138,12 +143,12 @@ public class ApplicationTests{ createMap(); int bx = 4; int by = 4; - world.setBlock(world.tile(bx, by), Blocks.core, Team.blue); + world.setBlock(world.tile(bx, by), Blocks.coreShard, Team.blue); assertEquals(world.tile(bx, by).getTeam(), Team.blue); for(int x = bx-1; x <= bx + 1; x++){ for(int y = by-1; y <= by + 1; y++){ if(x == bx && by == y){ - assertEquals(world.tile(x, y).block(), Blocks.core); + assertEquals(world.tile(x, y).block(), Blocks.coreShard); }else{ assertTrue(world.tile(x, y).block() == Blocks.part && world.tile(x, y).getLinked() == world.tile(bx, by)); } @@ -231,8 +236,8 @@ public class ApplicationTests{ d2.addBuildRequest(new BuildRequest(1, 1, 0, Blocks.copperWallLarge)); Time.setDeltaProvider(() -> 9999999f); - d1.updateBuilding(d1); - d2.updateBuilding(d2); + d1.updateBuilding(); + d2.updateBuilding(); assertEquals(Blocks.copperWallLarge, world.tile(0, 0).block()); assertEquals(Blocks.air, world.tile(2, 2).block()); @@ -253,16 +258,16 @@ public class ApplicationTests{ d2.addBuildRequest(new BuildRequest(1, 1)); Time.setDeltaProvider(() -> 3f); - d1.updateBuilding(d1); + d1.updateBuilding(); Time.setDeltaProvider(() -> 1f); - d2.updateBuilding(d2); + d2.updateBuilding(); assertEquals(content.getByName(ContentType.block, "build2"), world.tile(0, 0).block()); Time.setDeltaProvider(() -> 9999f); - d1.updateBuilding(d1); - d2.updateBuilding(d2); + d1.updateBuilding(); + d2.updateBuilding(); assertEquals(Blocks.air, world.tile(0, 0).block()); assertEquals(Blocks.air, world.tile(2, 2).block()); @@ -273,7 +278,7 @@ public class ApplicationTests{ createMap(); Tile core = world.tile(5, 5); - world.setBlock(core, Blocks.core, Team.blue); + world.setBlock(core, Blocks.coreShard, Team.blue); for(Item item : content.items()){ core.entity.items.set(item, 3000); } diff --git a/tests/src/test/java/power/FakeGraphics.java b/tests/src/test/java/power/FakeGraphics.java new file mode 100644 index 0000000000..3006810379 --- /dev/null +++ b/tests/src/test/java/power/FakeGraphics.java @@ -0,0 +1,222 @@ +package power; + +import io.anuke.arc.Graphics; +import io.anuke.arc.Graphics.Cursor.SystemCursor; +import io.anuke.arc.graphics.GL20; +import io.anuke.arc.graphics.GL30; +import io.anuke.arc.graphics.Pixmap; +import io.anuke.arc.graphics.glutils.GLVersion; + +public class FakeGraphics extends Graphics{ + static int frame; + + @Override + public boolean isGL30Available(){ + return false; + } + + @Override + public GL20 getGL20(){ + return null; + } + + @Override + public void setGL20(GL20 gl20){ + + } + + @Override + public GL30 getGL30(){ + return null; + } + + @Override + public void setGL30(GL30 gl30){ + + } + + @Override + public int getWidth(){ + return 0; + } + + @Override + public int getHeight(){ + return 0; + } + + @Override + public int getBackBufferWidth(){ + return 0; + } + + @Override + public int getBackBufferHeight(){ + return 0; + } + + @Override + public long getFrameId(){ + return frame++; + } + + @Override + public float getDeltaTime(){ + return 0; + } + + @Override + public float getRawDeltaTime(){ + return 0; + } + + @Override + public int getFramesPerSecond(){ + return 0; + } + + @Override + public GLVersion getGLVersion(){ + return null; + } + + @Override + public float getPpiX(){ + return 0; + } + + @Override + public float getPpiY(){ + return 0; + } + + @Override + public float getPpcX(){ + return 0; + } + + @Override + public float getPpcY(){ + return 0; + } + + @Override + public float getDensity(){ + return 0; + } + + @Override + public boolean supportsDisplayModeChange(){ + return false; + } + + @Override + public Monitor getPrimaryMonitor(){ + return null; + } + + @Override + public Monitor getMonitor(){ + return null; + } + + @Override + public Monitor[] getMonitors(){ + return new Monitor[0]; + } + + @Override + public DisplayMode[] getDisplayModes(){ + return new DisplayMode[0]; + } + + @Override + public DisplayMode[] getDisplayModes(Monitor monitor){ + return new DisplayMode[0]; + } + + @Override + public DisplayMode getDisplayMode(){ + return null; + } + + @Override + public DisplayMode getDisplayMode(Monitor monitor){ + return null; + } + + @Override + public boolean setFullscreenMode(DisplayMode displayMode){ + return false; + } + + @Override + public boolean setWindowedMode(int width, int height){ + return false; + } + + @Override + public void setTitle(String title){ + + } + + @Override + public void setUndecorated(boolean undecorated){ + + } + + @Override + public void setResizable(boolean resizable){ + + } + + @Override + public void setVSync(boolean vsync){ + + } + + @Override + public BufferFormat getBufferFormat(){ + return null; + } + + @Override + public boolean supportsExtension(String extension){ + return false; + } + + @Override + public boolean isContinuousRendering(){ + return false; + } + + @Override + public void setContinuousRendering(boolean isContinuous){ + + } + + @Override + public void requestRendering(){ + + } + + @Override + public boolean isFullscreen(){ + return false; + } + + @Override + public Cursor newCursor(Pixmap pixmap, int xHotspot, int yHotspot){ + return null; + } + + @Override + protected void setCursor(Cursor cursor){ + + } + + @Override + protected void setSystemCursor(SystemCursor systemCursor){ + + } +} diff --git a/tests/src/test/java/power/ItemLiquidGeneratorTests.java b/tests/src/test/java/power/ItemLiquidGeneratorTests.java index 83f58a3e49..87338158a1 100644 --- a/tests/src/test/java/power/ItemLiquidGeneratorTests.java +++ b/tests/src/test/java/power/ItemLiquidGeneratorTests.java @@ -7,12 +7,14 @@ import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.Liquid; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.power.ItemLiquidGenerator; -import org.junit.jupiter.api.*; +import org.junit.jupiter.api.DynamicTest; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestFactory; import java.util.ArrayList; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.DynamicTest.dynamicTest; /** @@ -30,8 +32,8 @@ public class ItemLiquidGeneratorTests extends PowerTestFixture{ private final float fakeItemDuration = 60f; // 60 ticks private final float maximumLiquidUsage = 0.5f; - public void createGenerator(ItemLiquidGenerator.InputType inputType){ - generator = new ItemLiquidGenerator(inputType, "fakegen"){ + public void createGenerator(InputType inputType){ + generator = new ItemLiquidGenerator(inputType != InputType.liquids, inputType != InputType.items, "fakegen"){ { powerProduction = 0.1f; itemDuration = 60f; @@ -59,13 +61,13 @@ public class ItemLiquidGeneratorTests extends PowerTestFixture{ DynamicTest[] generatorWorksProperlyWithLiquidInput(){ // Execute all tests for the case where only liquids are accepted and for the case where liquids and items are accepted (but supply only liquids) - ItemLiquidGenerator.InputType[] inputTypesToBeTested = new ItemLiquidGenerator.InputType[]{ - ItemLiquidGenerator.InputType.LiquidsOnly, - ItemLiquidGenerator.InputType.LiquidsAndItems + InputType[] inputTypesToBeTested = new InputType[]{ + InputType.liquids, + InputType.any }; ArrayList tests = new ArrayList<>(); - for(ItemLiquidGenerator.InputType inputType : inputTypesToBeTested){ + for(InputType inputType : inputTypesToBeTested){ tests.add(dynamicTest("01", () -> simulateLiquidConsumption(inputType, Liquids.oil, 0.0f, "No liquids provided"))); tests.add(dynamicTest("02", () -> simulateLiquidConsumption(inputType, Liquids.oil, maximumLiquidUsage / 4.0f, "Low oil provided"))); tests.add(dynamicTest("03", () -> simulateLiquidConsumption(inputType, Liquids.oil, maximumLiquidUsage * 1.0f, "Sufficient oil provided"))); @@ -77,7 +79,7 @@ public class ItemLiquidGeneratorTests extends PowerTestFixture{ return testArray; } - void simulateLiquidConsumption(ItemLiquidGenerator.InputType inputType, Liquid liquid, float availableLiquidAmount, String parameterDescription){ + void simulateLiquidConsumption(InputType inputType, Liquid liquid, float availableLiquidAmount, String parameterDescription){ final float baseEfficiency = liquid.flammability; final float expectedEfficiency = Math.min(1.0f, availableLiquidAmount / maximumLiquidUsage) * baseEfficiency; final float expectedConsumptionPerTick = Math.min(maximumLiquidUsage, availableLiquidAmount); @@ -102,13 +104,13 @@ public class ItemLiquidGeneratorTests extends PowerTestFixture{ DynamicTest[] generatorWorksProperlyWithItemInput(){ // Execute all tests for the case where only items are accepted and for the case where liquids and items are accepted (but supply only items) - ItemLiquidGenerator.InputType[] inputTypesToBeTested = new ItemLiquidGenerator.InputType[]{ - ItemLiquidGenerator.InputType.ItemsOnly, - ItemLiquidGenerator.InputType.LiquidsAndItems + InputType[] inputTypesToBeTested = new InputType[]{ + InputType.items, + InputType.any }; ArrayList tests = new ArrayList<>(); - for(ItemLiquidGenerator.InputType inputType : inputTypesToBeTested){ + for(InputType inputType : inputTypesToBeTested){ tests.add(dynamicTest("01", () -> simulateItemConsumption(inputType, Items.coal, 0, "No items provided"))); tests.add(dynamicTest("02", () -> simulateItemConsumption(inputType, Items.coal, 1, "Sufficient coal provided"))); tests.add(dynamicTest("03", () -> simulateItemConsumption(inputType, Items.coal, 10, "Excess coal provided"))); @@ -122,8 +124,8 @@ public class ItemLiquidGeneratorTests extends PowerTestFixture{ return testArray; } - void simulateItemConsumption(ItemLiquidGenerator.InputType inputType, Item item, int amount, String parameterDescription){ - final float expectedEfficiency = Math.min(1.0f, amount > 0 ? item.flammability : 0f); + void simulateItemConsumption(InputType inputType, Item item, int amount, String parameterDescription){ + final float expectedEfficiency = amount > 0 ? item.flammability : 0f; final float expectedRemainingItemAmount = Math.max(0, amount - 1); createGenerator(inputType); @@ -145,16 +147,16 @@ public class ItemLiquidGeneratorTests extends PowerTestFixture{ /** Makes sure the efficiency stays equal during the item duration. */ @Test void efficiencyRemainsConstantWithinItemDuration_ItemsOnly(){ - testItemDuration(ItemLiquidGenerator.InputType.ItemsOnly); + testItemDuration(InputType.items); } /** Makes sure the efficiency stays equal during the item duration. */ @Test void efficiencyRemainsConstantWithinItemDuration_ItemsAndLiquids(){ - testItemDuration(ItemLiquidGenerator.InputType.LiquidsAndItems); + testItemDuration(InputType.any); } - void testItemDuration(ItemLiquidGenerator.InputType inputType){ + void testItemDuration(InputType inputType){ createGenerator(inputType); // Burn a single coal and test for the duration @@ -172,4 +174,10 @@ public class ItemLiquidGeneratorTests extends PowerTestFixture{ generator.update(tile); assertEquals(0.0f, entity.productionEfficiency, "Duration: " + String.valueOf(currentDuration)); } + + enum InputType{ + items, + liquids, + any + } } diff --git a/tests/src/test/java/power/PowerTestFixture.java b/tests/src/test/java/power/PowerTestFixture.java index 38db7cc8a6..dd8fcf1597 100644 --- a/tests/src/test/java/power/PowerTestFixture.java +++ b/tests/src/test/java/power/PowerTestFixture.java @@ -1,5 +1,6 @@ package power; +import io.anuke.arc.Core; import io.anuke.arc.math.Mathf; import io.anuke.arc.util.Time; import io.anuke.mindustry.Vars; @@ -24,13 +25,13 @@ import java.lang.reflect.Field; * Note: All tests which subclass this will run with a fixed delta of 0.5! * */ public class PowerTestFixture{ - public static final float smallRoundingTolerance = Mathf.FLOAT_ROUNDING_ERROR; public static final float mediumRoundingTolerance = Mathf.FLOAT_ROUNDING_ERROR * 10; public static final float highRoundingTolerance = Mathf.FLOAT_ROUNDING_ERROR * 100; @BeforeAll static void initializeDependencies(){ + Core.graphics = new FakeGraphics(); Vars.content = new ContentLoader(); Vars.content.load(); Time.setDeltaProvider(() -> 0.5f); @@ -49,9 +50,9 @@ public class PowerTestFixture{ }}; } - protected static Block createFakeDirectConsumer(float powerPerTick, float minimumSatisfaction){ + protected static Block createFakeDirectConsumer(float powerPerTick){ return new PowerBlock("fakedirectconsumer"){{ - consumes.power(powerPerTick, minimumSatisfaction); + consumes.power(powerPerTick); }}; } @@ -99,7 +100,7 @@ public class PowerTestFixture{ return tile; }catch(Exception ex){ - return null; + throw new RuntimeException(ex); } } } diff --git a/tests/src/test/java/power/PowerTests.java b/tests/src/test/java/power/PowerTests.java index db37e3668a..4010f10a9c 100644 --- a/tests/src/test/java/power/PowerTests.java +++ b/tests/src/test/java/power/PowerTests.java @@ -1,5 +1,6 @@ package power; +import io.anuke.arc.Core; import io.anuke.arc.math.Mathf; import io.anuke.arc.util.Time; import io.anuke.mindustry.world.Tile; @@ -21,8 +22,9 @@ import static org.junit.jupiter.api.DynamicTest.dynamicTest; */ public class PowerTests extends PowerTestFixture{ - @BeforeEach - void initTest(){ + @BeforeAll + static void init(){ + Core.graphics = new FakeGraphics(); } @Nested @@ -50,7 +52,7 @@ public class PowerTests extends PowerTestFixture{ void simulateDirectConsumption(float producedPower, float requiredPower, float expectedSatisfaction, String parameterDescription){ Tile producerTile = createFakeTile(0, 0, createFakeProducerBlock(producedPower)); producerTile.entity().productionEfficiency = 0.5f; // Currently, 0.5f = 100% - Tile directConsumerTile = createFakeTile(0, 1, createFakeDirectConsumer(requiredPower, 0.6f)); + Tile directConsumerTile = createFakeTile(0, 1, createFakeDirectConsumer(requiredPower)); PowerGraph powerGraph = new PowerGraph(); powerGraph.add(producerTile); @@ -139,7 +141,7 @@ public class PowerTests extends PowerTestFixture{ } Tile directConsumerTile = null; if(requestedPower > 0.0f){ - directConsumerTile = createFakeTile(0, 1, createFakeDirectConsumer(requestedPower, 0.6f)); + directConsumerTile = createFakeTile(0, 1, createFakeDirectConsumer(requestedPower)); powerGraph.add(directConsumerTile); } float maxCapacity = 100f; @@ -160,7 +162,7 @@ public class PowerTests extends PowerTestFixture{ void directConsumptionStopsWithNoPower(){ Tile producerTile = createFakeTile(0, 0, createFakeProducerBlock(10.0f)); producerTile.entity().productionEfficiency = 1.0f; - Tile consumerTile = createFakeTile(0, 1, createFakeDirectConsumer(5.0f, 0.6f)); + Tile consumerTile = createFakeTile(0, 1, createFakeDirectConsumer(5.0f)); PowerGraph powerGraph = new PowerGraph(); powerGraph.add(producerTile); diff --git a/tools/build.gradle b/tools/build.gradle index e0a9db056c..aee8429983 100644 --- a/tools/build.gradle +++ b/tools/build.gradle @@ -11,10 +11,15 @@ import java.awt.image.BufferedImage def outFolder = "../core/assets-raw/sprites_out/" def genFolder = "../core/assets-raw/sprites_out/generated/" +def doAntialias = true + def antialias = {File file -> + if(!doAntialias) return + def image = ImageIO.read(file) def out = ImageIO.read(file) def getRGB = { int ix, int iy -> + //if(ix <= 0 || iy <= 0 || ix >= image.width || iy >= image.height) return 0 return image.getRGB(Math.max(Math.min(ix, image.width - 1), 0), Math.max(Math.min(iy, image.height - 1), 0)) } @@ -112,6 +117,7 @@ task scaleSprites4x(){ def scaled = new BufferedImage(image.getWidth() * 2, image.getHeight() * 2, BufferedImage.TYPE_INT_ARGB) def getRGB = { int ix, int iy -> + //if(ix <= 0 || iy <= 0 || ix >= image.width || iy >= image.height) return 0 return image.getRGB(Math.max(Math.min(ix, image.width - 1), 0), Math.max(Math.min(iy, image.height - 1), 0)) } @@ -154,7 +160,6 @@ task scaleSprites4x(){ } } - task scaleSprites(){ finalizedBy 'genSprites' diff --git a/tools/src/io/anuke/mindustry/Generators.java b/tools/src/io/anuke/mindustry/Generators.java index cac0ece66d..37b4b23172 100644 --- a/tools/src/io/anuke/mindustry/Generators.java +++ b/tools/src/io/anuke/mindustry/Generators.java @@ -2,15 +2,21 @@ package io.anuke.mindustry; import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.g2d.TextureRegion; +import io.anuke.arc.math.Mathf; import io.anuke.arc.util.Log; -import io.anuke.mindustry.entities.units.UnitType; +import io.anuke.mindustry.ImagePacker.GenRegion; import io.anuke.mindustry.type.ContentType; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.Mech; +import io.anuke.mindustry.type.UnitType; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Block.Icon; +import io.anuke.mindustry.world.blocks.Floor; import io.anuke.mindustry.world.blocks.OreBlock; +import java.io.IOException; +import java.nio.file.Files; + import static io.anuke.mindustry.Vars.content; import static io.anuke.mindustry.Vars.tilesize; @@ -19,6 +25,9 @@ public class Generators { public static void generate(){ ImagePacker.generate("block-icons", () -> { + Image colors = new Image(256, 1); + Color outlineColor = new Color(0, 0, 0, 0.3f); + for(Block block : content.blocks()){ TextureRegion[] regions = block.getGeneratedIcons(); @@ -33,20 +42,76 @@ public class Generators { image.draw(region); } - image.save(block.name + "-icon-full"); + if(regions.length > 1){ + image.save(block.name + "-icon-full"); + } for(Icon icon : Icon.values()){ - if(icon.size == 0) continue; + if(icon.size == 0 || (icon.size == image.width() && icon.size == image.height())) continue; Image scaled = new Image(icon.size, icon.size); scaled.drawScaled(image); scaled.save(block.name + "-icon-" + icon.name()); } + + if(block.outlineIcon){ + int radius = 3; + GenRegion region = (GenRegion)regions[regions.length-1]; + Image base = ImagePacker.get(region); + Image out = new Image(region.getWidth(), region.getHeight()); + for(int x = 0; x < out.width(); x++){ + for(int y = 0; y < out.height(); y++){ + + Color color = base.getColor(x, y); + if(color.a >= 0.01f){ + out.draw(x, y, color); + }else{ + boolean found = false; + outer: + for(int rx = -radius; rx <= radius; rx++){ + for(int ry = -radius; ry <= radius; ry++){ + if(Mathf.dst(rx, ry) <= radius && base.getColor(rx + x, ry + y).a > 0.01f){ + found = true; + break outer; + } + } + } + if(found){ + out.draw(x, y, outlineColor); + } + } + + } + } + + try{ + Files.delete(region.path); + }catch(IOException e){ + e.printStackTrace(); + } + + out.save(block.name); + } + + Color average = new Color(); + for(int x = 0; x < image.width(); x++){ + for(int y = 0; y < image.height(); y++){ + Color color = image.getColor(x, y); + average.r += color.r; + average.g += color.g; + average.b += color.b; + } + } + average.mul(1f / (image.width() * image.height())); + average.a = 1f; + colors.draw(block.id, 0, average); }catch(IllegalArgumentException e){ Log.info("Skipping &ly'{0}'", block.name); }catch(NullPointerException e){ Log.err("Block &ly'{0}'&lr has an null region!"); } } + + colors.save("../../../assets/sprites/block_colors"); }); ImagePacker.generate("mech-icons", () -> { @@ -64,10 +129,10 @@ public class Generators { image.drawCenter(mech.region); } - int off = (image.width() - mech.weapon.equipRegion.getWidth())/2; + int off = (image.width() - mech.weapon.region.getWidth())/2; - image.draw(mech.weapon.equipRegion, -(int)mech.weaponOffsetX + off, (int)mech.weaponOffsetY + off, false, false); - image.draw(mech.weapon.equipRegion, (int)mech.weaponOffsetX + off, (int)mech.weaponOffsetY + off, true, false); + image.draw(mech.weapon.region, -(int)mech.weaponOffsetX + off, (int)mech.weaponOffsetY + off, false, false); + image.draw(mech.weapon.region, (int)mech.weaponOffsetX + off, (int)mech.weaponOffsetY + off, true, false); image.save("mech-icon-" + mech.name); @@ -76,27 +141,26 @@ public class Generators { ImagePacker.generate("unit-icons", () -> { for(UnitType type : content.getBy(ContentType.unit)){ + if(type.isFlying) continue; type.load(); type.weapon.load(); Image image = ImagePacker.get(type.region); - if(!type.isFlying){ - image.draw(type.baseRegion); - image.draw(type.legRegion); - image.draw(type.legRegion, true, false); - image.draw(type.region); + image.draw(type.baseRegion); + image.draw(type.legRegion); + image.draw(type.legRegion, true, false); + image.draw(type.region); - image.draw(type.weapon.equipRegion, - -(int)type.weaponOffsetX + (image.width() - type.weapon.equipRegion.getWidth())/2, - (int)type.weaponOffsetY - (image.height() - type.weapon.equipRegion.getHeight())/2 + 1, - false, false); - image.draw(type.weapon.equipRegion, - (int)type.weaponOffsetX + (image.width() - type.weapon.equipRegion.getWidth())/2, - (int)type.weaponOffsetY - (image.height() - type.weapon.equipRegion.getHeight())/2 + 1, - true, false); - } + image.draw(type.weapon.region, + -(int)type.weapon.width + (image.width() - type.weapon.region.getWidth())/2, + (int)type.weaponOffsetY - (image.height() - type.weapon.region.getHeight())/2 + 1, + false, false); + image.draw(type.weapon.region, + (int)type.weapon.width + (image.width() - type.weapon.region.getWidth())/2, + (int)type.weaponOffsetY - (image.height() - type.weapon.region.getHeight())/2 + 1, + true, false); image.save("unit-icon-" + type.name); } @@ -143,6 +207,33 @@ public class Generators { } } }); + + ImagePacker.generate("edges", () -> { + for(Block block : content.blocks()){ + if(!(block instanceof Floor)) continue; + + Floor floor = (Floor)block; + + if(ImagePacker.has(floor.name + "-edge") || floor.blendGroup != floor){ + continue; + } + + try{ + Image image = ImagePacker.get(floor.generateIcons()[0]); + Image edge = ImagePacker.get("edge-stencil-" + floor.edgeStyle); + Image result = new Image(edge.width(), edge.height()); + + for(int x = 0; x < edge.width(); x++){ + for(int y = 0; y < edge.height(); y++){ + result.draw(x, y, edge.getColor(x, y).mul(image.getColor(x % image.width(), y % image.height()))); + } + } + + result.save(floor.name + "-edge"); + + }catch(Exception ignored){} + } + }); } } diff --git a/tools/src/io/anuke/mindustry/Image.java b/tools/src/io/anuke/mindustry/Image.java index e97babec9b..5d975200cd 100644 --- a/tools/src/io/anuke/mindustry/Image.java +++ b/tools/src/io/anuke/mindustry/Image.java @@ -52,6 +52,7 @@ class Image { } Color getColor(int x, int y){ + if(!Structs.inBounds(x, y, width(), height())) return color.set(0, 0, 0, 0); int i = image.getRGB(x, y); Color.argb8888ToColor(color, i); return color; diff --git a/tools/src/io/anuke/mindustry/ImagePacker.java b/tools/src/io/anuke/mindustry/ImagePacker.java index 2b696bbea5..ee1a00b811 100644 --- a/tools/src/io/anuke/mindustry/ImagePacker.java +++ b/tools/src/io/anuke/mindustry/ImagePacker.java @@ -16,6 +16,7 @@ import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.IOException; import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.Paths; public class ImagePacker{ @@ -38,7 +39,7 @@ public class ImagePacker{ fname = fname.substring(0, fname.length() - 4); BufferedImage image = ImageIO.read(path.toFile()); - GenRegion region = new GenRegion(fname){ + GenRegion region = new GenRegion(fname, path){ @Override public int getX(){ @@ -73,13 +74,21 @@ public class ImagePacker{ @Override public AtlasRegion find(String name){ if(!regionCache.containsKey(name)){ - GenRegion region = new GenRegion(name); + GenRegion region = new GenRegion(name, null); region.invalid = true; return region; } return (AtlasRegion)regionCache.get(name); } + @Override + public AtlasRegion find(String name, TextureRegion def){ + if(!regionCache.containsKey(name)){ + return (AtlasRegion)def; + } + return (AtlasRegion)regionCache.get(name); + } + @Override public boolean has(String s) { return regionCache.containsKey(s); @@ -111,6 +120,10 @@ public class ImagePacker{ return get(Core.atlas.find(name)); } + static boolean has(String name){ + return Core.atlas.has(name); + } + static Image get(TextureRegion region){ GenRegion.validate(region); @@ -124,9 +137,11 @@ public class ImagePacker{ static class GenRegion extends AtlasRegion{ String name; boolean invalid; + Path path; - GenRegion(String name){ + GenRegion(String name, Path path){ this.name = name; + this.path = path; } static void validate(TextureRegion region){